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