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