1 /* 2 * $RCSfile: JPEGTileDecoder.java,v $ 3 * 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Use is subject to license terms. 7 * 8 * $Revision: 1.1 $ 9 * $Date: 2005/02/11 04:56:57 $ 10 * $State: Exp $ 11 */package com.lightcrafts.media.jai.tilecodec; 12 13 import java.awt.Point; 14 import java.awt.RenderingHints; 15 import java.awt.image.Raster; 16 import java.awt.image.WritableRaster; 17 import java.awt.image.SampleModel; 18 import java.io.InputStream; 19 import java.io.ObjectInputStream; 20 import java.io.ByteArrayInputStream; 21 import java.io.IOException; 22 import com.lightcrafts.mediax.jai.ParameterListDescriptor; 23 import com.lightcrafts.mediax.jai.RasterFactory; 24 import com.lightcrafts.mediax.jai.tilecodec.TileCodecDescriptor; 25 import com.lightcrafts.mediax.jai.tilecodec.TileCodecParameterList; 26 import com.lightcrafts.mediax.jai.tilecodec.TileDecoderImpl; 27 import com.lightcrafts.mediax.jai.util.ImagingListener; 28 import com.sun.image.codec.jpeg.JPEGDecodeParam; 29 import com.sun.image.codec.jpeg.JPEGImageDecoder; 30 import com.sun.image.codec.jpeg.JPEGCodec; 31 import com.sun.image.codec.jpeg.JPEGQTable; 32 import com.lightcrafts.media.jai.util.ImageUtil; 33 /** 34 * A concrete implementation of the <code>TileDecoderImpl</code> class 35 * for the jpeg tile codec. 36 */ 37 public class JPEGTileDecoder extends TileDecoderImpl { 38 /* The associated TileCodecDescriptor */ 39 private TileCodecDescriptor tcd = null; 40 41 /** 42 * Constructs a <code>JPEGTileDecoder</code>. 43 * <code>JPEGTileDecoder</code> may throw a 44 * <code>IllegalArgumentException</code> if <code>param</code>'s 45 * <code>getParameterListDescriptor()</code> method does not return 46 * the same descriptor as that from the associated 47 * <code>TileCodecDescriptor</code>'s 48 * <code>getParameterListDescriptor</code> method for the "tileDecoder" 49 * registry mode. 50 * 51 * <p> If param is null, then the default parameter list for decoding 52 * as defined by the associated <code>TileCodecDescriptor</code>'s 53 * <code>getDefaultParameters()</code> method will be used for decoding. 54 * 55 * @param input The <code>InputStream</code> to decode data from. 56 * @param param The object containing the tile decoding parameters. 57 * @throws IllegalArgumentException if input is null. 58 * @throws IllegalArgumentException if param is not appropriate. 59 */ JPEGTileDecoder(InputStream input, TileCodecParameterList param)60 public JPEGTileDecoder(InputStream input, TileCodecParameterList param) { 61 super("jpeg", input, param); 62 tcd = TileCodecUtils.getTileCodecDescriptor("tileDecoder", "jpeg"); 63 } 64 65 /** 66 * Returns a <code>Raster</code> that contains the decoded contents 67 * of the <code>InputStream</code> associated with this 68 * <code>TileDecoder</code>. 69 * 70 * <p>This method can perform the decoding correctly only when 71 * <code>includesLocationInfoInfo()</code> returns true. 72 * 73 * @throws IOException if an I/O error occurs while reading from the 74 * associated InputStream. 75 * @throws IllegalArgumentException if the associated 76 * TileCodecDescriptor's includesLocationInfoInfo() returns false. 77 */ decode()78 public Raster decode() throws IOException{ 79 if (!tcd.includesLocationInfo()) 80 throw new IllegalArgumentException( 81 JaiI18N.getString("JPEGTileDecoder0") ); 82 return decode(null); 83 } 84 decode(Point location)85 public Raster decode(Point location) throws IOException{ 86 SampleModel sm = null; 87 byte[] data = null; 88 89 ObjectInputStream ois = new ObjectInputStream(inputStream); 90 91 try { 92 // read the quality and qualitySet from the stream 93 paramList.setParameter("quality", ois.readFloat()); 94 paramList.setParameter("qualitySet", ois.readBoolean()); 95 sm = TileCodecUtils.deserializeSampleModel(ois.readObject()); 96 location = (Point)ois.readObject(); 97 data = (byte[]) ois.readObject(); 98 } 99 catch (ClassNotFoundException e) { 100 ImagingListener listener = 101 ImageUtil.getImagingListener((RenderingHints)null); 102 listener.errorOccurred(JaiI18N.getString("ClassNotFound"), 103 e, this, false); 104 // e.printStackTrace(); 105 return null; 106 } 107 finally { 108 ois.close(); 109 } 110 111 ByteArrayInputStream bais = new ByteArrayInputStream(data); 112 JPEGImageDecoder decoder = JPEGCodec.createJPEGDecoder(bais); 113 114 Raster ras = decoder.decodeAsRaster() 115 .createTranslatedChild(location.x, location.y); 116 extractParameters(decoder.getJPEGDecodeParam(), 117 ras.getSampleModel().getNumBands()); 118 119 // set the original sample model to the decoded raster 120 if (sm != null) { 121 int minX = ras.getMinX(); 122 int minY = ras.getMinY(); 123 int h = ras.getHeight(); 124 int w = ras.getWidth(); 125 double[] buf = ras.getPixels(minX, minY, w, h, (double[])null); 126 ras = RasterFactory.createWritableRaster(sm, 127 new Point(minX, minY)); 128 ((WritableRaster)ras).setPixels(minX, minY, w, h, buf); 129 } 130 return ras; 131 } 132 extractParameters(JPEGDecodeParam jdp, int bandNum)133 private void extractParameters(JPEGDecodeParam jdp, int bandNum) { 134 135 // extract the horizontal subsampling rates 136 int[] horizontalSubsampling = new int[bandNum]; 137 for (int i = 0; i < bandNum; i++) 138 horizontalSubsampling[i] = jdp.getHorizontalSubsampling(i); 139 paramList.setParameter("horizontalSubsampling", horizontalSubsampling); 140 141 // extract the vertical subsampling rates 142 int[] verticalSubsampling = new int[bandNum]; 143 for (int i = 0; i < bandNum; i++) 144 verticalSubsampling[i] = jdp.getVerticalSubsampling(i); 145 paramList.setParameter("verticalSubsampling", verticalSubsampling); 146 147 // if the quality is not set, extract the quantization tables from 148 // the stream; otherwise, define them with the default values. 149 if (!paramList.getBooleanParameter("qualitySet")) 150 for (int i = 0; i < 4; i++) { 151 JPEGQTable table = jdp.getQTable(i); 152 paramList.setParameter("quantizationTable"+i, 153 (table == null) ? null : table.getTable()); 154 } 155 else { 156 ParameterListDescriptor pld 157 = paramList.getParameterListDescriptor(); 158 for (int i = 0; i < 4; i++) { 159 paramList.setParameter("quantizationTable"+i, 160 pld.getParamDefaultValue("quantizationTable"+i)); 161 } 162 } 163 164 // extract the quantizationTableMapping 165 int[] quanTableMapping = new int[bandNum]; 166 for (int i = 0; i < bandNum; i++) 167 quanTableMapping[i] = jdp.getQTableComponentMapping(i); 168 paramList.setParameter("quantizationTableMapping", quanTableMapping); 169 170 // extract the writeTableInfo and writeImageInfo 171 paramList.setParameter("writeTableInfo", jdp.isTableInfoValid()); 172 paramList.setParameter("writeImageInfo", jdp.isImageInfoValid()); 173 174 // extract the restart interval 175 paramList.setParameter("restartInterval", jdp.getRestartInterval()); 176 177 // define writeJFIFHeader by examing the APP0_MARKER is set or not 178 paramList.setParameter("writeJFIFHeader", 179 jdp.getMarker(JPEGDecodeParam.APP0_MARKER)); 180 } 181 } 182 183