KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > lowagie > text > Image


1 /*
2  * $Id: Image.java 2765 2007-05-20 11:11:16Z blowagie $
3  * $Name$
4  *
5  * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
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;
52
53 import java.awt.Graphics2D JavaDoc;
54 import java.awt.color.ICC_Profile JavaDoc;
55 import java.awt.image.BufferedImage JavaDoc;
56 import java.io.IOException JavaDoc;
57 import java.io.InputStream JavaDoc;
58 import java.lang.reflect.Constructor JavaDoc;
59 import java.net.MalformedURLException JavaDoc;
60 import java.net.URL JavaDoc;
61 import java.util.ArrayList JavaDoc;
62
63 import com.lowagie.text.pdf.PRIndirectReference;
64 import com.lowagie.text.pdf.PdfArray;
65 import com.lowagie.text.pdf.PdfContentByte;
66 import com.lowagie.text.pdf.PdfDictionary;
67 import com.lowagie.text.pdf.PdfIndirectReference;
68 import com.lowagie.text.pdf.PdfName;
69 import com.lowagie.text.pdf.PdfNumber;
70 import com.lowagie.text.pdf.PdfOCG;
71 import com.lowagie.text.pdf.PdfObject;
72 import com.lowagie.text.pdf.PdfReader;
73 import com.lowagie.text.pdf.PdfTemplate;
74 import com.lowagie.text.pdf.PdfWriter;
75 import com.lowagie.text.pdf.RandomAccessFileOrArray;
76 import com.lowagie.text.pdf.codec.BmpImage;
77 import com.lowagie.text.pdf.codec.CCITTG4Encoder;
78 import com.lowagie.text.pdf.codec.GifImage;
79 import com.lowagie.text.pdf.codec.PngImage;
80 import com.lowagie.text.pdf.codec.TiffImage;
81
82 /**
83  * An <CODE>Image</CODE> is the representation of a graphic element (JPEG, PNG
84  * or GIF) that has to be inserted into the document
85  *
86  * @see Element
87  * @see Rectangle
88  */

89
90 public abstract class Image extends Rectangle {
91
92     // static final membervariables
93

94     /** this is a kind of image alignment. */
95     public static final int DEFAULT = 0;
96
97     /** this is a kind of image alignment. */
98     public static final int RIGHT = 2;
99
100     /** this is a kind of image alignment. */
101     public static final int LEFT = 0;
102
103     /** this is a kind of image alignment. */
104     public static final int MIDDLE = 1;
105
106     /** this is a kind of image alignment. */
107     public static final int TEXTWRAP = 4;
108
109     /** this is a kind of image alignment. */
110     public static final int UNDERLYING = 8;
111
112     /** This represents a coordinate in the transformation matrix. */
113     public static final int AX = 0;
114
115     /** This represents a coordinate in the transformation matrix. */
116     public static final int AY = 1;
117
118     /** This represents a coordinate in the transformation matrix. */
119     public static final int BX = 2;
120
121     /** This represents a coordinate in the transformation matrix. */
122     public static final int BY = 3;
123
124     /** This represents a coordinate in the transformation matrix. */
125     public static final int CX = 4;
126
127     /** This represents a coordinate in the transformation matrix. */
128     public static final int CY = 5;
129
130     /** This represents a coordinate in the transformation matrix. */
131     public static final int DX = 6;
132
133     /** This represents a coordinate in the transformation matrix. */
134     public static final int DY = 7;
135
136     /** type of image */
137     public static final int ORIGINAL_NONE = 0;
138
139     /** type of image */
140     public static final int ORIGINAL_JPEG = 1;
141
142     /** type of image */
143     public static final int ORIGINAL_PNG = 2;
144
145     /** type of image */
146     public static final int ORIGINAL_GIF = 3;
147
148     /** type of image */
149     public static final int ORIGINAL_BMP = 4;
150
151     /** type of image */
152     public static final int ORIGINAL_TIFF = 5;
153
154     /** type of image */
155     public static final int ORIGINAL_WMF = 6;
156
157     /** type of image */
158     public static final int ORIGINAL_PS = 7;
159
160     // member variables
161

162     /** The imagetype. */
163     protected int type;
164
165     /** The URL of the image. */
166     protected URL JavaDoc url;
167
168     /** The raw data of the image. */
169     protected byte rawData[];
170
171     /** The bits per component of the raw image. It also flags a CCITT image. */
172     protected int bpc = 1;
173     
174     /** The template to be treated as an image. */
175     protected PdfTemplate template[] = new PdfTemplate[1];
176
177     /** The alignment of the Image. */
178     protected int alignment;
179
180     /** Text that can be shown instead of the image. */
181     protected String JavaDoc alt;
182
183     /** This is the absolute X-position of the image. */
184     protected float absoluteX = Float.NaN;
185
186     /** This is the absolute Y-position of the image. */
187     protected float absoluteY = Float.NaN;
188
189     /** This is the width of the image without rotation. */
190     protected float plainWidth;
191
192     /** This is the width of the image without rotation. */
193     protected float plainHeight;
194
195     /** This is the scaled width of the image taking rotation into account. */
196     protected float scaledWidth;
197
198     /** This is the original height of the image taking rotation into account. */
199     protected float scaledHeight;
200
201     /** an iText attributed unique id for this image. */
202     protected Long JavaDoc mySerialId = getSerialId();
203
204     // image from file or URL
205

206     /**
207      * Constructs an <CODE>Image</CODE> -object, using an <VAR>url </VAR>.
208      *
209      * @param url
210      * the <CODE>URL</CODE> where the image can be found.
211      */

212     public Image(URL JavaDoc url) {
213         super(0, 0);
214         this.url = url;
215         this.alignment = DEFAULT;
216         rotationRadians = 0;
217     }
218
219     /**
220      * Gets an instance of an Image.
221      *
222      * @param url
223      * an URL
224      * @return an Image
225      * @throws BadElementException
226      * @throws MalformedURLException
227      * @throws IOException
228      */

229     public static Image getInstance(URL JavaDoc url) throws BadElementException,
230             MalformedURLException JavaDoc, IOException JavaDoc {
231         InputStream JavaDoc is = null;
232         try {
233             is = url.openStream();
234             int c1 = is.read();
235             int c2 = is.read();
236             int c3 = is.read();
237             int c4 = is.read();
238             is.close();
239
240             is = null;
241             if (c1 == 'G' && c2 == 'I' && c3 == 'F') {
242                 GifImage gif = new GifImage(url);
243                 Image img = gif.getImage(1);
244                 return img;
245             }
246             if (c1 == 0xFF && c2 == 0xD8) {
247                 return new Jpeg(url);
248             }
249             if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1]
250                     && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) {
251                 return PngImage.getImage(url);
252             }
253             if (c1 == 0xD7 && c2 == 0xCD) {
254                 return new ImgWMF(url);
255             }
256             if (c1 == 'B' && c2 == 'M') {
257                 return BmpImage.getImage(url);
258             }
259             if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42)
260                     || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) {
261                 RandomAccessFileOrArray ra = null;
262                 try {
263                     if (url.getProtocol().equals("file")) {
264                         String JavaDoc file = url.getFile();
265                         file = Utilities.unEscapeURL(file);
266                         ra = new RandomAccessFileOrArray(file);
267                     } else
268                         ra = new RandomAccessFileOrArray(url);
269                     Image img = TiffImage.getTiffImage(ra, 1);
270                     img.url = url;
271                     return img;
272                 } finally {
273                     if (ra != null)
274                         ra.close();
275                 }
276
277             }
278             throw new IOException JavaDoc(url.toString()
279                     + " is not a recognized imageformat.");
280         } finally {
281             if (is != null) {
282                 is.close();
283             }
284         }
285     }
286
287     /**
288      * Gets an instance of an Image.
289      *
290      * @param filename
291      * a filename
292      * @return an object of type <CODE>Gif</CODE>,<CODE>Jpeg</CODE> or
293      * <CODE>Png</CODE>
294      * @throws BadElementException
295      * @throws MalformedURLException
296      * @throws IOException
297      */

