source: trunk/third/tiff/libtiff/tif_getimage.c @ 18174

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