001: /*
002: * $RCSfile: MlibAffineNearestOpImage.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/11/14 22:45:29 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.mlib;
013:
014: import java.awt.Rectangle;
015: import java.awt.image.DataBuffer;
016: import java.awt.image.SampleModel;
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 java.awt.image.renderable.RenderedImageFactory;
022: import java.awt.geom.AffineTransform;
023: import javax.media.jai.AreaOpImage;
024: import javax.media.jai.ImageLayout;
025: import javax.media.jai.Interpolation;
026: import javax.media.jai.InterpolationNearest;
027: import javax.media.jai.KernelJAI;
028: import javax.media.jai.OpImage;
029: import java.util.Map;
030: import javax.media.jai.BorderExtender;
031: import com.sun.medialib.mlib.*;
032:
033: // import com.sun.media.jai.test.OpImageTester;
034:
035: /**
036: * An OpImage class to perform Nearest-Neighbour AffineTransform
037: * on a source image.
038: *
039: */
040: public class MlibAffineNearestOpImage extends MlibAffineOpImage {
041:
042: /**
043: * Creates a MlibAffineNearestOpImage given a ParameterBlock containing the
044: * image source and the AffineTransform. The image dimensions are derived
045: * from the source image. The tile grid layout, SampleModel, and
046: * ColorModel may optionally be specified by an ImageLayout
047: * object.
048: *
049: * @param source a RenderedImage.
050: * @param layout an ImageLayout optionally containing the tile grid layout,
051: * SampleModel, and ColorModel, or null.
052: * @param tr the AffineTransform.
053: * @param interp the Interpolation to be used (Nearest-Neighbour)
054: */
055: public MlibAffineNearestOpImage(RenderedImage source,
056: BorderExtender extender, Map config, ImageLayout layout,
057: AffineTransform tr, Interpolation interp,
058: double[] backgroundValues) {
059: super (source, layout, config, extender, tr, interp,
060: backgroundValues);
061: }
062:
063: /**
064: * Performs nearest-neighbour affine transformation on a specified
065: * rectangle. The sources are cobbled.
066: *
067: * @param sources an array of source Rasters, guaranteed to provide all
068: * necessary source data for computing the output.
069: * @param dest a WritableRaster tile containing the area to be computed.
070: * @param destRect the rectangle within dest to be processed.
071: */
072: protected void computeRect(Raster[] sources, WritableRaster dest,
073: Rectangle destRect) {
074:
075: Raster source = sources[0];
076: Rectangle srcRect = source.getBounds();
077:
078: int formatTag = MediaLibAccessor.findCompatibleTag(sources,
079: dest);
080:
081: MediaLibAccessor srcAccessor = new MediaLibAccessor(source,
082: srcRect, formatTag);
083: MediaLibAccessor dstAccessor = new MediaLibAccessor(dest,
084: destRect, formatTag);
085:
086: //
087: // The AffineTransform needs to be readjusted as per the
088: // location of the current source & destination rectangles
089: //
090:
091: // Clone the global transform so as not to write to an instance
092: // variable as this method may be called from different threads.
093: double[] medialib_tr = (double[]) this .medialib_tr.clone();
094:
095: medialib_tr[2] = m_transform[0] * srcRect.x + m_transform[1]
096: * srcRect.y + m_transform[2] - destRect.x;
097: medialib_tr[5] = m_transform[3] * srcRect.x + m_transform[4]
098: * srcRect.y + m_transform[5] - destRect.y;
099:
100: mediaLibImage srcML[], dstML[];
101:
102: switch (dstAccessor.getDataType()) {
103: case DataBuffer.TYPE_BYTE:
104: case DataBuffer.TYPE_USHORT:
105: case DataBuffer.TYPE_SHORT:
106: case DataBuffer.TYPE_INT:
107: srcML = srcAccessor.getMediaLibImages();
108: dstML = dstAccessor.getMediaLibImages();
109:
110: if (setBackground)
111: Image.Affine2(dstML[0], srcML[0], medialib_tr,
112: Constants.MLIB_NEAREST,
113: Constants.MLIB_EDGE_DST_NO_WRITE,
114: intBackgroundValues);
115: else
116: Image.Affine(dstML[0], srcML[0], medialib_tr,
117: Constants.MLIB_NEAREST,
118: Constants.MLIB_EDGE_DST_NO_WRITE);
119: break;
120:
121: case DataBuffer.TYPE_FLOAT:
122: case DataBuffer.TYPE_DOUBLE:
123: srcML = srcAccessor.getMediaLibImages();
124: dstML = dstAccessor.getMediaLibImages();
125:
126: if (setBackground)
127: Image.Affine2_Fp(dstML[0], srcML[0], medialib_tr,
128: Constants.MLIB_NEAREST,
129: Constants.MLIB_EDGE_DST_NO_WRITE,
130: backgroundValues);
131: else
132: Image.Affine_Fp(dstML[0], srcML[0], medialib_tr,
133: Constants.MLIB_NEAREST,
134: Constants.MLIB_EDGE_DST_NO_WRITE);
135: break;
136:
137: default:
138: String className = this .getClass().getName();
139: throw new RuntimeException(JaiI18N.getString("Generic2"));
140: }
141:
142: if (dstAccessor.isDataCopy()) {
143: dstAccessor.copyDataToRaster();
144: }
145: }
146:
147: // public static OpImage createTestImage(OpImageTester oit) {
148: // Interpolation interp = new InterpolationNearest();
149: // AffineTransform tr = new AffineTransform(0.707107,
150: // -0.707106,
151: // 0.707106,
152: // 0.707107,
153: // 0.0,
154: // 0.0);
155: // return new MlibAffineNearestOpImage(oit.getSource(), null,
156: // new ImageLayout(oit.getSource()),
157: // tr,
158: // interp);
159: // }
160:
161: // // Calls a method on OpImage that uses introspection, to make this
162: // // class, discover it's createTestImage() call, call it and then
163: // // benchmark the performance of the created OpImage chain.
164: // public static void main (String args[]) {
165: // String classname = "com.sun.media.jai.mlib.MlibAffineNearestOpImage";
166: // OpImageTester.performDiagnostics(classname, args);
167: // }
168: }
|