298     public static Image getInstance(String JavaDoc filename)
299             throws BadElementException, MalformedURLException JavaDoc, IOException JavaDoc {
300         return getInstance(Utilities.toURL(filename));
301     }
302     
303     /**
304      * gets an instance of an Image
305      *
306      * @param imgb
307      * raw image date
308      * @return an Image object
309      * @throws BadElementException
310      * @throws MalformedURLException
311      * @throws IOException
312      */

313     public static Image getInstance(byte imgb[]) throws BadElementException,
314             MalformedURLException JavaDoc, IOException JavaDoc {
315         InputStream JavaDoc is = null;
316         try {
317             is = new java.io.ByteArrayInputStream JavaDoc(imgb);
318             int c1 = is.read();
319             int c2 = is.read();
320             int c3 = is.read();
321             int c4 = is.read();
322             is.close();
323
324             is = null;
325             if (c1 == 'G' && c2 == 'I' && c3 == 'F') {
326                 GifImage gif = new GifImage(imgb);
327                 return gif.getImage(1);
328             }
329             if (c1 == 0xFF && c2 == 0xD8) {
330                 return new Jpeg(imgb);
331             }
332             if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1]
333                     && c3 == PngImage.PNGID[2] && c4 == PngImage.PNGID[3]) {
334                 return PngImage.getImage(imgb);
335             }
336             if (c1 == 0xD7 && c2 == 0xCD) {
337                 return new ImgWMF(imgb);
338             }
339             if (c1 == 'B' && c2 == 'M') {
340                 return BmpImage.getImage(imgb);
341             }
342             if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42)
343                     || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) {
344                 RandomAccessFileOrArray ra = null;
345                 try {
346                     ra = new RandomAccessFileOrArray(imgb);
347                     Image img = TiffImage.getTiffImage(ra, 1);
348                     if (img.getOriginalData() == null)
349                         img.setOriginalData(imgb);
350                     return img;
351                 } finally {
352                     if (ra != null)
353                         ra.close();
354                 }
355
356             }
357             throw new IOException JavaDoc(
358                     "The byte array is not a recognized imageformat.");
359         } finally {
360             if (is != null) {
361                 is.close();
362             }
363         }
364     }
365
366     /**
367      * Gets an instance of an Image in raw mode.
368      *
369      * @param width
370      * the width of the image in pixels
371      * @param height
372      * the height of the image in pixels
373      * @param components
374      * 1,3 or 4 for GrayScale, RGB and CMYK
375      * @param data
376      * the image data
377      * @param bpc
378      * bits per component
379      * @return an object of type <CODE>ImgRaw</CODE>
380      * @throws BadElementException
381      * on error
382      */

383     public static Image getInstance(int width, int height, int components,
384             int bpc, byte data[]) throws BadElementException {
385         return Image.getInstance(width, height, components, bpc, data, null);
386     }
387
388     /**
389      * Creates an Image with CCITT G3 or G4 compression. It assumes that the
390      * data bytes are already compressed.
391      *
392      * @param width
393      * the exact width of the image
394      * @param height
395      * the exact height of the image
396      * @param reverseBits
397      * reverses the bits in <code>data</code>. Bit 0 is swapped
398      * with bit 7 and so on
399      * @param typeCCITT
400      * the type of compression in <code>data</code>. It can be
401      * CCITTG4, CCITTG31D, CCITTG32D
402      * @param parameters
403      * parameters associated with this stream. Possible values are
404      * CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and
405      * CCITT_ENDOFBLOCK or a combination of them
406      * @param data
407      * the image data
408      * @return an Image object
409      * @throws BadElementException
410      * on error
411      */

412     public static Image getInstance(int width, int height, boolean reverseBits,
413             int typeCCITT, int parameters, byte[] data)
414             throws BadElementException {
415         return Image.getInstance(width, height, reverseBits, typeCCITT,
416                 parameters, data, null);
417     }
418
419     /**
420      * Creates an Image with CCITT G3 or G4 compression. It assumes that the
421      * data bytes are already compressed.
422      *
423      * @param width
424      * the exact width of the image
425      * @param height
426      * the exact height of the image
427      * @param reverseBits
428      * reverses the bits in <code>data</code>. Bit 0 is swapped
429      * with bit 7 and so on
430      * @param typeCCITT
431      * the type of compression in <code>data</code>. It can be
432      * CCITTG4, CCITTG31D, CCITTG32D
433      * @param parameters
434      * parameters associated with this stream. Possible values are
435      * CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and
436      * CCITT_ENDOFBLOCK or a combination of them
437      * @param data
438      * the image data
439      * @param transparency
440      * transparency information in the Mask format of the image
441      * dictionary
442      * @return an Image object
443      * @throws BadElementException
444      * on error
445      */

446     public static Image getInstance(int width, int height, boolean reverseBits,
447             int typeCCITT, int parameters, byte[] data, int transparency[])
448             throws BadElementException {
449         if (transparency != null && transparency.length != 2)
450             throw new BadElementException(
451                     "Transparency length must be equal to 2 with CCITT images");
452         Image img = new ImgCCITT(width, height, reverseBits, typeCCITT,
453                 parameters, data);
454         img.transparency = transparency;
455         return img;
456     }
457
458     /**
459      * Gets an instance of an Image in raw mode.
460      *
461      * @param width
462      * the width of the image in pixels
463      * @param height
464      * the height of the image in pixels
465      * @param components
466      * 1,3 or 4 for GrayScale, RGB and CMYK
467      * @param data
468      * the image data
469      * @param bpc
470      * bits per component
471      * @param transparency
472      * transparency information in the Mask format of the image
473      * dictionary
474      * @return an object of type <CODE>ImgRaw</CODE>
475      * @throws BadElementException
476      * on error
477      */

478     public static Image getInstance(int width, int height, int components,
479             int bpc, byte data[], int transparency[])
480             throws BadElementException {
481         if (transparency != null && transparency.length != components * 2)
482             throw new BadElementException(
483                     "Transparency length must be equal to (componentes * 2)");
484         if (components == 1 && bpc == 1) {
485             byte g4[] = CCITTG4Encoder.compress(data, width, height);
486             return Image.getInstance(width, height, false, Image.CCITTG4,
487                     Image.CCITT_BLACKIS1, g4, transparency);
488         }
489         Image img = new ImgRaw(width, height, components, bpc, data);
490         img.transparency = transparency;
491         return img;
492     }
493
494     // images from a PdfTemplate
495

496     /**
497      * gets an instance of an Image
498      *
499      * @param template
500      * a PdfTemplate that has to be wrapped in an Image object
501      * @return an Image object
502      * @throws BadElementException
503      */

504     public static Image getInstance(PdfTemplate template)
505             throws BadElementException {
506         return new ImgTemplate(template);
507     }
508     
509     // images from a java.awt.Image
510

511     /**
512      * Gets an instance of an Image from a java.awt.Image.
513      *
514      * @param image
515      * the <CODE>java.awt.Image</CODE> to convert
516      * @param color
517      * if different from <CODE>null</CODE> the transparency pixels
518      * are replaced by this color
519      * @param forceBW
520      * if <CODE>true</CODE> the image is treated as black and white
521      * @return an object of type <CODE>ImgRaw</CODE>
522      * @throws BadElementException
523      * on error
524      * @throws IOException
525      * on error
526      */

