1 /* $Id: tif_getimage.c,v 1.63.2.4 2010-06-08 18:50:42 bfriesen 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 PickContigCase(TIFFRGBAImage*);
40 static int PickSeparateCase(TIFFRGBAImage*);
41 static const char photoTag[] = "PhotometricInterpretation";
44 * Helper constants used in Orientation tag handling
46 #define FLIP_VERTICALLY 0x01
47 #define FLIP_HORIZONTALLY 0x02
50 * Color conversion constants. We will define display types here.
53 TIFFDisplay display_sRGB = {
54 { /* XYZ -> luminance matrix */
55 { 3.2410F, -1.5374F, -0.4986F },
56 { -0.9692F, 1.8760F, 0.0416F },
57 { 0.0556F, -0.2040F, 1.0570F }
59 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
60 255, 255, 255, /* Pixel values for ref. white */
61 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */
62 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */
66 * Check the image to see if TIFFReadRGBAImage can deal with it.
67 * 1/0 is returned according to whether or not the image can
68 * be handled. If 0 is returned, emsg contains the reason
69 * why it is being rejected.
72 TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
74 TIFFDirectory* td = &tif->tif_dir;
78 if (!tif->tif_decodestatus) {
79 sprintf(emsg, "Sorry, requested compression method is not configured");
82 switch (td->td_bitspersample) {
90 sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
91 td->td_bitspersample);
94 colorchannels = td->td_samplesperpixel - td->td_extrasamples;
95 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
96 switch (colorchannels) {
98 photometric = PHOTOMETRIC_MINISBLACK;
101 photometric = PHOTOMETRIC_RGB;
104 sprintf(emsg, "Missing needed %s tag", photoTag);
108 switch (photometric) {
109 case PHOTOMETRIC_MINISWHITE:
110 case PHOTOMETRIC_MINISBLACK:
111 case PHOTOMETRIC_PALETTE:
112 if (td->td_planarconfig == PLANARCONFIG_CONTIG
113 && td->td_samplesperpixel != 1
114 && td->td_bitspersample < 8 ) {
116 "Sorry, can not handle contiguous data with %s=%d, "
117 "and %s=%d and Bits/Sample=%d",
118 photoTag, photometric,
119 "Samples/pixel", td->td_samplesperpixel,
120 td->td_bitspersample);
124 * We should likely validate that any extra samples are either
125 * to be ignored, or are alpha, and if alpha we should try to use
126 * them. But for now we won't bother with this.
129 case PHOTOMETRIC_YCBCR:
131 * TODO: if at all meaningful and useful, make more complete
132 * support check here, or better still, refactor to let supporting
133 * code decide whether there is support and what meaningfull
137 case PHOTOMETRIC_RGB:
138 if (colorchannels < 3) {
139 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
140 "Color channels", colorchannels);
144 case PHOTOMETRIC_SEPARATED:
147 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
148 if (inkset != INKSET_CMYK) {
150 "Sorry, can not handle separated image with %s=%d",
154 if (td->td_samplesperpixel < 4) {
156 "Sorry, can not handle separated image with %s=%d",
157 "Samples/pixel", td->td_samplesperpixel);
162 case PHOTOMETRIC_LOGL:
163 if (td->td_compression != COMPRESSION_SGILOG) {
164 sprintf(emsg, "Sorry, LogL data must have %s=%d",
165 "Compression", COMPRESSION_SGILOG);
169 case PHOTOMETRIC_LOGLUV:
170 if (td->td_compression != COMPRESSION_SGILOG &&
171 td->td_compression != COMPRESSION_SGILOG24) {
172 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
173 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
176 if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
177 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
178 "Planarconfiguration", td->td_planarconfig);
182 case PHOTOMETRIC_CIELAB:
185 sprintf(emsg, "Sorry, can not handle image with %s=%d",
186 photoTag, photometric);
193 TIFFRGBAImageEnd(TIFFRGBAImage* img)
196 _TIFFfree(img->Map), img->Map = NULL;
198 _TIFFfree(img->BWmap), img->BWmap = NULL;
200 _TIFFfree(img->PALmap), img->PALmap = NULL;
202 _TIFFfree(img->ycbcr), img->ycbcr = NULL;
204 _TIFFfree(img->cielab), img->cielab = NULL;
206 _TIFFfree( img->redcmap );
207 _TIFFfree( img->greencmap );
208 _TIFFfree( img->bluecmap );
213 isCCITTCompression(TIFF* tif)
216 TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
217 return (compress == COMPRESSION_CCITTFAX3 ||
218 compress == COMPRESSION_CCITTFAX4 ||
219 compress == COMPRESSION_CCITTRLE ||
220 compress == COMPRESSION_CCITTRLEW);
224 TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
231 uint16 *red_orig, *green_orig, *blue_orig;
234 /* Initialize to normal values */
238 img->greencmap = NULL;
239 img->bluecmap = NULL;
240 img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
243 img->stoponerr = stop;
244 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
245 switch (img->bitspersample) {
253 sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
258 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
259 TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
260 &extrasamples, &sampleinfo);
261 if (extrasamples >= 1)
263 switch (sampleinfo[0]) {
264 case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */
265 if (img->samplesperpixel > 3) /* correct info about alpha channel */
266 img->alpha = EXTRASAMPLE_ASSOCALPHA;
268 case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
269 case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
270 img->alpha = sampleinfo[0];
275 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
276 if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
277 img->photometric = PHOTOMETRIC_MINISWHITE;
279 if( extrasamples == 0
280 && img->samplesperpixel == 4
281 && img->photometric == PHOTOMETRIC_RGB )
283 img->alpha = EXTRASAMPLE_ASSOCALPHA;
288 colorchannels = img->samplesperpixel - extrasamples;
289 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
290 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
291 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
292 switch (colorchannels) {
294 if (isCCITTCompression(tif))
295 img->photometric = PHOTOMETRIC_MINISWHITE;
297 img->photometric = PHOTOMETRIC_MINISBLACK;
300 img->photometric = PHOTOMETRIC_RGB;
303 sprintf(emsg, "Missing needed %s tag", photoTag);
307 switch (img->photometric) {
308 case PHOTOMETRIC_PALETTE:
309 if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
310 &red_orig, &green_orig, &blue_orig)) {
311 sprintf(emsg, "Missing required \"Colormap\" tag");
315 /* copy the colormaps so we can modify them */
316 n_color = (1L << img->bitspersample);
317 img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
318 img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
319 img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
320 if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
321 sprintf(emsg, "Out of memory for colormap copy");
325 _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
326 _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
327 _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
330 case PHOTOMETRIC_MINISWHITE:
331 case PHOTOMETRIC_MINISBLACK:
332 if (planarconfig == PLANARCONFIG_CONTIG
333 && img->samplesperpixel != 1
334 && img->bitspersample < 8 ) {
336 "Sorry, can not handle contiguous data with %s=%d, "
337 "and %s=%d and Bits/Sample=%d",
338 photoTag, img->photometric,
339 "Samples/pixel", img->samplesperpixel,
344 case PHOTOMETRIC_YCBCR:
345 /* It would probably be nice to have a reality check here. */
346 if (planarconfig == PLANARCONFIG_CONTIG)
347 /* can rely on libjpeg to convert to RGB */
348 /* XXX should restore current state on exit */
350 case COMPRESSION_JPEG:
352 * TODO: when complete tests verify complete desubsampling
353 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
354 * favor of tif_getimage.c native handling
356 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
357 img->photometric = PHOTOMETRIC_RGB;
364 * TODO: if at all meaningful and useful, make more complete
365 * support check here, or better still, refactor to let supporting
366 * code decide whether there is support and what meaningfull
370 case PHOTOMETRIC_RGB:
371 if (colorchannels < 3) {
372 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
373 "Color channels", colorchannels);
377 case PHOTOMETRIC_SEPARATED:
380 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
381 if (inkset != INKSET_CMYK) {
382 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
386 if (img->samplesperpixel < 4) {
387 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
388 "Samples/pixel", img->samplesperpixel);
393 case PHOTOMETRIC_LOGL:
394 if (compress != COMPRESSION_SGILOG) {
395 sprintf(emsg, "Sorry, LogL data must have %s=%d",
396 "Compression", COMPRESSION_SGILOG);
399 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
400 img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
401 img->bitspersample = 8;
403 case PHOTOMETRIC_LOGLUV:
404 if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
405 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
406 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
409 if (planarconfig != PLANARCONFIG_CONTIG) {
410 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
411 "Planarconfiguration", planarconfig);
414 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
415 img->photometric = PHOTOMETRIC_RGB; /* little white lie */
416 img->bitspersample = 8;
418 case PHOTOMETRIC_CIELAB:
421 sprintf(emsg, "Sorry, can not handle image with %s=%d",
422 photoTag, img->photometric);
430 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
431 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
432 TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
434 !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
436 if (!PickContigCase(img)) {
437 sprintf(emsg, "Sorry, can not handle image");
441 if (!PickSeparateCase(img)) {
442 sprintf(emsg, "Sorry, can not handle image");
450 TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
452 if (img->get == NULL) {
453 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
456 if (img->put.any == NULL) {
457 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
458 "No \"put\" routine setupl; probably can not handle image format");
461 return (*img->get)(img, raster, w, h);
465 * Read the specified image into an ABGR-format rastertaking in account
466 * specified orientation.
469 TIFFReadRGBAImageOriented(TIFF* tif,
470 uint32 rwidth, uint32 rheight, uint32* raster,
471 int orientation, int stop)
473 char emsg[1024] = "";
477 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
478 img.req_orientation = orientation;
479 /* XXX verify rwidth and rheight against width and height */
480 ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
482 TIFFRGBAImageEnd(&img);
484 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
491 * Read the specified image into an ABGR-format raster. Use bottom left
492 * origin for raster by default.
495 TIFFReadRGBAImage(TIFF* tif,
496 uint32 rwidth, uint32 rheight, uint32* raster, int stop)
498 return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
499 ORIENTATION_BOTLEFT, stop);
503 setorientation(TIFFRGBAImage* img)
505 switch (img->orientation) {
506 case ORIENTATION_TOPLEFT:
507 case ORIENTATION_LEFTTOP:
508 if (img->req_orientation == ORIENTATION_TOPRIGHT ||
509 img->req_orientation == ORIENTATION_RIGHTTOP)
510 return FLIP_HORIZONTALLY;
511 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
512 img->req_orientation == ORIENTATION_RIGHTBOT)
513 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
514 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
515 img->req_orientation == ORIENTATION_LEFTBOT)
516 return FLIP_VERTICALLY;
519 case ORIENTATION_TOPRIGHT:
520 case ORIENTATION_RIGHTTOP:
521 if (img->req_orientation == ORIENTATION_TOPLEFT ||
522 img->req_orientation == ORIENTATION_LEFTTOP)
523 return FLIP_HORIZONTALLY;
524 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
525 img->req_orientation == ORIENTATION_RIGHTBOT)
526 return FLIP_VERTICALLY;
527 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
528 img->req_orientation == ORIENTATION_LEFTBOT)
529 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
532 case ORIENTATION_BOTRIGHT:
533 case ORIENTATION_RIGHTBOT:
534 if (img->req_orientation == ORIENTATION_TOPLEFT ||
535 img->req_orientation == ORIENTATION_LEFTTOP)
536 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
537 else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
538 img->req_orientation == ORIENTATION_RIGHTTOP)
539 return FLIP_VERTICALLY;
540 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
541 img->req_orientation == ORIENTATION_LEFTBOT)
542 return FLIP_HORIZONTALLY;
545 case ORIENTATION_BOTLEFT:
546 case ORIENTATION_LEFTBOT:
547 if (img->req_orientation == ORIENTATION_TOPLEFT ||
548 img->req_orientation == ORIENTATION_LEFTTOP)
549 return FLIP_VERTICALLY;
550 else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
551 img->req_orientation == ORIENTATION_RIGHTTOP)
552 return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
553 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
554 img->req_orientation == ORIENTATION_RIGHTBOT)
555 return FLIP_HORIZONTALLY;
558 default: /* NOTREACHED */
564 * Get an tile-organized image that has
565 * PlanarConfiguration contiguous if SamplesPerPixel > 1
567 * SamplesPerPixel == 1
570 gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
572 TIFF* tif = img->tif;
573 tileContigRoutine put = img->put.contig;
574 uint32 col, row, y, rowstoread;
578 int32 fromskew, toskew;
582 buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
584 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
587 _TIFFmemset(buf, 0, TIFFTileSize(tif));
588 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
589 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
591 flip = setorientation(img);
592 if (flip & FLIP_VERTICALLY) {
594 toskew = -(int32)(tw + w);
598 toskew = -(int32)(tw - w);
601 for (row = 0; row < h; row += nrow)
603 rowstoread = th - (row + img->row_offset) % th;
604 nrow = (row + rowstoread > h ? h - row : rowstoread);
605 for (col = 0; col < w; col += tw)
607 if (TIFFReadTile(tif, buf, col+img->col_offset,
608 row+img->row_offset, 0, 0) < 0 && img->stoponerr)
614 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
619 * Tile is clipped horizontally. Calculate
620 * visible portion and skewing factors.
622 uint32 npix = w - col;
623 fromskew = tw - npix;
624 (*put)(img, raster+y*w+col, col, y,
625 npix, nrow, fromskew, toskew + fromskew, buf + pos);
629 (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
633 y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
637 if (flip & FLIP_HORIZONTALLY) {
640 for (line = 0; line < h; line++) {
641 uint32 *left = raster + (line * w);
642 uint32 *right = left + w - 1;
644 while ( left < right ) {
657 * Get an tile-organized image that has
658 * SamplesPerPixel > 1
659 * PlanarConfiguration separated
660 * We assume that all such images are RGB.
663 gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
665 TIFF* tif = img->tif;
666 tileSeparateRoutine put = img->put.separate;
667 uint32 col, row, y, rowstoread;
676 int32 fromskew, toskew;
677 int alpha = img->alpha;
681 tilesize = TIFFTileSize(tif);
682 buf = (unsigned char*) _TIFFmalloc((alpha?4:3)*tilesize);
684 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
687 _TIFFmemset(buf, 0, (alpha?4:3)*tilesize);
691 pa = (alpha?(p2+tilesize):NULL);
692 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
693 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
695 flip = setorientation(img);
696 if (flip & FLIP_VERTICALLY) {
698 toskew = -(int32)(tw + w);
702 toskew = -(int32)(tw - w);
705 for (row = 0; row < h; row += nrow)
707 rowstoread = th - (row + img->row_offset) % th;
708 nrow = (row + rowstoread > h ? h - row : rowstoread);
709 for (col = 0; col < w; col += tw)
711 if (TIFFReadTile(tif, p0, col+img->col_offset,
712 row+img->row_offset,0,0) < 0 && img->stoponerr)
717 if (TIFFReadTile(tif, p1, col+img->col_offset,
718 row+img->row_offset,0,1) < 0 && img->stoponerr)
723 if (TIFFReadTile(tif, p2, col+img->col_offset,
724 row+img->row_offset,0,2) < 0 && img->stoponerr)
731 if (TIFFReadTile(tif,pa,col+img->col_offset,
732 row+img->row_offset,0,3) < 0 && img->stoponerr)
739 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
744 * Tile is clipped horizontally. Calculate
745 * visible portion and skewing factors.
747 uint32 npix = w - col;
748 fromskew = tw - npix;
749 (*put)(img, raster+y*w+col, col, y,
750 npix, nrow, fromskew, toskew + fromskew,
751 p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
753 (*put)(img, raster+y*w+col, col, y,
754 tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
758 y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
761 if (flip & FLIP_HORIZONTALLY) {
764 for (line = 0; line < h; line++) {
765 uint32 *left = raster + (line * w);
766 uint32 *right = left + w - 1;
768 while ( left < right ) {
782 * Get a strip-organized image that has
783 * PlanarConfiguration contiguous if SamplesPerPixel > 1
785 * SamplesPerPixel == 1
788 gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
790 TIFF* tif = img->tif;
791 tileContigRoutine put = img->put.contig;
792 uint32 row, y, nrow, nrowsub, rowstoread;
796 uint16 subsamplinghor,subsamplingver;
797 uint32 imagewidth = img->width;
799 int32 fromskew, toskew;
802 buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
804 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
807 _TIFFmemset(buf, 0, TIFFStripSize(tif));
809 flip = setorientation(img);
810 if (flip & FLIP_VERTICALLY) {
812 toskew = -(int32)(w + w);
815 toskew = -(int32)(w - w);
818 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
819 TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
820 scanline = TIFFNewScanlineSize(tif);
821 fromskew = (w < imagewidth ? imagewidth - w : 0);
822 for (row = 0; row < h; row += nrow)
824 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
825 nrow = (row + rowstoread > h ? h - row : rowstoread);
827 if ((nrowsub%subsamplingver)!=0)
828 nrowsub+=subsamplingver-nrowsub%subsamplingver;
829 if (TIFFReadEncodedStrip(tif,
830 TIFFComputeStrip(tif,row+img->row_offset, 0),
832 ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline) < 0
839 pos = ((row + img->row_offset) % rowsperstrip) * scanline;
840 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
841 y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
844 if (flip & FLIP_HORIZONTALLY) {
847 for (line = 0; line < h; line++) {
848 uint32 *left = raster + (line * w);
849 uint32 *right = left + w - 1;
851 while ( left < right ) {
865 * Get a strip-organized image with
866 * SamplesPerPixel > 1
867 * PlanarConfiguration separated
868 * We assume that all such images are RGB.
871 gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
873 TIFF* tif = img->tif;
874 tileSeparateRoutine put = img->put.separate;
876 unsigned char *p0, *p1, *p2, *pa;
877 uint32 row, y, nrow, rowstoread;
880 uint32 rowsperstrip, offset_row;
881 uint32 imagewidth = img->width;
883 int32 fromskew, toskew;
884 int alpha = img->alpha;
887 stripsize = TIFFStripSize(tif);
888 p0 = buf = (unsigned char *)_TIFFmalloc((alpha?4:3)*stripsize);
890 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
893 _TIFFmemset(buf, 0, (alpha?4:3)*stripsize);
896 pa = (alpha?(p2+stripsize):NULL);
898 flip = setorientation(img);
899 if (flip & FLIP_VERTICALLY) {
901 toskew = -(int32)(w + w);
905 toskew = -(int32)(w - w);
908 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
909 scanline = TIFFScanlineSize(tif);
910 fromskew = (w < imagewidth ? imagewidth - w : 0);
911 for (row = 0; row < h; row += nrow)
913 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
914 nrow = (row + rowstoread > h ? h - row : rowstoread);
915 offset_row = row + img->row_offset;
916 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
917 p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
923 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
924 p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
930 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
931 p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
939 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3),
940 pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
948 pos = ((row + img->row_offset) % rowsperstrip) * scanline;
949 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
950 p2 + pos, (alpha?(pa+pos):NULL));
951 y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
954 if (flip & FLIP_HORIZONTALLY) {
957 for (line = 0; line < h; line++) {
958 uint32 *left = raster + (line * w);
959 uint32 *right = left + w - 1;
961 while ( left < right ) {
975 * The following routines move decoded data returned
976 * from the TIFF library into rasters filled with packed
977 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
979 * The routines have been created according to the most
980 * important cases and optimized. PickContigCase and
981 * PickSeparateCase analyze the parameters and select
982 * the appropriate "get" and "put" routine to use.
984 #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
985 #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
986 #define REPEAT2(op) op; op
987 #define CASE8(x,op) \
989 case 7: op; case 6: op; case 5: op; \
990 case 4: op; case 3: op; case 2: op; \
993 #define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
996 #define UNROLL8(w, op1, op2) { \
998 for (_x = w; _x >= 8; _x -= 8) { \
1007 #define UNROLL4(w, op1, op2) { \
1009 for (_x = w; _x >= 4; _x -= 4) { \
1018 #define UNROLL2(w, op1, op2) { \
1020 for (_x = w; _x >= 2; _x -= 2) { \
1030 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1031 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1033 #define A1 (((uint32)0xffL)<<24)
1034 #define PACK(r,g,b) \
1035 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1036 #define PACK4(r,g,b,a) \
1037 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1038 #define W2B(v) (((v)>>8)&0xff)
1039 #define PACKW(r,g,b) \
1040 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1041 #define PACKW4(r,g,b,a) \
1042 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1044 #define DECLAREContigPutFunc(name) \
1046 TIFFRGBAImage* img, \
1048 uint32 x, uint32 y, \
1049 uint32 w, uint32 h, \
1050 int32 fromskew, int32 toskew, \
1055 * 8-bit palette => colormap/RGB
1057 DECLAREContigPutFunc(put8bitcmaptile)
1059 uint32** PALmap = img->PALmap;
1060 int samplesperpixel = img->samplesperpixel;
1064 for (x = w; x-- > 0;)
1066 *cp++ = PALmap[*pp][0];
1067 pp += samplesperpixel;
1075 * 4-bit palette => colormap/RGB
1077 DECLAREContigPutFunc(put4bitcmaptile)
1079 uint32** PALmap = img->PALmap;
1085 UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
1092 * 2-bit palette => colormap/RGB
1094 DECLAREContigPutFunc(put2bitcmaptile)
1096 uint32** PALmap = img->PALmap;
1102 UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
1109 * 1-bit palette => colormap/RGB
1111 DECLAREContigPutFunc(put1bitcmaptile)
1113 uint32** PALmap = img->PALmap;
1119 UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
1126 * 8-bit greyscale => colormap/RGB
1128 DECLAREContigPutFunc(putgreytile)
1130 int samplesperpixel = img->samplesperpixel;
1131 uint32** BWmap = img->BWmap;
1135 for (x = w; x-- > 0;)
1137 *cp++ = BWmap[*pp][0];
1138 pp += samplesperpixel;
1146 * 16-bit greyscale => colormap/RGB
1148 DECLAREContigPutFunc(put16bitbwtile)
1150 int samplesperpixel = img->samplesperpixel;
1151 uint32** BWmap = img->BWmap;
1155 uint16 *wp = (uint16 *) pp;
1157 for (x = w; x-- > 0;)
1159 /* use high order byte of 16bit value */
1161 *cp++ = BWmap[*wp >> 8][0];
1162 pp += 2 * samplesperpixel;
1163 wp += samplesperpixel;
1171 * 1-bit bilevel => colormap/RGB
1173 DECLAREContigPutFunc(put1bitbwtile)
1175 uint32** BWmap = img->BWmap;
1181 UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
1188 * 2-bit greyscale => colormap/RGB
1190 DECLAREContigPutFunc(put2bitbwtile)
1192 uint32** BWmap = img->BWmap;
1198 UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
1205 * 4-bit greyscale => colormap/RGB
1207 DECLAREContigPutFunc(put4bitbwtile)
1209 uint32** BWmap = img->BWmap;
1215 UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
1222 * 8-bit packed samples, no Map => RGB
1224 DECLAREContigPutFunc(putRGBcontig8bittile)
1226 int samplesperpixel = img->samplesperpixel;
1229 fromskew *= samplesperpixel;
1232 *cp++ = PACK(pp[0], pp[1], pp[2]);
1233 pp += samplesperpixel);
1240 * 8-bit packed samples => RGBA w/ associated alpha
1241 * (known to have Map == NULL)
1243 DECLAREContigPutFunc(putRGBAAcontig8bittile)
1245 int samplesperpixel = img->samplesperpixel;
1248 fromskew *= samplesperpixel;
1251 *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
1252 pp += samplesperpixel);
1259 * 8-bit packed samples => RGBA w/ unassociated alpha
1260 * (known to have Map == NULL)
1262 DECLAREContigPutFunc(putRGBUAcontig8bittile)
1264 int samplesperpixel = img->samplesperpixel;
1266 fromskew *= samplesperpixel;
1269 for (x = w; x-- > 0;) {
1271 r = (a*pp[0] + 127) / 255;
1272 g = (a*pp[1] + 127) / 255;
1273 b = (a*pp[2] + 127) / 255;
1274 *cp++ = PACK4(r,g,b,a);
1275 pp += samplesperpixel;
1283 * 16-bit packed samples => RGB
1285 DECLAREContigPutFunc(putRGBcontig16bittile)
1287 int samplesperpixel = img->samplesperpixel;
1288 uint16 *wp = (uint16 *)pp;
1290 fromskew *= samplesperpixel;
1292 for (x = w; x-- > 0;) {
1293 *cp++ = PACKW(wp[0],wp[1],wp[2]);
1294 wp += samplesperpixel;
1302 * 16-bit packed samples => RGBA w/ associated alpha
1303 * (known to have Map == NULL)
1305 DECLAREContigPutFunc(putRGBAAcontig16bittile)
1307 int samplesperpixel = img->samplesperpixel;
1308 uint16 *wp = (uint16 *)pp;
1310 fromskew *= samplesperpixel;
1312 for (x = w; x-- > 0;) {
1313 *cp++ = PACKW4(wp[0],wp[1],wp[2],wp[3]);
1314 wp += samplesperpixel;
1322 * 16-bit packed samples => RGBA w/ unassociated alpha
1323 * (known to have Map == NULL)
1325 DECLAREContigPutFunc(putRGBUAcontig16bittile)
1327 int samplesperpixel = img->samplesperpixel;
1328 uint16 *wp = (uint16 *)pp;
1330 fromskew *= samplesperpixel;
1333 for (x = w; x-- > 0;) {
1335 r = (a*W2B(wp[0]) + 127) / 255;
1336 g = (a*W2B(wp[1]) + 127) / 255;
1337 b = (a*W2B(wp[2]) + 127) / 255;
1338 *cp++ = PACK4(r,g,b,a);
1339 wp += samplesperpixel;
1347 * 8-bit packed CMYK samples w/o Map => RGB
1349 * NB: The conversion of CMYK->RGB is *very* crude.
1351 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
1353 int samplesperpixel = img->samplesperpixel;
1357 fromskew *= samplesperpixel;
1361 r = (k*(255-pp[0]))/255;
1362 g = (k*(255-pp[1]))/255;
1363 b = (k*(255-pp[2]))/255;
1364 *cp++ = PACK(r, g, b);
1365 pp += samplesperpixel);
1372 * 8-bit packed CMYK samples w/Map => RGB
1374 * NB: The conversion of CMYK->RGB is *very* crude.
1376 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
1378 int samplesperpixel = img->samplesperpixel;
1379 TIFFRGBValue* Map = img->Map;
1383 fromskew *= samplesperpixel;
1385 for (x = w; x-- > 0;) {
1387 r = (k*(255-pp[0]))/255;
1388 g = (k*(255-pp[1]))/255;
1389 b = (k*(255-pp[2]))/255;
1390 *cp++ = PACK(Map[r], Map[g], Map[b]);
1391 pp += samplesperpixel;
1398 #define DECLARESepPutFunc(name) \
1400 TIFFRGBAImage* img,\
1402 uint32 x, uint32 y, \
1403 uint32 w, uint32 h,\
1404 int32 fromskew, int32 toskew,\
1405 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1409 * 8-bit unpacked samples => RGB
1411 DECLARESepPutFunc(putRGBseparate8bittile)
1413 (void) img; (void) x; (void) y; (void) a;
1415 UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
1416 SKEW(r, g, b, fromskew);
1422 * 8-bit unpacked samples => RGBA w/ associated alpha
1424 DECLARESepPutFunc(putRGBAAseparate8bittile)
1426 (void) img; (void) x; (void) y;
1428 UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
1429 SKEW4(r, g, b, a, fromskew);
1435 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1437 DECLARESepPutFunc(putRGBUAseparate8bittile)
1439 (void) img; (void) y;
1441 uint32 rv, gv, bv, av;
1442 for (x = w; x-- > 0;) {
1444 rv = (av* *r++ + 127) / 255;
1445 gv = (av* *g++ + 127) / 255;
1446 bv = (av* *b++ + 127) / 255;
1447 *cp++ = PACK4(rv,gv,bv,av);
1449 SKEW4(r, g, b, a, fromskew);
1455 * 16-bit unpacked samples => RGB
1457 DECLARESepPutFunc(putRGBseparate16bittile)
1459 uint16 *wr = (uint16*) r;
1460 uint16 *wg = (uint16*) g;
1461 uint16 *wb = (uint16*) b;
1462 (void) img; (void) y; (void) a;
1464 for (x = 0; x < w; x++)
1465 *cp++ = PACKW(*wr++,*wg++,*wb++);
1466 SKEW(wr, wg, wb, fromskew);
1472 * 16-bit unpacked samples => RGBA w/ associated alpha
1474 DECLARESepPutFunc(putRGBAAseparate16bittile)
1476 uint16 *wr = (uint16*) r;
1477 uint16 *wg = (uint16*) g;
1478 uint16 *wb = (uint16*) b;
1479 uint16 *wa = (uint16*) a;
1480 (void) img; (void) y;
1482 for (x = 0; x < w; x++)
1483 *cp++ = PACKW4(*wr++,*wg++,*wb++,*wa++);
1484 SKEW4(wr, wg, wb, wa, fromskew);
1490 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1492 DECLARESepPutFunc(putRGBUAseparate16bittile)
1494 uint16 *wr = (uint16*) r;
1495 uint16 *wg = (uint16*) g;
1496 uint16 *wb = (uint16*) b;
1497 uint16 *wa = (uint16*) a;
1498 (void) img; (void) y;
1501 for (x = w; x-- > 0;) {
1503 r = (a*W2B(*wr++) + 127) / 255;
1504 g = (a*W2B(*wg++) + 127) / 255;
1505 b = (a*W2B(*wb++) + 127) / 255;
1506 *cp++ = PACK4(r,g,b,a);
1508 SKEW4(wr, wg, wb, wa, fromskew);
1514 * 8-bit packed CIE L*a*b 1976 samples => RGB
1516 DECLAREContigPutFunc(putcontig8bitCIELab)
1523 for (x = w; x-- > 0;) {
1524 TIFFCIELabToXYZ(img->cielab,
1525 (unsigned char)pp[0],
1529 TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
1530 *cp++ = PACK(r, g, b);
1539 * YCbCr -> RGB conversion and packing routines.
1542 #define YCbCrtoRGB(dst, Y) { \
1544 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1545 dst = PACK(r, g, b); \
1549 * 8-bit packed YCbCr samples => RGB
1550 * This function is generic for different sampling sizes,
1551 * and can handle blocks sizes that aren't multiples of the
1552 * sampling size. However, it is substantially less optimized
1553 * than the specific sampling cases. It is used as a fallback
1554 * for difficult blocks.
1557 static void putcontig8bitYCbCrGenericTile(
1562 int32 fromskew, int32 toskew,
1568 uint32* cp1 = cp+w+toskew;
1569 uint32* cp2 = cp1+w+toskew;
1570 uint32* cp3 = cp2+w+toskew;
1571 int32 incr = 3*w+4*toskew;
1573 int group_size = v_group * h_group + 2;
1576 fromskew = (fromskew * group_size) / h_group;
1578 for( yy = 0; yy < h; yy++ )
1580 unsigned char *pp_line;
1581 int y_line_group = yy / v_group;
1582 int y_remainder = yy - y_line_group * v_group;
1584 pp_line = pp + v_line_group *
1587 for( xx = 0; xx < w; xx++ )
1592 for (; h >= 4; h -= 4) {
1598 YCbCrtoRGB(cp [0], pp[ 0]);
1599 YCbCrtoRGB(cp [1], pp[ 1]);
1600 YCbCrtoRGB(cp [2], pp[ 2]);
1601 YCbCrtoRGB(cp [3], pp[ 3]);
1602 YCbCrtoRGB(cp1[0], pp[ 4]);
1603 YCbCrtoRGB(cp1[1], pp[ 5]);
1604 YCbCrtoRGB(cp1[2], pp[ 6]);
1605 YCbCrtoRGB(cp1[3], pp[ 7]);
1606 YCbCrtoRGB(cp2[0], pp[ 8]);
1607 YCbCrtoRGB(cp2[1], pp[ 9]);
1608 YCbCrtoRGB(cp2[2], pp[10]);
1609 YCbCrtoRGB(cp2[3], pp[11]);
1610 YCbCrtoRGB(cp3[0], pp[12]);
1611 YCbCrtoRGB(cp3[1], pp[13]);
1612 YCbCrtoRGB(cp3[2], pp[14]);
1613 YCbCrtoRGB(cp3[3], pp[15]);
1615 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1618 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1625 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1627 DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
1629 uint32* cp1 = cp+w+toskew;
1630 uint32* cp2 = cp1+w+toskew;
1631 uint32* cp3 = cp2+w+toskew;
1632 int32 incr = 3*w+4*toskew;
1635 /* adjust fromskew */
1636 fromskew = (fromskew * 18) / 4;
1637 if ((h & 3) == 0 && (w & 3) == 0) {
1638 for (; h >= 4; h -= 4) {
1644 YCbCrtoRGB(cp [0], pp[ 0]);
1645 YCbCrtoRGB(cp [1], pp[ 1]);
1646 YCbCrtoRGB(cp [2], pp[ 2]);
1647 YCbCrtoRGB(cp [3], pp[ 3]);
1648 YCbCrtoRGB(cp1[0], pp[ 4]);
1649 YCbCrtoRGB(cp1[1], pp[ 5]);
1650 YCbCrtoRGB(cp1[2], pp[ 6]);
1651 YCbCrtoRGB(cp1[3], pp[ 7]);
1652 YCbCrtoRGB(cp2[0], pp[ 8]);
1653 YCbCrtoRGB(cp2[1], pp[ 9]);
1654 YCbCrtoRGB(cp2[2], pp[10]);
1655 YCbCrtoRGB(cp2[3], pp[11]);
1656 YCbCrtoRGB(cp3[0], pp[12]);
1657 YCbCrtoRGB(cp3[1], pp[13]);
1658 YCbCrtoRGB(cp3[2], pp[14]);
1659 YCbCrtoRGB(cp3[3], pp[15]);
1661 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1664 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1669 for (x = w; x > 0;) {
1675 default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
1676 case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
1677 case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1678 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1682 default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
1683 case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
1684 case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1685 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1689 default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
1690 case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
1691 case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1692 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1696 default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
1697 case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
1698 case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1699 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1703 cp += x; cp1 += x; cp2 += x; cp3 += x;
1707 cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
1715 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1722 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1724 DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
1726 uint32* cp1 = cp+w+toskew;
1727 int32 incr = 2*toskew+w;
1730 fromskew = (fromskew * 10) / 4;
1731 if ((h & 3) == 0 && (w & 1) == 0) {
1732 for (; h >= 2; h -= 2) {
1738 YCbCrtoRGB(cp [0], pp[0]);
1739 YCbCrtoRGB(cp [1], pp[1]);
1740 YCbCrtoRGB(cp [2], pp[2]);
1741 YCbCrtoRGB(cp [3], pp[3]);
1742 YCbCrtoRGB(cp1[0], pp[4]);
1743 YCbCrtoRGB(cp1[1], pp[5]);
1744 YCbCrtoRGB(cp1[2], pp[6]);
1745 YCbCrtoRGB(cp1[3], pp[7]);
1750 cp += incr, cp1 += incr;
1755 for (x = w; x > 0;) {
1761 default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1762 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1766 default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1767 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1771 default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1772 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1776 default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1777 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1793 cp += incr, cp1 += incr;
1800 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1802 DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
1805 /* XXX adjust fromskew */
1812 YCbCrtoRGB(cp [0], pp[0]);
1813 YCbCrtoRGB(cp [1], pp[1]);
1814 YCbCrtoRGB(cp [2], pp[2]);
1815 YCbCrtoRGB(cp [3], pp[3]);
1827 case 3: YCbCrtoRGB(cp [2], pp[2]);
1828 case 2: YCbCrtoRGB(cp [1], pp[1]);
1829 case 1: YCbCrtoRGB(cp [0], pp[0]);
1844 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1846 DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
1850 fromskew = (fromskew / 2) * 6;
1857 YCbCrtoRGB(cp[0], pp[0]);
1858 YCbCrtoRGB(cp[1], pp[1]);
1859 YCbCrtoRGB(cp2[0], pp[2]);
1860 YCbCrtoRGB(cp2[1], pp[3]);
1869 YCbCrtoRGB(cp[0], pp[0]);
1870 YCbCrtoRGB(cp2[0], pp[2]);
1885 YCbCrtoRGB(cp[0], pp[0]);
1886 YCbCrtoRGB(cp[1], pp[1]);
1895 YCbCrtoRGB(cp[0], pp[0]);
1901 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
1903 DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
1906 fromskew = (fromskew * 4) / 2;
1913 YCbCrtoRGB(cp[0], pp[0]);
1914 YCbCrtoRGB(cp[1], pp[1]);
1925 YCbCrtoRGB(cp[0], pp[0]);
1937 * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
1939 DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
1943 fromskew = (fromskew / 2) * 4;
1950 YCbCrtoRGB(cp[0], pp[0]);
1951 YCbCrtoRGB(cp2[0], pp[1]);
1966 YCbCrtoRGB(cp[0], pp[0]);
1974 * 8-bit packed YCbCr samples w/ no subsampling => RGB
1976 DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
1981 x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
1986 YCbCrtoRGB(*cp++, pp[0]);
1996 * 8-bit packed YCbCr samples w/ no subsampling => RGB
1998 DECLARESepPutFunc(putseparate8bitYCbCr11tile)
2002 /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2007 TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
2008 *cp++ = PACK(dr,dg,db);
2010 SKEW(r, g, b, fromskew);
2017 initYCbCrConversion(TIFFRGBAImage* img)
2019 static char module[] = "initYCbCrConversion";
2021 float *luma, *refBlackWhite;
2023 if (img->ycbcr == NULL) {
2024 img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
2025 TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
2026 + 4*256*sizeof (TIFFRGBValue)
2027 + 2*256*sizeof (int)
2028 + 3*256*sizeof (int32)
2030 if (img->ycbcr == NULL) {
2031 TIFFErrorExt(img->tif->tif_clientdata, module,
2032 "No space for YCbCr->RGB conversion state");
2037 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
2038 TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
2040 if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
2045 static tileContigRoutine
2046 initCIELabConversion(TIFFRGBAImage* img)
2048 static char module[] = "initCIELabConversion";
2054 img->cielab = (TIFFCIELabToRGB *)
2055 _TIFFmalloc(sizeof(TIFFCIELabToRGB));
2057 TIFFErrorExt(img->tif->tif_clientdata, module,
2058 "No space for CIE L*a*b*->RGB conversion state.");
2063 TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
2064 refWhite[1] = 100.0F;
2065 refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
2066 refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
2067 / whitePoint[1] * refWhite[1];
2068 if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
2069 TIFFErrorExt(img->tif->tif_clientdata, module,
2070 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2071 _TIFFfree(img->cielab);
2075 return putcontig8bitCIELab;
2079 * Greyscale images with less than 8 bits/sample are handled
2080 * with a table to avoid lots of shifts and masks. The table
2081 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2082 * pixel values simply by indexing into the table with one
2086 makebwmap(TIFFRGBAImage* img)
2088 TIFFRGBValue* Map = img->Map;
2089 int bitspersample = img->bitspersample;
2090 int nsamples = 8 / bitspersample;
2097 img->BWmap = (uint32**) _TIFFmalloc(
2098 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2099 if (img->BWmap == NULL) {
2100 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
2103 p = (uint32*)(img->BWmap + 256);
2104 for (i = 0; i < 256; i++) {
2107 switch (bitspersample) {
2108 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2140 * Construct a mapping table to convert from the range
2141 * of the data samples to [0,255] --for display. This
2142 * process also handles inverting B&W images when needed.
2145 setupMap(TIFFRGBAImage* img)
2149 range = (int32)((1L<<img->bitspersample)-1);
2151 /* treat 16 bit the same as eight bit */
2152 if( img->bitspersample == 16 )
2153 range = (int32) 255;
2155 img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
2156 if (img->Map == NULL) {
2157 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
2158 "No space for photometric conversion table");
2161 if (img->photometric == PHOTOMETRIC_MINISWHITE) {
2162 for (x = 0; x <= range; x++)
2163 img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
2165 for (x = 0; x <= range; x++)
2166 img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
2168 if (img->bitspersample <= 16 &&
2169 (img->photometric == PHOTOMETRIC_MINISBLACK ||
2170 img->photometric == PHOTOMETRIC_MINISWHITE)) {
2172 * Use photometric mapping table to construct
2173 * unpacking tables for samples <= 8 bits.
2175 if (!makebwmap(img))
2177 /* no longer need Map, free it */
2178 _TIFFfree(img->Map), img->Map = NULL;
2184 checkcmap(TIFFRGBAImage* img)
2186 uint16* r = img->redcmap;
2187 uint16* g = img->greencmap;
2188 uint16* b = img->bluecmap;
2189 long n = 1L<<img->bitspersample;
2192 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
2198 cvtcmap(TIFFRGBAImage* img)
2200 uint16* r = img->redcmap;
2201 uint16* g = img->greencmap;
2202 uint16* b = img->bluecmap;
2205 for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
2206 #define CVT(x) ((uint16)((x)>>8))
2215 * Palette images with <= 8 bits/sample are handled
2216 * with a table to avoid lots of shifts and masks. The table
2217 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2218 * pixel values simply by indexing into the table with one
2222 makecmap(TIFFRGBAImage* img)
2224 int bitspersample = img->bitspersample;
2225 int nsamples = 8 / bitspersample;
2226 uint16* r = img->redcmap;
2227 uint16* g = img->greencmap;
2228 uint16* b = img->bluecmap;
2232 img->PALmap = (uint32**) _TIFFmalloc(
2233 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2234 if (img->PALmap == NULL) {
2235 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
2238 p = (uint32*)(img->PALmap + 256);
2239 for (i = 0; i < 256; i++) {
2242 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2243 switch (bitspersample) {
2274 * Construct any mapping table used
2275 * by the associated put routine.
2278 buildMap(TIFFRGBAImage* img)
2280 switch (img->photometric) {
2281 case PHOTOMETRIC_RGB:
2282 case PHOTOMETRIC_YCBCR:
2283 case PHOTOMETRIC_SEPARATED:
2284 if (img->bitspersample == 8)
2287 case PHOTOMETRIC_MINISBLACK:
2288 case PHOTOMETRIC_MINISWHITE:
2292 case PHOTOMETRIC_PALETTE:
2294 * Convert 16-bit colormap to 8-bit (unless it looks
2295 * like an old-style 8-bit colormap).
2297 if (checkcmap(img) == 16)
2300 TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
2302 * Use mapping table and colormap to construct
2303 * unpacking tables for samples < 8 bits.
2305 if (img->bitspersample <= 8 && !makecmap(img))
2313 * Select the appropriate conversion routine for packed data.
2316 PickContigCase(TIFFRGBAImage* img)
2318 img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
2319 img->put.contig = NULL;
2320 switch (img->photometric) {
2321 case PHOTOMETRIC_RGB:
2322 switch (img->bitspersample) {
2324 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2325 img->put.contig = putRGBAAcontig8bittile;
2326 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2328 img->put.contig = putRGBUAcontig8bittile;
2331 img->put.contig = putRGBcontig8bittile;
2334 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2336 img->put.contig = putRGBAAcontig16bittile;
2338 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2340 img->put.contig = putRGBUAcontig16bittile;
2344 img->put.contig = putRGBcontig16bittile;
2349 case PHOTOMETRIC_SEPARATED:
2350 if (buildMap(img)) {
2351 if (img->bitspersample == 8) {
2353 img->put.contig = putRGBcontig8bitCMYKtile;
2355 img->put.contig = putRGBcontig8bitCMYKMaptile;
2359 case PHOTOMETRIC_PALETTE:
2360 if (buildMap(img)) {
2361 switch (img->bitspersample) {
2363 img->put.contig = put8bitcmaptile;
2366 img->put.contig = put4bitcmaptile;
2369 img->put.contig = put2bitcmaptile;
2372 img->put.contig = put1bitcmaptile;
2377 case PHOTOMETRIC_MINISWHITE:
2378 case PHOTOMETRIC_MINISBLACK:
2379 if (buildMap(img)) {
2380 switch (img->bitspersample) {
2382 img->put.contig = put16bitbwtile;
2385 img->put.contig = putgreytile;
2388 img->put.contig = put4bitbwtile;
2391 img->put.contig = put2bitbwtile;
2394 img->put.contig = put1bitbwtile;
2399 case PHOTOMETRIC_YCBCR:
2400 if (img->bitspersample == 8)
2402 if (initYCbCrConversion(img)!=0)
2405 * The 6.0 spec says that subsampling must be
2406 * one of 1, 2, or 4, and that vertical subsampling
2407 * must always be <= horizontal subsampling; so
2408 * there are only a few possibilities and we just
2409 * enumerate the cases.
2410 * Joris: added support for the [1,2] case, nonetheless, to accomodate
2413 uint16 SubsamplingHor;
2414 uint16 SubsamplingVer;
2415 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
2416 switch ((SubsamplingHor<<4)|SubsamplingVer) {
2418 img->put.contig = putcontig8bitYCbCr44tile;
2421 img->put.contig = putcontig8bitYCbCr42tile;
2424 img->put.contig = putcontig8bitYCbCr41tile;
2427 img->put.contig = putcontig8bitYCbCr22tile;
2430 img->put.contig = putcontig8bitYCbCr21tile;
2433 img->put.contig = putcontig8bitYCbCr12tile;
2436 img->put.contig = putcontig8bitYCbCr11tile;
2442 case PHOTOMETRIC_CIELAB:
2443 if (buildMap(img)) {
2444 if (img->bitspersample == 8)
2445 img->put.contig = initCIELabConversion(img);
2449 return ((img->get!=NULL) && (img->put.contig!=NULL));
2453 * Select the appropriate conversion routine for unpacked data.
2455 * NB: we assume that unpacked single channel data is directed
2456 * to the "packed routines.
2459 PickSeparateCase(TIFFRGBAImage* img)
2461 img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
2462 img->put.separate = NULL;
2463 switch (img->photometric) {
2464 case PHOTOMETRIC_RGB:
2465 switch (img->bitspersample) {
2467 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2468 img->put.separate = putRGBAAseparate8bittile;
2469 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2471 img->put.separate = putRGBUAseparate8bittile;
2474 img->put.separate = putRGBseparate8bittile;
2477 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2479 img->put.separate = putRGBAAseparate16bittile;
2481 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2483 img->put.separate = putRGBUAseparate16bittile;
2487 img->put.separate = putRGBseparate16bittile;
2492 case PHOTOMETRIC_YCBCR:
2493 if ((img->bitspersample==8) && (img->samplesperpixel==3))
2495 if (initYCbCrConversion(img)!=0)
2498 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
2499 switch ((hs<<4)|vs) {
2501 img->put.separate = putseparate8bitYCbCr11tile;
2503 /* TODO: add other cases here */
2509 return ((img->get!=NULL) && (img->put.separate!=NULL));
2513 * Read a whole strip off data from the file, and convert to RGBA form.
2514 * If this is the last strip, then it will only contain the portion of
2515 * the strip that is actually within the image space. The result is
2516 * organized in bottom to top form.
2521 TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
2524 char emsg[1024] = "";
2527 uint32 rowsperstrip, rows_to_read;
2529 if( TIFFIsTiled( tif ) )
2531 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2532 "Can't use TIFFReadRGBAStrip() with tiled file.");
2536 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
2537 if( (row % rowsperstrip) != 0 )
2539 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2540 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2544 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2546 img.row_offset = row;
2549 if( row + rowsperstrip > img.height )
2550 rows_to_read = img.height - row;
2552 rows_to_read = rowsperstrip;
2554 ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
2556 TIFFRGBAImageEnd(&img);
2558 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2566 * Read a whole tile off data from the file, and convert to RGBA form.
2567 * The returned RGBA data is organized from bottom to top of tile,
2568 * and may include zeroed areas if the tile extends off the image.
2572 TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
2575 char emsg[1024] = "";
2578 uint32 tile_xsize, tile_ysize;
2579 uint32 read_xsize, read_ysize;
2583 * Verify that our request is legal - on a tile file, and on a
2587 if( !TIFFIsTiled( tif ) )
2589 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2590 "Can't use TIFFReadRGBATile() with stripped file.");
2594 TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
2595 TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
2596 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
2598 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2599 "Row/col passed to TIFFReadRGBATile() must be top"
2600 "left corner of a tile.");
2605 * Setup the RGBA reader.
2608 if (!TIFFRGBAImageOK(tif, emsg)
2609 || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2610 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2615 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2616 * edge of the image, even to fill an otherwise valid tile. So we
2617 * figure out how much we can read, and fix up the tile buffer to
2618 * a full tile configuration afterwards.
2621 if( row + tile_ysize > img.height )
2622 read_ysize = img.height - row;
2624 read_ysize = tile_ysize;
2626 if( col + tile_xsize > img.width )
2627 read_xsize = img.width - col;
2629 read_xsize = tile_xsize;
2632 * Read the chunk of imagery.
2635 img.row_offset = row;
2636 img.col_offset = col;
2638 ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
2640 TIFFRGBAImageEnd(&img);
2643 * If our read was incomplete we will need to fix up the tile by
2644 * shifting the data around as if a full tile of data is being returned.
2646 * This is all the more complicated because the image is organized in
2647 * bottom to top format.
2650 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
2653 for( i_row = 0; i_row < read_ysize; i_row++ ) {
2654 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
2655 raster + (read_ysize - i_row - 1) * read_xsize,
2656 read_xsize * sizeof(uint32) );
2657 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
2658 0, sizeof(uint32) * (tile_xsize - read_xsize) );
2661 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
2662 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
2663 0, sizeof(uint32) * tile_xsize );
2669 /* vim: set ts=8 sts=8 sw=8 noet: */