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