예제 #1
0
  CFF(final FontFile2 currentFontFile, final boolean isCID) {

    glyphs = new T1Glyphs(isCID);
    if (isCID) {
      glyphs.init(65536, true);
    }

    // move to start and check exists
    final int startPointer = currentFontFile.selectTable(FontFile2.CFF);

    // read 'cff' table
    if (startPointer != 0) {

      try {
        final int length = currentFontFile.getTableSize(FontFile2.CFF);

        final byte[] data = currentFontFile.readBytes(startPointer, length);

        // initialise glyphs
        new Type1C(data, null, glyphs);

        hasCFFdata = true;
      } catch (final Exception e) {
        LogWriter.writeLog("Exception: " + e.getMessage());
      }
    }
  }
  @Override
  public byte[] getPdfBuffer() {

    byte[] pdfByteArray = null;
    final FastByteArrayOutputStream os;

    try {
      os = new FastByteArrayOutputStream();

      // Download buffer
      final byte[] buffer = new byte[4096];

      // Download the PDF document
      int read;
      while ((read = iis.read(buffer)) != -1) {
        os.write(buffer, 0, read);
      }

      // Copy output stream to byte array
      pdfByteArray = os.toByteArray();

    } catch (final IOException e) {
      LogWriter.writeLog("[PDF] Exception " + e + " getting byte[] for " + fileName);
    }

    return pdfByteArray;
  }
  public String[] getRecentDocuments() {
    final String[] recentDocuments;

    try {
      final NodeList nl = doc.getElementsByTagName("recentfiles");
      final List fileNames = new ArrayList();

      if (nl != null && nl.getLength() > 0) {
        final NodeList allRecentDocs = ((Element) nl.item(0)).getElementsByTagName("*");

        for (int i = 0; i < allRecentDocs.getLength(); i++) {
          final Node item = allRecentDocs.item(i);
          final NamedNodeMap attrs = item.getAttributes();
          fileNames.add(attrs.getNamedItem("name").getNodeValue());
        }
      }

      // prune unwanted entries
      while (fileNames.size() > noOfRecentDocs) {
        fileNames.remove(0);
      }

      Collections.reverse(fileNames);

      recentDocuments = (String[]) fileNames.toArray(new String[noOfRecentDocs]);
    } catch (final Exception e) {
      LogWriter.writeLog("Exception " + e + " getting recent documents");
      return null;
    }

    return recentDocuments;
  }
  /**
   * write out logging information for forms, <b>print</b> is a boolean flag, if true prints to the
   * screen
   */
  public static void writeFormLog(final String message, final boolean print) {
    if (print) {
      System.out.println("[forms] " + message);
    }

    writeLog("[forms] " + message);
  }
  public PropertiesFile() {

    try {
      final String jarLoc =
          getClass().getProtectionDomain().getCodeSource().getLocation().toURI().getPath();
      userDir = jarLoc.substring(0, jarLoc.lastIndexOf('/'));

      if (!userDir
          .isEmpty()) { // if userDir is "" we will get /.properties.xml which is not good on
                        // Mac/Linux
        configFile = userDir + separator + ".properties.xml";
      } else {
        configFile = ".properties.xml";
      }

      if ((DecoderOptions.isRunningOnWindows) && (configFile.length() > 1)) {
        configFile = configFile.substring(1);
        configFile = configFile.replaceAll("\\\\", "/");
      }

    } catch (final Exception e) {
      userDir = System.getProperty("user.dir");
      configFile = userDir + separator + ".properties.xml";
      LogWriter.writeLog("Exception " + e);
    }
  }
  /**
   * Retrieve the URL of the actual image to use f
   *
   * @param path Preferred name and location
   * @return URL of file to use
   */
  public URL getURLForImage(String path) {

    path = iconLocation + path;

    final String file = path.substring(path.lastIndexOf('/') + 1);
    URL url;

    // Check if file location provided
    path = path.substring(0, path.indexOf('.')) + ".gif";
    File p = new File(path);
    url = getClass().getResource(path);

    // It's a file location check for gif
    if (p.exists()) {
      try {
        url = p.toURI().toURL();
      } catch (final MalformedURLException e) {
        LogWriter.writeLog("Exception attempting get path for image " + e);
      }
    }

    if (url == null) {
      path = path.substring(0, path.indexOf('.')) + ".png";
      p = new File(path);
      url = getClass().getResource(path);

      // It's a file location check for png
      if (p.exists()) {
        try {
          url = p.toURI().toURL();
        } catch (final MalformedURLException e) {
          LogWriter.writeLog("Exception attempting get path for image " + e);
        }
      }
    }

    if (url != null) {
      return url;
    } else { // use default graphic

      path = "/org/jpedal/examples/viewer/res/" + file;
      url = getClass().getResource(path);
      return url;
    }
  }
  /** returns current location pointer and sets to new value */
  public void movePointer(final long pointer) {
    try {
      // make sure inside file
      if (pointer > pdf_datafile.length()) {

        if (LogWriter.isOutput()) {
          LogWriter.writeLog("Attempting to access ref outside file");
        }
        // throw new PdfException("Exception moving file pointer - ref outside file");
      } else {
        pdf_datafile.seek(pointer);
      }
    } catch (final Exception e) {
      if (LogWriter.isOutput()) {
        LogWriter.writeLog("Exception " + e + " moving pointer to  " + pointer + " in file.");
      }
    }
  }
  /** setup log file and check it is readable also sets command line options */
  public static final void setupLogFile(final String command_line_values) {

    if (command_line_values != null) {

      // verbose mode echos to screen
      if (command_line_values.indexOf('v') != -1) {
        verbose = true;
        writeLog("Verbose on");
      } else {
        verbose = false;
      }
    }

    // write out info
    if (!testing) {
      writeLog("Software started - " + TimeNow.getTimeNow());
    }
    writeLog("=======================================================");
  }
예제 #9
0
  /** get root dir */
  public final int[] getRotatedPages() {

    int[] pagesToExport = null;

    if (printAll.isSelected()) {
      pagesToExport = new int[end_page];
      for (int i = 0; i < end_page; i++) pagesToExport[i] = i + 1;

    } else if (printCurrent.isSelected()) {
      pagesToExport = new int[1];
      pagesToExport[0] = currentPage;

    } else if (printPages.isSelected()) {

      try {
        PageRanges pages = new PageRanges(pagesBox.getText());

        int count = 0;
        int i = -1;
        while ((i = pages.next(i)) != -1) count++;

        pagesToExport = new int[count];
        count = 0;
        i = -1;
        while ((i = pages.next(i)) != -1) {
          if (i > end_page) {
            if (SimpleViewer.showMessages)
              JOptionPane.showMessageDialog(
                  this,
                  Messages.getMessage("PdfViewerText.Page")
                      + ' '
                      + i
                      + ' '
                      + Messages.getMessage("PdfViewerError.OutOfBounds")
                      + ' '
                      + Messages.getMessage("PdfViewerText.PageCount")
                      + ' '
                      + end_page);

            return null;
          }
          pagesToExport[count] = i;
          count++;
        }
      } catch (IllegalArgumentException e) {
        LogWriter.writeLog("Exception " + e + " in exporting pdfs");
        if (SimpleViewer.showMessages)
          JOptionPane.showMessageDialog(this, Messages.getMessage("PdfViewerError.InvalidSyntax"));
      }
    }

    return pagesToExport;
  }
  public Values() {

    String altSP = System.getProperty("org.jpedal.securityprovider");

    try {
      if (altSP == null) {
        altSP = "/org/bouncycastle/";
      }

      isEncryptOnClasspath = getClass().getResource(altSP) != null;
    } catch (final Exception e) {
      if (LogWriter.isOutput()) {
        LogWriter.writeLog("Exception in encryption " + e);
      }
      isEncryptOnClasspath = false;
    } catch (final Error e) {
      if (LogWriter.isOutput()) {
        LogWriter.writeLog("Exception in encryption " + e);
      }
      isEncryptOnClasspath = false;
    }
  }
예제 #11
0
  static byte[] getBytes(final long start, final int count, final RandomAccessBuffer pdf_datafile) {

    final byte[] buffer = new byte[count];

    try {
      pdf_datafile.seek(start);
      pdf_datafile.read(buffer); // get next chars
    } catch (final IOException e) {
      LogWriter.writeLog("Exception: " + e.getMessage());
    }

    return buffer;
  }
  /**
   * Get the cursor image as a buffered image for use in FX code
   *
   * @param type int value representing the cursor type
   * @return BufferedImage of the image to use for the cursor
   */
  public BufferedImage getCursorImageForFX(final int type) {
    switch (type) {
      case GRAB_CURSOR:
        try {
          return ImageIO.read(getURLForImage("grab32.png"));
        } catch (final Exception e) {

          LogWriter.writeLog("Exception in getting image " + e);

          return null;
        }
      case GRABBING_CURSOR:
        try {
          return ImageIO.read(getURLForImage("grabbing32.png"));
        } catch (final Exception e) {

          LogWriter.writeLog("Exception in getting image " + e);

          return null;
        }
      default:
        return null;
    }
  }
예제 #13
0
  /** update status if client being used also writes to log (called internally as file decoded) */
  public final void updateStatus(String progress_bar, int debug_level_to_use) {

    current = progress_bar;

    // update status if in client
    if (showMessages == true) {
      SwingUtilities.invokeLater(
          new Runnable() {
            public void run() {
              status.setString(current);
              status.setValue(progress_size);
            }
          });
    }
    if (debug_level > debug_level_to_use && LogWriter.isOutput()) LogWriter.writeLog(progress_bar);
  }
  public String getValue(final String elementName) {
    final NamedNodeMap attrs;
    try {
      final NodeList nl = doc.getElementsByTagName(elementName);
      final Element element = (Element) nl.item(0);
      if (element == null) {
        return "";
      }
      attrs = element.getAttributes();

    } catch (final Exception e) {
      LogWriter.writeLog("Exception " + e + " generating properties file");
      return "";
    }

    return attrs.getNamedItem("value").getNodeValue();
  }
