]> git.saurik.com Git - wxWidgets.git/blame - src/tiff/tif_getimage.c
fixed text control creation broken by my MacPreControlCreate() change
[wxWidgets.git] / src / tiff / tif_getimage.c
CommitLineData
b47c832e
RR
1/* $Header$ */
2
3/*
4 * Copyright (c) 1991-1997 Sam Leffler
5 * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6 *
615a9936 7 * Permission to use, copy, modify, distribute, and sell this software and
b47c832e
RR
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.
615a9936
DW
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 *
b47c832e
RR
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,
615a9936
DW
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
b47c832e
RR
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 <assert.h>
34#include <stdio.h>
35
615a9936
DW
36static int LINKAGEMODE gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
37static int LINKAGEMODE gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
38static int LINKAGEMODE gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
39static int LINKAGEMODE gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
40static int LINKAGEMODE pickTileContigCase(TIFFRGBAImage*);
41static int LINKAGEMODE pickTileSeparateCase(TIFFRGBAImage*);
b47c832e
RR
42
43static const char photoTag[] = "PhotometricInterpretation";
44
45/*
46 * Check the image to see if TIFFReadRGBAImage can deal with it.
47 * 1/0 is returned according to whether or not the image can
48 * be handled. If 0 is returned, emsg contains the reason
49 * why it is being rejected.
50 */
51int
52TIFFRGBAImageOK(TIFF* tif, char emsg[1024])
53{
54 TIFFDirectory* td = &tif->tif_dir;
55 uint16 photometric;
56 int colorchannels;
57
58 switch (td->td_bitspersample) {
59 case 1: case 2: case 4:
60 case 8: case 16:
61 break;
62 default:
63 sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
64 td->td_bitspersample);
65 return (0);
66 }
67 colorchannels = td->td_samplesperpixel - td->td_extrasamples;
68 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
69 switch (colorchannels) {
70 case 1:
71 photometric = PHOTOMETRIC_MINISBLACK;
72 break;
73 case 3:
74 photometric = PHOTOMETRIC_RGB;
75 break;
76 default:
77 sprintf(emsg, "Missing needed %s tag", photoTag);
78 return (0);
79 }
80 }
81 switch (photometric) {
82 case PHOTOMETRIC_MINISWHITE:
83 case PHOTOMETRIC_MINISBLACK:
84 case PHOTOMETRIC_PALETTE:
85 if (td->td_planarconfig == PLANARCONFIG_CONTIG && td->td_samplesperpixel != 1) {
86 sprintf(emsg,
87 "Sorry, can not handle contiguous data with %s=%d, and %s=%d",
88 photoTag, photometric,
89 "Samples/pixel", td->td_samplesperpixel);
90 return (0);
91 }
92 break;
93 case PHOTOMETRIC_YCBCR:
94 if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
95 sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
96 "Planarconfiguration", td->td_planarconfig);
97 return (0);
98 }
99 break;
615a9936 100 case PHOTOMETRIC_RGB:
b47c832e
RR
101 if (colorchannels < 3) {
102 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
103 "Color channels", colorchannels);
104 return (0);
105 }
106 break;
107#ifdef CMYK_SUPPORT
108 case PHOTOMETRIC_SEPARATED:
109 if (td->td_inkset != INKSET_CMYK) {
110 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
111 "InkSet", td->td_inkset);
112 return (0);
113 }
114 if (td->td_samplesperpixel != 4) {
115 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
116 "Samples/pixel", td->td_samplesperpixel);
117 return (0);
118 }
119 break;
120#endif
121 case PHOTOMETRIC_LOGL:
122 if (td->td_compression != COMPRESSION_SGILOG) {
123 sprintf(emsg, "Sorry, LogL data must have %s=%d",
124 "Compression", COMPRESSION_SGILOG);
125 return (0);
126 }
127 break;
128 case PHOTOMETRIC_LOGLUV:
129 if (td->td_compression != COMPRESSION_SGILOG &&
130 td->td_compression != COMPRESSION_SGILOG24) {
131 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
132 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
133 return (0);
134 }
135 if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
136 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
137 "Planarconfiguration", td->td_planarconfig);
138 return (0);
139 }
140 break;
141 default:
142 sprintf(emsg, "Sorry, can not handle image with %s=%d",
143 photoTag, photometric);
144 return (0);
145 }
146 return (1);
147}
148
149void
150TIFFRGBAImageEnd(TIFFRGBAImage* img)
151{
152 if (img->Map)
153 _TIFFfree(img->Map), img->Map = NULL;
154 if (img->BWmap)
155 _TIFFfree(img->BWmap), img->BWmap = NULL;
156 if (img->PALmap)
157 _TIFFfree(img->PALmap), img->PALmap = NULL;
158 if (img->ycbcr)
159 _TIFFfree(img->ycbcr), img->ycbcr = NULL;
160
161 if( img->redcmap ) {
162 _TIFFfree( img->redcmap );
163 _TIFFfree( img->greencmap );
164 _TIFFfree( img->bluecmap );
165 }
166}
167
168static int
169isCCITTCompression(TIFF* tif)
170{
171 uint16 compress;
172 TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
173 return (compress == COMPRESSION_CCITTFAX3 ||
174 compress == COMPRESSION_CCITTFAX4 ||
175 compress == COMPRESSION_CCITTRLE ||
176 compress == COMPRESSION_CCITTRLEW);
177}
178
179int
180TIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
181{
182 uint16* sampleinfo;
183 uint16 extrasamples;
184 uint16 planarconfig;
185 uint16 compress;
186 int colorchannels;
187 uint16 *red_orig, *green_orig, *blue_orig;
188 int n_color;
189
190 /* Initialize to normal values */
191 img->row_offset = 0;
192 img->col_offset = 0;
193 img->redcmap = NULL;
194 img->greencmap = NULL;
195 img->bluecmap = NULL;
615a9936 196
b47c832e
RR
197 img->tif = tif;
198 img->stoponerr = stop;
199 TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
200 switch (img->bitspersample) {
201 case 1: case 2: case 4:
202 case 8: case 16:
203 break;
204 default:
205 sprintf(emsg, "Sorry, can not image with %d-bit samples",
206 img->bitspersample);
207 return (0);
208 }
209 img->alpha = 0;
210 TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
211 TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
212 &extrasamples, &sampleinfo);
213 if (extrasamples == 1)
214 switch (sampleinfo[0]) {
215 case EXTRASAMPLE_ASSOCALPHA: /* data is pre-multiplied */
216 case EXTRASAMPLE_UNASSALPHA: /* data is not pre-multiplied */
217 img->alpha = sampleinfo[0];
218 break;
219 }
220 colorchannels = img->samplesperpixel - extrasamples;
221 TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
222 TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
223 if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
224 switch (colorchannels) {
225 case 1:
226 if (isCCITTCompression(tif))
227 img->photometric = PHOTOMETRIC_MINISWHITE;
228 else
229 img->photometric = PHOTOMETRIC_MINISBLACK;
230 break;
231 case 3:
232 img->photometric = PHOTOMETRIC_RGB;
233 break;
234 default:
235 sprintf(emsg, "Missing needed %s tag", photoTag);
236 return (0);
237 }
238 }
239 switch (img->photometric) {
240 case PHOTOMETRIC_PALETTE:
241 if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
242 &red_orig, &green_orig, &blue_orig)) {
243 TIFFError(TIFFFileName(tif), "Missing required \"Colormap\" tag");
244 return (0);
245 }
246
247 /* copy the colormaps so we can modify them */
248 n_color = (1L << img->bitspersample);
249 img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
250 img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
251 img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
252 if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
253 TIFFError(TIFFFileName(tif), "Out of memory for colormap copy");
254 return (0);
255 }
256
257 memcpy( img->redcmap, red_orig, n_color * 2 );
258 memcpy( img->greencmap, green_orig, n_color * 2 );
259 memcpy( img->bluecmap, blue_orig, n_color * 2 );
615a9936 260
b47c832e
RR
261 /* fall thru... */
262 case PHOTOMETRIC_MINISWHITE:
263 case PHOTOMETRIC_MINISBLACK:
264 if (planarconfig == PLANARCONFIG_CONTIG && img->samplesperpixel != 1) {
265 sprintf(emsg,
266 "Sorry, can not handle contiguous data with %s=%d, and %s=%d",
267 photoTag, img->photometric,
268 "Samples/pixel", img->samplesperpixel);
269 return (0);
270 }
271 break;
272 case PHOTOMETRIC_YCBCR:
273 if (planarconfig != PLANARCONFIG_CONTIG) {
274 sprintf(emsg, "Sorry, can not handle YCbCr images with %s=%d",
275 "Planarconfiguration", planarconfig);
276 return (0);
277 }
278 /* It would probably be nice to have a reality check here. */
279 if (compress == COMPRESSION_JPEG && planarconfig == PLANARCONFIG_CONTIG) {
280 /* can rely on libjpeg to convert to RGB */
281 /* XXX should restore current state on exit */
282 TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
283 img->photometric = PHOTOMETRIC_RGB;
284 }
285 break;
615a9936 286 case PHOTOMETRIC_RGB:
b47c832e
RR
287 if (colorchannels < 3) {
288 sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
289 "Color channels", colorchannels);
290 return (0);
291 }
292 break;
293 case PHOTOMETRIC_SEPARATED: {
294 uint16 inkset;
295 TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
296 if (inkset != INKSET_CMYK) {
297 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
298 "InkSet", inkset);
299 return (0);
300 }
301 if (img->samplesperpixel != 4) {
302 sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
303 "Samples/pixel", img->samplesperpixel);
304 return (0);
305 }
306 break;
307 }
308 case PHOTOMETRIC_LOGL:
309 if (compress != COMPRESSION_SGILOG) {
310 sprintf(emsg, "Sorry, LogL data must have %s=%d",
311 "Compression", COMPRESSION_SGILOG);
312 return (0);
313 }
314 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
315 img->photometric = PHOTOMETRIC_MINISBLACK; /* little white lie */
316 img->bitspersample = 8;
317 break;
318 case PHOTOMETRIC_LOGLUV:
319 if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
320 sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
321 "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
322 return (0);
323 }
324 if (planarconfig != PLANARCONFIG_CONTIG) {
325 sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
326 "Planarconfiguration", planarconfig);
327 return (0);
328 }
329 TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
330 img->photometric = PHOTOMETRIC_RGB; /* little white lie */
331 img->bitspersample = 8;
332 break;
333 default:
334 sprintf(emsg, "Sorry, can not handle image with %s=%d",
335 photoTag, img->photometric);
336 return (0);
337 }
338 img->Map = NULL;
339 img->BWmap = NULL;
340 img->PALmap = NULL;
341 img->ycbcr = NULL;
342 TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
343 TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
344 TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
345 img->isContig =
346 !(planarconfig == PLANARCONFIG_SEPARATE && colorchannels > 1);
347 if (img->isContig) {
348 img->get = TIFFIsTiled(tif) ? gtTileContig : gtStripContig;
349 (void) pickTileContigCase(img);
350 } else {
351 img->get = TIFFIsTiled(tif) ? gtTileSeparate : gtStripSeparate;
352 (void) pickTileSeparateCase(img);
353 }
354 return (1);
355}
356
357int
358TIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
359{
360 if (img->get == NULL) {
361 TIFFError(TIFFFileName(img->tif), "No \"get\" routine setup");
362 return (0);
363 }
364 if (img->put.any == NULL) {
365 TIFFError(TIFFFileName(img->tif),
366 "No \"put\" routine setupl; probably can not handle image format");
367 return (0);
368 }
369 return (*img->get)(img, raster, w, h);
370}
371
372/*
373 * Read the specified image into an ABGR-format raster.
374 */
375int
376TIFFReadRGBAImage(TIFF* tif,
377 uint32 rwidth, uint32 rheight, uint32* raster, int stop)
378{
379 char emsg[1024];
380 TIFFRGBAImage img;
381 int ok;
382
383 if (TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
384 /* XXX verify rwidth and rheight against width and height */
385 ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
386 rwidth, img.height);
387 TIFFRGBAImageEnd(&img);
388 } else {
389 TIFFError(TIFFFileName(tif), emsg);
390 ok = 0;
391 }
392 return (ok);
393}
394
395static uint32
396setorientation(TIFFRGBAImage* img, uint32 h)
397{
398 TIFF* tif = img->tif;
399 uint32 y;
400
401 switch (img->orientation) {
402 case ORIENTATION_BOTRIGHT:
403 case ORIENTATION_RIGHTBOT: /* XXX */
404 case ORIENTATION_LEFTBOT: /* XXX */
405 TIFFWarning(TIFFFileName(tif), "using bottom-left orientation");
406 img->orientation = ORIENTATION_BOTLEFT;
407 /* fall thru... */
408 case ORIENTATION_BOTLEFT:
409 y = 0;
410 break;
411 case ORIENTATION_TOPRIGHT:
412 case ORIENTATION_RIGHTTOP: /* XXX */
413 case ORIENTATION_LEFTTOP: /* XXX */
414 default:
415 TIFFWarning(TIFFFileName(tif), "using top-left orientation");
416 img->orientation = ORIENTATION_TOPLEFT;
417 /* fall thru... */
418 case ORIENTATION_TOPLEFT:
419 y = h-1;
420 break;
421 }
422 return (y);
423}
424
425/*
426 * Get an tile-organized image that has
427 * PlanarConfiguration contiguous if SamplesPerPixel > 1
428 * or
429 * SamplesPerPixel == 1
430 */
431static int
432gtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
433{
434 TIFF* tif = img->tif;
435 tileContigRoutine put = img->put.contig;
436 uint16 orientation;
437 uint32 col, row, y;
438 uint32 tw, th;
439 u_char* buf;
440 int32 fromskew, toskew;
441 uint32 nrow;
442
443 buf = (u_char*) _TIFFmalloc(TIFFTileSize(tif));
444 if (buf == 0) {
445 TIFFError(TIFFFileName(tif), "No space for tile buffer");
446 return (0);
447 }
448 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
449 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
450 y = setorientation(img, h);
451 orientation = img->orientation;
452 toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? tw+w : tw-w);
453 for (row = 0; row < h; row += th) {
454 nrow = (row + th > h ? h - row : th);
455 for (col = 0; col < w; col += tw) {
456 if (TIFFReadTile(tif, buf, col+img->col_offset,
457 row+img->row_offset, 0, 0) < 0 && img->stoponerr)
458 break;
459 if (col + tw > w) {
460 /*
461 * Tile is clipped horizontally. Calculate
462 * visible portion and skewing factors.
463 */
464 uint32 npix = w - col;
465 fromskew = tw - npix;
466 (*put)(img, raster+y*w+col, col, y,
467 npix, nrow, fromskew, toskew + fromskew, buf);
468 } else {
469 (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf);
470 }
471 }
472 y += (orientation == ORIENTATION_TOPLEFT ?
473 -(int32) nrow : (int32) nrow);
474 }
475 _TIFFfree(buf);
476 return (1);
477}
478
479/*
480 * Get an tile-organized image that has
481 * SamplesPerPixel > 1
482 * PlanarConfiguration separated
483 * We assume that all such images are RGB.
484 */
485static int
486gtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
487{
488 TIFF* tif = img->tif;
489 tileSeparateRoutine put = img->put.separate;
490 uint16 orientation;
491 uint32 col, row, y;
492 uint32 tw, th;
493 u_char* buf;
494 u_char* r;
495 u_char* g;
496 u_char* b;
497 u_char* a;
498 tsize_t tilesize;
499 int32 fromskew, toskew;
500 int alpha = img->alpha;
501 uint32 nrow;
502
503 tilesize = TIFFTileSize(tif);
504 buf = (u_char*) _TIFFmalloc(4*tilesize);
505 if (buf == 0) {
506 TIFFError(TIFFFileName(tif), "No space for tile buffer");
507 return (0);
508 }
509 r = buf;
510 g = r + tilesize;
511 b = g + tilesize;
512 a = b + tilesize;
513 if (!alpha)
514 memset(a, 0xff, tilesize);
515 TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
516 TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
517 y = setorientation(img, h);
518 orientation = img->orientation;
519 toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? tw+w : tw-w);
520 for (row = 0; row < h; row += th) {
521 nrow = (row + th > h ? h - row : th);
522 for (col = 0; col < w; col += tw) {
523 if (TIFFReadTile(tif, r, col+img->col_offset,
524 row+img->row_offset,0,0) < 0 && img->stoponerr)
525 break;
526 if (TIFFReadTile(tif, g, col+img->col_offset,
527 row+img->row_offset,0,1) < 0 && img->stoponerr)
528 break;
529 if (TIFFReadTile(tif, b, col+img->col_offset,
530 row+img->row_offset,0,2) < 0 && img->stoponerr)
531 break;
532 if (alpha && TIFFReadTile(tif,a,col+img->col_offset,
533 row+img->row_offset,0,3) < 0 && img->stoponerr)
534 break;
535 if (col + tw > w) {
536 /*
537 * Tile is clipped horizontally. Calculate
538 * visible portion and skewing factors.
539 */
540 uint32 npix = w - col;
541 fromskew = tw - npix;
542 (*put)(img, raster+y*w+col, col, y,
543 npix, nrow, fromskew, toskew + fromskew, r, g, b, a);
544 } else {
545 (*put)(img, raster+y*w+col, col, y,
546 tw, nrow, 0, toskew, r, g, b, a);
547 }
548 }
549 y += (orientation == ORIENTATION_TOPLEFT ?
550 -(int32) nrow : (int32) nrow);
551 }
552 _TIFFfree(buf);
553 return (1);
554}
555
556/*
557 * Get a strip-organized image that has
558 * PlanarConfiguration contiguous if SamplesPerPixel > 1
559 * or
560 * SamplesPerPixel == 1
561 */
562static int
563gtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
564{
565 TIFF* tif = img->tif;
566 tileContigRoutine put = img->put.contig;
567 uint16 orientation;
568 uint32 row, y, nrow;
569 u_char* buf;
570 uint32 rowsperstrip;
571 uint32 imagewidth = img->width;
572 tsize_t scanline;
573 int32 fromskew, toskew;
574
575 buf = (u_char*) _TIFFmalloc(TIFFStripSize(tif));
576 if (buf == 0) {
577 TIFFError(TIFFFileName(tif), "No space for strip buffer");
578 return (0);
579 }
580 y = setorientation(img, h);
581 orientation = img->orientation;
582 toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? w+w : w-w);
583 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
584 scanline = TIFFScanlineSize(tif);
585 fromskew = (w < imagewidth ? imagewidth - w : 0);
586 for (row = 0; row < h; row += rowsperstrip) {
587 nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
588 if (TIFFReadEncodedStrip(tif,
589 TIFFComputeStrip(tif,row+img->row_offset, 0),
590 buf, nrow*scanline) < 0
591 && img->stoponerr)
592 break;
593 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf);
594 y += (orientation == ORIENTATION_TOPLEFT ?
595 -(int32) nrow : (int32) nrow);
596 }
597 _TIFFfree(buf);
598 return (1);
599}
600
601/*
602 * Get a strip-organized image with
603 * SamplesPerPixel > 1
604 * PlanarConfiguration separated
605 * We assume that all such images are RGB.
606 */
607static int
608gtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
609{
610 TIFF* tif = img->tif;
611 tileSeparateRoutine put = img->put.separate;
612 uint16 orientation;
613 u_char *buf;
614 u_char *r, *g, *b, *a;
615 uint32 row, y, nrow;
616 tsize_t scanline;
617 uint32 rowsperstrip, offset_row;
618 uint32 imagewidth = img->width;
619 tsize_t stripsize;
620 int32 fromskew, toskew;
621 int alpha = img->alpha;
622
623 stripsize = TIFFStripSize(tif);
624 r = buf = (u_char *)_TIFFmalloc(4*stripsize);
625 if (buf == 0) {
626 TIFFError(TIFFFileName(tif), "No space for tile buffer");
627 return (0);
628 }
629 g = r + stripsize;
630 b = g + stripsize;
631 a = b + stripsize;
632 if (!alpha)
633 memset(a, 0xff, stripsize);
634 y = setorientation(img, h);
635 orientation = img->orientation;
636 toskew = -(int32) (orientation == ORIENTATION_TOPLEFT ? w+w : w-w);
637 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
638 scanline = TIFFScanlineSize(tif);
639 fromskew = (w < imagewidth ? imagewidth - w : 0);
640 for (row = 0; row < h; row += rowsperstrip) {
641 nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
642 offset_row = row + img->row_offset;
643 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
644 r, nrow*scanline) < 0 && img->stoponerr)
645 break;
646 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
647 g, nrow*scanline) < 0 && img->stoponerr)
648 break;
649 if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
650 b, nrow*scanline) < 0 && img->stoponerr)
651 break;
652 if (alpha &&
653 (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 3),
654 a, nrow*scanline) < 0 && img->stoponerr))
655 break;
656 (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, r, g, b, a);
657 y += (orientation == ORIENTATION_TOPLEFT ?
658 -(int32) nrow : (int32) nrow);
659 }
660 _TIFFfree(buf);
661 return (1);
662}
663
664/*
665 * The following routines move decoded data returned
666 * from the TIFF library into rasters filled with packed
667 * ABGR pixels (i.e. suitable for passing to lrecwrite.)
668 *
669 * The routines have been created according to the most
670 * important cases and optimized. pickTileContigCase and
671 * pickTileSeparateCase analyze the parameters and select
672 * the appropriate "put" routine to use.
673 */
674#define REPEAT8(op) REPEAT4(op); REPEAT4(op)
675#define REPEAT4(op) REPEAT2(op); REPEAT2(op)
676#define REPEAT2(op) op; op
677#define CASE8(x,op) \
678 switch (x) { \
679 case 7: op; case 6: op; case 5: op; \
680 case 4: op; case 3: op; case 2: op; \
681 case 1: op; \
682 }
683#define CASE4(x,op) switch (x) { case 3: op; case 2: op; case 1: op; }
684#define NOP
685
686#define UNROLL8(w, op1, op2) { \
687 uint32 _x; \
688 for (_x = w; _x >= 8; _x -= 8) { \
689 op1; \
690 REPEAT8(op2); \
691 } \
692 if (_x > 0) { \
693 op1; \
694 CASE8(_x,op2); \
695 } \
696}
697#define UNROLL4(w, op1, op2) { \
698 uint32 _x; \
699 for (_x = w; _x >= 4; _x -= 4) { \
700 op1; \
701 REPEAT4(op2); \
702 } \
703 if (_x > 0) { \
704 op1; \
705 CASE4(_x,op2); \
706 } \
707}
708#define UNROLL2(w, op1, op2) { \
709 uint32 _x; \
710 for (_x = w; _x >= 2; _x -= 2) { \
711 op1; \
712 REPEAT2(op2); \
713 } \
714 if (_x) { \
715 op1; \
716 op2; \
717 } \
718}
615a9936 719
b47c832e
RR
720#define SKEW(r,g,b,skew) { r += skew; g += skew; b += skew; }
721#define SKEW4(r,g,b,a,skew) { r += skew; g += skew; b += skew; a+= skew; }
722
723#define A1 ((uint32)(0xffL<<24))
724#define PACK(r,g,b) \
725 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
726#define PACK4(r,g,b,a) \
727 ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
728#define W2B(v) (((v)>>8)&0xff)
729#define PACKW(r,g,b) \
730 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
731#define PACKW4(r,g,b,a) \
732 ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
733
734#define DECLAREContigPutFunc(name) \
615a9936 735static void LINKAGEMODE name(\
b47c832e
RR
736 TIFFRGBAImage* img, \
737 uint32* cp, \
738 uint32 x, uint32 y, \
739 uint32 w, uint32 h, \
740 int32 fromskew, int32 toskew, \
741 u_char* pp \
742)
743
744/*
745 * 8-bit palette => colormap/RGB
746 */
747DECLAREContigPutFunc(put8bitcmaptile)
748{
749 uint32** PALmap = img->PALmap;
750
751 (void) x; (void) y;
752 while (h-- > 0) {
753 UNROLL8(w, NOP, *cp++ = PALmap[*pp++][0]);
754 cp += toskew;
755 pp += fromskew;
756 }
757}
758
759/*
760 * 4-bit palette => colormap/RGB
761 */
762DECLAREContigPutFunc(put4bitcmaptile)
763{
764 uint32** PALmap = img->PALmap;
765
766 (void) x; (void) y;
767 fromskew /= 2;
768 while (h-- > 0) {
769 uint32* bw;
770 UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
771 cp += toskew;
772 pp += fromskew;
773 }
774}
775
776/*
777 * 2-bit palette => colormap/RGB
778 */
779DECLAREContigPutFunc(put2bitcmaptile)
780{
781 uint32** PALmap = img->PALmap;
782
783 (void) x; (void) y;
784 fromskew /= 4;
785 while (h-- > 0) {
786 uint32* bw;
787 UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
788 cp += toskew;
789 pp += fromskew;
790 }
791}
792
793/*
794 * 1-bit palette => colormap/RGB
795 */
796DECLAREContigPutFunc(put1bitcmaptile)
797{
798 uint32** PALmap = img->PALmap;
799
800 (void) x; (void) y;
801 fromskew /= 8;
802 while (h-- > 0) {
803 uint32* bw;
804 UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
805 cp += toskew;
806 pp += fromskew;
807 }
808}
809
810/*
811 * 8-bit greyscale => colormap/RGB
812 */
813DECLAREContigPutFunc(putgreytile)
814{
815 uint32** BWmap = img->BWmap;
816
817 (void) y;
818 while (h-- > 0) {
819 for (x = w; x-- > 0;)
820 *cp++ = BWmap[*pp++][0];
821 cp += toskew;
822 pp += fromskew;
823 }
824}
825
826/*
827 * 1-bit bilevel => colormap/RGB
828 */
829DECLAREContigPutFunc(put1bitbwtile)
830{
831 uint32** BWmap = img->BWmap;
832
833 (void) x; (void) y;
834 fromskew /= 8;
835 while (h-- > 0) {
836 uint32* bw;
837 UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
838 cp += toskew;
839 pp += fromskew;
840 }
841}
842
843/*
844 * 2-bit greyscale => colormap/RGB
845 */
846DECLAREContigPutFunc(put2bitbwtile)
847{
848 uint32** BWmap = img->BWmap;
849
850 (void) x; (void) y;
851 fromskew /= 4;
852 while (h-- > 0) {
853 uint32* bw;
854 UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
855 cp += toskew;
856 pp += fromskew;
857 }
858}
859
860/*
861 * 4-bit greyscale => colormap/RGB
862 */
863DECLAREContigPutFunc(put4bitbwtile)
864{
865 uint32** BWmap = img->BWmap;
866
867 (void) x; (void) y;
868 fromskew /= 2;
869 while (h-- > 0) {
870 uint32* bw;
871 UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
872 cp += toskew;
873 pp += fromskew;
874 }
875}
876
877/*
878 * 8-bit packed samples, no Map => RGB
879 */
880DECLAREContigPutFunc(putRGBcontig8bittile)
881{
882 int samplesperpixel = img->samplesperpixel;
883
884 (void) x; (void) y;
885 fromskew *= samplesperpixel;
886 while (h-- > 0) {
887 UNROLL8(w, NOP,
888 *cp++ = PACK(pp[0], pp[1], pp[2]);
889 pp += samplesperpixel);
890 cp += toskew;
891 pp += fromskew;
892 }
893}
894
895/*
896 * 8-bit packed samples, w/ Map => RGB
897 */
898DECLAREContigPutFunc(putRGBcontig8bitMaptile)
899{
900 TIFFRGBValue* Map = img->Map;
901 int samplesperpixel = img->samplesperpixel;
902
903 (void) y;
904 fromskew *= samplesperpixel;
905 while (h-- > 0) {
906 for (x = w; x-- > 0;) {
907 *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
908 pp += samplesperpixel;
909 }
910 pp += fromskew;
911 cp += toskew;
912 }
913}
914
915/*
916 * 8-bit packed samples => RGBA w/ associated alpha
917 * (known to have Map == NULL)
918 */
919DECLAREContigPutFunc(putRGBAAcontig8bittile)
920{
921 int samplesperpixel = img->samplesperpixel;
922
923 (void) x; (void) y;
924 fromskew *= samplesperpixel;
925 while (h-- > 0) {
926 UNROLL8(w, NOP,
927 *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
928 pp += samplesperpixel);
929 cp += toskew;
930 pp += fromskew;
931 }
932}
933
934/*
935 * 8-bit packed samples => RGBA w/ unassociated alpha
936 * (known to have Map == NULL)
937 */
938DECLAREContigPutFunc(putRGBUAcontig8bittile)
939{
940 int samplesperpixel = img->samplesperpixel;
941
942 (void) y;
943 fromskew *= samplesperpixel;
944 while (h-- > 0) {
945 uint32 r, g, b, a;
946 for (x = w; x-- > 0;) {
947 a = pp[3];
948 r = (pp[0] * a) / 255;
949 g = (pp[1] * a) / 255;
950 b = (pp[2] * a) / 255;
951 *cp++ = PACK4(r,g,b,a);
952 pp += samplesperpixel;
953 }
954 cp += toskew;
955 pp += fromskew;
956 }
957}
958
959/*
960 * 16-bit packed samples => RGB
961 */
962DECLAREContigPutFunc(putRGBcontig16bittile)
963{
964 int samplesperpixel = img->samplesperpixel;
965 uint16 *wp = (uint16 *)pp;
966
967 (void) y;
968 fromskew *= samplesperpixel;
969 while (h-- > 0) {
970 for (x = w; x-- > 0;) {
971 *cp++ = PACKW(wp[0], wp[1], wp[2]);
972 wp += samplesperpixel;
973 }
974 cp += toskew;
975 wp += fromskew;
976 }
977}
978
979/*
980 * 16-bit packed samples => RGBA w/ associated alpha
981 * (known to have Map == NULL)
982 */
983DECLAREContigPutFunc(putRGBAAcontig16bittile)
984{
985 int samplesperpixel = img->samplesperpixel;
986 uint16 *wp = (uint16 *)pp;
987
988 (void) y;
989 fromskew *= samplesperpixel;
990 while (h-- > 0) {
991 for (x = w; x-- > 0;) {
992 *cp++ = PACKW4(wp[0], wp[1], wp[2], wp[3]);
993 wp += samplesperpixel;
994 }
995 cp += toskew;
996 wp += fromskew;
997 }
998}
999
1000/*
1001 * 16-bit packed samples => RGBA w/ unassociated alpha
1002 * (known to have Map == NULL)
1003 */
1004DECLAREContigPutFunc(putRGBUAcontig16bittile)
1005{
1006 int samplesperpixel = img->samplesperpixel;
1007 uint16 *wp = (uint16 *)pp;
1008
1009 (void) y;
1010 fromskew *= samplesperpixel;
1011 while (h-- > 0) {
1012 uint32 r,g,b,a;
1013 /*
1014 * We shift alpha down four bits just in case unsigned
1015 * arithmetic doesn't handle the full range.
1016 * We still have plenty of accuracy, since the output is 8 bits.
1017 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1018 * Since we want r*a * 0xff for eight bit output,
1019 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1020 */
1021 for (x = w; x-- > 0;) {
615a9936 1022 a = wp[3] >> 4;
b47c832e
RR
1023 r = (wp[0] * a) / 0x10eff;
1024 g = (wp[1] * a) / 0x10eff;
1025 b = (wp[2] * a) / 0x10eff;
1026 *cp++ = PACK4(r,g,b,a);
1027 wp += samplesperpixel;
1028 }
1029 cp += toskew;
1030 wp += fromskew;
1031 }
1032}
1033
1034/*
1035 * 8-bit packed CMYK samples w/o Map => RGB
1036 *
1037 * NB: The conversion of CMYK->RGB is *very* crude.
1038 */
1039DECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
1040{
1041 int samplesperpixel = img->samplesperpixel;
1042 uint16 r, g, b, k;
1043
1044 (void) x; (void) y;
1045 fromskew *= samplesperpixel;
1046 while (h-- > 0) {
1047 UNROLL8(w, NOP,
1048 k = 255 - pp[3];
1049 r = (k*(255-pp[0]))/255;
1050 g = (k*(255-pp[1]))/255;
1051 b = (k*(255-pp[2]))/255;
1052 *cp++ = PACK(r, g, b);
1053 pp += samplesperpixel);
1054 cp += toskew;
1055 pp += fromskew;
1056 }
1057}
1058
1059/*
1060 * 8-bit packed CMYK samples w/Map => RGB
1061 *
1062 * NB: The conversion of CMYK->RGB is *very* crude.
1063 */
1064DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
1065{
1066 int samplesperpixel = img->samplesperpixel;
1067 TIFFRGBValue* Map = img->Map;
1068 uint16 r, g, b, k;
1069
1070 (void) y;
1071 fromskew *= samplesperpixel;
1072 while (h-- > 0) {
1073 for (x = w; x-- > 0;) {
1074 k = 255 - pp[3];
1075 r = (k*(255-pp[0]))/255;
1076 g = (k*(255-pp[1]))/255;
1077 b = (k*(255-pp[2]))/255;
1078 *cp++ = PACK(Map[r], Map[g], Map[b]);
1079 pp += samplesperpixel;
1080 }
1081 pp += fromskew;
1082 cp += toskew;
1083 }
1084}
1085
1086#define DECLARESepPutFunc(name) \
615a9936 1087static void LINKAGEMODE name(\
b47c832e
RR
1088 TIFFRGBAImage* img,\
1089 uint32* cp,\
1090 uint32 x, uint32 y, \
1091 uint32 w, uint32 h,\
1092 int32 fromskew, int32 toskew,\
1093 u_char* r, u_char* g, u_char* b, u_char* a\
1094)
1095
1096/*
1097 * 8-bit unpacked samples => RGB
1098 */
1099DECLARESepPutFunc(putRGBseparate8bittile)
1100{
1101 (void) img; (void) x; (void) y; (void) a;
1102 while (h-- > 0) {
1103 UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
1104 SKEW(r, g, b, fromskew);
1105 cp += toskew;
1106 }
1107}
1108
1109/*
1110 * 8-bit unpacked samples => RGB
1111 */
1112DECLARESepPutFunc(putRGBseparate8bitMaptile)
1113{
1114 TIFFRGBValue* Map = img->Map;
1115
1116 (void) y; (void) a;
1117 while (h-- > 0) {
1118 for (x = w; x > 0; x--)
1119 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
1120 SKEW(r, g, b, fromskew);
1121 cp += toskew;
1122 }
1123}
1124
1125/*
1126 * 8-bit unpacked samples => RGBA w/ associated alpha
1127 */
1128DECLARESepPutFunc(putRGBAAseparate8bittile)
1129{
1130 (void) img; (void) x; (void) y;
1131 while (h-- > 0) {
1132 UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
1133 SKEW4(r, g, b, a, fromskew);
1134 cp += toskew;
1135 }
1136}
1137
1138/*
1139 * 8-bit unpacked samples => RGBA w/ unassociated alpha
1140 */
1141DECLARESepPutFunc(putRGBUAseparate8bittile)
1142{
1143 (void) img; (void) y;
1144 while (h-- > 0) {
1145 uint32 rv, gv, bv, av;
1146 for (x = w; x-- > 0;) {
1147 av = *a++;
1148 rv = (*r++ * av) / 255;
1149 gv = (*g++ * av) / 255;
1150 bv = (*b++ * av) / 255;
1151 *cp++ = PACK4(rv,gv,bv,av);
1152 }
1153 SKEW4(r, g, b, a, fromskew);
1154 cp += toskew;
1155 }
1156}
1157
1158/*
1159 * 16-bit unpacked samples => RGB
1160 */
1161DECLARESepPutFunc(putRGBseparate16bittile)
1162{
1163 uint16 *wr = (uint16*) r;
1164 uint16 *wg = (uint16*) g;
1165 uint16 *wb = (uint16*) b;
1166
1167 (void) img; (void) y; (void) a;
1168 while (h-- > 0) {
1169 for (x = 0; x < w; x++)
1170 *cp++ = PACKW(*wr++, *wg++, *wb++);
1171 SKEW(wr, wg, wb, fromskew);
1172 cp += toskew;
1173 }
1174}
1175
1176/*
1177 * 16-bit unpacked samples => RGBA w/ associated alpha
1178 */
1179DECLARESepPutFunc(putRGBAAseparate16bittile)
1180{
1181 uint16 *wr = (uint16*) r;
1182 uint16 *wg = (uint16*) g;
1183 uint16 *wb = (uint16*) b;
1184 uint16 *wa = (uint16*) a;
1185
1186 (void) img; (void) y;
1187 while (h-- > 0) {
1188 for (x = 0; x < w; x++)
1189 *cp++ = PACKW4(*wr++, *wg++, *wb++, *wa++);
1190 SKEW4(wr, wg, wb, wa, fromskew);
1191 cp += toskew;
1192 }
1193}
1194
1195/*
1196 * 16-bit unpacked samples => RGBA w/ unassociated alpha
1197 */
1198DECLARESepPutFunc(putRGBUAseparate16bittile)
1199{
1200 uint16 *wr = (uint16*) r;
1201 uint16 *wg = (uint16*) g;
1202 uint16 *wb = (uint16*) b;
1203 uint16 *wa = (uint16*) a;
1204
1205 (void) img; (void) y;
1206 while (h-- > 0) {
1207 uint32 r,g,b,a;
1208 /*
1209 * We shift alpha down four bits just in case unsigned
1210 * arithmetic doesn't handle the full range.
1211 * We still have plenty of accuracy, since the output is 8 bits.
1212 * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff)
1213 * Since we want r*a * 0xff for eight bit output,
1214 * we divide by (0xffff * 0xfff) / 0xff == 0x10eff.
1215 */
1216 for (x = w; x-- > 0;) {
615a9936 1217 a = *wa++ >> 4;
b47c832e
RR
1218 r = (*wr++ * a) / 0x10eff;
1219 g = (*wg++ * a) / 0x10eff;
1220 b = (*wb++ * a) / 0x10eff;
1221 *cp++ = PACK4(r,g,b,a);
1222 }
1223 SKEW4(wr, wg, wb, wa, fromskew);
1224 cp += toskew;
1225 }
1226}
1227
1228/*
1229 * YCbCr -> RGB conversion and packing routines. The colorspace
1230 * conversion algorithm comes from the IJG v5a code; see below
1231 * for more information on how it works.
1232 */
1233
1234#define YCbCrtoRGB(dst, yc) { \
1235 int Y = (yc); \
1236 dst = PACK( \
1237 clamptab[Y+Crrtab[Cr]], \
1238 clamptab[Y + (int)((Cbgtab[Cb]+Crgtab[Cr])>>16)], \
1239 clamptab[Y+Cbbtab[Cb]]); \
1240}
1241#define YCbCrSetup \
1242 TIFFYCbCrToRGB* ycbcr = img->ycbcr; \
1243 int* Crrtab = ycbcr->Cr_r_tab; \
1244 int* Cbbtab = ycbcr->Cb_b_tab; \
1245 int32* Crgtab = ycbcr->Cr_g_tab; \
1246 int32* Cbgtab = ycbcr->Cb_g_tab; \
1247 TIFFRGBValue* clamptab = ycbcr->clamptab
1248
1249/*
1250 * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1251 */
1252DECLAREContigPutFunc(putcontig8bitYCbCr44tile)
1253{
1254 YCbCrSetup;
1255 uint32* cp1 = cp+w+toskew;
1256 uint32* cp2 = cp1+w+toskew;
1257 uint32* cp3 = cp2+w+toskew;
1258 int32 incr = 3*w+4*toskew;
1259
1260 (void) y;
1261 /* XXX adjust fromskew */
1262 for (; h >= 4; h -= 4) {
1263 x = w>>2;
1264 do {
1265 int Cb = pp[16];
1266 int Cr = pp[17];
1267
1268 YCbCrtoRGB(cp [0], pp[ 0]);
1269 YCbCrtoRGB(cp [1], pp[ 1]);
1270 YCbCrtoRGB(cp [2], pp[ 2]);
1271 YCbCrtoRGB(cp [3], pp[ 3]);
1272 YCbCrtoRGB(cp1[0], pp[ 4]);
1273 YCbCrtoRGB(cp1[1], pp[ 5]);
1274 YCbCrtoRGB(cp1[2], pp[ 6]);
1275 YCbCrtoRGB(cp1[3], pp[ 7]);
1276 YCbCrtoRGB(cp2[0], pp[ 8]);
1277 YCbCrtoRGB(cp2[1], pp[ 9]);
1278 YCbCrtoRGB(cp2[2], pp[10]);
1279 YCbCrtoRGB(cp2[3], pp[11]);
1280 YCbCrtoRGB(cp3[0], pp[12]);
1281 YCbCrtoRGB(cp3[1], pp[13]);
1282 YCbCrtoRGB(cp3[2], pp[14]);
1283 YCbCrtoRGB(cp3[3], pp[15]);
1284
1285 cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1286 pp += 18;
1287 } while (--x);
1288 cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1289 pp += fromskew;
1290 }
1291}
1292
1293/*
1294 * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1295 */
1296DECLAREContigPutFunc(putcontig8bitYCbCr42tile)
1297{
1298 YCbCrSetup;
1299 uint32* cp1 = cp+w+toskew;
1300 int32 incr = 2*toskew+w;
1301
1302 (void) y;
1303 /* XXX adjust fromskew */
1304 for (; h >= 2; h -= 2) {
1305 x = w>>2;
1306 do {
1307 int Cb = pp[8];
1308 int Cr = pp[9];
1309
1310 YCbCrtoRGB(cp [0], pp[0]);
1311 YCbCrtoRGB(cp [1], pp[1]);
1312 YCbCrtoRGB(cp [2], pp[2]);
1313 YCbCrtoRGB(cp [3], pp[3]);
1314 YCbCrtoRGB(cp1[0], pp[4]);
1315 YCbCrtoRGB(cp1[1], pp[5]);
1316 YCbCrtoRGB(cp1[2], pp[6]);
1317 YCbCrtoRGB(cp1[3], pp[7]);
1318
1319 cp += 4, cp1 += 4;
1320 pp += 10;
1321 } while (--x);
1322 cp += incr, cp1 += incr;
1323 pp += fromskew;
1324 }
1325}
1326
1327/*
1328 * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1329 */
1330DECLAREContigPutFunc(putcontig8bitYCbCr41tile)
1331{
1332 YCbCrSetup;
1333
1334 (void) y;
1335 /* XXX adjust fromskew */
1336 do {
1337 x = w>>2;
1338 do {
1339 int Cb = pp[4];
1340 int Cr = pp[5];
1341
1342 YCbCrtoRGB(cp [0], pp[0]);
1343 YCbCrtoRGB(cp [1], pp[1]);
1344 YCbCrtoRGB(cp [2], pp[2]);
1345 YCbCrtoRGB(cp [3], pp[3]);
1346
1347 cp += 4;
1348 pp += 6;
1349 } while (--x);
1350 cp += toskew;
1351 pp += fromskew;
1352 } while (--h);
1353}
1354
1355/*
1356 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1357 */
1358DECLAREContigPutFunc(putcontig8bitYCbCr22tile)
1359{
1360 YCbCrSetup;
1361 uint32* cp1 = cp+w+toskew;
1362 int32 incr = 2*toskew+w;
1363
1364 (void) y;
1365 /* XXX adjust fromskew */
1366 for (; h >= 2; h -= 2) {
1367 x = w>>1;
1368 do {
1369 int Cb = pp[4];
1370 int Cr = pp[5];
1371
1372 YCbCrtoRGB(cp [0], pp[0]);
1373 YCbCrtoRGB(cp [1], pp[1]);
1374 YCbCrtoRGB(cp1[0], pp[2]);
1375 YCbCrtoRGB(cp1[1], pp[3]);
1376
1377 cp += 2, cp1 += 2;
1378 pp += 6;
1379 } while (--x);
1380 cp += incr, cp1 += incr;
1381 pp += fromskew;
1382 }
1383}
1384
1385/*
1386 * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
1387 */
1388DECLAREContigPutFunc(putcontig8bitYCbCr21tile)
1389{
1390 YCbCrSetup;
1391
1392 (void) y;
1393 /* XXX adjust fromskew */
1394 do {
1395 x = w>>1;
1396 do {
1397 int Cb = pp[2];
1398 int Cr = pp[3];
1399
1400 YCbCrtoRGB(cp[0], pp[0]);
1401 YCbCrtoRGB(cp[1], pp[1]);
1402
1403 cp += 2;
1404 pp += 4;
1405 } while (--x);
1406 cp += toskew;
1407 pp += fromskew;
1408 } while (--h);
1409}
1410
1411/*
1412 * 8-bit packed YCbCr samples w/ no subsampling => RGB
1413 */
1414DECLAREContigPutFunc(putcontig8bitYCbCr11tile)
1415{
1416 YCbCrSetup;
1417
1418 (void) y;
1419 /* XXX adjust fromskew */
1420 do {
1421 x = w>>1;
1422 do {
1423 int Cb = pp[1];
1424 int Cr = pp[2];
1425
1426 YCbCrtoRGB(*cp++, pp[0]);
1427
1428 pp += 3;
1429 } while (--x);
1430 cp += toskew;
1431 pp += fromskew;
1432 } while (--h);
1433}
1434#undef YCbCrSetup
1435#undef YCbCrtoRGB
1436
1437#define LumaRed coeffs[0]
1438#define LumaGreen coeffs[1]
1439#define LumaBlue coeffs[2]
1440#define SHIFT 16
1441#define FIX(x) ((int32)((x) * (1L<<SHIFT) + 0.5))
1442#define ONE_HALF ((int32)(1<<(SHIFT-1)))
1443
1444/*
1445 * Initialize the YCbCr->RGB conversion tables. The conversion
1446 * is done according to the 6.0 spec:
1447 *
1448 * R = Y + Cr*(2 - 2*LumaRed)
1449 * B = Y + Cb*(2 - 2*LumaBlue)
1450 * G = Y
1451 * - LumaBlue*Cb*(2-2*LumaBlue)/LumaGreen
1452 * - LumaRed*Cr*(2-2*LumaRed)/LumaGreen
1453 *
1454 * To avoid floating point arithmetic the fractional constants that
1455 * come out of the equations are represented as fixed point values
1456 * in the range 0...2^16. We also eliminate multiplications by
1457 * pre-calculating possible values indexed by Cb and Cr (this code
1458 * assumes conversion is being done for 8-bit samples).
1459 */
1460static void
1461TIFFYCbCrToRGBInit(TIFFYCbCrToRGB* ycbcr, TIFF* tif)
1462{
1463 TIFFRGBValue* clamptab;
1464 float* coeffs;
1465 int i;
1466
1467 clamptab = (TIFFRGBValue*)(
1468 (tidata_t) ycbcr+TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long)));
1469 _TIFFmemset(clamptab, 0, 256); /* v < 0 => 0 */
1470 ycbcr->clamptab = (clamptab += 256);
1471 for (i = 0; i < 256; i++)
1472 clamptab[i] = i;
1473 _TIFFmemset(clamptab+256, 255, 2*256); /* v > 255 => 255 */
1474 TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS, &coeffs);
1475 _TIFFmemcpy(ycbcr->coeffs, coeffs, 3*sizeof (float));
1476 { float f1 = 2-2*LumaRed; int32 D1 = FIX(f1);
1477 float f2 = LumaRed*f1/LumaGreen; int32 D2 = -FIX(f2);
1478 float f3 = 2-2*LumaBlue; int32 D3 = FIX(f3);
1479 float f4 = LumaBlue*f3/LumaGreen; int32 D4 = -FIX(f4);
1480 int x;
1481
1482 ycbcr->Cr_r_tab = (int*) (clamptab + 3*256);
1483 ycbcr->Cb_b_tab = ycbcr->Cr_r_tab + 256;
1484 ycbcr->Cr_g_tab = (int32*) (ycbcr->Cb_b_tab + 256);
1485 ycbcr->Cb_g_tab = ycbcr->Cr_g_tab + 256;
1486 /*
1487 * i is the actual input pixel value in the range 0..255
1488 * Cb and Cr values are in the range -128..127 (actually
1489 * they are in a range defined by the ReferenceBlackWhite
1490 * tag) so there is some range shifting to do here when
1491 * constructing tables indexed by the raw pixel data.
1492 *
1493 * XXX handle ReferenceBlackWhite correctly to calculate
1494 * Cb/Cr values to use in constructing the tables.
1495 */
1496 for (i = 0, x = -128; i < 256; i++, x++) {
1497 ycbcr->Cr_r_tab[i] = (int)((D1*x + ONE_HALF)>>SHIFT);
1498 ycbcr->Cb_b_tab[i] = (int)((D3*x + ONE_HALF)>>SHIFT);
1499 ycbcr->Cr_g_tab[i] = D2*x;
1500 ycbcr->Cb_g_tab[i] = D4*x + ONE_HALF;
1501 }
1502 }
1503}
1504#undef SHIFT
1505#undef ONE_HALF
1506#undef FIX
1507#undef LumaBlue
1508#undef LumaGreen
1509#undef LumaRed
1510
1511static tileContigRoutine
1512initYCbCrConversion(TIFFRGBAImage* img)
1513{
1514 uint16 hs, vs;
1515
1516 if (img->ycbcr == NULL) {
1517 img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
1518 TIFFroundup(sizeof (TIFFYCbCrToRGB), sizeof (long))
1519 + 4*256*sizeof (TIFFRGBValue)
1520 + 2*256*sizeof (int)
1521 + 2*256*sizeof (int32)
1522 );
1523 if (img->ycbcr == NULL) {
1524 TIFFError(TIFFFileName(img->tif),
1525 "No space for YCbCr->RGB conversion state");
1526 return (NULL);
1527 }
1528 TIFFYCbCrToRGBInit(img->ycbcr, img->tif);
1529 } else {
1530 float* coeffs;
1531
1532 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &coeffs);
1533 if (_TIFFmemcmp(coeffs, img->ycbcr->coeffs, 3*sizeof (float)) != 0)
1534 TIFFYCbCrToRGBInit(img->ycbcr, img->tif);
1535 }
1536 /*
1537 * The 6.0 spec says that subsampling must be
1538 * one of 1, 2, or 4, and that vertical subsampling
1539 * must always be <= horizontal subsampling; so
1540 * there are only a few possibilities and we just
1541 * enumerate the cases.
1542 */
1543 TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
1544 switch ((hs<<4)|vs) {
50b27824
VZ
1545 case 0x44: return (&putcontig8bitYCbCr44tile);
1546 case 0x42: return (&putcontig8bitYCbCr42tile);
1547 case 0x41: return (&putcontig8bitYCbCr41tile);
1548 case 0x22: return (&putcontig8bitYCbCr22tile);
1549 case 0x21: return (&putcontig8bitYCbCr21tile);
1550 case 0x11: return (&putcontig8bitYCbCr11tile);
b47c832e
RR
1551 }
1552 return (NULL);
1553}
1554
1555/*
1556 * Greyscale images with less than 8 bits/sample are handled
1557 * with a table to avoid lots of shifts and masks. The table
1558 * is setup so that put*bwtile (below) can retrieve 8/bitspersample
1559 * pixel values simply by indexing into the table with one
1560 * number.
1561 */
1562static int
1563makebwmap(TIFFRGBAImage* img)
1564{
1565 TIFFRGBValue* Map = img->Map;
1566 int bitspersample = img->bitspersample;
1567 int nsamples = 8 / bitspersample;
1568 int i;
1569 uint32* p;
1570
1571 img->BWmap = (uint32**) _TIFFmalloc(
1572 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
1573 if (img->BWmap == NULL) {
1574 TIFFError(TIFFFileName(img->tif), "No space for B&W mapping table");
1575 return (0);
1576 }
1577 p = (uint32*)(img->BWmap + 256);
1578 for (i = 0; i < 256; i++) {
1579 TIFFRGBValue c;
1580 img->BWmap[i] = p;
1581 switch (bitspersample) {
1582#define GREY(x) c = Map[x]; *p++ = PACK(c,c,c);
1583 case 1:
1584 GREY(i>>7);
1585 GREY((i>>6)&1);
1586 GREY((i>>5)&1);
1587 GREY((i>>4)&1);
1588 GREY((i>>3)&1);
1589 GREY((i>>2)&1);
1590 GREY((i>>1)&1);
1591 GREY(i&1);
1592 break;
1593 case 2:
1594 GREY(i>>6);
1595 GREY((i>>4)&3);
1596 GREY((i>>2)&3);
1597 GREY(i&3);
1598 break;
1599 case 4:
1600 GREY(i>>4);
1601 GREY(i&0xf);
1602 break;
1603 case 8:
1604 GREY(i);
1605 break;
1606 }
1607#undef GREY
1608 }
1609 return (1);
1610}
1611
1612/*
1613 * Construct a mapping table to convert from the range
1614 * of the data samples to [0,255] --for display. This
1615 * process also handles inverting B&W images when needed.
615a9936 1616 */
b47c832e
RR
1617static int
1618setupMap(TIFFRGBAImage* img)
1619{
1620 int32 x, range;
1621
1622 range = (int32)((1L<<img->bitspersample)-1);
1623 img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
1624 if (img->Map == NULL) {
1625 TIFFError(TIFFFileName(img->tif),
1626 "No space for photometric conversion table");
1627 return (0);
1628 }
1629 if (img->photometric == PHOTOMETRIC_MINISWHITE) {
1630 for (x = 0; x <= range; x++)
1631 img->Map[x] = ((range - x) * 255) / range;
1632 } else {
1633 for (x = 0; x <= range; x++)
1634 img->Map[x] = (x * 255) / range;
1635 }
1636 if (img->bitspersample <= 8 &&
1637 (img->photometric == PHOTOMETRIC_MINISBLACK ||
1638 img->photometric == PHOTOMETRIC_MINISWHITE)) {
1639 /*
1640 * Use photometric mapping table to construct
1641 * unpacking tables for samples <= 8 bits.
1642 */
1643 if (!makebwmap(img))
1644 return (0);
1645 /* no longer need Map, free it */
1646 _TIFFfree(img->Map), img->Map = NULL;
1647 }
1648 return (1);
1649}
1650
1651static int
1652checkcmap(TIFFRGBAImage* img)
1653{
1654 uint16* r = img->redcmap;
1655 uint16* g = img->greencmap;
1656 uint16* b = img->bluecmap;
1657 long n = 1L<<img->bitspersample;
1658
1659 while (n-- > 0)
1660 if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
1661 return (16);
1662 return (8);
1663}
1664
1665static void
1666cvtcmap(TIFFRGBAImage* img)
1667{
1668 uint16* r = img->redcmap;
1669 uint16* g = img->greencmap;
1670 uint16* b = img->bluecmap;
1671 long i;
1672
1673 for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
1674#define CVT(x) ((uint16)((x)>>8))
1675 r[i] = CVT(r[i]);
1676 g[i] = CVT(g[i]);
1677 b[i] = CVT(b[i]);
1678#undef CVT
1679 }
1680}
1681
1682/*
1683 * Palette images with <= 8 bits/sample are handled
1684 * with a table to avoid lots of shifts and masks. The table
1685 * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
1686 * pixel values simply by indexing into the table with one
1687 * number.
1688 */
1689static int
1690makecmap(TIFFRGBAImage* img)
1691{
1692 int bitspersample = img->bitspersample;
1693 int nsamples = 8 / bitspersample;
1694 uint16* r = img->redcmap;
1695 uint16* g = img->greencmap;
1696 uint16* b = img->bluecmap;
1697 uint32 *p;
1698 int i;
1699
1700 img->PALmap = (uint32**) _TIFFmalloc(
1701 256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
1702 if (img->PALmap == NULL) {
1703 TIFFError(TIFFFileName(img->tif), "No space for Palette mapping table");
1704 return (0);
1705 }
1706 p = (uint32*)(img->PALmap + 256);
1707 for (i = 0; i < 256; i++) {
1708 TIFFRGBValue c;
1709 img->PALmap[i] = p;
1710#define CMAP(x) c = x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
1711 switch (bitspersample) {
1712 case 1:
1713 CMAP(i>>7);
1714 CMAP((i>>6)&1);
1715 CMAP((i>>5)&1);
1716 CMAP((i>>4)&1);
1717 CMAP((i>>3)&1);
1718 CMAP((i>>2)&1);
1719 CMAP((i>>1)&1);
1720 CMAP(i&1);
1721 break;
1722 case 2:
1723 CMAP(i>>6);
1724 CMAP((i>>4)&3);
1725 CMAP((i>>2)&3);
1726 CMAP(i&3);
1727 break;
1728 case 4:
1729 CMAP(i>>4);
1730 CMAP(i&0xf);
1731 break;
1732 case 8:
1733 CMAP(i);
1734 break;
1735 }
1736#undef CMAP
1737 }
1738 return (1);
1739}
1740
615a9936 1741/*
b47c832e
RR
1742 * Construct any mapping table used
1743 * by the associated put routine.
1744 */
1745static int
1746buildMap(TIFFRGBAImage* img)
1747{
1748 switch (img->photometric) {
1749 case PHOTOMETRIC_RGB:
1750 case PHOTOMETRIC_YCBCR:
1751 case PHOTOMETRIC_SEPARATED:
1752 if (img->bitspersample == 8)
1753 break;
1754 /* fall thru... */
1755 case PHOTOMETRIC_MINISBLACK:
1756 case PHOTOMETRIC_MINISWHITE:
1757 if (!setupMap(img))
1758 return (0);
1759 break;
1760 case PHOTOMETRIC_PALETTE:
1761 /*
1762 * Convert 16-bit colormap to 8-bit (unless it looks
1763 * like an old-style 8-bit colormap).
1764 */
1765 if (checkcmap(img) == 16)
1766 cvtcmap(img);
1767 else
1768 TIFFWarning(TIFFFileName(img->tif), "Assuming 8-bit colormap");
1769 /*
1770 * Use mapping table and colormap to construct
1771 * unpacking tables for samples < 8 bits.
1772 */
1773 if (img->bitspersample <= 8 && !makecmap(img))
1774 return (0);
1775 break;
1776 }
1777 return (1);
1778}
1779
1780/*
1781 * Select the appropriate conversion routine for packed data.
1782 */
1783static int
1784pickTileContigCase(TIFFRGBAImage* img)
1785{
1786 tileContigRoutine put = 0;
1787
1788 if (buildMap(img)) {
1789 switch (img->photometric) {
1790 case PHOTOMETRIC_RGB:
1791 switch (img->bitspersample) {
1792 case 8:
1793 if (!img->Map) {
1794 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
1795 put = putRGBAAcontig8bittile;
1796 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
1797 put = putRGBUAcontig8bittile;
1798 else
1799 put = putRGBcontig8bittile;
1800 } else
1801 put = putRGBcontig8bitMaptile;
1802 break;
1803 case 16:
1804 put = putRGBcontig16bittile;
1805 if (!img->Map) {
1806 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
1807 put = putRGBAAcontig16bittile;
1808 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
1809 put = putRGBUAcontig16bittile;
1810 }
1811 break;
1812 }
1813 break;
1814 case PHOTOMETRIC_SEPARATED:
1815 if (img->bitspersample == 8) {
1816 if (!img->Map)
1817 put = putRGBcontig8bitCMYKtile;
1818 else
1819 put = putRGBcontig8bitCMYKMaptile;
1820 }
1821 break;
1822 case PHOTOMETRIC_PALETTE:
1823 switch (img->bitspersample) {
1824 case 8: put = put8bitcmaptile; break;
1825 case 4: put = put4bitcmaptile; break;
1826 case 2: put = put2bitcmaptile; break;
1827 case 1: put = put1bitcmaptile; break;
1828 }
1829 break;
1830 case PHOTOMETRIC_MINISWHITE:
1831 case PHOTOMETRIC_MINISBLACK:
1832 switch (img->bitspersample) {
1833 case 8: put = putgreytile; break;
1834 case 4: put = put4bitbwtile; break;
1835 case 2: put = put2bitbwtile; break;
1836 case 1: put = put1bitbwtile; break;
1837 }
1838 break;
1839 case PHOTOMETRIC_YCBCR:
1840 if (img->bitspersample == 8)
1841 put = initYCbCrConversion(img);
1842 break;
1843 }
1844 }
1845 return ((img->put.contig = put) != 0);
1846}
1847
1848/*
1849 * Select the appropriate conversion routine for unpacked data.
1850 *
1851 * NB: we assume that unpacked single channel data is directed
1852 * to the "packed routines.
1853 */
1854static int
1855pickTileSeparateCase(TIFFRGBAImage* img)
1856{
1857 tileSeparateRoutine put = 0;
1858
1859 if (buildMap(img)) {
1860 switch (img->photometric) {
1861 case PHOTOMETRIC_RGB:
1862 switch (img->bitspersample) {
1863 case 8:
1864 if (!img->Map) {
1865 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
1866 put = putRGBAAseparate8bittile;
1867 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
1868 put = putRGBUAseparate8bittile;
1869 else
1870 put = putRGBseparate8bittile;
1871 } else
1872 put = putRGBseparate8bitMaptile;
1873 break;
1874 case 16:
1875 put = putRGBseparate16bittile;
1876 if (!img->Map) {
1877 if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
1878 put = putRGBAAseparate16bittile;
1879 else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
1880 put = putRGBUAseparate16bittile;
1881 }
1882 break;
1883 }
1884 break;
1885 }
1886 }
1887 return ((img->put.separate = put) != 0);
1888}
1889
1890/*
1891 * Read a whole strip off data from the file, and convert to RGBA form.
1892 * If this is the last strip, then it will only contain the portion of
1893 * the strip that is actually within the image space. The result is
1894 * organized in bottom to top form.
1895 */
1896
1897
1898int
1899TIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
1900
1901{
1902 char emsg[1024];
1903 TIFFRGBAImage img;
1904 int ok;
1905 uint32 rowsperstrip, rows_to_read;
1906
1907 if( TIFFIsTiled( tif ) )
1908 {
1909 TIFFError(TIFFFileName(tif),
1910 "Can't use TIFFReadRGBAStrip() with tiled file.");
1911 return (0);
1912 }
615a9936 1913
b47c832e
RR
1914 TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
1915 if( (row % rowsperstrip) != 0 )
1916 {
1917 TIFFError(TIFFFileName(tif),
1918 "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
1919 return (0);
1920 }
1921
1922 if (TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
1923
1924 img.row_offset = row;
1925 img.col_offset = 0;
1926
1927 if( row + rowsperstrip > img.height )
1928 rows_to_read = img.height - row;
1929 else
1930 rows_to_read = rowsperstrip;
615a9936 1931
b47c832e 1932 ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
615a9936 1933
b47c832e
RR
1934 TIFFRGBAImageEnd(&img);
1935 } else {
1936 TIFFError(TIFFFileName(tif), emsg);
1937 ok = 0;
1938 }
615a9936 1939
b47c832e
RR
1940 return (ok);
1941}
1942
1943/*
1944 * Read a whole tile off data from the file, and convert to RGBA form.
1945 * The returned RGBA data is organized from bottom to top of tile,
1946 * and may include zeroed areas if the tile extends off the image.
1947 */
1948
1949int
1950TIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
1951
1952{
1953 char emsg[1024];
1954 TIFFRGBAImage img;
1955 int ok;
1956 uint32 tile_xsize, tile_ysize;
1957 uint32 read_xsize, read_ysize;
1958 int i_row;
1959
1960 /*
1961 * Verify that our request is legal - on a tile file, and on a
1962 * tile boundary.
1963 */
615a9936 1964
b47c832e
RR
1965 if( !TIFFIsTiled( tif ) )
1966 {
1967 TIFFError(TIFFFileName(tif),
1968 "Can't use TIFFReadRGBATile() with stripped file.");
1969 return (0);
1970 }
615a9936 1971
b47c832e
RR
1972 TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
1973 TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
1974 if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
1975 {
1976 TIFFError(TIFFFileName(tif),
1977 "Row/col passed to TIFFReadRGBATile() must be top"
1978 "left corner of a tile.");
1979 return (0);
1980 }
1981
1982 /*
1983 * Setup the RGBA reader.
1984 */
615a9936 1985
b47c832e
RR
1986 if ( !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
1987 TIFFError(TIFFFileName(tif), emsg);
1988 return( 0 );
1989 }
1990
1991 /*
1992 * The TIFFRGBAImageGet() function doesn't allow us to get off the
1993 * edge of the image, even to fill an otherwise valid tile. So we
1994 * figure out how much we can read, and fix up the tile buffer to
1995 * a full tile configuration afterwards.
1996 */
1997
1998 if( row + tile_ysize > img.height )
1999 read_ysize = img.height - row;
2000 else
2001 read_ysize = tile_ysize;
615a9936 2002
b47c832e
RR
2003 if( col + tile_xsize > img.width )
2004 read_xsize = img.width - col;
2005 else
2006 read_xsize = tile_xsize;
2007
2008 /*
2009 * Read the chunk of imagery.
2010 */
615a9936 2011
b47c832e
RR
2012 img.row_offset = row;
2013 img.col_offset = col;
2014
2015 ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
615a9936 2016
b47c832e
RR
2017 TIFFRGBAImageEnd(&img);
2018
2019 /*
2020 * If our read was incomplete we will need to fix up the tile by
2021 * shifting the data around as if a full tile of data is being returned.
2022 *
2023 * This is all the more complicated because the image is organized in
615a9936 2024 * bottom to top format.
b47c832e
RR
2025 */
2026
2027 if( read_xsize == tile_xsize && read_ysize == tile_ysize )
2028 return( ok );
2029
2030 for( i_row = 0; i_row < read_ysize; i_row++ )
2031 {
2032 _TIFFmemcpy( raster + (tile_ysize - i_row - 1) * tile_xsize,
2033 raster + (read_ysize - i_row - 1) * read_xsize,
2034 read_xsize * sizeof(uint32) );
2035 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
2036 0, sizeof(uint32) * (tile_xsize - read_xsize) );
2037 }
2038
2039 for( i_row = read_ysize; i_row < tile_ysize; i_row++ )
2040 {
2041 _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
2042 0, sizeof(uint32) * tile_xsize );
2043 }
615a9936 2044
b47c832e
RR
2045 return (ok);
2046}