示例#1
0
        /// <summary>Use this method to set the XMP Metadata for each page.</summary>
        /// <param name="xmpMetadata">The xmpMetadata to set.</param>
        /// <exception cref="System.IO.IOException"/>
        public virtual void SetXmpMetadata(byte[] xmpMetadata)
        {
            PdfStream xmp = ((PdfStream) new PdfStream().MakeIndirect(GetDocument()));

            xmp.GetOutputStream().Write(xmpMetadata);
            xmp.Put(PdfName.Type, PdfName.Metadata);
            xmp.Put(PdfName.Subtype, PdfName.XML);
            GetPdfObject().Put(PdfName.Metadata, xmp);
        }
示例#2
0
        public virtual void SoundActionTest()
        {
            String      fileName = "soundActionTest.pdf";
            PdfDocument document = CreateDocument(new PdfWriter(destinationFolder + fileName), false);
            Stream      @is      = new FileStream(sourceFolder + "sample.aif", FileMode.Open, FileAccess.Read);
            PdfStream   sound1   = new PdfStream(document, @is);

            sound1.Put(PdfName.R, new PdfNumber(32117));
            sound1.Put(PdfName.E, PdfName.Signed);
            sound1.Put(PdfName.B, new PdfNumber(16));
            sound1.Put(PdfName.C, new PdfNumber(1));
            document.GetPage(2).SetAdditionalAction(PdfName.O, PdfAction.CreateSound(sound1));
            document.Close();
            NUnit.Framework.Assert.IsNull(new CompareTool().CompareByContent(destinationFolder + fileName, sourceFolder
                                                                             + "cmp_" + fileName, destinationFolder, "diff_"));
        }
示例#3
0
        public virtual void CustomMemoryHandlerSingleTest()
        {
            MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler();

            handler.SetMaxSizeOfSingleDecompressedPdfStream(1000);
            PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties(
                                                                        ).SetMemoryLimitsAwareHandler(handler)), new PdfWriter(new MemoryStream()));
            PdfStream stream = pdfDocument.GetFirstPage().GetContentStream(0);

            byte[]   b     = stream.GetBytes(false);
            PdfArray array = new PdfArray();

            stream.Put(PdfName.Filter, array);
            NUnit.Framework.Assert.AreEqual(51, PdfReader.DecodeBytes(b, stream).Length);
            array.Add(PdfName.Fl);
            NUnit.Framework.Assert.AreEqual(40, PdfReader.DecodeBytes(b, stream).Length);
            array.Add(PdfName.Fl);
            NUnit.Framework.Assert.AreEqual(992, PdfReader.DecodeBytes(b, stream).Length);
            array.Add(PdfName.Fl);
            String expectedExceptionMessage = PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed;
            String thrownExceptionMessage   = null;

            try {
                PdfReader.DecodeBytes(b, stream);
            }
            catch (MemoryLimitsAwareException e) {
                thrownExceptionMessage = e.Message;
            }
            NUnit.Framework.Assert.AreEqual(expectedExceptionMessage, thrownExceptionMessage);
        }
示例#4
0
        protected internal virtual void UpdateCompressionFilter(PdfStream pdfStream)
        {
            PdfObject filter = pdfStream.Get(PdfName.Filter);

            if (filter == null)
            {
                pdfStream.Put(PdfName.Filter, PdfName.FlateDecode);
            }
            else
            {
                PdfArray filters = new PdfArray();
                filters.Add(PdfName.FlateDecode);
                if (filter is PdfArray)
                {
                    filters.AddAll((PdfArray)filter);
                }
                else
                {
                    filters.Add(filter);
                }
                PdfObject decodeParms = pdfStream.Get(PdfName.DecodeParms);
                if (decodeParms != null)
                {
                    if (decodeParms is PdfDictionary)
                    {
                        PdfArray array = new PdfArray();
                        array.Add(new PdfNull());
                        array.Add(decodeParms);
                        pdfStream.Put(PdfName.DecodeParms, array);
                    }
                    else
                    {
                        if (decodeParms is PdfArray)
                        {
                            ((PdfArray)decodeParms).Add(0, new PdfNull());
                        }
                        else
                        {
                            throw new PdfException(PdfException.DecodeParameterType1IsNotSupported).SetMessageParams(decodeParms.GetType
                                                                                                                         ().ToString());
                        }
                    }
                }
                pdfStream.Put(PdfName.Filter, filters);
            }
        }
        public virtual void TestJPXDecodeFilter()
        {
            PdfStream pdfStream = new PdfStream(FLATE_DECODED_BYTES);

            pdfStream.Put(PdfName.Filter, new PdfArray(JavaUtil.ArraysAsList((PdfObject)PdfName.FlateDecode, (PdfObject
                                                                                                              )PdfName.JPXDecode)));
            NUnit.Framework.Assert.AreEqual(BYTES, pdfStream.GetBytes());
        }