527     public static Image getInstance(java.awt.Image JavaDoc image, java.awt.Color JavaDoc color,
528             boolean forceBW) throws BadElementException, IOException JavaDoc {
529         
530         if(image instanceof BufferedImage JavaDoc){
531             BufferedImage JavaDoc bi = (BufferedImage JavaDoc) image;
532             if(bi.getType()==BufferedImage.TYPE_BYTE_BINARY) {
533                 forceBW=true;
534             }
535         }
536         
537         java.awt.image.PixelGrabber JavaDoc pg = new java.awt.image.PixelGrabber JavaDoc(image,
538                 0, 0, -1, -1, true);
539         try {
540             pg.grabPixels();
541         } catch (InterruptedException JavaDoc e) {
542             throw new IOException JavaDoc(
543                     "java.awt.Image Interrupted waiting for pixels!");
544         }
545         if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) {
546             throw new IOException JavaDoc("java.awt.Image fetch aborted or errored");
547         }
548         int w = pg.getWidth();
549         int h = pg.getHeight();
550         int[] pixels = (int[]) pg.getPixels();
551         if (forceBW) {
552             int byteWidth = (w / 8) + ((w & 7) != 0 ? 1 : 0);
553             byte[] pixelsByte = new byte[byteWidth * h];
554
555             int index = 0;
556             int size = h * w;
557             int transColor = 1;
558             if (color != null) {
559                 transColor = (color.getRed() + color.getGreen()
560                         + color.getBlue() < 384) ? 0 : 1;
561             }
562             int transparency[] = null;
563             int cbyte = 0x80;
564             int wMarker = 0;
565             int currByte = 0;
566             if (color != null) {
567                 for (int j = 0; j < size; j++) {
568                     int alpha = (pixels[j] >> 24) & 0xff;
569                     if (alpha < 250) {
570                         if (transColor == 1)
571                             currByte |= cbyte;
572                     } else {
573                         if ((pixels[j] & 0x888) != 0)
574                             currByte |= cbyte;
575                     }
576                     cbyte >>= 1;
577                     if (cbyte == 0 || wMarker + 1 >= w) {
578                         pixelsByte[index++] = (byte) currByte;
579                         cbyte = 0x80;
580                         currByte = 0;
581                     }
582                     ++wMarker;
583                     if (wMarker >= w)
584                         wMarker = 0;
585                 }
586             } else {
587                 for (int j = 0; j < size; j++) {
588                     if (transparency == null) {
589                         int alpha = (pixels[j] >> 24) & 0xff;
590                         if (alpha == 0) {
591                             transparency = new int[2];
592                             transparency[0] = transparency[1] = ((pixels[j] & 0x888) != 0) ? 1
593                                     : 0;
594                         }
595                     }
596                     if ((pixels[j] & 0x888) != 0)
597                         currByte |= cbyte;
598                     cbyte >>= 1;
599                     if (cbyte == 0 || wMarker + 1 >= w) {
600                         pixelsByte[index++] = (byte) currByte;
601                         cbyte = 0x80;
602                         currByte = 0;
603                     }
604                     ++wMarker;
605                     if (wMarker >= w)
606                         wMarker = 0;
607                 }
608             }
609             return Image.getInstance(w, h, 1, 1, pixelsByte, transparency);
610         } else {
611             byte[] pixelsByte = new byte[w * h * 3];
612             byte[] smask = null;
613
614             int index = 0;
615             int size = h * w;
616             int red = 255;
617             int green = 255;
618             int blue = 255;
619             if (color != null) {
620                 red = color.getRed();
621                 green = color.getGreen();
622                 blue = color.getBlue();
623             }
624             int transparency[] = null;
625             if (color != null) {
626                 for (int j = 0; j < size; j++) {
627                     int alpha = (pixels[j] >> 24) & 0xff;
628                     if (alpha < 250) {
629                         pixelsByte[index++] = (byte) red;
630                         pixelsByte[index++] = (byte) green;
631                         pixelsByte[index++] = (byte) blue;
632                     } else {
633                         pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff);
634                         pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff);
635                         pixelsByte[index++] = (byte) ((pixels[j]) & 0xff);
636                     }
637                 }
638             } else {
639                 int transparentPixel = 0;
640                 smask = new byte[w * h];
641                 boolean shades = false;
642                 for (int j = 0; j < size; j++) {
643                     byte alpha = smask[j] = (byte) ((pixels[j] >> 24) & 0xff);
644                     /* bugfix by Chris Nokleberg */
645                     if (!shades) {
646                         if (alpha != 0 && alpha != -1) {
647                             shades = true;
648                         } else if (transparency == null) {
649                             if (alpha == 0) {
650                                 transparentPixel = pixels[j] & 0xffffff;
651                                 transparency = new int[6];
652                                 transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff;
653                                 transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff;
654                                 transparency[4] = transparency[5] = transparentPixel & 0xff;
655                             }
656                         } else if ((pixels[j] & 0xffffff) != transparentPixel) {
657                             shades = true;
658                         }
659                     }
660                     pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff);
661                     pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff);
662                     pixelsByte[index++] = (byte) ((pixels[j]) & 0xff);
663                 }
664                 if (shades)
665                     transparency = null;
666                 else
667                     smask = null;
668             }
669             Image img = Image.getInstance(w, h, 3, 8, pixelsByte, transparency);
670             if (smask != null) {
671                 Image sm = Image.getInstance(w, h, 1, 8, smask);
672                 try {
673                     sm.makeMask();
674                     img.setImageMask(sm);
675                 } catch (DocumentException de) {
676                     throw new ExceptionConverter(de);
677                 }
678             }
679             return img;
680         }
681     }
682
683     /**
684      * Gets an instance of an Image from a java.awt.Image.
685      *
686      * @param image
687      * the <CODE>java.awt.Image</CODE> to convert
688      * @param color
689      * if different from <CODE>null</CODE> the transparency pixels
690      * are replaced by this color
691      * @return an object of type <CODE>ImgRaw</CODE>
692      * @throws BadElementException
693      * on error
694      * @throws IOException
695      * on error
696      */

697     public static Image getInstance(java.awt.Image JavaDoc image, java.awt.Color JavaDoc color)
698             throws BadElementException, IOException JavaDoc {
699         return Image.getInstance(image, color, false);
700     }
701     
702     /**
703      * Gets an instance of a Image from a java.awt.Image.
704      * The image is added as a JPEG with a userdefined quality.
705      *
706      * @param writer
707      * the <CODE>PdfWriter</CODE> object to which the image will be added
708      * @param awtImage
709      * the <CODE>java.awt.Image</CODE> to convert
710      * @param quality
711      * a float value between 0 and 1
712      * @return an object of type <CODE>PdfTemplate</CODE>
713      * @throws BadElementException
714      * on error
715      * @throws IOException
716      */

717     public static Image getInstance(PdfWriter writer, java.awt.Image JavaDoc awtImage, float quality) throws BadElementException, IOException JavaDoc {
718         return getInstance(new PdfContentByte(writer), awtImage, quality);
719     }
720     
721     /**
722      * Gets an instance of a Image from a java.awt.Image.
723      * The image is added as a JPEG with a userdefined quality.
724      *
725      * @param cb
726      * the <CODE>PdfContentByte</CODE> object to which the image will be added
727      * @param awtImage
728      * the <CODE>java.awt.Image</CODE> to convert
729      * @param quality
730      * a float value between 0 and 1
731      * @return an object of type <CODE>PdfTemplate</CODE>
732      * @throws BadElementException
733      * on error
734      * @throws IOException
735      */

736     public static Image getInstance(PdfContentByte cb, java.awt.Image JavaDoc awtImage, float quality) throws BadElementException, IOException JavaDoc {
737         java.awt.image.PixelGrabber JavaDoc pg = new java.awt.image.PixelGrabber JavaDoc(awtImage,
738                 0, 0, -1, -1, true);
739         try {
740             pg.grabPixels();
741         } catch (InterruptedException JavaDoc e) {
742             throw new IOException JavaDoc(
743                     "java.awt.Image Interrupted waiting for pixels!");
744         }
745         if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) {
746             throw new IOException JavaDoc("java.awt.Image fetch aborted or errored");
747         }
748         int w = pg.getWidth();
749         int h = pg.getHeight();
750         PdfTemplate tp = cb.createTemplate(w, h);
751         Graphics2D JavaDoc g2d = tp.createGraphics(w, h, true, quality);
752         g2d.drawImage(awtImage, 0, 0, null);
753         g2d.dispose();
754         return getInstance(tp);
755     }
756
757     // image from indirect reference
758

