1 #ifndef lint
2 static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_getimage.c,v 1.8 92/03/11 09:19:10 sam Exp $";
3 #endif
4 
5 /*
6  * Copyright (c) 1991, 1992 Sam Leffler
7  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
8  *
9  * Permission to use, copy, modify, distribute, and sell this software and
10  * its documentation for any purpose is hereby granted without fee, provided
11  * that (i) the above copyright notices and this permission notice appear in
12  * all copies of the software and related documentation, and (ii) the names of
13  * Sam Leffler and Silicon Graphics may not be used in any advertising or
14  * publicity relating to the software without the specific, prior written
15  * permission of Sam Leffler and Silicon Graphics.
16  *
17  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
18  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
19  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
22  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
23  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
24  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
25  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
26  * OF THIS SOFTWARE.
27  */
28 
29 /*
30  * TIFF Library
31  *
32  * Read and return a packed RGBA image.
33  */
34 #include "tiffio.h"
35 #include "tiffcompat.h"
36 #include "prototypes.h"
37 
38 typedef	u_char RGBvalue;
39 
40 static	u_long width, height;		/* image width & height */
41 static	u_short bitspersample;
42 static	u_short samplesperpixel;
43 static	u_short photometric;
44 static	u_short orientation;
45 /* colormap for pallete images */
46 static	u_short *redcmap, *greencmap, *bluecmap;
47 static	int stoponerr;			/* stop on read error */
48 static	char *filename;
49 /* YCbCr support */
50 static	u_short YCbCrHorizSampling;
51 static	u_short YCbCrVertSampling;
52 static	float *YCbCrCoeffs;
53 static	float *refBlackWhite;
54 
55 static	u_long **BWmap;
56 static	u_long **PALmap;
57 
58 static	int gt();
59 
TIFFReadRGBAImage(tif,rwidth,rheight,raster,stop)60 TIFFReadRGBAImage(tif, rwidth, rheight, raster, stop)
61 	TIFF *tif;
62 	u_long rwidth, rheight;
63 	u_long *raster;
64 	int stop;
65 {
66 	int ok;
67 	u_long width, height;
68 
69 	TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
70 	switch (bitspersample) {
71 	case 1: case 2: case 4:
72 	case 8: case 16:
73 		break;
74 	default:
75 		TIFFError(TIFFFileName(tif),
76 		    "Sorry, can not handle %d-bit pictures", bitspersample);
77 		return (0);
78 	}
79 	TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
80 	switch (samplesperpixel) {
81 	case 1: case 3: case 4:
82 		break;
83 	default:
84 		TIFFError(TIFFFileName(tif),
85 		    "Sorry, can not handle %d-channel images", samplesperpixel);
86 		return (0);
87 	}
88 	if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
89 		switch (samplesperpixel) {
90 		case 1:
91 			photometric = PHOTOMETRIC_MINISBLACK;
92 			break;
93 		case 3: case 4:
94 			photometric = PHOTOMETRIC_RGB;
95 			break;
96 		default:
97 			TIFFError(TIFFFileName(tif),
98 			    "Missing needed \"PhotometricInterpretation\" tag");
99 			return (0);
100 		}
101 		TIFFError(TIFFFileName(tif),
102 		    "No \"PhotometricInterpretation\" tag, assuming %s\n",
103 		    photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
104 	}
105 	/* XXX maybe should check photometric? */
106 	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
107 	TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
108 	/* XXX verify rwidth and rheight against width and height */
109 	stoponerr = stop;
110 	BWmap = NULL;
111 	PALmap = NULL;
112 	ok = gt(tif, rwidth, height, raster + (rheight-height)*rwidth);
113 	if (BWmap)
114 		free((char *)BWmap);
115 	if (PALmap)
116 		free((char *)PALmap);
117 	return (ok);
118 }
119 
120 static int
checkcmap(n,r,g,b)121 checkcmap(n, r, g, b)
122 	int n;
123 	u_short *r, *g, *b;
124 {
125 	while (n-- > 0)
126 		if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
127 			return (16);
128 	TIFFWarning(filename, "Assuming 8-bit colormap");
129 	return (8);
130 }
131 
132 static	gtTileContig();
133 static	gtTileSeparate();
134 static	gtStripContig();
135 static	gtStripSeparate();
136 static	void initYCbCrConversion();
137 
138 static
gt(tif,w,h,raster)139 gt(tif, w, h, raster)
140 	TIFF *tif;
141 	int w, h;
142 	u_long *raster;
143 {
144 	u_short minsamplevalue, maxsamplevalue, planarconfig;
145 	RGBvalue *Map;
146 	int e;
147 
148 	TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
149 	TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
150 	Map = NULL;
151 	switch (photometric) {
152 	case PHOTOMETRIC_YCBCR:
153 		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
154 		    &YCbCrCoeffs);
155 		TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
156 		    &YCbCrHorizSampling, &YCbCrVertSampling);
157 		TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
158 		    &refBlackWhite);
159 		initYCbCrConversion();
160 		/* fall thru... */
161 	case PHOTOMETRIC_RGB:
162 		if (minsamplevalue == 0 && maxsamplevalue == 255)
163 			break;
164 		/* fall thru... */
165 	case PHOTOMETRIC_MINISBLACK:
166 	case PHOTOMETRIC_MINISWHITE: {
167 		register int x, range;
168 
169 		range = maxsamplevalue - minsamplevalue;
170 		Map = (RGBvalue *)malloc((range + 1) * sizeof (RGBvalue));
171 		if (Map == NULL) {
172 			TIFFError(filename,
173 			    "No space for photometric conversion table");
174 			return (0);
175 		}
176 		if (photometric == PHOTOMETRIC_MINISWHITE) {
177 			for (x = 0; x <= range; x++)
178 			Map[x] = ((range - x) * 255) / range;
179 		} else {
180 			for (x = 0; x <= range; x++)
181 			Map[x] = (x * 255) / range;
182 		}
183 		if (photometric != PHOTOMETRIC_RGB && bitspersample <= 8) {
184 			/*
185 			 * Use photometric mapping table to construct
186 			 * unpacking tables for samples <= 8 bits.
187 			 */
188 			if (!makebwmap(Map))
189 				return (0);
190 			/* no longer need Map, free it */
191 			free((char *)Map);
192 			Map = NULL;
193 		}
194 		break;
195 	}
196 	case PHOTOMETRIC_PALETTE:
197 		if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
198 				  &redcmap, &greencmap, &bluecmap)) {
199 			TIFFError(filename,
200 			    "Missing required \"Colormap\" tag");
201 			return (0);
202 		}
203 		/*
204 		 * Convert 16-bit colormap to 8-bit (unless it looks
205 		 * like an old-style 8-bit colormap).
206 		 */
207 		if (checkcmap(1<<bitspersample, redcmap, greencmap, bluecmap) == 16) {
208 			int i;
209 			for (i = (1<<bitspersample)-1; i > 0; i--) {
210 #define	CVT(x)		(((x) * 255) / ((1L<<16)-1))
211 				redcmap[i] = CVT(redcmap[i]);
212 				greencmap[i] = CVT(greencmap[i]);
213 				bluecmap[i] = CVT(bluecmap[i]);
214 			}
215 		}
216 		if (bitspersample <= 8) {
217 			/*
218 			 * Use mapping table and colormap to construct
219 			 * unpacking tables for samples < 8 bits.
220 			 */
221 			if (!makecmap(redcmap, greencmap, bluecmap))
222 				return (0);
223 		}
224 		break;
225 	}
226 	TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
227 	if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel > 1) {
228 		e = TIFFIsTiled(tif) ?
229 		    gtTileSeparate(tif, raster, Map, h, w) :
230 		    gtStripSeparate(tif, raster, Map, h, w);
231 	} else {
232 		e = TIFFIsTiled(tif) ?
233 		    gtTileContig(tif, raster, Map, h, w) :
234 		    gtStripContig(tif, raster, Map, h, w);
235 	}
236 	if (Map)
237 		free((char *)Map);
238 	return (e);
239 }
240 
241 u_long
setorientation(tif,h)242 setorientation(tif, h)
243 	TIFF *tif;
244 	u_long h;
245 {
246 	u_long y;
247 
248 	TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
249 	switch (orientation) {
250 	case ORIENTATION_BOTRIGHT:
251 	case ORIENTATION_RIGHTBOT:	/* XXX */
252 	case ORIENTATION_LEFTBOT:	/* XXX */
253 		TIFFWarning(filename, "using bottom-left orientation");
254 		orientation = ORIENTATION_BOTLEFT;
255 		/* fall thru... */
256 	case ORIENTATION_BOTLEFT:
257 		y = 0;
258 		break;
259 	case ORIENTATION_TOPRIGHT:
260 	case ORIENTATION_RIGHTTOP:	/* XXX */
261 	case ORIENTATION_LEFTTOP:	/* XXX */
262 	default:
263 		TIFFWarning(filename, "using top-left orientation");
264 		orientation = ORIENTATION_TOPLEFT;
265 		/* fall thru... */
266 	case ORIENTATION_TOPLEFT:
267 		y = h-1;
268 		break;
269 	}
270 	return (y);
271 }
272 
273 #if USE_PROTOTYPES
274 typedef void (*tileContigRoutine)
275     (u_long*, u_char*, RGBvalue*, u_long, u_long, int, int);
276 static tileContigRoutine pickTileContigCase(RGBvalue*);
277 #else
278 typedef void (*tileContigRoutine)();
279 static tileContigRoutine pickTileContigCase();
280 #endif
281 
282 /*
283  * Get an tile-organized image that has
284  *	PlanarConfiguration contiguous if SamplesPerPixel > 1
285  * or
286  *	SamplesPerPixel == 1
287  */
288 static
gtTileContig(tif,raster,Map,h,w)289 gtTileContig(tif, raster, Map, h, w)
290 	TIFF *tif;
291 	u_long *raster;
292 	RGBvalue *Map;
293 	u_long h, w;
294 {
295 	u_long col, row, y;
296 	u_long tw, th;
297 	u_char *buf;
298 	int fromskew, toskew;
299 	u_int nrow;
300 	tileContigRoutine put;
301 
302 	put = pickTileContigCase(Map);
303 	if (put == 0)
304 		return (0);
305 	buf = (u_char *)malloc(TIFFTileSize(tif));
306 	if (buf == 0) {
307 		TIFFError(filename, "No space for tile buffer");
308 		return (0);
309 	}
310 	TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
311 	TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
312 	y = setorientation(tif, h);
313 	toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
314 	for (row = 0; row < h; row += th) {
315 		nrow = (row + th > h ? h - row : th);
316 		for (col = 0; col < w; col += tw) {
317 			if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 &&
318 			    stoponerr)
319 				break;
320 			if (col + tw > w) {
321 				/*
322 				 * Tile is clipped horizontally.  Calculate
323 				 * visible portion and skewing factors.
324 				 */
325 				u_long npix = w - col;
326 				fromskew = tw - npix;
327 				(*put)(raster + y*w + col, buf, Map,
328 				    npix, nrow, fromskew, toskew + fromskew);
329 			} else
330 				(*put)(raster + y*w + col, buf, Map,
331 				    tw, nrow, 0, toskew);
332 		}
333 		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
334 	}
335 	free(buf);
336 	return (1);
337 }
338 
339 #if USE_PROTOTYPES
340 typedef void (*tileSeparateRoutine)
341     (u_long*, u_char*, u_char*, u_char*, RGBvalue*, u_long, u_long, int, int);
342 static tileSeparateRoutine pickTileSeparateCase(RGBvalue*);
343 #else
344 typedef void (*tileSeparateRoutine)();
345 static tileSeparateRoutine pickTileSeparateCase();
346 #endif
347 
348 /*
349  * Get an tile-organized image that has
350  *	 SamplesPerPixel > 1
351  *	 PlanarConfiguration separated
352  * We assume that all such images are RGB.
353  */
354 static
gtTileSeparate(tif,raster,Map,h,w)355 gtTileSeparate(tif, raster, Map, h, w)
356 	TIFF *tif;
357 	u_long *raster;
358 	RGBvalue *Map;
359 	u_long h, w;
360 {
361 	u_long col, row, y;
362 	u_long tw, th;
363 	u_char *buf;
364 	u_char *r, *g, *b;
365 	int tilesize;
366 	int fromskew, toskew;
367 	u_int nrow;
368 	tileSeparateRoutine put;
369 
370 	put = pickTileSeparateCase(Map);
371 	if (put == 0)
372 		return (0);
373 	tilesize = TIFFTileSize(tif);
374 	buf = (u_char *)malloc(3*tilesize);
375 	if (buf == 0) {
376 		TIFFError(filename, "No space for tile buffer");
377 		return (0);
378 	}
379 	r = buf;
380 	g = r + tilesize;
381 	b = g + tilesize;
382 	TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
383 	TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
384 	y = setorientation(tif, h);
385 	toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
386 	for (row = 0; row < h; row += th) {
387 		nrow = (row + th > h ? h - row : th);
388 		for (col = 0; col < w; col += tw) {
389 			if (TIFFReadTile(tif, r, col, row,0,0) < 0 && stoponerr)
390 				break;
391 			if (TIFFReadTile(tif, g, col, row,0,1) < 0 && stoponerr)
392 				break;
393 			if (TIFFReadTile(tif, b, col, row,0,2) < 0 && stoponerr)
394 				break;
395 			if (col + tw > w) {
396 				/*
397 				 * Tile is clipped horizontally.  Calculate
398 				 * visible portion and skewing factors.
399 				 */
400 				u_long npix = w - col;
401 				fromskew = tw - npix;
402 				(*put)(raster + y*w + col, r, g, b, Map,
403 				    npix, nrow, fromskew, toskew + fromskew);
404 			} else
405 				(*put)(raster + y*w + col, r, g, b, Map,
406 				    tw, nrow, 0, toskew);
407 		}
408 		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
409 	}
410 	free(buf);
411 	return (1);
412 }
413 
414 /*
415  * Get a strip-organized image that has
416  *	PlanarConfiguration contiguous if SamplesPerPixel > 1
417  * or
418  *	SamplesPerPixel == 1
419  */
420 static
gtStripContig(tif,raster,Map,h,w)421 gtStripContig(tif, raster, Map, h, w)
422 	TIFF *tif;
423 	u_long *raster;
424 	RGBvalue *Map;
425 	u_long h, w;
426 {
427 	u_long row, y, nrow;
428 	u_char *buf;
429 	tileContigRoutine put;
430 	u_long rowsperstrip;
431 	u_long imagewidth;
432 	int scanline;
433 	int fromskew, toskew;
434 
435 	put = pickTileContigCase(Map);
436 	if (put == 0)
437 		return (0);
438 	buf = (u_char *)malloc(TIFFStripSize(tif));
439 	if (buf == 0) {
440 		TIFFError(filename, "No space for strip buffer");
441 		return (0);
442 	}
443 	y = setorientation(tif, h);
444 	toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
445 	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
446 	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
447 	scanline = TIFFScanlineSize(tif);
448 	fromskew = (w < imagewidth ? imagewidth - w : 0);
449 	for (row = 0; row < h; row += rowsperstrip) {
450 		nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
451 		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
452 		    buf, nrow*scanline) < 0 && stoponerr)
453 			break;
454 		(*put)(raster + y*w, buf, Map, w, nrow, fromskew, toskew);
455 		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
456 	}
457 	free(buf);
458 	return (1);
459 }
460 
461 /*
462  * Get a strip-organized image with
463  *	 SamplesPerPixel > 1
464  *	 PlanarConfiguration separated
465  * We assume that all such images are RGB.
466  */
467 static
gtStripSeparate(tif,raster,Map,h,w)468 gtStripSeparate(tif, raster, Map, h, w)
469 	TIFF *tif;
470 	u_long *raster;
471 	register RGBvalue *Map;
472 	u_long h, w;
473 {
474 	u_char *buf;
475 	u_char *r, *g, *b;
476 	u_long row, y, nrow;
477 	int scanline;
478 	tileSeparateRoutine put;
479 	u_long rowsperstrip;
480 	u_long imagewidth;
481 	u_int stripsize;
482 	int fromskew, toskew;
483 
484 	stripsize = TIFFStripSize(tif);
485 	r = buf = (u_char *)malloc(3*stripsize);
486 	if (buf == 0)
487 		return (0);
488 	g = r + stripsize;
489 	b = g + stripsize;
490 	put = pickTileSeparateCase(Map);
491 	if (put == 0) {
492 		TIFFError(filename, "Can not handle format");
493 		return (0);
494 	}
495 	y = setorientation(tif, h);
496 	toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
497 	TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
498 	TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
499 	scanline = TIFFScanlineSize(tif);
500 	fromskew = (w < imagewidth ? imagewidth - w : 0);
501 	for (row = 0; row < h; row += rowsperstrip) {
502 		nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
503 		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
504 		    r, nrow*scanline) < 0 && stoponerr)
505 			break;
506 		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
507 		    g, nrow*scanline) < 0 && stoponerr)
508 			break;
509 		if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
510 		    b, nrow*scanline) < 0 && stoponerr)
511 			break;
512 		(*put)(raster + y*w, r, g, b, Map, w, nrow, fromskew, toskew);
513 		y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
514 	}
515 	free(buf);
516 	return (1);
517 }
518 
519 #define	PACK(r,g,b)	((u_long)(r)|((u_long)(g)<<8)|((u_long)(b)<<16))
520 
521 /*
522  * Greyscale images with less than 8 bits/sample are handled
523  * with a table to avoid lots of shifts and masks.  The table
524  * is setup so that put*bwtile (below) can retrieve 8/bitspersample
525  * pixel values simply by indexing into the table with one
526  * number.
527  */
makebwmap(Map)528 makebwmap(Map)
529 	RGBvalue *Map;
530 {
531 	register int i;
532 	int nsamples = 8 / bitspersample;
533 	register u_long *p;
534 
535 	BWmap = (u_long **)malloc(
536 	    256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
537 	if (BWmap == NULL) {
538 		TIFFError(filename, "No space for B&W mapping table");
539 		return (0);
540 	}
541 	p = (u_long *)(BWmap + 256);
542 	for (i = 0; i < 256; i++) {
543 		BWmap[i] = p;
544 		switch (bitspersample) {
545 			register RGBvalue c;
546 #define	GREY(x)	c = Map[x]; *p++ = PACK(c,c,c);
547 		case 1:
548 			GREY(i>>7);
549 			GREY((i>>6)&1);
550 			GREY((i>>5)&1);
551 			GREY((i>>4)&1);
552 			GREY((i>>3)&1);
553 			GREY((i>>2)&1);
554 			GREY((i>>1)&1);
555 			GREY(i&1);
556 			break;
557 		case 2:
558 			GREY(i>>6);
559 			GREY((i>>4)&3);
560 			GREY((i>>2)&3);
561 			GREY(i&3);
562 			break;
563 		case 4:
564 			GREY(i>>4);
565 			GREY(i&0xf);
566 			break;
567 		case 8:
568 			GREY(i);
569 			break;
570 		}
571 #undef	GREY
572 	}
573 	return (1);
574 }
575 
576 /*
577  * Palette images with <= 8 bits/sample are handled
578  * with a table to avoid lots of shifts and masks.  The table
579  * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
580  * pixel values simply by indexing into the table with one
581  * number.
582  */
makecmap(rmap,gmap,bmap)583 makecmap(rmap, gmap, bmap)
584 	u_short *rmap, *gmap, *bmap;
585 {
586 	register int i;
587 	int nsamples = 8 / bitspersample;
588 	register u_long *p;
589 
590 	PALmap = (u_long **)malloc(
591 	    256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
592 	if (PALmap == NULL) {
593 		TIFFError(filename, "No space for Palette mapping table");
594 		return (0);
595 	}
596 	p = (u_long *)(PALmap + 256);
597 	for (i = 0; i < 256; i++) {
598 		PALmap[i] = p;
599 #define	CMAP(x)	\
600 c = x; *p++ = PACK(rmap[c]&0xff, gmap[c]&0xff, bmap[c]&0xff);
601 		switch (bitspersample) {
602 			register RGBvalue c;
603 		case 1:
604 			CMAP(i>>7);
605 			CMAP((i>>6)&1);
606 			CMAP((i>>5)&1);
607 			CMAP((i>>4)&1);
608 			CMAP((i>>3)&1);
609 			CMAP((i>>2)&1);
610 			CMAP((i>>1)&1);
611 			CMAP(i&1);
612 			break;
613 		case 2:
614 			CMAP(i>>6);
615 			CMAP((i>>4)&3);
616 			CMAP((i>>2)&3);
617 			CMAP(i&3);
618 			break;
619 		case 4:
620 			CMAP(i>>4);
621 			CMAP(i&0xf);
622 			break;
623 		case 8:
624 			CMAP(i);
625 			break;
626 		}
627 #undef CMAP
628 	}
629 	return (1);
630 }
631 
632 /*
633  * The following routines move decoded data returned
634  * from the TIFF library into rasters filled with packed
635  * ABGR pixels (i.e. suitable for passing to lrecwrite.)
636  *
637  * The routines have been created according to the most
638  * important cases and optimized.  pickTileContigCase and
639  * pickTileSeparateCase analyze the parameters and select
640  * the appropriate "put" routine to use.
641  */
642 #define	REPEAT8(op)	REPEAT4(op); REPEAT4(op)
643 #define	REPEAT4(op)	REPEAT2(op); REPEAT2(op)
644 #define	REPEAT2(op)	op; op
645 #define	CASE8(x,op)				\
646 	switch (x) {				\
647 	case 7: op; case 6: op; case 5: op;	\
648 	case 4: op; case 3: op; case 2: op;	\
649 	case 1: op;				\
650 	}
651 #define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
652 
653 #define	UNROLL8(w, op1, op2) {		\
654 	register u_long x;		\
655 	for (x = w; x >= 8; x -= 8) {	\
656 		op1;			\
657 		REPEAT8(op2);		\
658 	}				\
659 	if (x > 0) {			\
660 		op1;			\
661 		CASE8(x,op2);		\
662 	}				\
663 }
664 #define	UNROLL4(w, op1, op2) {		\
665 	register u_long x;		\
666 	for (x = w; x >= 4; x -= 4) {	\
667 		op1;			\
668 		REPEAT4(op2);		\
669 	}				\
670 	if (x > 0) {			\
671 		op1;			\
672 		CASE4(x,op2);		\
673 	}				\
674 }
675 #define	UNROLL2(w, op1, op2) {		\
676 	register u_long x;		\
677 	for (x = w; x >= 2; x -= 2) {	\
678 		op1;			\
679 		REPEAT2(op2);		\
680 	}				\
681 	if (x) {			\
682 		op1;			\
683 		op2;			\
684 	}				\
685 }
686 
687 
688 #define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }
689 
690 /*
691  * 8-bit palette => colormap/RGB
692  */
693 static void
put8bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)694 put8bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
695 	register u_long *cp;
696 	register u_char *pp;
697 	RGBvalue *Map;
698 	u_long w, h;
699 	int fromskew, toskew;
700 {
701 	while (h-- > 0) {
702 		UNROLL8(w,, *cp++ = PALmap[*pp++][0]);
703 		cp += toskew;
704 		pp += fromskew;
705 	}
706 }
707 
708 /*
709  * 4-bit palette => colormap/RGB
710  */
711 static void
put4bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)712 put4bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
713 	register u_long *cp;
714 	register u_char *pp;
715 	register RGBvalue *Map;
716 	u_long w, h;
717 	int fromskew, toskew;
718 {
719 	register u_long *bw;
720 
721 	fromskew /= 2;
722 	while (h-- > 0) {
723 		UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
724 		cp += toskew;
725 		pp += fromskew;
726 	}
727 }
728 
729 /*
730  * 2-bit palette => colormap/RGB
731  */
732 static void
put2bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)733 put2bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
734 	register u_long *cp;
735 	register u_char *pp;
736 	register RGBvalue *Map;
737 	u_long w, h;
738 	int fromskew, toskew;
739 {
740 	register u_long *bw;
741 
742 	fromskew /= 4;
743 	while (h-- > 0) {
744 		UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
745 		cp += toskew;
746 		pp += fromskew;
747 	}
748 }
749 
750 /*
751  * 1-bit palette => colormap/RGB
752  */
753 static void
put1bitcmaptile(cp,pp,Map,w,h,fromskew,toskew)754 put1bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
755 	register u_long *cp;
756 	register u_char *pp;
757 	register RGBvalue *Map;
758 	u_long w, h;
759 	int fromskew, toskew;
760 {
761 	register u_long *bw;
762 
763 	fromskew /= 8;
764 	while (h-- > 0) {
765 		UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
766 		cp += toskew;
767 		pp += fromskew;
768 	}
769 }
770 
771 /*
772  * 8-bit greyscale => colormap/RGB
773  */
774 static void
putgreytile(cp,pp,Map,w,h,fromskew,toskew)775 putgreytile(cp, pp, Map, w, h, fromskew, toskew)
776 	register u_long *cp;
777 	register u_char *pp;
778 	RGBvalue *Map;
779 	u_long w, h;
780 	int fromskew, toskew;
781 {
782 	while (h-- > 0) {
783 		register u_long x;
784 		for (x = w; x-- > 0;)
785 			*cp++ = BWmap[*pp++][0];
786 		cp += toskew;
787 		pp += fromskew;
788 	}
789 }
790 
791 /*
792  * 1-bit bilevel => colormap/RGB
793  */
794 static void
put1bitbwtile(cp,pp,Map,w,h,fromskew,toskew)795 put1bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
796 	u_long *cp;
797 	u_char *pp;
798 	RGBvalue *Map;
799 	u_long w, h;
800 	int fromskew, toskew;
801 {
802 	register u_long *bw;
803 
804 	fromskew /= 8;
805 	while (h-- > 0) {
806 		UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
807 		cp += toskew;
808 		pp += fromskew;
809 	}
810 }
811 
812 /*
813  * 2-bit greyscale => colormap/RGB
814  */
815 static void
put2bitbwtile(cp,pp,Map,w,h,fromskew,toskew)816 put2bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
817 	u_long *cp;
818 	u_char *pp;
819 	RGBvalue *Map;
820 	u_long w, h;
821 	int fromskew, toskew;
822 {
823 	register u_long *bw;
824 
825 	fromskew /= 4;
826 	while (h-- > 0) {
827 		UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
828 		cp += toskew;
829 		pp += fromskew;
830 	}
831 }
832 
833 /*
834  * 4-bit greyscale => colormap/RGB
835  */
836 static void
put4bitbwtile(cp,pp,Map,w,h,fromskew,toskew)837 put4bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
838 	u_long *cp;
839 	u_char *pp;
840 	RGBvalue *Map;
841 	u_long w, h;
842 	int fromskew, toskew;
843 {
844 	register u_long *bw;
845 
846 	fromskew /= 2;
847 	while (h-- > 0) {
848 		UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
849 		cp += toskew;
850 		pp += fromskew;
851 	}
852 }
853 
854 /*
855  * 8-bit packed samples => RGB
856  */
857 static void
putRGBcontig8bittile(cp,pp,Map,w,h,fromskew,toskew)858 putRGBcontig8bittile(cp, pp, Map, w, h, fromskew, toskew)
859 	register u_long *cp;
860 	register u_char *pp;
861 	register RGBvalue *Map;
862 	u_long w, h;
863 	int fromskew, toskew;
864 {
865 	fromskew *= samplesperpixel;
866 	if (Map) {
867 		while (h-- > 0) {
868 			register u_long x;
869 			for (x = w; x-- > 0;) {
870 				*cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
871 				pp += samplesperpixel;
872 			}
873 			pp += fromskew;
874 			cp += toskew;
875 		}
876 	} else {
877 		while (h-- > 0) {
878 			UNROLL8(w,,
879 			    *cp++ = PACK(pp[0], pp[1], pp[2]);
880 			    pp += samplesperpixel);
881 			cp += toskew;
882 			pp += fromskew;
883 		}
884 	}
885 }
886 
887 /*
888  * 16-bit packed samples => RGB
889  */
890 static void
putRGBcontig16bittile(cp,pp,Map,w,h,fromskew,toskew)891 putRGBcontig16bittile(cp, pp, Map, w, h, fromskew, toskew)
892 	register u_long *cp;
893 	u_char *pp;
894 	register RGBvalue *Map;
895 	u_long w, h;
896 	int fromskew, toskew;
897 {
898 	register u_short *wp = (u_short *)pp;
899 	register u_int x;
900 
901 	fromskew *= samplesperpixel;
902 	if (Map) {
903 		while (h-- > 0) {
904 			for (x = w; x-- > 0;) {
905 				*cp++ = PACK(Map[wp[0]], Map[wp[1]], Map[wp[2]]);
906 				wp += samplesperpixel;
907 			}
908 			cp += toskew;
909 			wp += fromskew;
910 		}
911 	} else {
912 		while (h-- > 0) {
913 			for (x = w; x-- > 0;) {
914 				*cp++ = PACK(wp[0], wp[1], wp[2]);
915 				wp += samplesperpixel;
916 			}
917 			cp += toskew;
918 			wp += fromskew;
919 		}
920 	}
921 }
922 
923 /*
924  * 8-bit unpacked samples => RGB
925  */
926 static void
putRGBseparate8bittile(cp,r,g,b,Map,w,h,fromskew,toskew)927 putRGBseparate8bittile(cp, r, g, b, Map, w, h, fromskew, toskew)
928 	register u_long *cp;
929 	register u_char *r, *g, *b;
930 	register RGBvalue *Map;
931 	u_long w, h;
932 	int fromskew, toskew;
933 
934 {
935 	if (Map) {
936 		while (h-- > 0) {
937 			register u_long x;
938 			for (x = w; x > 0; x--)
939 				*cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
940 			SKEW(r, g, b, fromskew);
941 			cp += toskew;
942 		}
943 	} else {
944 		while (h-- > 0) {
945 			UNROLL8(w,, *cp++ = PACK(*r++, *g++, *b++));
946 			SKEW(r, g, b, fromskew);
947 			cp += toskew;
948 		}
949 	}
950 }
951 
952 /*
953  * 16-bit unpacked samples => RGB
954  */
955 static void
putRGBseparate16bittile(cp,br,bg,bb,Map,w,h,fromskew,toskew)956 putRGBseparate16bittile(cp, br, bg, bb, Map, w, h, fromskew, toskew)
957 	register u_long *cp;
958 	u_char *br, *bg, *bb;
959 	register RGBvalue *Map;
960 	u_long w, h;
961 	int fromskew, toskew;
962 {
963 	register u_short *r = (u_short *)br;
964 	register u_short *g = (u_short *)bg;
965 	register u_short *b = (u_short *)bb;
966 	register u_long x;
967 
968 	if (Map) {
969 		while (h-- > 0) {
970 			for (x = w; x > 0; x--)
971 				*cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
972 			SKEW(r, g, b, fromskew);
973 			cp += toskew;
974 		}
975 	} else {
976 		while (h-- > 0) {
977 			for (x = 0; x < w; x++)
978 				*cp++ = PACK(*r++, *g++, *b++);
979 			SKEW(r, g, b, fromskew);
980 			cp += toskew;
981 		}
982 	}
983 }
984 
985 #define	Code2V(c, RB, RW, CR)	((((c)-RB)*(float)CR)/(float)(RW-RB))
986 #define	CLAMP(f,min,max) \
987     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
988 
989 #define	LumaRed		YCbCrCoeffs[0]
990 #define	LumaGreen	YCbCrCoeffs[1]
991 #define	LumaBlue	YCbCrCoeffs[2]
992 
993 static	float D1, D2;
994 static	float D3, D4;
995 
996 static void
initYCbCrConversion()997 initYCbCrConversion()
998 {
999 	D1 = 2 - 2*LumaRed;
1000 	D2 = D1*LumaRed / LumaGreen;
1001 	D3 = 2 - 2*LumaBlue;
1002 	D4 = D2*LumaBlue / LumaGreen;
1003 }
1004 
1005 static void
putRGBContigYCbCrClump(cp,pp,cw,ch,w,n,fromskew,toskew)1006 putRGBContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
1007 	register u_long *cp;
1008 	register u_char *pp;
1009 	int cw, ch;
1010 	u_long w;
1011 	int n, fromskew, toskew;
1012 {
1013 	float Cb, Cr;
1014 	int j, k;
1015 
1016 	Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
1017 	Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
1018 	for (j = 0; j < ch; j++) {
1019 		for (k = 0; k < cw; k++) {
1020 			float Y, R, G, B;
1021 			Y = Code2V(*pp++,
1022 			    refBlackWhite[0], refBlackWhite[1], 255);
1023 			R = Y + Cr*D1;
1024 			B = Y + Cb*D3;
1025 			G = Y - Cb*D4 - Cr*D2;
1026 			cp[k] = PACK(CLAMP(R,0,255),
1027 				     CLAMP(G,0,255),
1028 				     CLAMP(B,0,255));
1029 		}
1030 		cp += w+toskew;
1031 		pp += fromskew;
1032 	}
1033 }
1034 #undef LumaBlue
1035 #undef LumaGreen
1036 #undef LumaRed
1037 #undef CLAMP
1038 #undef Code2V
1039 
1040 /*
1041  * 8-bit packed YCbCr samples => RGB
1042  */
1043 static void
putcontig8bitYCbCrtile(cp,pp,Map,w,h,fromskew,toskew)1044 putcontig8bitYCbCrtile(cp, pp, Map, w, h, fromskew, toskew)
1045 	register u_long *cp;
1046 	register u_char *pp;
1047 	register RGBvalue *Map;
1048 	u_long w, h;
1049 	int fromskew, toskew;
1050 {
1051 	u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
1052 	u_long *tp;
1053 	u_long x;
1054 
1055 	/* XXX adjust fromskew */
1056 	while (h >= YCbCrVertSampling) {
1057 		tp = cp;
1058 		for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
1059 			putRGBContigYCbCrClump(tp, pp,
1060 			    YCbCrHorizSampling, YCbCrVertSampling,
1061 			    w, Coff, 0, toskew);
1062 			tp += YCbCrHorizSampling;
1063 			pp += Coff+2;
1064 		}
1065 		if (x > 0) {
1066 			putRGBContigYCbCrClump(tp, pp,
1067 			    x, YCbCrVertSampling,
1068 			    w, Coff, YCbCrHorizSampling - x, toskew);
1069 			pp += Coff+2;
1070 		}
1071 		cp += YCbCrVertSampling*(w + toskew);
1072 		pp += fromskew;
1073 		h -= YCbCrVertSampling;
1074 	}
1075 	if (h > 0) {
1076 		tp = cp;
1077 		for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
1078 			putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, h,
1079 			    w, Coff, 0, toskew);
1080 			tp += YCbCrHorizSampling;
1081 			pp += Coff+2;
1082 		}
1083 		if (x > 0)
1084 			putRGBContigYCbCrClump(tp, pp, x, h,
1085 			    w, Coff, YCbCrHorizSampling - x, toskew);
1086 	}
1087 }
1088 
1089 /*
1090  * Select the appropriate conversion routine for packed data.
1091  */
1092 static tileContigRoutine
DECLARE1(pickTileContigCase,RGBvalue *,Map)1093 DECLARE1(pickTileContigCase, RGBvalue*, Map)
1094 {
1095 	tileContigRoutine put = 0;
1096 
1097 	switch (photometric) {
1098 	case PHOTOMETRIC_RGB:
1099 		put = (bitspersample == 8 ?
1100 		    putRGBcontig8bittile : putRGBcontig16bittile);
1101 		break;
1102 	case PHOTOMETRIC_PALETTE:
1103 		switch (bitspersample) {
1104 		case 8:	put = put8bitcmaptile; break;
1105 		case 4: put = put4bitcmaptile; break;
1106 		case 2: put = put2bitcmaptile; break;
1107 		case 1: put = put1bitcmaptile; break;
1108 		}
1109 		break;
1110 	case PHOTOMETRIC_MINISWHITE:
1111 	case PHOTOMETRIC_MINISBLACK:
1112 		switch (bitspersample) {
1113 		case 8:	put = putgreytile; break;
1114 		case 4: put = put4bitbwtile; break;
1115 		case 2: put = put2bitbwtile; break;
1116 		case 1: put = put1bitbwtile; break;
1117 		}
1118 		break;
1119 	case PHOTOMETRIC_YCBCR:
1120 		switch (bitspersample) {
1121 		case 8: put = putcontig8bitYCbCrtile; break;
1122 		}
1123 		break;
1124 	}
1125 	if (put == 0)
1126 		TIFFError(filename, "Can not handle format");
1127 	return (put);
1128 }
1129 
1130 /*
1131  * Select the appropriate conversion routine for unpacked data.
1132  *
1133  * NB: we assume that unpacked single channel data is directed
1134  *	 to the "packed routines.
1135  */
1136 static tileSeparateRoutine
DECLARE1(pickTileSeparateCase,RGBvalue *,Map)1137 DECLARE1(pickTileSeparateCase, RGBvalue*, Map)
1138 {
1139 	tileSeparateRoutine put = 0;
1140 
1141 	switch (photometric) {
1142 	case PHOTOMETRIC_RGB:
1143 		put = (bitspersample == 8 ?
1144 		    putRGBseparate8bittile : putRGBseparate16bittile);
1145 		break;
1146 	}
1147 	if (put == 0)
1148 		TIFFError(filename, "Can not handle format");
1149 	return (put);
1150 }
1151