示例#6
0
        public virtual void SoundActionWithToLowVolumeTest()
        {
            PdfDocument document = CreateDocument(new PdfWriter(new MemoryStream()), false);
            Stream      @is      = new FileStream(sourceFolder + "sample.aif", FileMode.Open, FileAccess.Read);
            PdfStream   sound1   = new PdfStream(document, @is);

            sound1.Put(PdfName.R, new PdfNumber(32117));
            sound1.Put(PdfName.E, PdfName.Signed);
            sound1.Put(PdfName.B, new PdfNumber(16));
            sound1.Put(PdfName.C, new PdfNumber(1));
            try {
                document.GetPage(2).SetAdditionalAction(PdfName.O, PdfAction.CreateSound(sound1, -1.1f, false, false, false
                                                                                         ));
                NUnit.Framework.Assert.Fail("Exception not thrown");
            }
            catch (Exception e) {
                NUnit.Framework.Assert.AreEqual("volume", e.Message);
            }
            document.Close();
        }
        public virtual void TestJBIG2DecodeFilter()
        {
            PdfStream pdfStream = new PdfStream(FLATE_DECODED_BYTES);

            pdfStream.Put(PdfName.Filter, new PdfArray(JavaUtil.ArraysAsList((PdfObject)PdfName.FlateDecode, (PdfObject
                                                                                                              )PdfName.JBIG2Decode)));
            NUnit.Framework.Assert.That(() => {
                pdfStream.GetBytes(true);
            }
                                        , NUnit.Framework.Throws.InstanceOf <PdfException>().With.Message.EqualTo(MessageFormatUtil.Format(PdfException.Filter1IsNotSupported, PdfName.JBIG2Decode)))
            ;
        }
        public virtual void DifferentFiltersEmptyTest()
        {
            byte[]   b     = new byte[1000];
            PdfArray array = new PdfArray();

            array.Add(PdfName.Fl);
            array.Add(PdfName.AHx);
            array.Add(PdfName.A85);
            array.Add(PdfName.RunLengthDecode);
            PdfStream stream = new PdfStream(b);

            stream.Put(PdfName.Filter, array);
            NUnit.Framework.Assert.AreEqual(0, PdfReader.DecodeBytes(b, stream).Length);
        }
 public virtual void DefaultMemoryHandlerTest()
 {
     using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "timing.pdf"), new PdfWriter
                                                          (new MemoryStream()))) {
         PdfStream stream = pdfDocument.GetFirstPage().GetContentStream(0);
         byte[]    b      = stream.GetBytes(false);
         PdfArray  array  = new PdfArray();
         stream.Put(PdfName.Filter, array);
         NUnit.Framework.Assert.AreEqual(51, PdfReader.DecodeBytes(b, stream).Length);
         array.Add(PdfName.Fl);
         NUnit.Framework.Assert.AreEqual(40, PdfReader.DecodeBytes(b, stream).Length);
         array.Add(PdfName.Fl);
         NUnit.Framework.Assert.AreEqual(992, PdfReader.DecodeBytes(b, stream).Length);
         array.Add(PdfName.Fl);
         NUnit.Framework.Assert.AreEqual(1000000, PdfReader.DecodeBytes(b, stream).Length);
     }
 }
        public virtual void OverriddenMemoryHandlerNoStreamsAreSuspiciousTest()
        {
            MemoryLimitsAwareHandler handler = new _MemoryLimitsAwareHandler_235();

            handler.SetMaxSizeOfSingleDecompressedPdfStream(20);
            using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties
                                                                               ().SetMemoryLimitsAwareHandler(handler)), new PdfWriter(new MemoryStream()))) {
                PdfStream stream = pdfDocument.GetFirstPage().GetContentStream(0);
                byte[]    b      = stream.GetBytes(false);
                PdfArray  array  = new PdfArray();
                stream.Put(PdfName.Filter, array);
                array.Add(PdfName.Fl);
                array.Add(PdfName.Fl);
                // Limit is reached but the stream with several copies of the filter is not considered
                // to be suspicious
                PdfReader.DecodeBytes(b, stream);
            }
        }
        public virtual void OneFilterCustomMemoryHandlerSingleTest()
        {
            MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler();

            handler.SetMaxSizeOfSingleDecompressedPdfStream(20);
            using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties
                                                                               ().SetMemoryLimitsAwareHandler(handler)), new PdfWriter(new MemoryStream()))) {
                PdfStream stream = pdfDocument.GetFirstPage().GetContentStream(0);
                byte[]    b      = stream.GetBytes(false);
                PdfArray  array  = new PdfArray();
                stream.Put(PdfName.Filter, array);
                // Limit is reached, but the stream has no filters. Therefore we don't consider ot to be suspicious
                NUnit.Framework.Assert.AreEqual(51, PdfReader.DecodeBytes(b, stream).Length);
                // Limit is reached, but the stream has only one filter. Therefore we don't consider ot to be suspicious
                array.Add(PdfName.Fl);
                NUnit.Framework.Assert.AreEqual(40, PdfReader.DecodeBytes(b, stream).Length);
            }
        }
 public virtual void OverriddenMemoryHandlerAllStreamsAreSuspiciousTest()
 {
     NUnit.Framework.Assert.That(() => {
         MemoryLimitsAwareHandler handler = new _MemoryLimitsAwareHandler_203();
         handler.SetMaxSizeOfSingleDecompressedPdfStream(20);
         using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties
                                                                            ().SetMemoryLimitsAwareHandler(handler)), new PdfWriter(new MemoryStream()))) {
             PdfStream stream = pdfDocument.GetFirstPage().GetContentStream(0);
             byte[] b         = stream.GetBytes(false);
             PdfArray array   = new PdfArray();
             stream.Put(PdfName.Filter, array);
             array.Add(PdfName.Fl);
             // Limit is reached, and the stream with one filter is considered to be suspicious
             PdfReader.DecodeBytes(b, stream);
         }
     }
                                 , NUnit.Framework.Throws.InstanceOf <MemoryLimitsAwareException>().With.Message.EqualTo(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed))
     ;
 }
