]> 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/*
2 * "$Id: image-tiff.c 4741 2005-10-02 04:25:52Z mike $"
3 *
4 * TIFF file routines for the Common UNIX Printing System (CUPS).
5 *
6 * Copyright 1993-2005 by Easy Software Products.
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
786 if (img->colorspace == CUPS_IMAGE_RGB)
787 {
788 if (lut)
789 cupsImageLut(in, img->xsize * 3, lut);
790
791 _cupsImagePutRow(img, 0, y, img->xsize, in);
792 }
793 else
794 {
795 switch (img->colorspace)
796 {
797 default :
798 break;
799
800 case CUPS_IMAGE_WHITE :
801 cupsImageRGBToWhite(in, out, img->xsize);
802 break;
803 case CUPS_IMAGE_BLACK :
804 cupsImageRGBToBlack(in, out, img->xsize);
805 break;
806 case CUPS_IMAGE_CMY :
807 cupsImageRGBToCMY(in, out, img->xsize);
808 break;
809 case CUPS_IMAGE_CMYK :
810 cupsImageRGBToCMYK(in, out, img->xsize);
811 break;
812 }
813
814 if (lut)
815 cupsImageLut(out, img->xsize * bpp, lut);
816
817 _cupsImagePutRow(img, 0, y, img->xsize, out);
818 }
819 }
820 }
821 else
822 {
823 /*
824 * Column major order...
825 */
826
827 for (x = xstart, xcount = img->xsize, row = 0;
828 xcount > 0;
829 xcount --, x += xdir, row ++)
830 {
831 if (bits == 1)
832 {
833 TIFFReadScanline(tif, scanline, row, 0);
834 for (ycount = img->ysize, scanptr = scanline,
835 p = in + 3 * ystart, bit = 128;
836 ycount > 0;
837 ycount --, p += ydir)
838 {
839 if (*scanptr & bit)
840 {
841 p[0] = redcmap[1];
842 p[1] = greencmap[1];
843 p[2] = bluecmap[1];
844 }
845 else
846 {
847 p[0] = redcmap[0];
848 p[1] = greencmap[0];
849 p[2] = bluecmap[0];
850 }
851
852 if (bit > 1)
853 bit >>= 1;
854 else
855 {
856 bit = 128;
857 scanptr ++;
858 }
859 }
860 }
861 else if (bits == 2)
862 {
863 TIFFReadScanline(tif, scanline, row, 0);
864 for (ycount = img->ysize, scanptr = scanline,
865 p = in + 3 * ystart, bit = 0xc0;
866 ycount > 0;
867 ycount --, p += ydir)
868 {
869 pixel = *scanptr & 0xc0;
870 while (pixel > 3)
871 pixel >>= 2;
872
873 p[0] = redcmap[pixel];
874 p[1] = greencmap[pixel];
875 p[2] = bluecmap[pixel];
876
877 if (bit > 3)
878 bit >>= 2;
879 else
880 {
881 bit = 0xc0;
882 scanptr ++;
883 }
884 }
885 }
886 else if (bits == 4)
887 {
888 TIFFReadScanline(tif, scanline, row, 0);
889 for (ycount = img->ysize, scanptr = scanline,
890 p = in + 3 * ystart, bit = 0xf0;
891 ycount > 0;
892 ycount --, p += ydir)
893 {
894 if (bit == 0xf0)
895 {
896 pixel = (*scanptr & 0xf0) >> 4;
897 p[0] = redcmap[pixel];
898 p[1] = greencmap[pixel];
899 p[2] = bluecmap[pixel];
900 bit = 0x0f;
901 }
902 else
903 {
904 pixel = *scanptr++ & 0x0f;
905 p[0] = redcmap[pixel];
906 p[1] = greencmap[pixel];
907 p[2] = bluecmap[pixel];
908 bit = 0xf0;
909 }
910 }
911 }
912 else
913 {
914 TIFFReadScanline(tif, scanline, row, 0);
915
916 for (ycount = img->ysize, p = in + 3 * ystart, scanptr = scanline;
917 ycount > 0;
918 ycount --, p += ydir)
919 {
920 p[0] = redcmap[*scanptr];
921 p[1] = greencmap[*scanptr];
922 p[2] = bluecmap[*scanptr++];
923 }
924 }
925
926 if (img->colorspace == CUPS_IMAGE_RGB)
927 {
928 if (lut)
929 cupsImageLut(in, img->ysize * 3, lut);
930
931 _cupsImagePutCol(img, x, 0, img->ysize, in);
932 }
933 else
934 {
935 switch (img->colorspace)
936 {
937 default :
938 break;
939
940 case CUPS_IMAGE_WHITE :
941 cupsImageRGBToWhite(in, out, img->ysize);
942 break;
943 case CUPS_IMAGE_BLACK :
944 cupsImageRGBToBlack(in, out, img->ysize);
945 break;
946 case CUPS_IMAGE_CMY :
947 cupsImageRGBToCMY(in, out, img->ysize);
948 break;
949 case CUPS_IMAGE_CMYK :
950 cupsImageRGBToCMYK(in, out, img->ysize);
951 break;
952 }
953
954 if (lut)
955 cupsImageLut(out, img->ysize * bpp, lut);
956
957 _cupsImagePutCol(img, x, 0, img->ysize, out);
958 }
959 }
960 }
961 break;
962
963 case PHOTOMETRIC_RGB :
964 if (orientation < ORIENTATION_LEFTTOP)
965 {
966 /*
967 * Row major order...
968 */
969
970 for (y = ystart, ycount = img->ysize, row = 0;
971 ycount > 0;
972 ycount --, y += ydir, row ++)
973 {
974 if (bits == 1)
975 {
976 TIFFReadScanline(tif, scanline, row, 0);
977 for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
978 xcount > 0;
979 xcount --, p += pstep)
980 {
981 if (*scanptr & bit & 0x88)
982 p[0] = 255;
983 else
984 p[0] = 0;
985
986 if (*scanptr & bit & 0x44)
987 p[1] = 255;
988 else
989 p[1] = 0;
990
991 if (*scanptr & bit & 0x22)
992 p[2] = 255;
993 else
994 p[2] = 0;
995
996 if (bit == 0xf0)
997 bit = 0x0f;
998 else
999 {
1000 bit = 0xf0;
1001 scanptr ++;
1002 }
1003 }
1004 }
1005 else if (bits == 2)
1006 {
1007 TIFFReadScanline(tif, scanline, row, 0);
1008 for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
1009 xcount > 0;
1010 xcount --, p += pstep, scanptr ++)
1011 {
1012 pixel = *scanptr >> 2;
1013 p[0] = 255 * (pixel & 3) / 3;
1014 pixel >>= 2;
1015 p[1] = 255 * (pixel & 3) / 3;
1016 pixel >>= 2;
1017 p[2] = 255 * (pixel & 3) / 3;
1018 }
1019 }
1020 else if (bits == 4)
1021 {
1022 TIFFReadScanline(tif, scanline, row, 0);
1023 for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
1024 xcount > 0;
1025 xcount -= 2, p += 2 * pstep, scanptr += 3)
1026 {
1027 pixel = scanptr[0];
1028 p[1] = 255 * (pixel & 15) / 15;
1029 pixel >>= 4;
1030 p[0] = 255 * (pixel & 15) / 15;
1031 pixel = scanptr[1];
1032 p[2] = 255 * ((pixel >> 4) & 15) / 15;
1033
1034 if (xcount > 1)
1035 {
1036 p[pstep + 0] = 255 * (pixel & 15) / 15;
1037 pixel = scanptr[2];
1038 p[pstep + 2] = 255 * (pixel & 15) / 15;
1039 pixel >>= 4;
1040 p[pstep + 1] = 255 * (pixel & 15) / 15;
1041 }
1042 }
1043 }
1044 else if (xdir < 0 || alpha)
1045 {
1046 TIFFReadScanline(tif, scanline, row, 0);
1047
1048 if (alpha)
1049 {
1050 for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
1051 xcount > 0;
1052 xcount --, p += pstep, scanptr += 4)
1053 {
1054 p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
1055 p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
1056 p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
1057 }
1058 }
1059 else
1060 {
1061 for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
1062 xcount > 0;
1063 xcount --, p += pstep, scanptr += 3)
1064 {
1065 p[0] = scanptr[0];
1066 p[1] = scanptr[1];
1067 p[2] = scanptr[2];
1068 }
1069 }
1070 }
1071 else
1072 TIFFReadScanline(tif, in, row, 0);
1073
1074 if ((saturation != 100 || hue != 0) && bpp > 1)
1075 cupsImageRGBAdjust(in, img->xsize, saturation, hue);
1076
1077 if (img->colorspace == CUPS_IMAGE_RGB)
1078 {
1079 if (lut)
1080 cupsImageLut(in, img->xsize * 3, lut);
1081
1082 _cupsImagePutRow(img, 0, y, img->xsize, in);
1083 }
1084 else
1085 {
1086 switch (img->colorspace)
1087 {
1088 default :
1089 break;
1090
1091 case CUPS_IMAGE_WHITE :
1092 cupsImageRGBToWhite(in, out, img->xsize);
1093 break;
1094 case CUPS_IMAGE_BLACK :
1095 cupsImageRGBToBlack(in, out, img->xsize);
1096 break;
1097 case CUPS_IMAGE_CMY :
1098 cupsImageRGBToCMY(in, out, img->xsize);
1099 break;
1100 case CUPS_IMAGE_CMYK :
1101 cupsImageRGBToCMYK(in, out, img->xsize);
1102 break;
1103 }
1104
1105 if (lut)
1106 cupsImageLut(out, img->xsize * bpp, lut);
1107
1108 _cupsImagePutRow(img, 0, y, img->xsize, out);
1109 }
1110 }
1111 }
1112 else
1113 {
1114 /*
1115 * Column major order...
1116 */
1117
1118 for (x = xstart, xcount = img->xsize, row = 0;
1119 xcount > 0;
1120 xcount --, x += xdir, row ++)
1121 {
1122 if (bits == 1)
1123 {
1124 TIFFReadScanline(tif, scanline, row, 0);
1125 for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3, bit = 0xf0;
1126 ycount > 0;
1127 ycount --, p += pstep)
1128 {
1129 if (*scanptr & bit & 0x88)
1130 p[0] = 255;
1131 else
1132 p[0] = 0;
1133
1134 if (*scanptr & bit & 0x44)
1135 p[1] = 255;
1136 else
1137 p[1] = 0;
1138
1139 if (*scanptr & bit & 0x22)
1140 p[2] = 255;
1141 else
1142 p[2] = 0;
1143
1144 if (bit == 0xf0)
1145 bit = 0x0f;
1146 else
1147 {
1148 bit = 0xf0;
1149 scanptr ++;
1150 }
1151 }
1152 }
1153 else if (bits == 2)
1154 {
1155 TIFFReadScanline(tif, scanline, row, 0);
1156 for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3;
1157 ycount > 0;
1158 ycount --, p += pstep, scanptr ++)
1159 {
1160 pixel = *scanptr >> 2;
1161 p[0] = 255 * (pixel & 3) / 3;
1162 pixel >>= 2;
1163 p[1] = 255 * (pixel & 3) / 3;
1164 pixel >>= 2;
1165 p[2] = 255 * (pixel & 3) / 3;
1166 }
1167 }
1168 else if (bits == 4)
1169 {
1170 TIFFReadScanline(tif, scanline, row, 0);
1171 for (ycount = img->ysize, scanptr = scanline, p = in + ystart * 3;
1172 ycount > 0;
1173 ycount -= 2, p += 2 * pstep, scanptr += 3)
1174 {
1175 pixel = scanptr[0];
1176 p[1] = 255 * (pixel & 15) / 15;
1177 pixel >>= 4;
1178 p[0] = 255 * (pixel & 15) / 15;
1179 pixel = scanptr[1];
1180 p[2] = 255 * ((pixel >> 4) & 15) / 15;
1181
1182 if (ycount > 1)
1183 {
1184 p[pstep + 0] = 255 * (pixel & 15) / 15;
1185 pixel = scanptr[2];
1186 p[pstep + 2] = 255 * (pixel & 15) / 15;
1187 pixel >>= 4;
1188 p[pstep + 1] = 255 * (pixel & 15) / 15;
1189 }
1190 }
1191 }
1192 else if (ydir < 0 || alpha)
1193 {
1194 TIFFReadScanline(tif, scanline, row, 0);
1195
1196 if (alpha)
1197 {
1198 for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline;
1199 ycount > 0;
1200 ycount --, p += pstep, scanptr += 4)
1201 {
1202 p[0] = (scanptr[0] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
1203 p[1] = (scanptr[1] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
1204 p[2] = (scanptr[2] * scanptr[3] + 255 * (255 - scanptr[3])) / 255;
1205 }
1206 }
1207 else
1208 {
1209 for (ycount = img->ysize, p = in + ystart * 3, scanptr = scanline;
1210 ycount > 0;
1211 ycount --, p += pstep, scanptr += 3)
1212 {
1213 p[0] = scanptr[0];
1214 p[1] = scanptr[1];
1215 p[2] = scanptr[2];
1216 }
1217 }
1218 }
1219 else
1220 TIFFReadScanline(tif, in, row, 0);
1221
1222 if ((saturation != 100 || hue != 0) && bpp > 1)
1223 cupsImageRGBAdjust(in, img->ysize, saturation, hue);
1224
1225 if (img->colorspace == CUPS_IMAGE_RGB)
1226 {
1227 if (lut)
1228 cupsImageLut(in, img->ysize * 3, lut);
1229
1230 _cupsImagePutCol(img, x, 0, img->ysize, in);
1231 }
1232 else
1233 {
1234 switch (img->colorspace)
1235 {
1236 default :
1237 break;
1238
1239 case CUPS_IMAGE_WHITE :
1240 cupsImageRGBToWhite(in, out, img->ysize);
1241 break;
1242 case CUPS_IMAGE_BLACK :
1243 cupsImageRGBToBlack(in, out, img->ysize);
1244 break;
1245 case CUPS_IMAGE_CMY :
1246 cupsImageRGBToCMY(in, out, img->ysize);
1247 break;
1248 case CUPS_IMAGE_CMYK :
1249 cupsImageRGBToCMYK(in, out, img->ysize);
1250 break;
1251 }
1252
1253 if (lut)
1254 cupsImageLut(out, img->ysize * bpp, lut);
1255
1256 _cupsImagePutCol(img, x, 0, img->ysize, out);
1257 }
1258 }
1259 }
1260 break;
1261
1262 case PHOTOMETRIC_SEPARATED :
1263 inkset = INKSET_CMYK;
1264 numinks = 4;
1265
1266#ifdef TIFFTAG_NUMBEROFINKS
1267 if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset) &&
1268 !TIFFGetField(tif, TIFFTAG_NUMBEROFINKS, &numinks))
1269#else
1270 if (!TIFFGetField(tif, TIFFTAG_INKSET, &inkset))
1271#endif /* TIFFTAG_NUMBEROFINKS */
1272 {
1273 fputs("WARNING: No inkset or number-of-inks tag in the file!\n", stderr);
1274 }
1275
1276 if (inkset == INKSET_CMYK || numinks == 4)
1277 {
1278 if (orientation < ORIENTATION_LEFTTOP)
1279 {
1280 /*
1281 * Row major order...
1282 */
1283
1284 for (y = ystart, ycount = img->ysize, row = 0;
1285 ycount > 0;
1286 ycount --, y += ydir, row ++)
1287 {
1288 if (bits == 1)
1289 {
1290 TIFFReadScanline(tif, scanline, row, 0);
1291 for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
1292 xcount > 0;
1293 xcount --, p += pstep)
1294 {
1295 if (*scanptr & bit & 0x11)
1296 {
1297 p[0] = 0;
1298 p[1] = 0;
1299 p[2] = 0;
1300 }
1301 else
1302 {
1303 if (*scanptr & bit & 0x88)
1304 p[0] = 0;
1305 else
1306 p[0] = 255;
1307
1308 if (*scanptr & bit & 0x44)
1309 p[1] = 0;
1310 else
1311 p[1] = 255;
1312
1313 if (*scanptr & bit & 0x22)
1314 p[2] = 0;
1315 else
1316 p[2] = 255;
1317 }
1318
1319 if (bit == 0xf0)
1320 bit = 0x0f;
1321 else
1322 {
1323 bit = 0xf0;
1324 scanptr ++;
1325 }
1326 }
1327 }
1328 else if (bits == 2)
1329 {
1330 TIFFReadScanline(tif, scanline, row, 0);
1331 for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
1332 xcount > 0;
1333 xcount --, p += pstep, scanptr ++)
1334 {
1335 pixel = *scanptr;
1336 k = 255 * (pixel & 3) / 3;
1337 if (k == 255)
1338 {
1339 p[0] = 0;
1340 p[1] = 0;
1341 p[2] = 0;
1342 }
1343 else
1344 {
1345 pixel >>= 2;
1346 b = 255 - 255 * (pixel & 3) / 3 - k;
1347 if (b < 0)
1348 p[2] = 0;
1349 else if (b < 256)
1350 p[2] = b;
1351 else
1352 p[2] = 255;
1353
1354 pixel >>= 2;
1355 g = 255 - 255 * (pixel & 3) / 3 - k;
1356 if (g < 0)
1357 p[1] = 0;
1358 else if (g < 256)
1359 p[1] = g;
1360 else
1361 p[1] = 255;
1362
1363 pixel >>= 2;
1364 r = 255 - 255 * (pixel & 3) / 3 - k;
1365 if (r < 0)
1366 p[0] = 0;
1367 else if (r < 256)
1368 p[0] = r;
1369 else
1370 p[0] = 255;
1371 }
1372 }
1373 }
1374 else if (bits == 4)
1375 {
1376 TIFFReadScanline(tif, scanline, row, 0);
1377 for (xcount = img->xsize, scanptr = scanline, p = in + xstart * 3;
1378 xcount > 0;
1379 xcount --, p += pstep, scanptr += 2)
1380 {
1381 pixel = scanptr[1];
1382 k = 255 * (pixel & 15) / 15;
1383 if (k == 255)
1384 {
1385 p[0] = 0;
1386 p[1] = 0;
1387 p[2] = 0;
1388 }
1389 else
1390 {
1391 pixel >>= 4;
1392 b = 255 - 255 * (pixel & 15) / 15 - k;
1393 if (b < 0)
1394 p[2] = 0;
1395 else if (b < 256)
1396 p[2] = b;
1397 else
1398 p[2] = 255;
1399
1400 pixel = scanptr[0];
1401 g = 255 - 255 * (pixel & 15) / 15 - k;
1402 if (g < 0)
1403 p[1] = 0;
1404 else if (g < 256)
1405 p[1] = g;
1406 else
1407 p[1] = 255;
1408
1409 pixel >>= 4;
1410 r = 255 - 255 * (pixel & 15) / 15 - k;
1411 if (r < 0)
1412 p[0] = 0;
1413 else if (r < 256)
1414 p[0] = r;
1415 else
1416 p[0] = 255;
1417 }
1418 }
1419 }
1420 else if (img->colorspace == CUPS_IMAGE_CMYK)
1421 {
1422 TIFFReadScanline(tif, scanline, row, 0);
1423 _cupsImagePutRow(img, 0, y, img->xsize, scanline);
1424 }
1425 else
1426 {
1427 TIFFReadScanline(tif, scanline, row, 0);
1428
1429 for (xcount = img->xsize, p = in + xstart * 3, scanptr = scanline;
1430 xcount > 0;
1431 xcount --, p += pstep, scanptr += 4)
1432 {
1433 k = scanptr[3];
1434 if (k == 255)
1435 {
1436 p[0] = 0;
1437 p[1] = 0;
1438 p[2] = 0;
1439 }
1440 else
1441 {
1442 r = 255 - scanptr[0] - k;
1443 if (r < 0)
1444 p[0] = 0;
1445 else if (r < 256)
1446 p[0] = r;
1447 else
1448 p[0] = 255;
1449
1450 g = 255 - scanptr[1] - k;
1451 if (g < 0)
1452 p[1] = 0;
1453 else if (g < 256)
1454 p[1] = g;
1455 else
1456 p[1] = 255;
1457
1458 b = 255 - scanptr[2] - k;
1459 if (b < 0)
1460 p[2] = 0;
1461 else if (b < 256)
1462 p[2] = b;
1463 else
1464 p[2] = 255;
1465 }
1466 }
1467 }
1468
1469 if ((saturation != 100 || hue != 0) && bpp > 1)
1470 cupsImageRGBAdjust(in, img->xsize, saturation, hue);
1471
1472 if (img->colorspace == CUPS_IMAGE_RGB)
1473 {
1474 if (lut)
1475 cupsImageLut(in, img->xsize * 3, lut);
1476
1477 _cupsImagePutRow(img, 0, y, img->xsize, in);
1478 }
1479 else if (img->colorspace == CUPS_IMAGE_WHITE)
1480 {
1481 switch (img->colorspace)
1482 {
1483 default :
1484 break;
1485
1486 case CUPS_IMAGE_WHITE :
1487 cupsImageRGBToWhite(in, out, img->xsize);
1488 break;
1489 case CUPS_IMAGE_BLACK :
1490 cupsImageRGBToBlack(in, out, img->xsize);
1491 break;
1492 case CUPS_IMAGE_CMY :
1493 cupsImageRGBToCMY(in, out, img->xsize);
1494 break;
1495 case CUPS_IMAGE_CMYK :
1496 cupsImageRGBToCMYK(in, out, img->xsize);
1497 break;
1498 }
1499
1500 if (lut)
1501 cupsImageLut(out, img->xsize * 3, lut);
1502
1503 _cupsImagePutRow(img, 0, y, img->xsize, out);
1504 }
1505 }
1506 }
1507 else
1508 {
1509 /*
1510 * Column major order...
1511 */
1512
1513 for (x = xstart, xcount = img->xsize, row = 0;
1514 xcount > 0;
1515 xcount --, x += xdir, row ++)
1516 {
1517 if (bits == 1)
1518 {
1519 TIFFReadScanline(tif, scanline, row, 0);
1520 for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3, bit = 0xf0;
1521 ycount > 0;
1522 ycount --, p += pstep)
1523 {
1524 if (*scanptr & bit & 0x11)
1525 {
1526 p[0] = 0;
1527 p[1] = 0;
1528 p[2] = 0;
1529 }
1530 else
1531 {
1532 if (*scanptr & bit & 0x88)
1533 p[0] = 0;
1534 else
1535 p[0] = 255;
1536
1537 if (*scanptr & bit & 0x44)
1538 p[1] = 0;
1539 else
1540 p[1] = 255;
1541
1542 if (*scanptr & bit & 0x22)
1543 p[2] = 0;
1544 else
1545 p[2] = 255;
1546 }
1547
1548 if (bit == 0xf0)
1549 bit = 0x0f;
1550 else
1551 {
1552 bit = 0xf0;
1553 scanptr ++;
1554 }
1555 }
1556 }
1557 else if (bits == 2)
1558 {
1559 TIFFReadScanline(tif, scanline, row, 0);
1560 for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3;
1561 ycount > 0;
1562 ycount --, p += pstep, scanptr ++)
1563 {
1564 pixel = *scanptr;
1565 k = 255 * (pixel & 3) / 3;
1566 if (k == 255)
1567 {
1568 p[0] = 0;
1569 p[1] = 0;
1570 p[2] = 0;
1571 }
1572 else
1573 {
1574 pixel >>= 2;
1575 b = 255 - 255 * (pixel & 3) / 3 - k;
1576 if (b < 0)
1577 p[2] = 0;
1578 else if (b < 256)
1579 p[2] = b;
1580 else
1581 p[2] = 255;
1582
1583 pixel >>= 2;
1584 g = 255 - 255 * (pixel & 3) / 3 - k;
1585 if (g < 0)
1586 p[1] = 0;
1587 else if (g < 256)
1588 p[1] = g;
1589 else
1590 p[1] = 255;
1591
1592 pixel >>= 2;
1593 r = 255 - 255 * (pixel & 3) / 3 - k;
1594 if (r < 0)
1595 p[0] = 0;
1596 else if (r < 256)
1597 p[0] = r;
1598 else
1599 p[0] = 255;
1600 }
1601 }
1602 }
1603 else if (bits == 4)
1604 {
1605 TIFFReadScanline(tif, scanline, row, 0);
1606 for (ycount = img->ysize, scanptr = scanline, p = in + xstart * 3;
1607 ycount > 0;
1608 ycount --, p += pstep, scanptr += 2)
1609 {
1610 pixel = scanptr[1];
1611 k = 255 * (pixel & 15) / 15;
1612 if (k == 255)
1613 {
1614 p[0] = 0;
1615 p[1] = 0;
1616 p[2] = 0;
1617 }
1618 else
1619 {
1620 pixel >>= 4;
1621 b = 255 - 255 * (pixel & 15) / 15 - k;
1622 if (b < 0)
1623 p[2] = 0;
1624 else if (b < 256)
1625 p[2] = b;
1626 else
1627 p[2] = 255;
1628
1629 pixel = scanptr[0];
1630 g = 255 - 255 * (pixel & 15) / 15 - k;
1631 if (g < 0)
1632 p[1] = 0;
1633 else if (g < 256)
1634 p[1] = g;
1635 else
1636 p[1] = 255;
1637
1638 pixel >>= 4;
1639 r = 255 - 255 * (pixel & 15) / 15 - k;
1640 if (r < 0)
1641 p[0] = 0;
1642 else if (r < 256)
1643 p[0] = r;
1644 else
1645 p[0] = 255;
1646 }
1647 }
1648 }
1649 else if (img->colorspace == CUPS_IMAGE_CMYK)
1650 {
1651 TIFFReadScanline(tif, scanline, row, 0);
1652 _cupsImagePutCol(img, x, 0, img->ysize, scanline);
1653 }
1654 else
1655 {
1656 TIFFReadScanline(tif, scanline, row, 0);
1657
1658 for (ycount = img->ysize, p = in + xstart * 3, scanptr = scanline;
1659 ycount > 0;
1660 ycount --, p += pstep, scanptr += 4)
1661 {
1662 k = scanptr[3];
1663 if (k == 255)
1664 {
1665 p[0] = 0;
1666 p[1] = 0;
1667 p[2] = 0;
1668 }
1669 else
1670 {
1671 r = 255 - scanptr[0] - k;
1672 if (r < 0)
1673 p[0] = 0;
1674 else if (r < 256)
1675 p[0] = r;
1676 else
1677 p[0] = 255;
1678
1679 g = 255 - scanptr[1] - k;
1680 if (g < 0)
1681 p[1] = 0;
1682 else if (g < 256)
1683 p[1] = g;
1684 else
1685 p[1] = 255;
1686
1687 b = 255 - scanptr[2] - k;
1688 if (b < 0)
1689 p[2] = 0;
1690 else if (b < 256)
1691 p[2] = b;
1692 else
1693 p[2] = 255;
1694 }
1695 }
1696 }
1697
1698 if ((saturation != 100 || hue != 0) && bpp > 1)
1699 cupsImageRGBAdjust(in, img->ysize, saturation, hue);
1700
1701 if (img->colorspace == CUPS_IMAGE_RGB)
1702 {
1703 if (lut)
1704 cupsImageLut(in, img->ysize * 3, lut);
1705
1706 _cupsImagePutCol(img, x, 0, img->ysize, in);
1707 }
1708 else if (img->colorspace == CUPS_IMAGE_WHITE)
1709 {
1710 switch (img->colorspace)
1711 {
1712 default :
1713 break;
1714
1715 case CUPS_IMAGE_WHITE :
1716 cupsImageRGBToWhite(in, out, img->ysize);
1717 break;
1718 case CUPS_IMAGE_BLACK :
1719 cupsImageRGBToBlack(in, out, img->ysize);
1720 break;
1721 case CUPS_IMAGE_CMY :
1722 cupsImageRGBToCMY(in, out, img->ysize);
1723 break;
1724 case CUPS_IMAGE_CMYK :
1725 cupsImageRGBToCMYK(in, out, img->ysize);
1726 break;
1727 }
1728
1729 if (lut)
1730 cupsImageLut(out, img->ysize * bpp, lut);
1731
1732 _cupsImagePutCol(img, x, 0, img->ysize, out);
1733 }
1734 }
1735 }
1736
1737 break;
1738 }
1739
1740 default :
1741 _TIFFfree(scanline);
1742 free(in);
1743 free(out);
1744
1745 TIFFClose(tif);
1746 fputs("ERROR: Unknown TIFF photometric value!\n", stderr);
1747 return (-1);
1748 }
1749
1750 /*
1751 * Free temporary buffers, close the TIFF file, and return.
1752 */
1753
1754 _TIFFfree(scanline);
1755 free(in);
1756 free(out);
1757
1758 TIFFClose(tif);
1759 return (0);
1760}
1761#endif /* HAVE_LIBTIFF */
1762
1763
1764/*
1765 * End of "$Id: image-tiff.c 4741 2005-10-02 04:25:52Z mike $".
1766 */