📄 pdfreader.java
字号:
/* * $Id: PdfReader.java 3537 2008-07-08 08:53:00Z blowagie $ * * Copyright 2001, 2002 Paulo Soares * * The contents of this file are subject to the Mozilla Public License Version 1.1 * (the "License"); you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the License. * * The Original Code is 'iText, a free JAVA-PDF library'. * * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie. * All Rights Reserved. * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved. * * Contributor(s): all the names of the contributors are added in the source code * where applicable. * * Alternatively, the contents of this file may be used under the terms of the * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the * provisions of LGPL are applicable instead of those above. If you wish to * allow use of your version of this file only under the terms of the LGPL * License and not to allow others to use your version of this file under * the MPL, indicate your decision by deleting the provisions above and * replace them with the notice and other provisions required by the LGPL. * If you do not delete the provisions above, a recipient may use your version * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE. * * This library is free software; you can redistribute it and/or modify it * under the terms of the MPL as stated above or under the terms of the GNU * Library General Public License as published by the Free Software Foundation; * either version 2 of the License, or any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more * details. * * If you didn't download this code from the following link, you should check if * you aren't using an obsolete version: * http://www.lowagie.com/iText/ */package com.lowagie.text.pdf;import java.io.ByteArrayInputStream;import java.io.ByteArrayOutputStream;import java.io.DataInputStream;import java.io.IOException;import java.io.InputStream;import java.net.URL;import java.util.ArrayList;import java.util.Arrays;import java.util.Collections;import java.util.HashMap;import java.util.Iterator;import java.util.List;import java.util.Map;import java.util.Set;import java.util.zip.InflaterInputStream;import java.util.Stack;import java.security.Key;import java.security.MessageDigest;import java.security.cert.Certificate;import com.lowagie.text.ExceptionConverter;import com.lowagie.text.PageSize;import com.lowagie.text.Rectangle;import com.lowagie.text.pdf.interfaces.PdfViewerPreferences;import com.lowagie.text.pdf.internal.PdfViewerPreferencesImp;import org.bouncycastle.cms.CMSEnvelopedData;import org.bouncycastle.cms.RecipientInformation;/** Reads a PDF document. * @author Paulo Soares (psoares@consiste.pt) * @author Kazuya Ujihara */public class PdfReader implements PdfViewerPreferences { static final PdfName pageInhCandidates[] = { PdfName.MEDIABOX, PdfName.ROTATE, PdfName.RESOURCES, PdfName.CROPBOX }; static final byte endstream[] = PdfEncodings.convertToBytes("endstream", null); static final byte endobj[] = PdfEncodings.convertToBytes("endobj", null); protected PRTokeniser tokens; // Each xref pair is a position // type 0 -> -1, 0 // type 1 -> offset, 0 // type 2 -> index, obj num protected int xref[]; protected HashMap objStmMark; protected IntHashtable objStmToOffset; protected boolean newXrefType; private ArrayList xrefObj; PdfDictionary rootPages; protected PdfDictionary trailer; protected PdfDictionary catalog; protected PageRefs pageRefs; protected PRAcroForm acroForm = null; protected boolean acroFormParsed = false; protected boolean encrypted = false; protected boolean rebuilt = false; protected int freeXref; protected boolean tampered = false; protected int lastXref; protected int eofPos; protected char pdfVersion; protected PdfEncryption decrypt; protected byte password[] = null; //added by ujihara for decryption protected Key certificateKey = null; //added by Aiken Sam for certificate decryption protected Certificate certificate = null; //added by Aiken Sam for certificate decryption protected String certificateKeyProvider = null; //added by Aiken Sam for certificate decryption private boolean ownerPasswordUsed; protected ArrayList strings = new ArrayList(); protected boolean sharedStreams = true; protected boolean consolidateNamedDestinations = false; protected int rValue; protected int pValue; private int objNum; private int objGen; private int fileLength; private boolean hybridXref; private int lastXrefPartial = -1; private boolean partial; private PRIndirectReference cryptoRef; private PdfViewerPreferencesImp viewerPreferences = new PdfViewerPreferencesImp(); private boolean encryptionError; /** * Holds value of property appendable. */ private boolean appendable; protected PdfReader() { } /** Reads and parses a PDF document. * @param filename the file name of the document * @throws IOException on error */ public PdfReader(String filename) throws IOException { this(filename, null); } /** Reads and parses a PDF document. * @param filename the file name of the document * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(String filename, byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(filename); readPdf(); } /** Reads and parses a PDF document. * @param pdfIn the byte array with the document * @throws IOException on error */ public PdfReader(byte pdfIn[]) throws IOException { this(pdfIn, null); } /** Reads and parses a PDF document. * @param pdfIn the byte array with the document * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(byte pdfIn[], byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(pdfIn); readPdf(); } /** Reads and parses a PDF document. * @param filename the file name of the document * @param certificate the certificate to read the document * @param certificateKey the private key of the certificate * @param certificateKeyProvider the security provider for certificateKey * @throws IOException on error */ public PdfReader(String filename, Certificate certificate, Key certificateKey, String certificateKeyProvider) throws IOException { this.certificate = certificate; this.certificateKey = certificateKey; this.certificateKeyProvider = certificateKeyProvider; tokens = new PRTokeniser(filename); readPdf(); } /** Reads and parses a PDF document. * @param url the URL of the document * @throws IOException on error */ public PdfReader(URL url) throws IOException { this(url, null); } /** Reads and parses a PDF document. * @param url the URL of the document * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(URL url, byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(new RandomAccessFileOrArray(url)); readPdf(); } /** * Reads and parses a PDF document. * @param is the <CODE>InputStream</CODE> containing the document. The stream is read to the * end but is not closed * @param ownerPassword the password to read the document * @throws IOException on error */ public PdfReader(InputStream is, byte ownerPassword[]) throws IOException { password = ownerPassword; tokens = new PRTokeniser(new RandomAccessFileOrArray(is)); readPdf(); } /** * Reads and parses a PDF document. * @param is the <CODE>InputStream</CODE> containing the document. The stream is read to the * end but is not closed * @throws IOException on error */ public PdfReader(InputStream is) throws IOException { this(is, null); } /** * Reads and parses a pdf document. Contrary to the other constructors only the xref is read * into memory. The reader is said to be working in "partial" mode as only parts of the pdf * are read as needed. The pdf is left open but may be closed at any time with * <CODE>PdfReader.close()</CODE>, reopen is automatic. * @param raf the document location * @param ownerPassword the password or <CODE>null</CODE> for no password * @throws IOException on error */ public PdfReader(RandomAccessFileOrArray raf, byte ownerPassword[]) throws IOException { password = ownerPassword; partial = true; tokens = new PRTokeniser(raf); readPdfPartial(); } /** Creates an independent duplicate. * @param reader the <CODE>PdfReader</CODE> to duplicate */ public PdfReader(PdfReader reader) { this.appendable = reader.appendable; this.consolidateNamedDestinations = reader.consolidateNamedDestinations; this.encrypted = reader.encrypted; this.rebuilt = reader.rebuilt; this.sharedStreams = reader.sharedStreams; this.tampered = reader.tampered; this.password = reader.password; this.pdfVersion = reader.pdfVersion; this.eofPos = reader.eofPos; this.freeXref = reader.freeXref; this.lastXref = reader.lastXref; this.tokens = new PRTokeniser(reader.tokens.getSafeFile()); if (reader.decrypt != null) this.decrypt = new PdfEncryption(reader.decrypt); this.pValue = reader.pValue; this.rValue = reader.rValue; this.xrefObj = new ArrayList(reader.xrefObj); for (int k = 0; k < reader.xrefObj.size(); ++k) { this.xrefObj.set(k, duplicatePdfObject((PdfObject)reader.xrefObj.get(k), this)); } this.pageRefs = new PageRefs(reader.pageRefs, this); this.trailer = (PdfDictionary)duplicatePdfObject(reader.trailer, this); this.catalog = (PdfDictionary)getPdfObject(trailer.get(PdfName.ROOT)); this.rootPages = (PdfDictionary)getPdfObject(catalog.get(PdfName.PAGES)); this.fileLength = reader.fileLength; this.partial = reader.partial; this.hybridXref = reader.hybridXref; this.objStmToOffset = reader.objStmToOffset; this.xref = reader.xref; this.cryptoRef = (PRIndirectReference)duplicatePdfObject(reader.cryptoRef, this); this.ownerPasswordUsed = reader.ownerPasswordUsed; } /** Gets a new file instance of the original PDF * document. * @return a new file instance of the original PDF document */ public RandomAccessFileOrArray getSafeFile() { return tokens.getSafeFile(); } protected PdfReaderInstance getPdfReaderInstance(PdfWriter writer) { return new PdfReaderInstance(this, writer); } /** Gets the number of pages in the document. * @return the number of pages in the document */ public int getNumberOfPages() { return pageRefs.size(); } /** Returns the document's catalog. This dictionary is not a copy, * any changes will be reflected in the catalog. * @return the document's catalog */ public PdfDictionary getCatalog() { return catalog; } /** Returns the document's acroform, if it has one. * @return the document's acroform */ public PRAcroForm getAcroForm() { if (!acroFormParsed) { acroFormParsed = true; PdfObject form = catalog.get(PdfName.ACROFORM); if (form != null) { try { acroForm = new PRAcroForm(this); acroForm.readAcroForm((PdfDictionary)getPdfObject(form)); } catch (Exception e) { acroForm = null; } } } return acroForm; } /** * Gets the page rotation. This value can be 0, 90, 180 or 270. * @param index the page number. The first page is 1 * @return the page rotation */ 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 {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -