예제 #1
0
  public Map<String, Image> getImages() {
    Map<String, Image> images = new HashMap<String, Image>();
    COSDictionary xobjectsDictionary =
        (COSDictionary) getDictionary().getDictionaryObject(COSName.XOBJECT);
    if (xobjectsDictionary == null) {
      return images;
    }

    for (COSName objName : xobjectsDictionary.keySet()) {
      try {
        COSBase xobject = xobjectsDictionary.getDictionaryObject(objName);
        if (xobject instanceof COSStream) {
          COSStream xstream = (COSStream) xobject;
          String subtype = xstream.getNameAsString(COSName.SUBTYPE);
          if (!subtype.equals("Image")) {
            continue;
          }

          PDFunction tintTransformer = getTintTransformer(xstream);

          PDStream pdstream = new PDStream(xstream);
          byte[] data = getStreamData(pdstream);
          Image image = processStream(data, tintTransformer);
          if (image != null) {
            images.put(objName.getName(), image);
          }
        }
      } catch (Exception e) {
        LOG.error("error while creating a image", e);
      }
    }

    return images;
  }
 /**
  * Decode JBIG2 data using Java ImageIO library.
  *
  * <p>{@inheritDoc}
  */
 public void decode(
     InputStream compressedData, OutputStream result, COSDictionary options, int filterIndex)
     throws IOException {
   /**
    * A working JBIG2 ImageIO plugin is needed to decode JBIG2 encoded streams. The following is
    * known to be working. It can't be bundled with PDFBox because of an incompatible license.
    * http://code.google.com/p/jbig2-imageio/
    */
   Iterator<ImageReader> readers = ImageIO.getImageReadersByFormatName("JBIG2");
   if (!readers.hasNext()) {
     LOG.error("Can't find an ImageIO plugin to decode the JBIG2 encoded datastream.");
     return;
   }
   ImageReader reader = readers.next();
   COSDictionary decodeP = (COSDictionary) options.getDictionaryObject(COSName.DECODE_PARMS);
   COSInteger bits = (COSInteger) options.getDictionaryObject(COSName.BITS_PER_COMPONENT);
   COSStream st = null;
   if (decodeP != null) {
     st = (COSStream) decodeP.getDictionaryObject(COSName.JBIG2_GLOBALS);
   }
   if (st != null) {
     reader.setInput(
         ImageIO.createImageInputStream(
             new SequenceInputStream(st.getFilteredStream(), compressedData)));
   } else {
     reader.setInput(ImageIO.createImageInputStream(compressedData));
   }
   BufferedImage bi = reader.read(0);
   reader.dispose();
   if (bi != null) {
     // I am assuming since JBIG2 is always black and white
     // depending on your renderer this might or might be needed
     if (bi.getColorModel().getPixelSize() != bits.intValue()) {
       if (bits.intValue() != 1) {
         LOG.error("Do not know how to deal with JBIG2 with more than 1 bit");
         return;
       }
       BufferedImage packedImage =
           new BufferedImage(bi.getWidth(), bi.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
       Graphics graphics = packedImage.getGraphics();
       graphics.drawImage(bi, 0, 0, null);
       graphics.dispose();
       bi = packedImage;
     }
     DataBuffer dBuf = bi.getData().getDataBuffer();
     if (dBuf.getDataType() == DataBuffer.TYPE_BYTE) {
       result.write(((DataBufferByte) dBuf).getData());
     } else {
       LOG.error("Image data buffer not of type byte but type " + dBuf.getDataType());
     }
   } else {
     LOG.error("Something went wrong when decoding the JBIG2 encoded datastream.");
   }
 }
예제 #3
0
  /** {@inheritDoc} */
  protected void determineEncoding() {
    String cmapName = null;
    COSName encodingName = null;
    COSBase encoding = getEncoding();
    Encoding fontEncoding = null;
    if (encoding != null) {
      if (encoding instanceof COSName) {
        if (cmap == null) {
          encodingName = (COSName) encoding;
          cmap = cmapObjects.get(encodingName.getName());
          if (cmap == null) {
            cmapName = encodingName.getName();
          }
        }
        if (cmap == null && cmapName != null) {
          try {
            fontEncoding = EncodingManager.INSTANCE.getEncoding(encodingName);
          } catch (IOException exception) {
            LOG.debug("Debug: Could not find encoding for " + encodingName);
          }
        }
      } else if (encoding instanceof COSStream) {
        if (cmap == null) {
          COSStream encodingStream = (COSStream) encoding;
          try {
            cmap = parseCmap(null, encodingStream.getUnfilteredStream());
          } catch (IOException exception) {
            LOG.error("Error: Could not parse the embedded CMAP");
          }
        }
      } else if (encoding instanceof COSDictionary) {
        try {
          fontEncoding = new DictionaryEncoding((COSDictionary) encoding);
        } catch (IOException exception) {
          LOG.error("Error: Could not create the DictionaryEncoding");
        }
      }
    }
    setFontEncoding(fontEncoding);
    extractToUnicodeEncoding();

    if (cmap == null && cmapName != null) {
      String resourceName = resourceRootCMAP + cmapName;
      try {
        cmap = parseCmap(resourceRootCMAP, ResourceLoader.loadResource(resourceName));
        if (cmap == null && encodingName == null) {
          LOG.error("Error: Could not parse predefined CMAP file for '" + cmapName + "'");
        }
      } catch (IOException exception) {
        LOG.error("Error: Could not find predefined CMAP file for '" + cmapName + "'");
      }
    }
  }
예제 #4
0
 /**
  * This method checks if required fields are present.
  *
  * @param result the list of error to update if the validation fails.
  * @return true if all fields are present, false otherwise.
  */
 protected boolean checkMandatoryFields(List<ValidationError> errors) {
   boolean res = pattern.getItem(COSName.getPDFName(DICTIONARY_KEY_RESOURCES)) != null;
   res = res && pattern.getItem(COSName.getPDFName(PATTERN_KEY_BBOX)) != null;
   res = res && pattern.getItem(COSName.getPDFName(PATTERN_KEY_PAINT_TYPE)) != null;
   res = res && pattern.getItem(COSName.getPDFName(PATTERN_KEY_TILING_TYPE)) != null;
   res = res && pattern.getItem(COSName.getPDFName(PATTERN_KEY_XSTEP)) != null;
   res = res && pattern.getItem(COSName.getPDFName(PATTERN_KEY_YSTEP)) != null;
   if (!res) {
     errors.add(new ValidationError(ERROR_GRAPHIC_INVALID_PATTERN_DEFINITION));
   }
   return res;
 }
예제 #5
0
 private COSStream getStream(Map<String, COSStream> streams, Token token) throws IOException {
   COSStream stream = streams.get(token.getDSSIdAsString());
   if (stream == null) {
     RandomAccessBuffer storage = new RandomAccessBuffer();
     stream = new COSStream(storage);
     OutputStream unfilteredStream = stream.createUnfilteredStream();
     unfilteredStream.write(token.getEncoded());
     unfilteredStream.flush();
     streams.put(token.getDSSIdAsString(), stream);
   }
   return stream;
 }
예제 #6
0
  @SuppressWarnings("unchecked")
  public static void main_3(String[] args) throws IOException {

    PDDocument doc = PDDocument.load(iconFile);

    List<PDPage> pages = doc.getDocumentCatalog().getAllPages();

    List<COSObject> objects = doc.getDocument().getObjects();

    for (COSObject cosObject : objects) {

      COSBase cosbase = cosObject.getObject();

      if (cosObject.getObject() instanceof COSStream) {

        COSStream cosstream = (COSStream) cosbase;

        COSBase filter = cosstream.getDictionaryObject(COSName.FILTER);

        COSBase subtype = cosstream.getDictionaryObject(COSName.SUBTYPE);

        if (subtype != null && subtype.equals(COSName.IMAGE)) {

          System.out.println(filter);

          InputStream filtered = cosstream.getFilteredStream();
          // PDStream stream = new PDStream(costream);

          System.out.println(Hex.encodeHex(IOUtils.toByteArray(filtered)));
        }
      }
    }

    for (PDPage pdPage : pages) {

      PDResources resources = pdPage.getResources();

      Map<String, PDXObject> images = resources.getXObjects();

      Set<String> keys = images.keySet();

      for (String key : keys) {

        PDXObject image = images.get(key);

        byte[] imgData = image.getPDStream().getByteArray();

        System.out.println(Hex.encodeHex(imgData));
      }
    }
  }
  /**
   * This will get the logical content stream with none of the filters.
   *
   * @return the bytes of the logical (decoded) stream
   * @throws IOException when encoding/decoding causes an exception
   */
  public InputStream getUnfilteredStream() throws IOException {
    Vector<InputStream> inputStreams = new Vector<InputStream>();
    byte[] inbetweenStreamBytes = "\n".getBytes("ISO-8859-1");

    for (int i = 0; i < streams.size(); i++) {
      COSStream stream = (COSStream) streams.getObject(i);
      inputStreams.add(stream.getUnfilteredStream());
      // handle the case where there is no whitespace in the
      // between streams in the contents array, without this
      // it is possible that two operators will get concatenated
      // together
      inputStreams.add(new ByteArrayInputStream(inbetweenStreamBytes));
    }

    return new SequenceInputStream(inputStreams.elements());
  }
예제 #8
0
  protected PDFunction getTintTransformer(COSStream xstream) throws IOException {
    COSBase cs = xstream.getDictionaryObject(COSName.COLORSPACE, COSName.CS);
    if (cs == null) {
      return null;
    }

    COSArray array = getCOSArray(cs);
    if (array == null) {
      return null;
    }
    String name = ((COSName) array.getObject(0)).getName();

    if (name.equals("DeviceN")) {
      PDFunction function = PDFunction.create(array.getObject(3));
      return function;
    }

    return null;
  }
 /**
  * This will get an object from this streams dictionary.
  *
  * @param key The key to the object.
  * @return The dictionary object with the key or null if one does not exist.
  */
 public COSBase getItem(COSName key) {
   return firstStream.getItem(key);
 }
 /**
  * This will get the scratch file associated with this stream.
  *
  * @return The scratch file where this stream is being stored.
  */
 public RandomAccess getScratchFile() {
   return firstStream.getScratchFile();
 }
 /**
  * This will create an output stream that can be written to.
  *
  * @return An output stream which raw data bytes should be written to.
  * @throws IOException If there is an error creating the stream.
  */
 public OutputStream createUnfilteredStream() throws IOException {
   return firstStream.createUnfilteredStream();
 }
 /**
  * set the filters to be applied to the stream.
  *
  * @param filters The filters to set on this stream.
  * @throws IOException If there is an error clearing the old filters.
  */
 public void setFilters(COSBase filters) throws IOException {
   // should this be allowed?  Should this
   // propagate to all streams in the array?
   firstStream.setFilters(filters);
 }
 /**
  * This will create a new stream for which filtered byte should be written to. You probably don't
  * want this but want to use the createUnfilteredStream, which is used to write raw bytes to.
  *
  * @param expectedLength An entry where a length is expected.
  * @return A stream that can be written to.
  * @throws IOException If there is an error creating the stream.
  */
 public OutputStream createFilteredStream(COSBase expectedLength) throws IOException {
   return firstStream.createFilteredStream(expectedLength);
 }
 /**
  * This will return the filters to apply to the byte stream the method will return. - null if no
  * filters are to be applied - a COSName if one filter is to be applied - a COSArray containing
  * COSNames if multiple filters are to be applied
  *
  * @return the COSBase object representing the filters
  */
 public COSBase getFilters() {
   return firstStream.getFilters();
 }
 /**
  * This will get an object from this streams dictionary and dereference it if necessary.
  *
  * @param key The key to the object.
  * @return The dictionary object with the key or null if one does not exist.
  */
 public COSBase getDictionaryObject(COSName key) {
   return firstStream.getDictionaryObject(key);
 }