4 * Copyright (c) 1991-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
7 * Permission to use, copy, modify, distribute, and sell this software and
8 * its documentation for any purpose is hereby granted without fee, provided
9 * that (i) the above copyright notices and this permission notice appear in
10 * all copies of the software and related documentation, and (ii) the names of
11 * Sam Leffler and Silicon Graphics may not be used in any advertising or
12 * publicity relating to the software without the specific, prior written
13 * permission of Sam Leffler and Silicon Graphics.
15 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
30 * Read and return a packed RGBA image.
35 static int gtTileContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
36 static int gtTileSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
37 static int gtStripContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
38 static int gtStripSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
39 static int pickTileContigCase(TIFFRGBAImage
*);
40 static int pickTileSeparateCase(TIFFRGBAImage
*);
42 static const char photoTag
[] = "PhotometricInterpretation";
45 * Helper constants used in Orientation tag handling
47 #define FLIP_VERTICALLY 0x01
48 #define FLIP_HORIZONTALLY 0x02
51 * Color conversion constants. We will define display types here.
54 TIFFDisplay display_sRGB
= {
55 { /* XYZ -> luminance matrix */
56 { 3.2410F
, -1.5374F
, -0.4986F
},
57 { -0.9692F
, 1.8760F
, 0.0416F
},
58 { 0.0556F
, -0.2040F
, 1.0570F
}
60 100.0F
, 100.0F
, 100.0F
, /* Light o/p for reference white */
61 255, 255, 255, /* Pixel values for ref. white */
62 1.0F
, 1.0F
, 1.0F
, /* Residual light o/p for black pixel */
63 2.4F
, 2.4F
, 2.4F
, /* Gamma values for the three guns */
67 * Check the image to see if TIFFReadRGBAImage can deal with it.
68 * 1/0 is returned according to whether or not the image can
69 * be handled. If 0 is returned, emsg contains the reason
70 * why it is being rejected.
73 TIFFRGBAImageOK(TIFF
* tif
, char emsg
[1024])
75 TIFFDirectory
* td
= &tif
->tif_dir
;
79 if (!tif
->tif_decodestatus
) {
80 sprintf(emsg
, "Sorry, requested compression method is not configured");
83 switch (td
->td_bitspersample
) {
84 case 1: case 2: case 4:
88 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
89 td
->td_bitspersample
);
92 colorchannels
= td
->td_samplesperpixel
- td
->td_extrasamples
;
93 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &photometric
)) {
94 switch (colorchannels
) {
96 photometric
= PHOTOMETRIC_MINISBLACK
;
99 photometric
= PHOTOMETRIC_RGB
;
102 sprintf(emsg
, "Missing needed %s tag", photoTag
);
106 switch (photometric
) {
107 case PHOTOMETRIC_MINISWHITE
:
108 case PHOTOMETRIC_MINISBLACK
:
109 case PHOTOMETRIC_PALETTE
:
110 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
111 && td
->td_samplesperpixel
!= 1
112 && td
->td_bitspersample
< 8 ) {
114 "Sorry, can not handle contiguous data with %s=%d, "
115 "and %s=%d and Bits/Sample=%d",
116 photoTag
, photometric
,
117 "Samples/pixel", td
->td_samplesperpixel
,
118 td
->td_bitspersample
);
122 ** We should likely validate that any extra samples are either
123 ** to be ignored, or are alpha, and if alpha we should try to use
124 ** them. But for now we won't bother with this.
127 case PHOTOMETRIC_YCBCR
:
128 if (td
->td_planarconfig
!= PLANARCONFIG_CONTIG
) {
129 sprintf(emsg
, "Sorry, can not handle YCbCr images with %s=%d",
130 "Planarconfiguration", td
->td_planarconfig
);
134 case PHOTOMETRIC_RGB
:
135 if (colorchannels
< 3) {
136 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
137 "Color channels", colorchannels
);
141 case PHOTOMETRIC_SEPARATED
:
144 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
145 if (inkset
!= INKSET_CMYK
) {
147 "Sorry, can not handle separated image with %s=%d",
151 if (td
->td_samplesperpixel
< 4) {
153 "Sorry, can not handle separated image with %s=%d",
154 "Samples/pixel", td
->td_samplesperpixel
);
159 case PHOTOMETRIC_LOGL
:
160 if (td
->td_compression
!= COMPRESSION_SGILOG
) {
161 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
162 "Compression", COMPRESSION_SGILOG
);
166 case PHOTOMETRIC_LOGLUV
:
167 if (td
->td_compression
!= COMPRESSION_SGILOG
&&
168 td
->td_compression
!= COMPRESSION_SGILOG24
) {
169 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
170 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
173 if (td
->td_planarconfig
!= PLANARCONFIG_CONTIG
) {
174 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
175 "Planarconfiguration", td
->td_planarconfig
);
179 case PHOTOMETRIC_CIELAB
:
182 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
183 photoTag
, photometric
);
190 TIFFRGBAImageEnd(TIFFRGBAImage
* img
)
193 _TIFFfree(img
->Map
), img
->Map
= NULL
;
195 _TIFFfree(img
->BWmap
), img
->BWmap
= NULL
;
197 _TIFFfree(img
->PALmap
), img
->PALmap
= NULL
;
199 _TIFFfree(img
->ycbcr
), img
->ycbcr
= NULL
;
201 _TIFFfree(img
->cielab
), img
->cielab
= NULL
;
204 _TIFFfree( img
->redcmap
);
205 _TIFFfree( img
->greencmap
);
206 _TIFFfree( img
->bluecmap
);
211 isCCITTCompression(TIFF
* tif
)
214 TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compress
);
215 return (compress
== COMPRESSION_CCITTFAX3
||
216 compress
== COMPRESSION_CCITTFAX4
||
217 compress
== COMPRESSION_CCITTRLE
||
218 compress
== COMPRESSION_CCITTRLEW
);
222 TIFFRGBAImageBegin(TIFFRGBAImage
* img
, TIFF
* tif
, int stop
, char emsg
[1024])
229 uint16
*red_orig
, *green_orig
, *blue_orig
;
232 /* Initialize to normal values */
236 img
->greencmap
= NULL
;
237 img
->bluecmap
= NULL
;
238 img
->req_orientation
= ORIENTATION_BOTLEFT
; /* It is the default */
241 img
->stoponerr
= stop
;
242 TIFFGetFieldDefaulted(tif
, TIFFTAG_BITSPERSAMPLE
, &img
->bitspersample
);
243 switch (img
->bitspersample
) {
244 case 1: case 2: case 4:
248 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
253 TIFFGetFieldDefaulted(tif
, TIFFTAG_SAMPLESPERPIXEL
, &img
->samplesperpixel
);
254 TIFFGetFieldDefaulted(tif
, TIFFTAG_EXTRASAMPLES
,
255 &extrasamples
, &sampleinfo
);
256 if (extrasamples
>= 1)
258 switch (sampleinfo
[0]) {
259 case EXTRASAMPLE_UNSPECIFIED
: /* Workaround for some images without */
260 if (img
->samplesperpixel
> 3) /* correct info about alpha channel */
261 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
263 case EXTRASAMPLE_ASSOCALPHA
: /* data is pre-multiplied */
264 case EXTRASAMPLE_UNASSALPHA
: /* data is not pre-multiplied */
265 img
->alpha
= sampleinfo
[0];
270 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
271 if( !TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
))
272 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
274 if( extrasamples
== 0
275 && img
->samplesperpixel
== 4
276 && img
->photometric
== PHOTOMETRIC_RGB
)
278 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
283 colorchannels
= img
->samplesperpixel
- extrasamples
;
284 TIFFGetFieldDefaulted(tif
, TIFFTAG_COMPRESSION
, &compress
);
285 TIFFGetFieldDefaulted(tif
, TIFFTAG_PLANARCONFIG
, &planarconfig
);
286 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
)) {
287 switch (colorchannels
) {
289 if (isCCITTCompression(tif
))
290 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
292 img
->photometric
= PHOTOMETRIC_MINISBLACK
;
295 img
->photometric
= PHOTOMETRIC_RGB
;
298 sprintf(emsg
, "Missing needed %s tag", photoTag
);
302 switch (img
->photometric
) {
303 case PHOTOMETRIC_PALETTE
:
304 if (!TIFFGetField(tif
, TIFFTAG_COLORMAP
,
305 &red_orig
, &green_orig
, &blue_orig
)) {
306 sprintf(emsg
, "Missing required \"Colormap\" tag");
310 /* copy the colormaps so we can modify them */
311 n_color
= (1L << img
->bitspersample
);
312 img
->redcmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
313 img
->greencmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
314 img
->bluecmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
315 if( !img
->redcmap
|| !img
->greencmap
|| !img
->bluecmap
) {
316 sprintf(emsg
, "Out of memory for colormap copy");
320 _TIFFmemcpy( img
->redcmap
, red_orig
, n_color
* 2 );
321 _TIFFmemcpy( img
->greencmap
, green_orig
, n_color
* 2 );
322 _TIFFmemcpy( img
->bluecmap
, blue_orig
, n_color
* 2 );
325 case PHOTOMETRIC_MINISWHITE
:
326 case PHOTOMETRIC_MINISBLACK
:
327 if (planarconfig
== PLANARCONFIG_CONTIG
328 && img
->samplesperpixel
!= 1
329 && img
->bitspersample
< 8 ) {
331 "Sorry, can not handle contiguous data with %s=%d, "
332 "and %s=%d and Bits/Sample=%d",
333 photoTag
, img
->photometric
,
334 "Samples/pixel", img
->samplesperpixel
,
339 case PHOTOMETRIC_YCBCR
:
340 if (planarconfig
!= PLANARCONFIG_CONTIG
) {
341 sprintf(emsg
, "Sorry, can not handle YCbCr images with %s=%d",
342 "Planarconfiguration", planarconfig
);
345 /* It would probably be nice to have a reality check here. */
346 if (planarconfig
== PLANARCONFIG_CONTIG
)
347 /* can rely on libjpeg to convert to RGB */
348 /* XXX should restore current state on exit */
350 case COMPRESSION_OJPEG
:
351 case COMPRESSION_JPEG
:
352 TIFFSetField(tif
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
353 img
->photometric
= PHOTOMETRIC_RGB
;
361 case PHOTOMETRIC_RGB
:
362 if (colorchannels
< 3) {
363 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
364 "Color channels", colorchannels
);
368 case PHOTOMETRIC_SEPARATED
: {
370 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
371 if (inkset
!= INKSET_CMYK
) {
372 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
376 if (img
->samplesperpixel
< 4) {
377 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
378 "Samples/pixel", img
->samplesperpixel
);
383 case PHOTOMETRIC_LOGL
:
384 if (compress
!= COMPRESSION_SGILOG
) {
385 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
386 "Compression", COMPRESSION_SGILOG
);
389 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
390 img
->photometric
= PHOTOMETRIC_MINISBLACK
; /* little white lie */
391 img
->bitspersample
= 8;
393 case PHOTOMETRIC_LOGLUV
:
394 if (compress
!= COMPRESSION_SGILOG
&& compress
!= COMPRESSION_SGILOG24
) {
395 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
396 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
399 if (planarconfig
!= PLANARCONFIG_CONTIG
) {
400 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
401 "Planarconfiguration", planarconfig
);
404 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
405 img
->photometric
= PHOTOMETRIC_RGB
; /* little white lie */
406 img
->bitspersample
= 8;
408 case PHOTOMETRIC_CIELAB
:
411 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
412 photoTag
, img
->photometric
);
420 TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &img
->width
);
421 TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &img
->height
);
422 TIFFGetFieldDefaulted(tif
, TIFFTAG_ORIENTATION
, &img
->orientation
);
424 !(planarconfig
== PLANARCONFIG_SEPARATE
&& colorchannels
> 1);
426 img
->get
= TIFFIsTiled(tif
) ? gtTileContig
: gtStripContig
;
427 if (!pickTileContigCase(img
)) {
428 sprintf(emsg
, "Sorry, can not handle image");
432 img
->get
= TIFFIsTiled(tif
) ? gtTileSeparate
: gtStripSeparate
;
433 if (!pickTileSeparateCase(img
)) {
434 sprintf(emsg
, "Sorry, can not handle image");
442 TIFFRGBAImageGet(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
444 if (img
->get
== NULL
) {
445 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No \"get\" routine setup");
448 if (img
->put
.any
== NULL
) {
449 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
450 "No \"put\" routine setupl; probably can not handle image format");
453 return (*img
->get
)(img
, raster
, w
, h
);
457 * Read the specified image into an ABGR-format rastertaking in account
458 * specified orientation.
461 TIFFReadRGBAImageOriented(TIFF
* tif
,
462 uint32 rwidth
, uint32 rheight
, uint32
* raster
,
463 int orientation
, int stop
)
465 char emsg
[1024] = "";
469 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, stop
, emsg
)) {
470 img
.req_orientation
= orientation
;
471 /* XXX verify rwidth and rheight against width and height */
472 ok
= TIFFRGBAImageGet(&img
, raster
+(rheight
-img
.height
)*rwidth
,
474 TIFFRGBAImageEnd(&img
);
476 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), emsg
);
483 * Read the specified image into an ABGR-format raster. Use bottom left
484 * origin for raster by default.
487 TIFFReadRGBAImage(TIFF
* tif
,
488 uint32 rwidth
, uint32 rheight
, uint32
* raster
, int stop
)
490 return TIFFReadRGBAImageOriented(tif
, rwidth
, rheight
, raster
,
491 ORIENTATION_BOTLEFT
, stop
);
495 setorientation(TIFFRGBAImage
* img
)
497 switch (img
->orientation
) {
498 case ORIENTATION_TOPLEFT
:
499 case ORIENTATION_LEFTTOP
:
500 if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
501 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
502 return FLIP_HORIZONTALLY
;
503 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
504 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
505 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
506 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
507 img
->req_orientation
== ORIENTATION_LEFTBOT
)
508 return FLIP_VERTICALLY
;
511 case ORIENTATION_TOPRIGHT
:
512 case ORIENTATION_RIGHTTOP
:
513 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
514 img
->req_orientation
== ORIENTATION_LEFTTOP
)
515 return FLIP_HORIZONTALLY
;
516 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
517 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
518 return FLIP_VERTICALLY
;
519 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
520 img
->req_orientation
== ORIENTATION_LEFTBOT
)
521 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
524 case ORIENTATION_BOTRIGHT
:
525 case ORIENTATION_RIGHTBOT
:
526 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
527 img
->req_orientation
== ORIENTATION_LEFTTOP
)
528 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
529 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
530 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
531 return FLIP_VERTICALLY
;
532 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
533 img
->req_orientation
== ORIENTATION_LEFTBOT
)
534 return FLIP_HORIZONTALLY
;
537 case ORIENTATION_BOTLEFT
:
538 case ORIENTATION_LEFTBOT
:
539 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
540 img
->req_orientation
== ORIENTATION_LEFTTOP
)
541 return FLIP_VERTICALLY
;
542 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
543 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
544 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
545 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
546 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
547 return FLIP_HORIZONTALLY
;
550 default: /* NOTREACHED */
556 * Get an tile-organized image that has
557 * PlanarConfiguration contiguous if SamplesPerPixel > 1
559 * SamplesPerPixel == 1
562 gtTileContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
564 TIFF
* tif
= img
->tif
;
565 tileContigRoutine put
= img
->put
.contig
;
566 uint32 col
, row
, y
, rowstoread
;
570 int32 fromskew
, toskew
;
574 buf
= (unsigned char*) _TIFFmalloc(TIFFTileSize(tif
));
576 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for tile buffer");
579 _TIFFmemset(buf
, 0, TIFFTileSize(tif
));
580 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
581 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
583 flip
= setorientation(img
);
584 if (flip
& FLIP_VERTICALLY
) {
586 toskew
= -(int32
)(tw
+ w
);
590 toskew
= -(int32
)(tw
- w
);
593 for (row
= 0; row
< h
; row
+= nrow
)
595 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
596 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
597 for (col
= 0; col
< w
; col
+= tw
)
599 if (TIFFReadTile(tif
, buf
, col
+img
->col_offset
,
600 row
+img
->row_offset
, 0, 0) < 0 && img
->stoponerr
)
606 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
);
611 * Tile is clipped horizontally. Calculate
612 * visible portion and skewing factors.
614 uint32 npix
= w
- col
;
615 fromskew
= tw
- npix
;
616 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
617 npix
, nrow
, fromskew
, toskew
+ fromskew
, buf
+ pos
);
621 (*put
)(img
, raster
+y
*w
+col
, col
, y
, tw
, nrow
, 0, toskew
, buf
+ pos
);
625 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
629 if (flip
& FLIP_HORIZONTALLY
) {
632 for (line
= 0; line
< h
; line
++) {
633 uint32
*left
= raster
+ (line
* w
);
634 uint32
*right
= left
+ w
- 1;
636 while ( left
< right
) {
649 * Get an tile-organized image that has
650 * SamplesPerPixel > 1
651 * PlanarConfiguration separated
652 * We assume that all such images are RGB.
655 gtTileSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
657 TIFF
* tif
= img
->tif
;
658 tileSeparateRoutine put
= img
->put
.separate
;
659 uint32 col
, row
, y
, rowstoread
;
668 int32 fromskew
, toskew
;
669 int alpha
= img
->alpha
;
673 tilesize
= TIFFTileSize(tif
);
674 buf
= (unsigned char*) _TIFFmalloc(4*tilesize
);
676 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for tile buffer");
679 _TIFFmemset(buf
, 0, 4*tilesize
);
685 _TIFFmemset(a
, 0xff, tilesize
);
686 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
687 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
689 flip
= setorientation(img
);
690 if (flip
& FLIP_VERTICALLY
) {
692 toskew
= -(int32
)(tw
+ w
);
696 toskew
= -(int32
)(tw
- w
);
699 for (row
= 0; row
< h
; row
+= nrow
)
701 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
702 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
703 for (col
= 0; col
< w
; col
+= tw
)
705 if (TIFFReadTile(tif
, r
, col
+img
->col_offset
,
706 row
+img
->row_offset
,0,0) < 0 && img
->stoponerr
)
711 if (TIFFReadTile(tif
, g
, col
+img
->col_offset
,
712 row
+img
->row_offset
,0,1) < 0 && img
->stoponerr
)
717 if (TIFFReadTile(tif
, b
, col
+img
->col_offset
,
718 row
+img
->row_offset
,0,2) < 0 && img
->stoponerr
)
723 if (alpha
&& TIFFReadTile(tif
,a
,col
+img
->col_offset
,
724 row
+img
->row_offset
,0,3) < 0 && img
->stoponerr
)
730 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
);
735 * Tile is clipped horizontally. Calculate
736 * visible portion and skewing factors.
738 uint32 npix
= w
- col
;
739 fromskew
= tw
- npix
;
740 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
741 npix
, nrow
, fromskew
, toskew
+ fromskew
,
742 r
+ pos
, g
+ pos
, b
+ pos
, a
+ pos
);
744 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
745 tw
, nrow
, 0, toskew
, r
+ pos
, g
+ pos
, b
+ pos
, a
+ pos
);
749 y
+= (flip
& FLIP_VERTICALLY
?-(int32
) nrow
: (int32
) nrow
);
752 if (flip
& FLIP_HORIZONTALLY
) {
755 for (line
= 0; line
< h
; line
++) {
756 uint32
*left
= raster
+ (line
* w
);
757 uint32
*right
= left
+ w
- 1;
759 while ( left
< right
) {
773 * Get a strip-organized image that has
774 * PlanarConfiguration contiguous if SamplesPerPixel > 1
776 * SamplesPerPixel == 1
779 gtStripContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
781 TIFF
* tif
= img
->tif
;
782 tileContigRoutine put
= img
->put
.contig
;
783 uint32 row
, y
, nrow
, rowstoread
;
787 uint32 imagewidth
= img
->width
;
789 int32 fromskew
, toskew
;
792 buf
= (unsigned char*) _TIFFmalloc(TIFFStripSize(tif
));
794 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for strip buffer");
797 _TIFFmemset(buf
, 0, TIFFStripSize(tif
));
799 flip
= setorientation(img
);
800 if (flip
& FLIP_VERTICALLY
) {
802 toskew
= -(int32
)(w
+ w
);
805 toskew
= -(int32
)(w
- w
);
808 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
809 scanline
= TIFFScanlineSize(tif
);
810 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
811 for (row
= 0; row
< h
; row
+= nrow
)
813 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
814 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
815 if (TIFFReadEncodedStrip(tif
,
816 TIFFComputeStrip(tif
,row
+img
->row_offset
, 0),
818 ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
825 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
;
826 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, buf
+ pos
);
827 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
830 if (flip
& FLIP_HORIZONTALLY
) {
833 for (line
= 0; line
< h
; line
++) {
834 uint32
*left
= raster
+ (line
* w
);
835 uint32
*right
= left
+ w
- 1;
837 while ( left
< right
) {
851 * Get a strip-organized image with
852 * SamplesPerPixel > 1
853 * PlanarConfiguration separated
854 * We assume that all such images are RGB.
857 gtStripSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
859 TIFF
* tif
= img
->tif
;
860 tileSeparateRoutine put
= img
->put
.separate
;
862 unsigned char *r
, *g
, *b
, *a
;
863 uint32 row
, y
, nrow
, rowstoread
;
866 uint32 rowsperstrip
, offset_row
;
867 uint32 imagewidth
= img
->width
;
869 int32 fromskew
, toskew
;
870 int alpha
= img
->alpha
;
873 stripsize
= TIFFStripSize(tif
);
874 r
= buf
= (unsigned char *)_TIFFmalloc(4*stripsize
);
876 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for tile buffer");
879 _TIFFmemset(buf
, 0, 4*stripsize
);
884 _TIFFmemset(a
, 0xff, stripsize
);
886 flip
= setorientation(img
);
887 if (flip
& FLIP_VERTICALLY
) {
889 toskew
= -(int32
)(w
+ w
);
893 toskew
= -(int32
)(w
- w
);
896 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
897 scanline
= TIFFScanlineSize(tif
);
898 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
899 for (row
= 0; row
< h
; row
+= nrow
)
901 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
902 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
903 offset_row
= row
+ img
->row_offset
;
904 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 0),
905 r
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
911 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 1),
912 g
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
918 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 2),
919 b
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
926 (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 3),
927 a
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) < 0
934 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
;
935 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, r
+ pos
, g
+ pos
,
937 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
940 if (flip
& FLIP_HORIZONTALLY
) {
943 for (line
= 0; line
< h
; line
++) {
944 uint32
*left
= raster
+ (line
* w
);
945 uint32
*right
= left
+ w
- 1;
947 while ( left
< right
) {
961 * The following routines move decoded data returned
962 * from the TIFF library into rasters filled with packed
963 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
965 * The routines have been created according to the most
966 * important cases and optimized. pickTileContigCase and
967 * pickTileSeparateCase analyze the parameters and select
968 * the appropriate "put" routine to use.
970 #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
971 #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
972 #define REPEAT2(op) op; op
973 #define CASE8(x,op) \
975 case 7: op; case 6: op; case 5: op; \
976 case 4: op; case 3: op; case 2: op; \
979 #define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
982 #define UNROLL8(w, op1, op2) { \
984 for (_x = w; _x >= 8; _x -= 8) { \
993 #define UNROLL4(w, op1, op2) { \
995 for (_x = w; _x >= 4; _x -= 4) { \
1004 #define UNROLL2(w, op1, op2) { \
1006 for (_x = w; _x >= 2; _x -= 2) { \
1016 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1017 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1019 #define A1 (((uint32)0xffL)<<24)
1020 #define PACK(r,g,b) \
1021 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1022 #define PACK4(r,g,b,a) \
1023 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1024 #define W2B(v) (((v)>>8)&0xff)
1025 #define PACKW(r,g,b) \
1026 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1027 #define PACKW4(r,g,b,a) \
1028 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1030 #define DECLAREContigPutFunc(name) \
1032 TIFFRGBAImage* img, \
1034 uint32 x, uint32 y, \
1035 uint32 w, uint32 h, \
1036 int32 fromskew, int32 toskew, \
1041 * 8-bit palette => colormap/RGB
1043 DECLAREContigPutFunc(put8bitcmaptile
)
1045 uint32
** PALmap
= img
->PALmap
;
1046 int samplesperpixel
= img
->samplesperpixel
;
1050 for (x
= w
; x
-- > 0;)
1052 *cp
++ = PALmap
[*pp
][0];
1053 pp
+= samplesperpixel
;
1061 * 4-bit palette => colormap/RGB
1063 DECLAREContigPutFunc(put4bitcmaptile
)
1065 uint32
** PALmap
= img
->PALmap
;
1071 UNROLL2(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1078 * 2-bit palette => colormap/RGB
1080 DECLAREContigPutFunc(put2bitcmaptile
)
1082 uint32
** PALmap
= img
->PALmap
;
1088 UNROLL4(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1095 * 1-bit palette => colormap/RGB
1097 DECLAREContigPutFunc(put1bitcmaptile
)
1099 uint32
** PALmap
= img
->PALmap
;
1105 UNROLL8(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1112 * 8-bit greyscale => colormap/RGB
1114 DECLAREContigPutFunc(putgreytile
)
1116 int samplesperpixel
= img
->samplesperpixel
;
1117 uint32
** BWmap
= img
->BWmap
;
1121 for (x
= w
; x
-- > 0;)
1123 *cp
++ = BWmap
[*pp
][0];
1124 pp
+= samplesperpixel
;
1132 * 16-bit greyscale => colormap/RGB
1134 DECLAREContigPutFunc(put16bitbwtile
)
1136 int samplesperpixel
= img
->samplesperpixel
;
1137 uint32
** BWmap
= img
->BWmap
;
1141 uint16
*wp
= (uint16
*) pp
;
1143 for (x
= w
; x
-- > 0;)
1145 /* use high order byte of 16bit value */
1147 *cp
++ = BWmap
[*wp
>> 8][0];
1148 pp
+= 2 * samplesperpixel
;
1149 wp
+= samplesperpixel
;
1157 * 1-bit bilevel => colormap/RGB
1159 DECLAREContigPutFunc(put1bitbwtile
)
1161 uint32
** BWmap
= img
->BWmap
;
1167 UNROLL8(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1174 * 2-bit greyscale => colormap/RGB
1176 DECLAREContigPutFunc(put2bitbwtile
)
1178 uint32
** BWmap
= img
->BWmap
;
1184 UNROLL4(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1191 * 4-bit greyscale => colormap/RGB
1193 DECLAREContigPutFunc(put4bitbwtile
)
1195 uint32
** BWmap
= img
->BWmap
;
1201 UNROLL2(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1208 * 8-bit packed samples, no Map => RGB
1210 DECLAREContigPutFunc(putRGBcontig8bittile
)
1212 int samplesperpixel
= img
->samplesperpixel
;
1215 fromskew
*= samplesperpixel
;
1218 *cp
++ = PACK(pp
[0], pp
[1], pp
[2]);
1219 pp
+= samplesperpixel
);
1226 * 8-bit packed samples, w/ Map => RGB
1228 DECLAREContigPutFunc(putRGBcontig8bitMaptile
)
1230 TIFFRGBValue
* Map
= img
->Map
;
1231 int samplesperpixel
= img
->samplesperpixel
;
1234 fromskew
*= samplesperpixel
;
1236 for (x
= w
; x
-- > 0;) {
1237 *cp
++ = PACK(Map
[pp
[0]], Map
[pp
[1]], Map
[pp
[2]]);
1238 pp
+= samplesperpixel
;
1246 * 8-bit packed samples => RGBA w/ associated alpha
1247 * (known to have Map == NULL)
1249 DECLAREContigPutFunc(putRGBAAcontig8bittile
)
1251 int samplesperpixel
= img
->samplesperpixel
;
1254 fromskew
*= samplesperpixel
;
1257 *cp
++ = PACK4(pp
[0], pp
[1], pp
[2], pp
[3]);
1258 pp
+= samplesperpixel
);
1265 * 8-bit packed samples => RGBA w/ unassociated alpha
1266 * (known to have Map == NULL)
1268 DECLAREContigPutFunc(putRGBUAcontig8bittile
)
1270 int samplesperpixel
= img
->samplesperpixel
;
1273 fromskew
*= samplesperpixel
;
1276 for (x
= w
; x
-- > 0;) {
1278 r
= (pp
[0] * a
) / 255;
1279 g
= (pp
[1] * a
) / 255;
1280 b
= (pp
[2] * a
) / 255;
1281 *cp
++ = PACK4(r
,g
,b
,a
);
1282 pp
+= samplesperpixel
;
1290 * 16-bit packed samples => RGB
1292 DECLAREContigPutFunc(putRGBcontig16bittile
)
1294 int samplesperpixel
= img
->samplesperpixel
;
1295 uint16
*wp
= (uint16
*)pp
;
1298 fromskew
*= samplesperpixel
;
1300 for (x
= w
; x
-- > 0;) {
1301 *cp
++ = PACKW(wp
[0], wp
[1], wp
[2]);
1302 wp
+= samplesperpixel
;
1310 * 16-bit packed samples => RGBA w/ associated alpha
1311 * (known to have Map == NULL)
1313 DECLAREContigPutFunc(putRGBAAcontig16bittile
)
1315 int samplesperpixel
= img
->samplesperpixel
;
1316 uint16
*wp
= (uint16
*)pp
;
1319 fromskew
*= samplesperpixel
;
1321 for (x
= w
; x
-- > 0;) {
1322 *cp
++ = PACKW4(wp
[0], wp
[1], wp
[2], wp
[3]);
1323 wp
+= samplesperpixel
;
1331 * 16-bit packed samples => RGBA w/ unassociated alpha
1332 * (known to have Map == NULL)
1334 DECLAREContigPutFunc(putRGBUAcontig16bittile
)
1336 int samplesperpixel
= img
->samplesperpixel
;
1337 uint16
*wp
= (uint16
*)pp
;
1340 fromskew
*= samplesperpixel
;
1344 * We shift alpha down four bits just in case unsigned
1345 * arithmetic doesn't handle the full range.
1346 * We still have plenty of accuracy, since the output is 8 bits.
1347 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1348 * Since we want r*a * 0xff for eight bit output,
1349 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1351 for (x
= w
; x
-- > 0;) {
1353 r
= (wp
[0] * a
) / 0x10eff;
1354 g
= (wp
[1] * a
) / 0x10eff;
1355 b
= (wp
[2] * a
) / 0x10eff;
1356 *cp
++ = PACK4(r
,g
,b
,a
);
1357 wp
+= samplesperpixel
;
1365 * 8-bit packed CMYK samples w/o Map => RGB
1367 * NB: The conversion of CMYK->RGB is *very* crude.
1369 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile
)
1371 int samplesperpixel
= img
->samplesperpixel
;
1375 fromskew
*= samplesperpixel
;
1379 r
= (k
*(255-pp
[0]))/255;
1380 g
= (k
*(255-pp
[1]))/255;
1381 b
= (k
*(255-pp
[2]))/255;
1382 *cp
++ = PACK(r
, g
, b
);
1383 pp
+= samplesperpixel
);
1390 * 8-bit packed CMYK samples w/Map => RGB
1392 * NB: The conversion of CMYK->RGB is *very* crude.
1394 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile
)
1396 int samplesperpixel
= img
->samplesperpixel
;
1397 TIFFRGBValue
* Map
= img
->Map
;
1401 fromskew
*= samplesperpixel
;
1403 for (x
= w
; x
-- > 0;) {
1405 r
= (k
*(255-pp
[0]))/255;
1406 g
= (k
*(255-pp
[1]))/255;
1407 b
= (k
*(255-pp
[2]))/255;
1408 *cp
++ = PACK(Map
[r
], Map
[g
], Map
[b
]);
1409 pp
+= samplesperpixel
;
1416 #define DECLARESepPutFunc(name) \
1418 TIFFRGBAImage* img,\
1420 uint32 x, uint32 y, \
1421 uint32 w, uint32 h,\
1422 int32 fromskew, int32 toskew,\
1423 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1427 * 8-bit unpacked samples => RGB
1429 DECLARESepPutFunc(putRGBseparate8bittile
)
1431 (void) img
; (void) x
; (void) y
; (void) a
;
1433 UNROLL8(w
, NOP
, *cp
++ = PACK(*r
++, *g
++, *b
++));
1434 SKEW(r
, g
, b
, fromskew
);
1440 * 8-bit unpacked samples => RGB
1442 DECLARESepPutFunc(putRGBseparate8bitMaptile
)
1444 TIFFRGBValue
* Map
= img
->Map
;
1448 for (x
= w
; x
> 0; x
--)
1449 *cp
++ = PACK(Map
[*r
++], Map
[*g
++], Map
[*b
++]);
1450 SKEW(r
, g
, b
, fromskew
);
1456 * 8-bit unpacked samples => RGBA w/ associated alpha
1458 DECLARESepPutFunc(putRGBAAseparate8bittile
)
1460 (void) img
; (void) x
; (void) y
;
1462 UNROLL8(w
, NOP
, *cp
++ = PACK4(*r
++, *g
++, *b
++, *a
++));
1463 SKEW4(r
, g
, b
, a
, fromskew
);
1469 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1471 DECLARESepPutFunc(putRGBUAseparate8bittile
)
1473 (void) img
; (void) y
;
1475 uint32 rv
, gv
, bv
, av
;
1476 for (x
= w
; x
-- > 0;) {
1478 rv
= (*r
++ * av
) / 255;
1479 gv
= (*g
++ * av
) / 255;
1480 bv
= (*b
++ * av
) / 255;
1481 *cp
++ = PACK4(rv
,gv
,bv
,av
);
1483 SKEW4(r
, g
, b
, a
, fromskew
);
1489 * 16-bit unpacked samples => RGB
1491 DECLARESepPutFunc(putRGBseparate16bittile
)
1493 uint16
*wr
= (uint16
*) r
;
1494 uint16
*wg
= (uint16
*) g
;
1495 uint16
*wb
= (uint16
*) b
;
1497 (void) img
; (void) y
; (void) a
;
1499 for (x
= 0; x
< w
; x
++)
1500 *cp
++ = PACKW(*wr
++, *wg
++, *wb
++);
1501 SKEW(wr
, wg
, wb
, fromskew
);
1507 * 16-bit unpacked samples => RGBA w/ associated alpha
1509 DECLARESepPutFunc(putRGBAAseparate16bittile
)
1511 uint16
*wr
= (uint16
*) r
;
1512 uint16
*wg
= (uint16
*) g
;
1513 uint16
*wb
= (uint16
*) b
;
1514 uint16
*wa
= (uint16
*) a
;
1516 (void) img
; (void) y
;
1518 for (x
= 0; x
< w
; x
++)
1519 *cp
++ = PACKW4(*wr
++, *wg
++, *wb
++, *wa
++);
1520 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1526 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1528 DECLARESepPutFunc(putRGBUAseparate16bittile
)
1530 uint16
*wr
= (uint16
*) r
;
1531 uint16
*wg
= (uint16
*) g
;
1532 uint16
*wb
= (uint16
*) b
;
1533 uint16
*wa
= (uint16
*) a
;
1535 (void) img
; (void) y
;
1539 * We shift alpha down four bits just in case unsigned
1540 * arithmetic doesn't handle the full range.
1541 * We still have plenty of accuracy, since the output is 8 bits.
1542 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1543 * Since we want r*a * 0xff for eight bit output,
1544 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1546 for (x
= w
; x
-- > 0;) {
1548 r
= (*wr
++ * a
) / 0x10eff;
1549 g
= (*wg
++ * a
) / 0x10eff;
1550 b
= (*wb
++ * a
) / 0x10eff;
1551 *cp
++ = PACK4(r
,g
,b
,a
);
1553 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1559 * 8-bit packed CIE L*a*b 1976 samples => RGB
1561 DECLAREContigPutFunc(putcontig8bitCIELab
)
1568 for (x
= w
; x
-- > 0;) {
1569 TIFFCIELabToXYZ(img
->cielab
,
1570 (unsigned char)pp
[0],
1574 TIFFXYZToRGB(img
->cielab
, X
, Y
, Z
, &r
, &g
, &b
);
1575 *cp
++ = PACK(r
, g
, b
);
1584 * YCbCr -> RGB conversion and packing routines.
1587 #define YCbCrtoRGB(dst, Y) { \
1589 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1590 dst = PACK(r, g, b); \
1594 * 8-bit packed YCbCr samples => RGB
1595 * This function is generic for different sampling sizes,
1596 * and can handle blocks sizes that aren't multiples of the
1597 * sampling size. However, it is substantially less optimized
1598 * than the specific sampling cases. It is used as a fallback
1599 * for difficult blocks.
1602 static void putcontig8bitYCbCrGenericTile(
1607 int32 fromskew
, int32 toskew
,
1613 uint32
* cp1
= cp
+w
+toskew
;
1614 uint32
* cp2
= cp1
+w
+toskew
;
1615 uint32
* cp3
= cp2
+w
+toskew
;
1616 int32 incr
= 3*w
+4*toskew
;
1618 int group_size
= v_group
* h_group
+ 2;
1621 fromskew
= (fromskew
* group_size
) / h_group
;
1623 for( yy
= 0; yy
< h
; yy
++ )
1625 unsigned char *pp_line
;
1626 int y_line_group
= yy
/ v_group
;
1627 int y_remainder
= yy
- y_line_group
* v_group
;
1629 pp_line
= pp
+ v_line_group
*
1632 for( xx
= 0; xx
< w
; xx
++ )
1637 for (; h
>= 4; h
-= 4) {
1643 YCbCrtoRGB(cp
[0], pp
[ 0]);
1644 YCbCrtoRGB(cp
[1], pp
[ 1]);
1645 YCbCrtoRGB(cp
[2], pp
[ 2]);
1646 YCbCrtoRGB(cp
[3], pp
[ 3]);
1647 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1648 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1649 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1650 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1651 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1652 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1653 YCbCrtoRGB(cp2
[2], pp
[10]);
1654 YCbCrtoRGB(cp2
[3], pp
[11]);
1655 YCbCrtoRGB(cp3
[0], pp
[12]);
1656 YCbCrtoRGB(cp3
[1], pp
[13]);
1657 YCbCrtoRGB(cp3
[2], pp
[14]);
1658 YCbCrtoRGB(cp3
[3], pp
[15]);
1660 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1663 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1670 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1672 DECLAREContigPutFunc(putcontig8bitYCbCr44tile
)
1674 uint32
* cp1
= cp
+w
+toskew
;
1675 uint32
* cp2
= cp1
+w
+toskew
;
1676 uint32
* cp3
= cp2
+w
+toskew
;
1677 int32 incr
= 3*w
+4*toskew
;
1680 /* adjust fromskew */
1681 fromskew
= (fromskew
* 18) / 4;
1682 if ((h
& 3) == 0 && (w
& 3) == 0) {
1683 for (; h
>= 4; h
-= 4) {
1689 YCbCrtoRGB(cp
[0], pp
[ 0]);
1690 YCbCrtoRGB(cp
[1], pp
[ 1]);
1691 YCbCrtoRGB(cp
[2], pp
[ 2]);
1692 YCbCrtoRGB(cp
[3], pp
[ 3]);
1693 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1694 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1695 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1696 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1697 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1698 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1699 YCbCrtoRGB(cp2
[2], pp
[10]);
1700 YCbCrtoRGB(cp2
[3], pp
[11]);
1701 YCbCrtoRGB(cp3
[0], pp
[12]);
1702 YCbCrtoRGB(cp3
[1], pp
[13]);
1703 YCbCrtoRGB(cp3
[2], pp
[14]);
1704 YCbCrtoRGB(cp3
[3], pp
[15]);
1706 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1709 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1714 for (x
= w
; x
> 0;) {
1720 default: YCbCrtoRGB(cp3
[3], pp
[15]); /* FALLTHROUGH */
1721 case 3: YCbCrtoRGB(cp2
[3], pp
[11]); /* FALLTHROUGH */
1722 case 2: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1723 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1727 default: YCbCrtoRGB(cp3
[2], pp
[14]); /* FALLTHROUGH */
1728 case 3: YCbCrtoRGB(cp2
[2], pp
[10]); /* FALLTHROUGH */
1729 case 2: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1730 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1734 default: YCbCrtoRGB(cp3
[1], pp
[13]); /* FALLTHROUGH */
1735 case 3: YCbCrtoRGB(cp2
[1], pp
[ 9]); /* FALLTHROUGH */
1736 case 2: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1737 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1741 default: YCbCrtoRGB(cp3
[0], pp
[12]); /* FALLTHROUGH */
1742 case 3: YCbCrtoRGB(cp2
[0], pp
[ 8]); /* FALLTHROUGH */
1743 case 2: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1744 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1748 cp
+= x
; cp1
+= x
; cp2
+= x
; cp3
+= x
;
1752 cp
+= 4; cp1
+= 4; cp2
+= 4; cp3
+= 4;
1760 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1767 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1769 DECLAREContigPutFunc(putcontig8bitYCbCr42tile
)
1771 uint32
* cp1
= cp
+w
+toskew
;
1772 int32 incr
= 2*toskew
+w
;
1775 fromskew
= (fromskew
* 10) / 4;
1776 if ((h
& 3) == 0 && (w
& 1) == 0) {
1777 for (; h
>= 2; h
-= 2) {
1783 YCbCrtoRGB(cp
[0], pp
[0]);
1784 YCbCrtoRGB(cp
[1], pp
[1]);
1785 YCbCrtoRGB(cp
[2], pp
[2]);
1786 YCbCrtoRGB(cp
[3], pp
[3]);
1787 YCbCrtoRGB(cp1
[0], pp
[4]);
1788 YCbCrtoRGB(cp1
[1], pp
[5]);
1789 YCbCrtoRGB(cp1
[2], pp
[6]);
1790 YCbCrtoRGB(cp1
[3], pp
[7]);
1795 cp
+= incr
, cp1
+= incr
;
1800 for (x
= w
; x
> 0;) {
1806 default: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1807 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1811 default: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1812 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1816 default: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1817 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1821 default: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1822 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1838 cp
+= incr
, cp1
+= incr
;
1845 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1847 DECLAREContigPutFunc(putcontig8bitYCbCr41tile
)
1850 /* XXX adjust fromskew */
1857 YCbCrtoRGB(cp
[0], pp
[0]);
1858 YCbCrtoRGB(cp
[1], pp
[1]);
1859 YCbCrtoRGB(cp
[2], pp
[2]);
1860 YCbCrtoRGB(cp
[3], pp
[3]);
1872 case 3: YCbCrtoRGB(cp
[2], pp
[2]);
1873 case 2: YCbCrtoRGB(cp
[1], pp
[1]);
1874 case 1: YCbCrtoRGB(cp
[0], pp
[0]);
1889 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1891 DECLAREContigPutFunc(putcontig8bitYCbCr22tile
)
1893 uint32
* cp1
= cp
+w
+toskew
;
1894 int32 incr
= 2*toskew
+w
;
1897 fromskew
= (fromskew
* 6) / 2;
1898 if ((h
& 1) == 0 && (w
& 1) == 0) {
1899 for (; h
>= 2; h
-= 2) {
1905 YCbCrtoRGB(cp
[0], pp
[0]);
1906 YCbCrtoRGB(cp
[1], pp
[1]);
1907 YCbCrtoRGB(cp1
[0], pp
[2]);
1908 YCbCrtoRGB(cp1
[1], pp
[3]);
1913 cp
+= incr
, cp1
+= incr
;
1918 for (x
= w
; x
> 0;) {
1924 default: YCbCrtoRGB(cp1
[1], pp
[ 3]); /* FALLTHROUGH */
1925 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1929 default: YCbCrtoRGB(cp1
[0], pp
[ 2]); /* FALLTHROUGH */
1930 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1946 cp
+= incr
, cp1
+= incr
;
1953 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
1955 DECLAREContigPutFunc(putcontig8bitYCbCr21tile
)
1958 fromskew
= (fromskew
* 4) / 2;
1965 YCbCrtoRGB(cp
[0], pp
[0]);
1966 YCbCrtoRGB(cp
[1], pp
[1]);
1977 YCbCrtoRGB(cp
[0], pp
[0]);
1989 * 8-bit packed YCbCr samples w/ no subsampling => RGB
1991 DECLAREContigPutFunc(putcontig8bitYCbCr11tile
)
1996 x
= w
; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
2001 YCbCrtoRGB(*cp
++, pp
[0]);
2011 static tileContigRoutine
2012 initYCbCrConversion(TIFFRGBAImage
* img
)
2014 static char module[] = "initCIELabConversion";
2016 float *luma
, *refBlackWhite
;
2019 if (img
->ycbcr
== NULL
) {
2020 img
->ycbcr
= (TIFFYCbCrToRGB
*) _TIFFmalloc(
2021 TIFFroundup(sizeof (TIFFYCbCrToRGB
), sizeof (long))
2022 + 4*256*sizeof (TIFFRGBValue
)
2023 + 2*256*sizeof (int)
2024 + 3*256*sizeof (int32
)
2026 if (img
->ycbcr
== NULL
) {
2027 TIFFErrorExt(img
->tif
->tif_clientdata
, module,
2028 "No space for YCbCr->RGB conversion state");
2033 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRCOEFFICIENTS
, &luma
);
2034 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_REFERENCEBLACKWHITE
,
2036 if (TIFFYCbCrToRGBInit(img
->ycbcr
, luma
, refBlackWhite
) < 0)
2040 * The 6.0 spec says that subsampling must be
2041 * one of 1, 2, or 4, and that vertical subsampling
2042 * must always be <= horizontal subsampling; so
2043 * there are only a few possibilities and we just
2044 * enumerate the cases.
2046 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &hs
, &vs
);
2047 switch ((hs
<<4)|vs
) {
2048 case 0x44: return &putcontig8bitYCbCr44tile
;
2049 case 0x42: return &putcontig8bitYCbCr42tile
;
2050 case 0x41: return &putcontig8bitYCbCr41tile
;
2051 case 0x22: return &putcontig8bitYCbCr22tile
;
2052 case 0x21: return &putcontig8bitYCbCr21tile
;
2053 case 0x11: return &putcontig8bitYCbCr11tile
;
2059 static tileContigRoutine
2060 initCIELabConversion(TIFFRGBAImage
* img
)
2062 static char module[] = "initCIELabConversion";
2068 img
->cielab
= (TIFFCIELabToRGB
*)
2069 _TIFFmalloc(sizeof(TIFFCIELabToRGB
));
2071 TIFFErrorExt(img
->tif
->tif_clientdata
, module,
2072 "No space for CIE L*a*b*->RGB conversion state.");
2077 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_WHITEPOINT
, &whitePoint
);
2078 refWhite
[1] = 100.0F
;
2079 refWhite
[0] = whitePoint
[0] / whitePoint
[1] * refWhite
[1];
2080 refWhite
[2] = (1.0F
- whitePoint
[0] - whitePoint
[1])
2081 / whitePoint
[1] * refWhite
[1];
2082 if (TIFFCIELabToRGBInit(img
->cielab
, &display_sRGB
, refWhite
) < 0) {
2083 TIFFErrorExt(img
->tif
->tif_clientdata
, module,
2084 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2085 _TIFFfree(img
->cielab
);
2089 return &putcontig8bitCIELab
;
2093 * Greyscale images with less than 8 bits/sample are handled
2094 * with a table to avoid lots of shifts and masks. The table
2095 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2096 * pixel values simply by indexing into the table with one
2100 makebwmap(TIFFRGBAImage
* img
)
2102 TIFFRGBValue
* Map
= img
->Map
;
2103 int bitspersample
= img
->bitspersample
;
2104 int nsamples
= 8 / bitspersample
;
2111 img
->BWmap
= (uint32
**) _TIFFmalloc(
2112 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2113 if (img
->BWmap
== NULL
) {
2114 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for B&W mapping table");
2117 p
= (uint32
*)(img
->BWmap
+ 256);
2118 for (i
= 0; i
< 256; i
++) {
2121 switch (bitspersample
) {
2122 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2154 * Construct a mapping table to convert from the range
2155 * of the data samples to [0,255] --for display. This
2156 * process also handles inverting B&W images when needed.
2159 setupMap(TIFFRGBAImage
* img
)
2163 range
= (int32
)((1L<<img
->bitspersample
)-1);
2165 /* treat 16 bit the same as eight bit */
2166 if( img
->bitspersample
== 16 )
2167 range
= (int32
) 255;
2169 img
->Map
= (TIFFRGBValue
*) _TIFFmalloc((range
+1) * sizeof (TIFFRGBValue
));
2170 if (img
->Map
== NULL
) {
2171 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
2172 "No space for photometric conversion table");
2175 if (img
->photometric
== PHOTOMETRIC_MINISWHITE
) {
2176 for (x
= 0; x
<= range
; x
++)
2177 img
->Map
[x
] = (TIFFRGBValue
) (((range
- x
) * 255) / range
);
2179 for (x
= 0; x
<= range
; x
++)
2180 img
->Map
[x
] = (TIFFRGBValue
) ((x
* 255) / range
);
2182 if (img
->bitspersample
<= 16 &&
2183 (img
->photometric
== PHOTOMETRIC_MINISBLACK
||
2184 img
->photometric
== PHOTOMETRIC_MINISWHITE
)) {
2186 * Use photometric mapping table to construct
2187 * unpacking tables for samples <= 8 bits.
2189 if (!makebwmap(img
))
2191 /* no longer need Map, free it */
2192 _TIFFfree(img
->Map
), img
->Map
= NULL
;
2198 checkcmap(TIFFRGBAImage
* img
)
2200 uint16
* r
= img
->redcmap
;
2201 uint16
* g
= img
->greencmap
;
2202 uint16
* b
= img
->bluecmap
;
2203 long n
= 1L<<img
->bitspersample
;
2206 if (*r
++ >= 256 || *g
++ >= 256 || *b
++ >= 256)
2212 cvtcmap(TIFFRGBAImage
* img
)
2214 uint16
* r
= img
->redcmap
;
2215 uint16
* g
= img
->greencmap
;
2216 uint16
* b
= img
->bluecmap
;
2219 for (i
= (1L<<img
->bitspersample
)-1; i
>= 0; i
--) {
2220 #define CVT(x) ((uint16)((x)>>8))
2229 * Palette images with <= 8 bits/sample are handled
2230 * with a table to avoid lots of shifts and masks. The table
2231 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2232 * pixel values simply by indexing into the table with one
2236 makecmap(TIFFRGBAImage
* img
)
2238 int bitspersample
= img
->bitspersample
;
2239 int nsamples
= 8 / bitspersample
;
2240 uint16
* r
= img
->redcmap
;
2241 uint16
* g
= img
->greencmap
;
2242 uint16
* b
= img
->bluecmap
;
2246 img
->PALmap
= (uint32
**) _TIFFmalloc(
2247 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2248 if (img
->PALmap
== NULL
) {
2249 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for Palette mapping table");
2252 p
= (uint32
*)(img
->PALmap
+ 256);
2253 for (i
= 0; i
< 256; i
++) {
2256 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2257 switch (bitspersample
) {
2288 * Construct any mapping table used
2289 * by the associated put routine.
2292 buildMap(TIFFRGBAImage
* img
)
2294 switch (img
->photometric
) {
2295 case PHOTOMETRIC_RGB
:
2296 case PHOTOMETRIC_YCBCR
:
2297 case PHOTOMETRIC_SEPARATED
:
2298 if (img
->bitspersample
== 8)
2301 case PHOTOMETRIC_MINISBLACK
:
2302 case PHOTOMETRIC_MINISWHITE
:
2306 case PHOTOMETRIC_PALETTE
:
2308 * Convert 16-bit colormap to 8-bit (unless it looks
2309 * like an old-style 8-bit colormap).
2311 if (checkcmap(img
) == 16)
2314 TIFFWarningExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "Assuming 8-bit colormap");
2316 * Use mapping table and colormap to construct
2317 * unpacking tables for samples < 8 bits.
2319 if (img
->bitspersample
<= 8 && !makecmap(img
))
2327 * Select the appropriate conversion routine for packed data.
2330 pickTileContigCase(TIFFRGBAImage
* img
)
2332 tileContigRoutine put
= 0;
2334 if (buildMap(img
)) {
2335 switch (img
->photometric
) {
2336 case PHOTOMETRIC_RGB
:
2337 switch (img
->bitspersample
) {
2340 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2341 put
= putRGBAAcontig8bittile
;
2342 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2343 put
= putRGBUAcontig8bittile
;
2345 put
= putRGBcontig8bittile
;
2347 put
= putRGBcontig8bitMaptile
;
2350 put
= putRGBcontig16bittile
;
2352 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2353 put
= putRGBAAcontig16bittile
;
2354 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2355 put
= putRGBUAcontig16bittile
;
2360 case PHOTOMETRIC_SEPARATED
:
2361 if (img
->bitspersample
== 8) {
2363 put
= putRGBcontig8bitCMYKtile
;
2365 put
= putRGBcontig8bitCMYKMaptile
;
2368 case PHOTOMETRIC_PALETTE
:
2369 switch (img
->bitspersample
) {
2370 case 8: put
= put8bitcmaptile
; break;
2371 case 4: put
= put4bitcmaptile
; break;
2372 case 2: put
= put2bitcmaptile
; break;
2373 case 1: put
= put1bitcmaptile
; break;
2376 case PHOTOMETRIC_MINISWHITE
:
2377 case PHOTOMETRIC_MINISBLACK
:
2378 switch (img
->bitspersample
) {
2379 case 16: put
= put16bitbwtile
; break;
2380 case 8: put
= putgreytile
; break;
2381 case 4: put
= put4bitbwtile
; break;
2382 case 2: put
= put2bitbwtile
; break;
2383 case 1: put
= put1bitbwtile
; break;
2386 case PHOTOMETRIC_YCBCR
:
2387 if (img
->bitspersample
== 8)
2388 put
= initYCbCrConversion(img
);
2390 case PHOTOMETRIC_CIELAB
:
2391 if (img
->bitspersample
== 8)
2392 put
= initCIELabConversion(img
);
2396 return ((img
->put
.contig
= put
) != 0);
2400 * Select the appropriate conversion routine for unpacked data.
2402 * NB: we assume that unpacked single channel data is directed
2403 * to the "packed routines.
2406 pickTileSeparateCase(TIFFRGBAImage
* img
)
2408 tileSeparateRoutine put
= 0;
2410 if (buildMap(img
)) {
2411 switch (img
->photometric
) {
2412 case PHOTOMETRIC_RGB
:
2413 switch (img
->bitspersample
) {
2416 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2417 put
= putRGBAAseparate8bittile
;
2418 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2419 put
= putRGBUAseparate8bittile
;
2421 put
= putRGBseparate8bittile
;
2423 put
= putRGBseparate8bitMaptile
;
2426 put
= putRGBseparate16bittile
;
2428 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2429 put
= putRGBAAseparate16bittile
;
2430 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2431 put
= putRGBUAseparate16bittile
;
2438 return ((img
->put
.separate
= put
) != 0);
2442 * Read a whole strip off data from the file, and convert to RGBA form.
2443 * If this is the last strip, then it will only contain the portion of
2444 * the strip that is actually within the image space. The result is
2445 * organized in bottom to top form.
2450 TIFFReadRGBAStrip(TIFF
* tif
, uint32 row
, uint32
* raster
)
2453 char emsg
[1024] = "";
2456 uint32 rowsperstrip
, rows_to_read
;
2458 if( TIFFIsTiled( tif
) )
2460 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2461 "Can't use TIFFReadRGBAStrip() with tiled file.");
2465 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
2466 if( (row
% rowsperstrip
) != 0 )
2468 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2469 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2473 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) {
2475 img
.row_offset
= row
;
2478 if( row
+ rowsperstrip
> img
.height
)
2479 rows_to_read
= img
.height
- row
;
2481 rows_to_read
= rowsperstrip
;
2483 ok
= TIFFRGBAImageGet(&img
, raster
, img
.width
, rows_to_read
);
2485 TIFFRGBAImageEnd(&img
);
2487 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), emsg
);
2495 * Read a whole tile off data from the file, and convert to RGBA form.
2496 * The returned RGBA data is organized from bottom to top of tile,
2497 * and may include zeroed areas if the tile extends off the image.
2501 TIFFReadRGBATile(TIFF
* tif
, uint32 col
, uint32 row
, uint32
* raster
)
2504 char emsg
[1024] = "";
2507 uint32 tile_xsize
, tile_ysize
;
2508 uint32 read_xsize
, read_ysize
;
2512 * Verify that our request is legal - on a tile file, and on a
2516 if( !TIFFIsTiled( tif
) )
2518 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2519 "Can't use TIFFReadRGBATile() with stripped file.");
2523 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILEWIDTH
, &tile_xsize
);
2524 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILELENGTH
, &tile_ysize
);
2525 if( (col
% tile_xsize
) != 0 || (row
% tile_ysize
) != 0 )
2527 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2528 "Row/col passed to TIFFReadRGBATile() must be top"
2529 "left corner of a tile.");
2534 * Setup the RGBA reader.
2537 if (!TIFFRGBAImageOK(tif
, emsg
)
2538 || !TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) {
2539 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), emsg
);
2544 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2545 * edge of the image, even to fill an otherwise valid tile. So we
2546 * figure out how much we can read, and fix up the tile buffer to
2547 * a full tile configuration afterwards.
2550 if( row
+ tile_ysize
> img
.height
)
2551 read_ysize
= img
.height
- row
;
2553 read_ysize
= tile_ysize
;
2555 if( col
+ tile_xsize
> img
.width
)
2556 read_xsize
= img
.width
- col
;
2558 read_xsize
= tile_xsize
;
2561 * Read the chunk of imagery.
2564 img
.row_offset
= row
;
2565 img
.col_offset
= col
;
2567 ok
= TIFFRGBAImageGet(&img
, raster
, read_xsize
, read_ysize
);
2569 TIFFRGBAImageEnd(&img
);
2572 * If our read was incomplete we will need to fix up the tile by
2573 * shifting the data around as if a full tile of data is being returned.
2575 * This is all the more complicated because the image is organized in
2576 * bottom to top format.
2579 if( read_xsize
== tile_xsize
&& read_ysize
== tile_ysize
)
2582 for( i_row
= 0; i_row
< read_ysize
; i_row
++ ) {
2583 memmove( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
2584 raster
+ (read_ysize
- i_row
- 1) * read_xsize
,
2585 read_xsize
* sizeof(uint32
) );
2586 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
+read_xsize
,
2587 0, sizeof(uint32
) * (tile_xsize
- read_xsize
) );
2590 for( i_row
= read_ysize
; i_row
< tile_ysize
; i_row
++ ) {
2591 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
2592 0, sizeof(uint32
) * tile_xsize
);
2598 /* vim: set ts=8 sts=8 sw=8 noet: */