⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 pdfreader.java

📁 处理PDF
💻 JAVA
📖 第 1 页 / 共 5 页
字号:
            int length = ((PdfNumber)sections.get(idx + 1)).intValue();            ensureXrefSize((start + length) * 2);            while (length-- > 0) {                int type = 1;                if (wc[0] > 0) {                    type = 0;                    for (int k = 0; k < wc[0]; ++k)                        type = (type << 8) + (b[bptr++] & 0xff);                }                int field2 = 0;                for (int k = 0; k < wc[1]; ++k)                    field2 = (field2 << 8) + (b[bptr++] & 0xff);                int field3 = 0;                for (int k = 0; k < wc[2]; ++k)                    field3 = (field3 << 8) + (b[bptr++] & 0xff);                int base = start * 2;                if (xref[base] == 0 && xref[base + 1] == 0) {                    switch (type) {                        case 0:                            xref[base] = -1;                            break;                        case 1:                            xref[base] = field2;                            break;                        case 2:                            xref[base] = field3;                            xref[base + 1] = field2;                            if (partial) {                                objStmToOffset.put(field2, 0);                            }                            else {                                Integer on = new Integer(field2);                                IntHashtable seq = (IntHashtable)objStmMark.get(on);                                if (seq == null) {                                    seq = new IntHashtable();                                    seq.put(field3, 1);                                    objStmMark.put(on, seq);                                }                                else                                    seq.put(field3, 1);                            }                            break;                    }                }                ++start;            }        }        thisStream *= 2;        if (thisStream < xref.length)            xref[thisStream] = -1;        if (prev == -1)            return true;        return readXRefStream(prev);    }    protected void rebuildXref() throws IOException {        hybridXref = false;        newXrefType = false;        tokens.seek(0);        int xr[][] = new int[1024][];        int top = 0;        trailer = null;        byte line[] = new byte[64];        for (;;) {            int pos = tokens.getFilePointer();            if (!tokens.readLineSegment(line))                break;            if (line[0] == 't') {                if (!PdfEncodings.convertToString(line, null).startsWith("trailer"))                    continue;                tokens.seek(pos);                tokens.nextToken();                pos = tokens.getFilePointer();                try {                    PdfDictionary dic = (PdfDictionary)readPRObject();                    if (dic.get(PdfName.ROOT) != null)                        trailer = dic;                    else                        tokens.seek(pos);                }                catch (Exception e) {                    tokens.seek(pos);                }            }            else if (line[0] >= '0' && line[0] <= '9') {                int obj[] = PRTokeniser.checkObjectStart(line);                if (obj == null)                    continue;                int num = obj[0];                int gen = obj[1];                if (num >= xr.length) {                    int newLength = num * 2;                    int xr2[][] = new int[newLength][];                    System.arraycopy(xr, 0, xr2, 0, top);                    xr = xr2;                }                if (num >= top)                    top = num + 1;                if (xr[num] == null || gen >= xr[num][1]) {                    obj[0] = pos;                    xr[num] = obj;                }            }        }        if (trailer == null)            throw new IOException("trailer not found.");        xref = new int[top * 2];        for (int k = 0; k < top; ++k) {            int obj[] = xr[k];            if (obj != null)                xref[k * 2] = obj[0];        }    }    protected PdfDictionary readDictionary() throws IOException {        PdfDictionary dic = new PdfDictionary();        while (true) {            tokens.nextValidToken();            if (tokens.getTokenType() == PRTokeniser.TK_END_DIC)                break;            if (tokens.getTokenType() != PRTokeniser.TK_NAME)                tokens.throwError("Dictionary key is not a name.");            PdfName name = new PdfName(tokens.getStringValue(), false);            PdfObject obj = readPRObject();            int type = obj.type();            if (-type == PRTokeniser.TK_END_DIC)                tokens.throwError("Unexpected '>>'");            if (-type == PRTokeniser.TK_END_ARRAY)                tokens.throwError("Unexpected ']'");            dic.put(name, obj);        }        return dic;    }    protected PdfArray readArray() throws IOException {        PdfArray array = new PdfArray();        while (true) {            PdfObject obj = readPRObject();            int type = obj.type();            if (-type == PRTokeniser.TK_END_ARRAY)                break;            if (-type == PRTokeniser.TK_END_DIC)                tokens.throwError("Unexpected '>>'");            array.add(obj);        }        return array;    }    protected PdfObject readPRObject() throws IOException {        tokens.nextValidToken();        int type = tokens.getTokenType();        switch (type) {            case PRTokeniser.TK_START_DIC: {                PdfDictionary dic = readDictionary();                int pos = tokens.getFilePointer();                // be careful in the trailer. May not be a "next" token.                if (tokens.nextToken() && tokens.getStringValue().equals("stream")) {                    int ch = tokens.read();                    if (ch != '\n')                        ch = tokens.read();                    if (ch != '\n')                        tokens.backOnePosition(ch);                    PRStream stream = new PRStream(this, tokens.getFilePointer());                    stream.putAll(dic);                    stream.setObjNum(objNum, objGen);                    return stream;                }                else {                    tokens.seek(pos);                    return dic;                }            }            case PRTokeniser.TK_START_ARRAY:                return readArray();            case PRTokeniser.TK_NUMBER:                return new PdfNumber(tokens.getStringValue());            case PRTokeniser.TK_STRING:                PdfString str = new PdfString(tokens.getStringValue(), null).setHexWriting(tokens.isHexString());                str.setObjNum(objNum, objGen);                if (strings != null)                    strings.add(str);                return str;            case PRTokeniser.TK_NAME:                return new PdfName(tokens.getStringValue(), false);            case PRTokeniser.TK_REF:                int num = tokens.getReference();                PRIndirectReference ref = new PRIndirectReference(this, num, tokens.getGeneration());                return ref;            default:                String sv = tokens.getStringValue();                if ("null".equals(sv))                    return PdfNull.PDFNULL;                else if ("true".equals(sv))                    return PdfBoolean.PDFTRUE;                else if ("false".equals(sv))                    return PdfBoolean.PDFFALSE;                return new PdfLiteral(-type, tokens.getStringValue());        }    }    /** Decodes a stream that has the FlateDecode filter.     * @param in the input data     * @return the decoded data     */    public static byte[] FlateDecode(byte in[]) {        byte b[] = FlateDecode(in, true);        if (b == null)            return FlateDecode(in, false);        return b;    }    /**     * @param in     * @param dicPar     * @return a byte array     */    public static byte[] decodePredictor(byte in[], PdfObject dicPar) {        if (dicPar == null || !dicPar.isDictionary())            return in;        PdfDictionary dic = (PdfDictionary)dicPar;        PdfObject obj = getPdfObject(dic.get(PdfName.PREDICTOR));        if (obj == null || !obj.isNumber())            return in;        int predictor = ((PdfNumber)obj).intValue();        if (predictor < 10)            return in;        int width = 1;        obj = getPdfObject(dic.get(PdfName.COLUMNS));        if (obj != null && obj.isNumber())            width = ((PdfNumber)obj).intValue();        int colors = 1;        obj = getPdfObject(dic.get(PdfName.COLORS));        if (obj != null && obj.isNumber())            colors = ((PdfNumber)obj).intValue();        int bpc = 8;        obj = getPdfObject(dic.get(PdfName.BITSPERCOMPONENT));        if (obj != null && obj.isNumber())            bpc = ((PdfNumber)obj).intValue();        DataInputStream dataStream = new DataInputStream(new ByteArrayInputStream(in));        ByteArrayOutputStream fout = new ByteArrayOutputStream(in.length);        int bytesPerPixel = colors * bpc / 8;        int bytesPerRow = (colors*width*bpc + 7)/8;        byte[] curr = new byte[bytesPerRow];        byte[] prior = new byte[bytesPerRow];        // Decode the (sub)image row-by-row        while (true) {            // Read the filter type byte and a row of data            int filter = 0;            try {                filter = dataStream.read();                if (filter < 0) {                    return fout.toByteArray();                }                dataStream.readFully(curr, 0, bytesPerRow);            } catch (Exception e) {                return fout.toByteArray();            }            switch (filter) {                case 0: //PNG_FILTER_NONE                    break;                case 1: //PNG_FILTER_SUB                    for (int i = bytesPerPixel; i < bytesPerRow; i++) {                        curr[i] += curr[i - bytesPerPixel];                    }                    break;                case 2: //PNG_FILTER_UP                    for (int i = 0; i < bytesPerRow; i++) {                        curr[i] += prior[i];                    }                    break;                case 3: //PNG_FILTER_AVERAGE                    for (int i = 0; i < bytesPerPixel; i++) {                        curr[i] += prior[i] / 2;                    }                    for (int i = bytesPerPixel; i < bytesPerRow; i++) {                        curr[i] += ((curr[i - bytesPerPixel] & 0xff) + (prior[i] & 0xff))/2;                    }                    break;                case 4: //PNG_FILTER_PAETH                    for (int i = 0; i < bytesPerPixel; i++) {                        curr[i] += prior[i];                    }                    for (int i = bytesPerPixel; i < bytesPerRow; i++) {                        int a = curr[i - bytesPerPixel] & 0xff;                        int b = prior[i] & 0xff;                        int c = prior[i - bytesPerPixel] & 0xff;                        int p = a + b - c;                        int pa = Math.abs(p - a);                        int pb = Math.abs(p - b);                        int pc = Math.abs(p - c);                        int ret;                        if ((pa <= pb) && (pa <= pc)) {                            ret = a;                        } else if (pb <= pc) {                            ret = b;                        } else {                            ret = c;                        }                        curr[i] += (byte)(ret);                    }                    break;                default:                    // Error -- unknown filter type                    throw new RuntimeException("PNG filter unknown.");            }            try {                fout.write(curr);            }            catch (IOException ioe) {                // Never happens            }            // Swap curr and prior            byte[] tmp = prior;            prior = curr;            curr = tmp;        }    }    /** A helper to FlateDecode.     * @param in the input data     * @param strict <CODE>true</CODE> to read a correct stream. <CODE>false</CODE>     * to try to read a corrupted stream     * @return the decoded data     */    public static byte[] FlateDecode(byte in[], boolean strict) {        ByteArrayInputStream stream = new ByteArrayInputStream(in);        InflaterInputStream zip = new InflaterInputStream(stream);        ByteArrayOutputStream out = new ByteArrayOutputStream();        byte b[] = new byte[strict ? 4092 : 1];        try {            int n;            while ((n = zip.read(b)) >= 0) {                out.write(b, 0, n);            }            zip.close();            out.close();            return out.toByteArray();        }        catch (Exception e) {            if (strict)         

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -