2 * Copyright (c) 1991-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that (i) the above copyright notices and this permission notice appear in
8 * all copies of the software and related documentation, and (ii) the names of
9 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 * publicity relating to the software without the specific, prior written
11 * permission of Sam Leffler and Silicon Graphics.
13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
28 * Read and return a packed RGBA image.
33 static int gtTileContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
34 static int gtTileSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
35 static int gtStripContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
36 static int gtStripSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
37 static int PickContigCase(TIFFRGBAImage
*);
38 static int PickSeparateCase(TIFFRGBAImage
*);
40 static int BuildMapUaToAa(TIFFRGBAImage
* img
);
41 static int BuildMapBitdepth16To8(TIFFRGBAImage
* img
);
43 static const char photoTag
[] = "PhotometricInterpretation";
46 * Helper constants used in Orientation tag handling
48 #define FLIP_VERTICALLY 0x01
49 #define FLIP_HORIZONTALLY 0x02
52 * Color conversion constants. We will define display types here.
55 static const TIFFDisplay display_sRGB
= {
56 { /* XYZ -> luminance matrix */
57 { 3.2410F
, -1.5374F
, -0.4986F
},
58 { -0.9692F
, 1.8760F
, 0.0416F
},
59 { 0.0556F
, -0.2040F
, 1.0570F
}
61 100.0F
, 100.0F
, 100.0F
, /* Light o/p for reference white */
62 255, 255, 255, /* Pixel values for ref. white */
63 1.0F
, 1.0F
, 1.0F
, /* Residual light o/p for black pixel */
64 2.4F
, 2.4F
, 2.4F
, /* Gamma values for the three guns */
68 * Check the image to see if TIFFReadRGBAImage can deal with it.
69 * 1/0 is returned according to whether or not the image can
70 * be handled. If 0 is returned, emsg contains the reason
71 * why it is being rejected.
74 TIFFRGBAImageOK(TIFF
* tif
, char emsg
[1024])
76 TIFFDirectory
* td
= &tif
->tif_dir
;
80 if (!tif
->tif_decodestatus
) {
81 sprintf(emsg
, "Sorry, requested compression method is not configured");
84 switch (td
->td_bitspersample
) {
92 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
93 td
->td_bitspersample
);
96 if (td
->td_sampleformat
== SAMPLEFORMAT_IEEEFP
) {
97 sprintf(emsg
, "Sorry, can not handle images with IEEE floating-point samples");
100 colorchannels
= td
->td_samplesperpixel
- td
->td_extrasamples
;
101 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &photometric
)) {
102 switch (colorchannels
) {
104 photometric
= PHOTOMETRIC_MINISBLACK
;
107 photometric
= PHOTOMETRIC_RGB
;
110 sprintf(emsg
, "Missing needed %s tag", photoTag
);
114 switch (photometric
) {
115 case PHOTOMETRIC_MINISWHITE
:
116 case PHOTOMETRIC_MINISBLACK
:
117 case PHOTOMETRIC_PALETTE
:
118 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
119 && td
->td_samplesperpixel
!= 1
120 && td
->td_bitspersample
< 8 ) {
122 "Sorry, can not handle contiguous data with %s=%d, "
123 "and %s=%d and Bits/Sample=%d",
124 photoTag
, photometric
,
125 "Samples/pixel", td
->td_samplesperpixel
,
126 td
->td_bitspersample
);
130 * We should likely validate that any extra samples are either
131 * to be ignored, or are alpha, and if alpha we should try to use
132 * them. But for now we won't bother with this.
135 case PHOTOMETRIC_YCBCR
:
137 * TODO: if at all meaningful and useful, make more complete
138 * support check here, or better still, refactor to let supporting
139 * code decide whether there is support and what meaningful
143 case PHOTOMETRIC_RGB
:
144 if (colorchannels
< 3) {
145 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
146 "Color channels", colorchannels
);
150 case PHOTOMETRIC_SEPARATED
:
153 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
154 if (inkset
!= INKSET_CMYK
) {
156 "Sorry, can not handle separated image with %s=%d",
160 if (td
->td_samplesperpixel
< 4) {
162 "Sorry, can not handle separated image with %s=%d",
163 "Samples/pixel", td
->td_samplesperpixel
);
168 case PHOTOMETRIC_LOGL
:
169 if (td
->td_compression
!= COMPRESSION_SGILOG
) {
170 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
171 "Compression", COMPRESSION_SGILOG
);
175 case PHOTOMETRIC_LOGLUV
:
176 if (td
->td_compression
!= COMPRESSION_SGILOG
&&
177 td
->td_compression
!= COMPRESSION_SGILOG24
) {
178 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
179 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
182 if (td
->td_planarconfig
!= PLANARCONFIG_CONTIG
) {
183 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
184 "Planarconfiguration", td
->td_planarconfig
);
187 if ( td
->td_samplesperpixel
!= 3 || colorchannels
!= 3 ) {
189 "Sorry, can not handle image with %s=%d, %s=%d",
190 "Samples/pixel", td
->td_samplesperpixel
,
191 "colorchannels", colorchannels
);
195 case PHOTOMETRIC_CIELAB
:
196 if ( td
->td_samplesperpixel
!= 3 || colorchannels
!= 3 || td
->td_bitspersample
!= 8 ) {
198 "Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
199 "Samples/pixel", td
->td_samplesperpixel
,
200 "colorchannels", colorchannels
,
201 "Bits/sample", td
->td_bitspersample
);
206 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
207 photoTag
, photometric
);
214 TIFFRGBAImageEnd(TIFFRGBAImage
* img
)
221 _TIFFfree(img
->BWmap
);
225 _TIFFfree(img
->PALmap
);
229 _TIFFfree(img
->ycbcr
);
233 _TIFFfree(img
->cielab
);
237 _TIFFfree(img
->UaToAa
);
240 if (img
->Bitdepth16To8
) {
241 _TIFFfree(img
->Bitdepth16To8
);
242 img
->Bitdepth16To8
= NULL
;
246 _TIFFfree( img
->redcmap
);
247 _TIFFfree( img
->greencmap
);
248 _TIFFfree( img
->bluecmap
);
249 img
->redcmap
= img
->greencmap
= img
->bluecmap
= NULL
;
254 isCCITTCompression(TIFF
* tif
)
257 TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compress
);
258 return (compress
== COMPRESSION_CCITTFAX3
||
259 compress
== COMPRESSION_CCITTFAX4
||
260 compress
== COMPRESSION_CCITTRLE
||
261 compress
== COMPRESSION_CCITTRLEW
);
265 TIFFRGBAImageBegin(TIFFRGBAImage
* img
, TIFF
* tif
, int stop
, char emsg
[1024])
272 uint16
*red_orig
, *green_orig
, *blue_orig
;
275 if( !TIFFRGBAImageOK(tif
, emsg
) )
278 /* Initialize to normal values */
282 img
->greencmap
= NULL
;
283 img
->bluecmap
= NULL
;
290 img
->Bitdepth16To8
= NULL
;
291 img
->req_orientation
= ORIENTATION_BOTLEFT
; /* It is the default */
294 img
->stoponerr
= stop
;
295 TIFFGetFieldDefaulted(tif
, TIFFTAG_BITSPERSAMPLE
, &img
->bitspersample
);
296 switch (img
->bitspersample
) {
304 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
309 TIFFGetFieldDefaulted(tif
, TIFFTAG_SAMPLESPERPIXEL
, &img
->samplesperpixel
);
310 TIFFGetFieldDefaulted(tif
, TIFFTAG_EXTRASAMPLES
,
311 &extrasamples
, &sampleinfo
);
312 if (extrasamples
>= 1)
314 switch (sampleinfo
[0]) {
315 case EXTRASAMPLE_UNSPECIFIED
: /* Workaround for some images without */
316 if (img
->samplesperpixel
> 3) /* correct info about alpha channel */
317 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
319 case EXTRASAMPLE_ASSOCALPHA
: /* data is pre-multiplied */
320 case EXTRASAMPLE_UNASSALPHA
: /* data is not pre-multiplied */
321 img
->alpha
= sampleinfo
[0];
326 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
327 if( !TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
))
328 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
330 if( extrasamples
== 0
331 && img
->samplesperpixel
== 4
332 && img
->photometric
== PHOTOMETRIC_RGB
)
334 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
339 colorchannels
= img
->samplesperpixel
- extrasamples
;
340 TIFFGetFieldDefaulted(tif
, TIFFTAG_COMPRESSION
, &compress
);
341 TIFFGetFieldDefaulted(tif
, TIFFTAG_PLANARCONFIG
, &planarconfig
);
342 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
)) {
343 switch (colorchannels
) {
345 if (isCCITTCompression(tif
))
346 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
348 img
->photometric
= PHOTOMETRIC_MINISBLACK
;
351 img
->photometric
= PHOTOMETRIC_RGB
;
354 sprintf(emsg
, "Missing needed %s tag", photoTag
);
358 switch (img
->photometric
) {
359 case PHOTOMETRIC_PALETTE
:
360 if (!TIFFGetField(tif
, TIFFTAG_COLORMAP
,
361 &red_orig
, &green_orig
, &blue_orig
)) {
362 sprintf(emsg
, "Missing required \"Colormap\" tag");
366 /* copy the colormaps so we can modify them */
367 n_color
= (1U << img
->bitspersample
);
368 img
->redcmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
369 img
->greencmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
370 img
->bluecmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
371 if( !img
->redcmap
|| !img
->greencmap
|| !img
->bluecmap
) {
372 sprintf(emsg
, "Out of memory for colormap copy");
376 _TIFFmemcpy( img
->redcmap
, red_orig
, n_color
* 2 );
377 _TIFFmemcpy( img
->greencmap
, green_orig
, n_color
* 2 );
378 _TIFFmemcpy( img
->bluecmap
, blue_orig
, n_color
* 2 );
380 /* fall through... */
381 case PHOTOMETRIC_MINISWHITE
:
382 case PHOTOMETRIC_MINISBLACK
:
383 if (planarconfig
== PLANARCONFIG_CONTIG
384 && img
->samplesperpixel
!= 1
385 && img
->bitspersample
< 8 ) {
387 "Sorry, can not handle contiguous data with %s=%d, "
388 "and %s=%d and Bits/Sample=%d",
389 photoTag
, img
->photometric
,
390 "Samples/pixel", img
->samplesperpixel
,
395 case PHOTOMETRIC_YCBCR
:
396 /* It would probably be nice to have a reality check here. */
397 if (planarconfig
== PLANARCONFIG_CONTIG
)
398 /* can rely on libjpeg to convert to RGB */
399 /* XXX should restore current state on exit */
401 case COMPRESSION_JPEG
:
403 * TODO: when complete tests verify complete desubsampling
404 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
405 * favor of tif_getimage.c native handling
407 TIFFSetField(tif
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
408 img
->photometric
= PHOTOMETRIC_RGB
;
415 * TODO: if at all meaningful and useful, make more complete
416 * support check here, or better still, refactor to let supporting
417 * code decide whether there is support and what meaningful
421 case PHOTOMETRIC_RGB
:
422 if (colorchannels
< 3) {
423 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
424 "Color channels", colorchannels
);
428 case PHOTOMETRIC_SEPARATED
:
431 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
432 if (inkset
!= INKSET_CMYK
) {
433 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
437 if (img
->samplesperpixel
< 4) {
438 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
439 "Samples/pixel", img
->samplesperpixel
);
444 case PHOTOMETRIC_LOGL
:
445 if (compress
!= COMPRESSION_SGILOG
) {
446 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
447 "Compression", COMPRESSION_SGILOG
);
450 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
451 img
->photometric
= PHOTOMETRIC_MINISBLACK
; /* little white lie */
452 img
->bitspersample
= 8;
454 case PHOTOMETRIC_LOGLUV
:
455 if (compress
!= COMPRESSION_SGILOG
&& compress
!= COMPRESSION_SGILOG24
) {
456 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
457 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
460 if (planarconfig
!= PLANARCONFIG_CONTIG
) {
461 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
462 "Planarconfiguration", planarconfig
);
465 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
466 img
->photometric
= PHOTOMETRIC_RGB
; /* little white lie */
467 img
->bitspersample
= 8;
469 case PHOTOMETRIC_CIELAB
:
472 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
473 photoTag
, img
->photometric
);
476 TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &img
->width
);
477 TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &img
->height
);
478 TIFFGetFieldDefaulted(tif
, TIFFTAG_ORIENTATION
, &img
->orientation
);
480 !(planarconfig
== PLANARCONFIG_SEPARATE
&& img
->samplesperpixel
> 1);
482 if (!PickContigCase(img
)) {
483 sprintf(emsg
, "Sorry, can not handle image");
487 if (!PickSeparateCase(img
)) {
488 sprintf(emsg
, "Sorry, can not handle image");
495 TIFFRGBAImageEnd( img
);
500 TIFFRGBAImageGet(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
502 if (img
->get
== NULL
) {
503 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No \"get\" routine setup");
506 if (img
->put
.any
== NULL
) {
507 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
508 "No \"put\" routine setupl; probably can not handle image format");
511 return (*img
->get
)(img
, raster
, w
, h
);
515 * Read the specified image into an ABGR-format rastertaking in account
516 * specified orientation.
519 TIFFReadRGBAImageOriented(TIFF
* tif
,
520 uint32 rwidth
, uint32 rheight
, uint32
* raster
,
521 int orientation
, int stop
)
523 char emsg
[1024] = "";
527 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, stop
, emsg
)) {
528 img
.req_orientation
= (uint16
)orientation
;
529 /* XXX verify rwidth and rheight against width and height */
530 ok
= TIFFRGBAImageGet(&img
, raster
+(rheight
-img
.height
)*rwidth
,
532 TIFFRGBAImageEnd(&img
);
534 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
541 * Read the specified image into an ABGR-format raster. Use bottom left
542 * origin for raster by default.
545 TIFFReadRGBAImage(TIFF
* tif
,
546 uint32 rwidth
, uint32 rheight
, uint32
* raster
, int stop
)
548 return TIFFReadRGBAImageOriented(tif
, rwidth
, rheight
, raster
,
549 ORIENTATION_BOTLEFT
, stop
);
553 setorientation(TIFFRGBAImage
* img
)
555 switch (img
->orientation
) {
556 case ORIENTATION_TOPLEFT
:
557 case ORIENTATION_LEFTTOP
:
558 if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
559 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
560 return FLIP_HORIZONTALLY
;
561 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
562 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
563 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
564 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
565 img
->req_orientation
== ORIENTATION_LEFTBOT
)
566 return FLIP_VERTICALLY
;
569 case ORIENTATION_TOPRIGHT
:
570 case ORIENTATION_RIGHTTOP
:
571 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
572 img
->req_orientation
== ORIENTATION_LEFTTOP
)
573 return FLIP_HORIZONTALLY
;
574 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
575 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
576 return FLIP_VERTICALLY
;
577 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
578 img
->req_orientation
== ORIENTATION_LEFTBOT
)
579 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
582 case ORIENTATION_BOTRIGHT
:
583 case ORIENTATION_RIGHTBOT
:
584 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
585 img
->req_orientation
== ORIENTATION_LEFTTOP
)
586 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
587 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
588 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
589 return FLIP_VERTICALLY
;
590 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
591 img
->req_orientation
== ORIENTATION_LEFTBOT
)
592 return FLIP_HORIZONTALLY
;
595 case ORIENTATION_BOTLEFT
:
596 case ORIENTATION_LEFTBOT
:
597 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
598 img
->req_orientation
== ORIENTATION_LEFTTOP
)
599 return FLIP_VERTICALLY
;
600 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
601 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
602 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
603 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
604 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
605 return FLIP_HORIZONTALLY
;
608 default: /* NOTREACHED */
614 * Get an tile-organized image that has
615 * PlanarConfiguration contiguous if SamplesPerPixel > 1
617 * SamplesPerPixel == 1
620 gtTileContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
622 TIFF
* tif
= img
->tif
;
623 tileContigRoutine put
= img
->put
.contig
;
624 uint32 col
, row
, y
, rowstoread
;
627 unsigned char* buf
= NULL
;
628 int32 fromskew
, toskew
;
631 uint32 this_tw
, tocol
;
632 int32 this_toskew
, leftmost_toskew
;
633 int32 leftmost_fromskew
;
637 bufsize
= TIFFTileSize(tif
);
639 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", "No space for tile buffer");
643 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
644 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
646 flip
= setorientation(img
);
647 if (flip
& FLIP_VERTICALLY
) {
649 toskew
= -(int32
)(tw
+ w
);
653 toskew
= -(int32
)(tw
- w
);
657 * Leftmost tile is clipped on left side if col_offset > 0.
659 leftmost_fromskew
= img
->col_offset
% tw
;
660 leftmost_tw
= tw
- leftmost_fromskew
;
661 leftmost_toskew
= toskew
+ leftmost_fromskew
;
662 for (row
= 0; ret
!= 0 && row
< h
; row
+= nrow
)
664 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
665 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
666 fromskew
= leftmost_fromskew
;
667 this_tw
= leftmost_tw
;
668 this_toskew
= leftmost_toskew
;
670 col
= img
->col_offset
;
673 if (_TIFFReadTileAndAllocBuffer(tif
, (void**) &buf
, bufsize
, col
,
674 row
+img
->row_offset
, 0, 0)==(tmsize_t
)(-1) &&
675 (buf
== NULL
|| img
->stoponerr
))
680 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
) + \
681 ((tmsize_t
) fromskew
* img
->samplesperpixel
);
682 if (tocol
+ this_tw
> w
)
685 * Rightmost tile is clipped on right side.
687 fromskew
= tw
- (w
- tocol
);
688 this_tw
= tw
- fromskew
;
689 this_toskew
= toskew
+ fromskew
;
691 (*put
)(img
, raster
+y
*w
+tocol
, tocol
, y
, this_tw
, nrow
, fromskew
, this_toskew
, buf
+ pos
);
695 * After the leftmost tile, tiles are no longer clipped on left side.
699 this_toskew
= toskew
;
702 y
+= ((flip
& FLIP_VERTICALLY
) ? -(int32
) nrow
: (int32
) nrow
);
706 if (flip
& FLIP_HORIZONTALLY
) {
709 for (line
= 0; line
< h
; line
++) {
710 uint32
*left
= raster
+ (line
* w
);
711 uint32
*right
= left
+ w
- 1;
713 while ( left
< right
) {
727 * Get an tile-organized image that has
728 * SamplesPerPixel > 1
729 * PlanarConfiguration separated
730 * We assume that all such images are RGB.
733 gtTileSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
735 TIFF
* tif
= img
->tif
;
736 tileSeparateRoutine put
= img
->put
.separate
;
737 uint32 col
, row
, y
, rowstoread
;
740 unsigned char* buf
= NULL
;
741 unsigned char* p0
= NULL
;
742 unsigned char* p1
= NULL
;
743 unsigned char* p2
= NULL
;
744 unsigned char* pa
= NULL
;
747 int32 fromskew
, toskew
;
748 int alpha
= img
->alpha
;
751 uint16 colorchannels
;
752 uint32 this_tw
, tocol
;
753 int32 this_toskew
, leftmost_toskew
;
754 int32 leftmost_fromskew
;
757 tilesize
= TIFFTileSize(tif
);
758 bufsize
= TIFFSafeMultiply(tmsize_t
,alpha
?4:3,tilesize
);
760 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Integer overflow in %s", "gtTileSeparate");
764 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
765 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
767 flip
= setorientation(img
);
768 if (flip
& FLIP_VERTICALLY
) {
770 toskew
= -(int32
)(tw
+ w
);
774 toskew
= -(int32
)(tw
- w
);
777 switch( img
->photometric
)
779 case PHOTOMETRIC_MINISWHITE
:
780 case PHOTOMETRIC_MINISBLACK
:
781 case PHOTOMETRIC_PALETTE
:
791 * Leftmost tile is clipped on left side if col_offset > 0.
793 leftmost_fromskew
= img
->col_offset
% tw
;
794 leftmost_tw
= tw
- leftmost_fromskew
;
795 leftmost_toskew
= toskew
+ leftmost_fromskew
;
796 for (row
= 0; ret
!= 0 && row
< h
; row
+= nrow
)
798 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
799 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
800 fromskew
= leftmost_fromskew
;
801 this_tw
= leftmost_tw
;
802 this_toskew
= leftmost_toskew
;
804 col
= img
->col_offset
;
809 if (_TIFFReadTileAndAllocBuffer(
810 tif
, (void**) &buf
, bufsize
, col
,
811 row
+img
->row_offset
,0,0)==(tmsize_t
)(-1)
812 && (buf
== NULL
|| img
->stoponerr
))
818 if( colorchannels
== 1 )
821 pa
= (alpha
?(p0
+3*tilesize
):NULL
);
827 pa
= (alpha
?(p2
+tilesize
):NULL
);
830 else if (TIFFReadTile(tif
, p0
, col
,
831 row
+img
->row_offset
,0,0)==(tmsize_t
)(-1) && img
->stoponerr
)
836 if (colorchannels
> 1
837 && TIFFReadTile(tif
, p1
, col
,
838 row
+img
->row_offset
,0,1) == (tmsize_t
)(-1)
844 if (colorchannels
> 1
845 && TIFFReadTile(tif
, p2
, col
,
846 row
+img
->row_offset
,0,2) == (tmsize_t
)(-1)
853 && TIFFReadTile(tif
,pa
,col
,
854 row
+img
->row_offset
,0,colorchannels
) == (tmsize_t
)(-1)
861 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
) + \
862 ((tmsize_t
) fromskew
* img
->samplesperpixel
);
863 if (tocol
+ this_tw
> w
)
866 * Rightmost tile is clipped on right side.
868 fromskew
= tw
- (w
- tocol
);
869 this_tw
= tw
- fromskew
;
870 this_toskew
= toskew
+ fromskew
;
872 (*put
)(img
, raster
+y
*w
+tocol
, tocol
, y
, this_tw
, nrow
, fromskew
, this_toskew
, \
873 p0
+ pos
, p1
+ pos
, p2
+ pos
, (alpha
?(pa
+pos
):NULL
));
877 * After the leftmost tile, tiles are no longer clipped on left side.
881 this_toskew
= toskew
;
884 y
+= ((flip
& FLIP_VERTICALLY
) ?-(int32
) nrow
: (int32
) nrow
);
887 if (flip
& FLIP_HORIZONTALLY
) {
890 for (line
= 0; line
< h
; line
++) {
891 uint32
*left
= raster
+ (line
* w
);
892 uint32
*right
= left
+ w
- 1;
894 while ( left
< right
) {
909 * Get a strip-organized image that has
910 * PlanarConfiguration contiguous if SamplesPerPixel > 1
912 * SamplesPerPixel == 1
915 gtStripContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
917 TIFF
* tif
= img
->tif
;
918 tileContigRoutine put
= img
->put
.contig
;
919 uint32 row
, y
, nrow
, nrowsub
, rowstoread
;
921 unsigned char* buf
= NULL
;
923 uint16 subsamplinghor
,subsamplingver
;
924 uint32 imagewidth
= img
->width
;
926 int32 fromskew
, toskew
;
928 tmsize_t maxstripsize
;
930 TIFFGetFieldDefaulted(tif
, TIFFTAG_YCBCRSUBSAMPLING
, &subsamplinghor
, &subsamplingver
);
931 if( subsamplingver
== 0 ) {
932 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Invalid vertical YCbCr subsampling");
936 maxstripsize
= TIFFStripSize(tif
);
938 flip
= setorientation(img
);
939 if (flip
& FLIP_VERTICALLY
) {
941 toskew
= -(int32
)(w
+ w
);
944 toskew
= -(int32
)(w
- w
);
947 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
949 scanline
= TIFFScanlineSize(tif
);
950 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
951 for (row
= 0; row
< h
; row
+= nrow
)
953 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
954 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
956 if ((nrowsub
%subsamplingver
)!=0)
957 nrowsub
+=subsamplingver
-nrowsub
%subsamplingver
;
958 if (_TIFFReadEncodedStripAndAllocBuffer(tif
,
959 TIFFComputeStrip(tif
,row
+img
->row_offset
, 0),
962 ((row
+ img
->row_offset
)%rowsperstrip
+ nrowsub
) * scanline
)==(tmsize_t
)(-1)
963 && (buf
== NULL
|| img
->stoponerr
))
969 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
+ \
970 ((tmsize_t
) img
->col_offset
* img
->samplesperpixel
);
971 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, buf
+ pos
);
972 y
+= ((flip
& FLIP_VERTICALLY
) ? -(int32
) nrow
: (int32
) nrow
);
975 if (flip
& FLIP_HORIZONTALLY
) {
978 for (line
= 0; line
< h
; line
++) {
979 uint32
*left
= raster
+ (line
* w
);
980 uint32
*right
= left
+ w
- 1;
982 while ( left
< right
) {
997 * Get a strip-organized image with
998 * SamplesPerPixel > 1
999 * PlanarConfiguration separated
1000 * We assume that all such images are RGB.
1003 gtStripSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
1005 TIFF
* tif
= img
->tif
;
1006 tileSeparateRoutine put
= img
->put
.separate
;
1007 unsigned char *buf
= NULL
;
1008 unsigned char *p0
= NULL
, *p1
= NULL
, *p2
= NULL
, *pa
= NULL
;
1009 uint32 row
, y
, nrow
, rowstoread
;
1012 uint32 rowsperstrip
, offset_row
;
1013 uint32 imagewidth
= img
->width
;
1016 int32 fromskew
, toskew
;
1017 int alpha
= img
->alpha
;
1019 uint16 colorchannels
;
1021 stripsize
= TIFFStripSize(tif
);
1022 bufsize
= TIFFSafeMultiply(tmsize_t
,alpha
?4:3,stripsize
);
1024 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Integer overflow in %s", "gtStripSeparate");
1028 flip
= setorientation(img
);
1029 if (flip
& FLIP_VERTICALLY
) {
1031 toskew
= -(int32
)(w
+ w
);
1035 toskew
= -(int32
)(w
- w
);
1038 switch( img
->photometric
)
1040 case PHOTOMETRIC_MINISWHITE
:
1041 case PHOTOMETRIC_MINISBLACK
:
1042 case PHOTOMETRIC_PALETTE
:
1051 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
1052 scanline
= TIFFScanlineSize(tif
);
1053 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
1054 for (row
= 0; row
< h
; row
+= nrow
)
1056 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
1057 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
1058 offset_row
= row
+ img
->row_offset
;
1061 if (_TIFFReadEncodedStripAndAllocBuffer(
1062 tif
, TIFFComputeStrip(tif
, offset_row
, 0),
1063 (void**) &buf
, bufsize
,
1064 ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
1065 && (buf
== NULL
|| img
->stoponerr
))
1071 if( colorchannels
== 1 )
1074 pa
= (alpha
?(p0
+3*stripsize
):NULL
);
1078 p1
= p0
+ stripsize
;
1079 p2
= p1
+ stripsize
;
1080 pa
= (alpha
?(p2
+stripsize
):NULL
);
1083 else if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 0),
1084 p0
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
1090 if (colorchannels
> 1
1091 && TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 1),
1092 p1
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) == (tmsize_t
)(-1)
1098 if (colorchannels
> 1
1099 && TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 2),
1100 p2
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) == (tmsize_t
)(-1)
1108 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, colorchannels
),
1109 pa
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
1117 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
+ \
1118 ((tmsize_t
) img
->col_offset
* img
->samplesperpixel
);
1119 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, p0
+ pos
, p1
+ pos
,
1120 p2
+ pos
, (alpha
?(pa
+pos
):NULL
));
1121 y
+= ((flip
& FLIP_VERTICALLY
) ? -(int32
) nrow
: (int32
) nrow
);
1124 if (flip
& FLIP_HORIZONTALLY
) {
1127 for (line
= 0; line
< h
; line
++) {
1128 uint32
*left
= raster
+ (line
* w
);
1129 uint32
*right
= left
+ w
- 1;
1131 while ( left
< right
) {
1132 uint32 temp
= *left
;
1146 * The following routines move decoded data returned
1147 * from the TIFF library into rasters filled with packed
1148 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
1150 * The routines have been created according to the most
1151 * important cases and optimized. PickContigCase and
1152 * PickSeparateCase analyze the parameters and select
1153 * the appropriate "get" and "put" routine to use.
1155 #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
1156 #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
1157 #define REPEAT2(op) op; op
1158 #define CASE8(x,op) \
1160 case 7: op; /*-fallthrough*/ \
1161 case 6: op; /*-fallthrough*/ \
1162 case 5: op; /*-fallthrough*/ \
1163 case 4: op; /*-fallthrough*/ \
1164 case 3: op; /*-fallthrough*/ \
1165 case 2: op; /*-fallthrough*/ \
1168 #define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; }
1171 #define UNROLL8(w, op1, op2) { \
1173 for (_x = w; _x >= 8; _x -= 8) { \
1182 #define UNROLL4(w, op1, op2) { \
1184 for (_x = w; _x >= 4; _x -= 4) { \
1193 #define UNROLL2(w, op1, op2) { \
1195 for (_x = w; _x >= 2; _x -= 2) { \
1205 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1206 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1208 #define A1 (((uint32)0xffL)<<24)
1209 #define PACK(r,g,b) \
1210 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1211 #define PACK4(r,g,b,a) \
1212 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1213 #define W2B(v) (((v)>>8)&0xff)
1214 /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
1215 #define PACKW(r,g,b) \
1216 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1217 #define PACKW4(r,g,b,a) \
1218 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1220 #define DECLAREContigPutFunc(name) \
1222 TIFFRGBAImage* img, \
1224 uint32 x, uint32 y, \
1225 uint32 w, uint32 h, \
1226 int32 fromskew, int32 toskew, \
1231 * 8-bit palette => colormap/RGB
1233 DECLAREContigPutFunc(put8bitcmaptile
)
1235 uint32
** PALmap
= img
->PALmap
;
1236 int samplesperpixel
= img
->samplesperpixel
;
1239 for( ; h
> 0; --h
) {
1240 for (x
= w
; x
> 0; --x
)
1242 *cp
++ = PALmap
[*pp
][0];
1243 pp
+= samplesperpixel
;
1251 * 4-bit palette => colormap/RGB
1253 DECLAREContigPutFunc(put4bitcmaptile
)
1255 uint32
** PALmap
= img
->PALmap
;
1259 for( ; h
> 0; --h
) {
1261 UNROLL2(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1268 * 2-bit palette => colormap/RGB
1270 DECLAREContigPutFunc(put2bitcmaptile
)
1272 uint32
** PALmap
= img
->PALmap
;
1276 for( ; h
> 0; --h
) {
1278 UNROLL4(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1285 * 1-bit palette => colormap/RGB
1287 DECLAREContigPutFunc(put1bitcmaptile
)
1289 uint32
** PALmap
= img
->PALmap
;
1293 for( ; h
> 0; --h
) {
1295 UNROLL8(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1302 * 8-bit greyscale => colormap/RGB
1304 DECLAREContigPutFunc(putgreytile
)
1306 int samplesperpixel
= img
->samplesperpixel
;
1307 uint32
** BWmap
= img
->BWmap
;
1310 for( ; h
> 0; --h
) {
1311 for (x
= w
; x
> 0; --x
)
1313 *cp
++ = BWmap
[*pp
][0];
1314 pp
+= samplesperpixel
;
1322 * 8-bit greyscale with associated alpha => colormap/RGBA
1324 DECLAREContigPutFunc(putagreytile
)
1326 int samplesperpixel
= img
->samplesperpixel
;
1327 uint32
** BWmap
= img
->BWmap
;
1330 for( ; h
> 0; --h
) {
1331 for (x
= w
; x
> 0; --x
)
1333 *cp
++ = BWmap
[*pp
][0] & ((uint32
)*(pp
+1) << 24 | ~A1
);
1334 pp
+= samplesperpixel
;
1342 * 16-bit greyscale => colormap/RGB
1344 DECLAREContigPutFunc(put16bitbwtile
)
1346 int samplesperpixel
= img
->samplesperpixel
;
1347 uint32
** BWmap
= img
->BWmap
;
1350 for( ; h
> 0; --h
) {
1351 uint16
*wp
= (uint16
*) pp
;
1353 for (x
= w
; x
> 0; --x
)
1355 /* use high order byte of 16bit value */
1357 *cp
++ = BWmap
[*wp
>> 8][0];
1358 pp
+= 2 * samplesperpixel
;
1359 wp
+= samplesperpixel
;
1367 * 1-bit bilevel => colormap/RGB
1369 DECLAREContigPutFunc(put1bitbwtile
)
1371 uint32
** BWmap
= img
->BWmap
;
1375 for( ; h
> 0; --h
) {
1377 UNROLL8(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1384 * 2-bit greyscale => colormap/RGB
1386 DECLAREContigPutFunc(put2bitbwtile
)
1388 uint32
** BWmap
= img
->BWmap
;
1392 for( ; h
> 0; --h
) {
1394 UNROLL4(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1401 * 4-bit greyscale => colormap/RGB
1403 DECLAREContigPutFunc(put4bitbwtile
)
1405 uint32
** BWmap
= img
->BWmap
;
1409 for( ; h
> 0; --h
) {
1411 UNROLL2(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1418 * 8-bit packed samples, no Map => RGB
1420 DECLAREContigPutFunc(putRGBcontig8bittile
)
1422 int samplesperpixel
= img
->samplesperpixel
;
1425 fromskew
*= samplesperpixel
;
1426 for( ; h
> 0; --h
) {
1428 *cp
++ = PACK(pp
[0], pp
[1], pp
[2]);
1429 pp
+= samplesperpixel
);
1436 * 8-bit packed samples => RGBA w/ associated alpha
1437 * (known to have Map == NULL)
1439 DECLAREContigPutFunc(putRGBAAcontig8bittile
)
1441 int samplesperpixel
= img
->samplesperpixel
;
1444 fromskew
*= samplesperpixel
;
1445 for( ; h
> 0; --h
) {
1447 *cp
++ = PACK4(pp
[0], pp
[1], pp
[2], pp
[3]);
1448 pp
+= samplesperpixel
);
1455 * 8-bit packed samples => RGBA w/ unassociated alpha
1456 * (known to have Map == NULL)
1458 DECLAREContigPutFunc(putRGBUAcontig8bittile
)
1460 int samplesperpixel
= img
->samplesperpixel
;
1462 fromskew
*= samplesperpixel
;
1463 for( ; h
> 0; --h
) {
1466 for (x
= w
; x
> 0; --x
) {
1468 m
= img
->UaToAa
+((size_t) a
<<8);
1472 *cp
++ = PACK4(r
,g
,b
,a
);
1473 pp
+= samplesperpixel
;
1481 * 16-bit packed samples => RGB
1483 DECLAREContigPutFunc(putRGBcontig16bittile
)
1485 int samplesperpixel
= img
->samplesperpixel
;
1486 uint16
*wp
= (uint16
*)pp
;
1488 fromskew
*= samplesperpixel
;
1489 for( ; h
> 0; --h
) {
1490 for (x
= w
; x
> 0; --x
) {
1491 *cp
++ = PACK(img
->Bitdepth16To8
[wp
[0]],
1492 img
->Bitdepth16To8
[wp
[1]],
1493 img
->Bitdepth16To8
[wp
[2]]);
1494 wp
+= samplesperpixel
;
1502 * 16-bit packed samples => RGBA w/ associated alpha
1503 * (known to have Map == NULL)
1505 DECLAREContigPutFunc(putRGBAAcontig16bittile
)
1507 int samplesperpixel
= img
->samplesperpixel
;
1508 uint16
*wp
= (uint16
*)pp
;
1510 fromskew
*= samplesperpixel
;
1511 for( ; h
> 0; --h
) {
1512 for (x
= w
; x
> 0; --x
) {
1513 *cp
++ = PACK4(img
->Bitdepth16To8
[wp
[0]],
1514 img
->Bitdepth16To8
[wp
[1]],
1515 img
->Bitdepth16To8
[wp
[2]],
1516 img
->Bitdepth16To8
[wp
[3]]);
1517 wp
+= samplesperpixel
;
1525 * 16-bit packed samples => RGBA w/ unassociated alpha
1526 * (known to have Map == NULL)
1528 DECLAREContigPutFunc(putRGBUAcontig16bittile
)
1530 int samplesperpixel
= img
->samplesperpixel
;
1531 uint16
*wp
= (uint16
*)pp
;
1533 fromskew
*= samplesperpixel
;
1534 for( ; h
> 0; --h
) {
1537 for (x
= w
; x
> 0; --x
) {
1538 a
= img
->Bitdepth16To8
[wp
[3]];
1539 m
= img
->UaToAa
+((size_t) a
<<8);
1540 r
= m
[img
->Bitdepth16To8
[wp
[0]]];
1541 g
= m
[img
->Bitdepth16To8
[wp
[1]]];
1542 b
= m
[img
->Bitdepth16To8
[wp
[2]]];
1543 *cp
++ = PACK4(r
,g
,b
,a
);
1544 wp
+= samplesperpixel
;
1552 * 8-bit packed CMYK samples w/o Map => RGB
1554 * NB: The conversion of CMYK->RGB is *very* crude.
1556 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile
)
1558 int samplesperpixel
= img
->samplesperpixel
;
1562 fromskew
*= samplesperpixel
;
1563 for( ; h
> 0; --h
) {
1566 r
= (k
*(255-pp
[0]))/255;
1567 g
= (k
*(255-pp
[1]))/255;
1568 b
= (k
*(255-pp
[2]))/255;
1569 *cp
++ = PACK(r
, g
, b
);
1570 pp
+= samplesperpixel
);
1577 * 8-bit packed CMYK samples w/Map => RGB
1579 * NB: The conversion of CMYK->RGB is *very* crude.
1581 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile
)
1583 int samplesperpixel
= img
->samplesperpixel
;
1584 TIFFRGBValue
* Map
= img
->Map
;
1588 fromskew
*= samplesperpixel
;
1589 for( ; h
> 0; --h
) {
1590 for (x
= w
; x
> 0; --x
) {
1592 r
= (k
*(255-pp
[0]))/255;
1593 g
= (k
*(255-pp
[1]))/255;
1594 b
= (k
*(255-pp
[2]))/255;
1595 *cp
++ = PACK(Map
[r
], Map
[g
], Map
[b
]);
1596 pp
+= samplesperpixel
;
1603 #define DECLARESepPutFunc(name) \
1605 TIFFRGBAImage* img,\
1607 uint32 x, uint32 y, \
1608 uint32 w, uint32 h,\
1609 int32 fromskew, int32 toskew,\
1610 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1614 * 8-bit unpacked samples => RGB
1616 DECLARESepPutFunc(putRGBseparate8bittile
)
1618 (void) img
; (void) x
; (void) y
; (void) a
;
1619 for( ; h
> 0; --h
) {
1620 UNROLL8(w
, NOP
, *cp
++ = PACK(*r
++, *g
++, *b
++));
1621 SKEW(r
, g
, b
, fromskew
);
1627 * 8-bit unpacked samples => RGBA w/ associated alpha
1629 DECLARESepPutFunc(putRGBAAseparate8bittile
)
1631 (void) img
; (void) x
; (void) y
;
1632 for( ; h
> 0; --h
) {
1633 UNROLL8(w
, NOP
, *cp
++ = PACK4(*r
++, *g
++, *b
++, *a
++));
1634 SKEW4(r
, g
, b
, a
, fromskew
);
1640 * 8-bit unpacked CMYK samples => RGBA
1642 DECLARESepPutFunc(putCMYKseparate8bittile
)
1644 (void) img
; (void) y
;
1645 for( ; h
> 0; --h
) {
1646 uint32 rv
, gv
, bv
, kv
;
1647 for (x
= w
; x
> 0; --x
) {
1649 rv
= (kv
*(255-*r
++))/255;
1650 gv
= (kv
*(255-*g
++))/255;
1651 bv
= (kv
*(255-*b
++))/255;
1652 *cp
++ = PACK4(rv
,gv
,bv
,255);
1654 SKEW4(r
, g
, b
, a
, fromskew
);
1660 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1662 DECLARESepPutFunc(putRGBUAseparate8bittile
)
1664 (void) img
; (void) y
;
1665 for( ; h
> 0; --h
) {
1666 uint32 rv
, gv
, bv
, av
;
1668 for (x
= w
; x
> 0; --x
) {
1670 m
= img
->UaToAa
+((size_t) av
<<8);
1674 *cp
++ = PACK4(rv
,gv
,bv
,av
);
1676 SKEW4(r
, g
, b
, a
, fromskew
);
1682 * 16-bit unpacked samples => RGB
1684 DECLARESepPutFunc(putRGBseparate16bittile
)
1686 uint16
*wr
= (uint16
*) r
;
1687 uint16
*wg
= (uint16
*) g
;
1688 uint16
*wb
= (uint16
*) b
;
1689 (void) img
; (void) y
; (void) a
;
1690 for( ; h
> 0; --h
) {
1691 for (x
= 0; x
< w
; x
++)
1692 *cp
++ = PACK(img
->Bitdepth16To8
[*wr
++],
1693 img
->Bitdepth16To8
[*wg
++],
1694 img
->Bitdepth16To8
[*wb
++]);
1695 SKEW(wr
, wg
, wb
, fromskew
);
1701 * 16-bit unpacked samples => RGBA w/ associated alpha
1703 DECLARESepPutFunc(putRGBAAseparate16bittile
)
1705 uint16
*wr
= (uint16
*) r
;
1706 uint16
*wg
= (uint16
*) g
;
1707 uint16
*wb
= (uint16
*) b
;
1708 uint16
*wa
= (uint16
*) a
;
1709 (void) img
; (void) y
;
1710 for( ; h
> 0; --h
) {
1711 for (x
= 0; x
< w
; x
++)
1712 *cp
++ = PACK4(img
->Bitdepth16To8
[*wr
++],
1713 img
->Bitdepth16To8
[*wg
++],
1714 img
->Bitdepth16To8
[*wb
++],
1715 img
->Bitdepth16To8
[*wa
++]);
1716 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1722 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1724 DECLARESepPutFunc(putRGBUAseparate16bittile
)
1726 uint16
*wr
= (uint16
*) r
;
1727 uint16
*wg
= (uint16
*) g
;
1728 uint16
*wb
= (uint16
*) b
;
1729 uint16
*wa
= (uint16
*) a
;
1730 (void) img
; (void) y
;
1731 for( ; h
> 0; --h
) {
1734 for (x
= w
; x
> 0; --x
) {
1735 a2
= img
->Bitdepth16To8
[*wa
++];
1736 m
= img
->UaToAa
+((size_t) a2
<<8);
1737 r2
= m
[img
->Bitdepth16To8
[*wr
++]];
1738 g2
= m
[img
->Bitdepth16To8
[*wg
++]];
1739 b2
= m
[img
->Bitdepth16To8
[*wb
++]];
1740 *cp
++ = PACK4(r2
,g2
,b2
,a2
);
1742 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1748 * 8-bit packed CIE L*a*b 1976 samples => RGB
1750 DECLAREContigPutFunc(putcontig8bitCIELab
)
1756 for( ; h
> 0; --h
) {
1757 for (x
= w
; x
> 0; --x
) {
1758 TIFFCIELabToXYZ(img
->cielab
,
1759 (unsigned char)pp
[0],
1763 TIFFXYZToRGB(img
->cielab
, X
, Y
, Z
, &r
, &g
, &b
);
1764 *cp
++ = PACK(r
, g
, b
);
1773 * YCbCr -> RGB conversion and packing routines.
1776 #define YCbCrtoRGB(dst, Y) { \
1778 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1779 dst = PACK(r, g, b); \
1783 * 8-bit packed YCbCr samples => RGB
1784 * This function is generic for different sampling sizes,
1785 * and can handle blocks sizes that aren't multiples of the
1786 * sampling size. However, it is substantially less optimized
1787 * than the specific sampling cases. It is used as a fallback
1788 * for difficult blocks.
1791 static void putcontig8bitYCbCrGenericTile(
1796 int32 fromskew
, int32 toskew
,
1802 uint32
* cp1
= cp
+w
+toskew
;
1803 uint32
* cp2
= cp1
+w
+toskew
;
1804 uint32
* cp3
= cp2
+w
+toskew
;
1805 int32 incr
= 3*w
+4*toskew
;
1807 int group_size
= v_group
* h_group
+ 2;
1810 fromskew
= (fromskew
* group_size
) / h_group
;
1812 for( yy
= 0; yy
< h
; yy
++ )
1814 unsigned char *pp_line
;
1815 int y_line_group
= yy
/ v_group
;
1816 int y_remainder
= yy
- y_line_group
* v_group
;
1818 pp_line
= pp
+ v_line_group
*
1821 for( xx
= 0; xx
< w
; xx
++ )
1826 for (; h
>= 4; h
-= 4) {
1832 YCbCrtoRGB(cp
[0], pp
[ 0]);
1833 YCbCrtoRGB(cp
[1], pp
[ 1]);
1834 YCbCrtoRGB(cp
[2], pp
[ 2]);
1835 YCbCrtoRGB(cp
[3], pp
[ 3]);
1836 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1837 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1838 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1839 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1840 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1841 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1842 YCbCrtoRGB(cp2
[2], pp
[10]);
1843 YCbCrtoRGB(cp2
[3], pp
[11]);
1844 YCbCrtoRGB(cp3
[0], pp
[12]);
1845 YCbCrtoRGB(cp3
[1], pp
[13]);
1846 YCbCrtoRGB(cp3
[2], pp
[14]);
1847 YCbCrtoRGB(cp3
[3], pp
[15]);
1849 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1852 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1859 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1861 DECLAREContigPutFunc(putcontig8bitYCbCr44tile
)
1863 uint32
* cp1
= cp
+w
+toskew
;
1864 uint32
* cp2
= cp1
+w
+toskew
;
1865 uint32
* cp3
= cp2
+w
+toskew
;
1866 int32 incr
= 3*w
+4*toskew
;
1869 /* adjust fromskew */
1870 fromskew
= (fromskew
/ 4) * (4*2+2);
1871 if ((h
& 3) == 0 && (w
& 3) == 0) {
1872 for (; h
>= 4; h
-= 4) {
1878 YCbCrtoRGB(cp
[0], pp
[ 0]);
1879 YCbCrtoRGB(cp
[1], pp
[ 1]);
1880 YCbCrtoRGB(cp
[2], pp
[ 2]);
1881 YCbCrtoRGB(cp
[3], pp
[ 3]);
1882 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1883 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1884 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1885 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1886 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1887 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1888 YCbCrtoRGB(cp2
[2], pp
[10]);
1889 YCbCrtoRGB(cp2
[3], pp
[11]);
1890 YCbCrtoRGB(cp3
[0], pp
[12]);
1891 YCbCrtoRGB(cp3
[1], pp
[13]);
1892 YCbCrtoRGB(cp3
[2], pp
[14]);
1893 YCbCrtoRGB(cp3
[3], pp
[15]);
1909 for (x
= w
; x
> 0;) {
1915 default: YCbCrtoRGB(cp3
[3], pp
[15]); /* FALLTHROUGH */
1916 case 3: YCbCrtoRGB(cp2
[3], pp
[11]); /* FALLTHROUGH */
1917 case 2: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1918 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1922 default: YCbCrtoRGB(cp3
[2], pp
[14]); /* FALLTHROUGH */
1923 case 3: YCbCrtoRGB(cp2
[2], pp
[10]); /* FALLTHROUGH */
1924 case 2: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1925 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1929 default: YCbCrtoRGB(cp3
[1], pp
[13]); /* FALLTHROUGH */
1930 case 3: YCbCrtoRGB(cp2
[1], pp
[ 9]); /* FALLTHROUGH */
1931 case 2: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1932 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1936 default: YCbCrtoRGB(cp3
[0], pp
[12]); /* FALLTHROUGH */
1937 case 3: YCbCrtoRGB(cp2
[0], pp
[ 8]); /* FALLTHROUGH */
1938 case 2: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1939 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1943 cp
+= x
; cp1
+= x
; cp2
+= x
; cp3
+= x
;
1947 cp
+= 4; cp1
+= 4; cp2
+= 4; cp3
+= 4;
1965 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1967 DECLAREContigPutFunc(putcontig8bitYCbCr42tile
)
1969 uint32
* cp1
= cp
+w
+toskew
;
1970 int32 incr
= 2*toskew
+w
;
1973 fromskew
= (fromskew
/ 4) * (4*2+2);
1974 if ((w
& 3) == 0 && (h
& 1) == 0) {
1975 for (; h
>= 2; h
-= 2) {
1981 YCbCrtoRGB(cp
[0], pp
[0]);
1982 YCbCrtoRGB(cp
[1], pp
[1]);
1983 YCbCrtoRGB(cp
[2], pp
[2]);
1984 YCbCrtoRGB(cp
[3], pp
[3]);
1985 YCbCrtoRGB(cp1
[0], pp
[4]);
1986 YCbCrtoRGB(cp1
[1], pp
[5]);
1987 YCbCrtoRGB(cp1
[2], pp
[6]);
1988 YCbCrtoRGB(cp1
[3], pp
[7]);
2000 for (x
= w
; x
> 0;) {
2006 default: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
2007 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
2011 default: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
2012 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
2016 default: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
2017 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
2021 default: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
2022 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
2046 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
2048 DECLAREContigPutFunc(putcontig8bitYCbCr41tile
)
2051 fromskew
= (fromskew
/ 4) * (4*1+2);
2058 YCbCrtoRGB(cp
[0], pp
[0]);
2059 YCbCrtoRGB(cp
[1], pp
[1]);
2060 YCbCrtoRGB(cp
[2], pp
[2]);
2061 YCbCrtoRGB(cp
[3], pp
[3]);
2074 case 3: YCbCrtoRGB(cp
[2], pp
[2]); /*-fallthrough*/
2075 case 2: YCbCrtoRGB(cp
[1], pp
[1]); /*-fallthrough*/
2076 case 1: YCbCrtoRGB(cp
[0], pp
[0]); /*-fallthrough*/
2091 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
2093 DECLAREContigPutFunc(putcontig8bitYCbCr22tile
)
2096 int32 incr
= 2*toskew
+w
;
2098 fromskew
= (fromskew
/ 2) * (2*2+2);
2105 YCbCrtoRGB(cp
[0], pp
[0]);
2106 YCbCrtoRGB(cp
[1], pp
[1]);
2107 YCbCrtoRGB(cp2
[0], pp
[2]);
2108 YCbCrtoRGB(cp2
[1], pp
[3]);
2117 YCbCrtoRGB(cp
[0], pp
[0]);
2118 YCbCrtoRGB(cp2
[0], pp
[2]);
2133 YCbCrtoRGB(cp
[0], pp
[0]);
2134 YCbCrtoRGB(cp
[1], pp
[1]);
2143 YCbCrtoRGB(cp
[0], pp
[0]);
2149 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
2151 DECLAREContigPutFunc(putcontig8bitYCbCr21tile
)
2154 fromskew
= (fromskew
/ 2) * (2*1+2);
2161 YCbCrtoRGB(cp
[0], pp
[0]);
2162 YCbCrtoRGB(cp
[1], pp
[1]);
2174 YCbCrtoRGB(cp
[0], pp
[0]);
2186 * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
2188 DECLAREContigPutFunc(putcontig8bitYCbCr12tile
)
2191 int32 incr
= 2*toskew
+w
;
2193 fromskew
= (fromskew
/ 1) * (1 * 2 + 2);
2200 YCbCrtoRGB(cp
[0], pp
[0]);
2201 YCbCrtoRGB(cp2
[0], pp
[1]);
2216 YCbCrtoRGB(cp
[0], pp
[0]);
2224 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2226 DECLAREContigPutFunc(putcontig8bitYCbCr11tile
)
2229 fromskew
= (fromskew
/ 1) * (1 * 1 + 2);
2231 x
= w
; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
2236 YCbCrtoRGB(*cp
++, pp
[0]);
2246 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2248 DECLARESepPutFunc(putseparate8bitYCbCr11tile
)
2252 /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2253 for( ; h
> 0; --h
) {
2257 TIFFYCbCrtoRGB(img
->ycbcr
,*r
++,*g
++,*b
++,&dr
,&dg
,&db
);
2258 *cp
++ = PACK(dr
,dg
,db
);
2260 SKEW(r
, g
, b
, fromskew
);
2266 static int isInRefBlackWhiteRange(float f
)
2268 return f
> (float)(-0x7FFFFFFF + 128) && f
< (float)0x7FFFFFFF;
2272 initYCbCrConversion(TIFFRGBAImage
* img
)
2274 static const char module
[] = "initYCbCrConversion";
2276 float *luma
, *refBlackWhite
;
2278 if (img
->ycbcr
== NULL
) {
2279 img
->ycbcr
= (TIFFYCbCrToRGB
*) _TIFFmalloc(
2280 TIFFroundup_32(sizeof (TIFFYCbCrToRGB
), sizeof (long))
2281 + 4*256*sizeof (TIFFRGBValue
)
2282 + 2*256*sizeof (int)
2283 + 3*256*sizeof (int32
)
2285 if (img
->ycbcr
== NULL
) {
2286 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2287 "No space for YCbCr->RGB conversion state");
2292 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRCOEFFICIENTS
, &luma
);
2293 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_REFERENCEBLACKWHITE
,
2296 /* Do some validation to avoid later issues. Detect NaN for now */
2297 /* and also if lumaGreen is zero since we divide by it later */
2298 if( luma
[0] != luma
[0] ||
2299 luma
[1] != luma
[1] ||
2301 luma
[2] != luma
[2] )
2303 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2304 "Invalid values for YCbCrCoefficients tag");
2308 if( !isInRefBlackWhiteRange(refBlackWhite
[0]) ||
2309 !isInRefBlackWhiteRange(refBlackWhite
[1]) ||
2310 !isInRefBlackWhiteRange(refBlackWhite
[2]) ||
2311 !isInRefBlackWhiteRange(refBlackWhite
[3]) ||
2312 !isInRefBlackWhiteRange(refBlackWhite
[4]) ||
2313 !isInRefBlackWhiteRange(refBlackWhite
[5]) )
2315 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2316 "Invalid values for ReferenceBlackWhite tag");
2320 if (TIFFYCbCrToRGBInit(img
->ycbcr
, luma
, refBlackWhite
) < 0)
2325 static tileContigRoutine
2326 initCIELabConversion(TIFFRGBAImage
* img
)
2328 static const char module
[] = "initCIELabConversion";
2333 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_WHITEPOINT
, &whitePoint
);
2334 if (whitePoint
[1] == 0.0f
) {
2335 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2336 "Invalid value for WhitePoint tag.");
2341 img
->cielab
= (TIFFCIELabToRGB
*)
2342 _TIFFmalloc(sizeof(TIFFCIELabToRGB
));
2344 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2345 "No space for CIE L*a*b*->RGB conversion state.");
2350 refWhite
[1] = 100.0F
;
2351 refWhite
[0] = whitePoint
[0] / whitePoint
[1] * refWhite
[1];
2352 refWhite
[2] = (1.0F
- whitePoint
[0] - whitePoint
[1])
2353 / whitePoint
[1] * refWhite
[1];
2354 if (TIFFCIELabToRGBInit(img
->cielab
, &display_sRGB
, refWhite
) < 0) {
2355 TIFFErrorExt(img
->tif
->tif_clientdata
, module
,
2356 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2357 _TIFFfree(img
->cielab
);
2361 return putcontig8bitCIELab
;
2365 * Greyscale images with less than 8 bits/sample are handled
2366 * with a table to avoid lots of shifts and masks. The table
2367 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2368 * pixel values simply by indexing into the table with one
2372 makebwmap(TIFFRGBAImage
* img
)
2374 TIFFRGBValue
* Map
= img
->Map
;
2375 int bitspersample
= img
->bitspersample
;
2376 int nsamples
= 8 / bitspersample
;
2383 img
->BWmap
= (uint32
**) _TIFFmalloc(
2384 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2385 if (img
->BWmap
== NULL
) {
2386 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for B&W mapping table");
2389 p
= (uint32
*)(img
->BWmap
+ 256);
2390 for (i
= 0; i
< 256; i
++) {
2393 switch (bitspersample
) {
2394 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2426 * Construct a mapping table to convert from the range
2427 * of the data samples to [0,255] --for display. This
2428 * process also handles inverting B&W images when needed.
2431 setupMap(TIFFRGBAImage
* img
)
2435 range
= (int32
)((1L<<img
->bitspersample
)-1);
2437 /* treat 16 bit the same as eight bit */
2438 if( img
->bitspersample
== 16 )
2439 range
= (int32
) 255;
2441 img
->Map
= (TIFFRGBValue
*) _TIFFmalloc((range
+1) * sizeof (TIFFRGBValue
));
2442 if (img
->Map
== NULL
) {
2443 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
2444 "No space for photometric conversion table");
2447 if (img
->photometric
== PHOTOMETRIC_MINISWHITE
) {
2448 for (x
= 0; x
<= range
; x
++)
2449 img
->Map
[x
] = (TIFFRGBValue
) (((range
- x
) * 255) / range
);
2451 for (x
= 0; x
<= range
; x
++)
2452 img
->Map
[x
] = (TIFFRGBValue
) ((x
* 255) / range
);
2454 if (img
->bitspersample
<= 16 &&
2455 (img
->photometric
== PHOTOMETRIC_MINISBLACK
||
2456 img
->photometric
== PHOTOMETRIC_MINISWHITE
)) {
2458 * Use photometric mapping table to construct
2459 * unpacking tables for samples <= 8 bits.
2461 if (!makebwmap(img
))
2463 /* no longer need Map, free it */
2464 _TIFFfree(img
->Map
);
2471 checkcmap(TIFFRGBAImage
* img
)
2473 uint16
* r
= img
->redcmap
;
2474 uint16
* g
= img
->greencmap
;
2475 uint16
* b
= img
->bluecmap
;
2476 long n
= 1L<<img
->bitspersample
;
2479 if (*r
++ >= 256 || *g
++ >= 256 || *b
++ >= 256)
2485 cvtcmap(TIFFRGBAImage
* img
)
2487 uint16
* r
= img
->redcmap
;
2488 uint16
* g
= img
->greencmap
;
2489 uint16
* b
= img
->bluecmap
;
2492 for (i
= (1L<<img
->bitspersample
)-1; i
>= 0; i
--) {
2493 #define CVT(x) ((uint16)((x)>>8))
2502 * Palette images with <= 8 bits/sample are handled
2503 * with a table to avoid lots of shifts and masks. The table
2504 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2505 * pixel values simply by indexing into the table with one
2509 makecmap(TIFFRGBAImage
* img
)
2511 int bitspersample
= img
->bitspersample
;
2512 int nsamples
= 8 / bitspersample
;
2513 uint16
* r
= img
->redcmap
;
2514 uint16
* g
= img
->greencmap
;
2515 uint16
* b
= img
->bluecmap
;
2519 img
->PALmap
= (uint32
**) _TIFFmalloc(
2520 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2521 if (img
->PALmap
== NULL
) {
2522 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for Palette mapping table");
2525 p
= (uint32
*)(img
->PALmap
+ 256);
2526 for (i
= 0; i
< 256; i
++) {
2529 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2530 switch (bitspersample
) {
2561 * Construct any mapping table used
2562 * by the associated put routine.
2565 buildMap(TIFFRGBAImage
* img
)
2567 switch (img
->photometric
) {
2568 case PHOTOMETRIC_RGB
:
2569 case PHOTOMETRIC_YCBCR
:
2570 case PHOTOMETRIC_SEPARATED
:
2571 if (img
->bitspersample
== 8)
2573 /* fall through... */
2574 case PHOTOMETRIC_MINISBLACK
:
2575 case PHOTOMETRIC_MINISWHITE
:
2579 case PHOTOMETRIC_PALETTE
:
2581 * Convert 16-bit colormap to 8-bit (unless it looks
2582 * like an old-style 8-bit colormap).
2584 if (checkcmap(img
) == 16)
2587 TIFFWarningExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "Assuming 8-bit colormap");
2589 * Use mapping table and colormap to construct
2590 * unpacking tables for samples < 8 bits.
2592 if (img
->bitspersample
<= 8 && !makecmap(img
))
2600 * Select the appropriate conversion routine for packed data.
2603 PickContigCase(TIFFRGBAImage
* img
)
2605 img
->get
= TIFFIsTiled(img
->tif
) ? gtTileContig
: gtStripContig
;
2606 img
->put
.contig
= NULL
;
2607 switch (img
->photometric
) {
2608 case PHOTOMETRIC_RGB
:
2609 switch (img
->bitspersample
) {
2611 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
&&
2612 img
->samplesperpixel
>= 4)
2613 img
->put
.contig
= putRGBAAcontig8bittile
;
2614 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
&&
2615 img
->samplesperpixel
>= 4)
2617 if (BuildMapUaToAa(img
))
2618 img
->put
.contig
= putRGBUAcontig8bittile
;
2620 else if( img
->samplesperpixel
>= 3 )
2621 img
->put
.contig
= putRGBcontig8bittile
;
2624 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
&&
2625 img
->samplesperpixel
>=4 )
2627 if (BuildMapBitdepth16To8(img
))
2628 img
->put
.contig
= putRGBAAcontig16bittile
;
2630 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
&&
2631 img
->samplesperpixel
>=4 )
2633 if (BuildMapBitdepth16To8(img
) &&
2634 BuildMapUaToAa(img
))
2635 img
->put
.contig
= putRGBUAcontig16bittile
;
2637 else if( img
->samplesperpixel
>=3 )
2639 if (BuildMapBitdepth16To8(img
))
2640 img
->put
.contig
= putRGBcontig16bittile
;
2645 case PHOTOMETRIC_SEPARATED
:
2646 if (img
->samplesperpixel
>=4 && buildMap(img
)) {
2647 if (img
->bitspersample
== 8) {
2649 img
->put
.contig
= putRGBcontig8bitCMYKtile
;
2651 img
->put
.contig
= putRGBcontig8bitCMYKMaptile
;
2655 case PHOTOMETRIC_PALETTE
:
2656 if (buildMap(img
)) {
2657 switch (img
->bitspersample
) {
2659 img
->put
.contig
= put8bitcmaptile
;
2662 img
->put
.contig
= put4bitcmaptile
;
2665 img
->put
.contig
= put2bitcmaptile
;
2668 img
->put
.contig
= put1bitcmaptile
;
2673 case PHOTOMETRIC_MINISWHITE
:
2674 case PHOTOMETRIC_MINISBLACK
:
2675 if (buildMap(img
)) {
2676 switch (img
->bitspersample
) {
2678 img
->put
.contig
= put16bitbwtile
;
2681 if (img
->alpha
&& img
->samplesperpixel
== 2)
2682 img
->put
.contig
= putagreytile
;
2684 img
->put
.contig
= putgreytile
;
2687 img
->put
.contig
= put4bitbwtile
;
2690 img
->put
.contig
= put2bitbwtile
;
2693 img
->put
.contig
= put1bitbwtile
;
2698 case PHOTOMETRIC_YCBCR
:
2699 if ((img
->bitspersample
==8) && (img
->samplesperpixel
==3))
2701 if (initYCbCrConversion(img
)!=0)
2704 * The 6.0 spec says that subsampling must be
2705 * one of 1, 2, or 4, and that vertical subsampling
2706 * must always be <= horizontal subsampling; so
2707 * there are only a few possibilities and we just
2708 * enumerate the cases.
2709 * Joris: added support for the [1,2] case, nonetheless, to accommodate
2712 uint16 SubsamplingHor
;
2713 uint16 SubsamplingVer
;
2714 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &SubsamplingHor
, &SubsamplingVer
);
2715 switch ((SubsamplingHor
<<4)|SubsamplingVer
) {
2717 img
->put
.contig
= putcontig8bitYCbCr44tile
;
2720 img
->put
.contig
= putcontig8bitYCbCr42tile
;
2723 img
->put
.contig
= putcontig8bitYCbCr41tile
;
2726 img
->put
.contig
= putcontig8bitYCbCr22tile
;
2729 img
->put
.contig
= putcontig8bitYCbCr21tile
;
2732 img
->put
.contig
= putcontig8bitYCbCr12tile
;
2735 img
->put
.contig
= putcontig8bitYCbCr11tile
;
2741 case PHOTOMETRIC_CIELAB
:
2742 if (img
->samplesperpixel
== 3 && buildMap(img
)) {
2743 if (img
->bitspersample
== 8)
2744 img
->put
.contig
= initCIELabConversion(img
);
2748 return ((img
->get
!=NULL
) && (img
->put
.contig
!=NULL
));
2752 * Select the appropriate conversion routine for unpacked data.
2754 * NB: we assume that unpacked single channel data is directed
2755 * to the "packed routines.
2758 PickSeparateCase(TIFFRGBAImage
* img
)
2760 img
->get
= TIFFIsTiled(img
->tif
) ? gtTileSeparate
: gtStripSeparate
;
2761 img
->put
.separate
= NULL
;
2762 switch (img
->photometric
) {
2763 case PHOTOMETRIC_MINISWHITE
:
2764 case PHOTOMETRIC_MINISBLACK
:
2765 /* greyscale images processed pretty much as RGB by gtTileSeparate */
2766 case PHOTOMETRIC_RGB
:
2767 switch (img
->bitspersample
) {
2769 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2770 img
->put
.separate
= putRGBAAseparate8bittile
;
2771 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2773 if (BuildMapUaToAa(img
))
2774 img
->put
.separate
= putRGBUAseparate8bittile
;
2777 img
->put
.separate
= putRGBseparate8bittile
;
2780 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2782 if (BuildMapBitdepth16To8(img
))
2783 img
->put
.separate
= putRGBAAseparate16bittile
;
2785 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2787 if (BuildMapBitdepth16To8(img
) &&
2788 BuildMapUaToAa(img
))
2789 img
->put
.separate
= putRGBUAseparate16bittile
;
2793 if (BuildMapBitdepth16To8(img
))
2794 img
->put
.separate
= putRGBseparate16bittile
;
2799 case PHOTOMETRIC_SEPARATED
:
2800 if (img
->bitspersample
== 8 && img
->samplesperpixel
== 4)
2802 img
->alpha
= 1; // Not alpha, but seems like the only way to get 4th band
2803 img
->put
.separate
= putCMYKseparate8bittile
;
2806 case PHOTOMETRIC_YCBCR
:
2807 if ((img
->bitspersample
==8) && (img
->samplesperpixel
==3))
2809 if (initYCbCrConversion(img
)!=0)
2812 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &hs
, &vs
);
2813 switch ((hs
<<4)|vs
) {
2815 img
->put
.separate
= putseparate8bitYCbCr11tile
;
2817 /* TODO: add other cases here */
2823 return ((img
->get
!=NULL
) && (img
->put
.separate
!=NULL
));
2827 BuildMapUaToAa(TIFFRGBAImage
* img
)
2829 static const char module
[]="BuildMapUaToAa";
2832 assert(img
->UaToAa
==NULL
);
2833 img
->UaToAa
=_TIFFmalloc(65536);
2834 if (img
->UaToAa
==NULL
)
2836 TIFFErrorExt(img
->tif
->tif_clientdata
,module
,"Out of memory");
2840 for (na
=0; na
<256; na
++)
2842 for (nv
=0; nv
<256; nv
++)
2843 *m
++=(uint8
)((nv
*na
+127)/255);
2849 BuildMapBitdepth16To8(TIFFRGBAImage
* img
)
2851 static const char module
[]="BuildMapBitdepth16To8";
2854 assert(img
->Bitdepth16To8
==NULL
);
2855 img
->Bitdepth16To8
=_TIFFmalloc(65536);
2856 if (img
->Bitdepth16To8
==NULL
)
2858 TIFFErrorExt(img
->tif
->tif_clientdata
,module
,"Out of memory");
2861 m
=img
->Bitdepth16To8
;
2862 for (n
=0; n
<65536; n
++)
2863 *m
++=(uint8
)((n
+128)/257);
2869 * Read a whole strip off data from the file, and convert to RGBA form.
2870 * If this is the last strip, then it will only contain the portion of
2871 * the strip that is actually within the image space. The result is
2872 * organized in bottom to top form.
2877 TIFFReadRGBAStrip(TIFF
* tif
, uint32 row
, uint32
* raster
)
2880 return TIFFReadRGBAStripExt(tif
, row
, raster
, 0 );
2884 TIFFReadRGBAStripExt(TIFF
* tif
, uint32 row
, uint32
* raster
, int stop_on_error
)
2887 char emsg
[1024] = "";
2890 uint32 rowsperstrip
, rows_to_read
;
2892 if( TIFFIsTiled( tif
) )
2894 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2895 "Can't use TIFFReadRGBAStrip() with tiled file.");
2899 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
2900 if( (row
% rowsperstrip
) != 0 )
2902 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2903 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2907 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, stop_on_error
, emsg
)) {
2909 img
.row_offset
= row
;
2912 if( row
+ rowsperstrip
> img
.height
)
2913 rows_to_read
= img
.height
- row
;
2915 rows_to_read
= rowsperstrip
;
2917 ok
= TIFFRGBAImageGet(&img
, raster
, img
.width
, rows_to_read
);
2919 TIFFRGBAImageEnd(&img
);
2921 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
2929 * Read a whole tile off data from the file, and convert to RGBA form.
2930 * The returned RGBA data is organized from bottom to top of tile,
2931 * and may include zeroed areas if the tile extends off the image.
2935 TIFFReadRGBATile(TIFF
* tif
, uint32 col
, uint32 row
, uint32
* raster
)
2938 return TIFFReadRGBATileExt(tif
, col
, row
, raster
, 0 );
2943 TIFFReadRGBATileExt(TIFF
* tif
, uint32 col
, uint32 row
, uint32
* raster
, int stop_on_error
)
2945 char emsg
[1024] = "";
2948 uint32 tile_xsize
, tile_ysize
;
2949 uint32 read_xsize
, read_ysize
;
2953 * Verify that our request is legal - on a tile file, and on a
2957 if( !TIFFIsTiled( tif
) )
2959 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2960 "Can't use TIFFReadRGBATile() with stripped file.");
2964 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILEWIDTH
, &tile_xsize
);
2965 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILELENGTH
, &tile_ysize
);
2966 if( (col
% tile_xsize
) != 0 || (row
% tile_ysize
) != 0 )
2968 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2969 "Row/col passed to TIFFReadRGBATile() must be top"
2970 "left corner of a tile.");
2975 * Setup the RGBA reader.
2978 if (!TIFFRGBAImageOK(tif
, emsg
)
2979 || !TIFFRGBAImageBegin(&img
, tif
, stop_on_error
, emsg
)) {
2980 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
2985 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2986 * edge of the image, even to fill an otherwise valid tile. So we
2987 * figure out how much we can read, and fix up the tile buffer to
2988 * a full tile configuration afterwards.
2991 if( row
+ tile_ysize
> img
.height
)
2992 read_ysize
= img
.height
- row
;
2994 read_ysize
= tile_ysize
;
2996 if( col
+ tile_xsize
> img
.width
)
2997 read_xsize
= img
.width
- col
;
2999 read_xsize
= tile_xsize
;
3002 * Read the chunk of imagery.
3005 img
.row_offset
= row
;
3006 img
.col_offset
= col
;
3008 ok
= TIFFRGBAImageGet(&img
, raster
, read_xsize
, read_ysize
);
3010 TIFFRGBAImageEnd(&img
);
3013 * If our read was incomplete we will need to fix up the tile by
3014 * shifting the data around as if a full tile of data is being returned.
3016 * This is all the more complicated because the image is organized in
3017 * bottom to top format.
3020 if( read_xsize
== tile_xsize
&& read_ysize
== tile_ysize
)
3023 for( i_row
= 0; i_row
< read_ysize
; i_row
++ ) {
3024 memmove( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
3025 raster
+ (read_ysize
- i_row
- 1) * read_xsize
,
3026 read_xsize
* sizeof(uint32
) );
3027 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
+read_xsize
,
3028 0, sizeof(uint32
) * (tile_xsize
- read_xsize
) );
3031 for( i_row
= read_ysize
; i_row
< tile_ysize
; i_row
++ ) {
3032 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
3033 0, sizeof(uint32
) * tile_xsize
);
3039 /* vim: set ts=8 sts=8 sw=8 noet: */