Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygentif_read.c
Go to the documentation of this file.
00001 /* $Id: tif_read.c,v 1.16.2.3 2010-06-09 14:32:47 bfriesen Exp $ */ 00002 00003 /* 00004 * Copyright (c) 1988-1997 Sam Leffler 00005 * Copyright (c) 1991-1997 Silicon Graphics, Inc. 00006 * 00007 * Permission to use, copy, modify, distribute, and sell this software and 00008 * its documentation for any purpose is hereby granted without fee, provided 00009 * that (i) the above copyright notices and this permission notice appear in 00010 * all copies of the software and related documentation, and (ii) the names of 00011 * Sam Leffler and Silicon Graphics may not be used in any advertising or 00012 * publicity relating to the software without the specific, prior written 00013 * permission of Sam Leffler and Silicon Graphics. 00014 * 00015 * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 00016 * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 00017 * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. 00018 * 00019 * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR 00020 * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, 00021 * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, 00022 * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 00023 * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 00024 * OF THIS SOFTWARE. 00025 */ 00026 00027 /* 00028 * TIFF Library. 00029 * Scanline-oriented Read Support 00030 */ 00031 #include "tiffiop.h" 00032 #include <stdio.h> 00033 00034 int TIFFFillStrip(TIFF*, tstrip_t); 00035 int TIFFFillTile(TIFF*, ttile_t); 00036 static int TIFFStartStrip(TIFF*, tstrip_t); 00037 static int TIFFStartTile(TIFF*, ttile_t); 00038 static int TIFFCheckRead(TIFF*, int); 00039 00040 #define NOSTRIP ((tstrip_t) -1) /* undefined state */ 00041 #define NOTILE ((ttile_t) -1) /* undefined state */ 00042 00043 /* 00044 * Seek to a random row+sample in a file. 00045 */ 00046 static int 00047 TIFFSeek(TIFF* tif, uint32 row, tsample_t sample) 00048 { 00049 register TIFFDirectory *td = &tif->tif_dir; 00050 tstrip_t strip; 00051 00052 if (row >= td->td_imagelength) { /* out of range */ 00053 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00054 "%lu: Row out of range, max %lu", 00055 (unsigned long) row, 00056 (unsigned long) td->td_imagelength); 00057 return (0); 00058 } 00059 if (td->td_planarconfig == PLANARCONFIG_SEPARATE) { 00060 if (sample >= td->td_samplesperpixel) { 00061 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00062 "%lu: Sample out of range, max %lu", 00063 (unsigned long) sample, (unsigned long) td->td_samplesperpixel); 00064 return (0); 00065 } 00066 strip = sample*td->td_stripsperimage + row/td->td_rowsperstrip; 00067 } else 00068 strip = row / td->td_rowsperstrip; 00069 if (strip != tif->tif_curstrip) { /* different strip, refill */ 00070 if (!TIFFFillStrip(tif, strip)) 00071 return (0); 00072 } else if (row < tif->tif_row) { 00073 /* 00074 * Moving backwards within the same strip: backup 00075 * to the start and then decode forward (below). 00076 * 00077 * NB: If you're planning on lots of random access within a 00078 * strip, it's better to just read and decode the entire 00079 * strip, and then access the decoded data in a random fashion. 00080 */ 00081 if (!TIFFStartStrip(tif, strip)) 00082 return (0); 00083 } 00084 if (row != tif->tif_row) { 00085 /* 00086 * Seek forward to the desired row. 00087 */ 00088 if (!(*tif->tif_seek)(tif, row - tif->tif_row)) 00089 return (0); 00090 tif->tif_row = row; 00091 } 00092 return (1); 00093 } 00094 00095 int 00096 TIFFReadScanline(TIFF* tif, tdata_t buf, uint32 row, tsample_t sample) 00097 { 00098 int e; 00099 00100 if (!TIFFCheckRead(tif, 0)) 00101 return (-1); 00102 if( (e = TIFFSeek(tif, row, sample)) != 0) { 00103 /* 00104 * Decompress desired row into user buffer. 00105 */ 00106 e = (*tif->tif_decoderow) 00107 (tif, (tidata_t) buf, tif->tif_scanlinesize, sample); 00108 00109 /* we are now poised at the beginning of the next row */ 00110 tif->tif_row = row + 1; 00111 00112 if (e) 00113 (*tif->tif_postdecode)(tif, (tidata_t) buf, 00114 tif->tif_scanlinesize); 00115 } 00116 return (e > 0 ? 1 : -1); 00117 } 00118 00119 /* 00120 * Read a strip of data and decompress the specified 00121 * amount into the user-supplied buffer. 00122 */ 00123 tsize_t 00124 TIFFReadEncodedStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) 00125 { 00126 TIFFDirectory *td = &tif->tif_dir; 00127 uint32 nrows; 00128 tsize_t stripsize; 00129 tstrip_t sep_strip, strips_per_sep; 00130 00131 if (!TIFFCheckRead(tif, 0)) 00132 return (-1); 00133 if (strip >= td->td_nstrips) { 00134 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00135 "%ld: Strip out of range, max %ld", 00136 (long) strip, (long) td->td_nstrips); 00137 return (-1); 00138 } 00139 /* 00140 * Calculate the strip size according to the number of 00141 * rows in the strip (check for truncated last strip on any 00142 * of the separations). 00143 */ 00144 if( td->td_rowsperstrip >= td->td_imagelength ) 00145 strips_per_sep = 1; 00146 else 00147 strips_per_sep = (td->td_imagelength+td->td_rowsperstrip-1) 00148 / td->td_rowsperstrip; 00149 00150 sep_strip = strip % strips_per_sep; 00151 00152 if (sep_strip != strips_per_sep-1 || 00153 (nrows = td->td_imagelength % td->td_rowsperstrip) == 0) 00154 nrows = td->td_rowsperstrip; 00155 00156 stripsize = TIFFVStripSize(tif, nrows); 00157 if (size == (tsize_t) -1) 00158 size = stripsize; 00159 else if (size > stripsize) 00160 size = stripsize; 00161 if (TIFFFillStrip(tif, strip) 00162 && (*tif->tif_decodestrip)(tif, (tidata_t) buf, size, 00163 (tsample_t)(strip / td->td_stripsperimage)) > 0 ) { 00164 (*tif->tif_postdecode)(tif, (tidata_t) buf, size); 00165 return (size); 00166 } else 00167 return ((tsize_t) -1); 00168 } 00169 00170 static tsize_t 00171 TIFFReadRawStrip1(TIFF* tif, 00172 tstrip_t strip, tdata_t buf, tsize_t size, const char* module) 00173 { 00174 TIFFDirectory *td = &tif->tif_dir; 00175 00176 assert((tif->tif_flags&TIFF_NOREADRAW)==0); 00177 if (!isMapped(tif)) { 00178 tsize_t cc; 00179 00180 if (!SeekOK(tif, td->td_stripoffset[strip])) { 00181 TIFFErrorExt(tif->tif_clientdata, module, 00182 "%s: Seek error at scanline %lu, strip %lu", 00183 tif->tif_name, 00184 (unsigned long) tif->tif_row, (unsigned long) strip); 00185 return (-1); 00186 } 00187 cc = TIFFReadFile(tif, buf, size); 00188 if (cc != size) { 00189 TIFFErrorExt(tif->tif_clientdata, module, 00190 "%s: Read error at scanline %lu; got %lu bytes, expected %lu", 00191 tif->tif_name, 00192 (unsigned long) tif->tif_row, 00193 (unsigned long) cc, 00194 (unsigned long) size); 00195 return (-1); 00196 } 00197 } else { 00198 if (td->td_stripoffset[strip] + size > tif->tif_size) { 00199 TIFFErrorExt(tif->tif_clientdata, module, 00200 "%s: Read error at scanline %lu, strip %lu; got %lu bytes, expected %lu", 00201 tif->tif_name, 00202 (unsigned long) tif->tif_row, 00203 (unsigned long) strip, 00204 (unsigned long) tif->tif_size - td->td_stripoffset[strip], 00205 (unsigned long) size); 00206 return (-1); 00207 } 00208 _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[strip], 00209 size); 00210 } 00211 return (size); 00212 } 00213 00214 /* 00215 * Read a strip of data from the file. 00216 */ 00217 tsize_t 00218 TIFFReadRawStrip(TIFF* tif, tstrip_t strip, tdata_t buf, tsize_t size) 00219 { 00220 static const char module[] = "TIFFReadRawStrip"; 00221 TIFFDirectory *td = &tif->tif_dir; 00222 /* 00223 * FIXME: butecount should have tsize_t type, but for now libtiff 00224 * defines tsize_t as a signed 32-bit integer and we are losing 00225 * ability to read arrays larger than 2^31 bytes. So we are using 00226 * uint32 instead of tsize_t here. 00227 */ 00228 uint32 bytecount; 00229 00230 if (!TIFFCheckRead(tif, 0)) 00231 return ((tsize_t) -1); 00232 if (strip >= td->td_nstrips) { 00233 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00234 "%lu: Strip out of range, max %lu", 00235 (unsigned long) strip, 00236 (unsigned long) td->td_nstrips); 00237 return ((tsize_t) -1); 00238 } 00239 if (tif->tif_flags&TIFF_NOREADRAW) 00240 { 00241 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00242 "Compression scheme does not support access to raw uncompressed data"); 00243 return ((tsize_t) -1); 00244 } 00245 bytecount = td->td_stripbytecount[strip]; 00246 if (bytecount <= 0) { 00247 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00248 "%lu: Invalid strip byte count, strip %lu", 00249 (unsigned long) bytecount, (unsigned long) strip); 00250 return ((tsize_t) -1); 00251 } 00252 if (size != (tsize_t)-1 && (uint32)size < bytecount) 00253 bytecount = size; 00254 return (TIFFReadRawStrip1(tif, strip, buf, bytecount, module)); 00255 } 00256 00257 /* 00258 * Read the specified strip and setup for decoding. The data buffer is 00259 * expanded, as necessary, to hold the strip's data. 00260 */ 00261 int 00262 TIFFFillStrip(TIFF* tif, tstrip_t strip) 00263 { 00264 static const char module[] = "TIFFFillStrip"; 00265 TIFFDirectory *td = &tif->tif_dir; 00266 00267 if ((tif->tif_flags&TIFF_NOREADRAW)==0) 00268 { 00269 /* 00270 * FIXME: butecount should have tsize_t type, but for now 00271 * libtiff defines tsize_t as a signed 32-bit integer and we 00272 * are losing ability to read arrays larger than 2^31 bytes. 00273 * So we are using uint32 instead of tsize_t here. 00274 */ 00275 uint32 bytecount = td->td_stripbytecount[strip]; 00276 if (bytecount <= 0) { 00277 TIFFErrorExt(tif->tif_clientdata, module, 00278 "%s: Invalid strip byte count %lu, strip %lu", 00279 tif->tif_name, (unsigned long) bytecount, 00280 (unsigned long) strip); 00281 return (0); 00282 } 00283 if (isMapped(tif) && 00284 (isFillOrder(tif, td->td_fillorder) 00285 || (tif->tif_flags & TIFF_NOBITREV))) { 00286 /* 00287 * The image is mapped into memory and we either don't 00288 * need to flip bits or the compression routine is 00289 * going to handle this operation itself. In this 00290 * case, avoid copying the raw data and instead just 00291 * reference the data from the memory mapped file 00292 * image. This assumes that the decompression 00293 * routines do not modify the contents of the raw data 00294 * buffer (if they try to, the application will get a 00295 * fault since the file is mapped read-only). 00296 */ 00297 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) 00298 _TIFFfree(tif->tif_rawdata); 00299 tif->tif_flags &= ~TIFF_MYBUFFER; 00300 /* 00301 * We must check for overflow, potentially causing 00302 * an OOB read. Instead of simple 00303 * 00304 * td->td_stripoffset[strip]+bytecount > tif->tif_size 00305 * 00306 * comparison (which can overflow) we do the following 00307 * two comparisons: 00308 */ 00309 if (bytecount > tif->tif_size || 00310 td->td_stripoffset[strip] > tif->tif_size - bytecount) { 00311 /* 00312 * This error message might seem strange, but 00313 * it's what would happen if a read were done 00314 * instead. 00315 */ 00316 TIFFErrorExt(tif->tif_clientdata, module, 00317 00318 "%s: Read error on strip %lu; " 00319 "got %lu bytes, expected %lu", 00320 tif->tif_name, (unsigned long) strip, 00321 (unsigned long) tif->tif_size - td->td_stripoffset[strip], 00322 (unsigned long) bytecount); 00323 tif->tif_curstrip = NOSTRIP; 00324 return (0); 00325 } 00326 tif->tif_rawdatasize = bytecount; 00327 tif->tif_rawdata = tif->tif_base + td->td_stripoffset[strip]; 00328 } else { 00329 /* 00330 * Expand raw data buffer, if needed, to hold data 00331 * strip coming from file (perhaps should set upper 00332 * bound on the size of a buffer we'll use?). 00333 */ 00334 if (bytecount > (uint32)tif->tif_rawdatasize) { 00335 tif->tif_curstrip = NOSTRIP; 00336 if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { 00337 TIFFErrorExt(tif->tif_clientdata, 00338 module, 00339 "%s: Data buffer too small to hold strip %lu", 00340 tif->tif_name, 00341 (unsigned long) strip); 00342 return (0); 00343 } 00344 if (!TIFFReadBufferSetup(tif, 0, 00345 TIFFroundup(bytecount, 1024))) 00346 return (0); 00347 } 00348 if ((uint32)TIFFReadRawStrip1(tif, strip, 00349 (unsigned char *)tif->tif_rawdata, 00350 bytecount, module) != bytecount) 00351 return (0); 00352 if (!isFillOrder(tif, td->td_fillorder) && 00353 (tif->tif_flags & TIFF_NOBITREV) == 0) 00354 TIFFReverseBits(tif->tif_rawdata, bytecount); 00355 } 00356 } 00357 return (TIFFStartStrip(tif, strip)); 00358 } 00359 00360 /* 00361 * Tile-oriented Read Support 00362 * Contributed by Nancy Cam (Silicon Graphics). 00363 */ 00364 00365 /* 00366 * Read and decompress a tile of data. The 00367 * tile is selected by the (x,y,z,s) coordinates. 00368 */ 00369 tsize_t 00370 TIFFReadTile(TIFF* tif, 00371 tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s) 00372 { 00373 if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) 00374 return (-1); 00375 return (TIFFReadEncodedTile(tif, 00376 TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1)); 00377 } 00378 00379 /* 00380 * Read a tile of data and decompress the specified 00381 * amount into the user-supplied buffer. 00382 */ 00383 tsize_t 00384 TIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) 00385 { 00386 TIFFDirectory *td = &tif->tif_dir; 00387 tsize_t tilesize = tif->tif_tilesize; 00388 00389 if (!TIFFCheckRead(tif, 1)) 00390 return (-1); 00391 if (tile >= td->td_nstrips) { 00392 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00393 "%ld: Tile out of range, max %ld", 00394 (long) tile, (unsigned long) td->td_nstrips); 00395 return (-1); 00396 } 00397 if (size == (tsize_t) -1) 00398 size = tilesize; 00399 else if (size > tilesize) 00400 size = tilesize; 00401 if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, 00402 (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) { 00403 (*tif->tif_postdecode)(tif, (tidata_t) buf, size); 00404 return (size); 00405 } else 00406 return (-1); 00407 } 00408 00409 static tsize_t 00410 TIFFReadRawTile1(TIFF* tif, 00411 ttile_t tile, tdata_t buf, tsize_t size, const char* module) 00412 { 00413 TIFFDirectory *td = &tif->tif_dir; 00414 00415 assert((tif->tif_flags&TIFF_NOREADRAW)==0); 00416 if (!isMapped(tif)) { 00417 tsize_t cc; 00418 00419 if (!SeekOK(tif, td->td_stripoffset[tile])) { 00420 TIFFErrorExt(tif->tif_clientdata, module, 00421 "%s: Seek error at row %ld, col %ld, tile %ld", 00422 tif->tif_name, 00423 (long) tif->tif_row, 00424 (long) tif->tif_col, 00425 (long) tile); 00426 return ((tsize_t) -1); 00427 } 00428 cc = TIFFReadFile(tif, buf, size); 00429 if (cc != size) { 00430 TIFFErrorExt(tif->tif_clientdata, module, 00431 "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu", 00432 tif->tif_name, 00433 (long) tif->tif_row, 00434 (long) tif->tif_col, 00435 (unsigned long) cc, 00436 (unsigned long) size); 00437 return ((tsize_t) -1); 00438 } 00439 } else { 00440 if (td->td_stripoffset[tile] + size > tif->tif_size) { 00441 TIFFErrorExt(tif->tif_clientdata, module, 00442 "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu", 00443 tif->tif_name, 00444 (long) tif->tif_row, 00445 (long) tif->tif_col, 00446 (long) tile, 00447 (unsigned long) tif->tif_size - td->td_stripoffset[tile], 00448 (unsigned long) size); 00449 return ((tsize_t) -1); 00450 } 00451 _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size); 00452 } 00453 return (size); 00454 } 00455 00456 /* 00457 * Read a tile of data from the file. 00458 */ 00459 tsize_t 00460 TIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size) 00461 { 00462 static const char module[] = "TIFFReadRawTile"; 00463 TIFFDirectory *td = &tif->tif_dir; 00464 /* 00465 * FIXME: butecount should have tsize_t type, but for now libtiff 00466 * defines tsize_t as a signed 32-bit integer and we are losing 00467 * ability to read arrays larger than 2^31 bytes. So we are using 00468 * uint32 instead of tsize_t here. 00469 */ 00470 uint32 bytecount; 00471 00472 if (!TIFFCheckRead(tif, 1)) 00473 return ((tsize_t) -1); 00474 if (tile >= td->td_nstrips) { 00475 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00476 "%lu: Tile out of range, max %lu", 00477 (unsigned long) tile, (unsigned long) td->td_nstrips); 00478 return ((tsize_t) -1); 00479 } 00480 if (tif->tif_flags&TIFF_NOREADRAW) 00481 { 00482 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00483 "Compression scheme does not support access to raw uncompressed data"); 00484 return ((tsize_t) -1); 00485 } 00486 bytecount = td->td_stripbytecount[tile]; 00487 if (size != (tsize_t) -1 && (uint32)size < bytecount) 00488 bytecount = size; 00489 return (TIFFReadRawTile1(tif, tile, buf, bytecount, module)); 00490 } 00491 00492 /* 00493 * Read the specified tile and setup for decoding. The data buffer is 00494 * expanded, as necessary, to hold the tile's data. 00495 */ 00496 int 00497 TIFFFillTile(TIFF* tif, ttile_t tile) 00498 { 00499 static const char module[] = "TIFFFillTile"; 00500 TIFFDirectory *td = &tif->tif_dir; 00501 00502 if ((tif->tif_flags&TIFF_NOREADRAW)==0) 00503 { 00504 /* 00505 * FIXME: butecount should have tsize_t type, but for now 00506 * libtiff defines tsize_t as a signed 32-bit integer and we 00507 * are losing ability to read arrays larger than 2^31 bytes. 00508 * So we are using uint32 instead of tsize_t here. 00509 */ 00510 uint32 bytecount = td->td_stripbytecount[tile]; 00511 if (bytecount <= 0) { 00512 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, 00513 "%lu: Invalid tile byte count, tile %lu", 00514 (unsigned long) bytecount, (unsigned long) tile); 00515 return (0); 00516 } 00517 if (isMapped(tif) && 00518 (isFillOrder(tif, td->td_fillorder) 00519 || (tif->tif_flags & TIFF_NOBITREV))) { 00520 /* 00521 * The image is mapped into memory and we either don't 00522 * need to flip bits or the compression routine is 00523 * going to handle this operation itself. In this 00524 * case, avoid copying the raw data and instead just 00525 * reference the data from the memory mapped file 00526 * image. This assumes that the decompression 00527 * routines do not modify the contents of the raw data 00528 * buffer (if they try to, the application will get a 00529 * fault since the file is mapped read-only). 00530 */ 00531 if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) 00532 _TIFFfree(tif->tif_rawdata); 00533 tif->tif_flags &= ~TIFF_MYBUFFER; 00534 /* 00535 * We must check for overflow, potentially causing 00536 * an OOB read. Instead of simple 00537 * 00538 * td->td_stripoffset[tile]+bytecount > tif->tif_size 00539 * 00540 * comparison (which can overflow) we do the following 00541 * two comparisons: 00542 */ 00543 if (bytecount > tif->tif_size || 00544 td->td_stripoffset[tile] > tif->tif_size - bytecount) { 00545 tif->tif_curtile = NOTILE; 00546 return (0); 00547 } 00548 tif->tif_rawdatasize = bytecount; 00549 tif->tif_rawdata = 00550 tif->tif_base + td->td_stripoffset[tile]; 00551 } else { 00552 /* 00553 * Expand raw data buffer, if needed, to hold data 00554 * tile coming from file (perhaps should set upper 00555 * bound on the size of a buffer we'll use?). 00556 */ 00557 if (bytecount > (uint32)tif->tif_rawdatasize) { 00558 tif->tif_curtile = NOTILE; 00559 if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { 00560 TIFFErrorExt(tif->tif_clientdata, 00561 module, 00562 "%s: Data buffer too small to hold tile %ld", 00563 tif->tif_name, 00564 (long) tile); 00565 return (0); 00566 } 00567 if (!TIFFReadBufferSetup(tif, 0, 00568 TIFFroundup(bytecount, 1024))) 00569 return (0); 00570 } 00571 if ((uint32)TIFFReadRawTile1(tif, tile, 00572 (unsigned char *)tif->tif_rawdata, 00573 bytecount, module) != bytecount) 00574 return (0); 00575 if (!isFillOrder(tif, td->td_fillorder) && 00576 (tif->tif_flags & TIFF_NOBITREV) == 0) 00577 TIFFReverseBits(tif->tif_rawdata, bytecount); 00578 } 00579 } 00580 return (TIFFStartTile(tif, tile)); 00581 } 00582 00583 /* 00584 * Setup the raw data buffer in preparation for 00585 * reading a strip of raw data. If the buffer 00586 * is specified as zero, then a buffer of appropriate 00587 * size is allocated by the library. Otherwise, 00588 * the client must guarantee that the buffer is 00589 * large enough to hold any individual strip of 00590 * raw data. 00591 */ 00592 int 00593 TIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size) 00594 { 00595 static const char module[] = "TIFFReadBufferSetup"; 00596 00597 assert((tif->tif_flags&TIFF_NOREADRAW)==0); 00598 if (tif->tif_rawdata) { 00599 if (tif->tif_flags & TIFF_MYBUFFER) 00600 _TIFFfree(tif->tif_rawdata); 00601 tif->tif_rawdata = NULL; 00602 } 00603 00604 if (bp) { 00605 tif->tif_rawdatasize = size; 00606 tif->tif_rawdata = (tidata_t) bp; 00607 tif->tif_flags &= ~TIFF_MYBUFFER; 00608 } else { 00609 tif->tif_rawdatasize = TIFFroundup(size, 1024); 00610 if (tif->tif_rawdatasize > 0) 00611 tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize); 00612 tif->tif_flags |= TIFF_MYBUFFER; 00613 } 00614 if ((tif->tif_rawdata == NULL) || (tif->tif_rawdatasize == 0)) { 00615 TIFFErrorExt(tif->tif_clientdata, module, 00616 "%s: No space for data buffer at scanline %ld", 00617 tif->tif_name, (long) tif->tif_row); 00618 tif->tif_rawdatasize = 0; 00619 return (0); 00620 } 00621 return (1); 00622 } 00623 00624 /* 00625 * Set state to appear as if a 00626 * strip has just been read in. 00627 */ 00628 static int 00629 TIFFStartStrip(TIFF* tif, tstrip_t strip) 00630 { 00631 TIFFDirectory *td = &tif->tif_dir; 00632 00633 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 00634 if (!(*tif->tif_setupdecode)(tif)) 00635 return (0); 00636 tif->tif_flags |= TIFF_CODERSETUP; 00637 } 00638 tif->tif_curstrip = strip; 00639 tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; 00640 if (tif->tif_flags&TIFF_NOREADRAW) 00641 { 00642 tif->tif_rawcp = NULL; 00643 tif->tif_rawcc = 0; 00644 } 00645 else 00646 { 00647 tif->tif_rawcp = tif->tif_rawdata; 00648 tif->tif_rawcc = td->td_stripbytecount[strip]; 00649 } 00650 return ((*tif->tif_predecode)(tif, 00651 (tsample_t)(strip / td->td_stripsperimage))); 00652 } 00653 00654 /* 00655 * Set state to appear as if a 00656 * tile has just been read in. 00657 */ 00658 static int 00659 TIFFStartTile(TIFF* tif, ttile_t tile) 00660 { 00661 TIFFDirectory *td = &tif->tif_dir; 00662 00663 if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { 00664 if (!(*tif->tif_setupdecode)(tif)) 00665 return (0); 00666 tif->tif_flags |= TIFF_CODERSETUP; 00667 } 00668 tif->tif_curtile = tile; 00669 tif->tif_row = 00670 (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) * 00671 td->td_tilelength; 00672 tif->tif_col = 00673 (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) * 00674 td->td_tilewidth; 00675 if (tif->tif_flags&TIFF_NOREADRAW) 00676 { 00677 tif->tif_rawcp = NULL; 00678 tif->tif_rawcc = 0; 00679 } 00680 else 00681 { 00682 tif->tif_rawcp = tif->tif_rawdata; 00683 tif->tif_rawcc = td->td_stripbytecount[tile]; 00684 } 00685 return ((*tif->tif_predecode)(tif, 00686 (tsample_t)(tile/td->td_stripsperimage))); 00687 } 00688 00689 static int 00690 TIFFCheckRead(TIFF* tif, int tiles) 00691 { 00692 if (tif->tif_mode == O_WRONLY) { 00693 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, "File not open for reading"); 00694 return (0); 00695 } 00696 if (tiles ^ isTiled(tif)) { 00697 TIFFErrorExt(tif->tif_clientdata, tif->tif_name, tiles ? 00698 "Can not read tiles from a stripped image" : 00699 "Can not read scanlines from a tiled image"); 00700 return (0); 00701 } 00702 return (1); 00703 } 00704 00705 void 00706 _TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc) 00707 { 00708 (void) tif; (void) buf; (void) cc; 00709 } 00710 00711 void 00712 _TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc) 00713 { 00714 (void) tif; 00715 assert((cc & 1) == 0); 00716 TIFFSwabArrayOfShort((uint16*) buf, cc/2); 00717 } 00718 00719 void 00720 _TIFFSwab24BitData(TIFF* tif, tidata_t buf, tsize_t cc) 00721 { 00722 (void) tif; 00723 assert((cc % 3) == 0); 00724 TIFFSwabArrayOfTriples((uint8*) buf, cc/3); 00725 } 00726 00727 void 00728 _TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc) 00729 { 00730 (void) tif; 00731 assert((cc & 3) == 0); 00732 TIFFSwabArrayOfLong((uint32*) buf, cc/4); 00733 } 00734 00735 void 00736 _TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc) 00737 { 00738 (void) tif; 00739 assert((cc & 7) == 0); 00740 TIFFSwabArrayOfDouble((double*) buf, cc/8); 00741 } 00742 00743 /* vim: set ts=8 sts=8 sw=8 noet: */ 00744 /* 00745 * Local Variables: 00746 * mode: c 00747 * c-basic-offset: 8 00748 * fill-column: 78 00749 * End: 00750 */ Generated on Mon May 28 2012 04:19:24 for ReactOS by
1.7.6.1
|