/// <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); }
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_")); }
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); }
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()); }
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)) ; }
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)) ; }
/// <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; }
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); }
/// <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(); }
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); } }
/// <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(); }