759     /**
760      * Holds value of property directReference.
761      * An image is embedded into a PDF as an Image XObject.
762      * This object is referenced by a PdfIndirectReference object.
763      */

764     private PdfIndirectReference directReference;
765     
766     /**
767      * Getter for property directReference.
768      * @return Value of property directReference.
769      */

770     public PdfIndirectReference getDirectReference() {
771         return this.directReference;
772     }
773     
774     /**
775      * Setter for property directReference.
776      * @param directReference New value of property directReference.
777      */

778     public void setDirectReference(PdfIndirectReference directReference) {
779         this.directReference = directReference;
780     }
781     
782     /**
783      * Reuses an existing image.
784      * @param ref the reference to the image dictionary
785      * @throws BadElementException on error
786      * @return the image
787      */

788     public static Image getInstance(PRIndirectReference ref) throws BadElementException {
789         PdfDictionary dic = (PdfDictionary)PdfReader.getPdfObjectRelease(ref);
790         int width = ((PdfNumber)PdfReader.getPdfObjectRelease(dic.get(PdfName.WIDTH))).intValue();
791         int height = ((PdfNumber)PdfReader.getPdfObjectRelease(dic.get(PdfName.HEIGHT))).intValue();
792         Image imask = null;
793         PdfObject obj = dic.get(PdfName.SMASK);
794         if (obj != null && obj.isIndirect()) {
795             imask = getInstance((PRIndirectReference)obj);
796         }
797         else {
798             obj = dic.get(PdfName.MASK);
799             if (obj != null && obj.isIndirect()) {
800                 PdfObject obj2 = PdfReader.getPdfObjectRelease(obj);
801                 if (obj2 instanceof PdfDictionary)
802                     imask = getInstance((PRIndirectReference)obj);
803             }
804         }
805         Image img = new ImgRaw(width, height, 1, 1, null);
806         img.imageMask = imask;
807         img.directReference = ref;
808         return img;
809     }
810
811     // copy constructor
812

813     /**
814      * Constructs an <CODE>Image</CODE> -object, using an <VAR>url </VAR>.
815      *
816      * @param image
817      * another Image object.
818      */

819     protected Image(Image image) {
820         super(image);
821         this.type = image.type;
822         this.url = image.url;
823         this.rawData = image.rawData;
824         this.bpc = image.bpc;
825         this.template = image.template;
826         this.alignment = image.alignment;
827         this.alt = image.alt;
828         this.absoluteX = image.absoluteX;
829         this.absoluteY = image.absoluteY;
830         this.plainWidth = image.plainWidth;
831         this.plainHeight = image.plainHeight;
832         this.scaledWidth = image.scaledWidth;
833         this.scaledHeight = image.scaledHeight;
834         this.mySerialId = image.mySerialId;
835
836         this.directReference = image.directReference;
837         
838         this.rotationRadians = image.rotationRadians;
839         this.initialRotation = image.initialRotation;
840         this.indentationLeft = image.indentationLeft;
841         this.indentationRight = image.indentationRight;
842         this.spacingBefore = image.spacingBefore;
843         this.spacingAfter = image.spacingAfter;
844
845         this.widthPercentage = image.widthPercentage;
846         this.annotation = image.annotation;
847         this.layer = image.layer;
848         this.interpolation = image.interpolation;
849         this.originalType = image.originalType;
850         this.originalData = image.originalData;
851         this.deflated = image.deflated;
852         this.dpiX = image.dpiX;
853         this.dpiY = image.dpiY;
854         this.XYRatio = image.XYRatio;
855         
856         this.colorspace = image.colorspace;
857         this.invert = image.invert;
858         this.profile = image.profile;
859         this.additional = image.additional;
860         this.mask = image.mask;
861         this.imageMask = image.imageMask;
862         this.smask = image.smask;
863         this.transparency = image.transparency;
864     }
865
866     /**
867      * gets an instance of an Image
868      *
869      * @param image
870      * an Image object
871      * @return a new Image object
872      */

873     public static Image getInstance(Image image) {
874         if (image == null)
875             return null;
876         try {
877             Class JavaDoc cs = image.getClass();
878             Constructor JavaDoc constructor = cs
879                     .getDeclaredConstructor(new Class JavaDoc[] { Image.class });
880             return (Image) constructor.newInstance(new Object JavaDoc[] { image });
881         } catch (Exception JavaDoc e) {
882             throw new ExceptionConverter(e);
883         }
884     }
885
886     // implementation of the Element interface
887

888     /**
889      * Returns the type.
890      *
891      * @return a type
892      */

893
894     public int type() {
895         return type;
896     }
897
898     // checking the type of Image
899

900     /**
901      * Returns <CODE>true</CODE> if the image is a <CODE>Jpeg</CODE>
902      * -object.
903      *
904      * @return a <CODE>boolean</CODE>
905      */

906
907     public boolean isJpeg() {
908         return type == JPEG;
909     }
910
911     /**
912      * Returns <CODE>true</CODE> if the image is a <CODE>ImgRaw</CODE>
913      * -object.
914      *
915      * @return a <CODE>boolean</CODE>
916      */

917
918     public boolean isImgRaw() {
919         return type == IMGRAW;
920     }
921
922     /**
923      * Returns <CODE>true</CODE> if the image is an <CODE>ImgTemplate</CODE>
924      * -object.
925      *
926      * @return a <CODE>boolean</CODE>
927      */

928
929     public boolean isImgTemplate() {
930         return type == IMGTEMPLATE;
931     }
932     
933     // getters and setters
934

935     /**
936      * Gets the <CODE>String</CODE> -representation of the reference to the
937      * image.
938      *
939      * @return a <CODE>String</CODE>
940      */

941
942     public URL JavaDoc getUrl() {
943         return url;
944     }
945
946     /**
947      * Sets the url of the image
948      *
949      * @param url
950      * the url of the image
951      */

952     public void setUrl(URL JavaDoc url) {
953         this.url = url;
954     }
955
956     /**
957      * Gets the raw data for the image.
958      * <P>
959      * Remark: this only makes sense for Images of the type <CODE>RawImage
960      * </CODE>.
961      *
962      * @return the raw data
963      */

964     public byte[] getRawData() {
965         return rawData;
966     }
967
968     /**
969      * Gets the bpc for the image.
970      * <P>
971      * Remark: this only makes sense for Images of the type <CODE>RawImage
972      * </CODE>.
973      *
974      * @return a bpc value
975      */

976     public int getBpc() {
977         return bpc;
978     }
979
980     /**
981      * Gets the template to be used as an image.
982      * <P>
983      * Remark: this only makes sense for Images of the type <CODE>ImgTemplate
984      * </CODE>.
985      *
986      * @return the template
987      */

988     public PdfTemplate getTemplateData() {
989         return template[0];
990     }
991
992     /**
993      * Sets data from a PdfTemplate
994      *
995      * @param template
996      * the template with the content
997      */

998     public void setTemplateData(PdfTemplate template) {
999         this.template[0] = template;
1000    }
1001
1002    /**
1003     * Gets the alignment for the image.
1004     *
1005     * @return a value
1006     */

1007    public int getAlignment() {
1008        return alignment;
1009    }
1010
1011    /**
1012     * Sets the alignment for the image.
1013     *
1014     * @param alignment
1015     * the alignment
1016     */

1017
1018    public void setAlignment(int alignment) {
1019        this.alignment = alignment;
1020    }
1021
1022    /**
1023     * Gets the alternative text for the image.
1024     *
1025     * @return a <CODE>String</CODE>
1026     */

