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