001: /*
002: * $RCSfile: MlibScaleNearestOpImage.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:04 $
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.Raster;
017: import java.awt.image.RenderedImage;
018: import java.awt.image.WritableRaster;
019: import javax.media.jai.ImageLayout;
020: import javax.media.jai.Interpolation;
021: import javax.media.jai.InterpolationNearest;
022: import javax.media.jai.OpImage;
023: import java.util.Map;
024: import javax.media.jai.BorderExtender;
025: import com.sun.medialib.mlib.*;
026:
027: // import com.sun.media.jai.test.OpImageTester;
028:
029: /**
030: * An OpImage class that scales an image using nearest-neighbor
031: * interpolation.
032: *
033: */
034: final class MlibScaleNearestOpImage extends MlibScaleOpImage {
035:
036: /**
037: * Constructs an MlibScaleNearestOpImage. The image dimensions are copied
038: * from the source image. The tile grid layout, SampleModel, and
039: * ColorModel may optionally be specified by an ImageLayout object.
040: *
041: * @param source a RenderedImage.
042: * @param layout an ImageLayout optionally containing the tile
043: * grid layout, SampleModel, and ColorModel, or null.
044: * @param xScale the x scaling factor.
045: * @param yScale the y scaling factor.
046: * @param xTrans the x translation factor.
047: * @param yTrans the y translation factor.
048: * @param interp the Nearest interpolation object.
049: */
050: public MlibScaleNearestOpImage(RenderedImage source,
051: BorderExtender extender, Map config, ImageLayout layout,
052: float xScale, float yScale, float xTrans, float yTrans,
053: Interpolation interp) {
054: super (source, extender, config, layout, xScale, yScale, xTrans,
055: yTrans, interp, true);
056: }
057:
058: /**
059: * Scale the given rectangle by the specified scale and translation
060: * factors. The sources are cobbled.
061: *
062: * @param sources an array of sources, guarantee to provide all
063: * necessary source data for computing the rectangle.
064: * @param dest a tile that contains the rectangle to be computed.
065: * @param destRect the rectangle within this OpImage to be processed.
066: */
067: protected void computeRect(Raster[] sources, WritableRaster dest,
068: Rectangle destRect) {
069:
070: Raster source = sources[0];
071: Rectangle srcRect = source.getBounds();
072:
073: int formatTag = MediaLibAccessor.findCompatibleTag(sources,
074: dest);
075:
076: MediaLibAccessor srcAccessor = new MediaLibAccessor(source,
077: srcRect, formatTag);
078: MediaLibAccessor dstAccessor = new MediaLibAccessor(dest,
079: destRect, formatTag);
080:
081: // Get the floating point scale factors
082: float mlibScaleX = scaleX;
083: float mlibScaleY = scaleY;
084:
085: // Translation to be specified to Medialib. Note that we have to
086: // specify an additional translation since all images are 0 based
087: // in Medialib. Note that scale and translation scalars have
088: // rational representations.
089:
090: // Calculate intermediate values using rational arithmetic.
091: long tempDenomX = scaleXRationalDenom * transXRationalDenom;
092: long tempDenomY = scaleYRationalDenom * transYRationalDenom;
093: long tempNumerX = (srcRect.x * scaleXRationalNum * transXRationalDenom)
094: + (transXRationalNum * scaleXRationalDenom)
095: - (destRect.x * tempDenomX);
096: long tempNumerY = (srcRect.y * scaleYRationalNum * transYRationalDenom)
097: + (transYRationalNum * scaleYRationalDenom)
098: - (destRect.y * tempDenomY);
099: float tx = (float) tempNumerX / (float) tempDenomX;
100: float ty = (float) tempNumerY / (float) tempDenomY;
101:
102: mediaLibImage srcML[], dstML[];
103:
104: switch (dstAccessor.getDataType()) {
105: case DataBuffer.TYPE_BYTE:
106: case DataBuffer.TYPE_USHORT:
107: case DataBuffer.TYPE_SHORT:
108: case DataBuffer.TYPE_INT:
109: srcML = srcAccessor.getMediaLibImages();
110: dstML = dstAccessor.getMediaLibImages();
111: for (int i = 0; i < dstML.length; i++) {
112: Image.ZoomTranslate(dstML[i], srcML[i],
113: (double) mlibScaleX, (double) mlibScaleY,
114: (double) tx, (double) ty,
115: Constants.MLIB_NEAREST,
116: Constants.MLIB_EDGE_DST_NO_WRITE);
117: }
118: break;
119:
120: case DataBuffer.TYPE_FLOAT:
121: case DataBuffer.TYPE_DOUBLE:
122: srcML = srcAccessor.getMediaLibImages();
123: dstML = dstAccessor.getMediaLibImages();
124: for (int i = 0; i < dstML.length; i++) {
125: Image.ZoomTranslate_Fp(dstML[i], srcML[i],
126: (double) mlibScaleX, (double) mlibScaleY,
127: (double) tx, (double) ty,
128: Constants.MLIB_NEAREST,
129: Constants.MLIB_EDGE_DST_NO_WRITE);
130: }
131: break;
132:
133: default:
134: String className = this .getClass().getName();
135: throw new RuntimeException(JaiI18N.getString("Generic2"));
136: }
137:
138: if (dstAccessor.isDataCopy()) {
139: dstAccessor.clampDataArrays();
140: dstAccessor.copyDataToRaster();
141: }
142: }
143:
144: // public static OpImage createTestImage(OpImageTester oit) {
145: // Interpolation interp = new InterpolationNearest();
146: // return new MlibScaleNearestOpImage(oit.getSource(), null,
147: // new ImageLayout(oit.getSource()),
148: // 2, 2, 0, 0, interp);
149: // }
150:
151: // // Calls a method on OpImage that uses introspection, to make this
152: // // class, discover it's createTestImage() call, call it and then
153: // // benchmark the performance of the created OpImage chain.
154: // public static void main (String args[]) {
155: // String classname = "com.sun.media.jai.mlib.MlibScaleNearestOpImage";
156: // OpImageTester.performDiagnostics(classname, args);
157: // }
158: }
|