001: /*
002: * $RCSfile: JPEGTileDecoder.java,v $
003: *
004: * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved.
005: *
006: * Use is subject to license terms.
007: *
008: * $Revision: 1.1 $
009: * $Date: 2005/02/11 04:56:57 $
010: * $State: Exp $
011: */package com.sun.media.jai.tilecodec;
012:
013: import java.awt.Point;
014: import java.awt.RenderingHints;
015: import java.awt.image.Raster;
016: import java.awt.image.WritableRaster;
017: import java.awt.image.SampleModel;
018: import java.io.InputStream;
019: import java.io.ObjectInputStream;
020: import java.io.ByteArrayInputStream;
021: import java.io.IOException;
022: import javax.media.jai.JAI;
023: import javax.media.jai.ParameterListDescriptor;
024: import javax.media.jai.RasterFactory;
025: import javax.media.jai.tilecodec.TileCodecDescriptor;
026: import javax.media.jai.tilecodec.TileCodecParameterList;
027: import javax.media.jai.tilecodec.TileDecoderImpl;
028: import javax.media.jai.util.ImagingListener;
029: import com.sun.image.codec.jpeg.JPEGDecodeParam;
030: import com.sun.image.codec.jpeg.JPEGImageDecoder;
031: import com.sun.image.codec.jpeg.JPEGCodec;
032: import com.sun.image.codec.jpeg.JPEGQTable;
033: import sun.awt.image.codec.JPEGParam;
034: import com.sun.media.jai.util.ImageUtil;
035:
036: /**
037: * A concrete implementation of the <code>TileDecoderImpl</code> class
038: * for the jpeg tile codec.
039: */
040: public class JPEGTileDecoder extends TileDecoderImpl {
041: /* The associated TileCodecDescriptor */
042: private TileCodecDescriptor tcd = null;
043:
044: /**
045: * Constructs a <code>JPEGTileDecoder</code>.
046: * <code>JPEGTileDecoder</code> may throw a
047: * <code>IllegalArgumentException</code> if <code>param</code>'s
048: * <code>getParameterListDescriptor()</code> method does not return
049: * the same descriptor as that from the associated
050: * <code>TileCodecDescriptor</code>'s
051: * <code>getParameterListDescriptor</code> method for the "tileDecoder"
052: * registry mode.
053: *
054: * <p> If param is null, then the default parameter list for decoding
055: * as defined by the associated <code>TileCodecDescriptor</code>'s
056: * <code>getDefaultParameters()</code> method will be used for decoding.
057: *
058: * @param input The <code>InputStream</code> to decode data from.
059: * @param param The object containing the tile decoding parameters.
060: * @throws IllegalArgumentException if input is null.
061: * @throws IllegalArgumentException if param is not appropriate.
062: */
063: public JPEGTileDecoder(InputStream input,
064: TileCodecParameterList param) {
065: super ("jpeg", input, param);
066: tcd = TileCodecUtils.getTileCodecDescriptor("tileDecoder",
067: "jpeg");
068: }
069:
070: /**
071: * Returns a <code>Raster</code> that contains the decoded contents
072: * of the <code>InputStream</code> associated with this
073: * <code>TileDecoder</code>.
074: *
075: * <p>This method can perform the decoding correctly only when
076: * <code>includesLocationInfoInfo()</code> returns true.
077: *
078: * @throws IOException if an I/O error occurs while reading from the
079: * associated InputStream.
080: * @throws IllegalArgumentException if the associated
081: * TileCodecDescriptor's includesLocationInfoInfo() returns false.
082: */
083: public Raster decode() throws IOException {
084: if (!tcd.includesLocationInfo())
085: throw new IllegalArgumentException(JaiI18N
086: .getString("JPEGTileDecoder0"));
087: return decode(null);
088: }
089:
090: public Raster decode(Point location) throws IOException {
091: SampleModel sm = null;
092: byte[] data = null;
093:
094: ObjectInputStream ois = new ObjectInputStream(inputStream);
095:
096: try {
097: // read the quality and qualitySet from the stream
098: paramList.setParameter("quality", ois.readFloat());
099: paramList.setParameter("qualitySet", ois.readBoolean());
100: sm = TileCodecUtils
101: .deserializeSampleModel(ois.readObject());
102: location = (Point) ois.readObject();
103: data = (byte[]) ois.readObject();
104: } catch (ClassNotFoundException e) {
105: ImagingListener listener = ImageUtil
106: .getImagingListener((RenderingHints) null);
107: listener.errorOccurred(JaiI18N.getString("ClassNotFound"),
108: e, this , false);
109: // e.printStackTrace();
110: return null;
111: } finally {
112: ois.close();
113: }
114:
115: ByteArrayInputStream bais = new ByteArrayInputStream(data);
116: JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(bais);
117:
118: Raster ras = decoder.decodeAsRaster().createTranslatedChild(
119: location.x, location.y);
120: extractParameters(decoder.getJPEGDecodeParam(), ras
121: .getSampleModel().getNumBands());
122:
123: // set the original sample model to the decoded raster
124: if (sm != null) {
125: int minX = ras.getMinX();
126: int minY = ras.getMinY();
127: int h = ras.getHeight();
128: int w = ras.getWidth();
129: double[] buf = ras.getPixels(minX, minY, w, h,
130: (double[]) null);
131: ras = RasterFactory.createWritableRaster(sm, new Point(
132: minX, minY));
133: ((WritableRaster) ras).setPixels(minX, minY, w, h, buf);
134: }
135: return ras;
136: }
137:
138: private void extractParameters(JPEGDecodeParam jdp, int bandNum) {
139:
140: // extract the horizontal subsampling rates
141: int[] horizontalSubsampling = new int[bandNum];
142: for (int i = 0; i < bandNum; i++)
143: horizontalSubsampling[i] = jdp.getHorizontalSubsampling(i);
144: paramList.setParameter("horizontalSubsampling",
145: horizontalSubsampling);
146:
147: // extract the vertical subsampling rates
148: int[] verticalSubsampling = new int[bandNum];
149: for (int i = 0; i < bandNum; i++)
150: verticalSubsampling[i] = jdp.getVerticalSubsampling(i);
151: paramList.setParameter("verticalSubsampling",
152: verticalSubsampling);
153:
154: // if the quality is not set, extract the quantization tables from
155: // the stream; otherwise, define them with the default values.
156: if (!paramList.getBooleanParameter("qualitySet"))
157: for (int i = 0; i < 4; i++) {
158: JPEGQTable table = jdp.getQTable(i);
159: paramList.setParameter("quantizationTable" + i,
160: (table == null) ? null : table.getTable());
161: }
162: else {
163: ParameterListDescriptor pld = paramList
164: .getParameterListDescriptor();
165: for (int i = 0; i < 4; i++) {
166: paramList.setParameter("quantizationTable" + i, pld
167: .getParamDefaultValue("quantizationTable" + i));
168: }
169: }
170:
171: // extract the quantizationTableMapping
172: int[] quanTableMapping = new int[bandNum];
173: for (int i = 0; i < bandNum; i++)
174: quanTableMapping[i] = jdp.getQTableComponentMapping(i);
175: paramList.setParameter("quantizationTableMapping",
176: quanTableMapping);
177:
178: // extract the writeTableInfo and writeImageInfo
179: paramList
180: .setParameter("writeTableInfo", jdp.isTableInfoValid());
181: paramList
182: .setParameter("writeImageInfo", jdp.isImageInfoValid());
183:
184: // extract the restart interval
185: paramList.setParameter("restartInterval", jdp
186: .getRestartInterval());
187:
188: // define writeJFIFHeader by examing the APP0_MARKER is set or not
189: paramList.setParameter("writeJFIFHeader", jdp
190: .getMarker(JPEGDecodeParam.APP0_MARKER));
191: }
192: }
|