예제 #15
0
  public RandomAccessMemoryMapBuffer(InputStream in) {

    this.pointer = -1;

    length = 0;

    FileOutputStream to = null;
    BufferedInputStream from = null;

    try {

      file = File.createTempFile("page", ".bin", new File(ObjectStore.temp_dir));
      // file.deleteOnExit();

      to = new java.io.FileOutputStream(file);

      from = new BufferedInputStream(in);

      // write
      byte[] buffer = new byte[65535];
      int bytes_read;
      while ((bytes_read = from.read(buffer)) != -1) {
        to.write(buffer, 0, bytes_read);
        length = length + bytes_read;
      }

    } catch (Exception e) {
      e.printStackTrace();
      // LogWriter.writeLog("Unable to save jpeg " + name);

    }
    // close streams
    try {
      if (to != null) to.close();
      if (from != null) from.close();
    } catch (Exception e) {
      LogWriter.writeLog("Exception " + e + " closing files");
    }

    try {
      init();
    } catch (Exception e) {
      e.printStackTrace();
    }
  }
  /**
   * open pdf file using a byte stream - By default files under 16384 bytes are cached to disk but
   * this can be altered by setting PdfFileReader.alwaysCacheInMemory to a maximimum size or -1
   * (always keep in memory)
   */
  public final void openPdfFile(final byte[] data) throws PdfException {

    final RandomAccessBuffer pdf_datafile;

    try {
      // use byte[] directly if small otherwise use Memory Map
      if (PdfFileReader.alwaysCacheInMemory == -1
          || data.length < PdfFileReader.alwaysCacheInMemory) {
        pdf_datafile = new RandomAccessDataBuffer(data);
      } else { // cache as file and access via RandomAccess

        // pdf_datafile = new RandomAccessMemoryMapBuffer( data ); old version very slow

        try {

          final File file = File.createTempFile("page", ".bin", new File(ObjectStore.temp_dir));
          tempFileName = file.getAbsolutePath();

          // file.deleteOnExit();

          final java.io.FileOutputStream a = new java.io.FileOutputStream(file);

          a.write(data);
          a.flush();
          a.close();

          pdf_datafile = new RandomAccessFileBuffer(tempFileName, "r");
        } catch (final Exception e) {
          throw new RuntimeException(
              "Unable to create temporary file in " + ObjectStore.temp_dir + ' ' + e);
        }
      }

      objectReader.init(pdf_datafile);

      // eof = pdf_datafile.length();
      // pdf_datafile = new RandomAccessFile( filename, "r" );

    } catch (final Exception e) {

      LogWriter.writeLog("Exception " + e + " accessing file");

      throw new PdfException("Exception " + e + " accessing file");
    }
  }
  public void addRecentDocument(final String file) {
    try {
      final Element recentElement = (Element) doc.getElementsByTagName("recentfiles").item(0);

      checkExists(file, recentElement);

      final Element elementToAdd = doc.createElement("file");
      elementToAdd.setAttribute("name", file);

      recentElement.appendChild(elementToAdd);

      removeOldFiles(recentElement);

      // writeDoc();
    } catch (final Exception e) {
      LogWriter.writeLog("Exception " + e + " adding recent document to properties file");
    }
  }
  /** close the file */
  public final void closePdfFile() {
    try {
      objectReader.closeFile();

      if (pdf_datafile != null) {
        pdf_datafile.close();
      }

      // ensure temp file deleted
      if (tempFileName != null) {
        final File fileToDelete = new File(tempFileName);
        fileToDelete.delete();
        tempFileName = null;
      }
    } catch (final Exception e) {
      LogWriter.writeLog("Exception " + e + " closing file");
    }
  }
  byte[] getBytes(final long start, final int count) {
    final byte[] buffer = new byte[count];

    if (start >= 0) {
      try {
        pdf_datafile.seek(start);
        pdf_datafile.read(buffer); // get next chars
      } catch (final IOException e) {
        // tell user and log
        if (LogWriter.isOutput()) {
          LogWriter.writeLog("Exception: " + e.getMessage());
        }
        //
      }
    }

    return buffer;
  }
  /**
   * open pdf file<br>
   * Only files allowed (not http) so we can handle Random Access of pdf
   */
  public final void openPdfFile(final String filename) throws PdfException {

    final RandomAccessBuffer pdf_datafile;

    try {

      pdf_datafile = new RandomAccessFileBuffer(filename, "r");
      // pdf_datafile = new RandomAccessFCTest( new FileInputStream(filename));

      objectReader.init(pdf_datafile);

      // this.eof = pdf_datafile.length();

    } catch (final Exception e) {
      LogWriter.writeLog("Exception " + e + " accessing file");

      throw new PdfException("Exception " + e + " accessing file");
    }
  }
  /**
   * open pdf file<br>
   * Only files allowed (not http) so we can handle Random Access of pdf
   */
  public final void openPdfFile(final InputStream in) throws PdfException {

    try {

      // use byte[] directly if small otherwise use Memory Map
      pdf_datafile = new RandomAccessMemoryMapBuffer(in);

      objectReader.init(pdf_datafile);

      // this.eof = pdf_datafile.length();
      // pdf_datafile = new RandomAccessFile( filename, "r" );

    } catch (final Exception e) {

      LogWriter.writeLog("Exception " + e + " accessing file");

      throw new PdfException("Exception " + e + " accessing file");
    }
  }
  public void setValue(final String elementName, final String newValue) {

    try {
      final NodeList nl = doc.getElementsByTagName(elementName);
      final Element element = (Element) nl.item(0);
      if (element == null || newValue == null) {
        ShowGUIMessage.showGUIMessage(
            "The property "
                + elementName
                + " was either not found in the properties file or the value "
                + newValue
                + " was not set.",
            "Property not found.");
      } else {
        element.setAttribute("value", newValue);
      }

    } catch (final Exception e) {
      LogWriter.writeLog("Exception " + e + " setting value in properties file");
    }
  }
  /** Hinted constructor */
  public TTGlyph(
      final Glyf currentGlyf,
      final FontFile2 glyfTable,
      final Hmtx currentHmtx,
      final int idx,
      final float unitsPerEm,
      final TTVM vm) {

    super(currentGlyf, glyfTable, currentHmtx, idx, unitsPerEm, vm);

    /**/
    if (debug) {
      try {
        System.out.println("debugging" + idx);
        final java.awt.image.BufferedImage img =
            new java.awt.image.BufferedImage(700, 700, java.awt.image.BufferedImage.TYPE_INT_ARGB);

        final Graphics2D gg2 = img.createGraphics();

        for (int jj = 0; jj < paths.size() - 1; jj++) {
          if (jj == 0) {
            gg2.setColor(Color.red);
          } else {
            gg2.setColor(Color.blue);
          }

          gg2.fill(paths.elementAt(jj));

          gg2.draw(paths.elementAt(jj).getBounds());
        }
        // org.jpedal.gui.ShowGUIMessage.showGUIMessage("glyf "+ '/' +paths.size(),img,"glyf "+ '/'
        // +paths.size()+ '/' +compCount);
      } catch (final Exception e) {
        LogWriter.writeLog("Exception: " + e.getMessage());
      }
    }

    // if(idx==2060)
    // ShowGUIMessage.showGUIMessage("done",img,"glyf done");
  }
  /**
   * test first bytes to see if new 1.5 style table with obj or contains ref
   *
   * @throws PdfException
   */
  private boolean isCompressedStream(int pointer, final int eof) throws PdfException {

    final boolean debug = false;

    int bufSize = 50, charReached_legacy = 0, charReached_comp1 = 0, charReached_comp2 = 0;

    final int[] objStm = {'O', 'b', 'j', 'S', 't', 'm'};
    final int[] XRef = {'X', 'R', 'e', 'f'};

    int type = UNSET;

    // flag to show if at start of data for check
    boolean firstRead = true;

    while (true) {

      /** adjust buffer if less than 1024 bytes left in file */
      if (pointer + bufSize > eof) {
        bufSize = eof - pointer;
      }

      if (bufSize < 0) {
        bufSize = 50;
      }

      if (pointer < 0) {
        pointer += bufSize;
        continue;
      }

      final byte[] buffer = getBytes(pointer, bufSize);

      // allow for fact sometimes start of data wrong
      if (firstRead && buffer[0] == 'r' && buffer[1] == 'e' && buffer[2] == 'f') {
        charReached_legacy = 1;
      }

      firstRead = false; // switch off

      /** look for xref or obj */
      for (int i = 0; i < bufSize; i++) {

        final byte currentByte = buffer[i];

        if (debug) {
          System.out.print((char) currentByte);
        }

        /** check for xref OR end - reset if not */
        if (currentByte == oldPattern[charReached_legacy] && type != COMPRESSED) {
          charReached_legacy++;
          type = LEGACY;
        } else if ((currentByte == objStm[charReached_comp1])
            && (charReached_comp1 == 0 || type == COMPRESSED)) {

          charReached_comp1++;
          type = COMPRESSED;
        } else if ((currentByte == XRef[charReached_comp2])
            && (charReached_comp2 == 0 || type == COMPRESSED)) {

          charReached_comp2++;
          type = COMPRESSED;
        } else {

          charReached_legacy = 0;
          charReached_comp1 = 0;
          charReached_comp2 = 0;

          type = UNSET;
        }

        if (charReached_legacy == 3 || charReached_comp1 == 4 || charReached_comp2 == 3) {
          break;
        }
      }

      if (charReached_legacy == 3 || charReached_comp1 == 4 || charReached_comp2 == 3) {
        break;
      }

      // update pointer
      pointer += bufSize;
    }

    /** throw exception if no match or tell user which type */
    if (type == UNSET) {
      try {
        closeFile();
      } catch (final IOException e1) {
        if (LogWriter.isOutput()) {
          LogWriter.writeLog("Exception " + 1 + " closing file " + e1);
        }
      }
      throw new PdfException("Exception unable to find ref or obj in trailer");
    }

    return type == COMPRESSED;
  }
  /** read first start ref from last 1024 bytes */
  private int readFirstStartRef() throws PdfException {

    // reset flag
    offset.setRefTableInvalid(false);

    int pointer = -1;
    int i = 1019;
    final StringBuilder startRef = new StringBuilder(10);

    /** move to end of file and read last 1024 bytes */
    final int block = 1024;
    byte[] lastBytes = new byte[block];
    long end;

    /** set endpoint, losing null chars and anything before EOF */
    final int[] EndOfFileMarker = {37, 37, 69, 79};
    int valReached = 3;
    boolean EOFFound = false;
    try {
      end = eof;

      /** lose nulls and other trash from end of file */
      final int bufSize = 255;
      while (true) {
        final byte[] buffer = getBytes(end - bufSize, bufSize);

        int offset = 0;

        for (int ii = bufSize - 1; ii > -1; ii--) {

          // see if we can decrement EOF tracker or restart check
          if (!EOFFound) {
            valReached = 3;
          }

          if (buffer[ii] == EndOfFileMarker[valReached]) {
            valReached--;
            EOFFound = true;
          } else {
            EOFFound = false;
          }

          // move to next byte
          offset--;

          if (valReached < 0) {
            ii = -1;
          }
        }

        // exit if found values on loop
        if (valReached < 0) {
          end -= offset;
          break;
        } else {
          end -= bufSize;
        }

        // allow for no eof
        if (end < 0) {
          end = eof;
          break;
        }
      }

      // end=end+bufSize;

      // allow for very small file
      int count = (int) (end - block);

      if (count < 0) {
        count = 0;
        final int size = (int) eof;
        lastBytes = new byte[size];
        i = size + 3; // force reset below
      }

      lastBytes = getBytes(count, lastBytes.length);

    } catch (final Exception e) {
      if (LogWriter.isOutput()) {
        LogWriter.writeLog("Exception " + e + " reading last 1024 bytes");
      }

      throw new PdfException(e + " reading last 1024 bytes");
    }

    //		for(int ii=0;ii<lastBytes.length;ii++){
    //		System.out.print((char)lastBytes[ii]);
    //		}
    //		System.out.println();

    // look for tref as end of startxref
    final int fileSize = lastBytes.length;

    if (i > fileSize) {
      i = fileSize - 5;
    }

    while (i > -1) {

      // first check is because startref works as well a startxref !!
      if (((lastBytes[i] == 116 && lastBytes[i + 1] == 120)
              || (lastBytes[i] == 114 && lastBytes[i + 1] == 116))
          && (lastBytes[i + 2] == 114)
          && (lastBytes[i + 3] == 101)
          && (lastBytes[i + 4] == 102)) {
        break;
      }

      i--;
    }

    /** trap buggy files */
    if (i == -1) {
      try {
        closeFile();
      } catch (final IOException e1) {
        if (LogWriter.isOutput()) {
          LogWriter.writeLog("Exception " + e1 + " closing file");
        }
      }
      throw new PdfException("No Startxref found in last 1024 bytes ");
    }

    i += 5; // allow for word length

    // move to start of value ignoring spaces or returns
    while (i < 1024 && (lastBytes[i] == 10 || lastBytes[i] == 32 || lastBytes[i] == 13)) {
      i++;
    }

    // move to start of value ignoring spaces or returns
    while ((i < 1024) && (lastBytes[i] != 10) && (lastBytes[i] != 32) && (lastBytes[i] != 13)) {
      startRef.append((char) lastBytes[i]);
      i++;
    }

    /** convert xref to string to get pointer */
    if (startRef.length() > 0) {
      pointer = Integer.parseInt(startRef.toString());
    }

    if (pointer == -1) {
      if (LogWriter.isOutput()) {
        LogWriter.writeLog("No Startref found in last 1024 bytes ");
      }
      try {
        closeFile();
      } catch (final IOException e1) {
        if (LogWriter.isOutput()) {
          LogWriter.writeLog("Exception " + e1 + " closing file");
        }
      }
      throw new PdfException("No Startref found in last 1024 bytes ");
    }

    return pointer;
  }
  @Override
  public int setConstant(
      final int pdfKeyType, final int keyStart, final int keyLength, final byte[] raw) {

    int PDFvalue = PdfDictionary.Unknown;

    int id = 0, x = 0, next;

    try {

      // convert token to unique key which we can lookup

      for (int i2 = keyLength - 1; i2 > -1; i2--) {

        next = raw[keyStart + i2];

        next -= 48;

        id += ((next) << x);

        x += 8;
      }

      switch (id) {
        case PdfDictionary.Image:
          PDFvalue = PdfDictionary.Image;
          break;

        case PdfDictionary.Form:
          PDFvalue = PdfDictionary.Form;
          break;

          //                case StandardFonts.CIDTYPE0:
          //                    PDFvalue =StandardFonts.CIDTYPE0;
          //                break;

        default:

          //                	if(pdfKeyType==PdfDictionary.Encoding){
          //                		PDFvalue=PdfCIDEncodings.getConstant(id);
          //
          //                		if(PDFvalue==PdfDictionary.Unknown){
          //
          //                			byte[] bytes=new byte[keyLength];
          //
          //                            System.arraycopy(raw,keyStart,bytes,0,keyLength);
          //
          //                			unknownValue=new String(bytes);
          //                		}
          //
          //                		if(debug && PDFvalue==PdfDictionary.Unknown){
          //                			System.out.println("Value not in PdfCIDEncodings");
          //
          //                           	 byte[] bytes=new byte[keyLength];
          //
          //                               System.arraycopy(raw,keyStart,bytes,0,keyLength);
          //                               System.out.println("Add to CIDEncodings and as String");
          //                               System.out.println("key="+new String(bytes)+" "+id+" not
          // implemented in setConstant in PdfFont Object");
          //
          //                               System.out.println("final public static int CMAP_"+new
          // String(bytes)+"="+id+";");
          //
          //                		}
          //                	}else
          PDFvalue = super.setConstant(pdfKeyType, id);

          if (PDFvalue == -1 && debug) {

            final byte[] bytes = new byte[keyLength];

            System.arraycopy(raw, keyStart, bytes, 0, keyLength);
            System.out.println(
                "key="
                    + new String(bytes)
                    + ' '
                    + id
                    + " not implemented in setConstant in "
                    + this);

            System.out.println("final public static int " + new String(bytes) + '=' + id + ';');
          }

          break;
      }

    } catch (final Exception e) {
      LogWriter.writeLog("Exception: " + e.getMessage());
    }

    // System.out.println(pdfKeyType+"="+PDFvalue);
    // switch(pdfKeyType){

    //        	case PdfDictionary.Subtype:
    //        		subtype=PDFvalue;
    //        		break;

    // }

    return PDFvalue;
  }
  /** read reference table from file so we can locate objects in pdf file and read the trailers */
  private PdfObject readLegacyReferenceTable(
      PdfObject rootObj, int pointer, final int eof, final PdfFileReader currentPdfFile)
      throws PdfException {

    int endTable, current = 0; // current object number
    byte[] Bytes;
    int bufSize = 1024;

    /** read and decode 1 or more trailers */
    while (true) {

      try {

        // allow for pointer outside file
        Bytes = Trailer.readTrailer(bufSize, pointer, eof, pdf_datafile);

      } catch (final Exception e) {

        try {
          closeFile();
        } catch (final IOException e1) {
          if (LogWriter.isOutput()) {
            LogWriter.writeLog("Exception " + e + " closing file " + e1);
          }
        }
        throw new PdfException("Exception " + e + " reading trailer");
      }

      if (Bytes == null) // safety catch
      {
        break;
      }

      /** get trailer */
      int i = 0;

      final int maxLen = Bytes.length;

      // for(int a=0;a<100;a++)
      //	System.out.println((char)Bytes[i+a]);
      while (i < maxLen) { // look for trailer keyword
        if (Bytes[i] == 116
            && Bytes[i + 1] == 114
            && Bytes[i + 2] == 97
            && Bytes[i + 3] == 105
            && Bytes[i + 4] == 108
            && Bytes[i + 5] == 101
            && Bytes[i + 6] == 114) {
          break;
        }

        i++;
      }

      // save endtable position for later
      endTable = i;

      if (i == Bytes.length) {
        break;
      }

      // move to beyond <<
      while (Bytes[i] != 60 && Bytes[i - 1] != 60) {
        i++;
      }

      i++;
      final PdfObject pdfObject = new CompressedObject("1 0 R");
      Dictionary.readDictionary(pdfObject, i, Bytes, -1, true, currentPdfFile, false);

      // move to beyond >>
      int level = 0;
      while (true) {

        if (Bytes[i] == 60 && Bytes[i - 1] == 60) {
          level++;
          i++;
        } else if (Bytes[i] == '[') {
          i++;
          while (Bytes[i] != ']') {
            i++;
            if (i == Bytes.length) {
              break;
            }
          }
        } else if (Bytes[i] == 62 && Bytes[i - 1] == 62) {
          level--;
          i++;
        }

        if (level == 0) {
          break;
        }

        i++;
      }

      // handle optional XRefStm
      final int XRefStm = pdfObject.getInt(PdfDictionary.XRefStm);

      if (XRefStm != -1) {
        pointer = XRefStm;
      } else { // usual way

        boolean hasRef = true;

        /** handle spaces and comments */
        while (Bytes[i] == 10 || Bytes[i] == 13) {
          i++;
        }

        while (Bytes[i] == '%') {
          while (Bytes[i] != 10) {

            i++;
          }
          i++;
        }
        /* fix for /Users/markee/Downloads/oneiderapartnerbrochure_web_1371798737.pdf
        /**/

        // look for xref as end of startref
        while (Bytes[i] != 116
            && Bytes[i + 1] != 120
            && Bytes[i + 2] != 114
            && Bytes[i + 3] != 101
            && Bytes[i + 4] != 102) {

          if (Bytes[i] == 'o' && Bytes[i + 1] == 'b' && Bytes[i + 2] == 'j') {
            hasRef = false;
            break;
          }
          i++;
        }

        if (hasRef) {

          i += 8;
          // move to start of value ignoring spaces or returns
          while ((i < maxLen) && (Bytes[i] == 10 || Bytes[i] == 32 || Bytes[i] == 13)) {
            i++;
          }

          final int s = i;

          // allow for characters between xref and startref
          while (i < maxLen && Bytes[i] != 10 && Bytes[i] != 32 && Bytes[i] != 13) {
            i++;
          }

          /** convert xref to string to get pointer */
          if (s != i) {
            pointer = NumberUtils.parseInt(s, i, Bytes);
          }
        }
      }

      i = 0;

      // allow for bum data at start
      while (Bytes[i] == 13 || Bytes[i] == 10 || Bytes[i] == 9) {
        i++;
      }

      if (pointer == -1) {
        if (LogWriter.isOutput()) {
          LogWriter.writeLog("No startRef");
        }

        /** now read the objects for the trailers */
      } else if (Bytes[i] == 120
          && Bytes[i + 1] == 114
          && Bytes[i + 2] == 101
          && Bytes[i + 3] == 102) { // make sure starts xref

        i = 5;

        // move to start of value ignoring spaces or returns
        while (Bytes[i] == 10 || Bytes[i] == 32 || Bytes[i] == 13) {
          i++;
        }

        current = offset.readXRefs(current, Bytes, endTable, i, eof, pdf_datafile);

        /**
         * now process trailer values - only first set of table values for root, encryption and info
         */
        if (rootObj == null) {

          rootObj = pdfObject.getDictionary(PdfDictionary.Root);

          encryptObj = pdfObject.getDictionary(PdfDictionary.Encrypt);
          if (encryptObj != null) {

            final byte[][] IDs = pdfObject.getStringArray(PdfDictionary.ID);
            if (IDs != null && this.ID == null) {
              // only the first encountered ID should be used as a fileID for decryption
              this.ID = IDs[0];
            }
          }

          infoObject = pdfObject.getDictionary(PdfDictionary.Info);
        }

        // make sure first values used if several tables and code for prev
        pointer = pdfObject.getInt(PdfDictionary.Prev);

        // see if other trailers
        if (pointer != -1 && pointer < this.eof) {
          // reset values for loop
          bufSize = 1024;

          // track ref table so we can work out object length
          offset.addXref(pointer);

        } else // reset if fails second test above
        {
          pointer = -1;
        }

      } else {
        pointer = -1;

        // needs to be read to pick up potential /Pages value
        //noinspection ObjectAllocationInLoop
        rootObj = new PageObject(BrokenRefTable.findOffsets(pdf_datafile, offset));
        currentPdfFile.readObject(rootObj);

        offset.setRefTableInvalid(true);
      }
      if (pointer == -1) {
        break;
      }
    }

    if (encryptObj == null
        && rootObj != null) { // manual check for broken file (ignore if Encrypted)

      int type = -1;

      int status = rootObj.getStatus();
      byte[] data = rootObj.getUnresolvedData();

      try {

        final ObjectDecoder objectDecoder = new ObjectDecoder(currentPdfFile);
        objectDecoder.checkResolved(rootObj);

        type = rootObj.getParameterConstant(PdfDictionary.Type);

      } catch (Exception e) { // we need to ignore so just catch, put back as was and log

        rootObj.setStatus(status);
        rootObj.setUnresolvedData(data, status);
        if (LogWriter.isOutput()) {
          LogWriter.writeLog("[PDF] Exception reading type on root object " + e);
        }
      }

      // something gone wrong so manually index
      if (type == PdfDictionary.Font) { // see 21153 - ref table in wrong order
        rootObj = null; // /will reset in code at end
      }
    }

    // something gone wrong so manually index
    if (rootObj == null) { // see 21382

      offset.clear();
      offset.reuse();

      // needs to be read to pick up potential /Pages value
      //noinspection ObjectAllocationInLoop
      rootObj = new PageObject(BrokenRefTable.findOffsets(pdf_datafile, offset));
      currentPdfFile.readObject(rootObj);

      offset.setRefTableInvalid(true);
    }

    return rootObj;
  }
  /**
   * read reference table start to see if new 1.5 type or traditional xref
   *
   * @throws PdfException
   */
  public final PdfObject readReferenceTable(
      final PdfObject linearObj,
      final PdfFileReader currentPdfFile,
      final ObjectReader objectReader)
      throws PdfException {

    int pointer = -1;
    final int eof = (int) this.eof;

    boolean islinearizedCompressed = false;

    if (linearObj == null) {
      pointer = readFirstStartRef();
    } else { // find at start of Linearized
      final byte[] data = pdf_datafile.getPdfBuffer();

      final int count = data.length;
      int ptr = 5;
      for (int i = 0; i < count; i++) {

        // track start of this object (needed for compressed)
        if (data[i] == 'e'
            && data[i + 1] == 'n'
            && data[i + 2] == 'd'
            && data[i + 3] == 'o'
            && data[i + 4] == 'b'
            && data[i + 5] == 'j') {
          ptr = i + 6;
        }

        if (data[i] == 'x' && data[i + 1] == 'r' && data[i + 2] == 'e' && data[i + 3] == 'f') {
          pointer = i;
          i = count;
        } else if (data[i] == 'X'
            && data[i + 1] == 'R'
            && data[i + 2] == 'e'
            && data[i + 3] == 'f') {

          islinearizedCompressed = true;

          pointer = ptr;
          while (data[pointer] == 10 || data[pointer] == 13 || data[pointer] == 32) {
            pointer++;
          }

          i = count;
        }
      }
    }

    offset.addXref(pointer);

    PdfObject rootObj = null;

    if (pointer >= eof || pointer == 0) {

      if (LogWriter.isOutput()) {
        LogWriter.writeLog("Pointer not if file - trying to manually find startref");
      }

      offset.setRefTableInvalid(true);

      try {
        rootObj = new PageObject(BrokenRefTable.findOffsets(pdf_datafile, offset));
      } catch (Error err) {
        throw new PdfException(err.getMessage() + " attempting to manually scan file for objects");
      }

      currentPdfFile.readObject(rootObj);
      return rootObj;

    } else if (islinearizedCompressed || isCompressedStream(pointer, eof)) {
      return readCompressedStream(rootObj, pointer, currentPdfFile, objectReader, linearObj);
    } else {
      return readLegacyReferenceTable(rootObj, pointer, eof, currentPdfFile);
    }
  }