示例#13
0
        public virtual void NoMemoryHandlerTest()
        {
            PdfDocument pdfDocument = new PdfDocument(new PdfWriter(new MemoryStream()));
            FileStream  @is         = new FileStream(sourceFolder + "stream", FileMode.Open, FileAccess.Read);

            byte[] b = new byte[51];
            @is.Read(b);
            PdfArray  array  = new PdfArray();
            PdfStream stream = new PdfStream(b);

            stream.Put(PdfName.Filter, array);
            stream.MakeIndirect(pdfDocument);
            NUnit.Framework.Assert.AreEqual(51, PdfReader.DecodeBytes(b, stream).Length);
            array.Add(PdfName.Fl);
            NUnit.Framework.Assert.AreEqual(40, PdfReader.DecodeBytes(b, stream).Length);
            array.Add(PdfName.Fl);
            NUnit.Framework.Assert.AreEqual(992, PdfReader.DecodeBytes(b, stream).Length);
            array.Add(PdfName.Fl);
            NUnit.Framework.Assert.AreEqual(1000000, PdfReader.DecodeBytes(b, stream).Length);
        }
        public virtual void CustomMemoryHandlerSingleTest()
        {
            MemoryLimitsAwareHandler handler = new MemoryLimitsAwareHandler();

            handler.SetMaxSizeOfSingleDecompressedPdfStream(1000);
            NUnit.Framework.Assert.That(() => {
                using (PdfDocument pdfDocument = new PdfDocument(new PdfReader(sourceFolder + "timing.pdf", new ReaderProperties
                                                                                   ().SetMemoryLimitsAwareHandler(handler)), new PdfWriter(new MemoryStream()))) {
                    PdfStream stream = pdfDocument.GetFirstPage().GetContentStream(0);
                    byte[] b         = stream.GetBytes(false);
                    PdfArray array   = new PdfArray();
                    stream.Put(PdfName.Filter, array);
                    NUnit.Framework.Assert.AreEqual(51, PdfReader.DecodeBytes(b, stream).Length);
                    array.Add(PdfName.Fl);
                    NUnit.Framework.Assert.AreEqual(40, PdfReader.DecodeBytes(b, stream).Length);
                    array.Add(PdfName.Fl);
                    NUnit.Framework.Assert.AreEqual(992, PdfReader.DecodeBytes(b, stream).Length);
                    array.Add(PdfName.Fl);
                    PdfReader.DecodeBytes(b, stream);
                }
            }
                                        , NUnit.Framework.Throws.InstanceOf <MemoryLimitsAwareException>().With.Message.EqualTo(PdfException.DuringDecompressionSingleStreamOccupiedMoreMemoryThanAllowed))
            ;
        }
