4  * Copyright (c) 1991-1997 Sam Leffler 
   5  * Copyright (c) 1991-1997 Silicon Graphics, Inc. 
   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. 
  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.   
  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  
  30  * Read and return a packed RGBA image. 
  35 static  int gtTileContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
); 
  36 static  int gtTileSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
); 
  37 static  int gtStripContig(TIFFRGBAImage
*, uint32
*, uint32
, uint32
); 
  38 static  int gtStripSeparate(TIFFRGBAImage
*, uint32
*, uint32
, uint32
); 
  39 static  int pickTileContigCase(TIFFRGBAImage
*); 
  40 static  int pickTileSeparateCase(TIFFRGBAImage
*); 
  42 static  const char photoTag
[] = "PhotometricInterpretation"; 
  45  * Helper constants used in Orientation tag handling 
  47 #define FLIP_VERTICALLY 0x01 
  48 #define FLIP_HORIZONTALLY 0x02 
  51  * Color conversion constants. We will define display types here. 
  54 TIFFDisplay display_sRGB 
= { 
  55         {                       /* XYZ -> luminance matrix */ 
  56                 {  3.2410F
, -1.5374F
, -0.4986F 
}, 
  57                 {  -0.9692F
, 1.8760F
, 0.0416F 
}, 
  58                 {  0.0556F
, -0.2040F
, 1.0570F 
} 
  60         100.0F
, 100.0F
, 100.0F
, /* Light o/p for reference white */ 
  61         255, 255, 255,          /* Pixel values for ref. white */ 
  62         1.0F
, 1.0F
, 1.0F
,       /* Residual light o/p for black pixel */ 
  63         2.4F
, 2.4F
, 2.4F
,       /* Gamma values for the three guns */ 
  67  * Check the image to see if TIFFReadRGBAImage can deal with it. 
  68  * 1/0 is returned according to whether or not the image can 
  69  * be handled.  If 0 is returned, emsg contains the reason 
  70  * why it is being rejected. 
  73 TIFFRGBAImageOK(TIFF
* tif
, char emsg
[1024]) 
  75     TIFFDirectory
* td 
= &tif
->tif_dir
; 
  79     if (!tif
->tif_decodestatus
) { 
  80         sprintf(emsg
, "Sorry, requested compression method is not configured"); 
  83     switch (td
->td_bitspersample
) { 
  84     case 1: case 2: case 4: 
  88         sprintf(emsg
, "Sorry, can not handle images with %d-bit samples", 
  89             td
->td_bitspersample
); 
  92     colorchannels 
= td
->td_samplesperpixel 
- td
->td_extrasamples
; 
  93     if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &photometric
)) { 
  94         switch (colorchannels
) { 
  96             photometric 
= PHOTOMETRIC_MINISBLACK
; 
  99             photometric 
= PHOTOMETRIC_RGB
; 
 102             sprintf(emsg
, "Missing needed %s tag", photoTag
); 
 106     switch (photometric
) { 
 107     case PHOTOMETRIC_MINISWHITE
: 
 108     case PHOTOMETRIC_MINISBLACK
: 
 109     case PHOTOMETRIC_PALETTE
: 
 110         if (td
->td_planarconfig 
== PLANARCONFIG_CONTIG 
 
 111             && td
->td_samplesperpixel 
!= 1 
 112             && td
->td_bitspersample 
< 8 ) { 
 114                     "Sorry, can not handle contiguous data with %s=%d, " 
 115                     "and %s=%d and Bits/Sample=%d", 
 116                     photoTag
, photometric
, 
 117                     "Samples/pixel", td
->td_samplesperpixel
, 
 118                     td
->td_bitspersample
); 
 122         ** We should likely validate that any extra samples are either 
 123         ** to be ignored, or are alpha, and if alpha we should try to use 
 124         ** them.  But for now we won't bother with this.  
 127     case PHOTOMETRIC_YCBCR
: 
 128         if (td
->td_planarconfig 
!= PLANARCONFIG_CONTIG
) { 
 129             sprintf(emsg
, "Sorry, can not handle YCbCr images with %s=%d", 
 130                 "Planarconfiguration", td
->td_planarconfig
); 
 134     case PHOTOMETRIC_RGB
:  
 135         if (colorchannels 
< 3) { 
 136             sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d", 
 137                 "Color channels", colorchannels
); 
 141     case PHOTOMETRIC_SEPARATED
: 
 144                 TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
); 
 145                 if (inkset 
!= INKSET_CMYK
) { 
 147                             "Sorry, can not handle separated image with %s=%d", 
 151                 if (td
->td_samplesperpixel 
< 4) { 
 153                             "Sorry, can not handle separated image with %s=%d", 
 154                             "Samples/pixel", td
->td_samplesperpixel
); 
 159     case PHOTOMETRIC_LOGL
: 
 160         if (td
->td_compression 
!= COMPRESSION_SGILOG
) { 
 161             sprintf(emsg
, "Sorry, LogL data must have %s=%d", 
 162                 "Compression", COMPRESSION_SGILOG
); 
 166     case PHOTOMETRIC_LOGLUV
: 
 167         if (td
->td_compression 
!= COMPRESSION_SGILOG 
&& 
 168                 td
->td_compression 
!= COMPRESSION_SGILOG24
) { 
 169             sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d", 
 170                 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
); 
 173         if (td
->td_planarconfig 
!= PLANARCONFIG_CONTIG
) { 
 174             sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d", 
 175                 "Planarconfiguration", td
->td_planarconfig
); 
 179     case PHOTOMETRIC_CIELAB
: 
 182         sprintf(emsg
, "Sorry, can not handle image with %s=%d", 
 183             photoTag
, photometric
); 
 190 TIFFRGBAImageEnd(TIFFRGBAImage
* img
) 
 193                 _TIFFfree(img
->Map
), img
->Map 
= NULL
; 
 195                 _TIFFfree(img
->BWmap
), img
->BWmap 
= NULL
; 
 197                 _TIFFfree(img
->PALmap
), img
->PALmap 
= NULL
; 
 199                 _TIFFfree(img
->ycbcr
), img
->ycbcr 
= NULL
; 
 201                 _TIFFfree(img
->cielab
), img
->cielab 
= NULL
; 
 204                 _TIFFfree( img
->redcmap 
); 
 205                 _TIFFfree( img
->greencmap 
); 
 206                 _TIFFfree( img
->bluecmap 
); 
 211 isCCITTCompression(TIFF
* tif
) 
 214     TIFFGetField(tif
, TIFFTAG_COMPRESSION
, &compress
); 
 215     return (compress 
== COMPRESSION_CCITTFAX3 
|| 
 216             compress 
== COMPRESSION_CCITTFAX4 
|| 
 217             compress 
== COMPRESSION_CCITTRLE 
|| 
 218             compress 
== COMPRESSION_CCITTRLEW
); 
 222 TIFFRGBAImageBegin(TIFFRGBAImage
* img
, TIFF
* tif
, int stop
, char emsg
[1024]) 
 229     uint16 
*red_orig
, *green_orig
, *blue_orig
; 
 232     /* Initialize to normal values */ 
 236     img
->greencmap 
= NULL
; 
 237     img
->bluecmap 
= NULL
; 
 238     img
->req_orientation 
= ORIENTATION_BOTLEFT
;     /* It is the default */ 
 241     img
->stoponerr 
= stop
; 
 242     TIFFGetFieldDefaulted(tif
, TIFFTAG_BITSPERSAMPLE
, &img
->bitspersample
); 
 243     switch (img
->bitspersample
) { 
 244     case 1: case 2: case 4: 
 248         sprintf(emsg
, "Sorry, can not handle images with %d-bit samples", 
 253     TIFFGetFieldDefaulted(tif
, TIFFTAG_SAMPLESPERPIXEL
, &img
->samplesperpixel
); 
 254     TIFFGetFieldDefaulted(tif
, TIFFTAG_EXTRASAMPLES
, 
 255         &extrasamples
, &sampleinfo
); 
 256     if (extrasamples 
>= 1) 
 258         switch (sampleinfo
[0]) { 
 259         case EXTRASAMPLE_UNSPECIFIED
:   /* Workaround for some images without */ 
 260                 if (img
->samplesperpixel 
> 3)   /* correct info about alpha channel */ 
 261                         img
->alpha 
= EXTRASAMPLE_ASSOCALPHA
; 
 263         case EXTRASAMPLE_ASSOCALPHA
:    /* data is pre-multiplied */ 
 264         case EXTRASAMPLE_UNASSALPHA
:    /* data is not pre-multiplied */ 
 265                 img
->alpha 
= sampleinfo
[0]; 
 270 #ifdef DEFAULT_EXTRASAMPLE_AS_ALPHA 
 271     if( !TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
)) 
 272         img
->photometric 
= PHOTOMETRIC_MINISWHITE
; 
 274     if( extrasamples 
== 0  
 275         && img
->samplesperpixel 
== 4  
 276         && img
->photometric 
== PHOTOMETRIC_RGB 
) 
 278         img
->alpha 
= EXTRASAMPLE_ASSOCALPHA
; 
 283     colorchannels 
= img
->samplesperpixel 
- extrasamples
; 
 284     TIFFGetFieldDefaulted(tif
, TIFFTAG_COMPRESSION
, &compress
); 
 285     TIFFGetFieldDefaulted(tif
, TIFFTAG_PLANARCONFIG
, &planarconfig
); 
 286     if (!TIFFGetField(tif
, TIFFTAG_PHOTOMETRIC
, &img
->photometric
)) { 
 287         switch (colorchannels
) { 
 289             if (isCCITTCompression(tif
)) 
 290                 img
->photometric 
= PHOTOMETRIC_MINISWHITE
; 
 292                 img
->photometric 
= PHOTOMETRIC_MINISBLACK
; 
 295             img
->photometric 
= PHOTOMETRIC_RGB
; 
 298             sprintf(emsg
, "Missing needed %s tag", photoTag
); 
 302     switch (img
->photometric
) { 
 303     case PHOTOMETRIC_PALETTE
: 
 304         if (!TIFFGetField(tif
, TIFFTAG_COLORMAP
, 
 305             &red_orig
, &green_orig
, &blue_orig
)) { 
 306             sprintf(emsg
, "Missing required \"Colormap\" tag"); 
 310         /* copy the colormaps so we can modify them */ 
 311         n_color 
= (1L << img
->bitspersample
); 
 312         img
->redcmap 
= (uint16 
*) _TIFFmalloc(sizeof(uint16
)*n_color
); 
 313         img
->greencmap 
= (uint16 
*) _TIFFmalloc(sizeof(uint16
)*n_color
); 
 314         img
->bluecmap 
= (uint16 
*) _TIFFmalloc(sizeof(uint16
)*n_color
); 
 315         if( !img
->redcmap 
|| !img
->greencmap 
|| !img
->bluecmap 
) { 
 316             sprintf(emsg
, "Out of memory for colormap copy"); 
 320         _TIFFmemcpy( img
->redcmap
, red_orig
, n_color 
* 2 ); 
 321         _TIFFmemcpy( img
->greencmap
, green_orig
, n_color 
* 2 ); 
 322         _TIFFmemcpy( img
->bluecmap
, blue_orig
, n_color 
* 2 ); 
 325     case PHOTOMETRIC_MINISWHITE
: 
 326     case PHOTOMETRIC_MINISBLACK
: 
 327         if (planarconfig 
== PLANARCONFIG_CONTIG 
 
 328             && img
->samplesperpixel 
!= 1 
 329             && img
->bitspersample 
< 8 ) { 
 331                     "Sorry, can not handle contiguous data with %s=%d, " 
 332                     "and %s=%d and Bits/Sample=%d", 
 333                     photoTag
, img
->photometric
, 
 334                     "Samples/pixel", img
->samplesperpixel
, 
 339     case PHOTOMETRIC_YCBCR
: 
 340         if (planarconfig 
!= PLANARCONFIG_CONTIG
) { 
 341             sprintf(emsg
, "Sorry, can not handle YCbCr images with %s=%d", 
 342                 "Planarconfiguration", planarconfig
); 
 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 */ 
 350                 case COMPRESSION_OJPEG
: 
 351                 case COMPRESSION_JPEG
: 
 352                     TIFFSetField(tif
, TIFFTAG_JPEGCOLORMODE
, JPEGCOLORMODE_RGB
); 
 353                     img
->photometric 
= PHOTOMETRIC_RGB
; 
 361     case PHOTOMETRIC_RGB
:  
 362         if (colorchannels 
< 3) { 
 363             sprintf(emsg
, "Sorry, can not handle RGB image with %s=%d", 
 364                 "Color channels", colorchannels
); 
 368     case PHOTOMETRIC_SEPARATED
: { 
 370         TIFFGetFieldDefaulted(tif
, TIFFTAG_INKSET
, &inkset
); 
 371         if (inkset 
!= INKSET_CMYK
) { 
 372             sprintf(emsg
, "Sorry, can not handle separated image with %s=%d", 
 376         if (img
->samplesperpixel 
< 4) { 
 377             sprintf(emsg
, "Sorry, can not handle separated image with %s=%d", 
 378                 "Samples/pixel", img
->samplesperpixel
); 
 383     case PHOTOMETRIC_LOGL
: 
 384         if (compress 
!= COMPRESSION_SGILOG
) { 
 385             sprintf(emsg
, "Sorry, LogL data must have %s=%d", 
 386                 "Compression", COMPRESSION_SGILOG
); 
 389         TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
); 
 390         img
->photometric 
= PHOTOMETRIC_MINISBLACK
;      /* little white lie */ 
 391         img
->bitspersample 
= 8; 
 393     case PHOTOMETRIC_LOGLUV
: 
 394         if (compress 
!= COMPRESSION_SGILOG 
&& compress 
!= COMPRESSION_SGILOG24
) { 
 395             sprintf(emsg
, "Sorry, LogLuv data must have %s=%d or %d", 
 396                 "Compression", COMPRESSION_SGILOG
, COMPRESSION_SGILOG24
); 
 399         if (planarconfig 
!= PLANARCONFIG_CONTIG
) { 
 400             sprintf(emsg
, "Sorry, can not handle LogLuv images with %s=%d", 
 401                 "Planarconfiguration", planarconfig
); 
 404         TIFFSetField(tif
, TIFFTAG_SGILOGDATAFMT
, SGILOGDATAFMT_8BIT
); 
 405         img
->photometric 
= PHOTOMETRIC_RGB
;             /* little white lie */ 
 406         img
->bitspersample 
= 8; 
 408     case PHOTOMETRIC_CIELAB
: 
 411         sprintf(emsg
, "Sorry, can not handle image with %s=%d", 
 412             photoTag
, img
->photometric
); 
 420     TIFFGetField(tif
, TIFFTAG_IMAGEWIDTH
, &img
->width
); 
 421     TIFFGetField(tif
, TIFFTAG_IMAGELENGTH
, &img
->height
); 
 422     TIFFGetFieldDefaulted(tif
, TIFFTAG_ORIENTATION
, &img
->orientation
); 
 424         !(planarconfig 
== PLANARCONFIG_SEPARATE 
&& colorchannels 
> 1); 
 426         img
->get 
= TIFFIsTiled(tif
) ? gtTileContig 
: gtStripContig
; 
 427         if (!pickTileContigCase(img
)) { 
 428                 sprintf(emsg
, "Sorry, can not handle image"); 
 432         img
->get 
= TIFFIsTiled(tif
) ? gtTileSeparate 
: gtStripSeparate
; 
 433         if (!pickTileSeparateCase(img
)) { 
 434                 sprintf(emsg
, "Sorry, can not handle image"); 
 442 TIFFRGBAImageGet(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
) 
 444     if (img
->get 
== NULL
) { 
 445                 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "No \"get\" routine setup"); 
 448         if (img
->put
.any 
== NULL
) { 
 449                 TIFFErrorExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), 
 450                 "No \"put\" routine setupl; probably can not handle image format"); 
 453     return (*img
->get
)(img
, raster
, w
, h
); 
 457  * Read the specified image into an ABGR-format rastertaking in account 
 458  * specified orientation. 
 461 TIFFReadRGBAImageOriented(TIFF
* tif
, 
 462                           uint32 rwidth
, uint32 rheight
, uint32
* raster
, 
 463                           int orientation
, int stop
) 
 465     char emsg
[1024] = ""; 
 469         if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, stop
, emsg
)) { 
 470                 img
.req_orientation 
= orientation
; 
 471                 /* XXX verify rwidth and rheight against width and height */ 
 472                 ok 
= TIFFRGBAImageGet(&img
, raster
+(rheight
-img
.height
)*rwidth
, 
 474                 TIFFRGBAImageEnd(&img
); 
 476                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), emsg
); 
 483  * Read the specified image into an ABGR-format raster. Use bottom left 
 484  * origin for raster by default. 
 487 TIFFReadRGBAImage(TIFF
* tif
, 
 488                   uint32 rwidth
, uint32 rheight
, uint32
* raster
, int stop
) 
 490         return TIFFReadRGBAImageOriented(tif
, rwidth
, rheight
, raster
, 
 491                                          ORIENTATION_BOTLEFT
, stop
); 
 495 setorientation(TIFFRGBAImage
* img
) 
 497         switch (img
->orientation
) { 
 498                 case ORIENTATION_TOPLEFT
: 
 499                 case ORIENTATION_LEFTTOP
: 
 500                         if (img
->req_orientation 
== ORIENTATION_TOPRIGHT 
|| 
 501                             img
->req_orientation 
== ORIENTATION_RIGHTTOP
) 
 502                                 return FLIP_HORIZONTALLY
; 
 503                         else if (img
->req_orientation 
== ORIENTATION_BOTRIGHT 
|| 
 504                             img
->req_orientation 
== ORIENTATION_RIGHTBOT
) 
 505                                 return FLIP_HORIZONTALLY 
| FLIP_VERTICALLY
; 
 506                         else if (img
->req_orientation 
== ORIENTATION_BOTLEFT 
|| 
 507                             img
->req_orientation 
== ORIENTATION_LEFTBOT
) 
 508                                 return FLIP_VERTICALLY
; 
 511                 case ORIENTATION_TOPRIGHT
: 
 512                 case ORIENTATION_RIGHTTOP
: 
 513                         if (img
->req_orientation 
== ORIENTATION_TOPLEFT 
|| 
 514                             img
->req_orientation 
== ORIENTATION_LEFTTOP
) 
 515                                 return FLIP_HORIZONTALLY
; 
 516                         else if (img
->req_orientation 
== ORIENTATION_BOTRIGHT 
|| 
 517                             img
->req_orientation 
== ORIENTATION_RIGHTBOT
) 
 518                                 return FLIP_VERTICALLY
; 
 519                         else if (img
->req_orientation 
== ORIENTATION_BOTLEFT 
|| 
 520                             img
->req_orientation 
== ORIENTATION_LEFTBOT
) 
 521                                 return FLIP_HORIZONTALLY 
| FLIP_VERTICALLY
; 
 524                 case ORIENTATION_BOTRIGHT
: 
 525                 case ORIENTATION_RIGHTBOT
: 
 526                         if (img
->req_orientation 
== ORIENTATION_TOPLEFT 
|| 
 527                             img
->req_orientation 
== ORIENTATION_LEFTTOP
) 
 528                                 return FLIP_HORIZONTALLY 
| FLIP_VERTICALLY
; 
 529                         else if (img
->req_orientation 
== ORIENTATION_TOPRIGHT 
|| 
 530                             img
->req_orientation 
== ORIENTATION_RIGHTTOP
) 
 531                                 return FLIP_VERTICALLY
; 
 532                         else if (img
->req_orientation 
== ORIENTATION_BOTLEFT 
|| 
 533                             img
->req_orientation 
== ORIENTATION_LEFTBOT
) 
 534                                 return FLIP_HORIZONTALLY
; 
 537                 case ORIENTATION_BOTLEFT
: 
 538                 case ORIENTATION_LEFTBOT
: 
 539                         if (img
->req_orientation 
== ORIENTATION_TOPLEFT 
|| 
 540                             img
->req_orientation 
== ORIENTATION_LEFTTOP
) 
 541                                 return FLIP_VERTICALLY
; 
 542                         else if (img
->req_orientation 
== ORIENTATION_TOPRIGHT 
|| 
 543                             img
->req_orientation 
== ORIENTATION_RIGHTTOP
) 
 544                                 return FLIP_HORIZONTALLY 
| FLIP_VERTICALLY
; 
 545                         else if (img
->req_orientation 
== ORIENTATION_BOTRIGHT 
|| 
 546                             img
->req_orientation 
== ORIENTATION_RIGHTBOT
) 
 547                                 return FLIP_HORIZONTALLY
; 
 550                 default:        /* NOTREACHED */ 
 556  * Get an tile-organized image that has 
 557  *      PlanarConfiguration contiguous if SamplesPerPixel > 1 
 559  *      SamplesPerPixel == 1 
 562 gtTileContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
) 
 564     TIFF
* tif 
= img
->tif
; 
 565     tileContigRoutine put 
= img
->put
.contig
; 
 566     uint32 col
, row
, y
, rowstoread
; 
 570     int32 fromskew
, toskew
; 
 574     buf 
= (unsigned char*) _TIFFmalloc(TIFFTileSize(tif
)); 
 576                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for tile buffer"); 
 579     _TIFFmemset(buf
, 0, TIFFTileSize(tif
)); 
 580     TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
); 
 581     TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
); 
 583     flip 
= setorientation(img
); 
 584     if (flip 
& FLIP_VERTICALLY
) { 
 586             toskew 
= -(int32
)(tw 
+ w
); 
 590             toskew 
= -(int32
)(tw 
- w
); 
 593     for (row 
= 0; row 
< h
; row 
+= nrow
) 
 595         rowstoread 
= th 
- (row 
+ img
->row_offset
) % th
; 
 596         nrow 
= (row 
+ rowstoread 
> h 
? h 
- row 
: rowstoread
); 
 597         for (col 
= 0; col 
< w
; col 
+= tw
)  
 599             if (TIFFReadTile(tif
, buf
, col
+img
->col_offset
, 
 600                              row
+img
->row_offset
, 0, 0) < 0 && img
->stoponerr
) 
 606             pos 
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
); 
 611                  * Tile is clipped horizontally.  Calculate 
 612                  * visible portion and skewing factors. 
 614                 uint32 npix 
= w 
- col
; 
 615                 fromskew 
= tw 
- npix
; 
 616                 (*put
)(img
, raster
+y
*w
+col
, col
, y
, 
 617                        npix
, nrow
, fromskew
, toskew 
+ fromskew
, buf 
+ pos
); 
 621                 (*put
)(img
, raster
+y
*w
+col
, col
, y
, tw
, nrow
, 0, toskew
, buf 
+ pos
); 
 625         y 
+= (flip 
& FLIP_VERTICALLY 
? -(int32
) nrow 
: (int32
) nrow
); 
 629     if (flip 
& FLIP_HORIZONTALLY
) { 
 632             for (line 
= 0; line 
< h
; line
++) { 
 633                     uint32 
*left 
= raster 
+ (line 
* w
); 
 634                     uint32 
*right 
= left 
+ w 
- 1; 
 636                     while ( left 
< right 
) { 
 649  * Get an tile-organized image that has 
 650  *       SamplesPerPixel > 1 
 651  *       PlanarConfiguration separated 
 652  * We assume that all such images are RGB. 
 655 gtTileSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
) 
 657     TIFF
* tif 
= img
->tif
; 
 658     tileSeparateRoutine put 
= img
->put
.separate
; 
 659     uint32 col
, row
, y
, rowstoread
; 
 668     int32 fromskew
, toskew
; 
 669     int alpha 
= img
->alpha
; 
 673     tilesize 
= TIFFTileSize(tif
); 
 674     buf 
= (unsigned char*) _TIFFmalloc(4*tilesize
); 
 676                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for tile buffer"); 
 679     _TIFFmemset(buf
, 0, 4*tilesize
); 
 685         _TIFFmemset(a
, 0xff, tilesize
); 
 686     TIFFGetField(tif
, TIFFTAG_TILEWIDTH
, &tw
); 
 687     TIFFGetField(tif
, TIFFTAG_TILELENGTH
, &th
); 
 689     flip 
= setorientation(img
); 
 690     if (flip 
& FLIP_VERTICALLY
) { 
 692             toskew 
= -(int32
)(tw 
+ w
); 
 696             toskew 
= -(int32
)(tw 
- w
); 
 699     for (row 
= 0; row 
< h
; row 
+= nrow
)  
 701         rowstoread 
= th 
- (row 
+ img
->row_offset
) % th
; 
 702         nrow 
= (row 
+ rowstoread 
> h 
? h 
- row 
: rowstoread
); 
 703         for (col 
= 0; col 
< w
; col 
+= tw
)  
 705             if (TIFFReadTile(tif
, r
, col
+img
->col_offset
, 
 706                              row
+img
->row_offset
,0,0) < 0 && img
->stoponerr
) 
 711             if (TIFFReadTile(tif
, g
, col
+img
->col_offset
, 
 712                              row
+img
->row_offset
,0,1) < 0 && img
->stoponerr
) 
 717             if (TIFFReadTile(tif
, b
, col
+img
->col_offset
, 
 718                              row
+img
->row_offset
,0,2) < 0 && img
->stoponerr
) 
 723             if (alpha 
&& TIFFReadTile(tif
,a
,col
+img
->col_offset
, 
 724                                       row
+img
->row_offset
,0,3) < 0 && img
->stoponerr
) 
 730             pos 
= ((row
+img
->row_offset
) % th
) * TIFFTileRowSize(tif
); 
 735                  * Tile is clipped horizontally.  Calculate 
 736                  * visible portion and skewing factors. 
 738                 uint32 npix 
= w 
- col
; 
 739                 fromskew 
= tw 
- npix
; 
 740                 (*put
)(img
, raster
+y
*w
+col
, col
, y
, 
 741                        npix
, nrow
, fromskew
, toskew 
+ fromskew
,  
 742                        r 
+ pos
, g 
+ pos
, b 
+ pos
, a 
+ pos
); 
 744                 (*put
)(img
, raster
+y
*w
+col
, col
, y
, 
 745                        tw
, nrow
, 0, toskew
, r 
+ pos
, g 
+ pos
, b 
+ pos
, a 
+ pos
); 
 749         y 
+= (flip 
& FLIP_VERTICALLY 
?-(int32
) nrow 
: (int32
) nrow
); 
 752     if (flip 
& FLIP_HORIZONTALLY
) { 
 755             for (line 
= 0; line 
< h
; line
++) { 
 756                     uint32 
*left 
= raster 
+ (line 
* w
); 
 757                     uint32 
*right 
= left 
+ w 
- 1; 
 759                     while ( left 
< right 
) { 
 773  * Get a strip-organized image that has 
 774  *      PlanarConfiguration contiguous if SamplesPerPixel > 1 
 776  *      SamplesPerPixel == 1 
 779 gtStripContig(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
) 
 781     TIFF
* tif 
= img
->tif
; 
 782     tileContigRoutine put 
= img
->put
.contig
; 
 783     uint32 row
, y
, nrow
, rowstoread
; 
 787     uint32 imagewidth 
= img
->width
; 
 789     int32 fromskew
, toskew
; 
 792     buf 
= (unsigned char*) _TIFFmalloc(TIFFStripSize(tif
)); 
 794                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for strip buffer"); 
 797     _TIFFmemset(buf
, 0, TIFFStripSize(tif
)); 
 799     flip 
= setorientation(img
); 
 800     if (flip 
& FLIP_VERTICALLY
) { 
 802             toskew 
= -(int32
)(w 
+ w
); 
 805             toskew 
= -(int32
)(w 
- w
); 
 808     TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
); 
 809     scanline 
= TIFFScanlineSize(tif
); 
 810     fromskew 
= (w 
< imagewidth 
? imagewidth 
- w 
: 0); 
 811     for (row 
= 0; row 
< h
; row 
+= nrow
)  
 813         rowstoread 
= rowsperstrip 
- (row 
+ img
->row_offset
) % rowsperstrip
; 
 814         nrow 
= (row 
+ rowstoread 
> h 
? h 
- row 
: rowstoread
); 
 815         if (TIFFReadEncodedStrip(tif
, 
 816                                  TIFFComputeStrip(tif
,row
+img
->row_offset
, 0), 
 818                                  ((row 
+ img
->row_offset
)%rowsperstrip 
+ nrow
) * scanline
) < 0 
 825         pos 
= ((row 
+ img
->row_offset
) % rowsperstrip
) * scanline
; 
 826         (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, buf 
+ pos
); 
 827         y 
+= (flip 
& FLIP_VERTICALLY 
? -(int32
) nrow 
: (int32
) nrow
); 
 830     if (flip 
& FLIP_HORIZONTALLY
) { 
 833             for (line 
= 0; line 
< h
; line
++) { 
 834                     uint32 
*left 
= raster 
+ (line 
* w
); 
 835                     uint32 
*right 
= left 
+ w 
- 1; 
 837                     while ( left 
< right 
) { 
 851  * Get a strip-organized image with 
 852  *       SamplesPerPixel > 1 
 853  *       PlanarConfiguration separated 
 854  * We assume that all such images are RGB. 
 857 gtStripSeparate(TIFFRGBAImage
* img
, uint32
* raster
, uint32 w
, uint32 h
) 
 859     TIFF
* tif 
= img
->tif
; 
 860     tileSeparateRoutine put 
= img
->put
.separate
; 
 862     unsigned char *r
, *g
, *b
, *a
; 
 863     uint32 row
, y
, nrow
, rowstoread
; 
 866     uint32 rowsperstrip
, offset_row
; 
 867     uint32 imagewidth 
= img
->width
; 
 869     int32 fromskew
, toskew
; 
 870     int alpha 
= img
->alpha
; 
 873     stripsize 
= TIFFStripSize(tif
); 
 874     r 
= buf 
= (unsigned char *)_TIFFmalloc(4*stripsize
); 
 876                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), "No space for tile buffer"); 
 879     _TIFFmemset(buf
, 0, 4*stripsize
); 
 884         _TIFFmemset(a
, 0xff, stripsize
); 
 886     flip 
= setorientation(img
); 
 887     if (flip 
& FLIP_VERTICALLY
) { 
 889             toskew 
= -(int32
)(w 
+ w
); 
 893             toskew 
= -(int32
)(w 
- w
); 
 896     TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
); 
 897     scanline 
= TIFFScanlineSize(tif
); 
 898     fromskew 
= (w 
< imagewidth 
? imagewidth 
- w 
: 0); 
 899     for (row 
= 0; row 
< h
; row 
+= nrow
)  
 901         rowstoread 
= rowsperstrip 
- (row 
+ img
->row_offset
) % rowsperstrip
;      
 902         nrow 
= (row 
+ rowstoread 
> h 
? h 
- row 
: rowstoread
); 
 903         offset_row 
= row 
+ img
->row_offset
; 
 904         if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 0), 
 905                                  r
, ((row 
+ img
->row_offset
)%rowsperstrip 
+ nrow
) * scanline
) < 0  
 911         if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 1), 
 912                                  g
, ((row 
+ img
->row_offset
)%rowsperstrip 
+ nrow
) * scanline
) < 0  
 918         if (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 2), 
 919                                  b
, ((row 
+ img
->row_offset
)%rowsperstrip 
+ nrow
) * scanline
) < 0  
 926             (TIFFReadEncodedStrip(tif
, TIFFComputeStrip(tif
, offset_row
, 3), 
 927                                   a
, ((row 
+ img
->row_offset
)%rowsperstrip 
+ nrow
) * scanline
) < 0  
 934         pos 
= ((row 
+ img
->row_offset
) % rowsperstrip
) * scanline
; 
 935         (*put
)(img
, raster
+y
*w
, 0, y
, w
, nrow
, fromskew
, toskew
, r 
+ pos
, g 
+ pos
,  
 937         y 
+= (flip 
& FLIP_VERTICALLY 
? -(int32
) nrow 
: (int32
) nrow
); 
 940     if (flip 
& FLIP_HORIZONTALLY
) { 
 943             for (line 
= 0; line 
< h
; line
++) { 
 944                     uint32 
*left 
= raster 
+ (line 
* w
); 
 945                     uint32 
*right 
= left 
+ w 
- 1; 
 947                     while ( left 
< right 
) { 
 961  * The following routines move decoded data returned 
 962  * from the TIFF library into rasters filled with packed 
 963  * ABGR pixels (i.e. suitable for passing to lrecwrite.) 
 965  * The routines have been created according to the most 
 966  * important cases and optimized.  pickTileContigCase and 
 967  * pickTileSeparateCase analyze the parameters and select 
 968  * the appropriate "put" routine to use. 
 970 #define REPEAT8(op)     REPEAT4(op); REPEAT4(op) 
 971 #define REPEAT4(op)     REPEAT2(op); REPEAT2(op) 
 972 #define REPEAT2(op)     op; op 
 973 #define CASE8(x,op)                     \ 
 975     case 7: op; case 6: op; case 5: op; \ 
 976     case 4: op; case 3: op; case 2: op; \ 
 979 #define CASE4(x,op)     switch (x) { case 3: op; case 2: op; case 1: op; } 
 982 #define UNROLL8(w, op1, op2) {          \ 
 984     for (_x = w; _x >= 8; _x -= 8) {    \ 
 993 #define UNROLL4(w, op1, op2) {          \ 
 995     for (_x = w; _x >= 4; _x -= 4) {    \ 
1004 #define UNROLL2(w, op1, op2) {          \ 
1006     for (_x = w; _x >= 2; _x -= 2) {    \ 
1016 #define SKEW(r,g,b,skew)        { r += skew; g += skew; b += skew; } 
1017 #define SKEW4(r,g,b,a,skew)     { r += skew; g += skew; b += skew; a+= skew; } 
1019 #define A1 (((uint32)0xffL)<<24) 
1020 #define PACK(r,g,b)     \ 
1021         ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|A1) 
1022 #define PACK4(r,g,b,a)  \ 
1023         ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|((uint32)(a)<<24)) 
1024 #define W2B(v) (((v)>>8)&0xff) 
1025 #define PACKW(r,g,b)    \ 
1026         ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|A1) 
1027 #define PACKW4(r,g,b,a) \ 
1028         ((uint32)W2B(r)|((uint32)W2B(g)<<8)|((uint32)W2B(b)<<16)|((uint32)W2B(a)<<24)) 
1030 #define DECLAREContigPutFunc(name) \ 
1032     TIFFRGBAImage* img, \ 
1034     uint32 x, uint32 y, \ 
1035     uint32 w, uint32 h, \ 
1036     int32 fromskew, int32 toskew, \ 
1041  * 8-bit palette => colormap/RGB 
1043 DECLAREContigPutFunc(put8bitcmaptile
) 
1045     uint32
** PALmap 
= img
->PALmap
; 
1046     int samplesperpixel 
= img
->samplesperpixel
; 
1050         for (x 
= w
; x
-- > 0;) 
1052             *cp
++ = PALmap
[*pp
][0]; 
1053             pp 
+= samplesperpixel
; 
1061  * 4-bit palette => colormap/RGB 
1063 DECLAREContigPutFunc(put4bitcmaptile
) 
1065     uint32
** PALmap 
= img
->PALmap
; 
1071         UNROLL2(w
, bw 
= PALmap
[*pp
++], *cp
++ = *bw
++); 
1078  * 2-bit palette => colormap/RGB 
1080 DECLAREContigPutFunc(put2bitcmaptile
) 
1082     uint32
** PALmap 
= img
->PALmap
; 
1088         UNROLL4(w
, bw 
= PALmap
[*pp
++], *cp
++ = *bw
++); 
1095  * 1-bit palette => colormap/RGB 
1097 DECLAREContigPutFunc(put1bitcmaptile
) 
1099     uint32
** PALmap 
= img
->PALmap
; 
1105         UNROLL8(w
, bw 
= PALmap
[*pp
++], *cp
++ = *bw
++); 
1112  * 8-bit greyscale => colormap/RGB 
1114 DECLAREContigPutFunc(putgreytile
) 
1116     int samplesperpixel 
= img
->samplesperpixel
; 
1117     uint32
** BWmap 
= img
->BWmap
; 
1121         for (x 
= w
; x
-- > 0;) 
1123             *cp
++ = BWmap
[*pp
][0]; 
1124             pp 
+= samplesperpixel
; 
1132  * 16-bit greyscale => colormap/RGB 
1134 DECLAREContigPutFunc(put16bitbwtile
) 
1136     int samplesperpixel 
= img
->samplesperpixel
; 
1137     uint32
** BWmap 
= img
->BWmap
; 
1141         uint16 
*wp 
= (uint16 
*) pp
; 
1143         for (x 
= w
; x
-- > 0;) 
1145             /* use high order byte of 16bit value */ 
1147             *cp
++ = BWmap
[*wp 
>> 8][0]; 
1148             pp 
+= 2 * samplesperpixel
; 
1149             wp 
+= samplesperpixel
; 
1157  * 1-bit bilevel => colormap/RGB 
1159 DECLAREContigPutFunc(put1bitbwtile
) 
1161     uint32
** BWmap 
= img
->BWmap
; 
1167         UNROLL8(w
, bw 
= BWmap
[*pp
++], *cp
++ = *bw
++); 
1174  * 2-bit greyscale => colormap/RGB 
1176 DECLAREContigPutFunc(put2bitbwtile
) 
1178     uint32
** BWmap 
= img
->BWmap
; 
1184         UNROLL4(w
, bw 
= BWmap
[*pp
++], *cp
++ = *bw
++); 
1191  * 4-bit greyscale => colormap/RGB 
1193 DECLAREContigPutFunc(put4bitbwtile
) 
1195     uint32
** BWmap 
= img
->BWmap
; 
1201         UNROLL2(w
, bw 
= BWmap
[*pp
++], *cp
++ = *bw
++); 
1208  * 8-bit packed samples, no Map => RGB 
1210 DECLAREContigPutFunc(putRGBcontig8bittile
) 
1212     int samplesperpixel 
= img
->samplesperpixel
; 
1215     fromskew 
*= samplesperpixel
; 
1218             *cp
++ = PACK(pp
[0], pp
[1], pp
[2]); 
1219             pp 
+= samplesperpixel
); 
1226  * 8-bit packed samples, w/ Map => RGB 
1228 DECLAREContigPutFunc(putRGBcontig8bitMaptile
) 
1230     TIFFRGBValue
* Map 
= img
->Map
; 
1231     int samplesperpixel 
= img
->samplesperpixel
; 
1234     fromskew 
*= samplesperpixel
; 
1236         for (x 
= w
; x
-- > 0;) { 
1237             *cp
++ = PACK(Map
[pp
[0]], Map
[pp
[1]], Map
[pp
[2]]); 
1238             pp 
+= samplesperpixel
; 
1246  * 8-bit packed samples => RGBA w/ associated alpha 
1247  * (known to have Map == NULL) 
1249 DECLAREContigPutFunc(putRGBAAcontig8bittile
) 
1251     int samplesperpixel 
= img
->samplesperpixel
; 
1254     fromskew 
*= samplesperpixel
; 
1257             *cp
++ = PACK4(pp
[0], pp
[1], pp
[2], pp
[3]); 
1258             pp 
+= samplesperpixel
); 
1265  * 8-bit packed samples => RGBA w/ unassociated alpha 
1266  * (known to have Map == NULL) 
1268 DECLAREContigPutFunc(putRGBUAcontig8bittile
) 
1270     int samplesperpixel 
= img
->samplesperpixel
; 
1273     fromskew 
*= samplesperpixel
; 
1276         for (x 
= w
; x
-- > 0;) { 
1278             r 
= (pp
[0] * a
) / 255; 
1279             g 
= (pp
[1] * a
) / 255; 
1280             b 
= (pp
[2] * a
) / 255; 
1281             *cp
++ = PACK4(r
,g
,b
,a
); 
1282             pp 
+= samplesperpixel
; 
1290  * 16-bit packed samples => RGB 
1292 DECLAREContigPutFunc(putRGBcontig16bittile
) 
1294     int samplesperpixel 
= img
->samplesperpixel
; 
1295     uint16 
*wp 
= (uint16 
*)pp
; 
1298     fromskew 
*= samplesperpixel
; 
1300         for (x 
= w
; x
-- > 0;) { 
1301             *cp
++ = PACKW(wp
[0], wp
[1], wp
[2]); 
1302             wp 
+= samplesperpixel
; 
1310  * 16-bit packed samples => RGBA w/ associated alpha 
1311  * (known to have Map == NULL) 
1313 DECLAREContigPutFunc(putRGBAAcontig16bittile
) 
1315     int samplesperpixel 
= img
->samplesperpixel
; 
1316     uint16 
*wp 
= (uint16 
*)pp
; 
1319     fromskew 
*= samplesperpixel
; 
1321         for (x 
= w
; x
-- > 0;) { 
1322             *cp
++ = PACKW4(wp
[0], wp
[1], wp
[2], wp
[3]); 
1323             wp 
+= samplesperpixel
; 
1331  * 16-bit packed samples => RGBA w/ unassociated alpha 
1332  * (known to have Map == NULL) 
1334 DECLAREContigPutFunc(putRGBUAcontig16bittile
) 
1336     int samplesperpixel 
= img
->samplesperpixel
; 
1337     uint16 
*wp 
= (uint16 
*)pp
; 
1340     fromskew 
*= samplesperpixel
; 
1344          * We shift alpha down four bits just in case unsigned 
1345          * arithmetic doesn't handle the full range. 
1346          * We still have plenty of accuracy, since the output is 8 bits. 
1347          * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff) 
1348          * Since we want r*a * 0xff for eight bit output, 
1349          * we divide by (0xffff * 0xfff) / 0xff == 0x10eff. 
1351         for (x 
= w
; x
-- > 0;) { 
1353             r 
= (wp
[0] * a
) / 0x10eff; 
1354             g 
= (wp
[1] * a
) / 0x10eff; 
1355             b 
= (wp
[2] * a
) / 0x10eff; 
1356             *cp
++ = PACK4(r
,g
,b
,a
); 
1357             wp 
+= samplesperpixel
; 
1365  * 8-bit packed CMYK samples w/o Map => RGB 
1367  * NB: The conversion of CMYK->RGB is *very* crude. 
1369 DECLAREContigPutFunc(putRGBcontig8bitCMYKtile
) 
1371     int samplesperpixel 
= img
->samplesperpixel
; 
1375     fromskew 
*= samplesperpixel
; 
1379             r 
= (k
*(255-pp
[0]))/255; 
1380             g 
= (k
*(255-pp
[1]))/255; 
1381             b 
= (k
*(255-pp
[2]))/255; 
1382             *cp
++ = PACK(r
, g
, b
); 
1383             pp 
+= samplesperpixel
); 
1390  * 8-bit packed CMYK samples w/Map => RGB 
1392  * NB: The conversion of CMYK->RGB is *very* crude. 
1394 DECLAREContigPutFunc(putRGBcontig8bitCMYKMaptile
) 
1396     int samplesperpixel 
= img
->samplesperpixel
; 
1397     TIFFRGBValue
* Map 
= img
->Map
; 
1401     fromskew 
*= samplesperpixel
; 
1403         for (x 
= w
; x
-- > 0;) { 
1405             r 
= (k
*(255-pp
[0]))/255; 
1406             g 
= (k
*(255-pp
[1]))/255; 
1407             b 
= (k
*(255-pp
[2]))/255; 
1408             *cp
++ = PACK(Map
[r
], Map
[g
], Map
[b
]); 
1409             pp 
+= samplesperpixel
; 
1416 #define DECLARESepPutFunc(name) \ 
1418     TIFFRGBAImage* img,\ 
1420     uint32 x, uint32 y, \ 
1421     uint32 w, uint32 h,\ 
1422     int32 fromskew, int32 toskew,\ 
1423     unsigned char* r, unsigned char* g, unsigned char* b, unsigned char* a\ 
1427  * 8-bit unpacked samples => RGB 
1429 DECLARESepPutFunc(putRGBseparate8bittile
) 
1431     (void) img
; (void) x
; (void) y
; (void) a
; 
1433         UNROLL8(w
, NOP
, *cp
++ = PACK(*r
++, *g
++, *b
++)); 
1434         SKEW(r
, g
, b
, fromskew
); 
1440  * 8-bit unpacked samples => RGB 
1442 DECLARESepPutFunc(putRGBseparate8bitMaptile
) 
1444     TIFFRGBValue
* Map 
= img
->Map
; 
1448         for (x 
= w
; x 
> 0; x
--) 
1449             *cp
++ = PACK(Map
[*r
++], Map
[*g
++], Map
[*b
++]); 
1450         SKEW(r
, g
, b
, fromskew
); 
1456  * 8-bit unpacked samples => RGBA w/ associated alpha 
1458 DECLARESepPutFunc(putRGBAAseparate8bittile
) 
1460     (void) img
; (void) x
; (void) y
; 
1462         UNROLL8(w
, NOP
, *cp
++ = PACK4(*r
++, *g
++, *b
++, *a
++)); 
1463         SKEW4(r
, g
, b
, a
, fromskew
); 
1469  * 8-bit unpacked samples => RGBA w/ unassociated alpha 
1471 DECLARESepPutFunc(putRGBUAseparate8bittile
) 
1473     (void) img
; (void) y
; 
1475         uint32 rv
, gv
, bv
, av
; 
1476         for (x 
= w
; x
-- > 0;) { 
1478             rv 
= (*r
++ * av
) / 255; 
1479             gv 
= (*g
++ * av
) / 255; 
1480             bv 
= (*b
++ * av
) / 255; 
1481             *cp
++ = PACK4(rv
,gv
,bv
,av
); 
1483         SKEW4(r
, g
, b
, a
, fromskew
); 
1489  * 16-bit unpacked samples => RGB 
1491 DECLARESepPutFunc(putRGBseparate16bittile
) 
1493     uint16 
*wr 
= (uint16
*) r
; 
1494     uint16 
*wg 
= (uint16
*) g
; 
1495     uint16 
*wb 
= (uint16
*) b
; 
1497     (void) img
; (void) y
; (void) a
; 
1499         for (x 
= 0; x 
< w
; x
++) 
1500             *cp
++ = PACKW(*wr
++, *wg
++, *wb
++); 
1501         SKEW(wr
, wg
, wb
, fromskew
); 
1507  * 16-bit unpacked samples => RGBA w/ associated alpha 
1509 DECLARESepPutFunc(putRGBAAseparate16bittile
) 
1511     uint16 
*wr 
= (uint16
*) r
; 
1512     uint16 
*wg 
= (uint16
*) g
; 
1513     uint16 
*wb 
= (uint16
*) b
; 
1514     uint16 
*wa 
= (uint16
*) a
; 
1516     (void) img
; (void) y
; 
1518         for (x 
= 0; x 
< w
; x
++) 
1519             *cp
++ = PACKW4(*wr
++, *wg
++, *wb
++, *wa
++); 
1520         SKEW4(wr
, wg
, wb
, wa
, fromskew
); 
1526  * 16-bit unpacked samples => RGBA w/ unassociated alpha 
1528 DECLARESepPutFunc(putRGBUAseparate16bittile
) 
1530     uint16 
*wr 
= (uint16
*) r
; 
1531     uint16 
*wg 
= (uint16
*) g
; 
1532     uint16 
*wb 
= (uint16
*) b
; 
1533     uint16 
*wa 
= (uint16
*) a
; 
1535     (void) img
; (void) y
; 
1539          * We shift alpha down four bits just in case unsigned 
1540          * arithmetic doesn't handle the full range. 
1541          * We still have plenty of accuracy, since the output is 8 bits. 
1542          * So we have (r * 0xffff) * (a * 0xfff)) = r*a * (0xffff*0xfff) 
1543          * Since we want r*a * 0xff for eight bit output, 
1544          * we divide by (0xffff * 0xfff) / 0xff == 0x10eff. 
1546         for (x 
= w
; x
-- > 0;) { 
1548             r 
= (*wr
++ * a
) / 0x10eff; 
1549             g 
= (*wg
++ * a
) / 0x10eff; 
1550             b 
= (*wb
++ * a
) / 0x10eff; 
1551             *cp
++ = PACK4(r
,g
,b
,a
); 
1553         SKEW4(wr
, wg
, wb
, wa
, fromskew
); 
1559  * 8-bit packed CIE L*a*b 1976 samples => RGB 
1561 DECLAREContigPutFunc(putcontig8bitCIELab
) 
1568                 for (x 
= w
; x
-- > 0;) { 
1569                         TIFFCIELabToXYZ(img
->cielab
, 
1570                                         (unsigned char)pp
[0], 
1574                         TIFFXYZToRGB(img
->cielab
, X
, Y
, Z
, &r
, &g
, &b
); 
1575                         *cp
++ = PACK(r
, g
, b
); 
1584  * YCbCr -> RGB conversion and packing routines. 
1587 #define YCbCrtoRGB(dst, Y) {                                            \ 
1589         TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b);            \ 
1590         dst = PACK(r, g, b);                                            \ 
1594  * 8-bit packed YCbCr samples => RGB  
1595  * This function is generic for different sampling sizes,  
1596  * and can handle blocks sizes that aren't multiples of the 
1597  * sampling size.  However, it is substantially less optimized 
1598  * than the specific sampling cases.  It is used as a fallback 
1599  * for difficult blocks. 
1602 static void putcontig8bitYCbCrGenericTile(  
1607     int32 fromskew
, int32 toskew
,  
1613     uint32
* cp1 
= cp
+w
+toskew
; 
1614     uint32
* cp2 
= cp1
+w
+toskew
; 
1615     uint32
* cp3 
= cp2
+w
+toskew
; 
1616     int32 incr 
= 3*w
+4*toskew
; 
1618     int     group_size 
= v_group 
* h_group 
+ 2; 
1621     fromskew 
= (fromskew 
* group_size
) / h_group
; 
1623     for( yy 
= 0; yy 
< h
; yy
++ ) 
1625         unsigned char *pp_line
; 
1626         int     y_line_group 
= yy 
/ v_group
; 
1627         int     y_remainder 
= yy 
- y_line_group 
* v_group
; 
1629         pp_line 
= pp 
+ v_line_group 
*  
1632         for( xx 
= 0; xx 
< w
; xx
++ ) 
1637     for (; h 
>= 4; h 
-= 4) { 
1643             YCbCrtoRGB(cp 
[0], pp
[ 0]); 
1644             YCbCrtoRGB(cp 
[1], pp
[ 1]); 
1645             YCbCrtoRGB(cp 
[2], pp
[ 2]); 
1646             YCbCrtoRGB(cp 
[3], pp
[ 3]); 
1647             YCbCrtoRGB(cp1
[0], pp
[ 4]); 
1648             YCbCrtoRGB(cp1
[1], pp
[ 5]); 
1649             YCbCrtoRGB(cp1
[2], pp
[ 6]); 
1650             YCbCrtoRGB(cp1
[3], pp
[ 7]); 
1651             YCbCrtoRGB(cp2
[0], pp
[ 8]); 
1652             YCbCrtoRGB(cp2
[1], pp
[ 9]); 
1653             YCbCrtoRGB(cp2
[2], pp
[10]); 
1654             YCbCrtoRGB(cp2
[3], pp
[11]); 
1655             YCbCrtoRGB(cp3
[0], pp
[12]); 
1656             YCbCrtoRGB(cp3
[1], pp
[13]); 
1657             YCbCrtoRGB(cp3
[2], pp
[14]); 
1658             YCbCrtoRGB(cp3
[3], pp
[15]); 
1660             cp 
+= 4, cp1 
+= 4, cp2 
+= 4, cp3 
+= 4; 
1663         cp 
+= incr
, cp1 
+= incr
, cp2 
+= incr
, cp3 
+= incr
; 
1670  * 8-bit packed YCbCr samples w/ 4,4 subsampling => RGB 
1672 DECLAREContigPutFunc(putcontig8bitYCbCr44tile
) 
1674     uint32
* cp1 
= cp
+w
+toskew
; 
1675     uint32
* cp2 
= cp1
+w
+toskew
; 
1676     uint32
* cp3 
= cp2
+w
+toskew
; 
1677     int32 incr 
= 3*w
+4*toskew
; 
1680     /* adjust fromskew */ 
1681     fromskew 
= (fromskew 
* 18) / 4; 
1682     if ((h 
& 3) == 0 && (w 
& 3) == 0) {                                  
1683         for (; h 
>= 4; h 
-= 4) { 
1689                 YCbCrtoRGB(cp 
[0], pp
[ 0]); 
1690                 YCbCrtoRGB(cp 
[1], pp
[ 1]); 
1691                 YCbCrtoRGB(cp 
[2], pp
[ 2]); 
1692                 YCbCrtoRGB(cp 
[3], pp
[ 3]); 
1693                 YCbCrtoRGB(cp1
[0], pp
[ 4]); 
1694                 YCbCrtoRGB(cp1
[1], pp
[ 5]); 
1695                 YCbCrtoRGB(cp1
[2], pp
[ 6]); 
1696                 YCbCrtoRGB(cp1
[3], pp
[ 7]); 
1697                 YCbCrtoRGB(cp2
[0], pp
[ 8]); 
1698                 YCbCrtoRGB(cp2
[1], pp
[ 9]); 
1699                 YCbCrtoRGB(cp2
[2], pp
[10]); 
1700                 YCbCrtoRGB(cp2
[3], pp
[11]); 
1701                 YCbCrtoRGB(cp3
[0], pp
[12]); 
1702                 YCbCrtoRGB(cp3
[1], pp
[13]); 
1703                 YCbCrtoRGB(cp3
[2], pp
[14]); 
1704                 YCbCrtoRGB(cp3
[3], pp
[15]); 
1706                 cp 
+= 4, cp1 
+= 4, cp2 
+= 4, cp3 
+= 4; 
1709             cp 
+= incr
, cp1 
+= incr
, cp2 
+= incr
, cp3 
+= incr
; 
1714             for (x 
= w
; x 
> 0;) { 
1720                     default: YCbCrtoRGB(cp3
[3], pp
[15]); /* FALLTHROUGH */ 
1721                     case 3:  YCbCrtoRGB(cp2
[3], pp
[11]); /* FALLTHROUGH */ 
1722                     case 2:  YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */ 
1723                     case 1:  YCbCrtoRGB(cp 
[3], pp
[ 3]); /* FALLTHROUGH */ 
1727                     default: YCbCrtoRGB(cp3
[2], pp
[14]); /* FALLTHROUGH */ 
1728                     case 3:  YCbCrtoRGB(cp2
[2], pp
[10]); /* FALLTHROUGH */ 
1729                     case 2:  YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */ 
1730                     case 1:  YCbCrtoRGB(cp 
[2], pp
[ 2]); /* FALLTHROUGH */ 
1734                     default: YCbCrtoRGB(cp3
[1], pp
[13]); /* FALLTHROUGH */ 
1735                     case 3:  YCbCrtoRGB(cp2
[1], pp
[ 9]); /* FALLTHROUGH */ 
1736                     case 2:  YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */ 
1737                     case 1:  YCbCrtoRGB(cp 
[1], pp
[ 1]); /* FALLTHROUGH */ 
1741                     default: YCbCrtoRGB(cp3
[0], pp
[12]); /* FALLTHROUGH */ 
1742                     case 3:  YCbCrtoRGB(cp2
[0], pp
[ 8]); /* FALLTHROUGH */ 
1743                     case 2:  YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */ 
1744                     case 1:  YCbCrtoRGB(cp 
[0], pp
[ 0]); /* FALLTHROUGH */ 
1748                     cp 
+= x
; cp1 
+= x
; cp2 
+= x
; cp3 
+= x
; 
1752                     cp 
+= 4; cp1 
+= 4; cp2 
+= 4; cp3 
+= 4; 
1760             cp 
+= incr
, cp1 
+= incr
, cp2 
+= incr
, cp3 
+= incr
; 
1767  * 8-bit packed YCbCr samples w/ 4,2 subsampling => RGB 
1769 DECLAREContigPutFunc(putcontig8bitYCbCr42tile
) 
1771     uint32
* cp1 
= cp
+w
+toskew
; 
1772     int32 incr 
= 2*toskew
+w
; 
1775     fromskew 
= (fromskew 
* 10) / 4; 
1776     if ((h 
& 3) == 0 && (w 
& 1) == 0) { 
1777         for (; h 
>= 2; h 
-= 2) { 
1783                 YCbCrtoRGB(cp 
[0], pp
[0]); 
1784                 YCbCrtoRGB(cp 
[1], pp
[1]); 
1785                 YCbCrtoRGB(cp 
[2], pp
[2]); 
1786                 YCbCrtoRGB(cp 
[3], pp
[3]); 
1787                 YCbCrtoRGB(cp1
[0], pp
[4]); 
1788                 YCbCrtoRGB(cp1
[1], pp
[5]); 
1789                 YCbCrtoRGB(cp1
[2], pp
[6]); 
1790                 YCbCrtoRGB(cp1
[3], pp
[7]); 
1795             cp 
+= incr
, cp1 
+= incr
; 
1800             for (x 
= w
; x 
> 0;) { 
1806                     default: YCbCrtoRGB(cp1
[3], pp
[ 7]); /* FALLTHROUGH */ 
1807                     case 1:  YCbCrtoRGB(cp 
[3], pp
[ 3]); /* FALLTHROUGH */ 
1811                     default: YCbCrtoRGB(cp1
[2], pp
[ 6]); /* FALLTHROUGH */ 
1812                     case 1:  YCbCrtoRGB(cp 
[2], pp
[ 2]); /* FALLTHROUGH */ 
1816                     default: YCbCrtoRGB(cp1
[1], pp
[ 5]); /* FALLTHROUGH */ 
1817                     case 1:  YCbCrtoRGB(cp 
[1], pp
[ 1]); /* FALLTHROUGH */ 
1821                     default: YCbCrtoRGB(cp1
[0], pp
[ 4]); /* FALLTHROUGH */ 
1822                     case 1:  YCbCrtoRGB(cp 
[0], pp
[ 0]); /* FALLTHROUGH */ 
1838             cp 
+= incr
, cp1 
+= incr
; 
1845  * 8-bit packed YCbCr samples w/ 4,1 subsampling => RGB 
1847 DECLAREContigPutFunc(putcontig8bitYCbCr41tile
) 
1850     /* XXX adjust fromskew */ 
1857             YCbCrtoRGB(cp 
[0], pp
[0]); 
1858             YCbCrtoRGB(cp 
[1], pp
[1]); 
1859             YCbCrtoRGB(cp 
[2], pp
[2]); 
1860             YCbCrtoRGB(cp 
[3], pp
[3]); 
1872               case 3: YCbCrtoRGB(cp 
[2], pp
[2]); 
1873               case 2: YCbCrtoRGB(cp 
[1], pp
[1]); 
1874               case 1: YCbCrtoRGB(cp 
[0], pp
[0]); 
1889  * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB 
1891 DECLAREContigPutFunc(putcontig8bitYCbCr22tile
) 
1893     uint32
* cp1 
= cp
+w
+toskew
; 
1894     int32 incr 
= 2*toskew
+w
; 
1897     fromskew 
= (fromskew 
* 6) / 2; 
1898     if ((h 
& 1) == 0 && (w 
& 1) == 0) { 
1899         for (; h 
>= 2; h 
-= 2) { 
1905                 YCbCrtoRGB(cp 
[0], pp
[0]); 
1906                 YCbCrtoRGB(cp 
[1], pp
[1]); 
1907                 YCbCrtoRGB(cp1
[0], pp
[2]); 
1908                 YCbCrtoRGB(cp1
[1], pp
[3]); 
1913             cp 
+= incr
, cp1 
+= incr
; 
1918             for (x 
= w
; x 
> 0;) { 
1924                     default: YCbCrtoRGB(cp1
[1], pp
[ 3]); /* FALLTHROUGH */ 
1925                     case 1:  YCbCrtoRGB(cp 
[1], pp
[ 1]); /* FALLTHROUGH */ 
1929                     default: YCbCrtoRGB(cp1
[0], pp
[ 2]); /* FALLTHROUGH */ 
1930                     case 1:  YCbCrtoRGB(cp 
[0], pp
[ 0]); /* FALLTHROUGH */ 
1946             cp 
+= incr
, cp1 
+= incr
; 
1953  * 8-bit packed YCbCr samples w/ 2,1 subsampling => RGB 
1955 DECLAREContigPutFunc(putcontig8bitYCbCr21tile
) 
1958     fromskew 
= (fromskew 
* 4) / 2; 
1965             YCbCrtoRGB(cp
[0], pp
[0]);  
1966             YCbCrtoRGB(cp
[1], pp
[1]); 
1977             YCbCrtoRGB(cp 
[0], pp
[0]); 
1989  * 8-bit packed YCbCr samples w/ no subsampling => RGB 
1991 DECLAREContigPutFunc(putcontig8bitYCbCr11tile
) 
1996         x 
= w
; /* was x = w>>1; patched 2000/09/25 warmerda@home.com */  
2001             YCbCrtoRGB(*cp
++, pp
[0]); 
2011 static tileContigRoutine
 
2012 initYCbCrConversion(TIFFRGBAImage
* img
) 
2014         static char module[] = "initCIELabConversion"; 
2016         float *luma
, *refBlackWhite
; 
2019         if (img
->ycbcr 
== NULL
) { 
2020             img
->ycbcr 
= (TIFFYCbCrToRGB
*) _TIFFmalloc( 
2021                     TIFFroundup(sizeof (TIFFYCbCrToRGB
), sizeof (long)) 
2022                     + 4*256*sizeof (TIFFRGBValue
) 
2023                     + 2*256*sizeof (int) 
2024                     + 3*256*sizeof (int32
) 
2026             if (img
->ycbcr 
== NULL
) { 
2027                         TIFFErrorExt(img
->tif
->tif_clientdata
, module, 
2028                               "No space for YCbCr->RGB conversion state"); 
2033         TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRCOEFFICIENTS
, &luma
); 
2034         TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_REFERENCEBLACKWHITE
, 
2036         if (TIFFYCbCrToRGBInit(img
->ycbcr
, luma
, refBlackWhite
) < 0) 
2040          * The 6.0 spec says that subsampling must be 
2041          * one of 1, 2, or 4, and that vertical subsampling 
2042          * must always be <= horizontal subsampling; so 
2043          * there are only a few possibilities and we just 
2044          * enumerate the cases. 
2046         TIFFGetFieldDefaulted(img
->tif
, TIFFTAG_YCBCRSUBSAMPLING
, &hs
, &vs
); 
2047         switch ((hs
<<4)|vs
) { 
2048                 case 0x44: return &putcontig8bitYCbCr44tile
; 
2049                 case 0x42: return &putcontig8bitYCbCr42tile
; 
2050                 case 0x41: return &putcontig8bitYCbCr41tile
; 
2051                 case 0x22: return &putcontig8bitYCbCr22tile
; 
2052                 case 0x21: return &putcontig8bitYCbCr21tile
; 
2053                 case 0x11: return &putcontig8bitYCbCr11tile
; 
2059 static tileContigRoutine
 
2060 initCIELabConversion(TIFFRGBAImage
* img
) 
2062         static char module[] = "initCIELabConversion"; 
2068                 img
->cielab 
= (TIFFCIELabToRGB 
*) 
2069                         _TIFFmalloc(sizeof(TIFFCIELabToRGB
)); 
2071                         TIFFErrorExt(img
->tif
->tif_clientdata
, module, 
2072                             "No space for CIE L*a*b*->RGB conversion state."); 
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
); 
2089         return &putcontig8bitCIELab
; 
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 
2100 makebwmap(TIFFRGBAImage
* img
) 
2102     TIFFRGBValue
* Map 
= img
->Map
; 
2103     int bitspersample 
= img
->bitspersample
; 
2104     int nsamples 
= 8 / bitspersample
; 
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"); 
2117     p 
= (uint32
*)(img
->BWmap 
+ 256); 
2118     for (i 
= 0; i 
< 256; i
++) { 
2121         switch (bitspersample
) { 
2122 #define GREY(x) c = Map[x]; *p++ = PACK(c,c,c); 
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. 
2159 setupMap(TIFFRGBAImage
* img
) 
2163     range 
= (int32
)((1L<<img
->bitspersample
)-1); 
2165     /* treat 16 bit the same as eight bit */ 
2166     if( img
->bitspersample 
== 16 ) 
2167         range 
= (int32
) 255; 
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"); 
2175     if (img
->photometric 
== PHOTOMETRIC_MINISWHITE
) { 
2176         for (x 
= 0; x 
<= range
; x
++) 
2177             img
->Map
[x
] = (TIFFRGBValue
) (((range 
- x
) * 255) / range
); 
2179         for (x 
= 0; x 
<= range
; x
++) 
2180             img
->Map
[x
] = (TIFFRGBValue
) ((x 
* 255) / range
); 
2182     if (img
->bitspersample 
<= 16 && 
2183         (img
->photometric 
== PHOTOMETRIC_MINISBLACK 
|| 
2184          img
->photometric 
== PHOTOMETRIC_MINISWHITE
)) { 
2186          * Use photometric mapping table to construct 
2187          * unpacking tables for samples <= 8 bits. 
2189         if (!makebwmap(img
)) 
2191         /* no longer need Map, free it */ 
2192         _TIFFfree(img
->Map
), img
->Map 
= NULL
; 
2198 checkcmap(TIFFRGBAImage
* img
) 
2200     uint16
* r 
= img
->redcmap
; 
2201     uint16
* g 
= img
->greencmap
; 
2202     uint16
* b 
= img
->bluecmap
; 
2203     long n 
= 1L<<img
->bitspersample
; 
2206         if (*r
++ >= 256 || *g
++ >= 256 || *b
++ >= 256) 
2212 cvtcmap(TIFFRGBAImage
* img
) 
2214     uint16
* r 
= img
->redcmap
; 
2215     uint16
* g 
= img
->greencmap
; 
2216     uint16
* b 
= img
->bluecmap
; 
2219     for (i 
= (1L<<img
->bitspersample
)-1; i 
>= 0; i
--) { 
2220 #define CVT(x)          ((uint16)((x)>>8)) 
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 
2236 makecmap(TIFFRGBAImage
* img
) 
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
; 
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"); 
2252     p 
= (uint32
*)(img
->PALmap 
+ 256); 
2253     for (i 
= 0; i 
< 256; i
++) { 
2256 #define CMAP(x) c = (TIFFRGBValue) x; *p++ = PACK(r[c]&0xff, g[c]&0xff, b[c]&0xff); 
2257         switch (bitspersample
) { 
2288  * Construct any mapping table used 
2289  * by the associated put routine. 
2292 buildMap(TIFFRGBAImage
* img
) 
2294     switch (img
->photometric
) { 
2295     case PHOTOMETRIC_RGB
: 
2296     case PHOTOMETRIC_YCBCR
: 
2297     case PHOTOMETRIC_SEPARATED
: 
2298         if (img
->bitspersample 
== 8) 
2301     case PHOTOMETRIC_MINISBLACK
: 
2302     case PHOTOMETRIC_MINISWHITE
: 
2306     case PHOTOMETRIC_PALETTE
: 
2308          * Convert 16-bit colormap to 8-bit (unless it looks 
2309          * like an old-style 8-bit colormap). 
2311         if (checkcmap(img
) == 16) 
2314             TIFFWarningExt(img
->tif
->tif_clientdata
, TIFFFileName(img
->tif
), "Assuming 8-bit colormap"); 
2316          * Use mapping table and colormap to construct 
2317          * unpacking tables for samples < 8 bits. 
2319         if (img
->bitspersample 
<= 8 && !makecmap(img
)) 
2327  * Select the appropriate conversion routine for packed data. 
2330 pickTileContigCase(TIFFRGBAImage
* img
) 
2332     tileContigRoutine put 
= 0; 
2334     if (buildMap(img
)) { 
2335         switch (img
->photometric
) { 
2336         case PHOTOMETRIC_RGB
: 
2337             switch (img
->bitspersample
) { 
2340                     if (img
->alpha 
== EXTRASAMPLE_ASSOCALPHA
) 
2341                         put 
= putRGBAAcontig8bittile
; 
2342                     else if (img
->alpha 
== EXTRASAMPLE_UNASSALPHA
) 
2343                         put 
= putRGBUAcontig8bittile
; 
2345                         put 
= putRGBcontig8bittile
; 
2347                     put 
= putRGBcontig8bitMaptile
; 
2350                 put 
= putRGBcontig16bittile
; 
2352                     if (img
->alpha 
== EXTRASAMPLE_ASSOCALPHA
) 
2353                         put 
= putRGBAAcontig16bittile
; 
2354                     else if (img
->alpha 
== EXTRASAMPLE_UNASSALPHA
) 
2355                         put 
= putRGBUAcontig16bittile
; 
2360         case PHOTOMETRIC_SEPARATED
: 
2361             if (img
->bitspersample 
== 8) { 
2363                     put 
= putRGBcontig8bitCMYKtile
; 
2365                     put 
= putRGBcontig8bitCMYKMaptile
; 
2368         case PHOTOMETRIC_PALETTE
: 
2369             switch (img
->bitspersample
) { 
2370             case 8:     put 
= put8bitcmaptile
; break; 
2371             case 4: put 
= put4bitcmaptile
; break; 
2372             case 2: put 
= put2bitcmaptile
; break; 
2373             case 1: put 
= put1bitcmaptile
; break; 
2376         case PHOTOMETRIC_MINISWHITE
: 
2377         case PHOTOMETRIC_MINISBLACK
: 
2378             switch (img
->bitspersample
) { 
2379             case 16: put 
= put16bitbwtile
; break; 
2380             case 8:  put 
= putgreytile
; break; 
2381             case 4:  put 
= put4bitbwtile
; break; 
2382             case 2:  put 
= put2bitbwtile
; break; 
2383             case 1:  put 
= put1bitbwtile
; break; 
2386         case PHOTOMETRIC_YCBCR
: 
2387             if (img
->bitspersample 
== 8) 
2388                 put 
= initYCbCrConversion(img
); 
2390         case PHOTOMETRIC_CIELAB
: 
2391             if (img
->bitspersample 
== 8) 
2392                 put 
= initCIELabConversion(img
); 
2396     return ((img
->put
.contig 
= put
) != 0); 
2400  * Select the appropriate conversion routine for unpacked data. 
2402  * NB: we assume that unpacked single channel data is directed 
2403  *       to the "packed routines. 
2406 pickTileSeparateCase(TIFFRGBAImage
* img
) 
2408     tileSeparateRoutine put 
= 0; 
2410     if (buildMap(img
)) { 
2411         switch (img
->photometric
) { 
2412         case PHOTOMETRIC_RGB
: 
2413             switch (img
->bitspersample
) { 
2416                     if (img
->alpha 
== EXTRASAMPLE_ASSOCALPHA
) 
2417                         put 
= putRGBAAseparate8bittile
; 
2418                     else if (img
->alpha 
== EXTRASAMPLE_UNASSALPHA
) 
2419                         put 
= putRGBUAseparate8bittile
; 
2421                         put 
= putRGBseparate8bittile
; 
2423                     put 
= putRGBseparate8bitMaptile
; 
2426                 put 
= putRGBseparate16bittile
; 
2428                     if (img
->alpha 
== EXTRASAMPLE_ASSOCALPHA
) 
2429                         put 
= putRGBAAseparate16bittile
; 
2430                     else if (img
->alpha 
== EXTRASAMPLE_UNASSALPHA
) 
2431                         put 
= putRGBUAseparate16bittile
; 
2438     return ((img
->put
.separate 
= put
) != 0); 
2442  * Read a whole strip off data from the file, and convert to RGBA form. 
2443  * If this is the last strip, then it will only contain the portion of 
2444  * the strip that is actually within the image space.  The result is 
2445  * organized in bottom to top form. 
2450 TIFFReadRGBAStrip(TIFF
* tif
, uint32 row
, uint32 
* raster 
) 
2453     char        emsg
[1024] = ""; 
2456     uint32      rowsperstrip
, rows_to_read
; 
2458     if( TIFFIsTiled( tif 
) ) 
2460                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), 
2461                   "Can't use TIFFReadRGBAStrip() with tiled file."); 
2465     TIFFGetFieldDefaulted(tif
, TIFFTAG_ROWSPERSTRIP
, &rowsperstrip
); 
2466     if( (row 
% rowsperstrip
) != 0 ) 
2468                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), 
2469                                 "Row passed to TIFFReadRGBAStrip() must be first in a strip."); 
2473     if (TIFFRGBAImageOK(tif
, emsg
) && TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) { 
2475         img
.row_offset 
= row
; 
2478         if( row 
+ rowsperstrip 
> img
.height 
) 
2479             rows_to_read 
= img
.height 
- row
; 
2481             rows_to_read 
= rowsperstrip
; 
2483         ok 
= TIFFRGBAImageGet(&img
, raster
, img
.width
, rows_to_read 
); 
2485         TIFFRGBAImageEnd(&img
); 
2487                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), emsg
); 
2495  * Read a whole tile off data from the file, and convert to RGBA form. 
2496  * The returned RGBA data is organized from bottom to top of tile, 
2497  * and may include zeroed areas if the tile extends off the image. 
2501 TIFFReadRGBATile(TIFF
* tif
, uint32 col
, uint32 row
, uint32 
* raster
) 
2504     char        emsg
[1024] = ""; 
2507     uint32      tile_xsize
, tile_ysize
; 
2508     uint32      read_xsize
, read_ysize
; 
2512      * Verify that our request is legal - on a tile file, and on a 
2516     if( !TIFFIsTiled( tif 
) ) 
2518                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), 
2519                                   "Can't use TIFFReadRGBATile() with stripped file."); 
2523     TIFFGetFieldDefaulted(tif
, TIFFTAG_TILEWIDTH
, &tile_xsize
); 
2524     TIFFGetFieldDefaulted(tif
, TIFFTAG_TILELENGTH
, &tile_ysize
); 
2525     if( (col 
% tile_xsize
) != 0 || (row 
% tile_ysize
) != 0 ) 
2527                 TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), 
2528                   "Row/col passed to TIFFReadRGBATile() must be top" 
2529                   "left corner of a tile."); 
2534      * Setup the RGBA reader. 
2537     if (!TIFFRGBAImageOK(tif
, emsg
)  
2538         || !TIFFRGBAImageBegin(&img
, tif
, 0, emsg
)) { 
2539             TIFFErrorExt(tif
->tif_clientdata
, TIFFFileName(tif
), emsg
); 
2544      * The TIFFRGBAImageGet() function doesn't allow us to get off the 
2545      * edge of the image, even to fill an otherwise valid tile.  So we 
2546      * figure out how much we can read, and fix up the tile buffer to 
2547      * a full tile configuration afterwards. 
2550     if( row 
+ tile_ysize 
> img
.height 
) 
2551         read_ysize 
= img
.height 
- row
; 
2553         read_ysize 
= tile_ysize
; 
2555     if( col 
+ tile_xsize 
> img
.width 
) 
2556         read_xsize 
= img
.width 
- col
; 
2558         read_xsize 
= tile_xsize
; 
2561      * Read the chunk of imagery. 
2564     img
.row_offset 
= row
; 
2565     img
.col_offset 
= col
; 
2567     ok 
= TIFFRGBAImageGet(&img
, raster
, read_xsize
, read_ysize 
); 
2569     TIFFRGBAImageEnd(&img
); 
2572      * If our read was incomplete we will need to fix up the tile by 
2573      * shifting the data around as if a full tile of data is being returned. 
2575      * This is all the more complicated because the image is organized in 
2576      * bottom to top format.  
2579     if( read_xsize 
== tile_xsize 
&& read_ysize 
== tile_ysize 
) 
2582     for( i_row 
= 0; i_row 
< read_ysize
; i_row
++ ) { 
2583         memmove( raster 
+ (tile_ysize 
- i_row 
- 1) * tile_xsize
, 
2584                  raster 
+ (read_ysize 
- i_row 
- 1) * read_xsize
, 
2585                  read_xsize 
* sizeof(uint32
) ); 
2586         _TIFFmemset( raster 
+ (tile_ysize 
- i_row 
- 1) * tile_xsize
+read_xsize
, 
2587                      0, sizeof(uint32
) * (tile_xsize 
- read_xsize
) ); 
2590     for( i_row 
= read_ysize
; i_row 
< tile_ysize
; i_row
++ ) { 
2591         _TIFFmemset( raster 
+ (tile_ysize 
- i_row 
- 1) * tile_xsize
, 
2592                      0, sizeof(uint32
) * tile_xsize 
); 
2598 /* vim: set ts=8 sts=8 sw=8 noet: */