예제 #29
0
  public static int setNameTreeValue(
      final PdfObject pdfObject,
      int i,
      final byte[] raw,
      final int length,
      final boolean ignoreRecursion,
      final int PDFkeyInt,
      final PdfFileReader objectReader) {

    boolean isRef = false;

    // move to start
    while (raw[i] != '[') { // can be number as well

      if (raw[i] == '(') { // allow for W (7)
        isRef = false;
        break;
      }

      // allow for number as in refer 9 0 R
      if (raw[i] >= '0' && raw[i] <= '9') {
        isRef = true;
        break;
      }

      i++;
    }

    // allow for direct or indirect
    byte[] data = raw;

    int start = i, j = i;

    int count = 0;

    // read ref data and slot in
    if (isRef) {
      // number
      final int[] values = StreamReaderUtils.readRefFromStream(raw, i);

      i = values[2];
      final int generation = values[1];
      final int number = values[0];

      if (raw[i] != 82) // we are expecting R to end ref
      {
        throw new RuntimeException(
            "3. Unexpected value in file "
                + raw[i]
                + " - please send to IDRsolutions for analysis");
      }

      if (!ignoreRecursion) {

        // read the Dictionary data
        data =
            objectReader.readObjectAsByteArray(
                pdfObject, objectReader.isCompressed(number, generation), number, generation);

        // allow for data in Linear object not yet loaded
        if (data == null) {
          pdfObject.setFullyResolved(false);

          if (debugFastCode) {
            System.out.println(padding + "Data not yet loaded");
          }

          i = length;
          return i;
        }

        // lose obj at start
        j = 3;
        while (data[j - 1] != 106
            && data[j - 2] != 98
            && data[j - 3] != 111
            && data[j - 3] != '<') {
          j++;
        }

        j = StreamReaderUtils.skipSpaces(data, j);

        // reset pointer
        start = j;
      }
    }

    // move to end
    while (j < data.length) {

      if (data[j] == '[' || data[j] == '(') {
        count++;
      } else if (data[j] == ']' || data[j] == ')') {
        count--;
      }

      if (count == 0) {
        break;
      }

      j++;
    }

    if (!ignoreRecursion) {
      final int stringLength = j - start + 1;
      byte[] newString = new byte[stringLength];

      System.arraycopy(data, start, newString, 0, stringLength);
      if (pdfObject.getObjectType() != PdfDictionary.Encrypt) {
        final DecryptionFactory decryption = objectReader.getDecryptionObject();
        if (decryption != null) {
          try {
            newString =
                decryption.decrypt(
                    newString, pdfObject.getObjectRefAsString(), false, null, false, false);
          } catch (final PdfSecurityException e) {
            LogWriter.writeLog("Exception: " + e.getMessage());
          }
        }
      }

      pdfObject.setTextStreamValue(PDFkeyInt, newString);

      if (debugFastCode) {
        System.out.println(padding + "name=" + new String(newString) + " set in " + pdfObject);
      }
    }

    // roll on
    if (!isRef) {
      i = j;
    }
    return i;
  }
  /**
   * Run length decode. If both data and cached stream are present it will check they are identical
   */
  @Override
  public void decode(
      final BufferedInputStream bis,
      final BufferedOutputStream streamCache,
      final String cacheName,
      final Map<String, String> cachedObjects) {

    this.bis = bis;
    this.streamCache = streamCache;
    this.cachedObjects = cachedObjects;

    try {

      final int count;
      int len;
      int nextLen;
      int value2;

      count = bis.available();

      for (int i = 0; i < count; i++) {

        nextLen = bis.read();
        if (nextLen >= 128) {
          nextLen -= 256;
        }

        len = nextLen;

        if (len < 0) {
          len = 256 + len;
        }

        if (len == 128) {

          i = count;

        } else if (len > 128) {

          i++;

          len = 257 - len;

          value2 = bis.read();
          if (value2 >= 128) {
            value2 -= 256;
          }

          for (int j = 0; j < len; j++) {
            streamCache.write(value2);
          }

        } else {
          i++;
          len++;
          for (int j = 0; j < len; j++) {

            value2 = bis.read();
            if (value2 >= 128) {
              value2 -= 256;
            }
            streamCache.write(value2);
          }

          i = i + len - 1;
        }
      }
    } catch (final IOException e1) {

      if (LogWriter.isOutput()) {
        LogWriter.writeLog("IO exception in RunLength " + e1);
      }
    }
  }