示例#15
0
        /// <summary>Writes cross reference table and trailer to PDF.</summary>
        /// <exception cref="System.IO.IOException"/>
        /// <exception cref="iText.Kernel.PdfException"/>
        protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, PdfObject fileId, PdfObject
                                                                 crypto)
        {
            PdfWriter writer = document.GetWriter();

            if (document.IsAppendMode())
            {
                // Increment generation number for all freed references.
                foreach (int?objNr in freeReferences)
                {
                    xref[(int)objNr].genNr++;
                }
            }
            else
            {
                foreach (int?objNr in freeReferences)
                {
                    xref[(int)objNr] = null;
                }
            }
            freeReferences.Clear();
            for (int i = count; i > 0; --i)
            {
                PdfIndirectReference lastRef = xref[i];
                if (lastRef == null || (lastRef.IsFree() && lastRef.GetGenNumber() == 0) || (!lastRef.CheckState(PdfObject
                                                                                                                 .FLUSHED) && !(document.properties.appendMode && !lastRef.CheckState(PdfObject.MODIFIED))))
                {
                    --count;
                }
                else
                {
                    break;
                }
            }
            IList <int> sections = new List <int>();
            int         first    = 0;
            int         len      = 1;

            if (document.IsAppendMode())
            {
                first = 1;
                len   = 0;
            }
            for (int i_1 = 1; i_1 < Size(); i_1++)
            {
                PdfIndirectReference reference = xref[i_1];
                if (reference != null)
                {
                    if ((document.properties.appendMode && !reference.CheckState(PdfObject.MODIFIED)) || (reference.IsFree() &&
                                                                                                          reference.GetGenNumber() == 0) || (!reference.CheckState(PdfObject.FLUSHED)))
                    {
                        reference = null;
                    }
                }
                if (reference == null)
                {
                    if (len > 0)
                    {
                        sections.Add(first);
                        sections.Add(len);
                    }
                    len = 0;
                }
                else
                {
                    if (len > 0)
                    {
                        len++;
                    }
                    else
                    {
                        first = i_1;
                        len   = 1;
                    }
                }
            }
            if (len > 0)
            {
                sections.Add(first);
                sections.Add(len);
            }
            if (document.properties.appendMode && sections.Count == 0)
            {
                // no modifications.
                xref = null;
                return;
            }
            long startxref = writer.GetCurrentPos();

            if (writer.IsFullCompression())
            {
                PdfStream xrefStream = ((PdfStream) new PdfStream().MakeIndirect(document));
                xrefStream.MakeIndirect(document);
                xrefStream.Put(PdfName.Type, PdfName.XRef);
                xrefStream.Put(PdfName.ID, fileId);
                if (crypto != null)
                {
                    xrefStream.Put(PdfName.Encrypt, crypto);
                }
                xrefStream.Put(PdfName.Size, new PdfNumber(this.Size()));
                List <PdfObject> tmpArray = new List <PdfObject>(3);
                tmpArray.Add(new PdfNumber(1));
                tmpArray.Add(new PdfNumber(4));
                tmpArray.Add(new PdfNumber(2));
                xrefStream.Put(PdfName.W, new PdfArray(tmpArray));
                xrefStream.Put(PdfName.Info, document.GetDocumentInfo().GetPdfObject());
                xrefStream.Put(PdfName.Root, document.GetCatalog().GetPdfObject());
                PdfArray index = new PdfArray();
                foreach (int?section in sections)
                {
                    index.Add(new PdfNumber((int)section));
                }
                if (document.properties.appendMode)
                {
                    PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref());
                    xrefStream.Put(PdfName.Prev, lastXref);
                }
                xrefStream.Put(PdfName.Index, index);
                iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref();
                for (int k = 0; k < sections.Count; k += 2)
                {
                    first = (int)sections[k];
                    len   = (int)sections[k + 1];
                    for (int i_2 = first; i_2 < first + len; i_2++)
                    {
                        PdfIndirectReference reference = xrefTable.Get(i_2);
                        if (reference == null)
                        {
                            continue;
                        }
                        if (reference.IsFree())
                        {
                            xrefStream.GetOutputStream().Write(0);
                            //NOTE The object number of the next free object should be at this position due to spec.
                            xrefStream.GetOutputStream().Write(IntToBytes(0));
                            xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetGenNumber()));
                        }
                        else
                        {
                            if (reference.GetObjStreamNumber() == 0)
                            {
                                xrefStream.GetOutputStream().Write(1);
                                System.Diagnostics.Debug.Assert(reference.GetOffset() < int.MaxValue);
                                xrefStream.GetOutputStream().Write(IntToBytes((int)reference.GetOffset()));
                                xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetGenNumber()));
                            }
                            else
                            {
                                xrefStream.GetOutputStream().Write(2);
                                xrefStream.GetOutputStream().Write(IntToBytes(reference.GetObjStreamNumber()));
                                xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetIndex()));
                            }
                        }
                    }
                }
                xrefStream.Flush();
            }
            else
            {
                writer.WriteString("xref\n");
                iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref();
                for (int k = 0; k < sections.Count; k += 2)
                {
                    first = (int)sections[k];
                    len   = (int)sections[k + 1];
                    writer.WriteInteger(first).WriteSpace().WriteInteger(len).WriteByte((byte)'\n');
                    for (int i_2 = first; i_2 < first + len; i_2++)
                    {
                        PdfIndirectReference reference = xrefTable.Get(i_2);
                        writer.WriteString(DecimalFormatUtil.FormatNumber(reference.GetOffset(), objectOffsetFormatter)).WriteSpace
                            ().WriteString(DecimalFormatUtil.FormatNumber(reference.GetGenNumber(), objectGenerationFormatter)).WriteSpace
                            ();
                        if (reference.IsFree())
                        {
                            writer.WriteBytes(freeXRefEntry);
                        }
                        else
                        {
                            writer.WriteBytes(inUseXRefEntry);
                        }
                    }
                }
                PdfDictionary trailer = document.GetTrailer();
                // Remove all unused keys in case stamp mode in case original file has full compression, but destination file has not.
                trailer.Remove(PdfName.W);
                trailer.Remove(PdfName.Index);
                trailer.Remove(PdfName.Type);
                trailer.Remove(PdfName.Length);
                trailer.Put(PdfName.Size, new PdfNumber(this.Size()));
                trailer.Put(PdfName.ID, fileId);
                if (crypto != null)
                {
                    trailer.Put(PdfName.Encrypt, crypto);
                }
                writer.WriteString("trailer\n");
                if (document.properties.appendMode)
                {
                    PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref());
                    trailer.Put(PdfName.Prev, lastXref);
                }
                writer.Write(document.GetTrailer());
                writer.Write('\n');
            }
            WriteKeyInfo(writer);
            writer.WriteString("startxref\n").WriteLong(startxref).WriteString("\n%%EOF\n");
            xref = null;
        }
