/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (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.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

/* $Id: PDFImageXObject.java 1758773 2016-09-01 13:02:29Z ssteiner $ */

package org.apache.fop.pdf;

// Java
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

/* modified by JKT to integrate with 0.12.0 */
/* modified by Eric SCHAEFFER to integrate with 0.13.0 */

PDF XObject A derivative of the PDF Object, is a PDF Stream that has not only a dictionary but a stream of image data. The dictionary just provides information like the stream length. This outputs the image dictionary and the image data. This is used as a reference for inserting the same image in the document in another place.
/** * PDF XObject * * A derivative of the PDF Object, is a PDF Stream that has not only a * dictionary but a stream of image data. * The dictionary just provides information like the stream length. * This outputs the image dictionary and the image data. * This is used as a reference for inserting the same image in the * document in another place. */
public class PDFImageXObject extends PDFXObject { private PDFImage pdfimage;
create an XObject with the given number and name and load the image in the object
Params:
  • xnumber – the pdf object X number
  • img – the pdf image that contains the image data
/** * create an XObject with the given number and name and load the * image in the object * * @param xnumber the pdf object X number * @param img the pdf image that contains the image data */
public PDFImageXObject(int xnumber, PDFImage img) { super(); put("Name", new PDFName("Im" + xnumber)); pdfimage = img; }
Output the image as PDF. This sets up the image dictionary and adds the image data stream.
Params:
  • stream – the output stream to write the data
Throws:
Returns:the length of the data written
/** * Output the image as PDF. * This sets up the image dictionary and adds the image data stream. * * @param stream the output stream to write the data * @throws IOException if there is an error writing the data * @return the length of the data written */
public int output(OutputStream stream) throws IOException { if (getDocument().getProfile().isPDFVTActive()) { ByteArrayOutputStream baos = new ByteArrayOutputStream(); pdfimage.outputContents(baos); put("GTS_XID", "uuid:" + UUID.nameUUIDFromBytes(baos.toByteArray())); } int length = super.output(stream); // let it gc // this object is retained as a reference to inserting // the same image but the image data is no longer needed pdfimage = null; return length; }
{@inheritDoc}
/** {@inheritDoc} */
protected void populateStreamDict(Object lengthEntry) { super.populateStreamDict(lengthEntry); if (pdfimage.isPS()) { populateDictionaryFromPS(); } else { populateDictionaryFromImage(); } } private void populateDictionaryFromPS() { getDocumentSafely().getProfile().verifyPSXObjectsAllowed(); put("Subtype", new PDFName("PS")); } private void populateDictionaryFromImage() { put("Subtype", new PDFName("Image")); put("Width", pdfimage.getWidth()); put("Height", pdfimage.getHeight()); put("BitsPerComponent", pdfimage.getBitsPerComponent()); PDFICCStream pdfICCStream = pdfimage.getICCStream(); if (pdfICCStream != null) { put("ColorSpace", new PDFArray(this, new Object[] {new PDFName("ICCBased"), pdfICCStream})); } else { PDFDeviceColorSpace cs = pdfimage.getColorSpace(); put("ColorSpace", new PDFName(cs.getName())); } if (pdfimage.isInverted()) { /* PhotoShop generates CMYK values that's inverse, * this will invert the values - too bad if it's not * a PhotoShop image... */ final Float zero = 0.0f; final Float one = 1.0f; PDFArray decode = new PDFArray(this); for (int i = 0, c = pdfimage.getColorSpace().getNumComponents(); i < c; i++) { decode.add(one); decode.add(zero); } put("Decode", decode); } if (pdfimage.isTransparent()) { PDFColor transp = pdfimage.getTransparentColor(); PDFArray mask = new PDFArray(this); if (pdfimage.getColorSpace().isGrayColorSpace()) { mask.add(Integer.valueOf(transp.red255())); mask.add(Integer.valueOf(transp.red255())); } else { mask.add(Integer.valueOf(transp.red255())); mask.add(Integer.valueOf(transp.red255())); mask.add(Integer.valueOf(transp.green255())); mask.add(Integer.valueOf(transp.green255())); mask.add(Integer.valueOf(transp.blue255())); mask.add(Integer.valueOf(transp.blue255())); } put("Mask", mask); } PDFReference ref = pdfimage.getSoftMaskReference(); if (ref != null) { put("SMask", ref); } //Important: do this at the end so previous values can be overwritten. pdfimage.populateXObjectDictionary(getDictionary()); }
{@inheritDoc}
/** {@inheritDoc} */
protected void outputRawStreamData(OutputStream out) throws IOException { pdfimage.outputContents(out); }
{@inheritDoc}
/** {@inheritDoc} */
protected int getSizeHint() throws IOException { return 0; }
{@inheritDoc}
/** {@inheritDoc} */
protected void prepareImplicitFilters() { PDFFilter pdfFilter = pdfimage.getPDFFilter(); if (pdfFilter != null) { getFilterList().ensureFilterInPlace(pdfFilter); } }
{@inheritDoc} This class uses the PDFImage instance to determine the default filter.
/** * {@inheritDoc} * This class uses the PDFImage instance to determine the default filter. */
protected String getDefaultFilterName() { return pdfimage.getFilterHint(); }
{@inheritDoc}
/** {@inheritDoc} */
protected boolean multipleFiltersAllowed() { return pdfimage.multipleFiltersAllowed(); } @Override public void getChildren(Set<PDFObject> children) { super.getChildren(children); PDFICCStream pdfICCStream = pdfimage.getICCStream(); if (pdfICCStream != null) { children.add(pdfICCStream); pdfICCStream.getChildren(children); } } }