Home | History | Annotate | Download | only in libtiff
      1 /* $Id: tif_tile.c,v 1.23 2012-06-06 05:33:55 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  * Tiled Image Support Routines.
     31  */
     32 #include "tiffiop.h"
     33 
     34 /*
     35  * Compute which tile an (x,y,z,s) value is in.
     36  */
     37 uint32
     38 TIFFComputeTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
     39 {
     40     TIFFDirectory *td = &tif->tif_dir;
     41     uint32 dx = td->td_tilewidth;
     42     uint32 dy = td->td_tilelength;
     43     uint32 dz = td->td_tiledepth;
     44     uint32 tile = 1;
     45 
     46     if (td->td_imagedepth == 1)
     47         z = 0;
     48     if (dx == (uint32) -1)
     49         dx = td->td_imagewidth;
     50     if (dy == (uint32) -1)
     51         dy = td->td_imagelength;
     52     if (dz == (uint32) -1)
     53         dz = td->td_imagedepth;
     54     if (dx != 0 && dy != 0 && dz != 0) {
     55         uint32 xpt = TIFFhowmany_32(td->td_imagewidth, dx);
     56         uint32 ypt = TIFFhowmany_32(td->td_imagelength, dy);
     57         uint32 zpt = TIFFhowmany_32(td->td_imagedepth, dz);
     58 
     59         if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
     60             tile = (xpt*ypt*zpt)*s +
     61                  (xpt*ypt)*(z/dz) +
     62                  xpt*(y/dy) +
     63                  x/dx;
     64         else
     65             tile = (xpt*ypt)*(z/dz) + xpt*(y/dy) + x/dx;
     66     }
     67     return (tile);
     68 }
     69 
     70 /*
     71  * Check an (x,y,z,s) coordinate
     72  * against the image bounds.
     73  */
     74 int
     75 TIFFCheckTile(TIFF* tif, uint32 x, uint32 y, uint32 z, uint16 s)
     76 {
     77     TIFFDirectory *td = &tif->tif_dir;
     78 
     79     if (x >= td->td_imagewidth) {
     80         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
     81                  "%lu: Col out of range, max %lu",
     82                  (unsigned long) x,
     83                  (unsigned long) (td->td_imagewidth - 1));
     84         return (0);
     85     }
     86     if (y >= td->td_imagelength) {
     87         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
     88                  "%lu: Row out of range, max %lu",
     89                  (unsigned long) y,
     90                  (unsigned long) (td->td_imagelength - 1));
     91         return (0);
     92     }
     93     if (z >= td->td_imagedepth) {
     94         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
     95                  "%lu: Depth out of range, max %lu",
     96                  (unsigned long) z,
     97                  (unsigned long) (td->td_imagedepth - 1));
     98         return (0);
     99     }
    100     if (td->td_planarconfig == PLANARCONFIG_SEPARATE &&
    101         s >= td->td_samplesperpixel) {
    102         TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
    103                  "%lu: Sample out of range, max %lu",
    104                  (unsigned long) s,
    105                  (unsigned long) (td->td_samplesperpixel - 1));
    106         return (0);
    107     }
    108     return (1);
    109 }
    110 
    111 /*
    112  * Compute how many tiles are in an image.
    113  */
    114 uint32
    115 TIFFNumberOfTiles(TIFF* tif)
    116 {
    117     TIFFDirectory *td = &tif->tif_dir;
    118     uint32 dx = td->td_tilewidth;
    119     uint32 dy = td->td_tilelength;
    120     uint32 dz = td->td_tiledepth;
    121     uint32 ntiles;
    122 
    123     if (dx == (uint32) -1)
    124         dx = td->td_imagewidth;
    125     if (dy == (uint32) -1)
    126         dy = td->td_imagelength;
    127     if (dz == (uint32) -1)
    128         dz = td->td_imagedepth;
    129     ntiles = (dx == 0 || dy == 0 || dz == 0) ? 0 :
    130         _TIFFMultiply32(tif, _TIFFMultiply32(tif, TIFFhowmany_32(td->td_imagewidth, dx),
    131         TIFFhowmany_32(td->td_imagelength, dy),
    132         "TIFFNumberOfTiles"),
    133         TIFFhowmany_32(td->td_imagedepth, dz), "TIFFNumberOfTiles");
    134     if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
    135         ntiles = _TIFFMultiply32(tif, ntiles, td->td_samplesperpixel,
    136             "TIFFNumberOfTiles");
    137     return (ntiles);
    138 }
    139 
    140 /*
    141  * Compute the # bytes in each row of a tile.
    142  */
    143 uint64
    144 TIFFTileRowSize64(TIFF* tif)
    145 {
    146     TIFFDirectory *td = &tif->tif_dir;
    147     uint64 rowsize;
    148 
    149     if (td->td_tilelength == 0 || td->td_tilewidth == 0)
    150         return (0);
    151     rowsize = _TIFFMultiply64(tif, td->td_bitspersample, td->td_tilewidth,
    152         "TIFFTileRowSize");
    153     if (td->td_planarconfig == PLANARCONFIG_CONTIG)
    154         rowsize = _TIFFMultiply64(tif, rowsize, td->td_samplesperpixel,
    155             "TIFFTileRowSize");
    156     return (TIFFhowmany8_64(rowsize));
    157 }
    158 tmsize_t
    159 TIFFTileRowSize(TIFF* tif)
    160 {
    161     static const char module[] = "TIFFTileRowSize";
    162     uint64 m;
    163     tmsize_t n;
    164     m=TIFFTileRowSize64(tif);
    165     n=(tmsize_t)m;
    166     if ((uint64)n!=m)
    167     {
    168         TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
    169         n=0;
    170     }
    171     return(n);
    172 }
    173 
    174 /*
    175  * Compute the # bytes in a variable length, row-aligned tile.
    176  */
    177 uint64
    178 TIFFVTileSize64(TIFF* tif, uint32 nrows)
    179 {
    180     static const char module[] = "TIFFVTileSize64";
    181     TIFFDirectory *td = &tif->tif_dir;
    182     if (td->td_tilelength == 0 || td->td_tilewidth == 0 ||
    183         td->td_tiledepth == 0)
    184         return (0);
    185     if ((td->td_planarconfig==PLANARCONFIG_CONTIG)&&
    186         (td->td_photometric==PHOTOMETRIC_YCBCR)&&
    187         (td->td_samplesperpixel==3)&&
    188         (!isUpSampled(tif)))
    189     {
    190         /*
    191          * Packed YCbCr data contain one Cb+Cr for every
    192          * HorizontalSampling*VerticalSampling Y values.
    193          * Must also roundup width and height when calculating
    194          * since images that are not a multiple of the
    195          * horizontal/vertical subsampling area include
    196          * YCbCr data for the extended image.
    197          */
    198         uint16 ycbcrsubsampling[2];
    199         uint16 samplingblock_samples;
    200         uint32 samplingblocks_hor;
    201         uint32 samplingblocks_ver;
    202         uint64 samplingrow_samples;
    203         uint64 samplingrow_size;
    204         TIFFGetFieldDefaulted(tif,TIFFTAG_YCBCRSUBSAMPLING,ycbcrsubsampling+0,
    205             ycbcrsubsampling+1);
    206         if ((ycbcrsubsampling[0] != 1 && ycbcrsubsampling[0] != 2 && ycbcrsubsampling[0] != 4)
    207             ||(ycbcrsubsampling[1] != 1 && ycbcrsubsampling[1] != 2 && ycbcrsubsampling[1] != 4))
    208         {
    209             TIFFErrorExt(tif->tif_clientdata,module,
    210                      "Invalid YCbCr subsampling (%dx%d)",
    211                      ycbcrsubsampling[0],
    212                      ycbcrsubsampling[1] );
    213             return 0;
    214         }
    215         samplingblock_samples=ycbcrsubsampling[0]*ycbcrsubsampling[1]+2;
    216         samplingblocks_hor=TIFFhowmany_32(td->td_tilewidth,ycbcrsubsampling[0]);
    217         samplingblocks_ver=TIFFhowmany_32(nrows,ycbcrsubsampling[1]);
    218         samplingrow_samples=_TIFFMultiply64(tif,samplingblocks_hor,samplingblock_samples,module);
    219         samplingrow_size=TIFFhowmany8_64(_TIFFMultiply64(tif,samplingrow_samples,td->td_bitspersample,module));
    220         return(_TIFFMultiply64(tif,samplingrow_size,samplingblocks_ver,module));
    221     }
    222     else
    223         return(_TIFFMultiply64(tif,nrows,TIFFTileRowSize64(tif),module));
    224 }
    225 tmsize_t
    226 TIFFVTileSize(TIFF* tif, uint32 nrows)
    227 {
    228     static const char module[] = "TIFFVTileSize";
    229     uint64 m;
    230     tmsize_t n;
    231     m=TIFFVTileSize64(tif,nrows);
    232     n=(tmsize_t)m;
    233     if ((uint64)n!=m)
    234     {
    235         TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
    236         n=0;
    237     }
    238     return(n);
    239 }
    240 
    241 /*
    242  * Compute the # bytes in a row-aligned tile.
    243  */
    244 uint64
    245 TIFFTileSize64(TIFF* tif)
    246 {
    247     return (TIFFVTileSize64(tif, tif->tif_dir.td_tilelength));
    248 }
    249 tmsize_t
    250 TIFFTileSize(TIFF* tif)
    251 {
    252     static const char module[] = "TIFFTileSize";
    253     uint64 m;
    254     tmsize_t n;
    255     m=TIFFTileSize64(tif);
    256     n=(tmsize_t)m;
    257     if ((uint64)n!=m)
    258     {
    259         TIFFErrorExt(tif->tif_clientdata,module,"Integer overflow");
    260         n=0;
    261     }
    262     return(n);
    263 }
    264 
    265 /*
    266  * Compute a default tile size based on the image
    267  * characteristics and a requested value.  If a
    268  * request is <1 then we choose a size according
    269  * to certain heuristics.
    270  */
    271 void
    272 TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
    273 {
    274     (*tif->tif_deftilesize)(tif, tw, th);
    275 }
    276 
    277 void
    278 _TIFFDefaultTileSize(TIFF* tif, uint32* tw, uint32* th)
    279 {
    280     (void) tif;
    281     if (*(int32*) tw < 1)
    282         *tw = 256;
    283     if (*(int32*) th < 1)
    284         *th = 256;
    285     /* roundup to a multiple of 16 per the spec */
    286     if (*tw & 0xf)
    287         *tw = TIFFroundup_32(*tw, 16);
    288     if (*th & 0xf)
    289         *th = TIFFroundup_32(*th, 16);
    290 }
    291 
    292 /* vim: set ts=8 sts=8 sw=8 noet: */
    293 /*
    294  * Local Variables:
    295  * mode: c
    296  * c-basic-offset: 8
    297  * fill-column: 78
    298  * End:
    299  */
    300