1027
1028    public String JavaDoc getAlt() {
1029        return alt;
1030    }
1031
1032    /**
1033     * Sets the alternative information for the image.
1034     *
1035     * @param alt
1036     * the alternative information
1037     */

1038
1039    public void setAlt(String JavaDoc alt) {
1040        this.alt = alt;
1041    }
1042
1043    /**
1044     * Sets the absolute position of the <CODE>Image</CODE>.
1045     *
1046     * @param absoluteX
1047     * @param absoluteY
1048     */

1049
1050    public void setAbsolutePosition(float absoluteX, float absoluteY) {
1051        this.absoluteX = absoluteX;
1052        this.absoluteY = absoluteY;
1053    }
1054
1055    /**
1056     * Checks if the <CODE>Images</CODE> has to be added at an absolute X
1057     * position.
1058     *
1059     * @return a boolean
1060     */

1061    public boolean hasAbsoluteX() {
1062        return !Float.isNaN(absoluteX);
1063    }
1064
1065    /**
1066     * Returns the absolute X position.
1067     *
1068     * @return a position
1069     */

1070    public float getAbsoluteX() {
1071        return absoluteX;
1072    }
1073
1074    /**
1075     * Checks if the <CODE>Images</CODE> has to be added at an absolute
1076     * position.
1077     *
1078     * @return a boolean
1079     */

1080    public boolean hasAbsoluteY() {
1081        return !Float.isNaN(absoluteY);
1082    }
1083
1084    /**
1085     * Returns the absolute Y position.
1086     *
1087     * @return a position
1088     */

1089    public float getAbsoluteY() {
1090        return absoluteY;
1091    }
1092
1093    // width and height
1094

1095    /**
1096     * Gets the scaled width of the image.
1097     *
1098     * @return a value
1099     */

1100    public float getScaledWidth() {
1101        return scaledWidth;
1102    }
1103
1104    /**
1105     * Gets the scaled height of the image.
1106     *
1107     * @return a value
1108     */

1109    public float getScaledHeight() {
1110        return scaledHeight;
1111    }
1112
1113    /**
1114     * Gets the plain width of the image.
1115     *
1116     * @return a value
1117     */

1118    public float getPlainWidth() {
1119        return plainWidth;
1120    }
1121
1122    /**
1123     * Gets the plain height of the image.
1124     *
1125     * @return a value
1126     */

1127    public float getPlainHeight() {
1128        return plainHeight;
1129    }
1130    
1131    /**
1132     * Scale the image to an absolute width and an absolute height.
1133     *
1134     * @param newWidth
1135     * the new width
1136     * @param newHeight
1137     * the new height
1138     */

1139    public void scaleAbsolute(float newWidth, float newHeight) {
1140        plainWidth = newWidth;
1141        plainHeight = newHeight;
1142        float[] matrix = matrix();
1143        scaledWidth = matrix[DX] - matrix[CX];
1144        scaledHeight = matrix[DY] - matrix[CY];
1145    }
1146
1147    /**
1148     * Scale the image to an absolute width.
1149     *
1150     * @param newWidth
1151     * the new width
1152     */

1153    public void scaleAbsoluteWidth(float newWidth) {
1154        plainWidth = newWidth;
1155        float[] matrix = matrix();
1156        scaledWidth = matrix[DX] - matrix[CX];
1157        scaledHeight = matrix[DY] - matrix[CY];
1158    }
1159
1160    /**
1161     * Scale the image to an absolute height.
1162     *
1163     * @param newHeight
1164     * the new height
1165     */

1166    public void scaleAbsoluteHeight(float newHeight) {
1167        plainHeight = newHeight;
1168        float[] matrix = matrix();
1169        scaledWidth = matrix[DX] - matrix[CX];
1170        scaledHeight = matrix[DY] - matrix[CY];
1171    }
1172
1173    /**
1174     * Scale the image to a certain percentage.
1175     *
1176     * @param percent
1177     * the scaling percentage
1178     */

1179    public void scalePercent(float percent) {
1180        scalePercent(percent, percent);
1181    }
1182
1183    /**
1184     * Scale the width and height of an image to a certain percentage.
1185     *
1186     * @param percentX
1187     * the scaling percentage of the width
1188     * @param percentY
1189     * the scaling percentage of the height
1190     */

1191    public void scalePercent(float percentX, float percentY) {
1192        plainWidth = (getWidth() * percentX) / 100f;
1193        plainHeight = (getHeight() * percentY) / 100f;
1194        float[] matrix = matrix();
1195        scaledWidth = matrix[DX] - matrix[CX];
1196        scaledHeight = matrix[DY] - matrix[CY];
1197    }
1198
1199    /**
1200     * Scales the image so that it fits a certain width and height.
1201     *
1202     * @param fitWidth
1203     * the width to fit
1204     * @param fitHeight
1205     * the height to fit
1206     */

1207    public void scaleToFit(float fitWidth, float fitHeight) {
1208        scalePercent(100);
1209        float percentX = (fitWidth * 100) / getScaledWidth();
1210        float percentY = (fitHeight * 100) / getScaledHeight();
1211        scalePercent(percentX < percentY ? percentX : percentY);
1212    }
1213
1214    /**
1215     * Returns the transformation matrix of the image.
1216     *
1217     * @return an array [AX, AY, BX, BY, CX, CY, DX, DY]
1218     */

1219    public float[] matrix() {
1220        float[] matrix = new float[8];
1221        float cosX = (float) Math.cos(rotationRadians);
1222        float sinX = (float) Math.sin(rotationRadians);
1223        matrix[AX] = plainWidth * cosX;
1224        matrix[AY] = plainWidth * sinX;
1225        matrix[BX] = (-plainHeight) * sinX;
1226        matrix[BY] = plainHeight * cosX;
1227        if (rotationRadians < Math.PI / 2f) {
1228            matrix[CX] = matrix[BX];
1229            matrix[CY] = 0;
1230            matrix[DX] = matrix[AX];
1231            matrix[DY] = matrix[AY] + matrix[BY];
1232        } else if (rotationRadians < Math.PI) {
1233            matrix[CX] = matrix[AX] + matrix[BX];
1234            matrix[CY] = matrix[BY];
1235            matrix[DX] = 0;
1236            matrix[DY] = matrix[AY];
1237        } else if (rotationRadians < Math.PI * 1.5f) {
1238            matrix[CX] = matrix[AX];
1239            matrix[CY] = matrix[AY] + matrix[BY];
1240            matrix[DX] = matrix[BX];
1241            matrix[DY] = 0;
1242        } else {
1243            matrix[CX] = 0;
1244            matrix[CY] = matrix[AY];
1245            matrix[DX] = matrix[AX] + matrix[BX];
1246            matrix[DY] = matrix[BY];
1247        }
1248        return matrix;
1249    }
1250
1251    // serial stamping
1252

1253    /** a static that is used for attributing a unique id to each image. */
1254    static long serialId = 0;
1255    
1256    /** Creates a new serial id. */
1257    static protected synchronized Long JavaDoc getSerialId() {
1258        ++serialId;
1259        return new Long JavaDoc(serialId);
1260    }
1261
1262    /**
1263     * Returns a serial id for the Image (reuse the same image more than once)
1264     *
1265     * @return a serialId
1266     */

1267    public Long JavaDoc getMySerialId() {
1268        return mySerialId;
1269    }
1270
1271    // rotation, note that the superclass also has a rotation value.
1272

1273    /** This is the rotation of the image in radians. */
1274    protected float rotationRadians;
1275    
1276    /** Holds value of property initialRotation. */
1277    private float initialRotation;
1278
1279    /**
1280     * Gets the current image rotation in radians.
1281     * @return the current image rotation in radians
1282     */

