Exemple #1
0
 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);
 }
Exemple #2
0
        /**
         * <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.");
            }
        }
Exemple #3
0
 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);
         }
     }
 }
Exemple #4
0
 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);
            }
        }
Exemple #6
0
        /**
         * <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
                       ));
        }
Exemple #8
0
        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);
        }
Exemple #9
0
        /**
         * <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);
        }
Exemple #10
0
        /**
         * <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.");
            }
        }
Exemple #11
0
            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; }
            }
Exemple #13
0
        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.
 }
Exemple #16
0
        /**
         * <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;
     }
 }
Exemple #18
0
        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
                );
        }
Exemple #19
0
        /**
         * <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);
        }
Exemple #21
0
 /**
  * <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);
     }
 }
Exemple #22
0
    /**
      <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);
                }
            }
        }
Exemple #25
0
            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));
                }
            }
Exemple #26
0
            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));
                }
            }
Exemple #27
0
        /**
         * <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));
            }
        }
Exemple #28
0
        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);
        }