001: /**
002: * Copyright (c) 2004-2006, www.pdfbox.org
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions are met:
007: *
008: * 1. Redistributions of source code must retain the above copyright notice,
009: * this list of conditions and the following disclaimer.
010: * 2. Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: * 3. Neither the name of pdfbox; nor the names of its
014: * contributors may be used to endorse or promote products derived from this
015: * software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
018: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
019: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
020: * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
021: * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
022: * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
023: * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
024: * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
025: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
026: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: *
028: * http://www.pdfbox.org
029: *
030: */package org.pdfbox.pdmodel.graphics.xobject;
031:
032: import java.awt.image.DataBufferByte;
033: import java.awt.image.BufferedImage;
034: import java.awt.image.ColorModel;
035: import java.awt.image.WritableRaster;
036: import java.io.IOException;
037: import java.io.OutputStream;
038:
039: import javax.imageio.ImageIO;
040:
041: import org.pdfbox.cos.COSArray;
042: import org.pdfbox.cos.COSBase;
043: import org.pdfbox.cos.COSDictionary;
044: import org.pdfbox.pdmodel.common.PDStream;
045:
046: import org.pdfbox.pdmodel.graphics.color.PDColorSpace;
047: import org.pdfbox.pdmodel.graphics.predictor.PredictorAlgorithm;
048:
049: /**
050: * This class contains a PixelMap Image.
051: * @author <a href="mailto:ben@benlitchfield.com">Ben Litchfield</a>
052: * @author mathiak
053: * @version $Revision: 1.8 $
054: */
055: public class PDPixelMap extends PDXObjectImage {
056: private BufferedImage image = null;
057:
058: /**
059: * Standard constructor. Basically does nothing.
060: * @param pdStream The stream that holds the pixel map.
061: */
062: public PDPixelMap(PDStream pdStream) {
063: super (pdStream, "png");
064: }
065:
066: /**
067: * Construct a pixel map image from an AWT image.
068: *
069: * @param doc The PDF document to embed the image in.
070: * @param awtImage The image to read data from.
071: *
072: * @throws IOException If there is an error while embedding this image.
073: */
074: /*
075: * This method is broken and needs to be implemented, any takers?
076: public PDPixelMap(PDDocument doc, BufferedImage awtImage) throws IOException
077: {
078: super( doc, "png");
079: image = awtImage;
080: setWidth( image.getWidth() );
081: setHeight( image.getHeight() );
082:
083: ColorModel cm = image.getColorModel();
084: ColorSpace cs = cm.getColorSpace();
085: PDColorSpace pdColorSpace = PDColorSpaceFactory.createColorSpace( doc, cs );
086: setColorSpace( pdColorSpace );
087: //setColorSpace( )
088:
089: PDStream stream = getPDStream();
090: OutputStream output = null;
091: try
092: {
093: output = stream.createOutputStream();
094: DataBuffer buffer = awtImage.getRaster().getDataBuffer();
095: if( buffer instanceof DataBufferByte )
096: {
097: DataBufferByte byteBuffer = (DataBufferByte)buffer;
098: byte[] data = byteBuffer.getData();
099: output.write( data );
100: }
101: setBitsPerComponent( cm.getPixelSize() );
102: }
103: finally
104: {
105: if( output != null )
106: {
107: output.close();
108: }
109: }
110: }*/
111:
112: /**
113: * Returns a {@link java.awt.image.BufferedImage} of the COSStream
114: * set in the constructor or null if the COSStream could not be encoded.
115: *
116: * @return {@inheritDoc}
117: *
118: * @throws IOException {@inheritDoc}
119: */
120: public BufferedImage getRGBImage() throws IOException {
121: if (image != null) {
122: return image;
123: }
124:
125: //byte[] index =
126: //ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_sRGB);
127: int width = getWidth();
128: int height = getHeight();
129: int bpc = getBitsPerComponent();
130: //COSInteger length =
131: // (COSInteger) stream.getStream().getDictionary().getDictionaryObject(COSName.LENGTH);
132: //byte[] array = new byte[stream.getFilteredStream().];
133: byte[] array = getPDStream().getByteArray();
134:
135: // Get the ColorModel right
136: PDColorSpace colorspace = getColorSpace();
137: ColorModel cm = colorspace.createColorModel(bpc);
138: WritableRaster raster = cm.createCompatibleWritableRaster(
139: width, height);
140: //DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();
141: DataBufferByte buffer = (DataBufferByte) raster.getDataBuffer();
142: byte[] bufferData = buffer.getData();
143: //System.arraycopy( array, 0, bufferData, 0, array.length );
144: int predictor = getPredictor();
145:
146: PredictorAlgorithm filter = PredictorAlgorithm
147: .getFilter(predictor);
148: filter.setWidth(width);
149: filter.setHeight(height);
150: filter.setBpp((bpc * 3) / 8);
151: filter.decode(array, bufferData);
152: image = new BufferedImage(cm, raster, false, null);
153: return image;
154: }
155:
156: /**
157: * Writes the image as .png.
158: *
159: * {@inheritDoc}
160: */
161: public void write2OutputStream(OutputStream out) throws IOException {
162: getRGBImage();
163: if (image != null) {
164: ImageIO.write(image, "png", out);
165: }
166: }
167:
168: /**
169: * DecodeParms is an optional parameter for filters.
170: *
171: * It is provided if any of the filters has nondefault parameters. If there
172: * is only one filter it is a dictionary, if there are multiple filters it
173: * is an array with an entry for each filter. An array entry can hold a null
174: * value if only the default values are used or a dictionary with
175: * parameters.
176: *
177: * @return The decoding parameters.
178: *
179: */
180: public COSDictionary getDecodeParams() {
181: COSBase decodeParms = getCOSStream().getDictionaryObject(
182: "DecodeParms");
183: if (decodeParms != null) {
184: if (decodeParms instanceof COSDictionary) {
185: return (COSDictionary) decodeParms;
186: } else if (decodeParms instanceof COSArray) {
187: // not implemented yet, which index should we use?
188: return null;//(COSDictionary)((COSArray)decodeParms).get(0);
189: } else {
190: return null;
191: }
192: }
193: return null;
194: }
195:
196: /**
197: * A code that selects the predictor algorithm.
198: *
199: * <ul>
200: * <li>1 No prediction (the default value)
201: * <li>2 TIFF Predictor 2
202: * <li>10 PNG prediction (on encoding, PNG None on all rows)
203: * <li>11 PNG prediction (on encoding, PNG Sub on all rows)
204: * <li>12 PNG prediction (on encoding, PNG Up on all rows)
205: * <li>13 PNG prediction (on encoding, PNG Average on all rows)
206: * <li>14 PNG prediction (on encoding, PNG Paeth on all rows)
207: * <li>15 PNG prediction (on encoding, PNG optimum)
208: * </ul>
209: *
210: * Default value: 1.
211: *
212: * @return predictor algorithm code
213: */
214: public int getPredictor() {
215: COSDictionary decodeParms = getDecodeParams();
216: if (decodeParms != null) {
217: int i = decodeParms.getInt("Predictor");
218: if (i != -1) {
219: return i;
220: }
221: }
222: return 1;
223: }
224: }
|