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