1283    public float getImageRotation() {
1284        double d = 2.0 * Math.PI;
1285        float rot = (float) ((rotationRadians - initialRotation) % d);
1286        if (rot < 0) {
1287            rot += d;
1288        }
1289        return rot;
1290    }
1291    
1292    /**
1293     * Sets the rotation of the image in radians.
1294     *
1295     * @param r
1296     * rotation in radians
1297     */

1298    public void setRotation(float r) {
1299        double d = 2.0 * Math.PI;
1300        rotationRadians = (float) ((r + initialRotation) % d);
1301        if (rotationRadians < 0) {
1302            rotationRadians += d;
1303        }
1304        float[] matrix = matrix();
1305        scaledWidth = matrix[DX] - matrix[CX];
1306        scaledHeight = matrix[DY] - matrix[CY];
1307    }
1308
1309    /**
1310     * Sets the rotation of the image in degrees.
1311     *
1312     * @param deg
1313     * rotation in degrees
1314     */

1315    public void setRotationDegrees(float deg) {
1316        double d = Math.PI;
1317        setRotation(deg / 180 * (float) d);
1318    }
1319    
1320    /**
1321     * Getter for property initialRotation.
1322     * @return Value of property initialRotation.
1323     */

1324    public float getInitialRotation() {
1325        return this.initialRotation;
1326    }
1327    
1328    /**
1329     * Some image formats, like TIFF may present the images rotated that have
1330     * to be compensated.
1331     * @param initialRotation New value of property initialRotation.
1332     */

1333    public void setInitialRotation(float initialRotation) {
1334        float old_rot = rotationRadians - this.initialRotation;
1335        this.initialRotation = initialRotation;
1336        setRotation(old_rot);
1337    }
1338    
1339    // indentations
1340

1341    /** the indentation to the left. */
1342    protected float indentationLeft = 0;
1343
1344    /** the indentation to the right. */
1345    protected float indentationRight = 0;
1346
1347    /** The spacing before the image. */
1348    protected float spacingBefore;
1349
1350    /** The spacing after the image. */
1351    protected float spacingAfter;
1352
1353    /**
1354     * Gets the left indentation.
1355     *
1356     * @return the left indentation
1357     */

1358    public float getIndentationLeft() {
1359        return indentationLeft;
1360    }
1361
1362    /**
1363     * Sets the left indentation.
1364     *
1365     * @param f
1366     */

1367    public void setIndentationLeft(float f) {
1368        indentationLeft = f;
1369    }
1370
1371    /**
1372     * Gets the right indentation.
1373     *
1374     * @return the right indentation
1375     */

1376    public float getIndentationRight() {
1377        return indentationRight;
1378    }
1379
1380    /**
1381     * Sets the right indentation.
1382     *
1383     * @param f
1384     */

1385    public void setIndentationRight(float f) {
1386        indentationRight = f;
1387    }
1388
1389    /**
1390     * Gets the spacing before this image.
1391     *
1392     * @return the spacing
1393     */

1394    public float getSpacingBefore() {
1395        return spacingBefore;
1396    }
1397
1398    /**
1399     * Sets the spacing before this image.
1400     *
1401     * @param spacing
1402     * the new spacing
1403     */

1404
1405    public void setSpacingBefore(float spacing) {
1406        this.spacingBefore = spacing;
1407    }
1408
1409    /**
1410     * Gets the spacing before this image.
1411     *
1412     * @return the spacing
1413     */

1414    public float getSpacingAfter() {
1415        return spacingAfter;
1416    }
1417
1418    /**
1419     * Sets the spacing after this image.
1420     *
1421     * @param spacing
1422     * the new spacing
1423     */

1424
1425    public void setSpacingAfter(float spacing) {
1426        this.spacingAfter = spacing;
1427    }
1428
1429    // widthpercentage (for the moment only used in ColumnText)
1430

1431    /**
1432     * Holds value of property widthPercentage.
1433     */

1434    private float widthPercentage = 100;
1435    
1436    /**
1437     * Getter for property widthPercentage.
1438     *
1439     * @return Value of property widthPercentage.
1440     */

1441    public float getWidthPercentage() {
1442        return this.widthPercentage;
1443    }
1444
1445    /**
1446     * Setter for property widthPercentage.
1447     *
1448     * @param widthPercentage
1449     * New value of property widthPercentage.
1450     */

1451    public void setWidthPercentage(float widthPercentage) {
1452        this.widthPercentage = widthPercentage;
1453    }
1454
1455    // annotation
1456

1457    /** if the annotation is not null the image will be clickable. */
1458    protected Annotation annotation = null;
1459    
1460    /**
1461     * Sets the annotation of this Image.
1462     *
1463     * @param annotation
1464     * the annotation
1465     */

1466    public void setAnnotation(Annotation annotation) {
1467        this.annotation = annotation;
1468    }
1469
1470    /**
1471     * Gets the annotation.
1472     *
1473     * @return the annotation that is linked to this image
1474     */

1475    public Annotation getAnnotation() {
1476        return annotation;
1477    }
1478
1479    // Optional Content
1480

1481    /** Optional Content layer to which we want this Image to belong. */
1482    protected PdfOCG layer;
1483    
1484    /**
1485     * Gets the layer this image belongs to.
1486     *
1487     * @return the layer this image belongs to or <code>null</code> for no
1488     * layer defined
1489     */

1490    public PdfOCG getLayer() {
1491        return layer;
1492    }
1493
1494    /**
1495     * Sets the layer this image belongs to.
1496     *
1497     * @param layer
1498     * the layer this image belongs to
1499     */

1500    public void setLayer(PdfOCG layer) {
1501        this.layer = layer;
1502    }
1503
1504    // interpolation
1505

1506    /** Holds value of property interpolation. */
1507    protected boolean interpolation;
1508
1509    /**
1510     * Getter for property interpolation.
1511     *
1512     * @return Value of property interpolation.
1513     */

1514    public boolean isInterpolation() {
1515        return interpolation;
1516    }
1517
1518    /**
1519     * Sets the image interpolation. Image interpolation attempts to produce a
1520     * smooth transition between adjacent sample values.
1521     *
1522     * @param interpolation
1523     * New value of property interpolation.
1524     */

1525    public void setInterpolation(boolean interpolation) {
1526        this.interpolation = interpolation;
1527    }
1528    
1529    // original type and data
1530

1531    /** Holds value of property originalType. */
1532    protected int originalType = ORIGINAL_NONE;
1533
1534    /** Holds value of property originalData. */
1535    protected byte[] originalData;
1536    
1537    /**
1538     * Getter for property originalType.
1539     *
1540     * @return Value of property originalType.
1541     *
1542     */

1543    public int getOriginalType() {
1544        return this.originalType;
1545    }
1546
1547    /**
1548     * Setter for property originalType.
1549     *
1550     * @param originalType
1551     * New value of property originalType.
1552     *
1553     */

1554    public void setOriginalType(int originalType) {
1555        this.originalType = originalType;
1556    }
1557
1558    /**
1559     * Getter for property originalData.
1560     *
1561     * @return Value of property originalData.
1562     *
1563     */

1564    public byte[] getOriginalData() {
1565        return this.originalData;
1566    }
1567
1568    /**
1569     * Setter for property originalData.
1570     *
1571     * @param originalData
1572     * New value of property originalData.
1573     *
1574     */

1575    public void setOriginalData(byte[] originalData) {
1576        this.originalData = originalData;
1577    }
1578
1579    // the following values are only set for specific types of images.
1580

1581    /** Holds value of property deflated. */
1582    protected boolean deflated = false;
1583
1584    /**
1585     * Getter for property deflated.
1586     *
1587     * @return Value of property deflated.
1588     *
1589     */

1590    public boolean isDeflated() {
1591        return this.deflated;
1592    }
1593
1594    /**
1595     * Setter for property deflated.
1596     *
1597     * @param deflated
1598     * New value of property deflated.
1599     */

1600    public void setDeflated(boolean deflated) {
1601        this.deflated = deflated;
1602    }
1603    
1604    // DPI info
1605

