static int TIFFReadRawTile1(TIFF tif, uint tile, byte[] buf, int size, string module) { TIFFDirectory td = tif.tif_dir; #if DEBUG if ((tif.tif_flags & TIF_FLAGS.TIFF_NOREADRAW) != 0) { throw new Exception("(tif.tif_flags&TIF_FLAGS.TIFF.NOREADRAW)==0"); } #endif if (!SeekOK(tif, td.td_stripoffset[tile])) { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Seek error at row {1}, col {2}, tile {3}", tif.tif_name, tif.tif_row, tif.tif_col, tile); return(-1); } int cc = TIFFReadFile(tif, buf, size); if (cc != size) { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Read error at row {1}, col {2}; got {3} bytes, expected {4}", tif.tif_name, tif.tif_row, tif.tif_col, cc, size); return(-1); } return(size); }
// Set state to appear as if a // strip has just been read in. static bool TIFFStartStrip(TIFF tif, uint strip) { TIFFDirectory td = tif.tif_dir; if ((tif.tif_flags & TIF_FLAGS.TIFF_CODERSETUP) == 0) { if (!tif.tif_setupdecode(tif)) { return(false); } tif.tif_flags |= TIF_FLAGS.TIFF_CODERSETUP; } tif.tif_curstrip = strip; tif.tif_row = (strip % td.td_stripsperimage) * td.td_rowsperstrip; if ((tif.tif_flags & TIF_FLAGS.TIFF_NOREADRAW) == TIF_FLAGS.TIFF_NOREADRAW) { tif.tif_rawdata = null; // ????? tif.tif_rawcp = 0; tif.tif_rawcc = 0; } else { tif.tif_rawcp = 0; //was tif.tif_rawdata; tif.tif_rawcc = td.td_stripbytecount[strip]; } return(tif.tif_predecode(tif, (ushort)(strip / td.td_stripsperimage))); }
private void CompareTiffImages(byte[] cmpBytes, byte[] resultBytes) { int cmpNumDirectories = TIFFDirectory.GetNumDirectories(new RandomAccessFileOrArray(new RandomAccessSourceFactory ().CreateSource(cmpBytes))); int resultNumDirectories = TIFFDirectory.GetNumDirectories(new RandomAccessFileOrArray(new RandomAccessSourceFactory ().CreateSource(resultBytes))); NUnit.Framework.Assert.AreEqual(cmpNumDirectories, resultNumDirectories); for (int dirNum = 0; dirNum < cmpNumDirectories; ++dirNum) { TIFFDirectory cmpDir = new TIFFDirectory(new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource (cmpBytes)), dirNum); TIFFDirectory resultDir = new TIFFDirectory(new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource (resultBytes)), dirNum); NUnit.Framework.Assert.AreEqual(cmpDir.GetNumEntries(), resultDir.GetNumEntries()); NUnit.Framework.Assert.AreEqual(cmpDir.GetIFDOffset(), resultDir.GetIFDOffset()); NUnit.Framework.Assert.AreEqual(cmpDir.GetNextIFDOffset(), resultDir.GetNextIFDOffset()); NUnit.Framework.Assert.AreEqual(cmpDir.GetTags(), resultDir.GetTags()); foreach (int tag in cmpDir.GetTags()) { NUnit.Framework.Assert.AreEqual(cmpDir.IsTagPresent(tag), resultDir.IsTagPresent(tag)); TIFFField cmpField = cmpDir.GetField(tag); TIFFField resultField = resultDir.GetField(tag); if (tag == TIFFConstants.TIFFTAG_SOFTWARE) { CompareSoftwareVersion(cmpField, resultField); } else { CompareFields(cmpField, resultField); } } CompareImageData(cmpDir, resultDir, cmpBytes, resultBytes); } }
// Return the number of bytes to read/write in a call to // one of the scanline-oriented i/o routines. Note that // this number may be 1/samples-per-pixel if data is // stored as separate planes. public static int TIFFScanlineSize(TIFF tif) { TIFFDirectory td = tif.tif_dir; uint scanline; if (td.td_planarconfig == PLANARCONFIG.CONTIG) { if (td.td_photometric == PHOTOMETRIC.YCBCR && !isUpSampled(tif)) { object[] ap = new object[2]; TIFFGetField(tif, TIFFTAG.YCBCRSUBSAMPLING, ap); ushort ycbcrsubsampling0 = __GetAsUshort(ap, 0); //ushort ycbcrsubsampling1=__GetAsUshort(ap, 1); // not needed if (ycbcrsubsampling0 == 0) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "Invalid YCbCr subsampling"); return(0); } scanline = TIFFroundup(td.td_imagewidth, ycbcrsubsampling0); scanline = TIFFhowmany8(multiply(tif, scanline, td.td_bitspersample, "TIFFScanlineSize")); return((int)summarize(tif, scanline, multiply(tif, 2, scanline / ycbcrsubsampling0, "TIFFVStripSize"), "TIFFVStripSize")); } scanline = multiply(tif, td.td_imagewidth, td.td_samplesperpixel, "TIFFScanlineSize"); } else { scanline = td.td_imagewidth; } return((int)TIFFhowmany8(multiply(tif, scanline, td.td_bitspersample, "TIFFScanlineSize"))); }
// Set state to appear as if a // tile has just been read in. static bool TIFFStartTile(TIFF tif, uint tile) { TIFFDirectory td = tif.tif_dir; if ((tif.tif_flags & TIF_FLAGS.TIFF_CODERSETUP) == 0) { if (!tif.tif_setupdecode(tif)) { return(false); } tif.tif_flags |= 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; if ((tif.tif_flags & TIF_FLAGS.TIFF_NOREADRAW) == TIF_FLAGS.TIFF_NOREADRAW) { tif.tif_rawdata = null; // ????? tif.tif_rawcp = 0; tif.tif_rawcc = 0; } else { tif.tif_rawcp = 0; //was tif.tif_rawdata; tif.tif_rawcc = td.td_stripbytecount[tile]; } return(tif.tif_predecode(tif, (ushort)(tile / td.td_stripsperimage))); }
// Read a tile of data and decompress the specified // amount into the user-supplied buffer. public static int TIFFReadEncodedTile(TIFF tif, uint tile, byte[] buf, int size) { TIFFDirectory td = tif.tif_dir; int tilesize = tif.tif_tilesize; if (!TIFFCheckRead(tif, true)) { return(-1); } if (tile >= td.td_nstrips) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Tile out of range, max {1}", tile, td.td_nstrips); return(-1); } if (size == -1) { size = tilesize; } else if (size > tilesize) { size = tilesize; } if (TIFFFillTile(tif, tile) && tif.tif_decodetile(tif, buf, size, (ushort)(tile / td.td_stripsperimage))) { tif.tif_postdecode(tif, buf, 0, size); return(size); } return(-1); }
private static long[] GetArrayLongShort(TIFFDirectory dir, int tag) { TIFFField field = dir.GetField(tag); if (field == null) { return(null); } long[] offset; if (field.GetFieldType() == TIFFField.TIFF_LONG) { offset = field.GetAsLongs(); } else { // must be short char[] temp = field.GetAsChars(); offset = new long[temp.Length]; for (int k = 0; k < temp.Length; ++k) { offset[k] = temp[k]; } } return(offset); }
// Check an (x,y,z,s) coordinate against the image bounds. public static bool TIFFCheckTile(TIFF tif, uint x, uint y, uint z, ushort s) { TIFFDirectory td = tif.tif_dir; if (x >= td.td_imagewidth) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Col out of range, max {1}", x, td.td_imagewidth - 1); return(false); } if (y >= td.td_imagelength) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Row out of range, max {1}", y, td.td_imagelength - 1); return(false); } if (z >= td.td_imagedepth) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Depth out of range, max {1}", z, td.td_imagedepth - 1); return(false); } if (td.td_planarconfig == PLANARCONFIG.SEPARATE && s >= td.td_samplesperpixel) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Sample out of range, max {1}", s, td.td_samplesperpixel - 1); return(false); } return(true); }
// Read a tile of data from the file. public static int TIFFReadRawTile(TIFF tif, uint tile, byte[] buf, int size) { string module = "TIFFReadRawTile"; TIFFDirectory td = tif.tif_dir; if (!TIFFCheckRead(tif, true)) { return(-1); } if (tile >= td.td_nstrips) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Tile out of range, max {1}", tile, td.td_nstrips); return(-1); } if ((tif.tif_flags & TIF_FLAGS.TIFF_NOREADRAW) == TIF_FLAGS.TIFF_NOREADRAW) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "Compression scheme does not support access to raw uncompressed data"); return(-1); } // FIXME: butecount should have tsize_t type, but for now libtiff // defines tsize_t as a signed 32-bit integer and we are losing // ability to read arrays larger than 2^31 bytes. So we are using // uint32 instead of tsize_t here. uint bytecount = td.td_stripbytecount[tile]; if (size != -1 && (uint)size < bytecount) { bytecount = (uint)size; } return(TIFFReadRawTile1(tif, tile, buf, (int)bytecount, module)); }
// Compute how many tiles are in an image. public static uint TIFFNumberOfTiles(TIFF tif) { TIFFDirectory td = tif.tif_dir; uint dx = td.td_tilewidth; uint dy = td.td_tilelength; uint dz = td.td_tiledepth; uint ntiles; if (dx == 0xffffffff) { dx = td.td_imagewidth; } if (dy == 0xffffffff) { dy = td.td_imagelength; } if (dz == 0xffffffff) { dz = td.td_imagedepth; } ntiles = (dx == 0 || dy == 0 || dz == 0)?0: multiply(tif, multiply(tif, TIFFhowmany(td.td_imagewidth, dx), TIFFhowmany(td.td_imagelength, dy), "TIFFNumberOfTiles"), TIFFhowmany(td.td_imagedepth, dz), "TIFFNumberOfTiles"); if (td.td_planarconfig == PLANARCONFIG.SEPARATE) { ntiles = multiply(tif, ntiles, td.td_samplesperpixel, "TIFFNumberOfTiles"); } return(ntiles); }
// Read a strip of data and decompress the specified // amount into the user-supplied buffer. public static int TIFFReadEncodedStrip(TIFF tif, int strip, byte[] buf, int size) { if (!TIFFCheckRead(tif, false)) { return(-1); } TIFFDirectory td = tif.tif_dir; if (strip >= td.td_nstrips) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Strip out of range, max {1}", strip, td.td_nstrips); return(-1); } // Calculate the strip size according to the number of // rows in the strip (check for truncated last strip on any // of the separations). uint strips_per_sep; if (td.td_rowsperstrip >= td.td_imagelength) { strips_per_sep = 1; } else { strips_per_sep = (td.td_imagelength + td.td_rowsperstrip - 1) / td.td_rowsperstrip; } uint sep_strip = (uint)strip % strips_per_sep; uint nrows = td.td_imagelength % td.td_rowsperstrip; if (sep_strip != strips_per_sep - 1 || nrows == 0) { nrows = td.td_rowsperstrip; } int stripsize = TIFFVStripSize(tif, nrows); if (size == -1) { size = stripsize; } else if (size > stripsize) { size = stripsize; } if (TIFFFillStrip(tif, (uint)strip) && tif.tif_decodestrip(tif, buf, size, (ushort)(strip / td.td_stripsperimage))) { tif.tif_postdecode(tif, buf, 0, size); return(size); } return(-1); }
public virtual void GetStringDataFromTiff() { byte[] bytes = File.ReadAllBytes(System.IO.Path.Combine(sourceFolder, "img_cmyk.tif")); TIFFDirectory dir = new TIFFDirectory(new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource (bytes)), 0); String[] stringArray = new String[] { "iText? 7.1.7-SNAPSHOT ?2000-2019 iText Group NV (AGPL-version)\u0000" }; NUnit.Framework.Assert.AreEqual(stringArray, dir.GetField(305).GetAsStrings()); }
/// <summary>Gets the number of pages the TIFF document has.</summary> /// <param name="raf"> /// a /// <c>RandomAccessFileOrArray</c> /// containing a TIFF image. /// </param> /// <returns>the number of pages.</returns> public static int GetNumberOfPages(RandomAccessFileOrArray raf) { try { return(TIFFDirectory.GetNumDirectories(raf)); } catch (Exception e) { throw new iText.IO.IOException(iText.IO.IOException.TiffImageException, e); } }
// Grow the strip data structures by delta strips. static bool TIFFGrowStrips(TIFF tif, int delta, string module) { TIFFDirectory td = tif.tif_dir; uint[] new_stripoffset = null, new_stripbytecount = null; #if DEBUG if (td.td_planarconfig != PLANARCONFIG.CONTIG) { throw new Exception("td.td_planarconfig!=PLANARCONFIG.CONTIG"); } #endif if (delta == 0) { return(true); } try { new_stripoffset = new uint[td.td_nstrips + delta]; new_stripbytecount = new uint[td.td_nstrips + delta]; if (delta > 0) { if (td.td_stripoffset != null) { td.td_stripoffset.CopyTo(new_stripoffset, 0); } if (td.td_stripbytecount != null) { td.td_stripbytecount.CopyTo(new_stripbytecount, 0); } } else { if (td.td_stripoffset != null) { Array.Copy(td.td_stripoffset, new_stripoffset, td.td_nstrips + delta); } if (td.td_stripbytecount != null) { Array.Copy(td.td_stripbytecount, new_stripbytecount, td.td_nstrips + delta); } } } catch { td.td_nstrips = 0; TIFFErrorExt(tif.tif_clientdata, module, "{0}: No space to expand strip arrays", tif.tif_name); return(false); } td.td_stripoffset = new_stripoffset; td.td_stripbytecount = new_stripbytecount; td.td_nstrips = (uint)(td.td_nstrips + delta); return(true); }
// Some stuff depends on this older version of TIFFScanlineSize // TODO: resolve this public static int TIFFOldScanlineSize(TIFF tif) { TIFFDirectory td = tif.tif_dir; uint scanline = multiply(tif, td.td_bitspersample, td.td_imagewidth, "TIFFScanlineSize"); if (td.td_planarconfig == PLANARCONFIG.CONTIG) { scanline = multiply(tif, scanline, td.td_samplesperpixel, "TIFFScanlineSize"); } return((int)TIFFhowmany8(scanline)); }
// Compute the # bytes in a (row-aligned) strip. // // Note that if RowsPerStrip is larger than the // recorded ImageLength, then the strip size is // truncated to reflect the actual space required // to hold the strip. public static int TIFFStripSize(TIFF tif) { TIFFDirectory td = tif.tif_dir; uint rps = td.td_rowsperstrip; if (rps > td.td_imagelength) { rps = td.td_imagelength; } return(TIFFVStripSize(tif, rps)); }
// Compute how many strips are in an image. public static int TIFFNumberOfStrips(TIFF tif) { TIFFDirectory td = tif.tif_dir; uint nstrips; nstrips = (td.td_rowsperstrip == 0xffffffff?1:TIFFhowmany(td.td_imagelength, td.td_rowsperstrip)); if (td.td_planarconfig == PLANARCONFIG.SEPARATE) { nstrips = multiply(tif, nstrips, td.td_samplesperpixel, "TIFFNumberOfStrips"); } return((int)nstrips); }
static bool PredictorSetupEncode(TIFF tif) { TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data; TIFFDirectory td = tif.tif_dir; if (!sp.setupencode(tif) || !PredictorSetup(tif)) { return(false); } if (sp.predictor == PREDICTOR.HORIZONTAL) { switch (td.td_bitspersample) { case 8: sp.encodepfunc = horDiff8; break; case 16: sp.encodepfunc = horDiff16; break; case 32: sp.encodepfunc = horDiff32; break; } // Override default encoding method with one that does the // predictor stuff. if (tif.tif_encoderow != PredictorEncodeRow) { sp.encoderow = tif.tif_encoderow; tif.tif_encoderow = PredictorEncodeRow; sp.encodestrip = tif.tif_encodestrip; tif.tif_encodestrip = PredictorEncodeTile; sp.encodetile = tif.tif_encodetile; tif.tif_encodetile = PredictorEncodeTile; } } else if (sp.predictor == PREDICTOR.FLOATINGPOINT) { sp.encodepfunc = fpDiff; // Override default encoding method with one that does the // predictor stuff. if (tif.tif_encoderow != PredictorEncodeRow) { sp.encoderow = tif.tif_encoderow; tif.tif_encoderow = PredictorEncodeRow; sp.encodestrip = tif.tif_encodestrip; tif.tif_encodestrip = PredictorEncodeTile; sp.encodetile = tif.tif_encodetile; tif.tif_encodetile = PredictorEncodeTile; } } return(true); }
// Compute the # bytes in a raw strip. public static int TIFFRawStripSize(TIFF tif, uint strip) { TIFFDirectory td = tif.tif_dir; int bytecount = (int)td.td_stripbytecount[strip]; if (bytecount <= 0) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Invalid strip byte count, strip {1}", bytecount, strip); return(-1); } return(bytecount); }
public static TIFFTAG TIFFGetTagListEntry(TIFF tif, int tag_index) { TIFFDirectory td = tif.tif_dir; if (tag_index < 0 || tag_index >= td.td_customValueCount) { return((TIFFTAG)(-1)); } else { return(td.td_customValues[tag_index].info.field_tag); } }
// Read the specified tile and setup for decoding. // The data buffer is expanded, as necessary, to // hold the tile's data. public static bool TIFFFillTile(TIFF tif, uint tile) { string module = "TIFFFillTile"; TIFFDirectory td = tif.tif_dir; if ((tif.tif_flags & TIF_FLAGS.TIFF_NOREADRAW) == 0) { // FIXME: bytecount should have tsize_t type, but for now libtiff // defines tsize_t as a signed 32-bit integer and we are losing // ability to read arrays larger than 2^31 bytes. So we are using // uint32 instead of tsize_t here. uint bytecount = td.td_stripbytecount[tile]; if (bytecount <= 0) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Invalid tile byte count, tile {1}", bytecount, tile); return(false); } // 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 & TIF_FLAGS.TIFF_MYBUFFER) == 0) { TIFFErrorExt(tif.tif_clientdata, module, "{0}: Data buffer too small to hold tile {1}", tif.tif_name, tile); return(false); } if (!TIFFReadBufferSetup(tif, null, (int)TIFFroundup(bytecount, 1024))) { return(false); } } if ((uint)TIFFReadRawTile1(tif, tile, tif.tif_rawdata, (int)bytecount, module) != bytecount) { return(false); } if (!isFillOrder(tif, td.td_fillorder) && (tif.tif_flags & TIF_FLAGS.TIFF_NOBITREV) == 0) { TIFFReverseBits(tif.tif_rawdata, 0, (uint)bytecount); } } return(TIFFStartTile(tif, tile)); }
// Compute the # bytes in each row of a tile. public static int TIFFTileRowSize(TIFF tif) { TIFFDirectory td = tif.tif_dir; uint rowsize; if (td.td_tilelength == 0 || td.td_tilewidth == 0) { return(0); } rowsize = multiply(tif, td.td_bitspersample, td.td_tilewidth, "TIFFTileRowSize"); if (td.td_planarconfig == PLANARCONFIG.CONTIG) { rowsize = multiply(tif, rowsize, td.td_samplesperpixel, "TIFFTileRowSize"); } return((int)TIFFhowmany8(rowsize)); }
static bool PredictorSetup(TIFF tif) { string module = "PredictorSetup"; TIFFPredictorState sp = (TIFFPredictorState)tif.tif_data; TIFFDirectory td = tif.tif_dir; switch (sp.predictor) { case PREDICTOR.NONE: return(true); // no differencing case PREDICTOR.HORIZONTAL: if (td.td_bitspersample != 8 && td.td_bitspersample != 16 && td.td_bitspersample != 32) { TIFFErrorExt(tif.tif_clientdata, module, "Horizontal differencing \"Predictor\" not supported with {0}-bit samples", td.td_bitspersample); return(false); } break; case PREDICTOR.FLOATINGPOINT: if (td.td_sampleformat != SAMPLEFORMAT.IEEEFP) { TIFFErrorExt(tif.tif_clientdata, module, "Floating point \"Predictor\" not supported with {0} data format", td.td_sampleformat); return(false); } break; default: TIFFErrorExt(tif.tif_clientdata, module, "\"Predictor\" value {0} not supported", sp.predictor); return(false); } sp.stride = (td.td_planarconfig == PLANARCONFIG.CONTIG?(int)td.td_samplesperpixel:1); // Calculate the scanline/tile-width size in bytes. if (isTiled(tif)) { sp.rowsize = TIFFTileRowSize(tif); } else { sp.rowsize = TIFFScanlineSize(tif); } return(true); }
// Compute which strip a (row, sample) value is in. public static int TIFFComputeStrip(TIFF tif, uint row, ushort sample) { TIFFDirectory td = tif.tif_dir; uint strip; strip = row / td.td_rowsperstrip; if (td.td_planarconfig == PLANARCONFIG.SEPARATE) { if (sample >= td.td_samplesperpixel) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "{0}: Sample out of range, max {1}", sample, td.td_samplesperpixel); return(0); } strip += sample * td.td_stripsperimage; } return((int)strip); }
public static bool TIFFSetupStrips(TIFF tif) { TIFFDirectory td = tif.tif_dir; if (isTiled(tif)) { td.td_stripsperimage = isUnspecified(tif, FIELD.TILEDIMENSIONS)?td.td_samplesperpixel:TIFFNumberOfTiles(tif); } else { td.td_stripsperimage = isUnspecified(tif, FIELD.ROWSPERSTRIP)?td.td_samplesperpixel:(uint)TIFFNumberOfStrips(tif); } td.td_nstrips = td.td_stripsperimage; if (td.td_planarconfig == PLANARCONFIG.SEPARATE) { td.td_stripsperimage /= td.td_samplesperpixel; } try { td.td_stripoffset = new uint[td.td_nstrips]; td.td_stripbytecount = new uint[td.td_nstrips]; } catch { return(false); } // Place data at the end-of-file // (by setting offsets to zero). TIFFSetFieldBit(tif, FIELD.STRIPOFFSETS); TIFFSetFieldBit(tif, FIELD.STRIPBYTECOUNTS); // FIX: Some tools don't like images without ROWSPERSTRIP set. if (!TIFFFieldSet(tif, FIELD.ROWSPERSTRIP)) { td.td_rowsperstrip = td.td_imagelength; TIFFSetFieldBit(tif, FIELD.ROWSPERSTRIP); } return(true); }
// Write the supplied data to the specified strip. // // NB: Image length must be setup before writing. public static int TIFFWriteRawStrip(TIFF tif, uint strip, byte[] data, int cc) { string module = "TIFFWriteRawStrip"; TIFFDirectory td = tif.tif_dir; if (!((tif.tif_flags & TIF_FLAGS.TIFF_BEENWRITING) != 0 || TIFFWriteCheck(tif, false, module))) { return(-1); } // Check strip array to make sure there's space. // We don't support dynamically growing files that // have data organized in separate bitplanes because // it's too painful. In that case we require that // the imagelength be set properly before the first // write (so that the strips array will be fully // allocated above). if (strip >= td.td_nstrips) { if (td.td_planarconfig == PLANARCONFIG.SEPARATE) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "Can not grow image by strips when using separate planes"); return(-1); } // Watch out for a growing image. The value of // strips/image will initially be 1 (since it // can't be deduced until the imagelength is known). if (strip >= td.td_stripsperimage) { td.td_stripsperimage = TIFFhowmany(td.td_imagelength, td.td_rowsperstrip); } if (!TIFFGrowStrips(tif, 1, module)) { return(-1); } } tif.tif_curstrip = strip; tif.tif_row = (strip % td.td_stripsperimage) * td.td_rowsperstrip; return(TIFFAppendToStrip(tif, strip, data, (uint)cc)?cc:-1); }
// Compute the # bytes in a variable length, row-aligned tile. public static int TIFFVTileSize(TIFF tif, uint nrows) { TIFFDirectory td = tif.tif_dir; uint tilesize; if (td.td_tilelength == 0 || td.td_tilewidth == 0 || td.td_tiledepth == 0) { return(0); } if (td.td_planarconfig == PLANARCONFIG.CONTIG && td.td_photometric == PHOTOMETRIC.YCBCR && !isUpSampled(tif)) { // Packed YCbCr data contain one Cb+Cr for every // HorizontalSampling*VerticalSampling Y values. // Must also roundup width and height when calculating // since images that are not a multiple of the // horizontal/vertical subsampling area include // YCbCr data for the extended image. uint w = TIFFroundup(td.td_tilewidth, td.td_ycbcrsubsampling[0]); uint rowsize = TIFFhowmany8(multiply(tif, w, td.td_bitspersample, "TIFFVTileSize")); uint samplingarea = (uint)td.td_ycbcrsubsampling[0] * td.td_ycbcrsubsampling[1]; if (samplingarea == 0) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "Invalid YCbCr subsampling"); return(0); } nrows = TIFFroundup(nrows, td.td_ycbcrsubsampling[1]); // NB: don't need TIFFhowmany here 'cuz everything is rounded tilesize = multiply(tif, nrows, rowsize, "TIFFVTileSize"); tilesize = summarize(tif, tilesize, multiply(tif, 2, tilesize / samplingarea, "TIFFVTileSize"), "TIFFVTileSize"); } else { tilesize = multiply(tif, nrows, (uint)TIFFTileRowSize(tif), "TIFFVTileSize"); } return((int)multiply(tif, tilesize, td.td_tiledepth, "TIFFVTileSize")); }
// Compute which tile an (x,y,z,s) value is in. public static uint TIFFComputeTile(TIFF tif, uint x, uint y, uint z, ushort s) { TIFFDirectory td = tif.tif_dir; uint dx = td.td_tilewidth; uint dy = td.td_tilelength; uint dz = td.td_tiledepth; if (td.td_imagedepth == 1) { z = 0; } if (dx == 0xffffffff) { dx = td.td_imagewidth; } if (dy == 0xffffffff) { dy = td.td_imagelength; } if (dz == 0xffffffff) { dz = td.td_imagedepth; } if (dx != 0 && dy != 0 && dz != 0) { uint xpt = TIFFhowmany(td.td_imagewidth, dx); uint ypt = TIFFhowmany(td.td_imagelength, dy); uint zpt = TIFFhowmany(td.td_imagedepth, dz); if (td.td_planarconfig == PLANARCONFIG.SEPARATE) { return(xpt * ypt * zpt * s + xpt * ypt * (z / dz) + xpt * (y / dy) + x / dx); } return(xpt * ypt * (z / dz) + xpt * (y / dy) + x / dx); } return(1); }
// Compute the # bytes in a variable height, row-aligned strip. public static int TIFFVStripSize(TIFF tif, uint nrows) { TIFFDirectory td = tif.tif_dir; if (nrows == 0xffffffff) { nrows = td.td_imagelength; } if (td.td_planarconfig == PLANARCONFIG.CONTIG && td.td_photometric == PHOTOMETRIC.YCBCR && !isUpSampled(tif)) { // Packed YCbCr data contain one Cb+Cr for every // HorizontalSampling*VerticalSampling Y values. // Must also roundup width and height when calculating // since images that are not a multiple of the // horizontal/vertical subsampling area include // YCbCr data for the extended image. object[] ap = new object[2]; TIFFGetField(tif, TIFFTAG.YCBCRSUBSAMPLING, ap); ushort ycbcrsubsampling0 = __GetAsUshort(ap, 0); ushort ycbcrsubsampling1 = __GetAsUshort(ap, 1); uint samplingarea = (uint)(ycbcrsubsampling0 * ycbcrsubsampling1); if (samplingarea == 0) { TIFFErrorExt(tif.tif_clientdata, tif.tif_name, "Invalid YCbCr subsampling"); return(0); } uint w = TIFFroundup(td.td_imagewidth, ycbcrsubsampling0); uint scanline = TIFFhowmany8(multiply(tif, w, td.td_bitspersample, "TIFFVStripSize")); nrows = TIFFroundup(nrows, ycbcrsubsampling1); // NB: don't need TIFFhowmany here 'cuz everything is rounded scanline = multiply(tif, nrows, scanline, "TIFFVStripSize"); return((int)summarize(tif, scanline, multiply(tif, 2, (scanline / samplingarea), "TIFFVStripSize"), "TIFFVStripSize")); } return((int)multiply(tif, nrows, (uint)TIFFScanlineSize(tif), "TIFFVStripSize")); }
static bool TIFFDefaultTransferFunction(TIFFDirectory td) { ushort[][] tf = td.td_transferfunction; tf[0] = tf[1] = tf[2] = null; if (td.td_bitspersample >= 4 * 8 - 2) { return(false); //4: sizeof(tsize_t) } int n = 1 << td.td_bitspersample; try { tf[0] = new ushort[n]; tf[0][0] = 0; for (int i = 1; i < n; i++) { double t = (double)i / ((double)n - 1.0); tf[0][i] = (ushort)Math.Floor(65535 * Math.Pow(t, 2.2) + 0.5); } if (td.td_samplesperpixel - td.td_extrasamples > 1) { tf[1] = new ushort[n]; tf[2] = new ushort[n]; tf[0].CopyTo(tf[1], 0); tf[0].CopyTo(tf[2], 0); } return(true); } catch { tf[0] = tf[1] = tf[2] = null; return(false); } }