📄 pdfreader.java
字号:
*/
public int getPageRotation(int index) {
return getPageRotation(pageRefs.getPageNRelease(index));
}
int getPageRotation(PdfDictionary page) {
PdfNumber rotate = (PdfNumber)getPdfObject(page.get(PdfName.ROTATE));
if (rotate == null)
return 0;
else {
int n = rotate.intValue();
n %= 360;
return n < 0 ? n + 360 : n;
}
}
/** Gets the page size, taking rotation into account. This
* is a <CODE>Rectangle</CODE> with the value of the /MediaBox and the /Rotate key.
* @param index the page number. The first page is 1
* @return a <CODE>Rectangle</CODE>
*/
public Rectangle getPageSizeWithRotation(int index) {
return getPageSizeWithRotation(pageRefs.getPageNRelease(index));
}
/**
* Gets the rotated page from a page dictionary.
* @param page the page dictionary
* @return the rotated page
*/
public Rectangle getPageSizeWithRotation(PdfDictionary page) {
Rectangle rect = getPageSize(page);
int rotation = getPageRotation(page);
while (rotation > 0) {
rect = rect.rotate();
rotation -= 90;
}
return rect;
}
/** Gets the page size without taking rotation into account. This
* is the value of the /MediaBox key.
* @param index the page number. The first page is 1
* @return the page size
*/
public Rectangle getPageSize(int index) {
return getPageSize(pageRefs.getPageNRelease(index));
}
/**
* Gets the page from a page dictionary
* @param page the page dictionary
* @return the page
*/
public Rectangle getPageSize(PdfDictionary page) {
PdfArray mediaBox = (PdfArray)getPdfObject(page.get(PdfName.MEDIABOX));
return getNormalizedRectangle(mediaBox);
}
/** Gets the crop box without taking rotation into account. This
* is the value of the /CropBox key. The crop box is the part
* of the document to be displayed or printed. It usually is the same
* as the media box but may be smaller. If the page doesn't have a crop
* box the page size will be returned.
* @param index the page number. The first page is 1
* @return the crop box
*/
public Rectangle getCropBox(int index) {
PdfDictionary page = pageRefs.getPageNRelease(index);
PdfArray cropBox = (PdfArray)getPdfObjectRelease(page.get(PdfName.CROPBOX));
if (cropBox == null)
return getPageSize(page);
return getNormalizedRectangle(cropBox);
}
/** Gets the box size. Allowed names are: "crop", "trim", "art", "bleed" and "media".
* @param index the page number. The first page is 1
* @param boxName the box name
* @return the box rectangle or null
*/
public Rectangle getBoxSize(int index, String boxName) {
PdfDictionary page = pageRefs.getPageNRelease(index);
PdfArray box = null;
if (boxName.equals("trim"))
box = (PdfArray)getPdfObjectRelease(page.get(PdfName.TRIMBOX));
else if (boxName.equals("art"))
box = (PdfArray)getPdfObjectRelease(page.get(PdfName.ARTBOX));
else if (boxName.equals("bleed"))
box = (PdfArray)getPdfObjectRelease(page.get(PdfName.BLEEDBOX));
else if (boxName.equals("crop"))
box = (PdfArray)getPdfObjectRelease(page.get(PdfName.CROPBOX));
else if (boxName.equals("media"))
box = (PdfArray)getPdfObjectRelease(page.get(PdfName.MEDIABOX));
if (box == null)
return null;
return getNormalizedRectangle(box);
}
/** Returns the content of the document information dictionary as a <CODE>HashMap</CODE>
* of <CODE>String</CODE>.
* @return content of the document information dictionary
*/
public HashMap getInfo() {
HashMap map = new HashMap();
PdfDictionary info = (PdfDictionary)getPdfObject(trailer.get(PdfName.INFO));
if (info == null)
return map;
for (Iterator it = info.getKeys().iterator(); it.hasNext();) {
PdfName key = (PdfName)it.next();
PdfObject obj = getPdfObject(info.get(key));
if (obj == null)
continue;
String value = obj.toString();
switch (obj.type()) {
case PdfObject.STRING: {
value = ((PdfString)obj).toUnicodeString();
break;
}
case PdfObject.NAME: {
value = PdfName.decodeName(value);
break;
}
}
map.put(PdfName.decodeName(key.toString()), value);
}
return map;
}
/** Normalizes a <CODE>Rectangle</CODE> so that llx and lly are smaller than urx and ury.
* @param box the original rectangle
* @return a normalized <CODE>Rectangle</CODE>
*/
public static Rectangle getNormalizedRectangle(PdfArray box) {
ArrayList rect = box.getArrayList();
float llx = ((PdfNumber)rect.get(0)).floatValue();
float lly = ((PdfNumber)rect.get(1)).floatValue();
float urx = ((PdfNumber)rect.get(2)).floatValue();
float ury = ((PdfNumber)rect.get(3)).floatValue();
return new Rectangle(Math.min(llx, urx), Math.min(lly, ury),
Math.max(llx, urx), Math.max(lly, ury));
}
protected void readPdf() throws IOException {
try {
fileLength = tokens.getFile().length();
pdfVersion = tokens.checkPdfHeader();
try {
readXref();
}
catch (Exception e) {
try {
rebuilt = true;
rebuildXref();
lastXref = -1;
}
catch (Exception ne) {
throw new IOException("Rebuild failed: " + ne.getMessage() + "; Original message: " + e.getMessage());
}
}
try {
readDocObj();
}
catch (Exception ne) {
if (rebuilt)
throw new IOException(ne.getMessage());
rebuilt = true;
encrypted = false;
rebuildXref();
lastXref = -1;
readDocObj();
}
strings.clear();
readPages();
eliminateSharedStreams();
removeUnusedObjects();
}
finally {
try {
tokens.close();
}
catch (Exception e) {
// empty on purpose
}
}
}
protected void readPdfPartial() throws IOException {
try {
fileLength = tokens.getFile().length();
pdfVersion = tokens.checkPdfHeader();
try {
readXref();
}
catch (Exception e) {
try {
rebuilt = true;
rebuildXref();
lastXref = -1;
}
catch (Exception ne) {
throw new IOException("Rebuild failed: " + ne.getMessage() + "; Original message: " + e.getMessage());
}
}
readDocObjPartial();
readPages();
}
catch (IOException e) {
try{tokens.close();}catch(Exception ee){}
throw e;
}
}
private boolean equalsArray(byte ar1[], byte ar2[], int size) {
for (int k = 0; k < size; ++k) {
if (ar1[k] != ar2[k])
return false;
}
return true;
}
/**
* @throws IOException
*/
private void readDecryptedDocObj() throws IOException {
if (encrypted)
return;
PdfObject encDic = trailer.get(PdfName.ENCRYPT);
if (encDic == null || encDic.toString().equals("null"))
return;
byte[] encryptionKey = null;
encrypted = true;
PdfDictionary enc = (PdfDictionary)getPdfObject(encDic);
String s;
PdfObject o;
PdfArray documentIDs = (PdfArray)getPdfObject(trailer.get(PdfName.ID));
byte documentID[] = null;
if (documentIDs != null) {
o = (PdfObject)documentIDs.getArrayList().get(0);
strings.remove(o);
s = o.toString();
documentID = com.lowagie.text.DocWriter.getISOBytes(s);
if (documentIDs.size() > 1)
strings.remove(documentIDs.getArrayList().get(1));
}
byte uValue[] = null;
byte oValue[] = null;
int cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40;
int lengthValue = 0;
PdfObject filter = getPdfObjectRelease(enc.get(PdfName.FILTER));
if (filter.equals(PdfName.STANDARD))
{
s = enc.get(PdfName.U).toString();
strings.remove(enc.get(PdfName.U));
uValue = com.lowagie.text.DocWriter.getISOBytes(s);
s = enc.get(PdfName.O).toString();
strings.remove(enc.get(PdfName.O));
oValue = com.lowagie.text.DocWriter.getISOBytes(s);
o = enc.get(PdfName.R);
if (!o.isNumber()) throw new IOException("Illegal R value.");
rValue = ((PdfNumber)o).intValue();
if (rValue != 2 && rValue != 3 && rValue != 4)
throw new IOException("Unknown encryption type (" + rValue + ")");
o = enc.get(PdfName.P);
if (!o.isNumber()) throw new IOException("Illegal P value.");
pValue = ((PdfNumber)o).intValue();
if ( rValue == 3 ){
o = enc.get(PdfName.LENGTH);
if (!o.isNumber())
throw new IOException("Illegal Length value.");
lengthValue = ( (PdfNumber) o).intValue();
if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0)
throw new IOException("Illegal Length value.");
cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
} else if (rValue == 4) {
PdfDictionary dic = (PdfDictionary)enc.get(PdfName.CF);
if (dic == null)
throw new IOException("/CF not found (encryption)");
dic = (PdfDictionary)dic.get(PdfName.STDCF);
if (dic == null)
throw new IOException("/StdCF not found (encryption)");
if (PdfName.V2.equals(dic.get(PdfName.CFM)))
cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
else if (PdfName.AESV2.equals(dic.get(PdfName.CFM)))
cryptoMode = PdfWriter.ENCRYPTION_AES_128;
else
throw new IOException("No compatible encryption found");
PdfObject em = enc.get(PdfName.ENCRYPTMETADATA);
if (em != null && em.toString().equals("false"))
cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA;
} else {
cryptoMode = PdfWriter.STANDARD_ENCRYPTION_40;
}
} else if (filter.equals(PdfName.PUBSEC)) {
boolean foundRecipient = false;
byte[] envelopedData = null;
PdfArray recipients = null;
o = enc.get(PdfName.V);
if (!o.isNumber()) throw new IOException("Illegal V value.");
int vValue = ((PdfNumber)o).intValue();
if (vValue != 1 && vValue != 2 && vValue != 4)
throw new IOException("Unknown encryption type V = " + rValue);
if ( vValue == 2 ){
o = enc.get(PdfName.LENGTH);
if (!o.isNumber())
throw new IOException("Illegal Length value.");
lengthValue = ( (PdfNumber) o).intValue();
if (lengthValue > 128 || lengthValue < 40 || lengthValue % 8 != 0)
throw new IOException("Illegal Length value.");
cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
recipients = (PdfArray)enc.get(PdfName.RECIPIENTS);
} else if (vValue == 4) {
PdfDictionary dic = (PdfDictionary)enc.get(PdfName.CF);
if (dic == null)
throw new IOException("/CF not found (encryption)");
dic = (PdfDictionary)dic.get(PdfName.DEFAULTCRYPTFILER);
if (dic == null)
throw new IOException("/DefaultCryptFilter not found (encryption)");
if (PdfName.V2.equals(dic.get(PdfName.CFM)))
{
cryptoMode = PdfWriter.STANDARD_ENCRYPTION_128;
lengthValue = 128;
}
else if (PdfName.AESV2.equals(dic.get(PdfName.CFM)))
{
cryptoMode = PdfWriter.ENCRYPTION_AES_128;
lengthValue = 128;
}
else
throw new IOException("No compatible encryption found");
PdfObject em = dic.get(PdfName.ENCRYPTMETADATA);
if (em != null && em.toString().equals("false"))
cryptoMode |= PdfWriter.DO_NOT_ENCRYPT_METADATA;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -