home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / NETWORK / netpbm_src.lzh / NETPBM / LIBTIFF / tif_getimage.c < prev    next >
Text File  |  1996-11-18  |  28KB  |  1,162 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_getimage.c,v 1.20 93/08/25 09:28:15 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 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. /*
  30.  * TIFF Library
  31.  *
  32.  * Read and return a packed RGBA image.
  33.  */
  34. #include "tiffiop.h"
  35.  
  36. typedef    u_char RGBvalue;
  37.  
  38. static    u_short bitspersample;
  39. static    u_short samplesperpixel;
  40. static    u_short photometric;
  41. static    u_short orientation;
  42. static    u_short extrasamples;
  43. static    u_short planarconfig;
  44. /* colormap for pallete images */
  45. static    u_short *redcmap, *greencmap, *bluecmap;
  46. static    int stoponerr;            /* stop on read error */
  47. /* YCbCr support */
  48. static    u_short YCbCrHorizSampling;
  49. static    u_short YCbCrVertSampling;
  50. static    float *YCbCrCoeffs;
  51. static    float *refBlackWhite;
  52.  
  53. static    u_long **BWmap;
  54. static    u_long **PALmap;
  55.  
  56. static    int gt(TIFF*, int, int, u_long*);
  57. static    int gtTileContig(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  58. static    int gtTileSeparate(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  59. static    int gtStripContig(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  60. static    int gtStripSeparate(TIFF*, u_long*, RGBvalue*, u_long, u_long);
  61. static    int makebwmap(TIFF*, RGBvalue*);
  62. static    int makecmap(TIFF*, u_short*, u_short*, u_short*);
  63. static    void initYCbCrConversion(void);
  64.  
  65. int
  66. TIFFReadRGBAImage(TIFF* tif,
  67.     u_long rwidth, u_long rheight, u_long* raster, int stop)
  68. {
  69.     int ok, alpha;
  70.     u_long width, height;
  71.     u_short *sampleinfo;
  72.  
  73.     TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  74.     switch (bitspersample) {
  75.     case 1: case 2: case 4:
  76.     case 8: case 16:
  77.         break;
  78.     default:
  79.         TIFFError(TIFFFileName(tif),
  80.             "Sorry, can not handle %d-bit images", bitspersample);
  81.         return (0);
  82.     }
  83.     TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  84.     if (samplesperpixel > 4) {
  85.         TIFFError(TIFFFileName(tif),
  86.             "Sorry, can not handle images with %d-samples/pixel",
  87.             samplesperpixel);
  88.         return (0);
  89.     }
  90.     TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
  91.         &extrasamples, &sampleinfo);
  92.     alpha = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
  93.     TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
  94.     switch (samplesperpixel - extrasamples) {
  95.     case 3:
  96.         break;
  97.     case 1: case 4:
  98. /* XXX */
  99.         if (!alpha || planarconfig != PLANARCONFIG_CONTIG)
  100.             break;
  101.         /* fall thru... */
  102.     default:
  103.         TIFFError(TIFFFileName(tif),
  104.             "Sorry, can not handle %d-channel %s images%s",
  105.             samplesperpixel,
  106.             planarconfig == PLANARCONFIG_CONTIG ?
  107.             "packed" : "separated",
  108.             alpha ? " with alpha" : "");
  109.         return (0);
  110.     }
  111.     if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
  112.         switch (samplesperpixel) {
  113.         case 1:
  114.             photometric = PHOTOMETRIC_MINISBLACK;
  115.             break;
  116.         case 3: case 4:
  117.             photometric = PHOTOMETRIC_RGB;
  118.             break;
  119.         default:
  120.             TIFFError(TIFFFileName(tif),
  121.                 "Missing needed \"PhotometricInterpretation\" tag");
  122.             return (0);
  123.         }
  124.         TIFFError(TIFFFileName(tif),
  125.             "No \"PhotometricInterpretation\" tag, assuming %s\n",
  126.             photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
  127.     }
  128.     switch (photometric) {
  129.     case PHOTOMETRIC_MINISWHITE:
  130.     case PHOTOMETRIC_MINISBLACK:
  131.     case PHOTOMETRIC_RGB:
  132.     case PHOTOMETRIC_PALETTE:
  133.     case PHOTOMETRIC_YCBCR:
  134.         break;
  135.     case PHOTOMETRIC_SEPARATED: {
  136.         u_short inkset;
  137.         TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
  138.         if (inkset != INKSET_CMYK) {
  139.             TIFFError(TIFFFileName(tif),
  140.                 "Sorry, can not handle separated image with %s=%d",
  141.                 "InkSet", inkset);
  142.             return (0);
  143.         }
  144.         break;
  145.     }
  146.     default:
  147.         TIFFError(TIFFFileName(tif),
  148.             "Sorry, can not handle image with %s=%d",
  149.             "PhotometricInterpretation", photometric);
  150.         return (0);
  151.     }
  152.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  153.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  154.     /* XXX verify rwidth and rheight against width and height */
  155.     stoponerr = stop;
  156.     BWmap = NULL;
  157.     PALmap = NULL;
  158.     ok = gt(tif, rwidth, height, raster + (rheight-height)*rwidth);
  159.     if (BWmap)
  160.         _TIFFfree((char *)BWmap);
  161.     if (PALmap)
  162.         _TIFFfree((char *)PALmap);
  163.     return (ok);
  164. }
  165.  
  166. static int
  167. checkcmap(int n, u_short* r, u_short* g, u_short* b)
  168. {
  169.     while (n-- > 0)
  170.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  171.             return (16);
  172.     return (8);
  173. }
  174.  
  175. /*
  176.  * Construct a mapping table to convert from the range
  177.  * of the data samples to [0,255] --for display.  This
  178.  * process also handles inverting B&W images when needed.
  179.  */ 
  180. static int
  181. setupMap(TIFF* tif,
  182.     u_short minsamplevalue, u_short maxsamplevalue, RGBvalue** pMap)
  183. {
  184.     register int x, range;
  185.     RGBvalue *Map;
  186.  
  187.     range = maxsamplevalue - minsamplevalue;
  188.     Map = (RGBvalue *)_TIFFmalloc((range + 1) * sizeof (RGBvalue));
  189.     if (Map == NULL) {
  190.         TIFFError(TIFFFileName(tif),
  191.             "No space for photometric conversion table");
  192.         return (0);
  193.     }
  194.     if (photometric == PHOTOMETRIC_MINISWHITE) {
  195.         for (x = 0; x <= range; x++)
  196.             Map[x] = ((range - x) * 255) / range;
  197.     } else {
  198.         for (x = 0; x <= range; x++)
  199.             Map[x] = (x * 255) / range;
  200.     }
  201.     if (bitspersample <= 8 &&
  202.         (photometric == PHOTOMETRIC_MINISBLACK ||
  203.          photometric == PHOTOMETRIC_MINISWHITE)) {
  204.         /*
  205.          * Use photometric mapping table to construct
  206.          * unpacking tables for samples <= 8 bits.
  207.          */
  208.         if (!makebwmap(tif, Map))
  209.             return (0);
  210.         /* no longer need Map, free it */
  211.         _TIFFfree((char *)Map);
  212.         Map = NULL;
  213.     }
  214.     *pMap = Map;
  215.     return (1);
  216. }
  217.  
  218. static int
  219. gt(TIFF* tif, int w, int h, u_long* raster)
  220. {
  221.     u_short minsamplevalue, maxsamplevalue;
  222.     RGBvalue *Map;
  223.     int e, ncomps;
  224.  
  225.     TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
  226.     TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
  227.     Map = NULL;
  228.     switch (photometric) {
  229.     case PHOTOMETRIC_YCBCR:
  230.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
  231.             &YCbCrCoeffs);
  232.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
  233.             &YCbCrHorizSampling, &YCbCrVertSampling);
  234.         TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
  235.             &refBlackWhite);
  236.         initYCbCrConversion();
  237.         /* fall thru... */
  238.     case PHOTOMETRIC_RGB:
  239.     case PHOTOMETRIC_SEPARATED:
  240.         if (minsamplevalue == 0 && maxsamplevalue == 255)
  241.             break;
  242.         /* fall thru... */
  243.     case PHOTOMETRIC_MINISBLACK:
  244.     case PHOTOMETRIC_MINISWHITE:
  245.         if (!setupMap(tif, minsamplevalue, maxsamplevalue, &Map))
  246.             return (0);
  247.         break;
  248.     case PHOTOMETRIC_PALETTE:
  249.         if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
  250.                   &redcmap, &greencmap, &bluecmap)) {
  251.             TIFFError(TIFFFileName(tif),
  252.                 "Missing required \"Colormap\" tag");
  253.             return (0);
  254.         }
  255.         /*
  256.          * Convert 16-bit colormap to 8-bit (unless it looks
  257.          * like an old-style 8-bit colormap).
  258.          */
  259.         if (checkcmap(1<<bitspersample, redcmap, greencmap, bluecmap) == 16) {
  260.             int i;
  261.             for (i = (1<<bitspersample)-1; i > 0; i--) {
  262. #define    CVT(x)        (((x) * 255) / ((1L<<16)-1))
  263.                 redcmap[i] = CVT(redcmap[i]);
  264.                 greencmap[i] = CVT(greencmap[i]);
  265.                 bluecmap[i] = CVT(bluecmap[i]);
  266.             }
  267.         } else
  268.             TIFFWarning(TIFFFileName(tif), "Assuming 8-bit colormap");
  269.         if (bitspersample <= 8) {
  270.             /*
  271.              * Use mapping table and colormap to construct
  272.              * unpacking tables for samples < 8 bits.
  273.              */
  274.             if (!makecmap(tif, redcmap, greencmap, bluecmap))
  275.                 return (0);
  276.         }
  277.         break;
  278.     }
  279.     ncomps = samplesperpixel - extrasamples;
  280.     if (planarconfig == PLANARCONFIG_SEPARATE && ncomps > 1) {
  281.         e = TIFFIsTiled(tif) ?
  282.             gtTileSeparate(tif, raster, Map, h, w) :
  283.             gtStripSeparate(tif, raster, Map, h, w);
  284.     } else {
  285.         e = TIFFIsTiled(tif) ? 
  286.             gtTileContig(tif, raster, Map, h, w) :
  287.             gtStripContig(tif, raster, Map, h, w);
  288.     }
  289.     if (Map)
  290.         _TIFFfree((char *)Map);
  291.     return (e);
  292. }
  293.  
  294. static u_long
  295. setorientation(TIFF* tif, u_long h)
  296. {
  297.     u_long y;
  298.  
  299.     TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
  300.     switch (orientation) {
  301.     case ORIENTATION_BOTRIGHT:
  302.     case ORIENTATION_RIGHTBOT:    /* XXX */
  303.     case ORIENTATION_LEFTBOT:    /* XXX */
  304.         TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
  305.         orientation = ORIENTATION_BOTLEFT;
  306.         /* fall thru... */
  307.     case ORIENTATION_BOTLEFT:
  308.         y = 0;
  309.         break;
  310.     case ORIENTATION_TOPRIGHT:
  311.     case ORIENTATION_RIGHTTOP:    /* XXX */
  312.     case ORIENTATION_LEFTTOP:    /* XXX */
  313.     default:
  314.         TIFFWarning(TIFFFileName(tif), "using top-left orientation");
  315.         orientation = ORIENTATION_TOPLEFT;
  316.         /* fall thru... */
  317.     case ORIENTATION_TOPLEFT:
  318.         y = h-1;
  319.         break;
  320.     }
  321.     return (y);
  322. }
  323.  
  324. typedef void (*tileContigRoutine)
  325.     (u_long*, u_char*, RGBvalue*, u_long, u_long, int, int);
  326. static tileContigRoutine pickTileContigCase(TIFF*, RGBvalue*);
  327.  
  328. /*
  329.  * Get an tile-organized image that has
  330.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  331.  * or
  332.  *    SamplesPerPixel == 1
  333.  */    
  334. static int
  335. gtTileContig(TIFF* tif, u_long* raster, RGBvalue* Map, u_long h, u_long w)
  336. {
  337.     u_long col, row, y;
  338.     u_long tw, th;
  339.     u_char *buf;
  340.     int fromskew, toskew;
  341.     u_int nrow;
  342.     tileContigRoutine put;
  343.  
  344.     put = pickTileContigCase(tif, Map);
  345.     if (put == 0)
  346.         return (0);
  347.     buf = (u_char *)_TIFFmalloc(TIFFTileSize(tif));
  348.     if (buf == 0) {
  349.         TIFFError(TIFFFileName(tif), "No space for tile buffer");
  350.         return (0);
  351.     }
  352.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  353.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  354.     y = setorientation(tif, h);
  355.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  356.     for (row = 0; row < h; row += th) {
  357.         nrow = (row + th > h ? h - row : th);
  358.         for (col = 0; col < w; col += tw) {
  359.             if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 &&
  360.                 stoponerr)
  361.                 break;
  362.             if (col + tw > w) {
  363.                 /*
  364.                  * Tile is clipped horizontally.  Calculate
  365.                  * visible portion and skewing factors.
  366.                  */
  367.                 u_long npix = w - col;
  368.                 fromskew = tw - npix;
  369.                 (*put)(raster + y*w + col, buf, Map,
  370.                     npix, nrow, fromskew, toskew + fromskew);
  371.             } else
  372.                 (*put)(raster + y*w + col, buf, Map,
  373.                     tw, nrow, 0, toskew);
  374.         }
  375.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  376.     }
  377.     _TIFFfree(buf);
  378.     return (1);
  379. }
  380.  
  381. typedef void (*tileSeparateRoutine)
  382.     (u_long*, u_char*, u_char*, u_char*, RGBvalue*, u_long, u_long, int, int);
  383. static tileSeparateRoutine pickTileSeparateCase(TIFF*, RGBvalue*);
  384.  
  385. /*
  386.  * Get an tile-organized image that has
  387.  *     SamplesPerPixel > 1
  388.  *     PlanarConfiguration separated
  389.  * We assume that all such images are RGB.
  390.  */    
  391. static int
  392. gtTileSeparate(TIFF* tif, u_long* raster, RGBvalue* Map, u_long h, u_long w)
  393. {
  394.     u_long col, row, y;
  395.     u_long tw, th;
  396.     u_char *buf;
  397.     u_char *r, *g, *b;
  398.     u_long tilesize;
  399.     int fromskew, toskew;
  400.     u_int nrow;
  401.     tileSeparateRoutine put;
  402.  
  403.     put = pickTileSeparateCase(tif, Map);
  404.     if (put == 0)
  405.         return (0);
  406.     tilesize = TIFFTileSize(tif);
  407.     buf = (u_char *)_TIFFmalloc(3*tilesize);
  408.     if (buf == 0) {
  409.         TIFFError(TIFFFileName(tif), "No space for tile buffer");
  410.         return (0);
  411.     }
  412.     r = buf;
  413.     g = r + tilesize;
  414.     b = g + tilesize;
  415.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  416.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  417.     y = setorientation(tif, h);
  418.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  419.     for (row = 0; row < h; row += th) {
  420.         nrow = (row + th > h ? h - row : th);
  421.         for (col = 0; col < w; col += tw) {
  422.             if (TIFFReadTile(tif, r, col, row,0,0) < 0 && stoponerr)
  423.                 break;
  424.             if (TIFFReadTile(tif, g, col, row,0,1) < 0 && stoponerr)
  425.                 break;
  426.             if (TIFFReadTile(tif, b, col, row,0,2) < 0 && stoponerr)
  427.                 break;
  428.             if (col + tw > w) {
  429.                 /*
  430.                  * Tile is clipped horizontally.  Calculate
  431.                  * visible portion and skewing factors.
  432.                  */
  433.                 u_long npix = w - col;
  434.                 fromskew = tw - npix;
  435.                 (*put)(raster + y*w + col, r, g, b, Map,
  436.                     npix, nrow, fromskew, toskew + fromskew);
  437.             } else
  438.                 (*put)(raster + y*w + col, r, g, b, Map,
  439.                     tw, nrow, 0, toskew);
  440.         }
  441.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  442.     }
  443.     _TIFFfree(buf);
  444.     return (1);
  445. }
  446.  
  447. /*
  448.  * Get a strip-organized image that has
  449.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  450.  * or
  451.  *    SamplesPerPixel == 1
  452.  */    
  453. static int
  454. gtStripContig(TIFF* tif, u_long* raster, RGBvalue* Map, u_long h, u_long w)
  455. {
  456.     u_long row, y, nrow;
  457.     u_char *buf;
  458.     tileContigRoutine put;
  459.     u_long rowsperstrip;
  460.     u_long imagewidth;
  461.     u_long scanline;
  462.     int fromskew, toskew;
  463.  
  464.     put = pickTileContigCase(tif, Map);
  465.     if (put == 0)
  466.         return (0);
  467.     buf = (u_char *)_TIFFmalloc(TIFFStripSize(tif));
  468.     if (buf == 0) {
  469.         TIFFError(TIFFFileName(tif), "No space for strip buffer");
  470.         return (0);
  471.     }
  472.     y = setorientation(tif, h);
  473.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  474.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  475.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  476.     scanline = TIFFScanlineSize(tif);
  477.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  478.     for (row = 0; row < h; row += rowsperstrip) {
  479.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  480.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  481.             buf, nrow*scanline) < 0 && stoponerr)
  482.             break;
  483.         (*put)(raster + y*w, buf, Map, w, nrow, fromskew, toskew);
  484.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  485.     }
  486.     _TIFFfree(buf);
  487.     return (1);
  488. }
  489.  
  490. /*
  491.  * Get a strip-organized image with
  492.  *     SamplesPerPixel > 1
  493.  *     PlanarConfiguration separated
  494.  * We assume that all such images are RGB.
  495.  */
  496. static int
  497. gtStripSeparate(TIFF* tif, u_long* raster, RGBvalue* Map, u_long h, u_long w)
  498. {
  499.     u_char *buf;
  500.     u_char *r, *g, *b;
  501.     u_long row, y, nrow;
  502.     u_long scanline;
  503.     tileSeparateRoutine put;
  504.     u_long rowsperstrip;
  505.     u_long imagewidth;
  506.     u_long stripsize;
  507.     int fromskew, toskew;
  508.  
  509.     stripsize = TIFFStripSize(tif);
  510.     r = buf = (u_char *)_TIFFmalloc(3*stripsize);
  511.     if (buf == 0)
  512.         return (0);
  513.     g = r + stripsize;
  514.     b = g + stripsize;
  515.     put = pickTileSeparateCase(tif, Map);
  516.     if (put == 0) {
  517.         TIFFError(TIFFFileName(tif), "Can not handle format");
  518.         return (0);
  519.     }
  520.     y = setorientation(tif, h);
  521.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  522.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  523.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  524.     scanline = TIFFScanlineSize(tif);
  525.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  526.     for (row = 0; row < h; row += rowsperstrip) {
  527.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  528.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  529.             r, nrow*scanline) < 0 && stoponerr)
  530.             break;
  531.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
  532.             g, nrow*scanline) < 0 && stoponerr)
  533.             break;
  534.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
  535.             b, nrow*scanline) < 0 && stoponerr)
  536.             break;
  537.         (*put)(raster + y*w, r, g, b, Map, w, nrow, fromskew, toskew);
  538.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  539.     }
  540.     _TIFFfree(buf);
  541.     return (1);
  542. }
  543.  
  544. #define    PACK(r,g,b)    ((u_long)(r)|((u_long)(g)<<8)|((u_long)(b)<<16))
  545.  
  546. /*
  547.  * Greyscale images with less than 8 bits/sample are handled
  548.  * with a table to avoid lots of shifts and masks.  The table
  549.  * is setup so that put*bwtile (below) can retrieve 8/bitspersample
  550.  * pixel values simply by indexing into the table with one
  551.  * number.
  552.  */
  553. static int
  554. makebwmap(TIFF* tif, RGBvalue* Map)
  555. {
  556.     register int i;
  557.     int nsamples = 8 / bitspersample;
  558.     register u_long *p;
  559.  
  560.     BWmap = (u_long **)_TIFFmalloc(
  561.         256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
  562.     if (BWmap == NULL) {
  563.         TIFFError(TIFFFileName(tif), "No space for B&W mapping table");
  564.         return (0);
  565.     }
  566.     p = (u_long *)(BWmap + 256);
  567.     for (i = 0; i < 256; i++) {
  568.         BWmap[i] = p;
  569.         switch (bitspersample) {
  570.             register RGBvalue c;
  571. #define    GREY(x)    c = Map[x]; *p++ = PACK(c,c,c);
  572.         case 1:
  573.             GREY(i>>7);
  574.             GREY((i>>6)&1);
  575.             GREY((i>>5)&1);
  576.             GREY((i>>4)&1);
  577.             GREY((i>>3)&1);
  578.             GREY((i>>2)&1);
  579.             GREY((i>>1)&1);
  580.             GREY(i&1);
  581.             break;
  582.         case 2:
  583.             GREY(i>>6);
  584.             GREY((i>>4)&3);
  585.             GREY((i>>2)&3);
  586.             GREY(i&3);
  587.             break;
  588.         case 4:
  589.             GREY(i>>4);
  590.             GREY(i&0xf);
  591.             break;
  592.         case 8:
  593.             GREY(i);
  594.             break;
  595.         }
  596. #undef    GREY
  597.     }
  598.     return (1);
  599. }
  600.  
  601. /*
  602.  * Palette images with <= 8 bits/sample are handled
  603.  * with a table to avoid lots of shifts and masks.  The table
  604.  * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
  605.  * pixel values simply by indexing into the table with one
  606.  * number.
  607.  */
  608. static int
  609. makecmap(TIFF* tif, u_short* rmap, u_short* gmap, u_short* bmap)
  610. {
  611.     register int i;
  612.     int nsamples = 8 / bitspersample;
  613.     register u_long *p;
  614.  
  615.     PALmap = (u_long **)_TIFFmalloc(
  616.         256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
  617.     if (PALmap == NULL) {
  618.         TIFFError(TIFFFileName(tif), "No space for Palette mapping table");
  619.         return (0);
  620.     }
  621.     p = (u_long *)(PALmap + 256);
  622.     for (i = 0; i < 256; i++) {
  623.         PALmap[i] = p;
  624. #define    CMAP(x)    \
  625. c = x; *p++ = PACK(rmap[c]&0xff, gmap[c]&0xff, bmap[c]&0xff);
  626.         switch (bitspersample) {
  627.             register RGBvalue c;
  628.         case 1:
  629.             CMAP(i>>7);
  630.             CMAP((i>>6)&1);
  631.             CMAP((i>>5)&1);
  632.             CMAP((i>>4)&1);
  633.             CMAP((i>>3)&1);
  634.             CMAP((i>>2)&1);
  635.             CMAP((i>>1)&1);
  636.             CMAP(i&1);
  637.             break;
  638.         case 2:
  639.             CMAP(i>>6);
  640.             CMAP((i>>4)&3);
  641.             CMAP((i>>2)&3);
  642.             CMAP(i&3);
  643.             break;
  644.         case 4:
  645.             CMAP(i>>4);
  646.             CMAP(i&0xf);
  647.             break;
  648.         case 8:
  649.             CMAP(i);
  650.             break;
  651.         }
  652. #undef CMAP
  653.     }
  654.     return (1);
  655. }
  656.  
  657. /*
  658.  * The following routines move decoded data returned
  659.  * from the TIFF library into rasters filled with packed
  660.  * ABGR pixels (i.e. suitable for passing to lrecwrite.)
  661.  *
  662.  * The routines have been created according to the most
  663.  * important cases and optimized.  pickTileContigCase and
  664.  * pickTileSeparateCase analyze the parameters and select
  665.  * the appropriate "put" routine to use.
  666.  */
  667. #define    REPEAT8(op)    REPEAT4(op); REPEAT4(op)
  668. #define    REPEAT4(op)    REPEAT2(op); REPEAT2(op)
  669. #define    REPEAT2(op)    op; op
  670. #define    CASE8(x,op)                \
  671.     switch (x) {                \
  672.     case 7: op; case 6: op; case 5: op;    \
  673.     case 4: op; case 3: op; case 2: op;    \
  674.     case 1: op;                \
  675.     }
  676. #define    CASE4(x,op)    switch (x) { case 3: op; case 2: op; case 1: op; }
  677.  
  678. #define    UNROLL8(w, op1, op2) {        \
  679.     register u_long x;        \
  680.     for (x = w; x >= 8; x -= 8) {    \
  681.         op1;            \
  682.         REPEAT8(op2);        \
  683.     }                \
  684.     if (x > 0) {            \
  685.         op1;            \
  686.         CASE8(x,op2);        \
  687.     }                \
  688. }
  689. #define    UNROLL4(w, op1, op2) {        \
  690.     register u_long x;        \
  691.     for (x = w; x >= 4; x -= 4) {    \
  692.         op1;            \
  693.         REPEAT4(op2);        \
  694.     }                \
  695.     if (x > 0) {            \
  696.         op1;            \
  697.         CASE4(x,op2);        \
  698.     }                \
  699. }
  700. #define    UNROLL2(w, op1, op2) {        \
  701.     register u_long x;        \
  702.     for (x = w; x >= 2; x -= 2) {    \
  703.         op1;            \
  704.         REPEAT2(op2);        \
  705.     }                \
  706.     if (x) {            \
  707.         op1;            \
  708.         op2;            \
  709.     }                \
  710. }
  711.             
  712.  
  713. #define    SKEW(r,g,b,skew)    { r += skew; g += skew; b += skew; }
  714.  
  715. #define    DECLAREContigPutFunc(name) \
  716. static void name(\
  717.     u_long* cp, \
  718.     u_char* pp, \
  719.     RGBvalue* Map, \
  720.     u_long w, u_long h, \
  721.     int fromskew, int toskew \
  722. )
  723.  
  724. /*
  725.  * 8-bit palette => colormap/RGB
  726.  */
  727. DECLAREContigPutFunc(put8bitcmaptile)
  728. {
  729.     while (h-- > 0) {
  730.         UNROLL8(w, NULL, *cp++ = PALmap[*pp++][0]);
  731.         cp += toskew;
  732.         pp += fromskew;
  733.     }
  734. }
  735.  
  736. /*
  737.  * 4-bit palette => colormap/RGB
  738.  */
  739. DECLAREContigPutFunc(put4bitcmaptile)
  740. {
  741.     register u_long *bw;
  742.  
  743.     fromskew /= 2;
  744.     while (h-- > 0) {
  745.         UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
  746.         cp += toskew;
  747.         pp += fromskew;
  748.     }
  749. }
  750.  
  751. /*
  752.  * 2-bit palette => colormap/RGB
  753.  */
  754. DECLAREContigPutFunc(put2bitcmaptile)
  755. {
  756.     register u_long *bw;
  757.  
  758.     fromskew /= 4;
  759.     while (h-- > 0) {
  760.         UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
  761.         cp += toskew;
  762.         pp += fromskew;
  763.     }
  764. }
  765.  
  766. /*
  767.  * 1-bit palette => colormap/RGB
  768.  */
  769. DECLAREContigPutFunc(put1bitcmaptile)
  770. {
  771.     register u_long *bw;
  772.  
  773.     fromskew /= 8;
  774.     while (h-- > 0) {
  775.         UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
  776.         cp += toskew;
  777.         pp += fromskew;
  778.     }
  779. }
  780.  
  781. /*
  782.  * 8-bit greyscale => colormap/RGB
  783.  */
  784. DECLAREContigPutFunc(putgreytile)
  785. {
  786.     while (h-- > 0) {
  787.         register u_long x;
  788.         for (x = w; x-- > 0;)
  789.             *cp++ = BWmap[*pp++][0];
  790.         cp += toskew;
  791.         pp += fromskew;
  792.     }
  793. }
  794.  
  795. /*
  796.  * 1-bit bilevel => colormap/RGB
  797.  */
  798. DECLAREContigPutFunc(put1bitbwtile)
  799. {
  800.     register u_long *bw;
  801.  
  802.     fromskew /= 8;
  803.     while (h-- > 0) {
  804.         UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
  805.         cp += toskew;
  806.         pp += fromskew;
  807.     }
  808. }
  809.  
  810. /*
  811.  * 2-bit greyscale => colormap/RGB
  812.  */
  813. DECLAREContigPutFunc(put2bitbwtile)
  814. {
  815.     register u_long *bw;
  816.  
  817.     fromskew /= 4;
  818.     while (h-- > 0) {
  819.         UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
  820.         cp += toskew;
  821.         pp += fromskew;
  822.     }
  823. }
  824.  
  825. /*
  826.  * 4-bit greyscale => colormap/RGB
  827.  */
  828. DECLAREContigPutFunc(put4bitbwtile)
  829. {
  830.     register u_long *bw;
  831.  
  832.     fromskew /= 2;
  833.     while (h-- > 0) {
  834.         UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
  835.         cp += toskew;
  836.         pp += fromskew;
  837.     }
  838. }
  839.  
  840. /*
  841.  * 8-bit packed samples => RGB
  842.  */
  843. DECLAREContigPutFunc(putRGBcontig8bittile)
  844. {
  845.     fromskew *= samplesperpixel;
  846.     if (Map) {
  847.         while (h-- > 0) {
  848.             register u_long x;
  849.             for (x = w; x-- > 0;) {
  850.                 *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  851.                 pp += samplesperpixel;
  852.             }
  853.             pp += fromskew;
  854.             cp += toskew;
  855.         }
  856.     } else {
  857.         while (h-- > 0) {
  858.             UNROLL8(w, NULL,
  859.                 *cp++ = PACK(pp[0], pp[1], pp[2]);
  860.                 pp += samplesperpixel);
  861.             cp += toskew;
  862.             pp += fromskew;
  863.         }
  864.     }
  865. }
  866.  
  867. /*
  868.  * 16-bit packed samples => RGB
  869.  */
  870. DECLAREContigPutFunc(putRGBcontig16bittile)
  871. {
  872.     register u_short *wp = (u_short *)pp;
  873.     register u_int x;
  874.  
  875.     fromskew *= samplesperpixel;
  876.     if (Map) {
  877.         while (h-- > 0) {
  878.             for (x = w; x-- > 0;) {
  879.                 *cp++ = PACK(Map[wp[0]], Map[wp[1]], Map[wp[2]]);
  880.                 wp += samplesperpixel;
  881.             }
  882.             cp += toskew;
  883.             wp += fromskew;
  884.         }
  885.     } else {
  886.         while (h-- > 0) {
  887.             for (x = w; x-- > 0;) {
  888.                 *cp++ = PACK(wp[0], wp[1], wp[2]);
  889.                 wp += samplesperpixel;
  890.             }
  891.             cp += toskew;
  892.             wp += fromskew;
  893.         }
  894.     }
  895. }
  896.  
  897. /*
  898.  * 8-bit packed CMYK samples => RGB
  899.  *
  900.  * NB: The conversion of CMYK->RGB is *very* crude.
  901.  */
  902. DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
  903. {
  904.     u_short r, g, b, k;
  905.  
  906.     fromskew *= samplesperpixel;
  907.     if (Map) {
  908.         while (h-- > 0) {
  909.             register u_long x;
  910.             for (x = w; x-- > 0;) {
  911.                 k = 255 - pp[3];
  912.                 r = (k*(255-pp[0]))/255;
  913.                 g = (k*(255-pp[1]))/255;
  914.                 b = (k*(255-pp[2]))/255;
  915.                 *cp++ = PACK(Map[r], Map[g], Map[b]);
  916.                 pp += samplesperpixel;
  917.             }
  918.             pp += fromskew;
  919.             cp += toskew;
  920.         }
  921.     } else {
  922.         while (h-- > 0) {
  923.             UNROLL8(w, NULL,
  924.                 k = 255 - pp[3];
  925.                 r = (k*(255-pp[0]))/255;
  926.                 g = (k*(255-pp[1]))/255;
  927.                 b = (k*(255-pp[2]))/255;
  928.                 *cp++ = PACK(r, g, b);
  929.                 pp += samplesperpixel);
  930.             cp += toskew;
  931.             pp += fromskew;
  932.         }
  933.     }
  934. }
  935.  
  936. #define    DECLARESepPutFunc(name) \
  937. static void name(\
  938.     u_long* cp, \
  939.     u_char* r, u_char* g, u_char* b, \
  940.     RGBvalue* Map, \
  941.     u_long w, u_long h, \
  942.     int fromskew, int toskew \
  943. )
  944.  
  945. /*
  946.  * 8-bit unpacked samples => RGB
  947.  */
  948. DECLARESepPutFunc(putRGBseparate8bittile)
  949. {
  950.     if (Map) {
  951.         while (h-- > 0) {
  952.             register u_long x;
  953.             for (x = w; x > 0; x--)
  954.                 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
  955.             SKEW(r, g, b, fromskew);
  956.             cp += toskew;
  957.         }
  958.     } else {
  959.         while (h-- > 0) {
  960.             UNROLL8(w, NULL, *cp++ = PACK(*r++, *g++, *b++));
  961.             SKEW(r, g, b, fromskew);
  962.             cp += toskew;
  963.         }
  964.     }
  965. }
  966.  
  967. /*
  968.  * 16-bit unpacked samples => RGB
  969.  */
  970. DECLARESepPutFunc(putRGBseparate16bittile)
  971. {
  972.     register u_short *wr = (u_short *)r;
  973.     register u_short *wg = (u_short *)g;
  974.     register u_short *wb = (u_short *)b;
  975.     register u_long x;
  976.  
  977.     if (Map) {
  978.         while (h-- > 0) {
  979.             for (x = w; x > 0; x--)
  980.                 *cp++ = PACK(Map[*wr++],Map[*wg++],Map[*wb++]);
  981.             SKEW(wr, wg, wb, fromskew);
  982.             cp += toskew;
  983.         }
  984.     } else {
  985.         while (h-- > 0) {
  986.             for (x = 0; x < w; x++)
  987.                 *cp++ = PACK(*wr++, *wg++, *wb++);
  988.             SKEW(wr, wg, wb, fromskew);
  989.             cp += toskew;
  990.         }
  991.     }
  992. }
  993.  
  994. #define    Code2V(c, RB, RW, CR)    ((((c)-RB)*(float)CR)/(float)(RW-RB))
  995. #define    CLAMP(f,min,max) \
  996.     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
  997.  
  998. #define    LumaRed        YCbCrCoeffs[0]
  999. #define    LumaGreen    YCbCrCoeffs[1]
  1000. #define    LumaBlue    YCbCrCoeffs[2]
  1001.  
  1002. static    float D1, D2;
  1003. static    float D3, D4;
  1004.  
  1005. static void
  1006. initYCbCrConversion(void)
  1007. {
  1008.     D1 = 2 - 2*LumaRed;
  1009.     D2 = D1*LumaRed / LumaGreen;
  1010.     D3 = 2 - 2*LumaBlue;
  1011.     D4 = D3*LumaBlue / LumaGreen;
  1012. }
  1013.  
  1014. static void
  1015. putRGBContigYCbCrClump(
  1016.     register u_long* cp, register u_char* pp,
  1017.     int cw, int ch,
  1018.     u_long w,
  1019.     int n, int fromskew, int toskew
  1020. )
  1021. {
  1022.     float Cb, Cr;
  1023.     int j, k;
  1024.  
  1025.     Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
  1026.     Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
  1027.     for (j = 0; j < ch; j++) {
  1028.         for (k = 0; k < cw; k++) {
  1029.             float Y, R, G, B;
  1030.             Y = Code2V(*pp++,
  1031.                 refBlackWhite[0], refBlackWhite[1], 255);
  1032.             R = Y + Cr*D1;
  1033.             B = Y + Cb*D3;
  1034.             G = Y - Cb*D4 - Cr*D2;
  1035.             cp[k] = PACK(CLAMP(R,0,255),
  1036.                      CLAMP(G,0,255),
  1037.                      CLAMP(B,0,255));
  1038.         }
  1039.         cp += w+toskew;
  1040.         pp += fromskew;
  1041.     }
  1042. }
  1043. #undef LumaBlue
  1044. #undef LumaGreen
  1045. #undef LumaRed
  1046. #undef CLAMP
  1047. #undef Code2V
  1048.  
  1049. /*
  1050.  * 8-bit packed YCbCr samples => RGB
  1051.  */
  1052. DECLAREContigPutFunc(putcontig8bitYCbCrtile)
  1053. {
  1054.     u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
  1055.     u_long *tp;
  1056.     u_long x;
  1057.  
  1058.     /* XXX adjust fromskew */
  1059.     while (h >= YCbCrVertSampling) {
  1060.         tp = cp;
  1061.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1062.             putRGBContigYCbCrClump(tp, pp,
  1063.                 YCbCrHorizSampling, YCbCrVertSampling,
  1064.                 w, Coff, 0, toskew);
  1065.             tp += YCbCrHorizSampling;
  1066.             pp += Coff+2;
  1067.         }
  1068.         if (x > 0) {
  1069.             putRGBContigYCbCrClump(tp, pp,
  1070.                 x, YCbCrVertSampling,
  1071.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1072.             pp += Coff+2;
  1073.         }
  1074.         cp += YCbCrVertSampling*(w + toskew);
  1075.         pp += fromskew;
  1076.         h -= YCbCrVertSampling;
  1077.     }
  1078.     if (h > 0) {
  1079.         tp = cp;
  1080.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1081.             putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, h,
  1082.                 w, Coff, 0, toskew);
  1083.             tp += YCbCrHorizSampling;
  1084.             pp += Coff+2;
  1085.         }
  1086.         if (x > 0)
  1087.             putRGBContigYCbCrClump(tp, pp, x, h,
  1088.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1089.     }
  1090. }
  1091.  
  1092. /*
  1093.  * Select the appropriate conversion routine for packed data.
  1094.  */
  1095. static tileContigRoutine
  1096. pickTileContigCase(TIFF* tif, RGBvalue* Map)
  1097. {
  1098.     tileContigRoutine put = 0;
  1099.  
  1100.     switch (photometric) {
  1101.     case PHOTOMETRIC_RGB:
  1102.         if (bitspersample == 8)
  1103.             put = putRGBcontig8bittile;
  1104.         else
  1105.             put = putRGBcontig16bittile;
  1106.         break;
  1107.     case PHOTOMETRIC_SEPARATED:
  1108.         if (bitspersample == 8)
  1109.             put = putRGBcontig8bitCMYKtile;
  1110.         break;
  1111.     case PHOTOMETRIC_PALETTE:
  1112.         switch (bitspersample) {
  1113.         case 8:    put = put8bitcmaptile; break;
  1114.         case 4: put = put4bitcmaptile; break;
  1115.         case 2: put = put2bitcmaptile; break;
  1116.         case 1: put = put1bitcmaptile; break;
  1117.         }
  1118.         break;
  1119.     case PHOTOMETRIC_MINISWHITE:
  1120.     case PHOTOMETRIC_MINISBLACK:
  1121.         switch (bitspersample) {
  1122.         case 8:    put = putgreytile; break;
  1123.         case 4: put = put4bitbwtile; break;
  1124.         case 2: put = put2bitbwtile; break;
  1125.         case 1: put = put1bitbwtile; break;
  1126.         }
  1127.         break;
  1128.     case PHOTOMETRIC_YCBCR:
  1129.         switch (bitspersample) {
  1130.         case 8: put = putcontig8bitYCbCrtile; break;
  1131.         }
  1132.         break;
  1133.     }
  1134.     if (put == 0)
  1135.         TIFFError(TIFFFileName(tif), "Can not handle format");
  1136.     return (put);
  1137. }
  1138.  
  1139. /*
  1140.  * Select the appropriate conversion routine for unpacked data.
  1141.  *
  1142.  * NB: we assume that unpacked single channel data is directed
  1143.  *     to the "packed routines.
  1144.  */
  1145. static tileSeparateRoutine
  1146. pickTileSeparateCase(TIFF* tif, RGBvalue* Map)
  1147. {
  1148.     tileSeparateRoutine put = 0;
  1149.  
  1150.     switch (photometric) {
  1151.     case PHOTOMETRIC_RGB:
  1152.         if (bitspersample == 8)
  1153.             put = putRGBseparate8bittile;
  1154.         else
  1155.             put = putRGBseparate16bittile;
  1156.         break;
  1157.     }
  1158.     if (put == 0)
  1159.         TIFFError(TIFFFileName(tif), "Can not handle format");
  1160.     return (put);
  1161. }
  1162.