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