use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class COSParser method parseXref.
/**
* Parses cross reference tables.
*
* @param startXRefOffset start offset of the first table
* @return the trailer dictionary
* @throws IOException if something went wrong
*/
protected COSDictionary parseXref(long startXRefOffset) throws IOException {
source.seek(startXRefOffset);
long startXrefOffset = Math.max(0, parseStartXref());
// check the startxref offset
long fixedOffset = checkXRefOffset(startXrefOffset);
if (fixedOffset > -1) {
startXrefOffset = fixedOffset;
}
document.setStartXref(startXrefOffset);
long prev = startXrefOffset;
// ---- parse whole chain of xref tables/object streams using PREV reference
Set<Long> prevSet = new HashSet<Long>();
while (prev > 0) {
// seek to xref table
source.seek(prev);
// skip white spaces
skipSpaces();
// -- parse xref
if (source.peek() == X) {
// use existing parser to parse xref table
if (!parseXrefTable(prev) || !parseTrailer()) {
throw new IOException("Expected trailer object at offset " + source.getPosition());
}
COSDictionary trailer = xrefTrailerResolver.getCurrentTrailer();
// check for a XRef stream, it may contain some object ids of compressed objects
if (trailer.containsKey(COSName.XREF_STM)) {
int streamOffset = trailer.getInt(COSName.XREF_STM);
// check the xref stream reference
fixedOffset = checkXRefOffset(streamOffset);
if (fixedOffset > -1 && fixedOffset != streamOffset) {
Log.w("PdfBox-Android", "/XRefStm offset " + streamOffset + " is incorrect, corrected to " + fixedOffset);
streamOffset = (int) fixedOffset;
trailer.setInt(COSName.XREF_STM, streamOffset);
}
if (streamOffset > 0) {
source.seek(streamOffset);
skipSpaces();
try {
parseXrefObjStream(prev, false);
} catch (IOException ex) {
if (isLenient) {
Log.e("PdfBox-Android", "Failed to parse /XRefStm at offset " + streamOffset, ex);
} else {
throw ex;
}
}
} else {
if (isLenient) {
Log.e("PdfBox-Android", "Skipped XRef stream due to a corrupt offset:" + streamOffset);
} else {
throw new IOException("Skipped XRef stream due to a corrupt offset:" + streamOffset);
}
}
}
prev = trailer.getLong(COSName.PREV);
if (prev > 0) {
// check the xref table reference
fixedOffset = checkXRefOffset(prev);
if (fixedOffset > -1 && fixedOffset != prev) {
prev = fixedOffset;
trailer.setLong(COSName.PREV, prev);
}
}
} else {
// parse xref stream
prev = parseXrefObjStream(prev, true);
if (prev > 0) {
// check the xref table reference
fixedOffset = checkXRefOffset(prev);
if (fixedOffset > -1 && fixedOffset != prev) {
prev = fixedOffset;
COSDictionary trailer = xrefTrailerResolver.getCurrentTrailer();
trailer.setLong(COSName.PREV, prev);
}
}
}
if (prevSet.contains(prev)) {
throw new IOException("/Prev loop at offset " + prev);
}
prevSet.add(prev);
}
// ---- build valid xrefs out of the xref chain
xrefTrailerResolver.setStartxref(startXrefOffset);
COSDictionary trailer = xrefTrailerResolver.getTrailer();
document.setTrailer(trailer);
document.setIsXRefStream(XRefType.STREAM == xrefTrailerResolver.getXrefType());
// check the offsets of all referenced objects
checkXrefOffsets();
// copy xref table
document.addXRefTable(xrefTrailerResolver.getXrefTable());
return trailer;
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class COSParser method parseDictionaryRecursive.
/**
* Resolves all not already parsed objects of a dictionary recursively.
*
* @param dictionaryObject dictionary to be parsed
* @throws IOException if something went wrong
*/
private void parseDictionaryRecursive(COSObject dictionaryObject) throws IOException {
parseObjectDynamically(dictionaryObject, true);
if (!(dictionaryObject.getObject() instanceof COSDictionary)) {
// to get the encryption directory
throw new IOException("Dictionary object expected at offset " + source.getPosition());
}
COSDictionary dictionary = (COSDictionary) dictionaryObject.getObject();
for (COSBase value : dictionary.getValues()) {
if (value instanceof COSObject) {
COSObject object = (COSObject) value;
if (object.getObject() == null) {
parseDictionaryRecursive(object);
}
}
}
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class COSParser method retrieveCOSDictionary.
private COSDictionary retrieveCOSDictionary(COSObjectKey key, long offset) throws IOException {
COSDictionary dictionary = null;
// handle compressed objects
if (offset < 0) {
COSObject compressedObject = document.getObjectFromPool(key);
if (compressedObject.getObject() == null) {
parseObjectStream((int) -offset);
}
COSBase baseObject = compressedObject.getObject();
if (baseObject instanceof COSDictionary) {
dictionary = (COSDictionary) baseObject;
}
} else {
source.seek(offset);
readObjectNumber();
readGenerationNumber();
readExpectedString(OBJ_MARKER, true);
if (source.peek() != '<') {
return null;
}
try {
dictionary = parseCOSDictionary();
} catch (IOException exception) {
Log.d("PdfBox-Android", "Skipped object " + key + ", either it's corrupt or not a dictionary");
}
}
return dictionary;
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class PDAnnotation method createAnnotation.
/**
* Create the correct annotation from the base COS object.
*
* @param base The COS object that is the annotation.
* @return The correctly typed annotation object.
*
* @throws IOException If the annotation type is unknown.
*/
public static PDAnnotation createAnnotation(COSBase base) throws IOException {
PDAnnotation annot = null;
if (base instanceof COSDictionary) {
COSDictionary annotDic = (COSDictionary) base;
String subtype = annotDic.getNameAsString(COSName.SUBTYPE);
if (PDAnnotationFileAttachment.SUB_TYPE.equals(subtype)) {
annot = new PDAnnotationFileAttachment(annotDic);
} else if (PDAnnotationLine.SUB_TYPE.equals(subtype)) {
annot = new PDAnnotationLine(annotDic);
} else if (PDAnnotationLink.SUB_TYPE.equals(subtype)) {
annot = new PDAnnotationLink(annotDic);
} else if (PDAnnotationPopup.SUB_TYPE.equals(subtype)) {
annot = new PDAnnotationPopup(annotDic);
} else if (PDAnnotationRubberStamp.SUB_TYPE.equals(subtype)) {
annot = new PDAnnotationRubberStamp(annotDic);
} else if (PDAnnotationSquareCircle.SUB_TYPE_SQUARE.equals(subtype) || PDAnnotationSquareCircle.SUB_TYPE_CIRCLE.equals(subtype)) {
annot = new PDAnnotationSquareCircle(annotDic);
} else if (PDAnnotationText.SUB_TYPE.equals(subtype)) {
annot = new PDAnnotationText(annotDic);
} else if (PDAnnotationTextMarkup.SUB_TYPE_HIGHLIGHT.equals(subtype) || PDAnnotationTextMarkup.SUB_TYPE_UNDERLINE.equals(subtype) || PDAnnotationTextMarkup.SUB_TYPE_SQUIGGLY.equals(subtype) || PDAnnotationTextMarkup.SUB_TYPE_STRIKEOUT.equals(subtype)) {
// see 12.5.6.10 Text Markup Annotations
annot = new PDAnnotationTextMarkup(annotDic);
} else if (PDAnnotationWidget.SUB_TYPE.equals(subtype)) {
annot = new PDAnnotationWidget(annotDic);
} else if (PDAnnotationMarkup.SUB_TYPE_FREETEXT.equals(subtype) || PDAnnotationMarkup.SUB_TYPE_POLYGON.equals(subtype) || PDAnnotationMarkup.SUB_TYPE_POLYLINE.equals(subtype) || PDAnnotationMarkup.SUB_TYPE_CARET.equals(subtype) || PDAnnotationMarkup.SUB_TYPE_INK.equals(subtype) || PDAnnotationMarkup.SUB_TYPE_SOUND.equals(subtype)) {
annot = new PDAnnotationMarkup(annotDic);
} else {
// TODO not yet implemented:
// Movie, Screen, PrinterMark, TrapNet, Watermark, 3D, Redact
annot = new PDAnnotationUnknown(annotDic);
Log.d("PdfBox-Android", "Unknown or unsupported annotation subtype " + subtype);
}
} else {
throw new IOException("Error: Unknown annotation type " + base);
}
return annot;
}
use of com.tom_roush.pdfbox.cos.COSDictionary in project PdfBox-Android by TomRoush.
the class PDPropBuild method getPubSec.
/**
* A build data dictionary for the PubSec software module
* that was used to create the parent signature.
*
* @return the PubSec as PDPropBuildPubSec object
*/
public PDPropBuildDataDict getPubSec() {
PDPropBuildDataDict pubSec = null;
COSDictionary pubSecDic = dictionary.getCOSDictionary(COSName.PUB_SEC);
if (pubSecDic != null) {
pubSec = new PDPropBuildDataDict(pubSecDic);
}
return pubSec;
}
Aggregations