示例#16
0
        protected internal virtual byte[] DecodeFlateBytes(PdfStream stream, byte[] bytes)
        {
            PdfObject filterObject = stream.Get(PdfName.Filter);

            if (filterObject == null)
            {
                return(bytes);
            }
            // check if flateDecode filter is on top
            PdfName  filterName;
            PdfArray filtersArray = null;

            if (filterObject is PdfName)
            {
                filterName = (PdfName)filterObject;
            }
            else
            {
                if (filterObject is PdfArray)
                {
                    filtersArray = (PdfArray)filterObject;
                    filterName   = filtersArray.GetAsName(0);
                }
                else
                {
                    throw new PdfException(PdfException.FilterIsNotANameOrArray);
                }
            }
            if (!PdfName.FlateDecode.Equals(filterName))
            {
                return(bytes);
            }
            // get decode params if present
            PdfDictionary decodeParams;
            PdfArray      decodeParamsArray  = null;
            PdfObject     decodeParamsObject = stream.Get(PdfName.DecodeParms);

            if (decodeParamsObject == null)
            {
                decodeParams = null;
            }
            else
            {
                if (decodeParamsObject.GetObjectType() == PdfObject.DICTIONARY)
                {
                    decodeParams = (PdfDictionary)decodeParamsObject;
                }
                else
                {
                    if (decodeParamsObject.GetObjectType() == PdfObject.ARRAY)
                    {
                        decodeParamsArray = (PdfArray)decodeParamsObject;
                        decodeParams      = decodeParamsArray.GetAsDictionary(0);
                    }
                    else
                    {
                        throw new PdfException(PdfException.DecodeParameterType1IsNotSupported).SetMessageParams(decodeParamsObject
                                                                                                                 .GetType().ToString());
                    }
                }
            }
            // decode
            byte[] res = FlateDecodeFilter.FlateDecode(bytes, true);
            if (res == null)
            {
                res = FlateDecodeFilter.FlateDecode(bytes, false);
            }
            bytes = FlateDecodeFilter.DecodePredictor(res, decodeParams);
            //remove filter and decode params
            filterObject = null;
            if (filtersArray != null)
            {
                filtersArray.Remove(0);
                if (filtersArray.Size() == 1)
                {
                    filterObject = filtersArray.Get(0);
                }
                else
                {
                    if (!filtersArray.IsEmpty())
                    {
                        filterObject = filtersArray;
                    }
                }
            }
            decodeParamsObject = null;
            if (decodeParamsArray != null)
            {
                decodeParamsArray.Remove(0);
                if (decodeParamsArray.Size() == 1 && decodeParamsArray.Get(0).GetObjectType() != PdfObject.NULL)
                {
                    decodeParamsObject = decodeParamsArray.Get(0);
                }
                else
                {
                    if (!decodeParamsArray.IsEmpty())
                    {
                        decodeParamsObject = decodeParamsArray;
                    }
                }
            }
            if (filterObject == null)
            {
                stream.Remove(PdfName.Filter);
            }
            else
            {
                stream.Put(PdfName.Filter, filterObject);
            }
            if (decodeParamsObject == null)
            {
                stream.Remove(PdfName.DecodeParms);
            }
            else
            {
                stream.Put(PdfName.DecodeParms, decodeParamsObject);
            }
            return(bytes);
        }
