001: /*
002:
003: Licensed to the Apache Software Foundation (ASF) under one or more
004: contributor license agreements. See the NOTICE file distributed with
005: this work for additional information regarding copyright ownership.
006: The ASF licenses this file to You under the Apache License, Version 2.0
007: (the "License"); you may not use this file except in compliance with
008: the License. You may obtain a copy of the License at
009:
010: http://www.apache.org/licenses/LICENSE-2.0
011:
012: Unless required by applicable law or agreed to in writing, software
013: distributed under the License is distributed on an "AS IS" BASIS,
014: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015: See the License for the specific language governing permissions and
016: limitations under the License.
017:
018: */
019: package org.apache.batik.ext.awt.image.codec.imageio;
020:
021: import java.awt.geom.Rectangle2D;
022: import java.awt.image.BufferedImage;
023: import java.awt.image.ColorModel;
024: import java.awt.image.WritableRaster;
025: import java.io.IOException;
026: import java.io.InputStream;
027: import java.util.Iterator;
028:
029: import javax.imageio.ImageIO;
030: import javax.imageio.ImageReader;
031: import javax.imageio.stream.ImageInputStream;
032:
033: import org.apache.batik.ext.awt.image.GraphicsUtil;
034: import org.apache.batik.ext.awt.image.renderable.DeferRable;
035: import org.apache.batik.ext.awt.image.renderable.Filter;
036: import org.apache.batik.ext.awt.image.renderable.RedRable;
037: import org.apache.batik.ext.awt.image.rendered.Any2sRGBRed;
038: import org.apache.batik.ext.awt.image.rendered.FormatRed;
039: import org.apache.batik.ext.awt.image.rendered.CachableRed;
040: import org.apache.batik.ext.awt.image.spi.ImageTagRegistry;
041: import org.apache.batik.ext.awt.image.spi.MagicNumberRegistryEntry;
042: import org.apache.batik.util.ParsedURL;
043:
044: /**
045: * This is the base class for all ImageIO-based RegistryEntry implementations. They
046: * have a slightly lower priority than the RegistryEntry implementations using the
047: * internal codecs, so these take precedence if they are available.
048: *
049: * @version $Id: AbstractImageIORegistryEntry.java 502538 2007-02-02 08:52:56Z dvholten $
050: */
051: public abstract class AbstractImageIORegistryEntry extends
052: MagicNumberRegistryEntry {
053:
054: /**
055: * Constructor
056: * @param name Format Name
057: * @param exts Standard set of extensions
058: * @param magicNumbers array of magic numbers any of which can match.
059: */
060: public AbstractImageIORegistryEntry(String name, String[] exts,
061: String[] mimeTypes, MagicNumber[] magicNumbers) {
062: super (name, PRIORITY + 100, exts, mimeTypes, magicNumbers);
063: }
064:
065: /**
066: * Constructor, simplifies construction of entry when only
067: * one extension and one magic number is required.
068: * @param name Format Name
069: * @param ext Standard extension
070: * @param offset Offset of magic number
071: * @param magicNumber byte array to match.
072: */
073: public AbstractImageIORegistryEntry(String name, String ext,
074: String mimeType, int offset, byte[] magicNumber) {
075: super (name, PRIORITY + 100, ext, mimeType, offset, magicNumber);
076: }
077:
078: /**
079: * Decode the Stream into a RenderableImage
080: *
081: * @param inIS The input stream that contains the image.
082: * @param origURL The original URL, if any, for documentation
083: * purposes only. This may be null.
084: * @param needRawData If true the image returned should not have
085: * any default color correction the file may
086: * specify applied.
087: */
088: public Filter handleStream(InputStream inIS, ParsedURL origURL,
089: boolean needRawData) {
090: final DeferRable dr = new DeferRable();
091: final InputStream is = inIS;
092: final String errCode;
093: final Object[] errParam;
094: if (origURL != null) {
095: errCode = ERR_URL_FORMAT_UNREADABLE;
096: errParam = new Object[] { getFormatName(), origURL };
097: } else {
098: errCode = ERR_STREAM_FORMAT_UNREADABLE;
099: errParam = new Object[] { getFormatName() };
100: }
101:
102: Thread t = new Thread() {
103: public void run() {
104: Filter filt;
105: try {
106: Iterator iter = ImageIO
107: .getImageReadersByMIMEType(getMimeTypes()
108: .get(0).toString());
109: if (!iter.hasNext()) {
110: throw new UnsupportedOperationException(
111: "No image reader for "
112: + getFormatName()
113: + " available!");
114: }
115: ImageReader reader = (ImageReader) iter.next();
116: ImageInputStream imageIn = ImageIO
117: .createImageInputStream(is);
118: reader.setInput(imageIn, true);
119:
120: int imageIndex = 0;
121: dr.setBounds(new Rectangle2D.Double(0, 0, reader
122: .getWidth(imageIndex), reader
123: .getHeight(imageIndex)));
124: CachableRed cr;
125: //Naïve approach probably wasting lots of memory
126: //and ignoring the gamma correction done by PNGRed :-(
127: BufferedImage bi = reader.read(imageIndex);
128: cr = GraphicsUtil.wrap(bi);
129: cr = new Any2sRGBRed(cr);
130: cr = new FormatRed(cr, GraphicsUtil.sRGB_Unpre);
131: WritableRaster wr = (WritableRaster) cr.getData();
132: ColorModel cm = cr.getColorModel();
133: BufferedImage image = new BufferedImage(cm, wr, cm
134: .isAlphaPremultiplied(), null);
135: cr = GraphicsUtil.wrap(image);
136: filt = new RedRable(cr);
137: } catch (IOException ioe) {
138: // Something bad happened here...
139: filt = ImageTagRegistry.getBrokenLinkImage(
140: AbstractImageIORegistryEntry.this , errCode,
141: errParam);
142: } catch (ThreadDeath td) {
143: filt = ImageTagRegistry.getBrokenLinkImage(
144: AbstractImageIORegistryEntry.this , errCode,
145: errParam);
146: dr.setSource(filt);
147: throw td;
148: } catch (Throwable t) {
149: filt = ImageTagRegistry.getBrokenLinkImage(
150: AbstractImageIORegistryEntry.this, errCode,
151: errParam);
152: }
153:
154: dr.setSource(filt);
155: }
156: };
157: t.start();
158: return dr;
159: }
160:
161: }
|