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