1 /* $Id: tif_getimage.c,v 1.1 2005/06/17 13:54:52 vp153 Exp $ */
4 * Copyright (c) 1991-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
30 * Read and return a packed RGBA image.
35 static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
36 static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
37 static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
38 static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
39 static int pickTileContigCase(TIFFRGBAImage*);
40 static int pickTileSeparateCase(TIFFRGBAImage*);
42 static const char photoTag[] = "PhotometricInterpretation";
45 * Helper constants used in Orientation tag handling
47 #define FLIP_VERTICALLY 0x01
48 #define FLIP_HORIZONTALLY 0x02
51 * Color conversion constants. We will define display types here.
54 TIFFDisplay display_sRGB = {
55 { /* XYZ -> luminance matrix */
56 { 3.2410F, -1.5374F, -0.4986F },
57 { -0.9692F, 1.8760F, 0.0416F },
58 { 0.0556F, -0.2040F, 1.0570F }
60 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
61 255, 255, 255, /* Pixel values for ref. white */
62 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */
63 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */
67 * Check the image to see if TIFFReadRGBAImage can deal with it.
68 * 1/0 is returned according to whether or not the image can
69 * be handled. If 0 is returned, emsg contains the reason
70 * why it is being rejected.
73 TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
75 TIFFDirectory* td = &tif->tif_dir;
79 if (!tif->tif_decodestatus) {
80 sprintf(emsg, "Sorry, requested compression method is not configured");
83 switch (td->td_bitspersample) {
84 case 1: case 2: case 4:
88 sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
89 td->td_bitspersample);
92 colorchannels = td->td_samplesperpixel - td->td_extrasamples;
93 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
94 switch (colorchannels) {
96 photometric = PHOTOMETRIC_MINISBLACK;
99 photometric = PHOTOMETRIC_RGB;
102 sprintf(emsg, "Missing needed %s tag", photoTag);
106 switch (photometric) {
107 case PHOTOMETRIC_MINISWHITE:
108 case PHOTOMETRIC_MINISBLACK:
109 case PHOTOMETRIC_PALETTE:
110 if (td->td_planarconfig == PLANARCONFIG_CONTIG
111 && td->td_samplesperpixel != 1
112 && td->td_bitspersample < 8 ) {
114 "Sorry, can not handle contiguous data with %s=%d, "
115 "and %s=%d and Bits/Sample=%d",
116 photoTag, photometric,
117 "Samples/pixel", td->td_samplesperpixel,
118 td->td_bitspersample);
122 ** We should likely validate that any extra samples are either
123 ** to be ignored, or are alpha, and if alpha we should try to use
124 ** them. But for now we won't bother with this.
127 case PHOTOMETRIC_YCBCR:
128 if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
129 sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
130 "Planarconfiguration", td->td_planarconfig);
134 case PHOTOMETRIC_RGB:
135 if (colorchannels < 3) {
136 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
137 "Color channels", colorchannels);
141 case PHOTOMETRIC_SEPARATED:
142 if (td->td_inkset != INKSET_CMYK) {
143 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
144 "InkSet", td->td_inkset);
147 if (td->td_samplesperpixel < 4) {
148 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
149 "Samples/pixel", td->td_samplesperpixel);
153 case PHOTOMETRIC_LOGL:
154 if (td->td_compression != COMPRESSION_SGILOG) {
155 sprintf(emsg, "Sorry, LogL data must have %s=%d",
156 "Compression", COMPRESSION_SGILOG);
160 case PHOTOMETRIC_LOGLUV:
161 if (td->td_compression != COMPRESSION_SGILOG &&
162 td->td_compression != COMPRESSION_SGILOG24) {
163 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
164 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
167 if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
168 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
169 "Planarconfiguration", td->td_planarconfig);
173 case PHOTOMETRIC_CIELAB:
176 sprintf(emsg, "Sorry, can not handle image with %s=%d",
177 photoTag, photometric);
184 TIFFRGBAImageEnd(TIFFRGBAImage* img)
187 _TIFFfree(img->Map), img->Map = NULL;
189 _TIFFfree(img->BWmap), img->BWmap = NULL;
191 _TIFFfree(img->PALmap), img->PALmap = NULL;
193 _TIFFfree(img->ycbcr), img->ycbcr = NULL;
195 _TIFFfree(img->cielab), img->cielab = NULL;
198 _TIFFfree( img->redcmap );
199 _TIFFfree( img->greencmap );
200 _TIFFfree( img->bluecmap );
205 isCCITTCompression(TIFF* tif)
208 TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
209 return (compress == COMPRESSION_CCITTFAX3 ||
210 compress == COMPRESSION_CCITTFAX4 ||
211 compress == COMPRESSION_CCITTRLE ||
212 compress == COMPRESSION_CCITTRLEW);
216 TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
223 uint16 *red_orig, *green_orig, *blue_orig;
226 /* Initialize to normal values */
230 img->greencmap = NULL;
231 img->bluecmap = NULL;
232 img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
235 img->stoponerr = stop;
236 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
237 switch (img->bitspersample) {
238 case 1: case 2: case 4:
242 sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
247 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
248 TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
249 &extrasamples, &sampleinfo);
250 if (extrasamples >= 1)
252 switch (sampleinfo[0]) {
253 case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */
254 if (img->samplesperpixel > 3) /* correct info about alpha channel */
255 img->alpha = EXTRASAMPLE_ASSOCALPHA;
257 case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
258 case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
259 img->alpha = sampleinfo[0];
264 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
265 if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
266 img->photometric = PHOTOMETRIC_MINISWHITE;
268 if( extrasamples == 0
269 && img->samplesperpixel == 4
270 && img->photometric == PHOTOMETRIC_RGB )
272 img->alpha = EXTRASAMPLE_ASSOCALPHA;
277 colorchannels = img->samplesperpixel - extrasamples;
278 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
279 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
280 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
281 switch (colorchannels) {
283 if (isCCITTCompression(tif))
284 img->photometric = PHOTOMETRIC_MINISWHITE;
286 img->photometric = PHOTOMETRIC_MINISBLACK;
289 img->photometric = PHOTOMETRIC_RGB;
292 sprintf(emsg, "Missing needed %s tag", photoTag);
296 switch (img->photometric) {
297 case PHOTOMETRIC_PALETTE:
298 if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
299 &red_orig, &green_orig, &blue_orig)) {
300 sprintf(emsg, "Missing required \"Colormap\" tag");
304 /* copy the colormaps so we can modify them */
305 n_color = (1L << img->bitspersample);
306 img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
307 img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
308 img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
309 if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
310 sprintf(emsg, "Out of memory for colormap copy");
314 _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
315 _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
316 _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
319 case PHOTOMETRIC_MINISWHITE:
320 case PHOTOMETRIC_MINISBLACK:
321 if (planarconfig == PLANARCONFIG_CONTIG
322 && img->samplesperpixel != 1
323 && img->bitspersample < 8 ) {
325 "Sorry, can not handle contiguous data with %s=%d, "
326 "and %s=%d and Bits/Sample=%d",
327 photoTag, img->photometric,
328 "Samples/pixel", img->samplesperpixel,
333 case PHOTOMETRIC_YCBCR:
334 if (planarconfig != PLANARCONFIG_CONTIG) {
335 sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
336 "Planarconfiguration", planarconfig);
339 /* It would probably be nice to have a reality check here. */
340 if (planarconfig == PLANARCONFIG_CONTIG)
341 /* can rely on libjpeg to convert to RGB */
342 /* XXX should restore current state on exit */
344 case COMPRESSION_OJPEG:
345 case COMPRESSION_JPEG:
346 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
347 img->photometric = PHOTOMETRIC_RGB;
355 case PHOTOMETRIC_RGB:
356 if (colorchannels < 3) {
357 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
358 "Color channels", colorchannels);
362 case PHOTOMETRIC_SEPARATED: {
364 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
365 if (inkset != INKSET_CMYK) {
366 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
370 if (img->samplesperpixel < 4) {
371 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
372 "Samples/pixel", img->samplesperpixel);
377 case PHOTOMETRIC_LOGL:
378 if (compress != COMPRESSION_SGILOG) {
379 sprintf(emsg, "Sorry, LogL data must have %s=%d",
380 "Compression", COMPRESSION_SGILOG);
383 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
384 img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
385 img->bitspersample = 8;
387 case PHOTOMETRIC_LOGLUV:
388 if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
389 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
390 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
393 if (planarconfig != PLANARCONFIG_CONTIG) {
394 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
395 "Planarconfiguration", planarconfig);
398 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
399 img->photometric = PHOTOMETRIC_RGB; /* little white lie */
400 img->bitspersample = 8;
402 case PHOTOMETRIC_CIELAB:
405 sprintf(emsg, "Sorry, can not handle image with %s=%d",
406 photoTag, img->photometric);
414 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
415 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
416 TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
418 !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
420 img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig;
421 if (!pickTileContigCase(img)) {
422 sprintf(emsg, "Sorry, can not handle image");
426 img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate;
427 if (!pickTileSeparateCase(img)) {
428 sprintf(emsg, "Sorry, can not handle image");
436 TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
438 if (img->get == NULL) {
439 TIFFError(TIFFFileName(img->tif), "No \"get\" routine setup");
442 if (img->put.any == NULL) {
443 TIFFError(TIFFFileName(img->tif),
444 "No \"put\" routine setupl; probably can not handle image format");
447 return (*img->get)(img, raster, w, h);
451 * Read the specified image into an ABGR-format rastertaking in account
452 * specified orientation.
455 TIFFReadRGBAImageOriented(TIFF* tif,
456 uint32 rwidth, uint32 rheight, uint32* raster,
457 int orientation, int stop)
459 char emsg[1024] = "";
463 if (TIFFRGBAImageOK(tif, emsg) &&
464 TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
465 img.req_orientation = orientation;
466 /* XXX verify rwidth and rheight against width and height */
467 ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
469 TIFFRGBAImageEnd(&img);
471 TIFFError(TIFFFileName(tif), emsg);
478 * Read the specified image into an ABGR-format raster. Use bottom left
479 * origin for raster by default.
482 TIFFReadRGBAImage(TIFF* tif,
483 uint32 rwidth, uint32 rheight, uint32* raster, int stop)
485 return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
486 ORIENTATION_BOTLEFT, stop);
490 setorientation(TIFFRGBAImage* img)
492 switch (img->orientation) {
493 case ORIENTATION_TOPLEFT:
494 case ORIENTATION_LEFTTOP:
495 if (img->req_orientation == ORIENTATION_TOPRIGHT ||
496 img->req_orientation == ORIENTATION_RIGHTTOP)
497 return FLIP_HORIZONTALLY;
498 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
499 img->req_orientation == ORIENTATION_RIGHTBOT)
500 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
501 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
502 img->req_orientation == ORIENTATION_LEFTBOT)
503 return FLIP_VERTICALLY;
506 case ORIENTATION_TOPRIGHT:
507 case ORIENTATION_RIGHTTOP:
508 if (img->req_orientation == ORIENTATION_TOPLEFT ||
509 img->req_orientation == ORIENTATION_LEFTTOP)
510 return FLIP_HORIZONTALLY;
511 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
512 img->req_orientation == ORIENTATION_RIGHTBOT)
513 return FLIP_VERTICALLY;
514 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
515 img->req_orientation == ORIENTATION_LEFTBOT)
516 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
519 case ORIENTATION_BOTRIGHT:
520 case ORIENTATION_RIGHTBOT:
521 if (img->req_orientation == ORIENTATION_TOPLEFT ||
522 img->req_orientation == ORIENTATION_LEFTTOP)
523 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
524 else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
525 img->req_orientation == ORIENTATION_RIGHTTOP)
526 return FLIP_VERTICALLY;
527 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
528 img->req_orientation == ORIENTATION_LEFTBOT)
529 return FLIP_HORIZONTALLY;
532 case ORIENTATION_BOTLEFT:
533 case ORIENTATION_LEFTBOT:
534 if (img->req_orientation == ORIENTATION_TOPLEFT ||
535 img->req_orientation == ORIENTATION_LEFTTOP)
536 return FLIP_VERTICALLY;
537 else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
538 img->req_orientation == ORIENTATION_RIGHTTOP)
539 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
540 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
541 img->req_orientation == ORIENTATION_RIGHTBOT)
542 return FLIP_HORIZONTALLY;
545 default: /* NOTREACHED */
551 * Get an tile-organized image that has
552 * PlanarConfiguration contiguous if SamplesPerPixel > 1
554 * SamplesPerPixel == 1
557 gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
559 TIFF* tif = img->tif;
560 tileContigRoutine put = img->put.contig;
561 uint32 col, row, y, rowstoread;
565 int32 fromskew, toskew;
569 buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
571 TIFFError(TIFFFileName(tif), "No space for tile buffer");
574 _TIFFmemset(buf, 0, TIFFTileSize(tif));
575 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
576 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
578 flip = setorientation(img);
579 if (flip & FLIP_VERTICALLY) {
581 toskew = -(int32)(tw + w);
585 toskew = -(int32)(tw - w);
588 for (row = 0; row < h; row += nrow)
590 rowstoread = th - (row + img->row_offset) % th;
591 nrow = (row + rowstoread > h ? h - row : rowstoread);
592 for (col = 0; col < w; col += tw)
594 if (TIFFReadTile(tif, buf, col+img->col_offset,
595 row+img->row_offset, 0, 0) < 0 && img->stoponerr)
601 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
606 * Tile is clipped horizontally. Calculate
607 * visible portion and skewing factors.
609 uint32 npix = w - col;
610 fromskew = tw - npix;
611 (*put)(img, raster+y*w+col, col, y,
612 npix, nrow, fromskew, toskew + fromskew, buf + pos);
616 (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
620 y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
624 if (flip & FLIP_HORIZONTALLY) {
627 for (line = 0; line < h; line++) {
628 uint32 *left = raster + (line * w);
629 uint32 *right = left + w - 1;
631 while ( left < right ) {
644 * Get an tile-organized image that has
645 * SamplesPerPixel > 1
646 * PlanarConfiguration separated
647 * We assume that all such images are RGB.
650 gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
652 TIFF* tif = img->tif;
653 tileSeparateRoutine put = img->put.separate;
654 uint32 col, row, y, rowstoread;
663 int32 fromskew, toskew;
664 int alpha = img->alpha;
668 tilesize = TIFFTileSize(tif);
669 buf = (unsigned char*) _TIFFmalloc(4*tilesize);
671 TIFFError(TIFFFileName(tif), "No space for tile buffer");
674 _TIFFmemset(buf, 0, 4*tilesize);
680 _TIFFmemset(a, 0xff, tilesize);
681 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
682 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
684 flip = setorientation(img);
685 if (flip & FLIP_VERTICALLY) {
687 toskew = -(int32)(tw + w);
691 toskew = -(int32)(tw - w);
694 for (row = 0; row < h; row += nrow)
696 rowstoread = th - (row + img->row_offset) % th;
697 nrow = (row + rowstoread > h ? h - row : rowstoread);
698 for (col = 0; col < w; col += tw)
700 if (TIFFReadTile(tif, r, col+img->col_offset,
701 row+img->row_offset,0,0) < 0 && img->stoponerr)
706 if (TIFFReadTile(tif, g, col+img->col_offset,
707 row+img->row_offset,0,1) < 0 && img->stoponerr)
712 if (TIFFReadTile(tif, b, col+img->col_offset,
713 row+img->row_offset,0,2) < 0 && img->stoponerr)
718 if (alpha && TIFFReadTile(tif,a,col+img->col_offset,
719 row+img->row_offset,0,3) < 0 && img->stoponerr)
725 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
730 * Tile is clipped horizontally. Calculate
731 * visible portion and skewing factors.
733 uint32 npix = w - col;
734 fromskew = tw - npix;
735 (*put)(img, raster+y*w+col, col, y,
736 npix, nrow, fromskew, toskew + fromskew,
737 r + pos, g + pos, b + pos, a + pos);
739 (*put)(img, raster+y*w+col, col, y,
740 tw, nrow, 0, toskew, r + pos, g + pos, b + pos, a + pos);
744 y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
747 if (flip & FLIP_HORIZONTALLY) {
750 for (line = 0; line < h; line++) {
751 uint32 *left = raster + (line * w);
752 uint32 *right = left + w - 1;
754 while ( left < right ) {
768 * Get a strip-organized image that has
769 * PlanarConfiguration contiguous if SamplesPerPixel > 1
771 * SamplesPerPixel == 1
774 gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
776 TIFF* tif = img->tif;
777 tileContigRoutine put = img->put.contig;
778 uint32 row, y, nrow, rowstoread;
782 uint32 imagewidth = img->width;
784 int32 fromskew, toskew;
787 buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
789 TIFFError(TIFFFileName(tif), "No space for strip buffer");
792 _TIFFmemset(buf, 0, TIFFStripSize(tif));
794 flip = setorientation(img);
795 if (flip & FLIP_VERTICALLY) {
797 toskew = -(int32)(w + w);
800 toskew = -(int32)(w - w);
803 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
804 scanline = TIFFScanlineSize(tif);
805 fromskew = (w < imagewidth ? imagewidth - w : 0);
806 for (row = 0; row < h; row += nrow)
808 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
809 nrow = (row + rowstoread > h ? h - row : rowstoread);
810 if (TIFFReadEncodedStrip(tif,
811 TIFFComputeStrip(tif,row+img->row_offset, 0),
813 ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
820 pos = ((row + img->row_offset) % rowsperstrip) * scanline;
821 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
822 y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
825 if (flip & FLIP_HORIZONTALLY) {
828 for (line = 0; line < h; line++) {
829 uint32 *left = raster + (line * w);
830 uint32 *right = left + w - 1;
832 while ( left < right ) {
846 * Get a strip-organized image with
847 * SamplesPerPixel > 1
848 * PlanarConfiguration separated
849 * We assume that all such images are RGB.
852 gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
854 TIFF* tif = img->tif;
855 tileSeparateRoutine put = img->put.separate;
857 unsigned char *r, *g, *b, *a;
858 uint32 row, y, nrow, rowstoread;
861 uint32 rowsperstrip, offset_row;
862 uint32 imagewidth = img->width;
864 int32 fromskew, toskew;
865 int alpha = img->alpha;
868 stripsize = TIFFStripSize(tif);
869 r = buf = (unsigned char *)_TIFFmalloc(4*stripsize);
871 TIFFError(TIFFFileName(tif), "No space for tile buffer");
874 _TIFFmemset(buf, 0, 4*stripsize);
879 _TIFFmemset(a, 0xff, stripsize);
881 flip = setorientation(img);
882 if (flip & FLIP_VERTICALLY) {
884 toskew = -(int32)(w + w);
888 toskew = -(int32)(w - w);
891 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
892 scanline = TIFFScanlineSize(tif);
893 fromskew = (w < imagewidth ? imagewidth - w : 0);
894 for (row = 0; row < h; row += nrow)
896 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
897 nrow = (row + rowstoread > h ? h - row : rowstoread);
898 offset_row = row + img->row_offset;
899 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
900 r, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
906 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
907 g, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
913 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
914 b, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
921 (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3),
922 a, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
929 pos = ((row + img->row_offset) % rowsperstrip) * scanline;
930 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, r + pos, g + pos,
932 y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
935 if (flip & FLIP_HORIZONTALLY) {
938 for (line = 0; line < h; line++) {
939 uint32 *left = raster + (line * w);
940 uint32 *right = left + w - 1;
942 while ( left < right ) {
956 * The following routines move decoded data returned
957 * from the TIFF library into rasters filled with packed
958 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
960 * The routines have been created according to the most
961 * important cases and optimized. pickTileContigCase and
962 * pickTileSeparateCase analyze the parameters and select
963 * the appropriate "put" routine to use.
965 #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
966 #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
967 #define REPEAT2(op) op; op
968 #define CASE8(x,op) \
970 case 7: op; case 6: op; case 5: op; \
971 case 4: op; case 3: op; case 2: op; \
974 #define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
977 #define UNROLL8(w, op1, op2) { \
979 for (_x = w; _x >= 8; _x -= 8) { \
988 #define UNROLL4(w, op1, op2) { \
990 for (_x = w; _x >= 4; _x -= 4) { \
999 #define UNROLL2(w, op1, op2) { \
1001 for (_x = w; _x >= 2; _x -= 2) { \
1011 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1012 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1014 #define A1 (((uint32)0xffL)<<24)
1015 #define PACK(r,g,b) \
1016 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1017 #define PACK4(r,g,b,a) \
1018 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1019 #define W2B(v) (((v)>>8)&0xff)
1020 #define PACKW(r,g,b) \
1021 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1022 #define PACKW4(r,g,b,a) \
1023 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1025 #define DECLAREContigPutFunc(name) \
1027 TIFFRGBAImage* img, \
1029 uint32 x, uint32 y, \
1030 uint32 w, uint32 h, \
1031 int32 fromskew, int32 toskew, \
1036 * 8-bit palette => colormap/RGB
1038 DECLAREContigPutFunc(put8bitcmaptile)
1040 uint32** PALmap = img->PALmap;
1041 int samplesperpixel = img->samplesperpixel;
1045 for (x = w; x-- > 0;)
1047 *cp++ = PALmap[*pp][0];
1048 pp += samplesperpixel;
1056 * 4-bit palette => colormap/RGB
1058 DECLAREContigPutFunc(put4bitcmaptile)
1060 uint32** PALmap = img->PALmap;
1066 UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
1073 * 2-bit palette => colormap/RGB
1075 DECLAREContigPutFunc(put2bitcmaptile)
1077 uint32** PALmap = img->PALmap;
1083 UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
1090 * 1-bit palette => colormap/RGB
1092 DECLAREContigPutFunc(put1bitcmaptile)
1094 uint32** PALmap = img->PALmap;
1100 UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
1107 * 8-bit greyscale => colormap/RGB
1109 DECLAREContigPutFunc(putgreytile)
1111 int samplesperpixel = img->samplesperpixel;
1112 uint32** BWmap = img->BWmap;
1116 for (x = w; x-- > 0;)
1118 *cp++ = BWmap[*pp][0];
1119 pp += samplesperpixel;
1127 * 16-bit greyscale => colormap/RGB
1129 DECLAREContigPutFunc(put16bitbwtile)
1131 int samplesperpixel = img->samplesperpixel;
1132 uint32** BWmap = img->BWmap;
1136 uint16 *wp = (uint16 *) pp;
1138 for (x = w; x-- > 0;)
1140 /* use high order byte of 16bit value */
1142 *cp++ = BWmap[*wp >> 8][0];
1143 pp += 2 * samplesperpixel;
1144 wp += samplesperpixel;
1152 * 1-bit bilevel => colormap/RGB
1154 DECLAREContigPutFunc(put1bitbwtile)
1156 uint32** BWmap = img->BWmap;
1162 UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
1169 * 2-bit greyscale => colormap/RGB
1171 DECLAREContigPutFunc(put2bitbwtile)
1173 uint32** BWmap = img->BWmap;
1179 UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
1186 * 4-bit greyscale => colormap/RGB
1188 DECLAREContigPutFunc(put4bitbwtile)
1190 uint32** BWmap = img->BWmap;
1196 UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
1203 * 8-bit packed samples, no Map => RGB
1205 DECLAREContigPutFunc(putRGBcontig8bittile)
1207 int samplesperpixel = img->samplesperpixel;
1210 fromskew *= samplesperpixel;
1213 *cp++ = PACK(pp[0], pp[1], pp[2]);
1214 pp += samplesperpixel);
1221 * 8-bit packed samples, w/ Map => RGB
1223 DECLAREContigPutFunc(putRGBcontig8bitMaptile)
1225 TIFFRGBValue* Map = img->Map;
1226 int samplesperpixel = img->samplesperpixel;
1229 fromskew *= samplesperpixel;
1231 for (x = w; x-- > 0;) {
1232 *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
1233 pp += samplesperpixel;
1241 * 8-bit packed samples => RGBA w/ associated alpha
1242 * (known to have Map == NULL)
1244 DECLAREContigPutFunc(putRGBAAcontig8bittile)
1246 int samplesperpixel = img->samplesperpixel;
1249 fromskew *= samplesperpixel;
1252 *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
1253 pp += samplesperpixel);
1260 * 8-bit packed samples => RGBA w/ unassociated alpha
1261 * (known to have Map == NULL)
1263 DECLAREContigPutFunc(putRGBUAcontig8bittile)
1265 int samplesperpixel = img->samplesperpixel;
1268 fromskew *= samplesperpixel;
1271 for (x = w; x-- > 0;) {
1273 r = (pp[0] * a) / 255;
1274 g = (pp[1] * a) / 255;
1275 b = (pp[2] * a) / 255;
1276 *cp++ = PACK4(r,g,b,a);
1277 pp += samplesperpixel;
1285 * 16-bit packed samples => RGB
1287 DECLAREContigPutFunc(putRGBcontig16bittile)
1289 int samplesperpixel = img->samplesperpixel;
1290 uint16 *wp = (uint16 *)pp;
1293 fromskew *= samplesperpixel;
1295 for (x = w; x-- > 0;) {
1296 *cp++ = PACKW(wp[0], wp[1], wp[2]);
1297 wp += samplesperpixel;
1305 * 16-bit packed samples => RGBA w/ associated alpha
1306 * (known to have Map == NULL)
1308 DECLAREContigPutFunc(putRGBAAcontig16bittile)
1310 int samplesperpixel = img->samplesperpixel;
1311 uint16 *wp = (uint16 *)pp;
1314 fromskew *= samplesperpixel;
1316 for (x = w; x-- > 0;) {
1317 *cp++ = PACKW4(wp[0], wp[1], wp[2], wp[3]);
1318 wp += samplesperpixel;
1326 * 16-bit packed samples => RGBA w/ unassociated alpha
1327 * (known to have Map == NULL)
1329 DECLAREContigPutFunc(putRGBUAcontig16bittile)
1331 int samplesperpixel = img->samplesperpixel;
1332 uint16 *wp = (uint16 *)pp;
1335 fromskew *= samplesperpixel;
1339 * We shift alpha down four bits just in case unsigned
1340 * arithmetic doesn't handle the full range.
1341 * We still have plenty of accuracy, since the output is 8 bits.
1342 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1343 * Since we want r*a * 0xff for eight bit output,
1344 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1346 for (x = w; x-- > 0;) {
1348 r = (wp[0] * a) / 0x10eff;
1349 g = (wp[1] * a) / 0x10eff;
1350 b = (wp[2] * a) / 0x10eff;
1351 *cp++ = PACK4(r,g,b,a);
1352 wp += samplesperpixel;
1360 * 8-bit packed CMYK samples w/o Map => RGB
1362 * NB: The conversion of CMYK->RGB is *very* crude.
1364 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
1366 int samplesperpixel = img->samplesperpixel;
1370 fromskew *= samplesperpixel;
1374 r = (k*(255-pp[0]))/255;
1375 g = (k*(255-pp[1]))/255;
1376 b = (k*(255-pp[2]))/255;
1377 *cp++ = PACK(r, g, b);
1378 pp += samplesperpixel);
1385 * 8-bit packed CMYK samples w/Map => RGB
1387 * NB: The conversion of CMYK->RGB is *very* crude.
1389 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
1391 int samplesperpixel = img->samplesperpixel;
1392 TIFFRGBValue* Map = img->Map;
1396 fromskew *= samplesperpixel;
1398 for (x = w; x-- > 0;) {
1400 r = (k*(255-pp[0]))/255;
1401 g = (k*(255-pp[1]))/255;
1402 b = (k*(255-pp[2]))/255;
1403 *cp++ = PACK(Map[r], Map[g], Map[b]);
1404 pp += samplesperpixel;
1411 #define DECLARESepPutFunc(name) \
1413 TIFFRGBAImage* img,\
1415 uint32 x, uint32 y, \
1416 uint32 w, uint32 h,\
1417 int32 fromskew, int32 toskew,\
1418 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1422 * 8-bit unpacked samples => RGB
1424 DECLARESepPutFunc(putRGBseparate8bittile)
1426 (void) img; (void) x; (void) y; (void) a;
1428 UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
1429 SKEW(r, g, b, fromskew);
1435 * 8-bit unpacked samples => RGB
1437 DECLARESepPutFunc(putRGBseparate8bitMaptile)
1439 TIFFRGBValue* Map = img->Map;
1443 for (x = w; x > 0; x--)
1444 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
1445 SKEW(r, g, b, fromskew);
1451 * 8-bit unpacked samples => RGBA w/ associated alpha
1453 DECLARESepPutFunc(putRGBAAseparate8bittile)
1455 (void) img; (void) x; (void) y;
1457 UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
1458 SKEW4(r, g, b, a, fromskew);
1464 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1466 DECLARESepPutFunc(putRGBUAseparate8bittile)
1468 (void) img; (void) y;
1470 uint32 rv, gv, bv, av;
1471 for (x = w; x-- > 0;) {
1473 rv = (*r++ * av) / 255;
1474 gv = (*g++ * av) / 255;
1475 bv = (*b++ * av) / 255;
1476 *cp++ = PACK4(rv,gv,bv,av);
1478 SKEW4(r, g, b, a, fromskew);
1484 * 16-bit unpacked samples => RGB
1486 DECLARESepPutFunc(putRGBseparate16bittile)
1488 uint16 *wr = (uint16*) r;
1489 uint16 *wg = (uint16*) g;
1490 uint16 *wb = (uint16*) b;
1492 (void) img; (void) y; (void) a;
1494 for (x = 0; x < w; x++)
1495 *cp++ = PACKW(*wr++, *wg++, *wb++);
1496 SKEW(wr, wg, wb, fromskew);
1502 * 16-bit unpacked samples => RGBA w/ associated alpha
1504 DECLARESepPutFunc(putRGBAAseparate16bittile)
1506 uint16 *wr = (uint16*) r;
1507 uint16 *wg = (uint16*) g;
1508 uint16 *wb = (uint16*) b;
1509 uint16 *wa = (uint16*) a;
1511 (void) img; (void) y;
1513 for (x = 0; x < w; x++)
1514 *cp++ = PACKW4(*wr++, *wg++, *wb++, *wa++);
1515 SKEW4(wr, wg, wb, wa, fromskew);
1521 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1523 DECLARESepPutFunc(putRGBUAseparate16bittile)
1525 uint16 *wr = (uint16*) r;
1526 uint16 *wg = (uint16*) g;
1527 uint16 *wb = (uint16*) b;
1528 uint16 *wa = (uint16*) a;
1530 (void) img; (void) y;
1534 * We shift alpha down four bits just in case unsigned
1535 * arithmetic doesn't handle the full range.
1536 * We still have plenty of accuracy, since the output is 8 bits.
1537 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1538 * Since we want r*a * 0xff for eight bit output,
1539 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1541 for (x = w; x-- > 0;) {
1543 r = (*wr++ * a) / 0x10eff;
1544 g = (*wg++ * a) / 0x10eff;
1545 b = (*wb++ * a) / 0x10eff;
1546 *cp++ = PACK4(r,g,b,a);
1548 SKEW4(wr, wg, wb, wa, fromskew);
1554 * 8-bit packed CIE L*a*b 1976 samples => RGB
1556 DECLAREContigPutFunc(putcontig8bitCIELab)
1563 for (x = w; x-- > 0;) {
1564 TIFFCIELabToXYZ(img->cielab,
1565 (unsigned char)pp[0],
1569 TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
1570 *cp++ = PACK(r, g, b);
1579 * YCbCr -> RGB conversion and packing routines.
1582 #define YCbCrtoRGB(dst, Y) { \
1584 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1585 dst = PACK(r, g, b); \
1589 * 8-bit packed YCbCr samples => RGB
1590 * This function is generic for different sampling sizes,
1591 * and can handle blocks sizes that aren't multiples of the
1592 * sampling size. However, it is substantially less optimized
1593 * than the specific sampling cases. It is used as a fallback
1594 * for difficult blocks.
1597 static void putcontig8bitYCbCrGenericTile(
1602 int32 fromskew, int32 toskew,
1608 uint32* cp1 = cp+w+toskew;
1609 uint32* cp2 = cp1+w+toskew;
1610 uint32* cp3 = cp2+w+toskew;
1611 int32 incr = 3*w+4*toskew;
1613 int group_size = v_group * h_group + 2;
1616 fromskew = (fromskew * group_size) / h_group;
1618 for( yy = 0; yy < h; yy++ )
1620 unsigned char *pp_line;
1621 int y_line_group = yy / v_group;
1622 int y_remainder = yy - y_line_group * v_group;
1624 pp_line = pp + v_line_group *
1627 for( xx = 0; xx < w; xx++ )
1632 for (; h >= 4; h -= 4) {
1638 YCbCrtoRGB(cp [0], pp[ 0]);
1639 YCbCrtoRGB(cp [1], pp[ 1]);
1640 YCbCrtoRGB(cp [2], pp[ 2]);
1641 YCbCrtoRGB(cp [3], pp[ 3]);
1642 YCbCrtoRGB(cp1[0], pp[ 4]);
1643 YCbCrtoRGB(cp1[1], pp[ 5]);
1644 YCbCrtoRGB(cp1[2], pp[ 6]);
1645 YCbCrtoRGB(cp1[3], pp[ 7]);
1646 YCbCrtoRGB(cp2[0], pp[ 8]);
1647 YCbCrtoRGB(cp2[1], pp[ 9]);
1648 YCbCrtoRGB(cp2[2], pp[10]);
1649 YCbCrtoRGB(cp2[3], pp[11]);
1650 YCbCrtoRGB(cp3[0], pp[12]);
1651 YCbCrtoRGB(cp3[1], pp[13]);
1652 YCbCrtoRGB(cp3[2], pp[14]);
1653 YCbCrtoRGB(cp3[3], pp[15]);
1655 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1658 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1665 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1667 DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
1669 uint32* cp1 = cp+w+toskew;
1670 uint32* cp2 = cp1+w+toskew;
1671 uint32* cp3 = cp2+w+toskew;
1672 int32 incr = 3*w+4*toskew;
1675 /* adjust fromskew */
1676 fromskew = (fromskew * 18) / 4;
1677 if ((h & 3) == 0 && (w & 3) == 0) {
1678 for (; h >= 4; h -= 4) {
1684 YCbCrtoRGB(cp [0], pp[ 0]);
1685 YCbCrtoRGB(cp [1], pp[ 1]);
1686 YCbCrtoRGB(cp [2], pp[ 2]);
1687 YCbCrtoRGB(cp [3], pp[ 3]);
1688 YCbCrtoRGB(cp1[0], pp[ 4]);
1689 YCbCrtoRGB(cp1[1], pp[ 5]);
1690 YCbCrtoRGB(cp1[2], pp[ 6]);
1691 YCbCrtoRGB(cp1[3], pp[ 7]);
1692 YCbCrtoRGB(cp2[0], pp[ 8]);
1693 YCbCrtoRGB(cp2[1], pp[ 9]);
1694 YCbCrtoRGB(cp2[2], pp[10]);
1695 YCbCrtoRGB(cp2[3], pp[11]);
1696 YCbCrtoRGB(cp3[0], pp[12]);
1697 YCbCrtoRGB(cp3[1], pp[13]);
1698 YCbCrtoRGB(cp3[2], pp[14]);
1699 YCbCrtoRGB(cp3[3], pp[15]);
1701 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1704 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1709 for (x = w; x > 0;) {
1715 default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
1716 case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
1717 case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1718 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1722 default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
1723 case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
1724 case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1725 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1729 default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
1730 case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
1731 case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1732 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1736 default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
1737 case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
1738 case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1739 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1743 cp += x; cp1 += x; cp2 += x; cp3 += x;
1747 cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
1755 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1762 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1764 DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
1766 uint32* cp1 = cp+w+toskew;
1767 int32 incr = 2*toskew+w;
1770 fromskew = (fromskew * 10) / 4;
1771 if ((h & 3) == 0 && (w & 1) == 0) {
1772 for (; h >= 2; h -= 2) {
1778 YCbCrtoRGB(cp [0], pp[0]);
1779 YCbCrtoRGB(cp [1], pp[1]);
1780 YCbCrtoRGB(cp [2], pp[2]);
1781 YCbCrtoRGB(cp [3], pp[3]);
1782 YCbCrtoRGB(cp1[0], pp[4]);
1783 YCbCrtoRGB(cp1[1], pp[5]);
1784 YCbCrtoRGB(cp1[2], pp[6]);
1785 YCbCrtoRGB(cp1[3], pp[7]);
1790 cp += incr, cp1 += incr;
1795 for (x = w; x > 0;) {
1801 default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1802 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1806 default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1807 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1811 default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1812 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1816 default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1817 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1833 cp += incr, cp1 += incr;
1840 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1842 DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
1845 /* XXX adjust fromskew */
1852 YCbCrtoRGB(cp [0], pp[0]);
1853 YCbCrtoRGB(cp [1], pp[1]);
1854 YCbCrtoRGB(cp [2], pp[2]);
1855 YCbCrtoRGB(cp [3], pp[3]);
1867 case 3: YCbCrtoRGB(cp [2], pp[2]);
1868 case 2: YCbCrtoRGB(cp [1], pp[1]);
1869 case 1: YCbCrtoRGB(cp [0], pp[0]);
1884 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1886 DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
1888 uint32* cp1 = cp+w+toskew;
1889 int32 incr = 2*toskew+w;
1892 fromskew = (fromskew * 6) / 2;
1893 if ((h & 1) == 0 && (w & 1) == 0) {
1894 for (; h >= 2; h -= 2) {
1900 YCbCrtoRGB(cp [0], pp[0]);
1901 YCbCrtoRGB(cp [1], pp[1]);
1902 YCbCrtoRGB(cp1[0], pp[2]);
1903 YCbCrtoRGB(cp1[1], pp[3]);
1908 cp += incr, cp1 += incr;
1913 for (x = w; x > 0;) {
1919 default: YCbCrtoRGB(cp1[1], pp[ 3]); /* FALLTHROUGH */
1920 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1924 default: YCbCrtoRGB(cp1[0], pp[ 2]); /* FALLTHROUGH */
1925 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1941 cp += incr, cp1 += incr;
1948 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
1950 DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
1953 fromskew = (fromskew * 4) / 2;
1960 YCbCrtoRGB(cp[0], pp[0]);
1961 YCbCrtoRGB(cp[1], pp[1]);
1972 YCbCrtoRGB(cp [0], pp[0]);
1984 * 8-bit packed YCbCr samples w/ no subsampling => RGB
1986 DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
1991 x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
1996 YCbCrtoRGB(*cp++, pp[0]);
2006 static tileContigRoutine
2007 initYCbCrConversion(TIFFRGBAImage* img)
2009 static char module[] = "initCIELabConversion";
2011 float *luma, *refBlackWhite;
2014 if (img->ycbcr == NULL) {
2015 img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
2016 TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
2017 + 4*256*sizeof (TIFFRGBValue)
2018 + 2*256*sizeof (int)
2019 + 3*256*sizeof (int32)
2021 if (img->ycbcr == NULL) {
2023 "No space for YCbCr->RGB conversion state");
2028 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
2029 TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
2031 if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
2035 * The 6.0 spec says that subsampling must be
2036 * one of 1, 2, or 4, and that vertical subsampling
2037 * must always be <= horizontal subsampling; so
2038 * there are only a few possibilities and we just
2039 * enumerate the cases.
2041 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
2042 switch ((hs<<4)|vs) {
2043 case 0x44: return (tileContigRoutine)(putcontig8bitYCbCr44tile);
2044 case 0x42: return (tileContigRoutine)(putcontig8bitYCbCr42tile);
2045 case 0x41: return (tileContigRoutine)(putcontig8bitYCbCr41tile);
2046 case 0x22: return (tileContigRoutine)(putcontig8bitYCbCr22tile);
2047 case 0x21: return (tileContigRoutine)(putcontig8bitYCbCr21tile);
2048 case 0x11: return (tileContigRoutine)(putcontig8bitYCbCr11tile);
2054 static tileContigRoutine
2055 initCIELabConversion(TIFFRGBAImage* img)
2057 static char module[] = "initCIELabConversion";
2063 img->cielab = (TIFFCIELabToRGB *)
2064 _TIFFmalloc(sizeof(TIFFCIELabToRGB));
2067 "No space for CIE L*a*b*->RGB conversion state.");
2072 TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
2073 refWhite[1] = 100.0F;
2074 refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
2075 refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
2076 / whitePoint[1] * refWhite[1];
2077 if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
2079 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2080 _TIFFfree(img->cielab);
2084 return (tileContigRoutine)putcontig8bitCIELab;
2088 * Greyscale images with less than 8 bits/sample are handled
2089 * with a table to avoid lots of shifts and masks. The table
2090 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2091 * pixel values simply by indexing into the table with one
2095 makebwmap(TIFFRGBAImage* img)
2097 TIFFRGBValue* Map = img->Map;
2098 int bitspersample = img->bitspersample;
2099 int nsamples = 8 / bitspersample;
2106 img->BWmap = (uint32**) _TIFFmalloc(
2107 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2108 if (img->BWmap == NULL) {
2109 TIFFError(TIFFFileName(img->tif), "No space for B&W mapping table");
2112 p = (uint32*)(img->BWmap + 256);
2113 for (i = 0; i < 256; i++) {
2116 switch (bitspersample) {
2117 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2149 * Construct a mapping table to convert from the range
2150 * of the data samples to [0,255] --for display. This
2151 * process also handles inverting B&W images when needed.
2154 setupMap(TIFFRGBAImage* img)
2158 range = (int32)((1L<<img->bitspersample)-1);
2160 /* treat 16 bit the same as eight bit */
2161 if( img->bitspersample == 16 )
2162 range = (int32) 255;
2164 img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
2165 if (img->Map == NULL) {
2166 TIFFError(TIFFFileName(img->tif),
2167 "No space for photometric conversion table");
2170 if (img->photometric == PHOTOMETRIC_MINISWHITE) {
2171 for (x = 0; x <= range; x++)
2172 img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
2174 for (x = 0; x <= range; x++)
2175 img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
2177 if (img->bitspersample <= 16 &&
2178 (img->photometric == PHOTOMETRIC_MINISBLACK ||
2179 img->photometric == PHOTOMETRIC_MINISWHITE)) {
2181 * Use photometric mapping table to construct
2182 * unpacking tables for samples <= 8 bits.
2184 if (!makebwmap(img))
2186 /* no longer need Map, free it */
2187 _TIFFfree(img->Map), img->Map = NULL;
2193 checkcmap(TIFFRGBAImage* img)
2195 uint16* r = img->redcmap;
2196 uint16* g = img->greencmap;
2197 uint16* b = img->bluecmap;
2198 long n = 1L<<img->bitspersample;
2201 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
2207 cvtcmap(TIFFRGBAImage* img)
2209 uint16* r = img->redcmap;
2210 uint16* g = img->greencmap;
2211 uint16* b = img->bluecmap;
2214 for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
2215 #define CVT(x) ((uint16)((x)>>8))
2224 * Palette images with <= 8 bits/sample are handled
2225 * with a table to avoid lots of shifts and masks. The table
2226 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2227 * pixel values simply by indexing into the table with one
2231 makecmap(TIFFRGBAImage* img)
2233 int bitspersample = img->bitspersample;
2234 int nsamples = 8 / bitspersample;
2235 uint16* r = img->redcmap;
2236 uint16* g = img->greencmap;
2237 uint16* b = img->bluecmap;
2241 img->PALmap = (uint32**) _TIFFmalloc(
2242 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2243 if (img->PALmap == NULL) {
2244 TIFFError(TIFFFileName(img->tif), "No space for Palette mapping table");
2247 p = (uint32*)(img->PALmap + 256);
2248 for (i = 0; i < 256; i++) {
2251 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2252 switch (bitspersample) {
2283 * Construct any mapping table used
2284 * by the associated put routine.
2287 buildMap(TIFFRGBAImage* img)
2289 switch (img->photometric) {
2290 case PHOTOMETRIC_RGB:
2291 case PHOTOMETRIC_YCBCR:
2292 case PHOTOMETRIC_SEPARATED:
2293 if (img->bitspersample == 8)
2296 case PHOTOMETRIC_MINISBLACK:
2297 case PHOTOMETRIC_MINISWHITE:
2301 case PHOTOMETRIC_PALETTE:
2303 * Convert 16-bit colormap to 8-bit (unless it looks
2304 * like an old-style 8-bit colormap).
2306 if (checkcmap(img) == 16)
2309 TIFFWarning(TIFFFileName(img->tif), "Assuming 8-bit colormap");
2311 * Use mapping table and colormap to construct
2312 * unpacking tables for samples < 8 bits.
2314 if (img->bitspersample <= 8 && !makecmap(img))
2322 * Select the appropriate conversion routine for packed data.
2325 pickTileContigCase(TIFFRGBAImage* img)
2327 tileContigRoutine put = 0;
2329 if (buildMap(img)) {
2330 switch (img->photometric) {
2331 case PHOTOMETRIC_RGB:
2332 switch (img->bitspersample) {
2335 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2336 put = putRGBAAcontig8bittile;
2337 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2338 put = putRGBUAcontig8bittile;
2340 put = putRGBcontig8bittile;
2342 put = putRGBcontig8bitMaptile;
2345 put = putRGBcontig16bittile;
2347 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2348 put = putRGBAAcontig16bittile;
2349 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2350 put = putRGBUAcontig16bittile;
2355 case PHOTOMETRIC_SEPARATED:
2356 if (img->bitspersample == 8) {
2358 put = putRGBcontig8bitCMYKtile;
2360 put = putRGBcontig8bitCMYKMaptile;
2363 case PHOTOMETRIC_PALETTE:
2364 switch (img->bitspersample) {
2365 case 8: put = put8bitcmaptile; break;
2366 case 4: put = put4bitcmaptile; break;
2367 case 2: put = put2bitcmaptile; break;
2368 case 1: put = put1bitcmaptile; break;
2371 case PHOTOMETRIC_MINISWHITE:
2372 case PHOTOMETRIC_MINISBLACK:
2373 switch (img->bitspersample) {
2374 case 16: put = put16bitbwtile; break;
2375 case 8: put = putgreytile; break;
2376 case 4: put = put4bitbwtile; break;
2377 case 2: put = put2bitbwtile; break;
2378 case 1: put = put1bitbwtile; break;
2381 case PHOTOMETRIC_YCBCR:
2382 if (img->bitspersample == 8)
2383 put = initYCbCrConversion(img);
2385 case PHOTOMETRIC_CIELAB:
2386 if (img->bitspersample == 8)
2387 put = initCIELabConversion(img);
2391 return ((img->put.contig = put) != 0);
2395 * Select the appropriate conversion routine for unpacked data.
2397 * NB: we assume that unpacked single channel data is directed
2398 * to the "packed routines.
2401 pickTileSeparateCase(TIFFRGBAImage* img)
2403 tileSeparateRoutine put = 0;
2405 if (buildMap(img)) {
2406 switch (img->photometric) {
2407 case PHOTOMETRIC_RGB:
2408 switch (img->bitspersample) {
2411 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2412 put = putRGBAAseparate8bittile;
2413 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2414 put = putRGBUAseparate8bittile;
2416 put = putRGBseparate8bittile;
2418 put = putRGBseparate8bitMaptile;
2421 put = putRGBseparate16bittile;
2423 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2424 put = putRGBAAseparate16bittile;
2425 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2426 put = putRGBUAseparate16bittile;
2433 return ((img->put.separate = put) != 0);
2437 * Read a whole strip off data from the file, and convert to RGBA form.
2438 * If this is the last strip, then it will only contain the portion of
2439 * the strip that is actually within the image space. The result is
2440 * organized in bottom to top form.
2445 TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
2448 char emsg[1024] = "";
2451 uint32 rowsperstrip, rows_to_read;
2453 if( TIFFIsTiled( tif ) )
2455 TIFFError(TIFFFileName(tif),
2456 "Can't use TIFFReadRGBAStrip() with tiled file.");
2460 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
2461 if( (row % rowsperstrip) != 0 )
2463 TIFFError(TIFFFileName(tif),
2464 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2468 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2470 img.row_offset = row;
2473 if( row + rowsperstrip > img.height )
2474 rows_to_read = img.height - row;
2476 rows_to_read = rowsperstrip;
2478 ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
2480 TIFFRGBAImageEnd(&img);
2482 TIFFError(TIFFFileName(tif), emsg);
2490 * Read a whole tile off data from the file, and convert to RGBA form.
2491 * The returned RGBA data is organized from bottom to top of tile,
2492 * and may include zeroed areas if the tile extends off the image.
2496 TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
2499 char emsg[1024] = "";
2502 uint32 tile_xsize, tile_ysize;
2503 uint32 read_xsize, read_ysize;
2507 * Verify that our request is legal - on a tile file, and on a
2511 if( !TIFFIsTiled( tif ) )
2513 TIFFError(TIFFFileName(tif),
2514 "Can't use TIFFReadRGBATile() with stripped file.");
2518 TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
2519 TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
2520 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
2522 TIFFError(TIFFFileName(tif),
2523 "Row/col passed to TIFFReadRGBATile() must be top"
2524 "left corner of a tile.");
2529 * Setup the RGBA reader.
2532 if (!TIFFRGBAImageOK(tif, emsg)
2533 || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2534 TIFFError(TIFFFileName(tif), emsg);
2539 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2540 * edge of the image, even to fill an otherwise valid tile. So we
2541 * figure out how much we can read, and fix up the tile buffer to
2542 * a full tile configuration afterwards.
2545 if( row + tile_ysize > img.height )
2546 read_ysize = img.height - row;
2548 read_ysize = tile_ysize;
2550 if( col + tile_xsize > img.width )
2551 read_xsize = img.width - col;
2553 read_xsize = tile_xsize;
2556 * Read the chunk of imagery.
2559 img.row_offset = row;
2560 img.col_offset = col;
2562 ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
2564 TIFFRGBAImageEnd(&img);
2567 * If our read was incomplete we will need to fix up the tile by
2568 * shifting the data around as if a full tile of data is being returned.
2570 * This is all the more complicated because the image is organized in
2571 * bottom to top format.
2574 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
2577 for( i_row = 0; i_row < read_ysize; i_row++ ) {
2578 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
2579 raster + (read_ysize - i_row - 1) * read_xsize,
2580 read_xsize * sizeof(uint32) );
2581 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
2582 0, sizeof(uint32) * (tile_xsize - read_xsize) );
2585 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
2586 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
2587 0, sizeof(uint32) * tile_xsize );
2593 /* vim: set ts=8 sts=8 sw=8 noet: */