use of com.tom_roush.pdfbox.cos.COSStream in project PdfBox-Android by TomRoush.
the class Overlay method createStream.
private COSStream createStream(String content) throws IOException {
COSStream stream = inputPDFDocument.getDocument().createCOSStream();
OutputStream out = stream.createOutputStream(content.length() > 20 ? COSName.FLATE_DECODE : null);
out.write(content.getBytes("ISO-8859-1"));
out.close();
return stream;
}
use of com.tom_roush.pdfbox.cos.COSStream in project PdfBox-Android by TomRoush.
the class PDFCloneUtility method cloneMerge.
/**
* Merges two objects of the same type by deep-cloning its members.
* <br>
* Base and target must be instances of the same class.
* @param base the base object to be cloned
* @param target the merge target
* @throws IOException if an I/O error occurs
*/
public void cloneMerge(final COSObjectable base, COSObjectable target) throws IOException {
if (base == null) {
return;
}
COSBase retval = clonedVersion.get(base);
if (retval != null) {
return;
// we are done, it has already been converted. // ### Is that correct for cloneMerge???
}
// TODO what when clone-merging a clone? Does it ever happen?
if (!(base instanceof COSBase)) {
cloneMerge(base.getCOSObject(), target.getCOSObject());
} else if (base instanceof COSObject) {
if (target instanceof COSObject) {
cloneMerge(((COSObject) base).getObject(), ((COSObject) target).getObject());
} else if (target instanceof COSDictionary || target instanceof COSArray) {
cloneMerge(((COSObject) base).getObject(), target);
}
} else if (base instanceof COSArray) {
COSArray array = (COSArray) base;
for (int i = 0; i < array.size(); i++) {
((COSArray) target).add(cloneForNewDocument(array.get(i)));
}
} else if (base instanceof COSStream) {
// does that make sense???
COSStream originalStream = (COSStream) base;
COSStream stream = destination.getDocument().createCOSStream();
OutputStream output = stream.createOutputStream(originalStream.getFilters());
IOUtils.copy(originalStream.createInputStream(), output);
output.close();
clonedVersion.put(base, stream);
for (Map.Entry<COSName, COSBase> entry : originalStream.entrySet()) {
stream.setItem(entry.getKey(), cloneForNewDocument(entry.getValue()));
}
retval = stream;
} else if (base instanceof COSDictionary) {
COSDictionary dic = (COSDictionary) base;
clonedVersion.put(base, retval);
for (Map.Entry<COSName, COSBase> entry : dic.entrySet()) {
COSName key = entry.getKey();
COSBase value = entry.getValue();
if (((COSDictionary) target).getItem(key) != null) {
cloneMerge(value, ((COSDictionary) target).getItem(key));
} else {
((COSDictionary) target).setItem(key, cloneForNewDocument(value));
}
}
} else {
retval = (COSBase) base;
}
clonedVersion.put(base, retval);
clonedValues.add(retval);
}
use of com.tom_roush.pdfbox.cos.COSStream in project PdfBox-Android by TomRoush.
the class LayerUtility method wrapInSaveRestore.
/**
* Some applications may not wrap their page content in a save/restore (q/Q) pair which can
* lead to problems with coordinate system transformations when content is appended. This
* method lets you add a q/Q pair around the existing page's content.
* @param page the page
* @throws IOException if an I/O error occurs
*/
public void wrapInSaveRestore(PDPage page) throws IOException {
COSStream saveGraphicsStateStream = getDocument().getDocument().createCOSStream();
OutputStream saveStream = saveGraphicsStateStream.createOutputStream();
saveStream.write("q\n".getBytes("ISO-8859-1"));
saveStream.close();
COSStream restoreGraphicsStateStream = getDocument().getDocument().createCOSStream();
OutputStream restoreStream = restoreGraphicsStateStream.createOutputStream();
restoreStream.write("Q\n".getBytes("ISO-8859-1"));
restoreStream.close();
// Wrap the existing page's content in a save/restore pair (q/Q) to have a controlled
// environment to add additional content.
COSDictionary pageDictionary = page.getCOSObject();
COSBase contents = pageDictionary.getDictionaryObject(COSName.CONTENTS);
if (contents instanceof COSStream) {
COSStream contentsStream = (COSStream) contents;
COSArray array = new COSArray();
array.add(saveGraphicsStateStream);
array.add(contentsStream);
array.add(restoreGraphicsStateStream);
pageDictionary.setItem(COSName.CONTENTS, array);
} else if (contents instanceof COSArray) {
COSArray contentsArray = (COSArray) contents;
contentsArray.add(0, saveGraphicsStateStream);
contentsArray.add(restoreGraphicsStateStream);
} else {
throw new IOException("Contents are unknown type: " + contents.getClass().getName());
}
}
use of com.tom_roush.pdfbox.cos.COSStream in project PdfBox-Android by TomRoush.
the class COSParser method parseCOSStream.
/**
* This will read a COSStream from the input stream using length attribute within dictionary. If
* length attribute is a indirect reference it is first resolved to get the stream length. This
* means we copy stream data without testing for 'endstream' or 'endobj' and thus it is no
* problem if these keywords occur within stream. We require 'endstream' to be found after
* stream data is read.
*
* @param dic dictionary that goes with this stream.
*
* @return parsed pdf stream.
*
* @throws IOException if an error occurred reading the stream, like problems with reading
* length attribute, stream does not end with 'endstream' after data read, stream too short etc.
*/
protected COSStream parseCOSStream(COSDictionary dic) throws IOException {
COSStream stream = document.createCOSStream(dic);
// read 'stream'; this was already tested in parseObjectsDynamically()
readString();
skipWhiteSpaces();
/*
* This needs to be dic.getItem because when we are parsing, the underlying object might still be null.
*/
COSNumber streamLengthObj = getLength(dic.getItem(COSName.LENGTH), dic.getCOSName(COSName.TYPE));
if (streamLengthObj == null) {
if (isLenient) {
Log.w("PdfBox-Android", "The stream doesn't provide any stream length, using fallback readUntilEnd, at offset " + source.getPosition());
} else {
throw new IOException("Missing length for stream.");
}
}
// get output stream to copy data to
if (streamLengthObj != null && validateStreamLength(streamLengthObj.longValue())) {
OutputStream out = stream.createRawOutputStream();
try {
readValidStream(out, streamLengthObj);
} finally {
out.close();
// restore original (possibly incorrect) length
stream.setItem(COSName.LENGTH, streamLengthObj);
}
} else {
OutputStream out = stream.createRawOutputStream();
try {
readUntilEndStream(new EndstreamOutputStream(out));
} finally {
out.close();
// restore original (possibly incorrect) length
if (streamLengthObj != null) {
stream.setItem(COSName.LENGTH, streamLengthObj);
}
}
}
String endStream = readString();
if (endStream.equals("endobj") && isLenient) {
Log.w("PdfBox-Android", "stream ends with 'endobj' instead of 'endstream' at offset " + source.getPosition());
// avoid follow-up warning about missing endobj
source.rewind(ENDOBJ.length);
} else if (endStream.length() > 9 && isLenient && endStream.substring(0, 9).equals(ENDSTREAM_STRING)) {
Log.w("PdfBox-Android", "stream ends with '" + endStream + "' instead of 'endstream' at offset " + source.getPosition());
// unread the "extra" bytes
source.rewind(endStream.substring(9).getBytes(ISO_8859_1).length);
} else if (!endStream.equals(ENDSTREAM_STRING)) {
throw new IOException("Error reading stream, expected='endstream' actual='" + endStream + "' at offset " + source.getPosition());
}
return stream;
}
use of com.tom_roush.pdfbox.cos.COSStream in project PdfBox-Android by TomRoush.
the class FDFFieldTest method testTextAsCOSStreamValue.
@Test
public void testTextAsCOSStreamValue() throws IOException {
String testString = "Test value";
byte[] testBytes = testString.getBytes("ASCII");
COSStream stream = createStream(testBytes, null);
FDFField field = new FDFField();
field.setValue(stream);
assertEquals(testString, field.getValue());
}
Aggregations