source: liacs/MIR2010/SourceCode/cximage/tiff/tif_getimage.c@ 375

Last change on this file since 375 was 95, checked in by Rick van der Zwet, 15 years ago

Bad boy, improper move of directory

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