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