示例#17
0
        /// <summary>Writes cross reference table and trailer to PDF.</summary>
        /// <exception cref="System.IO.IOException"/>
        protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, PdfObject fileId, PdfObject
                                                                 crypto)
        {
            PdfWriter writer = document.GetWriter();

            if (!document.properties.appendMode)
            {
                for (int i = count; i > 0; --i)
                {
                    PdfIndirectReference lastRef = xref[i];
                    if (lastRef == null || lastRef.IsFree())
                    {
                        RemoveFreeRefFromList(i);
                        --count;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            IList <int> sections = new List <int>();
            int         first    = 0;
            int         len      = 0;

            for (int i = 0; i < Size(); i++)
            {
                PdfIndirectReference reference = xref[i];
                if (document.properties.appendMode && reference != null && !reference.CheckState(PdfObject.MODIFIED))
                {
                    reference = null;
                }
                if (reference == null)
                {
                    if (len > 0)
                    {
                        sections.Add(first);
                        sections.Add(len);
                    }
                    len = 0;
                }
                else
                {
                    if (len > 0)
                    {
                        len++;
                    }
                    else
                    {
                        first = i;
                        len   = 1;
                    }
                }
            }
            if (len > 0)
            {
                sections.Add(first);
                sections.Add(len);
            }
            if (document.properties.appendMode && sections.Count == 0)
            {
                // no modifications.
                xref = null;
                return;
            }
            long startxref = writer.GetCurrentPos();

            if (writer.IsFullCompression())
            {
                PdfStream xrefStream = (PdfStream) new PdfStream().MakeIndirect(document);
                xrefStream.MakeIndirect(document);
                xrefStream.Put(PdfName.Type, PdfName.XRef);
                xrefStream.Put(PdfName.ID, fileId);
                if (crypto != null)
                {
                    xrefStream.Put(PdfName.Encrypt, crypto);
                }
                xrefStream.Put(PdfName.Size, new PdfNumber(this.Size()));
                List <PdfObject> tmpArray = new List <PdfObject>(3);
                tmpArray.Add(new PdfNumber(1));
                tmpArray.Add(new PdfNumber(4));
                tmpArray.Add(new PdfNumber(2));
                xrefStream.Put(PdfName.W, new PdfArray(tmpArray));
                xrefStream.Put(PdfName.Info, document.GetDocumentInfo().GetPdfObject());
                xrefStream.Put(PdfName.Root, document.GetCatalog().GetPdfObject());
                PdfArray index = new PdfArray();
                foreach (int?section in sections)
                {
                    index.Add(new PdfNumber((int)section));
                }
                if (document.properties.appendMode)
                {
                    PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref());
                    xrefStream.Put(PdfName.Prev, lastXref);
                }
                xrefStream.Put(PdfName.Index, index);
                iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref();
                for (int k = 0; k < sections.Count; k += 2)
                {
                    first = (int)sections[k];
                    len   = (int)sections[k + 1];
                    for (int i = first; i < first + len; i++)
                    {
                        PdfIndirectReference reference = xrefTable.Get(i);
                        if (reference.IsFree())
                        {
                            xrefStream.GetOutputStream().Write(0);
                            System.Diagnostics.Debug.Assert(reference.GetOffset() < int.MaxValue);
                            xrefStream.GetOutputStream().Write(IntToBytes((int)reference.GetOffset()));
                            xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetGenNumber()));
                        }
                        else
                        {
                            if (reference.GetObjStreamNumber() == 0)
                            {
                                xrefStream.GetOutputStream().Write(1);
                                System.Diagnostics.Debug.Assert(reference.GetOffset() < int.MaxValue);
                                xrefStream.GetOutputStream().Write(IntToBytes((int)reference.GetOffset()));
                                xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetGenNumber()));
                            }
                            else
                            {
                                xrefStream.GetOutputStream().Write(2);
                                xrefStream.GetOutputStream().Write(IntToBytes(reference.GetObjStreamNumber()));
                                xrefStream.GetOutputStream().Write(ShortToBytes(reference.GetIndex()));
                            }
                        }
                    }
                }
                xrefStream.Flush();
            }
            else
            {
                writer.WriteString("xref\n");
                iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref();
                for (int k = 0; k < sections.Count; k += 2)
                {
                    first = (int)sections[k];
                    len   = (int)sections[k + 1];
                    writer.WriteInteger(first).WriteSpace().WriteInteger(len).WriteByte((byte)'\n');
                    for (int i = first; i < first + len; i++)
                    {
                        PdfIndirectReference reference = xrefTable.Get(i);
                        StringBuilder        off       = new StringBuilder("0000000000").Append(reference.GetOffset());
                        StringBuilder        gen       = new StringBuilder("00000").Append(reference.GetGenNumber());
                        writer.WriteString(off.JSubstring(off.Length - 10, off.Length)).WriteSpace().WriteString(gen.JSubstring(gen
                                                                                                                                .Length - 5, gen.Length)).WriteSpace();
                        if (reference.IsFree())
                        {
                            writer.WriteBytes(freeXRefEntry);
                        }
                        else
                        {
                            writer.WriteBytes(inUseXRefEntry);
                        }
                    }
                }
                PdfDictionary trailer = document.GetTrailer();
                // Remove all unused keys in case stamp mode in case original file has full compression, but destination file has not.
                trailer.Remove(PdfName.W);
                trailer.Remove(PdfName.Index);
                trailer.Remove(PdfName.Type);
                trailer.Remove(PdfName.Length);
                trailer.Put(PdfName.Size, new PdfNumber(this.Size()));
                trailer.Put(PdfName.ID, fileId);
                if (crypto != null)
                {
                    trailer.Put(PdfName.Encrypt, crypto);
                }
                writer.WriteString("trailer\n");
                if (document.properties.appendMode)
                {
                    PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref());
                    trailer.Put(PdfName.Prev, lastXref);
                }
                writer.Write(document.GetTrailer());
                writer.Write('\n');
            }
            WriteKeyInfo(document);
            writer.WriteString("startxref\n").WriteLong(startxref).WriteString("\n%%EOF\n");
            xref = null;
            freeReferencesLinkedList.Clear();
        }
