blob: 34c73cdafc9bc9bacce1c6a3d06ab117098e013e [file] [log] [blame]
/*
* Copyright 1999-2004 The Apache Software Foundation.
*
* Licensed 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$ */
package org.apache.fop.pdf;
// Java
import java.io.IOException;
import java.io.OutputStream;
/* 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.
*/
public class PDFXObject extends AbstractPDFStream {
private PDFImage pdfimage;
private int xnum;
/**
* 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 PDFXObject(int xnumber, PDFImage img) {
super();
this.xnum = xnumber;
pdfimage = img;
}
/**
* Get the xnumber for this pdf object.
*
* @return the PDF XObject number
*/
public int getXNumber() {
return this.xnum;
}
/**
* 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
*/
protected int output(OutputStream stream) throws IOException {
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;
}
/**
* @see org.apache.fop.pdf.AbstractPDFStream#buildStreamDict(String)
*/
protected String buildStreamDict(String lengthEntry) {
String dictEntries = getFilterList().buildFilterDictEntries();
if (pdfimage.isPS()) {
return buildDictionaryFromPS(lengthEntry, dictEntries);
} else {
return buildDictionaryFromImage(lengthEntry, dictEntries);
}
}
private String buildDictionaryFromPS(String lengthEntry,
String dictEntries) {
StringBuffer sb = new StringBuffer(128);
sb.append(getObjectID());
sb.append("<</Type /XObject\n");
sb.append("/Subtype /PS\n");
sb.append("/Length " + lengthEntry);
sb.append(dictEntries);
sb.append("\n>>\n");
return sb.toString();
}
private String buildDictionaryFromImage(String lengthEntry,
String dictEntries) {
StringBuffer sb = new StringBuffer(128);
sb.append(getObjectID());
sb.append("<</Type /XObject\n");
sb.append("/Subtype /Image\n");
sb.append("/Name /Im" + xnum + "\n");
sb.append("/Length " + lengthEntry + "\n");
sb.append("/Width " + pdfimage.getWidth() + "\n");
sb.append("/Height " + pdfimage.getHeight() + "\n");
sb.append("/BitsPerComponent " + pdfimage.getBitsPerPixel() + "\n");
PDFICCStream pdfICCStream = pdfimage.getICCStream();
if (pdfICCStream != null) {
sb.append("/ColorSpace [/ICCBased "
+ pdfICCStream.referencePDF() + "]\n");
} else {
PDFColorSpace cs = pdfimage.getColorSpace();
sb.append("/ColorSpace /" + cs.getColorSpacePDFString()
+ "\n");
}
/* PhotoShop generates CMYK values that's inverse,
this will invert the values - too bad if it's not
a PhotoShop image...
*/
if (pdfimage.getColorSpace().getColorSpace()
== PDFColorSpace.DEVICE_CMYK) {
sb.append("/Decode [ 1.0 0.0 1.0 0.0 1.0 0.0 1.1 0.0 ]\n");
}
if (pdfimage.isTransparent()) {
PDFColor transp = pdfimage.getTransparentColor();
sb.append("/Mask ["
+ transp.red255() + " "
+ transp.red255() + " "
+ transp.green255() + " "
+ transp.green255() + " "
+ transp.blue255() + " "
+ transp.blue255() + "]\n");
}
String ref = pdfimage.getSoftMask();
if (ref != null) {
sb.append("/SMask " + ref + "\n");
}
sb.append(dictEntries);
sb.append("\n>>\n");
return sb.toString();
}
/**
* @see org.apache.fop.pdf.PDFStream#outputRawStreamData(OutputStream)
*/
protected void outputRawStreamData(OutputStream out) throws IOException {
pdfimage.outputContents(out);
}
/**
* @see org.apache.fop.pdf.AbstractPDFStream#getSizeHint()
*/
protected int getSizeHint() throws IOException {
return 0;
}
/**
* @see org.apache.fop.pdf.AbstractPDFStream#prepareImplicitFilters()
*/
protected void prepareImplicitFilters() {
if (pdfimage.isDCT()) {
getFilterList().ensureDCTFilterInPlace();
}
}
/**
* This sets up the default filters for XObjects. It uses the PDFImage
* instance to determine what default filters to apply.
* @see org.apache.fop.pdf.AbstractPDFStream#setupFilterList()
*/
protected void setupFilterList() {
if (!getFilterList().isInitialized()) {
getFilterList().addDefaultFilters(
getDocumentSafely().getFilterMap(),
pdfimage.getFilterHint());
}
super.setupFilterList();
}
}