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.
36 static int gtTileContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
37 static int gtTileSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
38 static int gtStripContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
39 static int gtStripSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
40 static int pickTileContigCase(TIFFRGBAImage
*);
41 static int pickTileSeparateCase(TIFFRGBAImage
*);
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 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
) {
85 case 1: case 2: case 4:
89 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
90 td
->td_bitspersample
);
93 colorchannels
= td
->td_samplesperpixel
- td
->td_extrasamples
;
94 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &photometric
)) {
95 switch (colorchannels
) {
97 photometric
= PHOTOMETRIC_MINISBLACK
;
100 photometric
= PHOTOMETRIC_RGB
;
103 sprintf(emsg
, "Missing needed %s tag", photoTag
);
107 switch (photometric
) {
108 case PHOTOMETRIC_MINISWHITE
:
109 case PHOTOMETRIC_MINISBLACK
:
110 case PHOTOMETRIC_PALETTE
:
111 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
112 && td
->td_samplesperpixel
!= 1
113 && td
->td_bitspersample
< 8 ) {
115 "Sorry, can not handle contiguous data with %s=%d, "
116 "and %s=%d and Bits/Sample=%d",
117 photoTag
, photometric
,
118 "Samples/pixel", td
->td_samplesperpixel
,
119 td
->td_bitspersample
);
123 ** We should likely validate that any extra samples are either
124 ** to be ignored, or are alpha, and if alpha we should try to use
125 ** them. But for now we won't bother with this.
128 case PHOTOMETRIC_YCBCR
:
129 if (td
->td_planarconfig
!= PLANARCONFIG_CONTIG
) {
130 sprintf(emsg
, "Sorry, can not handle YCbCr images with %s=%d",
131 "Planarconfiguration", td
->td_planarconfig
);
135 case PHOTOMETRIC_RGB
:
136 if (colorchannels
< 3) {
137 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
138 "Color channels", colorchannels
);
142 case PHOTOMETRIC_SEPARATED
:
143 if (td
->td_inkset
!= INKSET_CMYK
) {
144 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
145 "InkSet", td
->td_inkset
);
148 if (td
->td_samplesperpixel
< 4) {
149 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
150 "Samples/pixel", td
->td_samplesperpixel
);
154 case PHOTOMETRIC_LOGL
:
155 if (td
->td_compression
!= COMPRESSION_SGILOG
) {
156 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
157 "Compression", COMPRESSION_SGILOG
);
161 case PHOTOMETRIC_LOGLUV
:
162 if (td
->td_compression
!= COMPRESSION_SGILOG
&&
163 td
->td_compression
!= COMPRESSION_SGILOG24
) {
164 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
165 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
168 if (td
->td_planarconfig
!= PLANARCONFIG_CONTIG
) {
169 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
170 "Planarconfiguration", td
->td_planarconfig
);
174 case PHOTOMETRIC_CIELAB
:
177 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
178 photoTag
, photometric
);
185 TIFFRGBAImageEnd(TIFFRGBAImage
* img
)
188 _TIFFfree(img
->Map
), img
->Map
= NULL
;
190 _TIFFfree(img
->BWmap
), img
->BWmap
= NULL
;
192 _TIFFfree(img
->PALmap
), img
->PALmap
= NULL
;
194 _TIFFfree(img
->ycbcr
), img
->ycbcr
= NULL
;
196 _TIFFfree(img
->cielab
), img
->cielab
= NULL
;
199 _TIFFfree( img
->redcmap
);
200 _TIFFfree( img
->greencmap
);
201 _TIFFfree( img
->bluecmap
);
206 isCCITTCompression(TIFF
* tif
)
209 TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compress
);
210 return (compress
== COMPRESSION_CCITTFAX3
||
211 compress
== COMPRESSION_CCITTFAX4
||
212 compress
== COMPRESSION_CCITTRLE
||
213 compress
== COMPRESSION_CCITTRLEW
);
217 TIFFRGBAImageBegin(TIFFRGBAImage
* img
, TIFF
* tif
, int stop
, char emsg
[1024])
224 uint16
*red_orig
, *green_orig
, *blue_orig
;
227 /* Initialize to normal values */
231 img
->greencmap
= NULL
;
232 img
->bluecmap
= NULL
;
233 img
->req_orientation
= ORIENTATION_BOTLEFT
; /* It is the default */
236 img
->stoponerr
= stop
;
237 TIFFGetFieldDefaulted(tif
, TIFFTAG_BITSPERSAMPLE
, &img
->bitspersample
);
238 switch (img
->bitspersample
) {
239 case 1: case 2: case 4:
243 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
248 TIFFGetFieldDefaulted(tif
, TIFFTAG_SAMPLESPERPIXEL
, &img
->samplesperpixel
);
249 TIFFGetFieldDefaulted(tif
, TIFFTAG_EXTRASAMPLES
,
250 &extrasamples
, &sampleinfo
);
251 if (extrasamples
== 1)
253 switch (sampleinfo
[0]) {
254 case EXTRASAMPLE_UNSPECIFIED
: /* Workaround for some images without */
255 if (img
->samplesperpixel
== 4) /* correct info about alpha channel */
256 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
258 case EXTRASAMPLE_ASSOCALPHA
: /* data is pre-multiplied */
259 case EXTRASAMPLE_UNASSALPHA
: /* data is not pre-multiplied */
260 img
->alpha
= sampleinfo
[0];
265 #if DEFAULT_EXTRASAMPLE_AS_ALPHA == 1
266 if( !TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
))
267 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
269 if( extrasamples
== 0
270 && img
->samplesperpixel
== 4
271 && img
->photometric
== PHOTOMETRIC_RGB
)
273 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
278 colorchannels
= img
->samplesperpixel
- extrasamples
;
279 TIFFGetFieldDefaulted(tif
, TIFFTAG_COMPRESSION
, &compress
);
280 TIFFGetFieldDefaulted(tif
, TIFFTAG_PLANARCONFIG
, &planarconfig
);
281 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
)) {
282 switch (colorchannels
) {
284 if (isCCITTCompression(tif
))
285 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
287 img
->photometric
= PHOTOMETRIC_MINISBLACK
;
290 img
->photometric
= PHOTOMETRIC_RGB
;
293 sprintf(emsg
, "Missing needed %s tag", photoTag
);
297 switch (img
->photometric
) {
298 case PHOTOMETRIC_PALETTE
:
299 if (!TIFFGetField(tif
, TIFFTAG_COLORMAP
,
300 &red_orig
, &green_orig
, &blue_orig
)) {
301 TIFFError(TIFFFileName(tif
), "Missing required \"Colormap\" tag");
305 /* copy the colormaps so we can modify them */
306 n_color
= (1L << img
->bitspersample
);
307 img
->redcmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
308 img
->greencmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
309 img
->bluecmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
310 if( !img
->redcmap
|| !img
->greencmap
|| !img
->bluecmap
) {
311 TIFFError(TIFFFileName(tif
), "Out of memory for colormap copy");
315 memcpy( img
->redcmap
, red_orig
, n_color
* 2 );
316 memcpy( img
->greencmap
, green_orig
, n_color
* 2 );
317 memcpy( img
->bluecmap
, blue_orig
, n_color
* 2 );
320 case PHOTOMETRIC_MINISWHITE
:
321 case PHOTOMETRIC_MINISBLACK
:
322 if (planarconfig
== PLANARCONFIG_CONTIG
323 && img
->samplesperpixel
!= 1
324 && img
->bitspersample
< 8 ) {
326 "Sorry, can not handle contiguous data with %s=%d, "
327 "and %s=%d and Bits/Sample=%d",
328 photoTag
, img
->photometric
,
329 "Samples/pixel", img
->samplesperpixel
,
334 case PHOTOMETRIC_YCBCR
:
335 if (planarconfig
!= PLANARCONFIG_CONTIG
) {
336 sprintf(emsg
, "Sorry, can not handle YCbCr images with %s=%d",
337 "Planarconfiguration", planarconfig
);
340 /* It would probably be nice to have a reality check here. */
341 if (planarconfig
== PLANARCONFIG_CONTIG
)
342 /* can rely on libjpeg to convert to RGB */
343 /* XXX should restore current state on exit */
345 case COMPRESSION_OJPEG
:
346 case COMPRESSION_JPEG
:
347 TIFFSetField(tif
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
348 img
->photometric
= PHOTOMETRIC_RGB
;
356 case PHOTOMETRIC_RGB
:
357 if (colorchannels
< 3) {
358 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
359 "Color channels", colorchannels
);
363 case PHOTOMETRIC_SEPARATED
: {
365 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
366 if (inkset
!= INKSET_CMYK
) {
367 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
371 if (img
->samplesperpixel
< 4) {
372 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
373 "Samples/pixel", img
->samplesperpixel
);
378 case PHOTOMETRIC_LOGL
:
379 if (compress
!= COMPRESSION_SGILOG
) {
380 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
381 "Compression", COMPRESSION_SGILOG
);
384 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
385 img
->photometric
= PHOTOMETRIC_MINISBLACK
; /* little white lie */
386 img
->bitspersample
= 8;
388 case PHOTOMETRIC_LOGLUV
:
389 if (compress
!= COMPRESSION_SGILOG
&& compress
!= COMPRESSION_SGILOG24
) {
390 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
391 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
394 if (planarconfig
!= PLANARCONFIG_CONTIG
) {
395 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
396 "Planarconfiguration", planarconfig
);
399 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
400 img
->photometric
= PHOTOMETRIC_RGB
; /* little white lie */
401 img
->bitspersample
= 8;
403 case PHOTOMETRIC_CIELAB
:
406 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
407 photoTag
, img
->photometric
);
415 TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &img
->width
);
416 TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &img
->height
);
417 TIFFGetFieldDefaulted(tif
, TIFFTAG_ORIENTATION
, &img
->orientation
);
419 !(planarconfig
== PLANARCONFIG_SEPARATE
&& colorchannels
> 1);
421 img
->get
= TIFFIsTiled(tif
) ? gtTileContig
: gtStripContig
;
422 return pickTileContigCase(img
);
424 img
->get
= TIFFIsTiled(tif
) ? gtTileSeparate
: gtStripSeparate
;
425 return pickTileSeparateCase(img
);
430 TIFFRGBAImageGet(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
432 if (img
->get
== NULL
) {
433 TIFFError(TIFFFileName(img
->tif
), "No \"get\" routine setup");
436 if (img
->put
.any
== NULL
) {
437 TIFFError(TIFFFileName(img
->tif
),
438 "No \"put\" routine setupl; probably can not handle image format");
441 return (*img
->get
)(img
, raster
, w
, h
);
445 * Read the specified image into an ABGR-format rastertaking in account
446 * specified orientation.
449 TIFFReadRGBAImageOriented(TIFF
* tif
,
450 uint32 rwidth
, uint32 rheight
, uint32
* raster
,
451 int orientation
, int stop
)
457 if (TIFFRGBAImageOK(tif
, emsg
) &&
458 TIFFRGBAImageBegin(&img
, tif
, stop
, emsg
)) {
459 img
.req_orientation
= orientation
;
460 /* XXX verify rwidth and rheight against width and height */
461 ok
= TIFFRGBAImageGet(&img
, raster
+(rheight
-img
.height
)*rwidth
,
463 TIFFRGBAImageEnd(&img
);
465 TIFFError(TIFFFileName(tif
), emsg
);
472 * Read the specified image into an ABGR-format raster. Use bottom left
473 * origin for raster by default.
476 TIFFReadRGBAImage(TIFF
* tif
,
477 uint32 rwidth
, uint32 rheight
, uint32
* raster
, int stop
)
479 return TIFFReadRGBAImageOriented(tif
, rwidth
, rheight
, raster
,
480 ORIENTATION_BOTLEFT
, stop
);
484 setorientation(TIFFRGBAImage
* img
)
486 switch (img
->orientation
) {
487 case ORIENTATION_TOPLEFT
:
488 case ORIENTATION_LEFTTOP
:
489 if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
490 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
491 return FLIP_HORIZONTALLY
;
492 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
493 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
494 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
495 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
496 img
->req_orientation
== ORIENTATION_LEFTBOT
)
497 return FLIP_VERTICALLY
;
500 case ORIENTATION_TOPRIGHT
:
501 case ORIENTATION_RIGHTTOP
:
502 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
503 img
->req_orientation
== ORIENTATION_LEFTTOP
)
504 return FLIP_HORIZONTALLY
;
505 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
506 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
507 return FLIP_VERTICALLY
;
508 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
509 img
->req_orientation
== ORIENTATION_LEFTBOT
)
510 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
513 case ORIENTATION_BOTRIGHT
:
514 case ORIENTATION_RIGHTBOT
:
515 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
516 img
->req_orientation
== ORIENTATION_LEFTTOP
)
517 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
518 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
519 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
520 return FLIP_VERTICALLY
;
521 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
522 img
->req_orientation
== ORIENTATION_LEFTBOT
)
523 return FLIP_HORIZONTALLY
;
526 case ORIENTATION_BOTLEFT
:
527 case ORIENTATION_LEFTBOT
:
528 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
529 img
->req_orientation
== ORIENTATION_LEFTTOP
)
530 return FLIP_VERTICALLY
;
531 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
532 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
533 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
534 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
535 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
536 return FLIP_HORIZONTALLY
;
539 default: /* NOTREACHED */
545 * Get an tile-organized image that has
546 * PlanarConfiguration contiguous if SamplesPerPixel > 1
548 * SamplesPerPixel == 1
551 gtTileContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
553 TIFF
* tif
= img
->tif
;
554 tileContigRoutine put
= img
->put
.contig
;
555 uint32 col
, row
, y
, rowstoread
;
559 int32 fromskew
, toskew
;
563 buf
= (u_char
*) _TIFFmalloc(TIFFTileSize(tif
));
565 TIFFError(TIFFFileName(tif
), "No space for tile buffer");
568 _TIFFmemset(buf
, 0, TIFFTileSize(tif
));
569 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
570 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
572 flip
= setorientation(img
);
573 if (flip
& FLIP_VERTICALLY
) {
575 toskew
= -(int32
)(tw
+ w
);
579 toskew
= -(int32
)(tw
- w
);
582 for (row
= 0; row
< h
; row
+= nrow
)
584 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
585 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
586 for (col
= 0; col
< w
; col
+= tw
)
588 if (TIFFReadTile(tif
, buf
, col
+img
->col_offset
,
589 row
+img
->row_offset
, 0, 0) < 0 && img
->stoponerr
)
595 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
);
600 * Tile is clipped horizontally. Calculate
601 * visible portion and skewing factors.
603 uint32 npix
= w
- col
;
604 fromskew
= tw
- npix
;
605 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
606 npix
, nrow
, fromskew
, toskew
+ fromskew
, buf
+ pos
);
610 (*put
)(img
, raster
+y
*w
+col
, col
, y
, tw
, nrow
, 0, toskew
, buf
+ pos
);
614 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
618 if (flip
& FLIP_HORIZONTALLY
) {
621 for (line
= 0; line
< h
; line
++) {
622 uint32
*left
= raster
+ (line
* w
);
623 uint32
*right
= left
+ w
- 1;
625 while ( left
< right
) {
638 * Get an tile-organized image that has
639 * SamplesPerPixel > 1
640 * PlanarConfiguration separated
641 * We assume that all such images are RGB.
644 gtTileSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
646 TIFF
* tif
= img
->tif
;
647 tileSeparateRoutine put
= img
->put
.separate
;
648 uint32 col
, row
, y
, rowstoread
;
657 int32 fromskew
, toskew
;
658 int alpha
= img
->alpha
;
662 tilesize
= TIFFTileSize(tif
);
663 buf
= (u_char
*) _TIFFmalloc(4*tilesize
);
665 TIFFError(TIFFFileName(tif
), "No space for tile buffer");
668 _TIFFmemset(buf
, 0, 4*tilesize
);
674 memset(a
, 0xff, tilesize
);
675 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
676 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
678 flip
= setorientation(img
);
679 if (flip
& FLIP_VERTICALLY
) {
681 toskew
= -(int32
)(tw
+ w
);
685 toskew
= -(int32
)(tw
- w
);
688 for (row
= 0; row
< h
; row
+= nrow
)
690 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
691 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
692 for (col
= 0; col
< w
; col
+= tw
)
694 if (TIFFReadTile(tif
, r
, col
+img
->col_offset
,
695 row
+img
->row_offset
,0,0) < 0 && img
->stoponerr
)
700 if (TIFFReadTile(tif
, g
, col
+img
->col_offset
,
701 row
+img
->row_offset
,0,1) < 0 && img
->stoponerr
)
706 if (TIFFReadTile(tif
, b
, col
+img
->col_offset
,
707 row
+img
->row_offset
,0,2) < 0 && img
->stoponerr
)
712 if (alpha
&& TIFFReadTile(tif
,a
,col
+img
->col_offset
,
713 row
+img
->row_offset
,0,3) < 0 && img
->stoponerr
)
719 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
);
724 * Tile is clipped horizontally. Calculate
725 * visible portion and skewing factors.
727 uint32 npix
= w
- col
;
728 fromskew
= tw
- npix
;
729 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
730 npix
, nrow
, fromskew
, toskew
+ fromskew
,
731 r
+ pos
, g
+ pos
, b
+ pos
, a
+ pos
);
733 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
734 tw
, nrow
, 0, toskew
, r
+ pos
, g
+ pos
, b
+ pos
, a
+ pos
);
738 y
+= (flip
& FLIP_VERTICALLY
?-(int32
) nrow
: (int32
) nrow
);
741 if (flip
& FLIP_HORIZONTALLY
) {
744 for (line
= 0; line
< h
; line
++) {
745 uint32
*left
= raster
+ (line
* w
);
746 uint32
*right
= left
+ w
- 1;
748 while ( left
< right
) {
762 * Get a strip-organized image that has
763 * PlanarConfiguration contiguous if SamplesPerPixel > 1
765 * SamplesPerPixel == 1
768 gtStripContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
770 TIFF
* tif
= img
->tif
;
771 tileContigRoutine put
= img
->put
.contig
;
772 uint32 row
, y
, nrow
, rowstoread
;
776 uint32 imagewidth
= img
->width
;
778 int32 fromskew
, toskew
;
781 buf
= (u_char
*) _TIFFmalloc(TIFFStripSize(tif
));
783 TIFFError(TIFFFileName(tif
), "No space for strip buffer");
786 _TIFFmemset(buf
, 0, TIFFStripSize(tif
));
788 flip
= setorientation(img
);
789 if (flip
& FLIP_VERTICALLY
) {
791 toskew
= -(int32
)(w
+ w
);
794 toskew
= -(int32
)(w
- w
);
797 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
798 scanline
= TIFFScanlineSize(tif
);
799 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
800 for (row
= 0; row
< h
; row
+= nrow
)
802 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
803 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
804 if (TIFFReadEncodedStrip(tif
,
805 TIFFComputeStrip(tif
,row
+img
->row_offset
, 0),
807 ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
814 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
;
815 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, buf
+ pos
);
816 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
819 if (flip
& FLIP_HORIZONTALLY
) {
822 for (line
= 0; line
< h
; line
++) {
823 uint32
*left
= raster
+ (line
* w
);
824 uint32
*right
= left
+ w
- 1;
826 while ( left
< right
) {
840 * Get a strip-organized image with
841 * SamplesPerPixel > 1
842 * PlanarConfiguration separated
843 * We assume that all such images are RGB.
846 gtStripSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
848 TIFF
* tif
= img
->tif
;
849 tileSeparateRoutine put
= img
->put
.separate
;
851 u_char
*r
, *g
, *b
, *a
;
852 uint32 row
, y
, nrow
, rowstoread
;
855 uint32 rowsperstrip
, offset_row
;
856 uint32 imagewidth
= img
->width
;
858 int32 fromskew
, toskew
;
859 int alpha
= img
->alpha
;
862 stripsize
= TIFFStripSize(tif
);
863 r
= buf
= (u_char
*)_TIFFmalloc(4*stripsize
);
865 TIFFError(TIFFFileName(tif
), "No space for tile buffer");
868 _TIFFmemset(buf
, 0, 4*stripsize
);
873 memset(a
, 0xff, stripsize
);
875 flip
= setorientation(img
);
876 if (flip
& FLIP_VERTICALLY
) {
878 toskew
= -(int32
)(w
+ w
);
882 toskew
= -(int32
)(w
- w
);
885 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
886 scanline
= TIFFScanlineSize(tif
);
887 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
888 for (row
= 0; row
< h
; row
+= nrow
)
890 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
891 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
892 offset_row
= row
+ img
->row_offset
;
893 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 0),
894 r
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
900 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 1),
901 g
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
907 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 2),
908 b
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
915 (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 3),
916 a
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
923 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
;
924 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, r
+ pos
, g
+ pos
,
926 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
929 if (flip
& FLIP_HORIZONTALLY
) {
932 for (line
= 0; line
< h
; line
++) {
933 uint32
*left
= raster
+ (line
* w
);
934 uint32
*right
= left
+ w
- 1;
936 while ( left
< right
) {
950 * The following routines move decoded data returned
951 * from the TIFF library into rasters filled with packed
952 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
954 * The routines have been created according to the most
955 * important cases and optimized. pickTileContigCase and
956 * pickTileSeparateCase analyze the parameters and select
957 * the appropriate "put" routine to use.
959 #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
960 #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
961 #define REPEAT2(op) op; op
962 #define CASE8(x,op) \
964 case 7: op; case 6: op; case 5: op; \
965 case 4: op; case 3: op; case 2: op; \
968 #define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
971 #define UNROLL8(w, op1, op2) { \
973 for (_x = w; _x >= 8; _x -= 8) { \
982 #define UNROLL4(w, op1, op2) { \
984 for (_x = w; _x >= 4; _x -= 4) { \
993 #define UNROLL2(w, op1, op2) { \
995 for (_x = w; _x >= 2; _x -= 2) { \
1005 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1006 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1008 #define A1 ((uint32)(0xffL<<24))
1009 #define PACK(r,g,b) \
1010 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1011 #define PACK4(r,g,b,a) \
1012 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1013 #define W2B(v) (((v)>>8)&0xff)
1014 #define PACKW(r,g,b) \
1015 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1016 #define PACKW4(r,g,b,a) \
1017 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1019 #define DECLAREContigPutFunc(name) \
1021 TIFFRGBAImage* img, \
1023 uint32 x, uint32 y, \
1024 uint32 w, uint32 h, \
1025 int32 fromskew, int32 toskew, \
1030 * 8-bit palette => colormap/RGB
1032 DECLAREContigPutFunc(put8bitcmaptile
)
1034 uint32
** PALmap
= img
->PALmap
;
1035 int samplesperpixel
= img
->samplesperpixel
;
1039 for (x
= w
; x
-- > 0;)
1041 *cp
++ = PALmap
[*pp
][0];
1042 pp
+= samplesperpixel
;
1050 * 4-bit palette => colormap/RGB
1052 DECLAREContigPutFunc(put4bitcmaptile
)
1054 uint32
** PALmap
= img
->PALmap
;
1060 UNROLL2(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1067 * 2-bit palette => colormap/RGB
1069 DECLAREContigPutFunc(put2bitcmaptile
)
1071 uint32
** PALmap
= img
->PALmap
;
1077 UNROLL4(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1084 * 1-bit palette => colormap/RGB
1086 DECLAREContigPutFunc(put1bitcmaptile
)
1088 uint32
** PALmap
= img
->PALmap
;
1094 UNROLL8(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1101 * 8-bit greyscale => colormap/RGB
1103 DECLAREContigPutFunc(putgreytile
)
1105 int samplesperpixel
= img
->samplesperpixel
;
1106 uint32
** BWmap
= img
->BWmap
;
1110 for (x
= w
; x
-- > 0;)
1112 *cp
++ = BWmap
[*pp
][0];
1113 pp
+= samplesperpixel
;
1121 * 16-bit greyscale => colormap/RGB
1123 DECLAREContigPutFunc(put16bitbwtile
)
1125 int samplesperpixel
= img
->samplesperpixel
;
1126 uint32
** BWmap
= img
->BWmap
;
1130 uint16
*wp
= (uint16
*) pp
;
1132 for (x
= w
; x
-- > 0;)
1134 /* use high order byte of 16bit value */
1136 *cp
++ = BWmap
[*wp
>> 8][0];
1137 pp
+= 2 * samplesperpixel
;
1138 wp
+= samplesperpixel
;
1146 * 1-bit bilevel => colormap/RGB
1148 DECLAREContigPutFunc(put1bitbwtile
)
1150 uint32
** BWmap
= img
->BWmap
;
1156 UNROLL8(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1163 * 2-bit greyscale => colormap/RGB
1165 DECLAREContigPutFunc(put2bitbwtile
)
1167 uint32
** BWmap
= img
->BWmap
;
1173 UNROLL4(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1180 * 4-bit greyscale => colormap/RGB
1182 DECLAREContigPutFunc(put4bitbwtile
)
1184 uint32
** BWmap
= img
->BWmap
;
1190 UNROLL2(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1197 * 8-bit packed samples, no Map => RGB
1199 DECLAREContigPutFunc(putRGBcontig8bittile
)
1201 int samplesperpixel
= img
->samplesperpixel
;
1204 fromskew
*= samplesperpixel
;
1207 *cp
++ = PACK(pp
[0], pp
[1], pp
[2]);
1208 pp
+= samplesperpixel
);
1215 * 8-bit packed samples, w/ Map => RGB
1217 DECLAREContigPutFunc(putRGBcontig8bitMaptile
)
1219 TIFFRGBValue
* Map
= img
->Map
;
1220 int samplesperpixel
= img
->samplesperpixel
;
1223 fromskew
*= samplesperpixel
;
1225 for (x
= w
; x
-- > 0;) {
1226 *cp
++ = PACK(Map
[pp
[0]], Map
[pp
[1]], Map
[pp
[2]]);
1227 pp
+= samplesperpixel
;
1235 * 8-bit packed samples => RGBA w/ associated alpha
1236 * (known to have Map == NULL)
1238 DECLAREContigPutFunc(putRGBAAcontig8bittile
)
1240 int samplesperpixel
= img
->samplesperpixel
;
1243 fromskew
*= samplesperpixel
;
1246 *cp
++ = PACK4(pp
[0], pp
[1], pp
[2], pp
[3]);
1247 pp
+= samplesperpixel
);
1254 * 8-bit packed samples => RGBA w/ unassociated alpha
1255 * (known to have Map == NULL)
1257 DECLAREContigPutFunc(putRGBUAcontig8bittile
)
1259 int samplesperpixel
= img
->samplesperpixel
;
1262 fromskew
*= samplesperpixel
;
1265 for (x
= w
; x
-- > 0;) {
1267 r
= (pp
[0] * a
) / 255;
1268 g
= (pp
[1] * a
) / 255;
1269 b
= (pp
[2] * a
) / 255;
1270 *cp
++ = PACK4(r
,g
,b
,a
);
1271 pp
+= samplesperpixel
;
1279 * 16-bit packed samples => RGB
1281 DECLAREContigPutFunc(putRGBcontig16bittile
)
1283 int samplesperpixel
= img
->samplesperpixel
;
1284 uint16
*wp
= (uint16
*)pp
;
1287 fromskew
*= samplesperpixel
;
1289 for (x
= w
; x
-- > 0;) {
1290 *cp
++ = PACKW(wp
[0], wp
[1], wp
[2]);
1291 wp
+= samplesperpixel
;
1299 * 16-bit packed samples => RGBA w/ associated alpha
1300 * (known to have Map == NULL)
1302 DECLAREContigPutFunc(putRGBAAcontig16bittile
)
1304 int samplesperpixel
= img
->samplesperpixel
;
1305 uint16
*wp
= (uint16
*)pp
;
1308 fromskew
*= samplesperpixel
;
1310 for (x
= w
; x
-- > 0;) {
1311 *cp
++ = PACKW4(wp
[0], wp
[1], wp
[2], wp
[3]);
1312 wp
+= samplesperpixel
;
1320 * 16-bit packed samples => RGBA w/ unassociated alpha
1321 * (known to have Map == NULL)
1323 DECLAREContigPutFunc(putRGBUAcontig16bittile
)
1325 int samplesperpixel
= img
->samplesperpixel
;
1326 uint16
*wp
= (uint16
*)pp
;
1329 fromskew
*= samplesperpixel
;
1333 * We shift alpha down four bits just in case unsigned
1334 * arithmetic doesn't handle the full range.
1335 * We still have plenty of accuracy, since the output is 8 bits.
1336 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1337 * Since we want r*a * 0xff for eight bit output,
1338 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1340 for (x
= w
; x
-- > 0;) {
1342 r
= (wp
[0] * a
) / 0x10eff;
1343 g
= (wp
[1] * a
) / 0x10eff;
1344 b
= (wp
[2] * a
) / 0x10eff;
1345 *cp
++ = PACK4(r
,g
,b
,a
);
1346 wp
+= samplesperpixel
;
1354 * 8-bit packed CMYK samples w/o Map => RGB
1356 * NB: The conversion of CMYK->RGB is *very* crude.
1358 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile
)
1360 int samplesperpixel
= img
->samplesperpixel
;
1364 fromskew
*= samplesperpixel
;
1368 r
= (k
*(255-pp
[0]))/255;
1369 g
= (k
*(255-pp
[1]))/255;
1370 b
= (k
*(255-pp
[2]))/255;
1371 *cp
++ = PACK(r
, g
, b
);
1372 pp
+= samplesperpixel
);
1379 * 8-bit packed CMYK samples w/Map => RGB
1381 * NB: The conversion of CMYK->RGB is *very* crude.
1383 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile
)
1385 int samplesperpixel
= img
->samplesperpixel
;
1386 TIFFRGBValue
* Map
= img
->Map
;
1390 fromskew
*= samplesperpixel
;
1392 for (x
= w
; x
-- > 0;) {
1394 r
= (k
*(255-pp
[0]))/255;
1395 g
= (k
*(255-pp
[1]))/255;
1396 b
= (k
*(255-pp
[2]))/255;
1397 *cp
++ = PACK(Map
[r
], Map
[g
], Map
[b
]);
1398 pp
+= samplesperpixel
;
1405 #define DECLARESepPutFunc(name) \
1407 TIFFRGBAImage* img,\
1409 uint32 x, uint32 y, \
1410 uint32 w, uint32 h,\
1411 int32 fromskew, int32 toskew,\
1412 u_char* r, u_char* g, u_char* b, u_char* a\
1416 * 8-bit unpacked samples => RGB
1418 DECLARESepPutFunc(putRGBseparate8bittile
)
1420 (void) img
; (void) x
; (void) y
; (void) a
;
1422 UNROLL8(w
, NOP
, *cp
++ = PACK(*r
++, *g
++, *b
++));
1423 SKEW(r
, g
, b
, fromskew
);
1429 * 8-bit unpacked samples => RGB
1431 DECLARESepPutFunc(putRGBseparate8bitMaptile
)
1433 TIFFRGBValue
* Map
= img
->Map
;
1437 for (x
= w
; x
> 0; x
--)
1438 *cp
++ = PACK(Map
[*r
++], Map
[*g
++], Map
[*b
++]);
1439 SKEW(r
, g
, b
, fromskew
);
1445 * 8-bit unpacked samples => RGBA w/ associated alpha
1447 DECLARESepPutFunc(putRGBAAseparate8bittile
)
1449 (void) img
; (void) x
; (void) y
;
1451 UNROLL8(w
, NOP
, *cp
++ = PACK4(*r
++, *g
++, *b
++, *a
++));
1452 SKEW4(r
, g
, b
, a
, fromskew
);
1458 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1460 DECLARESepPutFunc(putRGBUAseparate8bittile
)
1462 (void) img
; (void) y
;
1464 uint32 rv
, gv
, bv
, av
;
1465 for (x
= w
; x
-- > 0;) {
1467 rv
= (*r
++ * av
) / 255;
1468 gv
= (*g
++ * av
) / 255;
1469 bv
= (*b
++ * av
) / 255;
1470 *cp
++ = PACK4(rv
,gv
,bv
,av
);
1472 SKEW4(r
, g
, b
, a
, fromskew
);
1478 * 16-bit unpacked samples => RGB
1480 DECLARESepPutFunc(putRGBseparate16bittile
)
1482 uint16
*wr
= (uint16
*) r
;
1483 uint16
*wg
= (uint16
*) g
;
1484 uint16
*wb
= (uint16
*) b
;
1486 (void) img
; (void) y
; (void) a
;
1488 for (x
= 0; x
< w
; x
++)
1489 *cp
++ = PACKW(*wr
++, *wg
++, *wb
++);
1490 SKEW(wr
, wg
, wb
, fromskew
);
1496 * 16-bit unpacked samples => RGBA w/ associated alpha
1498 DECLARESepPutFunc(putRGBAAseparate16bittile
)
1500 uint16
*wr
= (uint16
*) r
;
1501 uint16
*wg
= (uint16
*) g
;
1502 uint16
*wb
= (uint16
*) b
;
1503 uint16
*wa
= (uint16
*) a
;
1505 (void) img
; (void) y
;
1507 for (x
= 0; x
< w
; x
++)
1508 *cp
++ = PACKW4(*wr
++, *wg
++, *wb
++, *wa
++);
1509 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1515 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1517 DECLARESepPutFunc(putRGBUAseparate16bittile
)
1519 uint16
*wr
= (uint16
*) r
;
1520 uint16
*wg
= (uint16
*) g
;
1521 uint16
*wb
= (uint16
*) b
;
1522 uint16
*wa
= (uint16
*) a
;
1524 (void) img
; (void) y
;
1528 * We shift alpha down four bits just in case unsigned
1529 * arithmetic doesn't handle the full range.
1530 * We still have plenty of accuracy, since the output is 8 bits.
1531 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1532 * Since we want r*a * 0xff for eight bit output,
1533 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1535 for (x
= w
; x
-- > 0;) {
1537 r
= (*wr
++ * a
) / 0x10eff;
1538 g
= (*wg
++ * a
) / 0x10eff;
1539 b
= (*wb
++ * a
) / 0x10eff;
1540 *cp
++ = PACK4(r
,g
,b
,a
);
1542 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1548 * 8-bit packed CIE L*a*b 1976 samples => RGB
1550 DECLAREContigPutFunc(putcontig8bitCIELab
)
1557 for (x
= w
; x
-- > 0;) {
1558 TIFFCIELabToXYZ(img
->cielab
,
1563 TIFFXYZToRGB(img
->cielab
, X
, Y
, Z
, &r
, &g
, &b
);
1564 *cp
++ = PACK(r
, g
, b
);
1573 * YCbCr -> RGB conversion and packing routines.
1576 #define YCbCrtoRGB(dst, Y) { \
1578 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1579 dst = PACK(r, g, b); \
1583 * 8-bit packed YCbCr samples => RGB
1584 * This function is generic for different sampling sizes,
1585 * and can handle blocks sizes that aren't multiples of the
1586 * sampling size. However, it is substantially less optimized
1587 * than the specific sampling cases. It is used as a fallback
1588 * for difficult blocks.
1591 static void putcontig8bitYCbCrGenericTile(
1596 int32 fromskew
, int32 toskew
,
1602 uint32
* cp1
= cp
+w
+toskew
;
1603 uint32
* cp2
= cp1
+w
+toskew
;
1604 uint32
* cp3
= cp2
+w
+toskew
;
1605 int32 incr
= 3*w
+4*toskew
;
1607 int group_size
= v_group
* h_group
+ 2;
1610 fromskew
= (fromskew
* group_size
) / h_group
;
1612 for( yy
= 0; yy
< h
; yy
++ )
1615 int y_line_group
= yy
/ v_group
;
1616 int y_remainder
= yy
- y_line_group
* v_group
;
1618 pp_line
= pp
+ v_line_group
*
1621 for( xx
= 0; xx
< w
; xx
++ )
1626 for (; h
>= 4; h
-= 4) {
1632 YCbCrtoRGB(cp
[0], pp
[ 0]);
1633 YCbCrtoRGB(cp
[1], pp
[ 1]);
1634 YCbCrtoRGB(cp
[2], pp
[ 2]);
1635 YCbCrtoRGB(cp
[3], pp
[ 3]);
1636 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1637 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1638 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1639 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1640 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1641 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1642 YCbCrtoRGB(cp2
[2], pp
[10]);
1643 YCbCrtoRGB(cp2
[3], pp
[11]);
1644 YCbCrtoRGB(cp3
[0], pp
[12]);
1645 YCbCrtoRGB(cp3
[1], pp
[13]);
1646 YCbCrtoRGB(cp3
[2], pp
[14]);
1647 YCbCrtoRGB(cp3
[3], pp
[15]);
1649 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1652 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1659 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1661 DECLAREContigPutFunc(putcontig8bitYCbCr44tile
)
1663 uint32
* cp1
= cp
+w
+toskew
;
1664 uint32
* cp2
= cp1
+w
+toskew
;
1665 uint32
* cp3
= cp2
+w
+toskew
;
1666 int32 incr
= 3*w
+4*toskew
;
1669 /* adjust fromskew */
1670 fromskew
= (fromskew
* 18) / 4;
1671 if ((h
& 3) == 0 && (w
& 3) == 0) {
1672 for (; h
>= 4; h
-= 4) {
1678 YCbCrtoRGB(cp
[0], pp
[ 0]);
1679 YCbCrtoRGB(cp
[1], pp
[ 1]);
1680 YCbCrtoRGB(cp
[2], pp
[ 2]);
1681 YCbCrtoRGB(cp
[3], pp
[ 3]);
1682 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1683 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1684 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1685 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1686 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1687 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1688 YCbCrtoRGB(cp2
[2], pp
[10]);
1689 YCbCrtoRGB(cp2
[3], pp
[11]);
1690 YCbCrtoRGB(cp3
[0], pp
[12]);
1691 YCbCrtoRGB(cp3
[1], pp
[13]);
1692 YCbCrtoRGB(cp3
[2], pp
[14]);
1693 YCbCrtoRGB(cp3
[3], pp
[15]);
1695 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1698 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1703 for (x
= w
; x
> 0;) {
1709 default: YCbCrtoRGB(cp3
[3], pp
[15]); /* FALLTHROUGH */
1710 case 3: YCbCrtoRGB(cp2
[3], pp
[11]); /* FALLTHROUGH */
1711 case 2: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1712 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1716 default: YCbCrtoRGB(cp3
[2], pp
[14]); /* FALLTHROUGH */
1717 case 3: YCbCrtoRGB(cp2
[2], pp
[10]); /* FALLTHROUGH */
1718 case 2: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1719 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1723 default: YCbCrtoRGB(cp3
[1], pp
[13]); /* FALLTHROUGH */
1724 case 3: YCbCrtoRGB(cp2
[1], pp
[ 9]); /* FALLTHROUGH */
1725 case 2: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1726 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1730 default: YCbCrtoRGB(cp3
[0], pp
[12]); /* FALLTHROUGH */
1731 case 3: YCbCrtoRGB(cp2
[0], pp
[ 8]); /* FALLTHROUGH */
1732 case 2: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1733 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1737 cp
+= x
; cp1
+= x
; cp2
+= x
; cp3
+= x
;
1741 cp
+= 4; cp1
+= 4; cp2
+= 4; cp3
+= 4;
1749 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1756 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1758 DECLAREContigPutFunc(putcontig8bitYCbCr42tile
)
1760 uint32
* cp1
= cp
+w
+toskew
;
1761 int32 incr
= 2*toskew
+w
;
1764 fromskew
= (fromskew
* 10) / 4;
1765 if ((h
& 3) == 0 && (w
& 1) == 0) {
1766 for (; h
>= 2; h
-= 2) {
1772 YCbCrtoRGB(cp
[0], pp
[0]);
1773 YCbCrtoRGB(cp
[1], pp
[1]);
1774 YCbCrtoRGB(cp
[2], pp
[2]);
1775 YCbCrtoRGB(cp
[3], pp
[3]);
1776 YCbCrtoRGB(cp1
[0], pp
[4]);
1777 YCbCrtoRGB(cp1
[1], pp
[5]);
1778 YCbCrtoRGB(cp1
[2], pp
[6]);
1779 YCbCrtoRGB(cp1
[3], pp
[7]);
1784 cp
+= incr
, cp1
+= incr
;
1789 for (x
= w
; x
> 0;) {
1795 default: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1796 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1800 default: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1801 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1805 default: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1806 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1810 default: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1811 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1827 cp
+= incr
, cp1
+= incr
;
1834 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1836 DECLAREContigPutFunc(putcontig8bitYCbCr41tile
)
1839 /* XXX adjust fromskew */
1846 YCbCrtoRGB(cp
[0], pp
[0]);
1847 YCbCrtoRGB(cp
[1], pp
[1]);
1848 YCbCrtoRGB(cp
[2], pp
[2]);
1849 YCbCrtoRGB(cp
[3], pp
[3]);
1861 case 3: YCbCrtoRGB(cp
[2], pp
[2]);
1862 case 2: YCbCrtoRGB(cp
[1], pp
[1]);
1863 case 1: YCbCrtoRGB(cp
[0], pp
[0]);
1878 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1880 DECLAREContigPutFunc(putcontig8bitYCbCr22tile
)
1882 uint32
* cp1
= cp
+w
+toskew
;
1883 int32 incr
= 2*toskew
+w
;
1886 fromskew
= (fromskew
* 6) / 2;
1887 if ((h
& 1) == 0 && (w
& 1) == 0) {
1888 for (; h
>= 2; h
-= 2) {
1894 YCbCrtoRGB(cp
[0], pp
[0]);
1895 YCbCrtoRGB(cp
[1], pp
[1]);
1896 YCbCrtoRGB(cp1
[0], pp
[2]);
1897 YCbCrtoRGB(cp1
[1], pp
[3]);
1902 cp
+= incr
, cp1
+= incr
;
1907 for (x
= w
; x
> 0;) {
1913 default: YCbCrtoRGB(cp1
[1], pp
[ 3]); /* FALLTHROUGH */
1914 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1918 default: YCbCrtoRGB(cp1
[0], pp
[ 2]); /* FALLTHROUGH */
1919 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1935 cp
+= incr
, cp1
+= incr
;
1942 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
1944 DECLAREContigPutFunc(putcontig8bitYCbCr21tile
)
1947 fromskew
= (fromskew
* 4) / 2;
1954 YCbCrtoRGB(cp
[0], pp
[0]);
1955 YCbCrtoRGB(cp
[1], pp
[1]);
1966 YCbCrtoRGB(cp
[0], pp
[0]);
1978 * 8-bit packed YCbCr samples w/ no subsampling => RGB
1980 DECLAREContigPutFunc(putcontig8bitYCbCr11tile
)
1985 x
= w
; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
1990 YCbCrtoRGB(*cp
++, pp
[0]);
2000 static tileContigRoutine
2001 initYCbCrConversion(TIFFRGBAImage
* img
)
2003 static char module[] = "initCIELabConversion";
2005 float *luma
, *refBlackWhite
;
2008 if (img
->ycbcr
== NULL
) {
2009 img
->ycbcr
= (TIFFYCbCrToRGB
*) _TIFFmalloc(
2010 TIFFroundup(sizeof (TIFFYCbCrToRGB
), sizeof (long))
2011 + 4*256*sizeof (TIFFRGBValue
)
2012 + 2*256*sizeof (int)
2013 + 3*256*sizeof (int32
)
2015 if (img
->ycbcr
== NULL
) {
2017 "No space for YCbCr->RGB conversion state");
2022 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRCOEFFICIENTS
, &luma
);
2023 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_REFERENCEBLACKWHITE
,
2025 if (TIFFYCbCrToRGBInit(img
->ycbcr
, luma
, refBlackWhite
) < 0)
2029 * The 6.0 spec says that subsampling must be
2030 * one of 1, 2, or 4, and that vertical subsampling
2031 * must always be <= horizontal subsampling; so
2032 * there are only a few possibilities and we just
2033 * enumerate the cases.
2035 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &hs
, &vs
);
2036 switch ((hs
<<4)|vs
) {
2037 case 0x44: return (&putcontig8bitYCbCr44tile
);
2038 case 0x42: return (&putcontig8bitYCbCr42tile
);
2039 case 0x41: return (&putcontig8bitYCbCr41tile
);
2040 case 0x22: return (&putcontig8bitYCbCr22tile
);
2041 case 0x21: return (&putcontig8bitYCbCr21tile
);
2042 case 0x11: return (&putcontig8bitYCbCr11tile
);
2048 static tileContigRoutine
2049 initCIELabConversion(TIFFRGBAImage
* img
)
2051 static char module[] = "initCIELabConversion";
2057 img
->cielab
= (TIFFCIELabToRGB
*)
2058 _TIFFmalloc(sizeof(TIFFCIELabToRGB
));
2061 "No space for CIE L*a*b*->RGB conversion state.");
2066 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_WHITEPOINT
, &whitePoint
);
2067 refWhite
[1] = 100.0F
;
2068 refWhite
[0] = whitePoint
[0] / whitePoint
[1] * refWhite
[1];
2069 refWhite
[2] = (1.0F
- whitePoint
[0] - whitePoint
[1])
2070 / whitePoint
[1] * refWhite
[1];
2071 if (TIFFCIELabToRGBInit(img
->cielab
, &display_sRGB
, refWhite
) < 0) {
2073 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2074 _TIFFfree(img
->cielab
);
2078 return &putcontig8bitCIELab
;
2082 * Greyscale images with less than 8 bits/sample are handled
2083 * with a table to avoid lots of shifts and masks. The table
2084 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2085 * pixel values simply by indexing into the table with one
2089 makebwmap(TIFFRGBAImage
* img
)
2091 TIFFRGBValue
* Map
= img
->Map
;
2092 int bitspersample
= img
->bitspersample
;
2093 int nsamples
= 8 / bitspersample
;
2100 img
->BWmap
= (uint32
**) _TIFFmalloc(
2101 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2102 if (img
->BWmap
== NULL
) {
2103 TIFFError(TIFFFileName(img
->tif
), "No space for B&W mapping table");
2106 p
= (uint32
*)(img
->BWmap
+ 256);
2107 for (i
= 0; i
< 256; i
++) {
2110 switch (bitspersample
) {
2111 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2143 * Construct a mapping table to convert from the range
2144 * of the data samples to [0,255] --for display. This
2145 * process also handles inverting B&W images when needed.
2148 setupMap(TIFFRGBAImage
* img
)
2152 range
= (int32
)((1L<<img
->bitspersample
)-1);
2154 /* treat 16 bit the same as eight bit */
2155 if( img
->bitspersample
== 16 )
2156 range
= (int32
) 255;
2158 img
->Map
= (TIFFRGBValue
*) _TIFFmalloc((range
+1) * sizeof (TIFFRGBValue
));
2159 if (img
->Map
== NULL
) {
2160 TIFFError(TIFFFileName(img
->tif
),
2161 "No space for photometric conversion table");
2164 if (img
->photometric
== PHOTOMETRIC_MINISWHITE
) {
2165 for (x
= 0; x
<= range
; x
++)
2166 img
->Map
[x
] = (TIFFRGBValue
) (((range
- x
) * 255) / range
);
2168 for (x
= 0; x
<= range
; x
++)
2169 img
->Map
[x
] = (TIFFRGBValue
) ((x
* 255) / range
);
2171 if (img
->bitspersample
<= 16 &&
2172 (img
->photometric
== PHOTOMETRIC_MINISBLACK
||
2173 img
->photometric
== PHOTOMETRIC_MINISWHITE
)) {
2175 * Use photometric mapping table to construct
2176 * unpacking tables for samples <= 8 bits.
2178 if (!makebwmap(img
))
2180 /* no longer need Map, free it */
2181 _TIFFfree(img
->Map
), img
->Map
= NULL
;
2187 checkcmap(TIFFRGBAImage
* img
)
2189 uint16
* r
= img
->redcmap
;
2190 uint16
* g
= img
->greencmap
;
2191 uint16
* b
= img
->bluecmap
;
2192 long n
= 1L<<img
->bitspersample
;
2195 if (*r
++ >= 256 || *g
++ >= 256 || *b
++ >= 256)
2201 cvtcmap(TIFFRGBAImage
* img
)
2203 uint16
* r
= img
->redcmap
;
2204 uint16
* g
= img
->greencmap
;
2205 uint16
* b
= img
->bluecmap
;
2208 for (i
= (1L<<img
->bitspersample
)-1; i
>= 0; i
--) {
2209 #define CVT(x) ((uint16)((x)>>8))
2218 * Palette images with <= 8 bits/sample are handled
2219 * with a table to avoid lots of shifts and masks. The table
2220 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2221 * pixel values simply by indexing into the table with one
2225 makecmap(TIFFRGBAImage
* img
)
2227 int bitspersample
= img
->bitspersample
;
2228 int nsamples
= 8 / bitspersample
;
2229 uint16
* r
= img
->redcmap
;
2230 uint16
* g
= img
->greencmap
;
2231 uint16
* b
= img
->bluecmap
;
2235 img
->PALmap
= (uint32
**) _TIFFmalloc(
2236 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2237 if (img
->PALmap
== NULL
) {
2238 TIFFError(TIFFFileName(img
->tif
), "No space for Palette mapping table");
2241 p
= (uint32
*)(img
->PALmap
+ 256);
2242 for (i
= 0; i
< 256; i
++) {
2245 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2246 switch (bitspersample
) {
2277 * Construct any mapping table used
2278 * by the associated put routine.
2281 buildMap(TIFFRGBAImage
* img
)
2283 switch (img
->photometric
) {
2284 case PHOTOMETRIC_RGB
:
2285 case PHOTOMETRIC_YCBCR
:
2286 case PHOTOMETRIC_SEPARATED
:
2287 if (img
->bitspersample
== 8)
2290 case PHOTOMETRIC_MINISBLACK
:
2291 case PHOTOMETRIC_MINISWHITE
:
2295 case PHOTOMETRIC_PALETTE
:
2297 * Convert 16-bit colormap to 8-bit (unless it looks
2298 * like an old-style 8-bit colormap).
2300 if (checkcmap(img
) == 16)
2303 TIFFWarning(TIFFFileName(img
->tif
), "Assuming 8-bit colormap");
2305 * Use mapping table and colormap to construct
2306 * unpacking tables for samples < 8 bits.
2308 if (img
->bitspersample
<= 8 && !makecmap(img
))
2316 * Select the appropriate conversion routine for packed data.
2319 pickTileContigCase(TIFFRGBAImage
* img
)
2321 tileContigRoutine put
= 0;
2323 if (buildMap(img
)) {
2324 switch (img
->photometric
) {
2325 case PHOTOMETRIC_RGB
:
2326 switch (img
->bitspersample
) {
2329 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2330 put
= putRGBAAcontig8bittile
;
2331 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2332 put
= putRGBUAcontig8bittile
;
2334 put
= putRGBcontig8bittile
;
2336 put
= putRGBcontig8bitMaptile
;
2339 put
= putRGBcontig16bittile
;
2341 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2342 put
= putRGBAAcontig16bittile
;
2343 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2344 put
= putRGBUAcontig16bittile
;
2349 case PHOTOMETRIC_SEPARATED
:
2350 if (img
->bitspersample
== 8) {
2352 put
= putRGBcontig8bitCMYKtile
;
2354 put
= putRGBcontig8bitCMYKMaptile
;
2357 case PHOTOMETRIC_PALETTE
:
2358 switch (img
->bitspersample
) {
2359 case 8: put
= put8bitcmaptile
; break;
2360 case 4: put
= put4bitcmaptile
; break;
2361 case 2: put
= put2bitcmaptile
; break;
2362 case 1: put
= put1bitcmaptile
; break;
2365 case PHOTOMETRIC_MINISWHITE
:
2366 case PHOTOMETRIC_MINISBLACK
:
2367 switch (img
->bitspersample
) {
2368 case 16: put
= put16bitbwtile
; break;
2369 case 8: put
= putgreytile
; break;
2370 case 4: put
= put4bitbwtile
; break;
2371 case 2: put
= put2bitbwtile
; break;
2372 case 1: put
= put1bitbwtile
; break;
2375 case PHOTOMETRIC_YCBCR
:
2376 if (img
->bitspersample
== 8)
2377 put
= initYCbCrConversion(img
);
2379 case PHOTOMETRIC_CIELAB
:
2380 if (img
->bitspersample
== 8)
2381 put
= initCIELabConversion(img
);
2385 return ((img
->put
.contig
= put
) != 0);
2389 * Select the appropriate conversion routine for unpacked data.
2391 * NB: we assume that unpacked single channel data is directed
2392 * to the "packed routines.
2395 pickTileSeparateCase(TIFFRGBAImage
* img
)
2397 tileSeparateRoutine put
= 0;
2399 if (buildMap(img
)) {
2400 switch (img
->photometric
) {
2401 case PHOTOMETRIC_RGB
:
2402 switch (img
->bitspersample
) {
2405 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2406 put
= putRGBAAseparate8bittile
;
2407 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2408 put
= putRGBUAseparate8bittile
;
2410 put
= putRGBseparate8bittile
;
2412 put
= putRGBseparate8bitMaptile
;
2415 put
= putRGBseparate16bittile
;
2417 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2418 put
= putRGBAAseparate16bittile
;
2419 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2420 put
= putRGBUAseparate16bittile
;
2427 return ((img
->put
.separate
= put
) != 0);
2431 * Read a whole strip off data from the file, and convert to RGBA form.
2432 * If this is the last strip, then it will only contain the portion of
2433 * the strip that is actually within the image space. The result is
2434 * organized in bottom to top form.
2439 TIFFReadRGBAStrip(TIFF
* tif
, uint32 row
, uint32
* raster
)
2445 uint32 rowsperstrip
, rows_to_read
;
2447 if( TIFFIsTiled( tif
) )
2449 TIFFError(TIFFFileName(tif
),
2450 "Can't use TIFFReadRGBAStrip() with tiled file.");
2454 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
2455 if( (row
% rowsperstrip
) != 0 )
2457 TIFFError(TIFFFileName(tif
),
2458 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2462 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) {
2464 img
.row_offset
= row
;
2467 if( row
+ rowsperstrip
> img
.height
)
2468 rows_to_read
= img
.height
- row
;
2470 rows_to_read
= rowsperstrip
;
2472 ok
= TIFFRGBAImageGet(&img
, raster
, img
.width
, rows_to_read
);
2474 TIFFRGBAImageEnd(&img
);
2476 TIFFError(TIFFFileName(tif
), emsg
);
2484 * Read a whole tile off data from the file, and convert to RGBA form.
2485 * The returned RGBA data is organized from bottom to top of tile,
2486 * and may include zeroed areas if the tile extends off the image.
2490 TIFFReadRGBATile(TIFF
* tif
, uint32 col
, uint32 row
, uint32
* raster
)
2496 uint32 tile_xsize
, tile_ysize
;
2497 uint32 read_xsize
, read_ysize
;
2501 * Verify that our request is legal - on a tile file, and on a
2505 if( !TIFFIsTiled( tif
) )
2507 TIFFError(TIFFFileName(tif
),
2508 "Can't use TIFFReadRGBATile() with stripped file.");
2512 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILEWIDTH
, &tile_xsize
);
2513 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILELENGTH
, &tile_ysize
);
2514 if( (col
% tile_xsize
) != 0 || (row
% tile_ysize
) != 0 )
2516 TIFFError(TIFFFileName(tif
),
2517 "Row/col passed to TIFFReadRGBATile() must be top"
2518 "left corner of a tile.");
2523 * Setup the RGBA reader.
2526 if (!TIFFRGBAImageOK(tif
, emsg
)
2527 || !TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) {
2528 TIFFError(TIFFFileName(tif
), emsg
);
2533 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2534 * edge of the image, even to fill an otherwise valid tile. So we
2535 * figure out how much we can read, and fix up the tile buffer to
2536 * a full tile configuration afterwards.
2539 if( row
+ tile_ysize
> img
.height
)
2540 read_ysize
= img
.height
- row
;
2542 read_ysize
= tile_ysize
;
2544 if( col
+ tile_xsize
> img
.width
)
2545 read_xsize
= img
.width
- col
;
2547 read_xsize
= tile_xsize
;
2550 * Read the chunk of imagery.
2553 img
.row_offset
= row
;
2554 img
.col_offset
= col
;
2556 ok
= TIFFRGBAImageGet(&img
, raster
, read_xsize
, read_ysize
);
2558 TIFFRGBAImageEnd(&img
);
2561 * If our read was incomplete we will need to fix up the tile by
2562 * shifting the data around as if a full tile of data is being returned.
2564 * This is all the more complicated because the image is organized in
2565 * bottom to top format.
2568 if( read_xsize
== tile_xsize
&& read_ysize
== tile_ysize
)
2571 for( i_row
= 0; i_row
< read_ysize
; i_row
++ ) {
2572 memmove( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
2573 raster
+ (read_ysize
- i_row
- 1) * read_xsize
,
2574 read_xsize
* sizeof(uint32
) );
2575 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
+read_xsize
,
2576 0, sizeof(uint32
) * (tile_xsize
- read_xsize
) );
2579 for( i_row
= read_ysize
; i_row
< tile_ysize
; i_row
++ ) {
2580 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
2581 0, sizeof(uint32
) * tile_xsize
);