Home | History | Annotate | Download | only in libtiff
      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 
     36 static int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
     37 static int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
     38 static int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
     39 static int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
     40 static int PickContigCase(TIFFRGBAImage*);
     41 static int PickSeparateCase(TIFFRGBAImage*);
     42 
     43 static int BuildMapUaToAa(TIFFRGBAImage* img);
     44 static int BuildMapBitdepth16To8(TIFFRGBAImage* img);
     45 
     46 static 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 
     58 static const TIFFDisplay display_sRGB = {
     59 	{			/* XYZ -> luminance matrix */
     60 		{  3.2410F, -1.5374F, -0.4986F },
     61 		{  -0.9692F, 1.8760F, 0.0416F },
     62 		{  0.0556F, -0.2040F, 1.0570F }
     63 	},
     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  */
     76 int
     77 TIFFRGBAImageOK(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 
    214 void
    215 TIFFRGBAImageEnd(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 
    240 static int
    241 isCCITTCompression(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 
    251 int
    252 TIFFRGBAImageBegin(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 
    486 int
    487 TIFFRGBAImageGet(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  */
    505 int
    506 TIFFReadRGBAImageOriented(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  */
    531 int
    532 TIFFReadRGBAImage(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 
    539 static int
    540 setorientation(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  */
    606 static int
    607 gtTileContig(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  */
    750 static int
    751 gtTileSeparate(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  */
    918 static int
    919 gtStripContig(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  */
   1008 static int
   1009 gtStripSeparate(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) \
   1207 static 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  */
   1219 DECLAREContigPutFunc(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  */
   1239 DECLAREContigPutFunc(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  */
   1256 DECLAREContigPutFunc(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  */
   1273 DECLAREContigPutFunc(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  */
   1290 DECLAREContigPutFunc(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  */
   1310 DECLAREContigPutFunc(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  */
   1330 DECLAREContigPutFunc(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  */
   1355 DECLAREContigPutFunc(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  */
   1372 DECLAREContigPutFunc(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  */
   1389 DECLAREContigPutFunc(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  */
   1406 DECLAREContigPutFunc(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  */
   1425 DECLAREContigPutFunc(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  */
   1444 DECLAREContigPutFunc(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  */
   1469 DECLAREContigPutFunc(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  */
   1491 DECLAREContigPutFunc(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  */
   1514 DECLAREContigPutFunc(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  */
   1542 DECLAREContigPutFunc(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  */
   1567 DECLAREContigPutFunc(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) \
   1590 static 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  */
   1602 DECLARESepPutFunc(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  */
   1615 DECLARESepPutFunc(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  */
   1628 DECLARESepPutFunc(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  */
   1648 DECLARESepPutFunc(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  */
   1670 DECLARESepPutFunc(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  */
   1689 DECLARESepPutFunc(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  */
   1710 DECLARESepPutFunc(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  */
   1736 DECLAREContigPutFunc(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
   1777 static 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  */
   1847 DECLAREContigPutFunc(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  */
   1944 DECLAREContigPutFunc(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  */
   2022 DECLAREContigPutFunc(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  */
   2067 DECLAREContigPutFunc(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  */
   2125 DECLAREContigPutFunc(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  */
   2162 DECLAREContigPutFunc(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  */
   2200 DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
   2201 {
   2202 	(void) y;
   2203 	fromskew *= 3;
   2204 	do {
   2205 		x = w; /* was x = w>>1; patched 2000/09/25 warmerda (at) 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  */
   2222 DECLARESepPutFunc(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 
   2240 static int
   2241 initYCbCrConversion(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 
   2269 static tileContigRoutine
   2270 initCIELabConversion(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  */
   2309 static int
   2310 makebwmap(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  */
   2368 static int
   2369 setupMap(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 
   2407 static int
   2408 checkcmap(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 
   2421 static void
   2422 cvtcmap(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  */
   2445 static int
   2446 makecmap(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  */
   2501 static int
   2502 buildMap(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  */
   2539 static int
   2540 PickContigCase(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  */
   2694 static int
   2695 PickSeparateCase(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 
   2763 static int
   2764 BuildMapUaToAa(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 
   2785 static int
   2786 BuildMapBitdepth16To8(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 
   2813 int
   2814 TIFFReadRGBAStrip(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 
   2864 int
   2865 TIFFReadRGBATile(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