private static byte[] GetByteRangeDigest(PdfDocument document, PdfPKCS7 pkcs7, PdfSignature signature, string digestAlg) { Org.BouncyCastle.Crypto.IDigest digest = Org.BouncyCastle.Security.DigestUtilities.GetDigest(digestAlg); iText.Kernel.Pdf.PdfArray b = signature.GetByteRange(); iText.IO.Source.RandomAccessFileOrArray rf = document.GetReader().GetSafeFile(); Stream rg = null; try { rg = new iText.IO.Source.RASInputStream(new iText.IO.Source.RandomAccessSourceFactory().CreateRanged(rf.CreateSourceView(), b.ToLongArray( ))); byte[] buf = new byte[8192]; int rd; while ((rd = rg.Read(buf, 0, buf.Length)) > 0) { digest.BlockUpdate(buf, 0, rd); } byte[] dig = new byte[digest.GetDigestSize()]; digest.DoFinal(dig, 0); return(dig); } catch (Exception e) { throw new iText.Kernel.PdfException(e); } finally { try { if (rg != null) { rg.Dispose(); } } catch (System.IO.IOException e) { // this really shouldn't ever happen - the source view we use is based on a Safe view, which is a no-op anyway throw new iText.Kernel.PdfException(e); } } }
public override bool IsMemoryLimitsAwarenessRequiredOnDecompression(PdfArray filters) { return(true); }
/// <summary>Sets the array of predefined procedure set names (see ISO-320001 Paragraph 14.2).</summary> /// <remarks> /// Sets the array of predefined procedure set names (see ISO-320001 Paragraph 14.2). /// Deprecated in PDF 2.0. /// </remarks> /// <param name="array">the array of predefined procedure set names to be set.</param> public virtual void SetProcSet(PdfArray array) { GetPdfObject().Put(PdfName.ProcSet, array); }
public virtual PdfDictionary BuildTree() { int?[] numbers = new int?[items.Count]; numbers = items.Keys.ToArray(numbers); JavaUtil.Sort(numbers); if (numbers.Length <= NODE_SIZE) { PdfDictionary dic = new PdfDictionary(); PdfArray ar = new PdfArray(); for (int k = 0; k < numbers.Length; ++k) { ar.Add(new PdfNumber((int)numbers[k])); ar.Add(items.Get(numbers[k])); } dic.Put(PdfName.Nums, ar); return(dic); } int skip = NODE_SIZE; PdfDictionary[] kids = new PdfDictionary[(numbers.Length + NODE_SIZE - 1) / NODE_SIZE]; for (int i = 0; i < kids.Length; ++i) { int offset = i * NODE_SIZE; int end = Math.Min(offset + NODE_SIZE, numbers.Length); PdfDictionary dic = new PdfDictionary(); PdfArray arr = new PdfArray(); arr.Add(new PdfNumber((int)numbers[offset])); arr.Add(new PdfNumber((int)numbers[end - 1])); dic.Put(PdfName.Limits, arr); arr = new PdfArray(); for (; offset < end; ++offset) { arr.Add(new PdfNumber((int)numbers[offset])); arr.Add(items.Get(numbers[offset])); } dic.Put(PdfName.Nums, arr); dic.MakeIndirect(catalog.GetDocument()); kids[i] = dic; } int top = kids.Length; while (true) { if (top <= NODE_SIZE) { PdfArray arr = new PdfArray(); for (int k = 0; k < top; ++k) { arr.Add(kids[k]); } PdfDictionary dic = new PdfDictionary(); dic.Put(PdfName.Kids, arr); return(dic); } skip *= NODE_SIZE; int tt = (numbers.Length + skip - 1) / skip; for (int k = 0; k < tt; ++k) { int offset = k * NODE_SIZE; int end = Math.Min(offset + NODE_SIZE, top); PdfDictionary dic = (PdfDictionary) new PdfDictionary().MakeIndirect(catalog.GetDocument()); PdfArray arr = new PdfArray(); arr.Add(new PdfNumber((int)numbers[k * skip])); arr.Add(new PdfNumber((int)numbers[Math.Min((k + 1) * skip, numbers.Length) - 1])); dic.Put(PdfName.Limits, arr); arr = new PdfArray(); for (; offset < end; ++offset) { arr.Add(kids[offset]); } dic.Put(PdfName.Kids, arr); kids[k] = dic; } top = tt; } }
/// <summary>Returns the value associated to this key as a Rectangle.</summary> /// <remarks> /// Returns the value associated to this key as a Rectangle. If the value isn't a PdfArray of which the /// firt four elements are PdfNumbers, null is returned. /// </remarks> /// <param name="key">the key of which the associated value needs to be returned</param> /// <returns>PdfArray associated with this key</returns> /// <seealso cref="PdfArray.ToRectangle()"/> public virtual Rectangle GetAsRectangle(PdfName key) { PdfArray a = GetAsArray(key); return(a == null ? null : a.ToRectangle()); }
private void LoadPage(int pageNum) { PdfIndirectReference targetPage = pageRefs[pageNum]; if (targetPage != null) { return; } //if we go here, we have to split PdfPages that contains pageNum int parentIndex = FindPageParent(pageNum); PdfPages parent = parents[parentIndex]; PdfArray kids = parent.GetKids(); if (kids == null) { throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1); } int kidsCount = parent.GetCount(); // we should handle separated pages, it means every PdfArray kids must contain either PdfPage or PdfPages, // mix of PdfPage and PdfPages not allowed. bool findPdfPages = false; // NOTE optimization? when we already found needed index for (int i = 0; i < kids.Size(); i++) { PdfDictionary page = kids.GetAsDictionary(i); // null values not allowed in pages tree. if (page == null) { throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1); } PdfObject pageKids = page.Get(PdfName.Kids); if (pageKids != null) { if (pageKids.IsArray()) { findPdfPages = true; } else { // kids must be of type array throw new PdfException(PdfException.InvalidPageStructure1).SetMessageParams(pageNum + 1); } } } if (findPdfPages) { // handle mix of PdfPage and PdfPages. // handle count property! IList <PdfPages> newParents = new List <PdfPages>(kids.Size()); PdfPages lastPdfPages = null; for (int i = 0; i < kids.Size() && kidsCount > 0; i++) { PdfDictionary pdfPagesObject = kids.GetAsDictionary(i); if (pdfPagesObject.GetAsArray(PdfName.Kids) == null) { // pdfPagesObject is PdfPage // possible if only first kid is PdfPage if (lastPdfPages == null) { lastPdfPages = new PdfPages(parent.GetFrom(), document, parent); kids.Set(i, lastPdfPages.GetPdfObject()); newParents.Add(lastPdfPages); } else { // Only remove from kids if we did not replace the entry with new PdfPages kids.Remove(i); i--; } // decrement count first so that page is not counted twice when moved to lastPdfPages parent.DecrementCount(); lastPdfPages.AddPage(pdfPagesObject); kidsCount--; } else { // pdfPagesObject is PdfPages int from = lastPdfPages == null?parent.GetFrom() : lastPdfPages.GetFrom() + lastPdfPages.GetCount(); lastPdfPages = new PdfPages(from, kidsCount, pdfPagesObject, parent); newParents.Add(lastPdfPages); kidsCount -= lastPdfPages.GetCount(); } } parents.JRemoveAt(parentIndex); for (int i = newParents.Count - 1; i >= 0; i--) { parents.Add(parentIndex, newParents[i]); } // recursive call, to load needed pageRef. // NOTE optimization? add to loadPage startParentIndex. LoadPage(pageNum); } else { int from = parent.GetFrom(); // Possible exception in case kids.getSize() < parent.getCount(). // In any case parent.getCount() has higher priority. // NOTE optimization? when we already found needed index for (int i = 0; i < parent.GetCount(); i++) { PdfDictionary kid = kids.GetAsDictionary(i); // make sure it's a dictionary if (kid != null) { pageRefs[from + i] = kid.GetIndirectReference(); } } } }
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); }