home *** CD-ROM | disk | FTP | other *** search
/ Encyclopedia of Graphics File Formats Companion / GFF_CD.ISO / software / unix / libtiff / lbtif3_3.tar / contrib / ras / tif2ras.c < prev   
C/C++ Source or Header  |  1991-05-20  |  9KB  |  338 lines

  1. #ifndef lint
  2. static char sccsid[] = "@(#)tif2ras.c 1.2 90/03/06";
  3. #endif
  4. /*-
  5.  * tif2ras.c - Converts from a Tagged Image File Format image to a Sun Raster.
  6.  *
  7.  * Copyright (c) 1990 by Sun Microsystems, Inc.
  8.  *
  9.  * Author: Patrick J. Naughton
  10.  * naughton@wind.sun.com
  11.  *
  12.  * Permission to use, copy, modify, and distribute this software and its
  13.  * documentation for any purpose and without fee is hereby granted,
  14.  * provided that the above copyright notice appear in all copies and that
  15.  * both that copyright notice and this permission notice appear in
  16.  * supporting documentation.
  17.  *
  18.  * This file is provided AS IS with no warranties of any kind.  The author
  19.  * shall have no liability with respect to the infringement of copyrights,
  20.  * trade secrets or any patents by this file or any part thereof.  In no
  21.  * event will the author be liable for any lost revenue or profits or
  22.  * other special, indirect and consequential damages.
  23.  *
  24.  * Comments and additions should be sent to the author:
  25.  *
  26.  *                     Patrick J. Naughton
  27.  *                     Sun Microsystems
  28.  *                     2550 Garcia Ave, MS 14-40
  29.  *                     Mountain View, CA 94043
  30.  *                     (415) 336-1080
  31.  *
  32.  * Revision History:
  33.  * 10-Jan-89: Created.
  34.  * 06-Mar-90: Change to byte encoded rasterfiles.
  35.  *          fix bug in call to ReadScanline().
  36.  *          fix bug in CVT() macro.
  37.  *          fix assignment of td, (missing &).
  38.  *
  39.  * Description:
  40.  *   This program takes a MicroSoft/Aldus "Tagged Image File Format" image or
  41.  * "TIFF" file as input and writes a Sun Rasterfile [see rasterfile(5)].  The
  42.  * output file may be standard output, but the input TIFF file must be a real
  43.  * file since seek(2) is used.
  44.  */
  45.  
  46. #include <stdio.h>
  47. #include <pixrect/pixrect_hs.h>
  48. #include "tiffio.h"
  49.  
  50. typedef int boolean;
  51. #define True (1)
  52. #define False (0)
  53. #define    CVT(x)        (((x) * 255) / ((1L<<16)-1))
  54.  
  55. boolean     Verbose = False;
  56. char       *pname;        /* program name (used for error messages) */
  57.  
  58. void
  59. error(s1, s2)
  60.     char       *s1,
  61.                *s2;
  62. {
  63.     fprintf(stderr, s1, pname, s2);
  64.     exit(1);
  65. }
  66.  
  67. void
  68. usage()
  69. {
  70.     error("usage: %s -[vq] TIFFfile [rasterfile]\n", NULL);
  71. }
  72.  
  73.  
  74. main(argc, argv)
  75.     int         argc;
  76.     char       *argv[];
  77. {
  78.     char       *inf = NULL;
  79.     char       *outf = NULL;
  80.     FILE       *fp;
  81.     long        width,
  82.                 height;
  83.     int         depth,
  84.                 numcolors;
  85.     register TIFF *tif;
  86.     TIFFDirectory *td;
  87.     register u_char *inp,
  88.                *outp;
  89.     register int col,
  90.                 i;
  91.     register long row;
  92.     u_char     *Map = NULL;
  93.     u_char     *buf;
  94.     short    bitspersample;
  95.     short    samplesperpixel;
  96.     short    photometric;
  97.     u_short    *redcolormap,
  98.            *bluecolormap,
  99.            *greencolormap;
  100.  
  101.     Pixrect    *pix;        /* The Sun Pixrect */
  102.     colormap_t  Colormap;    /* The Pixrect Colormap */
  103.     u_char      red[256],
  104.                 green[256],
  105.                 blue[256];
  106.  
  107.     setbuf(stderr, NULL);
  108.     pname = argv[0];
  109.  
  110.     while (--argc) {
  111.     if ((++argv)[0][0] == '-')
  112.         switch (argv[0][1]) {
  113.         case 'v':
  114.         Verbose = True;
  115.         break;
  116.         case 'q':
  117.         usage();
  118.         break;
  119.         default:
  120.         fprintf(stderr, "%s: illegal option -%c.\n", pname,
  121.             argv[0][1]);
  122.         exit(1);
  123.         }
  124.     else if (inf == NULL)
  125.         inf = argv[0];
  126.     else if (outf == NULL)
  127.         outf = argv[0];
  128.     else
  129.         usage();
  130.  
  131.     }
  132.  
  133.     if (inf == NULL)
  134.     error("%s: can't read input file from a stream.\n", NULL);
  135.  
  136.     if (Verbose)
  137.     fprintf(stderr, "Reading %s...", inf);
  138.  
  139.     tif = TIFFOpen(inf, "r");
  140.  
  141.     if (tif == NULL)
  142.     error("%s: error opening TIFF file %s", inf);
  143.  
  144.     if (Verbose)
  145.     TIFFPrintDirectory(tif, stderr, True, False, False);
  146.     TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  147.     if (bitspersample > 8)
  148.     error("%s: can't handle more than 8-bits per sample\n", NULL);
  149.  
  150.     TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  151.     switch (samplesperpixel) {
  152.     case 1:
  153.     if (bitspersample == 1)
  154.         depth = 1;
  155.     else
  156.         depth = 8;
  157.     break;
  158.     case 3:
  159.     case 4:
  160.     depth = 24;
  161.     break;
  162.     default:
  163.     error("%s: only handle 1-channel gray scale or 3-channel color\n");
  164.     }
  165.  
  166.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  167.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  168.  
  169.     if (Verbose)
  170.     fprintf(stderr, "%dx%dx%d image, ", width, height, depth);
  171.     if (Verbose)
  172.     fprintf(stderr, "%d bits/sample, %d samples/pixel, ",
  173.         bitspersample, samplesperpixel);
  174.  
  175.     pix = mem_create(width, height, depth);
  176.     if (pix == (Pixrect *) NULL)
  177.     error("%s: can't allocate memory for output pixrect...\n", NULL);
  178.  
  179.     numcolors = (1 << bitspersample);
  180.  
  181.     TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric);
  182.     if (numcolors == 2) {
  183.     if (Verbose)
  184.         fprintf(stderr, "monochrome ");
  185.     Colormap.type = RMT_NONE;
  186.     Colormap.length = 0;
  187.     Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
  188.     } else {
  189.     switch (photometric) {
  190.     case PHOTOMETRIC_MINISBLACK:
  191.         if (Verbose)
  192.         fprintf(stderr, "%d graylevels (min=black), ", numcolors);
  193.         Map = (u_char *) malloc(numcolors * sizeof(u_char));
  194.         for (i = 0; i < numcolors; i++)
  195.         Map[i] = (255 * i) / numcolors;
  196.         Colormap.type = RMT_EQUAL_RGB;
  197.         Colormap.length = numcolors;
  198.         Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
  199.         break;
  200.     case PHOTOMETRIC_MINISWHITE:
  201.         if (Verbose)
  202.         fprintf(stderr, "%d graylevels (min=white), ", numcolors);
  203.         Map = (u_char *) malloc(numcolors * sizeof(u_char));
  204.         for (i = 0; i < numcolors; i++)
  205.         Map[i] = 255 - ((255 * i) / numcolors);
  206.         Colormap.type = RMT_EQUAL_RGB;
  207.         Colormap.length = numcolors;
  208.         Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = Map;
  209.         break;
  210.     case PHOTOMETRIC_RGB:
  211.         if (Verbose)
  212.         fprintf(stderr, "truecolor ");
  213.         Colormap.type = RMT_NONE;
  214.         Colormap.length = 0;
  215.         Colormap.map[0] = Colormap.map[1] = Colormap.map[2] = NULL;
  216.         break;
  217.     case PHOTOMETRIC_PALETTE:
  218.         if (Verbose)
  219.         fprintf(stderr, "colormapped ");
  220.         Colormap.type = RMT_EQUAL_RGB;
  221.         Colormap.length = numcolors;
  222.         memset(red, 0, sizeof(red));
  223.         memset(green, 0, sizeof(green));
  224.         memset(blue, 0, sizeof(blue));
  225.         TIFFGetField(tif, TIFFTAG_COLORMAP,
  226.         &redcolormap, &greencolormap, &bluecolormap);
  227.         for (i = 0; i < numcolors; i++) {
  228.         red[i] = (u_char) CVT(redcolormap[i]);
  229.         green[i] = (u_char) CVT(greencolormap[i]);
  230.         blue[i] = (u_char) CVT(bluecolormap[i]);
  231.         }
  232.         Colormap.map[0] = red;
  233.         Colormap.map[1] = green;
  234.         Colormap.map[2] = blue;
  235.         break;
  236.     case PHOTOMETRIC_MASK:
  237.         error("%s: Don't know how to handle PHOTOMETRIC_MASK\n");
  238.         break;
  239.     case PHOTOMETRIC_DEPTH:
  240.         error("%s: Don't know how to handle PHOTOMETRIC_DEPTH\n");
  241.         break;
  242.     default:
  243.         error("%s: unknown photometric (cmap): %d\n", photometric);
  244.     }
  245.     }
  246.  
  247.     buf = (u_char *) malloc(TIFFScanlineSize(tif));
  248.     if (buf == NULL)
  249.     error("%s: can't allocate memory for scanline buffer...\n", NULL);
  250.  
  251.     for (row = 0; row < height; row++) {
  252.     if (TIFFReadScanline(tif, buf, row, 0) < 0)
  253.         error("%s: bad data read on line: %d\n", row);
  254.     inp = buf;
  255.     outp = (u_char *) mprd_addr(mpr_d(pix), 0, row);
  256.     switch (photometric) {
  257.     case PHOTOMETRIC_RGB:
  258.         if (samplesperpixel == 4)
  259.         for (col = 0; col < width; col++) {
  260.             *outp++ = *inp++;    /* Blue */
  261.             *outp++ = *inp++;    /* Green */
  262.             *outp++ = *inp++;    /* Red */
  263.             inp++;    /* skip alpha channel */
  264.         }
  265.         else
  266.         for (col = 0; col < width; col++) {
  267.             *outp++ = *inp++;    /* Blue */
  268.             *outp++ = *inp++;    /* Green */
  269.             *outp++ = *inp++;    /* Red */
  270.         }
  271.         break;
  272.     case PHOTOMETRIC_MINISWHITE:
  273.     case PHOTOMETRIC_MINISBLACK:
  274.         switch (bitspersample) {
  275.         case 1:
  276.         for (col = 0; col < ((width + 7) / 8); col++)
  277.             *outp++ = *inp++;
  278.         break;
  279.         case 2:
  280.         for (col = 0; col < ((width + 3) / 4); col++) {
  281.             *outp++ = (*inp >> 6) & 3;
  282.             *outp++ = (*inp >> 4) & 3;
  283.             *outp++ = (*inp >> 2) & 3;
  284.             *outp++ = *inp++ & 3;
  285.         }
  286.         break;
  287.         case 4:
  288.         for (col = 0; col < width / 2; col++) {
  289.             *outp++ = *inp >> 4;
  290.             *outp++ = *inp++ & 0xf;
  291.         }
  292.         break;
  293.         case 8:
  294.         for (col = 0; col < width; col++)
  295.             *outp++ = *inp++;
  296.         break;
  297.         default:
  298.         error("%s: bad bits/sample: %d\n", bitspersample);
  299.         }
  300.         break;
  301.     case PHOTOMETRIC_PALETTE:
  302.         memcpy(outp, inp, width);
  303.         break;
  304.     default:
  305.         error("%s: unknown photometric (write): %d\n", photometric);
  306.     }
  307.     }
  308.  
  309.     free((char *) buf);
  310.  
  311.     if (Verbose)
  312.     fprintf(stderr, "done.\n");
  313.  
  314.     if (outf == NULL || strcmp(outf, "Standard Output") == 0) {
  315.     outf = "Standard Output";
  316.     fp = stdout;
  317.     } else {
  318.     if (!(fp = fopen(outf, "w")))
  319.         error("%s: %s couldn't be opened for writing.\n", outf);
  320.     }
  321.  
  322.     if (Verbose)
  323.     fprintf(stderr, "Writing rasterfile in %s...", outf);
  324.  
  325.     if (pr_dump(pix, fp, &Colormap, RT_BYTE_ENCODED, 0) == PIX_ERR)
  326.     error("%s: error writing Sun Rasterfile: %s\n", outf);
  327.  
  328.     if (Verbose)
  329.     fprintf(stderr, "done.\n");
  330.  
  331.     pr_destroy(pix);
  332.  
  333.     if (fp != stdout)
  334.     fclose(fp);
  335.  
  336.     exit(0);
  337. }
  338.