1 /*
2  * Read a Photograph on CD format image.
3  *
4  * Created for xli by Graeme Gill,
5  *
6  * based on information (and some code) from xvphotocd by David Clunie,
7  *
8  * which was based on information from hpcdtoppm by Hadmut Danisch.
9  *
10  */
11 
12 #include "xli.h"
13 #include "imagetypes.h"
14 #include "pcd.h"
15 
16 #undef TEST_DELTA
17 
18 static int read_baseband(pcdHeader *hp, int toff, int sf);
19 static void upsample(pcdHeader *hp, byte *data, int sf);
20 static void pcd_ycc_rgb_init(void);
21 static void pcd_ycc_to_rgb(pcdHeader *hp, Image *image);
22 static void rot_block(byte *Lp, byte *C1p, byte *C2p, int hii, int vii,
23 	byte *op, int voi, int w, int h);
24 static huff *gethufftable(pcdHeader *hp, int *size);
25 static int gethuffdata(pcdHeader * hp, int p, int tb, int db, int sf);
26 
27 /* Read a block into the buffer and update the off counter. */
28 /* If size is > PCDBLOCK, skip blocks and read size % PCDBLOCK */
29 /* return TRUE on error */
pcd_read(pcdHeader * hp,long unsigned int size)30 static boolean pcd_read(pcdHeader *hp, long unsigned int size)
31 {
32 	/* Read in the header block */
33 	while (size > PCDBLOCK) {
34 		if (zread(hp->zf, hp->buf, PCDBLOCK) != PCDBLOCK)
35 			return TRUE;
36 
37 		size -= PCDBLOCK;
38 		hp->off += hp->nob;
39 		hp->nob = PCDBLOCK;
40 	}
41 	if (zread(hp->zf, hp->buf, size) != size)
42 		return TRUE;
43 	hp->off += hp->nob;
44 	hp->nob = size;
45 
46 	/* Reset the bit read stuff */
47 	hp->bp = hp->buf;
48 	hp->bytes_left = size;
49 	return FALSE;
50 }
51 
52 /* Read a block into the specified buffer and update the off counter. */
53 /* return TRUE on error */
pcd_read_to_buf(pcdHeader * hp,byte * buf,long unsigned int size)54 static boolean pcd_read_to_buf(pcdHeader *hp, byte *buf,
55 	long unsigned int size)
56 {
57 	if (zread(hp->zf, buf, size) != size)
58 		return TRUE;
59 
60 	hp->off += (hp->nob + size);
61 	hp->nob = 0;
62 
63 	/* Reset the bit read stuff */
64 	hp->bytes_left = 0;
65 	return FALSE;
66 }
67 
68 /* Read data to align file with the given offset */
69 /* The next read will be data starting at that offset */
70 /* (Need to do this or pcd_skip_blocks() before using */
71 /* bit fetch macros) */
pcd_skip(pcdHeader * hp,long unsigned int toff)72 static boolean pcd_skip(pcdHeader * hp, long unsigned int toff)
73 {
74 	if (toff < pcd_offset(hp)) {
75 		fprintf(stderr,
76 			"pcdLoad: internal error - tried to seek backwards\n");
77 		return TRUE;
78 	}
79 
80 	if (toff > pcd_offset(hp))
81 		if (pcd_read(hp, toff - pcd_offset(hp)))
82 			return TRUE;
83 
84 	/* Clear the byte/bit read stuff, */
85 	/* so it will fetch from aligned address. */
86 	hp->bits = 0;
87 	hp->bytes_left = 0;
88 	hp->bits_left = 0;
89 
90 	return FALSE;
91 }
92 
93 /* Skip to the end of the current block. */
pcd_skip_eob(pcdHeader * hp)94 static boolean pcd_skip_eob(pcdHeader * hp)
95 {
96 	unsigned int toff;
97 	toff = ((pcd_offset(hp) + PCDBMASK) >> PCDSHIFT);
98 	return (pcd_skip(hp, toff * PCDBLOCK));
99 }
100 
101 /* Read the header of the file, and */
102 /* Return TRUE if this looks like a pcd file */
read_pcdHeader(pcdHeader * hp,char * name)103 static boolean read_pcdHeader(pcdHeader * hp, char *name)
104 {
105 	int i, w, h, sz;
106 
107 	CURRFUNC("read_pcdHeader");
108 	if (zread(hp->zf, hp->buf, 32) != 32)
109 		return FALSE;
110 
111 	/* See if it is consistent with a pcd files */
112 	for (i = 0; i < 32; i++)
113 		if (hp->buf[i] != 0xff)
114 			return FALSE;
115 
116 	znocache(hp->zf);
117 
118 	/* Read in the rest of the block */
119 	if (zread(hp->zf, &hp->buf[32], PCDBLOCK - 32) != PCDBLOCK - 32)
120 		return FALSE;
121 
122 	hp->off = 0;
123 	hp->nob = PCDBLOCK;
124 
125 	/* Read in the header block */
126 	if (pcd_read(hp, PCDBLOCK))
127 		return FALSE;
128 
129 	/* Image format ident string (?) */
130 	bcopy(&hp->buf[0x0800 & PCDBMASK], hp->magic, 7);
131 	hp->magic[7] = '\000';
132 	if (strcmp(hp->magic, "PCD_IPI") != 0)
133 		return FALSE;	/* ? */
134 
135 	/* Source (?) */
136 	bcopy(&hp->buf[0x0816 & PCDBMASK], hp->source, 88);
137 	hp->source[88] = '\000';
138 
139 	/* Owner (?) */
140 	bcopy(&hp->buf[0x0870 & PCDBMASK], hp->owner, 20);
141 	hp->owner[20] = '\000';
142 
143 	/* Image orientation */
144 	switch (hp->buf[0x0e02 & PCDBMASK] & 3) {
145 	case 0:
146 		hp->rotate = PCD_NO_ROTATE;
147 		break;
148 	case 1:
149 		hp->rotate = PCD_ACLOCK_ROTATE;
150 		break;
151 	case 3:
152 		hp->rotate = PCD_CLOCK_ROTATE;
153 		break;
154 	default:
155 		fprintf(stderr, "pcd: warning, unrecognized image orientation\n");
156 		hp->rotate = PCD_NO_ROTATE;
157 		break;
158 	}
159 
160 	/* Figure out the default size of the image (allowing for rotation) */
161 	if (hp->rotate == PCD_NO_ROTATE)
162 		w = BASEW * 4, h = BASEH * 4;
163 	else
164 		w = BASEH * 4, h = BASEW * 4;
165 	for (sz = SZ_16B;; sz--, w /= 2, h /= 2) {
166 		if (sz == SZ_B16
167 		    || (w <= hp->width && h <= hp->height
168 		     && ((w * 2) > hp->width || (h * 2) > hp->height))) {
169 			hp->size = sz;
170 			hp->width = w;
171 			hp->height = h;
172 			break;
173 		}
174 	}
175 
176 	/* Re-compute for best quality zoom              */
177 	/* (should actually compute zoom up for speed,   */
178 	/*  and zoom down when "quality" flag selected.) */
179 	if ((hp->xzoom != 0 && hp->xzoom != 100)
180 	    || (hp->yzoom != 0 && hp->yzoom != 100)) {
181 		int tw, th;
182 
183 		if (hp->xzoom != 0 && hp->xzoom != 100)
184 			tw = (int) ((float) hp->width *
185 				(float) hp->xzoom / 100.0 + 0.5);
186 		else
187 			tw = hp->width;
188 
189 		if (hp->yzoom != 0 && hp->yzoom != 100)
190 			th = (int) ((float) hp->height *
191 				(float) hp->yzoom / 100.0 + 0.5);
192 		else
193 			th = hp->height;
194 
195 		/* Set for PCD size larger than requested size */
196 		if (hp->rotate == PCD_NO_ROTATE)
197 			w = BASEW / 4, h = BASEH / 4;
198 		else
199 			w = BASEH / 4, h = BASEW / 4;
200 		for (sz = SZ_B16;; sz++, w *= 2, h *= 2) {
201 			if (sz == SZ_16B || (w >= tw && h >= th)) {
202 				hp->size = sz;
203 				hp->width = w;
204 				hp->height = h;
205 				hp->xzoom = (unsigned int) ((float) tw /
206 					(float) w * 100.0 + 0.5);
207 				hp->yzoom = (unsigned int) ((float) th /
208 					(float) h * 100.0 + 0.5);
209 				break;
210 			}
211 		}
212 	}
213 
214 	/* Return un-rotated dimentions */
215 	if (hp->rotate != PCD_NO_ROTATE) {
216 		int t;
217 		t = hp->width;
218 		hp->width = hp->height;
219 		hp->height = t;
220 	}
221 	hp->name = name;
222 	return TRUE;
223 }
224 
225 /* Print a brief description of the image */
tell_about_pcd(pcdHeader * hp)226 static void tell_about_pcd(pcdHeader * hp)
227 {
228 	printf("%s is a %dx%d Photograph on CD Image%s\n",
229 	       hp->name,
230 	       hp->rotate == PCD_NO_ROTATE ? hp->width : hp->height,
231 	       hp->rotate == PCD_NO_ROTATE ? hp->height : hp->width,
232 	       hp->rotate == PCD_ACLOCK_ROTATE ? " (On right side)" :
233 	       hp->rotate == PCD_CLOCK_ROTATE ? " (On left side)" : "");
234 }
235 
pcdIdent(char * fullname,char * name)236 int pcdIdent(char *fullname, char *name)
237 {
238 	pcdHeader hdr;
239 
240 	CURRFUNC("pcdIdent");
241 	if (!(hdr.zf = zopen(fullname))) {
242 		perror("pcdIdent");
243 		return (0);
244 	}
245 	/* Set a target width and height to the display size */
246 	hdr.width = globals.dinfo.width;
247 	hdr.height = globals.dinfo.height;
248 
249 	if (!read_pcdHeader(&hdr, name)) {
250 		zclose(hdr.zf);
251 		return 0;	/* Nope, not a PCD file */
252 	}
253 	tell_about_pcd(&hdr);
254 	zclose(hdr.zf);
255 	return 1;
256 }
257 
pcdLoad(char * fullname,ImageOptions * image_ops,boolean verbose)258 Image *pcdLoad(char *fullname, ImageOptions * image_ops, boolean verbose)
259 {
260 	pcdHeader hdr;
261 	Image *image;
262 	unsigned long toff;
263 	int sf;			/* target/current image size */
264 
265 	CURRFUNC("pcdLoad");
266 
267 	if (!(hdr.zf = zopen(fullname))) {
268 		perror("pcdIdent");
269 		return (0);
270 	}
271 	/* Set a target width and height to the */
272 	/* screen size. */
273 	hdr.width = globals.dinfo.width * 1.0;
274 	hdr.height = globals.dinfo.height * 1.0;
275 	hdr.xzoom = image_ops->xzoom;
276 	hdr.yzoom = image_ops->yzoom;
277 
278 	if (!read_pcdHeader(&hdr, image_ops->name)) {
279 		zclose(hdr.zf);
280 		return NULL;	/* Nope, not a Photograph on CD file */
281 	}
282 	if (verbose)
283 		tell_about_pcd(&hdr);
284 	znocache(hdr.zf);
285 
286 	image = newTrueImage(hdr.width, hdr.height);
287 	image->title = dupString(hdr.name);
288 	image_ops->xzoom = hdr.xzoom;
289 	image_ops->yzoom = hdr.yzoom;
290 	hdr.Lp = image->data;
291 	hdr.C1p = hdr.Lp + (image->width * image->height);
292 	hdr.C2p = hdr.C1p + (image->width * image->height);
293 
294 	toff = 0;
295 	switch (hdr.size) {
296 	case SZ_B16:
297 		toff = 4 * PCDBLOCK;
298 		sf = 1;
299 		break;
300 	case SZ_B4:
301 		toff = 23 * PCDBLOCK;
302 		sf = 1;
303 		break;
304 	case SZ_B:
305 		toff = 96 * PCDBLOCK;
306 		sf = 1;
307 		break;
308 	case SZ_4B:
309 		toff = 96 * PCDBLOCK;
310 		sf = 2;
311 		break;
312 	case SZ_16B:
313 		toff = 96 * PCDBLOCK;
314 		sf = 4;
315 		break;
316 	default:
317 		fprintf(stderr, "pcdLoad: unknown size %d\n", hdr.size);
318 		goto data_error;
319 		break;
320 	}
321 
322 	/* Read the baseband image */
323 	if (read_baseband(&hdr, toff, sf))
324 		goto data_error;
325 
326 	/* Need to up-sample C1 and C2 */
327 	upsample(&hdr, hdr.C1p, sf);
328 	upsample(&hdr, hdr.C2p, sf);
329 
330 	/* Up sample all components for greater than baseline sizes */
331 	if (sf >= 2) {
332 		if (pcd_skip(&hdr, 384 * PCDBLOCK))	/* skip to start of greater than base stuff */
333 			goto data_short;
334 		sf /= 2;
335 		upsample(&hdr, hdr.Lp, sf);	/* upsample luma */
336 		gethuffdata(&hdr, 1, 4, 5, sf);		/* Add luma delta */
337 		upsample(&hdr, hdr.C1p, sf);	/* upsample chroma */
338 		upsample(&hdr, hdr.C2p, sf);
339 
340 		if (sf >= 2) {
341 			if (pcd_skip_eob(&hdr))		/* Round up to next block */
342 				goto data_short;
343 			sf /= 2;
344 			upsample(&hdr, hdr.Lp, sf);	/* upsample luma */
345 			gethuffdata(&hdr, 3, 12, 14, sf);	/* Add luma and chroma delta */
346 			upsample(&hdr, hdr.C1p, sf);	/* upsample chroma */
347 			upsample(&hdr, hdr.C2p, sf);
348 		}
349 	}
350 	/* Need to convert LC1C2 to RGB */
351 	pcd_ycc_to_rgb(&hdr, image);
352 
353 	zclose(hdr.zf);
354 	image->gamma = 2.05;	/* Approximate CCIR 709 */
355 	return image;
356 
357       data_short:
358 	fprintf(stderr, "pcdLoad: %s - Short read within Data\n", hdr.name);
359       data_error:
360 	zclose(hdr.zf);
361 	return image;
362 }
363 
364 
365 /* Read baseband image components in */
366 /* toff: File block offset to read components from */
367 /* sf: Scale factor down from image size */
read_baseband(pcdHeader * hp,int toff,int sf)368 int read_baseband(pcdHeader * hp, int toff, int sf)
369 {
370 	int h, w, hw;
371 	byte *Lp, *C1p, *C2p;
372 	w = hp->width / sf;	/* width */
373 	hw = w / 2;		/* Half width */
374 
375 	/* skip data to start of appropriate block */
376 	if (pcd_skip(hp, toff))
377 		goto data_short;
378 
379 	/* Read in an image */
380 	for (h = hp->height / (2 * sf), Lp = hp->Lp, C1p = hp->C1p, C2p = hp->C2p;
381 	     h > 0;
382 	     h--) {
383 		/* First row of luma */
384 		if (pcd_read_to_buf(hp, Lp, w))
385 			goto data_short;
386 		Lp += w;
387 
388 		/* Second row of luma */
389 		if (pcd_read_to_buf(hp, Lp, w))
390 			goto data_short;
391 		Lp += w;
392 
393 		/* C1 + C2 */
394 		if (pcd_read_to_buf(hp, C1p, hw))
395 			goto data_short;
396 		C1p += hw;
397 		if (pcd_read_to_buf(hp, C2p, hw))
398 			goto data_short;
399 		C2p += hw;
400 	}
401 	return FALSE;
402 
403       data_short:
404 	fprintf(stderr, "pcd: Short data read in baseband data\n");
405 	return TRUE;
406 }
407 
408 
409 /* xvphotocd upsample */
410 /* The input pixels are at the top left of each resulting four
411  * pixels. Pixels directly between the input pixels are
412  * the average of adjacent pixels. The remaing pixels
413  * are the average of the four diagonal input pixels.
414  */
upsample(pcdHeader * hp,byte * data,int sf)415 void upsample(pcdHeader * hp, byte * data, int sf)
416 			/* start point */
417 			/* Output target/curret size */
418 {
419 	int x, y;
420 	int w, hw, h, hh;	/* Width, half width, height, half height */
421 	int v1, v2;		/* Upper input values */
422 	int v3, v4;		/* Lower input values */
423 	byte *ui, *li;		/* upper/lower input pointers */
424 	byte *uo, *lo;		/* upper/lower output pointers */
425 
426 	w = hp->width / sf;
427 	hw = w / 2;
428 	h = hp->height / sf;
429 	hh = h / 2;
430 
431 	ui = li = uo = lo = 0;
432 	for (y = 0; y < h;) {
433 		if (y == 0) {
434 			ui = li = data + (hw * hh) - 1;		/* last input pixel */
435 			uo = lo = data + (w * h) - 1;	/* last output pixel */
436 			y++;
437 		} else if (y == (h - 1)) {
438 			uo = lo;
439 			ui = li;
440 			y++;
441 		} else
442 			y += 2;
443 
444 		/* First pixel */
445 		v2 = *li;
446 		li -= 1;
447 		v4 = *ui;
448 		ui -= 1;
449 
450 		/* v2 = v2 */
451 		v4 = v4 + v2;
452 
453 		/* First pixel in line */
454 		*lo = v2;
455 		lo -= 1;
456 		*uo = (v4 + 1) >> 1;
457 		uo -= 1;
458 
459 		/* Do middle of double line two pixels at a time */
460 		for (x = 3; x < w; x += 2) {
461 			v1 = v2;
462 			v2 = *li;
463 			li -= 1;
464 			v3 = v4;
465 			v4 = *ui;
466 			ui -= 1;
467 
468 			/* v2 = v2 */
469 			v4 = v4 + v2;
470 
471 			*lo = v1;
472 			*(lo - 1) = (v1 + v2 + 1) >> 1;
473 			lo -= 2;
474 
475 			*uo = (v3 + 1) >> 1;
476 			*(uo - 1) = (v3 + v4 + 2) >> 2;
477 			uo -= 2;
478 		}
479 
480 		/* Last pixel in line */
481 		*lo = v2;
482 		*uo = (v4 + 1) >> 1;
483 
484 		/* Bump input and output pointer to the next double line */
485 		/* ui = ui */
486 		li = ui + hw;
487 		lo = uo - 1;
488 		uo -= (w + 1);
489 	}
490 }
491 
492 /*
493  * LC1C2 to RGB
494  *
495  * Currently just an approximation, since PCD
496  * is (?) really CCIR 601-1 with CCIR 709 primaries,
497  * and what is used below is just an approximation.
498  *
499  * The following code is based on IJPG code.
500  */
501 
502 #define SCALEBITS	16
503 #define ONE_HALF	((int) 1 << (SCALEBITS-1))
504 #define FIX(x)		((int) ((x) * (1<<SCALEBITS) + 0.5))
505 
506 /* This table rounds values to the range 0 to 255 */
507 /* Compression is used for input values between 230 and 346 */
508 byte roundtab[768] =
509 {
510 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
511 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
512 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
513 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
514 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
515 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
516 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
517 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
518 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
519 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
520 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
521 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
522 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
523 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
524 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
525 	0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,  0,
526 	0,  1,  2,  3,  4,  5,  6,  7,  8,  9,  10, 11, 12, 13, 14, 15,
527 	16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
528 	32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
529 	48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
530 	64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
531 	80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
532 	96, 97, 98, 99, 100,101,102,103,104,105,106,107,108,109,110,111,
533 	112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,
534 	128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
535 	144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,
536 	160,161,162,163,164,165,166,167,168,169,170,171,172,173,174,175,
537 	176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,
538 	192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,
539 	208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223,
540 	224,225,226,227,228,229,230,231,232,233,234,235,236,237,237,238,
541 	239,240,240,241,241,242,243,243,244,244,244,245,245,246,246,246,
542 	247,247,247,248,248,248,248,249,249,249,249,249,250,250,250,250,
543 	250,251,251,251,251,251,251,251,251,252,252,252,252,252,252,252,
544 	252,252,252,253,253,253,253,253,253,253,253,253,253,253,253,253,
545 	253,253,253,254,254,254,254,254,254,254,254,254,254,254,254,254,
546 	254,254,254,254,254,254,254,254,254,254,254,255,255,255,255,255,
547 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
548 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
549 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
550 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
551 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
552 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
553 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
554 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
555 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
556 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
557 	255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255
558 };
559 
560 static byte *pcdlimit = NULL;	/* limit table */
561 static byte *pcdround;		/* rounding table */
562 static int *pcdL_y_tab;		/* => table for L to caley y conversion */
563 static int *pcdC2_r_tab;	/* => table for C2 to R conversion */
564 static int *pcdC1_b_tab;	/* => table for C1 to B conversion */
565 static int *pcdC2_g_tab;	/* => table for C2 to G conversion */
566 static int *pcdC1_g_tab;	/* => table for C1 to G conversion */
567 
568 
569 /*
570  * Initialize for colorspace conversion.
571  */
572 
pcd_ycc_rgb_init(void)573 void pcd_ycc_rgb_init(void)
574 {
575 	int i;
576 
577 	CURRFUNC("pcd_ycc_rgb_init");
578 	pcdlimit = 256 + (byte *) lmalloc(3 * 256 * sizeof(byte));
579 
580 	for (i = -256; i < 512; i++) {
581 		if (i < 0)
582 			pcdlimit[i] = 0;
583 		else if (i > 255)
584 			pcdlimit[i] = 255;
585 		else
586 			pcdlimit[i] = i;
587 	}
588 
589 	pcdround = &roundtab[256];
590 	pcdL_y_tab = (int *) lmalloc(256 * sizeof(int));
591 	pcdC2_r_tab = (int *) lmalloc(256 * sizeof(int));
592 	pcdC1_b_tab = (int *) lmalloc(256 * sizeof(int));
593 	pcdC2_g_tab = (int *) lmalloc(256 * sizeof(int));
594 	pcdC1_g_tab = (int *) lmalloc(256 * sizeof(int));
595 
596 	for (i = 0; i < 256; i++) {
597 		int C2, C1;
598 		/* PCD is supposed to be variation on CCIR 601-1 YCrCb
599 		 * It seems that the L channel 100% (diffuse reflection)
600 		 * is set at 182 (although images seem to exceed this value),
601 		 * the C1 zero at 156, and the C2 zero at 137.
602 		 * The Conversion to RGB is supposed to be:
603 		 * R = L + C2
604 		 * G = L - 0.194 C1 - 0.509 C2
605 		 * B = L + C1
606 		 *
607 		 * The primaries are supposed to be CCIR 709 [HDTV], which
608 		 * are slightly different to the normal SMPTE-C RGB primaries.
609 		 * The gamma is suposed to be CCIR 709 - that is linear below
610 		 * 0.018, and exp 1/0.45 above, rather than the SMPTE-C exp 2.2.
611 		 *
612 		 * exp 2.05 is used as an approximation.
613 		 *
614 		 * The following conversion scales RGB by 255/182 to make sure
615 		 * that maximum L gives 255,255,255. This probably causes some
616 		 * clipping. No correction is currently made for CCIR 709 ->
617 		 * SMPTE-C primaries.
618 		 */
619 		C1 = (i - 156);
620 		C2 = (i - 137);
621 #define MAXL 182.0
622 		pcdL_y_tab[i] = (int) (FIX(255.0 / MAXL) * i + ONE_HALF);
623 		pcdC2_r_tab[i] = (int) (FIX(255.0 / MAXL * 1.0) * C2);
624 		pcdC1_b_tab[i] = (int) (FIX(255.0 / MAXL * 1.0) * C1);
625 		pcdC2_g_tab[i] = (int) (-FIX(255.0 / MAXL * 0.509) * C2);
626 		pcdC1_g_tab[i] = (int) (-FIX(255.0 / MAXL * 0.194) * C1);
627 	}
628 }
629 
630 
631 /*
632  * Convert some rows of samples to the output colorspace.
633  * (do rotation at the same time if needed)
634  */
635 
pcd_ycc_to_rgb(pcdHeader * hp,Image * image)636 void pcd_ycc_to_rgb(pcdHeader * hp, Image * image)
637 {
638 	byte *Lp, *C1p, *C2p;
639 	unsigned char *odat;
640 	int x, y, w, h;
641 
642 	CURRFUNC("pcd_ycc_to_rgb");
643 
644 	/* Allocate some output data area */
645 	odat = (unsigned char *) lmalloc(image->width * image->height * 3);
646 
647 	if (pcdlimit == NULL)
648 		pcd_ycc_rgb_init();
649 
650 	/* We do rotation in blocks to minimize */
651 	/* virtual memory thrashing on big images. */
652 #define RBLOCK 128		/* rotate blocking */
653 
654 	Lp = hp->Lp;
655 	C1p = hp->C1p;
656 	C2p = hp->C2p;
657 	/* Image orientation */
658 	switch (hp->rotate) {
659 	case PCD_NO_ROTATE:
660 		w = image->width;
661 		h = image->height;
662 		rot_block(Lp, C1p, C2p, 1, w, odat, w * 3, w, h);
663 		break;
664 	case PCD_ACLOCK_ROTATE:
665 		w = image->height;
666 		h = image->width;
667 		for (y = 0; y < h; y += RBLOCK) {
668 			int soff, ww, wh;
669 			wh = h - y;
670 			if (wh > RBLOCK)
671 				wh = RBLOCK;
672 			for (x = 0; x < w; x += RBLOCK) {
673 				ww = w - x;
674 				if (ww > RBLOCK)
675 					ww = RBLOCK;
676 				soff = h - 1 - y + (x * h);
677 				rot_block(Lp + soff, C1p + soff, C2p + soff, h, -1, odat + 3 * (x + (y * w)), w * 3, ww, wh);
678 			}
679 		}
680 		image->width = w;
681 		image->height = h;
682 		break;
683 	case PCD_CLOCK_ROTATE:
684 		w = image->height;
685 		h = image->width;
686 		for (y = 0; y < h; y += RBLOCK) {
687 			int soff, ww, wh;
688 			wh = h - y;
689 			if (wh > RBLOCK)
690 				wh = RBLOCK;
691 			for (x = 0; x < w; x += RBLOCK) {
692 				ww = w - x;
693 				if (ww > RBLOCK)
694 					ww = RBLOCK;
695 				soff = (w - 1 - x) * h + y;
696 				rot_block(Lp + soff, C1p + soff, C2p + soff, -h, 1, odat + 3 * (x + (y * w)), w * 3, ww, wh);
697 			}
698 		}
699 		image->width = w;
700 		image->height = h;
701 		break;
702 	}
703 	lfree(image->data);
704 	image->data = odat;
705 }
706 
707 /* Rotate and convert a rectangular block */
rot_block(byte * Lp,byte * C1p,byte * C2p,int hii,int vii,byte * op,int voi,int w,int h)708 void rot_block(byte * Lp, byte * C1p, byte * C2p, int hii, int vii, byte * op, int voi, int w, int h)
709 				/* Input start pointers */
710 				/* Horizontal/virtical input increments */
711 					/* Output pointer */
712 				/* Virtical output increment */
713 {
714 	int x, y;
715 	voi -= w * 3;		/* account for horizontal movement */
716 	vii -= w * hii;
717 	for (y = 0; y < h; y++) {
718 		for (x = 0; x < w; x++) {
719 			int l, c1, c2;
720 			l = *Lp;
721 			c1 = *C1p;
722 			c2 = *C2p;
723 			l = pcdL_y_tab[l];
724 			*op = pcdround[(l + pcdC2_r_tab[c2]) >> SCALEBITS];
725 			*(op + 1) = pcdround[(l + pcdC1_g_tab[c1] + pcdC2_g_tab[c2]) >> SCALEBITS];
726 			*(op + 2) = pcdround[(l + pcdC1_b_tab[c1]) >> SCALEBITS];
727 			op += 3;
728 			Lp += hii;
729 			C1p += hii;
730 			C2p += hii;
731 		}
732 		op += voi;
733 		Lp += vii;
734 		C1p += vii;
735 		C2p += vii;
736 	}
737 }
738 
739 /* Huffman encoded data functions.  */
740 
741 /*
742 
743    Read the huffman tables which consist of an unsigned byte giving
744    the number of entries -1, followed by table entries, each of
745    which is a series of 4 unsigned bytes - length, highseq, lowseq,
746    and key.
747 
748    length is the number of bits of the huffman code -1.
749    highseq and lowseq are the huffman code which is msb justified.
750    key is the data value corresponding to that code.
751 
752    The huffman table is stored into an array huff structures.
753    The huff structure holds the length in bits of the
754    corresponding code, and the decoded data value.
755 
756    If the length of the code is less than the size of the array.
757    then the array will contain aliases of that code for every
758    combination of the unused bits.  This way the huffman decoding
759    becomes a straight table lookup. Note that the array must
760    be the size of the longest code.
761 
762  */
763 
764 #define get_byte(dest,hp) \
765 	{ \
766 	if ((hp)->bytes_left <= 0) \
767 		if (pcd_read((hp),PCDBLOCK)) \
768 			goto data_short; \
769 	--(hp)->bytes_left; \
770 	dest = *((hp)->bp++); \
771 	}
772 
773 #define EMPTYHUFF (-32768)	/* nonsense value */
774 
775 static huff *
gethufftable(pcdHeader * hp,int * size)776  gethufftable(pcdHeader * hp, int *size)
777 					/* Table length return value */
778 {
779 	unsigned num, i;
780 	huff *hufftab = NULL;
781 	boolean lht = FALSE;	/* Set if large (16 bit) huffman table */
782 
783 	get_byte(num, hp);
784 	num++;
785 
786 	/* Allocate double space to allow for branch nodes */
787 	hufftab = (huff *) lmalloc(sizeof(huff) * (1 << 12));
788 	bfill(hufftab, sizeof(huff) * (1 << 12), 0xff);
789 
790 	for (i = 0; i < num; i++) {
791 		unsigned int length, codeword, value;
792 		unsigned int j, k;
793 
794 		get_byte(length, hp);
795 		length++;	/* Bit length of code word */
796 		get_byte(codeword, hp);		/* ms byte of codeword */
797 		get_byte(value, hp);	/* ls byte of codeword */
798 		codeword = (codeword << 8) | value;
799 		get_byte(value, hp);	/* decoded value */
800 
801 		if (length > 12) {
802 			if (!lht) {
803 				int sz;
804 				/* Switch to large (16 bit) huffman table */
805 				hufftab = (huff *) lrealloc((byte *)hufftab,
806 					sizeof(huff) * (1 << 16));
807 				for (sz = sizeof(huff) * (1 << 12); sz < (sizeof(huff) * (1 << 16)); sz *= 2)
808 					bcopy((byte *) hufftab, ((byte *) hufftab) + sz, sz);
809 				lht = TRUE;
810 			}
811 			if (length > 16) {
812 				fprintf(stderr, "pcd: Huffman table corrupted\n");
813 				goto data_error;
814 			}
815 		}
816 		j = codeword;
817 		k = codeword + (1 << (16 - length));
818 		if (!lht) {
819 			j >>= (16 - 12);
820 			k >>= (16 - 12);
821 		}
822 		for (; j < k; j++) {
823 			hufftab[j].l = length;
824 			hufftab[j].v = value;
825 		}
826 	}
827 	*size = lht ? 16 : 12;
828 	return hufftab;
829 
830       data_short:
831 	fprintf(stderr, "pcd: Short data read in huffman table\n");
832       data_error:
833 	if (hufftab != NULL)
834 		lfree((byte *) hufftab);
835 	return NULL;
836 }
837 
838 
839 /* We keep the current bits left justified in hp->bits, */
840 /* and return bits right justified. */
841 
842 #define BITS_PER_WORD (sizeof(unsigned int)*8)
843 
844 #define load_byte(hp) \
845 	{ \
846 	if ((hp)->bytes_left <= 0) \
847 		if (pcd_read((hp),PCDBLOCK)) \
848 			goto data_short; \
849 	--(hp)->bytes_left; \
850 	(hp)->bits_left += 8; \
851 	(hp)->bits |= ((unsigned int)(*((hp)->bp++))) << (BITS_PER_WORD - (hp)->bits_left); \
852 	}
853 
854 /* Get (and consume) 1 bit */
855 #define get1bit(dest, hp) \
856 	{ \
857 	if ((hp)->bits_left < 1) \
858 		load_byte(hp); \
859 	(dest) = (hp)->bits >> (BITS_PER_WORD - 1); \
860 	(hp)->bits_left--; \
861 	(hp)->bits <<= 1; \
862 	}
863 
864 /* Get (and consume) nb bits */
865 #define getbits(dest, hp, nb) \
866 	{ \
867 	while ((hp)->bits_left < nb) \
868 		load_byte(hp); \
869 	(dest) = (hp)->bits >> (BITS_PER_WORD - nb); \
870 	(hp)->bits_left -= nb; \
871 	(hp)->bits <<= nb; \
872 	}
873 
874 /* Get nb bits without consuming them */
875 #define nextbits(dest, hp, nb) \
876 	{ \
877 	while ((hp)->bits_left < nb) \
878 		load_byte(hp); \
879 	(dest) = (hp)->bits >> (BITS_PER_WORD - nb); \
880 	}
881 
882 /* Consume nb bits */
883 #define skipbits(hp,nb) \
884 	{ \
885 	while ((hp)->bits_left < nb) \
886 		load_byte(hp); \
887 	(hp)->bits_left -= nb; \
888 	(hp)->bits <<= nb; \
889 	}
890 
891 /* Consume nb bits (assuming previous nextbits( >= nb)) */
892 #define usedbits(hp,nb) \
893 	{ \
894 	(hp)->bits_left -= nb; \
895 	(hp)->bits <<= nb; \
896 	}
897 
898 static int huff_sizes[3];	/* Sizes of huffman tables */
899 static huff *huffs[3];		/* Pointers to huffman tables */
900 
gethuffdata(pcdHeader * hp,int p,int tb,int db,int sf)901 static int gethuffdata(pcdHeader * hp, int p, int tb, int db, int sf)
902 				/* Number of planes expected */
903 				/* Table and Data block offsets from where file is now */
904 				/* scale factor from final size */
905 {
906 	byte *Lp, *C1p, *C2p;
907 	unsigned int bits;
908 	unsigned int soff;
909 	int w, h;		/* width, height */
910 	int i;
911 
912 	Lp = hp->Lp;
913 	C1p = hp->C1p;
914 	C2p = hp->C2p;
915 	w = hp->width / sf;
916 	h = hp->height / sf;
917 
918 	if (pcdlimit == NULL)
919 		pcd_ycc_rgb_init();
920 
921 	soff = pcd_offset(hp);	/* where we are now */
922 	if (pcd_skip(hp, soff + tb * PCDBLOCK))		/* skip to huffman table(s) */
923 		goto data_short;
924 
925 	huffs[0] = huffs[1] = huffs[2] = NULL;
926 	for (i = 0; i < p; i++)
927 		if ((huffs[i] = gethufftable(hp, &huff_sizes[i])) == NULL)
928 			goto data_error;
929 
930 	if (pcd_skip(hp, soff + db * PCDBLOCK))		/* skip to huffman data */
931 		goto data_short;
932 
933 	for (;;) {		/* skip until sync */
934 		nextbits(bits, hp, 24);
935 		if (bits == 0xfffffe)
936 			break;
937 		usedbits(hp, 24);
938 	}
939 
940 	for (;;) {		/* Grab pixel data */
941 		huff *hufft = 0;
942 		int huffsz = -1;
943 		byte *dp = 0;
944 		int wsf = 0;
945 		int col = 0;
946 
947 		nextbits(bits, hp, 24);
948 		if (bits == 0xfffffe) {		/* Found a sync marker */
949 			int plane;
950 			static int pmap[4] =
951 			{0, 3, 1, 2};
952 			int wvi;
953 			int row;
954 
955 			usedbits(hp, 24);
956 
957 			getbits(plane, hp, 2);	/* New line/plane header */
958 			plane = pmap[plane];
959 			getbits(row, hp, 13);
960 			getbits(bits, hp, 1);
961 			if (plane > p) {
962 				fprintf(stderr, "pcd: Illegal plane number in huffman data\n");
963 				goto data_error;
964 			}
965 			hufft = huffs[plane];
966 			huffsz = huff_sizes[plane];
967 			wsf = plane != 0 ? 2 : 1;
968 			wvi = w / wsf;
969 			if ((row * wsf) >= h) {
970 				if ((row * wsf) == h)
971 					break;
972 				fprintf(stderr, "pcd: Huffman data exceeds image size\n");
973 				goto data_error;
974 			}
975 			dp = plane == 0 ? Lp : plane == 1 ? C1p : C2p;
976 			dp += row * wvi;
977 			col = 0;
978 			continue;
979 		}
980 		/* Not sync, must be another pixel delta */
981 		if (col >= w) {
982 			fprintf(stderr, "pcd: Huffman data exceeds image size\n");
983 			goto data_error;
984 		}
985 		if (huffsz == 12) {
986 			int sh, sum;
987 			bits >>= (24 - 12);
988 			sh = hufft[bits].l;
989 			sum = hufft[bits].v;
990 			if (sh > 12) {
991 				fprintf(stderr, "pcd: Unknown huffman data code\n");
992 				goto data_error;
993 			}
994 			usedbits(hp, sh);
995 			sum += *dp;
996 			*dp = pcdlimit[sum];
997 			dp += 1;
998 			col += wsf;
999 		} else {	/* huffsz == 16 */
1000 			int sh, sum;
1001 			bits >>= (24 - 16);
1002 			sh = hufft[bits].l;
1003 			sum = hufft[bits].v;
1004 			if (sh > 16) {
1005 				fprintf(stderr, "pcd: Unknown huffman data code\n");
1006 				goto data_error;
1007 			}
1008 			usedbits(hp, sh);
1009 			sum += *dp;
1010 			*dp = pcdlimit[sum];
1011 			dp += 1;
1012 			col += wsf;
1013 		}
1014 	}
1015 
1016 	for (i = 0; i < p; i++)
1017 		if (huffs[i] != NULL)
1018 			lfree((byte *) huffs[i]);
1019 
1020 	return FALSE;
1021 
1022       data_short:
1023 	fprintf(stderr, "pcd: Short data read in huffman data\n");
1024       data_error:
1025 	for (i = 0; i < p; i++)
1026 		if (huffs[i])
1027 			if (huffs[i] != NULL)
1028 				lfree((byte *) huffs[i]);
1029 	return TRUE;
1030 }
1031