KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > rtf > graphic > RtfImage


1 /*
2  * $Id: RtfImage.java 2825 2007-06-04 09:15:21Z blowagie $
3  * $Name$
4  *
5  * Copyright 2001, 2002, 2003, 2004 by Mark Hall
6  *
7  * The contents of this file are subject to the Mozilla Public License Version 1.1
8  * (the "License"); you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at http://www.mozilla.org/MPL/
10  *
11  * Software distributed under the License is distributed on an "AS IS" basis,
12  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13  * for the specific language governing rights and limitations under the License.
14  *
15  * The Original Code is 'iText, a free JAVA-PDF library'.
16  *
17  * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
18  * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
19  * All Rights Reserved.
20  * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
21  * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
22  *
23  * Contributor(s): all the names of the contributors are added in the source code
24  * where applicable.
25  *
26  * Alternatively, the contents of this file may be used under the terms of the
27  * LGPL license (the ?GNU LIBRARY GENERAL PUBLIC LICENSE?), in which case the
28  * provisions of LGPL are applicable instead of those above. If you wish to
29  * allow use of your version of this file only under the terms of the LGPL
30  * License and not to allow others to use your version of this file under
31  * the MPL, indicate your decision by deleting the provisions above and
32  * replace them with the notice and other provisions required by the LGPL.
33  * If you do not delete the provisions above, a recipient may use your version
34  * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
35  *
36  * This library is free software; you can redistribute it and/or modify it
37  * under the terms of the MPL as stated above or under the terms of the GNU
38  * Library General Public License as published by the Free Software Foundation;
39  * either version 2 of the License, or any later version.
40  *
41  * This library is distributed in the hope that it will be useful, but WITHOUT
42  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
43  * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
44  * details.
45  *
46  * If you didn't download this code from the following link, you should check if
47  * you aren't using an obsolete version:
48  * http://www.lowagie.com/iText/
49  */

50
51 package com.lowagie.text.rtf.graphic;
52
53 import java.io.ByteArrayOutputStream JavaDoc;
54 import java.io.EOFException JavaDoc;
55 import java.io.IOException JavaDoc;
56 import java.io.InputStream JavaDoc;
57 import java.io.OutputStream JavaDoc;
58
59 import com.lowagie.text.DocumentException;
60 import com.lowagie.text.Element;
61 import com.lowagie.text.Image;
62 import com.lowagie.text.pdf.codec.wmf.MetaDo;
63 import com.lowagie.text.rtf.RtfElement;
64 import com.lowagie.text.rtf.document.RtfDocument;
65 import com.lowagie.text.rtf.document.output.RtfByteArrayBuffer;
66 import com.lowagie.text.rtf.style.RtfParagraphStyle;
67 import com.lowagie.text.rtf.text.RtfParagraph;
68
69 /**
70  * The RtfImage contains one image. Supported image types are jpeg, png, wmf, bmp.
71  *
72  * @version $Id: RtfImage.java 2825 2007-06-04 09:15:21Z blowagie $
73  * @author Mark Hall (mhall@edu.uni-klu.ac.at)
74  * @author Paulo Soares
75  * @author Thomas Bickel (tmb99@inode.at)
76  */

