1/* PDFlib GmbH cvsid: $Id: tif_strip.c 14574 2005-10-29 16:27:43Z bonefish $ */ 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 * Strip-organized Image Support Routines. 31 */ 32#include "tiffiop.h" 33 34/* 35 * Compute which strip a (row,sample) value is in. 36 */ 37tstrip_t 38TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample) 39{ 40 TIFFDirectory *td = &tif->tif_dir; 41 tstrip_t strip; 42 43 strip = row / td->td_rowsperstrip; 44 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 45 if (sample >= td->td_samplesperpixel) { 46 TIFFError(tif->tif_name, 47 "%u: Sample out of range, max %u", 48 sample, td->td_samplesperpixel); 49 return ((tstrip_t) 0); 50 } 51 strip += sample*td->td_stripsperimage; 52 } 53 return (strip); 54} 55 56/* 57 * Compute how many strips are in an image. 58 */ 59tstrip_t 60TIFFNumberOfStrips(TIFF* tif) 61{ 62 TIFFDirectory *td = &tif->tif_dir; 63 tstrip_t nstrips; 64 65 nstrips = (td->td_rowsperstrip == (uint32) -1 ? 66 (td->td_imagelength != 0 ? 1 : 0) : 67 TIFFhowmany(td->td_imagelength, td->td_rowsperstrip)); 68 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) 69 nstrips *= td->td_samplesperpixel; 70 return (nstrips); 71} 72 73/* 74 * Compute the # bytes in a variable height, row-aligned strip. 75 */ 76tsize_t 77TIFFVStripSize(TIFF* tif, uint32 nrows) 78{ 79 TIFFDirectory *td = &tif->tif_dir; 80 81 if (nrows == (uint32) -1) 82 nrows = td->td_imagelength; 83#ifdef YCBCR_SUPPORT 84 if (td->td_planarconfig == PLANARCONFIG_CONTIG && 85 td->td_photometric == PHOTOMETRIC_YCBCR && 86 !isUpSampled(tif)) { 87 /* 88 * Packed YCbCr data contain one Cb+Cr for every 89 * HorizontalSampling*VerticalSampling Y values. 90 * Must also roundup width and height when calculating 91 * since images that are not a multiple of the 92 * horizontal/vertical subsampling area include 93 * YCbCr data for the extended image. 94 */ 95 tsize_t w = 96 TIFFroundup(td->td_imagewidth, td->td_ycbcrsubsampling[0]); 97 tsize_t scanline = TIFFhowmany(w*td->td_bitspersample, 8); 98 tsize_t samplingarea = 99 td->td_ycbcrsubsampling[0]*td->td_ycbcrsubsampling[1]; 100 nrows = TIFFroundup(nrows, td->td_ycbcrsubsampling[1]); 101 /* NB: don't need TIFFhowmany here 'cuz everything is rounded */ 102 return ((tsize_t) 103 (nrows*scanline + 2*(nrows*scanline / samplingarea))); 104 } else 105#endif 106 return ((tsize_t)(nrows * TIFFScanlineSize(tif))); 107} 108 109/* 110 * Compute the # bytes in a (row-aligned) strip. 111 * 112 * Note that if RowsPerStrip is larger than the 113 * recorded ImageLength, then the strip size is 114 * truncated to reflect the actual space required 115 * to hold the strip. 116 */ 117tsize_t 118TIFFStripSize(TIFF* tif) 119{ 120 TIFFDirectory* td = &tif->tif_dir; 121 uint32 rps = td->td_rowsperstrip; 122 if (rps > td->td_imagelength) 123 rps = td->td_imagelength; 124 return (TIFFVStripSize(tif, rps)); 125} 126 127/* 128 * Compute a default strip size based on the image 129 * characteristics and a requested value. If the 130 * request is <1 then we choose a strip size according 131 * to certain heuristics. 132 */ 133uint32 134TIFFDefaultStripSize(TIFF* tif, uint32 request) 135{ 136 return (*tif->tif_defstripsize)(tif, request); 137} 138 139uint32 140_TIFFDefaultStripSize(TIFF* tif, uint32 s) 141{ 142 if ((int32) s < 1) { 143 /* 144 * If RowsPerStrip is unspecified, try to break the 145 * image up into strips that are approximately 8Kbytes. 146 */ 147 tsize_t scanline = TIFFScanlineSize(tif); 148 s = (uint32)(8*1024) / (scanline == 0 ? 1 : scanline); 149 if (s == 0) /* very wide images */ 150 s = 1; 151 } 152 return (s); 153} 154 155/* 156 * Return the number of bytes to read/write in a call to 157 * one of the scanline-oriented i/o routines. Note that 158 * this number may be 1/samples-per-pixel if data is 159 * stored as separate planes. 160 */ 161tsize_t 162TIFFScanlineSize(TIFF* tif) 163{ 164 TIFFDirectory *td = &tif->tif_dir; 165 tsize_t scanline; 166 167 scanline = td->td_bitspersample * td->td_imagewidth; 168 if (td->td_planarconfig == PLANARCONFIG_CONTIG) 169 scanline *= td->td_samplesperpixel; 170 return ((tsize_t) TIFFhowmany(scanline, 8)); 171} 172 173/* 174 * Return the number of bytes required to store a complete 175 * decoded and packed raster scanline (as opposed to the 176 * I/O size returned by TIFFScanlineSize which may be less 177 * if data is store as separate planes). 178 */ 179tsize_t 180TIFFRasterScanlineSize(TIFF* tif) 181{ 182 TIFFDirectory *td = &tif->tif_dir; 183 tsize_t scanline; 184 185 scanline = td->td_bitspersample * td->td_imagewidth; 186 if (td->td_planarconfig == PLANARCONFIG_CONTIG) { 187 scanline *= td->td_samplesperpixel; 188 return ((tsize_t) TIFFhowmany(scanline, 8)); 189 } else 190 return ((tsize_t) 191 TIFFhowmany(scanline, 8)*td->td_samplesperpixel); 192} 193