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

  1. /* $Header: /usr/people/sam/tiff/tools/RCS/sgi2tiff.c,v 1.26 1996/01/10 19:35:31 sam Rel $ */
  2.  
  3. /*
  4.  * Copyright (c) 1991-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. #include <gl/image.h>
  31. #include <ctype.h>
  32.  
  33. #include "tiffio.h"
  34.  
  35. #define    streq(a,b)    (strcmp(a,b) == 0)
  36. #define    strneq(a,b,n)    (strncmp(a,b,n) == 0)
  37.  
  38. static    short config = PLANARCONFIG_CONTIG;
  39. static    uint16 compression = COMPRESSION_LZW;
  40. static    uint16 predictor = 0;
  41. static    uint16 fillorder = 0;
  42. static    uint32 rowsperstrip = (uint32) -1;
  43. static    int jpegcolormode = JPEGCOLORMODE_RGB;
  44. static    int quality = 75;        /* JPEG quality */
  45. static    uint16 photometric;
  46.  
  47. static    void usage(void);
  48. static    int cpContig(IMAGE*, TIFF*);
  49. static    int cpSeparate(IMAGE*, TIFF*);
  50. static    int processCompressOptions(char*);
  51.  
  52. /* XXX image library has no prototypes */
  53. extern    IMAGE* iopen(const char*, const char*);
  54. extern    void iclose(IMAGE*);
  55. extern    void getrow(IMAGE*, short*, int, int);
  56.  
  57. int
  58. main(int argc, char* argv[])
  59. {
  60.     IMAGE *in;
  61.     TIFF *out;
  62.     int c;
  63.     extern int optind;
  64.     extern char* optarg;
  65.  
  66.     while ((c = getopt(argc, argv, "c:p:r:")) != -1)
  67.         switch (c) {
  68.         case 'c':        /* compression scheme */
  69.             if (!processCompressOptions(optarg))
  70.                 usage();
  71.             break;
  72.         case 'f':        /* fill order */
  73.             if (streq(optarg, "lsb2msb"))
  74.                 fillorder = FILLORDER_LSB2MSB;
  75.             else if (streq(optarg, "msb2lsb"))
  76.                 fillorder = FILLORDER_MSB2LSB;
  77.             else
  78.                 usage();
  79.             break;
  80.         case 'p':        /* planar configuration */
  81.             if (streq(optarg, "separate"))
  82.                 config = PLANARCONFIG_SEPARATE;
  83.             else if (streq(optarg, "contig"))
  84.                 config = PLANARCONFIG_CONTIG;
  85.             else
  86.                 usage();
  87.             break;
  88.         case 'r':        /* rows/strip */
  89.             rowsperstrip = atoi(optarg);
  90.             break;
  91.         case '?':
  92.             usage();
  93.             /*NOTREACHED*/
  94.         }
  95.     if (argc - optind != 2)
  96.         usage();
  97.     in = iopen(argv[optind], "r");
  98.     if (in == NULL)
  99.         return (-1);
  100.     out = TIFFOpen(argv[optind+1], "w");
  101.     if (out == NULL)
  102.         return (-2);
  103.     TIFFSetField(out, TIFFTAG_IMAGEWIDTH, (uint32) in->xsize);
  104.     TIFFSetField(out, TIFFTAG_IMAGELENGTH, (uint32) in->ysize);
  105.     TIFFSetField(out, TIFFTAG_BITSPERSAMPLE, 8);
  106.     TIFFSetField(out, TIFFTAG_COMPRESSION, compression);
  107.     if (in->zsize == 1)
  108.         photometric = PHOTOMETRIC_MINISBLACK;
  109.     else
  110.         photometric = PHOTOMETRIC_RGB;
  111.     switch (compression) {
  112.     case COMPRESSION_JPEG:
  113.         if (photometric == PHOTOMETRIC_RGB && jpegcolormode == JPEGCOLORMODE_RGB)
  114.             photometric = PHOTOMETRIC_YCBCR;
  115.         TIFFSetField(out, TIFFTAG_JPEGQUALITY, quality);
  116.         TIFFSetField(out, TIFFTAG_JPEGCOLORMODE, jpegcolormode);
  117.         break;
  118.     case COMPRESSION_LZW:
  119.     case COMPRESSION_DEFLATE:
  120.         if (predictor != 0)
  121.             TIFFSetField(out, TIFFTAG_PREDICTOR, predictor);
  122.         break;
  123.     }
  124.     TIFFSetField(out, TIFFTAG_PHOTOMETRIC, photometric);
  125.     if (fillorder != 0)
  126.         TIFFSetField(out, TIFFTAG_FILLORDER, fillorder);
  127.     TIFFSetField(out, TIFFTAG_ORIENTATION, ORIENTATION_TOPLEFT);
  128.     TIFFSetField(out, TIFFTAG_SAMPLESPERPIXEL, in->zsize);
  129.     if (in->zsize > 3) {
  130.         uint16 v[1];
  131.         v[0] = EXTRASAMPLE_UNASSALPHA;
  132.         TIFFSetField(out, TIFFTAG_EXTRASAMPLES, 1, v);
  133.     }
  134.     TIFFSetField(out, TIFFTAG_MINSAMPLEVALUE, (uint16) in->min);
  135.     TIFFSetField(out, TIFFTAG_MAXSAMPLEVALUE, (uint16) in->max);
  136.     TIFFSetField(out, TIFFTAG_PLANARCONFIG, config);
  137.     if (config != PLANARCONFIG_SEPARATE)
  138.         TIFFSetField(out, TIFFTAG_ROWSPERSTRIP,
  139.             TIFFDefaultStripSize(out, rowsperstrip));
  140.     else            /* force 1 row/strip for library limitation */
  141.         TIFFSetField(out, TIFFTAG_ROWSPERSTRIP, 1L);
  142.     if (in->name[0] != '\0')
  143.         TIFFSetField(out, TIFFTAG_IMAGEDESCRIPTION, in->name);
  144.     if (config == PLANARCONFIG_CONTIG)
  145.         cpContig(in, out);
  146.     else
  147.         cpSeparate(in, out);
  148.     (void) iclose(in);
  149.     (void) TIFFClose(out);
  150.     return (0);
  151. }
  152.  
  153. static int
  154. processCompressOptions(char* opt)
  155. {
  156.     if (streq(opt, "none"))
  157.         compression = COMPRESSION_NONE;
  158.     else if (streq(opt, "packbits"))
  159.         compression = COMPRESSION_PACKBITS;
  160.     else if (strneq(opt, "jpeg", 4)) {
  161.         char* cp = strchr(opt, ':');
  162.         if (cp && isdigit(cp[1]))
  163.             quality = atoi(cp+1);
  164.         if (cp && strchr(cp, 'r'))
  165.             jpegcolormode = JPEGCOLORMODE_RAW;
  166.         compression = COMPRESSION_JPEG;
  167.     } else if (strneq(opt, "lzw", 3)) {
  168.         char* cp = strchr(opt, ':');
  169.         if (cp)
  170.             predictor = atoi(cp+1);
  171.         compression = COMPRESSION_LZW;
  172.     } else if (strneq(opt, "zip", 3)) {
  173.         char* cp = strchr(opt, ':');
  174.         if (cp)
  175.             predictor = atoi(cp+1);
  176.         compression = COMPRESSION_DEFLATE;
  177.     } else
  178.         return (0);
  179.     return (1);
  180. }
  181.  
  182. static int
  183. cpContig(IMAGE* in, TIFF* out)
  184. {
  185.     tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
  186.     short *r = NULL;
  187.     int x, y;
  188.  
  189.     if (in->zsize == 3) {
  190.         short *g, *b;
  191.  
  192.         r = (short *)_TIFFmalloc(3 * in->xsize * sizeof (short));
  193.         g = r + in->xsize;
  194.         b = g + in->xsize;
  195.         for (y = in->ysize-1; y >= 0; y--) {
  196.             uint8* pp = (uint8*) buf;
  197.  
  198.             getrow(in, r, y, 0);
  199.             getrow(in, g, y, 1);
  200.             getrow(in, b, y, 2);
  201.             for (x = 0; x < in->xsize; x++) {
  202.                 pp[0] = r[x];
  203.                 pp[1] = g[x];
  204.                 pp[2] = b[x];
  205.                 pp += 3;
  206.             }
  207.             if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
  208.                 goto bad;
  209.         }
  210.     } else if (in->zsize == 4) {
  211.         short *g, *b, *a;
  212.  
  213.         r = (short *)_TIFFmalloc(4 * in->xsize * sizeof (short));
  214.         g = r + in->xsize;
  215.         b = g + in->xsize;
  216.         a = b + in->xsize;
  217.         for (y = in->ysize-1; y >= 0; y--) {
  218.             uint8* pp = (uint8*) buf;
  219.  
  220.             getrow(in, r, y, 0);
  221.             getrow(in, g, y, 1);
  222.             getrow(in, b, y, 2);
  223.             getrow(in, a, y, 3);
  224.             for (x = 0; x < in->xsize; x++) {
  225.                 pp[0] = r[x];
  226.                 pp[1] = g[x];
  227.                 pp[2] = b[x];
  228.                 pp[3] = a[x];
  229.                 pp += 4;
  230.             }
  231.             if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
  232.                 goto bad;
  233.         }
  234.     } else {
  235.         uint8* pp = (uint8*) buf;
  236.  
  237.         r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
  238.         for (y = in->ysize-1; y >= 0; y--) {
  239.             getrow(in, r, y, 0);
  240.             for (x = in->xsize-1; x >= 0; x--)
  241.                 pp[x] = r[x];
  242.             if (TIFFWriteScanline(out, buf, in->ysize-y-1, 0) < 0)
  243.                 goto bad;
  244.         }
  245.     }
  246.     if (r)
  247.         _TIFFfree(r);
  248.     _TIFFfree(buf);
  249.     return (1);
  250. bad:
  251.     if (r)
  252.         _TIFFfree(r);
  253.     _TIFFfree(buf);
  254.     return (0);
  255. }
  256.  
  257. static int
  258. cpSeparate(IMAGE* in, TIFF* out)
  259. {
  260.     tdata_t buf = _TIFFmalloc(TIFFScanlineSize(out));
  261.     short *r = (short *)_TIFFmalloc(in->xsize * sizeof (short));
  262.     uint8* pp = (uint8*) buf;
  263.     int x, y, z;
  264.  
  265.     for (z = 0; z < in->zsize; z++) {
  266.         for (y = in->ysize-1; y >= 0; y--) {
  267.             getrow(in, r, y, z);
  268.             for (x = 0; x < in->xsize; x++)
  269.                 pp[x] = r[x];
  270.             if (TIFFWriteScanline(out, buf, in->ysize-y-1, z) < 0)
  271.                 goto bad;
  272.         }
  273.     }
  274.     _TIFFfree(r);
  275.     _TIFFfree(buf);
  276.     return (1);
  277. bad:
  278.     _TIFFfree(r);
  279.     _TIFFfree(buf);
  280.     return (0);
  281. }
  282.  
  283. char* stuff[] = {
  284. "usage: sgi2tiff [options] input.rgb output.tif",
  285. "where options are:",
  286. " -r #        make each strip have no more than # rows",
  287. "",
  288. " -p contig    pack samples contiguously (e.g. RGBRGB...)",
  289. " -p separate    store samples separately (e.g. RRR...GGG...BBB...)",
  290. "",
  291. " -f lsb2msb    force lsb-to-msb FillOrder for output",
  292. " -f msb2lsb    force msb-to-lsb FillOrder for output",
  293. "",
  294. " -c lzw[:opts]    compress output with Lempel-Ziv & Welch encoding",
  295. " -c zip[:opts]    compress output with deflate encoding",
  296. " -c jpeg[:opts]compress output with JPEG encoding",
  297. " -c packbits    compress output with packbits encoding",
  298. " -c none    use no compression algorithm on output",
  299. "",
  300. "JPEG options:",
  301. " #        set compression quality level (0-100, default 75)",
  302. " r        output color image as RGB rather than YCbCr",
  303. "",
  304. "LZW and deflate options:",
  305. " #        set predictor value",
  306. "For example, -c lzw:2 to get LZW-encoded data with horizontal differencing",
  307. NULL
  308. };
  309.  
  310. static void
  311. usage(void)
  312. {
  313.     char buf[BUFSIZ];
  314.     int i;
  315.  
  316.     setbuf(stderr, buf);
  317.     for (i = 0; stuff[i] != NULL; i++)
  318.         fprintf(stderr, "%s\n", stuff[i]);
  319.     exit(-1);
  320. }
  321.