📄 tif_read.c
字号:
*//* * Read and decompress a tile of data. The * tile is selected by the (x,y,z,s) coordinates. */tsize_tTIFFReadTile(TIFF* tif, tdata_t buf, uint32 x, uint32 y, uint32 z, tsample_t s){ if (!TIFFCheckRead(tif, 1) || !TIFFCheckTile(tif, x, y, z, s)) return (-1); return (TIFFReadEncodedTile(tif, TIFFComputeTile(tif, x, y, z, s), buf, (tsize_t) -1));}/* * Read a tile of data and decompress the specified * amount into the user-supplied buffer. */tsize_tTIFFReadEncodedTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size){ TIFFDirectory *td = &tif->tif_dir; tsize_t tilesize = tif->tif_tilesize; if (!TIFFCheckRead(tif, 1)) return (-1); if (tile >= td->td_nstrips) { TIFFError(tif->tif_name, "%ld: Tile out of range, max %ld", (long) tile, (u_long) td->td_nstrips); return (-1); } if (size == (tsize_t) -1) size = tilesize; else if (size > tilesize) size = tilesize; if (TIFFFillTile(tif, tile) && (*tif->tif_decodetile)(tif, (tidata_t) buf, size, (tsample_t)(tile/td->td_stripsperimage))) { (*tif->tif_postdecode)(tif, (tidata_t) buf, size); return (size); } else return (-1);}static tsize_tTIFFReadRawTile1(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size, const char* module){ TIFFDirectory *td = &tif->tif_dir; if (!isMapped(tif)) { tsize_t cc; if (!SeekOK(tif, td->td_stripoffset[tile])) { TIFFError(module, "%s: Seek error at row %ld, col %ld, tile %ld", tif->tif_name, (long) tif->tif_row, (long) tif->tif_col, (long) tile); return ((tsize_t) -1); } cc = TIFFReadFile(tif, buf, size); if (cc != size) { TIFFError(module, "%s: Read error at row %ld, col %ld; got %lu bytes, expected %lu", tif->tif_name, (long) tif->tif_row, (long) tif->tif_col, (u_long) cc, (u_long) size); return ((tsize_t) -1); } } else { if (td->td_stripoffset[tile] + size > tif->tif_size) { TIFFError(module, "%s: Read error at row %ld, col %ld, tile %ld; got %lu bytes, expected %lu", tif->tif_name, (long) tif->tif_row, (long) tif->tif_col, (long) tile, (u_long) tif->tif_size - td->td_stripoffset[tile], (u_long) size); return ((tsize_t) -1); } _TIFFmemcpy(buf, tif->tif_base + td->td_stripoffset[tile], size); } return (size);}/* * Read a tile of data from the file. */tsize_tTIFFReadRawTile(TIFF* tif, ttile_t tile, tdata_t buf, tsize_t size){ static const char module[] = "TIFFReadRawTile"; TIFFDirectory *td = &tif->tif_dir; tsize_t bytecount; if (!TIFFCheckRead(tif, 1)) return ((tsize_t) -1); if (tile >= td->td_nstrips) { TIFFError(tif->tif_name, "%lu: Tile out of range, max %lu", (u_long) tile, (u_long) td->td_nstrips); return ((tsize_t) -1); } bytecount = td->td_stripbytecount[tile]; if (size != (tsize_t) -1 && size < bytecount) bytecount = size; return (TIFFReadRawTile1(tif, tile, buf, bytecount, module));}/* * Read the specified tile and setup for decoding. * The data buffer is expanded, as necessary, to * hold the tile's data. */static intTIFFFillTile(TIFF* tif, ttile_t tile){ static const char module[] = "TIFFFillTile"; TIFFDirectory *td = &tif->tif_dir; tsize_t bytecount; bytecount = td->td_stripbytecount[tile]; if (bytecount <= 0) { TIFFError(tif->tif_name, "%lu: Invalid tile byte count, tile %lu", (u_long) bytecount, (u_long) tile); return (0); } if (isMapped(tif) && (isFillOrder(tif, td->td_fillorder) || (tif->tif_flags & TIFF_NOBITREV))) { /* * The image is mapped into memory and we either don't * need to flip bits or the compression routine is going * to handle this operation itself. In this case, avoid * copying the raw data and instead just reference the * data from the memory mapped file image. This assumes * that the decompression routines do not modify the * contents of the raw data buffer (if they try to, * the application will get a fault since the file is * mapped read-only). */ if ((tif->tif_flags & TIFF_MYBUFFER) && tif->tif_rawdata) _TIFFfree(tif->tif_rawdata); tif->tif_flags &= ~TIFF_MYBUFFER; if ( td->td_stripoffset[tile] + bytecount > tif->tif_size) { tif->tif_curtile = NOTILE; return (0); } tif->tif_rawdatasize = bytecount; tif->tif_rawdata = tif->tif_base + td->td_stripoffset[tile]; } else { /* * Expand raw data buffer, if needed, to * hold data tile coming from file * (perhaps should set upper bound on * the size of a buffer we'll use?). */ if (bytecount > tif->tif_rawdatasize) { tif->tif_curtile = NOTILE; if ((tif->tif_flags & TIFF_MYBUFFER) == 0) { TIFFError(module, "%s: Data buffer too small to hold tile %ld", tif->tif_name, (long) tile); return (0); } if (!TIFFReadBufferSetup(tif, 0, TIFFroundup(bytecount, 1024))) return (0); } if (TIFFReadRawTile1(tif, tile, (u_char *)tif->tif_rawdata, bytecount, module) != bytecount) return (0); if (!isFillOrder(tif, td->td_fillorder) && (tif->tif_flags & TIFF_NOBITREV) == 0) TIFFReverseBits(tif->tif_rawdata, bytecount); } return (TIFFStartTile(tif, tile));}/* * Setup the raw data buffer in preparation for * reading a strip of raw data. If the buffer * is specified as zero, then a buffer of appropriate * size is allocated by the library. Otherwise, * the client must guarantee that the buffer is * large enough to hold any individual strip of * raw data. */intTIFFReadBufferSetup(TIFF* tif, tdata_t bp, tsize_t size){ static const char module[] = "TIFFReadBufferSetup"; if (tif->tif_rawdata) { if (tif->tif_flags & TIFF_MYBUFFER) _TIFFfree(tif->tif_rawdata); tif->tif_rawdata = NULL; } if (bp) { tif->tif_rawdatasize = size; tif->tif_rawdata = (tidata_t) bp; tif->tif_flags &= ~TIFF_MYBUFFER; } else { tif->tif_rawdatasize = TIFFroundup(size, 1024); tif->tif_rawdata = (tidata_t) _TIFFmalloc(tif->tif_rawdatasize); tif->tif_flags |= TIFF_MYBUFFER; } if (tif->tif_rawdata == NULL) { TIFFError(module, "%s: No space for data buffer at scanline %ld", tif->tif_name, (long) tif->tif_row); tif->tif_rawdatasize = 0; return (0); } return (1);}/* * Set state to appear as if a * strip has just been read in. */static intTIFFStartStrip(TIFF* tif, tstrip_t strip){ TIFFDirectory *td = &tif->tif_dir; if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupdecode)(tif)) return (0); tif->tif_flags |= TIFF_CODERSETUP; } tif->tif_curstrip = strip; tif->tif_row = (strip % td->td_stripsperimage) * td->td_rowsperstrip; tif->tif_rawcp = tif->tif_rawdata; tif->tif_rawcc = td->td_stripbytecount[strip]; return ((*tif->tif_predecode)(tif, (tsample_t)(strip / td->td_stripsperimage)));}/* * Set state to appear as if a * tile has just been read in. */static intTIFFStartTile(TIFF* tif, ttile_t tile){ TIFFDirectory *td = &tif->tif_dir; if ((tif->tif_flags & TIFF_CODERSETUP) == 0) { if (!(*tif->tif_setupdecode)(tif)) return (0); tif->tif_flags |= TIFF_CODERSETUP; } tif->tif_curtile = tile; tif->tif_row = (tile % TIFFhowmany(td->td_imagewidth, td->td_tilewidth)) * td->td_tilelength; tif->tif_col = (tile % TIFFhowmany(td->td_imagelength, td->td_tilelength)) * td->td_tilewidth; tif->tif_rawcp = tif->tif_rawdata; tif->tif_rawcc = td->td_stripbytecount[tile]; return ((*tif->tif_predecode)(tif, (tsample_t)(tile/td->td_stripsperimage)));}static intTIFFCheckRead(TIFF* tif, int tiles){ if (tif->tif_mode == O_WRONLY) { TIFFError(tif->tif_name, "File not open for reading"); return (0); } if (tiles ^ isTiled(tif)) { TIFFError(tif->tif_name, tiles ? "Can not read tiles from a stripped image" : "Can not read scanlines from a tiled image"); return (0); } return (1);}void_TIFFNoPostDecode(TIFF* tif, tidata_t buf, tsize_t cc){ (void) tif; (void) buf; (void) cc;}void_TIFFSwab16BitData(TIFF* tif, tidata_t buf, tsize_t cc){ (void) tif; assert((cc & 1) == 0); TIFFSwabArrayOfShort((uint16*) buf, cc/2);}void_TIFFSwab32BitData(TIFF* tif, tidata_t buf, tsize_t cc){ (void) tif; assert((cc & 3) == 0); TIFFSwabArrayOfLong((uint32*) buf, cc/4);}void_TIFFSwab64BitData(TIFF* tif, tidata_t buf, tsize_t cc){ (void) tif; assert((cc & 7) == 0); TIFFSwabArrayOfDouble((double*) buf, cc/8);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -