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