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

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/tiff2bw.c,v 1.7 93/08/26 15:10:39 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 <stdlib.h>
  31.  
  32. #include "tiffio.h"
  33.  
  34. #define    streq(a,b)    (strcmp((a),(b)) == 0)
  35. #define    CopyField(tag, v) \
  36.     if (TIFFGetField(in, tag, &v)) TIFFSetField(out, tag, v)
  37.  
  38. /* x% weighting -> fraction of full color */
  39. #define    CVT(x)    (((x)*255)/100)
  40. int    RED = CVT(28);        /* 28% */
  41. int    GREEN = CVT(59);    /* 59% */
  42. int    BLUE = CVT(11);        /* 11% */
  43.  
  44. static void
  45. usage(void)
  46. {
  47.     fprintf(stderr,
  48.     "usage: tiff2bw [-r red%%] [-g green%%] [-b blue%%] input output\n");
  49.     exit(1);
  50. }
  51.  
  52. static void
  53. compresscontig(unsigned char* out, unsigned char* rgb, uint32 n)
  54. {
  55.     register int v, red = RED, green = GREEN, blue = BLUE;
  56.  
  57.     while (n-- > 0) {
  58.         v = red*(*rgb++);
  59.         v += green*(*rgb++);
  60.         v += blue*(*rgb++);
  61.         *out++ = v>>8;
  62.     }
  63. }
  64.  
  65. static void
  66. compresssep(unsigned char* out,
  67.     unsigned char* r, unsigned char* g, unsigned char* b, uint32 n)
  68. {
  69.     register int red = RED, green = GREEN, blue = BLUE;
  70.  
  71.     while (n-- > 0)
  72.         *out++ = (red*(*r++) + green*(*g++) + blue*(*b++)) >> 8;
  73. }
  74.  
  75. void
  76. main(int argc, char* argv[])
  77. {
  78.     TIFF *in, *out;
  79.     uint32 w, h;
  80.     uint16 samplesperpixel, bitspersample, shortv, config;
  81.     float floatv;
  82.     register uint32 row;
  83.     register tsample_t s;
  84.     unsigned char *inbuf, *outbuf;
  85.     char thing[1024];
  86.     uint32 rowsperstrip;
  87.     int c;
  88.     extern int optind;
  89.     extern char *optarg;
  90.  
  91.     while ((c = getopt(argc, argv, "r:g:b:")) != -1)
  92.         switch (c) {
  93.         case 'r':
  94.             RED = CVT(atoi(optarg));
  95.             break;
  96.         case 'g':
  97.             GREEN = CVT(atoi(optarg));
  98.             break;
  99.         case 'b':
  100.             BLUE = CVT(atoi(optarg));
  101.             break;
  102.         case '?':
  103.             usage();
  104.             /*NOTREACHED*/
  105.         }
  106.     if (argc - optind < 2)
  107.         usage();
  108.     in = TIFFOpen(argv[optind], "r");
  109.     if (in == NULL)
  110.         exit(-1);
  111.     TIFFGetField(in, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  112.     if (samplesperpixel != 3) {
  113.         fprintf(stderr, "%s: Not a color image.\n", argv[0]);
  114.         exit(-1);
  115.     }
  116.     TIFFGetField(in, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  117.     if (bitspersample != 8) {
  118.         fprintf(stderr,
  119.             " %s: Sorry, only handle 8-bit samples.\n", argv[0]);
  120.         exit(-1);
  121.     }
  122.     out = TIFFOpen(argv[optind+1], "w");
  123.     if (out == NULL)
  124.         exit(-1);
  125.     CopyField(TIFFTAG_IMAGEWIDTH, w);
  126.     CopyField(TIFFTAG_IMAGELENGTH, h);
  127.     TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
  128.     TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, 1);
  129.     TIFFSetField(out, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
  130.     TIFFSetField(out, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
  131.     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
  132.     sprintf(thing, "B&W version of %s", argv[optind]);
  133.     TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, thing);
  134.     TIFFSetField(out, TIFFTAG_SOFTWARE, "tiff2bw");
  135.     CopyField(TIFFTAG_ORIENTATION, shortv);
  136.     CopyField(TIFFTAG_XRESOLUTION, floatv);
  137.     CopyField(TIFFTAG_YRESOLUTION, floatv);
  138.     CopyField(TIFFTAG_RESOLUTIONUNIT, shortv);
  139.     outbuf = (unsigned char *)malloc(TIFFScanlineSize(out));
  140.     rowsperstrip = (8*1024)/TIFFScanlineSize(out);
  141.     if (rowsperstrip == 0)
  142.         rowsperstrip = 1;
  143.     TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, rowsperstrip);
  144.     TIFFGetField(in, TIFFTAG_PLANARCONFIG, &config);
  145.     switch (config) {
  146.     case PLANARCONFIG_CONTIG:
  147.         inbuf = (unsigned char *)malloc(TIFFScanlineSize(in));
  148.         for (row = 0; row < h; row++) {
  149.             if (TIFFReadScanline(in, inbuf, row, 0) < 0)
  150.                 break;
  151.             compresscontig(outbuf, inbuf, w);
  152.             if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
  153.                 break;
  154.         }
  155.         break;
  156.     case PLANARCONFIG_SEPARATE: {
  157.         tsize_t rowbytes = TIFFScanlineSize(in);
  158.         inbuf = (unsigned char *)malloc(3*rowbytes);
  159.         for (row = 0; row < h; row++) {
  160.             for (s = 0; s < 3; s++)
  161.                 if (TIFFReadScanline(in,
  162.                     inbuf+s*rowbytes, row, s) < 0)
  163.                      exit(-1);
  164.             compresssep(outbuf,
  165.                 inbuf, inbuf+rowbytes, inbuf+2*rowbytes, w);
  166.             if (TIFFWriteScanline(out, outbuf, row, 0) < 0)
  167.                 break;
  168.         }
  169.     }
  170.     }
  171.     TIFFClose(out);
  172. }
  173.