All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.jpedal.io.ObjectUtils Maven / Gradle / Ivy

/*
 * ===========================================
 * Java Pdf Extraction Decoding Access Library
 * ===========================================
 *
 * Project Info:  http://www.idrsolutions.com
 * Help section for developers at http://www.idrsolutions.com/support/
 *
 * (C) Copyright 1997-2016 IDRsolutions and Contributors.
 *
 * This file is part of JPedal/JPDF2HTML5
 *
     This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) 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
    Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with this library; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


 *
 * ---------------
 * ObjectUtils.java
 * ---------------
 */
package org.jpedal.io;

import org.jpedal.io.types.StreamReaderUtils;
import org.jpedal.objects.raw.DecodeParmsObject;
import org.jpedal.objects.raw.PdfDictionary;
import org.jpedal.objects.raw.PdfObject;

/**
 * general static methods
 */
public class ObjectUtils {

    public static byte[] checkEndObject(byte[] array) {

        long objStart=-1,lastEndStream=-1;
        int ObjStartCount = 0;

        //check if mising endobj
        for (int i = 0; i < array.length - 8; i++) {

            //track endstream and first or second obj
            if ((ObjStartCount < 2) && (array[i] == 32) && (array[i + 1] == 111) &&
                    (array[i + 2] == 98) && (array[i + 3] == 106)) {
                ObjStartCount++;
                objStart = i;
            }
            if ((ObjStartCount < 2) && (array[i] == 101) && (array[i + 1] == 110) &&
                    (array[i + 2] == 100) && (array[i + 3] == 115) &&
                    (array[i + 4] == 116) && (array[i + 5] == 114) &&
                    (array[i + 6] == 101) && (array[i + 7] == 97) && (array[i + 8] == 109)) {
                lastEndStream = i + 9;
            }
        }

        if ((lastEndStream > 0) && (objStart > lastEndStream)) {
            final byte[] newArray = new byte[(int) lastEndStream];
            System.arraycopy(array, 0, newArray, 0, (int) lastEndStream);
            array = newArray;
        }
        return array;
    }
    
    public static byte[] readRawValue(final int j, final byte[] data, final int start) {

        byte[] newString;
        final int stringLength = j - start;

        if (stringLength < 1) {
            return new byte[0];
        }

        newString = new byte[stringLength];

        System.arraycopy(data, start, newString, 0, stringLength);

        return newString;
    }

