/// <summary> /// Handles an error by writing it text to the <see cref="Console.Error"/>. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class. Can be <c>null</c>.</param> /// <param name="method">The method where an error is detected.</param> /// <param name="format">A composite format string (see Remarks).</param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <remarks> /// The <paramref name="format"/> is a composite format string that uses the same format as /// <see cref="O:System.String.Format"/> method. The <paramref name="method"/> parameter, if /// not <c>null</c>, is printed before the message; it typically is used to identify the /// method in which an error is detected. /// </remarks> public virtual void ErrorHandler(Tiff tif, string method, string format, params object[] args) { TextWriter stderr = Console.Error; if (method != null) stderr.Write("{0}: ", method); stderr.Write(format, args); stderr.Write("\n"); }
public int getNumberofTiffPages(Tiff image) { int pageCount = 0; do { ++pageCount; } while (image.ReadDirectory()); return pageCount; }
public override void ErrorHandler(Tiff tif, string module, string fmt, params object[] ap) { using (TextWriter stdout = Console.Out) { if (module != null) stdout.Write("{0}: ", module); stdout.Write(fmt, ap); stdout.Write(".\n"); } }
/// <summary> /// Handles a warning by writing it text to the <see cref="Console.Error"/>. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class. Can be <c>null</c>.</param> /// <param name="method">The method where a warning is detected.</param> /// <param name="format">A composite format string (see Remarks).</param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <remarks> /// The <paramref name="format"/> is a composite format string that uses the same format as /// <see cref="O:System.String.Format"/> method. The <paramref name="method"/> parameter, if /// not <c>null</c>, is printed before the message; it typically is used to identify the /// method in which a warning is detected. /// </remarks> public virtual void WarningHandler(Tiff tif, string method, string format, params object[] args) { TextWriter stderr = Console.Error; if (method != null) { stderr.Write("{0}: ", method); } stderr.Write("Warning, "); stderr.Write(format, args); stderr.Write("\n"); }
public bool tiffcvt(Tiff inImage, Tiff outImage) { FieldValue[] result = inImage.GetField(TiffTag.IMAGEWIDTH); if (result == null) return false; int width = result[0].ToInt(); result = inImage.GetField(TiffTag.IMAGELENGTH); if (result == null) return false; int height = result[0].ToInt(); copyField(inImage, outImage, TiffTag.SUBFILETYPE); outImage.SetField(TiffTag.IMAGEWIDTH, width); outImage.SetField(TiffTag.IMAGELENGTH, height); outImage.SetField(TiffTag.BITSPERSAMPLE, 8); outImage.SetField(TiffTag.COMPRESSION, m_compression); outImage.SetField(TiffTag.PHOTOMETRIC, Photometric.RGB); copyField(inImage, outImage, TiffTag.FILLORDER); outImage.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT); if (m_noAlpha) outImage.SetField(TiffTag.SAMPLESPERPIXEL, 3); else outImage.SetField(TiffTag.SAMPLESPERPIXEL, 4); if (!m_noAlpha) { short[] v = new short[1]; v[0] = (short)ExtraSample.ASSOCALPHA; outImage.SetField(TiffTag.EXTRASAMPLES, 1, v); } copyField(inImage, outImage, TiffTag.XRESOLUTION); copyField(inImage, outImage, TiffTag.YRESOLUTION); copyField(inImage, outImage, TiffTag.RESOLUTIONUNIT); outImage.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG); if (!m_testFriendly) outImage.SetField(TiffTag.SOFTWARE, Tiff.GetVersion()); copyField(inImage, outImage, TiffTag.DOCUMENTNAME); if (m_processByBlock && inImage.IsTiled()) return cvt_by_tile(inImage, outImage, width, height); else if (m_processByBlock) return cvt_by_strip(inImage, outImage, width, height); return cvt_whole_image(inImage, outImage, width, height); }
static Tiff Open(string fileName, string mode, TiffErrorHandler errorHandler, TiffExtendProc extender) { const string module = "Open"; FileMode fileMode; FileAccess fileAccess; getMode(mode, module, out fileMode, out fileAccess); FileStream stream = null; try { if (fileAccess == FileAccess.Read) { stream = File.Open(fileName, fileMode, fileAccess, FileShare.Read); } else { stream = File.Open(fileName, fileMode, fileAccess); } } #if THREAD_SAFE_LIBTIFF #pragma warning disable CA1031 // Do not catch general exception types catch (Exception) #pragma warning restore CA1031 // Do not catch general exception types { return(null); } #else #pragma warning disable CA1031 // Do not catch general exception types catch (Exception e) #pragma warning restore CA1031 // Do not catch general exception types { Error(module, "Failed to open '{0}'. {1}", fileName, e.Message); return(null); } #endif Tiff tif = ClientOpen(fileName, mode, stream, new TiffStream(), errorHandler, extender); if (tif == null) { stream.Dispose(); } else { tif.m_fileStream = stream; } return(tif); }
private bool writeOK(byte[] buffer, int offset, int count) { try { m_stream.Write(m_clientdata, buffer, offset, count); } catch (Exception) { Tiff.Warning(this, "writeOK", "Failed to write {0} bytes", count); return(false); } return(true); }
private static TiffErrorHandler getErrorHandler(Tiff tif) { TiffErrorHandler errorHandler = null; #if THREAD_SAFE_LIBTIFF if (tif != null) { errorHandler = tif.m_errorHandler; } #else errorHandler = m_errorHandler; #endif return(errorHandler); }
static Tiff Open(string name, string mode, Stream stream, TiffErrorHandler errorHandler, TiffExtendProc extender) { Tiff tif = ClientOpen(name, mode, stream, new TiffStream(), errorHandler, extender); if (tif == null) { stream.Dispose(); } else { tif.m_fileStream = stream; } return(tif); }
private bool writeOK(byte[] buffer, int offset, int count) { try { m_stream.Write(m_clientdata, buffer, offset, count); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception) #pragma warning restore CA1031 // Do not catch general exception types { Tiff.Warning(this, "writeOK", "Failed to write {0} bytes", count); return(false); } return(true); }
private static Metadata ReadMetadata(T.Tiff tiff, int defaultTileWidth) { var x = tiff.GetField(T.TiffTag.IMAGEWIDTH); int width = tiff.GetField(T.TiffTag.IMAGEWIDTH)[0].ToInt(); int height = tiff.GetField(T.TiffTag.IMAGELENGTH)[0].ToInt(); var twtag = tiff.GetField(T.TiffTag.TILEWIDTH); var tileWidth = twtag == null ? defaultTileWidth : twtag[0].ToInt(); return(new Metadata { Width = width, Height = height, TileWidth = tileWidth, ScalingLevels = (int)(Math.Floor(Math.Log(Math.Max(width, height), 2)) - 3) }); }
private static (ProcessState state, SKImage image) ReadFullImage(T.Tiff tiff, ImageRequest request, bool allowSizeAboveFull) { int width = tiff.GetField(T.TiffTag.IMAGEWIDTH)[0].ToInt(); int height = tiff.GetField(T.TiffTag.IMAGELENGTH)[0].ToInt(); var restag = tiff.GetField(T.TiffTag.RESOLUTIONUNIT); var xrestag = tiff.GetField(T.TiffTag.XRESOLUTION); var yrestag = tiff.GetField(T.TiffTag.YRESOLUTION); var resunit = restag == null ? 2 : restag[0].ToShort(); var xres = xrestag == null ? 96 : xrestag[0].ToDouble(); var yres = yrestag == null ? 96 : yrestag[0].ToDouble(); // pixels per metre if (resunit == 3) { xres = xres / 0.0254; yres = yres / 0.0254; } var isTileable = tiff.IsTiled(); var state = ImageRequestInterpreter.GetInterpretedValues(request, width, height, allowSizeAboveFull); state.HorizontalResolution = Convert.ToUInt16(xres); state.VerticalResolution = Convert.ToUInt16(yres); var raster = new int[width * height]; if (!tiff.ReadRGBAImageOriented(width, height, raster, T.Orientation.TOPLEFT)) { throw new IOException("Unable to decode TIFF file"); } using (var bmp = CreateBitmapFromPixels(raster, width, height)) { var desiredWidth = Math.Max(1, (int)Math.Round(state.RegionWidth * state.ImageScale)); var desiredHeight = Math.Max(1, (int)Math.Round(state.RegionHeight * state.ImageScale)); Log.Debug("Desired size {@DesiredWidth}, {@DesiredHeight}", desiredWidth, desiredHeight); var regionWidth = state.RegionWidth; var regionHeight = state.RegionHeight; var srcRegion = SKRectI.Create(state.StartX, state.StartY, regionWidth, regionHeight); return(state, CopyImageRegion2(bmp, desiredWidth, desiredHeight, srcRegion)); } }
public void TagExtender(Tiff tif) { TiffFieldInfo[] tiffFieldInfo = { new TiffFieldInfo(TIFFTAG_ASCIITAG, -1, -1, TiffType.ASCII, FieldBit.Custom, true, false, "MyTag"), new TiffFieldInfo(TIFFTAG_SHORTTAG, 2, 2, TiffType.SHORT, FieldBit.Custom, false, true, "ShortTag"), new TiffFieldInfo(TIFFTAG_LONGTAG, 2, 2, TiffType.LONG, FieldBit.Custom, false, true, "LongTag"), new TiffFieldInfo(TIFFTAG_RATIONALTAG, 2, 2, TiffType.RATIONAL, FieldBit.Custom, false, true, "RationalTag"), new TiffFieldInfo(TIFFTAG_FLOATTAG, 2, 2, TiffType.FLOAT, FieldBit.Custom, false, true, "FloatTag"), new TiffFieldInfo(TIFFTAG_DOUBLETAG, 2, 2, TiffType.DOUBLE, FieldBit.Custom, false, true, "DoubleTag"), new TiffFieldInfo(TIFFTAG_BYTETAG, 2, 2, TiffType.BYTE, FieldBit.Custom, false, true, "ByteTag"), new TiffFieldInfo(TIFFTAG_IFDTAG, 1, 1, TiffType.IFD, FieldBit.Custom, false, false, "IfdTag"), }; tif.MergeFieldInfo(tiffFieldInfo, tiffFieldInfo.Length); if (m_parentExtender != null) m_parentExtender(tif); }
static Tiff Open(Stream stream, string mode, TiffErrorHandler errorHandler, TiffExtendProc extender) { const string module = "Open"; getMode(mode, module); Tiff tif = ClientOpen("Stream", mode, stream, new TiffStream(), errorHandler, extender); if (tif == null) { stream.Dispose(); } else { tif.m_fileStream = stream; } return(tif); }
public TiffGrid(string filename, string NewFileName) { ValuesToWrite = new Dictionary<int, Dictionary<int, double>>(); tiff_org = BitMiracle.LibTiff.Classic.Tiff.Open(Path.GetFullPath(filename), "r"); tiff = BitMiracle.LibTiff.Classic.Tiff.Open(Path.GetFullPath(NewFileName), "w"); foreach (TiffTag enu in Enum.GetValues(typeof(TiffTag))) { var val = tiff_org.GetField(enu); if (val != null & enu != TiffTag.EXTRASAMPLES) tiff.SetField(enu, val[0]); } for (int i = 0; i < tiff_org.GetTagListCount(); i++) { int k = tiff_org.GetTagListEntry(i); var ff = tiff_org.FindFieldInfo((TiffTag)k, TiffType.ANY); tiff.MergeFieldInfo(new TiffFieldInfo[] { ff }, 1); var val = tiff_org.GetField((TiffTag)tiff_org.GetTagListEntry(i)); tiff.SetField((TiffTag)k, val[0], val[1]); } var val2 = tiff_org.GetField((TiffTag)33922)[1].ToDoubleArray(); XOrigin = val2[3]; YOrigin = val2[4]; //Upper basegrid assumes Lower val2 = tiff_org.GetField((TiffTag)33550)[1].ToDoubleArray(); GridSize = val2[0]; GridSize = val2[1]; NumberOfColumns = tiff_org.GetField(TiffTag.IMAGEWIDTH)[0].ToInt(); NumberOfRows = tiff_org.GetField(TiffTag.IMAGELENGTH)[0].ToInt(); //Shift YOrigin to lower left YOrigin -= GridSize * NumberOfRows; scanline = new byte[tiff_org.ScanlineSize()]; bits = scanline.Count() / NumberOfColumns; ScanLineCache = new Dictionary<int, byte[]>(); }
public TiffGrid(string FileName) { string fname = Path.GetFullPath(FileName); tiff = Tiff.Open(FileName, "r"); var val = tiff.GetField((TiffTag)33922)[1].ToDoubleArray(); XOrigin = val[3]; YOrigin = val[4]; //Upper basegrid assumes Lower val = tiff.GetField((TiffTag)33550)[1].ToDoubleArray(); GridSize = val[0]; GridSize = val[1]; NumberOfColumns = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt(); NumberOfRows = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt(); scanline = new byte[tiff.ScanlineSize()]; bits = tiff.ScanlineSize() / NumberOfColumns; ScanLineCache = new Dictionary<int, byte[]>(); }
static Tiff Open(string fileName, string mode, TiffErrorHandler errorHandler, TiffExtendProc extender) { const string module = "Open"; FileMode fileMode; FileAccess fileAccess; getMode(mode, module, out fileMode, out fileAccess); FileStream stream = null; try { if (fileAccess == FileAccess.Read) { stream = File.Open(fileName, fileMode, fileAccess, FileShare.Read); } else { stream = File.Open(fileName, fileMode, fileAccess); } } catch (Exception e) { Error(module, "Failed to open '{0}'. {1}", fileName, e.Message); return(null); } Tiff tif = ClientOpen(fileName, mode, stream, new TiffStream(), errorHandler, extender); if (tif == null) { stream.Dispose(); } else { tif.m_fileStream = stream; } return(tif); }
private static void PrintTagInfo(Tiff tiff, TiffTag tiffTag) { try { var field = tiff.GetField(tiffTag); if (field != null) { Console.WriteLine($"{tiffTag}"); for (int i = 0; i < field.Length; i++) { Console.WriteLine($" [{i}] {field[i].Value}"); byte[] bytes = field[i].Value as byte[]; if (bytes != null) { Console.WriteLine($" Length: {bytes.Length}"); if (bytes.Length % 8 == 0) { for (int k = 0; k < bytes.Length / 8; k++) { Console.WriteLine($" [{k}] {BitConverter.ToDouble(bytes, k * 8)}"); } } try { Console.WriteLine($" > {System.Text.Encoding.ASCII.GetString(bytes).Trim()} < "); } catch (Exception ex) { } } } } } catch (Exception ex) { Console.WriteLine($"ERROR: {tiffTag}"); } }
private static int checkInkNamesString(Tiff tif, int slen, string s) { bool failed = false; short i = tif.m_dir.td_samplesperpixel; if (slen > 0) { int endPos = slen; int pos = 0; for (; i > 0; i--) { for (; s[pos] != '\0'; pos++) { if (pos >= endPos) { failed = true; break; } } if (failed) { break; } pos++; // skip \0 } if (!failed) { return(pos); } } Tiff.ErrorExt(tif, tif.m_clientdata, "TIFFSetField", "{0}: Invalid InkNames value; expecting {1} names, found {2}", tif.m_name, tif.m_dir.td_samplesperpixel, tif.m_dir.td_samplesperpixel - i); return(0); }
private static void SetTiffField(TiffInfo info, BitMiracle.LibTiff.Classic.Tiff image) { if (image == null) { throw new NullReferenceException("image"); } // We need to set some values for basic tags before we can add any data image.SetField(TiffTag.IMAGEWIDTH, info.Width); image.SetField(TiffTag.IMAGELENGTH, info.Height); image.SetField(TiffTag.BITSPERSAMPLE, info.BitsPerSample); image.SetField(TiffTag.SAMPLESPERPIXEL, info.SamplesPerPixel); image.SetField(TiffTag.ORIENTATION, info.Orientation); image.SetField(TiffTag.ROWSPERSTRIP, info.Height); image.SetField(TiffTag.XRESOLUTION, info.XResolution); image.SetField(TiffTag.YRESOLUTION, info.YResolution); image.SetField(TiffTag.RESOLUTIONUNIT, info.ResolutionUnit); image.SetField(TiffTag.PLANARCONFIG, info.PlanarConfig); image.SetField(TiffTag.PHOTOMETRIC, info.Photometric); image.SetField(TiffTag.COMPRESSION, info.Compression); image.SetField(TiffTag.FILLORDER, info.FillOrder); }
public TiffGrid(string FileName) { string fname = Path.GetFullPath(FileName); if (!File.Exists(fname)) return; tiff = BitMiracle.LibTiff.Classic.Tiff.Open(FileName, "r"); var val = tiff.GetField((TiffTag)33922)[1].ToDoubleArray(); XOrigin = val[3]; YOrigin = val[4]; //Upper basegrid assumes Lower val = tiff.GetField((TiffTag)33550)[1].ToDoubleArray(); GridSize = val[0]; GridSize = val[1]; NumberOfColumns = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt(); NumberOfRows = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt(); //Shift YOrigin to lower left YOrigin -= GridSize * NumberOfRows; scanline = new byte[tiff.ScanlineSize()]; bits = scanline.Count() / NumberOfColumns; ScanLineCache = new Dictionary<int, byte[]>(); }
bool readContigTilesIntoBuffer(Tiff inImage, byte[] buf, int imagelength, int imagewidth, short spp) { byte[] tilebuf = new byte[inImage.TileSize()]; FieldValue[] result = inImage.GetField(TiffTag.TILEWIDTH); int tw = result[0].ToInt(); result = inImage.GetField(TiffTag.TILELENGTH); int tl = result[0].ToInt(); int imagew = inImage.ScanlineSize(); int tilew = inImage.TileRowSize(); int iskew = imagew - tilew; int bufp = 0; for (int row = 0; row < imagelength; row += tl) { int nrow = (row + tl > imagelength) ? imagelength - row : tl; int colb = 0; for (int col = 0; col < imagewidth; col += tw) { if (inImage.ReadTile(tilebuf, 0, col, row, 0, 0) < 0 && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read tile at {0} {1}", col, row); return false; } if (colb + tilew > imagew) { int width = imagew - colb; int oskew = tilew - width; cpStripToTile(buf, bufp + colb, tilebuf, 0, nrow, width, oskew + iskew, oskew); } else cpStripToTile(buf, bufp + colb, tilebuf, 0, nrow, tilew, iskew, 0); colb += tilew; } bufp += imagew * nrow; } return true; }
bool readSeparateStripsIntoBuffer(Tiff inImage, byte[] buf, int imagelength, int imagewidth, short spp) { int scanlinesize = inImage.ScanlineSize(); if (scanlinesize == 0) return false; byte[] scanline = new byte[scanlinesize]; int bufp = 0; for (int row = 0; row < imagelength; row++) { /* merge channels */ for (short s = 0; s < spp; s++) { if (!inImage.ReadScanline(scanline, row, s) && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read scanline {0}", row); return false; } int n = scanlinesize; int bp = s; int sbuf = 0; while (n-- > 0) { buf[bufp + bp] = scanline[sbuf]; sbuf++; bp += spp; } } bufp += scanlinesize * spp; } return true; }
public override void ErrorHandler(Tiff tif, string method, string format, params object[] args) { }
/* * Contig -> contig by scanline while subtracting a bias image. */ bool cpBiasedContig2Contig(Tiff inImage, Tiff outImage, int imagelength, int imagewidth, short spp) { if (spp == 1) { int biasSize = m_bias.ScanlineSize(); int bufSize = inImage.ScanlineSize(); FieldValue[] result = m_bias.GetField(TiffTag.IMAGEWIDTH); int biasWidth = result[0].ToInt(); result = m_bias.GetField(TiffTag.IMAGELENGTH); int biasLength = result[0].ToInt(); if (biasSize == bufSize && imagelength == biasLength && imagewidth == biasWidth) { result = inImage.GetField(TiffTag.BITSPERSAMPLE); short sampleBits = result[0].ToShort(); if (sampleBits == 8 || sampleBits == 16 || sampleBits == 32) { byte[] buf = new byte[bufSize]; byte[] biasBuf = new byte[bufSize]; for (int row = 0; row < imagelength; row++) { if (!inImage.ReadScanline(buf, row, 0) && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read scanline {0}", row); return false; } if (!m_bias.ReadScanline(biasBuf, row, 0) && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read biased scanline {0}", row); return false; } if (sampleBits == 8) subtract8(buf, biasBuf, imagewidth); else if (sampleBits == 16) subtract16(buf, biasBuf, imagewidth); else if (sampleBits == 32) subtract32(buf, biasBuf, imagewidth); if (!outImage.WriteScanline(buf, row, 0)) { Tiff.Error(outImage.FileName(), "Error, can't write scanline {0}", row); return false; } } m_bias.SetDirectory(m_bias.CurrentDirectory()); /* rewind */ return true; } else { Tiff.Error(inImage.FileName(), "No support for biasing {0} bit pixels\n", sampleBits); return false; } } Tiff.Error(inImage.FileName(), "Bias image {0},{1}\nis not the same size as {2},{3}\n", m_bias.FileName(), m_bias.CurrentDirectory(), inImage.FileName(), inImage.CurrentDirectory()); return false; } else { Tiff.Error(inImage.FileName(), "Can't bias {0},{1} as it has >1 Sample/Pixel\n", inImage.FileName(), inImage.CurrentDirectory()); return false; } }
public bool Copy(Tiff inImage, Tiff outImage) { int width = 0; FieldValue[] result = inImage.GetField(TiffTag.IMAGEWIDTH); if (result != null) { width = result[0].ToInt(); outImage.SetField(TiffTag.IMAGEWIDTH, width); } int length = 0; result = inImage.GetField(TiffTag.IMAGELENGTH); if (result != null) { length = result[0].ToInt(); outImage.SetField(TiffTag.IMAGELENGTH, length); } short bitspersample = 1; result = inImage.GetField(TiffTag.BITSPERSAMPLE); if (result != null) { bitspersample = result[0].ToShort(); outImage.SetField(TiffTag.BITSPERSAMPLE, bitspersample); } short samplesperpixel = 1; result = inImage.GetField(TiffTag.SAMPLESPERPIXEL); if (result != null) { samplesperpixel = result[0].ToShort(); outImage.SetField(TiffTag.SAMPLESPERPIXEL, samplesperpixel); } if (m_compression != (Compression)(-1)) outImage.SetField(TiffTag.COMPRESSION, m_compression); else { result = inImage.GetField(TiffTag.COMPRESSION); if (result != null) { m_compression = (Compression)result[0].ToInt(); outImage.SetField(TiffTag.COMPRESSION, m_compression); } } result = inImage.GetFieldDefaulted(TiffTag.COMPRESSION); Compression input_compression = (Compression)result[0].ToInt(); result = inImage.GetFieldDefaulted(TiffTag.PHOTOMETRIC); Photometric input_photometric = (Photometric)result[0].ToShort(); if (input_compression == Compression.JPEG) { /* Force conversion to RGB */ inImage.SetField(TiffTag.JPEGCOLORMODE, JpegColorMode.RGB); } else if (input_photometric == Photometric.YCBCR) { /* Otherwise, can't handle subsampled input */ result = inImage.GetFieldDefaulted(TiffTag.YCBCRSUBSAMPLING); short subsamplinghor = result[0].ToShort(); short subsamplingver = result[1].ToShort(); if (subsamplinghor != 1 || subsamplingver != 1) { Console.Error.WriteLine("tiffcp: {0}: Can't copy/convert subsampled image.", inImage.FileName()); return false; } } if (m_compression == Compression.JPEG) { if (input_photometric == Photometric.RGB && m_jpegcolormode == JpegColorMode.RGB) outImage.SetField(TiffTag.PHOTOMETRIC, Photometric.YCBCR); else outImage.SetField(TiffTag.PHOTOMETRIC, input_photometric); } else if (m_compression == Compression.SGILOG || m_compression == Compression.SGILOG24) { outImage.SetField(TiffTag.PHOTOMETRIC, samplesperpixel == 1 ? Photometric.LOGL : Photometric.LOGLUV); } else { if (input_compression != Compression.JPEG) copyTag(inImage, outImage, TiffTag.PHOTOMETRIC, 1, TiffType.SHORT); } if (m_fillorder != 0) outImage.SetField(TiffTag.FILLORDER, m_fillorder); else copyTag(inImage, outImage, TiffTag.FILLORDER, 1, TiffType.SHORT); /* * Will copy `Orientation' tag from input image */ result = inImage.GetFieldDefaulted(TiffTag.ORIENTATION); m_orientation = (Orientation)result[0].ToByte(); switch (m_orientation) { case Orientation.BOTRIGHT: case Orientation.RIGHTBOT: Tiff.Warning(inImage.FileName(), "using bottom-left orientation"); m_orientation = Orientation.BOTLEFT; break; case Orientation.LEFTBOT: case Orientation.BOTLEFT: break; case Orientation.TOPRIGHT: case Orientation.RIGHTTOP: default: Tiff.Warning(inImage.FileName(), "using top-left orientation"); m_orientation = Orientation.TOPLEFT; break; case Orientation.LEFTTOP: case Orientation.TOPLEFT: break; } outImage.SetField(TiffTag.ORIENTATION, m_orientation); /* * Choose tiles/strip for the output image according to * the command line arguments (-tiles, -strips) and the * structure of the input image. */ if (m_outtiled == -1) { if (inImage.IsTiled()) m_outtiled = 1; else m_outtiled = 0; } if (m_outtiled != 0) { /* * Setup output file's tile width&height. If either * is not specified, use either the value from the * input image or, if nothing is defined, use the * library default. */ if (m_tilewidth == -1) { result = inImage.GetFieldDefaulted(TiffTag.TILEWIDTH); if (result != null) m_tilewidth = result[0].ToInt(); } if (m_tilelength == -1) { result = inImage.GetFieldDefaulted(TiffTag.TILELENGTH); if (result != null) m_tilelength = result[0].ToInt(); } outImage.DefaultTileSize(ref m_tilewidth, ref m_tilelength); outImage.SetField(TiffTag.TILEWIDTH, m_tilewidth); outImage.SetField(TiffTag.TILELENGTH, m_tilelength); } else { /* * RowsPerStrip is left unspecified: use either the * value from the input image or, if nothing is defined, * use the library default. */ if (m_rowsperstrip == 0) { result = inImage.GetField(TiffTag.ROWSPERSTRIP); if (result == null) m_rowsperstrip = outImage.DefaultStripSize(m_rowsperstrip); else m_rowsperstrip = result[0].ToInt(); if (m_rowsperstrip > length && m_rowsperstrip != -1) m_rowsperstrip = length; } else if (m_rowsperstrip == -1) m_rowsperstrip = length; outImage.SetField(TiffTag.ROWSPERSTRIP, m_rowsperstrip); } if (m_config != PlanarConfig.UNKNOWN) outImage.SetField(TiffTag.PLANARCONFIG, m_config); else { result = inImage.GetField(TiffTag.PLANARCONFIG); if (result != null) { m_config = (PlanarConfig)result[0].ToShort(); outImage.SetField(TiffTag.PLANARCONFIG, m_config); } } if (samplesperpixel <= 4) copyTag(inImage, outImage, TiffTag.TRANSFERFUNCTION, 4, TiffType.SHORT); copyTag(inImage, outImage, TiffTag.COLORMAP, 4, TiffType.SHORT); /* SMinSampleValue & SMaxSampleValue */ switch (m_compression) { case Compression.JPEG: outImage.SetField(TiffTag.JPEGQUALITY, m_quality); outImage.SetField(TiffTag.JPEGCOLORMODE, m_jpegcolormode); break; case Compression.LZW: case Compression.ADOBE_DEFLATE: case Compression.DEFLATE: if (m_predictor != -1) outImage.SetField(TiffTag.PREDICTOR, m_predictor); else { result = inImage.GetField(TiffTag.PREDICTOR); if (result != null) { m_predictor = result[0].ToShort(); outImage.SetField(TiffTag.PREDICTOR, m_predictor); } } break; case Compression.CCITTFAX3: case Compression.CCITTFAX4: if (m_compression == Compression.CCITTFAX3) { if (m_g3opts != Group3Opt.UNKNOWN) outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts); else { result = inImage.GetField(TiffTag.GROUP3OPTIONS); if (result != null) { m_g3opts = (Group3Opt)result[0].ToShort(); outImage.SetField(TiffTag.GROUP3OPTIONS, m_g3opts); } } } else copyTag(inImage, outImage, TiffTag.GROUP4OPTIONS, 1, TiffType.LONG); copyTag(inImage, outImage, TiffTag.BADFAXLINES, 1, TiffType.LONG); copyTag(inImage, outImage, TiffTag.CLEANFAXDATA, 1, TiffType.LONG); copyTag(inImage, outImage, TiffTag.CONSECUTIVEBADFAXLINES, 1, TiffType.LONG); copyTag(inImage, outImage, TiffTag.FAXRECVPARAMS, 1, TiffType.LONG); copyTag(inImage, outImage, TiffTag.FAXRECVTIME, 1, TiffType.LONG); copyTag(inImage, outImage, TiffTag.FAXSUBADDRESS, 1, TiffType.ASCII); break; } result = inImage.GetField(TiffTag.ICCPROFILE); if (result != null) outImage.SetField(TiffTag.ICCPROFILE, result[0], result[1]); result = inImage.GetField(TiffTag.NUMBEROFINKS); if (result != null) { short ninks = result[0].ToShort(); outImage.SetField(TiffTag.NUMBEROFINKS, ninks); result = inImage.GetField(TiffTag.INKNAMES); if (result != null) { string inknames = result[0].ToString(); string[] parts = inknames.Split(new char[] { '\0' }); int inknameslen = 0; foreach (string part in parts) inknameslen += part.Length + 1; outImage.SetField(TiffTag.INKNAMES, inknameslen, inknames); } } result = inImage.GetField(TiffTag.PAGENUMBER); if (m_pageInSeq == 1) { if (m_pageNum < 0) { /* only one input file */ if (result != null) outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]); } else { outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0); } } else { if (result != null) { if (m_pageNum < 0) { /* only one input file */ outImage.SetField(TiffTag.PAGENUMBER, result[0], result[1]); } else { outImage.SetField(TiffTag.PAGENUMBER, m_pageNum++, 0); } } } int NTAGS = g_tags.Length; for (int i = 0; i < NTAGS; i++) { tagToCopy p = g_tags[i]; copyTag(inImage, outImage, p.tag, p.count, p.type); } return pickFuncAndCopy(inImage, outImage, bitspersample, samplesperpixel, length, width); }
bool writeBufferToSeparateTiles(Tiff outImage, byte[] buf, int imagelength, int imagewidth, short spp) { byte[] obuf = new byte[outImage.TileSize()]; FieldValue[] result = outImage.GetField(TiffTag.TILELENGTH); int tl = result[0].ToInt(); result = outImage.GetField(TiffTag.TILEWIDTH); int tw = result[0].ToInt(); result = outImage.GetField(TiffTag.BITSPERSAMPLE); short bps = result[0].ToShort(); Debug.Assert(bps % 8 == 0); short bytes_per_sample = (short)(bps / 8); int imagew = outImage.ScanlineSize(); int tilew = outImage.TileRowSize(); int iimagew = outImage.RasterScanlineSize(); int iskew = iimagew - tilew * spp; int bufp = 0; for (int row = 0; row < imagelength; row += tl) { int nrow = (row + tl > imagelength) ? imagelength - row : tl; int colb = 0; for (int col = 0; col < imagewidth; col += tw) { for (short s = 0; s < spp; s++) { /* * Tile is clipped horizontally. Calculate * visible portion and skewing factors. */ if (colb + tilew > imagew) { int width = imagew - colb; int oskew = tilew - width; cpContigBufToSeparateBuf(obuf, buf, bufp + (colb * spp) + s, nrow, width / bytes_per_sample, oskew, (oskew * spp) + iskew, spp, bytes_per_sample); } else cpContigBufToSeparateBuf(obuf, buf, bufp + (colb * spp) + s, nrow, m_tilewidth, 0, iskew, spp, bytes_per_sample); if (outImage.WriteTile(obuf, col, row, 0, s) < 0) { Tiff.Error(outImage.FileName(), "Error, can't write tile at {0} {1} sample {2}", col, row, s); return false; } } colb += tilew; } bufp += nrow * iimagew; } return true; }
static bool writeBufferToSeparateStrips(Tiff outImage, byte[] buf, int imagelength, int imagewidth, short spp) { byte[] obuf = new byte[outImage.StripSize()]; FieldValue[] result = outImage.GetFieldDefaulted(TiffTag.ROWSPERSTRIP); int rowsperstrip = result[0].ToInt(); int rowsize = imagewidth * spp; int strip = 0; for (short s = 0; s < spp; s++) { for (int row = 0; row < imagelength; row += rowsperstrip) { int nrows = (row + rowsperstrip > imagelength) ? imagelength - row : rowsperstrip; int stripsize = outImage.VStripSize(nrows); cpContigBufToSeparateBuf(obuf, buf, row * rowsize + s, nrows, imagewidth, 0, 0, spp, 1); if (outImage.WriteEncodedStrip(strip++, obuf, stripsize) < 0) { Tiff.Error(outImage.FileName(), "Error, can't write strip {0}", strip - 1); return false; } } } return true; }
/// <summary> /// Invokes the library-wide error handling methods to (normally) write an error message /// to the <see cref="Console.Error"/>. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class. Can be <c>null</c>.</param> /// <param name="method">The method where an error is detected.</param> /// <param name="format">A composite format string (see Remarks).</param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <remarks> /// <para> /// The <paramref name="format"/> is a composite format string that uses the same format as /// <see cref="O:System.String.Format"/> method. The <paramref name="method"/> parameter, if /// not <c>null</c>, is printed before the message; it typically is used to identify the /// method in which an error is detected. /// </para> /// <para>Applications that desire to capture control in the event of an error should use /// <see cref="SetErrorHandler"/> to override the default error and warning handler. /// </para> /// </remarks> /// <overloads> /// Invokes the library-wide error handling methods to (normally) write an error message /// to the <see cref="Console.Error"/>. /// </overloads> public static void Error(Tiff tif, string method, string format, params object[] args) { TiffErrorHandler errorHandler = getErrorHandler(tif); if (errorHandler == null) return; errorHandler.ErrorHandler(tif, method, format, args); errorHandler.ErrorHandlerExt(tif, null, method, format, args); }
/// <summary> /// Handles an error by writing it text to the <see cref="Console.Error"/>. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class. Can be <c>null</c>.</param> /// <param name="clientData">A client data.</param> /// <param name="method">The method where an error is detected.</param> /// <param name="format">A composite format string (see Remarks).</param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <remarks><para> /// The <paramref name="format"/> is a composite format string that uses the same format as /// <see cref="O:System.String.Format"/> method. The <paramref name="method"/> parameter, if /// not <c>null</c>, is printed before the message; it typically is used to identify the /// method in which an error is detected. /// </para><para> /// The <paramref name="clientData"/> parameter can be anything. Its value and meaning is /// defined by an application and not the library. /// </para></remarks> public virtual void ErrorHandlerExt(Tiff tif, object clientData, string method, string format, params object[] args) { }
static bool cpImage(Tiff inImage, Tiff outImage, readFunc fin, writeFunc fout, int imagelength, int imagewidth, short spp) { bool status = false; int scanlinesize = inImage.RasterScanlineSize(); int bytes = scanlinesize * imagelength; /* * XXX: Check for integer overflow. */ if (scanlinesize != 0 && imagelength != 0 && (bytes / imagelength == scanlinesize)) { byte[] buf = new byte[bytes]; if (fin(inImage, buf, imagelength, imagewidth, spp)) status = fout(outImage, buf, imagelength, imagewidth, spp); } else { Tiff.Error(inImage.FileName(), "Error, no space for image buffer"); } return status; }
/* * Separate -> separate by row for rows/strip change. */ bool cpSeparate2SeparateByRow(Tiff inImage, Tiff outImage, int imagelength, int imagewidth, short spp) { byte[] buf = new byte[inImage.ScanlineSize()]; for (short s = 0; s < spp; s++) { for (int row = 0; row < imagelength; row++) { if (!inImage.ReadScanline(buf, row, s) && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read scanline {0}", row); return false; } if (!outImage.WriteScanline(buf, row, s)) { Tiff.Error(outImage.FileName(), "Error, can't write scanline {0}", row); return false; } } } return true; }
/// <summary> /// Prints formatted description of the contents of the current directory to the /// specified stream using specified print (formatting) options. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class.</param> /// <param name="stream">The stream to print to.</param> /// <param name="flags">The print (formatting) options.</param> public virtual void PrintDir(Tiff tif, Stream stream, TiffPrintFlags flags) { }
bool readSeparateTilesIntoBuffer(Tiff inImage, byte[] buf, int imagelength, int imagewidth, short spp) { byte[] tilebuf = new byte[inImage.TileSize()]; FieldValue[] result = inImage.GetField(TiffTag.TILEWIDTH); int tw = result[0].ToInt(); result = inImage.GetField(TiffTag.TILELENGTH); int tl = result[0].ToInt(); result = inImage.GetField(TiffTag.BITSPERSAMPLE); short bps = result[0].ToShort(); Debug.Assert(bps % 8 == 0); short bytes_per_sample = (short)(bps / 8); int imagew = inImage.RasterScanlineSize(); int tilew = inImage.TileRowSize(); int iskew = imagew - tilew * spp; int bufp = 0; for (int row = 0; row < imagelength; row += tl) { int nrow = (row + tl > imagelength) ? imagelength - row : tl; int colb = 0; for (int col = 0; col < imagewidth; col += tw) { for (short s = 0; s < spp; s++) { if (inImage.ReadTile(tilebuf, 0, col, row, 0, s) < 0 && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read tile at {0} {1}, sample {2}", col, row, s); return false; } /* * Tile is clipped horizontally. Calculate * visible portion and skewing factors. */ if (colb + tilew * spp > imagew) { int width = imagew - colb; int oskew = tilew * spp - width; cpSeparateBufToContigBuf(buf, bufp + colb + s * bytes_per_sample, tilebuf, nrow, width / (spp * bytes_per_sample), oskew + iskew, oskew / spp, spp, bytes_per_sample); } else cpSeparateBufToContigBuf(buf, bufp + colb + s * bytes_per_sample, tilebuf, nrow, tw, iskew, 0, spp, bytes_per_sample); } colb += tilew * spp; } bufp += imagew * nrow; } return true; }
static bool writeBufferToContigStrips(Tiff outImage, byte[] buffer, int imagelength, int imagewidth, short spp) { FieldValue[] result = outImage.GetFieldDefaulted(TiffTag.ROWSPERSTRIP); int rowsperstrip = result[0].ToInt(); int strip = 0; int offset = 0; for (int row = 0; row < imagelength; row += rowsperstrip) { int nrows = (row + rowsperstrip > imagelength) ? imagelength - row : rowsperstrip; int stripsize = outImage.VStripSize(nrows); if (outImage.WriteEncodedStrip(strip++, buffer, offset, stripsize) < 0) { Tiff.Error(outImage.FileName(), "Error, can't write strip {0}", strip - 1); return false; } offset += stripsize; } return true; }
/// <summary> /// Invokes the library-wide warning handling methods to (normally) write a warning message /// to the <see cref="Console.Error"/> and passes client data to the warning handler. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class. Can be <c>null</c>.</param> /// <param name="clientData">The client data to be passed to warning handler.</param> /// <param name="method">The method in which a warning is detected.</param> /// <param name="format">A composite format string (see Remarks).</param> /// <param name="args">An object array that contains zero or more objects to format.</param> /// <remarks> /// <para> /// The <paramref name="format"/> is a composite format string that uses the same format as /// <see cref="O:System.String.Format"/> method. The <paramref name="method"/> parameter, if /// not <c>null</c>, is printed before the message; it typically is used to identify the /// method in which a warning is detected. /// </para> /// <para> /// The <paramref name="clientData"/> parameter can be anything you want. It will be passed /// unchanged to the warning handler. Default warning handler does not use it. Only custom /// warning handlers may make use of it. /// </para> /// <para>Applications that desire to capture control in the event of a warning should use /// <see cref="SetErrorHandler"/> to override the default error and warning handler. /// </para> /// </remarks> /// <overloads> /// Invokes the library-wide warning handling methods to (normally) write a warning message /// to the <see cref="Console.Error"/> and passes client data to the warning handler. /// </overloads> public static void WarningExt(Tiff tif, object clientData, string method, string format, params object[] args) { TiffErrorHandler errorHandler = getErrorHandler(tif); if (errorHandler == null) return; errorHandler.WarningHandler(tif, method, format, args); errorHandler.WarningHandlerExt(tif, clientData, method, format, args); }
bool writeBufferToContigTiles(Tiff outImage, byte[] buf, int imagelength, int imagewidth, short spp) { byte[] obuf = new byte[outImage.TileSize()]; FieldValue[] result = outImage.GetField(TiffTag.TILELENGTH); int tl = result[0].ToInt(); result = outImage.GetField(TiffTag.TILEWIDTH); int tw = result[0].ToInt(); int imagew = outImage.ScanlineSize(); int tilew = outImage.TileRowSize(); int iskew = imagew - tilew; int bufp = 0; for (int row = 0; row < imagelength; row += m_tilelength) { int nrow = (row + tl > imagelength) ? imagelength - row : tl; int colb = 0; for (int col = 0; col < imagewidth; col += tw) { /* * Tile is clipped horizontally. Calculate * visible portion and skewing factors. */ if (colb + tilew > imagew) { int width = imagew - colb; int oskew = tilew - width; cpStripToTile(obuf, 0, buf, bufp + colb, nrow, width, oskew, oskew + iskew); } else cpStripToTile(obuf, 0, buf, bufp + colb, nrow, tilew, 0, iskew); if (outImage.WriteTile(obuf, col, row, 0, 0) < 0) { Tiff.Error(outImage.FileName(), "Error, can't write tile at {0} {1}", col, row); return false; } colb += tilew; } bufp += nrow * imagew; } return true; }
static Tiff ClientOpen(string name, string mode, Stream clientData, TiffStream stream, TiffErrorHandler errorHandler, TiffExtendProc extender) { const string module = "ClientOpen"; if (mode == null || mode.Length == 0) { ErrorExt(null, clientData, module, "{0}: mode string should contain at least one char", name); return(null); } int m = getMode(mode, module); Tiff tif = new Tiff(); #if THREAD_SAFE_LIBTIFF if (errorHandler != null) { tif.m_errorHandler = errorHandler; } if (extender != null) { tif.m_extender = extender; } #endif tif.m_name = name; tif.m_mode = m & ~(O_CREAT | O_TRUNC); tif.m_curdir = -1; // non-existent directory tif.m_curoff = 0; tif.m_curstrip = -1; // invalid strip tif.m_row = -1; // read/write pre-increment tif.m_clientdata = clientData; if (stream == null) { ErrorExt(tif, clientData, module, "TiffStream is null pointer."); return(null); } tif.m_stream = stream; // setup default state tif.m_currentCodec = tif.m_builtInCodecs[0]; // Default is to return data MSB2LSB and enable the use of // strip chopping when a file is opened read-only. tif.m_flags = TiffFlags.MSB2LSB; if (m == O_RDONLY || m == O_RDWR) { tif.m_flags |= STRIPCHOP_DEFAULT; } // Process library-specific flags in the open mode string. // See remarks for Open method for the list of supported flags. int modelength = mode.Length; for (int i = 0; i < modelength; i++) { switch (mode[i]) { case 'b': if ((m & O_CREAT) != 0) { tif.m_flags |= TiffFlags.SWAB; } break; case 'l': break; case 'B': tif.m_flags = (tif.m_flags & ~TiffFlags.FILLORDER) | TiffFlags.MSB2LSB; break; case 'L': tif.m_flags = (tif.m_flags & ~TiffFlags.FILLORDER) | TiffFlags.LSB2MSB; break; case 'H': tif.m_flags = (tif.m_flags & ~TiffFlags.FILLORDER) | TiffFlags.LSB2MSB; break; case 'C': if (m == O_RDONLY) { tif.m_flags |= TiffFlags.STRIPCHOP; } break; case 'c': if (m == O_RDONLY) { tif.m_flags &= ~TiffFlags.STRIPCHOP; } break; case 'h': tif.m_flags |= TiffFlags.HEADERONLY; break; case '4': tif.m_flags |= TiffFlags.NOBIGTIFF; break; case '8': tif.m_flags |= TiffFlags.ISBIGTIFF; break; } } // Read in TIFF header. if ((tif.m_mode & O_TRUNC) != 0 || !tif.readHeaderOk(ref tif.m_header)) { if (tif.m_mode == O_RDONLY) { ErrorExt(tif, tif.m_clientdata, name, "Cannot read TIFF header"); return(null); } // Setup header and write. if ((tif.m_flags & TiffFlags.SWAB) == TiffFlags.SWAB) { tif.m_header.tiff_magic = TIFF_BIGENDIAN; } else { tif.m_header.tiff_magic = TIFF_LITTLEENDIAN; } if ((tif.m_flags & TiffFlags.ISBIGTIFF) == TiffFlags.ISBIGTIFF) { tif.m_header.tiff_version = TIFF_BIGTIFF_VERSION; tif.m_header.tiff_diroff = 0; //filled in later tif.m_header.tiff_fill = 0; tif.m_header.tiff_offsize = sizeof(long); if ((tif.m_flags & TiffFlags.SWAB) == TiffFlags.SWAB) { SwabShort(ref tif.m_header.tiff_version); SwabShort(ref tif.m_header.tiff_offsize); } } else { tif.m_header.tiff_version = TIFF_VERSION; tif.m_header.tiff_diroff = 0; //filled in later tif.m_header.tiff_fill = sizeof(long); if ((tif.m_flags & TiffFlags.SWAB) == TiffFlags.SWAB) { SwabShort(ref tif.m_header.tiff_version); } } tif.seekFile(0, SeekOrigin.Begin); if (!tif.writeHeaderOK(tif.m_header)) { ErrorExt(tif, tif.m_clientdata, name, "Error writing TIFF header"); tif.m_mode = O_RDONLY; return(null); } // Setup the byte order handling. tif.initOrder(tif.m_header.tiff_magic); // Setup default directory. tif.setupDefaultDirectory(); tif.m_diroff = 0; tif.m_dirlist = null; tif.m_dirlistsize = 0; tif.m_dirnumber = 0; return(tif); } // Setup the byte order handling. if (tif.m_header.tiff_magic != TIFF_BIGENDIAN && tif.m_header.tiff_magic != TIFF_LITTLEENDIAN && tif.m_header.tiff_magic != MDI_LITTLEENDIAN) { ErrorExt(tif, tif.m_clientdata, name, "Not a TIFF or MDI file, bad magic number {0} (0x{1:x})", tif.m_header.tiff_magic, tif.m_header.tiff_magic); tif.m_mode = O_RDONLY; return(null); } tif.initOrder(tif.m_header.tiff_magic); // Swap header if required. if ((tif.m_flags & TiffFlags.SWAB) == TiffFlags.SWAB) { SwabShort(ref tif.m_header.tiff_version); SwabBigTiffValue(ref tif.m_header.tiff_diroff, tif.m_header.tiff_version == TIFF_BIGTIFF_VERSION, false); } // Now check version (if needed, it's been byte-swapped). // Note that this isn't actually a version number, it's a // magic number that doesn't change (stupid). if (tif.m_header.tiff_version == TIFF_BIGTIFF_VERSION) { if ((tif.m_flags & TiffFlags.NOBIGTIFF) == TiffFlags.NOBIGTIFF) { ErrorExt(tif, tif.m_clientdata, name, "This is a BigTIFF file. Non-BigTIFF mode '32' is forced"); tif.m_mode = O_RDONLY; return(null); } } if (tif.m_header.tiff_version == TIFF_VERSION) { if ((tif.m_flags & TiffFlags.ISBIGTIFF) == TiffFlags.ISBIGTIFF) { ErrorExt(tif, tif.m_clientdata, name, "This is a non-BigTIFF file. BigTIFF mode '64' is forced"); tif.m_mode = O_RDONLY; return(null); } } if (tif.m_header.tiff_version != TIFF_VERSION && tif.m_header.tiff_version != TIFF_BIGTIFF_VERSION) { ErrorExt(tif, tif.m_clientdata, name, "Not a TIFF file, bad version number {0} (0x{1:x})", tif.m_header.tiff_version, tif.m_header.tiff_version); tif.m_mode = O_RDONLY; return(null); } tif.m_flags |= TiffFlags.MYBUFFER; tif.m_rawcp = 0; tif.m_rawdata = null; tif.m_rawdatasize = 0; // Sometimes we do not want to read the first directory (for example, // it may be broken) and want to proceed to other directories. I this // case we use the HEADERONLY flag to open file and return // immediately after reading TIFF header. if ((tif.m_flags & TiffFlags.HEADERONLY) == TiffFlags.HEADERONLY) { return(tif); } // Setup initial directory. switch (mode[0]) { case 'r': tif.m_nextdiroff = tif.m_header.tiff_diroff; if (tif.ReadDirectory()) { tif.m_rawcc = -1; tif.m_flags |= TiffFlags.BUFFERSETUP; return(tif); } break; case 'a': // New directories are automatically append to the end of // the directory chain when they are written out (see WriteDirectory). tif.setupDefaultDirectory(); return(tif); } tif.m_mode = O_RDONLY; return(null); }
private static void copyTag(Tiff inImage, Tiff outImage, TiffTag tag, short count, TiffType type) { FieldValue[] result = null; switch (type) { case TiffType.SHORT: result = inImage.GetField(tag); if (result != null) { if (count == 1) outImage.SetField(tag, result[0]); else if (count == 2) outImage.SetField(tag, result[0], result[1]); else if (count == 4) outImage.SetField(tag, result[0], result[1], result[2]); else if (count == -1) outImage.SetField(tag, result[0], result[1]); } break; case TiffType.LONG: result = inImage.GetField(tag); if (result != null) outImage.SetField(tag, result[0]); break; case TiffType.RATIONAL: result = inImage.GetField(tag); if (result != null) outImage.SetField(tag, result[0]); break; case TiffType.ASCII: result = inImage.GetField(tag); if (result != null) outImage.SetField(tag, result[0]); break; case TiffType.DOUBLE: result = inImage.GetField(tag); if (result != null) outImage.SetField(tag, result[0]); break; default: Tiff.Error(inImage.FileName(), "Data type {0} is not supported, tag {1} skipped.", tag, type); break; } }
static Tiff Open(string fileName, string mode, TiffErrorHandler errorHandler) { return(Tiff.Open(fileName, mode, errorHandler, null)); }
/* * Select the appropriate copy function to use. */ bool pickFuncAndCopy(Tiff inImage, Tiff outImage, short bitspersample, short samplesperpixel, int length, int width) { using (TextWriter stderr = Console.Error) { FieldValue[] result = inImage.GetField(TiffTag.PLANARCONFIG); PlanarConfig shortv = (PlanarConfig)result[0].ToShort(); if (shortv != m_config && bitspersample != 8 && samplesperpixel > 1) { stderr.Write("{0}: Cannot handle different planar configuration w/ bits/sample != 8\n", inImage.FileName()); return false; } result = inImage.GetField(TiffTag.IMAGEWIDTH); int w = result[0].ToInt(); result = inImage.GetField(TiffTag.IMAGELENGTH); int l = result[0].ToInt(); bool bychunk; if (!(outImage.IsTiled() || inImage.IsTiled())) { result = inImage.GetField(TiffTag.ROWSPERSTRIP); if (result != null) { int irps = result[0].ToInt(); /* if biased, force decoded copying to allow image subtraction */ bychunk = (m_bias == null) && (m_rowsperstrip == irps); } else bychunk = false; } else { /* either inImage or outImage is tiled */ if (m_bias != null) { stderr.Write("{0}: Cannot handle tiled configuration w/bias image\n", inImage.FileName()); return false; } if (outImage.IsTiled()) { int tw; result = inImage.GetField(TiffTag.TILEWIDTH); if (result == null) tw = w; else tw = result[0].ToInt(); int tl; result = inImage.GetField(TiffTag.TILELENGTH); if (result == null) tl = l; else tl = result[0].ToInt(); bychunk = (tw == m_tilewidth && tl == m_tilelength); } else { /* outImage's not, so inImage must be tiled */ result = inImage.GetField(TiffTag.TILEWIDTH); int tw = result[0].ToInt(); result = inImage.GetField(TiffTag.TILELENGTH); int tl = result[0].ToInt(); bychunk = (tw == w && tl == m_rowsperstrip); } } if (inImage.IsTiled()) { if (outImage.IsTiled()) { /* Tiles -> Tiles */ if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.CONTIG) return cpContigTiles2ContigTiles(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.SEPARATE) return cpContigTiles2SeparateTiles(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.CONTIG) return cpSeparateTiles2ContigTiles(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.SEPARATE) return cpSeparateTiles2SeparateTiles(inImage, outImage, length, width, samplesperpixel); } else { /* Tiles -> Strips */ if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.CONTIG) return cpContigTiles2ContigStrips(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.SEPARATE) return cpContigTiles2SeparateStrips(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.CONTIG) return cpSeparateTiles2ContigStrips(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.SEPARATE) return cpSeparateTiles2SeparateStrips(inImage, outImage, length, width, samplesperpixel); } } else { if (outImage.IsTiled()) { /* Strips -> Tiles */ if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.CONTIG) return cpContigStrips2ContigTiles(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.SEPARATE) return cpContigStrips2SeparateTiles(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.CONTIG) return cpSeparateStrips2ContigTiles(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.SEPARATE) return cpSeparateStrips2SeparateTiles(inImage, outImage, length, width, samplesperpixel); } else { /* Strips -> Strips */ if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.CONTIG && !bychunk) { if (m_bias != null) return cpBiasedContig2Contig(inImage, outImage, length, width, samplesperpixel); return cpContig2ContigByRow(inImage, outImage, length, width, samplesperpixel); } else if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.CONTIG && bychunk) return cpDecodedStrips(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.CONTIG && m_config == PlanarConfig.SEPARATE) return cpContig2SeparateByRow(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.CONTIG) return cpSeparate2ContigByRow(inImage, outImage, length, width, samplesperpixel); else if (shortv == PlanarConfig.SEPARATE && m_config == PlanarConfig.SEPARATE) return cpSeparate2SeparateByRow(inImage, outImage, length, width, samplesperpixel); } } stderr.Write("tiffcp: {0}: Don't know how to copy/convert image.\n", inImage.FileName()); } return false; }
bool readContigStripsIntoBuffer(Tiff inImage, byte[] buffer, int imagelength, int imagewidth, short spp) { int scanlinesize = inImage.ScanlineSize(); int offset = 0; for (int row = 0; row < imagelength; row++) { if (!inImage.ReadScanline(buffer, offset, row, 0) && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read scanline {0}", row); return false; } offset += scanlinesize; } return true; }
/* * Strip -> strip for change in encoding. */ bool cpDecodedStrips(Tiff inImage, Tiff outImage, int imagelength, int imagewidth, short spp) { int stripsize = inImage.StripSize(); byte[] buf = new byte[stripsize]; int ns = inImage.NumberOfStrips(); int row = 0; for (int s = 0; s < ns; s++) { int cc = (row + m_rowsperstrip > imagelength) ? inImage.VStripSize(imagelength - row) : stripsize; if (inImage.ReadEncodedStrip(s, buf, 0, cc) < 0 && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read strip {0}", s); return false; } if (outImage.WriteEncodedStrip(s, buf, cc) < 0) { Tiff.Error(outImage.FileName(), "Error, can't write strip {0}", s); return false; } row += m_rowsperstrip; } return true; }
/* * Separate -> contig by row. */ bool cpSeparate2ContigByRow(Tiff inImage, Tiff outImage, int imagelength, int imagewidth, short spp) { byte[] inbuf = new byte[inImage.ScanlineSize()]; byte[] outbuf = new byte[outImage.ScanlineSize()]; for (int row = 0; row < imagelength; row++) { /* merge channels */ for (short s = 0; s < spp; s++) { if (!inImage.ReadScanline(inbuf, row, s) && !m_ignore) { Tiff.Error(inImage.FileName(), "Error, can't read scanline {0}", row); return false; } int inp = 0; int outp = s; for (int n = imagewidth; n-- > 0; ) { outbuf[outp] = inbuf[inp]; inp++; outp += spp; } } if (!outImage.WriteScanline(outbuf, row, 0)) { Tiff.Error(outImage.FileName(), "Error, can't write scanline {0}", row); return false; } } return true; }
/// <summary> /// Sets the value(s) of a tag in a TIFF file/stream open for writing. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class.</param> /// <param name="tag">The tag.</param> /// <param name="value">The tag value(s).</param> /// <returns> /// <c>true</c> if tag value(s) were set successfully; otherwise, <c>false</c>. /// </returns> /// <seealso cref="Tiff.SetField"/> public virtual bool SetField(Tiff tif, TiffTag tag, FieldValue[] value) { const string module = "vsetfield"; TiffDirectory td = tif.m_dir; bool status = true; int v32 = 0; int v = 0; bool end = false; bool badvalue = false; bool badvalue32 = false; switch (tag) { case TiffTag.SUBFILETYPE: td.td_subfiletype = (FileType)value[0].ToByte(); break; case TiffTag.IMAGEWIDTH: td.td_imagewidth = value[0].ToInt(); break; case TiffTag.IMAGELENGTH: td.td_imagelength = value[0].ToInt(); break; case TiffTag.BITSPERSAMPLE: td.td_bitspersample = value[0].ToShort(); // If the data require post-decoding processing to byte-swap samples, set it // up here. Note that since tags are required to be ordered, compression code // can override this behavior in the setup method if it wants to roll the post // decoding work in with its normal work. if ((tif.m_flags & TiffFlags.SWAB) == TiffFlags.SWAB) { switch (td.td_bitspersample) { case 16: tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab16Bit; break; case 24: tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab24Bit; break; case 32: tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab32Bit; break; case 64: tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab64Bit; break; case 128: // two 64's tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab64Bit; break; } } break; case TiffTag.COMPRESSION: v = value[0].ToInt() & 0xffff; Compression comp = (Compression)v; // If we're changing the compression scheme, then notify the previous module // so that it can cleanup any state it's setup. if (tif.fieldSet(FieldBit.Compression)) { if (td.td_compression == comp) { break; } tif.m_currentCodec.Cleanup(); tif.m_flags &= ~TiffFlags.CODERSETUP; } // Setup new compression scheme. status = tif.setCompressionScheme(comp); if (status) { td.td_compression = comp; } else { status = false; } break; case TiffTag.PHOTOMETRIC: td.td_photometric = (Photometric)value[0].ToInt(); break; case TiffTag.THRESHHOLDING: td.td_threshholding = (Threshold)value[0].ToByte(); break; case TiffTag.FILLORDER: v = value[0].ToInt(); FillOrder fo = (FillOrder)v; if (fo != FillOrder.LSB2MSB && fo != FillOrder.MSB2LSB) { badvalue = true; break; } td.td_fillorder = fo; break; case TiffTag.ORIENTATION: v = value[0].ToInt(); Orientation or = (Orientation)v; if (or < Orientation.TOPLEFT || Orientation.LEFTBOT < or) { badvalue = true; break; } else { td.td_orientation = or; } break; case TiffTag.SAMPLESPERPIXEL: // XXX should cross check - e.g. if pallette, then 1 v = value[0].ToInt(); if (v == 0) { badvalue = true; break; } td.td_samplesperpixel = (short)v; break; case TiffTag.ROWSPERSTRIP: v32 = value[0].ToInt(); if (v32 == 0) { badvalue32 = true; break; } td.td_rowsperstrip = v32; if (!tif.fieldSet(FieldBit.TileDimensions)) { td.td_tilelength = v32; td.td_tilewidth = td.td_imagewidth; } break; case TiffTag.MINSAMPLEVALUE: td.td_minsamplevalue = value[0].ToUShort(); break; case TiffTag.MAXSAMPLEVALUE: td.td_maxsamplevalue = value[0].ToUShort(); break; case TiffTag.SMINSAMPLEVALUE: td.td_sminsamplevalue = value[0].ToDouble(); break; case TiffTag.SMAXSAMPLEVALUE: td.td_smaxsamplevalue = value[0].ToDouble(); break; case TiffTag.XRESOLUTION: td.td_xresolution = value[0].ToFloat(); break; case TiffTag.YRESOLUTION: td.td_yresolution = value[0].ToFloat(); break; case TiffTag.PLANARCONFIG: v = value[0].ToInt(); PlanarConfig pc = (PlanarConfig)v; if (pc != PlanarConfig.CONTIG && pc != PlanarConfig.SEPARATE) { badvalue = true; break; } td.td_planarconfig = pc; break; case TiffTag.XPOSITION: td.td_xposition = value[0].ToFloat(); break; case TiffTag.YPOSITION: td.td_yposition = value[0].ToFloat(); break; case TiffTag.RESOLUTIONUNIT: v = value[0].ToInt(); ResUnit ru = (ResUnit)v; if (ru < ResUnit.NONE || ResUnit.CENTIMETER < ru) { badvalue = true; break; } td.td_resolutionunit = ru; break; case TiffTag.PAGENUMBER: td.td_pagenumber[0] = value[0].ToShort(); td.td_pagenumber[1] = value[1].ToShort(); break; case TiffTag.HALFTONEHINTS: td.td_halftonehints[0] = value[0].ToShort(); td.td_halftonehints[1] = value[1].ToShort(); break; case TiffTag.COLORMAP: v32 = 1 << td.td_bitspersample; Tiff.setShortArray(out td.td_colormap[0], value[0].ToShortArray(), v32); Tiff.setShortArray(out td.td_colormap[1], value[1].ToShortArray(), v32); Tiff.setShortArray(out td.td_colormap[2], value[2].ToShortArray(), v32); break; case TiffTag.EXTRASAMPLES: if (!setExtraSamples(td, ref v, value)) { badvalue = true; break; } break; case TiffTag.MATTEING: if (value[0].ToShort() != 0) { td.td_extrasamples = 1; } else { td.td_extrasamples = 0; } if (td.td_extrasamples != 0) { td.td_sampleinfo = new ExtraSample[1]; td.td_sampleinfo[0] = ExtraSample.ASSOCALPHA; } break; case TiffTag.TILEWIDTH: v32 = value[0].ToInt(); if ((v32 % 16) != 0) { if (tif.m_mode != Tiff.O_RDONLY) { badvalue32 = true; break; } Tiff.WarningExt(tif, tif.m_clientdata, tif.m_name, "Nonstandard tile width {0}, convert file", v32); } td.td_tilewidth = v32; tif.m_flags |= TiffFlags.ISTILED; break; case TiffTag.TILELENGTH: v32 = value[0].ToInt(); if ((v32 % 16) != 0) { if (tif.m_mode != Tiff.O_RDONLY) { badvalue32 = true; break; } Tiff.WarningExt(tif, tif.m_clientdata, tif.m_name, "Nonstandard tile length {0}, convert file", v32); } td.td_tilelength = v32; tif.m_flags |= TiffFlags.ISTILED; break; case TiffTag.TILEDEPTH: v32 = value[0].ToInt(); if (v32 == 0) { badvalue32 = true; break; } td.td_tiledepth = v32; break; case TiffTag.DATATYPE: v = value[0].ToInt(); SampleFormat sf = SampleFormat.VOID; switch (v) { case DATATYPE_VOID: sf = SampleFormat.VOID; break; case DATATYPE_INT: sf = SampleFormat.INT; break; case DATATYPE_UINT: sf = SampleFormat.UINT; break; case DATATYPE_IEEEFP: sf = SampleFormat.IEEEFP; break; default: badvalue = true; break; } if (!badvalue) { td.td_sampleformat = sf; } break; case TiffTag.SAMPLEFORMAT: v = value[0].ToInt(); sf = (SampleFormat)v; if (sf < SampleFormat.UINT || SampleFormat.COMPLEXIEEEFP < sf) { badvalue = true; break; } td.td_sampleformat = sf; // Try to fix up the SWAB function for complex data. if (td.td_sampleformat == SampleFormat.COMPLEXINT && td.td_bitspersample == 32 && tif.m_postDecodeMethod == Tiff.PostDecodeMethodType.pdmSwab32Bit) { tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab16Bit; } else if ((td.td_sampleformat == SampleFormat.COMPLEXINT || td.td_sampleformat == SampleFormat.COMPLEXIEEEFP) && td.td_bitspersample == 64 && tif.m_postDecodeMethod == Tiff.PostDecodeMethodType.pdmSwab64Bit) { tif.m_postDecodeMethod = Tiff.PostDecodeMethodType.pdmSwab32Bit; } break; case TiffTag.IMAGEDEPTH: td.td_imagedepth = value[0].ToInt(); break; case TiffTag.SUBIFD: if ((tif.m_flags & TiffFlags.INSUBIFD) != TiffFlags.INSUBIFD) { td.td_nsubifd = value[0].ToInt(); Tiff.setLong8Array(out td.td_subifd, value[1].TolongArray(), td.td_nsubifd); } else { Tiff.ErrorExt(tif, tif.m_clientdata, module, "{0}: Sorry, cannot nest SubIFDs", tif.m_name); status = false; } break; case TiffTag.YCBCRPOSITIONING: td.td_ycbcrpositioning = (YCbCrPosition)value[0].ToShort(); break; case TiffTag.YCBCRSUBSAMPLING: td.td_ycbcrsubsampling[0] = value[0].ToShort(); td.td_ycbcrsubsampling[1] = value[1].ToShort(); break; case TiffTag.TRANSFERFUNCTION: v = ((td.td_samplesperpixel - td.td_extrasamples) > 1 ? 3 : 1); for (int i = 0; i < v; i++) { Tiff.setShortArray(out td.td_transferfunction[i], value[0].ToShortArray(), 1 << td.td_bitspersample); } break; case TiffTag.REFERENCEBLACKWHITE: // XXX should check for null range Tiff.setFloatArray(out td.td_refblackwhite, value[0].ToFloatArray(), 6); break; case TiffTag.INKNAMES: v = value[0].ToInt(); string s = value[1].ToString(); v = checkInkNamesString(tif, v, s); status = v > 0; if (v > 0) { setNString(out td.td_inknames, s, v); td.td_inknameslen = v; } break; default: // This can happen if multiple images are open with // different codecs which have private tags. The global tag // information table may then have tags that are valid for // one file but not the other. If the client tries to set a // tag that is not valid for the image's codec then we'll // arrive here. This happens, for example, when tiffcp is // used to convert between compression schemes and // codec-specific tags are blindly copied. TiffFieldInfo fip = tif.FindFieldInfo(tag, TiffType.ANY); if (fip == null || fip.Bit != FieldBit.Custom) { Tiff.ErrorExt(tif, tif.m_clientdata, module, "{0}: Invalid {1}tag \"{2}\" (not supported by codec)", tif.m_name, Tiff.isPseudoTag(tag) ? "pseudo-" : string.Empty, fip != null ? fip.Name : "Unknown"); status = false; break; } // Find the existing entry for this custom value. int tvIndex = -1; for (int iCustom = 0; iCustom < td.td_customValueCount; iCustom++) { if (td.td_customValues[iCustom].info.Tag == tag) { tvIndex = iCustom; td.td_customValues[iCustom].value = null; break; } } // Grow the custom list if the entry was not found. if (tvIndex == -1) { td.td_customValueCount++; TiffTagValue[] new_customValues = Tiff.Realloc( td.td_customValues, td.td_customValueCount - 1, td.td_customValueCount); td.td_customValues = new_customValues; tvIndex = td.td_customValueCount - 1; td.td_customValues[tvIndex].info = fip; td.td_customValues[tvIndex].value = null; td.td_customValues[tvIndex].count = 0; } // Set custom value ... save a copy of the custom tag value. int tv_size = Tiff.dataSize(fip.Type); if (tv_size == 0) { status = false; Tiff.ErrorExt(tif, tif.m_clientdata, module, "{0}: Bad field type {1} for \"{2}\"", tif.m_name, fip.Type, fip.Name); end = true; break; } int paramIndex = 0; if (fip.PassCount) { if (fip.WriteCount == TiffFieldInfo.Variable2) { td.td_customValues[tvIndex].count = value[paramIndex++].ToInt(); } else { td.td_customValues[tvIndex].count = value[paramIndex++].ToInt(); } } else if (fip.WriteCount == TiffFieldInfo.Variable || fip.WriteCount == TiffFieldInfo.Variable2) { td.td_customValues[tvIndex].count = 1; } else if (fip.WriteCount == TiffFieldInfo.Spp) { td.td_customValues[tvIndex].count = td.td_samplesperpixel; } else { td.td_customValues[tvIndex].count = fip.WriteCount; } if (fip.Type == TiffType.ASCII) { string ascii; Tiff.setString(out ascii, value[paramIndex++].ToString()); td.td_customValues[tvIndex].value = Tiff.Latin1Encoding.GetBytes(ascii); } else { td.td_customValues[tvIndex].value = new byte[tv_size * td.td_customValues[tvIndex].count]; if ((fip.PassCount || fip.WriteCount == TiffFieldInfo.Variable || fip.WriteCount == TiffFieldInfo.Variable2 || fip.WriteCount == TiffFieldInfo.Spp || td.td_customValues[tvIndex].count > 1) && fip.Tag != TiffTag.PAGENUMBER && fip.Tag != TiffTag.HALFTONEHINTS && fip.Tag != TiffTag.YCBCRSUBSAMPLING && fip.Tag != TiffTag.DOTRANGE) { byte[] apBytes = value[paramIndex++].GetBytes(); Buffer.BlockCopy(apBytes, 0, td.td_customValues[tvIndex].value, 0, Math.Min(apBytes.Length, td.td_customValues[tvIndex].value.Length)); } else { // XXX: The following loop required to handle // PAGENUMBER, HALFTONEHINTS, // YCBCRSUBSAMPLING and DOTRANGE tags. // These tags are actually arrays and should be // passed as arrays to SetField() function, but // actually passed as a list of separate values. // This behavior must be changed in the future! // Upd: This loop also processes some EXIF tags with // UNDEFINED type (like EXIF_FILESOURCE or EXIF_SCENETYPE) // In this case input value is string-based, so // in TiffType.UNDEFINED case we use FieldValue.GetBytes()[0] // construction instead of direct call of FieldValue.ToByte() method. byte[] val = td.td_customValues[tvIndex].value; int valPos = 0; for (int i = 0; i < td.td_customValues[tvIndex].count; i++, valPos += tv_size) { switch (fip.Type) { case TiffType.BYTE: case TiffType.UNDEFINED: val[valPos] = value[paramIndex + i].GetBytes()[0]; break; case TiffType.SBYTE: val[valPos] = value[paramIndex + i].ToByte(); break; case TiffType.SHORT: Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToShort()), 0, val, valPos, tv_size); break; case TiffType.SSHORT: Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToShort()), 0, val, valPos, tv_size); break; case TiffType.LONG: case TiffType.IFD: Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToInt()), 0, val, valPos, tv_size); break; case TiffType.SLONG: Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToInt()), 0, val, valPos, tv_size); break; case TiffType.RATIONAL: case TiffType.SRATIONAL: case TiffType.FLOAT: Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToFloat()), 0, val, valPos, tv_size); break; case TiffType.DOUBLE: Buffer.BlockCopy(BitConverter.GetBytes(value[paramIndex + i].ToDouble()), 0, val, valPos, tv_size); break; default: Array.Clear(val, valPos, tv_size); status = false; break; } } } } break; } if (!end && !badvalue && !badvalue32) { if (status) { tif.setFieldBit(tif.FieldWithTag(tag).Bit); tif.m_flags |= TiffFlags.DIRTYDIRECT; } } if (badvalue) { Tiff.ErrorExt(tif, tif.m_clientdata, module, "{0}: Bad value {1} for \"{2}\" tag", tif.m_name, v, tif.FieldWithTag(tag).Name); return(false); } if (badvalue32) { Tiff.ErrorExt(tif, tif.m_clientdata, module, "{0}: Bad value {1} for \"{2}\" tag", tif.m_name, v32, tif.FieldWithTag(tag).Name); return(false); } return(status); }
/* * Contig strips -> separate tiles. */ bool cpContigStrips2SeparateTiles(Tiff inImage, Tiff outImage, int imagelength, int imagewidth, short spp) { return cpImage( inImage, outImage, new readFunc(readContigStripsIntoBuffer), new writeFunc(writeBufferToSeparateTiles), imagelength, imagewidth, spp); }
/// <summary> /// Gets the value(s) of a tag in an open TIFF file. /// </summary> /// <param name="tif">An instance of the <see cref="Tiff"/> class.</param> /// <param name="tag">The tag.</param> /// <returns>The value(s) of a tag in an open TIFF file/stream as array of /// <see cref="FieldValue"/> objects or <c>null</c> if there is no such tag set.</returns> /// <seealso cref="Tiff.GetField"/> public virtual FieldValue[] GetField(Tiff tif, TiffTag tag) { TiffDirectory td = tif.m_dir; FieldValue[] result = null; switch (tag) { case TiffTag.SUBFILETYPE: result = new FieldValue[1]; result[0].Set(td.td_subfiletype); break; case TiffTag.IMAGEWIDTH: result = new FieldValue[1]; result[0].Set(td.td_imagewidth); break; case TiffTag.IMAGELENGTH: result = new FieldValue[1]; result[0].Set(td.td_imagelength); break; case TiffTag.BITSPERSAMPLE: result = new FieldValue[1]; result[0].Set(td.td_bitspersample); break; case TiffTag.COMPRESSION: result = new FieldValue[1]; result[0].Set(td.td_compression); break; case TiffTag.PHOTOMETRIC: result = new FieldValue[1]; result[0].Set(td.td_photometric); break; case TiffTag.THRESHHOLDING: result = new FieldValue[1]; result[0].Set(td.td_threshholding); break; case TiffTag.FILLORDER: result = new FieldValue[1]; result[0].Set(td.td_fillorder); break; case TiffTag.ORIENTATION: result = new FieldValue[1]; result[0].Set(td.td_orientation); break; case TiffTag.SAMPLESPERPIXEL: result = new FieldValue[1]; result[0].Set(td.td_samplesperpixel); break; case TiffTag.ROWSPERSTRIP: result = new FieldValue[1]; result[0].Set(td.td_rowsperstrip); break; case TiffTag.MINSAMPLEVALUE: result = new FieldValue[1]; result[0].Set(td.td_minsamplevalue); break; case TiffTag.MAXSAMPLEVALUE: result = new FieldValue[1]; result[0].Set(td.td_maxsamplevalue); break; case TiffTag.SMINSAMPLEVALUE: result = new FieldValue[1]; result[0].Set(td.td_sminsamplevalue); break; case TiffTag.SMAXSAMPLEVALUE: result = new FieldValue[1]; result[0].Set(td.td_smaxsamplevalue); break; case TiffTag.XRESOLUTION: result = new FieldValue[1]; result[0].Set(td.td_xresolution); break; case TiffTag.YRESOLUTION: result = new FieldValue[1]; result[0].Set(td.td_yresolution); break; case TiffTag.PLANARCONFIG: result = new FieldValue[1]; result[0].Set(td.td_planarconfig); break; case TiffTag.XPOSITION: result = new FieldValue[1]; result[0].Set(td.td_xposition); break; case TiffTag.YPOSITION: result = new FieldValue[1]; result[0].Set(td.td_yposition); break; case TiffTag.RESOLUTIONUNIT: result = new FieldValue[1]; result[0].Set(td.td_resolutionunit); break; case TiffTag.PAGENUMBER: result = new FieldValue[2]; result[0].Set(td.td_pagenumber[0]); result[1].Set(td.td_pagenumber[1]); break; case TiffTag.HALFTONEHINTS: result = new FieldValue[2]; result[0].Set(td.td_halftonehints[0]); result[1].Set(td.td_halftonehints[1]); break; case TiffTag.COLORMAP: result = new FieldValue[3]; result[0].Set(td.td_colormap[0]); result[1].Set(td.td_colormap[1]); result[2].Set(td.td_colormap[2]); break; case TiffTag.STRIPOFFSETS: case TiffTag.TILEOFFSETS: result = new FieldValue[1]; result[0].Set(td.td_stripoffset); break; case TiffTag.STRIPBYTECOUNTS: case TiffTag.TILEBYTECOUNTS: result = new FieldValue[1]; result[0].Set(td.td_stripbytecount); break; case TiffTag.MATTEING: result = new FieldValue[1]; result[0].Set((td.td_extrasamples == 1 && td.td_sampleinfo[0] == ExtraSample.ASSOCALPHA)); break; case TiffTag.EXTRASAMPLES: result = new FieldValue[2]; result[0].Set(td.td_extrasamples); result[1].Set(td.td_sampleinfo); break; case TiffTag.TILEWIDTH: result = new FieldValue[1]; result[0].Set(td.td_tilewidth); break; case TiffTag.TILELENGTH: result = new FieldValue[1]; result[0].Set(td.td_tilelength); break; case TiffTag.TILEDEPTH: result = new FieldValue[1]; result[0].Set(td.td_tiledepth); break; case TiffTag.DATATYPE: switch (td.td_sampleformat) { case SampleFormat.UINT: result = new FieldValue[1]; result[0].Set(DATATYPE_UINT); break; case SampleFormat.INT: result = new FieldValue[1]; result[0].Set(DATATYPE_INT); break; case SampleFormat.IEEEFP: result = new FieldValue[1]; result[0].Set(DATATYPE_IEEEFP); break; case SampleFormat.VOID: result = new FieldValue[1]; result[0].Set(DATATYPE_VOID); break; } break; case TiffTag.SAMPLEFORMAT: result = new FieldValue[1]; result[0].Set(td.td_sampleformat); break; case TiffTag.IMAGEDEPTH: result = new FieldValue[1]; result[0].Set(td.td_imagedepth); break; case TiffTag.SUBIFD: result = new FieldValue[2]; result[0].Set(td.td_nsubifd); result[1].Set(td.td_subifd); break; case TiffTag.YCBCRPOSITIONING: result = new FieldValue[1]; result[0].Set(td.td_ycbcrpositioning); break; case TiffTag.YCBCRSUBSAMPLING: result = new FieldValue[2]; result[0].Set(td.td_ycbcrsubsampling[0]); result[1].Set(td.td_ycbcrsubsampling[1]); break; case TiffTag.TRANSFERFUNCTION: result = new FieldValue[3]; result[0].Set(td.td_transferfunction[0]); if (td.td_samplesperpixel - td.td_extrasamples > 1) { result[1].Set(td.td_transferfunction[1]); result[2].Set(td.td_transferfunction[2]); } break; case TiffTag.REFERENCEBLACKWHITE: if (td.td_refblackwhite != null) { result = new FieldValue[1]; result[0].Set(td.td_refblackwhite); } break; case TiffTag.INKNAMES: result = new FieldValue[1]; result[0].Set(td.td_inknames); break; default: // This can happen if multiple images are open with // different codecs which have private tags. The global tag // information table may then have tags that are valid for // one file but not the other. If the client tries to get a // tag that is not valid for the image's codec then we'll // arrive here. TiffFieldInfo fip = tif.FindFieldInfo(tag, TiffType.ANY); if (fip == null || fip.Bit != FieldBit.Custom) { Tiff.ErrorExt(tif, tif.m_clientdata, "_TIFFVGetField", "{0}: Invalid {1}tag \"{2}\" (not supported by codec)", tif.m_name, Tiff.isPseudoTag(tag) ? "pseudo-" : string.Empty, fip != null ? fip.Name : "Unknown"); result = null; break; } // Do we have a custom value? result = null; for (int i = 0; i < td.td_customValueCount; i++) { TiffTagValue tv = td.td_customValues[i]; if (tv.info.Tag != tag) { continue; } if (fip.PassCount) { result = new FieldValue[2]; if (fip.ReadCount == TiffFieldInfo.Variable2) { result[0].Set(tv.count); } else { // Assume TiffFieldInfo.Variable result[0].Set(tv.count); } result[1].Set(tv.value); } else { if ((fip.Type == TiffType.ASCII || fip.ReadCount == TiffFieldInfo.Variable || fip.ReadCount == TiffFieldInfo.Variable2 || fip.ReadCount == TiffFieldInfo.Spp || tv.count > 1) && fip.Tag != TiffTag.PAGENUMBER && fip.Tag != TiffTag.HALFTONEHINTS && fip.Tag != TiffTag.YCBCRSUBSAMPLING && fip.Tag != TiffTag.DOTRANGE) { result = new FieldValue[1]; byte[] value = tv.value; if (fip.Type == TiffType.ASCII && tv.value.Length > 0 && tv.value[tv.value.Length - 1] == 0) { // cut unwanted zero at the end value = new byte[Math.Max(tv.value.Length - 1, 0)]; Buffer.BlockCopy(tv.value, 0, value, 0, value.Length); } result[0].Set(value); } else { result = new FieldValue[tv.count]; byte[] val = tv.value; int valPos = 0; for (int j = 0; j < tv.count; j++, valPos += Tiff.dataSize(tv.info.Type)) { switch (fip.Type) { case TiffType.BYTE: case TiffType.UNDEFINED: case TiffType.SBYTE: result[j].Set(val[valPos]); break; case TiffType.SHORT: case TiffType.SSHORT: result[j].Set(BitConverter.ToInt16(val, valPos)); break; case TiffType.LONG: case TiffType.IFD: case TiffType.SLONG: result[j].Set(BitConverter.ToInt32(val, valPos)); break; case TiffType.RATIONAL: case TiffType.SRATIONAL: case TiffType.FLOAT: result[j].Set(BitConverter.ToSingle(val, valPos)); break; case TiffType.DOUBLE: result[j].Set(BitConverter.ToDouble(val, valPos)); break; default: result = null; break; } } } } break; } break; } return(result); }