~ubuntu-branches/ubuntu/precise/tiff/precise-security

« back to all changes in this revision

Viewing changes to .pc/CVE-2014-81xx-1.patch/libtiff/tif_getimage.c

  • Committer: Package Import Robot
  • Author(s): Marc Deslauriers
  • Date: 2015-03-30 08:11:18 UTC
  • Revision ID: package-import@ubuntu.com-20150330081118-bvaoaii1act27voq
Tags: 3.9.5-2ubuntu1.7
* SECURITY UPDATE: Fix multiple security issues
  - debian/patches/CVE-2014-81xx-1.patch to CVE-2014-81xx-11.patch
  - debian/patches/CVE-2014-8128-5.patch
  - debian/patches/CVE-2014-9655-1.patch to CVE-2014-9655-3.patch
  - debian/patches/read_overrun.patch
  - debian/patches/CVE-2014-8130.patch
  - CVE-2014-8127 (partially)
  - CVE-2014-8128
  - CVE-2014-8129
  - CVE-2014-8130
  - CVE-2014-9330
  - CVE-2014-9655

Show diffs side-by-side

added added

removed removed

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