tif_getimage.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:68k
源码类别:

打印编程

开发平台:

Visual C++

  1. /* $Id: tif_getimage.c,v 1.49 2005/12/24 15:36:16 dron Exp $ */
  2. /*
  3.  * Copyright (c) 1991-1997 Sam Leffler
  4.  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. /*
  26.  * TIFF Library
  27.  *
  28.  * Read and return a packed RGBA image.
  29.  */
  30. #include "tiffiop.h"
  31. #include <stdio.h>
  32. static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
  33. static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
  34. static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
  35. static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
  36. static int pickTileContigCase(TIFFRGBAImage*);
  37. static int pickTileSeparateCase(TIFFRGBAImage*);
  38. static const char photoTag[] = "PhotometricInterpretation";
  39. /* 
  40.  * Helper constants used in Orientation tag handling
  41.  */
  42. #define FLIP_VERTICALLY 0x01
  43. #define FLIP_HORIZONTALLY 0x02
  44. /*
  45.  * Color conversion constants. We will define display types here.
  46.  */
  47. TIFFDisplay display_sRGB = {
  48. { /* XYZ -> luminance matrix */
  49. {  3.2410F, -1.5374F, -0.4986F },
  50. {  -0.9692F, 1.8760F, 0.0416F },
  51. {  0.0556F, -0.2040F, 1.0570F }
  52. },
  53. 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
  54. 255, 255, 255, /* Pixel values for ref. white */
  55. 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */
  56. 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */
  57. };
  58. /*
  59.  * Check the image to see if TIFFReadRGBAImage can deal with it.
  60.  * 1/0 is returned according to whether or not the image can
  61.  * be handled.  If 0 is returned, emsg contains the reason
  62.  * why it is being rejected.
  63.  */
  64. int
  65. TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
  66. {
  67.     TIFFDirectory* td = &tif->tif_dir;
  68.     uint16 photometric;
  69.     int colorchannels;
  70.     if (!tif->tif_decodestatus) {
  71. sprintf(emsg, "Sorry, requested compression method is not configured");
  72. return (0);
  73.     }
  74.     switch (td->td_bitspersample) {
  75.     case 1: case 2: case 4:
  76.     case 8: case 16:
  77. break;
  78.     default:
  79. sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
  80.     td->td_bitspersample);
  81. return (0);
  82.     }
  83.     colorchannels = td->td_samplesperpixel - td->td_extrasamples;
  84.     if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
  85. switch (colorchannels) {
  86. case 1:
  87.     photometric = PHOTOMETRIC_MINISBLACK;
  88.     break;
  89. case 3:
  90.     photometric = PHOTOMETRIC_RGB;
  91.     break;
  92. default:
  93.     sprintf(emsg, "Missing needed %s tag", photoTag);
  94.     return (0);
  95. }
  96.     }
  97.     switch (photometric) {
  98.     case PHOTOMETRIC_MINISWHITE:
  99.     case PHOTOMETRIC_MINISBLACK:
  100.     case PHOTOMETRIC_PALETTE:
  101. if (td->td_planarconfig == PLANARCONFIG_CONTIG 
  102.             && td->td_samplesperpixel != 1
  103.             && td->td_bitspersample < 8 ) {
  104.     sprintf(emsg,
  105.                     "Sorry, can not handle contiguous data with %s=%d, "
  106.                     "and %s=%d and Bits/Sample=%d",
  107.                     photoTag, photometric,
  108.                     "Samples/pixel", td->td_samplesperpixel,
  109.                     td->td_bitspersample);
  110.     return (0);
  111. }
  112.         /*
  113.         ** We should likely validate that any extra samples are either
  114.         ** to be ignored, or are alpha, and if alpha we should try to use
  115.         ** them.  But for now we won't bother with this. 
  116.         */
  117. break;
  118.     case PHOTOMETRIC_YCBCR:
  119. if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
  120.     sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
  121. "Planarconfiguration", td->td_planarconfig);
  122.     return (0);
  123. }
  124. break;
  125.     case PHOTOMETRIC_RGB: 
  126. if (colorchannels < 3) {
  127.     sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
  128. "Color channels", colorchannels);
  129.     return (0);
  130. }
  131. break;
  132.     case PHOTOMETRIC_SEPARATED:
  133. {
  134. uint16 inkset;
  135. TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
  136. if (inkset != INKSET_CMYK) {
  137.     sprintf(emsg,
  138.     "Sorry, can not handle separated image with %s=%d",
  139.     "InkSet", inkset);
  140.     return 0;
  141. }
  142. if (td->td_samplesperpixel < 4) {
  143.     sprintf(emsg,
  144.     "Sorry, can not handle separated image with %s=%d",
  145.     "Samples/pixel", td->td_samplesperpixel);
  146.     return 0;
  147. }
  148. break;
  149. }
  150.     case PHOTOMETRIC_LOGL:
  151. if (td->td_compression != COMPRESSION_SGILOG) {
  152.     sprintf(emsg, "Sorry, LogL data must have %s=%d",
  153. "Compression", COMPRESSION_SGILOG);
  154.     return (0);
  155. }
  156. break;
  157.     case PHOTOMETRIC_LOGLUV:
  158. if (td->td_compression != COMPRESSION_SGILOG &&
  159. td->td_compression != COMPRESSION_SGILOG24) {
  160.     sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
  161. "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
  162.     return (0);
  163. }
  164. if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
  165.     sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
  166. "Planarconfiguration", td->td_planarconfig);
  167.     return (0);
  168. }
  169. break;
  170.     case PHOTOMETRIC_CIELAB:
  171. break;
  172.     default:
  173. sprintf(emsg, "Sorry, can not handle image with %s=%d",
  174.     photoTag, photometric);
  175. return (0);
  176.     }
  177.     return (1);
  178. }
  179. void
  180. TIFFRGBAImageEnd(TIFFRGBAImage* img)
  181. {
  182. if (img->Map)
  183. _TIFFfree(img->Map), img->Map = NULL;
  184. if (img->BWmap)
  185. _TIFFfree(img->BWmap), img->BWmap = NULL;
  186. if (img->PALmap)
  187. _TIFFfree(img->PALmap), img->PALmap = NULL;
  188. if (img->ycbcr)
  189. _TIFFfree(img->ycbcr), img->ycbcr = NULL;
  190. if (img->cielab)
  191. _TIFFfree(img->cielab), img->cielab = NULL;
  192. if( img->redcmap ) {
  193. _TIFFfree( img->redcmap );
  194. _TIFFfree( img->greencmap );
  195. _TIFFfree( img->bluecmap );
  196. }
  197. }
  198. static int
  199. isCCITTCompression(TIFF* tif)
  200. {
  201.     uint16 compress;
  202.     TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
  203.     return (compress == COMPRESSION_CCITTFAX3 ||
  204.     compress == COMPRESSION_CCITTFAX4 ||
  205.     compress == COMPRESSION_CCITTRLE ||
  206.     compress == COMPRESSION_CCITTRLEW);
  207. }
  208. int
  209. TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
  210. {
  211.     uint16* sampleinfo;
  212.     uint16 extrasamples;
  213.     uint16 planarconfig;
  214.     uint16 compress;
  215.     int colorchannels;
  216.     uint16 *red_orig, *green_orig, *blue_orig;
  217.     int n_color;
  218.     /* Initialize to normal values */
  219.     img->row_offset = 0;
  220.     img->col_offset = 0;
  221.     img->redcmap = NULL;
  222.     img->greencmap = NULL;
  223.     img->bluecmap = NULL;
  224.     img->req_orientation = ORIENTATION_BOTLEFT;     /* It is the default */
  225.     
  226.     img->tif = tif;
  227.     img->stoponerr = stop;
  228.     TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
  229.     switch (img->bitspersample) {
  230.     case 1: case 2: case 4:
  231.     case 8: case 16:
  232. break;
  233.     default:
  234. sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
  235.     img->bitspersample);
  236. return (0);
  237.     }
  238.     img->alpha = 0;
  239.     TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
  240.     TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
  241. &extrasamples, &sampleinfo);
  242.     if (extrasamples >= 1)
  243.     {
  244. switch (sampleinfo[0]) {
  245. case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */
  246. if (img->samplesperpixel > 3) /* correct info about alpha channel */
  247. img->alpha = EXTRASAMPLE_ASSOCALPHA;
  248. break;
  249. case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
  250. case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
  251. img->alpha = sampleinfo[0];
  252. break;
  253. }
  254.     }
  255. #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
  256.     if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
  257.         img->photometric = PHOTOMETRIC_MINISWHITE;
  258.     if( extrasamples == 0 
  259.         && img->samplesperpixel == 4 
  260.         && img->photometric == PHOTOMETRIC_RGB )
  261.     {
  262.         img->alpha = EXTRASAMPLE_ASSOCALPHA;
  263.         extrasamples = 1;
  264.     }
  265. #endif
  266.     colorchannels = img->samplesperpixel - extrasamples;
  267.     TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
  268.     TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
  269.     if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
  270. switch (colorchannels) {
  271. case 1:
  272.     if (isCCITTCompression(tif))
  273. img->photometric = PHOTOMETRIC_MINISWHITE;
  274.     else
  275. img->photometric = PHOTOMETRIC_MINISBLACK;
  276.     break;
  277. case 3:
  278.     img->photometric = PHOTOMETRIC_RGB;
  279.     break;
  280. default:
  281.     sprintf(emsg, "Missing needed %s tag", photoTag);
  282.     return (0);
  283. }
  284.     }
  285.     switch (img->photometric) {
  286.     case PHOTOMETRIC_PALETTE:
  287. if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
  288.     &red_orig, &green_orig, &blue_orig)) {
  289.     sprintf(emsg, "Missing required "Colormap" tag");
  290.     return (0);
  291. }
  292.         /* copy the colormaps so we can modify them */
  293.         n_color = (1L << img->bitspersample);
  294.         img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
  295.         img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
  296.         img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
  297.         if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
  298.     sprintf(emsg, "Out of memory for colormap copy");
  299.     return (0);
  300.         }
  301.         _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
  302.         _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
  303.         _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
  304.         
  305. /* fall thru... */
  306.     case PHOTOMETRIC_MINISWHITE:
  307.     case PHOTOMETRIC_MINISBLACK:
  308. if (planarconfig == PLANARCONFIG_CONTIG 
  309.             && img->samplesperpixel != 1
  310.             && img->bitspersample < 8 ) {
  311.     sprintf(emsg,
  312.                     "Sorry, can not handle contiguous data with %s=%d, "
  313.                     "and %s=%d and Bits/Sample=%d",
  314.                     photoTag, img->photometric,
  315.                     "Samples/pixel", img->samplesperpixel,
  316.                     img->bitspersample);
  317.     return (0);
  318. }
  319. break;
  320.     case PHOTOMETRIC_YCBCR:
  321. if (planarconfig != PLANARCONFIG_CONTIG) {
  322.     sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
  323. "Planarconfiguration", planarconfig);
  324.     return (0);
  325. }
  326. /* It would probably be nice to have a reality check here. */
  327. if (planarconfig == PLANARCONFIG_CONTIG)
  328.     /* can rely on libjpeg to convert to RGB */
  329.     /* XXX should restore current state on exit */
  330.     switch (compress) {
  331. case COMPRESSION_OJPEG:
  332. case COMPRESSION_JPEG:
  333.     TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
  334.     img->photometric = PHOTOMETRIC_RGB;
  335.                     break;
  336.                 default:
  337.                     /* do nothing */;
  338.                     break;
  339.     }
  340. break;
  341.     case PHOTOMETRIC_RGB: 
  342. if (colorchannels < 3) {
  343.     sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
  344. "Color channels", colorchannels);
  345.     return (0);
  346. }
  347. break;
  348.     case PHOTOMETRIC_SEPARATED: {
  349. uint16 inkset;
  350. TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
  351. if (inkset != INKSET_CMYK) {
  352.     sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
  353. "InkSet", inkset);
  354.     return (0);
  355. }
  356. if (img->samplesperpixel < 4) {
  357.     sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
  358. "Samples/pixel", img->samplesperpixel);
  359.     return (0);
  360. }
  361. break;
  362.     }
  363.     case PHOTOMETRIC_LOGL:
  364. if (compress != COMPRESSION_SGILOG) {
  365.     sprintf(emsg, "Sorry, LogL data must have %s=%d",
  366. "Compression", COMPRESSION_SGILOG);
  367.     return (0);
  368. }
  369. TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
  370. img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
  371. img->bitspersample = 8;
  372. break;
  373.     case PHOTOMETRIC_LOGLUV:
  374. if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
  375.     sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
  376. "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
  377.     return (0);
  378. }
  379. if (planarconfig != PLANARCONFIG_CONTIG) {
  380.     sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
  381. "Planarconfiguration", planarconfig);
  382.     return (0);
  383. }
  384. TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
  385. img->photometric = PHOTOMETRIC_RGB; /* little white lie */
  386. img->bitspersample = 8;
  387. break;
  388.     case PHOTOMETRIC_CIELAB:
  389. break;
  390.     default:
  391. sprintf(emsg, "Sorry, can not handle image with %s=%d",
  392.     photoTag, img->photometric);
  393. return (0);
  394.     }
  395.     img->Map = NULL;
  396.     img->BWmap = NULL;
  397.     img->PALmap = NULL;
  398.     img->ycbcr = NULL;
  399.     img->cielab = NULL;
  400.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
  401.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
  402.     TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
  403.     img->isContig =
  404. !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
  405.     if (img->isContig) {
  406. img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig;
  407. if (!pickTileContigCase(img)) {
  408. sprintf(emsg, "Sorry, can not handle image");
  409. return 0;
  410. }
  411.     } else {
  412. img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate;
  413. if (!pickTileSeparateCase(img)) {
  414. sprintf(emsg, "Sorry, can not handle image");
  415. return 0;
  416. }
  417.     }
  418.     return 1;
  419. }
  420. int
  421. TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
  422. {
  423.     if (img->get == NULL) {
  424. TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No "get" routine setup");
  425. return (0);
  426. }
  427. if (img->put.any == NULL) {
  428. TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
  429. "No "put" routine setupl; probably can not handle image format");
  430. return (0);
  431.     }
  432.     return (*img->get)(img, raster, w, h);
  433. }
  434. /*
  435.  * Read the specified image into an ABGR-format rastertaking in account
  436.  * specified orientation.
  437.  */
  438. int
  439. TIFFReadRGBAImageOriented(TIFF* tif,
  440.   uint32 rwidth, uint32 rheight, uint32* raster,
  441.   int orientation, int stop)
  442. {
  443.     char emsg[1024] = "";
  444.     TIFFRGBAImage img;
  445.     int ok;
  446. if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
  447. img.req_orientation = orientation;
  448. /* XXX verify rwidth and rheight against width and height */
  449. ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
  450. rwidth, img.height);
  451. TIFFRGBAImageEnd(&img);
  452. } else {
  453. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), emsg);
  454. ok = 0;
  455.     }
  456.     return (ok);
  457. }
  458. /*
  459.  * Read the specified image into an ABGR-format raster. Use bottom left
  460.  * origin for raster by default.
  461.  */
  462. int
  463. TIFFReadRGBAImage(TIFF* tif,
  464.   uint32 rwidth, uint32 rheight, uint32* raster, int stop)
  465. {
  466. return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
  467.  ORIENTATION_BOTLEFT, stop);
  468. }
  469. static int 
  470. setorientation(TIFFRGBAImage* img)
  471. {
  472. switch (img->orientation) {
  473. case ORIENTATION_TOPLEFT:
  474. case ORIENTATION_LEFTTOP:
  475. if (img->req_orientation == ORIENTATION_TOPRIGHT ||
  476.     img->req_orientation == ORIENTATION_RIGHTTOP)
  477. return FLIP_HORIZONTALLY;
  478. else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
  479.     img->req_orientation == ORIENTATION_RIGHTBOT)
  480. return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
  481. else if (img->req_orientation == ORIENTATION_BOTLEFT ||
  482.     img->req_orientation == ORIENTATION_LEFTBOT)
  483. return FLIP_VERTICALLY;
  484. else
  485. return 0;
  486. case ORIENTATION_TOPRIGHT:
  487. case ORIENTATION_RIGHTTOP:
  488. if (img->req_orientation == ORIENTATION_TOPLEFT ||
  489.     img->req_orientation == ORIENTATION_LEFTTOP)
  490. return FLIP_HORIZONTALLY;
  491. else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
  492.     img->req_orientation == ORIENTATION_RIGHTBOT)
  493. return FLIP_VERTICALLY;
  494. else if (img->req_orientation == ORIENTATION_BOTLEFT ||
  495.     img->req_orientation == ORIENTATION_LEFTBOT)
  496. return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
  497. else
  498. return 0;
  499. case ORIENTATION_BOTRIGHT:
  500. case ORIENTATION_RIGHTBOT:
  501. if (img->req_orientation == ORIENTATION_TOPLEFT ||
  502.     img->req_orientation == ORIENTATION_LEFTTOP)
  503. return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
  504. else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
  505.     img->req_orientation == ORIENTATION_RIGHTTOP)
  506. return FLIP_VERTICALLY;
  507. else if (img->req_orientation == ORIENTATION_BOTLEFT ||
  508.     img->req_orientation == ORIENTATION_LEFTBOT)
  509. return FLIP_HORIZONTALLY;
  510. else
  511. return 0;
  512. case ORIENTATION_BOTLEFT:
  513. case ORIENTATION_LEFTBOT:
  514. if (img->req_orientation == ORIENTATION_TOPLEFT ||
  515.     img->req_orientation == ORIENTATION_LEFTTOP)
  516. return FLIP_VERTICALLY;
  517. else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
  518.     img->req_orientation == ORIENTATION_RIGHTTOP)
  519. return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
  520. else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
  521.     img->req_orientation == ORIENTATION_RIGHTBOT)
  522. return FLIP_HORIZONTALLY;
  523. else
  524. return 0;
  525. default: /* NOTREACHED */
  526. return 0;
  527. }
  528. }
  529. /*
  530.  * Get an tile-organized image that has
  531.  * PlanarConfiguration contiguous if SamplesPerPixel > 1
  532.  * or
  533.  * SamplesPerPixel == 1
  534.  */
  535. static int
  536. gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
  537. {
  538.     TIFF* tif = img->tif;
  539.     tileContigRoutine put = img->put.contig;
  540.     uint32 col, row, y, rowstoread;
  541.     uint32 pos;
  542.     uint32 tw, th;
  543.     unsigned char* buf;
  544.     int32 fromskew, toskew;
  545.     uint32 nrow;
  546.     int ret = 1, flip;
  547.     buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
  548.     if (buf == 0) {
  549. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
  550. return (0);
  551.     }
  552.     _TIFFmemset(buf, 0, TIFFTileSize(tif));
  553.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  554.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  555.     flip = setorientation(img);
  556.     if (flip & FLIP_VERTICALLY) {
  557.     y = h - 1;
  558.     toskew = -(int32)(tw + w);
  559.     }
  560.     else {
  561.     y = 0;
  562.     toskew = -(int32)(tw - w);
  563.     }
  564.      
  565.     for (row = 0; row < h; row += nrow)
  566.     {
  567.         rowstoread = th - (row + img->row_offset) % th;
  568.      nrow = (row + rowstoread > h ? h - row : rowstoread);
  569. for (col = 0; col < w; col += tw) 
  570.         {
  571.             if (TIFFReadTile(tif, buf, col+img->col_offset,
  572.                              row+img->row_offset, 0, 0) < 0 && img->stoponerr)
  573.             {
  574.                 ret = 0;
  575.                 break;
  576.             }
  577.     
  578.             pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
  579.          if (col + tw > w) 
  580.             {
  581.                 /*
  582.                  * Tile is clipped horizontally.  Calculate
  583.                  * visible portion and skewing factors.
  584.                  */
  585.                 uint32 npix = w - col;
  586.                 fromskew = tw - npix;
  587.                 (*put)(img, raster+y*w+col, col, y,
  588.                        npix, nrow, fromskew, toskew + fromskew, buf + pos);
  589.             }
  590.             else 
  591.             {
  592.                 (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
  593.             }
  594.         }
  595.         y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
  596.     }
  597.     _TIFFfree(buf);
  598.     if (flip & FLIP_HORIZONTALLY) {
  599.     uint32 line;
  600.     for (line = 0; line < h; line++) {
  601.     uint32 *left = raster + (line * w);
  602.     uint32 *right = left + w - 1;
  603.     
  604.     while ( left < right ) {
  605.     uint32 temp = *left;
  606.     *left = *right;
  607.     *right = temp;
  608.     left++, right--;
  609.     }
  610.     }
  611.     }
  612.     return (ret);
  613. }
  614. /*
  615.  * Get an tile-organized image that has
  616.  *  SamplesPerPixel > 1
  617.  *  PlanarConfiguration separated
  618.  * We assume that all such images are RGB.
  619.  */
  620. static int
  621. gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
  622. {
  623.     TIFF* tif = img->tif;
  624.     tileSeparateRoutine put = img->put.separate;
  625.     uint32 col, row, y, rowstoread;
  626.     uint32 pos;
  627.     uint32 tw, th;
  628.     unsigned char* buf;
  629.     unsigned char* r;
  630.     unsigned char* g;
  631.     unsigned char* b;
  632.     unsigned char* a;
  633.     tsize_t tilesize;
  634.     int32 fromskew, toskew;
  635.     int alpha = img->alpha;
  636.     uint32 nrow;
  637.     int ret = 1, flip;
  638.     tilesize = TIFFTileSize(tif);
  639.     buf = (unsigned char*) _TIFFmalloc(4*tilesize);
  640.     if (buf == 0) {
  641. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
  642. return (0);
  643.     }
  644.     _TIFFmemset(buf, 0, 4*tilesize);
  645.     r = buf;
  646.     g = r + tilesize;
  647.     b = g + tilesize;
  648.     a = b + tilesize;
  649.     if (!alpha)
  650. _TIFFmemset(a, 0xff, tilesize);
  651.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  652.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  653.     flip = setorientation(img);
  654.     if (flip & FLIP_VERTICALLY) {
  655.     y = h - 1;
  656.     toskew = -(int32)(tw + w);
  657.     }
  658.     else {
  659.     y = 0;
  660.     toskew = -(int32)(tw - w);
  661.     }
  662.     for (row = 0; row < h; row += nrow) 
  663.     {
  664.         rowstoread = th - (row + img->row_offset) % th;
  665.      nrow = (row + rowstoread > h ? h - row : rowstoread);
  666.         for (col = 0; col < w; col += tw) 
  667.         {
  668.             if (TIFFReadTile(tif, r, col+img->col_offset,
  669.                              row+img->row_offset,0,0) < 0 && img->stoponerr)
  670.             {
  671.                 ret = 0;
  672.                 break;
  673.             }
  674.             if (TIFFReadTile(tif, g, col+img->col_offset,
  675.                              row+img->row_offset,0,1) < 0 && img->stoponerr)
  676.             {
  677.                 ret = 0;
  678.                 break;
  679.             }
  680.             if (TIFFReadTile(tif, b, col+img->col_offset,
  681.                              row+img->row_offset,0,2) < 0 && img->stoponerr)
  682.             {
  683.                 ret = 0;
  684.                 break;
  685.             }
  686.             if (alpha && TIFFReadTile(tif,a,col+img->col_offset,
  687.                                       row+img->row_offset,0,3) < 0 && img->stoponerr)
  688.             {
  689.                 ret = 0;
  690.                 break;
  691.             }
  692.             pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
  693.             if (col + tw > w) 
  694.             {
  695.                 /*
  696.                  * Tile is clipped horizontally.  Calculate
  697.                  * visible portion and skewing factors.
  698.                  */
  699.                 uint32 npix = w - col;
  700.                 fromskew = tw - npix;
  701.                 (*put)(img, raster+y*w+col, col, y,
  702.                        npix, nrow, fromskew, toskew + fromskew, 
  703.                        r + pos, g + pos, b + pos, a + pos);
  704.             } else {
  705.                 (*put)(img, raster+y*w+col, col, y,
  706.                        tw, nrow, 0, toskew, r + pos, g + pos, b + pos, a + pos);
  707.             }
  708.         }
  709.         y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
  710.     }
  711.     if (flip & FLIP_HORIZONTALLY) {
  712.     uint32 line;
  713.     for (line = 0; line < h; line++) {
  714.     uint32 *left = raster + (line * w);
  715.     uint32 *right = left + w - 1;
  716.     
  717.     while ( left < right ) {
  718.     uint32 temp = *left;
  719.     *left = *right;
  720.     *right = temp;
  721.     left++, right--;
  722.     }
  723.     }
  724.     }
  725.     _TIFFfree(buf);
  726.     return (ret);
  727. }
  728. /*
  729.  * Get a strip-organized image that has
  730.  * PlanarConfiguration contiguous if SamplesPerPixel > 1
  731.  * or
  732.  * SamplesPerPixel == 1
  733.  */
  734. static int
  735. gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
  736. {
  737.     TIFF* tif = img->tif;
  738.     tileContigRoutine put = img->put.contig;
  739.     uint32 row, y, nrow, rowstoread;
  740.     uint32 pos;
  741.     unsigned char* buf;
  742.     uint32 rowsperstrip;
  743.     uint32 imagewidth = img->width;
  744.     tsize_t scanline;
  745.     int32 fromskew, toskew;
  746.     int ret = 1, flip;
  747.     buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
  748.     if (buf == 0) {
  749. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
  750. return (0);
  751.     }
  752.     _TIFFmemset(buf, 0, TIFFStripSize(tif));
  753.     flip = setorientation(img);
  754.     if (flip & FLIP_VERTICALLY) {
  755.     y = h - 1;
  756.     toskew = -(int32)(w + w);
  757.     } else {
  758.     y = 0;
  759.     toskew = -(int32)(w - w);
  760.     }
  761.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  762.     scanline = TIFFScanlineSize(tif);
  763.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  764.     for (row = 0; row < h; row += nrow) 
  765.     {
  766.         rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
  767.         nrow = (row + rowstoread > h ? h - row : rowstoread);
  768.         if (TIFFReadEncodedStrip(tif,
  769.                                  TIFFComputeStrip(tif,row+img->row_offset, 0),
  770.                                  buf, 
  771.                                  ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
  772.             && img->stoponerr)
  773.         {
  774.             ret = 0;
  775.             break;
  776.         }
  777.         pos = ((row + img->row_offset) % rowsperstrip) * scanline;
  778.         (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
  779.         y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
  780.     }
  781.     if (flip & FLIP_HORIZONTALLY) {
  782.     uint32 line;
  783.     for (line = 0; line < h; line++) {
  784.     uint32 *left = raster + (line * w);
  785.     uint32 *right = left + w - 1;
  786.     
  787.     while ( left < right ) {
  788.     uint32 temp = *left;
  789.     *left = *right;
  790.     *right = temp;
  791.     left++, right--;
  792.     }
  793.     }
  794.     }
  795.     _TIFFfree(buf);
  796.     return (ret);
  797. }
  798. /*
  799.  * Get a strip-organized image with
  800.  *  SamplesPerPixel > 1
  801.  *  PlanarConfiguration separated
  802.  * We assume that all such images are RGB.
  803.  */
  804. static int
  805. gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
  806. {
  807.     TIFF* tif = img->tif;
  808.     tileSeparateRoutine put = img->put.separate;
  809.     unsigned char *buf;
  810.     unsigned char *r, *g, *b, *a;
  811.     uint32 row, y, nrow, rowstoread;
  812.     uint32 pos;
  813.     tsize_t scanline;
  814.     uint32 rowsperstrip, offset_row;
  815.     uint32 imagewidth = img->width;
  816.     tsize_t stripsize;
  817.     int32 fromskew, toskew;
  818.     int alpha = img->alpha;
  819.     int ret = 1, flip;
  820.     stripsize = TIFFStripSize(tif);
  821.     r = buf = (unsigned char *)_TIFFmalloc(4*stripsize);
  822.     if (buf == 0) {
  823. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
  824. return (0);
  825.     }
  826.     _TIFFmemset(buf, 0, 4*stripsize);
  827.     g = r + stripsize;
  828.     b = g + stripsize;
  829.     a = b + stripsize;
  830.     if (!alpha)
  831. _TIFFmemset(a, 0xff, stripsize);
  832.     flip = setorientation(img);
  833.     if (flip & FLIP_VERTICALLY) {
  834.     y = h - 1;
  835.     toskew = -(int32)(w + w);
  836.     }
  837.     else {
  838.     y = 0;
  839.     toskew = -(int32)(w - w);
  840.     }
  841.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  842.     scanline = TIFFScanlineSize(tif);
  843.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  844.     for (row = 0; row < h; row += nrow) 
  845.     {
  846.         rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;    
  847.         nrow = (row + rowstoread > h ? h - row : rowstoread);
  848.         offset_row = row + img->row_offset;
  849.      if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
  850.                                  r, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 
  851.             && img->stoponerr)
  852.         {
  853.             ret = 0;
  854.             break;
  855.         }
  856.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
  857.                                  g, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 
  858.             && img->stoponerr)
  859.         {
  860.             ret = 0;
  861.             break;
  862.         }
  863.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
  864.                                  b, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 
  865.             && img->stoponerr)
  866.         {
  867.             ret = 0;
  868.             break;
  869.         }
  870.         if (alpha &&
  871.             (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3),
  872.                                   a, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0 
  873.              && img->stoponerr))
  874.         {
  875.             ret = 0;
  876.             break;
  877.         }
  878.         pos = ((row + img->row_offset) % rowsperstrip) * scanline;
  879.         (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, r + pos, g + pos, 
  880.                b + pos, a + pos);
  881.         y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
  882.     }
  883.     if (flip & FLIP_HORIZONTALLY) {
  884.     uint32 line;
  885.     for (line = 0; line < h; line++) {
  886.     uint32 *left = raster + (line * w);
  887.     uint32 *right = left + w - 1;
  888.     
  889.     while ( left < right ) {
  890.     uint32 temp = *left;
  891.     *left = *right;
  892.     *right = temp;
  893.     left++, right--;
  894.     }
  895.     }
  896.     }
  897.     _TIFFfree(buf);
  898.     return (ret);
  899. }
  900. /*
  901.  * The following routines move decoded data returned
  902.  * from the TIFF library into rasters filled with packed
  903.  * ABGR pixels (i.e. suitable for passing to lrecwrite.)
  904.  *
  905.  * The routines have been created according to the most
  906.  * important cases and optimized.  pickTileContigCase and
  907.  * pickTileSeparateCase analyze the parameters and select
  908.  * the appropriate "put" routine to use.
  909.  */
  910. #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
  911. #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
  912. #define REPEAT2(op) op; op
  913. #define CASE8(x,op)
  914.     switch (x) {
  915.     case 7: op; case 6: op; case 5: op;
  916.     case 4: op; case 3: op; case 2: op;
  917.     case 1: op;
  918.     }
  919. #define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
  920. #define NOP
  921. #define UNROLL8(w, op1, op2) {
  922.     uint32 _x;
  923.     for (_x = w; _x >= 8; _x -= 8) {
  924. op1;
  925. REPEAT8(op2);
  926.     }
  927.     if (_x > 0) {
  928. op1;
  929. CASE8(_x,op2);
  930.     }
  931. }
  932. #define UNROLL4(w, op1, op2) {
  933.     uint32 _x;
  934.     for (_x = w; _x >= 4; _x -= 4) {
  935. op1;
  936. REPEAT4(op2);
  937.     }
  938.     if (_x > 0) {
  939. op1;
  940. CASE4(_x,op2);
  941.     }
  942. }
  943. #define UNROLL2(w, op1, op2) {
  944.     uint32 _x;
  945.     for (_x = w; _x >= 2; _x -= 2) {
  946. op1;
  947. REPEAT2(op2);
  948.     }
  949.     if (_x) {
  950. op1;
  951. op2;
  952.     }
  953. }
  954.     
  955. #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
  956. #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
  957. #define A1 (((uint32)0xffL)<<24)
  958. #define PACK(r,g,b)
  959. ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
  960. #define PACK4(r,g,b,a)
  961. ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
  962. #define W2B(v) (((v)>>8)&0xff)
  963. #define PACKW(r,g,b)
  964. ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
  965. #define PACKW4(r,g,b,a)
  966. ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
  967. #define DECLAREContigPutFunc(name) 
  968. static void name(
  969.     TIFFRGBAImage* img, 
  970.     uint32* cp, 
  971.     uint32 x, uint32 y, 
  972.     uint32 w, uint32 h, 
  973.     int32 fromskew, int32 toskew, 
  974.     unsigned char* pp 
  975. )
  976. /*
  977.  * 8-bit palette => colormap/RGB
  978.  */
  979. DECLAREContigPutFunc(put8bitcmaptile)
  980. {
  981.     uint32** PALmap = img->PALmap;
  982.     int samplesperpixel = img->samplesperpixel;
  983.     (void) y;
  984.     while (h-- > 0) {
  985. for (x = w; x-- > 0;)
  986.         {
  987.     *cp++ = PALmap[*pp][0];
  988.             pp += samplesperpixel;
  989.         }
  990. cp += toskew;
  991. pp += fromskew;
  992.     }
  993. }
  994. /*
  995.  * 4-bit palette => colormap/RGB
  996.  */
  997. DECLAREContigPutFunc(put4bitcmaptile)
  998. {
  999.     uint32** PALmap = img->PALmap;
  1000.     (void) x; (void) y;
  1001.     fromskew /= 2;
  1002.     while (h-- > 0) {
  1003. uint32* bw;
  1004. UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
  1005. cp += toskew;
  1006. pp += fromskew;
  1007.     }
  1008. }
  1009. /*
  1010.  * 2-bit palette => colormap/RGB
  1011.  */
  1012. DECLAREContigPutFunc(put2bitcmaptile)
  1013. {
  1014.     uint32** PALmap = img->PALmap;
  1015.     (void) x; (void) y;
  1016.     fromskew /= 4;
  1017.     while (h-- > 0) {
  1018. uint32* bw;
  1019. UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
  1020. cp += toskew;
  1021. pp += fromskew;
  1022.     }
  1023. }
  1024. /*
  1025.  * 1-bit palette => colormap/RGB
  1026.  */
  1027. DECLAREContigPutFunc(put1bitcmaptile)
  1028. {
  1029.     uint32** PALmap = img->PALmap;
  1030.     (void) x; (void) y;
  1031.     fromskew /= 8;
  1032.     while (h-- > 0) {
  1033. uint32* bw;
  1034. UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
  1035. cp += toskew;
  1036. pp += fromskew;
  1037.     }
  1038. }
  1039. /*
  1040.  * 8-bit greyscale => colormap/RGB
  1041.  */
  1042. DECLAREContigPutFunc(putgreytile)
  1043. {
  1044.     int samplesperpixel = img->samplesperpixel;
  1045.     uint32** BWmap = img->BWmap;
  1046.     (void) y;
  1047.     while (h-- > 0) {
  1048. for (x = w; x-- > 0;)
  1049.         {
  1050.     *cp++ = BWmap[*pp][0];
  1051.             pp += samplesperpixel;
  1052.         }
  1053. cp += toskew;
  1054. pp += fromskew;
  1055.     }
  1056. }
  1057. /*
  1058.  * 16-bit greyscale => colormap/RGB
  1059.  */
  1060. DECLAREContigPutFunc(put16bitbwtile)
  1061. {
  1062.     int samplesperpixel = img->samplesperpixel;
  1063.     uint32** BWmap = img->BWmap;
  1064.     (void) y;
  1065.     while (h-- > 0) {
  1066.         uint16 *wp = (uint16 *) pp;
  1067. for (x = w; x-- > 0;)
  1068.         {
  1069.             /* use high order byte of 16bit value */
  1070.     *cp++ = BWmap[*wp >> 8][0];
  1071.             pp += 2 * samplesperpixel;
  1072.             wp += samplesperpixel;
  1073.         }
  1074. cp += toskew;
  1075. pp += fromskew;
  1076.     }
  1077. }
  1078. /*
  1079.  * 1-bit bilevel => colormap/RGB
  1080.  */
  1081. DECLAREContigPutFunc(put1bitbwtile)
  1082. {
  1083.     uint32** BWmap = img->BWmap;
  1084.     (void) x; (void) y;
  1085.     fromskew /= 8;
  1086.     while (h-- > 0) {
  1087. uint32* bw;
  1088. UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
  1089. cp += toskew;
  1090. pp += fromskew;
  1091.     }
  1092. }
  1093. /*
  1094.  * 2-bit greyscale => colormap/RGB
  1095.  */
  1096. DECLAREContigPutFunc(put2bitbwtile)
  1097. {
  1098.     uint32** BWmap = img->BWmap;
  1099.     (void) x; (void) y;
  1100.     fromskew /= 4;
  1101.     while (h-- > 0) {
  1102. uint32* bw;
  1103. UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
  1104. cp += toskew;
  1105. pp += fromskew;
  1106.     }
  1107. }
  1108. /*
  1109.  * 4-bit greyscale => colormap/RGB
  1110.  */
  1111. DECLAREContigPutFunc(put4bitbwtile)
  1112. {
  1113.     uint32** BWmap = img->BWmap;
  1114.     (void) x; (void) y;
  1115.     fromskew /= 2;
  1116.     while (h-- > 0) {
  1117. uint32* bw;
  1118. UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
  1119. cp += toskew;
  1120. pp += fromskew;
  1121.     }
  1122. }
  1123. /*
  1124.  * 8-bit packed samples, no Map => RGB
  1125.  */
  1126. DECLAREContigPutFunc(putRGBcontig8bittile)
  1127. {
  1128.     int samplesperpixel = img->samplesperpixel;
  1129.     (void) x; (void) y;
  1130.     fromskew *= samplesperpixel;
  1131.     while (h-- > 0) {
  1132. UNROLL8(w, NOP,
  1133.     *cp++ = PACK(pp[0], pp[1], pp[2]);
  1134.     pp += samplesperpixel);
  1135. cp += toskew;
  1136. pp += fromskew;
  1137.     }
  1138. }
  1139. /*
  1140.  * 8-bit packed samples, w/ Map => RGB
  1141.  */
  1142. DECLAREContigPutFunc(putRGBcontig8bitMaptile)
  1143. {
  1144.     TIFFRGBValue* Map = img->Map;
  1145.     int samplesperpixel = img->samplesperpixel;
  1146.     (void) y;
  1147.     fromskew *= samplesperpixel;
  1148.     while (h-- > 0) {
  1149. for (x = w; x-- > 0;) {
  1150.     *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  1151.     pp += samplesperpixel;
  1152. }
  1153. pp += fromskew;
  1154. cp += toskew;
  1155.     }
  1156. }
  1157. /*
  1158.  * 8-bit packed samples => RGBA w/ associated alpha
  1159.  * (known to have Map == NULL)
  1160.  */
  1161. DECLAREContigPutFunc(putRGBAAcontig8bittile)
  1162. {
  1163.     int samplesperpixel = img->samplesperpixel;
  1164.     (void) x; (void) y;
  1165.     fromskew *= samplesperpixel;
  1166.     while (h-- > 0) {
  1167. UNROLL8(w, NOP,
  1168.     *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
  1169.     pp += samplesperpixel);
  1170. cp += toskew;
  1171. pp += fromskew;
  1172.     }
  1173. }
  1174. /*
  1175.  * 8-bit packed samples => RGBA w/ unassociated alpha
  1176.  * (known to have Map == NULL)
  1177.  */
  1178. DECLAREContigPutFunc(putRGBUAcontig8bittile)
  1179. {
  1180.     int samplesperpixel = img->samplesperpixel;
  1181.     (void) y;
  1182.     fromskew *= samplesperpixel;
  1183.     while (h-- > 0) {
  1184. uint32 r, g, b, a;
  1185. for (x = w; x-- > 0;) {
  1186.     a = pp[3];
  1187.     r = (pp[0] * a) / 255;
  1188.     g = (pp[1] * a) / 255;
  1189.     b = (pp[2] * a) / 255;
  1190.     *cp++ = PACK4(r,g,b,a);
  1191.     pp += samplesperpixel;
  1192. }
  1193. cp += toskew;
  1194. pp += fromskew;
  1195.     }
  1196. }
  1197. /*
  1198.  * 16-bit packed samples => RGB
  1199.  */
  1200. DECLAREContigPutFunc(putRGBcontig16bittile)
  1201. {
  1202.     int samplesperpixel = img->samplesperpixel;
  1203.     uint16 *wp = (uint16 *)pp;
  1204.     (void) y;
  1205.     fromskew *= samplesperpixel;
  1206.     while (h-- > 0) {
  1207. for (x = w; x-- > 0;) {
  1208.     *cp++ = PACKW(wp[0], wp[1], wp[2]);
  1209.     wp += samplesperpixel;
  1210. }
  1211. cp += toskew;
  1212. wp += fromskew;
  1213.     }
  1214. }
  1215. /*
  1216.  * 16-bit packed samples => RGBA w/ associated alpha
  1217.  * (known to have Map == NULL)
  1218.  */
  1219. DECLAREContigPutFunc(putRGBAAcontig16bittile)
  1220. {
  1221.     int samplesperpixel = img->samplesperpixel;
  1222.     uint16 *wp = (uint16 *)pp;
  1223.     (void) y;
  1224.     fromskew *= samplesperpixel;
  1225.     while (h-- > 0) {
  1226. for (x = w; x-- > 0;) {
  1227.     *cp++ = PACKW4(wp[0], wp[1], wp[2], wp[3]);
  1228.     wp += samplesperpixel;
  1229. }
  1230. cp += toskew;
  1231. wp += fromskew;
  1232.     }
  1233. }
  1234. /*
  1235.  * 16-bit packed samples => RGBA w/ unassociated alpha
  1236.  * (known to have Map == NULL)
  1237.  */
  1238. DECLAREContigPutFunc(putRGBUAcontig16bittile)
  1239. {
  1240.     int samplesperpixel = img->samplesperpixel;
  1241.     uint16 *wp = (uint16 *)pp;
  1242.     (void) y;
  1243.     fromskew *= samplesperpixel;
  1244.     while (h-- > 0) {
  1245. uint32 r,g,b,a;
  1246. /*
  1247.  * We shift alpha down four bits just in case unsigned
  1248.  * arithmetic doesn't handle the full range.
  1249.  * We still have plenty of accuracy, since the output is 8 bits.
  1250.  * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
  1251.  * Since we want r*a * 0xff for eight bit output,
  1252.  * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
  1253.  */
  1254. for (x = w; x-- > 0;) {
  1255.     a = wp[3] >> 4; 
  1256.     r = (wp[0] * a) / 0x10eff;
  1257.     g = (wp[1] * a) / 0x10eff;
  1258.     b = (wp[2] * a) / 0x10eff;
  1259.     *cp++ = PACK4(r,g,b,a);
  1260.     wp += samplesperpixel;
  1261. }
  1262. cp += toskew;
  1263. wp += fromskew;
  1264.     }
  1265. }
  1266. /*
  1267.  * 8-bit packed CMYK samples w/o Map => RGB
  1268.  *
  1269.  * NB: The conversion of CMYK->RGB is *very* crude.
  1270.  */
  1271. DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
  1272. {
  1273.     int samplesperpixel = img->samplesperpixel;
  1274.     uint16 r, g, b, k;
  1275.     (void) x; (void) y;
  1276.     fromskew *= samplesperpixel;
  1277.     while (h-- > 0) {
  1278. UNROLL8(w, NOP,
  1279.     k = 255 - pp[3];
  1280.     r = (k*(255-pp[0]))/255;
  1281.     g = (k*(255-pp[1]))/255;
  1282.     b = (k*(255-pp[2]))/255;
  1283.     *cp++ = PACK(r, g, b);
  1284.     pp += samplesperpixel);
  1285. cp += toskew;
  1286. pp += fromskew;
  1287.     }
  1288. }
  1289. /*
  1290.  * 8-bit packed CMYK samples w/Map => RGB
  1291.  *
  1292.  * NB: The conversion of CMYK->RGB is *very* crude.
  1293.  */
  1294. DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
  1295. {
  1296.     int samplesperpixel = img->samplesperpixel;
  1297.     TIFFRGBValue* Map = img->Map;
  1298.     uint16 r, g, b, k;
  1299.     (void) y;
  1300.     fromskew *= samplesperpixel;
  1301.     while (h-- > 0) {
  1302. for (x = w; x-- > 0;) {
  1303.     k = 255 - pp[3];
  1304.     r = (k*(255-pp[0]))/255;
  1305.     g = (k*(255-pp[1]))/255;
  1306.     b = (k*(255-pp[2]))/255;
  1307.     *cp++ = PACK(Map[r], Map[g], Map[b]);
  1308.     pp += samplesperpixel;
  1309. }
  1310. pp += fromskew;
  1311. cp += toskew;
  1312.     }
  1313. }
  1314. #define DECLARESepPutFunc(name) 
  1315. static void name(
  1316.     TIFFRGBAImage* img,
  1317.     uint32* cp,
  1318.     uint32 x, uint32 y, 
  1319.     uint32 w, uint32 h,
  1320.     int32 fromskew, int32 toskew,
  1321.     unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a
  1322. )
  1323. /*
  1324.  * 8-bit unpacked samples => RGB
  1325.  */
  1326. DECLARESepPutFunc(putRGBseparate8bittile)
  1327. {
  1328.     (void) img; (void) x; (void) y; (void) a;
  1329.     while (h-- > 0) {
  1330. UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
  1331. SKEW(r, g, b, fromskew);
  1332. cp += toskew;
  1333.     }
  1334. }
  1335. /*
  1336.  * 8-bit unpacked samples => RGB
  1337.  */
  1338. DECLARESepPutFunc(putRGBseparate8bitMaptile)
  1339. {
  1340.     TIFFRGBValue* Map = img->Map;
  1341.     (void) y; (void) a;
  1342.     while (h-- > 0) {
  1343. for (x = w; x > 0; x--)
  1344.     *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
  1345. SKEW(r, g, b, fromskew);
  1346. cp += toskew;
  1347.     }
  1348. }
  1349. /*
  1350.  * 8-bit unpacked samples => RGBA w/ associated alpha
  1351.  */
  1352. DECLARESepPutFunc(putRGBAAseparate8bittile)
  1353. {
  1354.     (void) img; (void) x; (void) y;
  1355.     while (h-- > 0) {
  1356. UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
  1357. SKEW4(r, g, b, a, fromskew);
  1358. cp += toskew;
  1359.     }
  1360. }
  1361. /*
  1362.  * 8-bit unpacked samples => RGBA w/ unassociated alpha
  1363.  */
  1364. DECLARESepPutFunc(putRGBUAseparate8bittile)
  1365. {
  1366.     (void) img; (void) y;
  1367.     while (h-- > 0) {
  1368. uint32 rv, gv, bv, av;
  1369. for (x = w; x-- > 0;) {
  1370.     av = *a++;
  1371.     rv = (*r++ * av) / 255;
  1372.     gv = (*g++ * av) / 255;
  1373.     bv = (*b++ * av) / 255;
  1374.     *cp++ = PACK4(rv,gv,bv,av);
  1375. }
  1376. SKEW4(r, g, b, a, fromskew);
  1377. cp += toskew;
  1378.     }
  1379. }
  1380. /*
  1381.  * 16-bit unpacked samples => RGB
  1382.  */
  1383. DECLARESepPutFunc(putRGBseparate16bittile)
  1384. {
  1385.     uint16 *wr = (uint16*) r;
  1386.     uint16 *wg = (uint16*) g;
  1387.     uint16 *wb = (uint16*) b;
  1388.     (void) img; (void) y; (void) a;
  1389.     while (h-- > 0) {
  1390. for (x = 0; x < w; x++)
  1391.     *cp++ = PACKW(*wr++, *wg++, *wb++);
  1392. SKEW(wr, wg, wb, fromskew);
  1393. cp += toskew;
  1394.     }
  1395. }
  1396. /*
  1397.  * 16-bit unpacked samples => RGBA w/ associated alpha
  1398.  */
  1399. DECLARESepPutFunc(putRGBAAseparate16bittile)
  1400. {
  1401.     uint16 *wr = (uint16*) r;
  1402.     uint16 *wg = (uint16*) g;
  1403.     uint16 *wb = (uint16*) b;
  1404.     uint16 *wa = (uint16*) a;
  1405.     (void) img; (void) y;
  1406.     while (h-- > 0) {
  1407. for (x = 0; x < w; x++)
  1408.     *cp++ = PACKW4(*wr++, *wg++, *wb++, *wa++);
  1409. SKEW4(wr, wg, wb, wa, fromskew);
  1410. cp += toskew;
  1411.     }
  1412. }
  1413. /*
  1414.  * 16-bit unpacked samples => RGBA w/ unassociated alpha
  1415.  */
  1416. DECLARESepPutFunc(putRGBUAseparate16bittile)
  1417. {
  1418.     uint16 *wr = (uint16*) r;
  1419.     uint16 *wg = (uint16*) g;
  1420.     uint16 *wb = (uint16*) b;
  1421.     uint16 *wa = (uint16*) a;
  1422.     (void) img; (void) y;
  1423.     while (h-- > 0) {
  1424. uint32 r,g,b,a;
  1425. /*
  1426.  * We shift alpha down four bits just in case unsigned
  1427.  * arithmetic doesn't handle the full range.
  1428.  * We still have plenty of accuracy, since the output is 8 bits.
  1429.  * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
  1430.  * Since we want r*a * 0xff for eight bit output,
  1431.  * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
  1432.  */
  1433. for (x = w; x-- > 0;) {
  1434.     a = *wa++ >> 4; 
  1435.     r = (*wr++ * a) / 0x10eff;
  1436.     g = (*wg++ * a) / 0x10eff;
  1437.     b = (*wb++ * a) / 0x10eff;
  1438.     *cp++ = PACK4(r,g,b,a);
  1439. }
  1440. SKEW4(wr, wg, wb, wa, fromskew);
  1441. cp += toskew;
  1442.     }
  1443. }
  1444. /*
  1445.  * 8-bit packed CIE L*a*b 1976 samples => RGB
  1446.  */
  1447. DECLAREContigPutFunc(putcontig8bitCIELab)
  1448. {
  1449. float X, Y, Z;
  1450. uint32 r, g, b;
  1451. (void) y;
  1452. fromskew *= 3;
  1453. while (h-- > 0) {
  1454. for (x = w; x-- > 0;) {
  1455. TIFFCIELabToXYZ(img->cielab,
  1456. (unsigned char)pp[0],
  1457. (signed char)pp[1],
  1458. (signed char)pp[2],
  1459. &X, &Y, &Z);
  1460. TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
  1461. *cp++ = PACK(r, g, b);
  1462. pp += 3;
  1463. }
  1464. cp += toskew;
  1465. pp += fromskew;
  1466. }
  1467. }
  1468. /*
  1469.  * YCbCr -> RGB conversion and packing routines.
  1470.  */
  1471. #define YCbCrtoRGB(dst, Y) {
  1472. uint32 r, g, b;
  1473. TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b);
  1474. dst = PACK(r, g, b);
  1475. }
  1476. /*
  1477.  * 8-bit packed YCbCr samples => RGB 
  1478.  * This function is generic for different sampling sizes, 
  1479.  * and can handle blocks sizes that aren't multiples of the
  1480.  * sampling size.  However, it is substantially less optimized
  1481.  * than the specific sampling cases.  It is used as a fallback
  1482.  * for difficult blocks.
  1483.  */
  1484. #ifdef notdef
  1485. static void putcontig8bitYCbCrGenericTile( 
  1486.     TIFFRGBAImage* img, 
  1487.     uint32* cp, 
  1488.     uint32 x, uint32 y, 
  1489.     uint32 w, uint32 h, 
  1490.     int32 fromskew, int32 toskew, 
  1491.     unsigned char* pp,
  1492.     int h_group, 
  1493.     int v_group )
  1494. {
  1495.     uint32* cp1 = cp+w+toskew;
  1496.     uint32* cp2 = cp1+w+toskew;
  1497.     uint32* cp3 = cp2+w+toskew;
  1498.     int32 incr = 3*w+4*toskew;
  1499.     int32   Cb, Cr;
  1500.     int     group_size = v_group * h_group + 2;
  1501.     (void) y;
  1502.     fromskew = (fromskew * group_size) / h_group;
  1503.     for( yy = 0; yy < h; yy++ )
  1504.     {
  1505.         unsigned char *pp_line;
  1506.         int     y_line_group = yy / v_group;
  1507.         int     y_remainder = yy - y_line_group * v_group;
  1508.         pp_line = pp + v_line_group * 
  1509.         
  1510.         for( xx = 0; xx < w; xx++ )
  1511.         {
  1512.             Cb = pp
  1513.         }
  1514.     }
  1515.     for (; h >= 4; h -= 4) {
  1516. x = w>>2;
  1517. do {
  1518.     Cb = pp[16];
  1519.     Cr = pp[17];
  1520.     YCbCrtoRGB(cp [0], pp[ 0]);
  1521.     YCbCrtoRGB(cp [1], pp[ 1]);
  1522.     YCbCrtoRGB(cp [2], pp[ 2]);
  1523.     YCbCrtoRGB(cp [3], pp[ 3]);
  1524.     YCbCrtoRGB(cp1[0], pp[ 4]);
  1525.     YCbCrtoRGB(cp1[1], pp[ 5]);
  1526.     YCbCrtoRGB(cp1[2], pp[ 6]);
  1527.     YCbCrtoRGB(cp1[3], pp[ 7]);
  1528.     YCbCrtoRGB(cp2[0], pp[ 8]);
  1529.     YCbCrtoRGB(cp2[1], pp[ 9]);
  1530.     YCbCrtoRGB(cp2[2], pp[10]);
  1531.     YCbCrtoRGB(cp2[3], pp[11]);
  1532.     YCbCrtoRGB(cp3[0], pp[12]);
  1533.     YCbCrtoRGB(cp3[1], pp[13]);
  1534.     YCbCrtoRGB(cp3[2], pp[14]);
  1535.     YCbCrtoRGB(cp3[3], pp[15]);
  1536.     cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
  1537.     pp += 18;
  1538. } while (--x);
  1539. cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
  1540. pp += fromskew;
  1541.     }
  1542. }
  1543. #endif
  1544. /*
  1545.  * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
  1546.  */
  1547. DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
  1548. {
  1549.     uint32* cp1 = cp+w+toskew;
  1550.     uint32* cp2 = cp1+w+toskew;
  1551.     uint32* cp3 = cp2+w+toskew;
  1552.     int32 incr = 3*w+4*toskew;
  1553.     (void) y;
  1554.     /* adjust fromskew */
  1555.     fromskew = (fromskew * 18) / 4;
  1556.     if ((h & 3) == 0 && (w & 3) == 0) {         
  1557.         for (; h >= 4; h -= 4) {
  1558.             x = w>>2;
  1559.             do {
  1560.                 int32 Cb = pp[16];
  1561.                 int32 Cr = pp[17];
  1562.                 YCbCrtoRGB(cp [0], pp[ 0]);
  1563.                 YCbCrtoRGB(cp [1], pp[ 1]);
  1564.                 YCbCrtoRGB(cp [2], pp[ 2]);
  1565.                 YCbCrtoRGB(cp [3], pp[ 3]);
  1566.                 YCbCrtoRGB(cp1[0], pp[ 4]);
  1567.                 YCbCrtoRGB(cp1[1], pp[ 5]);
  1568.                 YCbCrtoRGB(cp1[2], pp[ 6]);
  1569.                 YCbCrtoRGB(cp1[3], pp[ 7]);
  1570.                 YCbCrtoRGB(cp2[0], pp[ 8]);
  1571.                 YCbCrtoRGB(cp2[1], pp[ 9]);
  1572.                 YCbCrtoRGB(cp2[2], pp[10]);
  1573.                 YCbCrtoRGB(cp2[3], pp[11]);
  1574.                 YCbCrtoRGB(cp3[0], pp[12]);
  1575.                 YCbCrtoRGB(cp3[1], pp[13]);
  1576.                 YCbCrtoRGB(cp3[2], pp[14]);
  1577.                 YCbCrtoRGB(cp3[3], pp[15]);
  1578.                 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
  1579.                 pp += 18;
  1580.             } while (--x);
  1581.             cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
  1582.             pp += fromskew;
  1583.         }
  1584.     } else {
  1585.         while (h > 0) {
  1586.             for (x = w; x > 0;) {
  1587.                 int32 Cb = pp[16];
  1588.                 int32 Cr = pp[17];
  1589.                 switch (x) {
  1590.                 default:
  1591.                     switch (h) {
  1592.                     default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
  1593.                     case 3:  YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
  1594.                     case 2:  YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
  1595.                     case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
  1596.                     }                                    /* FALLTHROUGH */
  1597.                 case 3:
  1598.                     switch (h) {
  1599.                     default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
  1600.                     case 3:  YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
  1601.                     case 2:  YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
  1602.                     case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
  1603.                     }                                    /* FALLTHROUGH */
  1604.                 case 2:
  1605.                     switch (h) {
  1606.                     default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
  1607.                     case 3:  YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
  1608.                     case 2:  YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
  1609.                     case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
  1610.                     }                                    /* FALLTHROUGH */
  1611.                 case 1:
  1612.                     switch (h) {
  1613.                     default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
  1614.                     case 3:  YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
  1615.                     case 2:  YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
  1616.                     case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
  1617.                     }                                    /* FALLTHROUGH */
  1618.                 }
  1619.                 if (x < 4) {
  1620.                     cp += x; cp1 += x; cp2 += x; cp3 += x;
  1621.                     x = 0;
  1622.                 }
  1623.                 else {
  1624.                     cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
  1625.                     x -= 4;
  1626.                 }
  1627.                 pp += 18;
  1628.             }
  1629.             if (h <= 4)
  1630.                 break;
  1631.             h -= 4;
  1632.             cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
  1633.             pp += fromskew;
  1634.         }
  1635.     }
  1636. }
  1637. /*
  1638.  * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
  1639.  */
  1640. DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
  1641. {
  1642.     uint32* cp1 = cp+w+toskew;
  1643.     int32 incr = 2*toskew+w;
  1644.     (void) y;
  1645.     fromskew = (fromskew * 10) / 4;
  1646.     if ((h & 3) == 0 && (w & 1) == 0) {
  1647.         for (; h >= 2; h -= 2) {
  1648.             x = w>>2;
  1649.             do {
  1650.                 int32 Cb = pp[8];
  1651.                 int32 Cr = pp[9];
  1652.                 
  1653.                 YCbCrtoRGB(cp [0], pp[0]);
  1654.                 YCbCrtoRGB(cp [1], pp[1]);
  1655.                 YCbCrtoRGB(cp [2], pp[2]);
  1656.                 YCbCrtoRGB(cp [3], pp[3]);
  1657.                 YCbCrtoRGB(cp1[0], pp[4]);
  1658.                 YCbCrtoRGB(cp1[1], pp[5]);
  1659.                 YCbCrtoRGB(cp1[2], pp[6]);
  1660.                 YCbCrtoRGB(cp1[3], pp[7]);
  1661.                 
  1662.                 cp += 4, cp1 += 4;
  1663.                 pp += 10;
  1664.             } while (--x);
  1665.             cp += incr, cp1 += incr;
  1666.             pp += fromskew;
  1667.         }
  1668.     } else {
  1669.         while (h > 0) {
  1670.             for (x = w; x > 0;) {
  1671.                 int32 Cb = pp[8];
  1672.                 int32 Cr = pp[9];
  1673.                 switch (x) {
  1674.                 default:
  1675.                     switch (h) {
  1676.                     default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
  1677.                     case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
  1678.                     }                                    /* FALLTHROUGH */
  1679.                 case 3:
  1680.                     switch (h) {
  1681.                     default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
  1682.                     case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
  1683.                     }                                    /* FALLTHROUGH */
  1684.                 case 2:
  1685.                     switch (h) {
  1686.                     default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
  1687.                     case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
  1688.                     }                                    /* FALLTHROUGH */
  1689.                 case 1:
  1690.                     switch (h) {
  1691.                     default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
  1692.                     case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
  1693.                     }                                    /* FALLTHROUGH */
  1694.                 }
  1695.                 if (x < 4) {
  1696.                     cp += x; cp1 += x;
  1697.                     x = 0;
  1698.                 }
  1699.                 else {
  1700.                     cp += 4; cp1 += 4;
  1701.                     x -= 4;
  1702.                 }
  1703.                 pp += 10;
  1704.             }
  1705.             if (h <= 2)
  1706.                 break;
  1707.             h -= 2;
  1708.             cp += incr, cp1 += incr;
  1709.             pp += fromskew;
  1710.         }
  1711.     }
  1712. }
  1713. /*
  1714.  * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
  1715.  */
  1716. DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
  1717. {
  1718.     (void) y;
  1719.     /* XXX adjust fromskew */
  1720.     do {
  1721. x = w>>2;
  1722. do {
  1723.     int32 Cb = pp[4];
  1724.     int32 Cr = pp[5];
  1725.     YCbCrtoRGB(cp [0], pp[0]);
  1726.     YCbCrtoRGB(cp [1], pp[1]);
  1727.     YCbCrtoRGB(cp [2], pp[2]);
  1728.     YCbCrtoRGB(cp [3], pp[3]);
  1729.     cp += 4;
  1730.     pp += 6;
  1731. } while (--x);
  1732.         if( (w&3) != 0 )
  1733.         {
  1734.     int32 Cb = pp[4];
  1735.     int32 Cr = pp[5];
  1736.             switch( (w&3) ) {
  1737.               case 3: YCbCrtoRGB(cp [2], pp[2]);
  1738.               case 2: YCbCrtoRGB(cp [1], pp[1]);
  1739.               case 1: YCbCrtoRGB(cp [0], pp[0]);
  1740.               case 0: break;
  1741.             }
  1742.             cp += (w&3);
  1743.             pp += 6;
  1744.         }
  1745. cp += toskew;
  1746. pp += fromskew;
  1747.     } while (--h);
  1748. }
  1749. /*
  1750.  * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
  1751.  */
  1752. DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
  1753. {
  1754.     uint32* cp1 = cp+w+toskew;
  1755.     int32 incr = 2*toskew+w;
  1756.     (void) y;
  1757.     fromskew = (fromskew * 6) / 2;
  1758.     if ((h & 1) == 0 && (w & 1) == 0) {
  1759.         for (; h >= 2; h -= 2) {
  1760.             x = w>>1;
  1761.             do {
  1762.                 int32 Cb = pp[4];
  1763.                 int32 Cr = pp[5];
  1764.                 YCbCrtoRGB(cp [0], pp[0]);
  1765.                 YCbCrtoRGB(cp [1], pp[1]);
  1766.                 YCbCrtoRGB(cp1[0], pp[2]);
  1767.                 YCbCrtoRGB(cp1[1], pp[3]);
  1768.                 cp += 2, cp1 += 2;
  1769.                 pp += 6;
  1770.             } while (--x);
  1771.             cp += incr, cp1 += incr;
  1772.             pp += fromskew;
  1773.         }
  1774.     } else {
  1775.         while (h > 0) {
  1776.             for (x = w; x > 0;) {
  1777.                 int32 Cb = pp[4];
  1778.                 int32 Cr = pp[5];
  1779.                 switch (x) {
  1780.                 default:
  1781.                     switch (h) {
  1782.                     default: YCbCrtoRGB(cp1[1], pp[ 3]); /* FALLTHROUGH */
  1783.                     case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
  1784.                     }                                    /* FALLTHROUGH */
  1785.                 case 1:
  1786.                     switch (h) {
  1787.                     default: YCbCrtoRGB(cp1[0], pp[ 2]); /* FALLTHROUGH */
  1788.                     case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
  1789.                     }                                    /* FALLTHROUGH */
  1790.                 }
  1791.                 if (x < 2) {
  1792.                     cp += x; cp1 += x;
  1793.                     x = 0;
  1794.                 }
  1795.                 else {
  1796.                     cp += 2; cp1 += 2;
  1797.                     x -= 2;
  1798.                 }
  1799.                 pp += 6;
  1800.             }
  1801.             if (h <= 2)
  1802.                 break;
  1803.             h -= 2;
  1804.             cp += incr, cp1 += incr;
  1805.             pp += fromskew;
  1806.         }
  1807.     }
  1808. }
  1809. /*
  1810.  * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
  1811.  */
  1812. DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
  1813. {
  1814.     (void) y;
  1815.     fromskew = (fromskew * 4) / 2;
  1816.     do {
  1817. x = w>>1;
  1818. do {
  1819.     int32 Cb = pp[2];
  1820.     int32 Cr = pp[3];
  1821.     YCbCrtoRGB(cp[0], pp[0]); 
  1822.     YCbCrtoRGB(cp[1], pp[1]);
  1823.     cp += 2;
  1824.     pp += 4;
  1825. } while (--x);
  1826.         if( (w&1) != 0 )
  1827.         {
  1828.     int32 Cb = pp[2];
  1829.     int32 Cr = pp[3];
  1830.             
  1831.             YCbCrtoRGB(cp [0], pp[0]);
  1832.     cp += 1;
  1833.     pp += 4;
  1834.         }
  1835. cp += toskew;
  1836. pp += fromskew;
  1837.     } while (--h);
  1838. }
  1839. /*
  1840.  * 8-bit packed YCbCr samples w/ no subsampling => RGB
  1841.  */
  1842. DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
  1843. {
  1844.     (void) y;
  1845.     fromskew *= 3;
  1846.     do {
  1847.         x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */ 
  1848. do {
  1849.     int32 Cb = pp[1];
  1850.     int32 Cr = pp[2];
  1851.     YCbCrtoRGB(*cp++, pp[0]);
  1852.     pp += 3;
  1853. } while (--x);
  1854. cp += toskew;
  1855. pp += fromskew;
  1856.     } while (--h);
  1857. }
  1858. #undef YCbCrtoRGB
  1859. static tileContigRoutine
  1860. initYCbCrConversion(TIFFRGBAImage* img)
  1861. {
  1862. static char module[] = "initCIELabConversion";
  1863. float *luma, *refBlackWhite;
  1864. uint16 hs, vs;
  1865. if (img->ycbcr == NULL) {
  1866.     img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
  1867.     TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
  1868.     + 4*256*sizeof (TIFFRGBValue)
  1869.     + 2*256*sizeof (int)
  1870.     + 3*256*sizeof (int32)
  1871.     );
  1872.     if (img->ycbcr == NULL) {
  1873. TIFFErrorExt(img->tif->tif_clientdata, module,
  1874.       "No space for YCbCr->RGB conversion state");
  1875.     return (NULL);
  1876.     }
  1877. }
  1878. TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
  1879. TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
  1880.       &refBlackWhite);
  1881. if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
  1882. return NULL;
  1883. /*
  1884.  * The 6.0 spec says that subsampling must be
  1885.  * one of 1, 2, or 4, and that vertical subsampling
  1886.  * must always be <= horizontal subsampling; so
  1887.  * there are only a few possibilities and we just
  1888.  * enumerate the cases.
  1889.  */
  1890. TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
  1891. switch ((hs<<4)|vs) {
  1892. case 0x44: return (putcontig8bitYCbCr44tile);
  1893. case 0x42: return (putcontig8bitYCbCr42tile);
  1894. case 0x41: return (putcontig8bitYCbCr41tile);
  1895. case 0x22: return (putcontig8bitYCbCr22tile);
  1896. case 0x21: return (putcontig8bitYCbCr21tile);
  1897. case 0x11: return (putcontig8bitYCbCr11tile);
  1898. }
  1899. return (NULL);
  1900. }
  1901. static tileContigRoutine
  1902. initCIELabConversion(TIFFRGBAImage* img)
  1903. {
  1904. static char module[] = "initCIELabConversion";
  1905. float   *whitePoint;
  1906. float   refWhite[3];
  1907. if (!img->cielab) {
  1908. img->cielab = (TIFFCIELabToRGB *)
  1909. _TIFFmalloc(sizeof(TIFFCIELabToRGB));
  1910. if (!img->cielab) {
  1911. TIFFErrorExt(img->tif->tif_clientdata, module,
  1912.     "No space for CIE L*a*b*->RGB conversion state.");
  1913. return NULL;
  1914. }
  1915. }
  1916. TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
  1917. refWhite[1] = 100.0F;
  1918. refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
  1919. refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
  1920.       / whitePoint[1] * refWhite[1];
  1921. if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
  1922. TIFFErrorExt(img->tif->tif_clientdata, module,
  1923.     "Failed to initialize CIE L*a*b*->RGB conversion state.");
  1924. _TIFFfree(img->cielab);
  1925. return NULL;
  1926. }
  1927. return putcontig8bitCIELab;
  1928. }
  1929. /*
  1930.  * Greyscale images with less than 8 bits/sample are handled
  1931.  * with a table to avoid lots of shifts and masks.  The table
  1932.  * is setup so that put*bwtile (below) can retrieve 8/bitspersample
  1933.  * pixel values simply by indexing into the table with one
  1934.  * number.
  1935.  */
  1936. static int
  1937. makebwmap(TIFFRGBAImage* img)
  1938. {
  1939.     TIFFRGBValue* Map = img->Map;
  1940.     int bitspersample = img->bitspersample;
  1941.     int nsamples = 8 / bitspersample;
  1942.     int i;
  1943.     uint32* p;
  1944.     if( nsamples == 0 )
  1945.         nsamples = 1;
  1946.     img->BWmap = (uint32**) _TIFFmalloc(
  1947. 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
  1948.     if (img->BWmap == NULL) {
  1949. TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
  1950. return (0);
  1951.     }
  1952.     p = (uint32*)(img->BWmap + 256);
  1953.     for (i = 0; i < 256; i++) {
  1954. TIFFRGBValue c;
  1955. img->BWmap[i] = p;
  1956. switch (bitspersample) {
  1957. #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
  1958. case 1:
  1959.     GREY(i>>7);
  1960.     GREY((i>>6)&1);
  1961.     GREY((i>>5)&1);
  1962.     GREY((i>>4)&1);
  1963.     GREY((i>>3)&1);
  1964.     GREY((i>>2)&1);
  1965.     GREY((i>>1)&1);
  1966.     GREY(i&1);
  1967.     break;
  1968. case 2:
  1969.     GREY(i>>6);
  1970.     GREY((i>>4)&3);
  1971.     GREY((i>>2)&3);
  1972.     GREY(i&3);
  1973.     break;
  1974. case 4:
  1975.     GREY(i>>4);
  1976.     GREY(i&0xf);
  1977.     break;
  1978. case 8:
  1979.         case 16:
  1980.     GREY(i);
  1981.     break;
  1982. }
  1983. #undef GREY
  1984.     }
  1985.     return (1);
  1986. }
  1987. /*
  1988.  * Construct a mapping table to convert from the range
  1989.  * of the data samples to [0,255] --for display.  This
  1990.  * process also handles inverting B&W images when needed.
  1991.  */ 
  1992. static int
  1993. setupMap(TIFFRGBAImage* img)
  1994. {
  1995.     int32 x, range;
  1996.     range = (int32)((1L<<img->bitspersample)-1);
  1997.     
  1998.     /* treat 16 bit the same as eight bit */
  1999.     if( img->bitspersample == 16 )
  2000.         range = (int32) 255;
  2001.     img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
  2002.     if (img->Map == NULL) {
  2003. TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
  2004. "No space for photometric conversion table");
  2005. return (0);
  2006.     }
  2007.     if (img->photometric == PHOTOMETRIC_MINISWHITE) {
  2008. for (x = 0; x <= range; x++)
  2009.     img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
  2010.     } else {
  2011. for (x = 0; x <= range; x++)
  2012.     img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
  2013.     }
  2014.     if (img->bitspersample <= 16 &&
  2015. (img->photometric == PHOTOMETRIC_MINISBLACK ||
  2016.  img->photometric == PHOTOMETRIC_MINISWHITE)) {
  2017. /*
  2018.  * Use photometric mapping table to construct
  2019.  * unpacking tables for samples <= 8 bits.
  2020.  */
  2021. if (!makebwmap(img))
  2022.     return (0);
  2023. /* no longer need Map, free it */
  2024. _TIFFfree(img->Map), img->Map = NULL;
  2025.     }
  2026.     return (1);
  2027. }
  2028. static int
  2029. checkcmap(TIFFRGBAImage* img)
  2030. {
  2031.     uint16* r = img->redcmap;
  2032.     uint16* g = img->greencmap;
  2033.     uint16* b = img->bluecmap;
  2034.     long n = 1L<<img->bitspersample;
  2035.     while (n-- > 0)
  2036. if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  2037.     return (16);
  2038.     return (8);
  2039. }
  2040. static void
  2041. cvtcmap(TIFFRGBAImage* img)
  2042. {
  2043.     uint16* r = img->redcmap;
  2044.     uint16* g = img->greencmap;
  2045.     uint16* b = img->bluecmap;
  2046.     long i;
  2047.     for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
  2048. #define CVT(x) ((uint16)((x)>>8))
  2049. r[i] = CVT(r[i]);
  2050. g[i] = CVT(g[i]);
  2051. b[i] = CVT(b[i]);
  2052. #undef CVT
  2053.     }
  2054. }
  2055. /*
  2056.  * Palette images with <= 8 bits/sample are handled
  2057.  * with a table to avoid lots of shifts and masks.  The table
  2058.  * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
  2059.  * pixel values simply by indexing into the table with one
  2060.  * number.
  2061.  */
  2062. static int
  2063. makecmap(TIFFRGBAImage* img)
  2064. {
  2065.     int bitspersample = img->bitspersample;
  2066.     int nsamples = 8 / bitspersample;
  2067.     uint16* r = img->redcmap;
  2068.     uint16* g = img->greencmap;
  2069.     uint16* b = img->bluecmap;
  2070.     uint32 *p;
  2071.     int i;
  2072.     img->PALmap = (uint32**) _TIFFmalloc(
  2073. 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
  2074.     if (img->PALmap == NULL) {
  2075. TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
  2076. return (0);
  2077. }
  2078.     p = (uint32*)(img->PALmap + 256);
  2079.     for (i = 0; i < 256; i++) {
  2080. TIFFRGBValue c;
  2081. img->PALmap[i] = p;
  2082. #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
  2083. switch (bitspersample) {
  2084. case 1:
  2085.     CMAP(i>>7);
  2086.     CMAP((i>>6)&1);
  2087.     CMAP((i>>5)&1);
  2088.     CMAP((i>>4)&1);
  2089.     CMAP((i>>3)&1);
  2090.     CMAP((i>>2)&1);
  2091.     CMAP((i>>1)&1);
  2092.     CMAP(i&1);
  2093.     break;
  2094. case 2:
  2095.     CMAP(i>>6);
  2096.     CMAP((i>>4)&3);
  2097.     CMAP((i>>2)&3);
  2098.     CMAP(i&3);
  2099.     break;
  2100. case 4:
  2101.     CMAP(i>>4);
  2102.     CMAP(i&0xf);
  2103.     break;
  2104. case 8:
  2105.     CMAP(i);
  2106.     break;
  2107. }
  2108. #undef CMAP
  2109.     }
  2110.     return (1);
  2111. }
  2112. /* 
  2113.  * Construct any mapping table used
  2114.  * by the associated put routine.
  2115.  */
  2116. static int
  2117. buildMap(TIFFRGBAImage* img)
  2118. {
  2119.     switch (img->photometric) {
  2120.     case PHOTOMETRIC_RGB:
  2121.     case PHOTOMETRIC_YCBCR:
  2122.     case PHOTOMETRIC_SEPARATED:
  2123. if (img->bitspersample == 8)
  2124.     break;
  2125. /* fall thru... */
  2126.     case PHOTOMETRIC_MINISBLACK:
  2127.     case PHOTOMETRIC_MINISWHITE:
  2128. if (!setupMap(img))
  2129.     return (0);
  2130. break;
  2131.     case PHOTOMETRIC_PALETTE:
  2132. /*
  2133.  * Convert 16-bit colormap to 8-bit (unless it looks
  2134.  * like an old-style 8-bit colormap).
  2135.  */
  2136. if (checkcmap(img) == 16)
  2137.     cvtcmap(img);
  2138. else
  2139.     TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
  2140. /*
  2141.  * Use mapping table and colormap to construct
  2142.  * unpacking tables for samples < 8 bits.
  2143.  */
  2144. if (img->bitspersample <= 8 && !makecmap(img))
  2145.     return (0);
  2146. break;
  2147.     }
  2148.     return (1);
  2149. }
  2150. /*
  2151.  * Select the appropriate conversion routine for packed data.
  2152.  */
  2153. static int
  2154. pickTileContigCase(TIFFRGBAImage* img)
  2155. {
  2156.     tileContigRoutine put = 0;
  2157.     if (buildMap(img)) {
  2158. switch (img->photometric) {
  2159. case PHOTOMETRIC_RGB:
  2160.     switch (img->bitspersample) {
  2161.     case 8:
  2162. if (!img->Map) {
  2163.     if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
  2164. put = putRGBAAcontig8bittile;
  2165.     else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
  2166. put = putRGBUAcontig8bittile;
  2167.     else
  2168. put = putRGBcontig8bittile;
  2169. } else
  2170.     put = putRGBcontig8bitMaptile;
  2171. break;
  2172.     case 16:
  2173. put = putRGBcontig16bittile;
  2174. if (!img->Map) {
  2175.     if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
  2176. put = putRGBAAcontig16bittile;
  2177.     else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
  2178. put = putRGBUAcontig16bittile;
  2179. }
  2180. break;
  2181.     }
  2182.     break;
  2183. case PHOTOMETRIC_SEPARATED:
  2184.     if (img->bitspersample == 8) {
  2185. if (!img->Map)
  2186.     put = putRGBcontig8bitCMYKtile;
  2187. else
  2188.     put = putRGBcontig8bitCMYKMaptile;
  2189.     }
  2190.     break;
  2191. case PHOTOMETRIC_PALETTE:
  2192.     switch (img->bitspersample) {
  2193.     case 8: put = put8bitcmaptile; break;
  2194.     case 4: put = put4bitcmaptile; break;
  2195.     case 2: put = put2bitcmaptile; break;
  2196.     case 1: put = put1bitcmaptile; break;
  2197.     }
  2198.     break;
  2199. case PHOTOMETRIC_MINISWHITE:
  2200. case PHOTOMETRIC_MINISBLACK:
  2201.     switch (img->bitspersample) {
  2202.             case 16: put = put16bitbwtile; break;
  2203.     case 8:  put = putgreytile; break;
  2204.     case 4:  put = put4bitbwtile; break;
  2205.     case 2:  put = put2bitbwtile; break;
  2206.     case 1:  put = put1bitbwtile; break;
  2207.     }
  2208.     break;
  2209. case PHOTOMETRIC_YCBCR:
  2210.     if (img->bitspersample == 8)
  2211. put = initYCbCrConversion(img);
  2212.     break;
  2213. case PHOTOMETRIC_CIELAB:
  2214.     if (img->bitspersample == 8)
  2215. put = initCIELabConversion(img);
  2216.     break;
  2217. }
  2218.     }
  2219.     return ((img->put.contig = put) != 0);
  2220. }
  2221. /*
  2222.  * Select the appropriate conversion routine for unpacked data.
  2223.  *
  2224.  * NB: we assume that unpacked single channel data is directed
  2225.  *  to the "packed routines.
  2226.  */
  2227. static int
  2228. pickTileSeparateCase(TIFFRGBAImage* img)
  2229. {
  2230.     tileSeparateRoutine put = 0;
  2231.     if (buildMap(img)) {
  2232. switch (img->photometric) {
  2233. case PHOTOMETRIC_RGB:
  2234.     switch (img->bitspersample) {
  2235.     case 8:
  2236. if (!img->Map) {
  2237.     if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
  2238. put = putRGBAAseparate8bittile;
  2239.     else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
  2240. put = putRGBUAseparate8bittile;
  2241.     else
  2242. put = putRGBseparate8bittile;
  2243. } else
  2244.     put = putRGBseparate8bitMaptile;
  2245. break;
  2246.     case 16:
  2247. put = putRGBseparate16bittile;
  2248. if (!img->Map) {
  2249.     if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
  2250. put = putRGBAAseparate16bittile;
  2251.     else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
  2252. put = putRGBUAseparate16bittile;
  2253. }
  2254. break;
  2255.     }
  2256.     break;
  2257. }
  2258.     }
  2259.     return ((img->put.separate = put) != 0);
  2260. }
  2261. /*
  2262.  * Read a whole strip off data from the file, and convert to RGBA form.
  2263.  * If this is the last strip, then it will only contain the portion of
  2264.  * the strip that is actually within the image space.  The result is
  2265.  * organized in bottom to top form.
  2266.  */
  2267. int
  2268. TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
  2269. {
  2270.     char  emsg[1024] = "";
  2271.     TIFFRGBAImage img;
  2272.     int  ok;
  2273.     uint32 rowsperstrip, rows_to_read;
  2274.     if( TIFFIsTiled( tif ) )
  2275.     {
  2276. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
  2277.                   "Can't use TIFFReadRGBAStrip() with tiled file.");
  2278. return (0);
  2279.     }
  2280.     
  2281.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  2282.     if( (row % rowsperstrip) != 0 )
  2283.     {
  2284. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
  2285. "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
  2286. return (0);
  2287.     }
  2288.     if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
  2289.         img.row_offset = row;
  2290.         img.col_offset = 0;
  2291.         if( row + rowsperstrip > img.height )
  2292.             rows_to_read = img.height - row;
  2293.         else
  2294.             rows_to_read = rowsperstrip;
  2295.         
  2296. ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
  2297.         
  2298. TIFFRGBAImageEnd(&img);
  2299.     } else {
  2300. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), emsg);
  2301. ok = 0;
  2302.     }
  2303.     
  2304.     return (ok);
  2305. }
  2306. /*
  2307.  * Read a whole tile off data from the file, and convert to RGBA form.
  2308.  * The returned RGBA data is organized from bottom to top of tile,
  2309.  * and may include zeroed areas if the tile extends off the image.
  2310.  */
  2311. int
  2312. TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
  2313. {
  2314.     char  emsg[1024] = "";
  2315.     TIFFRGBAImage img;
  2316.     int  ok;
  2317.     uint32 tile_xsize, tile_ysize;
  2318.     uint32 read_xsize, read_ysize;
  2319.     uint32 i_row;
  2320.     /*
  2321.      * Verify that our request is legal - on a tile file, and on a
  2322.      * tile boundary.
  2323.      */
  2324.     
  2325.     if( !TIFFIsTiled( tif ) )
  2326.     {
  2327. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
  2328.   "Can't use TIFFReadRGBATile() with stripped file.");
  2329. return (0);
  2330.     }
  2331.     
  2332.     TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
  2333.     TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
  2334.     if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
  2335.     {
  2336. TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
  2337.                   "Row/col passed to TIFFReadRGBATile() must be top"
  2338.                   "left corner of a tile.");
  2339. return (0);
  2340.     }
  2341.     /*
  2342.      * Setup the RGBA reader.
  2343.      */
  2344.     
  2345.     if (!TIFFRGBAImageOK(tif, emsg) 
  2346. || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
  2347.     TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), emsg);
  2348.     return( 0 );
  2349.     }
  2350.     /*
  2351.      * The TIFFRGBAImageGet() function doesn't allow us to get off the
  2352.      * edge of the image, even to fill an otherwise valid tile.  So we
  2353.      * figure out how much we can read, and fix up the tile buffer to
  2354.      * a full tile configuration afterwards.
  2355.      */
  2356.     if( row + tile_ysize > img.height )
  2357.         read_ysize = img.height - row;
  2358.     else
  2359.         read_ysize = tile_ysize;
  2360.     
  2361.     if( col + tile_xsize > img.width )
  2362.         read_xsize = img.width - col;
  2363.     else
  2364.         read_xsize = tile_xsize;
  2365.     /*
  2366.      * Read the chunk of imagery.
  2367.      */
  2368.     
  2369.     img.row_offset = row;
  2370.     img.col_offset = col;
  2371.     ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
  2372.         
  2373.     TIFFRGBAImageEnd(&img);
  2374.     /*
  2375.      * If our read was incomplete we will need to fix up the tile by
  2376.      * shifting the data around as if a full tile of data is being returned.
  2377.      *
  2378.      * This is all the more complicated because the image is organized in
  2379.      * bottom to top format. 
  2380.      */
  2381.     if( read_xsize == tile_xsize && read_ysize == tile_ysize )
  2382.         return( ok );
  2383.     for( i_row = 0; i_row < read_ysize; i_row++ ) {
  2384.         memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
  2385.                  raster + (read_ysize - i_row - 1) * read_xsize,
  2386.                  read_xsize * sizeof(uint32) );
  2387.         _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
  2388.                      0, sizeof(uint32) * (tile_xsize - read_xsize) );
  2389.     }
  2390.     for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
  2391.         _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
  2392.                      0, sizeof(uint32) * tile_xsize );
  2393.     }
  2394.     return (ok);
  2395. }
  2396. /* vim: set ts=8 sts=8 sw=8 noet: */