1606    /** Holds value of property dpiX. */
1607    protected int dpiX = 0;
1608
1609    /** Holds value of property dpiY. */
1610    protected int dpiY = 0;
1611
1612    /**
1613     * Gets the dots-per-inch in the X direction. Returns 0 if not available.
1614     *
1615     * @return the dots-per-inch in the X direction
1616     */

1617    public int getDpiX() {
1618        return dpiX;
1619    }
1620
1621    /**
1622     * Gets the dots-per-inch in the Y direction. Returns 0 if not available.
1623     *
1624     * @return the dots-per-inch in the Y direction
1625     */

1626    public int getDpiY() {
1627        return dpiY;
1628    }
1629
1630    /**
1631     * Sets the dots per inch value
1632     *
1633     * @param dpiX
1634     * dpi for x coordinates
1635     * @param dpiY
1636     * dpi for y coordinates
1637     */

1638    public void setDpi(int dpiX, int dpiY) {
1639        this.dpiX = dpiX;
1640        this.dpiY = dpiY;
1641    }
1642    
1643    // XY Ratio
1644

1645    /** Holds value of property XYRatio. */
1646    private float XYRatio = 0;
1647
1648    /**
1649     * Gets the X/Y pixel dimensionless aspect ratio.
1650     *
1651     * @return the X/Y pixel dimensionless aspect ratio
1652     */

1653    public float getXYRatio() {
1654        return this.XYRatio;
1655    }
1656
1657    /**
1658     * Sets the X/Y pixel dimensionless aspect ratio.
1659     *
1660     * @param XYRatio
1661     * the X/Y pixel dimensionless aspect ratio
1662     */

1663    public void setXYRatio(float XYRatio) {
1664        this.XYRatio = XYRatio;
1665    }
1666    
1667    // color, colorspaces and transparency
1668

1669    /** this is the colorspace of a jpeg-image. */
1670    protected int colorspace = -1;
1671
1672    /**
1673     * Gets the colorspace for the image.
1674     * <P>
1675     * Remark: this only makes sense for Images of the type <CODE>Jpeg</CODE>.
1676     *
1677     * @return a colorspace value
1678     */

1679    public int getColorspace() {
1680        return colorspace;
1681    }
1682    
1683    /** Image color inversion */
1684    protected boolean invert = false;
1685
1686    /**
1687     * Getter for the inverted value
1688     *
1689     * @return true if the image is inverted
1690     */

1691    public boolean isInverted() {
1692        return invert;
1693    }
1694
1695    /**
1696     * Sets inverted true or false
1697     *
1698     * @param invert
1699     * true or false
1700     */

1701    public void setInverted(boolean invert) {
1702        this.invert = invert;
1703    }
1704
1705    /** ICC Profile attached */
1706    protected ICC_Profile JavaDoc profile = null;
1707
1708    /**
1709     * Tags this image with an ICC profile.
1710     *
1711     * @param profile
1712     * the profile
1713     */

1714    public void tagICC(ICC_Profile JavaDoc profile) {
1715        this.profile = profile;
1716    }
1717
1718    /**
1719     * Checks is the image has an ICC profile.
1720     *
1721     * @return the ICC profile or <CODE>null</CODE>
1722     */

1723    public boolean hasICCProfile() {
1724        return (this.profile != null);
1725    }
1726
1727    /**
1728     * Gets the images ICC profile.
1729     *
1730     * @return the ICC profile
1731     */

1732    public ICC_Profile JavaDoc getICCProfile() {
1733        return profile;
1734    }
1735
1736    /** a dictionary with additional information */
1737    private PdfDictionary additional = null;
1738    
1739    /**
1740     * Getter for the dictionary with additional information.
1741     *
1742     * @return a PdfDictionary with additional information.
1743     */

1744    public PdfDictionary getAdditional() {
1745        return this.additional;
1746    }
1747
1748    /**
1749     * Sets the /Colorspace key.
1750     *
1751     * @param additional
1752     * a PdfDictionary with additional information.
1753     */

1754    public void setAdditional(PdfDictionary additional) {
1755        this.additional = additional;
1756    }
1757
1758    /**
1759     * Replaces CalRGB and CalGray colorspaces with DeviceRGB and DeviceGray.
1760     */

1761    public void simplifyColorspace() {
1762        if (additional == null)
1763            return;
1764        PdfObject value = additional.get(PdfName.COLORSPACE);
1765        if (value == null || !value.isArray())
1766            return;
1767        PdfObject cs = simplifyColorspace(value);
1768        if (cs.isName())
1769            value = cs;
1770        else {
1771            PdfObject first = (PdfObject)(((PdfArray)value).getArrayList().get(0));
1772            if (PdfName.INDEXED.equals(first)) {
1773                ArrayList JavaDoc array = ((PdfArray)value).getArrayList();
1774                if (array.size() >= 2 && ((PdfObject)array.get(1)).isArray()) {
1775                     array.set(1, simplifyColorspace((PdfObject)array.get(1)));
1776                }
1777            }
1778        }
1779        additional.put(PdfName.COLORSPACE, value);
1780    }
1781    
1782    /**
1783     * Gets a PDF Name from an array or returns the object that was passed.
1784     */

1785    private PdfObject simplifyColorspace(PdfObject obj) {
1786        if (obj == null || !obj.isArray())
1787            return obj;
1788        PdfObject first = (PdfObject)(((PdfArray)obj).getArrayList().get(0));
1789        if (PdfName.CALGRAY.equals(first))
1790            return PdfName.DEVICEGRAY;
1791        else if (PdfName.CALRGB.equals(first))
1792            return PdfName.DEVICERGB;
1793        else
1794            return obj;
1795    }
1796
1797    /** Is this image a mask? */
1798    protected boolean mask = false;
1799    
1800    /** The image that serves as a mask for this image. */
1801    protected Image imageMask;
1802
1803    /** Holds value of property smask. */
1804    private boolean smask;
1805
1806    /**
1807     * Returns <CODE>true</CODE> if this <CODE>Image</CODE> is a mask.
1808     *
1809     * @return <CODE>true</CODE> if this <CODE>Image</CODE> is a mask
1810     */

1811    public boolean isMask() {
1812        return mask;
1813    }
1814
1815    /**
1816     * Make this <CODE>Image</CODE> a mask.
1817     *
1818     * @throws DocumentException
1819     * if this <CODE>Image</CODE> can not be a mask
1820     */

1821    public void makeMask() throws DocumentException {
1822        if (!isMaskCandidate())
1823            throw new DocumentException("This image can not be an image mask.");
1824        mask = true;
1825    }
1826
1827    /**
1828     * Returns <CODE>true</CODE> if this <CODE>Image</CODE> has the
1829     * requisites to be a mask.
1830     *
1831     * @return <CODE>true</CODE> if this <CODE>Image</CODE> can be a mask
1832     */

1833    public boolean isMaskCandidate() {
1834        if (type == IMGRAW) {
1835            if (bpc > 0xff)
1836                return true;
1837        }
1838        return colorspace == 1;
1839    }
1840
1841    /**
1842     * Gets the explicit masking.
1843     *
1844     * @return the explicit masking
1845     */

1846    public Image getImageMask() {
1847        return imageMask;
1848    }
1849
1850    /**
1851     * Sets the explicit masking.
1852     *
1853     * @param mask
1854     * the mask to be applied
1855     * @throws DocumentException
1856     * on error
1857     */

1858    public void setImageMask(Image mask) throws DocumentException {
1859        if (this.mask)
1860            throw new DocumentException(
1861                    "An image mask cannot contain another image mask.");
1862        if (!mask.mask)
1863            throw new DocumentException(
1864                    "The image mask is not a mask. Did you do makeMask()?");
1865        imageMask = mask;
1866        smask = (mask.bpc > 1 && mask.bpc <= 8);
1867    }
1868
1869    /**
1870     * Getter for property smask.
1871     *
1872     * @return Value of property smask.
1873     *
1874     */

