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

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/tools/RCS/sgigt.c,v 1.41 93/08/26 15:10:09 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 <gl.h>
  31. #include <device.h>
  32. #include <stdlib.h>
  33. #include <string.h>
  34. #include <getopt.h>
  35.  
  36. #include "tiffio.h"
  37.  
  38. typedef    unsigned char u_char;
  39. typedef    unsigned long u_long;
  40.  
  41. /* XXX fudge adjustment for window borders */
  42. #define    YFUDGE    20
  43. #define    XFUDGE    20
  44.  
  45. Cursor    hourglass = {
  46.     0x1ff0, 0x1ff0, 0x0820, 0x0820,
  47.     0x0820, 0x0c60, 0x06c0, 0x0100,
  48.     0x0100, 0x06c0, 0x0c60, 0x0820,
  49.     0x0820, 0x0820, 0x1ff0, 0x1ff0
  50. };
  51. uint32    width, height;            /* image width & height */
  52. uint16    bitspersample;
  53. uint16    samplesperpixel;
  54. uint16    photometric;
  55. uint16    orientation;
  56. uint16    extrasamples;
  57. uint16    planarconfig;
  58. uint16    *redcmap, *greencmap, *bluecmap;/* colormap for pallete images */
  59. uint16    YCbCrHorizSampling, YCbCrVertSampling;
  60. float    *YCbCrCoeffs;
  61. float    *refBlackWhite;
  62. int    isRGB = -1;
  63. int    verbose = 0;
  64. int    stoponerr = 0;            /* stop on read error */
  65.  
  66. char    *filename;
  67.  
  68. static    void checkImage(TIFF*);
  69. static    int gt(TIFF*, uint32, uint32, u_long*);
  70. extern    Colorindex rgb(float, float, float);
  71.  
  72. static void
  73. usage(void)
  74. {
  75.     fprintf(stderr, "usage: tiffgt [-d dirnum] [-f] [-lm] [-s] filename\n");
  76.     exit(-1);
  77. }
  78.  
  79. void
  80. main(int argc, char* argv[])
  81. {
  82.     u_long *raster;            /* displayable image */
  83.     char title[1024];
  84.     char *cp;
  85.     long max;
  86.     TIFF *tif;
  87.     int fg = 0, c, dirnum = -1, order = 0;
  88.  
  89.     while ((c = getopt(argc, argv, "d:cerflmsv")) != -1)
  90.         switch (c) {
  91.         case 'c':
  92.             isRGB = 0;
  93.             break;
  94.         case 'd':
  95.             dirnum = atoi(optarg);
  96.             break;
  97.         case 'f':
  98.             fg = 1;
  99.             break;
  100.         case 'l':
  101.             order = FILLORDER_LSB2MSB;
  102.             break;
  103.         case 'm':
  104.             order = FILLORDER_MSB2LSB;
  105.             break;
  106.         case 'r':
  107.             isRGB = 1;
  108.             break;
  109.         case 's':
  110.             stoponerr = 1;
  111.             break;
  112.         case 'v':
  113.             verbose = 1;
  114.             break;
  115.         case '?':
  116.             usage();
  117.             /*NOTREACHED*/
  118.         }
  119.     if (argc - optind < 1)
  120.         usage();
  121.     filename = argv[optind];
  122.     tif = TIFFOpen(filename, "r");
  123.     if (tif == NULL)
  124.         exit(-1);
  125.     if (dirnum != -1 && !TIFFSetDirectory(tif, dirnum)) {
  126.         TIFFError(filename, "Error, seeking to directory %d", dirnum);
  127.         exit(-1);
  128.     }
  129.     checkImage(tif);
  130.     if (order)
  131.         TIFFSetField(tif, TIFFTAG_FILLORDER, order);
  132.     /*
  133.      * Use a full-color window if the image is
  134.      * full color or a palette image and the
  135.      * hardware support is present.
  136.      */
  137.     if (isRGB == -1)
  138.         isRGB = (bitspersample >= 8 &&
  139.             (photometric == PHOTOMETRIC_RGB ||
  140.              photometric == PHOTOMETRIC_YCBCR ||
  141.              photometric == PHOTOMETRIC_SEPARATED ||
  142.              photometric == PHOTOMETRIC_PALETTE));
  143.     /*
  144.      * Check to see if the hardware can display 24-bit RGB.
  145.      */
  146.     if (isRGB && getgdesc(GD_BITS_NORM_SNG_RED) < bitspersample &&
  147.       !getgdesc(GD_DITHER))
  148.         isRGB = 0;
  149.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  150.     max = getgdesc(GD_XPMAX) - XFUDGE;
  151.     if (width > max)
  152.         width = max;
  153.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  154.     max = getgdesc(GD_YPMAX) - YFUDGE;
  155.     if (height > max)
  156.         height = max;
  157.     prefsize(width, height);
  158.     cp = strrchr(filename, '/');
  159.     if (cp == NULL)
  160.         cp = filename;
  161.     else
  162.         cp++;
  163.     if (fg)
  164.         foreground();
  165.     strcpy(title, cp);
  166.     if (dirnum > 0) {
  167.         char buf[40];
  168.         sprintf(buf, " [%d]", dirnum == -1 ? 0 : dirnum);
  169.         strcat(title, buf);
  170.     }
  171.     if (verbose)
  172.         strcat(title, isRGB ? " rgb" : " cmap");
  173.     if (winopen(title) < 0) {
  174.         TIFFError(filename, "Can not create window");
  175.         exit(-1);
  176.     }
  177.     raster = (u_long *)malloc(width * height * sizeof (long));
  178.     if (raster == 0) {
  179.         TIFFError(filename, "No space for raster buffer");
  180.         exit(-1);
  181.     }
  182.     singlebuffer();
  183.     if (isRGB) {
  184.         RGBmode();
  185.         gconfig();
  186.     } else {
  187.         cmode();
  188.         gconfig();
  189.     }
  190.     curstype(C16X1);
  191.     defcursor(1, hourglass);
  192.     setcursor(1, 0, 0);
  193.     rgb(0.5,0.5,0.5);
  194.     clear();
  195.     if (!gt(tif, width, height, raster))
  196.         exit(-1);
  197.     setcursor(0, 0, 0);
  198.     TIFFClose(tif);
  199.     qdevice(LEFTMOUSE);
  200.     for (;;) {
  201.         short val;
  202.         switch (qread(&val)) {
  203.         case REDRAW:
  204.             lrectwrite(0, 0, width-1, height-1, raster);
  205.             break;
  206.         case LEFTMOUSE:
  207.             if (val)
  208.                 exit(0);
  209.             break;
  210.         }
  211.     }
  212.     /*NOTREACHED*/
  213. }
  214.  
  215. static void
  216. checkImage(TIFF* tif)
  217. {
  218.     int alpha;
  219.     uint16* sampleinfo;
  220.  
  221.     TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  222.     switch (bitspersample) {
  223.     case 1: case 2: case 4:
  224.     case 8: case 16:
  225.         break;
  226.     default:
  227.         TIFFError(filename, "Sorry, can not handle %d-bit pictures",
  228.             bitspersample);
  229.         exit(-1);
  230.     }
  231.     TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  232.     TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
  233.         &extrasamples, &sampleinfo);
  234.     alpha = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
  235.     TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
  236.     switch (samplesperpixel - extrasamples) {
  237.     case 3:
  238.         break;
  239.     case 1: case 4:
  240. /* XXX */
  241.         if (!alpha || planarconfig != PLANARCONFIG_CONTIG)
  242.             break;
  243.         /* fall thru... */
  244.     default:
  245.             TIFFError(filename,
  246.             "Sorry, can not handle %d-channel %s images%s",
  247.             samplesperpixel,
  248.             planarconfig == PLANARCONFIG_CONTIG ?
  249.             "packed" : "separated",
  250.             alpha ? " with alpha" : "");
  251.         exit(-1);
  252.     }
  253.     if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
  254.         switch (samplesperpixel) {
  255.         case 1:
  256.             photometric = PHOTOMETRIC_MINISBLACK;
  257.             break;
  258.         case 3: case 4:
  259.             photometric = PHOTOMETRIC_RGB;
  260.             break;
  261.         default:
  262.             TIFFError(filename, "Missing needed \"%s\" tag",
  263.                 "PhotometricInterpretation");
  264.             exit(-1);
  265.         }
  266.         TIFFError(filename,
  267.             "No \"PhotometricInterpretation\" tag, assuming %s\n",
  268.             photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
  269.     }
  270.     switch (photometric) {
  271.     case PHOTOMETRIC_MINISWHITE:
  272.     case PHOTOMETRIC_MINISBLACK:
  273.     case PHOTOMETRIC_RGB:
  274.     case PHOTOMETRIC_PALETTE:
  275.     case PHOTOMETRIC_YCBCR:
  276.         break;
  277.     case PHOTOMETRIC_SEPARATED: {
  278.         uint16 inkset;
  279.         TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
  280.         if (inkset != INKSET_CMYK) {
  281.             TIFFError(filename,
  282.                 "Sorry, can not handle separated image with %s=%d",
  283.                 "InkSet", inkset);
  284.             exit(-1);
  285.         }
  286.         break;
  287.     }
  288.     default:
  289.         TIFFError(filename, "Sorry, can not handle image with %s=%d",
  290.             "PhotometricInterpretation", photometric);
  291.         exit(-1);
  292.     }
  293. }
  294.  
  295. static int
  296. checkcmap(int n, uint16* r, uint16* g, uint16* b)
  297. {
  298.     while (n-- > 0)
  299.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  300.             return (16);
  301.     TIFFWarning(filename, "Assuming 8-bit colormap");
  302.     return (8);
  303. }
  304.  
  305. /*
  306.  * {red,green,blue}_inverse are tables in libgutil.a that
  307.  * do an inverse map from (r,g,b) to the closest colormap
  308.  * index in the "standard" GL colormap.  grey_inverse is
  309.  * the equivalent map for mapping greyscale values to
  310.  * colormap indices.  We access these maps directly instead
  311.  * of through the rgbi and greyi functions to avoid the
  312.  * additional overhead of the color calls that they make.
  313.  */
  314. extern    u_char red_inverse[256];
  315. extern    u_char green_inverse[256];
  316. extern    u_char blue_inverse[256];
  317. extern    u_char grey_inverse[256];
  318. #define    greyi(g)    grey_inverse[g]
  319.  
  320. static u_char
  321. rgbi(u_char r, u_char g, u_char b)
  322. {
  323.     return (r == g && g == b ? grey_inverse[r] :
  324.         red_inverse[r] + green_inverse[g] + blue_inverse[b]);
  325. }
  326.  
  327. #define    howmany(x, y)    (((x)+((y)-1))/(y))
  328. u_long    **BWmap;
  329. u_long    **PALmap;
  330.  
  331. static     int makebwmap(RGBvalue* Map);
  332. static    int makecmap(uint16*, uint16*, uint16*);
  333. static    void initYCbCrConversion(void);
  334. static    int gtTileContig(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  335. static    int gtTileSeparate(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  336. static    int gtStripContig(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  337. static    int gtStripSeparate(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  338.  
  339. /*
  340.  * Construct a mapping table to convert from the range
  341.  * of the data samples to [0,255] --for display.  This
  342.  * process also handles inverting B&W images when needed.
  343.  */ 
  344. static int
  345. setupMap(uint16 minsamplevalue, uint16 maxsamplevalue, RGBvalue** pMap)
  346. {
  347.     register int x, range;
  348.     RGBvalue *Map;
  349.  
  350.     range = maxsamplevalue - minsamplevalue;
  351.     Map = (RGBvalue *)malloc((range + 1) * sizeof (RGBvalue));
  352.     if (Map == NULL) {
  353.         TIFFError(filename,
  354.             "No space for photometric conversion table");
  355.         return (0);
  356.     }
  357.     if (photometric == PHOTOMETRIC_MINISWHITE) {
  358.         for (x = 0; x <= range; x++)
  359.             Map[x] = ((range - x) * 255) / range;
  360.     } else {
  361.         for (x = 0; x <= range; x++)
  362.             Map[x] = (x * 255) / range;
  363.     }
  364.     if (bitspersample <= 8 &&
  365.         (photometric == PHOTOMETRIC_MINISBLACK ||
  366.          photometric == PHOTOMETRIC_MINISWHITE)) {
  367.         /*
  368.          * Use photometric mapping table to construct
  369.          * unpacking tables for samples <= 8 bits.
  370.          */
  371.         if (!makebwmap(Map))
  372.             return (0);
  373.         /* no longer need Map, free it */
  374.         free((char *)Map);
  375.         Map = NULL;
  376.     }
  377.     *pMap = Map;
  378.     return (1);
  379. }
  380.  
  381. static int
  382. gt(TIFF* tif, uint32 w, uint32 h, u_long* raster)
  383. {
  384.     uint16 minsamplevalue, maxsamplevalue;
  385.     RGBvalue *Map;
  386.     int e, ncomps;
  387.  
  388.     TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
  389.     TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
  390.     Map = NULL;
  391.     switch (photometric) {
  392.     case PHOTOMETRIC_YCBCR:
  393.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
  394.             &YCbCrCoeffs);
  395.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
  396.             &YCbCrHorizSampling, &YCbCrVertSampling);
  397.         TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
  398.             &refBlackWhite);
  399.         initYCbCrConversion();
  400.         /* fall thru... */
  401.     case PHOTOMETRIC_RGB:
  402.     case PHOTOMETRIC_SEPARATED:
  403.         if (minsamplevalue == 0 && maxsamplevalue == 255)
  404.             break;
  405.         /* fall thru... */
  406.     case PHOTOMETRIC_MINISBLACK:
  407.     case PHOTOMETRIC_MINISWHITE:
  408.         if (!setupMap(minsamplevalue, maxsamplevalue, &Map))
  409.             return (0);
  410.         break;
  411.     case PHOTOMETRIC_PALETTE:
  412.         if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
  413.             &redcmap, &greencmap, &bluecmap)) {
  414.             TIFFError(filename,
  415.                 "Missing required \"Colormap\" tag");
  416.             return (0);
  417.         }
  418.         /*
  419.          * Convert 16-bit colormap to 8-bit (unless it looks
  420.          * like an old-style 8-bit colormap).
  421.          */
  422.         if (checkcmap(1<<bitspersample, redcmap, greencmap, bluecmap) == 16) {
  423.             int i;
  424. #define    CVT(x)        (((x) * 255) / ((1L<<16)-1))
  425.             for (i = (1<<bitspersample)-1; i >= 0; i--) {
  426.                 redcmap[i] = CVT(redcmap[i]);
  427.                 greencmap[i] = CVT(greencmap[i]);
  428.                 bluecmap[i] = CVT(bluecmap[i]);
  429.             }
  430. #undef CVT
  431.         }
  432.         if (bitspersample <= 8) {
  433.             /*
  434.              * Use mapping table and colormap to construct
  435.              * unpacking tables for samples < 8 bits.
  436.              */
  437.             if (!makecmap(redcmap, greencmap, bluecmap))
  438.                 return (0);
  439.         }
  440.         break;
  441.     }
  442.     ncomps = samplesperpixel - extrasamples;    /* # color components */
  443.     if (planarconfig == PLANARCONFIG_SEPARATE && ncomps > 1) {
  444.         e = TIFFIsTiled(tif) ?
  445.             gtTileSeparate(tif, raster, Map, h, w) :
  446.             gtStripSeparate(tif, raster, Map, h, w);
  447.     } else {
  448.         e = TIFFIsTiled(tif) ? 
  449.             gtTileContig(tif, raster, Map, h, w) :
  450.             gtStripContig(tif, raster, Map, h, w);
  451.     }
  452.     if (Map)
  453.         free((char *)Map);
  454.     return (e);
  455. }
  456.  
  457. uint32
  458. setorientation(TIFF* tif, uint32 h)
  459. {
  460.     uint32 y;
  461.  
  462.     TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
  463.     switch (orientation) {
  464.     case ORIENTATION_BOTRIGHT:
  465.     case ORIENTATION_RIGHTBOT:    /* XXX */
  466.     case ORIENTATION_LEFTBOT:    /* XXX */
  467.         TIFFWarning(filename, "using bottom-left orientation");
  468.         orientation = ORIENTATION_BOTLEFT;
  469.         /* fall thru... */
  470.     case ORIENTATION_BOTLEFT:
  471.         y = 0;
  472.         break;
  473.     case ORIENTATION_TOPRIGHT:
  474.     case ORIENTATION_RIGHTTOP:    /* XXX */
  475.     case ORIENTATION_LEFTTOP:    /* XXX */
  476.     default:
  477.         TIFFWarning(filename, "using top-left orientation");
  478.         orientation = ORIENTATION_TOPLEFT;
  479.         /* fall thru... */
  480.     case ORIENTATION_TOPLEFT:
  481.         y = h-1;
  482.         break;
  483.     }
  484.     return (y);
  485. }
  486.  
  487. typedef void (*tileContigRoutine)
  488.     (u_long*, u_char*, RGBvalue*, uint32, uint32, int, int);
  489. static tileContigRoutine pickTileContigCase(RGBvalue*);
  490.  
  491. /*
  492.  * Get an tile-organized image that has
  493.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  494.  * or
  495.  *    SamplesPerPixel == 1
  496.  */    
  497. static
  498. gtTileContig(TIFF* tif, u_long* raster, RGBvalue* Map, uint32 h, uint32 w)
  499. {
  500.     uint32 col, row, y;
  501.     uint32 tw, th;
  502.     u_char *buf;
  503.     int fromskew, toskew;
  504.     uint32 nrow;
  505.     tileContigRoutine put;
  506.  
  507.     buf = (u_char *)malloc(TIFFTileSize(tif));
  508.     if (buf == 0) {
  509.         TIFFError(filename, "No space for tile buffer");
  510.         return (0);
  511.     }
  512.     put = pickTileContigCase(Map);
  513.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  514.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  515.     y = setorientation(tif, h);
  516.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  517.     for (row = 0; row < h; row += th) {
  518.         nrow = (row + th > h ? h - row : th);
  519.         for (col = 0; col < w; col += tw) {
  520.             if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 && stoponerr)
  521.                 break;
  522.             if (col + tw > w) {
  523.                 /*
  524.                  * Tile is clipped horizontally.  Calculate
  525.                  * visible portion and skewing factors.
  526.                  */
  527.                 uint32 npix = w - col;
  528.                 fromskew = tw - npix;
  529.                 (*put)(raster + y*w + col, buf, Map,
  530.                     npix, nrow, fromskew, toskew + fromskew);
  531.             } else
  532.                 (*put)(raster + y*w + col, buf, Map,
  533.                     tw, nrow, 0, toskew);
  534.         }
  535.         if (orientation == ORIENTATION_TOPLEFT) {
  536.             y -= nrow-1;
  537.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  538.             y--;
  539.         } else {
  540.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  541.             y += nrow;
  542.         }
  543.     }
  544.     free(buf);
  545.     return (1);
  546. }
  547.  
  548. typedef void (*tileSeparateRoutine)
  549.     (u_long*, u_char*, u_char*, u_char*, RGBvalue*, uint32, uint32, int, int);
  550. static tileSeparateRoutine pickTileSeparateCase(RGBvalue*);
  551.  
  552. /*
  553.  * Get an tile-organized image that has
  554.  *     SamplesPerPixel > 1
  555.  *     PlanarConfiguration separated
  556.  * We assume that all such images are RGB.
  557.  */    
  558. static int
  559. gtTileSeparate(TIFF* tif, u_long* raster, RGBvalue* Map, uint32 h, uint32 w)
  560. {
  561.     uint32 col, row, y;
  562.     uint32 tw, th;
  563.     u_char *buf;
  564.     u_char *r, *g, *b;
  565.     tsize_t tilesize;
  566.     int fromskew, toskew;
  567.     uint32 nrow;
  568.     tileSeparateRoutine put;
  569.  
  570.     tilesize = TIFFTileSize(tif);
  571.     buf = (u_char *)malloc(3*tilesize);
  572.     if (buf == 0) {
  573.         TIFFError(filename, "No space for tile buffer");
  574.         return (0);
  575.     }
  576.     r = buf;
  577.     g = r + tilesize;
  578.     b = g + tilesize;
  579.     put = pickTileSeparateCase(Map);
  580.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  581.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  582.     y = setorientation(tif, h);
  583.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  584.     for (row = 0; row < h; row += th) {
  585.         nrow = (row + th > h ? h - row : th);
  586.         for (col = 0; col < w; col += tw) {
  587.             if (TIFFReadTile(tif, r, col, row, 0, 0) < 0 && stoponerr)
  588.                 break;
  589.             if (TIFFReadTile(tif, g, col, row, 0, 1) < 0 && stoponerr)
  590.                 break;
  591.             if (TIFFReadTile(tif, b, col, row, 0, 2) < 0 && stoponerr)
  592.                 break;
  593.             if (col + tw > w) {
  594.                 /*
  595.                  * Tile is clipped horizontally.  Calculate
  596.                  * visible portion and skewing factors.
  597.                  */
  598.                 uint32 npix = w - col;
  599.                 fromskew = tw - npix;
  600.                 (*put)(raster + y*w + col, r, g, b, Map,
  601.                     npix, nrow, fromskew, toskew + fromskew);
  602.             } else
  603.                 (*put)(raster + y*w + col, r, g, b, Map,
  604.                     tw, nrow, 0, toskew);
  605.         }
  606.         if (orientation == ORIENTATION_TOPLEFT) {
  607.             y -= nrow-1;
  608.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  609.             y--;
  610.         } else {
  611.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  612.             y += nrow;
  613.         }
  614.     }
  615.     free(buf);
  616.     return (1);
  617. }
  618.  
  619. /*
  620.  * Get a strip-organized image that has
  621.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  622.  * or
  623.  *    SamplesPerPixel == 1
  624.  */    
  625. static int
  626. gtStripContig(TIFF* tif, u_long* raster, RGBvalue* Map, uint32 h, uint32 w)
  627. {
  628.     uint32 row, y, nrow;
  629.     u_char *buf;
  630.     tileContigRoutine put;
  631.     uint32 rowsperstrip;
  632.     uint32 imagewidth;
  633.     tsize_t scanline;
  634.     int fromskew, toskew;
  635.  
  636.     buf = (u_char *)malloc(TIFFStripSize(tif));
  637.     if (buf == 0) {
  638.         TIFFError(filename, "No space for strip buffer");
  639.         return (0);
  640.     }
  641.     put = pickTileContigCase(Map);
  642.     y = setorientation(tif, h);
  643.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  644.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  645.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  646.     scanline = TIFFScanlineSize(tif);
  647.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  648.     for (row = 0; row < h; row += rowsperstrip) {
  649.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  650.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  651.             buf, nrow*scanline) < 0 && stoponerr)
  652.             break;
  653.         (*put)(raster + y*w, buf, Map, w, nrow, fromskew, toskew);
  654.         if (orientation == ORIENTATION_TOPLEFT) {
  655.             y -= nrow-1;
  656.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  657.             y--;
  658.         } else {
  659.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  660.             y += nrow;
  661.         }
  662.     }
  663.     free(buf);
  664.     return (1);
  665. }
  666.  
  667. /*
  668.  * Get a strip-organized image with
  669.  *     SamplesPerPixel > 1
  670.  *     PlanarConfiguration separated
  671.  * We assume that all such images are RGB.
  672.  */
  673. static int
  674. gtStripSeparate(TIFF* tif, u_long* raster, RGBvalue* Map, uint32 h, uint32 w)
  675. {
  676.     u_char *buf;
  677.     u_char *r, *g, *b;
  678.     uint32 row, y, nrow;
  679.     tsize_t scanline;
  680.     tileSeparateRoutine put;
  681.     uint32 rowsperstrip;
  682.     uint32 imagewidth;
  683.     tsize_t stripsize;
  684.     int fromskew, toskew;
  685.  
  686.     stripsize = TIFFStripSize(tif);
  687.     r = buf = (u_char *)malloc(3*stripsize);
  688.     g = r + stripsize;
  689.     b = g + stripsize;
  690.     put = pickTileSeparateCase(Map);
  691.     y = setorientation(tif, h);
  692.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  693.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  694.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  695.     scanline = TIFFScanlineSize(tif);
  696.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  697.     for (row = 0; row < h; row += rowsperstrip) {
  698.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  699.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  700.             r, nrow*scanline) < 0 && stoponerr)
  701.             break;
  702.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
  703.             g, nrow*scanline) < 0 && stoponerr)
  704.             break;
  705.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
  706.             b, nrow*scanline) < 0 && stoponerr)
  707.             break;
  708.         (*put)(raster + y*w, r, g, b, Map, w, nrow, fromskew, toskew);
  709.         if (orientation == ORIENTATION_TOPLEFT) {
  710.             y -= nrow-1;
  711.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  712.             y--;
  713.         } else {
  714.             lrectwrite(0, y, w-1, y+nrow-1, raster + y*w);
  715.             y += nrow;
  716.         }
  717.     }
  718.     free(buf);
  719.     return (1);
  720. }
  721.  
  722. #define    PACK(r,g,b)    ((u_long)(r)|((u_long)(g)<<8)|((u_long)(b)<<16))
  723.  
  724. /*
  725.  * Greyscale images with less than 8 bits/sample are handled
  726.  * with a table to avoid lots of shifts and masks.  The table
  727.  * is setup so that put*bwtile (below) can retrieve 8/bitspersample
  728.  * pixel values simply by indexing into the table with one
  729.  * number.
  730.  */
  731. static int
  732. makebwmap(RGBvalue* Map)
  733. {
  734.     register int i;
  735.     int nsamples = 8 / bitspersample;
  736.     register u_long *p;
  737.  
  738.     BWmap = (u_long **)malloc(
  739.         256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
  740.     if (BWmap == NULL) {
  741.         TIFFError(filename, "No space for B&W mapping table");
  742.         return (0);
  743.     }
  744.     p = (u_long *)(BWmap + 256);
  745.     if (isRGB) {
  746.         for (i = 0; i < 256; i++) {
  747.             BWmap[i] = p;
  748.             switch (bitspersample) {
  749.                 register RGBvalue c;
  750. #define    GREY(x)    c = Map[x]; *p++ = PACK(c,c,c);
  751.             case 1:
  752.                 GREY(i>>7);
  753.                 GREY((i>>6)&1);
  754.                 GREY((i>>5)&1);
  755.                 GREY((i>>4)&1);
  756.                 GREY((i>>3)&1);
  757.                 GREY((i>>2)&1);
  758.                 GREY((i>>1)&1);
  759.                 GREY(i&1);
  760.                 break;
  761.             case 2:
  762.                 GREY(i>>6);
  763.                 GREY((i>>4)&3);
  764.                 GREY((i>>2)&3);
  765.                 GREY(i&3);
  766.                 break;
  767.             case 4:
  768.                 GREY(i>>4);
  769.                 GREY(i&0xf);
  770.                 break;
  771.             case 8:
  772.                 GREY(i);
  773.                 break;
  774.             }
  775. #undef    GREY
  776.         }
  777.     } else {
  778.         for (i = 0; i < 256; i++) {
  779.             BWmap[i] = p;
  780.             switch (bitspersample) {
  781. #define    GREY(x)    *p++ = greyi(Map[x]);
  782.             case 1:
  783.                 GREY(i>>7);
  784.                 GREY((i>>6)&1);
  785.                 GREY((i>>5)&1);
  786.                 GREY((i>>4)&1);
  787.                 GREY((i>>3)&1);
  788.                 GREY((i>>2)&1);
  789.                 GREY((i>>1)&1);
  790.                 GREY(i&1);
  791.                 break;
  792.             case 2:
  793.                 GREY(i>>6);
  794.                 GREY((i>>4)&3);
  795.                 GREY((i>>2)&3);
  796.                 GREY(i&3);
  797.                 break;
  798.             case 4:
  799.                 GREY(i>>4);
  800.                 GREY(i&0xf);
  801.                 break;
  802.             case 8:
  803.                 GREY(i);
  804.                 break;
  805.             }
  806. #undef    GREY
  807.         }
  808.     }
  809.     return (1);
  810. }
  811.  
  812. /*
  813.  * Palette images with <= 8 bits/sample are handled
  814.  * with a table to avoid lots of shifts and masks.  The table
  815.  * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
  816.  * pixel values simply by indexing into the table with one
  817.  * number.
  818.  */
  819. static int
  820. makecmap(uint16* rmap, uint16* gmap, uint16* bmap)
  821. {
  822.     register int i;
  823.     int nsamples = 8 / bitspersample;
  824.     register u_long *p;
  825.  
  826.     PALmap = (u_long **)malloc(
  827.         256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
  828.     if (PALmap == NULL) {
  829.         TIFFError(filename, "No space for Palette mapping table");
  830.         return (0);
  831.     }
  832.     p = (u_long *)(PALmap + 256);
  833.     if (isRGB) {
  834.         for (i = 0; i < 256; i++) {
  835.             PALmap[i] = p;
  836. #define    CMAP(x)    \
  837.     c = x; *p++ = PACK(rmap[c]&0xff, gmap[c]&0xff, bmap[c]&0xff);
  838.             switch (bitspersample) {
  839.                 register RGBvalue c;
  840.             case 1:
  841.                 CMAP(i>>7);
  842.                 CMAP((i>>6)&1);
  843.                 CMAP((i>>5)&1);
  844.                 CMAP((i>>4)&1);
  845.                 CMAP((i>>3)&1);
  846.                 CMAP((i>>2)&1);
  847.                 CMAP((i>>1)&1);
  848.                 CMAP(i&1);
  849.                 break;
  850.             case 2:
  851.                 CMAP(i>>6);
  852.                 CMAP((i>>4)&3);
  853.                 CMAP((i>>2)&3);
  854.                 CMAP(i&3);
  855.                 break;
  856.             case 4:
  857.                 CMAP(i>>4);
  858.                 CMAP(i&0xf);
  859.                 break;
  860.             case 8:
  861.                 CMAP(i);
  862.                 break;
  863.             }
  864. #undef CMAP
  865.         }
  866.     } else {
  867.         for (i = 0; i < 256; i++) {
  868.             PALmap[i] = p;
  869. #define    CMAP(x)    \
  870.     c = x; *p++ = rgbi(rmap[c], gmap[c], bmap[c]);
  871.             switch (bitspersample) {
  872.                 register RGBvalue c;
  873.             case 1:
  874.                 CMAP(i>>7);
  875.                 CMAP((i>>6)&1);
  876.                 CMAP((i>>5)&1);
  877.                 CMAP((i>>4)&1);
  878.                 CMAP((i>>3)&1);
  879.                 CMAP((i>>2)&1);
  880.                 CMAP((i>>1)&1);
  881.                 CMAP(i&1);
  882.                 break;
  883.             case 2:
  884.                 CMAP(i>>6);
  885.                 CMAP((i>>4)&3);
  886.                 CMAP((i>>2)&3);
  887.                 CMAP(i&3);
  888.                 break;
  889.             case 4:
  890.                 CMAP(i>>4);
  891.                 CMAP(i&0xf);
  892.                 break;
  893.             case 8:
  894.                 CMAP(i);
  895.                 break;
  896.             }
  897. #undef CMAP
  898.         }
  899.     }
  900.     return (1);
  901. }
  902.  
  903. /*
  904.  * The following routines move decoded data returned
  905.  * from the TIFF library into rasters that are suitable
  906.  * for passing to lrecwrite.  They do the necessary
  907.  * conversions based on whether the drawing mode is RGB
  908.  * colormap and whether or not there is a mapping table.
  909.  *
  910.  * The routines have been created according to the most
  911.  * important cases and optimized.  pickTileContigCase and
  912.  * pickTileSeparateCase analyze the parameters and select
  913.  * the appropriate "put" routine to use.
  914.  */
  915. #define    REPEAT8(op)    REPEAT4(op); REPEAT4(op)
  916. #define    REPEAT4(op)    REPEAT2(op); REPEAT2(op)
  917. #define    REPEAT2(op)    op; op
  918. #define    CASE8(x,op)                \
  919.     switch (x) {                \
  920.     case 7: op; case 6: op; case 5: op;    \
  921.     case 4: op; case 3: op; case 2: op;    \
  922.     case 1: op;                \
  923.     }
  924. #define    CASE4(x,op)    switch (x) { case 3: op; case 2: op; case 1: op; }
  925.  
  926. #define    UNROLL8(w, op1, op2) {        \
  927.     register uint32 x;        \
  928.     for (x = w; x >= 8; x -= 8) {    \
  929.         op1;            \
  930.         REPEAT8(op2);        \
  931.     }                \
  932.     if (x > 0) {            \
  933.         op1;            \
  934.         CASE8(x,op2);        \
  935.     }                \
  936. }
  937. #define    UNROLL4(w, op1, op2) {        \
  938.     register uint32 x;        \
  939.     for (x = w; x >= 4; x -= 4) {    \
  940.         op1;            \
  941.         REPEAT4(op2);        \
  942.     }                \
  943.     if (x > 0) {            \
  944.         op1;            \
  945.         CASE4(x,op2);        \
  946.     }                \
  947. }
  948. #define    UNROLL2(w, op1, op2) {        \
  949.     register uint32 x;        \
  950.     for (x = w; x >= 2; x -= 2) {    \
  951.         op1;            \
  952.         REPEAT2(op2);        \
  953.     }                \
  954.     if (x) {            \
  955.         op1;            \
  956.         op2;            \
  957.     }                \
  958. }
  959.             
  960.  
  961. #define    SKEW(r,g,b,skew)    { r += skew; g += skew; b += skew; }
  962.  
  963. #define    DECLAREContigPutFunc(name) \
  964. static void name(\
  965.     u_long* cp, \
  966.     u_char* pp, \
  967.     RGBvalue* Map, \
  968.     uint32 w, u_long h, \
  969.     int fromskew, int toskew \
  970. )
  971.  
  972. #define    DECLARESepPutFunc(name) \
  973. static void name(\
  974.     u_long* cp, \
  975.     u_char* r, u_char* g, u_char* b, \
  976.     RGBvalue* Map, \
  977.     uint32 w, uint32 h, \
  978.     int fromskew, int toskew \
  979. )
  980.  
  981. /*
  982.  * 8-bit packed samples => colormap
  983.  */
  984. DECLAREContigPutFunc(putcontig8bittile)
  985. {
  986.     register uint32 x;
  987.  
  988.     fromskew *= samplesperpixel;
  989.     if (Map) {
  990.         while (h-- > 0) {
  991.             for (x = w; x-- > 0;) {
  992.                 *cp++ = rgbi(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  993.                 pp += samplesperpixel;
  994.             }
  995.             cp += toskew;
  996.             pp += fromskew;
  997.         }
  998.     } else {
  999.         while (h-- > 0) {
  1000.             for (x = w; x-- > 0;) {
  1001.                 *cp++ = rgbi(pp[0], pp[1], pp[2]);
  1002.                 pp += samplesperpixel;
  1003.             }
  1004.             cp += toskew;
  1005.             pp += fromskew;
  1006.         }
  1007.     }
  1008. }
  1009.  
  1010. /*
  1011.  * 16-bit packed samples => colormap
  1012.  */
  1013. DECLAREContigPutFunc(putcontig16bittile)
  1014. {
  1015.     register uint32 x;
  1016.  
  1017.     fromskew *= samplesperpixel;
  1018.     if (Map) {
  1019.         while (h-- > 0) {
  1020.             for (x = w; x-- > 0;) {
  1021.                 *cp++ = rgbi(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  1022.                 pp += samplesperpixel;
  1023.             }
  1024.             cp += toskew;
  1025.             pp += fromskew;
  1026.         }
  1027.     } else {
  1028.         while (h-- > 0) {
  1029.             for (x = w; x-- > 0;) {
  1030.                 *cp++ = rgbi(pp[0], pp[1], pp[2]);
  1031.                 pp += samplesperpixel;
  1032.             }
  1033.             cp += toskew;
  1034.             pp += fromskew;
  1035.         }
  1036.     }
  1037. }
  1038.  
  1039. /*
  1040.  * 8-bit unpacked samples => colormap
  1041.  */
  1042. DECLARESepPutFunc(putseparate8bittile)
  1043. {
  1044.     register uint32 x;
  1045.  
  1046.     if (Map) {
  1047.         while (h-- > 0) {
  1048.             for (x = w; x-- > 0;)
  1049.                 *cp++ =
  1050.                   rgbi(Map[*r++], Map[*g++], Map[*b++]);
  1051.             SKEW(r, g, b, fromskew);
  1052.             cp += toskew;
  1053.         }
  1054.     } else {
  1055.         while (h-- > 0) {
  1056.             for (x = w; x-- > 0;)
  1057.                 *cp++ = rgbi(*r++, *g++, *b++);
  1058.             SKEW(r, g, b, fromskew);
  1059.             cp += toskew;
  1060.         }
  1061.     }
  1062. }
  1063.  
  1064. /*
  1065.  * 16-bit unpacked samples => colormap
  1066.  */
  1067. DECLARESepPutFunc(putseparate16bittile)
  1068. {
  1069.     register uint32 x;
  1070.  
  1071.     if (Map) {
  1072.         while (h-- > 0) {
  1073.             for (x = 0; x < w; x++)
  1074.                 *cp++ =
  1075.                   rgbi(Map[*r++], Map[*g++], Map[*b++]);
  1076.             SKEW(r, g, b, fromskew);
  1077.             cp += toskew;
  1078.         }
  1079.     } else {
  1080.         while (h-- > 0) {
  1081.             for (x = 0; x < w; x++)
  1082.                 *cp++ = rgbi(*r++, *g++, *b++);
  1083.             SKEW(r, g, b, fromskew);
  1084.             cp += toskew;
  1085.         }
  1086.     }
  1087. }
  1088.  
  1089. /*
  1090.  * 8-bit palette => colormap/RGB
  1091.  */
  1092. DECLAREContigPutFunc(put8bitcmaptile)
  1093. {
  1094.     while (h-- > 0) {
  1095.         UNROLL8(w,, *cp++ = PALmap[*pp++][0]);
  1096.         cp += toskew;
  1097.         pp += fromskew;
  1098.     }
  1099. }
  1100.  
  1101. /*
  1102.  * 4-bit palette => colormap/RGB
  1103.  */
  1104. DECLAREContigPutFunc(put4bitcmaptile)
  1105. {
  1106.     register u_long *bw;
  1107.  
  1108.     fromskew /= 2;
  1109.     while (h-- > 0) {
  1110.         UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
  1111.         cp += toskew;
  1112.         pp += fromskew;
  1113.     }
  1114. }
  1115.  
  1116. /*
  1117.  * 2-bit palette => colormap/RGB
  1118.  */
  1119. DECLAREContigPutFunc(put2bitcmaptile)
  1120. {
  1121.     register u_long *bw;
  1122.  
  1123.     fromskew /= 4;
  1124.     while (h-- > 0) {
  1125.         UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
  1126.         cp += toskew;
  1127.         pp += fromskew;
  1128.     }
  1129. }
  1130.  
  1131. /*
  1132.  * 1-bit palette => colormap/RGB
  1133.  */
  1134. DECLAREContigPutFunc(put1bitcmaptile)
  1135. {
  1136.     register u_long *bw;
  1137.  
  1138.     fromskew /= 8;
  1139.     while (h-- > 0) {
  1140.         UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
  1141.         cp += toskew;
  1142.         pp += fromskew;
  1143.     }
  1144. }
  1145.  
  1146. /*
  1147.  * 8-bit greyscale => colormap/RGB
  1148.  */
  1149. DECLAREContigPutFunc(putgreytile)
  1150. {
  1151.     while (h-- > 0) {
  1152.         register uint32 x;
  1153.         for (x = w; x-- > 0;)
  1154.             *cp++ = BWmap[*pp++][0];
  1155.         cp += toskew;
  1156.         pp += fromskew;
  1157.     }
  1158. }
  1159.  
  1160. /*
  1161.  * 1-bit bilevel => colormap/RGB
  1162.  */
  1163. DECLAREContigPutFunc(put1bitbwtile)
  1164. {
  1165.     register u_long *bw;
  1166.  
  1167.     fromskew /= 8;
  1168.     while (h-- > 0) {
  1169.         UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
  1170.         cp += toskew;
  1171.         pp += fromskew;
  1172.     }
  1173. }
  1174.  
  1175. /*
  1176.  * 2-bit greyscale => colormap/RGB
  1177.  */
  1178. DECLAREContigPutFunc(put2bitbwtile)
  1179. {
  1180.     register u_long *bw;
  1181.  
  1182.     fromskew /= 4;
  1183.     while (h-- > 0) {
  1184.         UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
  1185.         cp += toskew;
  1186.         pp += fromskew;
  1187.     }
  1188. }
  1189.  
  1190. /*
  1191.  * 4-bit greyscale => colormap/RGB
  1192.  */
  1193. DECLAREContigPutFunc(put4bitbwtile)
  1194. {
  1195.     register u_long *bw;
  1196.  
  1197.     fromskew /= 2;
  1198.     while (h-- > 0) {
  1199.         UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
  1200.         cp += toskew;
  1201.         pp += fromskew;
  1202.     }
  1203. }
  1204.  
  1205. /*
  1206.  * 8-bit packed RGB samples => RGB
  1207.  */
  1208. DECLAREContigPutFunc(putRGBcontig8bittile)
  1209. {
  1210.     fromskew *= samplesperpixel;
  1211.     if (Map) {
  1212.         while (h-- > 0) {
  1213.             register uint32 x;
  1214.             for (x = w; x-- > 0;) {
  1215.                 *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  1216.                 pp += samplesperpixel;
  1217.             }
  1218.             pp += fromskew;
  1219.             cp += toskew;
  1220.         }
  1221.     } else {
  1222.         while (h-- > 0) {
  1223.             UNROLL8(w,,
  1224.                 *cp++ = PACK(pp[0], pp[1], pp[2]);
  1225.                 pp += samplesperpixel);
  1226.             cp += toskew;
  1227.             pp += fromskew;
  1228.         }
  1229.     }
  1230. }
  1231.  
  1232. /*
  1233.  * 16-bit packed RGB samples => RGB
  1234.  */
  1235. DECLAREContigPutFunc(putRGBcontig16bittile)
  1236. {
  1237.     register uint32 x;
  1238.  
  1239.     fromskew *= samplesperpixel;
  1240.     if (Map) {
  1241.         while (h-- > 0) {
  1242.             for (x = w; x-- > 0;) {
  1243.                 *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  1244.                 pp += samplesperpixel;
  1245.             }
  1246.             cp += toskew;
  1247.             pp += fromskew;
  1248.         }
  1249.     } else {
  1250.         while (h-- > 0) {
  1251.             for (x = w; x-- > 0;) {
  1252.                 *cp++ = PACK(pp[0], pp[1], pp[2]);
  1253.                 pp += samplesperpixel;
  1254.             }
  1255.             cp += toskew;
  1256.             pp += fromskew;
  1257.         }
  1258.     }
  1259. }
  1260.  
  1261. /*
  1262.  * 8-bit unpacked RGB samples => RGB
  1263.  */
  1264. DECLARESepPutFunc(putRGBseparate8bittile)
  1265. {
  1266.     if (Map) {
  1267.         while (h-- > 0) {
  1268.             register uint32 x;
  1269.             for (x = w; x > 0; x--)
  1270.                 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
  1271.             SKEW(r, g, b, fromskew);
  1272.             cp += toskew;
  1273.         }
  1274.     } else {
  1275.         while (h-- > 0) {
  1276.             UNROLL8(w,, *cp++ = PACK(*r++, *g++, *b++));
  1277.             SKEW(r, g, b, fromskew);
  1278.             cp += toskew;
  1279.         }
  1280.     }
  1281. }
  1282.  
  1283. /*
  1284.  * 16-bit unpacked RGB samples => RGB
  1285.  */
  1286. DECLARESepPutFunc(putRGBseparate16bittile)
  1287. {
  1288.     register uint32 x;
  1289.  
  1290.     if (Map) {
  1291.         while (h-- > 0) {
  1292.             for (x = w; x > 0; x--)
  1293.                 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
  1294.             SKEW(r, g, b, fromskew);
  1295.             cp += toskew;
  1296.         }
  1297.     } else {
  1298.         while (h-- > 0) {
  1299.             for (x = 0; x < w; x++)
  1300.                 *cp++ = PACK(*r++, *g++, *b++);
  1301.             SKEW(r, g, b, fromskew);
  1302.             cp += toskew;
  1303.         }
  1304.     }
  1305. }
  1306.  
  1307. /*
  1308.  * 8-bit packed CMYK samples => RGB
  1309.  *
  1310.  * NB: The conversion of CMYK->RGB is *very* crude.
  1311.  */
  1312. DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
  1313. {
  1314.     uint16 r, g, b, k;
  1315.  
  1316.     fromskew *= samplesperpixel;
  1317.     if (Map) {
  1318.         while (h-- > 0) {
  1319.             register uint32 x;
  1320.             for (x = w; x-- > 0;) {
  1321.                 k = 255 - pp[3];
  1322.                 r = (k*(255-pp[0]))/255;
  1323.                 g = (k*(255-pp[1]))/255;
  1324.                 b = (k*(255-pp[2]))/255;
  1325.                 *cp++ = PACK(Map[r], Map[g], Map[b]);
  1326.                 pp += samplesperpixel;
  1327.             }
  1328.             pp += fromskew;
  1329.             cp += toskew;
  1330.         }
  1331.     } else {
  1332.         while (h-- > 0) {
  1333.             UNROLL8(w,,
  1334.                 k = 255 - pp[3];
  1335.                 r = (k*(255-pp[0]))/255;
  1336.                 g = (k*(255-pp[1]))/255;
  1337.                 b = (k*(255-pp[2]))/255;
  1338.                 *cp++ = PACK(r, g, b);
  1339.                 pp += samplesperpixel);
  1340.             cp += toskew;
  1341.             pp += fromskew;
  1342.         }
  1343.     }
  1344. }
  1345.  
  1346. /*
  1347.  * 8-bit packed CMYK samples => cmap
  1348.  *
  1349.  * NB: The conversion of CMYK->RGB is *very* crude.
  1350.  */
  1351. DECLAREContigPutFunc(putcontig8bitCMYKtile)
  1352. {
  1353.     uint16 r, g, b, k;
  1354.  
  1355.     fromskew *= samplesperpixel;
  1356.     if (Map) {
  1357.         while (h-- > 0) {
  1358.             register uint32 x;
  1359.             for (x = w; x-- > 0;) {
  1360.                 k = 255 - pp[3];
  1361.                 r = (k*(255-pp[0]))/255;
  1362.                 g = (k*(255-pp[1]))/255;
  1363.                 b = (k*(255-pp[2]))/255;
  1364.                 *cp++ = rgbi(Map[r], Map[g], Map[b]);
  1365.                 pp += samplesperpixel;
  1366.             }
  1367.             pp += fromskew;
  1368.             cp += toskew;
  1369.         }
  1370.     } else {
  1371.         while (h-- > 0) {
  1372.             UNROLL8(w,,
  1373.                 k = 255 - pp[3];
  1374.                 r = (k*(255-pp[0]))/255;
  1375.                 g = (k*(255-pp[1]))/255;
  1376.                 b = (k*(255-pp[2]))/255;
  1377.                 *cp++ = rgbi(r, g, b);
  1378.                 pp += samplesperpixel);
  1379.             cp += toskew;
  1380.             pp += fromskew;
  1381.         }
  1382.     }
  1383. }
  1384.  
  1385. #define    Code2V(c, RB, RW, CR)    ((((c)-RB)*(float)CR)/(float)(RW-RB))
  1386. #define    CLAMP(f,min,max) \
  1387.     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
  1388.  
  1389. #define    LumaRed        YCbCrCoeffs[0]
  1390. #define    LumaGreen    YCbCrCoeffs[1]
  1391. #define    LumaBlue    YCbCrCoeffs[2]
  1392.  
  1393. static    float D1, D2;
  1394. static    float D3, D4;
  1395.  
  1396. static void
  1397. initYCbCrConversion(void)
  1398. {
  1399.     D1 = 2 - 2*LumaRed;
  1400.     D2 = D1*LumaRed / LumaGreen;
  1401.     D3 = 2 - 2*LumaBlue;
  1402.     D4 = D3*LumaBlue / LumaGreen;
  1403. }
  1404.  
  1405. static void
  1406. putRGBContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
  1407.     register u_long *cp;
  1408.     register u_char *pp;
  1409.     int cw, ch;
  1410.     uint32 w;
  1411.     int n, fromskew, toskew;
  1412. {
  1413.     float Cb, Cr;
  1414.     int j, k;
  1415.  
  1416.     Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
  1417.     Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
  1418.     for (j = 0; j < ch; j++) {
  1419.         for (k = 0; k < cw; k++) {
  1420.             float Y, R, G, B;
  1421.             Y = Code2V(*pp++,
  1422.                 refBlackWhite[0], refBlackWhite[1], 255);
  1423.             R = Y + Cr*D1;
  1424.             B = Y + Cb*D3;
  1425.             G = Y - Cb*D4 - Cr*D2;
  1426.             cp[k] = PACK(CLAMP(R,0,255),
  1427.                      CLAMP(G,0,255),
  1428.                      CLAMP(B,0,255));
  1429.         }
  1430.         cp += w+toskew;
  1431.         pp += fromskew;
  1432.     }
  1433. }
  1434.  
  1435. static void
  1436. putCmapContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
  1437.     register u_long *cp;
  1438.     register u_char *pp;
  1439.     int cw, ch;
  1440.     uint32 w;
  1441.     int n, fromskew, toskew;
  1442. {
  1443.     float Cb, Cr;
  1444.     int j, k;
  1445.  
  1446.     Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
  1447.     Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
  1448.     for (j = 0; j < ch; j++) {
  1449.         for (k = 0; k < cw; k++) {
  1450.             float Y, R, G, B;
  1451.             Y = Code2V(*pp++,
  1452.                 refBlackWhite[0], refBlackWhite[1], 255);
  1453.             R = Y + Cr*D1;
  1454.             B = Y + Cb*D3;
  1455.             G = Y - Cb*D4 - Cr*D2;
  1456.             cp[k] = rgbi(CLAMP(R,0,255),
  1457.                      CLAMP(G,0,255),
  1458.                      CLAMP(B,0,255));
  1459.         }
  1460.         cp += w+toskew;
  1461.         pp += fromskew;
  1462.     }
  1463. }
  1464. #undef LumaBlue
  1465. #undef LumaGreen
  1466. #undef LumaRed
  1467. #undef CLAMP
  1468. #undef Code2V
  1469.  
  1470. typedef void (*YCbCrPut)(u_long*, u_char*, int, int, uint32, int, int, int);
  1471.  
  1472. /*
  1473.  * 8-bit packed YCbCr samples => RGB
  1474.  */
  1475. DECLAREContigPutFunc(putcontig8bitYCbCrtile)
  1476. {
  1477.     YCbCrPut put;
  1478.     int Coff = YCbCrVertSampling * YCbCrHorizSampling;
  1479.     u_long *tp;
  1480.     uint32 x;
  1481.  
  1482.     /* XXX adjust fromskew */
  1483.     put = (isRGB ? putRGBContigYCbCrClump : putCmapContigYCbCrClump);
  1484.     while (h >= YCbCrVertSampling) {
  1485.         tp = cp;
  1486.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1487.             (*put)(tp, pp, YCbCrHorizSampling, YCbCrVertSampling,
  1488.                 w, Coff, 0, toskew);
  1489.             tp += YCbCrHorizSampling;
  1490.             pp += Coff+2;
  1491.         }
  1492.         if (x > 0) {
  1493.             (*put)(tp, pp, x, YCbCrVertSampling,
  1494.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1495.             pp += Coff+2;
  1496.         }
  1497.         cp += YCbCrVertSampling*(w + toskew);
  1498.         pp += fromskew;
  1499.         h -= YCbCrVertSampling;
  1500.     }
  1501.     if (h > 0) {
  1502.         tp = cp;
  1503.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1504.             (*put)(tp, pp, YCbCrHorizSampling, h,
  1505.                 w, Coff, 0, toskew);
  1506.             tp += YCbCrHorizSampling;
  1507.             pp += Coff+2;
  1508.         }
  1509.         if (x > 0)
  1510.             (*put)(tp, pp, x, h,
  1511.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1512.     }
  1513. }
  1514.  
  1515. /*
  1516.  * Select the appropriate conversion routine for packed data.
  1517.  */
  1518. static tileContigRoutine
  1519. pickTileContigCase(RGBvalue* Map)
  1520. {
  1521.     tileContigRoutine put = 0;
  1522.  
  1523.     switch (photometric) {
  1524.     case PHOTOMETRIC_RGB:
  1525.         if (isRGB) {
  1526.             switch (bitspersample) {
  1527.             case 8:  put = putRGBcontig8bittile; break;
  1528.             case 16: put = putRGBcontig16bittile; break;
  1529.             }
  1530.         } else {
  1531.             switch (bitspersample) {
  1532.             case 8:  put = putcontig8bittile; break;
  1533.             case 16: put = putcontig16bittile; break;
  1534.             }
  1535.         }
  1536.         break;
  1537.     case PHOTOMETRIC_SEPARATED:
  1538.         if (isRGB) {
  1539.             switch (bitspersample) {
  1540.             case 8:  put = putRGBcontig8bitCMYKtile; break;
  1541.             }
  1542.         } else {
  1543.             switch (bitspersample) {
  1544.             case 8:  put = putcontig8bitCMYKtile; break;
  1545.             }
  1546.         }
  1547.         break;
  1548.     case PHOTOMETRIC_PALETTE:
  1549.         switch (bitspersample) {
  1550.         case 8:    put = put8bitcmaptile; break;
  1551.         case 4: put = put4bitcmaptile; break;
  1552.         case 2: put = put2bitcmaptile; break;
  1553.         case 1: put = put1bitcmaptile; break;
  1554.         }
  1555.         break;
  1556.     case PHOTOMETRIC_MINISWHITE:
  1557.     case PHOTOMETRIC_MINISBLACK:
  1558.         switch (bitspersample) {
  1559.         case 8:    put = putgreytile; break;
  1560.         case 4: put = put4bitbwtile; break;
  1561.         case 2: put = put2bitbwtile; break;
  1562.         case 1: put = put1bitbwtile; break;
  1563.         }
  1564.         break;
  1565.     case PHOTOMETRIC_YCBCR:
  1566.         switch (bitspersample) {
  1567.         case 8: put = putcontig8bitYCbCrtile; break;
  1568.         }
  1569.         break;
  1570.     }
  1571.     if (put == 0) {
  1572.         TIFFError(filename,
  1573.             "Can not handle %lu-bit file with photometric %u",
  1574.             bitspersample, photometric);
  1575.         exit(-1);
  1576.     }
  1577.     return (put);
  1578. }
  1579.  
  1580. /*
  1581.  * Select the appropriate conversion routine for unpacked data.
  1582.  *
  1583.  * NB: we assume that unpacked single channel data is directed
  1584.  *     to the "packed routines.
  1585.  */
  1586. static tileSeparateRoutine
  1587. pickTileSeparateCase(RGBvalue* Map)
  1588. {
  1589.     tileSeparateRoutine put = 0;
  1590.  
  1591.     switch (photometric) {
  1592.     case PHOTOMETRIC_RGB:
  1593.         if (isRGB) {
  1594.             switch (bitspersample) {
  1595. #ifdef notdef
  1596.             case 1:  put = putRGBseparate1bittile; break;
  1597.             case 2:  put = putRGBseparate2bittile; break;
  1598.             case 4:  put = putRGBseparate4bittile; break;
  1599. #endif
  1600.             case 8:  put = putRGBseparate8bittile; break;
  1601.             case 16: put = putRGBseparate16bittile; break;
  1602.             }
  1603.         } else {
  1604.             switch (bitspersample) {
  1605. #ifdef notdef
  1606.             case 1:  put = putseparate1bittile; break;
  1607.             case 2:  put = putseparate2bittile; break;
  1608.             case 4:  put = putseparate4bittile; break;
  1609. #endif
  1610.             case 8:  put = putseparate8bittile; break;
  1611.             case 16: put = putseparate16bittile; break;
  1612.             }
  1613.         }
  1614.         break;
  1615.     }
  1616.     if (put == 0) {
  1617.         TIFFError(filename,
  1618.             "Can not handle %lu-bit file with photometric %u",
  1619.             bitspersample, photometric);
  1620.         exit(-1);
  1621.     }
  1622.     return (put);
  1623. }
  1624.