77 public class RtfImage extends RtfElement {
78     
79     /**
80      * Constant for the shape/picture group
81      */

82     private static final byte[] PICTURE_GROUP = "\\*\\shppict".getBytes();
83     /**
84      * Constant for a picture
85      */

86     private static final byte[] PICTURE = "\\pict".getBytes();
87     /**
88      * Constant for a jpeg image
89      */

90     private static final byte[] PICTURE_JPEG = "\\jpegblip".getBytes();
91     /**
92      * Constant for a png image
93      */

94     private static final byte[] PICTURE_PNG = "\\pngblip".getBytes();
95     /**
96      * Constant for a bmp image
97      */

98     private static final byte[] PICTURE_BMP = "\\dibitmap0".getBytes();
99     /**
100      * Constant for a wmf image
101      */

102     private static final byte[] PICTURE_WMF = "\\wmetafile8".getBytes();
103     /**
104      * Constant for the picture width
105      */

106     private static final byte[] PICTURE_WIDTH = "\\picw".getBytes();
107     /**
108      * Constant for the picture height
109      */

110     private static final byte[] PICTURE_HEIGHT = "\\pich".getBytes();
111     /**
112      * Constant for the picture width scale
113      */

114     private static final byte[] PICTURE_SCALED_WIDTH = "\\picwgoal".getBytes();
115     /**
116      * Constant for the picture height scale
117      */

118     private static final byte[] PICTURE_SCALED_HEIGHT = "\\pichgoal".getBytes();
119     /**
120      * Constant for horizontal picture scaling
121      */

122     private static final byte[] PICTURE_SCALE_X = "\\picscalex".getBytes();
123     /**
124      * Constant for vertical picture scaling
125      */

126     private static final byte[] PICTURE_SCALE_Y = "\\picscaley".getBytes();
127     /**
128      * "\bin" constant
129      */

130     private static final byte[] PICTURE_BINARY_DATA = "\\bin".getBytes();
131     /**
132      * Constant for converting pixels to twips
133      */

134     private static final int PIXEL_TWIPS_FACTOR = 15;
135     
136     /**
137      * The type of image this is.
138      */

139     private final int imageType;
140     /**
141      * Binary image data.
142      */

143     private final byte[][] imageData;
144     /**
145      * The alignment of this picture
146      */

147     private int alignment = Element.ALIGN_LEFT;
148     /**
149      * The width of this picture
150      */

151     private float width = 0;
152     /**
153      * The height of this picutre
154      */

155     private float height = 0;
156     /**
157      * The intended display width of this picture
158      */

159     private float plainWidth = 0;
160     /**
161      * The intended display height of this picture
162      */

163     private float plainHeight = 0;
164     /**
165      * Whether this RtfImage is a top level element and should
166      * be an extra paragraph.
167      */

168     private boolean topLevelElement = false;
169     
170     /**
171      * Constructs a RtfImage for an Image.
172      *
173      * @param doc The RtfDocument this RtfImage belongs to
174      * @param image The Image that this RtfImage wraps
175      * @throws DocumentException If an error occured accessing the image content
176      */

177     public RtfImage(RtfDocument doc, Image image) throws DocumentException
178     {
179         super(doc);
180         imageType = image.getOriginalType();
181         if (!(imageType == Image.ORIGINAL_JPEG || imageType == Image.ORIGINAL_BMP
182                 || imageType == Image.ORIGINAL_PNG || imageType == Image.ORIGINAL_WMF || imageType == Image.ORIGINAL_GIF)) {
183             throw new DocumentException("Only BMP, PNG, WMF, GIF and JPEG images are supported by the RTF Writer");
184         }
185         alignment = image.getAlignment();
186         width = image.getWidth();
187         height = image.getHeight();
188         plainWidth = image.getPlainWidth();
189         plainHeight = image.getPlainHeight();
190         this.imageData = getImageData(image);
191     }
192     
193     /**
194      * Extracts the image data from the Image.
195      *
196      * @param image The image for which to extract the content
197      * @return The raw image data, not formated
198      * @throws DocumentException If an error occurs accessing the image content
199      */

200     private byte[][] getImageData(Image image) throws DocumentException
201     {
202         final int WMF_PLACEABLE_HEADER_SIZE = 22;
203         final RtfByteArrayBuffer bab = new RtfByteArrayBuffer();
204         
205         try {
206             if(imageType == Image.ORIGINAL_BMP) {
207                 bab.append(MetaDo.wrapBMP(image));
208             } else {
209                 final byte[] iod = image.getOriginalData();
210                 if(iod == null) {
211                     
212                     final InputStream JavaDoc imageIn = image.getUrl().openStream();
213                     if(imageType == Image.ORIGINAL_WMF) { //remove the placeable header first
214
for(int k = 0; k < WMF_PLACEABLE_HEADER_SIZE; k++) {
215                             if(imageIn.read() < 0) throw(new EOFException JavaDoc("while removing wmf placeable header"));
216                         }
217                     }
218                     bab.write(imageIn);
219                     imageIn.close();
220                     
221                 } else {
222                     
223                     if(imageType == Image.ORIGINAL_WMF) {
224                         //remove the placeable header
225
bab.write(iod, WMF_PLACEABLE_HEADER_SIZE, iod.length - WMF_PLACEABLE_HEADER_SIZE);
226                     } else {
227                         bab.append(iod);
228                     }
229                     
230                 }
231             }
232             
233             return(bab.toByteArrayArray());
234             
235         } catch(IOException JavaDoc ioe) {
236             throw new DocumentException(ioe.getMessage());
237         }
238     }
239     
240     
241     /**
242      * lookup table used for converting bytes to hex chars.
243      * TODO Should probably be refactored into a helper class
244      */

245     public final static byte[] byte2charLUT = new byte[512]; //'0001020304050607 ... fafbfcfdfeff'
246
static {
247         char c = '0';
248         for(int k = 0; k < 16; k++) {
249             for(int x = 0; x < 16; x++) {
250                 byte2charLUT[((k*16)+x)*2] = byte2charLUT[(((x*16)+k)*2)+1] = (byte)c;
251             }
252             if(++c == ':') c = 'a';
253         }
254     }
255     /**
256      * Writes the image data to the given buffer as hex encoded text.
257      *
258      * @param bab
259      * @throws IOException
260      */

261     private void writeImageDataHexEncoded(final OutputStream JavaDoc bab) throws IOException JavaDoc
262     {
263         int cnt = 0;
264         for(int k = 0; k < imageData.length; k++) {
265             final byte[] chunk = imageData[k];
266             for(int x = 0; x < chunk.length; x++) {
267                 bab.write(byte2charLUT, (chunk[x]&0xff)*2, 2);
268                 if(++cnt == 64) {
269                     bab.write('\n');
270                     cnt = 0;
271                 }
272             }
273         }
274         if(cnt > 0) bab.write('\n');
275     }
276     /**
277      * Returns the image raw data size in bytes.
278      *
279      * @return the size in bytes
280      */

281     private int imageDataSize()
282     {
283         int size = 0;
284         for(int k = 0; k < imageData.length; k++) {
285             size += imageData[k].length;
286         }
287         return(size);
288     }
289     
290     /**
291      * Writes the RtfImage content
292      *
293      * @return the RtfImage content
294      * @deprecated replaced by {@link #writeContent(OutputStream)}
295      */

296     public byte[] write()
297     {
298         final ByteArrayOutputStream JavaDoc result = new ByteArrayOutputStream JavaDoc();
299         try {
300             writeContent(result);
301         } catch(Exception JavaDoc ioe) {
302             ioe.printStackTrace();
303         }
304
305         return(result.toByteArray());
306     }
307     /**
308      * Writes the RtfImage content
309      */

310     public void writeContent(final OutputStream JavaDoc result) throws IOException JavaDoc
311     {
312         //new RuntimeException("info").printStackTrace();
313

314         if(this.topLevelElement) {
315             result.write(RtfParagraph.PARAGRAPH_DEFAULTS);
316             switch(alignment) {
317                 case Element.ALIGN_LEFT:
318                     result.write(RtfParagraphStyle.ALIGN_LEFT);
319                     break;
320                 case Element.ALIGN_RIGHT:
321                     result.write(RtfParagraphStyle.ALIGN_RIGHT);
322                     break;
323                 case Element.ALIGN_CENTER:
324                     result.write(RtfParagraphStyle.ALIGN_CENTER);
325                     break;
326                 case Element.ALIGN_JUSTIFIED:
327                     result.write(RtfParagraphStyle.ALIGN_JUSTIFY);
328                     break;
329             }
330         }
331         result.write(OPEN_GROUP);
332         result.write(PICTURE_GROUP);
333         result.write(OPEN_GROUP);
334         result.write(PICTURE);
335         switch(imageType) {
336             case Image.ORIGINAL_JPEG:
337                 result.write(PICTURE_JPEG);
338                 break;
339             case Image.ORIGINAL_PNG:
340             case Image.ORIGINAL_GIF:
341                 result.write(PICTURE_PNG);
342                 break;
343             case Image.ORIGINAL_WMF:
344             case Image.ORIGINAL_BMP:
345                 result.write(PICTURE_WMF);
346                 break;
347         }
348         result.write(PICTURE_WIDTH);
349         result.write(intToByteArray((int) width));
350         result.write(PICTURE_HEIGHT);
351         result.write(intToByteArray((int) height));
352         if(this.document.getDocumentSettings().isWriteImageScalingInformation()) {
353             result.write(PICTURE_SCALE_X);
354             result.write(intToByteArray((int)(100 * plainWidth / width)));
355             result.write(PICTURE_SCALE_Y);
356             result.write(intToByteArray((int)(100 * plainHeight / height)));
357         }
358         if(this.document.getDocumentSettings().isImagePDFConformance()) {
359             result.write(PICTURE_SCALED_WIDTH);
360             result.write(intToByteArray((int) (plainWidth * RtfElement.TWIPS_FACTOR)));
361             result.write(PICTURE_SCALED_HEIGHT);
362             result.write(intToByteArray((int) (plainHeight * RtfElement.TWIPS_FACTOR)));
363         } else {
364             if(this.width != this.plainWidth || this.imageType == Image.ORIGINAL_BMP) {
365                 result.write(PICTURE_SCALED_WIDTH);
366                 result.write(intToByteArray((int) (plainWidth * PIXEL_TWIPS_FACTOR)));
367             }
368             if(this.height != this.plainHeight || this.imageType == Image.ORIGINAL_BMP) {
369                 result.write(PICTURE_SCALED_HEIGHT);
370                 result.write(intToByteArray((int) (plainHeight * PIXEL_TWIPS_FACTOR)));
371             }
372         }
373
374         if(true) {
375             //binary
376
result.write('\n');
377             result.write(PICTURE_BINARY_DATA);
378             result.write(intToByteArray(imageDataSize()));
379             result.write(DELIMITER);
380             if(result instanceof RtfByteArrayBuffer) {
381                 ((RtfByteArrayBuffer)result).append(imageData);
382             } else {
383                 for(int k = 0; k < imageData.length; k++) {
384                     result.write(imageData[k]);
385                 }
386             }
387         } else {
388             //hex encoded
389
result.write(DELIMITER);
390             result.write('\n');
391             writeImageDataHexEncoded(result);
392         }
393         
394         result.write(CLOSE_GROUP);
395         result.write(CLOSE_GROUP);
396         if(this.topLevelElement) {
397             result.write(RtfParagraph.PARAGRAPH);
398             result.write(RtfParagraph.PARAGRAPH);
399         }
400         result.write('\n');
401     }
402     
403     /**
404      * Sets the alignment of this RtfImage. Uses the alignments from com.lowagie.text.Element.
405      *
406      * @param alignment The alignment to use.
407      */

408     public void setAlignment(int alignment) {
409         this.alignment = alignment;
410     }
411     
412     /**
413      * Set whether this RtfImage should behave like a top level element
414      * and enclose itself in a paragraph.
415      *
416      * @param topLevelElement Whether to behave like a top level element.
417      */

418     public void setTopLevelElement(boolean topLevelElement) {
419         this.topLevelElement = topLevelElement;
420     }
421     
422     
423 }
424
Popular Tags