public static IBuffer Extract(IBuffer buffer, PdfDataObject filter, PdfDirectObject parameters) { if (filter is PdfName) // Single filter. { buffer = buffer.Extract(Filter.Get((PdfName)filter), (PdfDictionary)parameters); } else // Multiple filters. { var filterIterator = ((PdfArray)filter).GetEnumerator(); var parametersIterator = (parameters != null ? ((PdfArray)parameters).GetEnumerator() : null); while (filterIterator.MoveNext()) { PdfDictionary filterParameters; if (parametersIterator == null) { filterParameters = null; } else { parametersIterator.MoveNext(); filterParameters = (PdfDictionary)Resolve(parametersIterator.Current); } buffer = buffer.Extract(Filter.Get((PdfName)Resolve(filterIterator.Current)), filterParameters); } } return(buffer); }
/** * <summary>Wraps the specified base object into a pattern object.</summary> * <param name="baseObject">Base object of a pattern object.</param> * <returns>Pattern object corresponding to the base object.</returns> */ public static Pattern Wrap(PdfDirectObject baseObject) { if (baseObject == null) { return(null); } if (baseObject.Wrapper is Pattern pattern) { return(pattern); } if (baseObject is PdfReference reference && reference.DataObject?.Wrapper is Pattern referencePattern) { baseObject.Wrapper = referencePattern; return(referencePattern); } PdfDataObject dataObject = baseObject.Resolve(); PdfDictionary dictionary = TryGetDictionary(dataObject); int patternType = ((PdfInteger)dictionary[PdfName.PatternType]).RawValue; switch (patternType) { case PatternType1: return(new TilingPattern(baseObject)); case PatternType2: return(new ShadingPattern(baseObject)); default: throw new NotSupportedException("Pattern type " + patternType + " unknown."); } }
public static void Decode(IBuffer buffer, PdfDataObject filter, PdfDirectObject parameters) { if (filter is PdfName) // Single filter. { buffer.Decode(Filter.Get((PdfName)filter), (PdfDictionary)parameters); } else // Multiple filters. { IEnumerator <PdfDirectObject> filterIterator = ((PdfArray)filter).GetEnumerator(); IEnumerator <PdfDirectObject> parametersIterator = (parameters != null ? ((PdfArray)parameters).GetEnumerator() : null); while (filterIterator.MoveNext()) { PdfDictionary filterParameters; if (parametersIterator == null) { filterParameters = null; } else { parametersIterator.MoveNext(); filterParameters = (PdfDictionary)Resolve(parametersIterator.Current); } buffer.Decode(Filter.Get((PdfName)Resolve(filterIterator.Current)), filterParameters); } } }
public ContentStream( PdfDataObject baseDataObject ) { this.baseDataObject = baseDataObject; MoveNextStream(); }
/** * <summary>Instantiates an existing file reference.</summary> * <param name="baseObject">Base object.</param> */ public static FileSpecification Wrap(PdfDirectObject baseObject) { if (baseObject == null) { return(null); } if (baseObject.Wrapper is FileSpecification specification) { return(specification); } if (baseObject is PdfReference pdfReference && pdfReference.DataObject?.Wrapper is FileSpecification referenceSpecification) { baseObject.Wrapper = referenceSpecification; return(referenceSpecification); } PdfDataObject baseDataObject = baseObject.Resolve(); if (baseDataObject is PdfString) { return(new SimpleFileSpecification(baseObject)); } else if (baseDataObject is PdfDictionary) { return(new FullFileSpecification(baseObject)); } else { return(null); } }
/** * <summary>Gets the positional information resulting from the collection evaluation.</summary> * <param name="evaluator">Expression used to evaluate the positional matching.</param> */ private int Evaluate( EvaluateNode evaluateNode ) { /* * NOTE: Layer hierarchies are represented through a somewhat flatten structure which needs * to be evaluated in order to match nodes in their actual place. */ PdfArray baseDataObject = BaseDataObject; int nodeIndex = -1; bool groupAllowed = true; for ( int baseIndex = 0, baseLength = base.Count; baseIndex < baseLength; baseIndex++ ) { PdfDataObject itemDataObject = baseDataObject.Resolve(baseIndex); if (itemDataObject is PdfDictionary || (itemDataObject is PdfArray && groupAllowed)) { nodeIndex++; int evaluation = evaluateNode(nodeIndex, baseIndex); if (evaluation > -1) { return(evaluation); } } groupAllowed = !(itemDataObject is PdfDictionary); } return(evaluateNode(nodeIndex, -1)); }
protected override Destination Wrap( PdfDirectObject baseObject, PdfIndirectObject container, PdfString name ) { /* * NOTE: A named destination may be either an array defining the destination, * or a dictionary with a D entry whose value is such an array [PDF:1.6:8.2.1]. */ PdfDirectObject destinationObject; { PdfDataObject baseDataObject = File.Resolve(baseObject); if (baseDataObject is PdfDictionary) { destinationObject = ((PdfDictionary)baseDataObject)[PdfName.D]; } else { destinationObject = baseObject; } } return(Destination.Wrap( destinationObject, baseObject is PdfReference ? ((PdfReference)baseObject).IndirectObject : container, name )); }
public xObjects::XObject ToXObject( Document context ) { xObjects::FormXObject form; { form = new xObjects::FormXObject(context, Box); form.Resources = (Resources)(context.Equals(Document) ? Resources // Same document: reuses the existing resources. : Resources.Clone(context) // Alien document: clones the resources. ); // Body (contents). { IBuffer formBody = form.BaseDataObject.Body; PdfDataObject contentsDataObject = BaseDataObject.Resolve(PdfName.Contents); if (contentsDataObject is PdfStream) { formBody.Append(((PdfStream)contentsDataObject).Body); } else { foreach (PdfDirectObject contentStreamObject in (PdfArray)contentsDataObject) { formBody.Append(((PdfStream)contentStreamObject.Resolve()).Body); } } } } return(form); }
/** * <summary>Gets the data size of the specified object expressed in bytes.</summary> * <param name="object">Data object whose size has to be calculated.</param> * <param name="visitedReferences">References to data objects excluded from calculation. * This set is useful, for example, to avoid recalculating the data size of shared resources. * During the operation, this set is populated with references to visited data objects.</param> * <param name="isRoot">Whether this data object represents the page root.</param> */ private static long GetSize( PdfDirectObject obj, HashSet <PdfReference> visitedReferences, bool isRoot ) { long dataSize = 0; { PdfDataObject dataObject = PdfObject.Resolve(obj); // 1. Evaluating the current object... if (obj is PdfReference) { PdfReference reference = (PdfReference)obj; if (visitedReferences.Contains(reference)) { return(0); // Avoids circular references. } if (dataObject is PdfDictionary && PdfName.Page.Equals(((PdfDictionary)dataObject)[PdfName.Type]) && !isRoot) { return(0); // Avoids references to other pages. } visitedReferences.Add(reference); // Calculate the data size of the current object! IOutputStream buffer = new Buffer(); reference.IndirectObject.WriteTo(buffer, reference.File); dataSize += buffer.Length; } // 2. Evaluating the current object's children... ICollection <PdfDirectObject> values = null; { if (dataObject is PdfStream) { dataObject = ((PdfStream)dataObject).Header; } if (dataObject is PdfDictionary) { values = ((PdfDictionary)dataObject).Values; } else if (dataObject is PdfArray) { values = (PdfArray)dataObject; } } if (values != null) { // Calculate the data size of the current object's children! foreach (PdfDirectObject value in values) { dataSize += GetSize(value, visitedReferences, false); } } } return(dataSize); }
/** * <summary>Wraps the specified base object into a pattern object.</summary> * <param name="baseObject">Base object of a pattern object.</param> * <param name="container">Indirect object possibly containing the pattern base object.</param> * <returns>Pattern object corresponding to the base object.</returns> */ public static Pattern Wrap( PdfDirectObject baseObject, PdfIndirectObject container ) { if (baseObject == null) { return(null); } PdfDataObject dataObject = File.Resolve(baseObject); PdfDictionary dictionary = GetDictionary(dataObject); int patternType = ((PdfInteger)dictionary[PdfName.PatternType]).RawValue; switch (patternType) { case PatternType1: return(new TilingPattern(baseObject, container)); case PatternType2: return(new ShadingPattern(baseObject, container)); default: throw new NotSupportedException("Pattern type " + patternType + " unknown."); } }
public IUILayerNode Wrap(PdfDirectObject baseObject) { if (baseObject == null) { return(null); } if (baseObject.Wrapper is IUILayerNode node) { return(node); } PdfDataObject baseDataObject = baseObject.Resolve(); if (baseDataObject is PdfDictionary) { return(Wrap <Layer>(baseObject)); } else if (baseDataObject is PdfArray) { return(Wrap <LayerCollection>(baseObject)); } else { throw new ArgumentException(baseDataObject.GetType().Name + " is NOT a valid layer node."); } }
public Layer this[ int index ] { get { PdfDataObject baseDataObject = BaseDataObject; if (baseDataObject == null) // No layer. { return(null); } else if (baseDataObject is PdfDictionary) // Single layer. { if (index != 0) { throw new IndexOutOfRangeException(); } return(Layer.Wrap(BaseObject)); } else // Multiple layers. { return(Layer.Wrap(((PdfArray)baseDataObject)[index])); } } set { EnsureArray()[index] = value.BaseObject; } }
internal Parser( PdfDataObject contentStream ) { this.contentStream = contentStream; MoveNextStream(); }
public ObjectEntry( int offset, FileParser parser ) : this(parser) { this.dataObject = null; this.offset = offset; }
public ObjectEntry( PdfDataObject dataObject, FileParser parser ) : this(parser) { this.dataObject = dataObject; this.offset = -1; // Undefined -- to set on stream serialization. }
/** * <summary>Finds the location of the sublayers object in the specified configuration; in case no * sublayers object is associated to this object, its virtual position is indicated.</summary> * <param name="configuration">Configuration context.</param> * <returns><code>null</code>, if this layer is outside the specified configuration.</returns> */ private LayersLocation FindLayersLocation( LayerConfiguration configuration ) { /* * NOTE: As layers are only weakly tied to configurations, their sublayers have to be sought * through the configuration structure tree. */ PdfDirectObject levelLayerObject = null; PdfArray levelObject = configuration.UILayers.BaseDataObject; IEnumerator <PdfDirectObject> levelIterator = levelObject.GetEnumerator(); Stack <object[]> levelIterators = new Stack <object[]>(); PdfDirectObject thisObject = BaseObject; PdfDirectObject currentLayerObject = null; while (true) { if (!levelIterator.MoveNext()) { if (levelIterators.Count == 0) { break; } object[] levelItems = levelIterators.Pop(); levelObject = (PdfArray)levelItems[0]; levelIterator = (IEnumerator <PdfDirectObject>)levelItems[1]; levelLayerObject = (PdfDirectObject)levelItems[2]; currentLayerObject = null; } else { PdfDirectObject nodeObject = levelIterator.Current; PdfDataObject nodeDataObject = PdfObject.Resolve(nodeObject); if (nodeDataObject is PdfDictionary) { if (nodeObject.Equals(thisObject)) { /* * NOTE: Sublayers are expressed as an array immediately following the parent layer node. */ return(new LayersLocation(levelLayerObject, levelObject, levelObject.IndexOf(thisObject) + 1, levelIterators)); } currentLayerObject = nodeObject; } else if (nodeDataObject is PdfArray) { levelIterators.Push(new object[] { levelObject, levelIterator, levelLayerObject }); levelObject = (PdfArray)nodeDataObject; levelIterator = levelObject.GetEnumerator(); levelLayerObject = currentLayerObject; currentLayerObject = null; } } } return(null); }
/** * <summary>Ensures that the specified object is decontextualized from this object.</summary> * <param name="obj">Object to decontextualize from this object.</param> * <seealso cref="Include(PdfDataObject)"/> */ internal void Exclude( PdfDataObject obj ) { if (obj != null) { obj.Parent = null; } }
public void Flush( ) { // Ensuring that there's room for the new content chunks inside the page's content stream... /* * NOTE: This specialized stamper is optimized for content insertion without modifying * existing content representations, leveraging the peculiar feature of page structures * to express their content streams as arrays of data streams. */ PdfArray streams; { PdfDirectObject contentsObject = page.BaseDataObject[PdfName.Contents]; PdfDataObject contentsDataObject = File.Resolve(contentsObject); // Single data stream? if (contentsDataObject is PdfStream) { /* * NOTE: Content stream MUST be expressed as an array of data streams in order to host * background- and foreground-stamped contents. */ streams = new PdfArray(); streams.Add(contentsObject); page.BaseDataObject[PdfName.Contents] = streams; page.Update(); // Fundamental to override original page contents collection. } else { streams = (PdfArray)contentsDataObject; if (!File.Update(contentsObject)) { page.Update(); } // Fundamental to override original page contents collection. } } // Background. // Serialize the content! background.Flush(); // Insert the serialized content into the page's content stream! streams.Insert( 0, (PdfReference)background.Scanner.Contents.BaseObject ); // Foreground. // Serialize the content! foreground.Flush(); // Append the serialized content into the page's content stream! streams.Add( (PdfReference)foreground.Scanner.Contents.BaseObject ); }
/** * <summary>Registers an <i>internal</i> data object.</summary> * <remarks>To register an external indirect object, use <see * cref="AddExternal(PdfIndirectObject)"/>.</remarks> * <returns>Indirect object corresponding to the registered data object.</returns> */ public PdfIndirectObject Add(PdfDataObject obj) { // Register a new indirect object wrapping the data object inside! PdfIndirectObject indirectObject = new PdfIndirectObject( file, obj, new XRefEntry(++lastObjectNumber, 0)); modifiedObjects[lastObjectNumber] = indirectObject; return(indirectObject); }
/** * <param name="file">Associated file.</param> * <param name="dataObject"> * <para>Data object associated to the indirect object. It MUST be</para> * <list type="bullet"> * <item><code>null</code>, if the indirect object is original or free.</item> * <item>NOT <code>null</code>, if the indirect object is new and in-use.</item> * </list> * </param> * <param name="xrefEntry">Cross-reference entry associated to the indirect object. If the * indirect object is new, its offset field MUST be set to 0.</param> */ internal PdfIndirectObject( File file, PdfDataObject dataObject, XRefEntry xrefEntry ) { this.file = file; this.dataObject = Include(dataObject); XrefEntry = xrefEntry; original = xrefEntry.Offset >= 0; reference = new PdfReference(this); }
/** * <summary>Gets a pattern's dictionary.</summary> * <param name="patternDataObject">Pattern data object.</param> */ private static PdfDictionary GetDictionary( PdfDataObject patternDataObject ) { if (patternDataObject is PdfDictionary) { return((PdfDictionary)patternDataObject); } else // MUST be PdfStream. { return(((PdfStream)patternDataObject).Header); } }
/** <summary>Gets the character map extracted from the given encoding object.</summary> <param name="encodingObject">Encoding object.</param> */ public static IDictionary<ByteArray,int> Get( PdfDataObject encodingObject ) { if(encodingObject == null) return null; if(encodingObject is PdfName) // Predefined CMap. return Get((PdfName)encodingObject); else if(encodingObject is PdfStream) // Embedded CMap file. return Get((PdfStream)encodingObject); else throw new NotSupportedException("Unknown encoding object type: " + encodingObject.GetType().Name); }
/** * <summary>Ensures that the specified object is contextualized into this object.</summary> * <param name="obj">Object to contextualize into this object; if it is already contextualized * into another object, it will be cloned to preserve its previous association.</param> * <returns>Contextualized object.</returns> * <seealso cref="Exclude(PdfDataObject)"/> */ internal PdfDataObject Include( PdfDataObject obj ) { if (obj != null) { if (obj.Parent != null) { obj = (PdfDataObject)obj.Clone(); } obj.Parent = this; } return(obj); }
protected override void LoadEncoding( ) { //FIXME: consolidate with Type1Font and TrueTypeFont! // Encoding. if (this.codes == null) { IDictionary <ByteArray, int> codes; PdfDataObject encodingObject = BaseDataObject.Resolve(PdfName.Encoding); if (encodingObject == null) // Native encoding. { codes = GetNativeEncoding(); } else if (encodingObject is PdfName) // Predefined encoding. { codes = Encoding.Get((PdfName)encodingObject).GetCodes(); } else // Custom encoding. { PdfDictionary encodingDictionary = (PdfDictionary)encodingObject; // 1. Base encoding. PdfName baseEncodingName = (PdfName)encodingDictionary[PdfName.BaseEncoding]; if (baseEncodingName == null) // Native base encoding. { codes = GetNativeEncoding(); } else // Predefined base encoding. { codes = Encoding.Get(baseEncodingName).GetCodes(); } // 2. Differences. LoadEncodingDifferences(encodingDictionary, codes); } this.codes = new BiDictionary <ByteArray, int>(codes); } // Glyph indexes. if (glyphIndexes == null) { glyphIndexes = new Dictionary <int, int>(); foreach (KeyValuePair <ByteArray, int> codeEntry in codes) { glyphIndexes[codeEntry.Value] = ConvertUtils.ByteArrayToInt(codeEntry.Key.Data); } } }
public int IndexOf(Layer item) { PdfDataObject baseDataObject = BaseDataObject; if (baseDataObject == null) // No layer. { return(-1); } else if (baseDataObject is PdfDictionary) // Single layer. { return(item.BaseObject.Equals(BaseObject) ? 0 : -1); } else // Multiple layers. { return(((PdfArray)baseDataObject).IndexOf(item.BaseObject)); } }
public bool Contains(Layer item) { PdfDataObject baseDataObject = BaseDataObject; if (baseDataObject == null) // No layer. { return(false); } else if (baseDataObject is PdfDictionary) // Single layer. { return(item.BaseObject.Equals(BaseObject)); } else // Multiple layers. { return(((PdfArray)baseDataObject).Contains(item.BaseObject)); } }
/** * <summary>Gets the Javascript script from the specified base data object.</summary> */ internal static string GetScript(PdfDictionary baseDataObject, PdfName key) { PdfDataObject scriptObject = baseDataObject.Resolve(key); if (scriptObject == null) { return(null); } else if (scriptObject is PdfTextString) { return(((PdfTextString)scriptObject).StringValue); } else { bytes::IBuffer scriptBuffer = ((PdfStream)scriptObject).Body; return(scriptBuffer.GetString(0, (int)scriptBuffer.Length)); } }
public xObjects::XObject ToXObject( Document context ) { File contextFile = context.File; xObjects::FormXObject form = new xObjects::FormXObject(context); PdfStream formStream = form.BaseDataObject; // Header. { PdfDictionary formHeader = formStream.Header; // Bounding box. formHeader[PdfName.BBox] = (PdfDirectObject)GetInheritableAttribute(PdfName.MediaBox).Clone(contextFile); // Resources. { PdfDirectObject resourcesObject = GetInheritableAttribute(PdfName.Resources); // Same document? /* NOTE: Try to reuse the resource dictionary whenever possible. */ formHeader[PdfName.Resources] = (context.Equals(Document) ? resourcesObject : (PdfDirectObject)resourcesObject.Clone(contextFile)); } } // Body (contents). { IBuffer formBody = formStream.Body; PdfDataObject contentsDataObject = BaseDataObject.Resolve(PdfName.Contents); if (contentsDataObject is PdfStream) { formBody.Append(((PdfStream)contentsDataObject).Body); } else { foreach (PdfDirectObject contentStreamObject in (PdfArray)contentsDataObject) { formBody.Append(((PdfStream)File.Resolve(contentStreamObject)).Body); } } } return(form); }
public override void Run( ) { // 1. Opening the PDF file... string filePath = PromptFileChoice("Please select a PDF file"); using (files::File file = new files::File(filePath)) { // 2. Iterating through the indirect object collection... int index = 0; foreach (PdfIndirectObject indirectObject in file.IndirectObjects) { // Get the data object associated to the indirect object! PdfDataObject dataObject = indirectObject.DataObject; // Is this data object a stream? if (dataObject is PdfStream) { PdfDictionary header = ((PdfStream)dataObject).Header; // Is this stream an image? if (header.ContainsKey(PdfName.Type) && header[PdfName.Type].Equals(PdfName.XObject) && header[PdfName.Subtype].Equals(PdfName.Image)) { // Which kind of image? if (header[PdfName.Filter].Equals(PdfName.DCTDecode)) // JPEG image. { // Get the image data (keeping it encoded)! IBuffer body = ((PdfStream)dataObject).GetBody(false); // Export the image! ExportImage( body, "ImageExtractionSample_" + (index++) + ".jpg" ); } else // Unsupported image. { Console.WriteLine("Image XObject " + indirectObject.Reference + " couldn't be extracted (filter: " + header[PdfName.Filter] + ")"); } } } } } }
/** * <summary>Register an <b>internal data object</b>.</summary> * <remarks> * Alternatives: * <list type="bullet"> * <item>To register a <b>modified internal indirect object</b>, use * <see cref="this"> indexer</see>.</item> * <item>To register an <b>external indirect object</b>, use * <see cref="Add(PdfIndirectObject)"/>.</item> * </list> * </remarks> */ public PdfIndirectObject Add( PdfDataObject obj ) { // Register a new indirect object wrapping the data object inside! lastObjectNumber++; PdfIndirectObject indirectObject = modifiedObjects[lastObjectNumber] = new PdfIndirectObject( file, obj, new XRefEntry( lastObjectNumber, 0, 0, XRefEntry.UsageEnum.InUse ) ); return(indirectObject); }