#region PDFsharp - A .NET library for processing PDF // // Authors: // Stefan Lange // // Copyright (c) 2005-2017 empira Software GmbH, Cologne Area (Germany) // // http://www.pdfsharp.com // http://sourceforge.net/projects/pdfsharp // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included // in all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. #endregion using System; using System.Diagnostics; using System.IO; using PdfSharp.Pdf.IO; namespace PdfSharp.Pdf.Advanced { /// /// Represents an object stream that contains compressed objects. /// PDF 1.5. /// public class PdfObjectStream : PdfDictionary { // Reference: 3.4.6 Object Streams / Page 100 /// /// Initializes a new instance of the class. /// public PdfObjectStream(PdfDocument document) : base(document) { #if DEBUG && CORE if (Internal.PdfDiagnostics.TraceObjectStreams) { Debug.WriteLine("PdfObjectStream(document) created."); } #endif } /// /// Initializes a new instance from an existing dictionary. Used for object type transformation. /// internal PdfObjectStream(PdfDictionary dict) : base(dict) { int n = Elements.GetInteger(Keys.N); int first = Elements.GetInteger(Keys.First); Stream.TryUnfilter(); Parser parser = new Parser(null, new MemoryStream(Stream.Value)); _header = parser.ReadObjectStreamHeader(n, first); #if DEBUG && CORE if (Internal.PdfDiagnostics.TraceObjectStreams) { Debug.WriteLine(String.Format("PdfObjectStream(document) created. Header item count: {0}", _header.GetLength(0))); } #endif } /// /// Reads the compressed object with the specified index. /// internal void ReadReferences(PdfCrossReferenceTable xrefTable) { ////// Create parser for stream. ////Parser parser = new Parser(_document, new MemoryStream(Stream.Value)); for (int idx = 0; idx < _header.Length; idx++) { int objectNumber = _header[idx][0]; int offset = _header[idx][1]; PdfObjectID objectID = new PdfObjectID(objectNumber); // HACK: -1 indicates compressed object. PdfReference iref = new PdfReference(objectID, -1); ////iref.ObjectID = objectID; ////iref.Value = xrefStream; if (!xrefTable.Contains(iref.ObjectID)) { xrefTable.Add(iref); } else { GetType(); } } } /// /// Reads the compressed object with the specified index. /// internal PdfReference ReadCompressedObject(int index) { Parser parser = new Parser(_document, new MemoryStream(Stream.Value)); int objectNumber = _header[index][0]; int offset = _header[index][1]; return parser.ReadCompressedObject(objectNumber, offset); } /// /// N pairs of integers. /// The first integer represents the object number of the compressed object. /// The second integer represents the absolute offset of that object in the decoded stream, /// i.e. the byte offset plus First entry. /// private readonly int[][] _header; // Reference: Page 102 /// /// Predefined keys common to all font dictionaries. /// public class Keys : PdfStream.Keys { // Reference: TABLE 3.14 Additional entries specific to an object stream dictionary / Page 101 /// /// (Required) The type of PDF object that this dictionary describes; /// must be ObjStmfor an object stream. /// [KeyInfo(KeyType.Name | KeyType.Required, FixedValue = "ObjStm")] public const string Type = "/Type"; /// /// (Required) The number of compressed objects in the stream. /// [KeyInfo(KeyType.Integer | KeyType.Required)] public const string N = "/N"; /// /// (Required) The byte offset (in the decoded stream) of the first /// compressed object. /// [KeyInfo(KeyType.Integer | KeyType.Required)] public const string First = "/First"; /// /// (Optional) A reference to an object stream, of which the current object /// stream is considered an extension. Both streams are considered part of /// a collection of object streams (see below). A given collection consists /// of a set of streams whose Extendslinks form a directed acyclic graph. /// [KeyInfo(KeyType.Stream | KeyType.Optional)] public const string Extends = "/Extends"; } } #if DEBUG && CORE static class ObjectStreamDiagnostics { public static void AddObjectStreamXRef() { } } #endif }