home *** CD-ROM | disk | FTP | other *** search
/ Crawly Crypt Collection 1 / crawlyvol1.bin / program / grfx_snd / tifflib / source / tiff2pnm.c < prev    next >
C/C++ Source or Header  |  1993-02-28  |  8KB  |  260 lines

  1. #pragma warn -use
  2. static char    *sccsid = "@(#)PBMplus/tiff2pnm 1.21, Copyright (c) Jef Poskanzer, Dieter Linde, "__DATE__;
  3. #pragma warn .use
  4. /*
  5.  * tiff2pnm.c - converts a Tagged Image File to a portable anymap
  6.  *
  7.  * Derived by Jef Poskanzer from tif2ras.c, which is:
  8.  *
  9.  * Copyright ©1990 by Sun Microsystems, Inc.
  10.  *
  11.  * Author: Patrick J. Naughton
  12.  * naughton@wind.sun.com
  13.  *
  14.  * Permission to use, copy, modify, and distribute this software and its
  15.  * documentation for any purpose and without fee is hereby granted,
  16.  * provided that the above copyright notice appear in all copies and that
  17.  * both that copyright notice and this permission notice appear in
  18.  * supporting documentation.
  19.  *
  20.  * This file is provided AS IS with no warranties of any kind.  The author
  21.  * shall have no liability with respect to the infringement of copyrights,
  22.  * trade secrets or any patents by this file or any part thereof.  In no
  23.  * event will the author be liable for any lost revenue or profits or
  24.  * other special, indirect and consequential damages.
  25.  */
  26. #include "pnm.h"
  27. #include "tiffio.h"
  28.  
  29. #define NEXTSAMPLE    {     if (bitsleft == 0) { \
  30.                         inP++; \
  31.                         bitsleft = 8; \
  32.                     } \
  33.                     bitsleft -= bps; \
  34.                     sample = (*inP >> bitsleft) & maxval; \
  35.                 }
  36.  
  37. /****************************************************************************
  38.  *
  39.  */
  40. void
  41. main(
  42.     int     argc,
  43.          char     *argv[]
  44.          )
  45. {
  46.         unsigned char    sample;
  47.         unsigned char    *inP, *buf;
  48.         int        col, bps, bitsleft, argn, cols, rows, grayscale, format, numcolors, row, i, headerdump;
  49.         xel        *xP, *xelrow;
  50.         xel         colormap[PNM_MAXMAXVAL + 1];
  51.         xelval         maxval;
  52.         TIFF           *tif;
  53.         FILE        *fp;
  54.         TIFFDirectory   *td;
  55.         char        *usage = "[-headerdump] [<tifffile>]";
  56.  
  57.         pnm_init("tiff2pnm", &argc, argv);
  58.  
  59.         argn = 1;
  60.         headerdump = 0;
  61.  
  62.         if (argn < argc && argv[argn][0] == '-' && argv[argn][1] != '\0') {
  63.             if (pm_keymatch(argv[argn], "-headerdump", 2))
  64.                     headerdump = 1;
  65.             else
  66.                     pm_usage(usage);
  67.             argn++;
  68.         }
  69.  
  70.         if (argn != argc) {
  71.             if ((tif = TIFFOpen(argv[argn], "rb")) == NULL)
  72.                     pm_error("error opening TIFF file %s", argv[argn]);
  73.             argn++;
  74.         }
  75.         else {
  76.             if ((tif = TIFFFdOpen(0, "stdin", "rb")) == NULL)
  77.                     pm_error("error opening stdin as TIFF file");
  78.         if (setvbuf(stdin, NULL, _IOFBF, stdbufsize))
  79.                     pm_error("out of memory allocating a filebuffer");
  80.         fsetmode(stdin, IO_BINARY);
  81.         fclrmode(stdin, IO_NBF);
  82.         }
  83.  
  84.         if (argn != argc)
  85.             pm_usage(usage);
  86.  
  87.         td = &tif->tif_dir;
  88.         if (headerdump)
  89.             TIFFPrintDirectory(tif, stderr, 0, 0, 0);
  90.         if ((bps = td->td_bitspersample) > 8)
  91.             pm_error("can't handle more than 8 bits per sample");
  92.  
  93.         switch (td->td_samplesperpixel) {
  94.             case 1:
  95.             case 3:
  96.             case 4:
  97.                 break;
  98.             default:
  99.                 pm_error("can only handle 1-channel gray scale or 1- or 3-channel color");
  100.         }
  101.  
  102.         cols = td->td_imagewidth;
  103.         rows = td->td_imagelength;
  104.  
  105.         if (headerdump) {
  106.             pm_message("%dx%dx%d image", cols, rows, bps * td->td_samplesperpixel);
  107.             pm_message("%d bits/sample, %d samples/pixel", bps, td->td_samplesperpixel);
  108.         }
  109.  
  110.         numcolors = (1 << bps);
  111.         if (numcolors - 1 > PNM_MAXMAXVAL)
  112.             pm_error("too many colors -- try recompiling with a larger PNM_MAXMAXVAL");
  113.         maxval = numcolors - 1;
  114.  
  115.         if (maxval == 1 && td->td_samplesperpixel == 1) {
  116.             if (headerdump)
  117.                     pm_message("monochrome");
  118.             grayscale = 1;
  119.         }
  120.         else {
  121.             switch (td->td_photometric) {
  122.                     case PHOTOMETRIC_MINISBLACK:
  123.                         if (headerdump)
  124.                             pm_message("%d graylevels (min=black)", numcolors);
  125.                         grayscale = 1;
  126.                         break;
  127.  
  128.                     case PHOTOMETRIC_MINISWHITE:
  129.                         if (headerdump)
  130.                             pm_message("%d graylevels (min=white)", numcolors);
  131.                         grayscale = 1;
  132.                         break;
  133.  
  134.                     case PHOTOMETRIC_PALETTE:
  135.                         if (headerdump)
  136.                             pm_message("colormapped");
  137.                         maxval = PNM_MAXMAXVAL;
  138.                         grayscale = 0;
  139.  
  140. #ifdef     PPM
  141.                         for (i = 0; i < numcolors; i++) {
  142.                             xelval    r, g, b;
  143.  
  144.                             r = (long)td->td_redcolormap[i] * PNM_MAXMAXVAL / 65535L;
  145.                             g = (long)td->td_greencolormap[i] * PNM_MAXMAXVAL / 65535L;
  146.                             b = (long)td->td_bluecolormap[i] * PNM_MAXMAXVAL / 65535L;
  147.                             PPM_ASSIGN(colormap[i], r, g, b);
  148.                         }
  149. #endif     /* PPM */
  150.  
  151.                         break;
  152.  
  153.                     case PHOTOMETRIC_RGB:
  154.                         if (headerdump)
  155.                             pm_message("truecolor");
  156.                         grayscale = 0;
  157.                         break;
  158.  
  159.                     case PHOTOMETRIC_MASK:
  160.                         pm_error("don't know how to handle PHOTOMETRIC_MASK");
  161.  
  162.                     case PHOTOMETRIC_DEPTH:
  163.                         pm_error("don't know how to handle PHOTOMETRIC_DEPTH");
  164.  
  165.                     default:
  166.                         pm_error("unknown photometric: %d", td->td_photometric);
  167.                 }
  168.            }
  169.  
  170.         if (grayscale) {
  171.             if (maxval == 1) {
  172.                     format = PBM_TYPE;
  173.                     pm_message("writing PBM file");
  174.                 }
  175.             else {
  176.  
  177. #ifdef     PGM
  178.                     format = PGM_TYPE;
  179.                     pm_message("writing PGM file");
  180. #else     /* PGM */
  181.                     pm_error("can't read grayscale TIFF file without PGM defined -- try reconfiguring");
  182. #endif     /* PGM */
  183.                 }
  184.         }
  185.         else {
  186.  
  187. #ifdef     PPM
  188.             format = PPM_TYPE;
  189.             pm_message("writing PPM file");
  190. #else     /* PPM */
  191.             pm_error("can't read color TIFF file without PPM defined -- try reconfiguring");
  192. #endif     /* PPM */
  193.         }
  194.  
  195.         if ((buf = (unsigned char *)malloc(TIFFScanlineSize(tif))) == NULL)
  196.                 pm_error("out of memory allocating scanline buffer");
  197.         pnm_writepnminit(stdout, cols, rows, maxval, format, 0);
  198.         xelrow = pnm_allocrow(cols);
  199.  
  200.         for (row = 0; row < rows; row++) {
  201.             if (TIFFReadScanline(tif, buf, row, 0) < 0)
  202.                     pm_error("bad data read on line %d", row);
  203.             inP = buf;
  204.             bitsleft = 8;
  205.             xP = xelrow;
  206.  
  207.             switch (td->td_photometric) {
  208.                     case PHOTOMETRIC_MINISBLACK:
  209.                         for (col = 0; col < cols; col++, xP++) {
  210.                             NEXTSAMPLE
  211.                             PNM_ASSIGN1(*xP, sample);
  212.                         }
  213.                         break;
  214.  
  215.                     case PHOTOMETRIC_MINISWHITE:
  216.                         for (col = 0; col < cols; col++, xP++) {
  217.                             NEXTSAMPLE
  218.                             sample = maxval - sample;
  219.                             PNM_ASSIGN1(*xP, sample);
  220.                         }
  221.                         break;
  222.  
  223.                     case PHOTOMETRIC_PALETTE:
  224.                         for (col = 0; col < cols; col++, xP++) {
  225.                             NEXTSAMPLE
  226.                             *xP = colormap[sample];
  227.                         }
  228.                         break;
  229.  
  230.                     case PHOTOMETRIC_RGB:
  231.  
  232. #ifdef     PPM
  233.                         for (col = 0; col < cols; col++, xP++) {
  234.                             xelval    r, g, b;
  235.  
  236.                             NEXTSAMPLE
  237.                             r = sample;
  238.                             NEXTSAMPLE
  239.                             g = sample;
  240.                             NEXTSAMPLE
  241.                             b = sample;
  242.                             if (td->td_samplesperpixel == 4)
  243.                                     NEXTSAMPLE    /* skip alpha channel */
  244.                             PPM_ASSIGN(*xP, r, g, b);
  245.                         }
  246.                         break;
  247. #else     /* PPM */
  248.                         pm_error("can't read color TIFF file without PPM defined -- try reconfiguring");
  249. #endif     /* PPM */
  250.  
  251.                     default:
  252.                         pm_error("unknown photometric: %d", td->td_photometric);
  253.                 }
  254.             pnm_writepnmrow(stdout, xelrow, cols, maxval, format, 0);
  255.            }
  256.  
  257.     fflush(stdout);
  258.         exit(0);
  259. }
  260.