ReactOS 0.4.16-dev-197-g92996da
tif_getimage.c
Go to the documentation of this file.
1/*
2 * Copyright (c) 1991-1997 Sam Leffler
3 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
4 *
5 * Permission to use, copy, modify, distribute, and sell this software and
6 * its documentation for any purpose is hereby granted without fee, provided
7 * that (i) the above copyright notices and this permission notice appear in
8 * all copies of the software and related documentation, and (ii) the names of
9 * Sam Leffler and Silicon Graphics may not be used in any advertising or
10 * publicity relating to the software without the specific, prior written
11 * permission of Sam Leffler and Silicon Graphics.
12 *
13 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
14 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
15 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
16 *
17 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
18 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
19 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
20 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
21 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
22 * OF THIS SOFTWARE.
23 */
24
25/*
26 * TIFF Library
27 *
28 * Read and return a packed RGBA image.
29 */
30#include <precomp.h>
31//#include <stdio.h>
32
37static int PickContigCase(TIFFRGBAImage*);
39
42
43static const char photoTag[] = "PhotometricInterpretation";
44
45/*
46 * Helper constants used in Orientation tag handling
47 */
48#define FLIP_VERTICALLY 0x01
49#define FLIP_HORIZONTALLY 0x02
50
51/*
52 * Color conversion constants. We will define display types here.
53 */
54
55static const TIFFDisplay display_sRGB = {
56 { /* XYZ -> luminance matrix */
57 { 3.2410F, -1.5374F, -0.4986F },
58 { -0.9692F, 1.8760F, 0.0416F },
59 { 0.0556F, -0.2040F, 1.0570F }
60 },
61 100.0F, 100.0F, 100.0F, /* Light o/p for reference white */
62 255, 255, 255, /* Pixel values for ref. white */
63 1.0F, 1.0F, 1.0F, /* Residual light o/p for black pixel */
64 2.4F, 2.4F, 2.4F, /* Gamma values for the three guns */
65};
66
67/*
68 * Check the image to see if TIFFReadRGBAImage can deal with it.
69 * 1/0 is returned according to whether or not the image can
70 * be handled. If 0 is returned, emsg contains the reason
71 * why it is being rejected.
72 */
73int
74TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
75{
76 TIFFDirectory* td = &tif->tif_dir;
77 uint16 photometric;
78 int colorchannels;
79
80 if (!tif->tif_decodestatus) {
81 sprintf(emsg, "Sorry, requested compression method is not configured");
82 return (0);
83 }
84 switch (td->td_bitspersample) {
85 case 1:
86 case 2:
87 case 4:
88 case 8:
89 case 16:
90 break;
91 default:
92 sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
94 return (0);
95 }
97 sprintf(emsg, "Sorry, can not handle images with IEEE floating-point samples");
98 return (0);
99 }
100 colorchannels = td->td_samplesperpixel - td->td_extrasamples;
101 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
102 switch (colorchannels) {
103 case 1:
104 photometric = PHOTOMETRIC_MINISBLACK;
105 break;
106 case 3:
107 photometric = PHOTOMETRIC_RGB;
108 break;
109 default:
110 sprintf(emsg, "Missing needed %s tag", photoTag);
111 return (0);
112 }
113 }
114 switch (photometric) {
119 && td->td_samplesperpixel != 1
120 && td->td_bitspersample < 8 ) {
121 sprintf(emsg,
122 "Sorry, can not handle contiguous data with %s=%d, "
123 "and %s=%d and Bits/Sample=%d",
124 photoTag, photometric,
125 "Samples/pixel", td->td_samplesperpixel,
126 td->td_bitspersample);
127 return (0);
128 }
129 /*
130 * We should likely validate that any extra samples are either
131 * to be ignored, or are alpha, and if alpha we should try to use
132 * them. But for now we won't bother with this.
133 */
134 break;
136 /*
137 * TODO: if at all meaningful and useful, make more complete
138 * support check here, or better still, refactor to let supporting
139 * code decide whether there is support and what meaningful
140 * error to return
141 */
142 break;
143 case PHOTOMETRIC_RGB:
144 if (colorchannels < 3) {
145 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
146 "Color channels", colorchannels);
147 return (0);
148 }
149 break;
151 {
152 uint16 inkset;
154 if (inkset != INKSET_CMYK) {
155 sprintf(emsg,
156 "Sorry, can not handle separated image with %s=%d",
157 "InkSet", inkset);
158 return 0;
159 }
160 if (td->td_samplesperpixel < 4) {
161 sprintf(emsg,
162 "Sorry, can not handle separated image with %s=%d",
163 "Samples/pixel", td->td_samplesperpixel);
164 return 0;
165 }
166 break;
167 }
168 case PHOTOMETRIC_LOGL:
170 sprintf(emsg, "Sorry, LogL data must have %s=%d",
171 "Compression", COMPRESSION_SGILOG);
172 return (0);
173 }
174 break;
178 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
180 return (0);
181 }
183 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
184 "Planarconfiguration", td->td_planarconfig);
185 return (0);
186 }
187 if ( td->td_samplesperpixel != 3 || colorchannels != 3 ) {
188 sprintf(emsg,
189 "Sorry, can not handle image with %s=%d, %s=%d",
190 "Samples/pixel", td->td_samplesperpixel,
191 "colorchannels", colorchannels);
192 return 0;
193 }
194 break;
196 if ( td->td_samplesperpixel != 3 || colorchannels != 3 || td->td_bitspersample != 8 ) {
197 sprintf(emsg,
198 "Sorry, can not handle image with %s=%d, %s=%d and %s=%d",
199 "Samples/pixel", td->td_samplesperpixel,
200 "colorchannels", colorchannels,
201 "Bits/sample", td->td_bitspersample);
202 return 0;
203 }
204 break;
205 default:
206 sprintf(emsg, "Sorry, can not handle image with %s=%d",
207 photoTag, photometric);
208 return (0);
209 }
210 return (1);
211}
212
213void
215{
216 if (img->Map) {
217 _TIFFfree(img->Map);
218 img->Map = NULL;
219 }
220 if (img->BWmap) {
221 _TIFFfree(img->BWmap);
222 img->BWmap = NULL;
223 }
224 if (img->PALmap) {
225 _TIFFfree(img->PALmap);
226 img->PALmap = NULL;
227 }
228 if (img->ycbcr) {
229 _TIFFfree(img->ycbcr);
230 img->ycbcr = NULL;
231 }
232 if (img->cielab) {
233 _TIFFfree(img->cielab);
234 img->cielab = NULL;
235 }
236 if (img->UaToAa) {
237 _TIFFfree(img->UaToAa);
238 img->UaToAa = NULL;
239 }
240 if (img->Bitdepth16To8) {
241 _TIFFfree(img->Bitdepth16To8);
242 img->Bitdepth16To8 = NULL;
243 }
244
245 if( img->redcmap ) {
246 _TIFFfree( img->redcmap );
247 _TIFFfree( img->greencmap );
248 _TIFFfree( img->bluecmap );
249 img->redcmap = img->greencmap = img->bluecmap = NULL;
250 }
251}
252
253static int
255{
258 return (compress == COMPRESSION_CCITTFAX3 ||
262}
263
264int
265TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
266{
267 uint16* sampleinfo;
268 uint16 extrasamples;
269 uint16 planarconfig;
271 int colorchannels;
272 uint16 *red_orig, *green_orig, *blue_orig;
273 int n_color;
274
275 if( !TIFFRGBAImageOK(tif, emsg) )
276 return 0;
277
278 /* Initialize to normal values */
279 img->row_offset = 0;
280 img->col_offset = 0;
281 img->redcmap = NULL;
282 img->greencmap = NULL;
283 img->bluecmap = NULL;
284 img->Map = NULL;
285 img->BWmap = NULL;
286 img->PALmap = NULL;
287 img->ycbcr = NULL;
288 img->cielab = NULL;
289 img->UaToAa = NULL;
290 img->Bitdepth16To8 = NULL;
291 img->req_orientation = ORIENTATION_BOTLEFT; /* It is the default */
292
293 img->tif = tif;
294 img->stoponerr = stop;
295 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
296 switch (img->bitspersample) {
297 case 1:
298 case 2:
299 case 4:
300 case 8:
301 case 16:
302 break;
303 default:
304 sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
305 img->bitspersample);
306 goto fail_return;
307 }
308 img->alpha = 0;
309 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
311 &extrasamples, &sampleinfo);
312 if (extrasamples >= 1)
313 {
314 switch (sampleinfo[0]) {
315 case EXTRASAMPLE_UNSPECIFIED: /* Workaround for some images without */
316 if (img->samplesperpixel > 3) /* correct info about alpha channel */
318 break;
319 case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
320 case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
321 img->alpha = sampleinfo[0];
322 break;
323 }
324 }
325
326#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
327 if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
328 img->photometric = PHOTOMETRIC_MINISWHITE;
329
330 if( extrasamples == 0
331 && img->samplesperpixel == 4
332 && img->photometric == PHOTOMETRIC_RGB )
333 {
335 extrasamples = 1;
336 }
337#endif
338
339 colorchannels = img->samplesperpixel - extrasamples;
341 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
342 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
343 switch (colorchannels) {
344 case 1:
345 if (isCCITTCompression(tif))
346 img->photometric = PHOTOMETRIC_MINISWHITE;
347 else
348 img->photometric = PHOTOMETRIC_MINISBLACK;
349 break;
350 case 3:
351 img->photometric = PHOTOMETRIC_RGB;
352 break;
353 default:
354 sprintf(emsg, "Missing needed %s tag", photoTag);
355 goto fail_return;
356 }
357 }
358 switch (img->photometric) {
361 &red_orig, &green_orig, &blue_orig)) {
362 sprintf(emsg, "Missing required \"Colormap\" tag");
363 goto fail_return;
364 }
365
366 /* copy the colormaps so we can modify them */
367 n_color = (1U << img->bitspersample);
368 img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
369 img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
370 img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
371 if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
372 sprintf(emsg, "Out of memory for colormap copy");
373 goto fail_return;
374 }
375
376 _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
377 _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
378 _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
379
380 /* fall through... */
383 if (planarconfig == PLANARCONFIG_CONTIG
384 && img->samplesperpixel != 1
385 && img->bitspersample < 8 ) {
386 sprintf(emsg,
387 "Sorry, can not handle contiguous data with %s=%d, "
388 "and %s=%d and Bits/Sample=%d",
389 photoTag, img->photometric,
390 "Samples/pixel", img->samplesperpixel,
391 img->bitspersample);
392 goto fail_return;
393 }
394 break;
396 /* It would probably be nice to have a reality check here. */
397 if (planarconfig == PLANARCONFIG_CONTIG)
398 /* can rely on libjpeg to convert to RGB */
399 /* XXX should restore current state on exit */
400 switch (compress) {
401 case COMPRESSION_JPEG:
402 /*
403 * TODO: when complete tests verify complete desubsampling
404 * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
405 * favor of tif_getimage.c native handling
406 */
408 img->photometric = PHOTOMETRIC_RGB;
409 break;
410 default:
411 /* do nothing */;
412 break;
413 }
414 /*
415 * TODO: if at all meaningful and useful, make more complete
416 * support check here, or better still, refactor to let supporting
417 * code decide whether there is support and what meaningful
418 * error to return
419 */
420 break;
421 case PHOTOMETRIC_RGB:
422 if (colorchannels < 3) {
423 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
424 "Color channels", colorchannels);
425 goto fail_return;
426 }
427 break;
429 {
430 uint16 inkset;
432 if (inkset != INKSET_CMYK) {
433 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
434 "InkSet", inkset);
435 goto fail_return;
436 }
437 if (img->samplesperpixel < 4) {
438 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
439 "Samples/pixel", img->samplesperpixel);
440 goto fail_return;
441 }
442 }
443 break;
444 case PHOTOMETRIC_LOGL:
446 sprintf(emsg, "Sorry, LogL data must have %s=%d",
447 "Compression", COMPRESSION_SGILOG);
448 goto fail_return;
449 }
451 img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
452 img->bitspersample = 8;
453 break;
456 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
458 goto fail_return;
459 }
460 if (planarconfig != PLANARCONFIG_CONTIG) {
461 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
462 "Planarconfiguration", planarconfig);
463 return (0);
464 }
466 img->photometric = PHOTOMETRIC_RGB; /* little white lie */
467 img->bitspersample = 8;
468 break;
470 break;
471 default:
472 sprintf(emsg, "Sorry, can not handle image with %s=%d",
473 photoTag, img->photometric);
474 goto fail_return;
475 }
476 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
477 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
478 TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
479 img->isContig =
480 !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
481 if (img->isContig) {
482 if (!PickContigCase(img)) {
483 sprintf(emsg, "Sorry, can not handle image");
484 goto fail_return;
485 }
486 } else {
487 if (!PickSeparateCase(img)) {
488 sprintf(emsg, "Sorry, can not handle image");
489 goto fail_return;
490 }
491 }
492 return 1;
493
494 fail_return:
496 return 0;
497}
498
499int
501{
502 if (img->get == NULL) {
503 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
504 return (0);
505 }
506 if (img->put.any == NULL) {
507 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
508 "No \"put\" routine setupl; probably can not handle image format");
509 return (0);
510 }
511 return (*img->get)(img, raster, w, h);
512}
513
514/*
515 * Read the specified image into an ABGR-format rastertaking in account
516 * specified orientation.
517 */
518int
520 uint32 rwidth, uint32 rheight, uint32* raster,
521 int orientation, int stop)
522{
523 char emsg[1024] = "";
525 int ok;
526
527 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
528 img.req_orientation = (uint16)orientation;
529 /* XXX verify rwidth and rheight against width and height */
530 ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
531 rwidth, img.height);
533 } else {
534 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
535 ok = 0;
536 }
537 return (ok);
538}
539
540/*
541 * Read the specified image into an ABGR-format raster. Use bottom left
542 * origin for raster by default.
543 */
544int
546 uint32 rwidth, uint32 rheight, uint32* raster, int stop)
547{
548 return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
549 ORIENTATION_BOTLEFT, stop);
550}
551
552static int
554{
555 switch (img->orientation) {
558 if (img->req_orientation == ORIENTATION_TOPRIGHT ||
559 img->req_orientation == ORIENTATION_RIGHTTOP)
560 return FLIP_HORIZONTALLY;
561 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
562 img->req_orientation == ORIENTATION_RIGHTBOT)
564 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
565 img->req_orientation == ORIENTATION_LEFTBOT)
566 return FLIP_VERTICALLY;
567 else
568 return 0;
571 if (img->req_orientation == ORIENTATION_TOPLEFT ||
572 img->req_orientation == ORIENTATION_LEFTTOP)
573 return FLIP_HORIZONTALLY;
574 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
575 img->req_orientation == ORIENTATION_RIGHTBOT)
576 return FLIP_VERTICALLY;
577 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
578 img->req_orientation == ORIENTATION_LEFTBOT)
580 else
581 return 0;
584 if (img->req_orientation == ORIENTATION_TOPLEFT ||
585 img->req_orientation == ORIENTATION_LEFTTOP)
587 else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
588 img->req_orientation == ORIENTATION_RIGHTTOP)
589 return FLIP_VERTICALLY;
590 else if (img->req_orientation == ORIENTATION_BOTLEFT ||
591 img->req_orientation == ORIENTATION_LEFTBOT)
592 return FLIP_HORIZONTALLY;
593 else
594 return 0;
597 if (img->req_orientation == ORIENTATION_TOPLEFT ||
598 img->req_orientation == ORIENTATION_LEFTTOP)
599 return FLIP_VERTICALLY;
600 else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
601 img->req_orientation == ORIENTATION_RIGHTTOP)
603 else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
604 img->req_orientation == ORIENTATION_RIGHTBOT)
605 return FLIP_HORIZONTALLY;
606 else
607 return 0;
608 default: /* NOTREACHED */
609 return 0;
610 }
611}
612
613/*
614 * Get an tile-organized image that has
615 * PlanarConfiguration contiguous if SamplesPerPixel > 1
616 * or
617 * SamplesPerPixel == 1
618 */
619static int
621{
622 TIFF* tif = img->tif;
623 tileContigRoutine put = img->put.contig;
624 uint32 col, row, y, rowstoread;
626 uint32 tw, th;
627 unsigned char* buf = NULL;
628 int32 fromskew, toskew;
629 uint32 nrow;
630 int ret = 1, flip;
631 uint32 this_tw, tocol;
632 int32 this_toskew, leftmost_toskew;
633 int32 leftmost_fromskew;
634 uint32 leftmost_tw;
636
637 bufsize = TIFFTileSize(tif);
638 if (bufsize == 0) {
639 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
640 return (0);
641 }
642
645
646 flip = setorientation(img);
647 if (flip & FLIP_VERTICALLY) {
648 y = h - 1;
649 toskew = -(int32)(tw + w);
650 }
651 else {
652 y = 0;
653 toskew = -(int32)(tw - w);
654 }
655
656 /*
657 * Leftmost tile is clipped on left side if col_offset > 0.
658 */
659 leftmost_fromskew = img->col_offset % tw;
660 leftmost_tw = tw - leftmost_fromskew;
661 leftmost_toskew = toskew + leftmost_fromskew;
662 for (row = 0; ret != 0 && row < h; row += nrow)
663 {
664 rowstoread = th - (row + img->row_offset) % th;
665 nrow = (row + rowstoread > h ? h - row : rowstoread);
666 fromskew = leftmost_fromskew;
667 this_tw = leftmost_tw;
668 this_toskew = leftmost_toskew;
669 tocol = 0;
670 col = img->col_offset;
671 while (tocol < w)
672 {
673 if (_TIFFReadTileAndAllocBuffer(tif, (void**) &buf, bufsize, col,
674 row+img->row_offset, 0, 0)==(tmsize_t)(-1) &&
675 (buf == NULL || img->stoponerr))
676 {
677 ret = 0;
678 break;
679 }
680 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \
681 ((tmsize_t) fromskew * img->samplesperpixel);
682 if (tocol + this_tw > w)
683 {
684 /*
685 * Rightmost tile is clipped on right side.
686 */
687 fromskew = tw - (w - tocol);
688 this_tw = tw - fromskew;
689 this_toskew = toskew + fromskew;
690 }
691 (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, buf + pos);
692 tocol += this_tw;
693 col += this_tw;
694 /*
695 * After the leftmost tile, tiles are no longer clipped on left side.
696 */
697 fromskew = 0;
698 this_tw = tw;
699 this_toskew = toskew;
700 }
701
702 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
703 }
704 _TIFFfree(buf);
705
706 if (flip & FLIP_HORIZONTALLY) {
707 uint32 line;
708
709 for (line = 0; line < h; line++) {
710 uint32 *left = raster + (line * w);
711 uint32 *right = left + w - 1;
712
713 while ( left < right ) {
714 uint32 temp = *left;
715 *left = *right;
716 *right = temp;
717 left++;
718 right--;
719 }
720 }
721 }
722
723 return (ret);
724}
725
726/*
727 * Get an tile-organized image that has
728 * SamplesPerPixel > 1
729 * PlanarConfiguration separated
730 * We assume that all such images are RGB.
731 */
732static int
734{
735 TIFF* tif = img->tif;
736 tileSeparateRoutine put = img->put.separate;
737 uint32 col, row, y, rowstoread;
739 uint32 tw, th;
740 unsigned char* buf = NULL;
741 unsigned char* p0 = NULL;
742 unsigned char* p1 = NULL;
743 unsigned char* p2 = NULL;
744 unsigned char* pa = NULL;
745 tmsize_t tilesize;
747 int32 fromskew, toskew;
748 int alpha = img->alpha;
749 uint32 nrow;
750 int ret = 1, flip;
751 uint16 colorchannels;
752 uint32 this_tw, tocol;
753 int32 this_toskew, leftmost_toskew;
754 int32 leftmost_fromskew;
755 uint32 leftmost_tw;
756
757 tilesize = TIFFTileSize(tif);
758 bufsize = _TIFFMultiplySSize(tif, alpha?4:3,tilesize, "gtTileSeparate");
759 if (bufsize == 0) {
760 return (0);
761 }
762
765
766 flip = setorientation(img);
767 if (flip & FLIP_VERTICALLY) {
768 y = h - 1;
769 toskew = -(int32)(tw + w);
770 }
771 else {
772 y = 0;
773 toskew = -(int32)(tw - w);
774 }
775
776 switch( img->photometric )
777 {
781 colorchannels = 1;
782 break;
783
784 default:
785 colorchannels = 3;
786 break;
787 }
788
789 /*
790 * Leftmost tile is clipped on left side if col_offset > 0.
791 */
792 leftmost_fromskew = img->col_offset % tw;
793 leftmost_tw = tw - leftmost_fromskew;
794 leftmost_toskew = toskew + leftmost_fromskew;
795 for (row = 0; ret != 0 && row < h; row += nrow)
796 {
797 rowstoread = th - (row + img->row_offset) % th;
798 nrow = (row + rowstoread > h ? h - row : rowstoread);
799 fromskew = leftmost_fromskew;
800 this_tw = leftmost_tw;
801 this_toskew = leftmost_toskew;
802 tocol = 0;
803 col = img->col_offset;
804 while (tocol < w)
805 {
806 if( buf == NULL )
807 {
809 tif, (void**) &buf, bufsize, col,
810 row+img->row_offset,0,0)==(tmsize_t)(-1)
811 && (buf == NULL || img->stoponerr))
812 {
813 ret = 0;
814 break;
815 }
816 p0 = buf;
817 if( colorchannels == 1 )
818 {
819 p2 = p1 = p0;
820 pa = (alpha?(p0+3*tilesize):NULL);
821 }
822 else
823 {
824 p1 = p0 + tilesize;
825 p2 = p1 + tilesize;
826 pa = (alpha?(p2+tilesize):NULL);
827 }
828 }
829 else if (TIFFReadTile(tif, p0, col,
830 row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
831 {
832 ret = 0;
833 break;
834 }
835 if (colorchannels > 1
836 && TIFFReadTile(tif, p1, col,
837 row+img->row_offset,0,1) == (tmsize_t)(-1)
838 && img->stoponerr)
839 {
840 ret = 0;
841 break;
842 }
843 if (colorchannels > 1
844 && TIFFReadTile(tif, p2, col,
845 row+img->row_offset,0,2) == (tmsize_t)(-1)
846 && img->stoponerr)
847 {
848 ret = 0;
849 break;
850 }
851 if (alpha
852 && TIFFReadTile(tif,pa,col,
853 row+img->row_offset,0,colorchannels) == (tmsize_t)(-1)
854 && img->stoponerr)
855 {
856 ret = 0;
857 break;
858 }
859
860 pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif) + \
861 ((tmsize_t) fromskew * img->samplesperpixel);
862 if (tocol + this_tw > w)
863 {
864 /*
865 * Rightmost tile is clipped on right side.
866 */
867 fromskew = tw - (w - tocol);
868 this_tw = tw - fromskew;
869 this_toskew = toskew + fromskew;
870 }
871 (*put)(img, raster+y*w+tocol, tocol, y, this_tw, nrow, fromskew, this_toskew, \
872 p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
873 tocol += this_tw;
874 col += this_tw;
875 /*
876 * After the leftmost tile, tiles are no longer clipped on left side.
877 */
878 fromskew = 0;
879 this_tw = tw;
880 this_toskew = toskew;
881 }
882
883 y += ((flip & FLIP_VERTICALLY) ?-(int32) nrow : (int32) nrow);
884 }
885
886 if (flip & FLIP_HORIZONTALLY) {
887 uint32 line;
888
889 for (line = 0; line < h; line++) {
890 uint32 *left = raster + (line * w);
891 uint32 *right = left + w - 1;
892
893 while ( left < right ) {
894 uint32 temp = *left;
895 *left = *right;
896 *right = temp;
897 left++;
898 right--;
899 }
900 }
901 }
902
903 _TIFFfree(buf);
904 return (ret);
905}
906
907/*
908 * Get a strip-organized image that has
909 * PlanarConfiguration contiguous if SamplesPerPixel > 1
910 * or
911 * SamplesPerPixel == 1
912 */
913static int
915{
916 TIFF* tif = img->tif;
917 tileContigRoutine put = img->put.contig;
918 uint32 row, y, nrow, nrowsub, rowstoread;
920 unsigned char* buf = NULL;
921 uint32 rowsperstrip;
922 uint16 subsamplinghor,subsamplingver;
923 uint32 imagewidth = img->width;
924 tmsize_t scanline;
925 int32 fromskew, toskew;
926 int ret = 1, flip;
927 tmsize_t maxstripsize;
928
929 TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
930 if( subsamplingver == 0 ) {
931 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Invalid vertical YCbCr subsampling");
932 return (0);
933 }
934
935 maxstripsize = TIFFStripSize(tif);
936
937 flip = setorientation(img);
938 if (flip & FLIP_VERTICALLY) {
939 y = h - 1;
940 toskew = -(int32)(w + w);
941 } else {
942 y = 0;
943 toskew = -(int32)(w - w);
944 }
945
946 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
947
948 scanline = TIFFScanlineSize(tif);
949 fromskew = (w < imagewidth ? imagewidth - w : 0);
950 for (row = 0; row < h; row += nrow)
951 {
952 uint32 temp;
953 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
954 nrow = (row + rowstoread > h ? h - row : rowstoread);
955 nrowsub = nrow;
956 if ((nrowsub%subsamplingver)!=0)
957 nrowsub+=subsamplingver-nrowsub%subsamplingver;
958 temp = (row + img->row_offset)%rowsperstrip + nrowsub;
959 if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) )
960 {
961 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripContig");
962 return 0;
963 }
965 TIFFComputeStrip(tif,row+img->row_offset, 0),
966 (void**)(&buf),
967 maxstripsize,
968 temp * scanline)==(tmsize_t)(-1)
969 && (buf == NULL || img->stoponerr))
970 {
971 ret = 0;
972 break;
973 }
974
975 pos = ((row + img->row_offset) % rowsperstrip) * scanline + \
976 ((tmsize_t) img->col_offset * img->samplesperpixel);
977 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
978 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
979 }
980
981 if (flip & FLIP_HORIZONTALLY) {
982 uint32 line;
983
984 for (line = 0; line < h; line++) {
985 uint32 *left = raster + (line * w);
986 uint32 *right = left + w - 1;
987
988 while ( left < right ) {
989 uint32 temp = *left;
990 *left = *right;
991 *right = temp;
992 left++;
993 right--;
994 }
995 }
996 }
997
998 _TIFFfree(buf);
999 return (ret);
1000}
1001
1002/*
1003 * Get a strip-organized image with
1004 * SamplesPerPixel > 1
1005 * PlanarConfiguration separated
1006 * We assume that all such images are RGB.
1007 */
1008static int
1010{
1011 TIFF* tif = img->tif;
1012 tileSeparateRoutine put = img->put.separate;
1013 unsigned char *buf = NULL;
1014 unsigned char *p0 = NULL, *p1 = NULL, *p2 = NULL, *pa = NULL;
1015 uint32 row, y, nrow, rowstoread;
1016 tmsize_t pos;
1017 tmsize_t scanline;
1018 uint32 rowsperstrip, offset_row;
1019 uint32 imagewidth = img->width;
1020 tmsize_t stripsize;
1022 int32 fromskew, toskew;
1023 int alpha = img->alpha;
1024 int ret = 1, flip;
1025 uint16 colorchannels;
1026
1027 stripsize = TIFFStripSize(tif);
1028 bufsize = _TIFFMultiplySSize(tif,alpha?4:3,stripsize, "gtStripSeparate");
1029 if (bufsize == 0) {
1030 return (0);
1031 }
1032
1033 flip = setorientation(img);
1034 if (flip & FLIP_VERTICALLY) {
1035 y = h - 1;
1036 toskew = -(int32)(w + w);
1037 }
1038 else {
1039 y = 0;
1040 toskew = -(int32)(w - w);
1041 }
1042
1043 switch( img->photometric )
1044 {
1048 colorchannels = 1;
1049 break;
1050
1051 default:
1052 colorchannels = 3;
1053 break;
1054 }
1055
1056 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1057 scanline = TIFFScanlineSize(tif);
1058 fromskew = (w < imagewidth ? imagewidth - w : 0);
1059 for (row = 0; row < h; row += nrow)
1060 {
1061 uint32 temp;
1062 rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
1063 nrow = (row + rowstoread > h ? h - row : rowstoread);
1064 offset_row = row + img->row_offset;
1065 temp = (row + img->row_offset)%rowsperstrip + nrow;
1066 if( scanline > 0 && temp > (size_t)(TIFF_TMSIZE_T_MAX / scanline) )
1067 {
1068 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in gtStripSeparate");
1069 return 0;
1070 }
1071 if( buf == NULL )
1072 {
1074 tif, TIFFComputeStrip(tif, offset_row, 0),
1075 (void**) &buf, bufsize,
1076 temp * scanline)==(tmsize_t)(-1)
1077 && (buf == NULL || img->stoponerr))
1078 {
1079 ret = 0;
1080 break;
1081 }
1082 p0 = buf;
1083 if( colorchannels == 1 )
1084 {
1085 p2 = p1 = p0;
1086 pa = (alpha?(p0+3*stripsize):NULL);
1087 }
1088 else
1089 {
1090 p1 = p0 + stripsize;
1091 p2 = p1 + stripsize;
1092 pa = (alpha?(p2+stripsize):NULL);
1093 }
1094 }
1095 else if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
1096 p0, temp * scanline)==(tmsize_t)(-1)
1097 && img->stoponerr)
1098 {
1099 ret = 0;
1100 break;
1101 }
1102 if (colorchannels > 1
1103 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
1104 p1, temp * scanline) == (tmsize_t)(-1)
1105 && img->stoponerr)
1106 {
1107 ret = 0;
1108 break;
1109 }
1110 if (colorchannels > 1
1111 && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
1112 p2, temp * scanline) == (tmsize_t)(-1)
1113 && img->stoponerr)
1114 {
1115 ret = 0;
1116 break;
1117 }
1118 if (alpha)
1119 {
1120 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
1121 pa, temp * scanline)==(tmsize_t)(-1)
1122 && img->stoponerr)
1123 {
1124 ret = 0;
1125 break;
1126 }
1127 }
1128
1129 pos = ((row + img->row_offset) % rowsperstrip) * scanline + \
1130 ((tmsize_t) img->col_offset * img->samplesperpixel);
1131 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
1132 p2 + pos, (alpha?(pa+pos):NULL));
1133 y += ((flip & FLIP_VERTICALLY) ? -(int32) nrow : (int32) nrow);
1134 }
1135
1136 if (flip & FLIP_HORIZONTALLY) {
1137 uint32 line;
1138
1139 for (line = 0; line < h; line++) {
1140 uint32 *left = raster + (line * w);
1141 uint32 *right = left + w - 1;
1142
1143 while ( left < right ) {
1144 uint32 temp = *left;
1145 *left = *right;
1146 *right = temp;
1147 left++;
1148 right--;
1149 }
1150 }
1151 }
1152
1153 _TIFFfree(buf);
1154 return (ret);
1155}
1156
1157/*
1158 * The following routines move decoded data returned
1159 * from the TIFF library into rasters filled with packed
1160 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
1161 *
1162 * The routines have been created according to the most
1163 * important cases and optimized. PickContigCase and
1164 * PickSeparateCase analyze the parameters and select
1165 * the appropriate "get" and "put" routine to use.
1166 */
1167#define REPEAT8(op) REPEAT4(op); REPEAT4(op)
1168#define REPEAT4(op) REPEAT2(op); REPEAT2(op)
1169#define REPEAT2(op) op; op
1170#define CASE8(x,op) \
1171 switch (x) { \
1172 case 7: op; /*-fallthrough*/ \
1173 case 6: op; /*-fallthrough*/ \
1174 case 5: op; /*-fallthrough*/ \
1175 case 4: op; /*-fallthrough*/ \
1176 case 3: op; /*-fallthrough*/ \
1177 case 2: op; /*-fallthrough*/ \
1178 case 1: op; \
1179 }
1180#define CASE4(x,op) switch (x) { case 3: op; /*-fallthrough*/ case 2: op; /*-fallthrough*/ case 1: op; }
1181#define NOP
1182
1183#define UNROLL8(w, op1, op2) { \
1184 uint32 _x; \
1185 for (_x = w; _x >= 8; _x -= 8) { \
1186 op1; \
1187 REPEAT8(op2); \
1188 } \
1189 if (_x > 0) { \
1190 op1; \
1191 CASE8(_x,op2); \
1192 } \
1193}
1194#define UNROLL4(w, op1, op2) { \
1195 uint32 _x; \
1196 for (_x = w; _x >= 4; _x -= 4) { \
1197 op1; \
1198 REPEAT4(op2); \
1199 } \
1200 if (_x > 0) { \
1201 op1; \
1202 CASE4(_x,op2); \
1203 } \
1204}
1205#define UNROLL2(w, op1, op2) { \
1206 uint32 _x; \
1207 for (_x = w; _x >= 2; _x -= 2) { \
1208 op1; \
1209 REPEAT2(op2); \
1210 } \
1211 if (_x) { \
1212 op1; \
1213 op2; \
1214 } \
1215}
1216
1217#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
1218#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
1219
1220#define A1 (((uint32)0xffL)<<24)
1221#define PACK(r,g,b) \
1222 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1223#define PACK4(r,g,b,a) \
1224 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1225#define W2B(v) (((v)>>8)&0xff)
1226/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
1227#define PACKW(r,g,b) \
1228 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1229#define PACKW4(r,g,b,a) \
1230 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1231
1232#define DECLAREContigPutFunc(name) \
1233static void name(\
1234 TIFFRGBAImage* img, \
1235 uint32* cp, \
1236 uint32 x, uint32 y, \
1237 uint32 w, uint32 h, \
1238 int32 fromskew, int32 toskew, \
1239 unsigned char* pp \
1240)
1241
1242/*
1243 * 8-bit palette => colormap/RGB
1244 */
1245DECLAREContigPutFunc(put8bitcmaptile)
1246{
1247 uint32** PALmap = img->PALmap;
1248 int samplesperpixel = img->samplesperpixel;
1249
1250 (void) y;
1251 for( ; h > 0; --h) {
1252 for (x = w; x > 0; --x)
1253 {
1254 *cp++ = PALmap[*pp][0];
1255 pp += samplesperpixel;
1256 }
1257 cp += toskew;
1258 pp += fromskew;
1259 }
1260}
1261
1262/*
1263 * 4-bit palette => colormap/RGB
1264 */
1265DECLAREContigPutFunc(put4bitcmaptile)
1266{
1267 uint32** PALmap = img->PALmap;
1268
1269 (void) x; (void) y;
1270 fromskew /= 2;
1271 for( ; h > 0; --h) {
1272 uint32* bw;
1273 UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
1274 cp += toskew;
1275 pp += fromskew;
1276 }
1277}
1278
1279/*
1280 * 2-bit palette => colormap/RGB
1281 */
1282DECLAREContigPutFunc(put2bitcmaptile)
1283{
1284 uint32** PALmap = img->PALmap;
1285
1286 (void) x; (void) y;
1287 fromskew /= 4;
1288 for( ; h > 0; --h) {
1289 uint32* bw;
1290 UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
1291 cp += toskew;
1292 pp += fromskew;
1293 }
1294}
1295
1296/*
1297 * 1-bit palette => colormap/RGB
1298 */
1299DECLAREContigPutFunc(put1bitcmaptile)
1300{
1301 uint32** PALmap = img->PALmap;
1302
1303 (void) x; (void) y;
1304 fromskew /= 8;
1305 for( ; h > 0; --h) {
1306 uint32* bw;
1307 UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
1308 cp += toskew;
1309 pp += fromskew;
1310 }
1311}
1312
1313/*
1314 * 8-bit greyscale => colormap/RGB
1315 */
1317{
1318 int samplesperpixel = img->samplesperpixel;
1319 uint32** BWmap = img->BWmap;
1320
1321 (void) y;
1322 for( ; h > 0; --h) {
1323 for (x = w; x > 0; --x)
1324 {
1325 *cp++ = BWmap[*pp][0];
1326 pp += samplesperpixel;
1327 }
1328 cp += toskew;
1329 pp += fromskew;
1330 }
1331}
1332
1333/*
1334 * 8-bit greyscale with associated alpha => colormap/RGBA
1335 */
1337{
1338 int samplesperpixel = img->samplesperpixel;
1339 uint32** BWmap = img->BWmap;
1340
1341 (void) y;
1342 for( ; h > 0; --h) {
1343 for (x = w; x > 0; --x)
1344 {
1345 *cp++ = BWmap[*pp][0] & ((uint32)*(pp+1) << 24 | ~A1);
1346 pp += samplesperpixel;
1347 }
1348 cp += toskew;
1349 pp += fromskew;
1350 }
1351}
1352
1353/*
1354 * 16-bit greyscale => colormap/RGB
1355 */
1357{
1358 int samplesperpixel = img->samplesperpixel;
1359 uint32** BWmap = img->BWmap;
1360
1361 (void) y;
1362 for( ; h > 0; --h) {
1363 uint16 *wp = (uint16 *) pp;
1364
1365 for (x = w; x > 0; --x)
1366 {
1367 /* use high order byte of 16bit value */
1368
1369 *cp++ = BWmap[*wp >> 8][0];
1370 pp += 2 * samplesperpixel;
1371 wp += samplesperpixel;
1372 }
1373 cp += toskew;
1374 pp += fromskew;
1375 }
1376}
1377
1378/*
1379 * 1-bit bilevel => colormap/RGB
1380 */
1382{
1383 uint32** BWmap = img->BWmap;
1384
1385 (void) x; (void) y;
1386 fromskew /= 8;
1387 for( ; h > 0; --h) {
1388 uint32* bw;
1389 UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
1390 cp += toskew;
1391 pp += fromskew;
1392 }
1393}
1394
1395/*
1396 * 2-bit greyscale => colormap/RGB
1397 */
1399{
1400 uint32** BWmap = img->BWmap;
1401
1402 (void) x; (void) y;
1403 fromskew /= 4;
1404 for( ; h > 0; --h) {
1405 uint32* bw;
1406 UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
1407 cp += toskew;
1408 pp += fromskew;
1409 }
1410}
1411
1412/*
1413 * 4-bit greyscale => colormap/RGB
1414 */
1416{
1417 uint32** BWmap = img->BWmap;
1418
1419 (void) x; (void) y;
1420 fromskew /= 2;
1421 for( ; h > 0; --h) {
1422 uint32* bw;
1423 UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
1424 cp += toskew;
1425 pp += fromskew;
1426 }
1427}
1428
1429/*
1430 * 8-bit packed samples, no Map => RGB
1431 */
1432DECLAREContigPutFunc(putRGBcontig8bittile)
1433{
1434 int samplesperpixel = img->samplesperpixel;
1435
1436 (void) x; (void) y;
1437 fromskew *= samplesperpixel;
1438 for( ; h > 0; --h) {
1439 UNROLL8(w, NOP,
1440 *cp++ = PACK(pp[0], pp[1], pp[2]);
1441 pp += samplesperpixel);
1442 cp += toskew;
1443 pp += fromskew;
1444 }
1445}
1446
1447/*
1448 * 8-bit packed samples => RGBA w/ associated alpha
1449 * (known to have Map == NULL)
1450 */
1451DECLAREContigPutFunc(putRGBAAcontig8bittile)
1452{
1453 int samplesperpixel = img->samplesperpixel;
1454
1455 (void) x; (void) y;
1456 fromskew *= samplesperpixel;
1457 for( ; h > 0; --h) {
1458 UNROLL8(w, NOP,
1459 *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
1460 pp += samplesperpixel);
1461 cp += toskew;
1462 pp += fromskew;
1463 }
1464}
1465
1466/*
1467 * 8-bit packed samples => RGBA w/ unassociated alpha
1468 * (known to have Map == NULL)
1469 */
1470DECLAREContigPutFunc(putRGBUAcontig8bittile)
1471{
1472 int samplesperpixel = img->samplesperpixel;
1473 (void) y;
1474 fromskew *= samplesperpixel;
1475 for( ; h > 0; --h) {
1476 uint32 r, g, b, a;
1477 uint8* m;
1478 for (x = w; x > 0; --x) {
1479 a = pp[3];
1480 m = img->UaToAa+((size_t) a<<8);
1481 r = m[pp[0]];
1482 g = m[pp[1]];
1483 b = m[pp[2]];
1484 *cp++ = PACK4(r,g,b,a);
1485 pp += samplesperpixel;
1486 }
1487 cp += toskew;
1488 pp += fromskew;
1489 }
1490}
1491
1492/*
1493 * 16-bit packed samples => RGB
1494 */
1495DECLAREContigPutFunc(putRGBcontig16bittile)
1496{
1497 int samplesperpixel = img->samplesperpixel;
1498 uint16 *wp = (uint16 *)pp;
1499 (void) y;
1500 fromskew *= samplesperpixel;
1501 for( ; h > 0; --h) {
1502 for (x = w; x > 0; --x) {
1503 *cp++ = PACK(img->Bitdepth16To8[wp[0]],
1504 img->Bitdepth16To8[wp[1]],
1505 img->Bitdepth16To8[wp[2]]);
1506 wp += samplesperpixel;
1507 }
1508 cp += toskew;
1509 wp += fromskew;
1510 }
1511}
1512
1513/*
1514 * 16-bit packed samples => RGBA w/ associated alpha
1515 * (known to have Map == NULL)
1516 */
1517DECLAREContigPutFunc(putRGBAAcontig16bittile)
1518{
1519 int samplesperpixel = img->samplesperpixel;
1520 uint16 *wp = (uint16 *)pp;
1521 (void) y;
1522 fromskew *= samplesperpixel;
1523 for( ; h > 0; --h) {
1524 for (x = w; x > 0; --x) {
1525 *cp++ = PACK4(img->Bitdepth16To8[wp[0]],
1526 img->Bitdepth16To8[wp[1]],
1527 img->Bitdepth16To8[wp[2]],
1528 img->Bitdepth16To8[wp[3]]);
1529 wp += samplesperpixel;
1530 }
1531 cp += toskew;
1532 wp += fromskew;
1533 }
1534}
1535
1536/*
1537 * 16-bit packed samples => RGBA w/ unassociated alpha
1538 * (known to have Map == NULL)
1539 */
1540DECLAREContigPutFunc(putRGBUAcontig16bittile)
1541{
1542 int samplesperpixel = img->samplesperpixel;
1543 uint16 *wp = (uint16 *)pp;
1544 (void) y;
1545 fromskew *= samplesperpixel;
1546 for( ; h > 0; --h) {
1547 uint32 r,g,b,a;
1548 uint8* m;
1549 for (x = w; x > 0; --x) {
1550 a = img->Bitdepth16To8[wp[3]];
1551 m = img->UaToAa+((size_t) a<<8);
1552 r = m[img->Bitdepth16To8[wp[0]]];
1553 g = m[img->Bitdepth16To8[wp[1]]];
1554 b = m[img->Bitdepth16To8[wp[2]]];
1555 *cp++ = PACK4(r,g,b,a);
1556 wp += samplesperpixel;
1557 }
1558 cp += toskew;
1559 wp += fromskew;
1560 }
1561}
1562
1563/*
1564 * 8-bit packed CMYK samples w/o Map => RGB
1565 *
1566 * NB: The conversion of CMYK->RGB is *very* crude.
1567 */
1568DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
1569{
1570 int samplesperpixel = img->samplesperpixel;
1571 uint16 r, g, b, k;
1572
1573 (void) x; (void) y;
1574 fromskew *= samplesperpixel;
1575 for( ; h > 0; --h) {
1576 UNROLL8(w, NOP,
1577 k = 255 - pp[3];
1578 r = (k*(255-pp[0]))/255;
1579 g = (k*(255-pp[1]))/255;
1580 b = (k*(255-pp[2]))/255;
1581 *cp++ = PACK(r, g, b);
1582 pp += samplesperpixel);
1583 cp += toskew;
1584 pp += fromskew;
1585 }
1586}
1587
1588/*
1589 * 8-bit packed CMYK samples w/Map => RGB
1590 *
1591 * NB: The conversion of CMYK->RGB is *very* crude.
1592 */
1593DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
1594{
1595 int samplesperpixel = img->samplesperpixel;
1596 TIFFRGBValue* Map = img->Map;
1597 uint16 r, g, b, k;
1598
1599 (void) y;
1600 fromskew *= samplesperpixel;
1601 for( ; h > 0; --h) {
1602 for (x = w; x > 0; --x) {
1603 k = 255 - pp[3];
1604 r = (k*(255-pp[0]))/255;
1605 g = (k*(255-pp[1]))/255;
1606 b = (k*(255-pp[2]))/255;
1607 *cp++ = PACK(Map[r], Map[g], Map[b]);
1608 pp += samplesperpixel;
1609 }
1610 pp += fromskew;
1611 cp += toskew;
1612 }
1613}
1614
1615#define DECLARESepPutFunc(name) \
1616static void name(\
1617 TIFFRGBAImage* img,\
1618 uint32* cp,\
1619 uint32 x, uint32 y, \
1620 uint32 w, uint32 h,\
1621 int32 fromskew, int32 toskew,\
1622 unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1623)
1624
1625/*
1626 * 8-bit unpacked samples => RGB
1627 */
1628DECLARESepPutFunc(putRGBseparate8bittile)
1629{
1630 (void) img; (void) x; (void) y; (void) a;
1631 for( ; h > 0; --h) {
1632 UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
1633 SKEW(r, g, b, fromskew);
1634 cp += toskew;
1635 }
1636}
1637
1638/*
1639 * 8-bit unpacked samples => RGBA w/ associated alpha
1640 */
1641DECLARESepPutFunc(putRGBAAseparate8bittile)
1642{
1643 (void) img; (void) x; (void) y;
1644 for( ; h > 0; --h) {
1645 UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
1646 SKEW4(r, g, b, a, fromskew);
1647 cp += toskew;
1648 }
1649}
1650
1651/*
1652 * 8-bit unpacked CMYK samples => RGBA
1653 */
1654DECLARESepPutFunc(putCMYKseparate8bittile)
1655{
1656 (void) img; (void) y;
1657 for( ; h > 0; --h) {
1658 uint32 rv, gv, bv, kv;
1659 for (x = w; x > 0; --x) {
1660 kv = 255 - *a++;
1661 rv = (kv*(255-*r++))/255;
1662 gv = (kv*(255-*g++))/255;
1663 bv = (kv*(255-*b++))/255;
1664 *cp++ = PACK4(rv,gv,bv,255);
1665 }
1666 SKEW4(r, g, b, a, fromskew);
1667 cp += toskew;
1668 }
1669}
1670
1671/*
1672 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1673 */
1674DECLARESepPutFunc(putRGBUAseparate8bittile)
1675{
1676 (void) img; (void) y;
1677 for( ; h > 0; --h) {
1678 uint32 rv, gv, bv, av;
1679 uint8* m;
1680 for (x = w; x > 0; --x) {
1681 av = *a++;
1682 m = img->UaToAa+((size_t) av<<8);
1683 rv = m[*r++];
1684 gv = m[*g++];
1685 bv = m[*b++];
1686 *cp++ = PACK4(rv,gv,bv,av);
1687 }
1688 SKEW4(r, g, b, a, fromskew);
1689 cp += toskew;
1690 }
1691}
1692
1693/*
1694 * 16-bit unpacked samples => RGB
1695 */
1696DECLARESepPutFunc(putRGBseparate16bittile)
1697{
1698 uint16 *wr = (uint16*) r;
1699 uint16 *wg = (uint16*) g;
1700 uint16 *wb = (uint16*) b;
1701 (void) img; (void) y; (void) a;
1702 for( ; h > 0; --h) {
1703 for (x = 0; x < w; x++)
1704 *cp++ = PACK(img->Bitdepth16To8[*wr++],
1705 img->Bitdepth16To8[*wg++],
1706 img->Bitdepth16To8[*wb++]);
1707 SKEW(wr, wg, wb, fromskew);
1708 cp += toskew;
1709 }
1710}
1711
1712/*
1713 * 16-bit unpacked samples => RGBA w/ associated alpha
1714 */
1715DECLARESepPutFunc(putRGBAAseparate16bittile)
1716{
1717 uint16 *wr = (uint16*) r;
1718 uint16 *wg = (uint16*) g;
1719 uint16 *wb = (uint16*) b;
1720 uint16 *wa = (uint16*) a;
1721 (void) img; (void) y;
1722 for( ; h > 0; --h) {
1723 for (x = 0; x < w; x++)
1724 *cp++ = PACK4(img->Bitdepth16To8[*wr++],
1725 img->Bitdepth16To8[*wg++],
1726 img->Bitdepth16To8[*wb++],
1727 img->Bitdepth16To8[*wa++]);
1728 SKEW4(wr, wg, wb, wa, fromskew);
1729 cp += toskew;
1730 }
1731}
1732
1733/*
1734 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1735 */
1736DECLARESepPutFunc(putRGBUAseparate16bittile)
1737{
1738 uint16 *wr = (uint16*) r;
1739 uint16 *wg = (uint16*) g;
1740 uint16 *wb = (uint16*) b;
1741 uint16 *wa = (uint16*) a;
1742 (void) img; (void) y;
1743 for( ; h > 0; --h) {
1744 uint32 r2,g2,b2,a2;
1745 uint8* m;
1746 for (x = w; x > 0; --x) {
1747 a2 = img->Bitdepth16To8[*wa++];
1748 m = img->UaToAa+((size_t) a2<<8);
1749 r2 = m[img->Bitdepth16To8[*wr++]];
1750 g2 = m[img->Bitdepth16To8[*wg++]];
1751 b2 = m[img->Bitdepth16To8[*wb++]];
1752 *cp++ = PACK4(r2,g2,b2,a2);
1753 }
1754 SKEW4(wr, wg, wb, wa, fromskew);
1755 cp += toskew;
1756 }
1757}
1758
1759/*
1760 * 8-bit packed CIE L*a*b 1976 samples => RGB
1761 */
1762DECLAREContigPutFunc(putcontig8bitCIELab)
1763{
1764 float X, Y, Z;
1765 uint32 r, g, b;
1766 (void) y;
1767 fromskew *= 3;
1768 for( ; h > 0; --h) {
1769 for (x = w; x > 0; --x) {
1770 TIFFCIELabToXYZ(img->cielab,
1771 (unsigned char)pp[0],
1772 (signed char)pp[1],
1773 (signed char)pp[2],
1774 &X, &Y, &Z);
1775 TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
1776 *cp++ = PACK(r, g, b);
1777 pp += 3;
1778 }
1779 cp += toskew;
1780 pp += fromskew;
1781 }
1782}
1783
1784/*
1785 * YCbCr -> RGB conversion and packing routines.
1786 */
1787
1788#define YCbCrtoRGB(dst, Y) { \
1789 uint32 r, g, b; \
1790 TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
1791 dst = PACK(r, g, b); \
1792}
1793
1794/*
1795 * 8-bit packed YCbCr samples => RGB
1796 * This function is generic for different sampling sizes,
1797 * and can handle blocks sizes that aren't multiples of the
1798 * sampling size. However, it is substantially less optimized
1799 * than the specific sampling cases. It is used as a fallback
1800 * for difficult blocks.
1801 */
1802#ifdef notdef
1803static void putcontig8bitYCbCrGenericTile(
1805 uint32* cp,
1806 uint32 x, uint32 y,
1807 uint32 w, uint32 h,
1808 int32 fromskew, int32 toskew,
1809 unsigned char* pp,
1810 int h_group,
1811 int v_group )
1812
1813{
1814 uint32* cp1 = cp+w+toskew;
1815 uint32* cp2 = cp1+w+toskew;
1816 uint32* cp3 = cp2+w+toskew;
1817 int32 incr = 3*w+4*toskew;
1818 int32 Cb, Cr;
1819 int group_size = v_group * h_group + 2;
1820
1821 (void) y;
1822 fromskew = (fromskew * group_size) / h_group;
1823
1824 for( yy = 0; yy < h; yy++ )
1825 {
1826 unsigned char *pp_line;
1827 int y_line_group = yy / v_group;
1828 int y_remainder = yy - y_line_group * v_group;
1829
1830 pp_line = pp + v_line_group *
1831
1832
1833 for( xx = 0; xx < w; xx++ )
1834 {
1835 Cb = pp
1836 }
1837 }
1838 for (; h >= 4; h -= 4) {
1839 x = w>>2;
1840 do {
1841 Cb = pp[16];
1842 Cr = pp[17];
1843
1844 YCbCrtoRGB(cp [0], pp[ 0]);
1845 YCbCrtoRGB(cp [1], pp[ 1]);
1846 YCbCrtoRGB(cp [2], pp[ 2]);
1847 YCbCrtoRGB(cp [3], pp[ 3]);
1848 YCbCrtoRGB(cp1[0], pp[ 4]);
1849 YCbCrtoRGB(cp1[1], pp[ 5]);
1850 YCbCrtoRGB(cp1[2], pp[ 6]);
1851 YCbCrtoRGB(cp1[3], pp[ 7]);
1852 YCbCrtoRGB(cp2[0], pp[ 8]);
1853 YCbCrtoRGB(cp2[1], pp[ 9]);
1854 YCbCrtoRGB(cp2[2], pp[10]);
1855 YCbCrtoRGB(cp2[3], pp[11]);
1856 YCbCrtoRGB(cp3[0], pp[12]);
1857 YCbCrtoRGB(cp3[1], pp[13]);
1858 YCbCrtoRGB(cp3[2], pp[14]);
1859 YCbCrtoRGB(cp3[3], pp[15]);
1860
1861 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1862 pp += 18;
1863 } while (--x);
1864 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1865 pp += fromskew;
1866 }
1867}
1868#endif
1869
1870/*
1871 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1872 */
1873DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
1874{
1875 uint32* cp1 = cp+w+toskew;
1876 uint32* cp2 = cp1+w+toskew;
1877 uint32* cp3 = cp2+w+toskew;
1878 int32 incr = 3*w+4*toskew;
1879
1880 (void) y;
1881 /* adjust fromskew */
1882 fromskew = (fromskew / 4) * (4*2+2);
1883 if ((h & 3) == 0 && (w & 3) == 0) {
1884 for (; h >= 4; h -= 4) {
1885 x = w>>2;
1886 do {
1887 int32 Cb = pp[16];
1888 int32 Cr = pp[17];
1889
1890 YCbCrtoRGB(cp [0], pp[ 0]);
1891 YCbCrtoRGB(cp [1], pp[ 1]);
1892 YCbCrtoRGB(cp [2], pp[ 2]);
1893 YCbCrtoRGB(cp [3], pp[ 3]);
1894 YCbCrtoRGB(cp1[0], pp[ 4]);
1895 YCbCrtoRGB(cp1[1], pp[ 5]);
1896 YCbCrtoRGB(cp1[2], pp[ 6]);
1897 YCbCrtoRGB(cp1[3], pp[ 7]);
1898 YCbCrtoRGB(cp2[0], pp[ 8]);
1899 YCbCrtoRGB(cp2[1], pp[ 9]);
1900 YCbCrtoRGB(cp2[2], pp[10]);
1901 YCbCrtoRGB(cp2[3], pp[11]);
1902 YCbCrtoRGB(cp3[0], pp[12]);
1903 YCbCrtoRGB(cp3[1], pp[13]);
1904 YCbCrtoRGB(cp3[2], pp[14]);
1905 YCbCrtoRGB(cp3[3], pp[15]);
1906
1907 cp += 4;
1908 cp1 += 4;
1909 cp2 += 4;
1910 cp3 += 4;
1911 pp += 18;
1912 } while (--x);
1913 cp += incr;
1914 cp1 += incr;
1915 cp2 += incr;
1916 cp3 += incr;
1917 pp += fromskew;
1918 }
1919 } else {
1920 while (h > 0) {
1921 for (x = w; x > 0;) {
1922 int32 Cb = pp[16];
1923 int32 Cr = pp[17];
1924 switch (x) {
1925 default:
1926 switch (h) {
1927 default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
1928 case 3: YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
1929 case 2: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1930 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1931 } /* FALLTHROUGH */
1932 case 3:
1933 switch (h) {
1934 default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
1935 case 3: YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
1936 case 2: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1937 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1938 } /* FALLTHROUGH */
1939 case 2:
1940 switch (h) {
1941 default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
1942 case 3: YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
1943 case 2: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1944 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1945 } /* FALLTHROUGH */
1946 case 1:
1947 switch (h) {
1948 default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
1949 case 3: YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
1950 case 2: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1951 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1952 } /* FALLTHROUGH */
1953 }
1954 if (x < 4) {
1955 cp += x; cp1 += x; cp2 += x; cp3 += x;
1956 x = 0;
1957 }
1958 else {
1959 cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
1960 x -= 4;
1961 }
1962 pp += 18;
1963 }
1964 if (h <= 4)
1965 break;
1966 h -= 4;
1967 cp += incr;
1968 cp1 += incr;
1969 cp2 += incr;
1970 cp3 += incr;
1971 pp += fromskew;
1972 }
1973 }
1974}
1975
1976/*
1977 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1978 */
1979DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
1980{
1981 uint32* cp1 = cp+w+toskew;
1982 int32 incr = 2*toskew+w;
1983
1984 (void) y;
1985 fromskew = (fromskew / 4) * (4*2+2);
1986 if ((w & 3) == 0 && (h & 1) == 0) {
1987 for (; h >= 2; h -= 2) {
1988 x = w>>2;
1989 do {
1990 int32 Cb = pp[8];
1991 int32 Cr = pp[9];
1992
1993 YCbCrtoRGB(cp [0], pp[0]);
1994 YCbCrtoRGB(cp [1], pp[1]);
1995 YCbCrtoRGB(cp [2], pp[2]);
1996 YCbCrtoRGB(cp [3], pp[3]);
1997 YCbCrtoRGB(cp1[0], pp[4]);
1998 YCbCrtoRGB(cp1[1], pp[5]);
1999 YCbCrtoRGB(cp1[2], pp[6]);
2000 YCbCrtoRGB(cp1[3], pp[7]);
2001
2002 cp += 4;
2003 cp1 += 4;
2004 pp += 10;
2005 } while (--x);
2006 cp += incr;
2007 cp1 += incr;
2008 pp += fromskew;
2009 }
2010 } else {
2011 while (h > 0) {
2012 for (x = w; x > 0;) {
2013 int32 Cb = pp[8];
2014 int32 Cr = pp[9];
2015 switch (x) {
2016 default:
2017 switch (h) {
2018 default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
2019 case 1: YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
2020 } /* FALLTHROUGH */
2021 case 3:
2022 switch (h) {
2023 default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
2024 case 1: YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
2025 } /* FALLTHROUGH */
2026 case 2:
2027 switch (h) {
2028 default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
2029 case 1: YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
2030 } /* FALLTHROUGH */
2031 case 1:
2032 switch (h) {
2033 default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
2034 case 1: YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
2035 } /* FALLTHROUGH */
2036 }
2037 if (x < 4) {
2038 cp += x; cp1 += x;
2039 x = 0;
2040 }
2041 else {
2042 cp += 4; cp1 += 4;
2043 x -= 4;
2044 }
2045 pp += 10;
2046 }
2047 if (h <= 2)
2048 break;
2049 h -= 2;
2050 cp += incr;
2051 cp1 += incr;
2052 pp += fromskew;
2053 }
2054 }
2055}
2056
2057/*
2058 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
2059 */
2060DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
2061{
2062 (void) y;
2063 fromskew = (fromskew / 4) * (4*1+2);
2064 do {
2065 x = w>>2;
2066 while(x>0) {
2067 int32 Cb = pp[4];
2068 int32 Cr = pp[5];
2069
2070 YCbCrtoRGB(cp [0], pp[0]);
2071 YCbCrtoRGB(cp [1], pp[1]);
2072 YCbCrtoRGB(cp [2], pp[2]);
2073 YCbCrtoRGB(cp [3], pp[3]);
2074
2075 cp += 4;
2076 pp += 6;
2077 x--;
2078 }
2079
2080 if( (w&3) != 0 )
2081 {
2082 int32 Cb = pp[4];
2083 int32 Cr = pp[5];
2084
2085 switch( (w&3) ) {
2086 case 3: YCbCrtoRGB(cp [2], pp[2]); /*-fallthrough*/
2087 case 2: YCbCrtoRGB(cp [1], pp[1]); /*-fallthrough*/
2088 case 1: YCbCrtoRGB(cp [0], pp[0]); /*-fallthrough*/
2089 case 0: break;
2090 }
2091
2092 cp += (w&3);
2093 pp += 6;
2094 }
2095
2096 cp += toskew;
2097 pp += fromskew;
2098 } while (--h);
2099
2100}
2101
2102/*
2103 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
2104 */
2105DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
2106{
2107 uint32* cp2;
2108 int32 incr = 2*toskew+w;
2109 (void) y;
2110 fromskew = (fromskew / 2) * (2*2+2);
2111 cp2 = cp+w+toskew;
2112 while (h>=2) {
2113 x = w;
2114 while (x>=2) {
2115 uint32 Cb = pp[4];
2116 uint32 Cr = pp[5];
2117 YCbCrtoRGB(cp[0], pp[0]);
2118 YCbCrtoRGB(cp[1], pp[1]);
2119 YCbCrtoRGB(cp2[0], pp[2]);
2120 YCbCrtoRGB(cp2[1], pp[3]);
2121 cp += 2;
2122 cp2 += 2;
2123 pp += 6;
2124 x -= 2;
2125 }
2126 if (x==1) {
2127 uint32 Cb = pp[4];
2128 uint32 Cr = pp[5];
2129 YCbCrtoRGB(cp[0], pp[0]);
2130 YCbCrtoRGB(cp2[0], pp[2]);
2131 cp ++ ;
2132 cp2 ++ ;
2133 pp += 6;
2134 }
2135 cp += incr;
2136 cp2 += incr;
2137 pp += fromskew;
2138 h-=2;
2139 }
2140 if (h==1) {
2141 x = w;
2142 while (x>=2) {
2143 uint32 Cb = pp[4];
2144 uint32 Cr = pp[5];
2145 YCbCrtoRGB(cp[0], pp[0]);
2146 YCbCrtoRGB(cp[1], pp[1]);
2147 cp += 2;
2148 cp2 += 2;
2149 pp += 6;
2150 x -= 2;
2151 }
2152 if (x==1) {
2153 uint32 Cb = pp[4];
2154 uint32 Cr = pp[5];
2155 YCbCrtoRGB(cp[0], pp[0]);
2156 }
2157 }
2158}
2159
2160/*
2161 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
2162 */
2163DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
2164{
2165 (void) y;
2166 fromskew = (fromskew / 2) * (2*1+2);
2167 do {
2168 x = w>>1;
2169 while(x>0) {
2170 int32 Cb = pp[2];
2171 int32 Cr = pp[3];
2172
2173 YCbCrtoRGB(cp[0], pp[0]);
2174 YCbCrtoRGB(cp[1], pp[1]);
2175
2176 cp += 2;
2177 pp += 4;
2178 x --;
2179 }
2180
2181 if( (w&1) != 0 )
2182 {
2183 int32 Cb = pp[2];
2184 int32 Cr = pp[3];
2185
2186 YCbCrtoRGB(cp[0], pp[0]);
2187
2188 cp += 1;
2189 pp += 4;
2190 }
2191
2192 cp += toskew;
2193 pp += fromskew;
2194 } while (--h);
2195}
2196
2197/*
2198 * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
2199 */
2200DECLAREContigPutFunc(putcontig8bitYCbCr12tile)
2201{
2202 uint32* cp2;
2203 int32 incr = 2*toskew+w;
2204 (void) y;
2205 fromskew = (fromskew / 1) * (1 * 2 + 2);
2206 cp2 = cp+w+toskew;
2207 while (h>=2) {
2208 x = w;
2209 do {
2210 uint32 Cb = pp[2];
2211 uint32 Cr = pp[3];
2212 YCbCrtoRGB(cp[0], pp[0]);
2213 YCbCrtoRGB(cp2[0], pp[1]);
2214 cp ++;
2215 cp2 ++;
2216 pp += 4;
2217 } while (--x);
2218 cp += incr;
2219 cp2 += incr;
2220 pp += fromskew;
2221 h-=2;
2222 }
2223 if (h==1) {
2224 x = w;
2225 do {
2226 uint32 Cb = pp[2];
2227 uint32 Cr = pp[3];
2228 YCbCrtoRGB(cp[0], pp[0]);
2229 cp ++;
2230 pp += 4;
2231 } while (--x);
2232 }
2233}
2234
2235/*
2236 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2237 */
2238DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
2239{
2240 (void) y;
2241 fromskew = (fromskew / 1) * (1 * 1 + 2);
2242 do {
2243 x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
2244 do {
2245 int32 Cb = pp[1];
2246 int32 Cr = pp[2];
2247
2248 YCbCrtoRGB(*cp++, pp[0]);
2249
2250 pp += 3;
2251 } while (--x);
2252 cp += toskew;
2253 pp += fromskew;
2254 } while (--h);
2255}
2256
2257/*
2258 * 8-bit packed YCbCr samples w/ no subsampling => RGB
2259 */
2260DECLARESepPutFunc(putseparate8bitYCbCr11tile)
2261{
2262 (void) y;
2263 (void) a;
2264 /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2265 for( ; h > 0; --h) {
2266 x = w;
2267 do {
2268 uint32 dr, dg, db;
2269 TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
2270 *cp++ = PACK(dr,dg,db);
2271 } while (--x);
2272 SKEW(r, g, b, fromskew);
2273 cp += toskew;
2274 }
2275}
2276#undef YCbCrtoRGB
2277
2278static int isInRefBlackWhiteRange(float f)
2279{
2280 return f > (float)(-0x7FFFFFFF + 128) && f < (float)0x7FFFFFFF;
2281}
2282
2283static int
2285{
2286 static const char module[] = "initYCbCrConversion";
2287
2288 float *luma, *refBlackWhite;
2289
2290 if (img->ycbcr == NULL) {
2291 img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
2292 TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))
2293 + 4*256*sizeof (TIFFRGBValue)
2294 + 2*256*sizeof (int)
2295 + 3*256*sizeof (int32)
2296 );
2297 if (img->ycbcr == NULL) {
2298 TIFFErrorExt(img->tif->tif_clientdata, module,
2299 "No space for YCbCr->RGB conversion state");
2300 return (0);
2301 }
2302 }
2303
2306 &refBlackWhite);
2307
2308 /* Do some validation to avoid later issues. Detect NaN for now */
2309 /* and also if lumaGreen is zero since we divide by it later */
2310 if( luma[0] != luma[0] ||
2311 luma[1] != luma[1] ||
2312 luma[1] == 0.0 ||
2313 luma[2] != luma[2] )
2314 {
2315 TIFFErrorExt(img->tif->tif_clientdata, module,
2316 "Invalid values for YCbCrCoefficients tag");
2317 return (0);
2318 }
2319
2320 if( !isInRefBlackWhiteRange(refBlackWhite[0]) ||
2321 !isInRefBlackWhiteRange(refBlackWhite[1]) ||
2322 !isInRefBlackWhiteRange(refBlackWhite[2]) ||
2323 !isInRefBlackWhiteRange(refBlackWhite[3]) ||
2324 !isInRefBlackWhiteRange(refBlackWhite[4]) ||
2325 !isInRefBlackWhiteRange(refBlackWhite[5]) )
2326 {
2327 TIFFErrorExt(img->tif->tif_clientdata, module,
2328 "Invalid values for ReferenceBlackWhite tag");
2329 return (0);
2330 }
2331
2332 if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
2333 return(0);
2334 return (1);
2335}
2336
2337static tileContigRoutine
2339{
2340 static const char module[] = "initCIELabConversion";
2341
2342 float *whitePoint;
2343 float refWhite[3];
2344
2345 TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
2346 if (whitePoint[1] == 0.0f ) {
2347 TIFFErrorExt(img->tif->tif_clientdata, module,
2348 "Invalid value for WhitePoint tag.");
2349 return NULL;
2350 }
2351
2352 if (!img->cielab) {
2353 img->cielab = (TIFFCIELabToRGB *)
2355 if (!img->cielab) {
2356 TIFFErrorExt(img->tif->tif_clientdata, module,
2357 "No space for CIE L*a*b*->RGB conversion state.");
2358 return NULL;
2359 }
2360 }
2361
2362 refWhite[1] = 100.0F;
2363 refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
2364 refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
2365 / whitePoint[1] * refWhite[1];
2366 if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
2367 TIFFErrorExt(img->tif->tif_clientdata, module,
2368 "Failed to initialize CIE L*a*b*->RGB conversion state.");
2369 _TIFFfree(img->cielab);
2370 return NULL;
2371 }
2372
2373 return putcontig8bitCIELab;
2374}
2375
2376/*
2377 * Greyscale images with less than 8 bits/sample are handled
2378 * with a table to avoid lots of shifts and masks. The table
2379 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2380 * pixel values simply by indexing into the table with one
2381 * number.
2382 */
2383static int
2385{
2386 TIFFRGBValue* Map = img->Map;
2387 int bitspersample = img->bitspersample;
2388 int nsamples = 8 / bitspersample;
2389 int i;
2390 uint32* p;
2391
2392 if( nsamples == 0 )
2393 nsamples = 1;
2394
2395 img->BWmap = (uint32**) _TIFFmalloc(
2396 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2397 if (img->BWmap == NULL) {
2398 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
2399 return (0);
2400 }
2401 p = (uint32*)(img->BWmap + 256);
2402 for (i = 0; i < 256; i++) {
2404 img->BWmap[i] = p;
2405 switch (bitspersample) {
2406#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
2407 case 1:
2408 GREY(i>>7);
2409 GREY((i>>6)&1);
2410 GREY((i>>5)&1);
2411 GREY((i>>4)&1);
2412 GREY((i>>3)&1);
2413 GREY((i>>2)&1);
2414 GREY((i>>1)&1);
2415 GREY(i&1);
2416 break;
2417 case 2:
2418 GREY(i>>6);
2419 GREY((i>>4)&3);
2420 GREY((i>>2)&3);
2421 GREY(i&3);
2422 break;
2423 case 4:
2424 GREY(i>>4);
2425 GREY(i&0xf);
2426 break;
2427 case 8:
2428 case 16:
2429 GREY(i);
2430 break;
2431 }
2432#undef GREY
2433 }
2434 return (1);
2435}
2436
2437/*
2438 * Construct a mapping table to convert from the range
2439 * of the data samples to [0,255] --for display. This
2440 * process also handles inverting B&W images when needed.
2441 */
2442static int
2444{
2445 int32 x, range;
2446
2447 range = (int32)((1L<<img->bitspersample)-1);
2448
2449 /* treat 16 bit the same as eight bit */
2450 if( img->bitspersample == 16 )
2451 range = (int32) 255;
2452
2453 img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
2454 if (img->Map == NULL) {
2455 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
2456 "No space for photometric conversion table");
2457 return (0);
2458 }
2459 if (img->photometric == PHOTOMETRIC_MINISWHITE) {
2460 for (x = 0; x <= range; x++)
2461 img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
2462 } else {
2463 for (x = 0; x <= range; x++)
2464 img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
2465 }
2466 if (img->bitspersample <= 16 &&
2467 (img->photometric == PHOTOMETRIC_MINISBLACK ||
2468 img->photometric == PHOTOMETRIC_MINISWHITE)) {
2469 /*
2470 * Use photometric mapping table to construct
2471 * unpacking tables for samples <= 8 bits.
2472 */
2473 if (!makebwmap(img))
2474 return (0);
2475 /* no longer need Map, free it */
2476 _TIFFfree(img->Map);
2477 img->Map = NULL;
2478 }
2479 return (1);
2480}
2481
2482static int
2484{
2485 uint16* r = img->redcmap;
2486 uint16* g = img->greencmap;
2487 uint16* b = img->bluecmap;
2488 long n = 1L<<img->bitspersample;
2489
2490 while (n-- > 0)
2491 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
2492 return (16);
2493 return (8);
2494}
2495
2496static void
2498{
2499 uint16* r = img->redcmap;
2500 uint16* g = img->greencmap;
2501 uint16* b = img->bluecmap;
2502 long i;
2503
2504 for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
2505#define CVT(x) ((uint16)((x)>>8))
2506 r[i] = CVT(r[i]);
2507 g[i] = CVT(g[i]);
2508 b[i] = CVT(b[i]);
2509#undef CVT
2510 }
2511}
2512
2513/*
2514 * Palette images with <= 8 bits/sample are handled
2515 * with a table to avoid lots of shifts and masks. The table
2516 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2517 * pixel values simply by indexing into the table with one
2518 * number.
2519 */
2520static int
2522{
2523 int bitspersample = img->bitspersample;
2524 int nsamples = 8 / bitspersample;
2525 uint16* r = img->redcmap;
2526 uint16* g = img->greencmap;
2527 uint16* b = img->bluecmap;
2528 uint32 *p;
2529 int i;
2530
2531 img->PALmap = (uint32**) _TIFFmalloc(
2532 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2533 if (img->PALmap == NULL) {
2534 TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
2535 return (0);
2536 }
2537 p = (uint32*)(img->PALmap + 256);
2538 for (i = 0; i < 256; i++) {
2540 img->PALmap[i] = p;
2541#define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2542 switch (bitspersample) {
2543 case 1:
2544 CMAP(i>>7);
2545 CMAP((i>>6)&1);
2546 CMAP((i>>5)&1);
2547 CMAP((i>>4)&1);
2548 CMAP((i>>3)&1);
2549 CMAP((i>>2)&1);
2550 CMAP((i>>1)&1);
2551 CMAP(i&1);
2552 break;
2553 case 2:
2554 CMAP(i>>6);
2555 CMAP((i>>4)&3);
2556 CMAP((i>>2)&3);
2557 CMAP(i&3);
2558 break;
2559 case 4:
2560 CMAP(i>>4);
2561 CMAP(i&0xf);
2562 break;
2563 case 8:
2564 CMAP(i);
2565 break;
2566 }
2567#undef CMAP
2568 }
2569 return (1);
2570}
2571
2572/*
2573 * Construct any mapping table used
2574 * by the associated put routine.
2575 */
2576static int
2578{
2579 switch (img->photometric) {
2580 case PHOTOMETRIC_RGB:
2581 case PHOTOMETRIC_YCBCR:
2583 if (img->bitspersample == 8)
2584 break;
2585 /* fall through... */
2588 if (!setupMap(img))
2589 return (0);
2590 break;
2592 /*
2593 * Convert 16-bit colormap to 8-bit (unless it looks
2594 * like an old-style 8-bit colormap).
2595 */
2596 if (checkcmap(img) == 16)
2597 cvtcmap(img);
2598 else
2599 TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
2600 /*
2601 * Use mapping table and colormap to construct
2602 * unpacking tables for samples < 8 bits.
2603 */
2604 if (img->bitspersample <= 8 && !makecmap(img))
2605 return (0);
2606 break;
2607 }
2608 return (1);
2609}
2610
2611/*
2612 * Select the appropriate conversion routine for packed data.
2613 */
2614static int
2616{
2617 img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
2618 img->put.contig = NULL;
2619 switch (img->photometric) {
2620 case PHOTOMETRIC_RGB:
2621 switch (img->bitspersample) {
2622 case 8:
2623 if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
2624 img->samplesperpixel >= 4)
2625 img->put.contig = putRGBAAcontig8bittile;
2626 else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
2627 img->samplesperpixel >= 4)
2628 {
2629 if (BuildMapUaToAa(img))
2630 img->put.contig = putRGBUAcontig8bittile;
2631 }
2632 else if( img->samplesperpixel >= 3 )
2633 img->put.contig = putRGBcontig8bittile;
2634 break;
2635 case 16:
2636 if (img->alpha == EXTRASAMPLE_ASSOCALPHA &&
2637 img->samplesperpixel >=4 )
2638 {
2640 img->put.contig = putRGBAAcontig16bittile;
2641 }
2642 else if (img->alpha == EXTRASAMPLE_UNASSALPHA &&
2643 img->samplesperpixel >=4 )
2644 {
2647 img->put.contig = putRGBUAcontig16bittile;
2648 }
2649 else if( img->samplesperpixel >=3 )
2650 {
2652 img->put.contig = putRGBcontig16bittile;
2653 }
2654 break;
2655 }
2656 break;
2658 if (img->samplesperpixel >=4 && buildMap(img)) {
2659 if (img->bitspersample == 8) {
2660 if (!img->Map)
2661 img->put.contig = putRGBcontig8bitCMYKtile;
2662 else
2663 img->put.contig = putRGBcontig8bitCMYKMaptile;
2664 }
2665 }
2666 break;
2668 if (buildMap(img)) {
2669 switch (img->bitspersample) {
2670 case 8:
2671 img->put.contig = put8bitcmaptile;
2672 break;
2673 case 4:
2674 img->put.contig = put4bitcmaptile;
2675 break;
2676 case 2:
2677 img->put.contig = put2bitcmaptile;
2678 break;
2679 case 1:
2680 img->put.contig = put1bitcmaptile;
2681 break;
2682 }
2683 }
2684 break;
2687 if (buildMap(img)) {
2688 switch (img->bitspersample) {
2689 case 16:
2690 img->put.contig = put16bitbwtile;
2691 break;
2692 case 8:
2693 if (img->alpha && img->samplesperpixel == 2)
2694 img->put.contig = putagreytile;
2695 else
2696 img->put.contig = putgreytile;
2697 break;
2698 case 4:
2699 img->put.contig = put4bitbwtile;
2700 break;
2701 case 2:
2702 img->put.contig = put2bitbwtile;
2703 break;
2704 case 1:
2705 img->put.contig = put1bitbwtile;
2706 break;
2707 }
2708 }
2709 break;
2710 case PHOTOMETRIC_YCBCR:
2711 if ((img->bitspersample==8) && (img->samplesperpixel==3))
2712 {
2713 if (initYCbCrConversion(img)!=0)
2714 {
2715 /*
2716 * The 6.0 spec says that subsampling must be
2717 * one of 1, 2, or 4, and that vertical subsampling
2718 * must always be <= horizontal subsampling; so
2719 * there are only a few possibilities and we just
2720 * enumerate the cases.
2721 * Joris: added support for the [1,2] case, nonetheless, to accommodate
2722 * some OJPEG files
2723 */
2724 uint16 SubsamplingHor;
2725 uint16 SubsamplingVer;
2726 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
2727 switch ((SubsamplingHor<<4)|SubsamplingVer) {
2728 case 0x44:
2729 img->put.contig = putcontig8bitYCbCr44tile;
2730 break;
2731 case 0x42:
2732 img->put.contig = putcontig8bitYCbCr42tile;
2733 break;
2734 case 0x41:
2735 img->put.contig = putcontig8bitYCbCr41tile;
2736 break;
2737 case 0x22:
2738 img->put.contig = putcontig8bitYCbCr22tile;
2739 break;
2740 case 0x21:
2741 img->put.contig = putcontig8bitYCbCr21tile;
2742 break;
2743 case 0x12:
2744 img->put.contig = putcontig8bitYCbCr12tile;
2745 break;
2746 case 0x11:
2747 img->put.contig = putcontig8bitYCbCr11tile;
2748 break;
2749 }
2750 }
2751 }
2752 break;
2753 case PHOTOMETRIC_CIELAB:
2754 if (img->samplesperpixel == 3 && buildMap(img)) {
2755 if (img->bitspersample == 8)
2756 img->put.contig = initCIELabConversion(img);
2757 break;
2758 }
2759 }
2760 return ((img->get!=NULL) && (img->put.contig!=NULL));
2761}
2762
2763/*
2764 * Select the appropriate conversion routine for unpacked data.
2765 *
2766 * NB: we assume that unpacked single channel data is directed
2767 * to the "packed routines.
2768 */
2769static int
2771{
2773 img->put.separate = NULL;
2774 switch (img->photometric) {
2777 /* greyscale images processed pretty much as RGB by gtTileSeparate */
2778 case PHOTOMETRIC_RGB:
2779 switch (img->bitspersample) {
2780 case 8:
2781 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2782 img->put.separate = putRGBAAseparate8bittile;
2783 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2784 {
2785 if (BuildMapUaToAa(img))
2786 img->put.separate = putRGBUAseparate8bittile;
2787 }
2788 else
2789 img->put.separate = putRGBseparate8bittile;
2790 break;
2791 case 16:
2792 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2793 {
2795 img->put.separate = putRGBAAseparate16bittile;
2796 }
2797 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2798 {
2801 img->put.separate = putRGBUAseparate16bittile;
2802 }
2803 else
2804 {
2806 img->put.separate = putRGBseparate16bittile;
2807 }
2808 break;
2809 }
2810 break;
2812 if (img->bitspersample == 8 && img->samplesperpixel == 4)
2813 {
2814 img->alpha = 1; // Not alpha, but seems like the only way to get 4th band
2815 img->put.separate = putCMYKseparate8bittile;
2816 }
2817 break;
2818 case PHOTOMETRIC_YCBCR:
2819 if ((img->bitspersample==8) && (img->samplesperpixel==3))
2820 {
2821 if (initYCbCrConversion(img)!=0)
2822 {
2823 uint16 hs, vs;
2825 switch ((hs<<4)|vs) {
2826 case 0x11:
2827 img->put.separate = putseparate8bitYCbCr11tile;
2828 break;
2829 /* TODO: add other cases here */
2830 }
2831 }
2832 }
2833 break;
2834 }
2835 return ((img->get!=NULL) && (img->put.separate!=NULL));
2836}
2837
2838static int
2840{
2841 static const char module[]="BuildMapUaToAa";
2842 uint8* m;
2843 uint16 na,nv;
2844 assert(img->UaToAa==NULL);
2845 img->UaToAa=_TIFFmalloc(65536);
2846 if (img->UaToAa==NULL)
2847 {
2848 TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
2849 return(0);
2850 }
2851 m=img->UaToAa;
2852 for (na=0; na<256; na++)
2853 {
2854 for (nv=0; nv<256; nv++)
2855 *m++=(uint8)((nv*na+127)/255);
2856 }
2857 return(1);
2858}
2859
2860static int
2862{
2863 static const char module[]="BuildMapBitdepth16To8";
2864 uint8* m;
2865 uint32 n;
2866 assert(img->Bitdepth16To8==NULL);
2867 img->Bitdepth16To8=_TIFFmalloc(65536);
2868 if (img->Bitdepth16To8==NULL)
2869 {
2870 TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
2871 return(0);
2872 }
2873 m=img->Bitdepth16To8;
2874 for (n=0; n<65536; n++)
2875 *m++=(uint8)((n+128)/257);
2876 return(1);
2877}
2878
2879
2880/*
2881 * Read a whole strip off data from the file, and convert to RGBA form.
2882 * If this is the last strip, then it will only contain the portion of
2883 * the strip that is actually within the image space. The result is
2884 * organized in bottom to top form.
2885 */
2886
2887
2888int
2890
2891{
2892 return TIFFReadRGBAStripExt(tif, row, raster, 0 );
2893}
2894
2895int
2896TIFFReadRGBAStripExt(TIFF* tif, uint32 row, uint32 * raster, int stop_on_error)
2897
2898{
2899 char emsg[1024] = "";
2901 int ok;
2902 uint32 rowsperstrip, rows_to_read;
2903
2904 if( TIFFIsTiled( tif ) )
2905 {
2907 "Can't use TIFFReadRGBAStrip() with tiled file.");
2908 return (0);
2909 }
2910
2911 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
2912 if( (row % rowsperstrip) != 0 )
2913 {
2915 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2916 return (0);
2917 }
2918
2919 if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
2920
2921 img.row_offset = row;
2922 img.col_offset = 0;
2923
2924 if( row + rowsperstrip > img.height )
2925 rows_to_read = img.height - row;
2926 else
2927 rows_to_read = rowsperstrip;
2928
2929 ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
2930
2932 } else {
2933 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2934 ok = 0;
2935 }
2936
2937 return (ok);
2938}
2939
2940/*
2941 * Read a whole tile off data from the file, and convert to RGBA form.
2942 * The returned RGBA data is organized from bottom to top of tile,
2943 * and may include zeroed areas if the tile extends off the image.
2944 */
2945
2946int
2948
2949{
2950 return TIFFReadRGBATileExt(tif, col, row, raster, 0 );
2951}
2952
2953
2954int
2955TIFFReadRGBATileExt(TIFF* tif, uint32 col, uint32 row, uint32 * raster, int stop_on_error )
2956{
2957 char emsg[1024] = "";
2959 int ok;
2960 uint32 tile_xsize, tile_ysize;
2961 uint32 read_xsize, read_ysize;
2962 uint32 i_row;
2963
2964 /*
2965 * Verify that our request is legal - on a tile file, and on a
2966 * tile boundary.
2967 */
2968
2969 if( !TIFFIsTiled( tif ) )
2970 {
2972 "Can't use TIFFReadRGBATile() with striped file.");
2973 return (0);
2974 }
2975
2976 TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
2977 TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
2978 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
2979 {
2981 "Row/col passed to TIFFReadRGBATile() must be top"
2982 "left corner of a tile.");
2983 return (0);
2984 }
2985
2986 /*
2987 * Setup the RGBA reader.
2988 */
2989
2990 if (!TIFFRGBAImageOK(tif, emsg)
2991 || !TIFFRGBAImageBegin(&img, tif, stop_on_error, emsg)) {
2992 TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2993 return( 0 );
2994 }
2995
2996 /*
2997 * The TIFFRGBAImageGet() function doesn't allow us to get off the
2998 * edge of the image, even to fill an otherwise valid tile. So we
2999 * figure out how much we can read, and fix up the tile buffer to
3000 * a full tile configuration afterwards.
3001 */
3002
3003 if( row + tile_ysize > img.height )
3004 read_ysize = img.height - row;
3005 else
3006 read_ysize = tile_ysize;
3007
3008 if( col + tile_xsize > img.width )
3009 read_xsize = img.width - col;
3010 else
3011 read_xsize = tile_xsize;
3012
3013 /*
3014 * Read the chunk of imagery.
3015 */
3016
3017 img.row_offset = row;
3018 img.col_offset = col;
3019
3020 ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
3021
3023
3024 /*
3025 * If our read was incomplete we will need to fix up the tile by
3026 * shifting the data around as if a full tile of data is being returned.
3027 *
3028 * This is all the more complicated because the image is organized in
3029 * bottom to top format.
3030 */
3031
3032 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
3033 return( ok );
3034
3035 for( i_row = 0; i_row < read_ysize; i_row++ ) {
3036 memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
3037 raster + (read_ysize - i_row - 1) * read_xsize,
3038 read_xsize * sizeof(uint32) );
3039 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
3040 0, sizeof(uint32) * (tile_xsize - read_xsize) );
3041 }
3042
3043 for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
3044 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
3045 0, sizeof(uint32) * tile_xsize );
3046 }
3047
3048 return (ok);
3049}
3050
3051/* vim: set ts=8 sts=8 sw=8 noet: */
3052/*
3053 * Local Variables:
3054 * mode: c
3055 * c-basic-offset: 8
3056 * fill-column: 78
3057 * End:
3058 */
static int bw
Definition: maze.c:120
#define ok(value,...)
Definition: atltest.h:57
unsigned short uint16
Definition: types.h:30
unsigned int uint32
Definition: types.h:32
unsigned char uint8
Definition: types.h:28
#define NULL
Definition: types.h:112
#define Z(I)
#define Y(I)
struct png_info_def *typedef unsigned char **typedef struct png_info_def *typedef struct png_info_def *typedef struct png_info_def *typedef unsigned char ** row
Definition: typeof.h:78
#define assert(x)
Definition: debug.h:53
long int32
Definition: platform.h:12
__kernel_size_t size_t
Definition: linux.h:237
GLint GLvoid * img
Definition: gl.h:1956
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLclampf GLclampf GLclampf alpha
Definition: gl.h:1740
GLint GLint GLint GLint GLint GLint y
Definition: gl.h:1548
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble n
Definition: glext.h:7729
GLdouble GLdouble right
Definition: glext.h:10859
GLfloat f
Definition: glext.h:7540
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
GLenum GLint * range
Definition: glext.h:7539
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLint left
Definition: glext.h:7726
GLboolean GLboolean g
Definition: glext.h:6204
GLfloat GLfloat p
Definition: glext.h:8902
GLenum GLuint GLsizei bufsize
Definition: glext.h:7473
GLboolean GLboolean GLboolean GLboolean a
Definition: glext.h:6204
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
const GLfloat * m
Definition: glext.h:10848
GLfloat GLfloat GLfloat GLfloat h
Definition: glext.h:7723
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define X(b, s)
#define a
Definition: ke_i.h:78
#define c
Definition: ke_i.h:80
#define b
Definition: ke_i.h:79
POINT cp
Definition: magnifier.c:59
#define put(ret, state, sp, n)
Definition: match.c:105
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define sprintf(buf, format,...)
Definition: sprintf.c:55
static const struct update_accum a2
Definition: msg.c:586
static CRYPT_DATA_BLOB b2[]
Definition: msg.c:582
static DNS_RECORDW r2
Definition: record.c:38
static vector_t * vs
Definition: server.c:127
static int ** pa
Definition: server.c:126
static float(__cdecl *square_half_float)(float x
int k
Definition: mpi.c:3369
int xx
Definition: npserver.c:29
static calc_node_t temp
Definition: rpn_ieee.c:38
int ZEXPORT compress(Bytef *dest, uLongf *destLen, const Bytef *source, uLong sourceLen)
Definition: compress.c:68
uint16 td_sampleformat
Definition: tif_dir.h:76
uint16 td_samplesperpixel
Definition: tif_dir.h:82
uint16 td_bitspersample
Definition: tif_dir.h:75
uint16 td_planarconfig
Definition: tif_dir.h:89
uint16 td_compression
Definition: tif_dir.h:77
uint16 td_extrasamples
Definition: tif_dir.h:94
Definition: parser.c:49
Definition: tiffiop.h:115
thandle_t tif_clientdata
Definition: tiffiop.h:207
TIFFDirectory tif_dir
Definition: tiffiop.h:151
int tif_decodestatus
Definition: tiffiop.h:172
int TIFFGetFieldDefaulted(TIFF *tif, uint32 tag,...)
Definition: tif_aux.c:345
tmsize_t _TIFFMultiplySSize(TIFF *tif, tmsize_t first, tmsize_t second, const char *where)
Definition: tif_aux.c:59
void TIFFYCbCrtoRGB(TIFFYCbCrToRGB *ycbcr, uint32 Y, int32 Cb, int32 Cr, uint32 *r, uint32 *g, uint32 *b)
Definition: tif_color.c:181
int TIFFYCbCrToRGBInit(TIFFYCbCrToRGB *ycbcr, float *luma, float *refBlackWhite)
Definition: tif_color.c:234
void TIFFXYZToRGB(TIFFCIELabToRGB *cielab, float X, float Y, float Z, uint32 *r, uint32 *g, uint32 *b)
Definition: tif_color.c:76
int TIFFCIELabToRGBInit(TIFFCIELabToRGB *cielab, const TIFFDisplay *display, float *refWhite)
Definition: tif_color.c:123
void TIFFCIELabToXYZ(TIFFCIELabToRGB *cielab, uint32 l, int32 a, int32 b, float *X, float *Y, float *Z)
Definition: tif_color.c:44
int TIFFSetField(TIFF *tif, uint32 tag,...)
Definition: tif_dir.c:807
int TIFFGetField(TIFF *tif, uint32 tag,...)
Definition: tif_dir.c:1232
void TIFFErrorExt(thandle_t fd, const char *module, const char *fmt,...)
Definition: tif_error.c:65
#define FLIP_VERTICALLY
Definition: tif_getimage.c:48
int TIFFReadRGBATile(TIFF *tif, uint32 col, uint32 row, uint32 *raster)
static int gtTileContig(TIFFRGBAImage *, uint32 *, uint32, uint32)
Definition: tif_getimage.c:620
static int isInRefBlackWhiteRange(float f)
#define SKEW4(r, g, b, a, skew)
static const TIFFDisplay display_sRGB
Definition: tif_getimage.c:55
int TIFFRGBAImageGet(TIFFRGBAImage *img, uint32 *raster, uint32 w, uint32 h)
Definition: tif_getimage.c:500
#define UNROLL8(w, op1, op2)
static int setupMap(TIFFRGBAImage *img)
int TIFFReadRGBAStrip(TIFF *tif, uint32 row, uint32 *raster)
#define GREY(x)
static int setorientation(TIFFRGBAImage *img)
Definition: tif_getimage.c:553
#define YCbCrtoRGB(dst, Y)
static int buildMap(TIFFRGBAImage *img)
static int gtStripContig(TIFFRGBAImage *, uint32 *, uint32, uint32)
Definition: tif_getimage.c:914
static int gtTileSeparate(TIFFRGBAImage *, uint32 *, uint32, uint32)
Definition: tif_getimage.c:733
int TIFFReadRGBAImage(TIFF *tif, uint32 rwidth, uint32 rheight, uint32 *raster, int stop)
Definition: tif_getimage.c:545
#define NOP
int TIFFReadRGBAImageOriented(TIFF *tif, uint32 rwidth, uint32 rheight, uint32 *raster, int orientation, int stop)
Definition: tif_getimage.c:519
static int gtStripSeparate(TIFFRGBAImage *, uint32 *, uint32, uint32)
int TIFFRGBAImageBegin(TIFFRGBAImage *img, TIFF *tif, int stop, char emsg[1024])
Definition: tif_getimage.c:265
#define PACK4(r, g, b, a)
int TIFFReadRGBAStripExt(TIFF *tif, uint32 row, uint32 *raster, int stop_on_error)
#define UNROLL4(w, op1, op2)
static int PickContigCase(TIFFRGBAImage *)
static tileContigRoutine initCIELabConversion(TIFFRGBAImage *img)
#define PACK(r, g, b)
#define DECLAREContigPutFunc(name)
int TIFFReadRGBATileExt(TIFF *tif, uint32 col, uint32 row, uint32 *raster, int stop_on_error)
static int isCCITTCompression(TIFF *tif)
Definition: tif_getimage.c:254
void TIFFRGBAImageEnd(TIFFRGBAImage *img)
Definition: tif_getimage.c:214
#define SKEW(r, g, b, skew)
static int makebwmap(TIFFRGBAImage *img)
static int initYCbCrConversion(TIFFRGBAImage *img)
static int BuildMapUaToAa(TIFFRGBAImage *img)
int TIFFRGBAImageOK(TIFF *tif, char emsg[1024])
Definition: tif_getimage.c:74
static void cvtcmap(TIFFRGBAImage *img)
#define UNROLL2(w, op1, op2)
static int checkcmap(TIFFRGBAImage *img)
#define FLIP_HORIZONTALLY
Definition: tif_getimage.c:49
static int makecmap(TIFFRGBAImage *img)
#define DECLARESepPutFunc(name)
#define CMAP(x)
#define CVT(x)
static int BuildMapBitdepth16To8(TIFFRGBAImage *img)
static int PickSeparateCase(TIFFRGBAImage *)
static const char photoTag[]
Definition: tif_getimage.c:43
const char * TIFFFileName(TIFF *tif)
Definition: tif_open.c:513
int TIFFIsTiled(TIFF *tif)
Definition: tif_open.c:594
tmsize_t _TIFFReadEncodedStripAndAllocBuffer(TIFF *tif, uint32 strip, void **buf, tmsize_t bufsizetoalloc, tmsize_t size_to_read)
Definition: tif_read.c:572
tmsize_t TIFFReadTile(TIFF *tif, void *buf, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_read.c:965
tmsize_t TIFFReadEncodedStrip(TIFF *tif, uint32 strip, void *buf, tmsize_t size)
Definition: tif_read.c:527
tmsize_t _TIFFReadTileAndAllocBuffer(TIFF *tif, void **buf, tmsize_t bufsizetoalloc, uint32 x, uint32 y, uint32 z, uint16 s)
Definition: tif_read.c:1029
uint32 TIFFComputeStrip(TIFF *tif, uint32 row, uint16 sample)
Definition: tif_strip.c:36
tmsize_t TIFFStripSize(TIFF *tif)
Definition: tif_strip.c:202
tmsize_t TIFFScanlineSize(TIFF *tif)
Definition: tif_strip.c:314
tmsize_t TIFFTileSize(TIFF *tif)
Definition: tif_tile.c:257
tmsize_t TIFFTileRowSize(TIFF *tif)
Definition: tif_tile.c:180
void _TIFFfree(void *p)
Definition: tif_unix.c:326
void _TIFFmemset(void *p, int v, tmsize_t c)
Definition: tif_unix.c:338
void * _TIFFmalloc(tmsize_t s)
Definition: tif_unix.c:309
void _TIFFmemcpy(void *d, const void *s, tmsize_t c)
Definition: tif_unix.c:344
void TIFFWarningExt(thandle_t fd, const char *module, const char *fmt,...)
Definition: tif_warning.c:65
#define TIFFTAG_BITSPERSAMPLE
Definition: tiff.h:156
#define ORIENTATION_BOTRIGHT
Definition: tiff.h:225
#define PLANARCONFIG_SEPARATE
Definition: tiff.h:240
#define ORIENTATION_LEFTTOP
Definition: tiff.h:227
#define ORIENTATION_BOTLEFT
Definition: tiff.h:226
#define TIFFTAG_WHITEPOINT
Definition: tiff.h:281
#define EXTRASAMPLE_UNASSALPHA
Definition: tiff.h:306
#define COMPRESSION_CCITTFAX3
Definition: tiff.h:160
#define COMPRESSION_CCITTRLE
Definition: tiff.h:159
#define EXTRASAMPLE_ASSOCALPHA
Definition: tiff.h:305
#define ORIENTATION_TOPLEFT
Definition: tiff.h:223
#define ORIENTATION_RIGHTBOT
Definition: tiff.h:229
#define ORIENTATION_RIGHTTOP
Definition: tiff.h:228
#define TIFFTAG_SAMPLESPERPIXEL
Definition: tiff.h:231
#define PHOTOMETRIC_LOGL
Definition: tiff.h:206
#define TIFFTAG_INKSET
Definition: tiff.h:296
#define COMPRESSION_SGILOG
Definition: tiff.h:186
#define COMPRESSION_CCITTRLEW
Definition: tiff.h:170
#define TIFFTAG_COLORMAP
Definition: tiff.h:283
#define PHOTOMETRIC_CIELAB
Definition: tiff.h:202
#define EXTRASAMPLE_UNSPECIFIED
Definition: tiff.h:304
#define TIFFTAG_PHOTOMETRIC
Definition: tiff.h:194
#define TIFFTAG_TILELENGTH
Definition: tiff.h:286
#define PHOTOMETRIC_PALETTE
Definition: tiff.h:198
#define TIFFTAG_EXTRASAMPLES
Definition: tiff.h:303
#define TIFFTAG_IMAGEWIDTH
Definition: tiff.h:154
#define PHOTOMETRIC_SEPARATED
Definition: tiff.h:200
#define TIFFTAG_YCBCRCOEFFICIENTS
Definition: tiff.h:361
#define TIFFTAG_ORIENTATION
Definition: tiff.h:222
#define PHOTOMETRIC_LOGLUV
Definition: tiff.h:207
#define SAMPLEFORMAT_IEEEFP
Definition: tiff.h:310
#define PHOTOMETRIC_YCBCR
Definition: tiff.h:201
#define SGILOGDATAFMT_8BIT
Definition: tiff.h:561
#define ORIENTATION_TOPRIGHT
Definition: tiff.h:224
#define INKSET_CMYK
Definition: tiff.h:297
#define PHOTOMETRIC_MINISWHITE
Definition: tiff.h:195
#define TIFFTAG_YCBCRSUBSAMPLING
Definition: tiff.h:362
#define TIFFTAG_SGILOGDATAFMT
Definition: tiff.h:557
#define TIFFTAG_ROWSPERSTRIP
Definition: tiff.h:232
#define ORIENTATION_LEFTBOT
Definition: tiff.h:230
#define COMPRESSION_SGILOG24
Definition: tiff.h:187
#define TIFFTAG_REFERENCEBLACKWHITE
Definition: tiff.h:366
#define TIFFTAG_TILEWIDTH
Definition: tiff.h:285
#define TIFFTAG_IMAGELENGTH
Definition: tiff.h:155
#define TIFFTAG_COMPRESSION
Definition: tiff.h:157
#define PHOTOMETRIC_MINISBLACK
Definition: tiff.h:196
#define PHOTOMETRIC_RGB
Definition: tiff.h:197
#define TIFFTAG_PLANARCONFIG
Definition: tiff.h:238
#define COMPRESSION_CCITTFAX4
Definition: tiff.h:162
#define TIFFTAG_JPEGCOLORMODE
Definition: tiff.h:520
#define JPEGCOLORMODE_RGB
Definition: tiff.h:522
#define COMPRESSION_JPEG
Definition: tiff.h:166
#define PLANARCONFIG_CONTIG
Definition: tiff.h:239
void(* tileSeparateRoutine)(TIFFRGBAImage *, uint32 *, uint32, uint32, uint32, uint32, int32, int32, unsigned char *, unsigned char *, unsigned char *, unsigned char *)
Definition: tiffio.h:192
TIFF_SSIZE_T tmsize_t
Definition: tiffio.h:65
unsigned char TIFFRGBValue
Definition: tiffio.h:136
void(* tileContigRoutine)(TIFFRGBAImage *, uint32 *, uint32, uint32, uint32, uint32, int32, int32, unsigned char *)
Definition: tiffio.h:189
#define TIFF_TMSIZE_T_MAX
Definition: tiffiop.h:81
#define TIFFroundup_32(x, y)
Definition: tiffiop.h:272
int ret