Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Tetragramm
GitHub Repository: Tetragramm/opencv
Path: blob/master/3rdparty/libtiff/tif_getimage.c
16337 views
1
/* $Id: tif_getimage.c,v 1.114 2017-11-17 20:21:00 erouault Exp $ */
2
3
/*
4
* Copyright (c) 1991-1997 Sam Leffler
5
* Copyright (c) 1991-1997 Silicon Graphics, Inc.
6
*
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.
14
*
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.
18
*
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
24
* OF THIS SOFTWARE.
25
*/
26
27
/*
28
* TIFF Library
29
*
30
* Read and return a packed RGBA image.
31
*/
32
#include "tiffiop.h"
33
#include <stdio.h>
34
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
42
static int BuildMapUaToAa(TIFFRGBAImage* img);
43
static int BuildMapBitdepth16To8(TIFFRGBAImage* img);
44
45
static const char photoTag[] = "PhotometricInterpretation";
46
47
/*
48
* Helper constants used in Orientation tag handling
49
*/
50
#define FLIP_VERTICALLY 0x01
51
#define FLIP_HORIZONTALLY 0x02
52
53
/*
54
* Color conversion constants. We will define display types here.
55
*/
56
57
static const TIFFDisplay display_sRGB = {
58
{ /* XYZ -> luminance matrix */
59
{ 3.2410F, -1.5374F, -0.4986F },
60
{ -0.9692F, 1.8760F, 0.0416F },
61
{ 0.0556F, -0.2040F, 1.0570F }
62
},
63
100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
64
255, 255, 255, /* Pixel values for ref. white */
65
1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */
66
2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */
67
};
68
69
/*
70
* Check the image to see if TIFFReadRGBAImage can deal with it.
71
* 1/0 is returned according to whether or not the image can
72
* be handled. If 0 is returned, emsg contains the reason
73
* why it is being rejected.
74
*/
75
int
76
TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
77
{
78
TIFFDirectory* td = &tif->tif_dir;
79
uint16 photometric;
80
int colorchannels;
81
82
if (!tif->tif_decodestatus) {
83
sprintf(emsg, "Sorry, requested compression method is not configured");
84
return (0);
85
}
86
switch (td->td_bitspersample) {
87
case 1:
88
case 2:
89
case 4:
90
case 8:
91
case 16:
92
break;
93
default:
94
sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
95
td->td_bitspersample);
96
return (0);
97
}
98
if (td->td_sampleformat == SAMPLEFORMAT_IEEEFP) {
99
sprintf(emsg, "Sorry, can not handle images with IEEE floating-point samples");
100
return (0);
101
}
102
colorchannels = td->td_samplesperpixel - td->td_extrasamples;
103
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
104
switch (colorchannels) {
105
case 1:
106
photometric = PHOTOMETRIC_MINISBLACK;
107
break;
108
case 3:
109
photometric = PHOTOMETRIC_RGB;
110
break;
111
default:
112
sprintf(emsg, "Missing needed %s tag", photoTag);
113
return (0);
114
}
115
}
116
switch (photometric) {
117
case PHOTOMETRIC_MINISWHITE:
118
case PHOTOMETRIC_MINISBLACK:
119
case PHOTOMETRIC_PALETTE:
120
if (td->td_planarconfig == PLANARCONFIG_CONTIG
121
&& td->td_samplesperpixel != 1
122
&& td->td_bitspersample < 8 ) {
123
sprintf(emsg,
124
"Sorry, can not handle contiguous data with %s=%d, "
125
"and %s=%d and Bits/Sample=%d",
126
photoTag, photometric,
127
"Samples/pixel", td->td_samplesperpixel,
128
td->td_bitspersample);
129
return (0);
130
}
131
/*
132
* We should likely validate that any extra samples are either
133
* to be ignored, or are alpha, and if alpha we should try to use
134
* them. But for now we won't bother with this.
135
*/
136
break;
137
case PHOTOMETRIC_YCBCR:
138
/*
139
* TODO: if at all meaningful and useful, make more complete
140
* support check here, or better still, refactor to let supporting
141
* code decide whether there is support and what meaningful
142
* error to return
143
*/
144
break;
145
case PHOTOMETRIC_RGB:
146
if (colorchannels < 3) {
147
sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
148
"Color channels", colorchannels);
149
return (0);
150
}
151
break;
152
case PHOTOMETRIC_SEPARATED:
153
{
154
uint16 inkset;
155
TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
156
if (inkset != INKSET_CMYK) {
157
sprintf(emsg,
158
"Sorry, can not handle separated image with %s=%d",
159
"InkSet", inkset);
160
return 0;
161
}
162
if (td->td_samplesperpixel < 4) {
163
sprintf(emsg,
164
"Sorry, can not handle separated image with %s=%d",
165
"Samples/pixel", td->td_samplesperpixel);
166
return 0;
167
}
168
break;
169
}
170
case PHOTOMETRIC_LOGL:
171
if (td->td_compression != COMPRESSION_SGILOG) {
172
sprintf(emsg, "Sorry, LogL data must have %s=%d",
173
"Compression", COMPRESSION_SGILOG);
174
return (0);
175
}
176
break;
177
case PHOTOMETRIC_LOGLUV:
178
if (td->td_compression != COMPRESSION_SGILOG &&
179
td->td_compression != COMPRESSION_SGILOG24) {
180
sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
181
"Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
182
return (0);
183
}
184
if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
185
sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
186
"Planarconfiguration", td->td_planarconfig);
187
return (0);
188
}
189
if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) {
190
sprintf(emsg,
191
"Sorry, can not handle image with %s=%d, %s=%d",
192
"Samples/pixel", td->td_samplesperpixel,
193
"colorchannels", colorchannels);
194
return 0;
195
}
196
break;
197
case PHOTOMETRIC_CIELAB:
198
if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) {
199
sprintf(emsg,
200
"Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
201
"Samples/pixel", td->td_samplesperpixel,
202
"colorchannels", colorchannels,
203
"Bits/sample", td->td_bitspersample);
204
return 0;
205
}
206
break;
207
default:
208
sprintf(emsg, "Sorry, can not handle image with %s=%d",
209
photoTag, photometric);
210
return (0);
211
}
212
return (1);
213
}
214
215
void
216
TIFFRGBAImageEnd(TIFFRGBAImage* img)
217
{
218
if (img->Map) {
219
_TIFFfree(img->Map);
220
img->Map = NULL;
221
}
222
if (img->BWmap) {
223
_TIFFfree(img->BWmap);
224
img->BWmap = NULL;
225
}
226
if (img->PALmap) {
227
_TIFFfree(img->PALmap);
228
img->PALmap = NULL;
229
}
230
if (img->ycbcr) {
231
_TIFFfree(img->ycbcr);
232
img->ycbcr = NULL;
233
}
234
if (img->cielab) {
235
_TIFFfree(img->cielab);
236
img->cielab = NULL;
237
}
238
if (img->UaToAa) {
239
_TIFFfree(img->UaToAa);
240
img->UaToAa = NULL;
241
}
242
if (img->Bitdepth16To8) {
243
_TIFFfree(img->Bitdepth16To8);
244
img->Bitdepth16To8 = NULL;
245
}
246
247
if( img->redcmap ) {
248
_TIFFfree( img->redcmap );
249
_TIFFfree( img->greencmap );
250
_TIFFfree( img->bluecmap );
251
img->redcmap = img->greencmap = img->bluecmap = NULL;
252
}
253
}
254
255
static int
256
isCCITTCompression(TIFF* tif)
257
{
258
uint16 compress;
259
TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
260
return (compress == COMPRESSION_CCITTFAX3 ||
261
compress == COMPRESSION_CCITTFAX4 ||
262
compress == COMPRESSION_CCITTRLE ||
263
compress == COMPRESSION_CCITTRLEW);
264
}
265
266
int
267
TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
268
{
269
uint16* sampleinfo;
270
uint16 extrasamples;
271
uint16 planarconfig;
272
uint16 compress;
273
int colorchannels;
274
uint16 *red_orig, *green_orig, *blue_orig;
275
int n_color;
276
277
if( !TIFFRGBAImageOK(tif, emsg) )
278
return 0;
279
280
/* Initialize to normal values */
281
img->row_offset = 0;
282
img->col_offset = 0;
283
img->redcmap = NULL;
284
img->greencmap = NULL;
285
img->bluecmap = NULL;
286
img->Map = NULL;
287
img->BWmap = NULL;
288
img->PALmap = NULL;
289
img->ycbcr = NULL;
290
img->cielab = NULL;
291
img->UaToAa = NULL;
292
img->Bitdepth16To8 = NULL;
293
img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
294
295
img->tif = tif;
296
img->stoponerr = stop;
297
TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
298
switch (img->bitspersample) {
299
case 1:
300
case 2:
301
case 4:
302
case 8:
303
case 16:
304
break;
305
default:
306
sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
307
img->bitspersample);
308
goto fail_return;
309
}
310
img->alpha = 0;
311
TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
312
TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
313
&extrasamples, &sampleinfo);
314
if (extrasamples >= 1)
315
{
316
switch (sampleinfo[0]) {
317
case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */
318
if (img->samplesperpixel > 3) /* correct info about alpha channel */
319
img->alpha = EXTRASAMPLE_ASSOCALPHA;
320
break;
321
case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
322
case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
323
img->alpha = sampleinfo[0];
324
break;
325
}
326
}
327
328
#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
329
if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
330
img->photometric = PHOTOMETRIC_MINISWHITE;
331
332
if( extrasamples == 0
333
&& img->samplesperpixel == 4
334
&& img->photometric == PHOTOMETRIC_RGB )
335
{
336
img->alpha = EXTRASAMPLE_ASSOCALPHA;
337
extrasamples = 1;
338
}
339
#endif
340
341
colorchannels = img->samplesperpixel - extrasamples;
342
TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
343
TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
344
if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
345
switch (colorchannels) {
346
case 1:
347
if (isCCITTCompression(tif))
348
img->photometric = PHOTOMETRIC_MINISWHITE;
349
else
350
img->photometric = PHOTOMETRIC_MINISBLACK;
351
break;
352
case 3:
353
img->photometric = PHOTOMETRIC_RGB;
354
break;
355
default:
356
sprintf(emsg, "Missing needed %s tag", photoTag);
357
goto fail_return;
358
}
359
}
360
switch (img->photometric) {
361
case PHOTOMETRIC_PALETTE:
362
if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
363
&red_orig, &green_orig, &blue_orig)) {
364
sprintf(emsg, "Missing required \"Colormap\" tag");
365
goto fail_return;
366
}
367
368
/* copy the colormaps so we can modify them */
369
n_color = (1U << img->bitspersample);
370
img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
371
img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
372
img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
373
if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
374
sprintf(emsg, "Out of memory for colormap copy");
375
goto fail_return;
376
}
377
378
_TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
379
_TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
380
_TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
381
382
/* fall through... */
383
case PHOTOMETRIC_MINISWHITE:
384
case PHOTOMETRIC_MINISBLACK:
385
if (planarconfig == PLANARCONFIG_CONTIG
386
&& img->samplesperpixel != 1
387
&& img->bitspersample < 8 ) {
388
sprintf(emsg,
389
"Sorry, can not handle contiguous data with %s=%d, "
390
"and %s=%d and Bits/Sample=%d",
391
photoTag, img->photometric,
392
"Samples/pixel", img->samplesperpixel,
393
img->bitspersample);
394
goto fail_return;
395
}
396
break;
397
case PHOTOMETRIC_YCBCR:
398
/* It would probably be nice to have a reality check here. */
399
if (planarconfig == PLANARCONFIG_CONTIG)
400
/* can rely on libjpeg to convert to RGB */
401
/* XXX should restore current state on exit */
402
switch (compress) {
403
case COMPRESSION_JPEG:
404
/*
405
* TODO: when complete tests verify complete desubsampling
406
* and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
407
* favor of tif_getimage.c native handling
408
*/
409
TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
410
img->photometric = PHOTOMETRIC_RGB;
411
break;
412
default:
413
/* do nothing */;
414
break;
415
}
416
/*
417
* TODO: if at all meaningful and useful, make more complete
418
* support check here, or better still, refactor to let supporting
419
* code decide whether there is support and what meaningful
420
* error to return
421
*/
422
break;
423
case PHOTOMETRIC_RGB:
424
if (colorchannels < 3) {
425
sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
426
"Color channels", colorchannels);
427
goto fail_return;
428
}
429
break;
430
case PHOTOMETRIC_SEPARATED:
431
{
432
uint16 inkset;
433
TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
434
if (inkset != INKSET_CMYK) {
435
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
436
"InkSet", inkset);
437
goto fail_return;
438
}
439
if (img->samplesperpixel < 4) {
440
sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
441
"Samples/pixel", img->samplesperpixel);
442
goto fail_return;
443
}
444
}
445
break;
446
case PHOTOMETRIC_LOGL:
447
if (compress != COMPRESSION_SGILOG) {
448
sprintf(emsg, "Sorry, LogL data must have %s=%d",
449
"Compression", COMPRESSION_SGILOG);
450
goto fail_return;
451
}
452
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
453
img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
454
img->bitspersample = 8;
455
break;
456
case PHOTOMETRIC_LOGLUV:
457
if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
458
sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
459
"Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
460
goto fail_return;
461
}
462
if (planarconfig != PLANARCONFIG_CONTIG) {
463
sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
464
"Planarconfiguration", planarconfig);
465
return (0);
466
}
467
TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
468
img->photometric = PHOTOMETRIC_RGB; /* little white lie */
469
img->bitspersample = 8;
470
break;
471
case PHOTOMETRIC_CIELAB:
472
break;
473
default:
474
sprintf(emsg, "Sorry, can not handle image with %s=%d",
475
photoTag, img->photometric);
476
goto fail_return;
477
}
478
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
479
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
480
TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
481
img->isContig =
482
!(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
483
if (img->isContig) {
484
if (!PickContigCase(img)) {
485
sprintf(emsg, "Sorry, can not handle image");
486
goto fail_return;
487
}
488
} else {
489
if (!PickSeparateCase(img)) {
490
sprintf(emsg, "Sorry, can not handle image");
491
goto fail_return;
492
}
493
}
494
return 1;
495
496
fail_return:
497
TIFFRGBAImageEnd( img );
498
return 0;
499
}
500
501
int
502
TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
503
{
504
if (img->get == NULL) {
505
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
506
return (0);
507
}
508
if (img->put.any == NULL) {
509
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
510
"No \"put\" routine setupl; probably can not handle image format");
511
return (0);
512
}
513
return (*img->get)(img, raster, w, h);
514
}
515
516
/*
517
* Read the specified image into an ABGR-format rastertaking in account
518
* specified orientation.
519
*/
520
int
521
TIFFReadRGBAImageOriented(TIFF* tif,
522
uint32 rwidth, uint32 rheight, uint32* raster,
523
int orientation, int stop)
524
{
525
char emsg[1024] = "";
526
TIFFRGBAImage img;
527
int ok;
528
529
if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
530
img.req_orientation = (uint16)orientation;
531
/* XXX verify rwidth and rheight against width and height */
532
ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
533
rwidth, img.height);
534
TIFFRGBAImageEnd(&img);
535
} else {
536
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
537
ok = 0;
538
}
539
return (ok);
540
}
541
542
/*
543
* Read the specified image into an ABGR-format raster. Use bottom left
544
* origin for raster by default.
545
*/
546
int
547
TIFFReadRGBAImage(TIFF* tif,
548
uint32 rwidth, uint32 rheight, uint32* raster, int stop)
549
{
550
return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
551
ORIENTATION_BOTLEFT, stop);
552
}
553
554
static int
555
setorientation(TIFFRGBAImage* img)
556
{
557
switch (img->orientation) {
558
case ORIENTATION_TOPLEFT:
559
case ORIENTATION_LEFTTOP:
560
if (img->req_orientation == ORIENTATION_TOPRIGHT ||
561
img->req_orientation == ORIENTATION_RIGHTTOP)
562
return FLIP_HORIZONTALLY;
563
else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
564
img->req_orientation == ORIENTATION_RIGHTBOT)
565
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
566
else if (img->req_orientation == ORIENTATION_BOTLEFT ||
567
img->req_orientation == ORIENTATION_LEFTBOT)
568
return FLIP_VERTICALLY;
569
else
570
return 0;
571
case ORIENTATION_TOPRIGHT:
572
case ORIENTATION_RIGHTTOP:
573
if (img->req_orientation == ORIENTATION_TOPLEFT ||
574
img->req_orientation == ORIENTATION_LEFTTOP)
575
return FLIP_HORIZONTALLY;
576
else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
577
img->req_orientation == ORIENTATION_RIGHTBOT)
578
return FLIP_VERTICALLY;
579
else if (img->req_orientation == ORIENTATION_BOTLEFT ||
580
img->req_orientation == ORIENTATION_LEFTBOT)
581
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
582
else
583
return 0;
584
case ORIENTATION_BOTRIGHT:
585
case ORIENTATION_RIGHTBOT:
586
if (img->req_orientation == ORIENTATION_TOPLEFT ||
587
img->req_orientation == ORIENTATION_LEFTTOP)
588
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
589
else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
590
img->req_orientation == ORIENTATION_RIGHTTOP)
591
return FLIP_VERTICALLY;
592
else if (img->req_orientation == ORIENTATION_BOTLEFT ||
593
img->req_orientation == ORIENTATION_LEFTBOT)
594
return FLIP_HORIZONTALLY;
595
else
596
return 0;
597
case ORIENTATION_BOTLEFT:
598
case ORIENTATION_LEFTBOT:
599
if (img->req_orientation == ORIENTATION_TOPLEFT ||
600
img->req_orientation == ORIENTATION_LEFTTOP)
601
return FLIP_VERTICALLY;
602
else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
603
img->req_orientation == ORIENTATION_RIGHTTOP)
604
return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
605
else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
606
img->req_orientation == ORIENTATION_RIGHTBOT)
607
return FLIP_HORIZONTALLY;
608
else
609
return 0;
610
default: /* NOTREACHED */
611
return 0;
612
}
613
}
614
615
/*
616
* Get an tile-organized image that has
617
* PlanarConfiguration contiguous if SamplesPerPixel > 1
618
* or
619
* SamplesPerPixel == 1
620
*/
621
static int
622
gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
623
{
624
TIFF* tif = img->tif;
625
tileContigRoutine put = img->put.contig;
626
uint32 col, row, y, rowstoread;
627
tmsize_t pos;
628
uint32 tw, th;
629
unsigned char* buf = NULL;
630
int32 fromskew, toskew;
631
uint32 nrow;
632
int ret = 1, flip;
633
uint32 this_tw, tocol;
634
int32 this_toskew, leftmost_toskew;
635
int32 leftmost_fromskew;
636
uint32 leftmost_tw;
637
tmsize_t bufsize;
638
639
bufsize = TIFFTileSize(tif);
640
if (bufsize == 0) {
641
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
642
return (0);
643
}
644
645
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
646
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
647
648
flip = setorientation(img);
649
if (flip & FLIP_VERTICALLY) {
650
y = h - 1;
651
toskew = -(int32)(tw + w);
652
}
653
else {
654
y = 0;
655
toskew = -(int32)(tw - w);
656
}
657
658
/*
659
* Leftmost tile is clipped on left side if col_offset > 0.
660
*/
661
leftmost_fromskew = img->col_offset % tw;
662
leftmost_tw = tw - leftmost_fromskew;
663
leftmost_toskew = toskew + leftmost_fromskew;
664
for (row = 0; ret != 0 && row < h; row += nrow)
665
{
666
rowstoread = th - (row + img->row_offset) % th;
667
nrow = (row + rowstoread > h ? h - row : rowstoread);
668
fromskew = leftmost_fromskew;
669
this_tw = leftmost_tw;
670
this_toskew = leftmost_toskew;
671
tocol = 0;
672
col = img->col_offset;
673
while (tocol < w)
674
{
675
if (_TIFFReadTileAndAllocBuffer(tif, (void**) &buf, bufsize, col,
676
row+img->row_offset, 0, 0)==(tmsize_t)(-1) &&
677
(buf == NULL || img->stoponerr))
678
{
679
ret = 0;
680
break;
681
}
682
pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \
683
((tmsize_t) fromskew * img->samplesperpixel);
684
if (tocol + this_tw > w)
685
{
686
/*
687
* Rightmost tile is clipped on right side.
688
*/
689
fromskew = tw - (w - tocol);
690
this_tw = tw - fromskew;
691
this_toskew = toskew + fromskew;
692
}
693
(*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos);
694
tocol += this_tw;
695
col += this_tw;
696
/*
697
* After the leftmost tile, tiles are no longer clipped on left side.
698
*/
699
fromskew = 0;
700
this_tw = tw;
701
this_toskew = toskew;
702
}
703
704
y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
705
}
706
_TIFFfree(buf);
707
708
if (flip & FLIP_HORIZONTALLY) {
709
uint32 line;
710
711
for (line = 0; line < h; line++) {
712
uint32 *left = raster + (line * w);
713
uint32 *right = left + w - 1;
714
715
while ( left < right ) {
716
uint32 temp = *left;
717
*left = *right;
718
*right = temp;
719
left++;
720
right--;
721
}
722
}
723
}
724
725
return (ret);
726
}
727
728
/*
729
* Get an tile-organized image that has
730
* SamplesPerPixel > 1
731
* PlanarConfiguration separated
732
* We assume that all such images are RGB.
733
*/
734
static int
735
gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
736
{
737
TIFF* tif = img->tif;
738
tileSeparateRoutine put = img->put.separate;
739
uint32 col, row, y, rowstoread;
740
tmsize_t pos;
741
uint32 tw, th;
742
unsigned char* buf = NULL;
743
unsigned char* p0 = NULL;
744
unsigned char* p1 = NULL;
745
unsigned char* p2 = NULL;
746
unsigned char* pa = NULL;
747
tmsize_t tilesize;
748
tmsize_t bufsize;
749
int32 fromskew, toskew;
750
int alpha = img->alpha;
751
uint32 nrow;
752
int ret = 1, flip;
753
uint16 colorchannels;
754
uint32 this_tw, tocol;
755
int32 this_toskew, leftmost_toskew;
756
int32 leftmost_fromskew;
757
uint32 leftmost_tw;
758
759
tilesize = TIFFTileSize(tif);
760
bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
761
if (bufsize == 0) {
762
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
763
return (0);
764
}
765
766
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
767
TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
768
769
flip = setorientation(img);
770
if (flip & FLIP_VERTICALLY) {
771
y = h - 1;
772
toskew = -(int32)(tw + w);
773
}
774
else {
775
y = 0;
776
toskew = -(int32)(tw - w);
777
}
778
779
switch( img->photometric )
780
{
781
case PHOTOMETRIC_MINISWHITE:
782
case PHOTOMETRIC_MINISBLACK:
783
case PHOTOMETRIC_PALETTE:
784
colorchannels = 1;
785
break;
786
787
default:
788
colorchannels = 3;
789
break;
790
}
791
792
/*
793
* Leftmost tile is clipped on left side if col_offset > 0.
794
*/
795
leftmost_fromskew = img->col_offset % tw;
796
leftmost_tw = tw - leftmost_fromskew;
797
leftmost_toskew = toskew + leftmost_fromskew;
798
for (row = 0; ret != 0 && row < h; row += nrow)
799
{
800
rowstoread = th - (row + img->row_offset) % th;
801
nrow = (row + rowstoread > h ? h - row : rowstoread);
802
fromskew = leftmost_fromskew;
803
this_tw = leftmost_tw;
804
this_toskew = leftmost_toskew;
805
tocol = 0;
806
col = img->col_offset;
807
while (tocol < w)
808
{
809
if( buf == NULL )
810
{
811
if (_TIFFReadTileAndAllocBuffer(
812
tif, (void**) &buf, bufsize, col,
813
row+img->row_offset,0,0)==(tmsize_t)(-1)
814
&& (buf == NULL || img->stoponerr))
815
{
816
ret = 0;
817
break;
818
}
819
p0 = buf;
820
if( colorchannels == 1 )
821
{
822
p2 = p1 = p0;
823
pa = (alpha?(p0+3*tilesize):NULL);
824
}
825
else
826
{
827
p1 = p0 + tilesize;
828
p2 = p1 + tilesize;
829
pa = (alpha?(p2+tilesize):NULL);
830
}
831
}
832
else if (TIFFReadTile(tif, p0, col,
833
row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
834
{
835
ret = 0;
836
break;
837
}
838
if (colorchannels > 1
839
&& TIFFReadTile(tif, p1, col,
840
row+img->row_offset,0,1) == (tmsize_t)(-1)
841
&& img->stoponerr)
842
{
843
ret = 0;
844
break;
845
}
846
if (colorchannels > 1
847
&& TIFFReadTile(tif, p2, col,
848
row+img->row_offset,0,2) == (tmsize_t)(-1)
849
&& img->stoponerr)
850
{
851
ret = 0;
852
break;
853
}
854
if (alpha
855
&& TIFFReadTile(tif,pa,col,
856
row+img->row_offset,0,colorchannels) == (tmsize_t)(-1)
857
&& img->stoponerr)
858
{
859
ret = 0;
860
break;
861
}
862
863
pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \
864
((tmsize_t) fromskew * img->samplesperpixel);
865
if (tocol + this_tw > w)
866
{
867
/*
868
* Rightmost tile is clipped on right side.
869
*/
870
fromskew = tw - (w - tocol);
871
this_tw = tw - fromskew;
872
this_toskew = toskew + fromskew;
873
}
874
(*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, \
875
p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
876
tocol += this_tw;
877
col += this_tw;
878
/*
879
* After the leftmost tile, tiles are no longer clipped on left side.
880
*/
881
fromskew = 0;
882
this_tw = tw;
883
this_toskew = toskew;
884
}
885
886
y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow);
887
}
888
889
if (flip & FLIP_HORIZONTALLY) {
890
uint32 line;
891
892
for (line = 0; line < h; line++) {
893
uint32 *left = raster + (line * w);
894
uint32 *right = left + w - 1;
895
896
while ( left < right ) {
897
uint32 temp = *left;
898
*left = *right;
899
*right = temp;
900
left++;
901
right--;
902
}
903
}
904
}
905
906
_TIFFfree(buf);
907
return (ret);
908
}
909
910
/*
911
* Get a strip-organized image that has
912
* PlanarConfiguration contiguous if SamplesPerPixel > 1
913
* or
914
* SamplesPerPixel == 1
915
*/
916
static int
917
gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
918
{
919
TIFF* tif = img->tif;
920
tileContigRoutine put = img->put.contig;
921
uint32 row, y, nrow, nrowsub, rowstoread;
922
tmsize_t pos;
923
unsigned char* buf = NULL;
924
uint32 rowsperstrip;
925
uint16 subsamplinghor,subsamplingver;
926
uint32 imagewidth = img->width;
927
tmsize_t scanline;
928
int32 fromskew, toskew;
929
int ret = 1, flip;
930
tmsize_t maxstripsize;
931
932
TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
933
if( subsamplingver == 0 ) {
934
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling");
935
return (0);
936
}
937
938
maxstripsize = TIFFStripSize(tif);
939
940
flip = setorientation(img);
941
if (flip & FLIP_VERTICALLY) {
942
y = h - 1;
943
toskew = -(int32)(w + w);
944
} else {
945
y = 0;
946
toskew = -(int32)(w - w);
947
}
948
949
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
950
951
scanline = TIFFScanlineSize(tif);
952
fromskew = (w < imagewidth ? imagewidth - w : 0);
953
for (row = 0; row < h; row += nrow)
954
{
955
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
956
nrow = (row + rowstoread > h ? h - row : rowstoread);
957
nrowsub = nrow;
958
if ((nrowsub%subsamplingver)!=0)
959
nrowsub+=subsamplingver-nrowsub%subsamplingver;
960
if (_TIFFReadEncodedStripAndAllocBuffer(tif,
961
TIFFComputeStrip(tif,row+img->row_offset, 0),
962
(void**)(&buf),
963
maxstripsize,
964
((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
965
&& (buf == NULL || img->stoponerr))
966
{
967
ret = 0;
968
break;
969
}
970
971
pos = ((row + img->row_offset) % rowsperstrip) * scanline + \
972
((tmsize_t) img->col_offset * img->samplesperpixel);
973
(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
974
y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
975
}
976
977
if (flip & FLIP_HORIZONTALLY) {
978
uint32 line;
979
980
for (line = 0; line < h; line++) {
981
uint32 *left = raster + (line * w);
982
uint32 *right = left + w - 1;
983
984
while ( left < right ) {
985
uint32 temp = *left;
986
*left = *right;
987
*right = temp;
988
left++;
989
right--;
990
}
991
}
992
}
993
994
_TIFFfree(buf);
995
return (ret);
996
}
997
998
/*
999
* Get a strip-organized image with
1000
* SamplesPerPixel > 1
1001
* PlanarConfiguration separated
1002
* We assume that all such images are RGB.
1003
*/
1004
static int
1005
gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
1006
{
1007
TIFF* tif = img->tif;
1008
tileSeparateRoutine put = img->put.separate;
1009
unsigned char *buf = NULL;
1010
unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL;
1011
uint32 row, y, nrow, rowstoread;
1012
tmsize_t pos;
1013
tmsize_t scanline;
1014
uint32 rowsperstrip, offset_row;
1015
uint32 imagewidth = img->width;
1016
tmsize_t stripsize;
1017
tmsize_t bufsize;
1018
int32 fromskew, toskew;
1019
int alpha = img->alpha;
1020
int ret = 1, flip;
1021
uint16 colorchannels;
1022
1023
stripsize = TIFFStripSize(tif);
1024
bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
1025
if (bufsize == 0) {
1026
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
1027
return (0);
1028
}
1029
1030
flip = setorientation(img);
1031
if (flip & FLIP_VERTICALLY) {
1032
y = h - 1;
1033
toskew = -(int32)(w + w);
1034
}
1035
else {
1036
y = 0;
1037
toskew = -(int32)(w - w);
1038
}
1039
1040
switch( img->photometric )
1041
{
1042
case PHOTOMETRIC_MINISWHITE:
1043
case PHOTOMETRIC_MINISBLACK:
1044
case PHOTOMETRIC_PALETTE:
1045
colorchannels = 1;
1046
break;
1047
1048
default:
1049
colorchannels = 3;
1050
break;
1051
}
1052
1053
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1054
scanline = TIFFScanlineSize(tif);
1055
fromskew = (w < imagewidth ? imagewidth - w : 0);
1056
for (row = 0; row < h; row += nrow)
1057
{
1058
rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
1059
nrow = (row + rowstoread > h ? h - row : rowstoread);
1060
offset_row = row + img->row_offset;
1061
if( buf == NULL )
1062
{
1063
if (_TIFFReadEncodedStripAndAllocBuffer(
1064
tif, TIFFComputeStrip(tif, offset_row, 0),
1065
(void**) &buf, bufsize,
1066
((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
1067
&& (buf == NULL || img->stoponerr))
1068
{
1069
ret = 0;
1070
break;
1071
}
1072
p0 = buf;
1073
if( colorchannels == 1 )
1074
{
1075
p2 = p1 = p0;
1076
pa = (alpha?(p0+3*stripsize):NULL);
1077
}
1078
else
1079
{
1080
p1 = p0 + stripsize;
1081
p2 = p1 + stripsize;
1082
pa = (alpha?(p2+stripsize):NULL);
1083
}
1084
}
1085
else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
1086
p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
1087
&& img->stoponerr)
1088
{
1089
ret = 0;
1090
break;
1091
}
1092
if (colorchannels > 1
1093
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
1094
p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
1095
&& img->stoponerr)
1096
{
1097
ret = 0;
1098
break;
1099
}
1100
if (colorchannels > 1
1101
&& TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
1102
p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
1103
&& img->stoponerr)
1104
{
1105
ret = 0;
1106
break;
1107
}
1108
if (alpha)
1109
{
1110
if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
1111
pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
1112
&& img->stoponerr)
1113
{
1114
ret = 0;
1115
break;
1116
}
1117
}
1118
1119
pos = ((row + img->row_offset) % rowsperstrip) * scanline + \
1120
((tmsize_t) img->col_offset * img->samplesperpixel);
1121
(*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
1122
p2 + pos, (alpha?(pa+pos):NULL));
1123
y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
1124
}
1125
1126
if (flip & FLIP_HORIZONTALLY) {
1127
uint32 line;
1128
1129
for (line = 0; line < h; line++) {
1130
uint32 *left = raster + (line * w);
1131
uint32 *right = left + w - 1;
1132
1133
while ( left < right ) {
1134
uint32 temp = *left;
1135
*left = *right;
1136
*right = temp;
1137
left++;
1138
right--;
1139
}
1140
}
1141
}
1142
1143
_TIFFfree(buf);
1144
return (ret);
1145
}
1146
1147
/*
1148
* The following routines move decoded data returned
1149
* from the TIFF library into rasters filled with packed
1150
* ABGR pixels (i.e. suitable for passing to lrecwrite.)
1151
*
1152
* The routines have been created according to the most
1153
* important cases and optimized. PickContigCase and
1154
* PickSeparateCase analyze the parameters and select
1155
* the appropriate "get" and "put" routine to use.
1156
*/
1157
#define REPEAT8(op) REPEAT4(op); REPEAT4(op)
1158
#define REPEAT4(op) REPEAT2(op); REPEAT2(op)
1159
#define REPEAT2(op) op; op
1160
#define CASE8(x,op) \
1161
switch (x) { \
1162
case 7: op; /*-fallthrough*/ \
1163
case 6: op; /*-fallthrough*/ \
1164
case 5: op; /*-fallthrough*/ \
1165
case 4: op; /*-fallthrough*/ \
1166
case 3: op; /*-fallthrough*/ \
1167
case 2: op; /*-fallthrough*/ \
1168
case 1: op; \
1169
}
1170
#define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; }
1171
#define NOP
1172
1173
#define UNROLL8(w, op1, op2) { \
1174
uint32 _x; \
1175
for (_x = w; _x >= 8; _x -= 8) { \
1176
op1; \
1177
REPEAT8(op2); \
1178
} \
1179
if (_x > 0) { \
1180
op1; \
1181
CASE8(_x,op2); \
1182
} \
1183
}
1184
#define UNROLL4(w, op1, op2) { \
1185
uint32 _x; \
1186
for (_x = w; _x >= 4; _x -= 4) { \
1187
op1; \
1188
REPEAT4(op2); \
1189
} \
1190
if (_x > 0) { \
1191
op1; \
1192
CASE4(_x,op2); \
1193
} \
1194
}
1195
#define UNROLL2(w, op1, op2) { \
1196
uint32 _x; \
1197
for (_x = w; _x >= 2; _x -= 2) { \
1198
op1; \
1199
REPEAT2(op2); \
1200
} \
1201
if (_x) { \
1202
op1; \
1203
op2; \
1204
} \
1205
}
1206
1207
#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1208
#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1209
1210
#define A1 (((uint32)0xffL)<<24)
1211
#define PACK(r,g,b) \
1212
((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1213
#define PACK4(r,g,b,a) \
1214
((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1215
#define W2B(v) (((v)>>8)&0xff)
1216
/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
1217
#define PACKW(r,g,b) \
1218
((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1219
#define PACKW4(r,g,b,a) \
1220
((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1221
1222
#define DECLAREContigPutFunc(name) \
1223
static void name(\
1224
TIFFRGBAImage* img, \
1225
uint32* cp, \
1226
uint32 x, uint32 y, \
1227
uint32 w, uint32 h, \
1228
int32 fromskew, int32 toskew, \
1229
unsigned char* pp \
1230
)
1231
1232
/*
1233
* 8-bit palette => colormap/RGB
1234
*/
1235
DECLAREContigPutFunc(put8bitcmaptile)
1236
{
1237
uint32** PALmap = img->PALmap;
1238
int samplesperpixel = img->samplesperpixel;
1239
1240
(void) y;
1241
for( ; h > 0; --h) {
1242
for (x = w; x > 0; --x)
1243
{
1244
*cp++ = PALmap[*pp][0];
1245
pp += samplesperpixel;
1246
}
1247
cp += toskew;
1248
pp += fromskew;
1249
}
1250
}
1251
1252
/*
1253
* 4-bit palette => colormap/RGB
1254
*/
1255
DECLAREContigPutFunc(put4bitcmaptile)
1256
{
1257
uint32** PALmap = img->PALmap;
1258
1259
(void) x; (void) y;
1260
fromskew /= 2;
1261
for( ; h > 0; --h) {
1262
uint32* bw;
1263
UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
1264
cp += toskew;
1265
pp += fromskew;
1266
}
1267
}
1268
1269
/*
1270
* 2-bit palette => colormap/RGB
1271
*/
1272
DECLAREContigPutFunc(put2bitcmaptile)
1273
{
1274
uint32** PALmap = img->PALmap;
1275
1276
(void) x; (void) y;
1277
fromskew /= 4;
1278
for( ; h > 0; --h) {
1279
uint32* bw;
1280
UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
1281
cp += toskew;
1282
pp += fromskew;
1283
}
1284
}
1285
1286
/*
1287
* 1-bit palette => colormap/RGB
1288
*/
1289
DECLAREContigPutFunc(put1bitcmaptile)
1290
{
1291
uint32** PALmap = img->PALmap;
1292
1293
(void) x; (void) y;
1294
fromskew /= 8;
1295
for( ; h > 0; --h) {
1296
uint32* bw;
1297
UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
1298
cp += toskew;
1299
pp += fromskew;
1300
}
1301
}
1302
1303
/*
1304
* 8-bit greyscale => colormap/RGB
1305
*/
1306
DECLAREContigPutFunc(putgreytile)
1307
{
1308
int samplesperpixel = img->samplesperpixel;
1309
uint32** BWmap = img->BWmap;
1310
1311
(void) y;
1312
for( ; h > 0; --h) {
1313
for (x = w; x > 0; --x)
1314
{
1315
*cp++ = BWmap[*pp][0];
1316
pp += samplesperpixel;
1317
}
1318
cp += toskew;
1319
pp += fromskew;
1320
}
1321
}
1322
1323
/*
1324
* 8-bit greyscale with associated alpha => colormap/RGBA
1325
*/
1326
DECLAREContigPutFunc(putagreytile)
1327
{
1328
int samplesperpixel = img->samplesperpixel;
1329
uint32** BWmap = img->BWmap;
1330
1331
(void) y;
1332
for( ; h > 0; --h) {
1333
for (x = w; x > 0; --x)
1334
{
1335
*cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1);
1336
pp += samplesperpixel;
1337
}
1338
cp += toskew;
1339
pp += fromskew;
1340
}
1341
}
1342
1343
/*
1344
* 16-bit greyscale => colormap/RGB
1345
*/
1346
DECLAREContigPutFunc(put16bitbwtile)
1347
{
1348
int samplesperpixel = img->samplesperpixel;
1349
uint32** BWmap = img->BWmap;
1350
1351
(void) y;
1352
for( ; h > 0; --h) {
1353
uint16 *wp = (uint16 *) pp;
1354
1355
for (x = w; x > 0; --x)
1356
{
1357
/* use high order byte of 16bit value */
1358
1359
*cp++ = BWmap[*wp >> 8][0];
1360
pp += 2 * samplesperpixel;
1361
wp += samplesperpixel;
1362
}
1363
cp += toskew;
1364
pp += fromskew;
1365
}
1366
}
1367
1368
/*
1369
* 1-bit bilevel => colormap/RGB
1370
*/
1371
DECLAREContigPutFunc(put1bitbwtile)
1372
{
1373
uint32** BWmap = img->BWmap;
1374
1375
(void) x; (void) y;
1376
fromskew /= 8;
1377
for( ; h > 0; --h) {
1378
uint32* bw;
1379
UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
1380
cp += toskew;
1381
pp += fromskew;
1382
}
1383
}
1384
1385
/*
1386
* 2-bit greyscale => colormap/RGB
1387
*/
1388
DECLAREContigPutFunc(put2bitbwtile)
1389
{
1390
uint32** BWmap = img->BWmap;
1391
1392
(void) x; (void) y;
1393
fromskew /= 4;
1394
for( ; h > 0; --h) {
1395
uint32* bw;
1396
UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
1397
cp += toskew;
1398
pp += fromskew;
1399
}
1400
}
1401
1402
/*
1403
* 4-bit greyscale => colormap/RGB
1404
*/
1405
DECLAREContigPutFunc(put4bitbwtile)
1406
{
1407
uint32** BWmap = img->BWmap;
1408
1409
(void) x; (void) y;
1410
fromskew /= 2;
1411
for( ; h > 0; --h) {
1412
uint32* bw;
1413
UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
1414
cp += toskew;
1415
pp += fromskew;
1416
}
1417
}
1418
1419
/*
1420
* 8-bit packed samples, no Map => RGB
1421
*/
1422
DECLAREContigPutFunc(putRGBcontig8bittile)
1423
{
1424
int samplesperpixel = img->samplesperpixel;
1425
1426
(void) x; (void) y;
1427
fromskew *= samplesperpixel;
1428
for( ; h > 0; --h) {
1429
UNROLL8(w, NOP,
1430
*cp++ = PACK(pp[0], pp[1], pp[2]);
1431
pp += samplesperpixel);
1432
cp += toskew;
1433
pp += fromskew;
1434
}
1435
}
1436
1437
/*
1438
* 8-bit packed samples => RGBA w/ associated alpha
1439
* (known to have Map == NULL)
1440
*/
1441
DECLAREContigPutFunc(putRGBAAcontig8bittile)
1442
{
1443
int samplesperpixel = img->samplesperpixel;
1444
1445
(void) x; (void) y;
1446
fromskew *= samplesperpixel;
1447
for( ; h > 0; --h) {
1448
UNROLL8(w, NOP,
1449
*cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
1450
pp += samplesperpixel);
1451
cp += toskew;
1452
pp += fromskew;
1453
}
1454
}
1455
1456
/*
1457
* 8-bit packed samples => RGBA w/ unassociated alpha
1458
* (known to have Map == NULL)
1459
*/
1460
DECLAREContigPutFunc(putRGBUAcontig8bittile)
1461
{
1462
int samplesperpixel = img->samplesperpixel;
1463
(void) y;
1464
fromskew *= samplesperpixel;
1465
for( ; h > 0; --h) {
1466
uint32 r, g, b, a;
1467
uint8* m;
1468
for (x = w; x > 0; --x) {
1469
a = pp[3];
1470
m = img->UaToAa+((size_t) a<<8);
1471
r = m[pp[0]];
1472
g = m[pp[1]];
1473
b = m[pp[2]];
1474
*cp++ = PACK4(r,g,b,a);
1475
pp += samplesperpixel;
1476
}
1477
cp += toskew;
1478
pp += fromskew;
1479
}
1480
}
1481
1482
/*
1483
* 16-bit packed samples => RGB
1484
*/
1485
DECLAREContigPutFunc(putRGBcontig16bittile)
1486
{
1487
int samplesperpixel = img->samplesperpixel;
1488
uint16 *wp = (uint16 *)pp;
1489
(void) y;
1490
fromskew *= samplesperpixel;
1491
for( ; h > 0; --h) {
1492
for (x = w; x > 0; --x) {
1493
*cp++ = PACK(img->Bitdepth16To8[wp[0]],
1494
img->Bitdepth16To8[wp[1]],
1495
img->Bitdepth16To8[wp[2]]);
1496
wp += samplesperpixel;
1497
}
1498
cp += toskew;
1499
wp += fromskew;
1500
}
1501
}
1502
1503
/*
1504
* 16-bit packed samples => RGBA w/ associated alpha
1505
* (known to have Map == NULL)
1506
*/
1507
DECLAREContigPutFunc(putRGBAAcontig16bittile)
1508
{
1509
int samplesperpixel = img->samplesperpixel;
1510
uint16 *wp = (uint16 *)pp;
1511
(void) y;
1512
fromskew *= samplesperpixel;
1513
for( ; h > 0; --h) {
1514
for (x = w; x > 0; --x) {
1515
*cp++ = PACK4(img->Bitdepth16To8[wp[0]],
1516
img->Bitdepth16To8[wp[1]],
1517
img->Bitdepth16To8[wp[2]],
1518
img->Bitdepth16To8[wp[3]]);
1519
wp += samplesperpixel;
1520
}
1521
cp += toskew;
1522
wp += fromskew;
1523
}
1524
}
1525
1526
/*
1527
* 16-bit packed samples => RGBA w/ unassociated alpha
1528
* (known to have Map == NULL)
1529
*/
1530
DECLAREContigPutFunc(putRGBUAcontig16bittile)
1531
{
1532
int samplesperpixel = img->samplesperpixel;
1533
uint16 *wp = (uint16 *)pp;
1534
(void) y;
1535
fromskew *= samplesperpixel;
1536
for( ; h > 0; --h) {
1537
uint32 r,g,b,a;
1538
uint8* m;
1539
for (x = w; x > 0; --x) {
1540
a = img->Bitdepth16To8[wp[3]];
1541
m = img->UaToAa+((size_t) a<<8);
1542
r = m[img->Bitdepth16To8[wp[0]]];
1543
g = m[img->Bitdepth16To8[wp[1]]];
1544
b = m[img->Bitdepth16To8[wp[2]]];
1545
*cp++ = PACK4(r,g,b,a);
1546
wp += samplesperpixel;
1547
}
1548
cp += toskew;
1549
wp += fromskew;
1550
}
1551
}
1552
1553
/*
1554
* 8-bit packed CMYK samples w/o Map => RGB
1555
*
1556
* NB: The conversion of CMYK->RGB is *very* crude.
1557
*/
1558
DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
1559
{
1560
int samplesperpixel = img->samplesperpixel;
1561
uint16 r, g, b, k;
1562
1563
(void) x; (void) y;
1564
fromskew *= samplesperpixel;
1565
for( ; h > 0; --h) {
1566
UNROLL8(w, NOP,
1567
k = 255 - pp[3];
1568
r = (k*(255-pp[0]))/255;
1569
g = (k*(255-pp[1]))/255;
1570
b = (k*(255-pp[2]))/255;
1571
*cp++ = PACK(r, g, b);
1572
pp += samplesperpixel);
1573
cp += toskew;
1574
pp += fromskew;
1575
}
1576
}
1577
1578
/*
1579
* 8-bit packed CMYK samples w/Map => RGB
1580
*
1581
* NB: The conversion of CMYK->RGB is *very* crude.
1582
*/
1583
DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
1584
{
1585
int samplesperpixel = img->samplesperpixel;
1586
TIFFRGBValue* Map = img->Map;
1587
uint16 r, g, b, k;
1588
1589
(void) y;
1590
fromskew *= samplesperpixel;
1591
for( ; h > 0; --h) {
1592
for (x = w; x > 0; --x) {
1593
k = 255 - pp[3];
1594
r = (k*(255-pp[0]))/255;
1595
g = (k*(255-pp[1]))/255;
1596
b = (k*(255-pp[2]))/255;
1597
*cp++ = PACK(Map[r], Map[g], Map[b]);
1598
pp += samplesperpixel;
1599
}
1600
pp += fromskew;
1601
cp += toskew;
1602
}
1603
}
1604
1605
#define DECLARESepPutFunc(name) \
1606
static void name(\
1607
TIFFRGBAImage* img,\
1608
uint32* cp,\
1609
uint32 x, uint32 y, \
1610
uint32 w, uint32 h,\
1611
int32 fromskew, int32 toskew,\
1612
unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1613
)
1614
1615
/*
1616
* 8-bit unpacked samples => RGB
1617
*/
1618
DECLARESepPutFunc(putRGBseparate8bittile)
1619
{
1620
(void) img; (void) x; (void) y; (void) a;
1621
for( ; h > 0; --h) {
1622
UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
1623
SKEW(r, g, b, fromskew);
1624
cp += toskew;
1625
}
1626
}
1627
1628
/*
1629
* 8-bit unpacked samples => RGBA w/ associated alpha
1630
*/
1631
DECLARESepPutFunc(putRGBAAseparate8bittile)
1632
{
1633
(void) img; (void) x; (void) y;
1634
for( ; h > 0; --h) {
1635
UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
1636
SKEW4(r, g, b, a, fromskew);
1637
cp += toskew;
1638
}
1639
}
1640
1641
/*
1642
* 8-bit unpacked CMYK samples => RGBA
1643
*/
1644
DECLARESepPutFunc(putCMYKseparate8bittile)
1645
{
1646
(void) img; (void) y;
1647
for( ; h > 0; --h) {
1648
uint32 rv, gv, bv, kv;
1649
for (x = w; x > 0; --x) {
1650
kv = 255 - *a++;
1651
rv = (kv*(255-*r++))/255;
1652
gv = (kv*(255-*g++))/255;
1653
bv = (kv*(255-*b++))/255;
1654
*cp++ = PACK4(rv,gv,bv,255);
1655
}
1656
SKEW4(r, g, b, a, fromskew);
1657
cp += toskew;
1658
}
1659
}
1660
1661
/*
1662
* 8-bit unpacked samples => RGBA w/ unassociated alpha
1663
*/
1664
DECLARESepPutFunc(putRGBUAseparate8bittile)
1665
{
1666
(void) img; (void) y;
1667
for( ; h > 0; --h) {
1668
uint32 rv, gv, bv, av;
1669
uint8* m;
1670
for (x = w; x > 0; --x) {
1671
av = *a++;
1672
m = img->UaToAa+((size_t) av<<8);
1673
rv = m[*r++];
1674
gv = m[*g++];
1675
bv = m[*b++];
1676
*cp++ = PACK4(rv,gv,bv,av);
1677
}
1678
SKEW4(r, g, b, a, fromskew);
1679
cp += toskew;
1680
}
1681
}
1682
1683
/*
1684
* 16-bit unpacked samples => RGB
1685
*/
1686
DECLARESepPutFunc(putRGBseparate16bittile)
1687
{
1688
uint16 *wr = (uint16*) r;
1689
uint16 *wg = (uint16*) g;
1690
uint16 *wb = (uint16*) b;
1691
(void) img; (void) y; (void) a;
1692
for( ; h > 0; --h) {
1693
for (x = 0; x < w; x++)
1694
*cp++ = PACK(img->Bitdepth16To8[*wr++],
1695
img->Bitdepth16To8[*wg++],
1696
img->Bitdepth16To8[*wb++]);
1697
SKEW(wr, wg, wb, fromskew);
1698
cp += toskew;
1699
}
1700
}
1701
1702
/*
1703
* 16-bit unpacked samples => RGBA w/ associated alpha
1704
*/
1705
DECLARESepPutFunc(putRGBAAseparate16bittile)
1706
{
1707
uint16 *wr = (uint16*) r;
1708
uint16 *wg = (uint16*) g;
1709
uint16 *wb = (uint16*) b;
1710
uint16 *wa = (uint16*) a;
1711
(void) img; (void) y;
1712
for( ; h > 0; --h) {
1713
for (x = 0; x < w; x++)
1714
*cp++ = PACK4(img->Bitdepth16To8[*wr++],
1715
img->Bitdepth16To8[*wg++],
1716
img->Bitdepth16To8[*wb++],
1717
img->Bitdepth16To8[*wa++]);
1718
SKEW4(wr, wg, wb, wa, fromskew);
1719
cp += toskew;
1720
}
1721
}
1722
1723
/*
1724
* 16-bit unpacked samples => RGBA w/ unassociated alpha
1725
*/
1726
DECLARESepPutFunc(putRGBUAseparate16bittile)
1727
{
1728
uint16 *wr = (uint16*) r;
1729
uint16 *wg = (uint16*) g;
1730
uint16 *wb = (uint16*) b;
1731
uint16 *wa = (uint16*) a;
1732
(void) img; (void) y;
1733
for( ; h > 0; --h) {
1734
uint32 r2,g2,b2,a2;
1735
uint8* m;
1736
for (x = w; x > 0; --x) {
1737
a2 = img->Bitdepth16To8[*wa++];
1738
m = img->UaToAa+((size_t) a2<<8);
1739
r2 = m[img->Bitdepth16To8[*wr++]];
1740
g2 = m[img->Bitdepth16To8[*wg++]];
1741
b2 = m[img->Bitdepth16To8[*wb++]];
1742
*cp++ = PACK4(r2,g2,b2,a2);
1743
}
1744
SKEW4(wr, wg, wb, wa, fromskew);
1745
cp += toskew;
1746
}
1747
}
1748
1749
/*
1750
* 8-bit packed CIE L*a*b 1976 samples => RGB
1751
*/
1752
DECLAREContigPutFunc(putcontig8bitCIELab)
1753
{
1754
float X, Y, Z;
1755
uint32 r, g, b;
1756
(void) y;
1757
fromskew *= 3;
1758
for( ; h > 0; --h) {
1759
for (x = w; x > 0; --x) {
1760
TIFFCIELabToXYZ(img->cielab,
1761
(unsigned char)pp[0],
1762
(signed char)pp[1],
1763
(signed char)pp[2],
1764
&X, &Y, &Z);
1765
TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
1766
*cp++ = PACK(r, g, b);
1767
pp += 3;
1768
}
1769
cp += toskew;
1770
pp += fromskew;
1771
}
1772
}
1773
1774
/*
1775
* YCbCr -> RGB conversion and packing routines.
1776
*/
1777
1778
#define YCbCrtoRGB(dst, Y) { \
1779
uint32 r, g, b; \
1780
TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1781
dst = PACK(r, g, b); \
1782
}
1783
1784
/*
1785
* 8-bit packed YCbCr samples => RGB
1786
* This function is generic for different sampling sizes,
1787
* and can handle blocks sizes that aren't multiples of the
1788
* sampling size. However, it is substantially less optimized
1789
* than the specific sampling cases. It is used as a fallback
1790
* for difficult blocks.
1791
*/
1792
#ifdef notdef
1793
static void putcontig8bitYCbCrGenericTile(
1794
TIFFRGBAImage* img,
1795
uint32* cp,
1796
uint32 x, uint32 y,
1797
uint32 w, uint32 h,
1798
int32 fromskew, int32 toskew,
1799
unsigned char* pp,
1800
int h_group,
1801
int v_group )
1802
1803
{
1804
uint32* cp1 = cp+w+toskew;
1805
uint32* cp2 = cp1+w+toskew;
1806
uint32* cp3 = cp2+w+toskew;
1807
int32 incr = 3*w+4*toskew;
1808
int32 Cb, Cr;
1809
int group_size = v_group * h_group + 2;
1810
1811
(void) y;
1812
fromskew = (fromskew * group_size) / h_group;
1813
1814
for( yy = 0; yy < h; yy++ )
1815
{
1816
unsigned char *pp_line;
1817
int y_line_group = yy / v_group;
1818
int y_remainder = yy - y_line_group * v_group;
1819
1820
pp_line = pp + v_line_group *
1821
1822
1823
for( xx = 0; xx < w; xx++ )
1824
{
1825
Cb = pp
1826
}
1827
}
1828
for (; h >= 4; h -= 4) {
1829
x = w>>2;
1830
do {
1831
Cb = pp[16];
1832
Cr = pp[17];
1833
1834
YCbCrtoRGB(cp [0], pp[ 0]);
1835
YCbCrtoRGB(cp [1], pp[ 1]);
1836
YCbCrtoRGB(cp [2], pp[ 2]);
1837
YCbCrtoRGB(cp [3], pp[ 3]);
1838
YCbCrtoRGB(cp1[0], pp[ 4]);
1839
YCbCrtoRGB(cp1[1], pp[ 5]);
1840
YCbCrtoRGB(cp1[2], pp[ 6]);
1841
YCbCrtoRGB(cp1[3], pp[ 7]);
1842
YCbCrtoRGB(cp2[0], pp[ 8]);
1843
YCbCrtoRGB(cp2[1], pp[ 9]);
1844
YCbCrtoRGB(cp2[2], pp[10]);
1845
YCbCrtoRGB(cp2[3], pp[11]);
1846
YCbCrtoRGB(cp3[0], pp[12]);
1847
YCbCrtoRGB(cp3[1], pp[13]);
1848
YCbCrtoRGB(cp3[2], pp[14]);
1849
YCbCrtoRGB(cp3[3], pp[15]);
1850
1851
cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1852
pp += 18;
1853
} while (--x);
1854
cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1855
pp += fromskew;
1856
}
1857
}
1858
#endif
1859
1860
/*
1861
* 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1862
*/
1863
DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
1864
{
1865
uint32* cp1 = cp+w+toskew;
1866
uint32* cp2 = cp1+w+toskew;
1867
uint32* cp3 = cp2+w+toskew;
1868
int32 incr = 3*w+4*toskew;
1869
1870
(void) y;
1871
/* adjust fromskew */
1872
fromskew = (fromskew / 4) * (4*2+2);
1873
if ((h & 3) == 0 && (w & 3) == 0) {
1874
for (; h >= 4; h -= 4) {
1875
x = w>>2;
1876
do {
1877
int32 Cb = pp[16];
1878
int32 Cr = pp[17];
1879
1880
YCbCrtoRGB(cp [0], pp[ 0]);
1881
YCbCrtoRGB(cp [1], pp[ 1]);
1882
YCbCrtoRGB(cp [2], pp[ 2]);
1883
YCbCrtoRGB(cp [3], pp[ 3]);
1884
YCbCrtoRGB(cp1[0], pp[ 4]);
1885
YCbCrtoRGB(cp1[1], pp[ 5]);
1886
YCbCrtoRGB(cp1[2], pp[ 6]);
1887
YCbCrtoRGB(cp1[3], pp[ 7]);
1888
YCbCrtoRGB(cp2[0], pp[ 8]);
1889
YCbCrtoRGB(cp2[1], pp[ 9]);
1890
YCbCrtoRGB(cp2[2], pp[10]);
1891
YCbCrtoRGB(cp2[3], pp[11]);
1892
YCbCrtoRGB(cp3[0], pp[12]);
1893
YCbCrtoRGB(cp3[1], pp[13]);
1894
YCbCrtoRGB(cp3[2], pp[14]);
1895
YCbCrtoRGB(cp3[3], pp[15]);
1896
1897
cp += 4;
1898
cp1 += 4;
1899
cp2 += 4;
1900
cp3 += 4;
1901
pp += 18;
1902
} while (--x);
1903
cp += incr;
1904
cp1 += incr;
1905
cp2 += incr;
1906
cp3 += incr;
1907
pp += fromskew;
1908
}
1909
} else {
1910
while (h > 0) {
1911
for (x = w; x > 0;) {
1912
int32 Cb = pp[16];
1913
int32 Cr = pp[17];
1914
switch (x) {
1915
default:
1916
switch (h) {
1917
default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
1918
case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
1919
case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1920
case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1921
} /* FALLTHROUGH */
1922
case 3:
1923
switch (h) {
1924
default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
1925
case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
1926
case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1927
case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1928
} /* FALLTHROUGH */
1929
case 2:
1930
switch (h) {
1931
default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
1932
case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
1933
case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1934
case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1935
} /* FALLTHROUGH */
1936
case 1:
1937
switch (h) {
1938
default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
1939
case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
1940
case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1941
case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1942
} /* FALLTHROUGH */
1943
}
1944
if (x < 4) {
1945
cp += x; cp1 += x; cp2 += x; cp3 += x;
1946
x = 0;
1947
}
1948
else {
1949
cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
1950
x -= 4;
1951
}
1952
pp += 18;
1953
}
1954
if (h <= 4)
1955
break;
1956
h -= 4;
1957
cp += incr;
1958
cp1 += incr;
1959
cp2 += incr;
1960
cp3 += incr;
1961
pp += fromskew;
1962
}
1963
}
1964
}
1965
1966
/*
1967
* 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1968
*/
1969
DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
1970
{
1971
uint32* cp1 = cp+w+toskew;
1972
int32 incr = 2*toskew+w;
1973
1974
(void) y;
1975
fromskew = (fromskew / 4) * (4*2+2);
1976
if ((w & 3) == 0 && (h & 1) == 0) {
1977
for (; h >= 2; h -= 2) {
1978
x = w>>2;
1979
do {
1980
int32 Cb = pp[8];
1981
int32 Cr = pp[9];
1982
1983
YCbCrtoRGB(cp [0], pp[0]);
1984
YCbCrtoRGB(cp [1], pp[1]);
1985
YCbCrtoRGB(cp [2], pp[2]);
1986
YCbCrtoRGB(cp [3], pp[3]);
1987
YCbCrtoRGB(cp1[0], pp[4]);
1988
YCbCrtoRGB(cp1[1], pp[5]);
1989
YCbCrtoRGB(cp1[2], pp[6]);
1990
YCbCrtoRGB(cp1[3], pp[7]);
1991
1992
cp += 4;
1993
cp1 += 4;
1994
pp += 10;
1995
} while (--x);
1996
cp += incr;
1997
cp1 += incr;
1998
pp += fromskew;
1999
}
2000
} else {
2001
while (h > 0) {
2002
for (x = w; x > 0;) {
2003
int32 Cb = pp[8];
2004
int32 Cr = pp[9];
2005
switch (x) {
2006
default:
2007
switch (h) {
2008
default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
2009
case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
2010
} /* FALLTHROUGH */
2011
case 3:
2012
switch (h) {
2013
default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
2014
case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
2015
} /* FALLTHROUGH */
2016
case 2:
2017
switch (h) {
2018
default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
2019
case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
2020
} /* FALLTHROUGH */
2021
case 1:
2022
switch (h) {
2023
default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
2024
case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
2025
} /* FALLTHROUGH */
2026
}
2027
if (x < 4) {
2028
cp += x; cp1 += x;
2029
x = 0;
2030
}
2031
else {
2032
cp += 4; cp1 += 4;
2033
x -= 4;
2034
}
2035
pp += 10;
2036
}
2037
if (h <= 2)
2038
break;
2039
h -= 2;
2040
cp += incr;
2041
cp1 += incr;
2042
pp += fromskew;
2043
}
2044
}
2045
}
2046
2047
/*
2048
* 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
2049
*/
2050
DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
2051
{
2052
(void) y;
2053
fromskew = (fromskew / 4) * (4*1+2);
2054
do {
2055
x = w>>2;
2056
while(x>0) {
2057
int32 Cb = pp[4];
2058
int32 Cr = pp[5];
2059
2060
YCbCrtoRGB(cp [0], pp[0]);
2061
YCbCrtoRGB(cp [1], pp[1]);
2062
YCbCrtoRGB(cp [2], pp[2]);
2063
YCbCrtoRGB(cp [3], pp[3]);
2064
2065
cp += 4;
2066
pp += 6;
2067
x--;
2068
}
2069
2070
if( (w&3) != 0 )
2071
{
2072
int32 Cb = pp[4];
2073
int32 Cr = pp[5];
2074
2075
switch( (w&3) ) {
2076
case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/
2077
case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/
2078
case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/
2079
case 0: break;
2080
}
2081
2082
cp += (w&3);
2083
pp += 6;
2084
}
2085
2086
cp += toskew;
2087
pp += fromskew;
2088
} while (--h);
2089
2090
}
2091
2092
/*
2093
* 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
2094
*/
2095
DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
2096
{
2097
uint32* cp2;
2098
int32 incr = 2*toskew+w;
2099
(void) y;
2100
fromskew = (fromskew / 2) * (2*2+2);
2101
cp2 = cp+w+toskew;
2102
while (h>=2) {
2103
x = w;
2104
while (x>=2) {
2105
uint32 Cb = pp[4];
2106
uint32 Cr = pp[5];
2107
YCbCrtoRGB(cp[0], pp[0]);
2108
YCbCrtoRGB(cp[1], pp[1]);
2109
YCbCrtoRGB(cp2[0], pp[2]);
2110
YCbCrtoRGB(cp2[1], pp[3]);
2111
cp += 2;
2112
cp2 += 2;
2113
pp += 6;
2114
x -= 2;
2115
}
2116
if (x==1) {
2117
uint32 Cb = pp[4];
2118
uint32 Cr = pp[5];
2119
YCbCrtoRGB(cp[0], pp[0]);
2120
YCbCrtoRGB(cp2[0], pp[2]);
2121
cp ++ ;
2122
cp2 ++ ;
2123
pp += 6;
2124
}
2125
cp += incr;
2126
cp2 += incr;
2127
pp += fromskew;
2128
h-=2;
2129
}
2130
if (h==1) {
2131
x = w;
2132
while (x>=2) {
2133
uint32 Cb = pp[4];
2134
uint32 Cr = pp[5];
2135
YCbCrtoRGB(cp[0], pp[0]);
2136
YCbCrtoRGB(cp[1], pp[1]);
2137
cp += 2;
2138
cp2 += 2;
2139
pp += 6;
2140
x -= 2;
2141
}
2142
if (x==1) {
2143
uint32 Cb = pp[4];
2144
uint32 Cr = pp[5];
2145
YCbCrtoRGB(cp[0], pp[0]);
2146
}
2147
}
2148
}
2149
2150
/*
2151
* 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
2152
*/
2153
DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
2154
{
2155
(void) y;
2156
fromskew = (fromskew / 2) * (2*1+2);
2157
do {
2158
x = w>>1;
2159
while(x>0) {
2160
int32 Cb = pp[2];
2161
int32 Cr = pp[3];
2162
2163
YCbCrtoRGB(cp[0], pp[0]);
2164
YCbCrtoRGB(cp[1], pp[1]);
2165
2166
cp += 2;
2167
pp += 4;
2168
x --;
2169
}
2170
2171
if( (w&1) != 0 )
2172
{
2173
int32 Cb = pp[2];
2174
int32 Cr = pp[3];
2175
2176
YCbCrtoRGB(cp[0], pp[0]);
2177
2178
cp += 1;
2179
pp += 4;
2180
}
2181
2182
cp += toskew;
2183
pp += fromskew;
2184
} while (--h);
2185
}
2186
2187
/*
2188
* 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
2189
*/
2190
DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
2191
{
2192
uint32* cp2;
2193
int32 incr = 2*toskew+w;
2194
(void) y;
2195
fromskew = (fromskew / 1) * (1 * 2 + 2);
2196
cp2 = cp+w+toskew;
2197
while (h>=2) {
2198
x = w;
2199
do {
2200
uint32 Cb = pp[2];
2201
uint32 Cr = pp[3];
2202
YCbCrtoRGB(cp[0], pp[0]);
2203
YCbCrtoRGB(cp2[0], pp[1]);
2204
cp ++;
2205
cp2 ++;
2206
pp += 4;
2207
} while (--x);
2208
cp += incr;
2209
cp2 += incr;
2210
pp += fromskew;
2211
h-=2;
2212
}
2213
if (h==1) {
2214
x = w;
2215
do {
2216
uint32 Cb = pp[2];
2217
uint32 Cr = pp[3];
2218
YCbCrtoRGB(cp[0], pp[0]);
2219
cp ++;
2220
pp += 4;
2221
} while (--x);
2222
}
2223
}
2224
2225
/*
2226
* 8-bit packed YCbCr samples w/ no subsampling => RGB
2227
*/
2228
DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
2229
{
2230
(void) y;
2231
fromskew = (fromskew / 1) * (1 * 1 + 2);
2232
do {
2233
x = w; /* was x = w>>1; patched 2000/09/25 [email protected] */
2234
do {
2235
int32 Cb = pp[1];
2236
int32 Cr = pp[2];
2237
2238
YCbCrtoRGB(*cp++, pp[0]);
2239
2240
pp += 3;
2241
} while (--x);
2242
cp += toskew;
2243
pp += fromskew;
2244
} while (--h);
2245
}
2246
2247
/*
2248
* 8-bit packed YCbCr samples w/ no subsampling => RGB
2249
*/
2250
DECLARESepPutFunc(putseparate8bitYCbCr11tile)
2251
{
2252
(void) y;
2253
(void) a;
2254
/* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2255
for( ; h > 0; --h) {
2256
x = w;
2257
do {
2258
uint32 dr, dg, db;
2259
TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
2260
*cp++ = PACK(dr,dg,db);
2261
} while (--x);
2262
SKEW(r, g, b, fromskew);
2263
cp += toskew;
2264
}
2265
}
2266
#undef YCbCrtoRGB
2267
2268
static int isInRefBlackWhiteRange(float f)
2269
{
2270
return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF;
2271
}
2272
2273
static int
2274
initYCbCrConversion(TIFFRGBAImage* img)
2275
{
2276
static const char module[] = "initYCbCrConversion";
2277
2278
float *luma, *refBlackWhite;
2279
2280
if (img->ycbcr == NULL) {
2281
img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
2282
TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))
2283
+ 4*256*sizeof (TIFFRGBValue)
2284
+ 2*256*sizeof (int)
2285
+ 3*256*sizeof (int32)
2286
);
2287
if (img->ycbcr == NULL) {
2288
TIFFErrorExt(img->tif->tif_clientdata, module,
2289
"No space for YCbCr->RGB conversion state");
2290
return (0);
2291
}
2292
}
2293
2294
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
2295
TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
2296
&refBlackWhite);
2297
2298
/* Do some validation to avoid later issues. Detect NaN for now */
2299
/* and also if lumaGreen is zero since we divide by it later */
2300
if( luma[0] != luma[0] ||
2301
luma[1] != luma[1] ||
2302
luma[1] == 0.0 ||
2303
luma[2] != luma[2] )
2304
{
2305
TIFFErrorExt(img->tif->tif_clientdata, module,
2306
"Invalid values for YCbCrCoefficients tag");
2307
return (0);
2308
}
2309
2310
if( !isInRefBlackWhiteRange(refBlackWhite[0]) ||
2311
!isInRefBlackWhiteRange(refBlackWhite[1]) ||
2312
!isInRefBlackWhiteRange(refBlackWhite[2]) ||
2313
!isInRefBlackWhiteRange(refBlackWhite[3]) ||
2314
!isInRefBlackWhiteRange(refBlackWhite[4]) ||
2315
!isInRefBlackWhiteRange(refBlackWhite[5]) )
2316
{
2317
TIFFErrorExt(img->tif->tif_clientdata, module,
2318
"Invalid values for ReferenceBlackWhite tag");
2319
return (0);
2320
}
2321
2322
if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
2323
return(0);
2324
return (1);
2325
}
2326
2327
static tileContigRoutine
2328
initCIELabConversion(TIFFRGBAImage* img)
2329
{
2330
static const char module[] = "initCIELabConversion";
2331
2332
float *whitePoint;
2333
float refWhite[3];
2334
2335
TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
2336
if (whitePoint[1] == 0.0f ) {
2337
TIFFErrorExt(img->tif->tif_clientdata, module,
2338
"Invalid value for WhitePoint tag.");
2339
return NULL;
2340
}
2341
2342
if (!img->cielab) {
2343
img->cielab = (TIFFCIELabToRGB *)
2344
_TIFFmalloc(sizeof(TIFFCIELabToRGB));
2345
if (!img->cielab) {
2346
TIFFErrorExt(img->tif->tif_clientdata, module,
2347
"No space for CIE L*a*b*->RGB conversion state.");
2348
return NULL;
2349
}
2350
}
2351
2352
refWhite[1] = 100.0F;
2353
refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
2354
refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
2355
/ whitePoint[1] * refWhite[1];
2356
if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
2357
TIFFErrorExt(img->tif->tif_clientdata, module,
2358
"Failed to initialize CIE L*a*b*->RGB conversion state.");
2359
_TIFFfree(img->cielab);
2360
return NULL;
2361
}
2362
2363
return putcontig8bitCIELab;
2364
}
2365
2366
/*
2367
* Greyscale images with less than 8 bits/sample are handled
2368
* with a table to avoid lots of shifts and masks. The table
2369
* is setup so that put*bwtile (below) can retrieve 8/bitspersample
2370
* pixel values simply by indexing into the table with one
2371
* number.
2372
*/
2373
static int
2374
makebwmap(TIFFRGBAImage* img)
2375
{
2376
TIFFRGBValue* Map = img->Map;
2377
int bitspersample = img->bitspersample;
2378
int nsamples = 8 / bitspersample;
2379
int i;
2380
uint32* p;
2381
2382
if( nsamples == 0 )
2383
nsamples = 1;
2384
2385
img->BWmap = (uint32**) _TIFFmalloc(
2386
256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2387
if (img->BWmap == NULL) {
2388
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
2389
return (0);
2390
}
2391
p = (uint32*)(img->BWmap + 256);
2392
for (i = 0; i < 256; i++) {
2393
TIFFRGBValue c;
2394
img->BWmap[i] = p;
2395
switch (bitspersample) {
2396
#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2397
case 1:
2398
GREY(i>>7);
2399
GREY((i>>6)&1);
2400
GREY((i>>5)&1);
2401
GREY((i>>4)&1);
2402
GREY((i>>3)&1);
2403
GREY((i>>2)&1);
2404
GREY((i>>1)&1);
2405
GREY(i&1);
2406
break;
2407
case 2:
2408
GREY(i>>6);
2409
GREY((i>>4)&3);
2410
GREY((i>>2)&3);
2411
GREY(i&3);
2412
break;
2413
case 4:
2414
GREY(i>>4);
2415
GREY(i&0xf);
2416
break;
2417
case 8:
2418
case 16:
2419
GREY(i);
2420
break;
2421
}
2422
#undef GREY
2423
}
2424
return (1);
2425
}
2426
2427
/*
2428
* Construct a mapping table to convert from the range
2429
* of the data samples to [0,255] --for display. This
2430
* process also handles inverting B&W images when needed.
2431
*/
2432
static int
2433
setupMap(TIFFRGBAImage* img)
2434
{
2435
int32 x, range;
2436
2437
range = (int32)((1L<<img->bitspersample)-1);
2438
2439
/* treat 16 bit the same as eight bit */
2440
if( img->bitspersample == 16 )
2441
range = (int32) 255;
2442
2443
img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
2444
if (img->Map == NULL) {
2445
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
2446
"No space for photometric conversion table");
2447
return (0);
2448
}
2449
if (img->photometric == PHOTOMETRIC_MINISWHITE) {
2450
for (x = 0; x <= range; x++)
2451
img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
2452
} else {
2453
for (x = 0; x <= range; x++)
2454
img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
2455
}
2456
if (img->bitspersample <= 16 &&
2457
(img->photometric == PHOTOMETRIC_MINISBLACK ||
2458
img->photometric == PHOTOMETRIC_MINISWHITE)) {
2459
/*
2460
* Use photometric mapping table to construct
2461
* unpacking tables for samples <= 8 bits.
2462
*/
2463
if (!makebwmap(img))
2464
return (0);
2465
/* no longer need Map, free it */
2466
_TIFFfree(img->Map);
2467
img->Map = NULL;
2468
}
2469
return (1);
2470
}
2471
2472
static int
2473
checkcmap(TIFFRGBAImage* img)
2474
{
2475
uint16* r = img->redcmap;
2476
uint16* g = img->greencmap;
2477
uint16* b = img->bluecmap;
2478
long n = 1L<<img->bitspersample;
2479
2480
while (n-- > 0)
2481
if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
2482
return (16);
2483
return (8);
2484
}
2485
2486
static void
2487
cvtcmap(TIFFRGBAImage* img)
2488
{
2489
uint16* r = img->redcmap;
2490
uint16* g = img->greencmap;
2491
uint16* b = img->bluecmap;
2492
long i;
2493
2494
for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
2495
#define CVT(x) ((uint16)((x)>>8))
2496
r[i] = CVT(r[i]);
2497
g[i] = CVT(g[i]);
2498
b[i] = CVT(b[i]);
2499
#undef CVT
2500
}
2501
}
2502
2503
/*
2504
* Palette images with <= 8 bits/sample are handled
2505
* with a table to avoid lots of shifts and masks. The table
2506
* is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2507
* pixel values simply by indexing into the table with one
2508
* number.
2509
*/
2510
static int
2511
makecmap(TIFFRGBAImage* img)
2512
{
2513
int bitspersample = img->bitspersample;
2514
int nsamples = 8 / bitspersample;
2515
uint16* r = img->redcmap;
2516
uint16* g = img->greencmap;
2517
uint16* b = img->bluecmap;
2518
uint32 *p;
2519
int i;
2520
2521
img->PALmap = (uint32**) _TIFFmalloc(
2522
256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2523
if (img->PALmap == NULL) {
2524
TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
2525
return (0);
2526
}
2527
p = (uint32*)(img->PALmap + 256);
2528
for (i = 0; i < 256; i++) {
2529
TIFFRGBValue c;
2530
img->PALmap[i] = p;
2531
#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2532
switch (bitspersample) {
2533
case 1:
2534
CMAP(i>>7);
2535
CMAP((i>>6)&1);
2536
CMAP((i>>5)&1);
2537
CMAP((i>>4)&1);
2538
CMAP((i>>3)&1);
2539
CMAP((i>>2)&1);
2540
CMAP((i>>1)&1);
2541
CMAP(i&1);
2542
break;
2543
case 2:
2544
CMAP(i>>6);
2545
CMAP((i>>4)&3);
2546
CMAP((i>>2)&3);
2547
CMAP(i&3);
2548
break;
2549
case 4:
2550
CMAP(i>>4);
2551
CMAP(i&0xf);
2552
break;
2553
case 8:
2554
CMAP(i);
2555
break;
2556
}
2557
#undef CMAP
2558
}
2559
return (1);
2560
}
2561
2562
/*
2563
* Construct any mapping table used
2564
* by the associated put routine.
2565
*/
2566
static int
2567
buildMap(TIFFRGBAImage* img)
2568
{
2569
switch (img->photometric) {
2570
case PHOTOMETRIC_RGB:
2571
case PHOTOMETRIC_YCBCR:
2572
case PHOTOMETRIC_SEPARATED:
2573
if (img->bitspersample == 8)
2574
break;
2575
/* fall through... */
2576
case PHOTOMETRIC_MINISBLACK:
2577
case PHOTOMETRIC_MINISWHITE:
2578
if (!setupMap(img))
2579
return (0);
2580
break;
2581
case PHOTOMETRIC_PALETTE:
2582
/*
2583
* Convert 16-bit colormap to 8-bit (unless it looks
2584
* like an old-style 8-bit colormap).
2585
*/
2586
if (checkcmap(img) == 16)
2587
cvtcmap(img);
2588
else
2589
TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
2590
/*
2591
* Use mapping table and colormap to construct
2592
* unpacking tables for samples < 8 bits.
2593
*/
2594
if (img->bitspersample <= 8 && !makecmap(img))
2595
return (0);
2596
break;
2597
}
2598
return (1);
2599
}
2600
2601
/*
2602
* Select the appropriate conversion routine for packed data.
2603
*/
2604
static int
2605
PickContigCase(TIFFRGBAImage* img)
2606
{
2607
img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
2608
img->put.contig = NULL;
2609
switch (img->photometric) {
2610
case PHOTOMETRIC_RGB:
2611
switch (img->bitspersample) {
2612
case 8:
2613
if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
2614
img->samplesperpixel >= 4)
2615
img->put.contig = putRGBAAcontig8bittile;
2616
else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
2617
img->samplesperpixel >= 4)
2618
{
2619
if (BuildMapUaToAa(img))
2620
img->put.contig = putRGBUAcontig8bittile;
2621
}
2622
else if( img->samplesperpixel >= 3 )
2623
img->put.contig = putRGBcontig8bittile;
2624
break;
2625
case 16:
2626
if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
2627
img->samplesperpixel >=4 )
2628
{
2629
if (BuildMapBitdepth16To8(img))
2630
img->put.contig = putRGBAAcontig16bittile;
2631
}
2632
else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
2633
img->samplesperpixel >=4 )
2634
{
2635
if (BuildMapBitdepth16To8(img) &&
2636
BuildMapUaToAa(img))
2637
img->put.contig = putRGBUAcontig16bittile;
2638
}
2639
else if( img->samplesperpixel >=3 )
2640
{
2641
if (BuildMapBitdepth16To8(img))
2642
img->put.contig = putRGBcontig16bittile;
2643
}
2644
break;
2645
}
2646
break;
2647
case PHOTOMETRIC_SEPARATED:
2648
if (img->samplesperpixel >=4 && buildMap(img)) {
2649
if (img->bitspersample == 8) {
2650
if (!img->Map)
2651
img->put.contig = putRGBcontig8bitCMYKtile;
2652
else
2653
img->put.contig = putRGBcontig8bitCMYKMaptile;
2654
}
2655
}
2656
break;
2657
case PHOTOMETRIC_PALETTE:
2658
if (buildMap(img)) {
2659
switch (img->bitspersample) {
2660
case 8:
2661
img->put.contig = put8bitcmaptile;
2662
break;
2663
case 4:
2664
img->put.contig = put4bitcmaptile;
2665
break;
2666
case 2:
2667
img->put.contig = put2bitcmaptile;
2668
break;
2669
case 1:
2670
img->put.contig = put1bitcmaptile;
2671
break;
2672
}
2673
}
2674
break;
2675
case PHOTOMETRIC_MINISWHITE:
2676
case PHOTOMETRIC_MINISBLACK:
2677
if (buildMap(img)) {
2678
switch (img->bitspersample) {
2679
case 16:
2680
img->put.contig = put16bitbwtile;
2681
break;
2682
case 8:
2683
if (img->alpha && img->samplesperpixel == 2)
2684
img->put.contig = putagreytile;
2685
else
2686
img->put.contig = putgreytile;
2687
break;
2688
case 4:
2689
img->put.contig = put4bitbwtile;
2690
break;
2691
case 2:
2692
img->put.contig = put2bitbwtile;
2693
break;
2694
case 1:
2695
img->put.contig = put1bitbwtile;
2696
break;
2697
}
2698
}
2699
break;
2700
case PHOTOMETRIC_YCBCR:
2701
if ((img->bitspersample==8) && (img->samplesperpixel==3))
2702
{
2703
if (initYCbCrConversion(img)!=0)
2704
{
2705
/*
2706
* The 6.0 spec says that subsampling must be
2707
* one of 1, 2, or 4, and that vertical subsampling
2708
* must always be <= horizontal subsampling; so
2709
* there are only a few possibilities and we just
2710
* enumerate the cases.
2711
* Joris: added support for the [1,2] case, nonetheless, to accommodate
2712
* some OJPEG files
2713
*/
2714
uint16 SubsamplingHor;
2715
uint16 SubsamplingVer;
2716
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
2717
switch ((SubsamplingHor<<4)|SubsamplingVer) {
2718
case 0x44:
2719
img->put.contig = putcontig8bitYCbCr44tile;
2720
break;
2721
case 0x42:
2722
img->put.contig = putcontig8bitYCbCr42tile;
2723
break;
2724
case 0x41:
2725
img->put.contig = putcontig8bitYCbCr41tile;
2726
break;
2727
case 0x22:
2728
img->put.contig = putcontig8bitYCbCr22tile;
2729
break;
2730
case 0x21:
2731
img->put.contig = putcontig8bitYCbCr21tile;
2732
break;
2733
case 0x12:
2734
img->put.contig = putcontig8bitYCbCr12tile;
2735
break;
2736
case 0x11:
2737
img->put.contig = putcontig8bitYCbCr11tile;
2738
break;
2739
}
2740
}
2741
}
2742
break;
2743
case PHOTOMETRIC_CIELAB:
2744
if (img->samplesperpixel == 3 && buildMap(img)) {
2745
if (img->bitspersample == 8)
2746
img->put.contig = initCIELabConversion(img);
2747
break;
2748
}
2749
}
2750
return ((img->get!=NULL) && (img->put.contig!=NULL));
2751
}
2752
2753
/*
2754
* Select the appropriate conversion routine for unpacked data.
2755
*
2756
* NB: we assume that unpacked single channel data is directed
2757
* to the "packed routines.
2758
*/
2759
static int
2760
PickSeparateCase(TIFFRGBAImage* img)
2761
{
2762
img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
2763
img->put.separate = NULL;
2764
switch (img->photometric) {
2765
case PHOTOMETRIC_MINISWHITE:
2766
case PHOTOMETRIC_MINISBLACK:
2767
/* greyscale images processed pretty much as RGB by gtTileSeparate */
2768
case PHOTOMETRIC_RGB:
2769
switch (img->bitspersample) {
2770
case 8:
2771
if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2772
img->put.separate = putRGBAAseparate8bittile;
2773
else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2774
{
2775
if (BuildMapUaToAa(img))
2776
img->put.separate = putRGBUAseparate8bittile;
2777
}
2778
else
2779
img->put.separate = putRGBseparate8bittile;
2780
break;
2781
case 16:
2782
if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2783
{
2784
if (BuildMapBitdepth16To8(img))
2785
img->put.separate = putRGBAAseparate16bittile;
2786
}
2787
else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2788
{
2789
if (BuildMapBitdepth16To8(img) &&
2790
BuildMapUaToAa(img))
2791
img->put.separate = putRGBUAseparate16bittile;
2792
}
2793
else
2794
{
2795
if (BuildMapBitdepth16To8(img))
2796
img->put.separate = putRGBseparate16bittile;
2797
}
2798
break;
2799
}
2800
break;
2801
case PHOTOMETRIC_SEPARATED:
2802
if (img->bitspersample == 8 && img->samplesperpixel == 4)
2803
{
2804
img->alpha = 1; // Not alpha, but seems like the only way to get 4th band
2805
img->put.separate = putCMYKseparate8bittile;
2806
}
2807
break;
2808
case PHOTOMETRIC_YCBCR:
2809
if ((img->bitspersample==8) && (img->samplesperpixel==3))
2810
{
2811
if (initYCbCrConversion(img)!=0)
2812
{
2813
uint16 hs, vs;
2814
TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
2815
switch ((hs<<4)|vs) {
2816
case 0x11:
2817
img->put.separate = putseparate8bitYCbCr11tile;
2818
break;
2819
/* TODO: add other cases here */
2820
}
2821
}
2822
}
2823
break;
2824
}
2825
return ((img->get!=NULL) && (img->put.separate!=NULL));
2826
}
2827
2828
static int
2829
BuildMapUaToAa(TIFFRGBAImage* img)
2830
{
2831
static const char module[]="BuildMapUaToAa";
2832
uint8* m;
2833
uint16 na,nv;
2834
assert(img->UaToAa==NULL);
2835
img->UaToAa=_TIFFmalloc(65536);
2836
if (img->UaToAa==NULL)
2837
{
2838
TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
2839
return(0);
2840
}
2841
m=img->UaToAa;
2842
for (na=0; na<256; na++)
2843
{
2844
for (nv=0; nv<256; nv++)
2845
*m++=(uint8)((nv*na+127)/255);
2846
}
2847
return(1);
2848
}
2849
2850
static int
2851
BuildMapBitdepth16To8(TIFFRGBAImage* img)
2852
{
2853
static const char module[]="BuildMapBitdepth16To8";
2854
uint8* m;
2855
uint32 n;
2856
assert(img->Bitdepth16To8==NULL);
2857
img->Bitdepth16To8=_TIFFmalloc(65536);
2858
if (img->Bitdepth16To8==NULL)
2859
{
2860
TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
2861
return(0);
2862
}
2863
m=img->Bitdepth16To8;
2864
for (n=0; n<65536; n++)
2865
*m++=(uint8)((n+128)/257);
2866
return(1);
2867
}
2868
2869
2870
/*
2871
* Read a whole strip off data from the file, and convert to RGBA form.
2872
* If this is the last strip, then it will only contain the portion of
2873
* the strip that is actually within the image space. The result is
2874
* organized in bottom to top form.
2875
*/
2876
2877
2878
int
2879
TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
2880
2881
{
2882
return TIFFReadRGBAStripExt(tif, row, raster, 0 );
2883
}
2884
2885
int
2886
TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error)
2887
2888
{
2889
char emsg[1024] = "";
2890
TIFFRGBAImage img;
2891
int ok;
2892
uint32 rowsperstrip, rows_to_read;
2893
2894
if( TIFFIsTiled( tif ) )
2895
{
2896
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2897
"Can't use TIFFReadRGBAStrip() with tiled file.");
2898
return (0);
2899
}
2900
2901
TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
2902
if( (row % rowsperstrip) != 0 )
2903
{
2904
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2905
"Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2906
return (0);
2907
}
2908
2909
if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
2910
2911
img.row_offset = row;
2912
img.col_offset = 0;
2913
2914
if( row + rowsperstrip > img.height )
2915
rows_to_read = img.height - row;
2916
else
2917
rows_to_read = rowsperstrip;
2918
2919
ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
2920
2921
TIFFRGBAImageEnd(&img);
2922
} else {
2923
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2924
ok = 0;
2925
}
2926
2927
return (ok);
2928
}
2929
2930
/*
2931
* Read a whole tile off data from the file, and convert to RGBA form.
2932
* The returned RGBA data is organized from bottom to top of tile,
2933
* and may include zeroed areas if the tile extends off the image.
2934
*/
2935
2936
int
2937
TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
2938
2939
{
2940
return TIFFReadRGBATileExt(tif, col, row, raster, 0 );
2941
}
2942
2943
2944
int
2945
TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error )
2946
{
2947
char emsg[1024] = "";
2948
TIFFRGBAImage img;
2949
int ok;
2950
uint32 tile_xsize, tile_ysize;
2951
uint32 read_xsize, read_ysize;
2952
uint32 i_row;
2953
2954
/*
2955
* Verify that our request is legal - on a tile file, and on a
2956
* tile boundary.
2957
*/
2958
2959
if( !TIFFIsTiled( tif ) )
2960
{
2961
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2962
"Can't use TIFFReadRGBATile() with stripped file.");
2963
return (0);
2964
}
2965
2966
TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
2967
TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
2968
if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
2969
{
2970
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2971
"Row/col passed to TIFFReadRGBATile() must be top"
2972
"left corner of a tile.");
2973
return (0);
2974
}
2975
2976
/*
2977
* Setup the RGBA reader.
2978
*/
2979
2980
if (!TIFFRGBAImageOK(tif, emsg)
2981
|| !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
2982
TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2983
return( 0 );
2984
}
2985
2986
/*
2987
* The TIFFRGBAImageGet() function doesn't allow us to get off the
2988
* edge of the image, even to fill an otherwise valid tile. So we
2989
* figure out how much we can read, and fix up the tile buffer to
2990
* a full tile configuration afterwards.
2991
*/
2992
2993
if( row + tile_ysize > img.height )
2994
read_ysize = img.height - row;
2995
else
2996
read_ysize = tile_ysize;
2997
2998
if( col + tile_xsize > img.width )
2999
read_xsize = img.width - col;
3000
else
3001
read_xsize = tile_xsize;
3002
3003
/*
3004
* Read the chunk of imagery.
3005
*/
3006
3007
img.row_offset = row;
3008
img.col_offset = col;
3009
3010
ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
3011
3012
TIFFRGBAImageEnd(&img);
3013
3014
/*
3015
* If our read was incomplete we will need to fix up the tile by
3016
* shifting the data around as if a full tile of data is being returned.
3017
*
3018
* This is all the more complicated because the image is organized in
3019
* bottom to top format.
3020
*/
3021
3022
if( read_xsize == tile_xsize && read_ysize == tile_ysize )
3023
return( ok );
3024
3025
for( i_row = 0; i_row < read_ysize; i_row++ ) {
3026
memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
3027
raster + (read_ysize - i_row - 1) * read_xsize,
3028
read_xsize * sizeof(uint32) );
3029
_TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
3030
0, sizeof(uint32) * (tile_xsize - read_xsize) );
3031
}
3032
3033
for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
3034
_TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
3035
0, sizeof(uint32) * tile_xsize );
3036
}
3037
3038
return (ok);
3039
}
3040
3041
/* vim: set ts=8 sts=8 sw=8 noet: */
3042
/*
3043
* Local Variables:
3044
* mode: c
3045
* c-basic-offset: 8
3046
* fill-column: 78
3047
* End:
3048
*/
3049
3050