001: /*
002: * $RCSfile: JPEGTileEncoder.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.image.Raster;
015: import java.awt.image.WritableRaster;
016: import java.awt.image.SampleModel;
017: import java.io.OutputStream;
018: import java.io.ObjectOutputStream;
019: import java.io.ByteArrayOutputStream;
020: import java.io.IOException;
021: import java.text.MessageFormat;
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.TileEncoderImpl;
028: import com.sun.image.codec.jpeg.JPEGEncodeParam;
029: import com.sun.image.codec.jpeg.JPEGImageEncoder;
030: import com.sun.image.codec.jpeg.JPEGCodec;
031: import com.sun.image.codec.jpeg.JPEGQTable;
032: import sun.awt.image.codec.JPEGParam;
033:
034: /**
035: * A concrete implementation of the <code>TileEncoderImpl</code> class
036: * for the jpeg tile codec.
037: */
038: public class JPEGTileEncoder extends TileEncoderImpl {
039: /* The associated TileCodecDescriptor */
040: private TileCodecDescriptor tcd = null;
041:
042: /**
043: * Constructs an <code>JPEGTileEncoder</code>. Concrete implementations
044: * of <code>TileEncoder</code> may throw an
045: * <code>IllegalArgumentException</code> if the
046: * <code>param</code>'s <code>getParameterListDescriptor()</code> method
047: * does not return the same descriptor as that from the associated
048: * <code>TileCodecDescriptor</code>'s
049: * <code>getParameterListDescriptor</code> method for the "tileEncoder"
050: * registry mode.
051: *
052: * <p> If param is null, then the default parameter list for encoding
053: * as defined by the associated <code>TileCodecDescriptor</code>'s
054: * <code>getDefaultParameters()</code> method will be used for encoding.
055: *
056: * @param output The <code>OutputStream</code> to write encoded data to.
057: * @param param The object containing the tile encoding parameters.
058: * @throws IllegalArgumentException if param is not the appropriate
059: * Class type.
060: * @throws IllegalArgumentException is output is null.
061: */
062: public JPEGTileEncoder(OutputStream output,
063: TileCodecParameterList param) {
064: super ("jpeg", output, param);
065: tcd = TileCodecUtils.getTileCodecDescriptor("tileEncoder",
066: "jpeg");
067: }
068:
069: /**
070: * Encodes a <code>Raster</code> and writes the output
071: * to the <code>OutputStream</code> associated with this
072: * <code>TileEncoder</code>.
073: *
074: * @param ras the <code>Raster</code> to encode.
075: * @throws IOException if an I/O error occurs while writing to the
076: * OutputStream.
077: * @throws IllegalArgumentException if ras is null.
078: */
079: public void encode(Raster ras) throws IOException {
080: if (ras == null)
081: throw new IllegalArgumentException(JaiI18N
082: .getString("TileEncoder1"));
083:
084: ByteArrayOutputStream baos = new ByteArrayOutputStream();
085:
086: SampleModel sm = ras.getSampleModel();
087:
088: JPEGEncodeParam j2dEP = convertToJ2DJPEGEncodeParam(paramList,
089: sm);
090: ((JPEGParam) j2dEP).setWidth(ras.getWidth());
091: ((JPEGParam) j2dEP).setHeight(ras.getHeight());
092:
093: JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(baos,
094: j2dEP);
095: encoder.encode(ras);
096:
097: byte[] data = baos.toByteArray();
098:
099: ObjectOutputStream oos = new ObjectOutputStream(outputStream);
100: oos.writeFloat(paramList.getFloatParameter("quality"));
101: oos.writeBoolean(paramList.getBooleanParameter("qualitySet"));
102: oos.writeObject(TileCodecUtils.serializeSampleModel(sm));
103:
104: Point location = new Point(ras.getMinX(), ras.getMinY());
105: oos.writeObject(location);
106:
107: oos.writeObject(data);
108: oos.close();
109: }
110:
111: private JPEGEncodeParam convertToJ2DJPEGEncodeParam(
112: TileCodecParameterList paramList, SampleModel sm) {
113:
114: if (sm == null)
115: return null;
116:
117: int nbands = sm.getNumBands();
118:
119: JPEGParam j2dJP = createDefaultJ2DJPEGEncodeParam(nbands);
120:
121: int[] hSubSamp = (int[]) paramList
122: .getObjectParameter("horizontalSubsampling");
123: int[] vSubSamp = (int[]) paramList
124: .getObjectParameter("verticalSubsampling");
125: int[] qTabSlot = (int[]) paramList
126: .getObjectParameter("quantizationTableMapping");
127:
128: for (int i = 0; i < nbands; i++) {
129: j2dJP.setHorizontalSubsampling(i, hSubSamp[i]);
130: j2dJP.setVerticalSubsampling(i, vSubSamp[i]);
131:
132: int[] qTab = (int[]) paramList
133: .getObjectParameter("quantizationTable" + i);
134: if (qTab != null
135: && qTab
136: .equals(ParameterListDescriptor.NO_PARAMETER_DEFAULT)) {
137: j2dJP.setQTableComponentMapping(i, qTabSlot[i]);
138: j2dJP.setQTable(qTabSlot[i], new JPEGQTable(qTab));
139: }
140: }
141:
142: if (paramList.getBooleanParameter("qualitySet")) {
143: float quality = paramList.getFloatParameter("quality");
144: j2dJP.setQuality(quality, true);
145: }
146:
147: int rInt = paramList.getIntParameter("restartInterval");
148: j2dJP.setRestartInterval(rInt);
149:
150: j2dJP.setImageInfoValid(paramList
151: .getBooleanParameter("writeImageInfo"));
152: j2dJP.setTableInfoValid(paramList
153: .getBooleanParameter("writeTableInfo"));
154:
155: if (paramList.getBooleanParameter("writeJFIFHeader")) {
156: j2dJP.setMarkerData(JPEGEncodeParam.APP0_MARKER, null);
157: }
158:
159: return (JPEGEncodeParam) j2dJP;
160: }
161:
162: private JPEGParam createDefaultJ2DJPEGEncodeParam(int nbands) {
163: if (nbands == 1)
164: return new JPEGParam(JPEGEncodeParam.COLOR_ID_GRAY, 1);
165: if (nbands == 3)
166: return new JPEGParam(JPEGEncodeParam.COLOR_ID_YCbCr, 3);
167: if (nbands == 4)
168: return new JPEGParam(JPEGEncodeParam.COLOR_ID_CMYK, 4);
169: return null;
170: }
171: }
|