示例#18
0
        private void Write(PdfStream pdfStream)
        {
            try {
                bool userDefinedCompression = pdfStream.GetCompressionLevel() != CompressionConstants.UNDEFINED_COMPRESSION;
                if (!userDefinedCompression)
                {
                    int defaultCompressionLevel = document != null?document.GetWriter().GetCompressionLevel() : CompressionConstants
                                                      .DEFAULT_COMPRESSION;

                    pdfStream.SetCompressionLevel(defaultCompressionLevel);
                }
                bool toCompress       = pdfStream.GetCompressionLevel() != CompressionConstants.NO_COMPRESSION;
                bool allowCompression = !pdfStream.ContainsKey(PdfName.Filter) && IsNotMetadataPdfStream(pdfStream);
                if (pdfStream.GetInputStream() != null)
                {
                    Stream fout = this;
                    DeflaterOutputStream   def = null;
                    OutputStreamEncryption ose = null;
                    if (crypto != null && !crypto.IsEmbeddedFilesOnly())
                    {
                        fout = ose = crypto.GetEncryptionStream(fout);
                    }
                    if (toCompress && (allowCompression || userDefinedCompression))
                    {
                        UpdateCompressionFilter(pdfStream);
                        fout = def = new DeflaterOutputStream(fout, pdfStream.GetCompressionLevel(), 0x8000);
                    }
                    this.Write((PdfDictionary)pdfStream);
                    WriteBytes(iText.Kernel.Pdf.PdfOutputStream.stream);
                    long   beginStreamContent = GetCurrentPos();
                    byte[] buf = new byte[4192];
                    while (true)
                    {
                        int n = pdfStream.GetInputStream().Read(buf);
                        if (n <= 0)
                        {
                            break;
                        }
                        fout.Write(buf, 0, n);
                    }
                    if (def != null)
                    {
                        def.Finish();
                    }
                    if (ose != null)
                    {
                        ose.Finish();
                    }
                    PdfNumber length = pdfStream.GetAsNumber(PdfName.Length);
                    length.SetValue((int)(GetCurrentPos() - beginStreamContent));
                    pdfStream.UpdateLength(length.IntValue());
                    WriteBytes(iText.Kernel.Pdf.PdfOutputStream.endstream);
                }
                else
                {
                    //When document is opened in stamping mode the output stream can be uninitialized.
                    //We have to initialize it and write all data from streams input to streams output.
                    if (pdfStream.GetOutputStream() == null && pdfStream.GetIndirectReference().GetReader() != null)
                    {
                        // If new specific compression is set for stream,
                        // then compressed stream should be decoded and written with new compression settings
                        byte[] bytes = pdfStream.GetIndirectReference().GetReader().ReadStreamBytes(pdfStream, false);
                        if (userDefinedCompression)
                        {
                            bytes = DecodeFlateBytes(pdfStream, bytes);
                        }
                        pdfStream.InitOutputStream(new ByteArrayOutputStream(bytes.Length));
                        pdfStream.GetOutputStream().Write(bytes);
                    }
                    System.Diagnostics.Debug.Assert(pdfStream.GetOutputStream() != null, "PdfStream lost OutputStream");
                    ByteArrayOutputStream byteArrayStream;
                    try {
                        if (toCompress && !ContainsFlateFilter(pdfStream) && (allowCompression || userDefinedCompression))
                        {
                            // compress
                            UpdateCompressionFilter(pdfStream);
                            byteArrayStream = new ByteArrayOutputStream();
                            DeflaterOutputStream zip = new DeflaterOutputStream(byteArrayStream, pdfStream.GetCompressionLevel());
                            if (pdfStream is PdfObjectStream)
                            {
                                PdfObjectStream objectStream = (PdfObjectStream)pdfStream;
                                ((ByteArrayOutputStream)objectStream.GetIndexStream().GetOutputStream()).WriteTo(zip);
                                ((ByteArrayOutputStream)objectStream.GetOutputStream().GetOutputStream()).WriteTo(zip);
                            }
                            else
                            {
                                System.Diagnostics.Debug.Assert(pdfStream.GetOutputStream() != null, "Error in outputStream");
                                ((ByteArrayOutputStream)pdfStream.GetOutputStream().GetOutputStream()).WriteTo(zip);
                            }
                            zip.Finish();
                        }
                        else
                        {
                            if (pdfStream is PdfObjectStream)
                            {
                                PdfObjectStream objectStream = (PdfObjectStream)pdfStream;
                                byteArrayStream = new ByteArrayOutputStream();
                                ((ByteArrayOutputStream)objectStream.GetIndexStream().GetOutputStream()).WriteTo(byteArrayStream);
                                ((ByteArrayOutputStream)objectStream.GetOutputStream().GetOutputStream()).WriteTo(byteArrayStream);
                            }
                            else
                            {
                                System.Diagnostics.Debug.Assert(pdfStream.GetOutputStream() != null, "Error in outputStream");
                                byteArrayStream = (ByteArrayOutputStream)pdfStream.GetOutputStream().GetOutputStream();
                            }
                        }
                        if (CheckEncryption(pdfStream))
                        {
                            ByteArrayOutputStream  encodedStream = new ByteArrayOutputStream();
                            OutputStreamEncryption ose           = crypto.GetEncryptionStream(encodedStream);
                            byteArrayStream.WriteTo(ose);
                            ose.Finish();
                            byteArrayStream = encodedStream;
                        }
                    }
                    catch (System.IO.IOException ioe) {
                        throw new PdfException(PdfException.IoException, ioe);
                    }
                    pdfStream.Put(PdfName.Length, new PdfNumber(byteArrayStream.Length));
                    pdfStream.UpdateLength((int)byteArrayStream.Length);
                    this.Write((PdfDictionary)pdfStream);
                    WriteBytes(iText.Kernel.Pdf.PdfOutputStream.stream);
                    byteArrayStream.WriteTo(this);
                    byteArrayStream.Dispose();
                    WriteBytes(iText.Kernel.Pdf.PdfOutputStream.endstream);
                }
            }
            catch (System.IO.IOException e) {
                throw new PdfException(PdfException.CannotWriteToPdfStream, e, pdfStream);
            }
        }
