tif_strip.c
上传用户:looem2003
上传日期:2014-07-20
资源大小:13733k
文件大小:8k
源码类别:

打印编程

开发平台:

Visual C++

  1. /* $Id: tif_strip.c,v 1.17 2006/03/21 16:29:33 dron Exp $ */
  2. /*
  3.  * Copyright (c) 1991-1997 Sam Leffler
  4.  * Copyright (c) 1991-1997 Silicon Graphics, Inc.
  5.  *
  6.  * Permission to use, copy, modify, distribute, and sell this software and 
  7.  * its documentation for any purpose is hereby granted without fee, provided
  8.  * that (i) the above copyright notices and this permission notice appear in
  9.  * all copies of the software and related documentation, and (ii) the names of
  10.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  11.  * publicity relating to the software without the specific, prior written
  12.  * permission of Sam Leffler and Silicon Graphics.
  13.  * 
  14.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  15.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  16.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  17.  * 
  18.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  19.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  20.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  21.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  22.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  23.  * OF THIS SOFTWARE.
  24.  */
  25. /*
  26.  * TIFF Library.
  27.  *
  28.  * Strip-organized Image Support Routines.
  29.  */
  30. #include "tiffiop.h"
  31. static uint32
  32. summarize(TIFF* tif, size_t summand1, size_t summand2, const char* where)
  33. {
  34. /*
  35.  * XXX: We are using casting to uint32 here, bacause sizeof(size_t)
  36.  * may be larger than sizeof(uint32) on 64-bit architectures.
  37.  */
  38. uint32 bytes = summand1 + summand2;
  39. if (bytes - summand1 != summand2) {
  40. TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
  41. bytes = 0;
  42. }
  43. return (bytes);
  44. }
  45. static uint32
  46. multiply(TIFF* tif, size_t nmemb, size_t elem_size, const char* where)
  47. {
  48. uint32 bytes = nmemb * elem_size;
  49. if (elem_size && bytes / elem_size != nmemb) {
  50. TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "Integer overflow in %s", where);
  51. bytes = 0;
  52. }
  53. return (bytes);
  54. }
  55. /*
  56.  * Compute which strip a (row,sample) value is in.
  57.  */
  58. tstrip_t
  59. TIFFComputeStrip(TIFF* tif, uint32 row, tsample_t sample)
  60. {
  61. TIFFDirectory *td = &tif->tif_dir;
  62. tstrip_t strip;
  63. strip = row / td->td_rowsperstrip;
  64. if (td->td_planarconfig == PLANARCONFIG_SEPARATE) {
  65. if (sample >= td->td_samplesperpixel) {
  66. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  67.     "%lu: Sample out of range, max %lu",
  68.     (unsigned long) sample, (unsigned long) td->td_samplesperpixel);
  69. return ((tstrip_t) 0);
  70. }
  71. strip += sample*td->td_stripsperimage;
  72. }
  73. return (strip);
  74. }
  75. /*
  76.  * Compute how many strips are in an image.
  77.  */
  78. tstrip_t
  79. TIFFNumberOfStrips(TIFF* tif)
  80. {
  81. TIFFDirectory *td = &tif->tif_dir;
  82. tstrip_t nstrips;
  83. nstrips = (td->td_rowsperstrip == (uint32) -1 ? 1 :
  84.      TIFFhowmany(td->td_imagelength, td->td_rowsperstrip));
  85. if (td->td_planarconfig == PLANARCONFIG_SEPARATE)
  86. nstrips = multiply(tif, nstrips, td->td_samplesperpixel,
  87.    "TIFFNumberOfStrips");
  88. return (nstrips);
  89. }
  90. /*
  91.  * Compute the # bytes in a variable height, row-aligned strip.
  92.  */
  93. tsize_t
  94. TIFFVStripSize(TIFF* tif, uint32 nrows)
  95. {
  96. TIFFDirectory *td = &tif->tif_dir;
  97. if (nrows == (uint32) -1)
  98. nrows = td->td_imagelength;
  99. if (td->td_planarconfig == PLANARCONFIG_CONTIG &&
  100.     td->td_photometric == PHOTOMETRIC_YCBCR &&
  101.     !isUpSampled(tif)) {
  102. /*
  103.  * Packed YCbCr data contain one Cb+Cr for every
  104.  * HorizontalSampling*VerticalSampling Y values.
  105.  * Must also roundup width and height when calculating
  106.  * since images that are not a multiple of the
  107.  * horizontal/vertical subsampling area include
  108.  * YCbCr data for the extended image.
  109.  */
  110.                 uint16 ycbcrsubsampling[2];
  111.                 tsize_t w, scanline, samplingarea;
  112.                 TIFFGetField( tif, TIFFTAG_YCBCRSUBSAMPLING, 
  113.                               ycbcrsubsampling + 0, 
  114.                               ycbcrsubsampling + 1 );
  115. samplingarea = ycbcrsubsampling[0]*ycbcrsubsampling[1];
  116. if (samplingarea == 0) {
  117. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  118.      "Invalid YCbCr subsampling");
  119. return 0;
  120. }
  121. w = TIFFroundup(td->td_imagewidth, ycbcrsubsampling[0]);
  122. scanline = TIFFhowmany8(multiply(tif, w, td->td_bitspersample,
  123.  "TIFFVStripSize"));
  124. nrows = TIFFroundup(nrows, ycbcrsubsampling[1]);
  125. /* NB: don't need TIFFhowmany here 'cuz everything is rounded */
  126. scanline = multiply(tif, nrows, scanline, "TIFFVStripSize");
  127. return ((tsize_t)
  128.     summarize(tif, scanline,
  129.       multiply(tif, 2, scanline / samplingarea,
  130.        "TIFFVStripSize"), "TIFFVStripSize"));
  131. } else
  132. return ((tsize_t) multiply(tif, nrows, TIFFScanlineSize(tif),
  133.    "TIFFVStripSize"));
  134. }
  135. /*
  136.  * Compute the # bytes in a raw strip.
  137.  */
  138. tsize_t
  139. TIFFRawStripSize(TIFF* tif, tstrip_t strip)
  140. {
  141. TIFFDirectory* td = &tif->tif_dir;
  142. tsize_t bytecount = td->td_stripbytecount[strip];
  143. if (bytecount <= 0) {
  144. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  145.   "%lu: Invalid strip byte count, strip %lu",
  146.   (unsigned long) bytecount, (unsigned long) strip);
  147. bytecount = (tsize_t) -1;
  148. }
  149. return bytecount;
  150. }
  151. /*
  152.  * Compute the # bytes in a (row-aligned) strip.
  153.  *
  154.  * Note that if RowsPerStrip is larger than the
  155.  * recorded ImageLength, then the strip size is
  156.  * truncated to reflect the actual space required
  157.  * to hold the strip.
  158.  */
  159. tsize_t
  160. TIFFStripSize(TIFF* tif)
  161. {
  162. TIFFDirectory* td = &tif->tif_dir;
  163. uint32 rps = td->td_rowsperstrip;
  164. if (rps > td->td_imagelength)
  165. rps = td->td_imagelength;
  166. return (TIFFVStripSize(tif, rps));
  167. }
  168. /*
  169.  * Compute a default strip size based on the image
  170.  * characteristics and a requested value.  If the
  171.  * request is <1 then we choose a strip size according
  172.  * to certain heuristics.
  173.  */
  174. uint32
  175. TIFFDefaultStripSize(TIFF* tif, uint32 request)
  176. {
  177. return (*tif->tif_defstripsize)(tif, request);
  178. }
  179. uint32
  180. _TIFFDefaultStripSize(TIFF* tif, uint32 s)
  181. {
  182. if ((int32) s < 1) {
  183. /*
  184.  * If RowsPerStrip is unspecified, try to break the
  185.  * image up into strips that are approximately
  186.  * STRIP_SIZE_DEFAULT bytes long.
  187.  */
  188. tsize_t scanline = TIFFScanlineSize(tif);
  189. s = (uint32)STRIP_SIZE_DEFAULT / (scanline == 0 ? 1 : scanline);
  190. if (s == 0) /* very wide images */
  191. s = 1;
  192. }
  193. return (s);
  194. }
  195. /*
  196.  * Return the number of bytes to read/write in a call to
  197.  * one of the scanline-oriented i/o routines.  Note that
  198.  * this number may be 1/samples-per-pixel if data is
  199.  * stored as separate planes.
  200.  */
  201. tsize_t
  202. TIFFScanlineSize(TIFF* tif)
  203. {
  204. TIFFDirectory *td = &tif->tif_dir;
  205. tsize_t scanline;
  206. if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
  207. if (td->td_photometric == PHOTOMETRIC_YCBCR
  208.     && !isUpSampled(tif)) {
  209. uint16 ycbcrsubsampling[2];
  210. TIFFGetField(tif, TIFFTAG_YCBCRSUBSAMPLING, 
  211.      ycbcrsubsampling + 0,
  212.      ycbcrsubsampling + 1);
  213. if (ycbcrsubsampling[0] == 0) {
  214. TIFFErrorExt(tif->tif_clientdata, tif->tif_name,
  215.      "Invalid YCbCr subsampling");
  216. return 0;
  217. }
  218. scanline = TIFFroundup(td->td_imagewidth,
  219.        ycbcrsubsampling[0]);
  220. scanline = TIFFhowmany8(multiply(tif, scanline,
  221.  td->td_bitspersample,
  222.  "TIFFScanlineSize"));
  223. return ((tsize_t)
  224. summarize(tif, scanline,
  225.   multiply(tif, 2,
  226. scanline / ycbcrsubsampling[0],
  227. "TIFFVStripSize"),
  228.   "TIFFVStripSize"));
  229. } else {
  230. scanline = multiply(tif, td->td_imagewidth,
  231.     td->td_samplesperpixel,
  232.     "TIFFScanlineSize");
  233. }
  234. } else
  235. scanline = td->td_imagewidth;
  236. return ((tsize_t) TIFFhowmany8(multiply(tif, scanline,
  237. td->td_bitspersample,
  238. "TIFFScanlineSize")));
  239. }
  240. /*
  241.  * Return the number of bytes required to store a complete
  242.  * decoded and packed raster scanline (as opposed to the
  243.  * I/O size returned by TIFFScanlineSize which may be less
  244.  * if data is store as separate planes).
  245.  */
  246. tsize_t
  247. TIFFRasterScanlineSize(TIFF* tif)
  248. {
  249. TIFFDirectory *td = &tif->tif_dir;
  250. tsize_t scanline;
  251. scanline = multiply (tif, td->td_bitspersample, td->td_imagewidth,
  252.      "TIFFRasterScanlineSize");
  253. if (td->td_planarconfig == PLANARCONFIG_CONTIG) {
  254. scanline = multiply (tif, scanline, td->td_samplesperpixel,
  255.      "TIFFRasterScanlineSize");
  256. return ((tsize_t) TIFFhowmany8(scanline));
  257. } else
  258. return ((tsize_t) multiply (tif, TIFFhowmany8(scanline),
  259.     td->td_samplesperpixel,
  260.     "TIFFRasterScanlineSize"));
  261. }
  262. /* vim: set ts=8 sts=8 sw=8 noet: */