001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017:
018: /* $Id: GifImage.java 426576 2006-07-28 15:44:37Z jeremias $ */
019:
020: package org.apache.fop.image;
021:
022: // Java
023: import java.awt.image.ImageProducer;
024: import java.awt.image.ColorModel;
025: import java.awt.image.IndexColorModel;
026: import java.awt.color.ColorSpace;
027: import java.awt.Color;
028: import java.io.InputStream;
029: import java.io.IOException;
030: import java.net.URLConnection;
031:
032: import org.apache.commons.io.IOUtils;
033:
034: /**
035: * FopImage object for GIF images, using Java native classes.
036: * @author Eric SCHAEFFER
037: * @author Modified by Eric Dalquist - 9/14/2001 - ebdalqui@mtu.edu
038: * @see AbstractFopImage
039: * @see FopImage
040: */
041: public class GifImage extends AbstractFopImage {
042:
043: /**
044: * Create a new gif image.
045: *
046: * @param imgInfo the image info for this gif image
047: */
048: public GifImage(FopImage.ImageInfo imgInfo) {
049: super (imgInfo);
050: }
051:
052: /**
053: * Load the bitmap for this gif image.
054: * This loads the data and creates a bitmap byte array
055: * of the image data.
056: * To decode the image a dummy URLConnection is used that
057: * will do the conversion.
058: *
059: * @return True if the load process succeeded
060: */
061: protected boolean loadBitmap() {
062: int[] tmpMap = null;
063: try {
064: URLConnection con = new DummyConnection(inputStream);
065:
066: ImageProducer ip = (ImageProducer) con.getContent();
067: if (ip == null) {
068: return false;
069: }
070: FopImageConsumer consumer = new FopImageConsumer(ip);
071: ip.startProduction(consumer);
072:
073: //Load the image into memory
074: while (!consumer.isImageReady()) {
075: Thread.sleep(500);
076: }
077:
078: this .height = consumer.getHeight();
079: this .width = consumer.getWidth();
080:
081: try {
082: tmpMap = consumer.getImage();
083: } catch (Exception ex) {
084: log.error("Image grabbing interrupted : "
085: + ex.getMessage(), ex);
086: return false;
087: }
088:
089: ColorModel cm = consumer.getColorModel();
090: this .bitsPerPixel = 8;
091: // this.bitsPerPixel = cm.getPixelSize();
092: this .colorSpace = ColorSpace
093: .getInstance(ColorSpace.CS_LINEAR_RGB);
094: if (cm.hasAlpha()) {
095: // java.awt.Transparency. BITMASK or OPAQUE or TRANSLUCENT
096: int transparencyType = cm.getTransparency();
097:
098: if (transparencyType == java.awt.Transparency.OPAQUE) {
099: this .isTransparent = false;
100: } else if (transparencyType == java.awt.Transparency.BITMASK) {
101: if (cm instanceof IndexColorModel) {
102: IndexColorModel indexcm = (IndexColorModel) cm;
103: this .isTransparent = false;
104: byte[] alphas = new byte[indexcm.getMapSize()];
105: byte[] reds = new byte[indexcm.getMapSize()];
106: byte[] greens = new byte[indexcm.getMapSize()];
107: byte[] blues = new byte[indexcm.getMapSize()];
108: indexcm.getAlphas(alphas);
109: indexcm.getReds(reds);
110: indexcm.getGreens(greens);
111: indexcm.getBlues(blues);
112: for (int i = 0; i < indexcm.getMapSize(); i++) {
113: if ((alphas[i] & 0xFF) == 0) {
114: this .isTransparent = true;
115: this .transparentColor = new Color(
116: (int) (reds[i] & 0xFF),
117: (int) (greens[i] & 0xFF),
118: (int) (blues[i] & 0xFF));
119: break;
120: }
121: }
122: } else {
123: // TRANSLUCENT
124: /*
125: * this.isTransparent = false;
126: * for (int i = 0; i < this.width * this.height; i++) {
127: * if (cm.getAlpha(tmpMap[i]) == 0) {
128: * this.isTransparent = true;
129: * this.transparentColor = new PDFColor(cm.getRed(tmpMap[i]),
130: * cm.getGreen(tmpMap[i]), cm.getBlue(tmpMap[i]));
131: * break;
132: * }
133: * }
134: */
135: // use special API...
136: this .isTransparent = false;
137: }
138: } else {
139: this .isTransparent = false;
140: }
141: } else {
142: this .isTransparent = false;
143: }
144: } catch (Exception ex) {
145: log.error("Error while loading image (Gif): "
146: + ex.getMessage(), ex);
147: return false;
148: } finally {
149: IOUtils.closeQuietly(inputStream);
150: inputStream = null;
151: }
152:
153: // Should take care of the ColorSpace and bitsPerPixel
154: this .bitmaps = new byte[this .width * this .height * 3];
155: for (int i = 0; i < this .height; i++) {
156: for (int j = 0; j < this .width; j++) {
157: int p = tmpMap[i * this .width + j];
158: int r = (p >> 16) & 0xFF;
159: int g = (p >> 8) & 0xFF;
160: int b = (p) & 0xFF;
161: this .bitmaps[3 * (i * this .width + j)] = (byte) (r & 0xFF);
162: this .bitmaps[3 * (i * this .width + j) + 1] = (byte) (g & 0xFF);
163: this .bitmaps[3 * (i * this .width + j) + 2] = (byte) (b & 0xFF);
164: }
165: }
166: return true;
167: }
168:
169: /** @see org.apache.fop.image.AbstractFopImage#loadOriginalData() */
170: protected boolean loadOriginalData() {
171: return loadDefaultOriginalData();
172: }
173:
174: /**
175: * A dummy url connection for a gif image in an input stream.
176: */
177: protected static class DummyConnection extends URLConnection {
178: private InputStream inputStream;
179:
180: DummyConnection(InputStream is) {
181: super (null);
182: inputStream = is;
183: }
184:
185: /**
186: * @see java.net.URLConnection#getInputStream()
187: */
188: public InputStream getInputStream() throws IOException {
189: return inputStream;
190: }
191:
192: /**
193: * @see java.net.URLConnection#connect()
194: */
195: public void connect() throws IOException {
196: // do nothing
197: }
198:
199: /**
200: * @see java.net.URLConnection#getContentType()
201: */
202: public String getContentType() {
203: return "image/gif";
204: }
205:
206: /**
207: * @see java.net.URLConnection#getContentLength()
208: */
209: public int getContentLength() {
210: try {
211: return inputStream.available();
212: } catch (IOException e) {
213: return -1;
214: }
215: }
216:
217: }
218: }
|