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