3 * Copyright (c) 1991-1997 Sam Leffler
4 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 * Permission to use, copy, modify, distribute, and sell this software and
7 * its documentation for any purpose is hereby granted without fee, provided
8 * that (i) the above copyright notices and this permission notice appear in
9 * all copies of the software and related documentation, and (ii) the names of
10 * Sam Leffler and Silicon Graphics may not be used in any advertising or
11 * publicity relating to the software without the specific, prior written
12 * permission of Sam Leffler and Silicon Graphics.
14 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
15 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
16 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
19 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
20 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
21 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
22 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
29 * Read and return a packed RGBA image.
34 static int gtTileContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
35 static int gtTileSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
36 static int gtStripContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
37 static int gtStripSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
);
38 static int PickContigCase(TIFFRGBAImage
*);
39 static int PickSeparateCase(TIFFRGBAImage
*);
41 static int BuildMapUaToAa(TIFFRGBAImage
* img
);
42 static int BuildMapBitdepth16To8(TIFFRGBAImage
* img
);
44 static const char photoTag
[] = "PhotometricInterpretation";
47 * Helper constants used in Orientation tag handling
49 #define FLIP_VERTICALLY 0x01
50 #define FLIP_HORIZONTALLY 0x02
53 * Color conversion constants. We will define display types here.
56 static const TIFFDisplay display_sRGB
= {
57 { /* XYZ -> luminance matrix */
58 { 3.2410F
, -1.5374F
, -0.4986F
},
59 { -0.9692F
, 1.8760F
, 0.0416F
},
60 { 0.0556F
, -0.2040F
, 1.0570F
}
62 100.0F
, 100.0F
, 100.0F
, /* Light o/p for reference white */
63 255, 255, 255, /* Pixel values for ref. white */
64 1.0F
, 1.0F
, 1.0F
, /* Residual light o/p for black pixel */
65 2.4F
, 2.4F
, 2.4F
, /* Gamma values for the three guns */
69 * Check the image to see if TIFFReadRGBAImage can deal with it.
70 * 1/0 is returned according to whether or not the image can
71 * be handled. If 0 is returned, emsg contains the reason
72 * why it is being rejected.
75 TIFFRGBAImageOK(TIFF
* tif
, char emsg
[1024])
77 TIFFDirectory
* td
= &tif
->tif_dir
;
81 if (!tif
->tif_decodestatus
) {
82 sprintf(emsg
, "Sorry, requested compression method is not configured");
85 switch (td
->td_bitspersample
) {
93 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
94 td
->td_bitspersample
);
97 colorchannels
= td
->td_samplesperpixel
- td
->td_extrasamples
;
98 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &photometric
)) {
99 switch (colorchannels
) {
101 photometric
= PHOTOMETRIC_MINISBLACK
;
104 photometric
= PHOTOMETRIC_RGB
;
107 sprintf(emsg
, "Missing needed %s tag", photoTag
);
111 switch (photometric
) {
112 case PHOTOMETRIC_MINISWHITE
:
113 case PHOTOMETRIC_MINISBLACK
:
114 case PHOTOMETRIC_PALETTE
:
115 if (td
->td_planarconfig
== PLANARCONFIG_CONTIG
116 && td
->td_samplesperpixel
!= 1
117 && td
->td_bitspersample
< 8 ) {
119 "Sorry, can not handle contiguous data with %s=%d, "
120 "and %s=%d and Bits/Sample=%d",
121 photoTag
, photometric
,
122 "Samples/pixel", td
->td_samplesperpixel
,
123 td
->td_bitspersample
);
127 * We should likely validate that any extra samples are either
128 * to be ignored, or are alpha, and if alpha we should try to use
129 * them. But for now we won't bother with this.
132 case PHOTOMETRIC_YCBCR
:
134 * TODO: if at all meaningful and useful, make more complete
135 * support check here, or better still, refactor to let supporting
136 * code decide whether there is support and what meaningfull
140 case PHOTOMETRIC_RGB
:
141 if (colorchannels
< 3) {
142 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
143 "Color channels", colorchannels
);
147 case PHOTOMETRIC_SEPARATED
:
150 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
151 if (inkset
!= INKSET_CMYK
) {
153 "Sorry, can not handle separated image with %s=%d",
157 if (td
->td_samplesperpixel
< 4) {
159 "Sorry, can not handle separated image with %s=%d",
160 "Samples/pixel", td
->td_samplesperpixel
);
165 case PHOTOMETRIC_LOGL
:
166 if (td
->td_compression
!= COMPRESSION_SGILOG
) {
167 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
168 "Compression", COMPRESSION_SGILOG
);
172 case PHOTOMETRIC_LOGLUV
:
173 if (td
->td_compression
!= COMPRESSION_SGILOG
&&
174 td
->td_compression
!= COMPRESSION_SGILOG24
) {
175 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
176 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
179 if (td
->td_planarconfig
!= PLANARCONFIG_CONTIG
) {
180 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
181 "Planarconfiguration", td
->td_planarconfig
);
185 case PHOTOMETRIC_CIELAB
:
188 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
189 photoTag
, photometric
);
196 TIFFRGBAImageEnd(TIFFRGBAImage
* img
)
199 _TIFFfree(img
->Map
), img
->Map
= NULL
;
201 _TIFFfree(img
->BWmap
), img
->BWmap
= NULL
;
203 _TIFFfree(img
->PALmap
), img
->PALmap
= NULL
;
205 _TIFFfree(img
->ycbcr
), img
->ycbcr
= NULL
;
207 _TIFFfree(img
->cielab
), img
->cielab
= NULL
;
209 _TIFFfree(img
->UaToAa
), img
->UaToAa
= NULL
;
210 if (img
->Bitdepth16To8
)
211 _TIFFfree(img
->Bitdepth16To8
), img
->Bitdepth16To8
= NULL
;
214 _TIFFfree( img
->redcmap
);
215 _TIFFfree( img
->greencmap
);
216 _TIFFfree( img
->bluecmap
);
217 img
->redcmap
= img
->greencmap
= img
->bluecmap
= NULL
;
222 isCCITTCompression(TIFF
* tif
)
225 TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compress
);
226 return (compress
== COMPRESSION_CCITTFAX3
||
227 compress
== COMPRESSION_CCITTFAX4
||
228 compress
== COMPRESSION_CCITTRLE
||
229 compress
== COMPRESSION_CCITTRLEW
);
233 TIFFRGBAImageBegin(TIFFRGBAImage
* img
, TIFF
* tif
, int stop
, char emsg
[1024])
240 uint16
*red_orig
, *green_orig
, *blue_orig
;
243 /* Initialize to normal values */
247 img
->greencmap
= NULL
;
248 img
->bluecmap
= NULL
;
249 img
->req_orientation
= ORIENTATION_BOTLEFT
; /* It is the default */
252 img
->stoponerr
= stop
;
253 TIFFGetFieldDefaulted(tif
, TIFFTAG_BITSPERSAMPLE
, &img
->bitspersample
);
254 switch (img
->bitspersample
) {
262 sprintf(emsg
, "Sorry, can not handle images with %d-bit samples",
267 TIFFGetFieldDefaulted(tif
, TIFFTAG_SAMPLESPERPIXEL
, &img
->samplesperpixel
);
268 TIFFGetFieldDefaulted(tif
, TIFFTAG_EXTRASAMPLES
,
269 &extrasamples
, &sampleinfo
);
270 if (extrasamples
>= 1)
272 switch (sampleinfo
[0]) {
273 case EXTRASAMPLE_UNSPECIFIED
: /* Workaround for some images without */
274 if (img
->samplesperpixel
> 3) /* correct info about alpha channel */
275 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
277 case EXTRASAMPLE_ASSOCALPHA
: /* data is pre-multiplied */
278 case EXTRASAMPLE_UNASSALPHA
: /* data is not pre-multiplied */
279 img
->alpha
= sampleinfo
[0];
284 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
285 if( !TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
))
286 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
288 if( extrasamples
== 0
289 && img
->samplesperpixel
== 4
290 && img
->photometric
== PHOTOMETRIC_RGB
)
292 img
->alpha
= EXTRASAMPLE_ASSOCALPHA
;
297 colorchannels
= img
->samplesperpixel
- extrasamples
;
298 TIFFGetFieldDefaulted(tif
, TIFFTAG_COMPRESSION
, &compress
);
299 TIFFGetFieldDefaulted(tif
, TIFFTAG_PLANARCONFIG
, &planarconfig
);
300 if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
)) {
301 switch (colorchannels
) {
303 if (isCCITTCompression(tif
))
304 img
->photometric
= PHOTOMETRIC_MINISWHITE
;
306 img
->photometric
= PHOTOMETRIC_MINISBLACK
;
309 img
->photometric
= PHOTOMETRIC_RGB
;
312 sprintf(emsg
, "Missing needed %s tag", photoTag
);
316 switch (img
->photometric
) {
317 case PHOTOMETRIC_PALETTE
:
318 if (!TIFFGetField(tif
, TIFFTAG_COLORMAP
,
319 &red_orig
, &green_orig
, &blue_orig
)) {
320 sprintf(emsg
, "Missing required \"Colormap\" tag");
324 /* copy the colormaps so we can modify them */
325 n_color
= (1L << img
->bitspersample
);
326 img
->redcmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
327 img
->greencmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
328 img
->bluecmap
= (uint16
*) _TIFFmalloc(sizeof(uint16
)*n_color
);
329 if( !img
->redcmap
|| !img
->greencmap
|| !img
->bluecmap
) {
330 sprintf(emsg
, "Out of memory for colormap copy");
334 _TIFFmemcpy( img
->redcmap
, red_orig
, n_color
* 2 );
335 _TIFFmemcpy( img
->greencmap
, green_orig
, n_color
* 2 );
336 _TIFFmemcpy( img
->bluecmap
, blue_orig
, n_color
* 2 );
339 case PHOTOMETRIC_MINISWHITE
:
340 case PHOTOMETRIC_MINISBLACK
:
341 if (planarconfig
== PLANARCONFIG_CONTIG
342 && img
->samplesperpixel
!= 1
343 && img
->bitspersample
< 8 ) {
345 "Sorry, can not handle contiguous data with %s=%d, "
346 "and %s=%d and Bits/Sample=%d",
347 photoTag
, img
->photometric
,
348 "Samples/pixel", img
->samplesperpixel
,
353 case PHOTOMETRIC_YCBCR
:
354 /* It would probably be nice to have a reality check here. */
355 if (planarconfig
== PLANARCONFIG_CONTIG
)
356 /* can rely on libjpeg to convert to RGB */
357 /* XXX should restore current state on exit */
359 case COMPRESSION_JPEG
:
361 * TODO: when complete tests verify complete desubsampling
362 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
363 * favor of tif_getimage.c native handling
365 TIFFSetField(tif
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
);
366 img
->photometric
= PHOTOMETRIC_RGB
;
373 * TODO: if at all meaningful and useful, make more complete
374 * support check here, or better still, refactor to let supporting
375 * code decide whether there is support and what meaningfull
379 case PHOTOMETRIC_RGB
:
380 if (colorchannels
< 3) {
381 sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d",
382 "Color channels", colorchannels
);
386 case PHOTOMETRIC_SEPARATED
:
389 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
);
390 if (inkset
!= INKSET_CMYK
) {
391 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
395 if (img
->samplesperpixel
< 4) {
396 sprintf(emsg
, "Sorry, can not handle separated image with %s=%d",
397 "Samples/pixel", img
->samplesperpixel
);
402 case PHOTOMETRIC_LOGL
:
403 if (compress
!= COMPRESSION_SGILOG
) {
404 sprintf(emsg
, "Sorry, LogL data must have %s=%d",
405 "Compression", COMPRESSION_SGILOG
);
408 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
409 img
->photometric
= PHOTOMETRIC_MINISBLACK
; /* little white lie */
410 img
->bitspersample
= 8;
412 case PHOTOMETRIC_LOGLUV
:
413 if (compress
!= COMPRESSION_SGILOG
&& compress
!= COMPRESSION_SGILOG24
) {
414 sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d",
415 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
);
418 if (planarconfig
!= PLANARCONFIG_CONTIG
) {
419 sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d",
420 "Planarconfiguration", planarconfig
);
423 TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
);
424 img
->photometric
= PHOTOMETRIC_RGB
; /* little white lie */
425 img
->bitspersample
= 8;
427 case PHOTOMETRIC_CIELAB
:
430 sprintf(emsg
, "Sorry, can not handle image with %s=%d",
431 photoTag
, img
->photometric
);
440 img
->Bitdepth16To8
= NULL
;
441 TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &img
->width
);
442 TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &img
->height
);
443 TIFFGetFieldDefaulted(tif
, TIFFTAG_ORIENTATION
, &img
->orientation
);
445 !(planarconfig
== PLANARCONFIG_SEPARATE
&& img
->samplesperpixel
> 1);
447 if (!PickContigCase(img
)) {
448 sprintf(emsg
, "Sorry, can not handle image");
452 if (!PickSeparateCase(img
)) {
453 sprintf(emsg
, "Sorry, can not handle image");
460 _TIFFfree( img
->redcmap
);
461 _TIFFfree( img
->greencmap
);
462 _TIFFfree( img
->bluecmap
);
463 img
->redcmap
= img
->greencmap
= img
->bluecmap
= NULL
;
468 TIFFRGBAImageGet(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
470 if (img
->get
== NULL
) {
471 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No \"get\" routine setup");
474 if (img
->put
.any
== NULL
) {
475 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
476 "No \"put\" routine setupl; probably can not handle image format");
479 return (*img
->get
)(img
, raster
, w
, h
);
483 * Read the specified image into an ABGR-format rastertaking in account
484 * specified orientation.
487 TIFFReadRGBAImageOriented(TIFF
* tif
,
488 uint32 rwidth
, uint32 rheight
, uint32
* raster
,
489 int orientation
, int stop
)
491 char emsg
[1024] = "";
495 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, stop
, emsg
)) {
496 img
.req_orientation
= orientation
;
497 /* XXX verify rwidth and rheight against width and height */
498 ok
= TIFFRGBAImageGet(&img
, raster
+(rheight
-img
.height
)*rwidth
,
500 TIFFRGBAImageEnd(&img
);
502 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
509 * Read the specified image into an ABGR-format raster. Use bottom left
510 * origin for raster by default.
513 TIFFReadRGBAImage(TIFF
* tif
,
514 uint32 rwidth
, uint32 rheight
, uint32
* raster
, int stop
)
516 return TIFFReadRGBAImageOriented(tif
, rwidth
, rheight
, raster
,
517 ORIENTATION_BOTLEFT
, stop
);
521 setorientation(TIFFRGBAImage
* img
)
523 switch (img
->orientation
) {
524 case ORIENTATION_TOPLEFT
:
525 case ORIENTATION_LEFTTOP
:
526 if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
527 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
528 return FLIP_HORIZONTALLY
;
529 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
530 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
531 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
532 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
533 img
->req_orientation
== ORIENTATION_LEFTBOT
)
534 return FLIP_VERTICALLY
;
537 case ORIENTATION_TOPRIGHT
:
538 case ORIENTATION_RIGHTTOP
:
539 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
540 img
->req_orientation
== ORIENTATION_LEFTTOP
)
541 return FLIP_HORIZONTALLY
;
542 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
543 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
544 return FLIP_VERTICALLY
;
545 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
546 img
->req_orientation
== ORIENTATION_LEFTBOT
)
547 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
550 case ORIENTATION_BOTRIGHT
:
551 case ORIENTATION_RIGHTBOT
:
552 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
553 img
->req_orientation
== ORIENTATION_LEFTTOP
)
554 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
555 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
556 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
557 return FLIP_VERTICALLY
;
558 else if (img
->req_orientation
== ORIENTATION_BOTLEFT
||
559 img
->req_orientation
== ORIENTATION_LEFTBOT
)
560 return FLIP_HORIZONTALLY
;
563 case ORIENTATION_BOTLEFT
:
564 case ORIENTATION_LEFTBOT
:
565 if (img
->req_orientation
== ORIENTATION_TOPLEFT
||
566 img
->req_orientation
== ORIENTATION_LEFTTOP
)
567 return FLIP_VERTICALLY
;
568 else if (img
->req_orientation
== ORIENTATION_TOPRIGHT
||
569 img
->req_orientation
== ORIENTATION_RIGHTTOP
)
570 return FLIP_HORIZONTALLY
| FLIP_VERTICALLY
;
571 else if (img
->req_orientation
== ORIENTATION_BOTRIGHT
||
572 img
->req_orientation
== ORIENTATION_RIGHTBOT
)
573 return FLIP_HORIZONTALLY
;
576 default: /* NOTREACHED */
582 * Get an tile-organized image that has
583 * PlanarConfiguration contiguous if SamplesPerPixel > 1
585 * SamplesPerPixel == 1
588 gtTileContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
590 TIFF
* tif
= img
->tif
;
591 tileContigRoutine put
= img
->put
.contig
;
592 uint32 col
, row
, y
, rowstoread
;
596 int32 fromskew
, toskew
;
600 buf
= (unsigned char*) _TIFFmalloc(TIFFTileSize(tif
));
602 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", "No space for tile buffer");
605 _TIFFmemset(buf
, 0, TIFFTileSize(tif
));
606 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
607 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
609 flip
= setorientation(img
);
610 if (flip
& FLIP_VERTICALLY
) {
612 toskew
= -(int32
)(tw
+ w
);
616 toskew
= -(int32
)(tw
- w
);
619 for (row
= 0; row
< h
; row
+= nrow
)
621 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
622 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
623 for (col
= 0; col
< w
; col
+= tw
)
625 if (TIFFReadTile(tif
, buf
, col
+img
->col_offset
,
626 row
+img
->row_offset
, 0, 0)==(tmsize_t
)(-1) && img
->stoponerr
)
632 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
);
637 * Tile is clipped horizontally. Calculate
638 * visible portion and skewing factors.
640 uint32 npix
= w
- col
;
641 fromskew
= tw
- npix
;
642 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
643 npix
, nrow
, fromskew
, toskew
+ fromskew
, buf
+ pos
);
647 (*put
)(img
, raster
+y
*w
+col
, col
, y
, tw
, nrow
, 0, toskew
, buf
+ pos
);
651 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
655 if (flip
& FLIP_HORIZONTALLY
) {
658 for (line
= 0; line
< h
; line
++) {
659 uint32
*left
= raster
+ (line
* w
);
660 uint32
*right
= left
+ w
- 1;
662 while ( left
< right
) {
675 * Get an tile-organized image that has
676 * SamplesPerPixel > 1
677 * PlanarConfiguration separated
678 * We assume that all such images are RGB.
681 gtTileSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
683 TIFF
* tif
= img
->tif
;
684 tileSeparateRoutine put
= img
->put
.separate
;
685 uint32 col
, row
, y
, rowstoread
;
695 int32 fromskew
, toskew
;
696 int alpha
= img
->alpha
;
701 tilesize
= TIFFTileSize(tif
);
702 bufsize
= TIFFSafeMultiply(tmsize_t
,alpha
?4:3,tilesize
);
704 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Integer overflow in %s", "gtTileSeparate");
707 buf
= (unsigned char*) _TIFFmalloc(bufsize
);
709 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", "No space for tile buffer");
712 _TIFFmemset(buf
, 0, bufsize
);
716 pa
= (alpha
?(p2
+tilesize
):NULL
);
717 TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
);
718 TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
);
720 flip
= setorientation(img
);
721 if (flip
& FLIP_VERTICALLY
) {
723 toskew
= -(int32
)(tw
+ w
);
727 toskew
= -(int32
)(tw
- w
);
730 switch( img
->photometric
)
732 case PHOTOMETRIC_MINISWHITE
:
733 case PHOTOMETRIC_MINISBLACK
:
734 case PHOTOMETRIC_PALETTE
:
744 for (row
= 0; row
< h
; row
+= nrow
)
746 rowstoread
= th
- (row
+ img
->row_offset
) % th
;
747 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
748 for (col
= 0; col
< w
; col
+= tw
)
750 if (TIFFReadTile(tif
, p0
, col
+img
->col_offset
,
751 row
+img
->row_offset
,0,0)==(tmsize_t
)(-1) && img
->stoponerr
)
756 if (colorchannels
> 1
757 && TIFFReadTile(tif
, p1
, col
+img
->col_offset
,
758 row
+img
->row_offset
,0,1) == (tmsize_t
)(-1)
764 if (colorchannels
> 1
765 && TIFFReadTile(tif
, p2
, col
+img
->col_offset
,
766 row
+img
->row_offset
,0,2) == (tmsize_t
)(-1)
773 && TIFFReadTile(tif
,pa
,col
+img
->col_offset
,
774 row
+img
->row_offset
,0,colorchannels
) == (tmsize_t
)(-1)
781 pos
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
);
786 * Tile is clipped horizontally. Calculate
787 * visible portion and skewing factors.
789 uint32 npix
= w
- col
;
790 fromskew
= tw
- npix
;
791 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
792 npix
, nrow
, fromskew
, toskew
+ fromskew
,
793 p0
+ pos
, p1
+ pos
, p2
+ pos
, (alpha
?(pa
+pos
):NULL
));
795 (*put
)(img
, raster
+y
*w
+col
, col
, y
,
796 tw
, nrow
, 0, toskew
, p0
+ pos
, p1
+ pos
, p2
+ pos
, (alpha
?(pa
+pos
):NULL
));
800 y
+= (flip
& FLIP_VERTICALLY
?-(int32
) nrow
: (int32
) nrow
);
803 if (flip
& FLIP_HORIZONTALLY
) {
806 for (line
= 0; line
< h
; line
++) {
807 uint32
*left
= raster
+ (line
* w
);
808 uint32
*right
= left
+ w
- 1;
810 while ( left
< right
) {
824 * Get a strip-organized image that has
825 * PlanarConfiguration contiguous if SamplesPerPixel > 1
827 * SamplesPerPixel == 1
830 gtStripContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
832 TIFF
* tif
= img
->tif
;
833 tileContigRoutine put
= img
->put
.contig
;
834 uint32 row
, y
, nrow
, nrowsub
, rowstoread
;
838 uint16 subsamplinghor
,subsamplingver
;
839 uint32 imagewidth
= img
->width
;
841 int32 fromskew
, toskew
;
844 buf
= (unsigned char*) _TIFFmalloc(TIFFStripSize(tif
));
846 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for strip buffer");
849 _TIFFmemset(buf
, 0, TIFFStripSize(tif
));
851 flip
= setorientation(img
);
852 if (flip
& FLIP_VERTICALLY
) {
854 toskew
= -(int32
)(w
+ w
);
857 toskew
= -(int32
)(w
- w
);
860 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
861 TIFFGetFieldDefaulted(tif
, TIFFTAG_YCBCRSUBSAMPLING
, &subsamplinghor
, &subsamplingver
);
862 scanline
= TIFFScanlineSize(tif
);
863 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
864 for (row
= 0; row
< h
; row
+= nrow
)
866 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
867 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
869 if ((nrowsub%subsamplingver
)!=0)
870 nrowsub
+=subsamplingver
-nrowsub%subsamplingver
;
871 if (TIFFReadEncodedStrip(tif
,
872 TIFFComputeStrip(tif
,row
+img
->row_offset
, 0),
874 ((row
+ img
->row_offset
)%rowsperstrip
+ nrowsub
) * scanline
)==(tmsize_t
)(-1)
881 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
;
882 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, buf
+ pos
);
883 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
886 if (flip
& FLIP_HORIZONTALLY
) {
889 for (line
= 0; line
< h
; line
++) {
890 uint32
*left
= raster
+ (line
* w
);
891 uint32
*right
= left
+ w
- 1;
893 while ( left
< right
) {
907 * Get a strip-organized image with
908 * SamplesPerPixel > 1
909 * PlanarConfiguration separated
910 * We assume that all such images are RGB.
913 gtStripSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
)
915 TIFF
* tif
= img
->tif
;
916 tileSeparateRoutine put
= img
->put
.separate
;
918 unsigned char *p0
, *p1
, *p2
, *pa
;
919 uint32 row
, y
, nrow
, rowstoread
;
922 uint32 rowsperstrip
, offset_row
;
923 uint32 imagewidth
= img
->width
;
926 int32 fromskew
, toskew
;
927 int alpha
= img
->alpha
;
928 int ret
= 1, flip
, colorchannels
;
930 stripsize
= TIFFStripSize(tif
);
931 bufsize
= TIFFSafeMultiply(tmsize_t
,alpha
?4:3,stripsize
);
933 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "Integer overflow in %s", "gtStripSeparate");
936 p0
= buf
= (unsigned char *)_TIFFmalloc(bufsize
);
938 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for tile buffer");
941 _TIFFmemset(buf
, 0, bufsize
);
944 pa
= (alpha
?(p2
+stripsize
):NULL
);
946 flip
= setorientation(img
);
947 if (flip
& FLIP_VERTICALLY
) {
949 toskew
= -(int32
)(w
+ w
);
953 toskew
= -(int32
)(w
- w
);
956 switch( img
->photometric
)
958 case PHOTOMETRIC_MINISWHITE
:
959 case PHOTOMETRIC_MINISBLACK
:
960 case PHOTOMETRIC_PALETTE
:
970 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
971 scanline
= TIFFScanlineSize(tif
);
972 fromskew
= (w
< imagewidth
? imagewidth
- w
: 0);
973 for (row
= 0; row
< h
; row
+= nrow
)
975 rowstoread
= rowsperstrip
- (row
+ img
->row_offset
) % rowsperstrip
;
976 nrow
= (row
+ rowstoread
> h
? h
- row
: rowstoread
);
977 offset_row
= row
+ img
->row_offset
;
978 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 0),
979 p0
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
985 if (colorchannels
> 1
986 && TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 1),
987 p1
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) == (tmsize_t
)(-1)
993 if (colorchannels
> 1
994 && TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 2),
995 p2
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
) == (tmsize_t
)(-1)
1003 if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, colorchannels
),
1004 pa
, ((row
+ img
->row_offset
)%rowsperstrip
+ nrow
) * scanline
)==(tmsize_t
)(-1)
1012 pos
= ((row
+ img
->row_offset
) % rowsperstrip
) * scanline
;
1013 (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, p0
+ pos
, p1
+ pos
,
1014 p2
+ pos
, (alpha
?(pa
+pos
):NULL
));
1015 y
+= (flip
& FLIP_VERTICALLY
? -(int32
) nrow
: (int32
) nrow
);
1018 if (flip
& FLIP_HORIZONTALLY
) {
1021 for (line
= 0; line
< h
; line
++) {
1022 uint32
*left
= raster
+ (line
* w
);
1023 uint32
*right
= left
+ w
- 1;
1025 while ( left
< right
) {
1026 uint32 temp
= *left
;
1039 * The following routines move decoded data returned
1040 * from the TIFF library into rasters filled with packed
1041 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
1043 * The routines have been created according to the most
1044 * important cases and optimized. PickContigCase and
1045 * PickSeparateCase analyze the parameters and select
1046 * the appropriate "get" and "put" routine to use.
1048 #define REPEAT8(op) REPEAT4(op); REPEAT4(op)
1049 #define REPEAT4(op) REPEAT2(op); REPEAT2(op)
1050 #define REPEAT2(op) op; op
1051 #define CASE8(x,op) \
1053 case 7: op; case 6: op; case 5: op; \
1054 case 4: op; case 3: op; case 2: op; \
1057 #define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
1060 #define UNROLL8(w, op1, op2) { \
1062 for (_x = w; _x >= 8; _x -= 8) { \
1071 #define UNROLL4(w, op1, op2) { \
1073 for (_x = w; _x >= 4; _x -= 4) { \
1082 #define UNROLL2(w, op1, op2) { \
1084 for (_x = w; _x >= 2; _x -= 2) { \
1094 #define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1095 #define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1097 #define A1 (((uint32)0xffL)<<24)
1098 #define PACK(r,g,b) \
1099 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1100 #define PACK4(r,g,b,a) \
1101 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1102 #define W2B(v) (((v)>>8)&0xff)
1103 /* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
1104 #define PACKW(r,g,b) \
1105 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1106 #define PACKW4(r,g,b,a) \
1107 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1109 #define DECLAREContigPutFunc(name) \
1111 TIFFRGBAImage* img, \
1113 uint32 x, uint32 y, \
1114 uint32 w, uint32 h, \
1115 int32 fromskew, int32 toskew, \
1120 * 8-bit palette => colormap/RGB
1122 DECLAREContigPutFunc(put8bitcmaptile
)
1124 uint32
** PALmap
= img
->PALmap
;
1125 int samplesperpixel
= img
->samplesperpixel
;
1129 for (x
= w
; x
-- > 0;)
1131 *cp
++ = PALmap
[*pp
][0];
1132 pp
+= samplesperpixel
;
1140 * 4-bit palette => colormap/RGB
1142 DECLAREContigPutFunc(put4bitcmaptile
)
1144 uint32
** PALmap
= img
->PALmap
;
1150 UNROLL2(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1157 * 2-bit palette => colormap/RGB
1159 DECLAREContigPutFunc(put2bitcmaptile
)
1161 uint32
** PALmap
= img
->PALmap
;
1167 UNROLL4(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1174 * 1-bit palette => colormap/RGB
1176 DECLAREContigPutFunc(put1bitcmaptile
)
1178 uint32
** PALmap
= img
->PALmap
;
1184 UNROLL8(w
, bw
= PALmap
[*pp
++], *cp
++ = *bw
++);
1191 * 8-bit greyscale => colormap/RGB
1193 DECLAREContigPutFunc(putgreytile
)
1195 int samplesperpixel
= img
->samplesperpixel
;
1196 uint32
** BWmap
= img
->BWmap
;
1200 for (x
= w
; x
-- > 0;)
1202 *cp
++ = BWmap
[*pp
][0];
1203 pp
+= samplesperpixel
;
1211 * 8-bit greyscale with associated alpha => colormap/RGBA
1213 DECLAREContigPutFunc(putagreytile
)
1215 int samplesperpixel
= img
->samplesperpixel
;
1216 uint32
** BWmap
= img
->BWmap
;
1220 for (x
= w
; x
-- > 0;)
1222 *cp
++ = BWmap
[*pp
][0] & (*(pp
+1) << 24 | ~A1
);
1223 pp
+= samplesperpixel
;
1231 * 16-bit greyscale => colormap/RGB
1233 DECLAREContigPutFunc(put16bitbwtile
)
1235 int samplesperpixel
= img
->samplesperpixel
;
1236 uint32
** BWmap
= img
->BWmap
;
1240 uint16
*wp
= (uint16
*) pp
;
1242 for (x
= w
; x
-- > 0;)
1244 /* use high order byte of 16bit value */
1246 *cp
++ = BWmap
[*wp
>> 8][0];
1247 pp
+= 2 * samplesperpixel
;
1248 wp
+= samplesperpixel
;
1256 * 1-bit bilevel => colormap/RGB
1258 DECLAREContigPutFunc(put1bitbwtile
)
1260 uint32
** BWmap
= img
->BWmap
;
1266 UNROLL8(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1273 * 2-bit greyscale => colormap/RGB
1275 DECLAREContigPutFunc(put2bitbwtile
)
1277 uint32
** BWmap
= img
->BWmap
;
1283 UNROLL4(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1290 * 4-bit greyscale => colormap/RGB
1292 DECLAREContigPutFunc(put4bitbwtile
)
1294 uint32
** BWmap
= img
->BWmap
;
1300 UNROLL2(w
, bw
= BWmap
[*pp
++], *cp
++ = *bw
++);
1307 * 8-bit packed samples, no Map => RGB
1309 DECLAREContigPutFunc(putRGBcontig8bittile
)
1311 int samplesperpixel
= img
->samplesperpixel
;
1314 fromskew
*= samplesperpixel
;
1317 *cp
++ = PACK(pp
[0], pp
[1], pp
[2]);
1318 pp
+= samplesperpixel
);
1325 * 8-bit packed samples => RGBA w/ associated alpha
1326 * (known to have Map == NULL)
1328 DECLAREContigPutFunc(putRGBAAcontig8bittile
)
1330 int samplesperpixel
= img
->samplesperpixel
;
1333 fromskew
*= samplesperpixel
;
1336 *cp
++ = PACK4(pp
[0], pp
[1], pp
[2], pp
[3]);
1337 pp
+= samplesperpixel
);
1344 * 8-bit packed samples => RGBA w/ unassociated alpha
1345 * (known to have Map == NULL)
1347 DECLAREContigPutFunc(putRGBUAcontig8bittile
)
1349 int samplesperpixel
= img
->samplesperpixel
;
1351 fromskew
*= samplesperpixel
;
1355 for (x
= w
; x
-- > 0;) {
1357 m
= img
->UaToAa
+(a
<<8);
1361 *cp
++ = PACK4(r
,g
,b
,a
);
1362 pp
+= samplesperpixel
;
1370 * 16-bit packed samples => RGB
1372 DECLAREContigPutFunc(putRGBcontig16bittile
)
1374 int samplesperpixel
= img
->samplesperpixel
;
1375 uint16
*wp
= (uint16
*)pp
;
1377 fromskew
*= samplesperpixel
;
1379 for (x
= w
; x
-- > 0;) {
1380 *cp
++ = PACK(img
->Bitdepth16To8
[wp
[0]],
1381 img
->Bitdepth16To8
[wp
[1]],
1382 img
->Bitdepth16To8
[wp
[2]]);
1383 wp
+= samplesperpixel
;
1391 * 16-bit packed samples => RGBA w/ associated alpha
1392 * (known to have Map == NULL)
1394 DECLAREContigPutFunc(putRGBAAcontig16bittile
)
1396 int samplesperpixel
= img
->samplesperpixel
;
1397 uint16
*wp
= (uint16
*)pp
;
1399 fromskew
*= samplesperpixel
;
1401 for (x
= w
; x
-- > 0;) {
1402 *cp
++ = PACK4(img
->Bitdepth16To8
[wp
[0]],
1403 img
->Bitdepth16To8
[wp
[1]],
1404 img
->Bitdepth16To8
[wp
[2]],
1405 img
->Bitdepth16To8
[wp
[3]]);
1406 wp
+= samplesperpixel
;
1414 * 16-bit packed samples => RGBA w/ unassociated alpha
1415 * (known to have Map == NULL)
1417 DECLAREContigPutFunc(putRGBUAcontig16bittile
)
1419 int samplesperpixel
= img
->samplesperpixel
;
1420 uint16
*wp
= (uint16
*)pp
;
1422 fromskew
*= samplesperpixel
;
1426 for (x
= w
; x
-- > 0;) {
1427 a
= img
->Bitdepth16To8
[wp
[3]];
1428 m
= img
->UaToAa
+(a
<<8);
1429 r
= m
[img
->Bitdepth16To8
[wp
[0]]];
1430 g
= m
[img
->Bitdepth16To8
[wp
[1]]];
1431 b
= m
[img
->Bitdepth16To8
[wp
[2]]];
1432 *cp
++ = PACK4(r
,g
,b
,a
);
1433 wp
+= samplesperpixel
;
1441 * 8-bit packed CMYK samples w/o Map => RGB
1443 * NB: The conversion of CMYK->RGB is *very* crude.
1445 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile
)
1447 int samplesperpixel
= img
->samplesperpixel
;
1451 fromskew
*= samplesperpixel
;
1455 r
= (k
*(255-pp
[0]))/255;
1456 g
= (k
*(255-pp
[1]))/255;
1457 b
= (k
*(255-pp
[2]))/255;
1458 *cp
++ = PACK(r
, g
, b
);
1459 pp
+= samplesperpixel
);
1466 * 8-bit packed CMYK samples w/Map => RGB
1468 * NB: The conversion of CMYK->RGB is *very* crude.
1470 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile
)
1472 int samplesperpixel
= img
->samplesperpixel
;
1473 TIFFRGBValue
* Map
= img
->Map
;
1477 fromskew
*= samplesperpixel
;
1479 for (x
= w
; x
-- > 0;) {
1481 r
= (k
*(255-pp
[0]))/255;
1482 g
= (k
*(255-pp
[1]))/255;
1483 b
= (k
*(255-pp
[2]))/255;
1484 *cp
++ = PACK(Map
[r
], Map
[g
], Map
[b
]);
1485 pp
+= samplesperpixel
;
1492 #define DECLARESepPutFunc(name) \
1494 TIFFRGBAImage* img,\
1496 uint32 x, uint32 y, \
1497 uint32 w, uint32 h,\
1498 int32 fromskew, int32 toskew,\
1499 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1503 * 8-bit unpacked samples => RGB
1505 DECLARESepPutFunc(putRGBseparate8bittile
)
1507 (void) img
; (void) x
; (void) y
; (void) a
;
1509 UNROLL8(w
, NOP
, *cp
++ = PACK(*r
++, *g
++, *b
++));
1510 SKEW(r
, g
, b
, fromskew
);
1516 * 8-bit unpacked samples => RGBA w/ associated alpha
1518 DECLARESepPutFunc(putRGBAAseparate8bittile
)
1520 (void) img
; (void) x
; (void) y
;
1522 UNROLL8(w
, NOP
, *cp
++ = PACK4(*r
++, *g
++, *b
++, *a
++));
1523 SKEW4(r
, g
, b
, a
, fromskew
);
1529 * 8-bit unpacked CMYK samples => RGBA
1531 DECLARESepPutFunc(putCMYKseparate8bittile
)
1533 (void) img
; (void) y
;
1535 uint32 rv
, gv
, bv
, kv
;
1536 for (x
= w
; x
-- > 0;) {
1538 rv
= (kv
*(255-*r
++))/255;
1539 gv
= (kv
*(255-*g
++))/255;
1540 bv
= (kv
*(255-*b
++))/255;
1541 *cp
++ = PACK4(rv
,gv
,bv
,255);
1543 SKEW4(r
, g
, b
, a
, fromskew
);
1549 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1551 DECLARESepPutFunc(putRGBUAseparate8bittile
)
1553 (void) img
; (void) y
;
1555 uint32 rv
, gv
, bv
, av
;
1557 for (x
= w
; x
-- > 0;) {
1559 m
= img
->UaToAa
+(av
<<8);
1563 *cp
++ = PACK4(rv
,gv
,bv
,av
);
1565 SKEW4(r
, g
, b
, a
, fromskew
);
1571 * 16-bit unpacked samples => RGB
1573 DECLARESepPutFunc(putRGBseparate16bittile
)
1575 uint16
*wr
= (uint16
*) r
;
1576 uint16
*wg
= (uint16
*) g
;
1577 uint16
*wb
= (uint16
*) b
;
1578 (void) img
; (void) y
; (void) a
;
1580 for (x
= 0; x
< w
; x
++)
1581 *cp
++ = PACK(img
->Bitdepth16To8
[*wr
++],
1582 img
->Bitdepth16To8
[*wg
++],
1583 img
->Bitdepth16To8
[*wb
++]);
1584 SKEW(wr
, wg
, wb
, fromskew
);
1590 * 16-bit unpacked samples => RGBA w/ associated alpha
1592 DECLARESepPutFunc(putRGBAAseparate16bittile
)
1594 uint16
*wr
= (uint16
*) r
;
1595 uint16
*wg
= (uint16
*) g
;
1596 uint16
*wb
= (uint16
*) b
;
1597 uint16
*wa
= (uint16
*) a
;
1598 (void) img
; (void) y
;
1600 for (x
= 0; x
< w
; x
++)
1601 *cp
++ = PACK4(img
->Bitdepth16To8
[*wr
++],
1602 img
->Bitdepth16To8
[*wg
++],
1603 img
->Bitdepth16To8
[*wb
++],
1604 img
->Bitdepth16To8
[*wa
++]);
1605 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1611 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1613 DECLARESepPutFunc(putRGBUAseparate16bittile
)
1615 uint16
*wr
= (uint16
*) r
;
1616 uint16
*wg
= (uint16
*) g
;
1617 uint16
*wb
= (uint16
*) b
;
1618 uint16
*wa
= (uint16
*) a
;
1619 (void) img
; (void) y
;
1623 for (x
= w
; x
-- > 0;) {
1624 a
= img
->Bitdepth16To8
[*wa
++];
1625 m
= img
->UaToAa
+(a
<<8);
1626 r
= m
[img
->Bitdepth16To8
[*wr
++]];
1627 g
= m
[img
->Bitdepth16To8
[*wg
++]];
1628 b
= m
[img
->Bitdepth16To8
[*wb
++]];
1629 *cp
++ = PACK4(r
,g
,b
,a
);
1631 SKEW4(wr
, wg
, wb
, wa
, fromskew
);
1637 * 8-bit packed CIE L*a*b 1976 samples => RGB
1639 DECLAREContigPutFunc(putcontig8bitCIELab
)
1646 for (x
= w
; x
-- > 0;) {
1647 TIFFCIELabToXYZ(img
->cielab
,
1648 (unsigned char)pp
[0],
1652 TIFFXYZToRGB(img
->cielab
, X
, Y
, Z
, &r
, &g
, &b
);
1653 *cp
++ = PACK(r
, g
, b
);
1662 * YCbCr -> RGB conversion and packing routines.
1665 #define YCbCrtoRGB(dst, Y) { \
1667 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1668 dst = PACK(r, g, b); \
1672 * 8-bit packed YCbCr samples => RGB
1673 * This function is generic for different sampling sizes,
1674 * and can handle blocks sizes that aren't multiples of the
1675 * sampling size. However, it is substantially less optimized
1676 * than the specific sampling cases. It is used as a fallback
1677 * for difficult blocks.
1680 static void putcontig8bitYCbCrGenericTile(
1685 int32 fromskew
, int32 toskew
,
1691 uint32
* cp1
= cp
+w
+toskew
;
1692 uint32
* cp2
= cp1
+w
+toskew
;
1693 uint32
* cp3
= cp2
+w
+toskew
;
1694 int32 incr
= 3*w
+4*toskew
;
1696 int group_size
= v_group
* h_group
+ 2;
1699 fromskew
= (fromskew
* group_size
) / h_group
;
1701 for( yy
= 0; yy
< h
; yy
++ )
1703 unsigned char *pp_line
;
1704 int y_line_group
= yy
/ v_group
;
1705 int y_remainder
= yy
- y_line_group
* v_group
;
1707 pp_line
= pp
+ v_line_group
*
1710 for( xx
= 0; xx
< w
; xx
++ )
1715 for (; h
>= 4; h
-= 4) {
1721 YCbCrtoRGB(cp
[0], pp
[ 0]);
1722 YCbCrtoRGB(cp
[1], pp
[ 1]);
1723 YCbCrtoRGB(cp
[2], pp
[ 2]);
1724 YCbCrtoRGB(cp
[3], pp
[ 3]);
1725 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1726 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1727 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1728 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1729 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1730 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1731 YCbCrtoRGB(cp2
[2], pp
[10]);
1732 YCbCrtoRGB(cp2
[3], pp
[11]);
1733 YCbCrtoRGB(cp3
[0], pp
[12]);
1734 YCbCrtoRGB(cp3
[1], pp
[13]);
1735 YCbCrtoRGB(cp3
[2], pp
[14]);
1736 YCbCrtoRGB(cp3
[3], pp
[15]);
1738 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1741 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1748 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1750 DECLAREContigPutFunc(putcontig8bitYCbCr44tile
)
1752 uint32
* cp1
= cp
+w
+toskew
;
1753 uint32
* cp2
= cp1
+w
+toskew
;
1754 uint32
* cp3
= cp2
+w
+toskew
;
1755 int32 incr
= 3*w
+4*toskew
;
1758 /* adjust fromskew */
1759 fromskew
= (fromskew
* 18) / 4;
1760 if ((h
& 3) == 0 && (w
& 3) == 0) {
1761 for (; h
>= 4; h
-= 4) {
1767 YCbCrtoRGB(cp
[0], pp
[ 0]);
1768 YCbCrtoRGB(cp
[1], pp
[ 1]);
1769 YCbCrtoRGB(cp
[2], pp
[ 2]);
1770 YCbCrtoRGB(cp
[3], pp
[ 3]);
1771 YCbCrtoRGB(cp1
[0], pp
[ 4]);
1772 YCbCrtoRGB(cp1
[1], pp
[ 5]);
1773 YCbCrtoRGB(cp1
[2], pp
[ 6]);
1774 YCbCrtoRGB(cp1
[3], pp
[ 7]);
1775 YCbCrtoRGB(cp2
[0], pp
[ 8]);
1776 YCbCrtoRGB(cp2
[1], pp
[ 9]);
1777 YCbCrtoRGB(cp2
[2], pp
[10]);
1778 YCbCrtoRGB(cp2
[3], pp
[11]);
1779 YCbCrtoRGB(cp3
[0], pp
[12]);
1780 YCbCrtoRGB(cp3
[1], pp
[13]);
1781 YCbCrtoRGB(cp3
[2], pp
[14]);
1782 YCbCrtoRGB(cp3
[3], pp
[15]);
1784 cp
+= 4, cp1
+= 4, cp2
+= 4, cp3
+= 4;
1787 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1792 for (x
= w
; x
> 0;) {
1798 default: YCbCrtoRGB(cp3
[3], pp
[15]); /* FALLTHROUGH */
1799 case 3: YCbCrtoRGB(cp2
[3], pp
[11]); /* FALLTHROUGH */
1800 case 2: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1801 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1805 default: YCbCrtoRGB(cp3
[2], pp
[14]); /* FALLTHROUGH */
1806 case 3: YCbCrtoRGB(cp2
[2], pp
[10]); /* FALLTHROUGH */
1807 case 2: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1808 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1812 default: YCbCrtoRGB(cp3
[1], pp
[13]); /* FALLTHROUGH */
1813 case 3: YCbCrtoRGB(cp2
[1], pp
[ 9]); /* FALLTHROUGH */
1814 case 2: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1815 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1819 default: YCbCrtoRGB(cp3
[0], pp
[12]); /* FALLTHROUGH */
1820 case 3: YCbCrtoRGB(cp2
[0], pp
[ 8]); /* FALLTHROUGH */
1821 case 2: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1822 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1826 cp
+= x
; cp1
+= x
; cp2
+= x
; cp3
+= x
;
1830 cp
+= 4; cp1
+= 4; cp2
+= 4; cp3
+= 4;
1838 cp
+= incr
, cp1
+= incr
, cp2
+= incr
, cp3
+= incr
;
1845 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1847 DECLAREContigPutFunc(putcontig8bitYCbCr42tile
)
1849 uint32
* cp1
= cp
+w
+toskew
;
1850 int32 incr
= 2*toskew
+w
;
1853 fromskew
= (fromskew
* 10) / 4;
1854 if ((h
& 3) == 0 && (w
& 1) == 0) {
1855 for (; h
>= 2; h
-= 2) {
1861 YCbCrtoRGB(cp
[0], pp
[0]);
1862 YCbCrtoRGB(cp
[1], pp
[1]);
1863 YCbCrtoRGB(cp
[2], pp
[2]);
1864 YCbCrtoRGB(cp
[3], pp
[3]);
1865 YCbCrtoRGB(cp1
[0], pp
[4]);
1866 YCbCrtoRGB(cp1
[1], pp
[5]);
1867 YCbCrtoRGB(cp1
[2], pp
[6]);
1868 YCbCrtoRGB(cp1
[3], pp
[7]);
1873 cp
+= incr
, cp1
+= incr
;
1878 for (x
= w
; x
> 0;) {
1884 default: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */
1885 case 1: YCbCrtoRGB(cp
[3], pp
[ 3]); /* FALLTHROUGH */
1889 default: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */
1890 case 1: YCbCrtoRGB(cp
[2], pp
[ 2]); /* FALLTHROUGH */
1894 default: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */
1895 case 1: YCbCrtoRGB(cp
[1], pp
[ 1]); /* FALLTHROUGH */
1899 default: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */
1900 case 1: YCbCrtoRGB(cp
[0], pp
[ 0]); /* FALLTHROUGH */
1916 cp
+= incr
, cp1
+= incr
;
1923 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1925 DECLAREContigPutFunc(putcontig8bitYCbCr41tile
)
1928 /* XXX adjust fromskew */
1935 YCbCrtoRGB(cp
[0], pp
[0]);
1936 YCbCrtoRGB(cp
[1], pp
[1]);
1937 YCbCrtoRGB(cp
[2], pp
[2]);
1938 YCbCrtoRGB(cp
[3], pp
[3]);
1950 case 3: YCbCrtoRGB(cp
[2], pp
[2]);
1951 case 2: YCbCrtoRGB(cp
[1], pp
[1]);
1952 case 1: YCbCrtoRGB(cp
[0], pp
[0]);
1967 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1969 DECLAREContigPutFunc(putcontig8bitYCbCr22tile
)
1972 int32 incr
= 2*toskew
+w
;
1974 fromskew
= (fromskew
/ 2) * 6;
1981 YCbCrtoRGB(cp
[0], pp
[0]);
1982 YCbCrtoRGB(cp
[1], pp
[1]);
1983 YCbCrtoRGB(cp2
[0], pp
[2]);
1984 YCbCrtoRGB(cp2
[1], pp
[3]);
1993 YCbCrtoRGB(cp
[0], pp
[0]);
1994 YCbCrtoRGB(cp2
[0], pp
[2]);
2009 YCbCrtoRGB(cp
[0], pp
[0]);
2010 YCbCrtoRGB(cp
[1], pp
[1]);
2019 YCbCrtoRGB(cp
[0], pp
[0]);
2025 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
2027 DECLAREContigPutFunc(putcontig8bitYCbCr21tile
)
2030 fromskew
= (fromskew
* 4) / 2;
2037 YCbCrtoRGB(cp
[0], pp
[0]);
2038 YCbCrtoRGB(cp
[1], pp
[1]);
2049 YCbCrtoRGB(cp
[0], pp
[0]);
2061 * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
2063 DECLAREContigPutFunc(putcontig8bitYCbCr12tile
)
2066 int32 incr
= 2*toskew
+w
;
2068 fromskew
= (fromskew
/ 2) * 4;
2075 YCbCrtoRGB(cp
[0], pp
[0]);
2076 YCbCrtoRGB(cp2
[0], pp
[1]);
2091 YCbCrtoRGB(cp
[0], pp
[0]);
2099 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2101 DECLAREContigPutFunc(putcontig8bitYCbCr11tile
)
2106 x
= w
; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
2111 YCbCrtoRGB(*cp
++, pp
[0]);
2121 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2123 DECLARESepPutFunc(putseparate8bitYCbCr11tile
)
2127 /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2132 TIFFYCbCrtoRGB(img
->ycbcr
,*r
++,*g
++,*b
++,&dr
,&dg
,&db
);
2133 *cp
++ = PACK(dr
,dg
,db
);
2135 SKEW(r
, g
, b
, fromskew
);
2142 initYCbCrConversion(TIFFRGBAImage
* img
)
2144 static const char module[] = "initYCbCrConversion";
2146 float *luma
, *refBlackWhite
;
2148 if (img
->ycbcr
== NULL
) {
2149 img
->ycbcr
= (TIFFYCbCrToRGB
*) _TIFFmalloc(
2150 TIFFroundup_32(sizeof (TIFFYCbCrToRGB
), sizeof (long))
2151 + 4*256*sizeof (TIFFRGBValue
)
2152 + 2*256*sizeof (int)
2153 + 3*256*sizeof (int32
)
2155 if (img
->ycbcr
== NULL
) {
2156 TIFFErrorExt(img
->tif
->tif_clientdata
, module,
2157 "No space for YCbCr->RGB conversion state");
2162 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRCOEFFICIENTS
, &luma
);
2163 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_REFERENCEBLACKWHITE
,
2165 if (TIFFYCbCrToRGBInit(img
->ycbcr
, luma
, refBlackWhite
) < 0)
2170 static tileContigRoutine
2171 initCIELabConversion(TIFFRGBAImage
* img
)
2173 static const char module[] = "initCIELabConversion";
2179 img
->cielab
= (TIFFCIELabToRGB
*)
2180 _TIFFmalloc(sizeof(TIFFCIELabToRGB
));
2182 TIFFErrorExt(img
->tif
->tif_clientdata
, module,
2183 "No space for CIE L*a*b*->RGB conversion state.");
2188 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_WHITEPOINT
, &whitePoint
);
2189 refWhite
[1] = 100.0F
;
2190 refWhite
[0] = whitePoint
[0] / whitePoint
[1] * refWhite
[1];
2191 refWhite
[2] = (1.0F
- whitePoint
[0] - whitePoint
[1])
2192 / whitePoint
[1] * refWhite
[1];
2193 if (TIFFCIELabToRGBInit(img
->cielab
, &display_sRGB
, refWhite
) < 0) {
2194 TIFFErrorExt(img
->tif
->tif_clientdata
, module,
2195 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2196 _TIFFfree(img
->cielab
);
2200 return &putcontig8bitCIELab
;
2204 * Greyscale images with less than 8 bits/sample are handled
2205 * with a table to avoid lots of shifts and masks. The table
2206 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2207 * pixel values simply by indexing into the table with one
2211 makebwmap(TIFFRGBAImage
* img
)
2213 TIFFRGBValue
* Map
= img
->Map
;
2214 int bitspersample
= img
->bitspersample
;
2215 int nsamples
= 8 / bitspersample
;
2222 img
->BWmap
= (uint32
**) _TIFFmalloc(
2223 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2224 if (img
->BWmap
== NULL
) {
2225 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for B&W mapping table");
2228 p
= (uint32
*)(img
->BWmap
+ 256);
2229 for (i
= 0; i
< 256; i
++) {
2232 switch (bitspersample
) {
2233 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2265 * Construct a mapping table to convert from the range
2266 * of the data samples to [0,255] --for display. This
2267 * process also handles inverting B&W images when needed.
2270 setupMap(TIFFRGBAImage
* img
)
2274 range
= (int32
)((1L<<img
->bitspersample
)-1);
2276 /* treat 16 bit the same as eight bit */
2277 if( img
->bitspersample
== 16 )
2278 range
= (int32
) 255;
2280 img
->Map
= (TIFFRGBValue
*) _TIFFmalloc((range
+1) * sizeof (TIFFRGBValue
));
2281 if (img
->Map
== NULL
) {
2282 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
),
2283 "No space for photometric conversion table");
2286 if (img
->photometric
== PHOTOMETRIC_MINISWHITE
) {
2287 for (x
= 0; x
<= range
; x
++)
2288 img
->Map
[x
] = (TIFFRGBValue
) (((range
- x
) * 255) / range
);
2290 for (x
= 0; x
<= range
; x
++)
2291 img
->Map
[x
] = (TIFFRGBValue
) ((x
* 255) / range
);
2293 if (img
->bitspersample
<= 16 &&
2294 (img
->photometric
== PHOTOMETRIC_MINISBLACK
||
2295 img
->photometric
== PHOTOMETRIC_MINISWHITE
)) {
2297 * Use photometric mapping table to construct
2298 * unpacking tables for samples <= 8 bits.
2300 if (!makebwmap(img
))
2302 /* no longer need Map, free it */
2303 _TIFFfree(img
->Map
), img
->Map
= NULL
;
2309 checkcmap(TIFFRGBAImage
* img
)
2311 uint16
* r
= img
->redcmap
;
2312 uint16
* g
= img
->greencmap
;
2313 uint16
* b
= img
->bluecmap
;
2314 long n
= 1L<<img
->bitspersample
;
2317 if (*r
++ >= 256 || *g
++ >= 256 || *b
++ >= 256)
2323 cvtcmap(TIFFRGBAImage
* img
)
2325 uint16
* r
= img
->redcmap
;
2326 uint16
* g
= img
->greencmap
;
2327 uint16
* b
= img
->bluecmap
;
2330 for (i
= (1L<<img
->bitspersample
)-1; i
>= 0; i
--) {
2331 #define CVT(x) ((uint16)((x)>>8))
2340 * Palette images with <= 8 bits/sample are handled
2341 * with a table to avoid lots of shifts and masks. The table
2342 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2343 * pixel values simply by indexing into the table with one
2347 makecmap(TIFFRGBAImage
* img
)
2349 int bitspersample
= img
->bitspersample
;
2350 int nsamples
= 8 / bitspersample
;
2351 uint16
* r
= img
->redcmap
;
2352 uint16
* g
= img
->greencmap
;
2353 uint16
* b
= img
->bluecmap
;
2357 img
->PALmap
= (uint32
**) _TIFFmalloc(
2358 256*sizeof (uint32
*)+(256*nsamples
*sizeof(uint32
)));
2359 if (img
->PALmap
== NULL
) {
2360 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No space for Palette mapping table");
2363 p
= (uint32
*)(img
->PALmap
+ 256);
2364 for (i
= 0; i
< 256; i
++) {
2367 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2368 switch (bitspersample
) {
2399 * Construct any mapping table used
2400 * by the associated put routine.
2403 buildMap(TIFFRGBAImage
* img
)
2405 switch (img
->photometric
) {
2406 case PHOTOMETRIC_RGB
:
2407 case PHOTOMETRIC_YCBCR
:
2408 case PHOTOMETRIC_SEPARATED
:
2409 if (img
->bitspersample
== 8)
2412 case PHOTOMETRIC_MINISBLACK
:
2413 case PHOTOMETRIC_MINISWHITE
:
2417 case PHOTOMETRIC_PALETTE
:
2419 * Convert 16-bit colormap to 8-bit (unless it looks
2420 * like an old-style 8-bit colormap).
2422 if (checkcmap(img
) == 16)
2425 TIFFWarningExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "Assuming 8-bit colormap");
2427 * Use mapping table and colormap to construct
2428 * unpacking tables for samples < 8 bits.
2430 if (img
->bitspersample
<= 8 && !makecmap(img
))
2438 * Select the appropriate conversion routine for packed data.
2441 PickContigCase(TIFFRGBAImage
* img
)
2443 img
->get
= TIFFIsTiled(img
->tif
) ? gtTileContig
: gtStripContig
;
2444 img
->put
.contig
= NULL
;
2445 switch (img
->photometric
) {
2446 case PHOTOMETRIC_RGB
:
2447 switch (img
->bitspersample
) {
2449 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2450 img
->put
.contig
= putRGBAAcontig8bittile
;
2451 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2453 if (BuildMapUaToAa(img
))
2454 img
->put
.contig
= putRGBUAcontig8bittile
;
2457 img
->put
.contig
= putRGBcontig8bittile
;
2460 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2462 if (BuildMapBitdepth16To8(img
))
2463 img
->put
.contig
= putRGBAAcontig16bittile
;
2465 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2467 if (BuildMapBitdepth16To8(img
) &&
2468 BuildMapUaToAa(img
))
2469 img
->put
.contig
= putRGBUAcontig16bittile
;
2473 if (BuildMapBitdepth16To8(img
))
2474 img
->put
.contig
= putRGBcontig16bittile
;
2479 case PHOTOMETRIC_SEPARATED
:
2480 if (buildMap(img
)) {
2481 if (img
->bitspersample
== 8) {
2483 img
->put
.contig
= putRGBcontig8bitCMYKtile
;
2485 img
->put
.contig
= putRGBcontig8bitCMYKMaptile
;
2489 case PHOTOMETRIC_PALETTE
:
2490 if (buildMap(img
)) {
2491 switch (img
->bitspersample
) {
2493 img
->put
.contig
= put8bitcmaptile
;
2496 img
->put
.contig
= put4bitcmaptile
;
2499 img
->put
.contig
= put2bitcmaptile
;
2502 img
->put
.contig
= put1bitcmaptile
;
2507 case PHOTOMETRIC_MINISWHITE
:
2508 case PHOTOMETRIC_MINISBLACK
:
2509 if (buildMap(img
)) {
2510 switch (img
->bitspersample
) {
2512 img
->put
.contig
= put16bitbwtile
;
2515 if (img
->alpha
&& img
->samplesperpixel
== 2)
2516 img
->put
.contig
= putagreytile
;
2518 img
->put
.contig
= putgreytile
;
2521 img
->put
.contig
= put4bitbwtile
;
2524 img
->put
.contig
= put2bitbwtile
;
2527 img
->put
.contig
= put1bitbwtile
;
2532 case PHOTOMETRIC_YCBCR
:
2533 if ((img
->bitspersample
==8) && (img
->samplesperpixel
==3))
2535 if (initYCbCrConversion(img
)!=0)
2538 * The 6.0 spec says that subsampling must be
2539 * one of 1, 2, or 4, and that vertical subsampling
2540 * must always be <= horizontal subsampling; so
2541 * there are only a few possibilities and we just
2542 * enumerate the cases.
2543 * Joris: added support for the [1,2] case, nonetheless, to accomodate
2546 uint16 SubsamplingHor
;
2547 uint16 SubsamplingVer
;
2548 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &SubsamplingHor
, &SubsamplingVer
);
2549 switch ((SubsamplingHor
<<4)|SubsamplingVer
) {
2551 img
->put
.contig
= putcontig8bitYCbCr44tile
;
2554 img
->put
.contig
= putcontig8bitYCbCr42tile
;
2557 img
->put
.contig
= putcontig8bitYCbCr41tile
;
2560 img
->put
.contig
= putcontig8bitYCbCr22tile
;
2563 img
->put
.contig
= putcontig8bitYCbCr21tile
;
2566 img
->put
.contig
= putcontig8bitYCbCr12tile
;
2569 img
->put
.contig
= putcontig8bitYCbCr11tile
;
2575 case PHOTOMETRIC_CIELAB
:
2576 if (buildMap(img
)) {
2577 if (img
->bitspersample
== 8)
2578 img
->put
.contig
= initCIELabConversion(img
);
2582 return ((img
->get
!=NULL
) && (img
->put
.contig
!=NULL
));
2586 * Select the appropriate conversion routine for unpacked data.
2588 * NB: we assume that unpacked single channel data is directed
2589 * to the "packed routines.
2592 PickSeparateCase(TIFFRGBAImage
* img
)
2594 img
->get
= TIFFIsTiled(img
->tif
) ? gtTileSeparate
: gtStripSeparate
;
2595 img
->put
.separate
= NULL
;
2596 switch (img
->photometric
) {
2597 case PHOTOMETRIC_MINISWHITE
:
2598 case PHOTOMETRIC_MINISBLACK
:
2599 /* greyscale images processed pretty much as RGB by gtTileSeparate */
2600 case PHOTOMETRIC_RGB
:
2601 switch (img
->bitspersample
) {
2603 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2604 img
->put
.separate
= putRGBAAseparate8bittile
;
2605 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2607 if (BuildMapUaToAa(img
))
2608 img
->put
.separate
= putRGBUAseparate8bittile
;
2611 img
->put
.separate
= putRGBseparate8bittile
;
2614 if (img
->alpha
== EXTRASAMPLE_ASSOCALPHA
)
2616 if (BuildMapBitdepth16To8(img
))
2617 img
->put
.separate
= putRGBAAseparate16bittile
;
2619 else if (img
->alpha
== EXTRASAMPLE_UNASSALPHA
)
2621 if (BuildMapBitdepth16To8(img
) &&
2622 BuildMapUaToAa(img
))
2623 img
->put
.separate
= putRGBUAseparate16bittile
;
2627 if (BuildMapBitdepth16To8(img
))
2628 img
->put
.separate
= putRGBseparate16bittile
;
2633 case PHOTOMETRIC_SEPARATED
:
2634 if (img
->bitspersample
== 8 && img
->samplesperpixel
== 4)
2636 img
->alpha
= 1; // Not alpha, but seems like the only way to get 4th band
2637 img
->put
.separate
= putCMYKseparate8bittile
;
2640 case PHOTOMETRIC_YCBCR
:
2641 if ((img
->bitspersample
==8) && (img
->samplesperpixel
==3))
2643 if (initYCbCrConversion(img
)!=0)
2646 TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &hs
, &vs
);
2647 switch ((hs
<<4)|vs
) {
2649 img
->put
.separate
= putseparate8bitYCbCr11tile
;
2651 /* TODO: add other cases here */
2657 return ((img
->get
!=NULL
) && (img
->put
.separate
!=NULL
));
2661 BuildMapUaToAa(TIFFRGBAImage
* img
)
2663 static const char module[]="BuildMapUaToAa";
2666 assert(img
->UaToAa
==NULL
);
2667 img
->UaToAa
=_TIFFmalloc(65536);
2668 if (img
->UaToAa
==NULL
)
2670 TIFFErrorExt(img
->tif
->tif_clientdata
,module,"Out of memory");
2674 for (na
=0; na
<256; na
++)
2676 for (nv
=0; nv
<256; nv
++)
2677 *m
++=(nv
*na
+127)/255;
2683 BuildMapBitdepth16To8(TIFFRGBAImage
* img
)
2685 static const char module[]="BuildMapBitdepth16To8";
2688 assert(img
->Bitdepth16To8
==NULL
);
2689 img
->Bitdepth16To8
=_TIFFmalloc(65536);
2690 if (img
->Bitdepth16To8
==NULL
)
2692 TIFFErrorExt(img
->tif
->tif_clientdata
,module,"Out of memory");
2695 m
=img
->Bitdepth16To8
;
2696 for (n
=0; n
<65536; n
++)
2703 * Read a whole strip off data from the file, and convert to RGBA form.
2704 * If this is the last strip, then it will only contain the portion of
2705 * the strip that is actually within the image space. The result is
2706 * organized in bottom to top form.
2711 TIFFReadRGBAStrip(TIFF
* tif
, uint32 row
, uint32
* raster
)
2714 char emsg
[1024] = "";
2717 uint32 rowsperstrip
, rows_to_read
;
2719 if( TIFFIsTiled( tif
) )
2721 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2722 "Can't use TIFFReadRGBAStrip() with tiled file.");
2726 TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
);
2727 if( (row
% rowsperstrip
) != 0 )
2729 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2730 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2734 if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) {
2736 img
.row_offset
= row
;
2739 if( row
+ rowsperstrip
> img
.height
)
2740 rows_to_read
= img
.height
- row
;
2742 rows_to_read
= rowsperstrip
;
2744 ok
= TIFFRGBAImageGet(&img
, raster
, img
.width
, rows_to_read
);
2746 TIFFRGBAImageEnd(&img
);
2748 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
2756 * Read a whole tile off data from the file, and convert to RGBA form.
2757 * The returned RGBA data is organized from bottom to top of tile,
2758 * and may include zeroed areas if the tile extends off the image.
2762 TIFFReadRGBATile(TIFF
* tif
, uint32 col
, uint32 row
, uint32
* raster
)
2765 char emsg
[1024] = "";
2768 uint32 tile_xsize
, tile_ysize
;
2769 uint32 read_xsize
, read_ysize
;
2773 * Verify that our request is legal - on a tile file, and on a
2777 if( !TIFFIsTiled( tif
) )
2779 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2780 "Can't use TIFFReadRGBATile() with stripped file.");
2784 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILEWIDTH
, &tile_xsize
);
2785 TIFFGetFieldDefaulted(tif
, TIFFTAG_TILELENGTH
, &tile_ysize
);
2786 if( (col
% tile_xsize
) != 0 || (row
% tile_ysize
) != 0 )
2788 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
),
2789 "Row/col passed to TIFFReadRGBATile() must be top"
2790 "left corner of a tile.");
2795 * Setup the RGBA reader.
2798 if (!TIFFRGBAImageOK(tif
, emsg
)
2799 || !TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) {
2800 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "%s", emsg
);
2805 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2806 * edge of the image, even to fill an otherwise valid tile. So we
2807 * figure out how much we can read, and fix up the tile buffer to
2808 * a full tile configuration afterwards.
2811 if( row
+ tile_ysize
> img
.height
)
2812 read_ysize
= img
.height
- row
;
2814 read_ysize
= tile_ysize
;
2816 if( col
+ tile_xsize
> img
.width
)
2817 read_xsize
= img
.width
- col
;
2819 read_xsize
= tile_xsize
;
2822 * Read the chunk of imagery.
2825 img
.row_offset
= row
;
2826 img
.col_offset
= col
;
2828 ok
= TIFFRGBAImageGet(&img
, raster
, read_xsize
, read_ysize
);
2830 TIFFRGBAImageEnd(&img
);
2833 * If our read was incomplete we will need to fix up the tile by
2834 * shifting the data around as if a full tile of data is being returned.
2836 * This is all the more complicated because the image is organized in
2837 * bottom to top format.
2840 if( read_xsize
== tile_xsize
&& read_ysize
== tile_ysize
)
2843 for( i_row
= 0; i_row
< read_ysize
; i_row
++ ) {
2844 memmove( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
2845 raster
+ (read_ysize
- i_row
- 1) * read_xsize
,
2846 read_xsize
* sizeof(uint32
) );
2847 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
+read_xsize
,
2848 0, sizeof(uint32
) * (tile_xsize
- read_xsize
) );
2851 for( i_row
= read_ysize
; i_row
< tile_ysize
; i_row
++ ) {
2852 _TIFFmemset( raster
+ (tile_ysize
- i_row
- 1) * tile_xsize
,
2853 0, sizeof(uint32
) * tile_xsize
);
2859 /* vim: set ts=8 sts=8 sw=8 noet: */