Q: My ultimate goal is to read the xml template from a pdf generated
with Adobe LiveCycle Designer, modify the xml and then replace the
modified xml back into the file. So far, I can get the xml, but can't
completely replace the stream succesfully. Thanks to your response I
can replace the stream but the new saved file is no longer recognized
by LiveCycle Designer. Upon further investigation, it apears that the
stream is replaced correctly, but the information that tells how the
stream is encoded in the PDF is lost. The following code illustrates
the point. Notice that before the stream swap the raw and decoded
first byte of the buffer values are different, but after the swap they
are the same. The output is: Pre Raw: 72, Pre Decoded 10, Post Raw:
72, Post Decoded: 72
How do I replace the stream while keeping the stream encode info in
the pdf file? What is the encoding\\decoding used (I could not find
it using GetDecodeName or GetAttachedFilter)? How do I get from Obj
new_xmp_stm = doc.CreateIndirectStream(new System.Text.UTF8Encoding
().GetBytes(str)); to the proper encoded stream to swap with the the
origional pdf file stream AND still allow the file to know what
encoding was used?
PDFDoc doc = new PDFDoc(@\"C:\\a\\PdfScript\\PdfScript\\test.pdf\");
doc.InitSecurityHandler();
Obj acro_form = doc.GetAcroForm();
if (acro_form != null)
{
// This PDF document contains forms...
if (acro_form.FindObj(\"XFA\") != null)
{
// This PDF document contains XFA forms...
Obj obj = acro_form.FindObj(\"XFA\");
byte[] buff = new byte[4000];
byte byteRawPre, byteDecodePre, byteRawPost, byteDecodePost;
pdftron.Filters.Filter filter;
pdftron.Filters.FilterReader fr;
filter = obj.GetAt(5).GetDecodedStream();
fr = new pdftron.Filters.FilterReader(filter);
fr.Read(buff);
byteDecodePre = buff[0];
filter = obj.GetAt(5).GetRawStream(false);
fr = new pdftron.Filters.FilterReader(filter);
fr.Read(buff);
byteRawPre = buff[0];
//replace stream with raw stream
Obj new_xmp_stm = doc.CreateIndirectStream(buff);//raw stream
doc.GetSDFDoc().Swap(new_xmp_stm.GetObjNum(), acro_form.Get(\"XFA
\").Value().GetAt(5).GetObjNum());
filter = obj.GetAt(5).GetDecodedStream();
fr = new pdftron.Filters.FilterReader(filter);
fr.Read(buff);
byteDecodePost = buff[0];
filter = obj.GetAt(5).GetRawStream(false);
fr = new pdftron.Filters.FilterReader(filter);
fr.Read(buff);
byteRawPost = buff[0];
string resStr = string.Format(
\"Pre Raw: {0}, Pre Decoded {1}, Post Raw: {2}, Post
Decoded: {3}\",
byteRawPre.ToString(), byteDecodePre.ToString(),
byteRawPost.ToString(), byteDecodePost.ToString());
MessageBox.Show(resStr);
doc.Save(@\"C:\\a\\PdfScript\\PdfScript\\test_out.pdf\",
SDFDoc.SaveOptions.e_linearized);
doc.Close();
}
}
//Note: You sent me an alternative: acro_form.Get(\"XFA\").Value
().PutAt(5, new_xmp_stm);
//But there is no PutAt in your library
----
A: To create Flate encoded (compressed) stream you need to pass a
second paramater to doc.CreateIndirectStream(reader, encoder). For
example:
// In C#
Obj new_stm = doc.CreateIndirectStream(reader, new FlateEncode
(null));
Regaring 'PutAt', sorry it was a typo. The correct method is Insert
(idx, val).