1875    public boolean isSmask() {
1876        return this.smask;
1877    }
1878
1879    /**
1880     * Setter for property smask.
1881     *
1882     * @param smask
1883     * New value of property smask.
1884     */

1885    public void setSmask(boolean smask) {
1886        this.smask = smask;
1887    }
1888
1889    /** this is the transparency information of the raw image */
1890    protected int transparency[];
1891
1892    /**
1893     * Returns the transparency.
1894     *
1895     * @return the transparency values
1896     */

1897
1898    public int[] getTransparency() {
1899        return transparency;
1900    }
1901
1902    /**
1903     * Sets the transparency values
1904     *
1905     * @param transparency
1906     * the transparency values
1907     */

1908    public void setTransparency(int transparency[]) {
1909        this.transparency = transparency;
1910    }
1911    
1912    // deprecated stuff
1913

1914    /**
1915     * Gets the <CODE>String</CODE> -representation of the reference to the
1916     * image.
1917     *
1918     * @return a <CODE>String</CODE>
1919     * @deprecated Use {@link #getUrl()} instead
1920     */

1921    
1922    public URL JavaDoc url() {
1923        return getUrl();
1924    }
1925
1926    /**
1927     * Gets the template to be used as an image.
1928     * <P>
1929     * Remark: this only makes sense for Images of the type <CODE>ImgTemplate
1930     * </CODE>.
1931     *
1932     * @return the template
1933     * @deprecated Use {@link #getTemplateData()} instead
1934     */

1935    public PdfTemplate templateData() {
1936        return getTemplateData();
1937    }
1938
1939    /**
1940     * Returns an <CODE>Image</CODE> that has been constructed taking in
1941     * account the value of some <VAR>attributes </VAR>.
1942     *
1943     * @param attributes
1944     * Some attributes
1945     * @return an <CODE>Image</CODE>
1946     * @throws BadElementException
1947     * @throws MalformedURLException
1948     * @throws IOException
1949     * @deprecated use ElementFactory.getImage(attributes)
1950     */

1951    public static Image getInstance(java.util.Properties JavaDoc attributes)
1952            throws BadElementException, MalformedURLException JavaDoc, IOException JavaDoc {
1953        return com.lowagie.text.factories.ElementFactory.getImage(attributes);
1954    }
1955    
1956    /**
1957     * Gets the left indentation.
1958     *
1959     * @return the left indentation
1960     * @deprecated Use {@link #getIndentationLeft()} instead
1961     */

1962    public float indentationLeft() {
1963        return getIndentationLeft();
1964    }
1965
1966    /**
1967     * Gets the right indentation.
1968     *
1969     * @return the right indentation
1970     * @deprecated Use {@link #getIndentationRight()} instead
1971     */

1972    public float indentationRight() {
1973        return getIndentationRight();
1974    }
1975
1976    /**
1977     * Gets the spacing before this image.
1978     *
1979     * @return the spacing
1980     * @deprecated Use {@link #getSpacingBefore()} instead
1981     */

1982    public float spacingBefore() {
1983        return getSpacingBefore();
1984    }
1985
1986    /**
1987     * Gets the spacing before this image.
1988     *
1989     * @return the spacing
1990     * @deprecated Use {@link #getSpacingAfter()} instead
1991     */

1992    public float spacingAfter() {
1993        return getSpacingAfter();
1994    }
1995
1996    /**
1997     * Gets the raw data for the image.
1998     * <P>
1999     * Remark: this only makes sense for Images of the type <CODE>RawImage
2000     * </CODE>.
2001     *
2002     * @return the raw data
2003     * @deprecated Use {@link #getRawData()} instead
2004     */

2005    public byte[] rawData() {
2006        return getRawData();
2007    }
2008    
2009    /**
2010     * Gets the bpc for the image.
2011     * <P>
2012     * Remark: this only makes sense for Images of the type <CODE>RawImage
2013     * </CODE>.
2014     *
2015     * @return a bpc value
2016     * @deprecated Use {@link #getBpc()} instead
2017     */

2018    public int bpc() {
2019        return getBpc();
2020    }
2021
2022    /**
2023     * Gets the annotation.
2024     *
2025     * @return the annotation that is linked to this image
2026     * @deprecated Use {@link #getAnnotation()} instead
2027     */

2028    public Annotation annotation() {
2029        return getAnnotation();
2030    }
2031
2032    /**
2033     * Checks if the <CODE>Images</CODE> has to be added at an absolute
2034     * position.
2035     *
2036     * @return a boolean
2037     * @deprecated Use {@link #hasAbsoluteY()} instead
2038     */

2039    public boolean hasAbsolutePosition() {
2040        return hasAbsoluteY();
2041    }
2042
2043    /**
2044     * Returns the absolute X position.
2045     *
2046     * @return a position
2047     * @deprecated Use {@link #getAbsoluteX()} instead
2048     */

2049    public float absoluteX() {
2050        return getAbsoluteX();
2051    }
2052
2053    /**
2054     * Returns the absolute Y position.
2055     *
2056     * @return a position
2057     * @deprecated Use {@link #getAbsoluteY()} instead
2058     */

2059    public float absoluteY() {
2060        return getAbsoluteY();
2061    }
2062
2063    /**
2064     * Gets the plain width of the image.
2065     *
2066     * @return a value
2067     * @deprecated Use {@link #getPlainWidth()} instead
2068     */

2069    public float plainWidth() {
2070        return getPlainWidth();
2071    }
2072
2073    /**
2074     * Gets the plain height of the image.
2075     *
2076     * @return a value
2077     * @deprecated Use {@link #getPlainHeight()} instead
2078     */

2079    public float plainHeight() {
2080        return getPlainHeight();
2081    }
2082
2083    /**
2084     * Gets the scaled height of the image.
2085     *
2086     * @return a value
2087     * @deprecated Use {@link #getScaledWidth()} instead
2088     */

2089    public float scaledWidth() {
2090        return getScaledWidth();
2091    }
2092
2093    /**
2094     * Gets the scaled height of the image.
2095     *
2096     * @return a value
2097     * @deprecated Use {@link #getScaledHeight()} instead
2098     */

2099    public float scaledHeight() {
2100        return getScaledHeight();
2101    }
2102
2103    /**
2104     * Gets the alignment for the image.
2105     *
2106     * @return a value
2107     * @deprecated Use {@link #getAlignment()} instead
2108     */

2109    public int alignment() {
2110        return getAlignment();
2111    }
2112
2113    /**
2114     * Gets the alternative text for the image.
2115     *
2116     * @return a <CODE>String</CODE>
2117     * @deprecated Use {@link #getAlt()} instead
2118     */

2119    
2120    public String JavaDoc alt() {
2121        return getAlt();
2122    }
2123    
2124    /**
2125     * Gets the colorspace for the image.
2126     * <P>
2127     * Remark: this only makes sense for Images of the type <CODE>Jpeg</CODE>.
2128     *
2129     * @return a colorspace value
2130     * @deprecated Use {@link #getColorspace()} instead
2131     */

2132    public int colorspace() {
2133        return getColorspace();
2134    }
2135
2136    /**
2137     * Inverts the meaning of the bits of a mask.
2138     *
2139     * @param invert
2140     * <CODE>true</CODE> to invert the meaning of the bits of a
2141     * mask
2142     * @deprecated use setInverted
2143     */

2144    public void setInvertMask(boolean invert) {
2145        setInverted(invert);
2146    }
2147
2148    /**
2149     * Returns <CODE>true</CODE> if the bits are to be inverted in the mask.
2150     *
2151     * @return <CODE>true</CODE> if the bits are to be inverted in the mask
2152     * @deprecated use isInvert()
2153     */

2154    public boolean isInvertMask() {
2155        return isInverted();
2156    }
2157}
Popular Tags