    public static byte[] readEscapedValue(final int j, final byte[] data, final int start, final boolean keepReturns) {
        
        //see if escape values
        boolean escapedValues=false;
        for(int aa=start;aa47 && nextByte<58){ //octal
                    
                    final StringBuilder octal=new StringBuilder(3);
                    
                    boolean notOctal=false;
                    for(int ii=0;ii<3;ii++){
                        
                        if(data[aa]=='\\' || data[aa]==')' || data[aa]<'0' || data[aa]>'9') //allow for less than 3 values
                        {
                            ii = 3;
                        } else{
                            octal.append((char)data[aa]);
                            
                            //catch for odd values
                            if(data[aa]>'7') {
                                notOctal = true;
                            }
                            
                            aa++;
                        }
                    }
                    //move back 1
                    aa--;
                    //isOctal=true;
                    if(notOctal) {
                        newString[jj] = (byte) Integer.parseInt(octal.toString());
                    } else {
                        newString[jj] = (byte) Integer.parseInt(octal.toString(), 8);
                    }
                    
                }else if(!keepReturns && (nextByte==13 || nextByte==10)){ //ignore bum data
                    jj--;
                }else {
                    newString[jj] = nextByte;
                }
                
                jj++;
            }else if(!keepReturns && (data[aa]==13 || data[aa]==10)){ //convert returns to spaces
                newString[jj]=32;
                jj++;
            }else{
                newString[jj]=data[aa];
                jj++;
            }
        }
        //now resize
        final byte[] rawString=newString;
        newString=new byte[jj];
        System.arraycopy(rawString, 0, newString, 0, jj);
        return newString;
    }


    /**
     * ensure all objects resolved
     * @param pdfObject
     * @param objReader
     * @return
     */
    public static PdfObject[] setupDecodeParms(final PdfObject pdfObject, final PdfFileReader objReader) {

        final PdfObject[] decodeParmsValues;
        final Object[] DecodeParmsArray = pdfObject.getObjectArray(PdfDictionary.DecodeParms);

        //if specific DecodeParms for each filter, set othereise use global
        if(DecodeParmsArray!=null){

            final int count=DecodeParmsArray.length;
            decodeParmsValues=new PdfObject[count];
            for(int i=0;i0){

            final int newLen=len-returnCount;
            int jj=0;
            final byte[] oldValue=newValues;
            newValues=new byte[newLen];

            for(int aa=0;aa' && raw[jj+1]=='>'){
                        levels--;

                        //allow for >>>>
                        if(raw[jj+2]=='>') {
                            jj++;
                        }
                    }

                    jj++;
                    if(levels==0 || jj>=count) {
                        break;
                    }
                }

                i=jj;

                jj=count;

            }else if(raw[jj]=='/'){
                jj=count;
            }else if(raw[jj]=='>' && raw[jj+1]=='>'){
                i=jj-1;
                jj=count;
            }else if(raw[jj]=='('){

                while(jj-1 && raw[j]=='\\'){
            j--;
            escapedFound++;
        }


        //System.out.println("escapedFound="+escapedFound+" "+(escapedFound & 2 ));
        return (escapedFound & 1) == 1;

    }

    public static int setDirectValue(final PdfObject pdfObject, int i, final byte[] raw, final int PDFkeyInt) {

        final int keyStart;
        i++;
        keyStart = i;
        while (i < raw.length && raw[i] != 32 && raw[i] != 10 && raw[i] != 13) {
            i++;
        }

        //store value
        pdfObject.setConstant(PDFkeyInt, keyStart, i - keyStart, raw);
        return i;
    }

    /**
     * used to debug object reading code
     * @param pdfObject
     * @param i
     * @param length
     * @param raw
     * @param padding
     */
    static void showData(final PdfObject pdfObject, final int i, final int length, final byte[] raw, final String padding) {

        System.out.println("\n\n"+ padding +" ------------readDictionaryAsObject ref="+ pdfObject.getObjectRefAsString() +" into "+pdfObject+"-----------------\ni="+i+"\nData=>>>>");
        System.out.print(padding);

        for(int jj=i;jj5 && raw[jj-5]=='s' && raw[jj-4]=='t' && raw[jj-3]=='r' && raw[jj-2]=='e' && raw[jj-1]=='a' &&raw[jj]=='m') {
                jj = length;
            }

            if(jj>2 && raw[jj-2]=='B' && raw[jj-1]=='D' &&raw[jj]=='C') {
                jj = length;
            }
        }
        System.out.println(padding +"\n<<<<-----------------------------------------------------\n");
    }

    public static String showMixedValuesAsString(final Object[] objectValues, String values) {

        if(objectValues==null) {
            return "null";
        }

        values += '[';
        final int count=objectValues.length;

        for(int jj=0;jj1) {
                    values += " , ";
                }
            }else{
                values = showMixedValuesAsString((Object[])objectValues[jj], values)+ ']';
                if(count-jj>1) {
                    values += " ,";
                }
            }
        }
        return values;
    }

    public static int skipToEndOfObject(int start, final byte[] data) {
        
        start += 2;
        int level = 1;

        while (level > 0) {
            //   System.out.print((char)data[start]);
            if (data[start] == '<' && data[start + 1] == '<') {
                start += 2;
                level++;
            } else if (data[start] == '>' && data[start + 1] == '>') {
                start += 2;
                level--;
            } else {
                start++;
            }
        }
        return start;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy