0001: /*
0002: * $Id: Image.java 2765 2007-05-20 11:11:16Z blowagie $
0003: * $Name$
0004: *
0005: * Copyright 1999, 2000, 2001, 2002 by Bruno Lowagie.
0006: *
0007: * The contents of this file are subject to the Mozilla Public License Version 1.1
0008: * (the "License"); you may not use this file except in compliance with the License.
0009: * You may obtain a copy of the License at http://www.mozilla.org/MPL/
0010: *
0011: * Software distributed under the License is distributed on an "AS IS" basis,
0012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
0013: * for the specific language governing rights and limitations under the License.
0014: *
0015: * The Original Code is 'iText, a free JAVA-PDF library'.
0016: *
0017: * The Initial Developer of the Original Code is Bruno Lowagie. Portions created by
0018: * the Initial Developer are Copyright (C) 1999, 2000, 2001, 2002 by Bruno Lowagie.
0019: * All Rights Reserved.
0020: * Co-Developer of the code is Paulo Soares. Portions created by the Co-Developer
0021: * are Copyright (C) 2000, 2001, 2002 by Paulo Soares. All Rights Reserved.
0022: *
0023: * Contributor(s): all the names of the contributors are added in the source code
0024: * where applicable.
0025: *
0026: * Alternatively, the contents of this file may be used under the terms of the
0027: * LGPL license (the "GNU LIBRARY GENERAL PUBLIC LICENSE"), in which case the
0028: * provisions of LGPL are applicable instead of those above. If you wish to
0029: * allow use of your version of this file only under the terms of the LGPL
0030: * License and not to allow others to use your version of this file under
0031: * the MPL, indicate your decision by deleting the provisions above and
0032: * replace them with the notice and other provisions required by the LGPL.
0033: * If you do not delete the provisions above, a recipient may use your version
0034: * of this file under either the MPL or the GNU LIBRARY GENERAL PUBLIC LICENSE.
0035: *
0036: * This library is free software; you can redistribute it and/or modify it
0037: * under the terms of the MPL as stated above or under the terms of the GNU
0038: * Library General Public License as published by the Free Software Foundation;
0039: * either version 2 of the License, or any later version.
0040: *
0041: * This library is distributed in the hope that it will be useful, but WITHOUT
0042: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
0043: * FOR A PARTICULAR PURPOSE. See the GNU Library general Public License for more
0044: * details.
0045: *
0046: * If you didn't download this code from the following link, you should check if
0047: * you aren't using an obsolete version:
0048: * http://www.lowagie.com/iText/
0049: */
0050:
0051: package com.lowagie.text;
0052:
0053: import java.awt.Graphics2D;
0054: import java.awt.color.ICC_Profile;
0055: import java.awt.image.BufferedImage;
0056: import java.io.IOException;
0057: import java.io.InputStream;
0058: import java.lang.reflect.Constructor;
0059: import java.net.MalformedURLException;
0060: import java.net.URL;
0061: import java.util.ArrayList;
0062:
0063: import com.lowagie.text.pdf.PRIndirectReference;
0064: import com.lowagie.text.pdf.PdfArray;
0065: import com.lowagie.text.pdf.PdfContentByte;
0066: import com.lowagie.text.pdf.PdfDictionary;
0067: import com.lowagie.text.pdf.PdfIndirectReference;
0068: import com.lowagie.text.pdf.PdfName;
0069: import com.lowagie.text.pdf.PdfNumber;
0070: import com.lowagie.text.pdf.PdfOCG;
0071: import com.lowagie.text.pdf.PdfObject;
0072: import com.lowagie.text.pdf.PdfReader;
0073: import com.lowagie.text.pdf.PdfTemplate;
0074: import com.lowagie.text.pdf.PdfWriter;
0075: import com.lowagie.text.pdf.RandomAccessFileOrArray;
0076: import com.lowagie.text.pdf.codec.BmpImage;
0077: import com.lowagie.text.pdf.codec.CCITTG4Encoder;
0078: import com.lowagie.text.pdf.codec.GifImage;
0079: import com.lowagie.text.pdf.codec.PngImage;
0080: import com.lowagie.text.pdf.codec.TiffImage;
0081:
0082: /**
0083: * An <CODE>Image</CODE> is the representation of a graphic element (JPEG, PNG
0084: * or GIF) that has to be inserted into the document
0085: *
0086: * @see Element
0087: * @see Rectangle
0088: */
0089:
0090: public abstract class Image extends Rectangle {
0091:
0092: // static final membervariables
0093:
0094: /** this is a kind of image alignment. */
0095: public static final int DEFAULT = 0;
0096:
0097: /** this is a kind of image alignment. */
0098: public static final int RIGHT = 2;
0099:
0100: /** this is a kind of image alignment. */
0101: public static final int LEFT = 0;
0102:
0103: /** this is a kind of image alignment. */
0104: public static final int MIDDLE = 1;
0105:
0106: /** this is a kind of image alignment. */
0107: public static final int TEXTWRAP = 4;
0108:
0109: /** this is a kind of image alignment. */
0110: public static final int UNDERLYING = 8;
0111:
0112: /** This represents a coordinate in the transformation matrix. */
0113: public static final int AX = 0;
0114:
0115: /** This represents a coordinate in the transformation matrix. */
0116: public static final int AY = 1;
0117:
0118: /** This represents a coordinate in the transformation matrix. */
0119: public static final int BX = 2;
0120:
0121: /** This represents a coordinate in the transformation matrix. */
0122: public static final int BY = 3;
0123:
0124: /** This represents a coordinate in the transformation matrix. */
0125: public static final int CX = 4;
0126:
0127: /** This represents a coordinate in the transformation matrix. */
0128: public static final int CY = 5;
0129:
0130: /** This represents a coordinate in the transformation matrix. */
0131: public static final int DX = 6;
0132:
0133: /** This represents a coordinate in the transformation matrix. */
0134: public static final int DY = 7;
0135:
0136: /** type of image */
0137: public static final int ORIGINAL_NONE = 0;
0138:
0139: /** type of image */
0140: public static final int ORIGINAL_JPEG = 1;
0141:
0142: /** type of image */
0143: public static final int ORIGINAL_PNG = 2;
0144:
0145: /** type of image */
0146: public static final int ORIGINAL_GIF = 3;
0147:
0148: /** type of image */
0149: public static final int ORIGINAL_BMP = 4;
0150:
0151: /** type of image */
0152: public static final int ORIGINAL_TIFF = 5;
0153:
0154: /** type of image */
0155: public static final int ORIGINAL_WMF = 6;
0156:
0157: /** type of image */
0158: public static final int ORIGINAL_PS = 7;
0159:
0160: // member variables
0161:
0162: /** The imagetype. */
0163: protected int type;
0164:
0165: /** The URL of the image. */
0166: protected URL url;
0167:
0168: /** The raw data of the image. */
0169: protected byte rawData[];
0170:
0171: /** The bits per component of the raw image. It also flags a CCITT image. */
0172: protected int bpc = 1;
0173:
0174: /** The template to be treated as an image. */
0175: protected PdfTemplate template[] = new PdfTemplate[1];
0176:
0177: /** The alignment of the Image. */
0178: protected int alignment;
0179:
0180: /** Text that can be shown instead of the image. */
0181: protected String alt;
0182:
0183: /** This is the absolute X-position of the image. */
0184: protected float absoluteX = Float.NaN;
0185:
0186: /** This is the absolute Y-position of the image. */
0187: protected float absoluteY = Float.NaN;
0188:
0189: /** This is the width of the image without rotation. */
0190: protected float plainWidth;
0191:
0192: /** This is the width of the image without rotation. */
0193: protected float plainHeight;
0194:
0195: /** This is the scaled width of the image taking rotation into account. */
0196: protected float scaledWidth;
0197:
0198: /** This is the original height of the image taking rotation into account. */
0199: protected float scaledHeight;
0200:
0201: /** an iText attributed unique id for this image. */
0202: protected Long mySerialId = getSerialId();
0203:
0204: // image from file or URL
0205:
0206: /**
0207: * Constructs an <CODE>Image</CODE> -object, using an <VAR>url </VAR>.
0208: *
0209: * @param url
0210: * the <CODE>URL</CODE> where the image can be found.
0211: */
0212: public Image(URL url) {
0213: super (0, 0);
0214: this .url = url;
0215: this .alignment = DEFAULT;
0216: rotationRadians = 0;
0217: }
0218:
0219: /**
0220: * Gets an instance of an Image.
0221: *
0222: * @param url
0223: * an URL
0224: * @return an Image
0225: * @throws BadElementException
0226: * @throws MalformedURLException
0227: * @throws IOException
0228: */
0229: public static Image getInstance(URL url)
0230: throws BadElementException, MalformedURLException,
0231: IOException {
0232: InputStream is = null;
0233: try {
0234: is = url.openStream();
0235: int c1 = is.read();
0236: int c2 = is.read();
0237: int c3 = is.read();
0238: int c4 = is.read();
0239: is.close();
0240:
0241: is = null;
0242: if (c1 == 'G' && c2 == 'I' && c3 == 'F') {
0243: GifImage gif = new GifImage(url);
0244: Image img = gif.getImage(1);
0245: return img;
0246: }
0247: if (c1 == 0xFF && c2 == 0xD8) {
0248: return new Jpeg(url);
0249: }
0250: if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1]
0251: && c3 == PngImage.PNGID[2]
0252: && c4 == PngImage.PNGID[3]) {
0253: return PngImage.getImage(url);
0254: }
0255: if (c1 == 0xD7 && c2 == 0xCD) {
0256: return new ImgWMF(url);
0257: }
0258: if (c1 == 'B' && c2 == 'M') {
0259: return BmpImage.getImage(url);
0260: }
0261: if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42)
0262: || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) {
0263: RandomAccessFileOrArray ra = null;
0264: try {
0265: if (url.getProtocol().equals("file")) {
0266: String file = url.getFile();
0267: file = Utilities.unEscapeURL(file);
0268: ra = new RandomAccessFileOrArray(file);
0269: } else
0270: ra = new RandomAccessFileOrArray(url);
0271: Image img = TiffImage.getTiffImage(ra, 1);
0272: img.url = url;
0273: return img;
0274: } finally {
0275: if (ra != null)
0276: ra.close();
0277: }
0278:
0279: }
0280: throw new IOException(url.toString()
0281: + " is not a recognized imageformat.");
0282: } finally {
0283: if (is != null) {
0284: is.close();
0285: }
0286: }
0287: }
0288:
0289: /**
0290: * Gets an instance of an Image.
0291: *
0292: * @param filename
0293: * a filename
0294: * @return an object of type <CODE>Gif</CODE>,<CODE>Jpeg</CODE> or
0295: * <CODE>Png</CODE>
0296: * @throws BadElementException
0297: * @throws MalformedURLException
0298: * @throws IOException
0299: */
0300: public static Image getInstance(String filename)
0301: throws BadElementException, MalformedURLException,
0302: IOException {
0303: return getInstance(Utilities.toURL(filename));
0304: }
0305:
0306: /**
0307: * gets an instance of an Image
0308: *
0309: * @param imgb
0310: * raw image date
0311: * @return an Image object
0312: * @throws BadElementException
0313: * @throws MalformedURLException
0314: * @throws IOException
0315: */
0316: public static Image getInstance(byte imgb[])
0317: throws BadElementException, MalformedURLException,
0318: IOException {
0319: InputStream is = null;
0320: try {
0321: is = new java.io.ByteArrayInputStream(imgb);
0322: int c1 = is.read();
0323: int c2 = is.read();
0324: int c3 = is.read();
0325: int c4 = is.read();
0326: is.close();
0327:
0328: is = null;
0329: if (c1 == 'G' && c2 == 'I' && c3 == 'F') {
0330: GifImage gif = new GifImage(imgb);
0331: return gif.getImage(1);
0332: }
0333: if (c1 == 0xFF && c2 == 0xD8) {
0334: return new Jpeg(imgb);
0335: }
0336: if (c1 == PngImage.PNGID[0] && c2 == PngImage.PNGID[1]
0337: && c3 == PngImage.PNGID[2]
0338: && c4 == PngImage.PNGID[3]) {
0339: return PngImage.getImage(imgb);
0340: }
0341: if (c1 == 0xD7 && c2 == 0xCD) {
0342: return new ImgWMF(imgb);
0343: }
0344: if (c1 == 'B' && c2 == 'M') {
0345: return BmpImage.getImage(imgb);
0346: }
0347: if ((c1 == 'M' && c2 == 'M' && c3 == 0 && c4 == 42)
0348: || (c1 == 'I' && c2 == 'I' && c3 == 42 && c4 == 0)) {
0349: RandomAccessFileOrArray ra = null;
0350: try {
0351: ra = new RandomAccessFileOrArray(imgb);
0352: Image img = TiffImage.getTiffImage(ra, 1);
0353: if (img.getOriginalData() == null)
0354: img.setOriginalData(imgb);
0355: return img;
0356: } finally {
0357: if (ra != null)
0358: ra.close();
0359: }
0360:
0361: }
0362: throw new IOException(
0363: "The byte array is not a recognized imageformat.");
0364: } finally {
0365: if (is != null) {
0366: is.close();
0367: }
0368: }
0369: }
0370:
0371: /**
0372: * Gets an instance of an Image in raw mode.
0373: *
0374: * @param width
0375: * the width of the image in pixels
0376: * @param height
0377: * the height of the image in pixels
0378: * @param components
0379: * 1,3 or 4 for GrayScale, RGB and CMYK
0380: * @param data
0381: * the image data
0382: * @param bpc
0383: * bits per component
0384: * @return an object of type <CODE>ImgRaw</CODE>
0385: * @throws BadElementException
0386: * on error
0387: */
0388: public static Image getInstance(int width, int height,
0389: int components, int bpc, byte data[])
0390: throws BadElementException {
0391: return Image.getInstance(width, height, components, bpc, data,
0392: null);
0393: }
0394:
0395: /**
0396: * Creates an Image with CCITT G3 or G4 compression. It assumes that the
0397: * data bytes are already compressed.
0398: *
0399: * @param width
0400: * the exact width of the image
0401: * @param height
0402: * the exact height of the image
0403: * @param reverseBits
0404: * reverses the bits in <code>data</code>. Bit 0 is swapped
0405: * with bit 7 and so on
0406: * @param typeCCITT
0407: * the type of compression in <code>data</code>. It can be
0408: * CCITTG4, CCITTG31D, CCITTG32D
0409: * @param parameters
0410: * parameters associated with this stream. Possible values are
0411: * CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and
0412: * CCITT_ENDOFBLOCK or a combination of them
0413: * @param data
0414: * the image data
0415: * @return an Image object
0416: * @throws BadElementException
0417: * on error
0418: */
0419: public static Image getInstance(int width, int height,
0420: boolean reverseBits, int typeCCITT, int parameters,
0421: byte[] data) throws BadElementException {
0422: return Image.getInstance(width, height, reverseBits, typeCCITT,
0423: parameters, data, null);
0424: }
0425:
0426: /**
0427: * Creates an Image with CCITT G3 or G4 compression. It assumes that the
0428: * data bytes are already compressed.
0429: *
0430: * @param width
0431: * the exact width of the image
0432: * @param height
0433: * the exact height of the image
0434: * @param reverseBits
0435: * reverses the bits in <code>data</code>. Bit 0 is swapped
0436: * with bit 7 and so on
0437: * @param typeCCITT
0438: * the type of compression in <code>data</code>. It can be
0439: * CCITTG4, CCITTG31D, CCITTG32D
0440: * @param parameters
0441: * parameters associated with this stream. Possible values are
0442: * CCITT_BLACKIS1, CCITT_ENCODEDBYTEALIGN, CCITT_ENDOFLINE and
0443: * CCITT_ENDOFBLOCK or a combination of them
0444: * @param data
0445: * the image data
0446: * @param transparency
0447: * transparency information in the Mask format of the image
0448: * dictionary
0449: * @return an Image object
0450: * @throws BadElementException
0451: * on error
0452: */
0453: public static Image getInstance(int width, int height,
0454: boolean reverseBits, int typeCCITT, int parameters,
0455: byte[] data, int transparency[]) throws BadElementException {
0456: if (transparency != null && transparency.length != 2)
0457: throw new BadElementException(
0458: "Transparency length must be equal to 2 with CCITT images");
0459: Image img = new ImgCCITT(width, height, reverseBits, typeCCITT,
0460: parameters, data);
0461: img.transparency = transparency;
0462: return img;
0463: }
0464:
0465: /**
0466: * Gets an instance of an Image in raw mode.
0467: *
0468: * @param width
0469: * the width of the image in pixels
0470: * @param height
0471: * the height of the image in pixels
0472: * @param components
0473: * 1,3 or 4 for GrayScale, RGB and CMYK
0474: * @param data
0475: * the image data
0476: * @param bpc
0477: * bits per component
0478: * @param transparency
0479: * transparency information in the Mask format of the image
0480: * dictionary
0481: * @return an object of type <CODE>ImgRaw</CODE>
0482: * @throws BadElementException
0483: * on error
0484: */
0485: public static Image getInstance(int width, int height,
0486: int components, int bpc, byte data[], int transparency[])
0487: throws BadElementException {
0488: if (transparency != null
0489: && transparency.length != components * 2)
0490: throw new BadElementException(
0491: "Transparency length must be equal to (componentes * 2)");
0492: if (components == 1 && bpc == 1) {
0493: byte g4[] = CCITTG4Encoder.compress(data, width, height);
0494: return Image.getInstance(width, height, false,
0495: Image.CCITTG4, Image.CCITT_BLACKIS1, g4,
0496: transparency);
0497: }
0498: Image img = new ImgRaw(width, height, components, bpc, data);
0499: img.transparency = transparency;
0500: return img;
0501: }
0502:
0503: // images from a PdfTemplate
0504:
0505: /**
0506: * gets an instance of an Image
0507: *
0508: * @param template
0509: * a PdfTemplate that has to be wrapped in an Image object
0510: * @return an Image object
0511: * @throws BadElementException
0512: */
0513: public static Image getInstance(PdfTemplate template)
0514: throws BadElementException {
0515: return new ImgTemplate(template);
0516: }
0517:
0518: // images from a java.awt.Image
0519:
0520: /**
0521: * Gets an instance of an Image from a java.awt.Image.
0522: *
0523: * @param image
0524: * the <CODE>java.awt.Image</CODE> to convert
0525: * @param color
0526: * if different from <CODE>null</CODE> the transparency pixels
0527: * are replaced by this color
0528: * @param forceBW
0529: * if <CODE>true</CODE> the image is treated as black and white
0530: * @return an object of type <CODE>ImgRaw</CODE>
0531: * @throws BadElementException
0532: * on error
0533: * @throws IOException
0534: * on error
0535: */
0536: public static Image getInstance(java.awt.Image image,
0537: java.awt.Color color, boolean forceBW)
0538: throws BadElementException, IOException {
0539:
0540: if (image instanceof BufferedImage) {
0541: BufferedImage bi = (BufferedImage) image;
0542: if (bi.getType() == BufferedImage.TYPE_BYTE_BINARY) {
0543: forceBW = true;
0544: }
0545: }
0546:
0547: java.awt.image.PixelGrabber pg = new java.awt.image.PixelGrabber(
0548: image, 0, 0, -1, -1, true);
0549: try {
0550: pg.grabPixels();
0551: } catch (InterruptedException e) {
0552: throw new IOException(
0553: "java.awt.Image Interrupted waiting for pixels!");
0554: }
0555: if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) {
0556: throw new IOException(
0557: "java.awt.Image fetch aborted or errored");
0558: }
0559: int w = pg.getWidth();
0560: int h = pg.getHeight();
0561: int[] pixels = (int[]) pg.getPixels();
0562: if (forceBW) {
0563: int byteWidth = (w / 8) + ((w & 7) != 0 ? 1 : 0);
0564: byte[] pixelsByte = new byte[byteWidth * h];
0565:
0566: int index = 0;
0567: int size = h * w;
0568: int transColor = 1;
0569: if (color != null) {
0570: transColor = (color.getRed() + color.getGreen()
0571: + color.getBlue() < 384) ? 0 : 1;
0572: }
0573: int transparency[] = null;
0574: int cbyte = 0x80;
0575: int wMarker = 0;
0576: int currByte = 0;
0577: if (color != null) {
0578: for (int j = 0; j < size; j++) {
0579: int alpha = (pixels[j] >> 24) & 0xff;
0580: if (alpha < 250) {
0581: if (transColor == 1)
0582: currByte |= cbyte;
0583: } else {
0584: if ((pixels[j] & 0x888) != 0)
0585: currByte |= cbyte;
0586: }
0587: cbyte >>= 1;
0588: if (cbyte == 0 || wMarker + 1 >= w) {
0589: pixelsByte[index++] = (byte) currByte;
0590: cbyte = 0x80;
0591: currByte = 0;
0592: }
0593: ++wMarker;
0594: if (wMarker >= w)
0595: wMarker = 0;
0596: }
0597: } else {
0598: for (int j = 0; j < size; j++) {
0599: if (transparency == null) {
0600: int alpha = (pixels[j] >> 24) & 0xff;
0601: if (alpha == 0) {
0602: transparency = new int[2];
0603: transparency[0] = transparency[1] = ((pixels[j] & 0x888) != 0) ? 1
0604: : 0;
0605: }
0606: }
0607: if ((pixels[j] & 0x888) != 0)
0608: currByte |= cbyte;
0609: cbyte >>= 1;
0610: if (cbyte == 0 || wMarker + 1 >= w) {
0611: pixelsByte[index++] = (byte) currByte;
0612: cbyte = 0x80;
0613: currByte = 0;
0614: }
0615: ++wMarker;
0616: if (wMarker >= w)
0617: wMarker = 0;
0618: }
0619: }
0620: return Image.getInstance(w, h, 1, 1, pixelsByte,
0621: transparency);
0622: } else {
0623: byte[] pixelsByte = new byte[w * h * 3];
0624: byte[] smask = null;
0625:
0626: int index = 0;
0627: int size = h * w;
0628: int red = 255;
0629: int green = 255;
0630: int blue = 255;
0631: if (color != null) {
0632: red = color.getRed();
0633: green = color.getGreen();
0634: blue = color.getBlue();
0635: }
0636: int transparency[] = null;
0637: if (color != null) {
0638: for (int j = 0; j < size; j++) {
0639: int alpha = (pixels[j] >> 24) & 0xff;
0640: if (alpha < 250) {
0641: pixelsByte[index++] = (byte) red;
0642: pixelsByte[index++] = (byte) green;
0643: pixelsByte[index++] = (byte) blue;
0644: } else {
0645: pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff);
0646: pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff);
0647: pixelsByte[index++] = (byte) ((pixels[j]) & 0xff);
0648: }
0649: }
0650: } else {
0651: int transparentPixel = 0;
0652: smask = new byte[w * h];
0653: boolean shades = false;
0654: for (int j = 0; j < size; j++) {
0655: byte alpha = smask[j] = (byte) ((pixels[j] >> 24) & 0xff);
0656: /* bugfix by Chris Nokleberg */
0657: if (!shades) {
0658: if (alpha != 0 && alpha != -1) {
0659: shades = true;
0660: } else if (transparency == null) {
0661: if (alpha == 0) {
0662: transparentPixel = pixels[j] & 0xffffff;
0663: transparency = new int[6];
0664: transparency[0] = transparency[1] = (transparentPixel >> 16) & 0xff;
0665: transparency[2] = transparency[3] = (transparentPixel >> 8) & 0xff;
0666: transparency[4] = transparency[5] = transparentPixel & 0xff;
0667: }
0668: } else if ((pixels[j] & 0xffffff) != transparentPixel) {
0669: shades = true;
0670: }
0671: }
0672: pixelsByte[index++] = (byte) ((pixels[j] >> 16) & 0xff);
0673: pixelsByte[index++] = (byte) ((pixels[j] >> 8) & 0xff);
0674: pixelsByte[index++] = (byte) ((pixels[j]) & 0xff);
0675: }
0676: if (shades)
0677: transparency = null;
0678: else
0679: smask = null;
0680: }
0681: Image img = Image.getInstance(w, h, 3, 8, pixelsByte,
0682: transparency);
0683: if (smask != null) {
0684: Image sm = Image.getInstance(w, h, 1, 8, smask);
0685: try {
0686: sm.makeMask();
0687: img.setImageMask(sm);
0688: } catch (DocumentException de) {
0689: throw new ExceptionConverter(de);
0690: }
0691: }
0692: return img;
0693: }
0694: }
0695:
0696: /**
0697: * Gets an instance of an Image from a java.awt.Image.
0698: *
0699: * @param image
0700: * the <CODE>java.awt.Image</CODE> to convert
0701: * @param color
0702: * if different from <CODE>null</CODE> the transparency pixels
0703: * are replaced by this color
0704: * @return an object of type <CODE>ImgRaw</CODE>
0705: * @throws BadElementException
0706: * on error
0707: * @throws IOException
0708: * on error
0709: */
0710: public static Image getInstance(java.awt.Image image,
0711: java.awt.Color color) throws BadElementException,
0712: IOException {
0713: return Image.getInstance(image, color, false);
0714: }
0715:
0716: /**
0717: * Gets an instance of a Image from a java.awt.Image.
0718: * The image is added as a JPEG with a userdefined quality.
0719: *
0720: * @param writer
0721: * the <CODE>PdfWriter</CODE> object to which the image will be added
0722: * @param awtImage
0723: * the <CODE>java.awt.Image</CODE> to convert
0724: * @param quality
0725: * a float value between 0 and 1
0726: * @return an object of type <CODE>PdfTemplate</CODE>
0727: * @throws BadElementException
0728: * on error
0729: * @throws IOException
0730: */
0731: public static Image getInstance(PdfWriter writer,
0732: java.awt.Image awtImage, float quality)
0733: throws BadElementException, IOException {
0734: return getInstance(new PdfContentByte(writer), awtImage,
0735: quality);
0736: }
0737:
0738: /**
0739: * Gets an instance of a Image from a java.awt.Image.
0740: * The image is added as a JPEG with a userdefined quality.
0741: *
0742: * @param cb
0743: * the <CODE>PdfContentByte</CODE> object to which the image will be added
0744: * @param awtImage
0745: * the <CODE>java.awt.Image</CODE> to convert
0746: * @param quality
0747: * a float value between 0 and 1
0748: * @return an object of type <CODE>PdfTemplate</CODE>
0749: * @throws BadElementException
0750: * on error
0751: * @throws IOException
0752: */
0753: public static Image getInstance(PdfContentByte cb,
0754: java.awt.Image awtImage, float quality)
0755: throws BadElementException, IOException {
0756: java.awt.image.PixelGrabber pg = new java.awt.image.PixelGrabber(
0757: awtImage, 0, 0, -1, -1, true);
0758: try {
0759: pg.grabPixels();
0760: } catch (InterruptedException e) {
0761: throw new IOException(
0762: "java.awt.Image Interrupted waiting for pixels!");
0763: }
0764: if ((pg.getStatus() & java.awt.image.ImageObserver.ABORT) != 0) {
0765: throw new IOException(
0766: "java.awt.Image fetch aborted or errored");
0767: }
0768: int w = pg.getWidth();
0769: int h = pg.getHeight();
0770: PdfTemplate tp = cb.createTemplate(w, h);
0771: Graphics2D g2d = tp.createGraphics(w, h, true, quality);
0772: g2d.drawImage(awtImage, 0, 0, null);
0773: g2d.dispose();
0774: return getInstance(tp);
0775: }
0776:
0777: // image from indirect reference
0778:
0779: /**
0780: * Holds value of property directReference.
0781: * An image is embedded into a PDF as an Image XObject.
0782: * This object is referenced by a PdfIndirectReference object.
0783: */
0784: private PdfIndirectReference directReference;
0785:
0786: /**
0787: * Getter for property directReference.
0788: * @return Value of property directReference.
0789: */
0790: public PdfIndirectReference getDirectReference() {
0791: return this .directReference;
0792: }
0793:
0794: /**
0795: * Setter for property directReference.
0796: * @param directReference New value of property directReference.
0797: */
0798: public void setDirectReference(PdfIndirectReference directReference) {
0799: this .directReference = directReference;
0800: }
0801:
0802: /**
0803: * Reuses an existing image.
0804: * @param ref the reference to the image dictionary
0805: * @throws BadElementException on error
0806: * @return the image
0807: */
0808: public static Image getInstance(PRIndirectReference ref)
0809: throws BadElementException {
0810: PdfDictionary dic = (PdfDictionary) PdfReader
0811: .getPdfObjectRelease(ref);
0812: int width = ((PdfNumber) PdfReader.getPdfObjectRelease(dic
0813: .get(PdfName.WIDTH))).intValue();
0814: int height = ((PdfNumber) PdfReader.getPdfObjectRelease(dic
0815: .get(PdfName.HEIGHT))).intValue();
0816: Image imask = null;
0817: PdfObject obj = dic.get(PdfName.SMASK);
0818: if (obj != null && obj.isIndirect()) {
0819: imask = getInstance((PRIndirectReference) obj);
0820: } else {
0821: obj = dic.get(PdfName.MASK);
0822: if (obj != null && obj.isIndirect()) {
0823: PdfObject obj2 = PdfReader.getPdfObjectRelease(obj);
0824: if (obj2 instanceof PdfDictionary)
0825: imask = getInstance((PRIndirectReference) obj);
0826: }
0827: }
0828: Image img = new ImgRaw(width, height, 1, 1, null);
0829: img.imageMask = imask;
0830: img.directReference = ref;
0831: return img;
0832: }
0833:
0834: // copy constructor
0835:
0836: /**
0837: * Constructs an <CODE>Image</CODE> -object, using an <VAR>url </VAR>.
0838: *
0839: * @param image
0840: * another Image object.
0841: */
0842: protected Image(Image image) {
0843: super (image);
0844: this .type = image.type;
0845: this .url = image.url;
0846: this .rawData = image.rawData;
0847: this .bpc = image.bpc;
0848: this .template = image.template;
0849: this .alignment = image.alignment;
0850: this .alt = image.alt;
0851: this .absoluteX = image.absoluteX;
0852: this .absoluteY = image.absoluteY;
0853: this .plainWidth = image.plainWidth;
0854: this .plainHeight = image.plainHeight;
0855: this .scaledWidth = image.scaledWidth;
0856: this .scaledHeight = image.scaledHeight;
0857: this .mySerialId = image.mySerialId;
0858:
0859: this .directReference = image.directReference;
0860:
0861: this .rotationRadians = image.rotationRadians;
0862: this .initialRotation = image.initialRotation;
0863: this .indentationLeft = image.indentationLeft;
0864: this .indentationRight = image.indentationRight;
0865: this .spacingBefore = image.spacingBefore;
0866: this .spacingAfter = image.spacingAfter;
0867:
0868: this .widthPercentage = image.widthPercentage;
0869: this .annotation = image.annotation;
0870: this .layer = image.layer;
0871: this .interpolation = image.interpolation;
0872: this .originalType = image.originalType;
0873: this .originalData = image.originalData;
0874: this .deflated = image.deflated;
0875: this .dpiX = image.dpiX;
0876: this .dpiY = image.dpiY;
0877: this .XYRatio = image.XYRatio;
0878:
0879: this .colorspace = image.colorspace;
0880: this .invert = image.invert;
0881: this .profile = image.profile;
0882: this .additional = image.additional;
0883: this .mask = image.mask;
0884: this .imageMask = image.imageMask;
0885: this .smask = image.smask;
0886: this .transparency = image.transparency;
0887: }
0888:
0889: /**
0890: * gets an instance of an Image
0891: *
0892: * @param image
0893: * an Image object
0894: * @return a new Image object
0895: */
0896: public static Image getInstance(Image image) {
0897: if (image == null)
0898: return null;
0899: try {
0900: Class cs = image.getClass();
0901: Constructor constructor = cs
0902: .getDeclaredConstructor(new Class[] { Image.class });
0903: return (Image) constructor
0904: .newInstance(new Object[] { image });
0905: } catch (Exception e) {
0906: throw new ExceptionConverter(e);
0907: }
0908: }
0909:
0910: // implementation of the Element interface
0911:
0912: /**
0913: * Returns the type.
0914: *
0915: * @return a type
0916: */
0917:
0918: public int type() {
0919: return type;
0920: }
0921:
0922: // checking the type of Image
0923:
0924: /**
0925: * Returns <CODE>true</CODE> if the image is a <CODE>Jpeg</CODE>
0926: * -object.
0927: *
0928: * @return a <CODE>boolean</CODE>
0929: */
0930:
0931: public boolean isJpeg() {
0932: return type == JPEG;
0933: }
0934:
0935: /**
0936: * Returns <CODE>true</CODE> if the image is a <CODE>ImgRaw</CODE>
0937: * -object.
0938: *
0939: * @return a <CODE>boolean</CODE>
0940: */
0941:
0942: public boolean isImgRaw() {
0943: return type == IMGRAW;
0944: }
0945:
0946: /**
0947: * Returns <CODE>true</CODE> if the image is an <CODE>ImgTemplate</CODE>
0948: * -object.
0949: *
0950: * @return a <CODE>boolean</CODE>
0951: */
0952:
0953: public boolean isImgTemplate() {
0954: return type == IMGTEMPLATE;
0955: }
0956:
0957: // getters and setters
0958:
0959: /**
0960: * Gets the <CODE>String</CODE> -representation of the reference to the
0961: * image.
0962: *
0963: * @return a <CODE>String</CODE>
0964: */
0965:
0966: public URL getUrl() {
0967: return url;
0968: }
0969:
0970: /**
0971: * Sets the url of the image
0972: *
0973: * @param url
0974: * the url of the image
0975: */
0976: public void setUrl(URL url) {
0977: this .url = url;
0978: }
0979:
0980: /**
0981: * Gets the raw data for the image.
0982: * <P>
0983: * Remark: this only makes sense for Images of the type <CODE>RawImage
0984: * </CODE>.
0985: *
0986: * @return the raw data
0987: */
0988: public byte[] getRawData() {
0989: return rawData;
0990: }
0991:
0992: /**
0993: * Gets the bpc for the image.
0994: * <P>
0995: * Remark: this only makes sense for Images of the type <CODE>RawImage
0996: * </CODE>.
0997: *
0998: * @return a bpc value
0999: */
1000: public int getBpc() {
1001: return bpc;
1002: }
1003:
1004: /**
1005: * Gets the template to be used as an image.
1006: * <P>
1007: * Remark: this only makes sense for Images of the type <CODE>ImgTemplate
1008: * </CODE>.
1009: *
1010: * @return the template
1011: */
1012: public PdfTemplate getTemplateData() {
1013: return template[0];
1014: }
1015:
1016: /**
1017: * Sets data from a PdfTemplate
1018: *
1019: * @param template
1020: * the template with the content
1021: */
1022: public void setTemplateData(PdfTemplate template) {
1023: this .template[0] = template;
1024: }
1025:
1026: /**
1027: * Gets the alignment for the image.
1028: *
1029: * @return a value
1030: */
1031: public int getAlignment() {
1032: return alignment;
1033: }
1034:
1035: /**
1036: * Sets the alignment for the image.
1037: *
1038: * @param alignment
1039: * the alignment
1040: */
1041:
1042: public void setAlignment(int alignment) {
1043: this .alignment = alignment;
1044: }
1045:
1046: /**
1047: * Gets the alternative text for the image.
1048: *
1049: * @return a <CODE>String</CODE>
1050: */
1051:
1052: public String getAlt() {
1053: return alt;
1054: }
1055:
1056: /**
1057: * Sets the alternative information for the image.
1058: *
1059: * @param alt
1060: * the alternative information
1061: */
1062:
1063: public void setAlt(String alt) {
1064: this .alt = alt;
1065: }
1066:
1067: /**
1068: * Sets the absolute position of the <CODE>Image</CODE>.
1069: *
1070: * @param absoluteX
1071: * @param absoluteY
1072: */
1073:
1074: public void setAbsolutePosition(float absoluteX, float absoluteY) {
1075: this .absoluteX = absoluteX;
1076: this .absoluteY = absoluteY;
1077: }
1078:
1079: /**
1080: * Checks if the <CODE>Images</CODE> has to be added at an absolute X
1081: * position.
1082: *
1083: * @return a boolean
1084: */
1085: public boolean hasAbsoluteX() {
1086: return !Float.isNaN(absoluteX);
1087: }
1088:
1089: /**
1090: * Returns the absolute X position.
1091: *
1092: * @return a position
1093: */
1094: public float getAbsoluteX() {
1095: return absoluteX;
1096: }
1097:
1098: /**
1099: * Checks if the <CODE>Images</CODE> has to be added at an absolute
1100: * position.
1101: *
1102: * @return a boolean
1103: */
1104: public boolean hasAbsoluteY() {
1105: return !Float.isNaN(absoluteY);
1106: }
1107:
1108: /**
1109: * Returns the absolute Y position.
1110: *
1111: * @return a position
1112: */
1113: public float getAbsoluteY() {
1114: return absoluteY;
1115: }
1116:
1117: // width and height
1118:
1119: /**
1120: * Gets the scaled width of the image.
1121: *
1122: * @return a value
1123: */
1124: public float getScaledWidth() {
1125: return scaledWidth;
1126: }
1127:
1128: /**
1129: * Gets the scaled height of the image.
1130: *
1131: * @return a value
1132: */
1133: public float getScaledHeight() {
1134: return scaledHeight;
1135: }
1136:
1137: /**
1138: * Gets the plain width of the image.
1139: *
1140: * @return a value
1141: */
1142: public float getPlainWidth() {
1143: return plainWidth;
1144: }
1145:
1146: /**
1147: * Gets the plain height of the image.
1148: *
1149: * @return a value
1150: */
1151: public float getPlainHeight() {
1152: return plainHeight;
1153: }
1154:
1155: /**
1156: * Scale the image to an absolute width and an absolute height.
1157: *
1158: * @param newWidth
1159: * the new width
1160: * @param newHeight
1161: * the new height
1162: */
1163: public void scaleAbsolute(float newWidth, float newHeight) {
1164: plainWidth = newWidth;
1165: plainHeight = newHeight;
1166: float[] matrix = matrix();
1167: scaledWidth = matrix[DX] - matrix[CX];
1168: scaledHeight = matrix[DY] - matrix[CY];
1169: }
1170:
1171: /**
1172: * Scale the image to an absolute width.
1173: *
1174: * @param newWidth
1175: * the new width
1176: */
1177: public void scaleAbsoluteWidth(float newWidth) {
1178: plainWidth = newWidth;
1179: float[] matrix = matrix();
1180: scaledWidth = matrix[DX] - matrix[CX];
1181: scaledHeight = matrix[DY] - matrix[CY];
1182: }
1183:
1184: /**
1185: * Scale the image to an absolute height.
1186: *
1187: * @param newHeight
1188: * the new height
1189: */
1190: public void scaleAbsoluteHeight(float newHeight) {
1191: plainHeight = newHeight;
1192: float[] matrix = matrix();
1193: scaledWidth = matrix[DX] - matrix[CX];
1194: scaledHeight = matrix[DY] - matrix[CY];
1195: }
1196:
1197: /**
1198: * Scale the image to a certain percentage.
1199: *
1200: * @param percent
1201: * the scaling percentage
1202: */
1203: public void scalePercent(float percent) {
1204: scalePercent(percent, percent);
1205: }
1206:
1207: /**
1208: * Scale the width and height of an image to a certain percentage.
1209: *
1210: * @param percentX
1211: * the scaling percentage of the width
1212: * @param percentY
1213: * the scaling percentage of the height
1214: */
1215: public void scalePercent(float percentX, float percentY) {
1216: plainWidth = (getWidth() * percentX) / 100f;
1217: plainHeight = (getHeight() * percentY) / 100f;
1218: float[] matrix = matrix();
1219: scaledWidth = matrix[DX] - matrix[CX];
1220: scaledHeight = matrix[DY] - matrix[CY];
1221: }
1222:
1223: /**
1224: * Scales the image so that it fits a certain width and height.
1225: *
1226: * @param fitWidth
1227: * the width to fit
1228: * @param fitHeight
1229: * the height to fit
1230: */
1231: public void scaleToFit(float fitWidth, float fitHeight) {
1232: scalePercent(100);
1233: float percentX = (fitWidth * 100) / getScaledWidth();
1234: float percentY = (fitHeight * 100) / getScaledHeight();
1235: scalePercent(percentX < percentY ? percentX : percentY);
1236: }
1237:
1238: /**
1239: * Returns the transformation matrix of the image.
1240: *
1241: * @return an array [AX, AY, BX, BY, CX, CY, DX, DY]
1242: */
1243: public float[] matrix() {
1244: float[] matrix = new float[8];
1245: float cosX = (float) Math.cos(rotationRadians);
1246: float sinX = (float) Math.sin(rotationRadians);
1247: matrix[AX] = plainWidth * cosX;
1248: matrix[AY] = plainWidth * sinX;
1249: matrix[BX] = (-plainHeight) * sinX;
1250: matrix[BY] = plainHeight * cosX;
1251: if (rotationRadians < Math.PI / 2f) {
1252: matrix[CX] = matrix[BX];
1253: matrix[CY] = 0;
1254: matrix[DX] = matrix[AX];
1255: matrix[DY] = matrix[AY] + matrix[BY];
1256: } else if (rotationRadians < Math.PI) {
1257: matrix[CX] = matrix[AX] + matrix[BX];
1258: matrix[CY] = matrix[BY];
1259: matrix[DX] = 0;
1260: matrix[DY] = matrix[AY];
1261: } else if (rotationRadians < Math.PI * 1.5f) {
1262: matrix[CX] = matrix[AX];
1263: matrix[CY] = matrix[AY] + matrix[BY];
1264: matrix[DX] = matrix[BX];
1265: matrix[DY] = 0;
1266: } else {
1267: matrix[CX] = 0;
1268: matrix[CY] = matrix[AY];
1269: matrix[DX] = matrix[AX] + matrix[BX];
1270: matrix[DY] = matrix[BY];
1271: }
1272: return matrix;
1273: }
1274:
1275: // serial stamping
1276:
1277: /** a static that is used for attributing a unique id to each image. */
1278: static long serialId = 0;
1279:
1280: /** Creates a new serial id. */
1281: static protected synchronized Long getSerialId() {
1282: ++serialId;
1283: return new Long(serialId);
1284: }
1285:
1286: /**
1287: * Returns a serial id for the Image (reuse the same image more than once)
1288: *
1289: * @return a serialId
1290: */
1291: public Long getMySerialId() {
1292: return mySerialId;
1293: }
1294:
1295: // rotation, note that the superclass also has a rotation value.
1296:
1297: /** This is the rotation of the image in radians. */
1298: protected float rotationRadians;
1299:
1300: /** Holds value of property initialRotation. */
1301: private float initialRotation;
1302:
1303: /**
1304: * Gets the current image rotation in radians.
1305: * @return the current image rotation in radians
1306: */
1307: public float getImageRotation() {
1308: double d = 2.0 * Math.PI;
1309: float rot = (float) ((rotationRadians - initialRotation) % d);
1310: if (rot < 0) {
1311: rot += d;
1312: }
1313: return rot;
1314: }
1315:
1316: /**
1317: * Sets the rotation of the image in radians.
1318: *
1319: * @param r
1320: * rotation in radians
1321: */
1322: public void setRotation(float r) {
1323: double d = 2.0 * Math.PI;
1324: rotationRadians = (float) ((r + initialRotation) % d);
1325: if (rotationRadians < 0) {
1326: rotationRadians += d;
1327: }
1328: float[] matrix = matrix();
1329: scaledWidth = matrix[DX] - matrix[CX];
1330: scaledHeight = matrix[DY] - matrix[CY];
1331: }
1332:
1333: /**
1334: * Sets the rotation of the image in degrees.
1335: *
1336: * @param deg
1337: * rotation in degrees
1338: */
1339: public void setRotationDegrees(float deg) {
1340: double d = Math.PI;
1341: setRotation(deg / 180 * (float) d);
1342: }
1343:
1344: /**
1345: * Getter for property initialRotation.
1346: * @return Value of property initialRotation.
1347: */
1348: public float getInitialRotation() {
1349: return this .initialRotation;
1350: }
1351:
1352: /**
1353: * Some image formats, like TIFF may present the images rotated that have
1354: * to be compensated.
1355: * @param initialRotation New value of property initialRotation.
1356: */
1357: public void setInitialRotation(float initialRotation) {
1358: float old_rot = rotationRadians - this .initialRotation;
1359: this .initialRotation = initialRotation;
1360: setRotation(old_rot);
1361: }
1362:
1363: // indentations
1364:
1365: /** the indentation to the left. */
1366: protected float indentationLeft = 0;
1367:
1368: /** the indentation to the right. */
1369: protected float indentationRight = 0;
1370:
1371: /** The spacing before the image. */
1372: protected float spacingBefore;
1373:
1374: /** The spacing after the image. */
1375: protected float spacingAfter;
1376:
1377: /**
1378: * Gets the left indentation.
1379: *
1380: * @return the left indentation
1381: */
1382: public float getIndentationLeft() {
1383: return indentationLeft;
1384: }
1385:
1386: /**
1387: * Sets the left indentation.
1388: *
1389: * @param f
1390: */
1391: public void setIndentationLeft(float f) {
1392: indentationLeft = f;
1393: }
1394:
1395: /**
1396: * Gets the right indentation.
1397: *
1398: * @return the right indentation
1399: */
1400: public float getIndentationRight() {
1401: return indentationRight;
1402: }
1403:
1404: /**
1405: * Sets the right indentation.
1406: *
1407: * @param f
1408: */
1409: public void setIndentationRight(float f) {
1410: indentationRight = f;
1411: }
1412:
1413: /**
1414: * Gets the spacing before this image.
1415: *
1416: * @return the spacing
1417: */
1418: public float getSpacingBefore() {
1419: return spacingBefore;
1420: }
1421:
1422: /**
1423: * Sets the spacing before this image.
1424: *
1425: * @param spacing
1426: * the new spacing
1427: */
1428:
1429: public void setSpacingBefore(float spacing) {
1430: this .spacingBefore = spacing;
1431: }
1432:
1433: /**
1434: * Gets the spacing before this image.
1435: *
1436: * @return the spacing
1437: */
1438: public float getSpacingAfter() {
1439: return spacingAfter;
1440: }
1441:
1442: /**
1443: * Sets the spacing after this image.
1444: *
1445: * @param spacing
1446: * the new spacing
1447: */
1448:
1449: public void setSpacingAfter(float spacing) {
1450: this .spacingAfter = spacing;
1451: }
1452:
1453: // widthpercentage (for the moment only used in ColumnText)
1454:
1455: /**
1456: * Holds value of property widthPercentage.
1457: */
1458: private float widthPercentage = 100;
1459:
1460: /**
1461: * Getter for property widthPercentage.
1462: *
1463: * @return Value of property widthPercentage.
1464: */
1465: public float getWidthPercentage() {
1466: return this .widthPercentage;
1467: }
1468:
1469: /**
1470: * Setter for property widthPercentage.
1471: *
1472: * @param widthPercentage
1473: * New value of property widthPercentage.
1474: */
1475: public void setWidthPercentage(float widthPercentage) {
1476: this .widthPercentage = widthPercentage;
1477: }
1478:
1479: // annotation
1480:
1481: /** if the annotation is not null the image will be clickable. */
1482: protected Annotation annotation = null;
1483:
1484: /**
1485: * Sets the annotation of this Image.
1486: *
1487: * @param annotation
1488: * the annotation
1489: */
1490: public void setAnnotation(Annotation annotation) {
1491: this .annotation = annotation;
1492: }
1493:
1494: /**
1495: * Gets the annotation.
1496: *
1497: * @return the annotation that is linked to this image
1498: */
1499: public Annotation getAnnotation() {
1500: return annotation;
1501: }
1502:
1503: // Optional Content
1504:
1505: /** Optional Content layer to which we want this Image to belong. */
1506: protected PdfOCG layer;
1507:
1508: /**
1509: * Gets the layer this image belongs to.
1510: *
1511: * @return the layer this image belongs to or <code>null</code> for no
1512: * layer defined
1513: */
1514: public PdfOCG getLayer() {
1515: return layer;
1516: }
1517:
1518: /**
1519: * Sets the layer this image belongs to.
1520: *
1521: * @param layer
1522: * the layer this image belongs to
1523: */
1524: public void setLayer(PdfOCG layer) {
1525: this .layer = layer;
1526: }
1527:
1528: // interpolation
1529:
1530: /** Holds value of property interpolation. */
1531: protected boolean interpolation;
1532:
1533: /**
1534: * Getter for property interpolation.
1535: *
1536: * @return Value of property interpolation.
1537: */
1538: public boolean isInterpolation() {
1539: return interpolation;
1540: }
1541:
1542: /**
1543: * Sets the image interpolation. Image interpolation attempts to produce a
1544: * smooth transition between adjacent sample values.
1545: *
1546: * @param interpolation
1547: * New value of property interpolation.
1548: */
1549: public void setInterpolation(boolean interpolation) {
1550: this .interpolation = interpolation;
1551: }
1552:
1553: // original type and data
1554:
1555: /** Holds value of property originalType. */
1556: protected int originalType = ORIGINAL_NONE;
1557:
1558: /** Holds value of property originalData. */
1559: protected byte[] originalData;
1560:
1561: /**
1562: * Getter for property originalType.
1563: *
1564: * @return Value of property originalType.
1565: *
1566: */
1567: public int getOriginalType() {
1568: return this .originalType;
1569: }
1570:
1571: /**
1572: * Setter for property originalType.
1573: *
1574: * @param originalType
1575: * New value of property originalType.
1576: *
1577: */
1578: public void setOriginalType(int originalType) {
1579: this .originalType = originalType;
1580: }
1581:
1582: /**
1583: * Getter for property originalData.
1584: *
1585: * @return Value of property originalData.
1586: *
1587: */
1588: public byte[] getOriginalData() {
1589: return this .originalData;
1590: }
1591:
1592: /**
1593: * Setter for property originalData.
1594: *
1595: * @param originalData
1596: * New value of property originalData.
1597: *
1598: */
1599: public void setOriginalData(byte[] originalData) {
1600: this .originalData = originalData;
1601: }
1602:
1603: // the following values are only set for specific types of images.
1604:
1605: /** Holds value of property deflated. */
1606: protected boolean deflated = false;
1607:
1608: /**
1609: * Getter for property deflated.
1610: *
1611: * @return Value of property deflated.
1612: *
1613: */
1614: public boolean isDeflated() {
1615: return this .deflated;
1616: }
1617:
1618: /**
1619: * Setter for property deflated.
1620: *
1621: * @param deflated
1622: * New value of property deflated.
1623: */
1624: public void setDeflated(boolean deflated) {
1625: this .deflated = deflated;
1626: }
1627:
1628: // DPI info
1629:
1630: /** Holds value of property dpiX. */
1631: protected int dpiX = 0;
1632:
1633: /** Holds value of property dpiY. */
1634: protected int dpiY = 0;
1635:
1636: /**
1637: * Gets the dots-per-inch in the X direction. Returns 0 if not available.
1638: *
1639: * @return the dots-per-inch in the X direction
1640: */
1641: public int getDpiX() {
1642: return dpiX;
1643: }
1644:
1645: /**
1646: * Gets the dots-per-inch in the Y direction. Returns 0 if not available.
1647: *
1648: * @return the dots-per-inch in the Y direction
1649: */
1650: public int getDpiY() {
1651: return dpiY;
1652: }
1653:
1654: /**
1655: * Sets the dots per inch value
1656: *
1657: * @param dpiX
1658: * dpi for x coordinates
1659: * @param dpiY
1660: * dpi for y coordinates
1661: */
1662: public void setDpi(int dpiX, int dpiY) {
1663: this .dpiX = dpiX;
1664: this .dpiY = dpiY;
1665: }
1666:
1667: // XY Ratio
1668:
1669: /** Holds value of property XYRatio. */
1670: private float XYRatio = 0;
1671:
1672: /**
1673: * Gets the X/Y pixel dimensionless aspect ratio.
1674: *
1675: * @return the X/Y pixel dimensionless aspect ratio
1676: */
1677: public float getXYRatio() {
1678: return this .XYRatio;
1679: }
1680:
1681: /**
1682: * Sets the X/Y pixel dimensionless aspect ratio.
1683: *
1684: * @param XYRatio
1685: * the X/Y pixel dimensionless aspect ratio
1686: */
1687: public void setXYRatio(float XYRatio) {
1688: this .XYRatio = XYRatio;
1689: }
1690:
1691: // color, colorspaces and transparency
1692:
1693: /** this is the colorspace of a jpeg-image. */
1694: protected int colorspace = -1;
1695:
1696: /**
1697: * Gets the colorspace for the image.
1698: * <P>
1699: * Remark: this only makes sense for Images of the type <CODE>Jpeg</CODE>.
1700: *
1701: * @return a colorspace value
1702: */
1703: public int getColorspace() {
1704: return colorspace;
1705: }
1706:
1707: /** Image color inversion */
1708: protected boolean invert = false;
1709:
1710: /**
1711: * Getter for the inverted value
1712: *
1713: * @return true if the image is inverted
1714: */
1715: public boolean isInverted() {
1716: return invert;
1717: }
1718:
1719: /**
1720: * Sets inverted true or false
1721: *
1722: * @param invert
1723: * true or false
1724: */
1725: public void setInverted(boolean invert) {
1726: this .invert = invert;
1727: }
1728:
1729: /** ICC Profile attached */
1730: protected ICC_Profile profile = null;
1731:
1732: /**
1733: * Tags this image with an ICC profile.
1734: *
1735: * @param profile
1736: * the profile
1737: */
1738: public void tagICC(ICC_Profile profile) {
1739: this .profile = profile;
1740: }
1741:
1742: /**
1743: * Checks is the image has an ICC profile.
1744: *
1745: * @return the ICC profile or <CODE>null</CODE>
1746: */
1747: public boolean hasICCProfile() {
1748: return (this .profile != null);
1749: }
1750:
1751: /**
1752: * Gets the images ICC profile.
1753: *
1754: * @return the ICC profile
1755: */
1756: public ICC_Profile getICCProfile() {
1757: return profile;
1758: }
1759:
1760: /** a dictionary with additional information */
1761: private PdfDictionary additional = null;
1762:
1763: /**
1764: * Getter for the dictionary with additional information.
1765: *
1766: * @return a PdfDictionary with additional information.
1767: */
1768: public PdfDictionary getAdditional() {
1769: return this .additional;
1770: }
1771:
1772: /**
1773: * Sets the /Colorspace key.
1774: *
1775: * @param additional
1776: * a PdfDictionary with additional information.
1777: */
1778: public void setAdditional(PdfDictionary additional) {
1779: this .additional = additional;
1780: }
1781:
1782: /**
1783: * Replaces CalRGB and CalGray colorspaces with DeviceRGB and DeviceGray.
1784: */
1785: public void simplifyColorspace() {
1786: if (additional == null)
1787: return;
1788: PdfObject value = additional.get(PdfName.COLORSPACE);
1789: if (value == null || !value.isArray())
1790: return;
1791: PdfObject cs = simplifyColorspace(value);
1792: if (cs.isName())
1793: value = cs;
1794: else {
1795: PdfObject first = (PdfObject) (((PdfArray) value)
1796: .getArrayList().get(0));
1797: if (PdfName.INDEXED.equals(first)) {
1798: ArrayList array = ((PdfArray) value).getArrayList();
1799: if (array.size() >= 2
1800: && ((PdfObject) array.get(1)).isArray()) {
1801: array.set(1, simplifyColorspace((PdfObject) array
1802: .get(1)));
1803: }
1804: }
1805: }
1806: additional.put(PdfName.COLORSPACE, value);
1807: }
1808:
1809: /**
1810: * Gets a PDF Name from an array or returns the object that was passed.
1811: */
1812: private PdfObject simplifyColorspace(PdfObject obj) {
1813: if (obj == null || !obj.isArray())
1814: return obj;
1815: PdfObject first = (PdfObject) (((PdfArray) obj).getArrayList()
1816: .get(0));
1817: if (PdfName.CALGRAY.equals(first))
1818: return PdfName.DEVICEGRAY;
1819: else if (PdfName.CALRGB.equals(first))
1820: return PdfName.DEVICERGB;
1821: else
1822: return obj;
1823: }
1824:
1825: /** Is this image a mask? */
1826: protected boolean mask = false;
1827:
1828: /** The image that serves as a mask for this image. */
1829: protected Image imageMask;
1830:
1831: /** Holds value of property smask. */
1832: private boolean smask;
1833:
1834: /**
1835: * Returns <CODE>true</CODE> if this <CODE>Image</CODE> is a mask.
1836: *
1837: * @return <CODE>true</CODE> if this <CODE>Image</CODE> is a mask
1838: */
1839: public boolean isMask() {
1840: return mask;
1841: }
1842:
1843: /**
1844: * Make this <CODE>Image</CODE> a mask.
1845: *
1846: * @throws DocumentException
1847: * if this <CODE>Image</CODE> can not be a mask
1848: */
1849: public void makeMask() throws DocumentException {
1850: if (!isMaskCandidate())
1851: throw new DocumentException(
1852: "This image can not be an image mask.");
1853: mask = true;
1854: }
1855:
1856: /**
1857: * Returns <CODE>true</CODE> if this <CODE>Image</CODE> has the
1858: * requisites to be a mask.
1859: *
1860: * @return <CODE>true</CODE> if this <CODE>Image</CODE> can be a mask
1861: */
1862: public boolean isMaskCandidate() {
1863: if (type == IMGRAW) {
1864: if (bpc > 0xff)
1865: return true;
1866: }
1867: return colorspace == 1;
1868: }
1869:
1870: /**
1871: * Gets the explicit masking.
1872: *
1873: * @return the explicit masking
1874: */
1875: public Image getImageMask() {
1876: return imageMask;
1877: }
1878:
1879: /**
1880: * Sets the explicit masking.
1881: *
1882: * @param mask
1883: * the mask to be applied
1884: * @throws DocumentException
1885: * on error
1886: */
1887: public void setImageMask(Image mask) throws DocumentException {
1888: if (this .mask)
1889: throw new DocumentException(
1890: "An image mask cannot contain another image mask.");
1891: if (!mask.mask)
1892: throw new DocumentException(
1893: "The image mask is not a mask. Did you do makeMask()?");
1894: imageMask = mask;
1895: smask = (mask.bpc > 1 && mask.bpc <= 8);
1896: }
1897:
1898: /**
1899: * Getter for property smask.
1900: *
1901: * @return Value of property smask.
1902: *
1903: */
1904: public boolean isSmask() {
1905: return this .smask;
1906: }
1907:
1908: /**
1909: * Setter for property smask.
1910: *
1911: * @param smask
1912: * New value of property smask.
1913: */
1914: public void setSmask(boolean smask) {
1915: this .smask = smask;
1916: }
1917:
1918: /** this is the transparency information of the raw image */
1919: protected int transparency[];
1920:
1921: /**
1922: * Returns the transparency.
1923: *
1924: * @return the transparency values
1925: */
1926:
1927: public int[] getTransparency() {
1928: return transparency;
1929: }
1930:
1931: /**
1932: * Sets the transparency values
1933: *
1934: * @param transparency
1935: * the transparency values
1936: */
1937: public void setTransparency(int transparency[]) {
1938: this .transparency = transparency;
1939: }
1940:
1941: // deprecated stuff
1942:
1943: /**
1944: * Gets the <CODE>String</CODE> -representation of the reference to the
1945: * image.
1946: *
1947: * @return a <CODE>String</CODE>
1948: * @deprecated Use {@link #getUrl()} instead
1949: */
1950:
1951: public URL url() {
1952: return getUrl();
1953: }
1954:
1955: /**
1956: * Gets the template to be used as an image.
1957: * <P>
1958: * Remark: this only makes sense for Images of the type <CODE>ImgTemplate
1959: * </CODE>.
1960: *
1961: * @return the template
1962: * @deprecated Use {@link #getTemplateData()} instead
1963: */
1964: public PdfTemplate templateData() {
1965: return getTemplateData();
1966: }
1967:
1968: /**
1969: * Returns an <CODE>Image</CODE> that has been constructed taking in
1970: * account the value of some <VAR>attributes </VAR>.
1971: *
1972: * @param attributes
1973: * Some attributes
1974: * @return an <CODE>Image</CODE>
1975: * @throws BadElementException
1976: * @throws MalformedURLException
1977: * @throws IOException
1978: * @deprecated use ElementFactory.getImage(attributes)
1979: */
1980: public static Image getInstance(java.util.Properties attributes)
1981: throws BadElementException, MalformedURLException,
1982: IOException {
1983: return com.lowagie.text.factories.ElementFactory
1984: .getImage(attributes);
1985: }
1986:
1987: /**
1988: * Gets the left indentation.
1989: *
1990: * @return the left indentation
1991: * @deprecated Use {@link #getIndentationLeft()} instead
1992: */
1993: public float indentationLeft() {
1994: return getIndentationLeft();
1995: }
1996:
1997: /**
1998: * Gets the right indentation.
1999: *
2000: * @return the right indentation
2001: * @deprecated Use {@link #getIndentationRight()} instead
2002: */
2003: public float indentationRight() {
2004: return getIndentationRight();
2005: }
2006:
2007: /**
2008: * Gets the spacing before this image.
2009: *
2010: * @return the spacing
2011: * @deprecated Use {@link #getSpacingBefore()} instead
2012: */
2013: public float spacingBefore() {
2014: return getSpacingBefore();
2015: }
2016:
2017: /**
2018: * Gets the spacing before this image.
2019: *
2020: * @return the spacing
2021: * @deprecated Use {@link #getSpacingAfter()} instead
2022: */
2023: public float spacingAfter() {
2024: return getSpacingAfter();
2025: }
2026:
2027: /**
2028: * Gets the raw data for the image.
2029: * <P>
2030: * Remark: this only makes sense for Images of the type <CODE>RawImage
2031: * </CODE>.
2032: *
2033: * @return the raw data
2034: * @deprecated Use {@link #getRawData()} instead
2035: */
2036: public byte[] rawData() {
2037: return getRawData();
2038: }
2039:
2040: /**
2041: * Gets the bpc for the image.
2042: * <P>
2043: * Remark: this only makes sense for Images of the type <CODE>RawImage
2044: * </CODE>.
2045: *
2046: * @return a bpc value
2047: * @deprecated Use {@link #getBpc()} instead
2048: */
2049: public int bpc() {
2050: return getBpc();
2051: }
2052:
2053: /**
2054: * Gets the annotation.
2055: *
2056: * @return the annotation that is linked to this image
2057: * @deprecated Use {@link #getAnnotation()} instead
2058: */
2059: public Annotation annotation() {
2060: return getAnnotation();
2061: }
2062:
2063: /**
2064: * Checks if the <CODE>Images</CODE> has to be added at an absolute
2065: * position.
2066: *
2067: * @return a boolean
2068: * @deprecated Use {@link #hasAbsoluteY()} instead
2069: */
2070: public boolean hasAbsolutePosition() {
2071: return hasAbsoluteY();
2072: }
2073:
2074: /**
2075: * Returns the absolute X position.
2076: *
2077: * @return a position
2078: * @deprecated Use {@link #getAbsoluteX()} instead
2079: */
2080: public float absoluteX() {
2081: return getAbsoluteX();
2082: }
2083:
2084: /**
2085: * Returns the absolute Y position.
2086: *
2087: * @return a position
2088: * @deprecated Use {@link #getAbsoluteY()} instead
2089: */
2090: public float absoluteY() {
2091: return getAbsoluteY();
2092: }
2093:
2094: /**
2095: * Gets the plain width of the image.
2096: *
2097: * @return a value
2098: * @deprecated Use {@link #getPlainWidth()} instead
2099: */
2100: public float plainWidth() {
2101: return getPlainWidth();
2102: }
2103:
2104: /**
2105: * Gets the plain height of the image.
2106: *
2107: * @return a value
2108: * @deprecated Use {@link #getPlainHeight()} instead
2109: */
2110: public float plainHeight() {
2111: return getPlainHeight();
2112: }
2113:
2114: /**
2115: * Gets the scaled height of the image.
2116: *
2117: * @return a value
2118: * @deprecated Use {@link #getScaledWidth()} instead
2119: */
2120: public float scaledWidth() {
2121: return getScaledWidth();
2122: }
2123:
2124: /**
2125: * Gets the scaled height of the image.
2126: *
2127: * @return a value
2128: * @deprecated Use {@link #getScaledHeight()} instead
2129: */
2130: public float scaledHeight() {
2131: return getScaledHeight();
2132: }
2133:
2134: /**
2135: * Gets the alignment for the image.
2136: *
2137: * @return a value
2138: * @deprecated Use {@link #getAlignment()} instead
2139: */
2140: public int alignment() {
2141: return getAlignment();
2142: }
2143:
2144: /**
2145: * Gets the alternative text for the image.
2146: *
2147: * @return a <CODE>String</CODE>
2148: * @deprecated Use {@link #getAlt()} instead
2149: */
2150:
2151: public String alt() {
2152: return getAlt();
2153: }
2154:
2155: /**
2156: * Gets the colorspace for the image.
2157: * <P>
2158: * Remark: this only makes sense for Images of the type <CODE>Jpeg</CODE>.
2159: *
2160: * @return a colorspace value
2161: * @deprecated Use {@link #getColorspace()} instead
2162: */
2163: public int colorspace() {
2164: return getColorspace();
2165: }
2166:
2167: /**
2168: * Inverts the meaning of the bits of a mask.
2169: *
2170: * @param invert
2171: * <CODE>true</CODE> to invert the meaning of the bits of a
2172: * mask
2173: * @deprecated use setInverted
2174: */
2175: public void setInvertMask(boolean invert) {
2176: setInverted(invert);
2177: }
2178:
2179: /**
2180: * Returns <CODE>true</CODE> if the bits are to be inverted in the mask.
2181: *
2182: * @return <CODE>true</CODE> if the bits are to be inverted in the mask
2183: * @deprecated use isInvert()
2184: */
2185: public boolean isInvertMask() {
2186: return isInverted();
2187: }
2188: }
|