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