001: /*
002: * $RCSfile: MlibTransposeOpImage.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.2 $
009: * $Date: 2005/12/13 21:23:07 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.mlib;
013:
014: import java.awt.Point;
015: import java.awt.Rectangle;
016: import java.awt.image.DataBuffer;
017: import java.awt.image.Raster;
018: import java.awt.image.RenderedImage;
019: import java.awt.image.WritableRaster;
020: import java.awt.image.renderable.ParameterBlock;
021: import javax.media.jai.GeometricOpImage;
022: import javax.media.jai.ImageLayout;
023: import javax.media.jai.OpImage;
024: import javax.media.jai.PlanarImage;
025: import javax.media.jai.RasterFactory;
026: import java.util.Map;
027: import javax.media.jai.RasterAccessor;
028: import com.sun.media.jai.opimage.TransposeOpImage;
029: import com.sun.medialib.mlib.*;
030:
031: // import com.sun.media.jai.test.OpImageTester;
032:
033: /**
034: * An OpImage class to perform a transpose (flip) of an image.
035: *
036: * @since EA3
037: *
038: */
039: final class MlibTransposeOpImage extends TransposeOpImage {
040:
041: /**
042: * Constructs an TransposeOpImage from a RenderedImage source,
043: * and Transpose type. The image dimensions are determined by
044: * forward-mapping the source bounds.
045: * The tile grid layout, SampleModel, and ColorModel are specified
046: * by the image source, possibly overridden by values from the
047: * ImageLayout parameter.
048: *
049: * @param source a RenderedImage.
050:
051: * or null. If null, a default cache will be used.
052: * @param layout an ImageLayout optionally containing the tile grid layout,
053: * SampleModel, and ColorModel, or null.
054: * @param type the desired Tranpose type.
055: */
056: public MlibTransposeOpImage(RenderedImage source, Map config,
057: ImageLayout layout, int type) {
058: super (source, config, layout, type);
059: }
060:
061: public Raster computeTile(int tileX, int tileY) {
062: //
063: // Create a new WritableRaster to represent this tile.
064: //
065: Point org = new Point(tileXToX(tileX), tileYToY(tileY));
066: WritableRaster dest = createWritableRaster(sampleModel, org);
067:
068: //
069: // Clip output rectangle to image bounds.
070: //
071: Rectangle destRect = getTileRect(tileX, tileY).intersection(
072: getBounds());
073:
074: //
075: // Get source
076: //
077: PlanarImage src = getSourceImage(0);
078:
079: //
080: // Determine effective source bounds.
081: //
082: Rectangle srcRect = mapDestRect(destRect, 0).intersection(
083: src.getBounds());
084:
085: Raster[] sources = new Raster[1];
086: sources[0] = src.getData(srcRect);
087:
088: //
089: // Compute the destination.
090: //
091: computeRect(sources, dest, destRect);
092:
093: // Recycle the source tile
094: if (src.overlapsMultipleTiles(srcRect)) {
095: recycleTile(sources[0]);
096: }
097:
098: return dest;
099: }
100:
101: protected void computeRect(Raster[] sources, WritableRaster dest,
102: Rectangle destRect) {
103: Raster source = sources[0];
104:
105: Rectangle srcRect = source.getBounds();
106:
107: int formatTag = MediaLibAccessor.findCompatibleTag(sources,
108: dest);
109:
110: MediaLibAccessor srcAccessor = new MediaLibAccessor(source,
111: srcRect, formatTag);
112: MediaLibAccessor dstAccessor = new MediaLibAccessor(dest,
113: destRect, formatTag);
114: int numBands = getSampleModel().getNumBands();
115:
116: mediaLibImage srcML[], dstML[];
117:
118: switch (dstAccessor.getDataType()) {
119: case DataBuffer.TYPE_BYTE:
120: case DataBuffer.TYPE_USHORT:
121: case DataBuffer.TYPE_SHORT:
122: case DataBuffer.TYPE_INT:
123: srcML = srcAccessor.getMediaLibImages();
124: dstML = dstAccessor.getMediaLibImages();
125: switch (type) {
126: case 0: // FLIP_VERTICAL
127: Image.FlipX(dstML[0], srcML[0]);
128: break;
129:
130: case 1: // FLIP_HORIZONTAL
131: Image.FlipY(dstML[0], srcML[0]);
132: break;
133:
134: case 2: // FLIP_DIAGONAL
135: Image.FlipMainDiag(dstML[0], srcML[0]);
136: break;
137:
138: case 3: // FLIP_ANTIDIAGONAL
139: Image.FlipAntiDiag(dstML[0], srcML[0]);
140: break;
141:
142: case 4: // ROTATE_90
143: Image.Rotate90(dstML[0], srcML[0]);
144: break;
145:
146: case 5: // ROTATE_180
147: Image.Rotate180(dstML[0], srcML[0]);
148: break;
149:
150: case 6: // ROTATE_270
151: Image.Rotate270(dstML[0], srcML[0]);
152: break;
153: }
154: break;
155:
156: case DataBuffer.TYPE_FLOAT:
157: case DataBuffer.TYPE_DOUBLE:
158: srcML = srcAccessor.getMediaLibImages();
159: dstML = dstAccessor.getMediaLibImages();
160: switch (type) {
161: case 0: // FLIP_VERTICAL
162: Image.FlipX_Fp(dstML[0], srcML[0]);
163: break;
164:
165: case 1: // FLIP_HORIZONTAL
166: Image.FlipY_Fp(dstML[0], srcML[0]);
167: break;
168:
169: case 2: // FLIP_DIAGONAL
170: Image.FlipMainDiag_Fp(dstML[0], srcML[0]);
171: break;
172:
173: case 3: // FLIP_ANTIDIAGONAL
174: Image.FlipAntiDiag_Fp(dstML[0], srcML[0]);
175: break;
176:
177: case 4: // ROTATE_90
178: Image.Rotate90_Fp(dstML[0], srcML[0]);
179: break;
180:
181: case 5: // ROTATE_180
182: Image.Rotate180_Fp(dstML[0], srcML[0]);
183: break;
184:
185: case 6: // ROTATE_270
186: Image.Rotate270_Fp(dstML[0], srcML[0]);
187: break;
188: }
189: break;
190:
191: default:
192: throw new RuntimeException(JaiI18N.getString("Generic2"));
193: }
194:
195: //
196: // If the RasterAccessor object set up a temporary buffer for the
197: // op to write to, tell the RasterAccessor to write that data
198: // to the raster, that we're done with it.
199: //
200: if (dstAccessor.isDataCopy()) {
201: dstAccessor.copyDataToRaster();
202: }
203: }
204:
205: // public static OpImage createTestImage(OpImageTester oit) {
206: // int type = 1;
207: // return new MlibTransposeOpImage(oit.getSource(), null,
208: // new ImageLayout(oit.getSource()),
209: // type);
210: // }
211:
212: // public static void main (String args[]) {
213: // String classname = "com.sun.media.jai.mlib.MlibTransposeOpImage";
214: // OpImageTester.performDiagnostics(classname,args);
215: // }
216: }
|