home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / libtiff / lbtif3_3.tar / tools / pal2rgb.c < prev    next >
C/C++ Source or Header  |  1993-08-26  |  7KB  |  251 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/pal2rgb.c,v 1.10 93/08/26 15:08:11 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1988, 1989, 1990, 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. #include <stdio.h>
  30. #include <string.h>
  31. #include <stdlib.h>
  32.  
  33. #include "tiffio.h"
  34.  
  35. #define    howmany(x, y)    (((x)+((y)-1))/(y))
  36. #define    streq(a,b)    (strcmp(a,b) == 0)
  37. #define    CopyField(tag, v) \
  38.     if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
  39. #define    CopyField3(tag, v1, v2, v3) \
  40.     if (TIFFGetField(in, tag, &v1, &v2, &v3)) TIFFSetField(out, tag, v1, v2, v3)
  41.  
  42. void    usage(void);
  43.  
  44. static int
  45. checkcmap(int n, uint16* r, uint16* g, uint16* b)
  46. {
  47.     while (n-- > 0)
  48.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  49.         return (16);
  50.     fprintf(stderr, "Warning, assuming 8-bit colormap.\n");
  51.     return (8);
  52. }
  53.  
  54. void
  55. main(int argc, char* argv[])
  56. {
  57.     uint16 bitspersample, samplesperpixel, shortv;
  58.     uint32 imagewidth, imagelength;
  59.     uint16 config = PLANARCONFIG_CONTIG;
  60.     uint16 compression = -1;
  61.     uint32 rowsperstrip = -1;
  62.     float floatv;
  63.     char *stringv;
  64.     uint32 longv;
  65.     uint16 *rmap, *gmap, *bmap;
  66.     uint32 row;
  67.     tsample_t s;
  68.     int cmap = -1;
  69.     TIFF *in, *out;
  70.  
  71.     argc--, argv++;
  72.     if (argc < 2)
  73.         usage();
  74.     for (; argc > 2 && argv[0][0] == '-'; argc--, argv++) {
  75.         if (streq(argv[0], "-none")) {
  76.             compression = COMPRESSION_NONE;
  77.             continue;
  78.         }
  79.         if (streq(argv[0], "-packbits")) {
  80.             compression = COMPRESSION_PACKBITS;
  81.             continue;
  82.         }
  83.         if (streq(argv[0], "-lzw")) {
  84.             compression = COMPRESSION_LZW;
  85.             continue;
  86.         }
  87.         if (streq(argv[0], "-contig")) {
  88.             config = PLANARCONFIG_CONTIG;
  89.             continue;
  90.         }
  91.         if (streq(argv[0], "-separate")) {
  92.             config = PLANARCONFIG_SEPARATE;
  93.             continue;
  94.         }
  95.         if (streq(argv[0], "-8bit")) {
  96.             cmap = 8;
  97.             continue;
  98.         }
  99.         if (streq(argv[0], "-16bit")) {
  100.             cmap = 16;
  101.             continue;
  102.         }
  103.         if (streq(argv[0], "-rowsperstrip")) {
  104.             argc--, argv++;
  105.             rowsperstrip = atoi(argv[0]);
  106.             continue;
  107.         }
  108.         usage();
  109.     }
  110.     in = TIFFOpen(argv[0], "r");
  111.     if (in == NULL)
  112.         exit(-1);
  113.     if (!TIFFGetField(in, TIFFTAG_PHOTOMETRIC, &shortv) ||
  114.         shortv != PHOTOMETRIC_PALETTE) {
  115.         fprintf(stderr, "%s: Expecting a palette image.\n", argv[0]);
  116.         exit(-1);
  117.     }
  118.     if (!TIFFGetField(in, TIFFTAG_COLORMAP, &rmap, &gmap, &bmap)) {
  119.         fprintf(stderr,
  120.             "%s: No colormap (not a valid palette image).\n",
  121.             argv[0]);
  122.         exit(-1);
  123.     }
  124.     out = TIFFOpen(argv[1], "w");
  125.     if (out == NULL)
  126.         exit(-2);
  127.     CopyField(TIFFTAG_SUBFILETYPE, longv);
  128.     CopyField(TIFFTAG_IMAGEWIDTH, imagewidth);
  129.     CopyField(TIFFTAG_IMAGELENGTH, imagelength);
  130.     CopyField(TIFFTAG_BITSPERSAMPLE, bitspersample);
  131.     if (bitspersample != 8) {
  132.         fprintf(stderr, "%s: Sorry, can only handle 8-bit images.\n",
  133.             argv[0]);
  134.         exit(-1);
  135.     }
  136.     if (compression != (uint16)-1)
  137.         TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
  138.     else
  139.         CopyField(TIFFTAG_COMPRESSION, compression);
  140.     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
  141.     CopyField(TIFFTAG_ORIENTATION, shortv);
  142.     TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 3);
  143.     CopyField(TIFFTAG_PREDICTOR, shortv);
  144.     CopyField(TIFFTAG_MINSAMPLEVALUE, shortv);
  145.     CopyField(TIFFTAG_MAXSAMPLEVALUE, shortv);
  146.     CopyField(TIFFTAG_XRESOLUTION, floatv);
  147.     CopyField(TIFFTAG_YRESOLUTION, floatv);
  148.     CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
  149.     TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
  150.     if (rowsperstrip <= 0)
  151.         rowsperstrip = (8*1024)/TIFFScanlineSize(out);
  152.     TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
  153.         rowsperstrip == 0 ? 1 : rowsperstrip);
  154.     CopyField(TIFFTAG_XPOSITION, floatv);
  155.     CopyField(TIFFTAG_YPOSITION, floatv);
  156.     CopyField(TIFFTAG_ARTIST, stringv);
  157.     CopyField(TIFFTAG_IMAGEDESCRIPTION, stringv);
  158.     CopyField(TIFFTAG_MAKE, stringv);
  159.     CopyField(TIFFTAG_MODEL, stringv);
  160.     CopyField(TIFFTAG_SOFTWARE, stringv);
  161.     CopyField(TIFFTAG_DATETIME, stringv);
  162.     CopyField(TIFFTAG_HOSTCOMPUTER, stringv);
  163.     CopyField(TIFFTAG_PAGENAME, stringv);
  164.     CopyField(TIFFTAG_DOCUMENTNAME, stringv);
  165.     (void) TIFFGetField(in, TIFFTAG_PLANARCONFIG, &shortv);
  166.     if (cmap == -1)
  167.         cmap = checkcmap(1<<bitspersample, rmap, gmap, bmap);
  168.     if (cmap == 16) {
  169.         /*
  170.          * Convert 16-bit colormap to 8-bit.
  171.          */
  172.         int i;
  173.  
  174.         for (i = (1<<bitspersample)-1; i > 0; i--) {
  175. #define    CVT(x)        (((x) * 255) / ((1L<<16)-1))
  176.             rmap[i] = CVT(rmap[i]);
  177.             gmap[i] = CVT(gmap[i]);
  178.             bmap[i] = CVT(bmap[i]);
  179.         }
  180.     }
  181.     { unsigned char *ibuf, *obuf;
  182.       register unsigned char* pp;
  183.       register uint32 x;
  184.       ibuf = (unsigned char*)malloc(TIFFScanlineSize(in));
  185.       obuf = (unsigned char*)malloc(TIFFScanlineSize(out));
  186.       switch (config) {
  187.       case PLANARCONFIG_CONTIG:
  188.         for (row = 0; row < imagelength; row++) {
  189.             if (!TIFFReadScanline(in, ibuf, row, 0))
  190.                 goto done;
  191.             pp = obuf;
  192.             for (x = 0; x < imagewidth; x++) {
  193.                 *pp++ = rmap[ibuf[x]];
  194.                 *pp++ = gmap[ibuf[x]];
  195.                 *pp++ = bmap[ibuf[x]];
  196.             }
  197.             if (!TIFFWriteScanline(out, obuf, row, 0))
  198.                 goto done;
  199.         }
  200.         break;
  201.       case PLANARCONFIG_SEPARATE:
  202.         for (row = 0; row < imagelength; row++) {
  203.             if (!TIFFReadScanline(in, ibuf, row, 0))
  204.                 goto done;
  205.             for (pp = obuf, x = 0; x < imagewidth; x++)
  206.                 *pp++ = rmap[ibuf[x]];
  207.             if (!TIFFWriteScanline(out, obuf, row, 0))
  208.                 goto done;
  209.             for (pp = obuf, x = 0; x < imagewidth; x++)
  210.                 *pp++ = gmap[ibuf[x]];
  211.             if (!TIFFWriteScanline(out, obuf, row, 0))
  212.                 goto done;
  213.             for (pp = obuf, x = 0; x < imagewidth; x++)
  214.                 *pp++ = bmap[ibuf[x]];
  215.             if (!TIFFWriteScanline(out, obuf, row, 0))
  216.                 goto done;
  217.         }
  218.         break;
  219.       }
  220.       free(ibuf);
  221.       free(obuf);
  222.     }
  223. done:
  224.     (void) TIFFClose(in);
  225.     (void) TIFFClose(out);
  226. }
  227.  
  228. void
  229. usage(void)
  230. {
  231.     fprintf(stderr, "usage: pal2rgb [options] input output\n");
  232.     fprintf(stderr, "where options are:\n");
  233.     fprintf(stderr,
  234.         " -contig\tpack samples contiguously (e.g. RGBRGB...)\n");
  235.     fprintf(stderr,
  236.         " -separate\tstore samples separately (e.g. RRR...GGG...BBB...)\n");
  237.     fprintf(stderr, "\n");
  238.     fprintf(stderr,
  239.         " -lzw\t\tcompress output with Lempel-Ziv & Welch encoding\n");
  240.     fprintf(stderr,
  241.         " -packbits\tcompress output with packbits encoding\n");
  242.     fprintf(stderr,
  243.         " -none\t\tuse no compression algorithm on output\n");
  244.     fprintf(stderr, "\n");
  245.     fprintf(stderr,
  246.         " -8bit\tassume 8-bit colormap values (instead of 16-bit)\n");
  247.     fprintf(stderr,
  248.         " -rowsperstrip #\tmake each strip have no more than # rows\n");
  249.     exit(-1);
  250. }
  251.