home *** CD-ROM | disk | FTP | other *** search
/ Practical Algorithms for Image Analysis / Practical Algorithms for Image Analysis.iso / TARFILE.GZ / tarfile / libtiff / tools / tiffinfo.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-11  |  10.1 KB  |  425 lines

  1. /* $Header: /usr/people/sam/tiff/tools/RCS/tiffinfo.c,v 1.26 1996/01/10 19:35:39 sam Rel $ */
  2.  
  3. /*
  4.  * Copyright (c) 1988-1996 Sam Leffler
  5.  * Copyright (c) 1991-1996 Silicon Graphics, Inc.
  6.  *
  7.  * Permission to use, copy, modify, distribute, and sell this software and 
  8.  * its documentation for any purpose is hereby granted without fee, provided
  9.  * that (i) the above copyright notices and this permission notice appear in
  10.  * all copies of the software and related documentation, and (ii) the names of
  11.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  12.  * publicity relating to the software without the specific, prior written
  13.  * permission of Sam Leffler and Silicon Graphics.
  14.  * 
  15.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  16.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  17.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  18.  * 
  19.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  20.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  21.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  22.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  23.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  24.  * OF THIS SOFTWARE.
  25.  */
  26.  
  27. #include <stdio.h>
  28. #include <stdlib.h>
  29. #include <string.h>
  30.  
  31. #include "tiffio.h"
  32.  
  33. #define    streq(a,b)    (strcmp(a,b) == 0)
  34.  
  35. int    showdata = 0;            /* show data */
  36. int    rawdata = 0;            /* show raw/decoded data */
  37. int    showwords = 0;            /* show data as bytes/words */
  38. int    readdata = 0;            /* read data in file */
  39. int    stoponerr = 1;            /* stop on first read error */
  40.  
  41. static    void usage(void);
  42. static    void tiffinfo(TIFF*, uint16, long);
  43.  
  44. int
  45. main(int argc, char* argv[])
  46. {
  47.     int dirnum = -1, multiplefiles, c;
  48.     uint16 order = 0;
  49.     TIFF* tif;
  50.     extern int optind;
  51.     extern char* optarg;
  52.     long flags = 0;
  53.     uint32 diroff = 0;
  54.  
  55.     while ((c = getopt(argc, argv, "f:o:cdDSjlmrsvw0123456789")) != -1)
  56.         switch (c) {
  57.         case '0': case '1': case '2': case '3':
  58.         case '4': case '5': case '6': case '7':
  59.         case '8': case '9':
  60.             dirnum = atoi(&argv[optind-1][1]);
  61.             break;
  62.         case 'd':
  63.             showdata++;
  64.             /* fall thru... */
  65.         case 'D':
  66.             readdata++;
  67.             break;
  68.         case 'c':
  69.             flags |= TIFFPRINT_COLORMAP | TIFFPRINT_CURVES;
  70.             break;
  71.         case 'f':        /* fill order */
  72.             if (streq(optarg, "lsb2msb"))
  73.                 order = FILLORDER_LSB2MSB;
  74.             else if (streq(optarg, "msb2lsb"))
  75.                 order = FILLORDER_MSB2LSB;
  76.             else
  77.                 usage();
  78.             break;
  79.         case 'i':
  80.             stoponerr = 0;
  81.             break;
  82.         case 'o':
  83.             diroff = strtoul(optarg, NULL, 0);
  84.             break;
  85.         case 'j':
  86.             flags |= TIFFPRINT_JPEGQTABLES |
  87.                  TIFFPRINT_JPEGACTABLES |
  88.                  TIFFPRINT_JPEGDCTABLES;
  89.             break;
  90.         case 'r':
  91.             rawdata = 1;
  92.             break;
  93.         case 's':
  94.             flags |= TIFFPRINT_STRIPS;
  95.             break;
  96.         case 'w':
  97.             showwords = 1;
  98.             break;
  99.         case '?':
  100.             usage();
  101.             /*NOTREACHED*/
  102.         }
  103.     if (optind >= argc)
  104.         usage();
  105.     multiplefiles = (argc - optind > 1);
  106.     for (; optind < argc; optind++) {
  107.         if (multiplefiles)
  108.             printf("%s:\n", argv[optind]);
  109.         tif = TIFFOpen(argv[optind], "r");
  110.         if (tif != NULL) {
  111.             if (dirnum != -1) {
  112.                 if (TIFFSetDirectory(tif, dirnum))
  113.                     tiffinfo(tif, order, flags);
  114.             } else if (diroff != 0) {
  115.                 if (TIFFSetSubDirectory(tif, diroff))
  116.                     tiffinfo(tif, order, flags);
  117.             } else {
  118.                 do
  119.                     tiffinfo(tif, order, flags);
  120.                 while (TIFFReadDirectory(tif));
  121.             }
  122.             TIFFClose(tif);
  123.         }
  124.     }
  125.     return (0);
  126. }
  127.  
  128. char* stuff[] = {
  129. "usage: tiffinfo [options] input...",
  130. "where options are:",
  131. " -D        read data",
  132. " -i        ignore read errors",
  133. " -c        display data for grey/color response curve or colormap",
  134. " -d        display raw/decoded image data",
  135. " -f lsb2msb    force lsb-to-msb FillOrder for input",
  136. " -f msb2lsb    force msb-to-lsb FillOrder for input",
  137. " -j        show JPEG tables",
  138. " -o offset    set initial directory offset",
  139. " -r        read/display raw image data instead of decoded data",
  140. " -s        display strip offsets and byte counts",
  141. " -w        display raw data in words rather than bytes",
  142. " -#        set initial directory (first directory is # 0)",
  143. NULL
  144. };
  145.  
  146. static void
  147. usage(void)
  148. {
  149.     char buf[BUFSIZ];
  150.     int i;
  151.  
  152.     setbuf(stderr, buf);
  153.     for (i = 0; stuff[i] != NULL; i++)
  154.         fprintf(stderr, "%s\n", stuff[i]);
  155.     exit(-1);
  156. }
  157.  
  158. static void
  159. ShowStrip(tstrip_t strip, unsigned char* pp, uint32 nrow, tsize_t scanline)
  160. {
  161.     register tsize_t cc;
  162.  
  163.     printf("Strip %lu:\n", (unsigned long) strip);
  164.     while (nrow-- > 0) {
  165.         for (cc = 0; cc < scanline; cc++) {
  166.             printf(" %02x", *pp++);
  167.             if (((cc+1) % 24) == 0)
  168.                 putchar('\n');
  169.         }
  170.         putchar('\n');
  171.     }
  172. }
  173.  
  174. void
  175. TIFFReadContigStripData(TIFF* tif)
  176. {
  177.     unsigned char *buf;
  178.     tsize_t scanline = TIFFScanlineSize(tif);
  179.  
  180.     buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
  181.     if (buf) {
  182.         uint32 row, h;
  183.         uint32 rowsperstrip = (uint32)-1;
  184.  
  185.         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  186.         TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  187.         for (row = 0; row < h; row += rowsperstrip) {
  188.             uint32 nrow = (row+rowsperstrip > h ?
  189.                 h-row : rowsperstrip);
  190.             tstrip_t strip = TIFFComputeStrip(tif, row, 0);
  191.             if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) {
  192.                 if (stoponerr)
  193.                     break;
  194.             } else if (showdata)
  195.                 ShowStrip(strip, buf, nrow, scanline);
  196.         }
  197.         _TIFFfree(buf);
  198.     }
  199. }
  200.  
  201. void
  202. TIFFReadSeparateStripData(TIFF* tif)
  203. {
  204.     unsigned char *buf;
  205.     tsize_t scanline = TIFFScanlineSize(tif);
  206.  
  207.     buf = (unsigned char *)_TIFFmalloc(TIFFStripSize(tif));
  208.     if (buf) {
  209.         uint32 row, h;
  210.         uint32 rowsperstrip = (uint32)-1;
  211.         tsample_t s, samplesperpixel;
  212.  
  213.         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  214.         TIFFGetField(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  215.         TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  216.         for (row = 0; row < h; row += rowsperstrip) {
  217.             for (s = 0; s < samplesperpixel; s++) {
  218.                 uint32 nrow = (row+rowsperstrip > h ?
  219.                     h-row : rowsperstrip);
  220.                 tstrip_t strip = TIFFComputeStrip(tif, row, s);
  221.                 if (TIFFReadEncodedStrip(tif, strip, buf, nrow*scanline) < 0) {
  222.                     if (stoponerr)
  223.                         break;
  224.                 } else if (showdata)
  225.                     ShowStrip(strip, buf, nrow, scanline);
  226.             }
  227.         }
  228.         _TIFFfree(buf);
  229.     }
  230. }
  231.  
  232. static void
  233. ShowTile(uint32 row, uint32 col, tsample_t sample,
  234.     unsigned char* pp, uint32 nrow, uint32 rowsize)
  235. {
  236.     register tsize_t cc;
  237.  
  238.     printf("Tile (%lu,%lu", (unsigned long) row, (unsigned long) col);
  239.     if (sample != (tsample_t) -1)
  240.         printf(",%u", sample);
  241.     printf("):\n");
  242.     while (nrow-- > 0) {
  243.         for (cc = 0; cc < rowsize; cc++) {
  244.             printf(" %02x", *pp++);
  245.             if (((cc+1) % 24) == 0)
  246.                 putchar('\n');
  247.         }
  248.         putchar('\n');
  249.     }
  250. }
  251.  
  252. void
  253. TIFFReadContigTileData(TIFF* tif)
  254. {
  255.     unsigned char *buf;
  256.     tsize_t rowsize = TIFFTileRowSize(tif);
  257.  
  258.     buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif));
  259.     if (buf) {
  260.         uint32 tw, th, w, h;
  261.         uint32 row, col;
  262.  
  263.         TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  264.         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  265.         TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  266.         TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  267.         for (row = 0; row < h; row += th) {
  268.             for (col = 0; col < w; col += tw) {
  269.                 if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0) {
  270.                     if (stoponerr)
  271.                         break;
  272.                 } else if (showdata)
  273.                     ShowTile(row, col, (tsample_t) -1, buf, th, rowsize);
  274.             }
  275.         }
  276.         _TIFFfree(buf);
  277.     }
  278. }
  279.  
  280. void
  281. TIFFReadSeparateTileData(TIFF* tif)
  282. {
  283.     unsigned char *buf;
  284.     tsize_t rowsize = TIFFTileRowSize(tif);
  285.  
  286.     buf = (unsigned char *)_TIFFmalloc(TIFFTileSize(tif));
  287.     if (buf) {
  288.         uint32 tw, th, w, h;
  289.         uint32 row, col;
  290.         tsample_t s, samplesperpixel;
  291.  
  292.         TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
  293.         TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
  294.         TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  295.         TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  296.         TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  297.         for (row = 0; row < h; row += th) {
  298.             for (col = 0; col < w; col += tw) {
  299.                 for (s = 0; s < samplesperpixel; s++) {
  300.                     if (TIFFReadTile(tif, buf, col, row, 0, s) < 0) {
  301.                         if (stoponerr)
  302.                             break;
  303.                     } else if (showdata)
  304.                         ShowTile(row, col, s, buf, th, rowsize);
  305.                 }
  306.             }
  307.         }
  308.         _TIFFfree(buf);
  309.     }
  310. }
  311.  
  312. void
  313. TIFFReadData(TIFF* tif)
  314. {
  315.     uint16 config;
  316.  
  317.     TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &config);
  318.     if (TIFFIsTiled(tif)) {
  319.         if (config == PLANARCONFIG_CONTIG)
  320.             TIFFReadContigTileData(tif);
  321.         else
  322.             TIFFReadSeparateTileData(tif);
  323.     } else {
  324.         if (config == PLANARCONFIG_CONTIG)
  325.             TIFFReadContigStripData(tif);
  326.         else
  327.             TIFFReadSeparateStripData(tif);
  328.     }
  329. }
  330.  
  331. static void
  332. ShowRawBytes(unsigned char* pp, uint32 n)
  333. {
  334.     tsize_t i;
  335.  
  336.     for (i = 0; i < n; i++) {
  337.         printf(" %02x", *pp++);
  338.         if (((i+1) % 24) == 0)
  339.             printf("\n ");
  340.     }
  341.     putchar('\n');
  342. }
  343.  
  344. static void
  345. ShowRawWords(uint16* pp, uint32 n)
  346. {
  347.     tsize_t i;
  348.  
  349.     for (i = 0; i < n; i++) {
  350.         printf(" %04x", *pp++);
  351.         if (((i+1) % 15) == 0)
  352.             printf("\n ");
  353.     }
  354.     putchar('\n');
  355. }
  356.  
  357. void
  358. TIFFReadRawData(TIFF* tif, int bitrev)
  359. {
  360.     tstrip_t nstrips = TIFFNumberOfStrips(tif);
  361.     const char* what = TIFFIsTiled(tif) ? "Tile" : "Strip";
  362.     uint32* stripbc;
  363.  
  364.     TIFFGetField(tif, TIFFTAG_STRIPBYTECOUNTS, &stripbc);
  365.     if (nstrips > 0) {
  366.         tsize_t bufsize = stripbc[0];
  367.         tdata_t buf = _TIFFmalloc(bufsize);
  368.         tstrip_t s;
  369.  
  370.         for (s = 0; s < nstrips; s++) {
  371.             if (stripbc[s] > bufsize) {
  372.                 buf = _TIFFrealloc(buf, stripbc[s]);
  373.                 bufsize = stripbc[s];
  374.             }
  375.             if (buf == NULL) {
  376.                 fprintf(stderr,
  377.                    "Cannot allocate buffer to read strip %lu\n",
  378.                     (unsigned long) s);
  379.                 break;
  380.             }
  381.             if (TIFFReadRawStrip(tif, s, buf, stripbc[s]) < 0) {
  382.                 fprintf(stderr, "Error reading strip %lu\n",
  383.                     (unsigned long) s);
  384.                 if (stoponerr)
  385.                     break;
  386.             } else if (showdata) {
  387.                 if (bitrev) {
  388.                     TIFFReverseBits(buf, stripbc[s]);
  389.                     printf("%s %lu: (bit reversed)\n ",
  390.                         what, (unsigned long) s);
  391.                 } else
  392.                     printf("%s %lu:\n ", what,
  393.                         (unsigned long) s);
  394.                 if (showwords)
  395.                     ShowRawWords((uint16*) buf, stripbc[s]>>1);
  396.                 else
  397.                     ShowRawBytes((unsigned char*) buf, stripbc[s]);
  398.             }
  399.         }
  400.         if (buf != NULL)
  401.             _TIFFfree(buf);
  402.     }
  403. }
  404.  
  405. static void
  406. tiffinfo(TIFF* tif, uint16 order, long flags)
  407. {
  408.     TIFFPrintDirectory(tif, stdout, flags);
  409.     if (!readdata)
  410.         return;
  411.     if (rawdata) {
  412.         if (order) {
  413.             uint16 o;
  414.             TIFFGetFieldDefaulted(tif,
  415.                 TIFFTAG_FILLORDER, &o);
  416.             TIFFReadRawData(tif, o != order);
  417.         } else
  418.             TIFFReadRawData(tif, 0);
  419.     } else {
  420.         if (order)
  421.             TIFFSetField(tif, TIFFTAG_FILLORDER, order);
  422.         TIFFReadData(tif);
  423.     }
  424. }
  425.