private static int readUnsignedShort(RandomAccessFileOrArray stream, bool isBigEndian) { if (isBigEndian) { return(stream.ReadUnsignedShort()); } else { return(stream.ReadUnsignedShortLe()); } }
/// <summary>Construct an icc profile from the file found at the passed path</summary> /// <param name="filename">path to the file contaning the profile</param> /// <returns>IccProfile constructed from the data</returns> public static iText.IO.Colors.IccProfile GetInstance(String filename) { RandomAccessFileOrArray raf; try { raf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateBestSource(filename)); } catch (System.IO.IOException e) { throw new iText.IO.IOException(iText.IO.IOException.InvalidIccProfile, e); } return(GetInstance(raf)); }
/// <summary>Extracts a revision from the document.</summary> /// <param name="field">the signature field name</param> /// <returns>an InputStream covering the revision. Returns null if it's not a signature field</returns> /// <exception cref="System.IO.IOException"/> public virtual Stream ExtractRevision(String field) { GetSignatureNames(); if (!sigNames.ContainsKey(field)) { return(null); } int length = sigNames.Get(field)[0]; RandomAccessFileOrArray raf = document.GetReader().GetSafeFile(); return(new RASInputStream(new WindowRandomAccessSource(raf.CreateSourceView(), 0, length))); }
/// <exception cref="System.IO.IOException"/> public static SubstLookupRecord[] ReadSubstLookupRecords(RandomAccessFileOrArray rf, int substCount) { SubstLookupRecord[] substPosLookUpRecords = new SubstLookupRecord[substCount]; for (int i = 0; i < substCount; ++i) { SubstLookupRecord slr = new SubstLookupRecord(); slr.sequenceIndex = rf.ReadUnsignedShort(); slr.lookupListIndex = rf.ReadUnsignedShort(); substPosLookUpRecords[i] = slr; } return(substPosLookUpRecords); }
private static long ReadUnsignedInt(RandomAccessFileOrArray stream, bool isBigEndian) { if (isBigEndian) { return(stream.ReadUnsignedInt()); } else { return(stream.ReadUnsignedIntLE()); } }
virtual public void TestFilePositionWithPushback() { RandomAccessFileOrArray rafoa = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateSource(data)); long offset = 72; rafoa.Seek(offset); Assert.AreEqual(offset, rafoa.FilePointer); byte pushbackVal = 42; rafoa.PushBack(pushbackVal); Assert.AreEqual(offset - 1, rafoa.FilePointer); }
public OpenTypeParser(String name) { String ttcName = GetTTCName(name); this.fileName = ttcName; if (ttcName.Length < name.Length) { ttcIndex = Convert.ToInt32(name.Substring(ttcName.Length + 1), System.Globalization.CultureInfo.InvariantCulture ); } raf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateBestSource(fileName)); InitializeSfntTables(); }
public static iText.IO.Font.Otf.OtfClass Create(RandomAccessFileOrArray rf, int classLocation) { iText.IO.Font.Otf.OtfClass otfClass; try { otfClass = new iText.IO.Font.Otf.OtfClass(rf, classLocation); } catch (System.IO.IOException) { ILog logger = LogManager.GetLogger(typeof(iText.IO.Font.Otf.OtfClass)); logger.Error(iText.IO.LogMessageConstant.OPENTYPE_GDEF_TABLE_ERROR); otfClass = null; } return(otfClass); }
/// <summary> /// Gets a byte array that can be used as a /JBIG2Globals, /// or null if not applicable to the given jbig2. /// </summary> /// <param name="ra">an random access file or array</param> /// <returns>a byte array</returns> public static byte[] GetGlobalSegment(RandomAccessFileOrArray ra) { try { var sr = new Jbig2SegmentReader(ra); sr.Read(); return(sr.GetGlobal(true)); } catch { return(null); } }
// --------------------------------------------------------------------------- public void AddJBIG2(Document document, String path) { RandomAccessFileOrArray ra = new RandomAccessFileOrArray(path); int n = JBIG2Image.GetNumberOfPages(ra); Image img; for (int i = 1; i <= n; i++) { img = JBIG2Image.GetJbig2Image(ra, i); img.ScaleToFit(523, 350); document.Add(img); } }
/// <exception cref="System.IO.IOException"/> public OpenTypeParser(String name) { String nameBase = FontProgram.GetBaseName(name); String ttcName = GetTTCName(nameBase); this.fileName = ttcName; if (ttcName.Length < nameBase.Length) { ttcIndex = System.Convert.ToInt32(nameBase.Substring(ttcName.Length + 1)); } raf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateBestSource(fileName)); Process(); }
public virtual void TestReadCoverageFormat2() { // Based on Example 6 from the specification // https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2 // 0002 0001 A04E A057 0000 String path = RESOURCE_FOLDER + "coverage-format-2.bin"; RandomAccessFileOrArray rf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateBestSource( path)); IList <int> glyphIds = OtfReadCommon.ReadCoverageFormat(rf, 0); NUnit.Framework.Assert.AreEqual(10, glyphIds.Count); NUnit.Framework.Assert.AreEqual(0xA04E, (int)glyphIds[0]); NUnit.Framework.Assert.AreEqual(0xA057, (int)glyphIds[9]); }
/// <summary> /// returns an Image representing the given page. /// </summary> /// <param name="ra">the file or array containing the image</param> /// <param name="page">the page number of the image</param> /// <returns>an Image object</returns> public static Image GetJbig2Image(RandomAccessFileOrArray ra, int page) { if (page < 1) { throw new ArgumentException("The page number must be >= 1."); } var sr = new Jbig2SegmentReader(ra); sr.Read(); var p = sr.GetPage(page); Image img = new ImgJbig2(p.PageBitmapWidth, p.PageBitmapHeight, p.GetData(true), sr.GetGlobal(true)); return(img); }
internal static byte[] ReadFontBytesFromPath(String path) { RandomAccessFileOrArray raf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateBestSource (path)); int bufLen = (int)raf.Length(); if (bufLen < raf.Length()) { throw new iText.IO.IOException(MessageFormatUtil.Format("Source data from \"{0}\" is bigger than byte array can hold." , path)); } byte[] buf = new byte[bufLen]; raf.ReadFully(buf); return(buf); }
/** * returns an Image representing the given page. * @param ra the file or array containing the image * @param page the page number of the image * @return an Image object */ public static Image GetJbig2Image(RandomAccessFileOrArray ra, int page) { if (page < 1) { throw new ArgumentException(MessageLocalization.GetComposedMessage("the.page.number.must.be.gt.eq.1")); } JBIG2SegmentReader sr = new JBIG2SegmentReader(ra); sr.Read(); JBIG2SegmentReader.JBIG2Page p = sr.GetPage(page); Image img = new ImgJBIG2(p.pageBitmapWidth, p.pageBitmapHeight, p.GetData(true), sr.GetGlobal(true)); return(img); }
/// <exception cref="System.IO.IOException"/> public static void TransferBytes(RandomAccessFileOrArray input, Stream output) { byte[] buffer = new byte[TRANSFER_SIZE]; for (; ;) { int len = input.Read(buffer, 0, TRANSFER_SIZE); if (len > 0) { output.Write(buffer, 0, len); } else { break; } } }
public static void InsertBookPages(int bookID, string path, int pagesCount) { string pagetext = ""; string picturesText = ""; PdfReader reader = new PdfReader(path); RandomAccessFileOrArray raf = new RandomAccessFileOrArray(path); for (int pageID = 1; pageID <= pagesCount; pageID++) { pagetext = ConvertArabic(PdfTextExtractor.GetTextFromPage(reader, pageID)); picturesText = GetPictureText(pageID, reader, raf); DataBaseTools.InsertBookPage(bookID, pagetext, picturesText); } raf.Close(); reader.Close(); }
// --------------------------------------------------------------------------- /** * Parses object and content information of a PDF into a text file. * @param pdf the original PDF * * this method uses code from; * PdfContentReaderTool.ListContentStreamForPage() * so i can pass in a byte array instead of file path * */ public string InspectPdf(byte[] pdf) { PdfReader reader = new PdfReader(pdf); int maxPageNum = reader.NumberOfPages; StringBuilder sb = new StringBuilder(); for (int pageNum = 1; pageNum <= maxPageNum; pageNum++) { sb.AppendLine("==============Page " + pageNum + "===================="); sb.AppendLine("- - - - - Dictionary - - - - - -"); PdfDictionary pageDictionary = reader.GetPageN(pageNum); sb.AppendLine( PdfContentReaderTool.GetDictionaryDetail(pageDictionary) ); sb.AppendLine("- - - - - XObject Summary - - - - - -"); sb.AppendLine(PdfContentReaderTool.GetXObjectDetail( pageDictionary.GetAsDict(PdfName.RESOURCES)) ); sb.AppendLine("- - - - - Content Stream - - - - - -"); RandomAccessFileOrArray f = reader.SafeFile; byte[] contentBytes = reader.GetPageContent(pageNum, f); f.Close(); foreach (byte b in contentBytes) { sb.Append((char)b); } sb.AppendLine("- - - - - Text Extraction - - - - - -"); String extractedText = PdfTextExtractor.GetTextFromPage( reader, pageNum, new LocationTextExtractionStrategy() ); if (extractedText.Length != 0) { sb.AppendLine(extractedText); } else { sb.AppendLine("No text found on page " + pageNum); } sb.AppendLine(); } return(sb.ToString()); }
public static void ProcessImage(ImageData jbig2) { if (jbig2.GetOriginalType() != ImageType.JBIG2) { throw new ArgumentException("JBIG2 image expected"); } Jbig2ImageData image = (Jbig2ImageData)jbig2; try { IRandomAccessSource ras; if (image.GetData() == null) { image.LoadData(); } ras = new RandomAccessSourceFactory().CreateSource(image.GetData()); RandomAccessFileOrArray raf = new RandomAccessFileOrArray(ras); Jbig2SegmentReader sr = new Jbig2SegmentReader(raf); sr.Read(); Jbig2SegmentReader.Jbig2Page p = sr.GetPage(image.GetPage()); raf.Close(); image.SetHeight(p.pageBitmapHeight); image.SetWidth(p.pageBitmapWidth); image.SetBpc(1); image.SetColorSpace(1); //TODO JBIG2 globals caching byte[] globals = sr.GetGlobal(true); //TODO due to the fact, that streams now may be transformed to indirect objects only on writing, //pdfStream.getDocument() cannot longer be the sign of inline/indirect images // in case inline image pdfStream.getDocument() will be null if (globals != null) { /*&& stream.getDocument() != null*/ IDictionary <String, Object> decodeParms = new Dictionary <String, Object>(); // PdfStream globalsStream = new PdfStream().makeIndirect(pdfStream.getDocument()); // globalsStream.getOutputStream().write(globals); decodeParms["JBIG2Globals"] = globals; image.decodeParms = decodeParms; } image.SetFilter("JBIG2Decode"); image.SetColorSpace(1); image.SetBpc(1); image.data = p.GetData(true); } catch (System.IO.IOException e) { throw new iText.IO.IOException(iText.IO.IOException.Jbig2ImageException, e); } }
//////////////////////////////////////////////////////////////////////////////////////////////////// public static List <System.Drawing.Image> ExtractImages(string PDFSourcePath) { List <System.Drawing.Image> imgList = new List <System.Drawing.Image>(); RandomAccessFileOrArray RAFObj = null; PdfReader PDFReaderObj = null; PdfObject PDFObj = null; PdfStream PDFStremObj = null; try { RAFObj = new RandomAccessFileOrArray(PDFSourcePath); PDFReaderObj = new PdfReader(RAFObj, null); for (int i = 0; i <= PDFReaderObj.XrefSize - 1; i++) { PDFObj = PDFReaderObj.GetPdfObject(i); if ((PDFObj != null) && PDFObj.IsStream()) { PDFStremObj = (PdfStream)PDFObj; iTextSharp.text.pdf.PdfObject subtype = PDFStremObj.Get(PdfName.SUBTYPE); if ((subtype != null) && subtype.ToString() == PdfName.IMAGE.ToString()) { try { PdfImageObject PdfImageObj = new PdfImageObject((PRStream)PDFStremObj); System.Drawing.Image ImgPDF = PdfImageObj.GetDrawingImage(); imgList.Add(ImgPDF); } catch (Exception) { } } } } PDFReaderObj.Close(); } catch (Exception ex) { throw new Exception(ex.Message); } return(imgList); }
public virtual void TestReadCoverageFormat1() { // Based on Example 5 from the specification // https://docs.microsoft.com/en-us/typography/opentype/spec/chapter2 // 0001 0005 0038 003B 0041 1042 A04A String path = RESOURCE_FOLDER + "coverage-format-1.bin"; RandomAccessFileOrArray rf = new RandomAccessFileOrArray(new RandomAccessSourceFactory().CreateBestSource( path)); IList <int> glyphIds = OtfReadCommon.ReadCoverageFormat(rf, 0); NUnit.Framework.Assert.AreEqual(5, glyphIds.Count); NUnit.Framework.Assert.AreEqual(0x38, (int)glyphIds[0]); NUnit.Framework.Assert.AreEqual(0x3B, (int)glyphIds[1]); NUnit.Framework.Assert.AreEqual(0x41, (int)glyphIds[2]); NUnit.Framework.Assert.AreEqual(0x1042, (int)glyphIds[3]); NUnit.Framework.Assert.AreEqual(0xA04A, (int)glyphIds[4]); }
/// <exception cref="System.IO.IOException"/> private bool IsAfmFile(RandomAccessFileOrArray raf) { StringBuilder builder = new StringBuilder(AFM_HEADER.Length); for (int i = 0; i < AFM_HEADER.Length; i++) { try { builder.Append((char)raf.ReadByte()); } catch (EndOfStreamException) { raf.Seek(0); return(false); } } raf.Seek(0); return(AFM_HEADER.Equals(builder.ToString())); }
/// <summary> /// Returns the number of image directories (subimages) stored in a /// given TIFF file, represented by a SeekableStream . /// </summary> public static int GetNumDirectories(RandomAccessFileOrArray stream) { long pointer = stream.FilePointer; // Save stream pointer stream.Seek(0L); var endian = stream.ReadUnsignedShort(); if (!isValidEndianTag(endian)) { throw new InvalidOperationException("Bad endianness tag (not 0x4949 or 0x4d4d)."); } var isBigEndian = (endian == 0x4d4d); var magic = readUnsignedShort(stream, isBigEndian); if (magic != 42) { throw new InvalidOperationException("Bad magic number, should be 42."); } stream.Seek(4L); var offset = readUnsignedInt(stream, isBigEndian); var numDirectories = 0; while (offset != 0L) { ++numDirectories; // EOFException means IFD was probably not properly terminated. try { stream.Seek(offset); var entries = readUnsignedShort(stream, isBigEndian); stream.Skip(12 * entries); offset = readUnsignedInt(stream, isBigEndian); } catch (EndOfStreamException) { //numDirectories--; break; } } stream.Seek(pointer); // Reset stream pointer return(numDirectories); }
public static byte[] GetBytes(Uri uri) { WebRequest wr = WebRequest.Create(uri); wr.Credentials = CredentialCache.DefaultCredentials; var isp = wr.GetResponse().GetResponseStream(); byte[] bytes = null; try { var a = new RandomAccessFileOrArray(isp); try { using (var aa = new MemoryStream()) { int b; while ((b = a.Read()) != -1) { aa.WriteByte((byte)b); } bytes = aa.ToArray(); } } finally { try { a.Close(); } catch (Exception) { } } } finally { try { isp.Close(); } catch (Exception) { } } return(bytes); }
/** * Constructs a TIFFDirectory from a SeekableStream. * The directory parameter specifies which directory to read from * the linked list present in the stream; directory 0 is normally * read but it is possible to store multiple images in a single * TIFF file by maintaing multiple directories. * * @param stream a SeekableStream to read from. * @param directory the index of the directory to read. */ public TIFFDirectory(RandomAccessFileOrArray stream, int directory) { long global_save_offset = stream.FilePointer; long ifd_offset; // Read the TIFF header stream.Seek(0L); int endian = stream.ReadUnsignedShort(); if (!IsValidEndianTag(endian)) { throw new ArgumentException("Bad endianness tag (not 0x4949 or 0x4d4d)."); } isBigEndian = (endian == 0x4d4d); int magic = ReadUnsignedShort(stream); if (magic != 42) { throw new ArgumentException("Bad magic number, should be 42."); } // Get the initial ifd offset as an unsigned int (using a long) ifd_offset = ReadUnsignedInt(stream); for (int i = 0; i < directory; i++) { if (ifd_offset == 0L) { throw new ArgumentException("Directory number too large."); } stream.Seek(ifd_offset); int entries = ReadUnsignedShort(stream); stream.Skip(12 * entries); ifd_offset = ReadUnsignedInt(stream); } stream.Seek(ifd_offset); Initialize(stream); stream.Seek(global_save_offset); }
public static List <CloudBlockBlob> ExtractImageUploadToAzure(PdfReader pdfReader, Stream blob, TraceWriter log, string name, ResumeDocModel resumeDocModel) { RandomAccessFileOrArray raf = new RandomAccessFileOrArray(blob); List <CloudBlockBlob> cloudBlockBlobs = new List <CloudBlockBlob>(); AzureStorageModel azureStorageModel = AzStorage.GetBlobDirectoryList(name); if (azureStorageModel.IblobList.Count() > 0) { foreach (IListBlobItem listBlobItem in azureStorageModel.IblobList) { CloudBlockBlob cloudBlob = listBlobItem as CloudBlockBlob; cloudBlob.DeleteIfExists(); } } try { for (int pageNumber = 1; pageNumber <= pdfReader.NumberOfPages; pageNumber++) { PdfDictionary pg = pdfReader.GetPageN(pageNumber); List <Image> IlistImages = GetImagesFromPdfDict(pg, pdfReader); EncoderParameters parms = new EncoderParameters(1); parms.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, 90L); var encoder = ImageCodecInfo.GetImageEncoders().First(c => c.FormatID == ImageFormat.Jpeg.Guid); foreach (Image image in IlistImages) { MemoryStream ms = new MemoryStream(); CloudBlockBlob cloudBlob = azureStorageModel.Container.GetBlockBlobReference(name + "/" + Guid.NewGuid() + ".jpeg"); image.Save(ms, encoder, parms); ms.Seek(0, SeekOrigin.Begin); // otherwise you'll get zero byte files cloudBlob.UploadFromStream(ms); cloudBlockBlobs.Add(cloudBlob); resumeDocModel.imageDetails.imageURLList.Add(cloudBlob.Uri.ToString()); } } } catch { throw; } finally { pdfReader.Close(); } return(cloudBlockBlobs); }
/// <summary>Creates a new TrueTypeFontSubSet</summary> /// <param name="directoryOffset">The offset from the start of the file to the table directory</param> /// <param name="fileName">the file name of the font</param> /// <param name="glyphsUsed">the glyphs used</param> internal TrueTypeFontSubset(String fileName, RandomAccessFileOrArray rf, ICollection <int> glyphsUsed, int directoryOffset, bool subset) { this.fileName = fileName; this.rf = rf; this.glyphsUsed = new HashSet <int>(glyphsUsed); this.directoryOffset = directoryOffset; // subset = false is possible with directoryOffset > 0, i.e. ttc font without subset. if (subset) { tableNames = TABLE_NAMES_SUBSET; } else { tableNames = TABLE_NAMES; } glyphsInList = new List <int>(glyphsUsed); }
internal static PdfReader CreatePdfReaderFromTiff(byte[] sourceBytes, Rectangle pageSize, Margins margins) { using (var document = new Document()) { using (var stream = new MemoryStream()) { using (var writer = PdfWriter.GetInstance(document, stream)) { var ra = new RandomAccessFileOrArray(sourceBytes); int numberOfPages = TiffImage.GetNumberOfPages(ra); for (int i = 1; i <= numberOfPages; i++) { var image = TiffImage.GetTiffImage(ra, i); Rectangle currentPageSize = pageSize == null ? new Rectangle(image.ScaledWidth + margins.Left + margins.Right + 1, image.ScaledHeight + margins.Top + margins.Bottom + 1) : pageSize; document.SetPageSize(currentPageSize); document.SetMargins(margins.Left, margins.Right, margins.Top, margins.Bottom); if (i == 1) { document.Open(); } else { document.NewPage(); } if (pageSize != null) { float width = pageSize.Width - (margins.Left + margins.Right + 1); float height = pageSize.Height - (margins.Top + margins.Bottom + 1); if (width <= 0 || height <= 0) { throw new IOException("Margin is too big."); } image.ScaleToFit(width, height); } document.Add(image); } document.Close(); ra.Close(); } var pdfArray = stream.ToArray(); return(new PdfReader(pdfArray)); } } }
// Utilities /** * Returns the number of image directories (subimages) stored in a * given TIFF file, represented by a <code>SeekableStream</code>. */ public static int GetNumDirectories(RandomAccessFileOrArray stream) { long pointer = stream.FilePointer; // Save stream pointer stream.Seek(0L); int endian = stream.ReadUnsignedShort(); if (!IsValidEndianTag(endian)) { throw new ArgumentException(MessageLocalization.GetComposedMessage("bad.endianness.tag.not.0x4949.or.0x4d4d")); } bool isBigEndian = (endian == 0x4d4d); int magic = ReadUnsignedShort(stream, isBigEndian); if (magic != 42) { throw new ArgumentException(MessageLocalization.GetComposedMessage("bad.magic.number.should.be.42")); } stream.Seek(4L); long offset = ReadUnsignedInt(stream, isBigEndian); int numDirectories = 0; while (offset != 0L) { ++numDirectories; // EOFException means IFD was probably not properly terminated. try { stream.Seek(offset); int entries = ReadUnsignedShort(stream, isBigEndian); stream.Skip(12 * entries); offset = ReadUnsignedInt(stream, isBigEndian); } catch (EndOfStreamException) { numDirectories--; break; } } stream.Seek(pointer); // Reset stream pointer return(numDirectories); }
/** * Constructs a TIFFDirectory from a SeekableStream. * The directory parameter specifies which directory to read from * the linked list present in the stream; directory 0 is normally * read but it is possible to store multiple images in a single * TIFF file by maintaing multiple directories. * * @param stream a SeekableStream to read from. * @param directory the index of the directory to read. */ public TIFFDirectory(RandomAccessFileOrArray stream, int directory) { long global_save_offset = stream.FilePointer; long ifd_offset; // Read the TIFF header stream.Seek(0L); int endian = stream.ReadUnsignedShort(); if (!IsValidEndianTag(endian)) { throw new ArgumentException(MessageLocalization.GetComposedMessage("bad.endianness.tag.not.0x4949.or.0x4d4d")); } isBigEndian = (endian == 0x4d4d); int magic = ReadUnsignedShort(stream); if (magic != 42) { throw new ArgumentException(MessageLocalization.GetComposedMessage("bad.magic.number.should.be.42")); } // Get the initial ifd offset as an unsigned int (using a long) ifd_offset = ReadUnsignedInt(stream); for (int i = 0; i < directory; i++) { if (ifd_offset == 0L) { throw new ArgumentException(MessageLocalization.GetComposedMessage("directory.number.too.large")); } stream.Seek(ifd_offset); int entries = ReadUnsignedShort(stream); stream.Skip(12 * entries); ifd_offset = ReadUnsignedInt(stream); } stream.Seek(ifd_offset); Initialize(stream); stream.Seek(global_save_offset); }
/** Reads a page from a TIFF image. Direct mode is not used. * @param s the file source * @param page the page to get. The first page is 1 * @return the <CODE>Image</CODE> */ public static Image GetTiffImage(RandomAccessFileOrArray s, int page) { return GetTiffImage(s, page, false); }
/** Reads a page from a TIFF image. * @param s the file source * @param page the page to get. The first page is 1 * @param direct for single strip, CCITT images, generate the image * by direct byte copying. It's faster but may not work * every time * @return the <CODE>Image</CODE> */ public static Image GetTiffImage(RandomAccessFileOrArray s, int page, bool direct) { if (page < 1) throw new ArgumentException("The page number must be >= 1."); TIFFDirectory dir = new TIFFDirectory(s, page - 1); if (dir.IsTagPresent(TIFFConstants.TIFFTAG_TILEWIDTH)) throw new ArgumentException("Tiles are not supported."); int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); switch (compression) { case TIFFConstants.COMPRESSION_CCITTRLEW: case TIFFConstants.COMPRESSION_CCITTRLE: case TIFFConstants.COMPRESSION_CCITTFAX3: case TIFFConstants.COMPRESSION_CCITTFAX4: break; default: return GetTiffImageColor(dir, s); } float rotation = 0; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) { int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION); if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT) rotation = (float)Math.PI; else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT) rotation = (float)(Math.PI / 2.0); else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT) rotation = -(float)(Math.PI / 2.0); } Image img = null; long tiffT4Options = 0; long tiffT6Options = 0; int fillOrder = 1; int h = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH); int w = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH); int dpiX = 0; int dpiY = 0; float XYRatio = 0; int resolutionUnit = TIFFConstants.RESUNIT_INCH; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT)) resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT); dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit); dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit); if (resolutionUnit == TIFFConstants.RESUNIT_NONE) { if (dpiY != 0) XYRatio = (float)dpiX / (float)dpiY; dpiX = 0; dpiY = 0; } int rowsStrip = h; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP); if (rowsStrip <= 0 || rowsStrip > h) rowsStrip = h; long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS); long[] size = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS); if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip) { // some TIFF producers are really lousy, so... size = new long[]{s.Length - (int)offset[0]}; } bool reverse = false; TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER); if (fillOrderField != null) fillOrder = fillOrderField.GetAsInt(0); reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB); int paramsn = 0; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PHOTOMETRIC)) { long photo = dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC); if (photo == TIFFConstants.PHOTOMETRIC_MINISBLACK) paramsn |= Image.CCITT_BLACKIS1; } int imagecomp = 0; switch (compression) { case TIFFConstants.COMPRESSION_CCITTRLEW: case TIFFConstants.COMPRESSION_CCITTRLE: imagecomp = Image.CCITTG3_1D; paramsn |= Image.CCITT_ENCODEDBYTEALIGN | Image.CCITT_ENDOFBLOCK; break; case TIFFConstants.COMPRESSION_CCITTFAX3: imagecomp = Image.CCITTG3_1D; paramsn |= Image.CCITT_ENDOFLINE | Image.CCITT_ENDOFBLOCK; TIFFField t4OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP3OPTIONS); if (t4OptionsField != null) { tiffT4Options = t4OptionsField.GetAsLong(0); if ((tiffT4Options & TIFFConstants.GROUP3OPT_2DENCODING) != 0) imagecomp = Image.CCITTG3_2D; if ((tiffT4Options & TIFFConstants.GROUP3OPT_FILLBITS) != 0) paramsn |= Image.CCITT_ENCODEDBYTEALIGN; } break; case TIFFConstants.COMPRESSION_CCITTFAX4: imagecomp = Image.CCITTG4; TIFFField t6OptionsField = dir.GetField(TIFFConstants.TIFFTAG_GROUP4OPTIONS); if (t6OptionsField != null) tiffT6Options = t6OptionsField.GetAsLong(0); break; } if (direct && rowsStrip == h) { //single strip, direct byte[] im = new byte[(int)size[0]]; s.Seek(offset[0]); s.ReadFully(im); img = Image.GetInstance(w, h, false, imagecomp, paramsn, im); img.Inverted = true; } else { int rowsLeft = h; CCITTG4Encoder g4 = new CCITTG4Encoder(w); for (int k = 0; k < offset.Length; ++k) { byte[] im = new byte[(int)size[k]]; s.Seek(offset[k]); s.ReadFully(im); int height = Math.Min(rowsStrip, rowsLeft); TIFFFaxDecoder decoder = new TIFFFaxDecoder(fillOrder, w, height); byte[] outBuf = new byte[(w + 7) / 8 * height]; switch (compression) { case TIFFConstants.COMPRESSION_CCITTRLEW: case TIFFConstants.COMPRESSION_CCITTRLE: decoder.Decode1D(outBuf, im, 0, height); g4.Fax4Encode(outBuf, height); break; case TIFFConstants.COMPRESSION_CCITTFAX3: try { decoder.Decode2D(outBuf, im, 0, height, tiffT4Options); } catch (Exception e) { // let's flip the fill bits and try again... tiffT4Options ^= TIFFConstants.GROUP3OPT_FILLBITS; try { decoder.Decode2D(outBuf, im, 0, height, tiffT4Options); } catch { throw e; } } g4.Fax4Encode(outBuf, height); break; case TIFFConstants.COMPRESSION_CCITTFAX4: decoder.DecodeT6(outBuf, im, 0, height, tiffT6Options); g4.Fax4Encode(outBuf, height); break; } rowsLeft -= rowsStrip; } byte[] g4pic = g4.Close(); img = Image.GetInstance(w, h, false, Image.CCITTG4, paramsn & Image.CCITT_BLACKIS1, g4pic); } img.SetDpi(dpiX, dpiY); img.XYRatio = XYRatio; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) { try { TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE); ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes()); if (icc_prof.NumComponents == 1) img.TagICC = icc_prof; } catch { //empty } } img.OriginalType = Image.ORIGINAL_TIFF; if (rotation != 0) img.InitialRotation = rotation; return img; }
protected static Image GetTiffImageColor(TIFFDirectory dir, RandomAccessFileOrArray s) { int predictor = 1; TIFFLZWDecoder lzwDecoder = null; int compression = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_COMPRESSION); switch (compression) { case TIFFConstants.COMPRESSION_NONE: case TIFFConstants.COMPRESSION_LZW: case TIFFConstants.COMPRESSION_PACKBITS: case TIFFConstants.COMPRESSION_DEFLATE: case TIFFConstants.COMPRESSION_ADOBE_DEFLATE: case TIFFConstants.COMPRESSION_OJPEG: case TIFFConstants.COMPRESSION_JPEG: break; default: throw new ArgumentException("The compression " + compression + " is not supported."); } int photometric = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PHOTOMETRIC); switch (photometric) { case TIFFConstants.PHOTOMETRIC_MINISWHITE: case TIFFConstants.PHOTOMETRIC_MINISBLACK: case TIFFConstants.PHOTOMETRIC_RGB: case TIFFConstants.PHOTOMETRIC_SEPARATED: case TIFFConstants.PHOTOMETRIC_PALETTE: break; default: if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) throw new ArgumentException("The photometric " + photometric + " is not supported."); break; } float rotation = 0; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ORIENTATION)) { int rot = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ORIENTATION); if (rot == TIFFConstants.ORIENTATION_BOTRIGHT || rot == TIFFConstants.ORIENTATION_BOTLEFT) rotation = (float)Math.PI; else if (rot == TIFFConstants.ORIENTATION_LEFTTOP || rot == TIFFConstants.ORIENTATION_LEFTBOT) rotation = (float)(Math.PI / 2.0); else if (rot == TIFFConstants.ORIENTATION_RIGHTTOP || rot == TIFFConstants.ORIENTATION_RIGHTBOT) rotation = -(float)(Math.PI / 2.0); } if (dir.IsTagPresent(TIFFConstants.TIFFTAG_PLANARCONFIG) && dir.GetFieldAsLong(TIFFConstants.TIFFTAG_PLANARCONFIG) == TIFFConstants.PLANARCONFIG_SEPARATE) throw new ArgumentException("Planar images are not supported."); if (dir.IsTagPresent(TIFFConstants.TIFFTAG_EXTRASAMPLES)) throw new ArgumentException("Extra samples are not supported."); int samplePerPixel = 1; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL)) // 1,3,4 samplePerPixel = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_SAMPLESPERPIXEL); int bitsPerSample = 1; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_BITSPERSAMPLE)) bitsPerSample = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_BITSPERSAMPLE); switch (bitsPerSample) { case 1: case 2: case 4: case 8: break; default: throw new ArgumentException("Bits per sample " + bitsPerSample + " is not supported."); } Image img = null; int h = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGELENGTH); int w = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_IMAGEWIDTH); int dpiX = 0; int dpiY = 0; int resolutionUnit = TIFFConstants.RESUNIT_INCH; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_RESOLUTIONUNIT)) resolutionUnit = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_RESOLUTIONUNIT); dpiX = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_XRESOLUTION), resolutionUnit); dpiY = GetDpi(dir.GetField(TIFFConstants.TIFFTAG_YRESOLUTION), resolutionUnit); int fillOrder = 1; bool reverse = false; TIFFField fillOrderField = dir.GetField(TIFFConstants.TIFFTAG_FILLORDER); if (fillOrderField != null) fillOrder = fillOrderField.GetAsInt(0); reverse = (fillOrder == TIFFConstants.FILLORDER_LSB2MSB); int rowsStrip = h; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ROWSPERSTRIP)) //another hack for broken tiffs rowsStrip = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_ROWSPERSTRIP); if (rowsStrip <= 0 || rowsStrip > h) rowsStrip = h; long[] offset = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPOFFSETS); long[] size = GetArrayLongShort(dir, TIFFConstants.TIFFTAG_STRIPBYTECOUNTS); if ((size == null || (size.Length == 1 && (size[0] == 0 || size[0] + offset[0] > s.Length))) && h == rowsStrip) { // some TIFF producers are really lousy, so... size = new long[]{s.Length - (int)offset[0]}; } if (compression == TIFFConstants.COMPRESSION_LZW) { TIFFField predictorField = dir.GetField(TIFFConstants.TIFFTAG_PREDICTOR); if (predictorField != null) { predictor = predictorField.GetAsInt(0); if (predictor != 1 && predictor != 2) { throw new Exception("Illegal value for Predictor in TIFF file."); } if (predictor == 2 && bitsPerSample != 8) { throw new Exception(bitsPerSample + "-bit samples are not supported for Horizontal differencing Predictor."); } } lzwDecoder = new TIFFLZWDecoder(w, predictor, samplePerPixel); } int rowsLeft = h; MemoryStream stream = null; ZOutputStream zip = null; CCITTG4Encoder g4 = null; if (bitsPerSample == 1 && samplePerPixel == 1) { g4 = new CCITTG4Encoder(w); } else { stream = new MemoryStream(); if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) zip = new ZOutputStream(stream); } if (compression == TIFFConstants.COMPRESSION_OJPEG) { // Assume that the TIFFTAG_JPEGIFBYTECOUNT tag is optional, since it's obsolete and // is often missing if ((!dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFOFFSET))) { throw new IOException("Missing tag(s) for OJPEG compression."); } int jpegOffset = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFOFFSET); int jpegLength = s.Length - jpegOffset; if (dir.IsTagPresent(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT)) { jpegLength = (int)dir.GetFieldAsLong(TIFFConstants.TIFFTAG_JPEGIFBYTECOUNT) + (int)size[0]; } byte[] jpeg = new byte[Math.Min(jpegLength, s.Length - jpegOffset)]; int posFilePointer = s.FilePointer; posFilePointer += jpegOffset; s.Seek(posFilePointer); s.ReadFully(jpeg); img = new Jpeg(jpeg); } else if (compression == TIFFConstants.COMPRESSION_JPEG) { if (size.Length > 1) throw new IOException("Compression JPEG is only supported with a single strip. This image has " + size.Length + " strips."); byte[] jpeg = new byte[(int)size[0]]; s.Seek(offset[0]); s.ReadFully(jpeg); img = new Jpeg(jpeg); } else { for (int k = 0; k < offset.Length; ++k) { byte[] im = new byte[(int)size[k]]; s.Seek(offset[k]); s.ReadFully(im); int height = Math.Min(rowsStrip, rowsLeft); byte[] outBuf = null; if (compression != TIFFConstants.COMPRESSION_NONE) outBuf = new byte[(w * bitsPerSample * samplePerPixel + 7) / 8 * height]; if (reverse) TIFFFaxDecoder.ReverseBits(im); switch (compression) { case TIFFConstants.COMPRESSION_DEFLATE: case TIFFConstants.COMPRESSION_ADOBE_DEFLATE: Inflate(im, outBuf); break; case TIFFConstants.COMPRESSION_NONE: outBuf = im; break; case TIFFConstants.COMPRESSION_PACKBITS: DecodePackbits(im, outBuf); break; case TIFFConstants.COMPRESSION_LZW: lzwDecoder.Decode(im, outBuf, height); break; } if (bitsPerSample == 1 && samplePerPixel == 1) { g4.Fax4Encode(outBuf, height); } else { zip.Write(outBuf, 0, outBuf.Length); } rowsLeft -= rowsStrip; } if (bitsPerSample == 1 && samplePerPixel == 1) { img = Image.GetInstance(w, h, false, Image.CCITTG4, photometric == TIFFConstants.PHOTOMETRIC_MINISBLACK ? Image.CCITT_BLACKIS1 : 0, g4.Close()); } else { zip.Close(); img = Image.GetInstance(w, h, samplePerPixel, bitsPerSample, stream.ToArray()); img.Deflated = true; } } img.SetDpi(dpiX, dpiY); if (compression != TIFFConstants.COMPRESSION_OJPEG && compression != TIFFConstants.COMPRESSION_JPEG) { if (dir.IsTagPresent(TIFFConstants.TIFFTAG_ICCPROFILE)) { try { TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_ICCPROFILE); ICC_Profile icc_prof = ICC_Profile.GetInstance(fd.GetAsBytes()); if (samplePerPixel == icc_prof.NumComponents) img.TagICC = icc_prof; } catch { //empty } } if (dir.IsTagPresent(TIFFConstants.TIFFTAG_COLORMAP)) { TIFFField fd = dir.GetField(TIFFConstants.TIFFTAG_COLORMAP); char[] rgb = fd.GetAsChars(); byte[] palette = new byte[rgb.Length]; int gColor = rgb.Length / 3; int bColor = gColor * 2; for (int k = 0; k < gColor; ++k) { palette[k * 3] = (byte)(rgb[k] >> 8); palette[k * 3 + 1] = (byte)(rgb[k + gColor] >> 8); palette[k * 3 + 2] = (byte)(rgb[k + bColor] >> 8); } PdfArray indexed = new PdfArray(); indexed.Add(PdfName.INDEXED); indexed.Add(PdfName.DEVICERGB); indexed.Add(new PdfNumber(gColor - 1)); indexed.Add(new PdfString(palette)); PdfDictionary additional = new PdfDictionary(); additional.Put(PdfName.COLORSPACE, indexed); img.Additional = additional; } img.OriginalType = Image.ORIGINAL_TIFF; } if (photometric == TIFFConstants.PHOTOMETRIC_MINISWHITE) img.Inverted = true; if (rotation != 0) img.InitialRotation = rotation; return img; }
/** Gets the number of pages the TIFF document has. * @param s the file source * @return the number of pages */ public static int GetNumberOfPages(RandomAccessFileOrArray s) { return TIFFDirectory.GetNumDirectories(s); }