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