示例#19
0
        /// <summary>Writes cross reference table and trailer to PDF.</summary>
        protected internal virtual void WriteXrefTableAndTrailer(PdfDocument document, PdfObject fileId, PdfObject
                                                                 crypto)
        {
            PdfWriter writer = document.GetWriter();

            if (!document.properties.appendMode)
            {
                for (int i = count; i > 0; --i)
                {
                    PdfIndirectReference lastRef = xref[i];
                    if (lastRef == null || lastRef.IsFree())
                    {
                        RemoveFreeRefFromList(i);
                        --count;
                    }
                    else
                    {
                        break;
                    }
                }
            }
            IList <int> sections = CreateSections(document, false);

            if (document.properties.appendMode && sections.Count == 0)
            {
                // no modifications.
                xref = null;
                return;
            }
            long startxref  = writer.GetCurrentPos();
            long xRefStmPos = -1;

            if (writer.IsFullCompression())
            {
                PdfStream xrefStream = (PdfStream) new PdfStream().MakeIndirect(document);
                xrefStream.MakeIndirect(document);
                xrefStream.Put(PdfName.Type, PdfName.XRef);
                xrefStream.Put(PdfName.ID, fileId);
                if (crypto != null)
                {
                    xrefStream.Put(PdfName.Encrypt, crypto);
                }
                xrefStream.Put(PdfName.Size, new PdfNumber(this.Size()));
                int offsetSize = GetOffsetSize(Math.Max(startxref, Size()));
                xrefStream.Put(PdfName.W, new PdfArray(JavaUtil.ArraysAsList((PdfObject) new PdfNumber(1), new PdfNumber(offsetSize
                                                                                                                         ), new PdfNumber(2))));
                xrefStream.Put(PdfName.Info, document.GetDocumentInfo().GetPdfObject());
                xrefStream.Put(PdfName.Root, document.GetCatalog().GetPdfObject());
                PdfArray index = new PdfArray();
                foreach (int?section in sections)
                {
                    index.Add(new PdfNumber((int)section));
                }
                if (document.properties.appendMode && !document.reader.hybridXref)
                {
                    // "not meaningful in hybrid-reference files"
                    PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref());
                    xrefStream.Put(PdfName.Prev, lastXref);
                }
                xrefStream.Put(PdfName.Index, index);
                iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref();
                for (int k = 0; k < sections.Count; k += 2)
                {
                    int first = (int)sections[k];
                    int len   = (int)sections[k + 1];
                    for (int i = first; i < first + len; i++)
                    {
                        PdfIndirectReference reference = xrefTable.Get(i);
                        if (reference.IsFree())
                        {
                            xrefStream.GetOutputStream().Write(0);
                            xrefStream.GetOutputStream().Write(reference.GetOffset(), offsetSize);
                            xrefStream.GetOutputStream().Write(reference.GetGenNumber(), 2);
                        }
                        else
                        {
                            if (reference.GetObjStreamNumber() == 0)
                            {
                                xrefStream.GetOutputStream().Write(1);
                                xrefStream.GetOutputStream().Write(reference.GetOffset(), offsetSize);
                                xrefStream.GetOutputStream().Write(reference.GetGenNumber(), 2);
                            }
                            else
                            {
                                xrefStream.GetOutputStream().Write(2);
                                xrefStream.GetOutputStream().Write(reference.GetObjStreamNumber(), offsetSize);
                                xrefStream.GetOutputStream().Write(reference.GetIndex(), 2);
                            }
                        }
                    }
                }
                xrefStream.Flush();
                xRefStmPos = startxref;
            }
            // For documents with hybrid cross-reference table, i.e. containing xref streams as well as regular xref sections,
            // we write additional regular xref section at the end of the document because the /Prev reference from
            // xref stream to a regular xref section doesn't seem to be valid
            bool needsRegularXref = !writer.IsFullCompression() || document.properties.appendMode && document.reader.hybridXref;

            if (needsRegularXref)
            {
                startxref = writer.GetCurrentPos();
                writer.WriteString("xref\n");
                iText.Kernel.Pdf.PdfXrefTable xrefTable = document.GetXref();
                if (xRefStmPos != -1)
                {
                    // Get rid of all objects from object stream. This is done for hybrid documents
                    sections = CreateSections(document, true);
                }
                for (int k = 0; k < sections.Count; k += 2)
                {
                    int first = (int)sections[k];
                    int len   = (int)sections[k + 1];
                    writer.WriteInteger(first).WriteSpace().WriteInteger(len).WriteByte((byte)'\n');
                    for (int i = first; i < first + len; i++)
                    {
                        PdfIndirectReference reference = xrefTable.Get(i);
                        StringBuilder        off       = new StringBuilder("0000000000").Append(reference.GetOffset());
                        StringBuilder        gen       = new StringBuilder("00000").Append(reference.GetGenNumber());
                        writer.WriteString(off.JSubstring(off.Length - 10, off.Length)).WriteSpace().WriteString(gen.JSubstring(gen
                                                                                                                                .Length - 5, gen.Length)).WriteSpace();
                        if (reference.IsFree())
                        {
                            writer.WriteBytes(freeXRefEntry);
                        }
                        else
                        {
                            writer.WriteBytes(inUseXRefEntry);
                        }
                    }
                }
                PdfDictionary trailer = document.GetTrailer();
                // Remove all unused keys in case stamp mode in case original file has full compression, but destination file has not.
                trailer.Remove(PdfName.W);
                trailer.Remove(PdfName.Index);
                trailer.Remove(PdfName.Type);
                trailer.Remove(PdfName.Length);
                trailer.Put(PdfName.Size, new PdfNumber(this.Size()));
                trailer.Put(PdfName.ID, fileId);
                if (xRefStmPos != -1)
                {
                    trailer.Put(PdfName.XRefStm, new PdfNumber(xRefStmPos));
                }
                if (crypto != null)
                {
                    trailer.Put(PdfName.Encrypt, crypto);
                }
                writer.WriteString("trailer\n");
                if (document.properties.appendMode)
                {
                    PdfNumber lastXref = new PdfNumber(document.reader.GetLastXref());
                    trailer.Put(PdfName.Prev, lastXref);
                }
                writer.Write(document.GetTrailer());
                writer.Write('\n');
            }
            WriteKeyInfo(document);
            writer.WriteString("startxref\n").WriteLong(startxref).WriteString("\n%%EOF\n");
            xref = null;
            freeReferencesLinkedList.Clear();
        }