/** * read an entire PDFObject. The intro line, which looks something like "4 0 obj" has already been * read. * * @param objNum the object number of the object being read, being the first number in the intro * line (4 in "4 0 obj") * @param objGen the object generation of the object being read, being the second number in the * intro line (0 in "4 0 obj"). * @param decrypter the decrypter to use */ private PDFObject readObjectDescription(int objNum, int objGen, PDFDecrypter decrypter) throws IOException { // we've already read the 4 0 obj bit. Next thing up is the object. // object descriptions end with the keyword endobj long debugpos = this.buf.position(); PDFObject obj = readObject(objNum, objGen, decrypter); // see if it's a dictionary. If so, this could be a stream. PDFObject endkey = readObject(objNum, objGen, decrypter); if (endkey.getType() != PDFObject.KEYWORD && endkey.getType() != PDFObject.STREAM) { PDFDebugger.debug( "WARNING: Expected 'stream' or 'endobj' but was " + endkey.getType() + " " + String.valueOf(endkey.getStringValue())); } if (obj.getType() == PDFObject.DICTIONARY && endkey.getStringValue() != null && endkey.getStringValue().equals("stream")) { // skip until we see \n readLine(); ByteBuffer data = readStream(obj); if (data == null) { data = ByteBuffer.allocate(0); } obj.setStream(data); endkey = readObject(objNum, objGen, decrypter); } // at this point, obj is the object, keyword should be "endobj" String endcheck = endkey.getStringValue(); if (endcheck == null || !endcheck.equals("endobj")) { PDFDebugger.debug("WARNING: object at " + debugpos + " didn't end with 'endobj'"); } obj.setObjectId(objNum, objGen); return obj; }
/** * read the stream portion of a PDFObject. Calls decodeStream to un-filter the stream as * necessary. * * @param dict the dictionary associated with this stream. * @return a ByteBuffer with the encoded stream data */ private ByteBuffer readStream(PDFObject dict) throws IOException { // pointer is at the start of a stream. read the stream and // decode, based on the entries in the dictionary PDFObject lengthObj = dict.getDictRef("Length"); int length = -1; if (lengthObj != null) { length = lengthObj.getIntValue(); } if (length < 0) { throw new PDFParseException("Unknown length for stream"); } // slice the data int start = this.buf.position(); ByteBuffer streamBuf = this.buf.slice(); streamBuf.limit(length); // move the current position to the end of the data this.buf.position(this.buf.position() + length); int ending = this.buf.position(); if (!nextItemIs("endstream")) { PDFDebugger.debug("read " + length + " chars from " + start + " to " + ending); throw new PDFParseException("Stream ended inappropriately"); } return streamBuf; // now decode stream // return PDFDecoder.decodeStream(dict, streamBuf); }