001: /*
002: * $Id: PdfImage.java 2752 2007-05-15 14:58:33Z blowagie $
003: * $Name$
004: *
005: * Copyright 1999, 2000, 2001, 2002 Bruno Lowagie
006: *
007: * The contents of this file are subject to the Mozilla Public License Version 1.1
008: * (the "License"); you may not use this file except in compliance with the License.
009: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the License.
014: *
015: * The Original Code is 'iText, a free JAVA-PDF library'.
016: *
017: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
018: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
019: * All Rights Reserved.
020: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
021: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
022: *
023: * Contributor(s): all the names of the contributors are added in the source code
024: * where applicable.
025: *
026: * Alternatively, the contents of this file may be used under the terms of the
027: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
028: * provisions of LGPL are applicable instead of those above. If you wish to
029: * allow use of your version of this file only under the terms of the LGPL
030: * License and not to allow others to use your version of this file under
031: * the MPL, indicate your decision by deleting the provisions above and
032: * replace them with the notice and other provisions required by the LGPL.
033: * If you do not delete the provisions above, a recipient may use your version
034: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
035: *
036: * This library is free software; you can redistribute it and/or modify it
037: * under the terms of the MPL as stated above or under the terms of the GNU
038: * Library General Public License as published by the Free Software Foundation;
039: * either version 2 of the License, or any later version.
040: *
041: * This library is distributed in the hope that it will be useful, but WITHOUT
042: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
043: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
044: * details.
045: *
046: * If you didn't download this code from the following link, you should check if
047: * you aren't using an obsolete version:
048: * http://www.lowagie.com/iText/
049: */
050:
051: package com.lowagie.text.pdf;
052:
053: import java.io.ByteArrayOutputStream;
054: import java.io.IOException;
055: import java.io.InputStream;
056: import java.io.OutputStream;
057:
058: import com.lowagie.text.Image;
059:
060: /**
061: * <CODE>PdfImage</CODE> is a <CODE>PdfStream</CODE> containing an image-<CODE>Dictionary</CODE> and -stream.
062: */
063:
064: public class PdfImage extends PdfStream {
065:
066: static final int TRANSFERSIZE = 4096;
067: // membervariables
068:
069: /** This is the <CODE>PdfName</CODE> of the image. */
070: protected PdfName name = null;
071:
072: // constructor
073:
074: /**
075: * Constructs a <CODE>PdfImage</CODE>-object.
076: *
077: * @param image the <CODE>Image</CODE>-object
078: * @param name the <CODE>PdfName</CODE> for this image
079: * @throws BadPdfFormatException on error
080: */
081:
082: public PdfImage(Image image, String name,
083: PdfIndirectReference maskRef) throws BadPdfFormatException {
084: super ();
085: this .name = new PdfName(name);
086: put(PdfName.TYPE, PdfName.XOBJECT);
087: put(PdfName.SUBTYPE, PdfName.IMAGE);
088: put(PdfName.WIDTH, new PdfNumber(image.getWidth()));
089: put(PdfName.HEIGHT, new PdfNumber(image.getHeight()));
090: if (image.getLayer() != null)
091: put(PdfName.OC, image.getLayer().getRef());
092: if (image.isMask()
093: && (image.getBpc() == 1 || image.getBpc() > 0xff))
094: put(PdfName.IMAGEMASK, PdfBoolean.PDFTRUE);
095: if (maskRef != null) {
096: if (image.isSmask())
097: put(PdfName.SMASK, maskRef);
098: else
099: put(PdfName.MASK, maskRef);
100: }
101: if (image.isMask() && image.isInverted())
102: put(PdfName.DECODE, new PdfLiteral("[1 0]"));
103: if (image.isInterpolation())
104: put(PdfName.INTERPOLATE, PdfBoolean.PDFTRUE);
105: InputStream is = null;
106: try {
107:
108: // Raw Image data
109: if (image.isImgRaw()) {
110: // will also have the CCITT parameters
111: int colorspace = image.getColorspace();
112: int transparency[] = image.getTransparency();
113: if (transparency != null && !image.isMask()
114: && maskRef == null) {
115: String s = "[";
116: for (int k = 0; k < transparency.length; ++k)
117: s += transparency[k] + " ";
118: s += "]";
119: put(PdfName.MASK, new PdfLiteral(s));
120: }
121: bytes = image.getRawData();
122: put(PdfName.LENGTH, new PdfNumber(bytes.length));
123: int bpc = image.getBpc();
124: if (bpc > 0xff) {
125: if (!image.isMask())
126: put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
127: put(PdfName.BITSPERCOMPONENT, new PdfNumber(1));
128: put(PdfName.FILTER, PdfName.CCITTFAXDECODE);
129: int k = bpc - Image.CCITTG3_1D;
130: PdfDictionary decodeparms = new PdfDictionary();
131: if (k != 0)
132: decodeparms.put(PdfName.K, new PdfNumber(k));
133: if ((colorspace & Image.CCITT_BLACKIS1) != 0)
134: decodeparms.put(PdfName.BLACKIS1,
135: PdfBoolean.PDFTRUE);
136: if ((colorspace & Image.CCITT_ENCODEDBYTEALIGN) != 0)
137: decodeparms.put(PdfName.ENCODEDBYTEALIGN,
138: PdfBoolean.PDFTRUE);
139: if ((colorspace & Image.CCITT_ENDOFLINE) != 0)
140: decodeparms.put(PdfName.ENDOFLINE,
141: PdfBoolean.PDFTRUE);
142: if ((colorspace & Image.CCITT_ENDOFBLOCK) != 0)
143: decodeparms.put(PdfName.ENDOFBLOCK,
144: PdfBoolean.PDFFALSE);
145: decodeparms.put(PdfName.COLUMNS, new PdfNumber(
146: image.getWidth()));
147: decodeparms.put(PdfName.ROWS, new PdfNumber(image
148: .getHeight()));
149: put(PdfName.DECODEPARMS, decodeparms);
150: } else {
151: switch (colorspace) {
152: case 1:
153: put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
154: if (image.isInverted())
155: put(PdfName.DECODE, new PdfLiteral("[1 0]"));
156: break;
157: case 3:
158: put(PdfName.COLORSPACE, PdfName.DEVICERGB);
159: if (image.isInverted())
160: put(PdfName.DECODE, new PdfLiteral(
161: "[1 0 1 0 1 0]"));
162: break;
163: case 4:
164: default:
165: put(PdfName.COLORSPACE, PdfName.DEVICECMYK);
166: if (image.isInverted())
167: put(PdfName.DECODE, new PdfLiteral(
168: "[1 0 1 0 1 0 1 0]"));
169: }
170: PdfDictionary additional = image.getAdditional();
171: if (additional != null)
172: putAll(additional);
173: if (image.isMask()
174: && (image.getBpc() == 1 || image.getBpc() > 8))
175: remove(PdfName.COLORSPACE);
176: put(PdfName.BITSPERCOMPONENT, new PdfNumber(image
177: .getBpc()));
178: if (image.isDeflated())
179: put(PdfName.FILTER, PdfName.FLATEDECODE);
180: else {
181: flateCompress();
182: }
183: }
184: return;
185: }
186:
187: // GIF, JPEG or PNG
188: String errorID;
189: if (image.getRawData() == null) {
190: is = image.getUrl().openStream();
191: errorID = image.getUrl().toString();
192: } else {
193: is = new java.io.ByteArrayInputStream(image
194: .getRawData());
195: errorID = "Byte array";
196: }
197: switch (image.type()) {
198: case Image.JPEG:
199: put(PdfName.FILTER, PdfName.DCTDECODE);
200: switch (image.getColorspace()) {
201: case 1:
202: put(PdfName.COLORSPACE, PdfName.DEVICEGRAY);
203: break;
204: case 3:
205: put(PdfName.COLORSPACE, PdfName.DEVICERGB);
206: break;
207: default:
208: put(PdfName.COLORSPACE, PdfName.DEVICECMYK);
209: if (image.isInverted()) {
210: put(PdfName.DECODE, new PdfLiteral(
211: "[1 0 1 0 1 0 1 0]"));
212: }
213: }
214: put(PdfName.BITSPERCOMPONENT, new PdfNumber(8));
215: if (image.getRawData() != null) {
216: bytes = image.getRawData();
217: put(PdfName.LENGTH, new PdfNumber(bytes.length));
218: return;
219: }
220: streamBytes = new ByteArrayOutputStream();
221: transferBytes(is, streamBytes, -1);
222: break;
223: default:
224: throw new BadPdfFormatException(errorID
225: + " is an unknown Image format.");
226: }
227: put(PdfName.LENGTH, new PdfNumber(streamBytes.size()));
228: } catch (IOException ioe) {
229: throw new BadPdfFormatException(ioe.getMessage());
230: } finally {
231: if (is != null) {
232: try {
233: is.close();
234: } catch (Exception ee) {
235: // empty on purpose
236: }
237: }
238: }
239: }
240:
241: /**
242: * Returns the <CODE>PdfName</CODE> of the image.
243: *
244: * @return the name
245: */
246:
247: public PdfName name() {
248: return name;
249: }
250:
251: static void transferBytes(InputStream in, OutputStream out, int len)
252: throws IOException {
253: byte buffer[] = new byte[TRANSFERSIZE];
254: if (len < 0)
255: len = 0x7ffffff;
256: int size;
257: while (len != 0) {
258: size = in.read(buffer, 0, Math.min(len, TRANSFERSIZE));
259: if (size < 0)
260: return;
261: out.write(buffer, 0, size);
262: len -= size;
263: }
264: }
265:
266: protected void importAll(PdfImage dup) {
267: name = dup.name;
268: compressed = dup.compressed;
269: streamBytes = dup.streamBytes;
270: bytes = dup.bytes;
271: hashMap = dup.hashMap;
272: }
273: }
|