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