1 /* $Id: tif_getimage.c,v 1.114 2017-11-17 20:21:00 erouault 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
*);
42 static int BuildMapUaToAa(TIFFRGBAImage
* img
);
43 static int BuildMapBitdepth16To8(TIFFRGBAImage
* img
);
45 static const char photoTag
[] = "PhotometricInterpretation";
48 * Helper constants used in Orientation tag handling
50 #define FLIP_VERTICALLY 0x01
51 #define FLIP_HORIZONTALLY 0x02
54 * Color conversion constants. We will define display types here.
57 static const TIFFDisplay display_sRGB
= {
58 { /* XYZ -> luminance matrix */
59 { 3.2410F
, -1.5374F
, -0.4986F
},
60 { -0.9692F
, 1.8760F
, 0.0416F
},
61 { 0.0556F
, -0.2040F
, 1.0570F
}
63 100.0F
, 100.0F
, 100.0F
, /* Light o/p for reference white */
64 255, 255, 255, /* Pixel values for ref. white */
65 1.0F
, 1.0F
, 1.0F
, /* Residual light o/p for black pixel */
66 2.4F
, 2.4F
, 2.4F
, /* Gamma values for the three guns */
70 * Check the image to see if TIFFReadRGBAImage can deal with it.
71 * 1/0 is returned according to whether or not the image can
72 * be handled. If 0 is returned, emsg contains the reason
73 * why it is being rejected.
76 TIFFRGBAImageOK(TIFF
* tif
, char emsg
[1024])
78 TIFFDirectory
* td
= &tif
->tif_dir
;
82 if (!tif
->tif_decodestatus
) {
83 sprintf(emsg
, "Sorry, requested compression method is not configured");
86 switch (td
->td_bitspersample
) {
94 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
95 td
->td_bitspersample
);
98 if (td
->td_sampleformat
== SAMPLEFORMAT_IEEEFP
) {
99 sprintf(emsg
, "Sorry, can not handle images with IEEE floating-point samples");
102 colorchannels
= td
->td_samplesperpixel
- td
->td_extrasamples
;
103 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &photometric
)) {
104 switch (colorchannels
) {
106 photometric
= PHOTOMETRIC_MINISBLACK
;
109 photometric
= PHOTOMETRIC_RGB
;
112 sprintf(emsg
, "Missing needed %s tag", photoTag
);
116 switch (photometric
) {
117 case PHOTOMETRIC_MINISWHITE
:
118 case PHOTOMETRIC_MINISBLACK
:
119 case PHOTOMETRIC_PALETTE
:
120 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
121 && td
->td_samplesperpixel
!= 1
122 && td
->td_bitspersample
< 8 ) {
124 "Sorry, can not handle contiguous data with %s=%d, "
125 "and %s=%d and Bits/Sample=%d",
126 photoTag
, photometric
,
127 "Samples/pixel", td
->td_samplesperpixel
,
128 td
->td_bitspersample
);
132 * We should likely validate that any extra samples are either
133 * to be ignored, or are alpha, and if alpha we should try to use
134 * them. But for now we won't bother with this.
137 case PHOTOMETRIC_YCBCR
:
139 * TODO: if at all meaningful and useful, make more complete
140 * support check here, or better still, refactor to let supporting
141 * code decide whether there is support and what meaningful
145 case PHOTOMETRIC_RGB
:
146 if (colorchannels
< 3) {
147 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
148 "Color channels", colorchannels
);
152 case PHOTOMETRIC_SEPARATED
:
155 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
156 if (inkset
!= INKSET_CMYK
) {
158 "Sorry, can not handle separated image with %s=%d",
162 if (td
->td_samplesperpixel
< 4) {
164 "Sorry, can not handle separated image with %s=%d",
165 "Samples/pixel", td
->td_samplesperpixel
);
170 case PHOTOMETRIC_LOGL
:
171 if (td
->td_compression
!= COMPRESSION_SGILOG
) {
172 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
173 "Compression", COMPRESSION_SGILOG
);
177 case PHOTOMETRIC_LOGLUV
:
178 if (td
->td_compression
!= COMPRESSION_SGILOG
&&
179 td
->td_compression
!= COMPRESSION_SGILOG24
) {
180 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
181 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
184 if (td
->td_planarconfig
!= PLANARCONFIG_CONTIG
) {
185 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
186 "Planarconfiguration", td
->td_planarconfig
);
189 if ( td
->td_samplesperpixel
!= 3 || colorchannels
!= 3 ) {
191 "Sorry, can not handle image with %s=%d, %s=%d",
192 "Samples/pixel", td
->td_samplesperpixel
,
193 "colorchannels", colorchannels
);
197 case PHOTOMETRIC_CIELAB
:
198 if ( td
->td_samplesperpixel
!= 3 || colorchannels
!= 3 || td
->td_bitspersample
!= 8 ) {
200 "Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
201 "Samples/pixel", td
->td_samplesperpixel
,
202 "colorchannels", colorchannels
,
203 "Bits/sample", td
->td_bitspersample
);
208 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
209 photoTag
, photometric
);
216 TIFFRGBAImageEnd(TIFFRGBAImage
* img
)
223 _TIFFfree(img
->BWmap
);
227 _TIFFfree(img
->PALmap
);
231 _TIFFfree(img
->ycbcr
);
235 _TIFFfree(img
->cielab
);
239 _TIFFfree(img
->UaToAa
);
242 if (img
->Bitdepth16To8
) {
243 _TIFFfree(img
->Bitdepth16To8
);
244 img
->Bitdepth16To8
= NULL
;
248 _TIFFfree( img
->redcmap
);
249 _TIFFfree( img
->greencmap
);
250 _TIFFfree( img
->bluecmap
);
251 img
->redcmap
= img
->greencmap
= img
->bluecmap
= NULL
;
256 isCCITTCompression(TIFF
* tif
)
259 TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compress
);
260 return (compress
== COMPRESSION_CCITTFAX3
||
261 compress
== COMPRESSION_CCITTFAX4
||
262 compress
== COMPRESSION_CCITTRLE
||
263 compress
== COMPRESSION_CCITTRLEW
);
267 TIFFRGBAImageBegin(TIFFRGBAImage
* img
, TIFF
* tif
, int stop
, char emsg
[1024])
274 uint16
*red_orig
, *green_orig
, *blue_orig
;
277 if( !TIFFRGBAImageOK(tif
, emsg
) )
280 /* Initialize to normal values */
284 img
->greencmap
= NULL
;
285 img
->bluecmap
= NULL
;
292 img
->Bitdepth16To8
= NULL
;
293 img
->req_orientation
= ORIENTATION_BOTLEFT
; /* It is the default */
296 img
->stoponerr
= stop
;
297 TIFFGetFieldDefaulted(tif
, TIFFTAG_BITSPERSAMPLE
, &img
->bitspersample
);
298 switch (img
->bitspersample
) {
306 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
311 TIFFGetFieldDefaulted(tif
, TIFFTAG_SAMPLESPERPIXEL
, &img
->samplesperpixel
);
312 TIFFGetFieldDefaulted(tif
, TIFFTAG_EXTRASAMPLES
,
313 &extrasamples
, &sampleinfo
);
314 if (extrasamples
>= 1)
316 switch (sampleinfo
[0]) {
317 case EXTRASAMPLE_UNSPECIFIED
: /* Workaround for some images without */
318 if (img
->samplesperpixel
> 3) /* correct info about alpha channel */
319 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
321 case EXTRASAMPLE_ASSOCALPHA
: /* data is pre-multiplied */
322 case EXTRASAMPLE_UNASSALPHA
: /* data is not pre-multiplied */
323 img
->alpha
= sampleinfo
[0];
328 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
329 if( !TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
))
330 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
332 if( extrasamples
== 0
333 && img
->samplesperpixel
== 4
334 && img
->photometric
== PHOTOMETRIC_RGB
)
336 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
341 colorchannels
= img
->samplesperpixel
- extrasamples
;
342 TIFFGetFieldDefaulted(tif
, TIFFTAG_COMPRESSION
, &compress
);
343 TIFFGetFieldDefaulted(tif
, TIFFTAG_PLANARCONFIG
, &planarconfig
);
344 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
)) {
345 switch (colorchannels
) {
347 if (isCCITTCompression(tif
))
348 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
350 img
->photometric
= PHOTOMETRIC_MINISBLACK
;
353 img
->photometric
= PHOTOMETRIC_RGB
;
356 sprintf(emsg
, "Missing needed %s tag", photoTag
);
360 switch (img
->photometric
) {
361 case PHOTOMETRIC_PALETTE
:
362 if (!TIFFGetField(tif
, TIFFTAG_COLORMAP
,
363 &red_orig
, &green_orig
, &blue_orig
)) {
364 sprintf(emsg
, "Missing required \"Colormap\" tag");
368 /* copy the colormaps so we can modify them */
369 n_color
= (1U << img
->bitspersample
);
370 img
->redcmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
371 img
->greencmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
372 img
->bluecmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
373 if( !img
->redcmap
|| !img
->greencmap
|| !img
->bluecmap
) {
374 sprintf(emsg
, "Out of memory for colormap copy");
378 _TIFFmemcpy( img
->redcmap
, red_orig
, n_color
* 2 );
379 _TIFFmemcpy( img
->greencmap
, green_orig
, n_color
* 2 );
380 _TIFFmemcpy( img
->bluecmap
, blue_orig
, n_color
* 2 );
382 /* fall through... */
383 case PHOTOMETRIC_MINISWHITE
:
384 case PHOTOMETRIC_MINISBLACK
:
385 if (planarconfig
== PLANARCONFIG_CONTIG
386 && img
->samplesperpixel
!= 1
387 && img
->bitspersample
< 8 ) {
389 "Sorry, can not handle contiguous data with %s=%d, "
390 "and %s=%d and Bits/Sample=%d",
391 photoTag
, img
->photometric
,
392 "Samples/pixel", img
->samplesperpixel
,
397 case PHOTOMETRIC_YCBCR
:
398 /* It would probably be nice to have a reality check here. */
399 if (planarconfig
== PLANARCONFIG_CONTIG
)
400 /* can rely on libjpeg to convert to RGB */
401 /* XXX should restore current state on exit */
403 case COMPRESSION_JPEG
:
405 * TODO: when complete tests verify complete desubsampling
406 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
407 * favor of tif_getimage.c native handling
409 TIFFSetField(tif
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
410 img
->photometric
= PHOTOMETRIC_RGB
;
417 * TODO: if at all meaningful and useful, make more complete
418 * support check here, or better still, refactor to let supporting
419 * code decide whether there is support and what meaningful
423 case PHOTOMETRIC_RGB
:
424 if (colorchannels
< 3) {
425 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
426 "Color channels", colorchannels
);
430 case PHOTOMETRIC_SEPARATED
:
433 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
434 if (inkset
!= INKSET_CMYK
) {
435 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
439 if (img
->samplesperpixel
< 4) {
440 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
441 "Samples/pixel", img
->samplesperpixel
);
446 case PHOTOMETRIC_LOGL
:
447 if (compress
!= COMPRESSION_SGILOG
) {
448 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
449 "Compression", COMPRESSION_SGILOG
);
452 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
453 img
->photometric
= PHOTOMETRIC_MINISBLACK
; /* little white lie */
454 img
->bitspersample
= 8;
456 case PHOTOMETRIC_LOGLUV
:
457 if (compress
!= COMPRESSION_SGILOG
&& compress
!= COMPRESSION_SGILOG24
) {
458 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
459 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
462 if (planarconfig
!= PLANARCONFIG_CONTIG
) {
463 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
464 "Planarconfiguration", planarconfig
);
467 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
468 img
->photometric
= PHOTOMETRIC_RGB
; /* little white lie */
469 img
->bitspersample
= 8;
471 case PHOTOMETRIC_CIELAB
:
474 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
475 photoTag
, img
->photometric
);
478 TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &img
->width
);
479 TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &img
->height
);
480 TIFFGetFieldDefaulted(tif
, TIFFTAG_ORIENTATION
, &img
->orientation
);
482 !(planarconfig
== PLANARCONFIG_SEPARATE
&& img
->samplesperpixel
> 1);
484 if (!PickContigCase(img
)) {
485 sprintf(emsg
, "Sorry, can not handle image");
489 if (!PickSeparateCase(img
)) {
490 sprintf(emsg
, "Sorry, can not handle image");
497 TIFFRGBAImageEnd( img
);
502 TIFFRGBAImageGet(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
504 if (img
->get
== NULL
) {
505 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No \"get\" routine setup");
508 if (img
->put
.any
== NULL
) {
509 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
510 "No \"put\" routine setupl; probably can not handle image format");
513 return (*img
->get
)(img
, raster
, w
, h
);
517 * Read the specified image into an ABGR-format rastertaking in account
518 * specified orientation.
521 TIFFReadRGBAImageOriented(TIFF
* tif
,
522 uint32 rwidth
, uint32 rheight
, uint32
* raster
,
523 int orientation
, int stop
)
525 char emsg
[1024] = "";
529 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, stop
, emsg
)) {
530 img
.req_orientation
= (uint16
)orientation
;
531 /* XXX verify rwidth and rheight against width and height */
532 ok
= TIFFRGBAImageGet(&img
, raster
+(rheight
-img
.height
)*rwidth
,
534 TIFFRGBAImageEnd(&img
);
536 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
543 * Read the specified image into an ABGR-format raster. Use bottom left
544 * origin for raster by default.
547 TIFFReadRGBAImage(TIFF
* tif
,
548 uint32 rwidth
, uint32 rheight
, uint32
* raster
, int stop
)
550 return TIFFReadRGBAImageOriented(tif
, rwidth
, rheight
, raster
,
551 ORIENTATION_BOTLEFT
, stop
);
555 setorientation(TIFFRGBAImage
* img
)
557 switch (img
->orientation
) {
558 case ORIENTATION_TOPLEFT
:
559 case ORIENTATION_LEFTTOP
:
560 if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
561 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
562 return FLIP_HORIZONTALLY
;
563 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
564 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
565 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
566 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
567 img
->req_orientation
== ORIENTATION_LEFTBOT
)
568 return FLIP_VERTICALLY
;
571 case ORIENTATION_TOPRIGHT
:
572 case ORIENTATION_RIGHTTOP
:
573 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
574 img
->req_orientation
== ORIENTATION_LEFTTOP
)
575 return FLIP_HORIZONTALLY
;
576 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
577 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
578 return FLIP_VERTICALLY
;
579 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
580 img
->req_orientation
== ORIENTATION_LEFTBOT
)
581 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
584 case ORIENTATION_BOTRIGHT
:
585 case ORIENTATION_RIGHTBOT
:
586 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
587 img
->req_orientation
== ORIENTATION_LEFTTOP
)
588 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
589 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
590 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
591 return FLIP_VERTICALLY
;
592 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
593 img
->req_orientation
== ORIENTATION_LEFTBOT
)
594 return FLIP_HORIZONTALLY
;
597 case ORIENTATION_BOTLEFT
:
598 case ORIENTATION_LEFTBOT
:
599 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
600 img
->req_orientation
== ORIENTATION_LEFTTOP
)
601 return FLIP_VERTICALLY
;
602 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
603 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
604 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
605 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
606 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
607 return FLIP_HORIZONTALLY
;
610 default: /* NOTREACHED */
616 * Get an tile-organized image that has
617 * PlanarConfiguration contiguous if SamplesPerPixel > 1
619 * SamplesPerPixel == 1
622 gtTileContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
624 TIFF
* tif
= img
->tif
;
625 tileContigRoutine put
= img
->put
.contig
;
626 uint32 col
, row
, y
, rowstoread
;
629 unsigned char* buf
= NULL
;
630 int32 fromskew
, toskew
;
633 uint32 this_tw
, tocol
;
634 int32 this_toskew
, leftmost_toskew
;
635 int32 leftmost_fromskew
;
639 bufsize
= TIFFTileSize(tif
);
641 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", "No space for tile buffer");
645 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
646 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
648 flip
= setorientation(img
);
649 if (flip
& FLIP_VERTICALLY
) {
651 toskew
= -(int32
)(tw
+ w
);
655 toskew
= -(int32
)(tw
- w
);
659 * Leftmost tile is clipped on left side if col_offset > 0.
661 leftmost_fromskew
= img
->col_offset
% tw
;
662 leftmost_tw
= tw
- leftmost_fromskew
;
663 leftmost_toskew
= toskew
+ leftmost_fromskew
;
664 for (row
= 0; ret
!= 0 && row
< h
; row
+= nrow
)
666 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
667 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
668 fromskew
= leftmost_fromskew
;
669 this_tw
= leftmost_tw
;
670 this_toskew
= leftmost_toskew
;
672 col
= img
->col_offset
;
675 if (_TIFFReadTileAndAllocBuffer(tif
, (void**) &buf
, bufsize
, col
,
676 row
+img
->row_offset
, 0, 0)==(tmsize_t
)(-1) &&
677 (buf
== NULL
|| img
->stoponerr
))
682 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
) + \
683 ((tmsize_t
) fromskew
* img
->samplesperpixel
);
684 if (tocol
+ this_tw
> w
)
687 * Rightmost tile is clipped on right side.
689 fromskew
= tw
- (w
- tocol
);
690 this_tw
= tw
- fromskew
;
691 this_toskew
= toskew
+ fromskew
;
693 (*put
)(img
, raster
+y
*w
+tocol
, tocol
, y
, this_tw
, nrow
, fromskew
, this_toskew
, buf
+ pos
);
697 * After the leftmost tile, tiles are no longer clipped on left side.
701 this_toskew
= toskew
;
704 y
+= ((flip
& FLIP_VERTICALLY
) ? -(int32
) nrow
: (int32
) nrow
);
708 if (flip
& FLIP_HORIZONTALLY
) {
711 for (line
= 0; line
< h
; line
++) {
712 uint32
*left
= raster
+ (line
* w
);
713 uint32
*right
= left
+ w
- 1;
715 while ( left
< right
) {
729 * Get an tile-organized image that has
730 * SamplesPerPixel > 1
731 * PlanarConfiguration separated
732 * We assume that all such images are RGB.
735 gtTileSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
737 TIFF
* tif
= img
->tif
;
738 tileSeparateRoutine put
= img
->put
.separate
;
739 uint32 col
, row
, y
, rowstoread
;
742 unsigned char* buf
= NULL
;
743 unsigned char* p0
= NULL
;
744 unsigned char* p1
= NULL
;
745 unsigned char* p2
= NULL
;
746 unsigned char* pa
= NULL
;
749 int32 fromskew
, toskew
;
750 int alpha
= img
->alpha
;
753 uint16 colorchannels
;
754 uint32 this_tw
, tocol
;
755 int32 this_toskew
, leftmost_toskew
;
756 int32 leftmost_fromskew
;
759 tilesize
= TIFFTileSize(tif
);
760 bufsize
= TIFFSafeMultiply(tmsize_t
,alpha
?4:3,tilesize
);
762 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Integer overflow in %s", "gtTileSeparate");
766 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
767 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
769 flip
= setorientation(img
);
770 if (flip
& FLIP_VERTICALLY
) {
772 toskew
= -(int32
)(tw
+ w
);
776 toskew
= -(int32
)(tw
- w
);
779 switch( img
->photometric
)
781 case PHOTOMETRIC_MINISWHITE
:
782 case PHOTOMETRIC_MINISBLACK
:
783 case PHOTOMETRIC_PALETTE
:
793 * Leftmost tile is clipped on left side if col_offset > 0.
795 leftmost_fromskew
= img
->col_offset
% tw
;
796 leftmost_tw
= tw
- leftmost_fromskew
;
797 leftmost_toskew
= toskew
+ leftmost_fromskew
;
798 for (row
= 0; ret
!= 0 && row
< h
; row
+= nrow
)
800 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
801 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
802 fromskew
= leftmost_fromskew
;
803 this_tw
= leftmost_tw
;
804 this_toskew
= leftmost_toskew
;
806 col
= img
->col_offset
;
811 if (_TIFFReadTileAndAllocBuffer(
812 tif
, (void**) &buf
, bufsize
, col
,
813 row
+img
->row_offset
,0,0)==(tmsize_t
)(-1)
814 && (buf
== NULL
|| img
->stoponerr
))
820 if( colorchannels
== 1 )
823 pa
= (alpha
?(p0
+3*tilesize
):NULL
);
829 pa
= (alpha
?(p2
+tilesize
):NULL
);
832 else if (TIFFReadTile(tif
, p0
, col
,
833 row
+img
->row_offset
,0,0)==(tmsize_t
)(-1) && img
->stoponerr
)
838 if (colorchannels
> 1
839 && TIFFReadTile(tif
, p1
, col
,
840 row
+img
->row_offset
,0,1) == (tmsize_t
)(-1)
846 if (colorchannels
> 1
847 && TIFFReadTile(tif
, p2
, col
,
848 row
+img
->row_offset
,0,2) == (tmsize_t
)(-1)
855 && TIFFReadTile(tif
,pa
,col
,
856 row
+img
->row_offset
,0,colorchannels
) == (tmsize_t
)(-1)
863 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
) + \
864 ((tmsize_t
) fromskew
* img
->samplesperpixel
);
865 if (tocol
+ this_tw
> w
)
868 * Rightmost tile is clipped on right side.
870 fromskew
= tw
- (w
- tocol
);
871 this_tw
= tw
- fromskew
;
872 this_toskew
= toskew
+ fromskew
;
874 (*put
)(img
, raster
+y
*w
+tocol
, tocol
, y
, this_tw
, nrow
, fromskew
, this_toskew
, \
875 p0
+ pos
, p1
+ pos
, p2
+ pos
, (alpha
?(pa
+pos
):NULL
));
879 * After the leftmost tile, tiles are no longer clipped on left side.
883 this_toskew
= toskew
;
886 y
+= ((flip
& FLIP_VERTICALLY
) ?-(int32
) nrow
: (int32
) nrow
);
889 if (flip
& FLIP_HORIZONTALLY
) {
892 for (line
= 0; line
< h
; line
++) {
893 uint32
*left
= raster
+ (line
* w
);
894 uint32
*right
= left
+ w
- 1;
896 while ( left
< right
) {
911 * Get a strip-organized image that has
912 * PlanarConfiguration contiguous if SamplesPerPixel > 1
914 * SamplesPerPixel == 1
917 gtStripContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
919 TIFF
* tif
= img
->tif
;
920 tileContigRoutine put
= img
->put
.contig
;
921 uint32 row
, y
, nrow
, nrowsub
, rowstoread
;
923 unsigned char* buf
= NULL
;
925 uint16 subsamplinghor
,subsamplingver
;
926 uint32 imagewidth
= img
->width
;
928 int32 fromskew
, toskew
;
930 tmsize_t maxstripsize
;
932 TIFFGetFieldDefaulted(tif
, TIFFTAG_YCBCRSUBSAMPLING
, &subsamplinghor
, &subsamplingver
);
933 if( subsamplingver
== 0 ) {
934 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Invalid vertical YCbCr subsampling");
938 maxstripsize
= TIFFStripSize(tif
);
940 flip
= setorientation(img
);
941 if (flip
& FLIP_VERTICALLY
) {
943 toskew
= -(int32
)(w
+ w
);
946 toskew
= -(int32
)(w
- w
);
949 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
951 scanline
= TIFFScanlineSize(tif
);
952 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
953 for (row
= 0; row
< h
; row
+= nrow
)
955 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
956 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
958 if ((nrowsub
%subsamplingver
)!=0)
959 nrowsub
+=subsamplingver
-nrowsub
%subsamplingver
;
960 if (_TIFFReadEncodedStripAndAllocBuffer(tif
,
961 TIFFComputeStrip(tif
,row
+img
->row_offset
, 0),
964 ((row
+ img
->row_offset
)%rowsperstrip
+ nrowsub
) * scanline
)==(tmsize_t
)(-1)
965 && (buf
== NULL
|| img
->stoponerr
))
971 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
+ \
972 ((tmsize_t
) img
->col_offset
* img
->samplesperpixel
);
973 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, buf
+ pos
);
974 y
+= ((flip
& FLIP_VERTICALLY
) ? -(int32
) nrow
: (int32
) nrow
);
977 if (flip
& FLIP_HORIZONTALLY
) {
980 for (line
= 0; line
< h
; line
++) {
981 uint32
*left
= raster
+ (line
* w
);
982 uint32
*right
= left
+ w
- 1;
984 while ( left
< right
) {
999 * Get a strip-organized image with
1000 * SamplesPerPixel > 1
1001 * PlanarConfiguration separated
1002 * We assume that all such images are RGB.
1005 gtStripSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
1007 TIFF
* tif
= img
->tif
;
1008 tileSeparateRoutine put
= img
->put
.separate
;
1009 unsigned char *buf
= NULL
;
1010 unsigned char *p0
= NULL
, *p1
= NULL
, *p2
= NULL
, *pa
= NULL
;
1011 uint32 row
, y
, nrow
, rowstoread
;
1014 uint32 rowsperstrip
, offset_row
;
1015 uint32 imagewidth
= img
->width
;
1018 int32 fromskew
, toskew
;
1019 int alpha
= img
->alpha
;
1021 uint16 colorchannels
;
1023 stripsize
= TIFFStripSize(tif
);
1024 bufsize
= TIFFSafeMultiply(tmsize_t
,alpha
?4:3,stripsize
);
1026 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Integer overflow in %s", "gtStripSeparate");
1030 flip
= setorientation(img
);
1031 if (flip
& FLIP_VERTICALLY
) {
1033 toskew
= -(int32
)(w
+ w
);
1037 toskew
= -(int32
)(w
- w
);
1040 switch( img
->photometric
)
1042 case PHOTOMETRIC_MINISWHITE
:
1043 case PHOTOMETRIC_MINISBLACK
:
1044 case PHOTOMETRIC_PALETTE
:
1053 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
1054 scanline
= TIFFScanlineSize(tif
);
1055 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
1056 for (row
= 0; row
< h
; row
+= nrow
)
1058 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
1059 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
1060 offset_row
= row
+ img
->row_offset
;
1063 if (_TIFFReadEncodedStripAndAllocBuffer(
1064 tif
, TIFFComputeStrip(tif
, offset_row
, 0),
1065 (void**) &buf
, bufsize
,
1066 ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
1067 && (buf
== NULL
|| img
->stoponerr
))
1073 if( colorchannels
== 1 )
1076 pa
= (alpha
?(p0
+3*stripsize
):NULL
);
1080 p1
= p0
+ stripsize
;
1081 p2
= p1
+ stripsize
;
1082 pa
= (alpha
?(p2
+stripsize
):NULL
);
1085 else if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 0),
1086 p0
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
1092 if (colorchannels
> 1
1093 && TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 1),
1094 p1
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) == (tmsize_t
)(-1)
1100 if (colorchannels
> 1
1101 && TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 2),
1102 p2
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) == (tmsize_t
)(-1)
1110 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, colorchannels
),
1111 pa
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
1119 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
+ \
1120 ((tmsize_t
) img
->col_offset
* img
->samplesperpixel
);
1121 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, p0
+ pos
, p1
+ pos
,
1122 p2
+ pos
, (alpha
?(pa
+pos
):NULL
));
1123 y
+= ((flip
& FLIP_VERTICALLY
) ? -(int32
) nrow
: (int32
) nrow
);
1126 if (flip
& FLIP_HORIZONTALLY
) {
1129 for (line
= 0; line
< h
; line
++) {
1130 uint32
*left
= raster
+ (line
* w
);
1131 uint32
*right
= left
+ w
- 1;
1133 while ( left
< right
) {
1134 uint32 temp
= *left
;
1148 * The following routines move decoded data returned
1149 * from the TIFF library into rasters filled with packed
1150 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
1152 * The routines have been created according to the most
1153 * important cases and optimized. PickContigCase and
1154 * PickSeparateCase analyze the parameters and select
1155 * the appropriate "get" and "put" routine to use.
1157 #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
1158 #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
1159 #define REPEAT2(op) op; op
1160 #define CASE8(x,op) \
1162 case 7: op; /*-fallthrough*/ \
1163 case 6: op; /*-fallthrough*/ \
1164 case 5: op; /*-fallthrough*/ \
1165 case 4: op; /*-fallthrough*/ \
1166 case 3: op; /*-fallthrough*/ \
1167 case 2: op; /*-fallthrough*/ \
1170 #define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; }
1173 #define UNROLL8(w, op1, op2) { \
1175 for (_x = w; _x >= 8; _x -= 8) { \
1184 #define UNROLL4(w, op1, op2) { \
1186 for (_x = w; _x >= 4; _x -= 4) { \
1195 #define UNROLL2(w, op1, op2) { \
1197 for (_x = w; _x >= 2; _x -= 2) { \
1207 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1208 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1210 #define A1 (((uint32)0xffL)<<24)
1211 #define PACK(r,g,b) \
1212 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1213 #define PACK4(r,g,b,a) \
1214 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1215 #define W2B(v) (((v)>>8)&0xff)
1216 /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
1217 #define PACKW(r,g,b) \
1218 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1219 #define PACKW4(r,g,b,a) \
1220 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1222 #define DECLAREContigPutFunc(name) \
1224 TIFFRGBAImage* img, \
1226 uint32 x, uint32 y, \
1227 uint32 w, uint32 h, \
1228 int32 fromskew, int32 toskew, \
1233 * 8-bit palette => colormap/RGB
1235 DECLAREContigPutFunc(put8bitcmaptile
)
1237 uint32
** PALmap
= img
->PALmap
;
1238 int samplesperpixel
= img
->samplesperpixel
;
1241 for( ; h
> 0; --h
) {
1242 for (x
= w
; x
> 0; --x
)
1244 *cp
++ = PALmap
[*pp
][0];
1245 pp
+= samplesperpixel
;
1253 * 4-bit palette => colormap/RGB
1255 DECLAREContigPutFunc(put4bitcmaptile
)
1257 uint32
** PALmap
= img
->PALmap
;
1261 for( ; h
> 0; --h
) {
1263 UNROLL2(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1270 * 2-bit palette => colormap/RGB
1272 DECLAREContigPutFunc(put2bitcmaptile
)
1274 uint32
** PALmap
= img
->PALmap
;
1278 for( ; h
> 0; --h
) {
1280 UNROLL4(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1287 * 1-bit palette => colormap/RGB
1289 DECLAREContigPutFunc(put1bitcmaptile
)
1291 uint32
** PALmap
= img
->PALmap
;
1295 for( ; h
> 0; --h
) {
1297 UNROLL8(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1304 * 8-bit greyscale => colormap/RGB
1306 DECLAREContigPutFunc(putgreytile
)
1308 int samplesperpixel
= img
->samplesperpixel
;
1309 uint32
** BWmap
= img
->BWmap
;
1312 for( ; h
> 0; --h
) {
1313 for (x
= w
; x
> 0; --x
)
1315 *cp
++ = BWmap
[*pp
][0];
1316 pp
+= samplesperpixel
;
1324 * 8-bit greyscale with associated alpha => colormap/RGBA
1326 DECLAREContigPutFunc(putagreytile
)
1328 int samplesperpixel
= img
->samplesperpixel
;
1329 uint32
** BWmap
= img
->BWmap
;
1332 for( ; h
> 0; --h
) {
1333 for (x
= w
; x
> 0; --x
)
1335 *cp
++ = BWmap
[*pp
][0] & ((uint32
)*(pp
+1) << 24 | ~A1
);
1336 pp
+= samplesperpixel
;
1344 * 16-bit greyscale => colormap/RGB
1346 DECLAREContigPutFunc(put16bitbwtile
)
1348 int samplesperpixel
= img
->samplesperpixel
;
1349 uint32
** BWmap
= img
->BWmap
;
1352 for( ; h
> 0; --h
) {
1353 uint16
*wp
= (uint16
*) pp
;
1355 for (x
= w
; x
> 0; --x
)
1357 /* use high order byte of 16bit value */
1359 *cp
++ = BWmap
[*wp
>> 8][0];
1360 pp
+= 2 * samplesperpixel
;
1361 wp
+= samplesperpixel
;
1369 * 1-bit bilevel => colormap/RGB
1371 DECLAREContigPutFunc(put1bitbwtile
)
1373 uint32
** BWmap
= img
->BWmap
;
1377 for( ; h
> 0; --h
) {
1379 UNROLL8(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1386 * 2-bit greyscale => colormap/RGB
1388 DECLAREContigPutFunc(put2bitbwtile
)
1390 uint32
** BWmap
= img
->BWmap
;
1394 for( ; h
> 0; --h
) {
1396 UNROLL4(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1403 * 4-bit greyscale => colormap/RGB
1405 DECLAREContigPutFunc(put4bitbwtile
)
1407 uint32
** BWmap
= img
->BWmap
;
1411 for( ; h
> 0; --h
) {
1413 UNROLL2(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1420 * 8-bit packed samples, no Map => RGB
1422 DECLAREContigPutFunc(putRGBcontig8bittile
)
1424 int samplesperpixel
= img
->samplesperpixel
;
1427 fromskew
*= samplesperpixel
;
1428 for( ; h
> 0; --h
) {
1430 *cp
++ = PACK(pp
[0], pp
[1], pp
[2]);
1431 pp
+= samplesperpixel
);
1438 * 8-bit packed samples => RGBA w/ associated alpha
1439 * (known to have Map == NULL)
1441 DECLAREContigPutFunc(putRGBAAcontig8bittile
)
1443 int samplesperpixel
= img
->samplesperpixel
;
1446 fromskew
*= samplesperpixel
;
1447 for( ; h
> 0; --h
) {
1449 *cp
++ = PACK4(pp
[0], pp
[1], pp
[2], pp
[3]);
1450 pp
+= samplesperpixel
);
1457 * 8-bit packed samples => RGBA w/ unassociated alpha
1458 * (known to have Map == NULL)
1460 DECLAREContigPutFunc(putRGBUAcontig8bittile
)
1462 int samplesperpixel
= img
->samplesperpixel
;
1464 fromskew
*= samplesperpixel
;
1465 for( ; h
> 0; --h
) {
1468 for (x
= w
; x
> 0; --x
) {
1470 m
= img
->UaToAa
+((size_t) a
<<8);
1474 *cp
++ = PACK4(r
,g
,b
,a
);
1475 pp
+= samplesperpixel
;
1483 * 16-bit packed samples => RGB
1485 DECLAREContigPutFunc(putRGBcontig16bittile
)
1487 int samplesperpixel
= img
->samplesperpixel
;
1488 uint16
*wp
= (uint16
*)pp
;
1490 fromskew
*= samplesperpixel
;
1491 for( ; h
> 0; --h
) {
1492 for (x
= w
; x
> 0; --x
) {
1493 *cp
++ = PACK(img
->Bitdepth16To8
[wp
[0]],
1494 img
->Bitdepth16To8
[wp
[1]],
1495 img
->Bitdepth16To8
[wp
[2]]);
1496 wp
+= samplesperpixel
;
1504 * 16-bit packed samples => RGBA w/ associated alpha
1505 * (known to have Map == NULL)
1507 DECLAREContigPutFunc(putRGBAAcontig16bittile
)
1509 int samplesperpixel
= img
->samplesperpixel
;
1510 uint16
*wp
= (uint16
*)pp
;
1512 fromskew
*= samplesperpixel
;
1513 for( ; h
> 0; --h
) {
1514 for (x
= w
; x
> 0; --x
) {
1515 *cp
++ = PACK4(img
->Bitdepth16To8
[wp
[0]],
1516 img
->Bitdepth16To8
[wp
[1]],
1517 img
->Bitdepth16To8
[wp
[2]],
1518 img
->Bitdepth16To8
[wp
[3]]);
1519 wp
+= samplesperpixel
;
1527 * 16-bit packed samples => RGBA w/ unassociated alpha
1528 * (known to have Map == NULL)
1530 DECLAREContigPutFunc(putRGBUAcontig16bittile
)
1532 int samplesperpixel
= img
->samplesperpixel
;
1533 uint16
*wp
= (uint16
*)pp
;
1535 fromskew
*= samplesperpixel
;
1536 for( ; h
> 0; --h
) {
1539 for (x
= w
; x
> 0; --x
) {
1540 a
= img
->Bitdepth16To8
[wp
[3]];
1541 m
= img
->UaToAa
+((size_t) a
<<8);
1542 r
= m
[img
->Bitdepth16To8
[wp
[0]]];
1543 g
= m
[img
->Bitdepth16To8
[wp
[1]]];
1544 b
= m
[img
->Bitdepth16To8
[wp
[2]]];
1545 *cp
++ = PACK4(r
,g
,b
,a
);
1546 wp
+= samplesperpixel
;
1554 * 8-bit packed CMYK samples w/o Map => RGB
1556 * NB: The conversion of CMYK->RGB is *very* crude.
1558 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile
)
1560 int samplesperpixel
= img
->samplesperpixel
;
1564 fromskew
*= samplesperpixel
;
1565 for( ; h
> 0; --h
) {
1568 r
= (k
*(255-pp
[0]))/255;
1569 g
= (k
*(255-pp
[1]))/255;
1570 b
= (k
*(255-pp
[2]))/255;
1571 *cp
++ = PACK(r
, g
, b
);
1572 pp
+= samplesperpixel
);
1579 * 8-bit packed CMYK samples w/Map => RGB
1581 * NB: The conversion of CMYK->RGB is *very* crude.
1583 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile
)
1585 int samplesperpixel
= img
->samplesperpixel
;
1586 TIFFRGBValue
* Map
= img
->Map
;
1590 fromskew
*= samplesperpixel
;
1591 for( ; h
> 0; --h
) {
1592 for (x
= w
; x
> 0; --x
) {
1594 r
= (k
*(255-pp
[0]))/255;
1595 g
= (k
*(255-pp
[1]))/255;
1596 b
= (k
*(255-pp
[2]))/255;
1597 *cp
++ = PACK(Map
[r
], Map
[g
], Map
[b
]);
1598 pp
+= samplesperpixel
;
1605 #define DECLARESepPutFunc(name) \
1607 TIFFRGBAImage* img,\
1609 uint32 x, uint32 y, \
1610 uint32 w, uint32 h,\
1611 int32 fromskew, int32 toskew,\
1612 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1616 * 8-bit unpacked samples => RGB
1618 DECLARESepPutFunc(putRGBseparate8bittile
)
1620 (void) img
; (void) x
; (void) y
; (void) a
;
1621 for( ; h
> 0; --h
) {
1622 UNROLL8(w
, NOP
, *cp
++ = PACK(*r
++, *g
++, *b
++));
1623 SKEW(r
, g
, b
, fromskew
);
1629 * 8-bit unpacked samples => RGBA w/ associated alpha
1631 DECLARESepPutFunc(putRGBAAseparate8bittile
)
1633 (void) img
; (void) x
; (void) y
;
1634 for( ; h
> 0; --h
) {
1635 UNROLL8(w
, NOP
, *cp
++ = PACK4(*r
++, *g
++, *b
++, *a
++));
1636 SKEW4(r
, g
, b
, a
, fromskew
);
1642 * 8-bit unpacked CMYK samples => RGBA
1644 DECLARESepPutFunc(putCMYKseparate8bittile
)
1646 (void) img
; (void) y
;
1647 for( ; h
> 0; --h
) {
1648 uint32 rv
, gv
, bv
, kv
;
1649 for (x
= w
; x
> 0; --x
) {
1651 rv
= (kv
*(255-*r
++))/255;
1652 gv
= (kv
*(255-*g
++))/255;
1653 bv
= (kv
*(255-*b
++))/255;
1654 *cp
++ = PACK4(rv
,gv
,bv
,255);
1656 SKEW4(r
, g
, b
, a
, fromskew
);
1662 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1664 DECLARESepPutFunc(putRGBUAseparate8bittile
)
1666 (void) img
; (void) y
;
1667 for( ; h
> 0; --h
) {
1668 uint32 rv
, gv
, bv
, av
;
1670 for (x
= w
; x
> 0; --x
) {
1672 m
= img
->UaToAa
+((size_t) av
<<8);
1676 *cp
++ = PACK4(rv
,gv
,bv
,av
);
1678 SKEW4(r
, g
, b
, a
, fromskew
);
1684 * 16-bit unpacked samples => RGB
1686 DECLARESepPutFunc(putRGBseparate16bittile
)
1688 uint16
*wr
= (uint16
*) r
;
1689 uint16
*wg
= (uint16
*) g
;
1690 uint16
*wb
= (uint16
*) b
;
1691 (void) img
; (void) y
; (void) a
;
1692 for( ; h
> 0; --h
) {
1693 for (x
= 0; x
< w
; x
++)
1694 *cp
++ = PACK(img
->Bitdepth16To8
[*wr
++],
1695 img
->Bitdepth16To8
[*wg
++],
1696 img
->Bitdepth16To8
[*wb
++]);
1697 SKEW(wr
, wg
, wb
, fromskew
);
1703 * 16-bit unpacked samples => RGBA w/ associated alpha
1705 DECLARESepPutFunc(putRGBAAseparate16bittile
)
1707 uint16
*wr
= (uint16
*) r
;
1708 uint16
*wg
= (uint16
*) g
;
1709 uint16
*wb
= (uint16
*) b
;
1710 uint16
*wa
= (uint16
*) a
;
1711 (void) img
; (void) y
;
1712 for( ; h
> 0; --h
) {
1713 for (x
= 0; x
< w
; x
++)
1714 *cp
++ = PACK4(img
->Bitdepth16To8
[*wr
++],
1715 img
->Bitdepth16To8
[*wg
++],
1716 img
->Bitdepth16To8
[*wb
++],
1717 img
->Bitdepth16To8
[*wa
++]);
1718 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1724 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1726 DECLARESepPutFunc(putRGBUAseparate16bittile
)
1728 uint16
*wr
= (uint16
*) r
;
1729 uint16
*wg
= (uint16
*) g
;
1730 uint16
*wb
= (uint16
*) b
;
1731 uint16
*wa
= (uint16
*) a
;
1732 (void) img
; (void) y
;
1733 for( ; h
> 0; --h
) {
1736 for (x
= w
; x
> 0; --x
) {
1737 a2
= img
->Bitdepth16To8
[*wa
++];
1738 m
= img
->UaToAa
+((size_t) a2
<<8);
1739 r2
= m
[img
->Bitdepth16To8
[*wr
++]];
1740 g2
= m
[img
->Bitdepth16To8
[*wg
++]];
1741 b2
= m
[img
->Bitdepth16To8
[*wb
++]];
1742 *cp
++ = PACK4(r2
,g2
,b2
,a2
);
1744 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1750 * 8-bit packed CIE L*a*b 1976 samples => RGB
1752 DECLAREContigPutFunc(putcontig8bitCIELab
)
1758 for( ; h
> 0; --h
) {
1759 for (x
= w
; x
> 0; --x
) {
1760 TIFFCIELabToXYZ(img
->cielab
,
1761 (unsigned char)pp
[0],
1765 TIFFXYZToRGB(img
->cielab
, X
, Y
, Z
, &r
, &g
, &b
);
1766 *cp
++ = PACK(r
, g
, b
);
1775 * YCbCr -> RGB conversion and packing routines.
1778 #define YCbCrtoRGB(dst, Y) { \
1780 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1781 dst = PACK(r, g, b); \
1785 * 8-bit packed YCbCr samples => RGB
1786 * This function is generic for different sampling sizes,
1787 * and can handle blocks sizes that aren't multiples of the
1788 * sampling size. However, it is substantially less optimized
1789 * than the specific sampling cases. It is used as a fallback
1790 * for difficult blocks.
1793 static void putcontig8bitYCbCrGenericTile(
1798 int32 fromskew
, int32 toskew
,
1804 uint32
* cp1
= cp
+w
+toskew
;
1805 uint32
* cp2
= cp1
+w
+toskew
;
1806 uint32
* cp3
= cp2
+w
+toskew
;
1807 int32 incr
= 3*w
+4*toskew
;
1809 int group_size
= v_group
* h_group
+ 2;
1812 fromskew
= (fromskew
* group_size
) / h_group
;
1814 for( yy
= 0; yy
< h
; yy
++ )
1816 unsigned char *pp_line
;
1817 int y_line_group
= yy
/ v_group
;
1818 int y_remainder
= yy
- y_line_group
* v_group
;
1820 pp_line
= pp
+ v_line_group
*
1823 for( xx
= 0; xx
< w
; xx
++ )
1828 for (; h
>= 4; h
-= 4) {
1834 YCbCrtoRGB(cp
[0], pp
[ 0]);
1835 YCbCrtoRGB(cp
[1], pp
[ 1]);
1836 YCbCrtoRGB(cp
[2], pp
[ 2]);
1837 YCbCrtoRGB(cp
[3], pp
[ 3]);
1838 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1839 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1840 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1841 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1842 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1843 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1844 YCbCrtoRGB(cp2
[2], pp
[10]);
1845 YCbCrtoRGB(cp2
[3], pp
[11]);
1846 YCbCrtoRGB(cp3
[0], pp
[12]);
1847 YCbCrtoRGB(cp3
[1], pp
[13]);
1848 YCbCrtoRGB(cp3
[2], pp
[14]);
1849 YCbCrtoRGB(cp3
[3], pp
[15]);
1851 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1854 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1861 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1863 DECLAREContigPutFunc(putcontig8bitYCbCr44tile
)
1865 uint32
* cp1
= cp
+w
+toskew
;
1866 uint32
* cp2
= cp1
+w
+toskew
;
1867 uint32
* cp3
= cp2
+w
+toskew
;
1868 int32 incr
= 3*w
+4*toskew
;
1871 /* adjust fromskew */
1872 fromskew
= (fromskew
/ 4) * (4*2+2);
1873 if ((h
& 3) == 0 && (w
& 3) == 0) {
1874 for (; h
>= 4; h
-= 4) {
1880 YCbCrtoRGB(cp
[0], pp
[ 0]);
1881 YCbCrtoRGB(cp
[1], pp
[ 1]);
1882 YCbCrtoRGB(cp
[2], pp
[ 2]);
1883 YCbCrtoRGB(cp
[3], pp
[ 3]);
1884 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1885 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1886 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1887 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1888 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1889 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1890 YCbCrtoRGB(cp2
[2], pp
[10]);
1891 YCbCrtoRGB(cp2
[3], pp
[11]);
1892 YCbCrtoRGB(cp3
[0], pp
[12]);
1893 YCbCrtoRGB(cp3
[1], pp
[13]);
1894 YCbCrtoRGB(cp3
[2], pp
[14]);
1895 YCbCrtoRGB(cp3
[3], pp
[15]);
1911 for (x
= w
; x
> 0;) {
1917 default: YCbCrtoRGB(cp3
[3], pp
[15]); /* FALLTHROUGH */
1918 case 3: YCbCrtoRGB(cp2
[3], pp
[11]); /* FALLTHROUGH */
1919 case 2: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1920 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1924 default: YCbCrtoRGB(cp3
[2], pp
[14]); /* FALLTHROUGH */
1925 case 3: YCbCrtoRGB(cp2
[2], pp
[10]); /* FALLTHROUGH */
1926 case 2: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1927 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1931 default: YCbCrtoRGB(cp3
[1], pp
[13]); /* FALLTHROUGH */
1932 case 3: YCbCrtoRGB(cp2
[1], pp
[ 9]); /* FALLTHROUGH */
1933 case 2: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1934 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1938 default: YCbCrtoRGB(cp3
[0], pp
[12]); /* FALLTHROUGH */
1939 case 3: YCbCrtoRGB(cp2
[0], pp
[ 8]); /* FALLTHROUGH */
1940 case 2: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1941 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1945 cp
+= x
; cp1
+= x
; cp2
+= x
; cp3
+= x
;
1949 cp
+= 4; cp1
+= 4; cp2
+= 4; cp3
+= 4;
1967 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1969 DECLAREContigPutFunc(putcontig8bitYCbCr42tile
)
1971 uint32
* cp1
= cp
+w
+toskew
;
1972 int32 incr
= 2*toskew
+w
;
1975 fromskew
= (fromskew
/ 4) * (4*2+2);
1976 if ((w
& 3) == 0 && (h
& 1) == 0) {
1977 for (; h
>= 2; h
-= 2) {
1983 YCbCrtoRGB(cp
[0], pp
[0]);
1984 YCbCrtoRGB(cp
[1], pp
[1]);
1985 YCbCrtoRGB(cp
[2], pp
[2]);
1986 YCbCrtoRGB(cp
[3], pp
[3]);
1987 YCbCrtoRGB(cp1
[0], pp
[4]);
1988 YCbCrtoRGB(cp1
[1], pp
[5]);
1989 YCbCrtoRGB(cp1
[2], pp
[6]);
1990 YCbCrtoRGB(cp1
[3], pp
[7]);
2002 for (x
= w
; x
> 0;) {
2008 default: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
2009 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
2013 default: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
2014 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
2018 default: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
2019 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
2023 default: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
2024 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
2048 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
2050 DECLAREContigPutFunc(putcontig8bitYCbCr41tile
)
2053 fromskew
= (fromskew
/ 4) * (4*1+2);
2060 YCbCrtoRGB(cp
[0], pp
[0]);
2061 YCbCrtoRGB(cp
[1], pp
[1]);
2062 YCbCrtoRGB(cp
[2], pp
[2]);
2063 YCbCrtoRGB(cp
[3], pp
[3]);
2076 case 3: YCbCrtoRGB(cp
[2], pp
[2]); /*-fallthrough*/
2077 case 2: YCbCrtoRGB(cp
[1], pp
[1]); /*-fallthrough*/
2078 case 1: YCbCrtoRGB(cp
[0], pp
[0]); /*-fallthrough*/
2093 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
2095 DECLAREContigPutFunc(putcontig8bitYCbCr22tile
)
2098 int32 incr
= 2*toskew
+w
;
2100 fromskew
= (fromskew
/ 2) * (2*2+2);
2107 YCbCrtoRGB(cp
[0], pp
[0]);
2108 YCbCrtoRGB(cp
[1], pp
[1]);
2109 YCbCrtoRGB(cp2
[0], pp
[2]);
2110 YCbCrtoRGB(cp2
[1], pp
[3]);
2119 YCbCrtoRGB(cp
[0], pp
[0]);
2120 YCbCrtoRGB(cp2
[0], pp
[2]);
2135 YCbCrtoRGB(cp
[0], pp
[0]);
2136 YCbCrtoRGB(cp
[1], pp
[1]);
2145 YCbCrtoRGB(cp
[0], pp
[0]);
2151 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
2153 DECLAREContigPutFunc(putcontig8bitYCbCr21tile
)
2156 fromskew
= (fromskew
/ 2) * (2*1+2);
2163 YCbCrtoRGB(cp
[0], pp
[0]);
2164 YCbCrtoRGB(cp
[1], pp
[1]);
2176 YCbCrtoRGB(cp
[0], pp
[0]);
2188 * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
2190 DECLAREContigPutFunc(putcontig8bitYCbCr12tile
)
2193 int32 incr
= 2*toskew
+w
;
2195 fromskew
= (fromskew
/ 1) * (1 * 2 + 2);
2202 YCbCrtoRGB(cp
[0], pp
[0]);
2203 YCbCrtoRGB(cp2
[0], pp
[1]);
2218 YCbCrtoRGB(cp
[0], pp
[0]);
2226 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2228 DECLAREContigPutFunc(putcontig8bitYCbCr11tile
)
2231 fromskew
= (fromskew
/ 1) * (1 * 1 + 2);
2233 x
= w
; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
2238 YCbCrtoRGB(*cp
++, pp
[0]);
2248 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2250 DECLARESepPutFunc(putseparate8bitYCbCr11tile
)
2254 /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2255 for( ; h
> 0; --h
) {
2259 TIFFYCbCrtoRGB(img
->ycbcr
,*r
++,*g
++,*b
++,&dr
,&dg
,&db
);
2260 *cp
++ = PACK(dr
,dg
,db
);
2262 SKEW(r
, g
, b
, fromskew
);
2268 static int isInRefBlackWhiteRange(float f
)
2270 return f
> (float)(-0x7FFFFFFF + 128) && f
< (float)0x7FFFFFFF;
2274 initYCbCrConversion(TIFFRGBAImage
* img
)
2276 static const char module
[] = "initYCbCrConversion";
2278 float *luma
, *refBlackWhite
;
2280 if (img
->ycbcr
== NULL
) {
2281 img
->ycbcr
= (TIFFYCbCrToRGB
*) _TIFFmalloc(
2282 TIFFroundup_32(sizeof (TIFFYCbCrToRGB
), sizeof (long))
2283 + 4*256*sizeof (TIFFRGBValue
)
2284 + 2*256*sizeof (int)
2285 + 3*256*sizeof (int32
)
2287 if (img
->ycbcr
== NULL
) {
2288 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2289 "No space for YCbCr->RGB conversion state");
2294 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRCOEFFICIENTS
, &luma
);
2295 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_REFERENCEBLACKWHITE
,
2298 /* Do some validation to avoid later issues. Detect NaN for now */
2299 /* and also if lumaGreen is zero since we divide by it later */
2300 if( luma
[0] != luma
[0] ||
2301 luma
[1] != luma
[1] ||
2303 luma
[2] != luma
[2] )
2305 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2306 "Invalid values for YCbCrCoefficients tag");
2310 if( !isInRefBlackWhiteRange(refBlackWhite
[0]) ||
2311 !isInRefBlackWhiteRange(refBlackWhite
[1]) ||
2312 !isInRefBlackWhiteRange(refBlackWhite
[2]) ||
2313 !isInRefBlackWhiteRange(refBlackWhite
[3]) ||
2314 !isInRefBlackWhiteRange(refBlackWhite
[4]) ||
2315 !isInRefBlackWhiteRange(refBlackWhite
[5]) )
2317 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2318 "Invalid values for ReferenceBlackWhite tag");
2322 if (TIFFYCbCrToRGBInit(img
->ycbcr
, luma
, refBlackWhite
) < 0)
2327 static tileContigRoutine
2328 initCIELabConversion(TIFFRGBAImage
* img
)
2330 static const char module
[] = "initCIELabConversion";
2335 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_WHITEPOINT
, &whitePoint
);
2336 if (whitePoint
[1] == 0.0f
) {
2337 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2338 "Invalid value for WhitePoint tag.");
2343 img
->cielab
= (TIFFCIELabToRGB
*)
2344 _TIFFmalloc(sizeof(TIFFCIELabToRGB
));
2346 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2347 "No space for CIE L*a*b*->RGB conversion state.");
2352 refWhite
[1] = 100.0F
;
2353 refWhite
[0] = whitePoint
[0] / whitePoint
[1] * refWhite
[1];
2354 refWhite
[2] = (1.0F
- whitePoint
[0] - whitePoint
[1])
2355 / whitePoint
[1] * refWhite
[1];
2356 if (TIFFCIELabToRGBInit(img
->cielab
, &display_sRGB
, refWhite
) < 0) {
2357 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2358 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2359 _TIFFfree(img
->cielab
);
2363 return putcontig8bitCIELab
;
2367 * Greyscale images with less than 8 bits/sample are handled
2368 * with a table to avoid lots of shifts and masks. The table
2369 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2370 * pixel values simply by indexing into the table with one
2374 makebwmap(TIFFRGBAImage
* img
)
2376 TIFFRGBValue
* Map
= img
->Map
;
2377 int bitspersample
= img
->bitspersample
;
2378 int nsamples
= 8 / bitspersample
;
2385 img
->BWmap
= (uint32
**) _TIFFmalloc(
2386 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2387 if (img
->BWmap
== NULL
) {
2388 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for B&W mapping table");
2391 p
= (uint32
*)(img
->BWmap
+ 256);
2392 for (i
= 0; i
< 256; i
++) {
2395 switch (bitspersample
) {
2396 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2428 * Construct a mapping table to convert from the range
2429 * of the data samples to [0,255] --for display. This
2430 * process also handles inverting B&W images when needed.
2433 setupMap(TIFFRGBAImage
* img
)
2437 range
= (int32
)((1L<<img
->bitspersample
)-1);
2439 /* treat 16 bit the same as eight bit */
2440 if( img
->bitspersample
== 16 )
2441 range
= (int32
) 255;
2443 img
->Map
= (TIFFRGBValue
*) _TIFFmalloc((range
+1) * sizeof (TIFFRGBValue
));
2444 if (img
->Map
== NULL
) {
2445 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
2446 "No space for photometric conversion table");
2449 if (img
->photometric
== PHOTOMETRIC_MINISWHITE
) {
2450 for (x
= 0; x
<= range
; x
++)
2451 img
->Map
[x
] = (TIFFRGBValue
) (((range
- x
) * 255) / range
);
2453 for (x
= 0; x
<= range
; x
++)
2454 img
->Map
[x
] = (TIFFRGBValue
) ((x
* 255) / range
);
2456 if (img
->bitspersample
<= 16 &&
2457 (img
->photometric
== PHOTOMETRIC_MINISBLACK
||
2458 img
->photometric
== PHOTOMETRIC_MINISWHITE
)) {
2460 * Use photometric mapping table to construct
2461 * unpacking tables for samples <= 8 bits.
2463 if (!makebwmap(img
))
2465 /* no longer need Map, free it */
2466 _TIFFfree(img
->Map
);
2473 checkcmap(TIFFRGBAImage
* img
)
2475 uint16
* r
= img
->redcmap
;
2476 uint16
* g
= img
->greencmap
;
2477 uint16
* b
= img
->bluecmap
;
2478 long n
= 1L<<img
->bitspersample
;
2481 if (*r
++ >= 256 || *g
++ >= 256 || *b
++ >= 256)
2487 cvtcmap(TIFFRGBAImage
* img
)
2489 uint16
* r
= img
->redcmap
;
2490 uint16
* g
= img
->greencmap
;
2491 uint16
* b
= img
->bluecmap
;
2494 for (i
= (1L<<img
->bitspersample
)-1; i
>= 0; i
--) {
2495 #define CVT(x) ((uint16)((x)>>8))
2504 * Palette images with <= 8 bits/sample are handled
2505 * with a table to avoid lots of shifts and masks. The table
2506 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2507 * pixel values simply by indexing into the table with one
2511 makecmap(TIFFRGBAImage
* img
)
2513 int bitspersample
= img
->bitspersample
;
2514 int nsamples
= 8 / bitspersample
;
2515 uint16
* r
= img
->redcmap
;
2516 uint16
* g
= img
->greencmap
;
2517 uint16
* b
= img
->bluecmap
;
2521 img
->PALmap
= (uint32
**) _TIFFmalloc(
2522 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2523 if (img
->PALmap
== NULL
) {
2524 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for Palette mapping table");
2527 p
= (uint32
*)(img
->PALmap
+ 256);
2528 for (i
= 0; i
< 256; i
++) {
2531 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2532 switch (bitspersample
) {
2563 * Construct any mapping table used
2564 * by the associated put routine.
2567 buildMap(TIFFRGBAImage
* img
)
2569 switch (img
->photometric
) {
2570 case PHOTOMETRIC_RGB
:
2571 case PHOTOMETRIC_YCBCR
:
2572 case PHOTOMETRIC_SEPARATED
:
2573 if (img
->bitspersample
== 8)
2575 /* fall through... */
2576 case PHOTOMETRIC_MINISBLACK
:
2577 case PHOTOMETRIC_MINISWHITE
:
2581 case PHOTOMETRIC_PALETTE
:
2583 * Convert 16-bit colormap to 8-bit (unless it looks
2584 * like an old-style 8-bit colormap).
2586 if (checkcmap(img
) == 16)
2589 TIFFWarningExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "Assuming 8-bit colormap");
2591 * Use mapping table and colormap to construct
2592 * unpacking tables for samples < 8 bits.
2594 if (img
->bitspersample
<= 8 && !makecmap(img
))
2602 * Select the appropriate conversion routine for packed data.
2605 PickContigCase(TIFFRGBAImage
* img
)
2607 img
->get
= TIFFIsTiled(img
->tif
) ? gtTileContig
: gtStripContig
;
2608 img
->put
.contig
= NULL
;
2609 switch (img
->photometric
) {
2610 case PHOTOMETRIC_RGB
:
2611 switch (img
->bitspersample
) {
2613 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
&&
2614 img
->samplesperpixel
>= 4)
2615 img
->put
.contig
= putRGBAAcontig8bittile
;
2616 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
&&
2617 img
->samplesperpixel
>= 4)
2619 if (BuildMapUaToAa(img
))
2620 img
->put
.contig
= putRGBUAcontig8bittile
;
2622 else if( img
->samplesperpixel
>= 3 )
2623 img
->put
.contig
= putRGBcontig8bittile
;
2626 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
&&
2627 img
->samplesperpixel
>=4 )
2629 if (BuildMapBitdepth16To8(img
))
2630 img
->put
.contig
= putRGBAAcontig16bittile
;
2632 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
&&
2633 img
->samplesperpixel
>=4 )
2635 if (BuildMapBitdepth16To8(img
) &&
2636 BuildMapUaToAa(img
))
2637 img
->put
.contig
= putRGBUAcontig16bittile
;
2639 else if( img
->samplesperpixel
>=3 )
2641 if (BuildMapBitdepth16To8(img
))
2642 img
->put
.contig
= putRGBcontig16bittile
;
2647 case PHOTOMETRIC_SEPARATED
:
2648 if (img
->samplesperpixel
>=4 && buildMap(img
)) {
2649 if (img
->bitspersample
== 8) {
2651 img
->put
.contig
= putRGBcontig8bitCMYKtile
;
2653 img
->put
.contig
= putRGBcontig8bitCMYKMaptile
;
2657 case PHOTOMETRIC_PALETTE
:
2658 if (buildMap(img
)) {
2659 switch (img
->bitspersample
) {
2661 img
->put
.contig
= put8bitcmaptile
;
2664 img
->put
.contig
= put4bitcmaptile
;
2667 img
->put
.contig
= put2bitcmaptile
;
2670 img
->put
.contig
= put1bitcmaptile
;
2675 case PHOTOMETRIC_MINISWHITE
:
2676 case PHOTOMETRIC_MINISBLACK
:
2677 if (buildMap(img
)) {
2678 switch (img
->bitspersample
) {
2680 img
->put
.contig
= put16bitbwtile
;
2683 if (img
->alpha
&& img
->samplesperpixel
== 2)
2684 img
->put
.contig
= putagreytile
;
2686 img
->put
.contig
= putgreytile
;
2689 img
->put
.contig
= put4bitbwtile
;
2692 img
->put
.contig
= put2bitbwtile
;
2695 img
->put
.contig
= put1bitbwtile
;
2700 case PHOTOMETRIC_YCBCR
:
2701 if ((img
->bitspersample
==8) && (img
->samplesperpixel
==3))
2703 if (initYCbCrConversion(img
)!=0)
2706 * The 6.0 spec says that subsampling must be
2707 * one of 1, 2, or 4, and that vertical subsampling
2708 * must always be <= horizontal subsampling; so
2709 * there are only a few possibilities and we just
2710 * enumerate the cases.
2711 * Joris: added support for the [1,2] case, nonetheless, to accommodate
2714 uint16 SubsamplingHor
;
2715 uint16 SubsamplingVer
;
2716 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &SubsamplingHor
, &SubsamplingVer
);
2717 switch ((SubsamplingHor
<<4)|SubsamplingVer
) {
2719 img
->put
.contig
= putcontig8bitYCbCr44tile
;
2722 img
->put
.contig
= putcontig8bitYCbCr42tile
;
2725 img
->put
.contig
= putcontig8bitYCbCr41tile
;
2728 img
->put
.contig
= putcontig8bitYCbCr22tile
;
2731 img
->put
.contig
= putcontig8bitYCbCr21tile
;
2734 img
->put
.contig
= putcontig8bitYCbCr12tile
;
2737 img
->put
.contig
= putcontig8bitYCbCr11tile
;
2743 case PHOTOMETRIC_CIELAB
:
2744 if (img
->samplesperpixel
== 3 && buildMap(img
)) {
2745 if (img
->bitspersample
== 8)
2746 img
->put
.contig
= initCIELabConversion(img
);
2750 return ((img
->get
!=NULL
) && (img
->put
.contig
!=NULL
));
2754 * Select the appropriate conversion routine for unpacked data.
2756 * NB: we assume that unpacked single channel data is directed
2757 * to the "packed routines.
2760 PickSeparateCase(TIFFRGBAImage
* img
)
2762 img
->get
= TIFFIsTiled(img
->tif
) ? gtTileSeparate
: gtStripSeparate
;
2763 img
->put
.separate
= NULL
;
2764 switch (img
->photometric
) {
2765 case PHOTOMETRIC_MINISWHITE
:
2766 case PHOTOMETRIC_MINISBLACK
:
2767 /* greyscale images processed pretty much as RGB by gtTileSeparate */
2768 case PHOTOMETRIC_RGB
:
2769 switch (img
->bitspersample
) {
2771 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2772 img
->put
.separate
= putRGBAAseparate8bittile
;
2773 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2775 if (BuildMapUaToAa(img
))
2776 img
->put
.separate
= putRGBUAseparate8bittile
;
2779 img
->put
.separate
= putRGBseparate8bittile
;
2782 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2784 if (BuildMapBitdepth16To8(img
))
2785 img
->put
.separate
= putRGBAAseparate16bittile
;
2787 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2789 if (BuildMapBitdepth16To8(img
) &&
2790 BuildMapUaToAa(img
))
2791 img
->put
.separate
= putRGBUAseparate16bittile
;
2795 if (BuildMapBitdepth16To8(img
))
2796 img
->put
.separate
= putRGBseparate16bittile
;
2801 case PHOTOMETRIC_SEPARATED
:
2802 if (img
->bitspersample
== 8 && img
->samplesperpixel
== 4)
2804 img
->alpha
= 1; // Not alpha, but seems like the only way to get 4th band
2805 img
->put
.separate
= putCMYKseparate8bittile
;
2808 case PHOTOMETRIC_YCBCR
:
2809 if ((img
->bitspersample
==8) && (img
->samplesperpixel
==3))
2811 if (initYCbCrConversion(img
)!=0)
2814 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &hs
, &vs
);
2815 switch ((hs
<<4)|vs
) {
2817 img
->put
.separate
= putseparate8bitYCbCr11tile
;
2819 /* TODO: add other cases here */
2825 return ((img
->get
!=NULL
) && (img
->put
.separate
!=NULL
));
2829 BuildMapUaToAa(TIFFRGBAImage
* img
)
2831 static const char module
[]="BuildMapUaToAa";
2834 assert(img
->UaToAa
==NULL
);
2835 img
->UaToAa
=_TIFFmalloc(65536);
2836 if (img
->UaToAa
==NULL
)
2838 TIFFErrorExt(img
->tif
->tif_clientdata
,module
,"Out of memory");
2842 for (na
=0; na
<256; na
++)
2844 for (nv
=0; nv
<256; nv
++)
2845 *m
++=(uint8
)((nv
*na
+127)/255);
2851 BuildMapBitdepth16To8(TIFFRGBAImage
* img
)
2853 static const char module
[]="BuildMapBitdepth16To8";
2856 assert(img
->Bitdepth16To8
==NULL
);
2857 img
->Bitdepth16To8
=_TIFFmalloc(65536);
2858 if (img
->Bitdepth16To8
==NULL
)
2860 TIFFErrorExt(img
->tif
->tif_clientdata
,module
,"Out of memory");
2863 m
=img
->Bitdepth16To8
;
2864 for (n
=0; n
<65536; n
++)
2865 *m
++=(uint8
)((n
+128)/257);
2871 * Read a whole strip off data from the file, and convert to RGBA form.
2872 * If this is the last strip, then it will only contain the portion of
2873 * the strip that is actually within the image space. The result is
2874 * organized in bottom to top form.
2879 TIFFReadRGBAStrip(TIFF
* tif
, uint32 row
, uint32
* raster
)
2882 return TIFFReadRGBAStripExt(tif
, row
, raster
, 0 );
2886 TIFFReadRGBAStripExt(TIFF
* tif
, uint32 row
, uint32
* raster
, int stop_on_error
)
2889 char emsg
[1024] = "";
2892 uint32 rowsperstrip
, rows_to_read
;
2894 if( TIFFIsTiled( tif
) )
2896 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2897 "Can't use TIFFReadRGBAStrip() with tiled file.");
2901 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
2902 if( (row
% rowsperstrip
) != 0 )
2904 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2905 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2909 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, stop_on_error
, emsg
)) {
2911 img
.row_offset
= row
;
2914 if( row
+ rowsperstrip
> img
.height
)
2915 rows_to_read
= img
.height
- row
;
2917 rows_to_read
= rowsperstrip
;
2919 ok
= TIFFRGBAImageGet(&img
, raster
, img
.width
, rows_to_read
);
2921 TIFFRGBAImageEnd(&img
);
2923 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
2931 * Read a whole tile off data from the file, and convert to RGBA form.
2932 * The returned RGBA data is organized from bottom to top of tile,
2933 * and may include zeroed areas if the tile extends off the image.
2937 TIFFReadRGBATile(TIFF
* tif
, uint32 col
, uint32 row
, uint32
* raster
)
2940 return TIFFReadRGBATileExt(tif
, col
, row
, raster
, 0 );
2945 TIFFReadRGBATileExt(TIFF
* tif
, uint32 col
, uint32 row
, uint32
* raster
, int stop_on_error
)
2947 char emsg
[1024] = "";
2950 uint32 tile_xsize
, tile_ysize
;
2951 uint32 read_xsize
, read_ysize
;
2955 * Verify that our request is legal - on a tile file, and on a
2959 if( !TIFFIsTiled( tif
) )
2961 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2962 "Can't use TIFFReadRGBATile() with stripped file.");
2966 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILEWIDTH
, &tile_xsize
);
2967 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILELENGTH
, &tile_ysize
);
2968 if( (col
% tile_xsize
) != 0 || (row
% tile_ysize
) != 0 )
2970 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2971 "Row/col passed to TIFFReadRGBATile() must be top"
2972 "left corner of a tile.");
2977 * Setup the RGBA reader.
2980 if (!TIFFRGBAImageOK(tif
, emsg
)
2981 || !TIFFRGBAImageBegin(&img
, tif
, stop_on_error
, emsg
)) {
2982 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
2987 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2988 * edge of the image, even to fill an otherwise valid tile. So we
2989 * figure out how much we can read, and fix up the tile buffer to
2990 * a full tile configuration afterwards.
2993 if( row
+ tile_ysize
> img
.height
)
2994 read_ysize
= img
.height
- row
;
2996 read_ysize
= tile_ysize
;
2998 if( col
+ tile_xsize
> img
.width
)
2999 read_xsize
= img
.width
- col
;
3001 read_xsize
= tile_xsize
;
3004 * Read the chunk of imagery.
3007 img
.row_offset
= row
;
3008 img
.col_offset
= col
;
3010 ok
= TIFFRGBAImageGet(&img
, raster
, read_xsize
, read_ysize
);
3012 TIFFRGBAImageEnd(&img
);
3015 * If our read was incomplete we will need to fix up the tile by
3016 * shifting the data around as if a full tile of data is being returned.
3018 * This is all the more complicated because the image is organized in
3019 * bottom to top format.
3022 if( read_xsize
== tile_xsize
&& read_ysize
== tile_ysize
)
3025 for( i_row
= 0; i_row
< read_ysize
; i_row
++ ) {
3026 memmove( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
3027 raster
+ (read_ysize
- i_row
- 1) * read_xsize
,
3028 read_xsize
* sizeof(uint32
) );
3029 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
+read_xsize
,
3030 0, sizeof(uint32
) * (tile_xsize
- read_xsize
) );
3033 for( i_row
= read_ysize
; i_row
< tile_ysize
; i_row
++ ) {
3034 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
3035 0, sizeof(uint32
) * tile_xsize
);
3041 /* vim: set ts=8 sts=8 sw=8 noet: */