1793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* $Id: tif_getimage.c,v 1.82 2012-06-06 00:17:49 fwarmerdam Exp $ */
2793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
3793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
4793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Copyright (c) 1991-1997 Sam Leffler
5793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Copyright (c) 1991-1997 Silicon Graphics, Inc.
6793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
7793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Permission to use, copy, modify, distribute, and sell this software and
8793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * its documentation for any purpose is hereby granted without fee, provided
9793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * that (i) the above copyright notices and this permission notice appear in
10793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * all copies of the software and related documentation, and (ii) the names of
11793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Sam Leffler and Silicon Graphics may not be used in any advertising or
12793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * publicity relating to the software without the specific, prior written
13793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * permission of Sam Leffler and Silicon Graphics.
14793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
15793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND,
16793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY
17793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
18793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
19793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
20793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
21793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
22793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF
23793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * OF THIS SOFTWARE.
25793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
26793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
27793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
28793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * TIFF Library
29793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
30793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read and return a packed RGBA image.
31793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
32793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include "tiffiop.h"
33793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#include <stdio.h>
34793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
35793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtTileContig(TIFFRGBAImage*, uint32*, uint32, uint32);
36793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtTileSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
37793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtStripContig(TIFFRGBAImage*, uint32*, uint32, uint32);
38793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int gtStripSeparate(TIFFRGBAImage*, uint32*, uint32, uint32);
39793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int PickContigCase(TIFFRGBAImage*);
40793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int PickSeparateCase(TIFFRGBAImage*);
41793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
42793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int BuildMapUaToAa(TIFFRGBAImage* img);
43793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int BuildMapBitdepth16To8(TIFFRGBAImage* img);
44793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
45793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic const char photoTag[] = "PhotometricInterpretation";
46793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
47793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
48793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Helper constants used in Orientation tag handling
49793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
50793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define FLIP_VERTICALLY 0x01
51793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define FLIP_HORIZONTALLY 0x02
52793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
53793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
54793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Color conversion constants. We will define display types here.
55793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
56793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
57793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic const TIFFDisplay display_sRGB = {
58793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {			/* XYZ -> luminance matrix */
59793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {  3.2410F, -1.5374F, -0.4986F },
60793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {  -0.9692F, 1.8760F, 0.0416F },
61793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {  0.0556F, -0.2040F, 1.0570F }
62793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    },
63793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    100.0F, 100.0F, 100.0F,	/* Light o/p for reference white */
64793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    255, 255, 255,		/* Pixel values for ref. white */
65793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    1.0F, 1.0F, 1.0F,	/* Residual light o/p for black pixel */
66793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    2.4F, 2.4F, 2.4F,	/* Gamma values for the three guns */
67793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler};
68793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
69793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
70793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Check the image to see if TIFFReadRGBAImage can deal with it.
71793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1/0 is returned according to whether or not the image can
72793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * be handled.  If 0 is returned, emsg contains the reason
73793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * why it is being rejected.
74793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
75793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint
76793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageOK(TIFF* tif, char emsg[1024])
77793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
78793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFDirectory* td = &tif->tif_dir;
79793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 photometric;
80793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int colorchannels;
81793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
82793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!tif->tif_decodestatus) {
83793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        sprintf(emsg, "Sorry, requested compression method is not configured");
84793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
85793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
86793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (td->td_bitspersample) {
87793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 1:
88793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 2:
89793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 4:
90793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 8:
91793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 16:
92793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
93793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        default:
94793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
95793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                td->td_bitspersample);
96793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return (0);
97793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
98793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    colorchannels = td->td_samplesperpixel - td->td_extrasamples;
99793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        switch (colorchannels) {
101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 1:
102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                photometric = PHOTOMETRIC_MINISBLACK;
103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 3:
105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                photometric = PHOTOMETRIC_RGB;
106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            default:
108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Missing needed %s tag", photoTag);
109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return (0);
110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (photometric) {
113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_MINISWHITE:
114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_MINISBLACK:
115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_PALETTE:
116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (td->td_planarconfig == PLANARCONFIG_CONTIG
117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                && td->td_samplesperpixel != 1
118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                && td->td_bitspersample < 8 ) {
119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg,
120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Sorry, can not handle contiguous data with %s=%d, "
121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "and %s=%d and Bits/Sample=%d",
122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    photoTag, photometric,
123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Samples/pixel", td->td_samplesperpixel,
124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    td->td_bitspersample);
125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return (0);
126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /*
128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * We should likely validate that any extra samples are either
129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * to be ignored, or are alpha, and if alpha we should try to use
130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * them.  But for now we won't bother with this.
131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            */
132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_YCBCR:
134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /*
135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * TODO: if at all meaningful and useful, make more complete
136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * support check here, or better still, refactor to let supporting
137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * code decide whether there is support and what meaningfull
138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * error to return
139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             */
140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_RGB:
142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (colorchannels < 3) {
143793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Color channels", colorchannels);
145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return (0);
146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_SEPARATED:
149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint16 inkset;
151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (inkset != INKSET_CMYK) {
153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    sprintf(emsg,
154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        "Sorry, can not handle separated image with %s=%d",
155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        "InkSet", inkset);
156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    return 0;
157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (td->td_samplesperpixel < 4) {
159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    sprintf(emsg,
160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        "Sorry, can not handle separated image with %s=%d",
161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        "Samples/pixel", td->td_samplesperpixel);
162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    return 0;
163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_LOGL:
167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (td->td_compression != COMPRESSION_SGILOG) {
168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, LogL data must have %s=%d",
169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Compression", COMPRESSION_SGILOG);
170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return (0);
171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_LOGLUV:
174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (td->td_compression != COMPRESSION_SGILOG &&
175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                td->td_compression != COMPRESSION_SGILOG24) {
176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return (0);
179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (td->td_planarconfig != PLANARCONFIG_CONTIG) {
181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Planarconfiguration", td->td_planarconfig);
183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return (0);
184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_CIELAB:
187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        default:
189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            sprintf(emsg, "Sorry, can not handle image with %s=%d",
190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                photoTag, photometric);
191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return (0);
192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (1);
194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslervoid
197793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageEnd(TIFFRGBAImage* img)
198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->Map)
200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->Map), img->Map = NULL;
201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->BWmap)
202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->BWmap), img->BWmap = NULL;
203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->PALmap)
204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->PALmap), img->PALmap = NULL;
205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->ycbcr)
206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->ycbcr), img->ycbcr = NULL;
207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->cielab)
208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->cielab), img->cielab = NULL;
209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->UaToAa)
210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->UaToAa), img->UaToAa = NULL;
211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->Bitdepth16To8)
212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->Bitdepth16To8), img->Bitdepth16To8 = NULL;
213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( img->redcmap ) {
215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree( img->redcmap );
216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree( img->greencmap );
217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree( img->bluecmap );
218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->redcmap = img->greencmap = img->bluecmap = NULL;
219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
223793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerisCCITTCompression(TIFF* tif)
224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 compress;
226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetField(tif, TIFFTAG_COMPRESSION, &compress);
227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (compress == COMPRESSION_CCITTFAX3 ||
228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        compress == COMPRESSION_CCITTFAX4 ||
229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        compress == COMPRESSION_CCITTRLE ||
230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        compress == COMPRESSION_CCITTRLEW);
231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint
234793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageBegin(TIFFRGBAImage* img, TIFF* tif, int stop, char emsg[1024])
235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* sampleinfo;
237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 extrasamples;
238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 planarconfig;
239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 compress;
240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int colorchannels;
241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *red_orig, *green_orig, *blue_orig;
242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int n_color;
243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* Initialize to normal values */
245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->row_offset = 0;
246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->col_offset = 0;
247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->redcmap = NULL;
248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->greencmap = NULL;
249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->bluecmap = NULL;
250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->req_orientation = ORIENTATION_BOTLEFT;     /* It is the default */
251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->tif = tif;
253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->stoponerr = stop;
254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &img->bitspersample);
255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (img->bitspersample) {
256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 1:
257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 2:
258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 4:
259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 8:
260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 16:
261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        default:
263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            sprintf(emsg, "Sorry, can not handle images with %d-bit samples",
264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->bitspersample);
265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            goto fail_return;
266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->alpha = 0;
268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &img->samplesperpixel);
269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_EXTRASAMPLES,
270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        &extrasamples, &sampleinfo);
271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (extrasamples >= 1)
272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        switch (sampleinfo[0]) {
274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case EXTRASAMPLE_UNSPECIFIED:          /* Workaround for some images without */
275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (img->samplesperpixel > 3)  /* correct info about alpha channel */
276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->alpha = EXTRASAMPLE_ASSOCALPHA;
277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case EXTRASAMPLE_ASSOCALPHA:           /* data is pre-multiplied */
279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case EXTRASAMPLE_UNASSALPHA:           /* data is not pre-multiplied */
280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->alpha = sampleinfo[0];
281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA
286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric))
287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img->photometric = PHOTOMETRIC_MINISWHITE;
288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( extrasamples == 0
290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        && img->samplesperpixel == 4
291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        && img->photometric == PHOTOMETRIC_RGB )
292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img->alpha = EXTRASAMPLE_ASSOCALPHA;
294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        extrasamples = 1;
295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    colorchannels = img->samplesperpixel - extrasamples;
299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_COMPRESSION, &compress);
300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &img->photometric)) {
302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        switch (colorchannels) {
303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 1:
304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (isCCITTCompression(tif))
305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->photometric = PHOTOMETRIC_MINISWHITE;
306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else
307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->photometric = PHOTOMETRIC_MINISBLACK;
308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            case 3:
310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->photometric = PHOTOMETRIC_RGB;
311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            default:
313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Missing needed %s tag", photoTag);
314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                goto fail_return;
315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (img->photometric) {
318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_PALETTE:
319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                &red_orig, &green_orig, &blue_orig)) {
321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Missing required \"Colormap\" tag");
322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                goto fail_return;
323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* copy the colormaps so we can modify them */
326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            n_color = (1L << img->bitspersample);
327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->redcmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->greencmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->bluecmap = (uint16 *) _TIFFmalloc(sizeof(uint16)*n_color);
330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if( !img->redcmap || !img->greencmap || !img->bluecmap ) {
331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Out of memory for colormap copy");
332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                goto fail_return;
333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            _TIFFmemcpy( img->redcmap, red_orig, n_color * 2 );
336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            _TIFFmemcpy( img->greencmap, green_orig, n_color * 2 );
337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            _TIFFmemcpy( img->bluecmap, blue_orig, n_color * 2 );
338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* fall thru... */
340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_MINISWHITE:
341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_MINISBLACK:
342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (planarconfig == PLANARCONFIG_CONTIG
343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                && img->samplesperpixel != 1
344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                && img->bitspersample < 8 ) {
345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg,
346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Sorry, can not handle contiguous data with %s=%d, "
347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "and %s=%d and Bits/Sample=%d",
348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    photoTag, img->photometric,
349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Samples/pixel", img->samplesperpixel,
350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->bitspersample);
351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                goto fail_return;
352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_YCBCR:
355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* It would probably be nice to have a reality check here. */
356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (planarconfig == PLANARCONFIG_CONTIG)
357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                /* can rely on libjpeg to convert to RGB */
358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                /* XXX should restore current state on exit */
359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                switch (compress) {
360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case COMPRESSION_JPEG:
361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        /*
362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         * TODO: when complete tests verify complete desubsampling
363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         * and YCbCr handling, remove use of TIFFTAG_JPEGCOLORMODE in
364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         * favor of tif_getimage.c native handling
365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                         */
366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        TIFFSetField(tif, TIFFTAG_JPEGCOLORMODE, JPEGCOLORMODE_RGB);
367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->photometric = PHOTOMETRIC_RGB;
368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default:
370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        /* do nothing */;
371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /*
374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * TODO: if at all meaningful and useful, make more complete
375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * support check here, or better still, refactor to let supporting
376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * code decide whether there is support and what meaningfull
377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             * error to return
378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler             */
379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_RGB:
381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (colorchannels < 3) {
382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, can not handle RGB image with %s=%d",
383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Color channels", colorchannels);
384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                goto fail_return;
385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_SEPARATED:
388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint16 inkset;
390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                TIFFGetFieldDefaulted(tif, TIFFTAG_INKSET, &inkset);
391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (inkset != INKSET_CMYK) {
392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        "InkSet", inkset);
394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                        goto fail_return;
395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (img->samplesperpixel < 4) {
397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    sprintf(emsg, "Sorry, can not handle separated image with %s=%d",
398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        "Samples/pixel", img->samplesperpixel);
399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                        goto fail_return;
400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_LOGL:
404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (compress != COMPRESSION_SGILOG) {
405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, LogL data must have %s=%d",
406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Compression", COMPRESSION_SGILOG);
407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                goto fail_return;
408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->photometric = PHOTOMETRIC_MINISBLACK;	/* little white lie */
411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->bitspersample = 8;
412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_LOGLUV:
414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (compress != COMPRESSION_SGILOG && compress != COMPRESSION_SGILOG24) {
415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, LogLuv data must have %s=%d or %d",
416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Compression", COMPRESSION_SGILOG, COMPRESSION_SGILOG24);
417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                goto fail_return;
418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (planarconfig != PLANARCONFIG_CONTIG) {
420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                sprintf(emsg, "Sorry, can not handle LogLuv images with %s=%d",
421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    "Planarconfiguration", planarconfig);
422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return (0);
423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFSetField(tif, TIFFTAG_SGILOGDATAFMT, SGILOGDATAFMT_8BIT);
425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->photometric = PHOTOMETRIC_RGB;		/* little white lie */
426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->bitspersample = 8;
427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_CIELAB:
429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        default:
431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            sprintf(emsg, "Sorry, can not handle image with %s=%d",
432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                photoTag, img->photometric);
433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        goto fail_return;
434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->Map = NULL;
436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->BWmap = NULL;
437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->PALmap = NULL;
438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->ycbcr = NULL;
439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->cielab = NULL;
440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->UaToAa = NULL;
441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->Bitdepth16To8 = NULL;
442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &img->width);
443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &img->height);
444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &img->orientation);
445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->isContig =
446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        !(planarconfig == PLANARCONFIG_SEPARATE && img->samplesperpixel > 1);
447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->isContig) {
448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (!PickContigCase(img)) {
449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            sprintf(emsg, "Sorry, can not handle image");
450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            goto fail_return;
451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } else {
453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (!PickSeparateCase(img)) {
454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            sprintf(emsg, "Sorry, can not handle image");
455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            goto fail_return;
456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return 1;
459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler  fail_return:
461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree( img->redcmap );
462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree( img->greencmap );
463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree( img->bluecmap );
464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img->redcmap = img->greencmap = img->bluecmap = NULL;
465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return 0;
466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint
469793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFRGBAImageGet(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->get == NULL) {
472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No \"get\" routine setup");
473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->put.any == NULL) {
476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        "No \"put\" routine setupl; probably can not handle image format");
478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (*img->get)(img, raster, w, h);
481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read the specified image into an ABGR-format rastertaking in account
485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * specified orientation.
486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint
488793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBAImageOriented(TIFF* tif,
489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              uint32 rwidth, uint32 rheight, uint32* raster,
490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              int orientation, int stop)
491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    char emsg[1024] = "";
493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImage img;
494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int ok;
495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, stop, emsg)) {
497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img.req_orientation = orientation;
498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        /* XXX verify rwidth and rheight against width and height */
499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ok = TIFFRGBAImageGet(&img, raster+(rheight-img.height)*rwidth,
500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            rwidth, img.height);
501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFRGBAImageEnd(&img);
502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } else {
503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ok = 0;
505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (ok);
507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read the specified image into an ABGR-format raster. Use bottom left
511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * origin for raster by default.
512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint
514793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBAImage(TIFF* tif,
515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          uint32 rwidth, uint32 rheight, uint32* raster, int stop)
516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return TIFFReadRGBAImageOriented(tif, rwidth, rheight, raster,
518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     ORIENTATION_BOTLEFT, stop);
519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslersetorientation(TIFFRGBAImage* img)
523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (img->orientation) {
525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_TOPLEFT:
526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_LEFTTOP:
527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (img->req_orientation == ORIENTATION_TOPRIGHT ||
528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_RIGHTTOP)
529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY;
530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_RIGHTBOT)
532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_BOTLEFT ||
534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_LEFTBOT)
535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_VERTICALLY;
536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return 0;
538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_TOPRIGHT:
539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_RIGHTTOP:
540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (img->req_orientation == ORIENTATION_TOPLEFT ||
541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_LEFTTOP)
542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY;
543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_RIGHTBOT)
545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_VERTICALLY;
546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_BOTLEFT ||
547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_LEFTBOT)
548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return 0;
551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_BOTRIGHT:
552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_RIGHTBOT:
553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (img->req_orientation == ORIENTATION_TOPLEFT ||
554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_LEFTTOP)
555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_RIGHTTOP)
558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_VERTICALLY;
559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_BOTLEFT ||
560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_LEFTBOT)
561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY;
562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return 0;
564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_BOTLEFT:
565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case ORIENTATION_LEFTBOT:
566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (img->req_orientation == ORIENTATION_TOPLEFT ||
567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_LEFTTOP)
568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_VERTICALLY;
569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_TOPRIGHT ||
570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_RIGHTTOP)
571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY | FLIP_VERTICALLY;
572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->req_orientation == ORIENTATION_BOTRIGHT ||
573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->req_orientation == ORIENTATION_RIGHTBOT)
574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return FLIP_HORIZONTALLY;
575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                return 0;
577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        default:	/* NOTREACHED */
578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return 0;
579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get an tile-organized image that has
584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	PlanarConfiguration contiguous if SamplesPerPixel > 1
585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * or
586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	SamplesPerPixel == 1
587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
589793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtTileContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFF* tif = img->tif;
592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tileContigRoutine put = img->put.contig;
593793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 col, row, y, rowstoread;
594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t pos;
595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 tw, th;
596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* buf;
597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 fromskew, toskew;
598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 nrow;
599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int ret = 1, flip;
600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    buf = (unsigned char*) _TIFFmalloc(TIFFTileSize(tif));
602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (buf == 0) {
603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFmemset(buf, 0, TIFFTileSize(tif));
607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flip = setorientation(img);
611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_VERTICALLY) {
612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = h - 1;
613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(tw + w);
614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else {
616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = 0;
617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(tw - w);
618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (row = 0; row < h; row += nrow)
621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rowstoread = th - (row + img->row_offset) % th;
623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nrow = (row + rowstoread > h ? h - row : rowstoread);
624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (col = 0; col < w; col += tw)
625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (TIFFReadTile(tif, buf, col+img->col_offset,
627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 row+img->row_offset, 0, 0)==(tmsize_t)(-1) && img->stoponerr)
628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ret = 0;
630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (col + tw > w)
636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                /*
638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 * Tile is clipped horizontally.  Calculate
639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 * visible portion and skewing factors.
640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 */
641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint32 npix = w - col;
642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                fromskew = tw - npix;
643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (*put)(img, raster+y*w+col, col, y,
644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                       npix, nrow, fromskew, toskew + fromskew, buf + pos);
645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (*put)(img, raster+y*w+col, col, y, tw, nrow, 0, toskew, buf + pos);
649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFfree(buf);
655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_HORIZONTALLY) {
657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 line;
658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (line = 0; line < h; line++) {
660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *left = raster + (line * w);
661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *right = left + w - 1;
662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            while ( left < right ) {
664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint32 temp = *left;
665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *left = *right;
666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *right = temp;
667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                left++, right--;
668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (ret);
673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get an tile-organized image that has
677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	 SamplesPerPixel > 1
678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	 PlanarConfiguration separated
679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * We assume that all such images are RGB.
680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
682793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtTileSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFF* tif = img->tif;
685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tileSeparateRoutine put = img->put.separate;
686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 col, row, y, rowstoread;
687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t pos;
688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 tw, th;
689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* buf;
690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* p0;
691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* p1;
692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* p2;
693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* pa;
694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t tilesize;
695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t bufsize;
696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 fromskew, toskew;
697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int alpha = img->alpha;
698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 nrow;
699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int ret = 1, flip;
700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int colorchannels;
701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tilesize = TIFFTileSize(tif);
703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,tilesize);
704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (bufsize == 0) {
705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtTileSeparate");
706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    buf = (unsigned char*) _TIFFmalloc(bufsize);
709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (buf == 0) {
710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", "No space for tile buffer");
711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFmemset(buf, 0, bufsize);
714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p0 = buf;
715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p1 = p0 + tilesize;
716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p2 = p1 + tilesize;
717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pa = (alpha?(p2+tilesize):NULL);
718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flip = setorientation(img);
722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_VERTICALLY) {
723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = h - 1;
724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(tw + w);
725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else {
727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = 0;
728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(tw - w);
729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        switch( img->photometric )
732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          case PHOTOMETRIC_MINISWHITE:
734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          case PHOTOMETRIC_MINISBLACK:
735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          case PHOTOMETRIC_PALETTE:
736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            colorchannels = 1;
737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            p2 = p1 = p0;
738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          default:
741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            colorchannels = 3;
742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (row = 0; row < h; row += nrow)
746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rowstoread = th - (row + img->row_offset) % th;
748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nrow = (row + rowstoread > h ? h - row : rowstoread);
749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (col = 0; col < w; col += tw)
750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (TIFFReadTile(tif, p0, col+img->col_offset,
752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                row+img->row_offset,0,0)==(tmsize_t)(-1) && img->stoponerr)
753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ret = 0;
755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (colorchannels > 1
758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            && TIFFReadTile(tif, p1, col+img->col_offset,
759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                            row+img->row_offset,0,1) == (tmsize_t)(-1)
760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            && img->stoponerr)
761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ret = 0;
763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (colorchannels > 1
766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            && TIFFReadTile(tif, p2, col+img->col_offset,
767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                            row+img->row_offset,0,2) == (tmsize_t)(-1)
768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            && img->stoponerr)
769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ret = 0;
771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (alpha
774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            && TIFFReadTile(tif,pa,col+img->col_offset,
775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                            row+img->row_offset,0,colorchannels) == (tmsize_t)(-1)
776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            && img->stoponerr)
777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        {
778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            ret = 0;
779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pos = ((row+img->row_offset) % th) * TIFFTileRowSize(tif);
783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (col + tw > w)
785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                /*
787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 * Tile is clipped horizontally.  Calculate
788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 * visible portion and skewing factors.
789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 */
790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint32 npix = w - col;
791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                fromskew = tw - npix;
792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (*put)(img, raster+y*w+col, col, y,
793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    npix, nrow, fromskew, toskew + fromskew,
794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            } else {
796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                (*put)(img, raster+y*w+col, col, y,
797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    tw, nrow, 0, toskew, p0 + pos, p1 + pos, p2 + pos, (alpha?(pa+pos):NULL));
798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y += (flip & FLIP_VERTICALLY ?-(int32) nrow : (int32) nrow);
802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_HORIZONTALLY) {
805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 line;
806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (line = 0; line < h; line++) {
808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *left = raster + (line * w);
809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *right = left + w - 1;
810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            while ( left < right ) {
812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint32 temp = *left;
813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *left = *right;
814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *right = temp;
815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                left++, right--;
816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFfree(buf);
821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (ret);
822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get a strip-organized image that has
826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	PlanarConfiguration contiguous if SamplesPerPixel > 1
827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * or
828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	SamplesPerPixel == 1
829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
831793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtStripContig(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFF* tif = img->tif;
834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tileContigRoutine put = img->put.contig;
835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 row, y, nrow, nrowsub, rowstoread;
836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t pos;
837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* buf;
838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 rowsperstrip;
839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 subsamplinghor,subsamplingver;
840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 imagewidth = img->width;
841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t scanline;
842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 fromskew, toskew;
843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int ret = 1, flip;
844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    buf = (unsigned char*) _TIFFmalloc(TIFFStripSize(tif));
846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (buf == 0) {
847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for strip buffer");
848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFmemset(buf, 0, TIFFStripSize(tif));
851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flip = setorientation(img);
853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_VERTICALLY) {
854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = h - 1;
855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(w + w);
856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } else {
857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = 0;
858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(w - w);
859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING, &subsamplinghor, &subsamplingver);
863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    scanline = TIFFScanlineSize(tif);
864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (w < imagewidth ? imagewidth - w : 0);
865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (row = 0; row < h; row += nrow)
866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nrow = (row + rowstoread > h ? h - row : rowstoread);
869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nrowsub = nrow;
870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if ((nrowsub%subsamplingver)!=0)
871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            nrowsub+=subsamplingver-nrowsub%subsamplingver;
872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (TIFFReadEncodedStrip(tif,
873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFComputeStrip(tif,row+img->row_offset, 0),
874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            buf,
875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ((row + img->row_offset)%rowsperstrip + nrowsub) * scanline)==(tmsize_t)(-1)
876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            && img->stoponerr)
877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ret = 0;
879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pos = ((row + img->row_offset) % rowsperstrip) * scanline;
883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, buf + pos);
884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_HORIZONTALLY) {
888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 line;
889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (line = 0; line < h; line++) {
891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *left = raster + (line * w);
892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *right = left + w - 1;
893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            while ( left < right ) {
895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint32 temp = *left;
896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *left = *right;
897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *right = temp;
898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                left++, right--;
899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFfree(buf);
904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (ret);
905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Get a strip-organized image with
909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	 SamplesPerPixel > 1
910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	 PlanarConfiguration separated
911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * We assume that all such images are RGB.
912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
914793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslergtStripSeparate(TIFFRGBAImage* img, uint32* raster, uint32 w, uint32 h)
915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFF* tif = img->tif;
917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tileSeparateRoutine put = img->put.separate;
918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char *buf;
919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char *p0, *p1, *p2, *pa;
920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 row, y, nrow, rowstoread;
921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t pos;
922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t scanline;
923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 rowsperstrip, offset_row;
924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 imagewidth = img->width;
925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t stripsize;
926793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    tmsize_t bufsize;
927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 fromskew, toskew;
928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int alpha = img->alpha;
929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int ret = 1, flip, colorchannels;
930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    stripsize = TIFFStripSize(tif);
932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    bufsize = TIFFSafeMultiply(tmsize_t,alpha?4:3,stripsize);
933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (bufsize == 0) {
934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "Integer overflow in %s", "gtStripSeparate");
935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p0 = buf = (unsigned char *)_TIFFmalloc(bufsize);
938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (buf == 0) {
939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "No space for tile buffer");
940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFmemset(buf, 0, bufsize);
943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p1 = p0 + stripsize;
944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p2 = p1 + stripsize;
945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pa = (alpha?(p2+stripsize):NULL);
946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    flip = setorientation(img);
948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_VERTICALLY) {
949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = h - 1;
950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(w + w);
951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else {
953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y = 0;
954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        toskew = -(int32)(w - w);
955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        switch( img->photometric )
958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          case PHOTOMETRIC_MINISWHITE:
960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          case PHOTOMETRIC_MINISBLACK:
961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          case PHOTOMETRIC_PALETTE:
962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            colorchannels = 1;
963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            p2 = p1 = p0;
964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler          default:
967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            colorchannels = 3;
968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
970793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    scanline = TIFFScanlineSize(tif);
973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (w < imagewidth ? imagewidth - w : 0);
974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (row = 0; row < h; row += nrow)
975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        rowstoread = rowsperstrip - (row + img->row_offset) % rowsperstrip;
977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nrow = (row + rowstoread > h ? h - row : rowstoread);
978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        offset_row = row + img->row_offset;
979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 0),
980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            p0, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            && img->stoponerr)
982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ret = 0;
984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (colorchannels > 1
987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 1),
988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                            p1, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            && img->stoponerr)
990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ret = 0;
992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (colorchannels > 1
995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    && TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, 2),
996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                                            p2, ((row + img->row_offset)%rowsperstrip + nrow) * scanline) == (tmsize_t)(-1)
997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            && img->stoponerr)
998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            ret = 0;
1000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
1001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (alpha)
1003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, offset_row, colorchannels),
1005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pa, ((row + img->row_offset)%rowsperstrip + nrow) * scanline)==(tmsize_t)(-1)
1006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                && img->stoponerr)
1007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
1008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                ret = 0;
1009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
1010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pos = ((row + img->row_offset) % rowsperstrip) * scanline;
1014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        (*put)(img, raster+y*w, 0, y, w, nrow, fromskew, toskew, p0 + pos, p1 + pos,
1015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            p2 + pos, (alpha?(pa+pos):NULL));
1016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        y += (flip & FLIP_VERTICALLY ? -(int32) nrow : (int32) nrow);
1017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (flip & FLIP_HORIZONTALLY) {
1020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 line;
1021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (line = 0; line < h; line++) {
1023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *left = raster + (line * w);
1024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 *right = left + w - 1;
1025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            while ( left < right ) {
1027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint32 temp = *left;
1028793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *left = *right;
1029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                *right = temp;
1030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                left++, right--;
1031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFfree(buf);
1036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (ret);
1037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The following routines move decoded data returned
1041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * from the TIFF library into rasters filled with packed
1042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * ABGR pixels (i.e. suitable for passing to lrecwrite.)
1043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
1044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The routines have been created according to the most
1045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * important cases and optimized.  PickContigCase and
1046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * PickSeparateCase analyze the parameters and select
1047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * the appropriate "get" and "put" routine to use.
1048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	REPEAT8(op)	REPEAT4(op); REPEAT4(op)
1050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	REPEAT4(op)	REPEAT2(op); REPEAT2(op)
1051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	REPEAT2(op)	op; op
1052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	CASE8(x,op)			\
1053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (x) {			\
1054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 7: op; case 6: op; case 5: op;	\
1055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 4: op; case 3: op; case 2: op;	\
1056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 1: op;				\
1057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	CASE4(x,op)	switch (x) { case 3: op; case 2: op; case 1: op; }
1059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	NOP
1060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	UNROLL8(w, op1, op2) {		\
1062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 _x;				\
1063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (_x = w; _x >= 8; _x -= 8) {	\
1064793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    op1;				\
1065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    REPEAT8(op2);			\
1066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }					\
1067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (_x > 0) {			\
1068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    op1;				\
1069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CASE8(_x,op2);			\
1070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }					\
1071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	UNROLL4(w, op1, op2) {		\
1073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 _x;				\
1074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (_x = w; _x >= 4; _x -= 4) {	\
1075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    op1;				\
1076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    REPEAT4(op2);			\
1077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }					\
1078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (_x > 0) {			\
1079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    op1;				\
1080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    CASE4(_x,op2);			\
1081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }					\
1082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	UNROLL2(w, op1, op2) {		\
1084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 _x;				\
1085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (_x = w; _x >= 2; _x -= 2) {	\
1086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    op1;				\
1087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    REPEAT2(op2);			\
1088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }					\
1089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (_x) {				\
1090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    op1;				\
1091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    op2;				\
1092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }					\
1093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	SKEW(r,g,b,skew)	{ r += skew; g += skew; b += skew; }
1096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	SKEW4(r,g,b,a,skew)	{ r += skew; g += skew; b += skew; a+= skew; }
1097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define A1 (((uint32)0xffL)<<24)
1099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	PACK(r,g,b)	\
1100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1)
1101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	PACK4(r,g,b,a)	\
1102793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24))
1103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define W2B(v) (((v)>>8)&0xff)
1104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* TODO: PACKW should have be made redundant in favor of Bitdepth16To8 LUT */
1105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	PACKW(r,g,b)	\
1106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1)
1107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	PACKW4(r,g,b,a)	\
1108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24))
1109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	DECLAREContigPutFunc(name) \
1111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void name(\
1112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImage* img, \
1113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp, \
1114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 x, uint32 y, \
1115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 w, uint32 h, \
1116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 fromskew, int32 toskew, \
1117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* pp \
1118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler)
1119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit palette => colormap/RGB
1122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1123793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put8bitcmaptile)
1124793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** PALmap = img->PALmap;
1126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (x = w; x-- > 0;)
1131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *cp++ = PALmap[*pp][0];
1133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += samplesperpixel;
1134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 4-bit palette => colormap/RGB
1142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1143793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put4bitcmaptile)
1144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** PALmap = img->PALmap;
1146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew /= 2;
1149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* bw;
1151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
1152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 2-bit palette => colormap/RGB
1159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1160793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put2bitcmaptile)
1161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** PALmap = img->PALmap;
1163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew /= 4;
1166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* bw;
1168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
1169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1172793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1-bit palette => colormap/RGB
1176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1177793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put1bitcmaptile)
1178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** PALmap = img->PALmap;
1180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew /= 8;
1183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* bw;
1185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
1186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit greyscale => colormap/RGB
1193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1194793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putgreytile)
1195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** BWmap = img->BWmap;
1198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (x = w; x-- > 0;)
1202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *cp++ = BWmap[*pp][0];
1204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += samplesperpixel;
1205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit greyscale with associated alpha => colormap/RGBA
1213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1214793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putagreytile)
1215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** BWmap = img->BWmap;
1218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (x = w; x-- > 0;)
1222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = BWmap[*pp][0] & (*(pp+1) << 24 | ~A1);
1224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += samplesperpixel;
1225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit greyscale => colormap/RGB
1233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1234793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put16bitbwtile)
1235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** BWmap = img->BWmap;
1238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint16 *wp = (uint16 *) pp;
1242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (x = w; x-- > 0;)
1244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            /* use high order byte of 16bit value */
1246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *cp++ = BWmap[*wp >> 8][0];
1248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 2 * samplesperpixel;
1249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            wp += samplesperpixel;
1250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 1-bit bilevel => colormap/RGB
1258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1259793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put1bitbwtile)
1260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** BWmap = img->BWmap;
1262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew /= 8;
1265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* bw;
1267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
1268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1271793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 2-bit greyscale => colormap/RGB
1275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1276793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put2bitbwtile)
1277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** BWmap = img->BWmap;
1279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew /= 4;
1282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* bw;
1284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
1285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 4-bit greyscale => colormap/RGB
1292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1293793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(put4bitbwtile)
1294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32** BWmap = img->BWmap;
1296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew /= 2;
1299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* bw;
1301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
1302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed samples, no Map => RGB
1309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1310793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig8bittile)
1311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL8(w, NOP,
1318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *cp++ = PACK(pp[0], pp[1], pp[2]);
1319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += samplesperpixel);
1320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed samples => RGBA w/ associated alpha
1327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL)
1328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1329793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBAAcontig8bittile)
1330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL8(w, NOP,
1337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *cp++ = PACK4(pp[0], pp[1], pp[2], pp[3]);
1338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += samplesperpixel);
1339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed samples => RGBA w/ unassociated alpha
1346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL)
1347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1348793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBUAcontig8bittile)
1349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 r, g, b, a;
1355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint8* m;
1356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            a = pp[3];
1358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m = img->UaToAa+(a<<8);
1359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            r = m[pp[0]];
1360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            g = m[pp[1]];
1361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            b = m[pp[2]];
1362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK4(r,g,b,a);
1363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += samplesperpixel;
1364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += fromskew;
1367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit packed samples => RGB
1372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1373793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig16bittile)
1374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wp = (uint16 *)pp;
1377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK(img->Bitdepth16To8[wp[0]],
1382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[wp[1]],
1383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[wp[2]]);
1384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            wp += samplesperpixel;
1385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        wp += fromskew;
1388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit packed samples => RGBA w/ associated alpha
1393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL)
1394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1395793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBAAcontig16bittile)
1396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wp = (uint16 *)pp;
1399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK4(img->Bitdepth16To8[wp[0]],
1404793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[wp[1]],
1405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[wp[2]],
1406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[wp[3]]);
1407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            wp += samplesperpixel;
1408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        wp += fromskew;
1411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit packed samples => RGBA w/ unassociated alpha
1416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * (known to have Map == NULL)
1417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1418793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBUAcontig16bittile)
1419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wp = (uint16 *)pp;
1422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 r,g,b,a;
1426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint8* m;
1427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            a = img->Bitdepth16To8[wp[3]];
1429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m = img->UaToAa+(a<<8);
1430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            r = m[img->Bitdepth16To8[wp[0]]];
1431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            g = m[img->Bitdepth16To8[wp[1]]];
1432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            b = m[img->Bitdepth16To8[wp[2]]];
1433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK4(r,g,b,a);
1434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            wp += samplesperpixel;
1435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        wp += fromskew;
1438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1442793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed CMYK samples w/o Map => RGB
1443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
1444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * NB: The conversion of CMYK->RGB is *very* crude.
1445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1446793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig8bitCMYKtile)
1447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 r, g, b, k;
1450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) x; (void) y;
1452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL8(w, NOP,
1455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        k = 255 - pp[3];
1456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        r = (k*(255-pp[0]))/255;
1457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        g = (k*(255-pp[1]))/255;
1458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        b = (k*(255-pp[2]))/255;
1459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *cp++ = PACK(r, g, b);
1460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += samplesperpixel);
1461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed CMYK samples w/Map => RGB
1468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
1469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * NB: The conversion of CMYK->RGB is *very* crude.
1470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1471793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile)
1472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int samplesperpixel = img->samplesperpixel;
1474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBValue* Map = img->Map;
1475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 r, g, b, k;
1476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= samplesperpixel;
1479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (x = w; x-- > 0;) {
1481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        k = 255 - pp[3];
1482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        r = (k*(255-pp[0]))/255;
1483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        g = (k*(255-pp[1]))/255;
1484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        b = (k*(255-pp[2]))/255;
1485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *cp++ = PACK(Map[r], Map[g], Map[b]);
1486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += samplesperpixel;
1487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	DECLARESepPutFunc(name) \
1494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void name(\
1495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImage* img,\
1496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp,\
1497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 x, uint32 y, \
1498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 w, uint32 h,\
1499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 fromskew, int32 toskew,\
1500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\
1501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler)
1502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked samples => RGB
1505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1506793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBseparate8bittile)
1507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) img; (void) x; (void) y; (void) a;
1509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    UNROLL8(w, NOP, *cp++ = PACK(*r++, *g++, *b++));
1511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    SKEW(r, g, b, fromskew);
1512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked samples => RGBA w/ associated alpha
1518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1519793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBAAseparate8bittile)
1520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) img; (void) x; (void) y;
1522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        UNROLL8(w, NOP, *cp++ = PACK4(*r++, *g++, *b++, *a++));
1524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SKEW4(r, g, b, a, fromskew);
1525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked CMYK samples => RGBA
1531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1532793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putCMYKseparate8bittile)
1533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) img; (void) y;
1535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 rv, gv, bv, kv;
1537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            kv = 255 - *a++;
1539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            rv = (kv*(255-*r++))/255;
1540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            gv = (kv*(255-*g++))/255;
1541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            bv = (kv*(255-*b++))/255;
1542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK4(rv,gv,bv,255);
1543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SKEW4(r, g, b, a, fromskew);
1545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit unpacked samples => RGBA w/ unassociated alpha
1551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1552793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBUAseparate8bittile)
1553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) img; (void) y;
1555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 rv, gv, bv, av;
1557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint8* m;
1558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            av = *a++;
1560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m = img->UaToAa+(av<<8);
1561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            rv = m[*r++];
1562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            gv = m[*g++];
1563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            bv = m[*b++];
1564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK4(rv,gv,bv,av);
1565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SKEW4(r, g, b, a, fromskew);
1567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit unpacked samples => RGB
1573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1574793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBseparate16bittile)
1575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wr = (uint16*) r;
1577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wg = (uint16*) g;
1578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wb = (uint16*) b;
1579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) img; (void) y; (void) a;
1580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = 0; x < w; x++)
1582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK(img->Bitdepth16To8[*wr++],
1583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[*wg++],
1584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[*wb++]);
1585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SKEW(wr, wg, wb, fromskew);
1586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit unpacked samples => RGBA w/ associated alpha
1592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1593793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBAAseparate16bittile)
1594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wr = (uint16*) r;
1596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wg = (uint16*) g;
1597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wb = (uint16*) b;
1598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wa = (uint16*) a;
1599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) img; (void) y;
1600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = 0; x < w; x++)
1602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK4(img->Bitdepth16To8[*wr++],
1603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[*wg++],
1604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[*wb++],
1605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->Bitdepth16To8[*wa++]);
1606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SKEW4(wr, wg, wb, wa, fromskew);
1607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 16-bit unpacked samples => RGBA w/ unassociated alpha
1613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1614793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putRGBUAseparate16bittile)
1615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wr = (uint16*) r;
1617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wg = (uint16*) g;
1618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wb = (uint16*) b;
1619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 *wa = (uint16*) a;
1620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) img; (void) y;
1621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint32 r,g,b,a;
1623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        uint8* m;
1624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            a = img->Bitdepth16To8[*wa++];
1626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            m = img->UaToAa+(a<<8);
1627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            r = m[img->Bitdepth16To8[*wr++]];
1628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            g = m[img->Bitdepth16To8[*wg++]];
1629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            b = m[img->Bitdepth16To8[*wb++]];
1630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK4(r,g,b,a);
1631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SKEW4(wr, wg, wb, wa, fromskew);
1633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed CIE L*a*b 1976 samples => RGB
1639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1640793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitCIELab)
1641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    float X, Y, Z;
1643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 r, g, b;
1644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= 3;
1646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
1647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (x = w; x-- > 0;) {
1648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFCIELabToXYZ(img->cielab,
1649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    (unsigned char)pp[0],
1650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    (signed char)pp[1],
1651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    (signed char)pp[2],
1652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    &X, &Y, &Z);
1653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFXYZToRGB(img->cielab, X, Y, Z, &r, &g, &b);
1654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK(r, g, b);
1655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 3;
1656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
1658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += fromskew;
1659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1662793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * YCbCr -> RGB conversion and packing routines.
1664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	YCbCrtoRGB(dst, Y) {						\
1667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 r, g, b;							\
1668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b);		\
1669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    dst = PACK(r, g, b);						\
1670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples => RGB
1674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * This function is generic for different sampling sizes,
1675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * and can handle blocks sizes that aren't multiples of the
1676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * sampling size.  However, it is substantially less optimized
1677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * than the specific sampling cases.  It is used as a fallback
1678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * for difficult blocks.
1679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#ifdef notdef
1681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void putcontig8bitYCbCrGenericTile(
1682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImage* img,
1683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp,
1684793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 x, uint32 y,
1685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 w, uint32 h,
1686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 fromskew, int32 toskew,
1687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    unsigned char* pp,
1688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int h_group,
1689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int v_group )
1690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp1 = cp+w+toskew;
1693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp2 = cp1+w+toskew;
1694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp3 = cp2+w+toskew;
1695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 incr = 3*w+4*toskew;
1696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32   Cb, Cr;
1697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int     group_size = v_group * h_group + 2;
1698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (fromskew * group_size) / h_group;
1701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( yy = 0; yy < h; yy++ )
1703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
1704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        unsigned char *pp_line;
1705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int     y_line_group = yy / v_group;
1706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int     y_remainder = yy - y_line_group * v_group;
1707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp_line = pp + v_line_group *
1709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for( xx = 0; xx < w; xx++ )
1712793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            Cb = pp
1714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (; h >= 4; h -= 4) {
1717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    x = w>>2;
1718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    do {
1719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        Cb = pp[16];
1720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        Cr = pp[17];
1721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [0], pp[ 0]);
1723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [1], pp[ 1]);
1724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [2], pp[ 2]);
1725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [3], pp[ 3]);
1726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp1[0], pp[ 4]);
1727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp1[1], pp[ 5]);
1728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp1[2], pp[ 6]);
1729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp1[3], pp[ 7]);
1730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp2[0], pp[ 8]);
1731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp2[1], pp[ 9]);
1732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp2[2], pp[10]);
1733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp2[3], pp[11]);
1734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp3[0], pp[12]);
1735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp3[1], pp[13]);
1736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp3[2], pp[14]);
1737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp3[3], pp[15]);
1738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += 18;
1741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } while (--x);
1742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#endif
1747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB
1750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1751793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr44tile)
1752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp1 = cp+w+toskew;
1754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp2 = cp1+w+toskew;
1755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp3 = cp2+w+toskew;
1756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 incr = 3*w+4*toskew;
1757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* adjust fromskew */
1760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (fromskew * 18) / 4;
1761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if ((h & 3) == 0 && (w & 3) == 0) {
1762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (; h >= 4; h -= 4) {
1763793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            x = w>>2;
1764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            do {
1765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cb = pp[16];
1766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cr = pp[17];
1767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [0], pp[ 0]);
1769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [1], pp[ 1]);
1770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [2], pp[ 2]);
1771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [3], pp[ 3]);
1772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[0], pp[ 4]);
1773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[1], pp[ 5]);
1774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[2], pp[ 6]);
1775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[3], pp[ 7]);
1776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp2[0], pp[ 8]);
1777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp2[1], pp[ 9]);
1778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp2[2], pp[10]);
1779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp2[3], pp[11]);
1780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp3[0], pp[12]);
1781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp3[1], pp[13]);
1782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp3[2], pp[14]);
1783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp3[3], pp[15]);
1784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cp += 4, cp1 += 4, cp2 += 4, cp3 += 4;
1786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pp += 18;
1787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            } while (--x);
1788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += fromskew;
1790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } else {
1792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        while (h > 0) {
1793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for (x = w; x > 0;) {
1794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cb = pp[16];
1795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cr = pp[17];
1796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                switch (x) {
1797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                default:
1798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp3[3], pp[15]); /* FALLTHROUGH */
1800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 3:  YCbCrtoRGB(cp2[3], pp[11]); /* FALLTHROUGH */
1801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 2:  YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 3:
1805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp3[2], pp[14]); /* FALLTHROUGH */
1807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 3:  YCbCrtoRGB(cp2[2], pp[10]); /* FALLTHROUGH */
1808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 2:  YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 2:
1812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp3[1], pp[13]); /* FALLTHROUGH */
1814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 3:  YCbCrtoRGB(cp2[1], pp[ 9]); /* FALLTHROUGH */
1815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 2:  YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 1:
1819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp3[0], pp[12]); /* FALLTHROUGH */
1821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 3:  YCbCrtoRGB(cp2[0], pp[ 8]); /* FALLTHROUGH */
1822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 2:  YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (x < 4) {
1827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cp += x; cp1 += x; cp2 += x; cp3 += x;
1828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    x = 0;
1829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else {
1831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cp += 4; cp1 += 4; cp2 += 4; cp3 += 4;
1832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    x -= 4;
1833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pp += 18;
1835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (h <= 4)
1837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
1838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            h -= 4;
1839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += incr, cp1 += incr, cp2 += incr, cp3 += incr;
1840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += fromskew;
1841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB
1847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1848793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr42tile)
1849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp1 = cp+w+toskew;
1851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 incr = 2*toskew+w;
1852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (fromskew * 10) / 4;
1855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if ((h & 3) == 0 && (w & 1) == 0) {
1856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (; h >= 2; h -= 2) {
1857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            x = w>>2;
1858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            do {
1859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cb = pp[8];
1860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cr = pp[9];
1861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [0], pp[0]);
1863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [1], pp[1]);
1864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [2], pp[2]);
1865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp [3], pp[3]);
1866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[0], pp[4]);
1867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[1], pp[5]);
1868793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[2], pp[6]);
1869793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                YCbCrtoRGB(cp1[3], pp[7]);
1870793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1871793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                cp += 4, cp1 += 4;
1872793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pp += 10;
1873793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            } while (--x);
1874793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += incr, cp1 += incr;
1875793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += fromskew;
1876793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1877793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } else {
1878793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        while (h > 0) {
1879793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            for (x = w; x > 0;) {
1880793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cb = pp[8];
1881793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                int32 Cr = pp[9];
1882793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                switch (x) {
1883793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                default:
1884793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1885793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp1[3], pp[ 7]); /* FALLTHROUGH */
1886793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [3], pp[ 3]); /* FALLTHROUGH */
1887793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1888793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 3:
1889793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1890793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp1[2], pp[ 6]); /* FALLTHROUGH */
1891793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [2], pp[ 2]); /* FALLTHROUGH */
1892793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1893793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 2:
1894793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1895793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp1[1], pp[ 5]); /* FALLTHROUGH */
1896793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [1], pp[ 1]); /* FALLTHROUGH */
1897793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1898793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 1:
1899793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch (h) {
1900793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    default: YCbCrtoRGB(cp1[0], pp[ 4]); /* FALLTHROUGH */
1901793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:  YCbCrtoRGB(cp [0], pp[ 0]); /* FALLTHROUGH */
1902793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }                                    /* FALLTHROUGH */
1903793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1904793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (x < 4) {
1905793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cp += x; cp1 += x;
1906793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    x = 0;
1907793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1908793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                else {
1909793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    cp += 4; cp1 += 4;
1910793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    x -= 4;
1911793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
1912793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                pp += 10;
1913793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1914793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (h <= 2)
1915793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
1916793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            h -= 2;
1917793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += incr, cp1 += incr;
1918793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += fromskew;
1919793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1920793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
1921793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1922793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1923793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1924793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB
1925793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1926793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr41tile)
1927793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1928793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1929793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* XXX adjust fromskew */
1930793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    do {
1931793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    x = w>>2;
1932793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    do {
1933793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int32 Cb = pp[4];
1934793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int32 Cr = pp[5];
1935793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1936793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [0], pp[0]);
1937793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [1], pp[1]);
1938793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [2], pp[2]);
1939793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        YCbCrtoRGB(cp [3], pp[3]);
1940793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1941793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += 4;
1942793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += 6;
1943793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } while (--x);
1944793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1945793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( (w&3) != 0 )
1946793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
1947793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int32 Cb = pp[4];
1948793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        int32 Cr = pp[5];
1949793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1950793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            switch( (w&3) ) {
1951793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              case 3: YCbCrtoRGB(cp [2], pp[2]);
1952793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              case 2: YCbCrtoRGB(cp [1], pp[1]);
1953793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              case 1: YCbCrtoRGB(cp [0], pp[0]);
1954793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              case 0: break;
1955793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
1956793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1957793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += (w&3);
1958793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 6;
1959793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1960793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1961793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp += toskew;
1962793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    pp += fromskew;
1963793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } while (--h);
1964793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1965793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
1966793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
1967793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
1968793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
1969793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
1970793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr22tile)
1971793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
1972793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp2;
1973793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 incr = 2*toskew+w;
1974793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
1975793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (fromskew / 2) * 6;
1976793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp2 = cp+w+toskew;
1977793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h>=2) {
1978793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        x = w;
1979793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        while (x>=2) {
1980793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cb = pp[4];
1981793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cr = pp[5];
1982793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
1983793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[1], pp[1]);
1984793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp2[0], pp[2]);
1985793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp2[1], pp[3]);
1986793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += 2;
1987793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp2 += 2;
1988793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 6;
1989793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            x -= 2;
1990793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
1991793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (x==1) {
1992793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cb = pp[4];
1993793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cr = pp[5];
1994793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
1995793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp2[0], pp[2]);
1996793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp ++ ;
1997793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp2 ++ ;
1998793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 6;
1999793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2000793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += incr;
2001793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp2 += incr;
2002793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += fromskew;
2003793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        h-=2;
2004793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2005793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (h==1) {
2006793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        x = w;
2007793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        while (x>=2) {
2008793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cb = pp[4];
2009793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cr = pp[5];
2010793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
2011793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[1], pp[1]);
2012793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += 2;
2013793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp2 += 2;
2014793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 6;
2015793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            x -= 2;
2016793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2017793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (x==1) {
2018793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cb = pp[4];
2019793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cr = pp[5];
2020793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
2021793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2022793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2023793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2024793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2025793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2026793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB
2027793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2028793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr21tile)
2029793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2030793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
2031793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (fromskew * 4) / 2;
2032793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    do {
2033793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        x = w>>1;
2034793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        do {
2035793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int32 Cb = pp[2];
2036793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int32 Cr = pp[3];
2037793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2038793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
2039793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[1], pp[1]);
2040793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2041793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += 2;
2042793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 4;
2043793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        } while (--x);
2044793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2045793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( (w&1) != 0 )
2046793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
2047793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int32 Cb = pp[2];
2048793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int32 Cr = pp[3];
2049793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2050793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
2051793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2052793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp += 1;
2053793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 4;
2054793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2055793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2056793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
2057793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += fromskew;
2058793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } while (--h);
2059793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2060793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2061793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2062793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ 1,2 subsampling => RGB
2063793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2064793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr12tile)
2065793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2066793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* cp2;
2067793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 incr = 2*toskew+w;
2068793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
2069793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew = (fromskew / 2) * 4;
2070793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    cp2 = cp+w+toskew;
2071793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h>=2) {
2072793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        x = w;
2073793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        do {
2074793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cb = pp[2];
2075793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cr = pp[3];
2076793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
2077793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp2[0], pp[1]);
2078793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp ++;
2079793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp2 ++;
2080793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 4;
2081793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        } while (--x);
2082793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += incr;
2083793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp2 += incr;
2084793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += fromskew;
2085793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        h-=2;
2086793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2087793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (h==1) {
2088793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        x = w;
2089793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        do {
2090793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cb = pp[2];
2091793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 Cr = pp[3];
2092793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(cp[0], pp[0]);
2093793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            cp ++;
2094793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 4;
2095793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        } while (--x);
2096793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2097793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2098793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2099793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2100793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ no subsampling => RGB
2101793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2102793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLAREContigPutFunc(putcontig8bitYCbCr11tile)
2103793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2104793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
2105793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    fromskew *= 3;
2106793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    do {
2107793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        x = w; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */
2108793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        do {
2109793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int32 Cb = pp[1];
2110793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            int32 Cr = pp[2];
2111793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2112793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            YCbCrtoRGB(*cp++, pp[0]);
2113793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2114793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            pp += 3;
2115793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        } while (--x);
2116793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
2117793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        pp += fromskew;
2118793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } while (--h);
2119793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2120793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2121793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2122793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * 8-bit packed YCbCr samples w/ no subsampling => RGB
2123793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2124793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerDECLARESepPutFunc(putseparate8bitYCbCr11tile)
2125793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2126793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) y;
2127793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (void) a;
2128793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* TODO: naming of input vars is still off, change obfuscating declaration inside define, or resolve obfuscation */
2129793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (h-- > 0) {
2130793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        x = w;
2131793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        do {
2132793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            uint32 dr, dg, db;
2133793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFYCbCrtoRGB(img->ycbcr,*r++,*g++,*b++,&dr,&dg,&db);
2134793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *cp++ = PACK(dr,dg,db);
2135793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        } while (--x);
2136793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        SKEW(r, g, b, fromskew);
2137793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cp += toskew;
2138793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2139793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2140793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef YCbCrtoRGB
2141793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2142793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2143793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerinitYCbCrConversion(TIFFRGBAImage* img)
2144793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2145793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    static const char module[] = "initYCbCrConversion";
2146793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2147793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    float *luma, *refBlackWhite;
2148793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2149793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->ycbcr == NULL) {
2150793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img->ycbcr = (TIFFYCbCrToRGB*) _TIFFmalloc(
2151793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFroundup_32(sizeof (TIFFYCbCrToRGB), sizeof (long))
2152793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            + 4*256*sizeof (TIFFRGBValue)
2153793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            + 2*256*sizeof (int)
2154793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            + 3*256*sizeof (int32)
2155793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            );
2156793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (img->ycbcr == NULL) {
2157793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFErrorExt(img->tif->tif_clientdata, module,
2158793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                "No space for YCbCr->RGB conversion state");
2159793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return (0);
2160793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2161793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2162793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2163793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRCOEFFICIENTS, &luma);
2164793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(img->tif, TIFFTAG_REFERENCEBLACKWHITE,
2165793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        &refBlackWhite);
2166793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (TIFFYCbCrToRGBInit(img->ycbcr, luma, refBlackWhite) < 0)
2167793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return(0);
2168793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (1);
2169793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2170793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2171793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic tileContigRoutine
2172793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerinitCIELabConversion(TIFFRGBAImage* img)
2173793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2174793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    static const char module[] = "initCIELabConversion";
2175793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2176793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    float   *whitePoint;
2177793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    float   refWhite[3];
2178793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2179793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!img->cielab) {
2180793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img->cielab = (TIFFCIELabToRGB *)
2181793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            _TIFFmalloc(sizeof(TIFFCIELabToRGB));
2182793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (!img->cielab) {
2183793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            TIFFErrorExt(img->tif->tif_clientdata, module,
2184793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                "No space for CIE L*a*b*->RGB conversion state.");
2185793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            return NULL;
2186793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2187793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2188793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2189793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(img->tif, TIFFTAG_WHITEPOINT, &whitePoint);
2190793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    refWhite[1] = 100.0F;
2191793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    refWhite[0] = whitePoint[0] / whitePoint[1] * refWhite[1];
2192793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    refWhite[2] = (1.0F - whitePoint[0] - whitePoint[1])
2193793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler              / whitePoint[1] * refWhite[1];
2194793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (TIFFCIELabToRGBInit(img->cielab, &display_sRGB, refWhite) < 0) {
2195793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata, module,
2196793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            "Failed to initialize CIE L*a*b*->RGB conversion state.");
2197793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFfree(img->cielab);
2198793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return NULL;
2199793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2200793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2201793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return putcontig8bitCIELab;
2202793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2203793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2204793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2205793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Greyscale images with less than 8 bits/sample are handled
2206793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * with a table to avoid lots of shifts and masks.  The table
2207793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * is setup so that put*bwtile (below) can retrieve 8/bitspersample
2208793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * pixel values simply by indexing into the table with one
2209793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * number.
2210793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2211793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2212793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslermakebwmap(TIFFRGBAImage* img)
2213793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2214793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBValue* Map = img->Map;
2215793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int bitspersample = img->bitspersample;
2216793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int nsamples = 8 / bitspersample;
2217793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i;
2218793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32* p;
2219793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2220793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( nsamples == 0 )
2221793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        nsamples = 1;
2222793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2223793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->BWmap = (uint32**) _TIFFmalloc(
2224793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2225793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->BWmap == NULL) {
2226793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for B&W mapping table");
2227793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2228793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2229793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p = (uint32*)(img->BWmap + 256);
2230793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (i = 0; i < 256; i++) {
2231793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBValue c;
2232793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->BWmap[i] = p;
2233793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (bitspersample) {
2234793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	GREY(x)	c = Map[x]; *p++ = PACK(c,c,c);
2235793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 1:
2236793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY(i>>7);
2237793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>6)&1);
2238793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>5)&1);
2239793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>4)&1);
2240793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>3)&1);
2241793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>2)&1);
2242793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>1)&1);
2243793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY(i&1);
2244793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2245793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 2:
2246793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY(i>>6);
2247793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>4)&3);
2248793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY((i>>2)&3);
2249793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY(i&3);
2250793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2251793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 4:
2252793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY(i>>4);
2253793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY(i&0xf);
2254793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2255793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 8:
2256793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 16:
2257793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        GREY(i);
2258793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2259793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2260793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef	GREY
2261793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2262793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (1);
2263793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2264793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2265793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2266793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Construct a mapping table to convert from the range
2267793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * of the data samples to [0,255] --for display.  This
2268793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * process also handles inverting B&W images when needed.
2269793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2270793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2271793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslersetupMap(TIFFRGBAImage* img)
2272793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2273793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int32 x, range;
2274793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2275793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    range = (int32)((1L<<img->bitspersample)-1);
2276793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2277793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* treat 16 bit the same as eight bit */
2278793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( img->bitspersample == 16 )
2279793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        range = (int32) 255;
2280793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2281793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->Map = (TIFFRGBValue*) _TIFFmalloc((range+1) * sizeof (TIFFRGBValue));
2282793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->Map == NULL) {
2283793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif),
2284793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            "No space for photometric conversion table");
2285793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2286793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2287793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->photometric == PHOTOMETRIC_MINISWHITE) {
2288793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (x = 0; x <= range; x++)
2289793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img->Map[x] = (TIFFRGBValue) (((range - x) * 255) / range);
2290793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } else {
2291793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (x = 0; x <= range; x++)
2292793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img->Map[x] = (TIFFRGBValue) ((x * 255) / range);
2293793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2294793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->bitspersample <= 16 &&
2295793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    (img->photometric == PHOTOMETRIC_MINISBLACK ||
2296793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     img->photometric == PHOTOMETRIC_MINISWHITE)) {
2297793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2298793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * Use photometric mapping table to construct
2299793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * unpacking tables for samples <= 8 bits.
2300793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2301793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!makebwmap(img))
2302793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2303793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* no longer need Map, free it */
2304793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    _TIFFfree(img->Map), img->Map = NULL;
2305793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2306793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (1);
2307793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2308793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2309793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2310793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslercheckcmap(TIFFRGBAImage* img)
2311793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2312793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* r = img->redcmap;
2313793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* g = img->greencmap;
2314793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* b = img->bluecmap;
2315793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    long n = 1L<<img->bitspersample;
2316793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2317793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    while (n-- > 0)
2318793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
2319793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (16);
2320793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (8);
2321793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2322793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2323793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic void
2324793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslercvtcmap(TIFFRGBAImage* img)
2325793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2326793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* r = img->redcmap;
2327793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* g = img->greencmap;
2328793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* b = img->bluecmap;
2329793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    long i;
2330793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2331793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (i = (1L<<img->bitspersample)-1; i >= 0; i--) {
2332793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	CVT(x)		((uint16)((x)>>8))
2333793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    r[i] = CVT(r[i]);
2334793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    g[i] = CVT(g[i]);
2335793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    b[i] = CVT(b[i]);
2336793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef	CVT
2337793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2338793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2339793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2340793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2341793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Palette images with <= 8 bits/sample are handled
2342793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * with a table to avoid lots of shifts and masks.  The table
2343793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
2344793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * pixel values simply by indexing into the table with one
2345793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * number.
2346793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2347793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2348793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslermakecmap(TIFFRGBAImage* img)
2349793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2350793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int bitspersample = img->bitspersample;
2351793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int nsamples = 8 / bitspersample;
2352793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* r = img->redcmap;
2353793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* g = img->greencmap;
2354793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16* b = img->bluecmap;
2355793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 *p;
2356793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int i;
2357793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2358793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->PALmap = (uint32**) _TIFFmalloc(
2359793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    256*sizeof (uint32 *)+(256*nsamples*sizeof(uint32)));
2360793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->PALmap == NULL) {
2361793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "No space for Palette mapping table");
2362793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2363793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2364793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    p = (uint32*)(img->PALmap + 256);
2365793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (i = 0; i < 256; i++) {
2366793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBValue c;
2367793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->PALmap[i] = p;
2368793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#define	CMAP(x)	c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff);
2369793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (bitspersample) {
2370793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 1:
2371793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP(i>>7);
2372793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>6)&1);
2373793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>5)&1);
2374793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>4)&1);
2375793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>3)&1);
2376793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>2)&1);
2377793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>1)&1);
2378793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP(i&1);
2379793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2380793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 2:
2381793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP(i>>6);
2382793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>4)&3);
2383793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP((i>>2)&3);
2384793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP(i&3);
2385793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2386793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 4:
2387793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP(i>>4);
2388793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP(i&0xf);
2389793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2390793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case 8:
2391793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        CMAP(i);
2392793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2393793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2394793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler#undef CMAP
2395793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2396793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (1);
2397793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2398793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2399793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2400793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Construct any mapping table used
2401793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * by the associated put routine.
2402793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2403793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2404793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerbuildMap(TIFFRGBAImage* img)
2405793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2406793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (img->photometric) {
2407793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_RGB:
2408793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_YCBCR:
2409793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_SEPARATED:
2410793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->bitspersample == 8)
2411793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2412793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /* fall thru... */
2413793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_MINISBLACK:
2414793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_MINISWHITE:
2415793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!setupMap(img))
2416793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2417793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    break;
2418793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_PALETTE:
2419793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2420793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * Convert 16-bit colormap to 8-bit (unless it looks
2421793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * like an old-style 8-bit colormap).
2422793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2423793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (checkcmap(img) == 16)
2424793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        cvtcmap(img);
2425793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
2426793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFWarningExt(img->tif->tif_clientdata, TIFFFileName(img->tif), "Assuming 8-bit colormap");
2427793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2428793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * Use mapping table and colormap to construct
2429793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * unpacking tables for samples < 8 bits.
2430793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2431793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->bitspersample <= 8 && !makecmap(img))
2432793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2433793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    break;
2434793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2435793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (1);
2436793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2437793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2438793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2439793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Select the appropriate conversion routine for packed data.
2440793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2441793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2442793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPickContigCase(TIFFRGBAImage* img)
2443793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2444793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->get = TIFFIsTiled(img->tif) ? gtTileContig : gtStripContig;
2445793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->put.contig = NULL;
2446793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (img->photometric) {
2447793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_RGB:
2448793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            switch (img->bitspersample) {
2449793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 8:
2450793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2451793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = putRGBAAcontig8bittile;
2452793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2453793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
2454793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if (BuildMapUaToAa(img))
2455793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putRGBUAcontig8bittile;
2456793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2457793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else
2458793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = putRGBcontig8bittile;
2459793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
2460793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 16:
2461793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2462793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
2463793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if (BuildMapBitdepth16To8(img))
2464793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putRGBAAcontig16bittile;
2465793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2466793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2467793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
2468793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if (BuildMapBitdepth16To8(img) &&
2469793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            BuildMapUaToAa(img))
2470793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putRGBUAcontig16bittile;
2471793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2472793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else
2473793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    {
2474793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if (BuildMapBitdepth16To8(img))
2475793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putRGBcontig16bittile;
2476793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2477793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
2478793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2479793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
2480793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_SEPARATED:
2481793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (buildMap(img)) {
2482793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (img->bitspersample == 8) {
2483793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    if (!img->Map)
2484793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = putRGBcontig8bitCMYKtile;
2485793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    else
2486793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = putRGBcontig8bitCMYKMaptile;
2487793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
2488793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2489793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
2490793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_PALETTE:
2491793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (buildMap(img)) {
2492793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                switch (img->bitspersample) {
2493793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 8:
2494793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put8bitcmaptile;
2495793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2496793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 4:
2497793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put4bitcmaptile;
2498793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2499793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 2:
2500793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put2bitcmaptile;
2501793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2502793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:
2503793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put1bitcmaptile;
2504793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2505793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
2506793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2507793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
2508793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_MINISWHITE:
2509793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_MINISBLACK:
2510793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (buildMap(img)) {
2511793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                switch (img->bitspersample) {
2512793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 16:
2513793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put16bitbwtile;
2514793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2515793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 8:
2516793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        if (img->alpha && img->samplesperpixel == 2)
2517793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putagreytile;
2518793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        else
2519793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putgreytile;
2520793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2521793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 4:
2522793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put4bitbwtile;
2523793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2524793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 2:
2525793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put2bitbwtile;
2526793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2527793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    case 1:
2528793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        img->put.contig = put1bitbwtile;
2529793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        break;
2530793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
2531793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2532793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
2533793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_YCBCR:
2534793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if ((img->bitspersample==8) && (img->samplesperpixel==3))
2535793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
2536793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (initYCbCrConversion(img)!=0)
2537793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                {
2538793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    /*
2539793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     * The 6.0 spec says that subsampling must be
2540793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     * one of 1, 2, or 4, and that vertical subsampling
2541793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     * must always be <= horizontal subsampling; so
2542793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     * there are only a few possibilities and we just
2543793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     * enumerate the cases.
2544793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     * Joris: added support for the [1,2] case, nonetheless, to accomodate
2545793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     * some OJPEG files
2546793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     */
2547793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    uint16 SubsamplingHor;
2548793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    uint16 SubsamplingVer;
2549793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &SubsamplingHor, &SubsamplingVer);
2550793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    switch ((SubsamplingHor<<4)|SubsamplingVer) {
2551793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case 0x44:
2552793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putcontig8bitYCbCr44tile;
2553793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2554793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case 0x42:
2555793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putcontig8bitYCbCr42tile;
2556793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2557793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case 0x41:
2558793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putcontig8bitYCbCr41tile;
2559793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2560793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case 0x22:
2561793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putcontig8bitYCbCr22tile;
2562793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2563793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case 0x21:
2564793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putcontig8bitYCbCr21tile;
2565793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2566793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case 0x12:
2567793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putcontig8bitYCbCr12tile;
2568793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2569793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                        case 0x11:
2570793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            img->put.contig = putcontig8bitYCbCr11tile;
2571793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                            break;
2572793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    }
2573793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
2574793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2575793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
2576793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case PHOTOMETRIC_CIELAB:
2577793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (buildMap(img)) {
2578793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (img->bitspersample == 8)
2579793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->put.contig = initCIELabConversion(img);
2580793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                break;
2581793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2582793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2583793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return ((img->get!=NULL) && (img->put.contig!=NULL));
2584793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2585793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2586793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2587793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Select the appropriate conversion routine for unpacked data.
2588793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *
2589793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * NB: we assume that unpacked single channel data is directed
2590793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler *	 to the "packed routines.
2591793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2592793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2593793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerPickSeparateCase(TIFFRGBAImage* img)
2594793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2595793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->get = TIFFIsTiled(img->tif) ? gtTileSeparate : gtStripSeparate;
2596793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->put.separate = NULL;
2597793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    switch (img->photometric) {
2598793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_MINISWHITE:
2599793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_MINISBLACK:
2600793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        /* greyscale images processed pretty much as RGB by gtTileSeparate */
2601793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_RGB:
2602793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        switch (img->bitspersample) {
2603793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 8:
2604793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2605793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->put.separate = putRGBAAseparate8bittile;
2606793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2607793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
2608793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (BuildMapUaToAa(img))
2609793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->put.separate = putRGBUAseparate8bittile;
2610793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2611793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
2612793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                img->put.separate = putRGBseparate8bittile;
2613793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
2614793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        case 16:
2615793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (img->alpha == EXTRASAMPLE_ASSOCALPHA)
2616793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
2617793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (BuildMapBitdepth16To8(img))
2618793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->put.separate = putRGBAAseparate16bittile;
2619793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2620793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else if (img->alpha == EXTRASAMPLE_UNASSALPHA)
2621793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
2622793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (BuildMapBitdepth16To8(img) &&
2623793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    BuildMapUaToAa(img))
2624793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->put.separate = putRGBUAseparate16bittile;
2625793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2626793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            else
2627793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
2628793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                if (BuildMapBitdepth16To8(img))
2629793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->put.separate = putRGBseparate16bittile;
2630793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2631793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            break;
2632793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2633793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2634793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_SEPARATED:
2635793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if (img->bitspersample == 8 && img->samplesperpixel == 4)
2636793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
2637793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->alpha = 1; // Not alpha, but seems like the only way to get 4th band
2638793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            img->put.separate = putCMYKseparate8bittile;
2639793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2640793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2641793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    case PHOTOMETRIC_YCBCR:
2642793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if ((img->bitspersample==8) && (img->samplesperpixel==3))
2643793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        {
2644793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            if (initYCbCrConversion(img)!=0)
2645793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            {
2646793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                uint16 hs, vs;
2647793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                TIFFGetFieldDefaulted(img->tif, TIFFTAG_YCBCRSUBSAMPLING, &hs, &vs);
2648793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                switch ((hs<<4)|vs) {
2649793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                case 0x11:
2650793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    img->put.separate = putseparate8bitYCbCr11tile;
2651793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    break;
2652793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                    /* TODO: add other cases here */
2653793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                }
2654793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            }
2655793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        }
2656793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        break;
2657793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2658793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return ((img->get!=NULL) && (img->put.separate!=NULL));
2659793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2660793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2661793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2662793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerBuildMapUaToAa(TIFFRGBAImage* img)
2663793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2664793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    static const char module[]="BuildMapUaToAa";
2665793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint8* m;
2666793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint16 na,nv;
2667793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert(img->UaToAa==NULL);
2668793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->UaToAa=_TIFFmalloc(65536);
2669793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->UaToAa==NULL)
2670793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2671793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
2672793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return(0);
2673793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2674793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m=img->UaToAa;
2675793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (na=0; na<256; na++)
2676793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2677793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        for (nv=0; nv<256; nv++)
2678793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            *m++=(nv*na+127)/255;
2679793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2680793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return(1);
2681793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2682793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2683793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerstatic int
2684793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerBuildMapBitdepth16To8(TIFFRGBAImage* img)
2685793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2686793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    static const char module[]="BuildMapBitdepth16To8";
2687793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint8* m;
2688793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32 n;
2689793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    assert(img->Bitdepth16To8==NULL);
2690793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img->Bitdepth16To8=_TIFFmalloc(65536);
2691793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (img->Bitdepth16To8==NULL)
2692793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2693793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(img->tif->tif_clientdata,module,"Out of memory");
2694793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return(0);
2695793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2696793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    m=img->Bitdepth16To8;
2697793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for (n=0; n<65536; n++)
2698793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        *m++=(n+128)/257;
2699793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return(1);
2700793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2701793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2702793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2703793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2704793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read a whole strip off data from the file, and convert to RGBA form.
2705793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * If this is the last strip, then it will only contain the portion of
2706793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * the strip that is actually within the image space.  The result is
2707793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * organized in bottom to top form.
2708793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2709793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2710793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2711793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint
2712793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBAStrip(TIFF* tif, uint32 row, uint32 * raster )
2713793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2714793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2715793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    char 	emsg[1024] = "";
2716793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImage img;
2717793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int 	ok;
2718793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32	rowsperstrip, rows_to_read;
2719793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2720793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( TIFFIsTiled( tif ) )
2721793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2722793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2723793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                  "Can't use TIFFReadRGBAStrip() with tiled file.");
2724793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (0);
2725793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2726793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2727793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
2728793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( (row % rowsperstrip) != 0 )
2729793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2730793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2731793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                "Row passed to TIFFReadRGBAStrip() must be first in a strip.");
2732793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2733793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2734793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2735793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (TIFFRGBAImageOK(tif, emsg) && TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2736793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2737793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img.row_offset = row;
2738793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        img.col_offset = 0;
2739793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2740793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        if( row + rowsperstrip > img.height )
2741793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            rows_to_read = img.height - row;
2742793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        else
2743793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler            rows_to_read = rowsperstrip;
2744793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2745793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ok = TIFFRGBAImageGet(&img, raster, img.width, rows_to_read );
2746793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2747793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImageEnd(&img);
2748793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    } else {
2749793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2750793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        ok = 0;
2751793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2752793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2753793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (ok);
2754793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2755793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2756793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2757793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Read a whole tile off data from the file, and convert to RGBA form.
2758793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * The returned RGBA data is organized from bottom to top of tile,
2759793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * and may include zeroed areas if the tile extends off the image.
2760793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2761793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2762793ee12c6df9cad3806238d32528c49a3ff9331dNoah Preslerint
2763793ee12c6df9cad3806238d32528c49a3ff9331dNoah PreslerTIFFReadRGBATile(TIFF* tif, uint32 col, uint32 row, uint32 * raster)
2764793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2765793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler{
2766793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    char 	emsg[1024] = "";
2767793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImage img;
2768793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    int 	ok;
2769793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32	tile_xsize, tile_ysize;
2770793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32	read_xsize, read_ysize;
2771793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    uint32	i_row;
2772793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2773793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2774793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * Verify that our request is legal - on a tile file, and on a
2775793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * tile boundary.
2776793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2777793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2778793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( !TIFFIsTiled( tif ) )
2779793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2780793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2781793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                  "Can't use TIFFReadRGBATile() with stripped file.");
2782793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return (0);
2783793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2784793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2785793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_TILEWIDTH, &tile_xsize);
2786793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFGetFieldDefaulted(tif, TIFFTAG_TILELENGTH, &tile_ysize);
2787793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( (col % tile_xsize) != 0 || (row % tile_ysize) != 0 )
2788793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    {
2789793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif),
2790793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                  "Row/col passed to TIFFReadRGBATile() must be top"
2791793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                  "left corner of a tile.");
2792793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (0);
2793793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2794793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2795793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2796793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * Setup the RGBA reader.
2797793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2798793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2799793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if (!TIFFRGBAImageOK(tif, emsg)
2800793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    || !TIFFRGBAImageBegin(&img, tif, 0, emsg)) {
2801793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        TIFFErrorExt(tif->tif_clientdata, TIFFFileName(tif), "%s", emsg);
2802793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return( 0 );
2803793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2804793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2805793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2806793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * The TIFFRGBAImageGet() function doesn't allow us to get off the
2807793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * edge of the image, even to fill an otherwise valid tile.  So we
2808793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * figure out how much we can read, and fix up the tile buffer to
2809793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * a full tile configuration afterwards.
2810793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2811793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2812793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( row + tile_ysize > img.height )
2813793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        read_ysize = img.height - row;
2814793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
2815793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        read_ysize = tile_ysize;
2816793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2817793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( col + tile_xsize > img.width )
2818793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        read_xsize = img.width - col;
2819793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    else
2820793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        read_xsize = tile_xsize;
2821793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2822793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2823793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * Read the chunk of imagery.
2824793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2825793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2826793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img.row_offset = row;
2827793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    img.col_offset = col;
2828793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2829793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    ok = TIFFRGBAImageGet(&img, raster, read_xsize, read_ysize );
2830793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2831793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    TIFFRGBAImageEnd(&img);
2832793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2833793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    /*
2834793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * If our read was incomplete we will need to fix up the tile by
2835793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * shifting the data around as if a full tile of data is being returned.
2836793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     *
2837793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * This is all the more complicated because the image is organized in
2838793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     * bottom to top format.
2839793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler     */
2840793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2841793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    if( read_xsize == tile_xsize && read_ysize == tile_ysize )
2842793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        return( ok );
2843793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2844793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i_row = 0; i_row < read_ysize; i_row++ ) {
2845793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        memmove( raster + (tile_ysize - i_row - 1) * tile_xsize,
2846793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 raster + (read_ysize - i_row - 1) * read_xsize,
2847793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                 read_xsize * sizeof(uint32) );
2848793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize+read_xsize,
2849793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     0, sizeof(uint32) * (tile_xsize - read_xsize) );
2850793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2851793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2852793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    for( i_row = read_ysize; i_row < tile_ysize; i_row++ ) {
2853793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler        _TIFFmemset( raster + (tile_ysize - i_row - 1) * tile_xsize,
2854793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler                     0, sizeof(uint32) * tile_xsize );
2855793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    }
2856793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2857793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler    return (ok);
2858793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler}
2859793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler
2860793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/* vim: set ts=8 sts=8 sw=8 noet: */
2861793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler/*
2862793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * Local Variables:
2863793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * mode: c
2864793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * c-basic-offset: 8
2865793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * fill-column: 78
2866793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler * End:
2867793ee12c6df9cad3806238d32528c49a3ff9331dNoah Presler */
2868