1
/* $Id: tif_getimage.c,v 1.63.2.3 2009-08-30 16:21:46 bfriesen Exp $ */
4
* Copyright (c) 1991-1997 Sam Leffler
5
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
7
* Permission to use, copy, modify, distribute, and sell this software and
8
* its documentation for any purpose is hereby granted without fee, provided
9
* that (i) the above copyright notices and this permission notice appear in
10
* all copies of the software and related documentation, and (ii) the names of
11
* Sam Leffler and Silicon Graphics may not be used in any advertising or
12
* publicity relating to the software without the specific, prior written
13
* permission of Sam Leffler and Silicon Graphics.
15
* THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16
* EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17
* WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
19
* IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20
* ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21
* OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22
* WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23
* LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
30
* Read and return a packed RGBA image.
35
static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
36
static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
37
static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
38
static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
39
static int PickContigCase(TIFFRGBAImage*);
40
static int PickSeparateCase(TIFFRGBAImage*);
41
static const char photoTag[] = "PhotometricInterpretation";
44
* Helper constants used in Orientation tag handling
46
#define FLIP_VERTICALLY 0x01
47
#define FLIP_HORIZONTALLY 0x02
50
* Color conversion constants. We will define display types here.
53
TIFFDisplay display_sRGB = {
54
{ /* XYZ -> luminance matrix */
55
{ 3.2410F, -1.5374F, -0.4986F },
56
{ -0.9692F, 1.8760F, 0.0416F },
57
{ 0.0556F, -0.2040F, 1.0570F }
59
100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
60
255, 255, 255, /* Pixel values for ref. white */
61
1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */
62
2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */
66
* Check the image to see if TIFFReadRGBAImage can deal with it.
67
* 1/0 is returned according to whether or not the image can
68
* be handled. If 0 is returned, emsg contains the reason
69
* why it is being rejected.
72
TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
74
TIFFDirectory* td = &tif->tif_dir;
78
if (!tif->tif_decodestatus) {
79
sprintf(emsg, "Sorry, requested compression method is not configured");
82
switch (td->td_bitspersample) {
90
sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
91
td->td_bitspersample);
94
colorchannels = td->td_samplesperpixel - td->td_extrasamples;
95
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
96
switch (colorchannels) {
98
photometric = PHOTOMETRIC_MINISBLACK;
101
photometric = PHOTOMETRIC_RGB;
104
sprintf(emsg, "Missing needed %s tag", photoTag);
108
switch (photometric) {
109
case PHOTOMETRIC_MINISWHITE:
110
case PHOTOMETRIC_MINISBLACK:
111
case PHOTOMETRIC_PALETTE:
112
if (td->td_planarconfig == PLANARCONFIG_CONTIG
113
&& td->td_samplesperpixel != 1
114
&& td->td_bitspersample < 8 ) {
116
"Sorry, can not handle contiguous data with %s=%d, "
117
"and %s=%d and Bits/Sample=%d",
118
photoTag, photometric,
119
"Samples/pixel", td->td_samplesperpixel,
120
td->td_bitspersample);
124
* We should likely validate that any extra samples are either
125
* to be ignored, or are alpha, and if alpha we should try to use
126
* them. But for now we won't bother with this.
129
case PHOTOMETRIC_YCBCR:
131
* TODO: if at all meaningful and useful, make more complete
132
* support check here, or better still, refactor to let supporting
133
* code decide whether there is support and what meaningfull
137
case PHOTOMETRIC_RGB:
138
if (colorchannels < 3) {
139
sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
140
"Color channels", colorchannels);
144
case PHOTOMETRIC_SEPARATED:
147
TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
148
if (inkset != INKSET_CMYK) {
150
"Sorry, can not handle separated image with %s=%d",
154
if (td->td_samplesperpixel < 4) {
156
"Sorry, can not handle separated image with %s=%d",
157
"Samples/pixel", td->td_samplesperpixel);
162
case PHOTOMETRIC_LOGL:
163
if (td->td_compression != COMPRESSION_SGILOG) {
164
sprintf(emsg, "Sorry, LogL data must have %s=%d",
165
"Compression", COMPRESSION_SGILOG);
169
case PHOTOMETRIC_LOGLUV:
170
if (td->td_compression != COMPRESSION_SGILOG &&
171
td->td_compression != COMPRESSION_SGILOG24) {
172
sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
173
"Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
176
if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
177
sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
178
"Planarconfiguration", td->td_planarconfig);
182
case PHOTOMETRIC_CIELAB:
185
sprintf(emsg, "Sorry, can not handle image with %s=%d",
186
photoTag, photometric);
193
TIFFRGBAImageEnd(TIFFRGBAImage* img)
196
_TIFFfree(img->Map), img->Map = NULL;
198
_TIFFfree(img->BWmap), img->BWmap = NULL;
200
_TIFFfree(img->PALmap), img->PALmap = NULL;
202
_TIFFfree(img->ycbcr), img->ycbcr = NULL;
204
_TIFFfree(img->cielab), img->cielab = NULL;
206
_TIFFfree( img->redcmap );
207
_TIFFfree( img->greencmap );
208
_TIFFfree( img->bluecmap );
213
isCCITTCompression(TIFF* tif)
216
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
217
return (compress == COMPRESSION_CCITTFAX3 ||
218
compress == COMPRESSION_CCITTFAX4 ||
219
compress == COMPRESSION_CCITTRLE ||
220
compress == COMPRESSION_CCITTRLEW);
224
TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
231
uint16 *red_orig, *green_orig, *blue_orig;
234
/* Initialize to normal values */
238
img->greencmap = NULL;
239
img->bluecmap = NULL;
240
img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
243
img->stoponerr = stop;
244
TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
245
switch (img->bitspersample) {
253
sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
258
TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
259
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
260
&extrasamples, &sampleinfo);
261
if (extrasamples >= 1)
263
switch (sampleinfo[0]) {
264
case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */
265
if (img->samplesperpixel > 3) /* correct info about alpha channel */
266
img->alpha = EXTRASAMPLE_ASSOCALPHA;
268
case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
269
case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
270
img->alpha = sampleinfo[0];
275
#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
276
if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
277
img->photometric = PHOTOMETRIC_MINISWHITE;
279
if( extrasamples == 0
280
&& img->samplesperpixel == 4
281
&& img->photometric == PHOTOMETRIC_RGB )
283
img->alpha = EXTRASAMPLE_ASSOCALPHA;
288
colorchannels = img->samplesperpixel - extrasamples;
289
TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
290
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
291
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
292
switch (colorchannels) {
294
if (isCCITTCompression(tif))
295
img->photometric = PHOTOMETRIC_MINISWHITE;
297
img->photometric = PHOTOMETRIC_MINISBLACK;
300
img->photometric = PHOTOMETRIC_RGB;
303
sprintf(emsg, "Missing needed %s tag", photoTag);
307
switch (img->photometric) {
308
case PHOTOMETRIC_PALETTE:
309
if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
310
&red_orig, &green_orig, &blue_orig)) {
311
sprintf(emsg, "Missing required \"Colormap\" tag");
315
/* copy the colormaps so we can modify them */
316
n_color = (1L << img->bitspersample);
317
img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
318
img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
319
img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
320
if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
321
sprintf(emsg, "Out of memory for colormap copy");
325
_TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
326
_TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
327
_TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
330
case PHOTOMETRIC_MINISWHITE:
331
case PHOTOMETRIC_MINISBLACK:
332
if (planarconfig == PLANARCONFIG_CONTIG
333
&& img->samplesperpixel != 1
334
&& img->bitspersample < 8 ) {
336
"Sorry, can not handle contiguous data with %s=%d, "
337
"and %s=%d and Bits/Sample=%d",
338
photoTag, img->photometric,
339
"Samples/pixel", img->samplesperpixel,
344
case PHOTOMETRIC_YCBCR:
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_JPEG:
352
* TODO: when complete tests verify complete desubsampling
353
* and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
354
* favor of tif_getimage.c native handling
356
TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
357
img->photometric = PHOTOMETRIC_RGB;
364
* TODO: if at all meaningful and useful, make more complete
365
* support check here, or better still, refactor to let supporting
366
* code decide whether there is support and what meaningfull
370
case PHOTOMETRIC_RGB:
371
if (colorchannels < 3) {
372
sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
373
"Color channels", colorchannels);
377
case PHOTOMETRIC_SEPARATED:
380
TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
381
if (inkset != INKSET_CMYK) {
382
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
386
if (img->samplesperpixel < 4) {
387
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
388
"Samples/pixel", img->samplesperpixel);
393
case PHOTOMETRIC_LOGL:
394
if (compress != COMPRESSION_SGILOG) {
395
sprintf(emsg, "Sorry, LogL data must have %s=%d",
396
"Compression", COMPRESSION_SGILOG);
399
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
400
img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
401
img->bitspersample = 8;
403
case PHOTOMETRIC_LOGLUV:
404
if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
405
sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
406
"Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
409
if (planarconfig != PLANARCONFIG_CONTIG) {
410
sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
411
"Planarconfiguration", planarconfig);
414
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
415
img->photometric = PHOTOMETRIC_RGB; /* little white lie */
416
img->bitspersample = 8;
418
case PHOTOMETRIC_CIELAB:
421
sprintf(emsg, "Sorry, can not handle image with %s=%d",
422
photoTag, img->photometric);
430
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
431
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
432
TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
434
!(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
436
if (!PickContigCase(img)) {
437
sprintf(emsg, "Sorry, can not handle image");
441
if (!PickSeparateCase(img)) {
442
sprintf(emsg, "Sorry, can not handle image");
450
TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
452
if (img->get == NULL) {
453
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
456
if (img->put.any == NULL) {
457
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
458
"No \"put\" routine setupl; probably can not handle image format");
461
return (*img->get)(img, raster, w, h);
465
* Read the specified image into an ABGR-format rastertaking in account
466
* specified orientation.
469
TIFFReadRGBAImageOriented(TIFF* tif,
470
uint32 rwidth, uint32 rheight, uint32* raster,
471
int orientation, int stop)
473
char emsg[1024] = "";
477
if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
478
img.req_orientation = orientation;
479
/* XXX verify rwidth and rheight against width and height */
480
ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
482
TIFFRGBAImageEnd(&img);
484
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
491
* Read the specified image into an ABGR-format raster. Use bottom left
492
* origin for raster by default.
495
TIFFReadRGBAImage(TIFF* tif,
496
uint32 rwidth, uint32 rheight, uint32* raster, int stop)
498
return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
499
ORIENTATION_BOTLEFT, stop);
503
setorientation(TIFFRGBAImage* img)
505
switch (img->orientation) {
506
case ORIENTATION_TOPLEFT:
507
case ORIENTATION_LEFTTOP:
508
if (img->req_orientation == ORIENTATION_TOPRIGHT ||
509
img->req_orientation == ORIENTATION_RIGHTTOP)
510
return FLIP_HORIZONTALLY;
511
else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
512
img->req_orientation == ORIENTATION_RIGHTBOT)
513
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
514
else if (img->req_orientation == ORIENTATION_BOTLEFT ||
515
img->req_orientation == ORIENTATION_LEFTBOT)
516
return FLIP_VERTICALLY;
519
case ORIENTATION_TOPRIGHT:
520
case ORIENTATION_RIGHTTOP:
521
if (img->req_orientation == ORIENTATION_TOPLEFT ||
522
img->req_orientation == ORIENTATION_LEFTTOP)
523
return FLIP_HORIZONTALLY;
524
else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
525
img->req_orientation == ORIENTATION_RIGHTBOT)
526
return FLIP_VERTICALLY;
527
else if (img->req_orientation == ORIENTATION_BOTLEFT ||
528
img->req_orientation == ORIENTATION_LEFTBOT)
529
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
532
case ORIENTATION_BOTRIGHT:
533
case ORIENTATION_RIGHTBOT:
534
if (img->req_orientation == ORIENTATION_TOPLEFT ||
535
img->req_orientation == ORIENTATION_LEFTTOP)
536
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
537
else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
538
img->req_orientation == ORIENTATION_RIGHTTOP)
539
return FLIP_VERTICALLY;
540
else if (img->req_orientation == ORIENTATION_BOTLEFT ||
541
img->req_orientation == ORIENTATION_LEFTBOT)
542
return FLIP_HORIZONTALLY;
545
case ORIENTATION_BOTLEFT:
546
case ORIENTATION_LEFTBOT:
547
if (img->req_orientation == ORIENTATION_TOPLEFT ||
548
img->req_orientation == ORIENTATION_LEFTTOP)
549
return FLIP_VERTICALLY;
550
else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
551
img->req_orientation == ORIENTATION_RIGHTTOP)
552
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
553
else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
554
img->req_orientation == ORIENTATION_RIGHTBOT)
555
return FLIP_HORIZONTALLY;
558
default: /* NOTREACHED */
564
* Get an tile-organized image that has
565
* PlanarConfiguration contiguous if SamplesPerPixel > 1
567
* SamplesPerPixel == 1
570
gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
572
TIFF* tif = img->tif;
573
tileContigRoutine put = img->put.contig;
574
uint32 col, row, y, rowstoread;
578
int32 fromskew, toskew;
582
buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
584
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
587
_TIFFmemset(buf, 0, TIFFTileSize(tif));
588
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
589
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
591
flip = setorientation(img);
592
if (flip & FLIP_VERTICALLY) {
594
toskew = -(int32)(tw + w);
598
toskew = -(int32)(tw - w);
601
for (row = 0; row < h; row += nrow)
603
rowstoread = th - (row + img->row_offset) % th;
604
nrow = (row + rowstoread > h ? h - row : rowstoread);
605
for (col = 0; col < w; col += tw)
607
if (TIFFReadTile(tif, buf, col+img->col_offset,
608
row+img->row_offset, 0, 0) < 0 && img->stoponerr)
614
pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
619
* Tile is clipped horizontally. Calculate
620
* visible portion and skewing factors.
622
uint32 npix = w - col;
623
fromskew = tw - npix;
624
(*put)(img, raster+y*w+col, col, y,
625
npix, nrow, fromskew, toskew + fromskew, buf + pos);
629
(*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
633
y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
637
if (flip & FLIP_HORIZONTALLY) {
640
for (line = 0; line < h; line++) {
641
uint32 *left = raster + (line * w);
642
uint32 *right = left + w - 1;
644
while ( left < right ) {
657
* Get an tile-organized image that has
658
* SamplesPerPixel > 1
659
* PlanarConfiguration separated
660
* We assume that all such images are RGB.
663
gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
665
TIFF* tif = img->tif;
666
tileSeparateRoutine put = img->put.separate;
667
uint32 col, row, y, rowstoread;
676
int32 fromskew, toskew;
677
int alpha = img->alpha;
681
tilesize = TIFFTileSize(tif);
682
buf = (unsigned char*) _TIFFmalloc((alpha?4:3)*tilesize);
684
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
687
_TIFFmemset(buf, 0, (alpha?4:3)*tilesize);
691
pa = (alpha?(p2+tilesize):NULL);
692
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
693
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
695
flip = setorientation(img);
696
if (flip & FLIP_VERTICALLY) {
698
toskew = -(int32)(tw + w);
702
toskew = -(int32)(tw - w);
705
for (row = 0; row < h; row += nrow)
707
rowstoread = th - (row + img->row_offset) % th;
708
nrow = (row + rowstoread > h ? h - row : rowstoread);
709
for (col = 0; col < w; col += tw)
711
if (TIFFReadTile(tif, p0, col+img->col_offset,
712
row+img->row_offset,0,0) < 0 && img->stoponerr)
717
if (TIFFReadTile(tif, p1, col+img->col_offset,
718
row+img->row_offset,0,1) < 0 && img->stoponerr)
723
if (TIFFReadTile(tif, p2, col+img->col_offset,
724
row+img->row_offset,0,2) < 0 && img->stoponerr)
731
if (TIFFReadTile(tif,pa,col+img->col_offset,
732
row+img->row_offset,0,3) < 0 && img->stoponerr)
739
pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
744
* Tile is clipped horizontally. Calculate
745
* visible portion and skewing factors.
747
uint32 npix = w - col;
748
fromskew = tw - npix;
749
(*put)(img, raster+y*w+col, col, y,
750
npix, nrow, fromskew, toskew + fromskew,
751
p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
753
(*put)(img, raster+y*w+col, col, y,
754
tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
758
y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
761
if (flip & FLIP_HORIZONTALLY) {
764
for (line = 0; line < h; line++) {
765
uint32 *left = raster + (line * w);
766
uint32 *right = left + w - 1;
768
while ( left < right ) {
782
* Get a strip-organized image that has
783
* PlanarConfiguration contiguous if SamplesPerPixel > 1
785
* SamplesPerPixel == 1
788
gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
790
TIFF* tif = img->tif;
791
tileContigRoutine put = img->put.contig;
792
uint32 row, y, nrow, nrowsub, rowstoread;
796
uint16 subsamplinghor,subsamplingver;
797
uint32 imagewidth = img->width;
799
int32 fromskew, toskew;
802
buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
804
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
807
_TIFFmemset(buf, 0, TIFFStripSize(tif));
809
flip = setorientation(img);
810
if (flip & FLIP_VERTICALLY) {
812
toskew = -(int32)(w + w);
815
toskew = -(int32)(w - w);
818
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
819
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
820
scanline = TIFFNewScanlineSize(tif);
821
fromskew = (w < imagewidth ? imagewidth - w : 0);
822
for (row = 0; row < h; row += nrow)
824
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
825
nrow = (row + rowstoread > h ? h - row : rowstoread);
827
if ((nrowsub%subsamplingver)!=0)
828
nrowsub+=subsamplingver-nrowsub%subsamplingver;
829
if (TIFFReadEncodedStrip(tif,
830
TIFFComputeStrip(tif,row+img->row_offset, 0),
832
((row + img->row_offset)%rowsperstrip + nrowsub) * scanline) < 0
839
pos = ((row + img->row_offset) % rowsperstrip) * scanline;
840
(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
841
y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
844
if (flip & FLIP_HORIZONTALLY) {
847
for (line = 0; line < h; line++) {
848
uint32 *left = raster + (line * w);
849
uint32 *right = left + w - 1;
851
while ( left < right ) {
865
* Get a strip-organized image with
866
* SamplesPerPixel > 1
867
* PlanarConfiguration separated
868
* We assume that all such images are RGB.
871
gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
873
TIFF* tif = img->tif;
874
tileSeparateRoutine put = img->put.separate;
876
unsigned char *p0, *p1, *p2, *pa;
877
uint32 row, y, nrow, rowstoread;
880
uint32 rowsperstrip, offset_row;
881
uint32 imagewidth = img->width;
883
int32 fromskew, toskew;
884
int alpha = img->alpha;
887
stripsize = TIFFStripSize(tif);
888
p0 = buf = (unsigned char *)_TIFFmalloc((alpha?4:3)*stripsize);
890
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
893
_TIFFmemset(buf, 0, (alpha?4:3)*stripsize);
896
pa = (alpha?(p2+stripsize):NULL);
898
flip = setorientation(img);
899
if (flip & FLIP_VERTICALLY) {
901
toskew = -(int32)(w + w);
905
toskew = -(int32)(w - w);
908
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
909
scanline = TIFFScanlineSize(tif);
910
fromskew = (w < imagewidth ? imagewidth - w : 0);
911
for (row = 0; row < h; row += nrow)
913
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
914
nrow = (row + rowstoread > h ? h - row : rowstoread);
915
offset_row = row + img->row_offset;
916
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
917
p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
923
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
924
p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
930
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
931
p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
939
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3),
940
pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) < 0
948
pos = ((row + img->row_offset) % rowsperstrip) * scanline;
949
(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
950
p2 + pos, (alpha?(pa+pos):NULL));
951
y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
954
if (flip & FLIP_HORIZONTALLY) {
957
for (line = 0; line < h; line++) {
958
uint32 *left = raster + (line * w);
959
uint32 *right = left + w - 1;
961
while ( left < right ) {
975
* The following routines move decoded data returned
976
* from the TIFF library into rasters filled with packed
977
* ABGR pixels (i.e. suitable for passing to lrecwrite.)
979
* The routines have been created according to the most
980
* important cases and optimized. PickContigCase and
981
* PickSeparateCase analyze the parameters and select
982
* the appropriate "get" and "put" routine to use.
984
#define REPEAT8(op) REPEAT4(op); REPEAT4(op)
985
#define REPEAT4(op) REPEAT2(op); REPEAT2(op)
986
#define REPEAT2(op) op; op
987
#define CASE8(x,op) \
989
case 7: op; case 6: op; case 5: op; \
990
case 4: op; case 3: op; case 2: op; \
993
#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
996
#define UNROLL8(w, op1, op2) { \
998
for (_x = w; _x >= 8; _x -= 8) { \
1007
#define UNROLL4(w, op1, op2) { \
1009
for (_x = w; _x >= 4; _x -= 4) { \
1018
#define UNROLL2(w, op1, op2) { \
1020
for (_x = w; _x >= 2; _x -= 2) { \
1030
#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1031
#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1033
#define A1 (((uint32)0xffL)<<24)
1034
#define PACK(r,g,b) \
1035
((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1036
#define PACK4(r,g,b,a) \
1037
((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1038
#define W2B(v) (((v)>>8)&0xff)
1039
#define PACKW(r,g,b) \
1040
((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1041
#define PACKW4(r,g,b,a) \
1042
((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1044
#define DECLAREContigPutFunc(name) \
1046
TIFFRGBAImage* img, \
1048
uint32 x, uint32 y, \
1049
uint32 w, uint32 h, \
1050
int32 fromskew, int32 toskew, \
1055
* 8-bit palette => colormap/RGB
1057
DECLAREContigPutFunc(put8bitcmaptile)
1059
uint32** PALmap = img->PALmap;
1060
int samplesperpixel = img->samplesperpixel;
1064
for (x = w; x-- > 0;)
1066
*cp++ = PALmap[*pp][0];
1067
pp += samplesperpixel;
1075
* 4-bit palette => colormap/RGB
1077
DECLAREContigPutFunc(put4bitcmaptile)
1079
uint32** PALmap = img->PALmap;
1085
UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
1092
* 2-bit palette => colormap/RGB
1094
DECLAREContigPutFunc(put2bitcmaptile)
1096
uint32** PALmap = img->PALmap;
1102
UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
1109
* 1-bit palette => colormap/RGB
1111
DECLAREContigPutFunc(put1bitcmaptile)
1113
uint32** PALmap = img->PALmap;
1119
UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
1126
* 8-bit greyscale => colormap/RGB
1128
DECLAREContigPutFunc(putgreytile)
1130
int samplesperpixel = img->samplesperpixel;
1131
uint32** BWmap = img->BWmap;
1135
for (x = w; x-- > 0;)
1137
*cp++ = BWmap[*pp][0];
1138
pp += samplesperpixel;
1146
* 16-bit greyscale => colormap/RGB
1148
DECLAREContigPutFunc(put16bitbwtile)
1150
int samplesperpixel = img->samplesperpixel;
1151
uint32** BWmap = img->BWmap;
1155
uint16 *wp = (uint16 *) pp;
1157
for (x = w; x-- > 0;)
1159
/* use high order byte of 16bit value */
1161
*cp++ = BWmap[*wp >> 8][0];
1162
pp += 2 * samplesperpixel;
1163
wp += samplesperpixel;
1171
* 1-bit bilevel => colormap/RGB
1173
DECLAREContigPutFunc(put1bitbwtile)
1175
uint32** BWmap = img->BWmap;
1181
UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
1188
* 2-bit greyscale => colormap/RGB
1190
DECLAREContigPutFunc(put2bitbwtile)
1192
uint32** BWmap = img->BWmap;
1198
UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
1205
* 4-bit greyscale => colormap/RGB
1207
DECLAREContigPutFunc(put4bitbwtile)
1209
uint32** BWmap = img->BWmap;
1215
UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
1222
* 8-bit packed samples, no Map => RGB
1224
DECLAREContigPutFunc(putRGBcontig8bittile)
1226
int samplesperpixel = img->samplesperpixel;
1229
fromskew *= samplesperpixel;
1232
*cp++ = PACK(pp[0], pp[1], pp[2]);
1233
pp += samplesperpixel);
1240
* 8-bit packed samples => RGBA w/ associated alpha
1241
* (known to have Map == NULL)
1243
DECLAREContigPutFunc(putRGBAAcontig8bittile)
1245
int samplesperpixel = img->samplesperpixel;
1248
fromskew *= samplesperpixel;
1251
*cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
1252
pp += samplesperpixel);
1259
* 8-bit packed samples => RGBA w/ unassociated alpha
1260
* (known to have Map == NULL)
1262
DECLAREContigPutFunc(putRGBUAcontig8bittile)
1264
int samplesperpixel = img->samplesperpixel;
1266
fromskew *= samplesperpixel;
1269
for (x = w; x-- > 0;) {
1271
r = (a*pp[0] + 127) / 255;
1272
g = (a*pp[1] + 127) / 255;
1273
b = (a*pp[2] + 127) / 255;
1274
*cp++ = PACK4(r,g,b,a);
1275
pp += samplesperpixel;
1283
* 16-bit packed samples => RGB
1285
DECLAREContigPutFunc(putRGBcontig16bittile)
1287
int samplesperpixel = img->samplesperpixel;
1288
uint16 *wp = (uint16 *)pp;
1290
fromskew *= samplesperpixel;
1292
for (x = w; x-- > 0;) {
1293
*cp++ = PACKW(wp[0],wp[1],wp[2]);
1294
wp += samplesperpixel;
1302
* 16-bit packed samples => RGBA w/ associated alpha
1303
* (known to have Map == NULL)
1305
DECLAREContigPutFunc(putRGBAAcontig16bittile)
1307
int samplesperpixel = img->samplesperpixel;
1308
uint16 *wp = (uint16 *)pp;
1310
fromskew *= samplesperpixel;
1312
for (x = w; x-- > 0;) {
1313
*cp++ = PACKW4(wp[0],wp[1],wp[2],wp[3]);
1314
wp += samplesperpixel;
1322
* 16-bit packed samples => RGBA w/ unassociated alpha
1323
* (known to have Map == NULL)
1325
DECLAREContigPutFunc(putRGBUAcontig16bittile)
1327
int samplesperpixel = img->samplesperpixel;
1328
uint16 *wp = (uint16 *)pp;
1330
fromskew *= samplesperpixel;
1333
for (x = w; x-- > 0;) {
1335
r = (a*W2B(wp[0]) + 127) / 255;
1336
g = (a*W2B(wp[1]) + 127) / 255;
1337
b = (a*W2B(wp[2]) + 127) / 255;
1338
*cp++ = PACK4(r,g,b,a);
1339
wp += samplesperpixel;
1347
* 8-bit packed CMYK samples w/o Map => RGB
1349
* NB: The conversion of CMYK->RGB is *very* crude.
1351
DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
1353
int samplesperpixel = img->samplesperpixel;
1357
fromskew *= samplesperpixel;
1361
r = (k*(255-pp[0]))/255;
1362
g = (k*(255-pp[1]))/255;
1363
b = (k*(255-pp[2]))/255;
1364
*cp++ = PACK(r, g, b);
1365
pp += samplesperpixel);
1372
* 8-bit packed CMYK samples w/Map => RGB
1374
* NB: The conversion of CMYK->RGB is *very* crude.
1376
DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
1378
int samplesperpixel = img->samplesperpixel;
1379
TIFFRGBValue* Map = img->Map;
1383
fromskew *= samplesperpixel;
1385
for (x = w; x-- > 0;) {
1387
r = (k*(255-pp[0]))/255;
1388
g = (k*(255-pp[1]))/255;
1389
b = (k*(255-pp[2]))/255;
1390
*cp++ = PACK(Map[r], Map[g], Map[b]);
1391
pp += samplesperpixel;
1398
#define DECLARESepPutFunc(name) \
1400
TIFFRGBAImage* img,\
1402
uint32 x, uint32 y, \
1403
uint32 w, uint32 h,\
1404
int32 fromskew, int32 toskew,\
1405
unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1409
* 8-bit unpacked samples => RGB
1411
DECLARESepPutFunc(putRGBseparate8bittile)
1413
(void) img; (void) x; (void) y; (void) a;
1415
UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
1416
SKEW(r, g, b, fromskew);
1422
* 8-bit unpacked samples => RGBA w/ associated alpha
1424
DECLARESepPutFunc(putRGBAAseparate8bittile)
1426
(void) img; (void) x; (void) y;
1428
UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
1429
SKEW4(r, g, b, a, fromskew);
1435
* 8-bit unpacked samples => RGBA w/ unassociated alpha
1437
DECLARESepPutFunc(putRGBUAseparate8bittile)
1439
(void) img; (void) y;
1441
uint32 rv, gv, bv, av;
1442
for (x = w; x-- > 0;) {
1444
rv = (av* *r++ + 127) / 255;
1445
gv = (av* *g++ + 127) / 255;
1446
bv = (av* *b++ + 127) / 255;
1447
*cp++ = PACK4(rv,gv,bv,av);
1449
SKEW4(r, g, b, a, fromskew);
1455
* 16-bit unpacked samples => RGB
1457
DECLARESepPutFunc(putRGBseparate16bittile)
1459
uint16 *wr = (uint16*) r;
1460
uint16 *wg = (uint16*) g;
1461
uint16 *wb = (uint16*) b;
1462
(void) img; (void) y; (void) a;
1464
for (x = 0; x < w; x++)
1465
*cp++ = PACKW(*wr++,*wg++,*wb++);
1466
SKEW(wr, wg, wb, fromskew);
1472
* 16-bit unpacked samples => RGBA w/ associated alpha
1474
DECLARESepPutFunc(putRGBAAseparate16bittile)
1476
uint16 *wr = (uint16*) r;
1477
uint16 *wg = (uint16*) g;
1478
uint16 *wb = (uint16*) b;
1479
uint16 *wa = (uint16*) a;
1480
(void) img; (void) y;
1482
for (x = 0; x < w; x++)
1483
*cp++ = PACKW4(*wr++,*wg++,*wb++,*wa++);
1484
SKEW4(wr, wg, wb, wa, fromskew);
1490
* 16-bit unpacked samples => RGBA w/ unassociated alpha
1492
DECLARESepPutFunc(putRGBUAseparate16bittile)
1494
uint16 *wr = (uint16*) r;
1495
uint16 *wg = (uint16*) g;
1496
uint16 *wb = (uint16*) b;
1497
uint16 *wa = (uint16*) a;
1498
(void) img; (void) y;
1501
for (x = w; x-- > 0;) {
1503
r = (a*W2B(*wr++) + 127) / 255;
1504
g = (a*W2B(*wg++) + 127) / 255;
1505
b = (a*W2B(*wb++) + 127) / 255;
1506
*cp++ = PACK4(r,g,b,a);
1508
SKEW4(wr, wg, wb, wa, fromskew);
1514
* 8-bit packed CIE L*a*b 1976 samples => RGB
1516
DECLAREContigPutFunc(putcontig8bitCIELab)
1523
for (x = w; x-- > 0;) {
1524
TIFFCIELabToXYZ(img->cielab,
1525
(unsigned char)pp[0],
1529
TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
1530
*cp++ = PACK(r, g, b);
1539
* YCbCr -> RGB conversion and packing routines.
1542
#define YCbCrtoRGB(dst, Y) { \
1544
TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1545
dst = PACK(r, g, b); \
1549
* 8-bit packed YCbCr samples => RGB
1550
* This function is generic for different sampling sizes,
1551
* and can handle blocks sizes that aren't multiples of the
1552
* sampling size. However, it is substantially less optimized
1553
* than the specific sampling cases. It is used as a fallback
1554
* for difficult blocks.
1557
static void putcontig8bitYCbCrGenericTile(
1562
int32 fromskew, int32 toskew,
1568
uint32* cp1 = cp+w+toskew;
1569
uint32* cp2 = cp1+w+toskew;
1570
uint32* cp3 = cp2+w+toskew;
1571
int32 incr = 3*w+4*toskew;
1573
int group_size = v_group * h_group + 2;
1576
fromskew = (fromskew * group_size) / h_group;
1578
for( yy = 0; yy < h; yy++ )
1580
unsigned char *pp_line;
1581
int y_line_group = yy / v_group;
1582
int y_remainder = yy - y_line_group * v_group;
1584
pp_line = pp + v_line_group *
1587
for( xx = 0; xx < w; xx++ )
1592
for (; h >= 4; h -= 4) {
1598
YCbCrtoRGB(cp [0], pp[ 0]);
1599
YCbCrtoRGB(cp [1], pp[ 1]);
1600
YCbCrtoRGB(cp [2], pp[ 2]);
1601
YCbCrtoRGB(cp [3], pp[ 3]);
1602
YCbCrtoRGB(cp1[0], pp[ 4]);
1603
YCbCrtoRGB(cp1[1], pp[ 5]);
1604
YCbCrtoRGB(cp1[2], pp[ 6]);
1605
YCbCrtoRGB(cp1[3], pp[ 7]);
1606
YCbCrtoRGB(cp2[0], pp[ 8]);
1607
YCbCrtoRGB(cp2[1], pp[ 9]);
1608
YCbCrtoRGB(cp2[2], pp[10]);
1609
YCbCrtoRGB(cp2[3], pp[11]);
1610
YCbCrtoRGB(cp3[0], pp[12]);
1611
YCbCrtoRGB(cp3[1], pp[13]);
1612
YCbCrtoRGB(cp3[2], pp[14]);
1613
YCbCrtoRGB(cp3[3], pp[15]);
1615
cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1618
cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1625
* 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1627
DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
1629
uint32* cp1 = cp+w+toskew;
1630
uint32* cp2 = cp1+w+toskew;
1631
uint32* cp3 = cp2+w+toskew;
1632
int32 incr = 3*w+4*toskew;
1635
/* adjust fromskew */
1636
fromskew = (fromskew * 18) / 4;
1637
if ((h & 3) == 0 && (w & 3) == 0) {
1638
for (; h >= 4; h -= 4) {
1644
YCbCrtoRGB(cp [0], pp[ 0]);
1645
YCbCrtoRGB(cp [1], pp[ 1]);
1646
YCbCrtoRGB(cp [2], pp[ 2]);
1647
YCbCrtoRGB(cp [3], pp[ 3]);
1648
YCbCrtoRGB(cp1[0], pp[ 4]);
1649
YCbCrtoRGB(cp1[1], pp[ 5]);
1650
YCbCrtoRGB(cp1[2], pp[ 6]);
1651
YCbCrtoRGB(cp1[3], pp[ 7]);
1652
YCbCrtoRGB(cp2[0], pp[ 8]);
1653
YCbCrtoRGB(cp2[1], pp[ 9]);
1654
YCbCrtoRGB(cp2[2], pp[10]);
1655
YCbCrtoRGB(cp2[3], pp[11]);
1656
YCbCrtoRGB(cp3[0], pp[12]);
1657
YCbCrtoRGB(cp3[1], pp[13]);
1658
YCbCrtoRGB(cp3[2], pp[14]);
1659
YCbCrtoRGB(cp3[3], pp[15]);
1661
cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1664
cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1669
for (x = w; x > 0;) {
1675
default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
1676
case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
1677
case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1678
case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1682
default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
1683
case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
1684
case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1685
case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1689
default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
1690
case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
1691
case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1692
case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1696
default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
1697
case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
1698
case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1699
case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1703
cp += x; cp1 += x; cp2 += x; cp3 += x;
1707
cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
1715
cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1722
* 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1724
DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
1726
uint32* cp1 = cp+w+toskew;
1727
int32 incr = 2*toskew+w;
1730
fromskew = (fromskew * 10) / 4;
1731
if ((h & 3) == 0 && (w & 1) == 0) {
1732
for (; h >= 2; h -= 2) {
1738
YCbCrtoRGB(cp [0], pp[0]);
1739
YCbCrtoRGB(cp [1], pp[1]);
1740
YCbCrtoRGB(cp [2], pp[2]);
1741
YCbCrtoRGB(cp [3], pp[3]);
1742
YCbCrtoRGB(cp1[0], pp[4]);
1743
YCbCrtoRGB(cp1[1], pp[5]);
1744
YCbCrtoRGB(cp1[2], pp[6]);
1745
YCbCrtoRGB(cp1[3], pp[7]);
1750
cp += incr, cp1 += incr;
1755
for (x = w; x > 0;) {
1761
default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1762
case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1766
default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1767
case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1771
default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1772
case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1776
default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1777
case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1793
cp += incr, cp1 += incr;
1800
* 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1802
DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
1805
/* XXX adjust fromskew */
1812
YCbCrtoRGB(cp [0], pp[0]);
1813
YCbCrtoRGB(cp [1], pp[1]);
1814
YCbCrtoRGB(cp [2], pp[2]);
1815
YCbCrtoRGB(cp [3], pp[3]);
1827
case 3: YCbCrtoRGB(cp [2], pp[2]);
1828
case 2: YCbCrtoRGB(cp [1], pp[1]);
1829
case 1: YCbCrtoRGB(cp [0], pp[0]);
1844
* 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1846
DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
1850
fromskew = (fromskew / 2) * 6;
1857
YCbCrtoRGB(cp[0], pp[0]);
1858
YCbCrtoRGB(cp[1], pp[1]);
1859
YCbCrtoRGB(cp2[0], pp[2]);
1860
YCbCrtoRGB(cp2[1], pp[3]);
1869
YCbCrtoRGB(cp[0], pp[0]);
1870
YCbCrtoRGB(cp2[0], pp[2]);
1885
YCbCrtoRGB(cp[0], pp[0]);
1886
YCbCrtoRGB(cp[1], pp[1]);
1895
YCbCrtoRGB(cp[0], pp[0]);
1901
* 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
1903
DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
1906
fromskew = (fromskew * 4) / 2;
1913
YCbCrtoRGB(cp[0], pp[0]);
1914
YCbCrtoRGB(cp[1], pp[1]);
1925
YCbCrtoRGB(cp[0], pp[0]);
1937
* 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
1939
DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
1943
fromskew = (fromskew / 2) * 4;
1950
YCbCrtoRGB(cp[0], pp[0]);
1951
YCbCrtoRGB(cp2[0], pp[1]);
1966
YCbCrtoRGB(cp[0], pp[0]);
1974
* 8-bit packed YCbCr samples w/ no subsampling => RGB
1976
DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
1981
x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
1986
YCbCrtoRGB(*cp++, pp[0]);
1996
* 8-bit packed YCbCr samples w/ no subsampling => RGB
1998
DECLARESepPutFunc(putseparate8bitYCbCr11tile)
2002
/* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2007
TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
2008
*cp++ = PACK(dr,dg,db);
2010
SKEW(r, g, b, fromskew);
2017
initYCbCrConversion(TIFFRGBAImage* img)
2019
static char module[] = "initYCbCrConversion";
2021
float *luma, *refBlackWhite;
2023
if (img->ycbcr == NULL) {
2024
img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
2025
TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
2026
+ 4*256*sizeof (TIFFRGBValue)
2027
+ 2*256*sizeof (int)
2028
+ 3*256*sizeof (int32)
2030
if (img->ycbcr == NULL) {
2031
TIFFErrorExt(img->tif->tif_clientdata, module,
2032
"No space for YCbCr->RGB conversion state");
2037
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
2038
TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
2040
if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
2045
static tileContigRoutine
2046
initCIELabConversion(TIFFRGBAImage* img)
2048
static char module[] = "initCIELabConversion";
2054
img->cielab = (TIFFCIELabToRGB *)
2055
_TIFFmalloc(sizeof(TIFFCIELabToRGB));
2057
TIFFErrorExt(img->tif->tif_clientdata, module,
2058
"No space for CIE L*a*b*->RGB conversion state.");
2063
TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
2064
refWhite[1] = 100.0F;
2065
refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
2066
refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
2067
/ whitePoint[1] * refWhite[1];
2068
if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
2069
TIFFErrorExt(img->tif->tif_clientdata, module,
2070
"Failed to initialize CIE L*a*b*->RGB conversion state.");
2071
_TIFFfree(img->cielab);
2075
return putcontig8bitCIELab;
2079
* Greyscale images with less than 8 bits/sample are handled
2080
* with a table to avoid lots of shifts and masks. The table
2081
* is setup so that put*bwtile (below) can retrieve 8/bitspersample
2082
* pixel values simply by indexing into the table with one
2086
makebwmap(TIFFRGBAImage* img)
2088
TIFFRGBValue* Map = img->Map;
2089
int bitspersample = img->bitspersample;
2090
int nsamples = 8 / bitspersample;
2097
img->BWmap = (uint32**) _TIFFmalloc(
2098
256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2099
if (img->BWmap == NULL) {
2100
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
2103
p = (uint32*)(img->BWmap + 256);
2104
for (i = 0; i < 256; i++) {
2107
switch (bitspersample) {
2108
#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2140
* Construct a mapping table to convert from the range
2141
* of the data samples to [0,255] --for display. This
2142
* process also handles inverting B&W images when needed.
2145
setupMap(TIFFRGBAImage* img)
2149
range = (int32)((1L<<img->bitspersample)-1);
2151
/* treat 16 bit the same as eight bit */
2152
if( img->bitspersample == 16 )
2153
range = (int32) 255;
2155
img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
2156
if (img->Map == NULL) {
2157
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
2158
"No space for photometric conversion table");
2161
if (img->photometric == PHOTOMETRIC_MINISWHITE) {
2162
for (x = 0; x <= range; x++)
2163
img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
2165
for (x = 0; x <= range; x++)
2166
img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
2168
if (img->bitspersample <= 16 &&
2169
(img->photometric == PHOTOMETRIC_MINISBLACK ||
2170
img->photometric == PHOTOMETRIC_MINISWHITE)) {
2172
* Use photometric mapping table to construct
2173
* unpacking tables for samples <= 8 bits.
2175
if (!makebwmap(img))
2177
/* no longer need Map, free it */
2178
_TIFFfree(img->Map), img->Map = NULL;
2184
checkcmap(TIFFRGBAImage* img)
2186
uint16* r = img->redcmap;
2187
uint16* g = img->greencmap;
2188
uint16* b = img->bluecmap;
2189
long n = 1L<<img->bitspersample;
2192
if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
2198
cvtcmap(TIFFRGBAImage* img)
2200
uint16* r = img->redcmap;
2201
uint16* g = img->greencmap;
2202
uint16* b = img->bluecmap;
2205
for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
2206
#define CVT(x) ((uint16)((x)>>8))
2215
* Palette images with <= 8 bits/sample are handled
2216
* with a table to avoid lots of shifts and masks. The table
2217
* is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2218
* pixel values simply by indexing into the table with one
2222
makecmap(TIFFRGBAImage* img)
2224
int bitspersample = img->bitspersample;
2225
int nsamples = 8 / bitspersample;
2226
uint16* r = img->redcmap;
2227
uint16* g = img->greencmap;
2228
uint16* b = img->bluecmap;
2232
img->PALmap = (uint32**) _TIFFmalloc(
2233
256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2234
if (img->PALmap == NULL) {
2235
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
2238
p = (uint32*)(img->PALmap + 256);
2239
for (i = 0; i < 256; i++) {
2242
#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2243
switch (bitspersample) {
2274
* Construct any mapping table used
2275
* by the associated put routine.
2278
buildMap(TIFFRGBAImage* img)
2280
switch (img->photometric) {
2281
case PHOTOMETRIC_RGB:
2282
case PHOTOMETRIC_YCBCR:
2283
case PHOTOMETRIC_SEPARATED:
2284
if (img->bitspersample == 8)
2287
case PHOTOMETRIC_MINISBLACK:
2288
case PHOTOMETRIC_MINISWHITE:
2292
case PHOTOMETRIC_PALETTE:
2294
* Convert 16-bit colormap to 8-bit (unless it looks
2295
* like an old-style 8-bit colormap).
2297
if (checkcmap(img) == 16)
2300
TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
2302
* Use mapping table and colormap to construct
2303
* unpacking tables for samples < 8 bits.
2305
if (img->bitspersample <= 8 && !makecmap(img))
2313
* Select the appropriate conversion routine for packed data.
2316
PickContigCase(TIFFRGBAImage* img)
2318
img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
2319
img->put.contig = NULL;
2320
switch (img->photometric) {
2321
case PHOTOMETRIC_RGB:
2322
switch (img->bitspersample) {
2324
if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2325
img->put.contig = putRGBAAcontig8bittile;
2326
else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2328
img->put.contig = putRGBUAcontig8bittile;
2331
img->put.contig = putRGBcontig8bittile;
2334
if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2336
img->put.contig = putRGBAAcontig16bittile;
2338
else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2340
img->put.contig = putRGBUAcontig16bittile;
2344
img->put.contig = putRGBcontig16bittile;
2349
case PHOTOMETRIC_SEPARATED:
2350
if (buildMap(img)) {
2351
if (img->bitspersample == 8) {
2353
img->put.contig = putRGBcontig8bitCMYKtile;
2355
img->put.contig = putRGBcontig8bitCMYKMaptile;
2359
case PHOTOMETRIC_PALETTE:
2360
if (buildMap(img)) {
2361
switch (img->bitspersample) {
2363
img->put.contig = put8bitcmaptile;
2366
img->put.contig = put4bitcmaptile;
2369
img->put.contig = put2bitcmaptile;
2372
img->put.contig = put1bitcmaptile;
2377
case PHOTOMETRIC_MINISWHITE:
2378
case PHOTOMETRIC_MINISBLACK:
2379
if (buildMap(img)) {
2380
switch (img->bitspersample) {
2382
img->put.contig = put16bitbwtile;
2385
img->put.contig = putgreytile;
2388
img->put.contig = put4bitbwtile;
2391
img->put.contig = put2bitbwtile;
2394
img->put.contig = put1bitbwtile;
2399
case PHOTOMETRIC_YCBCR:
2400
if (img->bitspersample == 8)
2402
if (initYCbCrConversion(img)!=0)
2405
* The 6.0 spec says that subsampling must be
2406
* one of 1, 2, or 4, and that vertical subsampling
2407
* must always be <= horizontal subsampling; so
2408
* there are only a few possibilities and we just
2409
* enumerate the cases.
2410
* Joris: added support for the [1,2] case, nonetheless, to accomodate
2413
uint16 SubsamplingHor;
2414
uint16 SubsamplingVer;
2415
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
2416
switch ((SubsamplingHor<<4)|SubsamplingVer) {
2418
img->put.contig = putcontig8bitYCbCr44tile;
2421
img->put.contig = putcontig8bitYCbCr42tile;
2424
img->put.contig = putcontig8bitYCbCr41tile;
2427
img->put.contig = putcontig8bitYCbCr22tile;
2430
img->put.contig = putcontig8bitYCbCr21tile;
2433
img->put.contig = putcontig8bitYCbCr12tile;
2436
img->put.contig = putcontig8bitYCbCr11tile;
2442
case PHOTOMETRIC_CIELAB:
2443
if (buildMap(img)) {
2444
if (img->bitspersample == 8)
2445
img->put.contig = initCIELabConversion(img);
2449
return ((img->get!=NULL) && (img->put.contig!=NULL));
2453
* Select the appropriate conversion routine for unpacked data.
2455
* NB: we assume that unpacked single channel data is directed
2456
* to the "packed routines.
2459
PickSeparateCase(TIFFRGBAImage* img)
2461
img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
2462
img->put.separate = NULL;
2463
switch (img->photometric) {
2464
case PHOTOMETRIC_RGB:
2465
switch (img->bitspersample) {
2467
if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2468
img->put.separate = putRGBAAseparate8bittile;
2469
else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2471
img->put.separate = putRGBUAseparate8bittile;
2474
img->put.separate = putRGBseparate8bittile;
2477
if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2479
img->put.separate = putRGBAAseparate16bittile;
2481
else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2483
img->put.separate = putRGBUAseparate16bittile;
2487
img->put.separate = putRGBseparate16bittile;
2492
case PHOTOMETRIC_YCBCR:
2493
if ((img->bitspersample==8) && (img->samplesperpixel==3))
2495
if (initYCbCrConversion(img)!=0)
2498
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
2499
switch ((hs<<4)|vs) {
2501
img->put.separate = putseparate8bitYCbCr11tile;
2503
/* TODO: add other cases here */
2509
return ((img->get!=NULL) && (img->put.separate!=NULL));
2513
* Read a whole strip off data from the file, and convert to RGBA form.
2514
* If this is the last strip, then it will only contain the portion of
2515
* the strip that is actually within the image space. The result is
2516
* organized in bottom to top form.
2521
TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
2524
char emsg[1024] = "";
2527
uint32 rowsperstrip, rows_to_read;
2529
if( TIFFIsTiled( tif ) )
2531
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2532
"Can't use TIFFReadRGBAStrip() with tiled file.");
2536
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
2537
if( (row % rowsperstrip) != 0 )
2539
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2540
"Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2544
if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2546
img.row_offset = row;
2549
if( row + rowsperstrip > img.height )
2550
rows_to_read = img.height - row;
2552
rows_to_read = rowsperstrip;
2554
ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
2556
TIFFRGBAImageEnd(&img);
2558
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2566
* Read a whole tile off data from the file, and convert to RGBA form.
2567
* The returned RGBA data is organized from bottom to top of tile,
2568
* and may include zeroed areas if the tile extends off the image.
2572
TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
2575
char emsg[1024] = "";
2578
uint32 tile_xsize, tile_ysize;
2579
uint32 read_xsize, read_ysize;
2583
* Verify that our request is legal - on a tile file, and on a
2587
if( !TIFFIsTiled( tif ) )
2589
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2590
"Can't use TIFFReadRGBATile() with stripped file.");
2594
TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
2595
TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
2596
if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
2598
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2599
"Row/col passed to TIFFReadRGBATile() must be top"
2600
"left corner of a tile.");
2605
* Setup the RGBA reader.
2608
if (!TIFFRGBAImageOK(tif, emsg)
2609
|| !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2610
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2615
* The TIFFRGBAImageGet() function doesn't allow us to get off the
2616
* edge of the image, even to fill an otherwise valid tile. So we
2617
* figure out how much we can read, and fix up the tile buffer to
2618
* a full tile configuration afterwards.
2621
if( row + tile_ysize > img.height )
2622
read_ysize = img.height - row;
2624
read_ysize = tile_ysize;
2626
if( col + tile_xsize > img.width )
2627
read_xsize = img.width - col;
2629
read_xsize = tile_xsize;
2632
* Read the chunk of imagery.
2635
img.row_offset = row;
2636
img.col_offset = col;
2638
ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
2640
TIFFRGBAImageEnd(&img);
2643
* If our read was incomplete we will need to fix up the tile by
2644
* shifting the data around as if a full tile of data is being returned.
2646
* This is all the more complicated because the image is organized in
2647
* bottom to top format.
2650
if( read_xsize == tile_xsize && read_ysize == tile_ysize )
2653
for( i_row = 0; i_row < read_ysize; i_row++ ) {
2654
memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
2655
raster + (read_ysize - i_row - 1) * read_xsize,
2656
read_xsize * sizeof(uint32) );
2657
_TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
2658
0, sizeof(uint32) * (tile_xsize - read_xsize) );
2661
for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
2662
_TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
2663
0, sizeof(uint32) * tile_xsize );
2669
/* vim: set ts=8 sts=8 sw=8 noet: */