xref: /aosp_15_r20/external/pdfium/third_party/libtiff/tif_getimage.c (revision 3ac0a46f773bac49fa9476ec2b1cf3f8da5ec3a4)
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