]>
Commit | Line | Data |
---|---|---|
ef416fc2 | 1 | /* |
bc44d920 | 2 | * "$Id: image-tiff.c 6649 2007-07-11 21:46:42Z mike $" |
ef416fc2 | 3 | * |
4 | * TIFF file routines for the Common UNIX Printing System (CUPS). | |
5 | * | |
bc44d920 | 6 | * Copyright 2007 by Apple Inc. |
c0e1af83 | 7 | * Copyright 1993-2007 by Easy Software Products. |
ef416fc2 | 8 | * |
9 | * These coded instructions, statements, and computer programs are the | |
bc44d920 | 10 | * property of Apple Inc. and are protected by Federal copyright |
11 | * law. Distribution and use rights are outlined in the file "LICENSE.txt" | |
12 | * which should have been included with this file. If this file is | |
13 | * file is missing or damaged, see the license at "http://www.cups.org/". | |
ef416fc2 | 14 | * |
15 | * This file is subject to the Apple OS-Developed Software exception. | |
16 | * | |
17 | * Contents: | |
18 | * | |
19 | * _cupsImageReadTIFF() - Read a TIFF image file. | |
20 | */ | |
21 | ||
22 | /* | |
23 | * Include necessary headers... | |
24 | */ | |
25 | ||
26 | #include "image-private.h" | |
27 | ||
28 | #ifdef HAVE_LIBTIFF | |
29 | # include <tiff.h> /* TIFF image definitions */ | |
30 | # include <tiffio.h> | |
31 | # include <unistd.h> | |
32 | ||
33 | ||
34 | /* | |
35 | * '_cupsImageReadTIFF()' - Read a TIFF image file. | |
36 | */ | |
37 | ||
38 | int /* O - Read status */ | |
39 | _cupsImageReadTIFF( | |
40 | cups_image_t *img, /* IO - cupsImage */ | |
41 | FILE *fp, /* I - cupsImage file */ | |
42 | cups_icspace_t primary, /* I - Primary choice for colorspace */ | |
43 | cups_icspace_t secondary, /* I - Secondary choice for colorspace */ | |
44 | int saturation, /* I - Color saturation (%) */ | |
45 | int hue, /* I - Color hue (degrees) */ | |
46 | const cups_ib_t *lut) /* I - Lookup table for gamma/brightness */ | |
47 | { | |
48 | TIFF *tif; /* TIFF file */ | |
49 | uint32 width, height; /* Size of image */ | |
50 | uint16 photometric, /* Colorspace */ | |
51 | compression, /* Type of compression */ | |
52 | orientation, /* Orientation */ | |
53 | resunit, /* Units for resolution */ | |
54 | samples, /* Number of samples/pixel */ | |
55 | bits, /* Number of bits/pixel */ | |
56 | inkset, /* Ink set for color separations */ | |
57 | numinks; /* Number of inks in set */ | |
58 | float xres, /* Horizontal resolution */ | |
59 | yres; /* Vertical resolution */ | |
60 | uint16 *redcmap, /* Red colormap information */ | |
61 | *greencmap, /* Green colormap information */ | |
62 | *bluecmap; /* Blue colormap information */ | |
63 | int c, /* Color index */ | |
64 | num_colors, /* Number of colors */ | |
65 | bpp, /* Bytes per pixel */ | |
66 | x, y, /* Current x & y */ | |
67 | row, /* Current row in image */ | |
68 | xstart, ystart, /* Starting x & y */ | |
69 | xdir, ydir, /* X & y direction */ | |
70 | xcount, ycount, /* X & Y counters */ | |
71 | pstep, /* Pixel step (= bpp or -2 * bpp) */ | |
72 | scanwidth, /* Width of scanline */ | |
73 | r, g, b, k, /* Red, green, blue, and black values */ | |
74 | alpha; /* cupsImage includes alpha? */ | |
75 | cups_ib_t *in, /* Input buffer */ | |
76 | *out, /* Output buffer */ | |
77 | *p, /* Pointer into buffer */ | |
78 | *scanline, /* Scanline buffer */ | |
79 | *scanptr, /* Pointer into scanline buffer */ | |
80 | bit, /* Current bit */ | |
81 | pixel, /* Current pixel */ | |
82 | zero, /* Zero value (bitmaps) */ | |
83 | one; /* One value (bitmaps) */ | |
84 | ||
85 | ||
86 | /* | |
87 | * Open the TIFF file and get the required parameters... | |
88 | */ | |
89 | ||
90 | lseek(fileno(fp), 0, SEEK_SET); /* Work around "feature" in some stdio's */ | |
91 | ||
92 | if ((tif = TIFFFdOpen(fileno(fp), "", "r")) == NULL) | |
93 | { | |
c0e1af83 | 94 | fputs("DEBUG: TIFFFdOpen() failed!\n", stderr); |
ef416fc2 | 95 | fclose(fp); |
96 | return (-1); | |
97 | } | |
98 | ||
99 | if (!TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width)) | |
100 | { | |
c0e1af83 | 101 | fputs("DEBUG: No image width tag in the file!\n", stderr); |
ef416fc2 | 102 | TIFFClose(tif); |
103 | fclose(fp); | |
104 | return (-1); | |
105 | } | |
106 | ||
107 | if (!TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height)) | |
108 | { | |
c0e1af83 | 109 | fputs("DEBUG: No image height tag in the file!\n", stderr); |
ef416fc2 | 110 | TIFFClose(tif); |
111 | fclose(fp); | |
112 | return (-1); | |
113 | } | |
114 | ||
115 | if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) | |
116 | { | |
c0e1af83 | 117 | fputs("DEBUG: No photometric tag in the file!\n", stderr); |
ef416fc2 | 118 | TIFFClose(tif); |
119 | fclose(fp); | |
120 | return (-1); | |
121 | } | |
122 | ||
123 | if (!TIFFGetField(tif, TIFFTAG_COMPRESSION, &compression)) | |
124 | { | |
c0e1af83 | 125 | fputs("DEBUG: No compression tag in the file!\n", stderr); |
ef416fc2 | 126 | TIFFClose(tif); |
127 | fclose(fp); | |
128 | return (-1); | |
129 | } | |
130 | ||
131 | if (!TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samples)) | |
132 | samples = 1; | |
133 | ||
134 | if (!TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bits)) | |
135 | bits = 1; | |
136 | ||
137 | /* | |
138 | * Get the image orientation... | |
139 | */ | |
140 | ||
141 | if (!TIFFGetField(tif, TIFFTAG_ORIENTATION, &orientation)) | |
142 | orientation = 0; | |
143 | ||
144 | /* | |
145 | * Get the image resolution... | |
146 | */ | |
147 | ||
148 | if (TIFFGetField(tif, TIFFTAG_XRESOLUTION, &xres) && | |
149 | TIFFGetField(tif, TIFFTAG_YRESOLUTION, &yres) && | |
150 | TIFFGetField(tif, TIFFTAG_RESOLUTIONUNIT, &resunit)) | |
151 | { | |
152 | if (resunit == RESUNIT_INCH) | |
153 | { | |
154 | img->xppi = xres; | |
155 | img->yppi = yres; | |
156 | } | |
157 | else if (resunit == RESUNIT_CENTIMETER) | |
158 | { | |
159 | img->xppi = xres * 2.54; | |
160 | img->yppi = yres * 2.54; | |
161 | } | |
162 | else | |
163 | { | |
164 | img->xppi = 128; | |
165 | img->yppi = 128; | |
166 | } | |
167 | ||
168 | if (img->xppi == 0 || img->yppi == 0) | |
169 | { | |
c0e1af83 | 170 | fputs("DEBUG: Bad TIFF resolution.\n", stderr); |
ef416fc2 | 171 | img->xppi = img->yppi = 128; |
172 | } | |
173 | ||
174 | fprintf(stderr, "DEBUG: TIFF resolution = %fx%f, units=%d\n", | |
175 | xres, yres, resunit); | |
176 | fprintf(stderr, "DEBUG: Stored resolution = %dx%d PPI\n", | |
177 | img->xppi, img->yppi); | |
178 | } | |
179 | ||
180 | /* | |
181 | * See if the image has an alpha channel... | |
182 | */ | |
183 | ||
184 | if (samples == 2 || (samples == 4 && photometric == PHOTOMETRIC_RGB)) | |
185 | alpha = 1; | |
186 | else | |
187 | alpha = 0; | |
188 | ||
189 | /* | |
190 | * Check the size of the image... | |
191 | */ | |
192 | ||
193 | if (width == 0 || width > CUPS_IMAGE_MAX_WIDTH || | |
194 | height == 0 || height > CUPS_IMAGE_MAX_HEIGHT || | |
195 | (bits != 1 && bits != 2 && bits != 4 && bits != 8) || | |
196 | samples < 1 || samples > 4) | |
197 | { | |
c0e1af83 | 198 | fprintf(stderr, "DEBUG: Bad TIFF dimensions %ux%ux%ux%u!\n", |
ef416fc2 | 199 | (unsigned)width, (unsigned)height, (unsigned)bits, |
200 | (unsigned)samples); | |
201 | TIFFClose(tif); | |
202 | fclose(fp); | |
203 | return (1); | |
204 | } | |
205 | ||
206 | /* | |
207 | * Setup the image size and colorspace... | |
208 | */ | |
209 | ||
210 | img->xsize = width; | |
211 | img->ysize = height; | |
212 | if (photometric == PHOTOMETRIC_MINISBLACK || | |
213 | photometric == PHOTOMETRIC_MINISWHITE) | |
214 | img->colorspace = secondary; | |
215 | else if (photometric == PHOTOMETRIC_SEPARATED && primary == CUPS_IMAGE_RGB_CMYK) | |
216 | img->colorspace = CUPS_IMAGE_CMYK; | |
217 | else if (primary == CUPS_IMAGE_RGB_CMYK) | |
218 | img->colorspace = CUPS_IMAGE_RGB; | |
219 | else | |
220 | img->colorspace = primary; | |
221 | ||
222 | fprintf(stderr, "DEBUG: img->colorspace = %d\n", img->colorspace); | |
223 | ||
224 | bpp = cupsImageGetDepth(img); | |
225 | ||
226 | cupsImageSetMaxTiles(img, 0); | |
227 | ||
228 | /* | |
229 | * Set the X & Y start and direction according to the image orientation... | |
230 | */ | |
231 | ||
232 | switch (orientation) | |
233 | { | |
234 | case ORIENTATION_TOPRIGHT : | |
235 | fputs("DEBUG: orientation = top-right\n", stderr); | |
236 | break; | |
237 | case ORIENTATION_RIGHTTOP : | |
238 | fputs("DEBUG: orientation = right-top\n", stderr); | |
239 | break; | |
240 | default : | |
241 | case ORIENTATION_TOPLEFT : | |
242 | fputs("DEBUG: orientation = top-left\n", stderr); | |
243 | break; | |
244 | case ORIENTATION_LEFTTOP : | |
245 | fputs("DEBUG: orientation = left-top\n", stderr); | |
246 | break; | |
247 | case ORIENTATION_BOTLEFT : | |
248 | fputs("DEBUG: orientation = bottom-left\n", stderr); | |
249 | break; | |
250 | case ORIENTATION_LEFTBOT : | |
251 | fputs("DEBUG: orientation = left-bottom\n", stderr); | |
252 | break; | |
253 | case ORIENTATION_BOTRIGHT : | |
254 | fputs("DEBUG: orientation = bottom-right\n", stderr); | |
255 | break; | |
256 | case ORIENTATION_RIGHTBOT : | |
257 | fputs("DEBUG: orientation = right-bottom\n", stderr); | |
258 | break; | |
259 | } | |
260 | ||
261 | switch (orientation) | |
262 | { | |
263 | case ORIENTATION_TOPRIGHT : | |
264 | case ORIENTATION_RIGHTTOP : | |
265 | xstart = img->xsize - 1; | |
266 | xdir = -1; | |
267 | ystart = 0; | |
268 | ydir = 1; | |
269 | break; | |
270 | default : | |
271 | case ORIENTATION_TOPLEFT : | |
272 | case ORIENTATION_LEFTTOP : | |
273 | xstart = 0; | |
274 | xdir = 1; | |
275 | ystart = 0; | |
276 | ydir = 1; | |
277 | break; | |
278 | case ORIENTATION_BOTLEFT : | |
279 | case ORIENTATION_LEFTBOT : | |
280 | xstart = 0; | |
281 | xdir = 1; | |
282 | ystart = img->ysize - 1; | |
283 | ydir = -1; | |
284 | break; | |
285 | case ORIENTATION_BOTRIGHT : | |
286 | case ORIENTATION_RIGHTBOT : | |
287 | xstart = img->xsize - 1; | |
288 | xdir = -1; | |
289 | ystart = img->ysize - 1; | |
290 | ydir = -1; | |
291 | break; | |
292 | } | |
293 | ||
294 | /* | |
295 | * Allocate a scanline buffer... | |
296 | */ | |
297 | ||
298 | scanwidth = TIFFScanlineSize(tif); | |
299 | scanline = _TIFFmalloc(scanwidth); | |
300 | ||
301 | /* | |
302 | * Allocate input and output buffers... | |
303 | */ | |
304 | ||
305 | if (orientation < ORIENTATION_LEFTTOP) | |
306 | { | |
307 | if (samples > 1 || photometric == PHOTOMETRIC_PALETTE) | |
308 | pstep = xdir * 3; | |
309 | else | |
310 | pstep = xdir; | |
311 | ||
312 | in = malloc(img->xsize * 3 + 3); | |
313 | out = malloc(img->xsize * bpp); | |
314 | } | |
315 | else | |
316 | { | |
317 | if (samples > 1 || photometric == PHOTOMETRIC_PALETTE) | |
318 | pstep = ydir * 3; | |
319 | else | |
320 | pstep = ydir; | |
321 | ||
322 | in = malloc(img->ysize * 3 + 3); | |
323 | out = malloc(img->ysize * bpp); | |
324 | } | |
325 | ||
326 | /* | |
327 | * Read the image. This is greatly complicated by the fact that TIFF | |
328 | * supports literally hundreds of different colorspaces and orientations, | |
329 | * each which must be handled separately... | |
330 | */ | |
331 | ||
332 | fprintf(stderr, "DEBUG: photometric = %d\n", photometric); | |
333 | fprintf(stderr, "DEBUG: compression = %d\n", compression); | |
334 | ||
335 | switch (photometric) | |
336 | { | |
337 | case PHOTOMETRIC_MINISWHITE : | |
338 | case PHOTOMETRIC_MINISBLACK : | |
339 | if (photometric == PHOTOMETRIC_MINISWHITE) | |
340 | { | |
341 | zero = 255; | |
342 | one = 0; | |
343 | } | |
344 | else | |
345 | { | |
346 | zero = 0; | |
347 | one = 255; | |
348 | } | |
349 | ||
350 | if (orientation < ORIENTATION_LEFTTOP) | |
351 | { | |
352 | /* | |
353 | * Row major order... | |
354 | */ | |
355 | ||
356 | for (y = ystart, ycount = img->ysize, row = 0; | |
357 | ycount > 0; | |
358 | ycount --, y += ydir, row ++) | |
359 | { | |
360 | if (bits == 1) | |
361 | { | |
362 | TIFFReadScanline(tif, scanline, row, 0); | |
363 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 128; | |
364 | xcount > 0; | |
365 | xcount --, p += pstep) | |
366 | { | |
367 | if (*scanptr & bit) | |
368 | *p = one; | |
369 | else | |
370 | *p = zero; | |
371 | ||
372 | if (bit > 1) | |
373 | bit >>= 1; | |
374 | else | |
375 | { | |
376 | bit = 128; | |
377 | scanptr ++; | |
378 | } | |
379 | } | |
380 | } | |
381 | else if (bits == 2) | |
382 | { | |
383 | TIFFReadScanline(tif, scanline, row, 0); | |
384 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xc0; | |
385 | xcount > 0; | |
386 | xcount --, p += pstep) | |
387 | { | |
388 | pixel = *scanptr & bit; | |
389 | while (pixel > 3) | |
390 | pixel >>= 2; | |
391 | *p = (255 * pixel / 3) ^ zero; | |
392 | ||
393 | if (bit > 3) | |
394 | bit >>= 2; | |
395 | else | |
396 | { | |
397 | bit = 0xc0; | |
398 | scanptr ++; | |
399 | } | |
400 | } | |
401 | } | |
402 | else if (bits == 4) | |
403 | { | |
404 | TIFFReadScanline(tif, scanline, row, 0); | |
405 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart, bit = 0xf0; | |
406 | xcount > 0; | |
407 | xcount --, p += pstep) | |
408 | { | |
409 | if (bit == 0xf0) | |
410 | { | |
411 | *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero; | |
412 | bit = 0x0f; | |
413 | } | |
414 | else | |
415 | { | |
416 | *p = (255 * (*scanptr & 0x0f) / 15) ^ zero; | |
417 | bit = 0xf0; | |
418 | scanptr ++; | |
419 | } | |
420 | } | |
421 | } | |
422 | else if (xdir < 0 || zero || alpha) | |
423 | { | |
424 | TIFFReadScanline(tif, scanline, row, 0); | |
425 | ||
426 | if (alpha) | |
427 | { | |
428 | if (zero) | |
429 | { | |
430 | for (xcount = img->xsize, p = in + xstart, scanptr = scanline; | |
431 | xcount > 0; | |
432 | xcount --, p += pstep, scanptr += 2) | |
433 | *p = (scanptr[1] * (255 - scanptr[0]) + | |
434 | (255 - scanptr[1]) * 255) / 255; | |
435 | } | |
436 | else | |
437 | { | |
438 | for (xcount = img->xsize, p = in + xstart, scanptr = scanline; | |
439 | xcount > 0; | |
440 | xcount --, p += pstep, scanptr += 2) | |
441 | *p = (scanptr[1] * scanptr[0] + | |
442 | (255 - scanptr[1]) * 255) / 255; | |
443 | } | |
444 | } | |
445 | else | |
446 | { | |
447 | if (zero) | |
448 | { | |
449 | for (xcount = img->xsize, p = in + xstart, scanptr = scanline; | |
450 | xcount > 0; | |
451 | xcount --, p += pstep, scanptr ++) | |
452 | *p = 255 - *scanptr; | |
453 | } | |
454 | else | |
455 | { | |
456 | for (xcount = img->xsize, p = in + xstart, scanptr = scanline; | |
457 | xcount > 0; | |
458 | xcount --, p += pstep, scanptr ++) | |
459 | *p = *scanptr; | |
460 | } | |
461 | } | |
462 | } | |
463 | else | |
464 | TIFFReadScanline(tif, in, row, 0); | |
465 | ||
466 | if (img->colorspace == CUPS_IMAGE_WHITE) | |
467 | { | |
468 | if (lut) | |
469 | cupsImageLut(in, img->xsize, lut); | |
470 | ||
471 | _cupsImagePutRow(img, 0, y, img->xsize, in); | |
472 | } | |
473 | else | |
474 | { | |
475 | switch (img->colorspace) | |
476 | { | |
477 | default : | |
478 | break; | |
479 | ||
480 | case CUPS_IMAGE_RGB : | |
481 | cupsImageWhiteToRGB(in, out, img->xsize); | |
482 | break; | |
483 | case CUPS_IMAGE_BLACK : | |
484 | cupsImageWhiteToBlack(in, out, img->xsize); | |
485 | break; | |
486 | case CUPS_IMAGE_CMY : | |
487 | cupsImageWhiteToCMY(in, out, img->xsize); | |
488 | break; | |
489 | case CUPS_IMAGE_CMYK : | |
490 | cupsImageWhiteToCMYK(in, out, img->xsize); | |
491 | break; | |
492 | } | |
493 | ||
494 | if (lut) | |
495 | cupsImageLut(out, img->xsize * bpp, lut); | |
496 | ||
497 | _cupsImagePutRow(img, 0, y, img->xsize, out); | |
498 | } | |
499 | } | |
500 | } | |
501 | else | |
502 | { | |
503 | /* | |
504 | * Column major order... | |
505 | */ | |
506 | ||
507 | for (x = xstart, xcount = img->xsize, row = 0; | |
508 | xcount > 0; | |
509 | xcount --, x += xdir, row ++) | |
510 | { | |
511 | if (bits == 1) | |
512 | { | |
513 | TIFFReadScanline(tif, scanline, row, 0); | |
514 | for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 128; | |
515 | ycount > 0; | |
516 | ycount --, p += ydir) | |
517 | { | |
518 | if (*scanptr & bit) | |
519 | *p = one; | |
520 | else | |
521 | *p = zero; | |
522 | ||
523 | if (bit > 1) | |
524 | bit >>= 1; | |
525 | else | |
526 | { | |
527 | bit = 128; | |
528 | scanptr ++; | |
529 | } | |
530 | } | |
531 | } | |
532 | else if (bits == 2) | |
533 | { | |
534 | TIFFReadScanline(tif, scanline, row, 0); | |
535 | for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xc0; | |
536 | ycount > 0; | |
537 | ycount --, p += ydir) | |
538 | { | |
539 | pixel = *scanptr & 0xc0; | |
540 | while (pixel > 3) | |
541 | pixel >>= 2; | |
542 | ||
543 | *p = (255 * pixel / 3) ^ zero; | |
544 | ||
545 | if (bit > 3) | |
546 | bit >>= 2; | |
547 | else | |
548 | { | |
549 | bit = 0xc0; | |
550 | scanptr ++; | |
551 | } | |
552 | } | |
553 | } | |
554 | else if (bits == 4) | |
555 | { | |
556 | TIFFReadScanline(tif, scanline, row, 0); | |
557 | for (ycount = img->ysize, scanptr = scanline, p = in + ystart, bit = 0xf0; | |
558 | ycount > 0; | |
559 | ycount --, p += ydir) | |
560 | { | |
561 | if (bit == 0xf0) | |
562 | { | |
563 | *p = (255 * ((*scanptr & 0xf0) >> 4) / 15) ^ zero; | |
564 | bit = 0x0f; | |
565 | } | |
566 | else | |
567 | { | |
568 | *p = (255 * (*scanptr & 0x0f) / 15) ^ zero; | |
569 | bit = 0xf0; | |
570 | scanptr ++; | |
571 | } | |
572 | } | |
573 | } | |
574 | else if (ydir < 0 || zero || alpha) | |
575 | { | |
576 | TIFFReadScanline(tif, scanline, row, 0); | |
577 | ||
578 | if (alpha) | |
579 | { | |
580 | if (zero) | |
581 | { | |
582 | for (ycount = img->ysize, p = in + ystart, scanptr = scanline; | |
583 | ycount > 0; | |
584 | ycount --, p += ydir, scanptr += 2) | |
585 | *p = (scanptr[1] * (255 - scanptr[0]) + | |
586 | (255 - scanptr[1]) * 255) / 255; | |
587 | } | |
588 | else | |
589 | { | |
590 | for (ycount = img->ysize, p = in + ystart, scanptr = scanline; | |
591 | ycount > 0; | |
592 | ycount --, p += ydir, scanptr += 2) | |
593 | *p = (scanptr[1] * scanptr[0] + | |
594 | (255 - scanptr[1]) * 255) / 255; | |
595 | } | |
596 | } | |
597 | else | |
598 | { | |
599 | if (zero) | |
600 | { | |
601 | for (ycount = img->ysize, p = in + ystart, scanptr = scanline; | |
602 | ycount > 0; | |
603 | ycount --, p += ydir, scanptr ++) | |
604 | *p = 255 - *scanptr; | |
605 | } | |
606 | else | |
607 | { | |
608 | for (ycount = img->ysize, p = in + ystart, scanptr = scanline; | |
609 | ycount > 0; | |
610 | ycount --, p += ydir, scanptr ++) | |
611 | *p = *scanptr; | |
612 | } | |
613 | } | |
614 | } | |
615 | else | |
616 | TIFFReadScanline(tif, in, row, 0); | |
617 | ||
618 | if (img->colorspace == CUPS_IMAGE_WHITE) | |
619 | { | |
620 | if (lut) | |
621 | cupsImageLut(in, img->ysize, lut); | |
622 | ||
623 | _cupsImagePutCol(img, x, 0, img->ysize, in); | |
624 | } | |
625 | else | |
626 | { | |
627 | switch (img->colorspace) | |
628 | { | |
629 | default : | |
630 | break; | |
631 | ||
632 | case CUPS_IMAGE_RGB : | |
633 | cupsImageWhiteToRGB(in, out, img->ysize); | |
634 | break; | |
635 | case CUPS_IMAGE_BLACK : | |
636 | cupsImageWhiteToBlack(in, out, img->ysize); | |
637 | break; | |
638 | case CUPS_IMAGE_CMY : | |
639 | cupsImageWhiteToCMY(in, out, img->ysize); | |
640 | break; | |
641 | case CUPS_IMAGE_CMYK : | |
642 | cupsImageWhiteToCMYK(in, out, img->ysize); | |
643 | break; | |
644 | } | |
645 | ||
646 | if (lut) | |
647 | cupsImageLut(out, img->ysize * bpp, lut); | |
648 | ||
649 | _cupsImagePutCol(img, x, 0, img->ysize, out); | |
650 | } | |
651 | } | |
652 | } | |
653 | break; | |
654 | ||
655 | case PHOTOMETRIC_PALETTE : | |
656 | if (!TIFFGetField(tif, TIFFTAG_COLORMAP, &redcmap, &greencmap, &bluecmap)) | |
657 | { | |
c0e1af83 | 658 | fputs("DEBUG: No colormap tag in the file!\n", stderr); |
ef416fc2 | 659 | fclose(fp); |
660 | return (-1); | |
661 | } | |
662 | ||
663 | num_colors = 1 << bits; | |
664 | ||
665 | for (c = 0; c < num_colors; c ++) | |
666 | { | |
667 | redcmap[c] >>= 8; | |
668 | greencmap[c] >>= 8; | |
669 | bluecmap[c] >>= 8; | |
670 | } | |
671 | ||
672 | if (orientation < ORIENTATION_LEFTTOP) | |
673 | { | |
674 | /* | |
675 | * Row major order... | |
676 | */ | |
677 | ||
678 | for (y = ystart, ycount = img->ysize, row = 0; | |
679 | ycount > 0; | |
680 | ycount --, y += ydir, row ++) | |
681 | { | |
682 | if (bits == 1) | |
683 | { | |
684 | TIFFReadScanline(tif, scanline, row, 0); | |
685 | for (xcount = img->xsize, scanptr = scanline, | |
686 | p = in + xstart * 3, bit = 128; | |
687 | xcount > 0; | |
688 | xcount --, p += pstep) | |
689 | { | |
690 | if (*scanptr & bit) | |
691 | { | |
692 | p[0] = redcmap[1]; | |
693 | p[1] = greencmap[1]; | |
694 | p[2] = bluecmap[1]; | |
695 | } | |
696 | else | |
697 | { | |
698 | p[0] = redcmap[0]; | |
699 | p[1] = greencmap[0]; | |
700 | p[2] = bluecmap[0]; | |
701 | } | |
702 | ||
703 | if (bit > 1) | |
704 | bit >>= 1; | |
705 | else | |
706 | { | |
707 | bit = 128; | |
708 | scanptr ++; | |
709 | } | |
710 | } | |
711 | } | |
712 | else if (bits == 2) | |
713 | { | |
714 | TIFFReadScanline(tif, scanline, row, 0); | |
715 | for (xcount = img->xsize, scanptr = scanline, | |
716 | p = in + xstart * 3, bit = 0xc0; | |
717 | xcount > 0; | |
718 | xcount --, p += pstep) | |
719 | { | |
720 | pixel = *scanptr & bit; | |
721 | while (pixel > 3) | |
722 | pixel >>= 2; | |
723 | ||
724 | p[0] = redcmap[pixel]; | |
725 | p[1] = greencmap[pixel]; | |
726 | p[2] = bluecmap[pixel]; | |
727 | ||
728 | if (bit > 3) | |
729 | bit >>= 2; | |
730 | else | |
731 | { | |
732 | bit = 0xc0; | |
733 | scanptr ++; | |
734 | } | |
735 | } | |
736 | } | |
737 | else if (bits == 4) | |
738 | { | |
739 | TIFFReadScanline(tif, scanline, row, 0); | |
740 | for (xcount = img->xsize, scanptr = scanline, | |
741 | p = in + 3 * xstart, bit = 0xf0; | |
742 | xcount > 0; | |
743 | xcount --, p += pstep) | |
744 | { | |
745 | if (bit == 0xf0) | |
746 | { | |
747 | pixel = (*scanptr & 0xf0) >> 4; | |
748 | p[0] = redcmap[pixel]; | |
749 | p[1] = greencmap[pixel]; | |
750 | p[2] = bluecmap[pixel]; | |
751 | bit = 0x0f; | |
752 | } | |
753 | else | |
754 | { | |
755 | pixel = *scanptr++ & 0x0f; | |
756 | p[0] = redcmap[pixel]; | |
757 | p[1] = greencmap[pixel]; | |
758 | p[2] = bluecmap[pixel]; | |
759 | bit = 0xf0; | |
760 | } | |
761 | } | |
762 | } | |
763 | else | |
764 | { | |
765 | TIFFReadScanline(tif, scanline, row, 0); | |
766 | ||
767 | for (xcount = img->xsize, p = in + 3 * xstart, scanptr = scanline; | |
768 | xcount > 0; | |
769 | xcount --, p += pstep) | |
770 | { | |
771 | p[0] = redcmap[*scanptr]; | |
772 | p[1] = greencmap[*scanptr]; | |
773 | p[2] = bluecmap[*scanptr++]; | |
774 | } | |
775 | } | |
776 | ||
f301802f | 777 | switch (img->colorspace) |
ef416fc2 | 778 | { |
f301802f | 779 | default : |
780 | break; | |
781 | ||
782 | case CUPS_IMAGE_WHITE : | |
783 | cupsImageRGBToWhite(in, out, img->xsize); | |
784 | break; | |
785 | case CUPS_IMAGE_RGB : | |
786 | cupsImageRGBToRGB(in, out, img->xsize); | |
787 | break; | |
788 | case CUPS_IMAGE_BLACK : | |
789 | cupsImageRGBToBlack(in, out, img->xsize); | |
790 | break; | |
791 | case CUPS_IMAGE_CMY : | |
792 | cupsImageRGBToCMY(in, out, img->xsize); | |
793 | break; | |
794 | case CUPS_IMAGE_CMYK : | |
795 | cupsImageRGBToCMYK(in, out, img->xsize); | |
796 | break; | |
ef416fc2 | 797 | } |
ef416fc2 | 798 | |
f301802f | 799 | if (lut) |
800 | cupsImageLut(out, img->xsize * bpp, lut); | |
ef416fc2 | 801 | |
f301802f | 802 | _cupsImagePutRow(img, 0, y, img->xsize, out); |
ef416fc2 | 803 | } |
804 | } | |
805 | else | |
806 | { | |
807 | /* | |
808 | * Column major order... | |
809 | */ | |
810 | ||
811 | for (x = xstart, xcount = img->xsize, row = 0; | |
812 | xcount > 0; | |
813 | xcount --, x += xdir, row ++) | |
814 | { | |
815 | if (bits == 1) | |
816 | { | |
817 | TIFFReadScanline(tif, scanline, row, 0); | |
818 | for (ycount = img->ysize, scanptr = scanline, | |
819 | p = in + 3 * ystart, bit = 128; | |
820 | ycount > 0; | |
821 | ycount --, p += ydir) | |
822 | { | |
823 | if (*scanptr & bit) | |
824 | { | |
825 | p[0] = redcmap[1]; | |
826 | p[1] = greencmap[1]; | |
827 | p[2] = bluecmap[1]; | |
828 | } | |
829 | else | |
830 | { | |
831 | p[0] = redcmap[0]; | |
832 | p[1] = greencmap[0]; | |
833 | p[2] = bluecmap[0]; | |
834 | } | |
835 | ||
836 | if (bit > 1) | |
837 | bit >>= 1; | |
838 | else | |
839 | { | |
840 | bit = 128; | |
841 | scanptr ++; | |
842 | } | |
843 | } | |
844 | } | |
845 | else if (bits == 2) | |
846 | { | |
847 | TIFFReadScanline(tif, scanline, row, 0); | |
848 | for (ycount = img->ysize, scanptr = scanline, | |
849 | p = in + 3 * ystart, bit = 0xc0; | |
850 | ycount > 0; | |
851 | ycount --, p += ydir) | |
852 | { | |
853 | pixel = *scanptr & 0xc0; | |
854 | while (pixel > 3) | |
855 | pixel >>= 2; | |
856 | ||
857 | p[0] = redcmap[pixel]; | |
858 | p[1] = greencmap[pixel]; | |
859 | p[2] = bluecmap[pixel]; | |
860 | ||
861 | if (bit > 3) | |
862 | bit >>= 2; | |
863 | else | |
864 | { | |
865 | bit = 0xc0; | |
866 | scanptr ++; | |
867 | } | |
868 | } | |
869 | } | |
870 | else if (bits == 4) | |
871 | { | |
872 | TIFFReadScanline(tif, scanline, row, 0); | |
873 | for (ycount = img->ysize, scanptr = scanline, | |
874 | p = in + 3 * ystart, bit = 0xf0; | |
875 | ycount > 0; | |
876 | ycount --, p += ydir) | |
877 | { | |
878 | if (bit == 0xf0) | |
879 | { | |
880 | pixel = (*scanptr & 0xf0) >> 4; | |
881 | p[0] = redcmap[pixel]; | |
882 | p[1] = greencmap[pixel]; | |
883 | p[2] = bluecmap[pixel]; | |
884 | bit = 0x0f; | |
885 | } | |
886 | else | |
887 | { | |
888 | pixel = *scanptr++ & 0x0f; | |
889 | p[0] = redcmap[pixel]; | |
890 | p[1] = greencmap[pixel]; | |
891 | p[2] = bluecmap[pixel]; | |
892 | bit = 0xf0; | |
893 | } | |
894 | } | |
895 | } | |
896 | else | |
897 | { | |
898 | TIFFReadScanline(tif, scanline, row, 0); | |
899 | ||
900 | for (ycount = img->ysize, p = in + 3 * ystart, scanptr = scanline; | |
901 | ycount > 0; | |
902 | ycount --, p += ydir) | |
903 | { | |
904 | p[0] = redcmap[*scanptr]; | |
905 | p[1] = greencmap[*scanptr]; | |
906 | p[2] = bluecmap[*scanptr++]; | |
907 | } | |
908 | } | |
909 | ||
f301802f | 910 | switch (img->colorspace) |
ef416fc2 | 911 | { |
f301802f | 912 | default : |
913 | break; | |
914 | ||
915 | case CUPS_IMAGE_WHITE : | |
916 | cupsImageRGBToWhite(in, out, img->ysize); | |
917 | break; | |
918 | case CUPS_IMAGE_RGB : | |
919 | cupsImageRGBToRGB(in, out, img->ysize); | |
920 | break; | |
921 | case CUPS_IMAGE_BLACK : | |
922 | cupsImageRGBToBlack(in, out, img->ysize); | |
923 | break; | |
924 | case CUPS_IMAGE_CMY : | |
925 | cupsImageRGBToCMY(in, out, img->ysize); | |
926 | break; | |
927 | case CUPS_IMAGE_CMYK : | |
928 | cupsImageRGBToCMYK(in, out, img->ysize); | |
929 | break; | |
ef416fc2 | 930 | } |
ef416fc2 | 931 | |
f301802f | 932 | if (lut) |
933 | cupsImageLut(out, img->ysize * bpp, lut); | |
ef416fc2 | 934 | |
f301802f | 935 | _cupsImagePutCol(img, x, 0, img->ysize, out); |
936 | } | |
ef416fc2 | 937 | } |
938 | break; | |
939 | ||
940 | case PHOTOMETRIC_RGB : | |
941 | if (orientation < ORIENTATION_LEFTTOP) | |
942 | { | |
943 | /* | |
944 | * Row major order... | |
945 | */ | |
946 | ||
947 | for (y = ystart, ycount = img->ysize, row = 0; | |
948 | ycount > 0; | |
949 | ycount --, y += ydir, row ++) | |
950 | { | |
951 | if (bits == 1) | |
952 | { | |
953 | TIFFReadScanline(tif, scanline, row, 0); | |
954 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; | |
955 | xcount > 0; | |
956 | xcount --, p += pstep) | |
957 | { | |
958 | if (*scanptr & bit & 0x88) | |
959 | p[0] = 255; | |
960 | else | |
961 | p[0] = 0; | |
962 | ||
963 | if (*scanptr & bit & 0x44) | |
964 | p[1] = 255; | |
965 | else | |
966 | p[1] = 0; | |
967 | ||
968 | if (*scanptr & bit & 0x22) | |
969 | p[2] = 255; | |
970 | else | |
971 | p[2] = 0; | |
972 | ||
973 | if (bit == 0xf0) | |
974 | bit = 0x0f; | |
975 | else | |
976 | { | |
977 | bit = 0xf0; | |
978 | scanptr ++; | |
979 | } | |
980 | } | |
981 | } | |
982 | else if (bits == 2) | |
983 | { | |
984 | TIFFReadScanline(tif, scanline, row, 0); | |
985 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; | |
986 | xcount > 0; | |
987 | xcount --, p += pstep, scanptr ++) | |
988 | { | |
989 | pixel = *scanptr >> 2; | |
990 | p[0] = 255 * (pixel & 3) / 3; | |
991 | pixel >>= 2; | |
992 | p[1] = 255 * (pixel & 3) / 3; | |
993 | pixel >>= 2; | |
994 | p[2] = 255 * (pixel & 3) / 3; | |
995 | } | |
996 | } | |
997 | else if (bits == 4) | |
998 | { | |
999 | TIFFReadScanline(tif, scanline, row, 0); | |
1000 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; | |
1001 | xcount > 0; | |
1002 | xcount -= 2, p += 2 * pstep, scanptr += 3) | |
1003 | { | |
1004 | pixel = scanptr[0]; | |
1005 | p[1] = 255 * (pixel & 15) / 15; | |
1006 | pixel >>= 4; | |
1007 | p[0] = 255 * (pixel & 15) / 15; | |
1008 | pixel = scanptr[1]; | |
1009 | p[2] = 255 * ((pixel >> 4) & 15) / 15; | |
1010 | ||
1011 | if (xcount > 1) | |
1012 | { | |
1013 | p[pstep + 0] = 255 * (pixel & 15) / 15; | |
1014 | pixel = scanptr[2]; | |
1015 | p[pstep + 2] = 255 * (pixel & 15) / 15; | |
1016 | pixel >>= 4; | |
1017 | p[pstep + 1] = 255 * (pixel & 15) / 15; | |
1018 | } | |
1019 | } | |
1020 | } | |
1021 | else if (xdir < 0 || alpha) | |
1022 | { | |
1023 | TIFFReadScanline(tif, scanline, row, 0); | |
1024 | ||
1025 | if (alpha) | |
1026 | { | |
1027 | for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; | |
1028 | xcount > 0; | |
1029 | xcount --, p += pstep, scanptr += 4) | |
1030 | { | |
1031 | p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; | |
1032 | p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; | |
1033 | p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; | |
1034 | } | |
1035 | } | |
1036 | else | |
1037 | { | |
1038 | for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; | |
1039 | xcount > 0; | |
1040 | xcount --, p += pstep, scanptr += 3) | |
1041 | { | |
1042 | p[0] = scanptr[0]; | |
1043 | p[1] = scanptr[1]; | |
1044 | p[2] = scanptr[2]; | |
1045 | } | |
1046 | } | |
1047 | } | |
1048 | else | |
1049 | TIFFReadScanline(tif, in, row, 0); | |
1050 | ||
1051 | if ((saturation != 100 || hue != 0) && bpp > 1) | |
1052 | cupsImageRGBAdjust(in, img->xsize, saturation, hue); | |
1053 | ||
f301802f | 1054 | switch (img->colorspace) |
ef416fc2 | 1055 | { |
f301802f | 1056 | default : |
1057 | break; | |
1058 | ||
1059 | case CUPS_IMAGE_WHITE : | |
1060 | cupsImageRGBToWhite(in, out, img->xsize); | |
1061 | break; | |
1062 | case CUPS_IMAGE_RGB : | |
1063 | cupsImageRGBToRGB(in, out, img->xsize); | |
1064 | break; | |
1065 | case CUPS_IMAGE_BLACK : | |
1066 | cupsImageRGBToBlack(in, out, img->xsize); | |
1067 | break; | |
1068 | case CUPS_IMAGE_CMY : | |
1069 | cupsImageRGBToCMY(in, out, img->xsize); | |
1070 | break; | |
1071 | case CUPS_IMAGE_CMYK : | |
1072 | cupsImageRGBToCMYK(in, out, img->xsize); | |
1073 | break; | |
ef416fc2 | 1074 | } |
ef416fc2 | 1075 | |
f301802f | 1076 | if (lut) |
1077 | cupsImageLut(out, img->xsize * bpp, lut); | |
ef416fc2 | 1078 | |
f301802f | 1079 | _cupsImagePutRow(img, 0, y, img->xsize, out); |
ef416fc2 | 1080 | } |
1081 | } | |
1082 | else | |
1083 | { | |
1084 | /* | |
1085 | * Column major order... | |
1086 | */ | |
1087 | ||
1088 | for (x = xstart, xcount = img->xsize, row = 0; | |
1089 | xcount > 0; | |
1090 | xcount --, x += xdir, row ++) | |
1091 | { | |
1092 | if (bits == 1) | |
1093 | { | |
1094 | TIFFReadScanline(tif, scanline, row, 0); | |
1095 | for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3, bit = 0xf0; | |
1096 | ycount > 0; | |
1097 | ycount --, p += pstep) | |
1098 | { | |
1099 | if (*scanptr & bit & 0x88) | |
1100 | p[0] = 255; | |
1101 | else | |
1102 | p[0] = 0; | |
1103 | ||
1104 | if (*scanptr & bit & 0x44) | |
1105 | p[1] = 255; | |
1106 | else | |
1107 | p[1] = 0; | |
1108 | ||
1109 | if (*scanptr & bit & 0x22) | |
1110 | p[2] = 255; | |
1111 | else | |
1112 | p[2] = 0; | |
1113 | ||
1114 | if (bit == 0xf0) | |
1115 | bit = 0x0f; | |
1116 | else | |
1117 | { | |
1118 | bit = 0xf0; | |
1119 | scanptr ++; | |
1120 | } | |
1121 | } | |
1122 | } | |
1123 | else if (bits == 2) | |
1124 | { | |
1125 | TIFFReadScanline(tif, scanline, row, 0); | |
1126 | for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3; | |
1127 | ycount > 0; | |
1128 | ycount --, p += pstep, scanptr ++) | |
1129 | { | |
1130 | pixel = *scanptr >> 2; | |
1131 | p[0] = 255 * (pixel & 3) / 3; | |
1132 | pixel >>= 2; | |
1133 | p[1] = 255 * (pixel & 3) / 3; | |
1134 | pixel >>= 2; | |
1135 | p[2] = 255 * (pixel & 3) / 3; | |
1136 | } | |
1137 | } | |
1138 | else if (bits == 4) | |
1139 | { | |
1140 | TIFFReadScanline(tif, scanline, row, 0); | |
1141 | for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3; | |
1142 | ycount > 0; | |
1143 | ycount -= 2, p += 2 * pstep, scanptr += 3) | |
1144 | { | |
1145 | pixel = scanptr[0]; | |
1146 | p[1] = 255 * (pixel & 15) / 15; | |
1147 | pixel >>= 4; | |
1148 | p[0] = 255 * (pixel & 15) / 15; | |
1149 | pixel = scanptr[1]; | |
1150 | p[2] = 255 * ((pixel >> 4) & 15) / 15; | |
1151 | ||
1152 | if (ycount > 1) | |
1153 | { | |
1154 | p[pstep + 0] = 255 * (pixel & 15) / 15; | |
1155 | pixel = scanptr[2]; | |
1156 | p[pstep + 2] = 255 * (pixel & 15) / 15; | |
1157 | pixel >>= 4; | |
1158 | p[pstep + 1] = 255 * (pixel & 15) / 15; | |
1159 | } | |
1160 | } | |
1161 | } | |
1162 | else if (ydir < 0 || alpha) | |
1163 | { | |
1164 | TIFFReadScanline(tif, scanline, row, 0); | |
1165 | ||
1166 | if (alpha) | |
1167 | { | |
1168 | for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline; | |
1169 | ycount > 0; | |
1170 | ycount --, p += pstep, scanptr += 4) | |
1171 | { | |
1172 | p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; | |
1173 | p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; | |
1174 | p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255; | |
1175 | } | |
1176 | } | |
1177 | else | |
1178 | { | |
1179 | for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline; | |
1180 | ycount > 0; | |
1181 | ycount --, p += pstep, scanptr += 3) | |
1182 | { | |
1183 | p[0] = scanptr[0]; | |
1184 | p[1] = scanptr[1]; | |
1185 | p[2] = scanptr[2]; | |
1186 | } | |
1187 | } | |
1188 | } | |
1189 | else | |
1190 | TIFFReadScanline(tif, in, row, 0); | |
1191 | ||
1192 | if ((saturation != 100 || hue != 0) && bpp > 1) | |
1193 | cupsImageRGBAdjust(in, img->ysize, saturation, hue); | |
1194 | ||
f301802f | 1195 | switch (img->colorspace) |
ef416fc2 | 1196 | { |
f301802f | 1197 | default : |
1198 | break; | |
1199 | ||
1200 | case CUPS_IMAGE_WHITE : | |
1201 | cupsImageRGBToWhite(in, out, img->ysize); | |
1202 | break; | |
1203 | case CUPS_IMAGE_RGB : | |
1204 | cupsImageRGBToRGB(in, out, img->ysize); | |
1205 | break; | |
1206 | case CUPS_IMAGE_BLACK : | |
1207 | cupsImageRGBToBlack(in, out, img->ysize); | |
1208 | break; | |
1209 | case CUPS_IMAGE_CMY : | |
1210 | cupsImageRGBToCMY(in, out, img->ysize); | |
1211 | break; | |
1212 | case CUPS_IMAGE_CMYK : | |
1213 | cupsImageRGBToCMYK(in, out, img->ysize); | |
1214 | break; | |
1215 | } | |
ef416fc2 | 1216 | |
f301802f | 1217 | if (lut) |
1218 | cupsImageLut(out, img->ysize * bpp, lut); | |
ef416fc2 | 1219 | |
f301802f | 1220 | _cupsImagePutCol(img, x, 0, img->ysize, out); |
ef416fc2 | 1221 | } |
1222 | } | |
1223 | break; | |
1224 | ||
1225 | case PHOTOMETRIC_SEPARATED : | |
1226 | inkset = INKSET_CMYK; | |
1227 | numinks = 4; | |
1228 | ||
1229 | #ifdef TIFFTAG_NUMBEROFINKS | |
1230 | if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset) && | |
1231 | !TIFFGetField(tif, TIFFTAG_NUMBEROFINKS, &numinks)) | |
1232 | #else | |
1233 | if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset)) | |
1234 | #endif /* TIFFTAG_NUMBEROFINKS */ | |
1235 | { | |
1236 | fputs("WARNING: No inkset or number-of-inks tag in the file!\n", stderr); | |
1237 | } | |
1238 | ||
1239 | if (inkset == INKSET_CMYK || numinks == 4) | |
1240 | { | |
1241 | if (orientation < ORIENTATION_LEFTTOP) | |
1242 | { | |
1243 | /* | |
1244 | * Row major order... | |
1245 | */ | |
1246 | ||
1247 | for (y = ystart, ycount = img->ysize, row = 0; | |
1248 | ycount > 0; | |
1249 | ycount --, y += ydir, row ++) | |
1250 | { | |
1251 | if (bits == 1) | |
1252 | { | |
1253 | TIFFReadScanline(tif, scanline, row, 0); | |
1254 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; | |
1255 | xcount > 0; | |
1256 | xcount --, p += pstep) | |
1257 | { | |
1258 | if (*scanptr & bit & 0x11) | |
1259 | { | |
1260 | p[0] = 0; | |
1261 | p[1] = 0; | |
1262 | p[2] = 0; | |
1263 | } | |
1264 | else | |
1265 | { | |
1266 | if (*scanptr & bit & 0x88) | |
1267 | p[0] = 0; | |
1268 | else | |
1269 | p[0] = 255; | |
1270 | ||
1271 | if (*scanptr & bit & 0x44) | |
1272 | p[1] = 0; | |
1273 | else | |
1274 | p[1] = 255; | |
1275 | ||
1276 | if (*scanptr & bit & 0x22) | |
1277 | p[2] = 0; | |
1278 | else | |
1279 | p[2] = 255; | |
1280 | } | |
1281 | ||
1282 | if (bit == 0xf0) | |
1283 | bit = 0x0f; | |
1284 | else | |
1285 | { | |
1286 | bit = 0xf0; | |
1287 | scanptr ++; | |
1288 | } | |
1289 | } | |
1290 | } | |
1291 | else if (bits == 2) | |
1292 | { | |
1293 | TIFFReadScanline(tif, scanline, row, 0); | |
1294 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; | |
1295 | xcount > 0; | |
1296 | xcount --, p += pstep, scanptr ++) | |
1297 | { | |
1298 | pixel = *scanptr; | |
1299 | k = 255 * (pixel & 3) / 3; | |
1300 | if (k == 255) | |
1301 | { | |
1302 | p[0] = 0; | |
1303 | p[1] = 0; | |
1304 | p[2] = 0; | |
1305 | } | |
1306 | else | |
1307 | { | |
1308 | pixel >>= 2; | |
1309 | b = 255 - 255 * (pixel & 3) / 3 - k; | |
1310 | if (b < 0) | |
1311 | p[2] = 0; | |
1312 | else if (b < 256) | |
1313 | p[2] = b; | |
1314 | else | |
1315 | p[2] = 255; | |
1316 | ||
1317 | pixel >>= 2; | |
1318 | g = 255 - 255 * (pixel & 3) / 3 - k; | |
1319 | if (g < 0) | |
1320 | p[1] = 0; | |
1321 | else if (g < 256) | |
1322 | p[1] = g; | |
1323 | else | |
1324 | p[1] = 255; | |
1325 | ||
1326 | pixel >>= 2; | |
1327 | r = 255 - 255 * (pixel & 3) / 3 - k; | |
1328 | if (r < 0) | |
1329 | p[0] = 0; | |
1330 | else if (r < 256) | |
1331 | p[0] = r; | |
1332 | else | |
1333 | p[0] = 255; | |
1334 | } | |
1335 | } | |
1336 | } | |
1337 | else if (bits == 4) | |
1338 | { | |
1339 | TIFFReadScanline(tif, scanline, row, 0); | |
1340 | for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3; | |
1341 | xcount > 0; | |
1342 | xcount --, p += pstep, scanptr += 2) | |
1343 | { | |
1344 | pixel = scanptr[1]; | |
1345 | k = 255 * (pixel & 15) / 15; | |
1346 | if (k == 255) | |
1347 | { | |
1348 | p[0] = 0; | |
1349 | p[1] = 0; | |
1350 | p[2] = 0; | |
1351 | } | |
1352 | else | |
1353 | { | |
1354 | pixel >>= 4; | |
1355 | b = 255 - 255 * (pixel & 15) / 15 - k; | |
1356 | if (b < 0) | |
1357 | p[2] = 0; | |
1358 | else if (b < 256) | |
1359 | p[2] = b; | |
1360 | else | |
1361 | p[2] = 255; | |
1362 | ||
1363 | pixel = scanptr[0]; | |
1364 | g = 255 - 255 * (pixel & 15) / 15 - k; | |
1365 | if (g < 0) | |
1366 | p[1] = 0; | |
1367 | else if (g < 256) | |
1368 | p[1] = g; | |
1369 | else | |
1370 | p[1] = 255; | |
1371 | ||
1372 | pixel >>= 4; | |
1373 | r = 255 - 255 * (pixel & 15) / 15 - k; | |
1374 | if (r < 0) | |
1375 | p[0] = 0; | |
1376 | else if (r < 256) | |
1377 | p[0] = r; | |
1378 | else | |
1379 | p[0] = 255; | |
1380 | } | |
1381 | } | |
1382 | } | |
1383 | else if (img->colorspace == CUPS_IMAGE_CMYK) | |
1384 | { | |
1385 | TIFFReadScanline(tif, scanline, row, 0); | |
1386 | _cupsImagePutRow(img, 0, y, img->xsize, scanline); | |
1387 | } | |
1388 | else | |
1389 | { | |
1390 | TIFFReadScanline(tif, scanline, row, 0); | |
1391 | ||
1392 | for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline; | |
1393 | xcount > 0; | |
1394 | xcount --, p += pstep, scanptr += 4) | |
1395 | { | |
1396 | k = scanptr[3]; | |
1397 | if (k == 255) | |
1398 | { | |
1399 | p[0] = 0; | |
1400 | p[1] = 0; | |
1401 | p[2] = 0; | |
1402 | } | |
1403 | else | |
1404 | { | |
1405 | r = 255 - scanptr[0] - k; | |
1406 | if (r < 0) | |
1407 | p[0] = 0; | |
1408 | else if (r < 256) | |
1409 | p[0] = r; | |
1410 | else | |
1411 | p[0] = 255; | |
1412 | ||
1413 | g = 255 - scanptr[1] - k; | |
1414 | if (g < 0) | |
1415 | p[1] = 0; | |
1416 | else if (g < 256) | |
1417 | p[1] = g; | |
1418 | else | |
1419 | p[1] = 255; | |
1420 | ||
1421 | b = 255 - scanptr[2] - k; | |
1422 | if (b < 0) | |
1423 | p[2] = 0; | |
1424 | else if (b < 256) | |
1425 | p[2] = b; | |
1426 | else | |
1427 | p[2] = 255; | |
1428 | } | |
1429 | } | |
1430 | } | |
1431 | ||
1432 | if ((saturation != 100 || hue != 0) && bpp > 1) | |
1433 | cupsImageRGBAdjust(in, img->xsize, saturation, hue); | |
1434 | ||
f301802f | 1435 | switch (img->colorspace) |
ef416fc2 | 1436 | { |
f301802f | 1437 | default : |
1438 | break; | |
ef416fc2 | 1439 | |
f301802f | 1440 | case CUPS_IMAGE_WHITE : |
1441 | cupsImageRGBToWhite(in, out, img->xsize); | |
1442 | break; | |
1443 | case CUPS_IMAGE_RGB : | |
1444 | cupsImageRGBToRGB(in, out, img->xsize); | |
1445 | break; | |
1446 | case CUPS_IMAGE_BLACK : | |
1447 | cupsImageRGBToBlack(in, out, img->xsize); | |
1448 | break; | |
1449 | case CUPS_IMAGE_CMY : | |
1450 | cupsImageRGBToCMY(in, out, img->xsize); | |
1451 | break; | |
1452 | case CUPS_IMAGE_CMYK : | |
1453 | cupsImageRGBToCMYK(in, out, img->xsize); | |
1454 | break; | |
ef416fc2 | 1455 | } |
ef416fc2 | 1456 | |
f301802f | 1457 | if (lut) |
1458 | cupsImageLut(out, img->xsize * 3, lut); | |
ef416fc2 | 1459 | |
f301802f | 1460 | _cupsImagePutRow(img, 0, y, img->xsize, out); |
ef416fc2 | 1461 | } |
1462 | } | |
1463 | else | |
1464 | { | |
1465 | /* | |
1466 | * Column major order... | |
1467 | */ | |
1468 | ||
1469 | for (x = xstart, xcount = img->xsize, row = 0; | |
1470 | xcount > 0; | |
1471 | xcount --, x += xdir, row ++) | |
1472 | { | |
1473 | if (bits == 1) | |
1474 | { | |
1475 | TIFFReadScanline(tif, scanline, row, 0); | |
1476 | for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0; | |
1477 | ycount > 0; | |
1478 | ycount --, p += pstep) | |
1479 | { | |
1480 | if (*scanptr & bit & 0x11) | |
1481 | { | |
1482 | p[0] = 0; | |
1483 | p[1] = 0; | |
1484 | p[2] = 0; | |
1485 | } | |
1486 | else | |
1487 | { | |
1488 | if (*scanptr & bit & 0x88) | |
1489 | p[0] = 0; | |
1490 | else | |
1491 | p[0] = 255; | |
1492 | ||
1493 | if (*scanptr & bit & 0x44) | |
1494 | p[1] = 0; | |
1495 | else | |
1496 | p[1] = 255; | |
1497 | ||
1498 | if (*scanptr & bit & 0x22) | |
1499 | p[2] = 0; | |
1500 | else | |
1501 | p[2] = 255; | |
1502 | } | |
1503 | ||
1504 | if (bit == 0xf0) | |
1505 | bit = 0x0f; | |
1506 | else | |
1507 | { | |
1508 | bit = 0xf0; | |
1509 | scanptr ++; | |
1510 | } | |
1511 | } | |
1512 | } | |
1513 | else if (bits == 2) | |
1514 | { | |
1515 | TIFFReadScanline(tif, scanline, row, 0); | |
1516 | for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3; | |
1517 | ycount > 0; | |
1518 | ycount --, p += pstep, scanptr ++) | |
1519 | { | |
1520 | pixel = *scanptr; | |
1521 | k = 255 * (pixel & 3) / 3; | |
1522 | if (k == 255) | |
1523 | { | |
1524 | p[0] = 0; | |
1525 | p[1] = 0; | |
1526 | p[2] = 0; | |
1527 | } | |
1528 | else | |
1529 | { | |
1530 | pixel >>= 2; | |
1531 | b = 255 - 255 * (pixel & 3) / 3 - k; | |
1532 | if (b < 0) | |
1533 | p[2] = 0; | |
1534 | else if (b < 256) | |
1535 | p[2] = b; | |
1536 | else | |
1537 | p[2] = 255; | |
1538 | ||
1539 | pixel >>= 2; | |
1540 | g = 255 - 255 * (pixel & 3) / 3 - k; | |
1541 | if (g < 0) | |
1542 | p[1] = 0; | |
1543 | else if (g < 256) | |
1544 | p[1] = g; | |
1545 | else | |
1546 | p[1] = 255; | |
1547 | ||
1548 | pixel >>= 2; | |
1549 | r = 255 - 255 * (pixel & 3) / 3 - k; | |
1550 | if (r < 0) | |
1551 | p[0] = 0; | |
1552 | else if (r < 256) | |
1553 | p[0] = r; | |
1554 | else | |
1555 | p[0] = 255; | |
1556 | } | |
1557 | } | |
1558 | } | |
1559 | else if (bits == 4) | |
1560 | { | |
1561 | TIFFReadScanline(tif, scanline, row, 0); | |
1562 | for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3; | |
1563 | ycount > 0; | |
1564 | ycount --, p += pstep, scanptr += 2) | |
1565 | { | |
1566 | pixel = scanptr[1]; | |
1567 | k = 255 * (pixel & 15) / 15; | |
1568 | if (k == 255) | |
1569 | { | |
1570 | p[0] = 0; | |
1571 | p[1] = 0; | |
1572 | p[2] = 0; | |
1573 | } | |
1574 | else | |
1575 | { | |
1576 | pixel >>= 4; | |
1577 | b = 255 - 255 * (pixel & 15) / 15 - k; | |
1578 | if (b < 0) | |
1579 | p[2] = 0; | |
1580 | else if (b < 256) | |
1581 | p[2] = b; | |
1582 | else | |
1583 | p[2] = 255; | |
1584 | ||
1585 | pixel = scanptr[0]; | |
1586 | g = 255 - 255 * (pixel & 15) / 15 - k; | |
1587 | if (g < 0) | |
1588 | p[1] = 0; | |
1589 | else if (g < 256) | |
1590 | p[1] = g; | |
1591 | else | |
1592 | p[1] = 255; | |
1593 | ||
1594 | pixel >>= 4; | |
1595 | r = 255 - 255 * (pixel & 15) / 15 - k; | |
1596 | if (r < 0) | |
1597 | p[0] = 0; | |
1598 | else if (r < 256) | |
1599 | p[0] = r; | |
1600 | else | |
1601 | p[0] = 255; | |
1602 | } | |
1603 | } | |
1604 | } | |
1605 | else if (img->colorspace == CUPS_IMAGE_CMYK) | |
1606 | { | |
1607 | TIFFReadScanline(tif, scanline, row, 0); | |
1608 | _cupsImagePutCol(img, x, 0, img->ysize, scanline); | |
1609 | } | |
1610 | else | |
1611 | { | |
1612 | TIFFReadScanline(tif, scanline, row, 0); | |
1613 | ||
1614 | for (ycount = img->ysize, p = in + xstart * 3, scanptr = scanline; | |
1615 | ycount > 0; | |
1616 | ycount --, p += pstep, scanptr += 4) | |
1617 | { | |
1618 | k = scanptr[3]; | |
1619 | if (k == 255) | |
1620 | { | |
1621 | p[0] = 0; | |
1622 | p[1] = 0; | |
1623 | p[2] = 0; | |
1624 | } | |
1625 | else | |
1626 | { | |
1627 | r = 255 - scanptr[0] - k; | |
1628 | if (r < 0) | |
1629 | p[0] = 0; | |
1630 | else if (r < 256) | |
1631 | p[0] = r; | |
1632 | else | |
1633 | p[0] = 255; | |
1634 | ||
1635 | g = 255 - scanptr[1] - k; | |
1636 | if (g < 0) | |
1637 | p[1] = 0; | |
1638 | else if (g < 256) | |
1639 | p[1] = g; | |
1640 | else | |
1641 | p[1] = 255; | |
1642 | ||
1643 | b = 255 - scanptr[2] - k; | |
1644 | if (b < 0) | |
1645 | p[2] = 0; | |
1646 | else if (b < 256) | |
1647 | p[2] = b; | |
1648 | else | |
1649 | p[2] = 255; | |
1650 | } | |
1651 | } | |
1652 | } | |
1653 | ||
1654 | if ((saturation != 100 || hue != 0) && bpp > 1) | |
1655 | cupsImageRGBAdjust(in, img->ysize, saturation, hue); | |
1656 | ||
f301802f | 1657 | switch (img->colorspace) |
ef416fc2 | 1658 | { |
f301802f | 1659 | default : |
1660 | break; | |
ef416fc2 | 1661 | |
f301802f | 1662 | case CUPS_IMAGE_WHITE : |
1663 | cupsImageRGBToWhite(in, out, img->ysize); | |
1664 | break; | |
1665 | case CUPS_IMAGE_RGB : | |
1666 | cupsImageRGBToRGB(in, out, img->ysize); | |
1667 | break; | |
1668 | case CUPS_IMAGE_BLACK : | |
1669 | cupsImageRGBToBlack(in, out, img->ysize); | |
1670 | break; | |
1671 | case CUPS_IMAGE_CMY : | |
1672 | cupsImageRGBToCMY(in, out, img->ysize); | |
1673 | break; | |
1674 | case CUPS_IMAGE_CMYK : | |
1675 | cupsImageRGBToCMYK(in, out, img->ysize); | |
1676 | break; | |
1677 | } | |
ef416fc2 | 1678 | |
f301802f | 1679 | if (lut) |
1680 | cupsImageLut(out, img->ysize * bpp, lut); | |
ef416fc2 | 1681 | |
f301802f | 1682 | _cupsImagePutCol(img, x, 0, img->ysize, out); |
ef416fc2 | 1683 | } |
1684 | } | |
1685 | ||
1686 | break; | |
1687 | } | |
1688 | ||
1689 | default : | |
1690 | _TIFFfree(scanline); | |
1691 | free(in); | |
1692 | free(out); | |
1693 | ||
1694 | TIFFClose(tif); | |
c0e1af83 | 1695 | fputs("DEBUG: Unknown TIFF photometric value!\n", stderr); |
ef416fc2 | 1696 | return (-1); |
1697 | } | |
1698 | ||
1699 | /* | |
1700 | * Free temporary buffers, close the TIFF file, and return. | |
1701 | */ | |
1702 | ||
1703 | _TIFFfree(scanline); | |
1704 | free(in); | |
1705 | free(out); | |
1706 | ||
1707 | TIFFClose(tif); | |
1708 | return (0); | |
1709 | } | |
1710 | #endif /* HAVE_LIBTIFF */ | |
1711 | ||
1712 | ||
1713 | /* | |
bc44d920 | 1714 | * End of "$Id: image-tiff.c 6649 2007-07-11 21:46:42Z mike $". |
ef416fc2 | 1715 | */ |