/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef = (IndirectReferences)indirects[key]; if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } iRef.SetCopied(); PdfObject obj = CopyObject(PdfReader.GetPdfObjectRelease(inp)); AddToBody(obj, theRef); return(theRef); }
/** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public void AddPage(PdfImportedPage iPage) { int pageNum = SetFromIPage(iPage); PdfDictionary thePage = reader.GetPageN(pageNum); PRIndirectReference origRef = reader.GetPageOrigRef(pageNum); reader.ReleasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null && !iRef.Copied) { pageReferences.Add(iRef.Ref); iRef.SetCopied(); } pageRef = CurrentPage; if (iRef == null) { iRef = new IndirectReferences(pageRef); indirects[key] = iRef; } iRef.SetCopied(); PdfDictionary newPage = CopyDictionary(thePage); root.AddPage(newPage); iPage.SetCopied(); ++currentPageNumber; }
/// <summary> /// Translate a PRIndirectReference to a PdfIndirectReference /// In addition, translates the object numbers, and copies the /// referenced object to the output file. /// NB: PRIndirectReferences (and PRIndirectObjects) really need to know what /// file they came from, because each file has its own namespace. The translation /// we do from their namespace to ours is *at best* heuristic, and guaranteed to /// fail under some circumstances. /// </summary> protected virtual PdfIndirectReference CopyIndirect(PrIndirectReference inp) { PdfIndirectReference theRef; var key = new RefKey(inp); var iRef = (IndirectReferences)Indirects[key]; if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = Body.PdfIndirectReference; iRef = new IndirectReferences(theRef); Indirects[key] = iRef; } var obj = PdfReader.GetPdfObjectRelease(inp); if (obj != null && obj.IsDictionary()) { var type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.Page.Equals(type)) { return(theRef); } } iRef.SetCopied(); obj = CopyObject(obj); AddToBody(obj, theRef); return(theRef); }
/// <summary> /// Add an imported page to our output /// @throws IOException, BadPdfFormatException /// </summary> /// <param name="iPage">an imported page</param> public void AddPage(PdfImportedPage iPage) { var pageNum = SetFromIPage(iPage); var thePage = Reader.GetPageN(pageNum); var origRef = Reader.GetPageOrigRef(pageNum); Reader.ReleasePage(pageNum); var key = new RefKey(origRef); PdfIndirectReference pageRef; var iRef = (IndirectReferences)Indirects[key]; if (iRef != null && !iRef.Copied) { PageReferences.Add(iRef.Ref); iRef.SetCopied(); } pageRef = CurrentPage; if (iRef == null) { iRef = new IndirectReferences(pageRef); Indirects[key] = iRef; } iRef.SetCopied(); var newPage = CopyDictionary(thePage); Root.AddPage(newPage); ++currentPageNumber; }
/** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public void AddPage(PdfImportedPage iPage) { int pageNum = SetFromIPage(iPage); PdfDictionary thePage = reader.GetPageN(pageNum); PRIndirectReference origRef = reader.GetPageOrigRef(pageNum); reader.ReleasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef = (IndirectReferences)indirects[key]; // if we already have an iref for the page (we got here by another link) if (iRef != null) { pageRef = iRef.Ref; } else { pageRef = body.PdfIndirectReference; iRef = new IndirectReferences(pageRef); indirects[key] = iRef; } pageReferences.Add(pageRef); ++currentPageNumber; if (!iRef.Copied) { iRef.SetCopied(); PdfDictionary newPage = CopyDictionary(thePage); newPage.Put(PdfName.PARENT, topPageParent); AddToBody(newPage, pageRef); } root.AddPage(pageRef); pageNumbersToRefs.Add(pageRef); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp, bool keepStructure, bool directRootKids) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if ((keepStructure) && (directRootKids)) { if (obj is PdfDictionary) { PdfDictionary dict = (PdfDictionary)obj; if (dict.Contains(PdfName.PG)) { return(null); } } } if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return(theRef); } } iRef.SetCopied(); parentObjects[obj] = inp; PdfObject res = CopyObject(obj, keepStructure, directRootKids); if (disableIndirects.ContainsKey(obj)) { iRef.Copied = false; } if ((res != null) && !(res is PdfNull)) { AddToBody(res, theRef); return(theRef); } indirects.Remove(key); return(null); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; bool validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PRStream)srcObj); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return(streamRef); } } PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (srcObj != null && srcObj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return(theRef); } } iRef.SetCopied(); if (validStream) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return(theRef); }
public override bool Equals(Object o) { if (!(o is RefKey)) { return(false); } RefKey other = (RefKey)o; return(this.gen == other.gen && this.num == other.num); }
public override bool Equals(object o) { if (!(o is RefKey)) { return(false); } RefKey other = (RefKey)o; return(Gen == other.Gen && Num == other.Num); }
/// <summary> /// Translate a PRIndirectReference to a PdfIndirectReference /// In addition, translates the object numbers, and copies the /// referenced object to the output file if it wasn't available /// in the cache yet. If it's in the cache, the reference to /// the already used stream is returned. /// NB: PRIndirectReferences (and PRIndirectObjects) really need to know what /// file they came from, because each file has its own namespace. The translation /// we do from their namespace to ours is *at best* heuristic, and guaranteed to /// fail under some circumstances. /// </summary> protected override PdfIndirectReference CopyIndirect(PrIndirectReference inp) { var srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; var validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PrStream)srcObj); validStream = true; var streamRef = (PdfIndirectReference)_streamMap[streamKey]; if (streamRef != null) { return(streamRef); } } PdfIndirectReference theRef; var key = new RefKey(inp); var iRef = (IndirectReferences)Indirects[key]; if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = Body.PdfIndirectReference; iRef = new IndirectReferences(theRef); Indirects[key] = iRef; } if (srcObj != null && srcObj.IsDictionary()) { var type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null && PdfName.Page.Equals(type)) { return(theRef); } } iRef.SetCopied(); if (validStream) { _streamMap[streamKey] = theRef; } var obj = CopyObject(srcObj); AddToBody(obj, theRef); return(theRef); }
protected override PdfIndirectReference CopyIndirect(PRIndirectReference @in) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(@in); PdfSmartCopy.ByteStore streamKey = null; bool validStream = false; if (srcObj.IsStream()) { streamKey = new PdfSmartCopy.ByteStore((PRStream) srcObj, serialized); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return streamRef; } } else if (srcObj.IsDictionary()) { streamKey = new PdfSmartCopy.ByteStore((PdfDictionary) srcObj, serialized); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return streamRef; } } PdfIndirectReference theRef; RefKey key = new RefKey(@in); IndirectReferences iRef; if (indirects.TryGetValue(key, out iRef)) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (srcObj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary) srcObj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return theRef; } } iRef.SetCopied(); if (validStream) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return theRef; }
private void AddKid(PdfObject obj) { if (!obj.IsIndirect()) { return; } PRIndirectReference currRef = (PRIndirectReference)obj; RefKey key = new RefKey(currRef); if (!writer.indirects.ContainsKey(key)) { writer.CopyIndirect(currRef, true, false); } PdfIndirectReference newKid = writer.indirects[key].Ref; if (writer.updateRootKids) { AddKid(structureTreeRoot, newKid); } }
/// <summary> /// Copy the acroform for an input document. Note that you can only have one, /// we make no effort to merge them. /// @throws IOException, BadPdfFormatException /// </summary> /// <param name="reader">The reader of the input file that is being copied</param> public void CopyAcroForm(PdfReader reader) { SetFromReader(reader); var catalog = reader.Catalog; PrIndirectReference hisRef = null; var o = catalog.Get(PdfName.Acroform); if (o != null && o.Type == PdfObject.INDIRECT) { hisRef = (PrIndirectReference)o; } if (hisRef == null) { return; // bugfix by John Engla } var key = new RefKey(hisRef); PdfIndirectReference myRef; var iRef = (IndirectReferences)Indirects[key]; if (iRef != null) { acroForm = myRef = iRef.Ref; } else { acroForm = myRef = Body.PdfIndirectReference; iRef = new IndirectReferences(myRef); Indirects[key] = iRef; } if (!iRef.Copied) { iRef.SetCopied(); var theForm = CopyDictionary((PdfDictionary)PdfReader.GetPdfObject(hisRef)); AddToBody(theForm, myRef); } }
/** * Copy the acroform for an input document. Note that you can only have one, * we make no effort to merge them. * @param reader The reader of the input file that is being copied * @throws IOException, BadPdfFormatException */ public void CopyAcroForm(PdfReader reader) { SetFromReader(reader); PdfDictionary catalog = reader.Catalog; PRIndirectReference hisRef = null; PdfObject o = catalog.Get(PdfName.ACROFORM); if (o != null && o.Type == PdfObject.INDIRECT) { hisRef = (PRIndirectReference)o; } if (hisRef == null) { return; // bugfix by John Engla } RefKey key = new RefKey(hisRef); PdfIndirectReference myRef; IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { acroForm = myRef = iRef.Ref; } else { acroForm = myRef = body.PdfIndirectReference; iRef = new IndirectReferences(myRef); indirects[key] = iRef; } if (!iRef.Copied) { iRef.SetCopied(); PdfDictionary theForm = CopyDictionary((PdfDictionary)PdfReader.GetPdfObject(hisRef)); AddToBody(theForm, myRef); } }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return(theRef); } } iRef.SetCopied(); obj = CopyObject(obj); AddToBody(obj, theRef); return(theRef); }
public new PdfIndirectObject AddToBody(PdfObject objecta, PdfIndirectReference refa, bool formBranching) { if (formBranching) { UpdateReferences(objecta); } PdfIndirectObject indObj; if ((tagged || mergeFields) && indirectObjects != null && (objecta.IsArray() || objecta.IsDictionary() || objecta.IsStream())) { RefKey key = new RefKey(refa); PdfIndirectObject obj; if (!indirectObjects.TryGetValue(key, out obj)) { obj = new PdfIndirectObject(refa, objecta, this); indirectObjects[key] = obj; } indObj = obj; } else { indObj = base.AddToBody(objecta, refa); } if (mergeFields && objecta.IsDictionary()) { PdfNumber annotId = ((PdfDictionary)objecta).GetAsNumber(PdfCopy.annotId); if (annotId != null) { if (formBranching) { mergedMap[annotId.IntValue] = indObj; mergedSet.Add(indObj); } else { unmergedMap[annotId.IntValue] = indObj; unmergedSet.Add(indObj); } } } return indObj; }
/** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public virtual void AddPage(PdfImportedPage iPage) { if (mergeFields && !mergeFieldsInternalCall) { throw new ArgumentException(MessageLocalization.GetComposedMessage("1.method.cannot.be.used.in.mergeFields.mode.please.use.addDocument", "addPage")); } int pageNum = SetFromIPage(iPage); PdfDictionary thePage = reader.GetPageN(pageNum); PRIndirectReference origRef = reader.GetPageOrigRef(pageNum); reader.ReleasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef; if (indirects.TryGetValue(key, out iRef) && !iRef.Copied) { pageReferences.Add(iRef.Ref); iRef.SetCopied(); } pageRef = CurrentPage; if (iRef == null) { iRef = new IndirectReferences(pageRef); indirects[key] = iRef; } iRef.SetCopied(); if (tagged) structTreeRootReference = (PRIndirectReference)reader.Catalog.Get(PdfName.STRUCTTREEROOT); PdfDictionary newPage = CopyDictionary(thePage); root.AddPage(newPage); iPage.SetCopied(); ++currentPageNumber; structTreeRootReference = null; }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected internal virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp, bool keepStructure, bool directRootKids) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iref; indirects.TryGetValue(key, out iref); PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if ((keepStructure) && (directRootKids)) if (obj is PdfDictionary) { PdfDictionary dict = (PdfDictionary) obj; if (dict.Contains(PdfName.PG)) return null; } if (iref != null) { theRef = iref.Ref; if (iref.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iref = new IndirectReferences(theRef); indirects[key] = iref; } if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return theRef; } } iref.SetCopied(); parentObjects[obj] = inp; PdfObject res = CopyObject(obj, keepStructure, directRootKids); if (disableIndirects.Contains(obj)) iref.Copied = false; if ((res != null) && !(res is PdfNull)) { AddToBody(res, theRef); return theRef; } indirects.Remove(key); return null; }
//return new found objects private List<PdfIndirectReference> FindActiveParents(HashSet2<RefKey> activeKeys){ List<PdfIndirectReference> newRefs = new List<PdfIndirectReference>(); List<RefKey> tmpActiveKeys = new List<RefKey>(activeKeys); for (int i = 0; i < tmpActiveKeys.Count; ++i) { PdfIndirectObject iobj; if (!indirectObjects.TryGetValue(tmpActiveKeys[i], out iobj) || !iobj.objecti.IsDictionary()) continue; PdfObject parent = ((PdfDictionary)iobj.objecti).Get(PdfName.P); if (parent != null && parent.Type == 0) { RefKey key = new RefKey((PdfIndirectReference)parent); if (!activeKeys.Contains(key)) { activeKeys.Add(key); tmpActiveKeys.Add(key); newRefs.Add((PdfIndirectReference) parent); } } } return newRefs; }
/** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public void AddPage(PdfImportedPage iPage) { int pageNum = SetFromIPage(iPage); PdfDictionary thePage = reader.GetPageN(pageNum); PRIndirectReference origRef = reader.GetPageOrigRef(pageNum); reader.ReleasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef; if (indirects.TryGetValue(key, out iRef) && !iRef.Copied) { pageReferences.Add(iRef.Ref); iRef.SetCopied(); } pageRef = CurrentPage; if (iRef == null) { iRef = new IndirectReferences(pageRef); indirects[key] = iRef; } iRef.SetCopied(); if (tagged) structTreeRootReference = (PRIndirectReference)reader.Catalog.Get(PdfName.STRUCTTREEROOT); PdfDictionary newPage = CopyDictionary(thePage); root.AddPage(newPage); iPage.SetCopied(); ++currentPageNumber; structTreeRootReference = null; }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef = (IndirectReferences)indirects[key] ; if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } iRef.SetCopied(); PdfObject obj = CopyObject(PdfReader.GetPdfObjectRelease(inp)); AddToBody(obj, theRef); return theRef; }
public override bool Equals(Object o) { RefKey other = (RefKey)o; return(this.gen == other.gen && this.num == other.num); }
private void SerObject(PdfObject obj, int level, ByteBuffer bb, Dictionary <RefKey, int> serialized) { if (level <= 0) { return; } if (obj == null) { bb.Append("$Lnull"); return; } PdfIndirectReference refe = null; ByteBuffer savedBb = null; if (obj.IsIndirect()) { refe = (PdfIndirectReference)obj; RefKey key = new RefKey(refe); if (serialized.ContainsKey(key)) { bb.Append(serialized[key]); return; } else { savedBb = bb; bb = new ByteBuffer(); } } obj = PdfReader.GetPdfObject(obj); if (obj.IsStream()) { bb.Append("$B"); SerDic((PdfDictionary)obj, level - 1, bb, serialized); if (level > 0) { bb.Append(DigestAlgorithms.Digest("MD5", PdfReader.GetStreamBytesRaw((PRStream)obj))); } } else if (obj.IsDictionary()) { SerDic((PdfDictionary)obj, level - 1, bb, serialized); } else if (obj.IsArray()) { SerArray((PdfArray)obj, level - 1, bb, serialized); } else if (obj.IsString()) { bb.Append("$S").Append(obj.ToString()); } else if (obj.IsName()) { bb.Append("$N").Append(obj.ToString()); } else { bb.Append("$L").Append(obj.ToString()); } if (savedBb != null) { RefKey key = new RefKey(refe); if (!serialized.ContainsKey(key)) { serialized[key] = CalculateHash(bb.Buffer); } savedBb.Append(bb); } }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; bool validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PRStream)srcObj, serialized); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return(streamRef); } } else if (srcObj.IsDictionary()) { streamKey = new ByteStore((PdfDictionary)srcObj, serialized); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return(streamRef); } } PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return(theRef); } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (srcObj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null) { if ((PdfName.PAGE.Equals(type))) { return(theRef); } if ((PdfName.CATALOG.Equals(type))) { LOGGER.Warn(MessageLocalization.GetComposedMessage("make.copy.of.catalog.dictionary.is.forbidden")); return(null); } } } iRef.SetCopied(); if (validStream) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return(theRef); }
protected internal override void CacheObject(PdfIndirectObject iobj) { if ((tagged || mergeFields) && indirectObjects != null) { savedObjects.Add(iobj); RefKey key = new RefKey(iobj.Number, iobj.Generation); if (!indirectObjects.ContainsKey(key)) indirectObjects[key] = iobj; } }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; bool validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PRStream)srcObj); validStream = true; PdfIndirectReference streamRef = (PdfIndirectReference) streamMap[streamKey]; if (streamRef != null) { return streamRef; } } PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef = (IndirectReferences) indirects[key]; if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (srcObj != null && srcObj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return theRef; } } iRef.SetCopied(); if (validStream) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return theRef; }
public override PdfIndirectObject AddToBody(PdfObject objecta, PdfIndirectReference refa) { if (tagged && indirectObjects != null && (objecta.IsArray() || objecta.IsDictionary())) { RefKey key = new RefKey(refa); PdfIndirectObject obj; if (!indirectObjects.TryGetValue(key, out obj)) { obj = new PdfIndirectObject(refa, objecta, this); indirectObjects[key] = obj; } return obj; } else { if (tagged && objecta.IsStream()) streams.Add(new RefKey(refa)); return base.AddToBody(objecta, refa); } }
public override PdfIndirectObject AddToBody(PdfObject objecta) { PdfIndirectObject iobj = base.AddToBody(objecta); if ((tagged || mergeFields) && indirectObjects != null) { savedObjects.Add(iobj); RefKey key = new RefKey(iobj.Number, iobj.Generation); if (!indirectObjects.ContainsKey(key)) indirectObjects[key] = iobj; } return iobj; }
private void FindActivesFromReference(PdfIndirectReference iref, List<PdfIndirectReference> actives, HashSet2<RefKey> activeKeys) { RefKey key = new RefKey(iref); PdfIndirectObject iobj; if (indirectObjects.TryGetValue(key, out iobj) && iobj.objecti.IsDictionary() && ContainsInactivePg((PdfDictionary) iobj.objecti, activeKeys)) return; if(!activeKeys.Contains(key)) { activeKeys.Add(key); actives.Add(iref); } }
private void AddKid(PdfObject obj) { if (!obj.IsIndirect()) return; PRIndirectReference currRef = (PRIndirectReference)obj; RefKey key = new RefKey(currRef); if (!writer.indirects.ContainsKey(key)) { writer.CopyIndirect(currRef, true, false); } PdfIndirectReference newKid = writer.indirects[key].Ref; if (writer.updateRootKids) { AddKid(structureTreeRoot, newKid); } }
private void FindActives(List<PdfIndirectReference> actives, HashSet2<RefKey> activeKeys, HashSet2<PdfName> activeClassMaps){ //collect all active objects from current active set (include kids, classmap, attributes) for (int i = 0; i < actives.Count; ++i) { RefKey key = new RefKey(actives[i]); PdfIndirectObject iobj; if (!indirectObjects.TryGetValue(key, out iobj) || iobj.objecti == null) continue; switch (iobj.objecti.Type){ case 0://PdfIndirectReference FindActivesFromReference((PdfIndirectReference)iobj.objecti, actives, activeKeys); break; case PdfObject.ARRAY: FindActivesFromArray((PdfArray)iobj.objecti, actives, activeKeys, activeClassMaps); break; case PdfObject.DICTIONARY: case PdfObject.STREAM: FindActivesFromDict((PdfDictionary)iobj.objecti, actives, activeKeys, activeClassMaps); break; } } }
/** * Copy the acroform for an input document. Note that you can only have one, * we make no effort to merge them. * @param reader The reader of the input file that is being copied * @throws IOException, BadPdfFormatException */ public void CopyAcroForm(PdfReader reader) { SetFromReader(reader); PdfDictionary catalog = reader.Catalog; PRIndirectReference hisRef = null; PdfObject o = catalog.Get(PdfName.ACROFORM); if (o != null && o.Type == PdfObject.INDIRECT) hisRef = (PRIndirectReference)o; if (hisRef == null) return; // bugfix by John Engla RefKey key = new RefKey(hisRef); PdfIndirectReference myRef; IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { acroForm = myRef = iRef.Ref; } else { acroForm = myRef = body.PdfIndirectReference; iRef = new IndirectReferences(myRef); indirects[key] = iRef; } if (! iRef.Copied) { iRef.SetCopied(); PdfDictionary theForm = CopyDictionary((PdfDictionary)PdfReader.GetPdfObject(hisRef)); AddToBody(theForm, myRef); } }
private void SerObject(PdfObject obj, int level, ByteBuffer bb, Dictionary<RefKey, int> serialized) { if (level <= 0) return; if (obj == null) { bb.Append("$Lnull"); return; } PdfIndirectReference refe = null; ByteBuffer savedBb = null; if (obj.IsIndirect()) { refe = (PdfIndirectReference)obj; RefKey key = new RefKey(refe); if (serialized.ContainsKey(key)) { bb.Append(serialized[key]); return; } else { savedBb = bb; bb = new ByteBuffer(); } } obj = PdfReader.GetPdfObject(obj); if (obj.IsStream()) { bb.Append("$B"); SerDic((PdfDictionary)obj, level - 1, bb, serialized); if (level > 0) { bb.Append(DigestAlgorithms.Digest("MD5", PdfReader.GetStreamBytesRaw((PRStream)obj))); } } else if (obj.IsDictionary()) { SerDic((PdfDictionary)obj, level - 1, bb,serialized); } else if (obj.IsArray()) { SerArray((PdfArray)obj, level - 1, bb,serialized); } else if (obj.IsString()) { bb.Append("$S").Append(obj.ToString()); } else if (obj.IsName()) { bb.Append("$N").Append(obj.ToString()); } else bb.Append("$L").Append(obj.ToString()); if (savedBb != null) { RefKey key = new RefKey(refe); if (!serialized.ContainsKey(key)) serialized[key] = CalculateHash(bb.Buffer); savedBb.Append(bb); } }
virtual protected void FixTaggedStructure() { Dictionary<int, PdfIndirectReference> numTree = structureTreeRoot.NumTree; HashSet2<RefKey> activeKeys = new HashSet2<RefKey>(); List<PdfIndirectReference> actives = new List<PdfIndirectReference>(); int pageRefIndex = 0; if (mergeFields && acroForm != null) { actives.Add(acroForm); activeKeys.Add(new RefKey(acroForm)); } foreach (PdfIndirectReference page in pageReferences) { actives.Add(page); activeKeys.Add(new RefKey(page)); } //from end, because some objects can appear on several pages because of MCR (out16.pdf) for (int i = numTree.Count - 1; i >= 0; --i) { PdfIndirectReference currNum = numTree[i]; RefKey numKey = new RefKey(currNum); PdfObject obj = indirectObjects[numKey].objecti; if (obj.IsDictionary()) { bool addActiveKeys = false; if (pageReferences.Contains((PdfIndirectReference) ((PdfDictionary) obj).Get(PdfName.PG))) { addActiveKeys = true; } else { PdfDictionary k = PdfStructTreeController.GetKDict((PdfDictionary) obj); if (k != null && pageReferences.Contains((PdfIndirectReference) k.Get(PdfName.PG))) { addActiveKeys = true; } } if (addActiveKeys) { activeKeys.Add(numKey); actives.Add(currNum); } else { numTree.Remove(i); } } else if (obj.IsArray()) { activeKeys.Add(numKey); actives.Add(currNum); PdfArray currNums = (PdfArray) obj; PdfIndirectReference currPage = pageReferences[pageRefIndex++]; actives.Add(currPage); activeKeys.Add(new RefKey(currPage)); PdfIndirectReference prevKid = null; for (int j = 0; j < currNums.Size; j++) { PdfIndirectReference currKid = (PdfIndirectReference) currNums.GetDirectObject(j); if (currKid.Equals(prevKid)) continue; RefKey kidKey = new RefKey(currKid); activeKeys.Add(kidKey); actives.Add(currKid); PdfIndirectObject iobj = indirectObjects[kidKey]; if (iobj.objecti.IsDictionary()) { PdfDictionary dict = (PdfDictionary) iobj.objecti; PdfIndirectReference pg = (PdfIndirectReference) dict.Get(PdfName.PG); //if pg is real page - do nothing, else set correct pg and remove first MCID if exists if (pg != null && !pageReferences.Contains(pg) && !pg.Equals(currPage)) { dict.Put(PdfName.PG, currPage); PdfArray kids = dict.GetAsArray(PdfName.K); if (kids != null) { PdfObject firstKid = kids.GetDirectObject(0); if (firstKid.IsNumber()) kids.Remove(0); } } } prevKid = currKid; } } } HashSet2<PdfName> activeClassMaps = new HashSet2<PdfName>(); //collect all active objects from current active set (include kids, classmap, attributes) FindActives(actives, activeKeys, activeClassMaps); //find parents of active objects List<PdfIndirectReference> newRefs = FindActiveParents(activeKeys); //find new objects with incorrect Pg; if find, set Pg from first correct kid. This correct kid must be. FixPgKey(newRefs, activeKeys); //remove unused kids of StructTreeRoot and remove unused objects from class map FixStructureTreeRoot(activeKeys, activeClassMaps); List<RefKey> inactiveKeys = new List<RefKey>(); foreach(KeyValuePair<RefKey, PdfIndirectObject> entry in indirectObjects) { if (!activeKeys.Contains(entry.Key)) { inactiveKeys.Add(entry.Key); } else { if (entry.Value.objecti.IsArray()) { RemoveInactiveReferences((PdfArray)entry.Value.objecti, activeKeys); } else if (entry.Value.objecti.IsDictionary()) { PdfObject kids = ((PdfDictionary)entry.Value.objecti).Get(PdfName.K); if (kids != null && kids.IsArray()) RemoveInactiveReferences((PdfArray)kids, activeKeys); } } } //because of concurrent modification detected by CLR foreach (RefKey key in inactiveKeys) indirectObjects[key] = null; }
/** * Add an imported page to our output * @param iPage an imported page * @throws IOException, BadPdfFormatException */ public void AddPage(PdfImportedPage iPage) { int pageNum = SetFromIPage(iPage); PdfDictionary thePage = reader.GetPageN(pageNum); PRIndirectReference origRef = reader.GetPageOrigRef(pageNum); reader.ReleasePage(pageNum); RefKey key = new RefKey(origRef); PdfIndirectReference pageRef; IndirectReferences iRef = (IndirectReferences)indirects[key] ; iRef = null; // temporary hack to have multiple pages, may break is some cases // if we already have an iref for the page (we got here by another link) if (iRef != null) { pageRef = iRef.Ref; } else { pageRef = body.PdfIndirectReference; iRef = new IndirectReferences(pageRef); indirects[key] = iRef; } pageReferences.Add(pageRef); ++currentPageNumber; if (! iRef.Copied) { iRef.SetCopied(); PdfDictionary newPage = CopyDictionary(thePage); newPage.Put(PdfName.PARENT, topPageParent); AddToBody(newPage, pageRef); } root.AddPage(pageRef); pageNumbersToRefs.Add(pageRef); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; if (srcObj.Type == PdfObject.STREAM) { byte[] streamContent = PdfReader.GetStreamBytesRaw((PRStream) srcObj); // Only the content is compared, probably the keys should also be compared streamKey = new ByteStore(streamContent); PdfIndirectReference streamRef = (PdfIndirectReference) streamMap[streamKey]; if (streamRef != null) { return streamRef; } } PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef = (IndirectReferences) indirects[key]; if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } iRef.SetCopied(); if (srcObj.Type == PdfObject.STREAM) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return theRef; }
protected void FlushIndirectObjects() { foreach (PdfIndirectObject iobj in savedObjects) indirectObjects.Remove(new PdfCopy.RefKey(iobj.Number, iobj.Generation)); HashSet2<RefKey> inactives = new HashSet2<RefKey>(); foreach (KeyValuePair<RefKey, PdfIndirectObject> entry in indirectObjects) { if (entry.Value != null) WriteObjectToBody(entry.Value); else inactives.Add(entry.Key); } List<PdfBody.PdfCrossReference> xrefs = new List<PdfBody.PdfCrossReference>(); foreach (PdfBody.PdfCrossReference xref in body.xrefs.Keys) xrefs.Add(xref); foreach (PdfBody.PdfCrossReference cr in xrefs) { if (cr == null) continue; RefKey key = new RefKey(cr.Refnum, 0); if (inactives.Contains(key)) body.xrefs.Remove(cr); } indirectObjects = null; }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file. * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected virtual PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } PdfObject obj = PdfReader.GetPdfObjectRelease(inp); if (obj != null && obj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)obj).Get(PdfName.TYPE)); if (type != null && PdfName.PAGE.Equals(type)) { return theRef; } } iRef.SetCopied(); obj = CopyObject(obj); AddToBody(obj, theRef); return theRef; }
private void ClearIndirects(PdfReader reader) { Dictionary<RefKey, IndirectReferences> currIndirects = indirectMap[reader]; List<RefKey> forDelete = new List<RefKey>(); foreach (KeyValuePair<RefKey, IndirectReferences> entry in currIndirects) { PdfIndirectReference iRef = entry.Value.Ref; RefKey key = new RefKey(iRef); PdfIndirectObject iobj; if (!indirectObjects.TryGetValue(key, out iobj)) { forDelete.Add(entry.Key); } else if (iobj.objecti.IsArray() || iobj.objecti.IsDictionary() || iobj.objecti.IsStream()) { forDelete.Add(entry.Key); } } foreach (RefKey key in forDelete) currIndirects.Remove(key); }
/** * Translate a PRIndirectReference to a PdfIndirectReference * In addition, translates the object numbers, and copies the * referenced object to the output file if it wasn't available * in the cache yet. If it's in the cache, the reference to * the already used stream is returned. * * NB: PRIndirectReferences (and PRIndirectObjects) really need to know what * file they came from, because each file has its own namespace. The translation * we do from their namespace to ours is *at best* heuristic, and guaranteed to * fail under some circumstances. */ protected override PdfIndirectReference CopyIndirect(PRIndirectReference inp) { PdfObject srcObj = PdfReader.GetPdfObjectRelease(inp); ByteStore streamKey = null; bool validStream = false; if (srcObj.IsStream()) { streamKey = new ByteStore((PRStream)srcObj, serialized); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return streamRef; } } else if (srcObj.IsDictionary()) { streamKey = new ByteStore((PdfDictionary)srcObj, serialized); validStream = true; PdfIndirectReference streamRef; if (streamMap.TryGetValue(streamKey, out streamRef)) { return streamRef; } } PdfIndirectReference theRef; RefKey key = new RefKey(inp); IndirectReferences iRef; indirects.TryGetValue(key, out iRef); if (iRef != null) { theRef = iRef.Ref; if (iRef.Copied) { return theRef; } } else { theRef = body.PdfIndirectReference; iRef = new IndirectReferences(theRef); indirects[key] = iRef; } if (srcObj.IsDictionary()) { PdfObject type = PdfReader.GetPdfObjectRelease(((PdfDictionary)srcObj).Get(PdfName.TYPE)); if (type != null) { if ((PdfName.PAGE.Equals(type))) { return theRef; } if ((PdfName.CATALOG.Equals(type))) { LOGGER.Warn(MessageLocalization.GetComposedMessage("make.copy.of.catalog.dictionary.is.forbidden")); return null; } } } iRef.SetCopied(); if (validStream) { streamMap[streamKey] = theRef; } PdfObject obj = CopyObject(srcObj); AddToBody(obj, theRef); return theRef; }
internal void FixStructureTreeRoot(HashSet2<RefKey> activeKeys, HashSet2<PdfName> activeClassMaps) { Dictionary<PdfName, PdfObject> newClassMap = new Dictionary<PdfName, PdfObject>(activeClassMaps.Count); foreach (PdfName key in activeClassMaps) { PdfObject cm = structureTreeRoot.classes[key]; if (cm != null) newClassMap[key] = cm; } structureTreeRoot.classes = newClassMap; PdfArray kids = structureTreeRoot.GetAsArray(PdfName.K); if (kids != null) for (int i = 0; i < kids.Size; ++i) { PdfIndirectReference iref = (PdfIndirectReference) kids[i]; RefKey key = new RefKey(iref); if (!activeKeys.Contains(key)) kids.Remove(i--); } }