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