1 /* 2 * $RCSfile: MlibScaleNearestOpImage.java,v $ 3 * 4 * Copyright (c) 2005 Sun Microsystems, Inc. All rights reserved. 5 * 6 * Use is subject to license terms. 7 * 8 * $Revision: 1.1 $ 9 * $Date: 2005/02/11 04:56:04 $ 10 * $State: Exp $ 11 */ 12 package com.lightcrafts.media.jai.mlib; 13 import java.awt.Rectangle; 14 import java.awt.image.DataBuffer; 15 import java.awt.image.Raster; 16 import java.awt.image.RenderedImage; 17 import java.awt.image.WritableRaster; 18 import com.lightcrafts.mediax.jai.ImageLayout; 19 import com.lightcrafts.mediax.jai.Interpolation; 20 import java.util.Map; 21 import com.lightcrafts.mediax.jai.BorderExtender; 22 import com.sun.medialib.mlib.*; 23 24 // import com.lightcrafts.media.jai.test.OpImageTester; 25 26 /** 27 * An OpImage class that scales an image using nearest-neighbor 28 * interpolation. 29 * 30 */ 31 final class MlibScaleNearestOpImage extends MlibScaleOpImage { 32 33 /** 34 * Constructs an MlibScaleNearestOpImage. The image dimensions are copied 35 * from the source image. The tile grid layout, SampleModel, and 36 * ColorModel may optionally be specified by an ImageLayout object. 37 * 38 * @param source a RenderedImage. 39 * @param layout an ImageLayout optionally containing the tile 40 * grid layout, SampleModel, and ColorModel, or null. 41 * @param xScale the x scaling factor. 42 * @param yScale the y scaling factor. 43 * @param xTrans the x translation factor. 44 * @param yTrans the y translation factor. 45 * @param interp the Nearest interpolation object. 46 */ MlibScaleNearestOpImage(RenderedImage source, BorderExtender extender, Map config, ImageLayout layout, float xScale, float yScale, float xTrans, float yTrans, Interpolation interp)47 public MlibScaleNearestOpImage(RenderedImage source, 48 BorderExtender extender, 49 Map config, 50 ImageLayout layout, 51 float xScale, float yScale, 52 float xTrans, float yTrans, 53 Interpolation interp) { 54 super(source, extender, config, 55 layout, xScale, yScale, xTrans, yTrans, interp, true); 56 } 57 58 /** 59 * Scale the given rectangle by the specified scale and translation 60 * factors. The sources are cobbled. 61 * 62 * @param sources an array of sources, guarantee to provide all 63 * necessary source data for computing the rectangle. 64 * @param dest a tile that contains the rectangle to be computed. 65 * @param destRect the rectangle within this OpImage to be processed. 66 */ computeRect(Raster[] sources, WritableRaster dest, Rectangle destRect)67 protected void computeRect(Raster[] sources, 68 WritableRaster dest, 69 Rectangle destRect) { 70 71 Raster source = sources[0]; 72 Rectangle srcRect = source.getBounds(); 73 74 int formatTag = MediaLibAccessor.findCompatibleTag(sources, dest); 75 76 MediaLibAccessor srcAccessor = new MediaLibAccessor(source, srcRect, 77 formatTag); 78 MediaLibAccessor dstAccessor = new MediaLibAccessor(dest, destRect, 79 formatTag); 80 81 // Get the floating point scale factors 82 float mlibScaleX = scaleX; 83 float mlibScaleY = scaleY; 84 85 // Translation to be specified to Medialib. Note that we have to 86 // specify an additional translation since all images are 0 based 87 // in Medialib. Note that scale and translation scalars have 88 // rational representations. 89 90 // Calculate intermediate values using rational arithmetic. 91 long tempDenomX = scaleXRationalDenom * transXRationalDenom; 92 long tempDenomY = scaleYRationalDenom * transYRationalDenom; 93 long tempNumerX = (srcRect.x * scaleXRationalNum * transXRationalDenom) + 94 (transXRationalNum * scaleXRationalDenom) - 95 (destRect.x * tempDenomX); 96 long tempNumerY = (srcRect.y * scaleYRationalNum * transYRationalDenom) + 97 (transYRationalNum * scaleYRationalDenom) - 98 (destRect.y * tempDenomY); 99 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, 114 (double)mlibScaleY, 115 (double)tx, (double)ty, 116 Constants.MLIB_NEAREST, 117 Constants.MLIB_EDGE_DST_NO_WRITE); 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], 127 (double)mlibScaleX, 128 (double)mlibScaleY, 129 (double)tx, (double)ty, 130 Constants.MLIB_NEAREST, 131 Constants.MLIB_EDGE_DST_NO_WRITE); 132 } 133 break; 134 135 default: 136 String className = this.getClass().getName(); 137 throw new RuntimeException(JaiI18N.getString("Generic2")); 138 } 139 140 if (dstAccessor.isDataCopy()) { 141 dstAccessor.clampDataArrays(); 142 dstAccessor.copyDataToRaster(); 143 } 144 } 145 146 // public static OpImage createTestImage(OpImageTester oit) { 147 // Interpolation interp = new InterpolationNearest(); 148 // return new MlibScaleNearestOpImage(oit.getSource(), null, 149 // new ImageLayout(oit.getSource()), 150 // 2, 2, 0, 0, interp); 151 // } 152 153 // // Calls a method on OpImage that uses introspection, to make this 154 // // class, discover it's createTestImage() call, call it and then 155 // // benchmark the performance of the created OpImage chain. 156 // public static void main (String args[]) { 157 // String classname = "com.lightcrafts.media.jai.mlib.MlibScaleNearestOpImage"; 158 // OpImageTester.performDiagnostics(classname, args); 159 // } 160 } 161