1 /* 2 * $RCSfile: TranslateCRIF.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:45 $ 10 * $State: Exp $ 11 */ 12 package com.lightcrafts.media.jai.opimage; 13 import java.awt.RenderingHints; 14 import java.awt.geom.Rectangle2D; 15 import java.awt.geom.AffineTransform; 16 import java.awt.image.DataBuffer; 17 import java.awt.image.MultiPixelPackedSampleModel; 18 import java.awt.image.SampleModel; 19 import java.awt.image.RenderedImage; 20 import java.awt.image.renderable.ParameterBlock; 21 import java.awt.image.renderable.RenderableImage; 22 import java.awt.image.renderable.RenderContext; 23 import com.lightcrafts.mediax.jai.BorderExtender; 24 import com.lightcrafts.mediax.jai.ImageLayout; 25 import com.lightcrafts.mediax.jai.Interpolation; 26 import com.lightcrafts.mediax.jai.InterpolationNearest; 27 import com.lightcrafts.mediax.jai.InterpolationBilinear; 28 import com.lightcrafts.mediax.jai.InterpolationBicubic; 29 import com.lightcrafts.mediax.jai.InterpolationBicubic2; 30 import com.lightcrafts.mediax.jai.TileCache; 31 import com.lightcrafts.mediax.jai.CRIFImpl; 32 33 /** 34 * This image factory supports image operator <code>TranslateOpImage</code> 35 * in the rendered and renderable image layers. 36 * 37 * @see TranslateOpImage 38 */ 39 public class TranslateCRIF extends CRIFImpl { 40 41 private static final float TOLERANCE = 0.01F; 42 43 /** Constructor. */ TranslateCRIF()44 public TranslateCRIF() { 45 super("translate"); 46 } 47 48 /** 49 * Creates a new instance of <code>TranslateOpImage</code> 50 * in the rendered layer. This method satisfies the 51 * implementation of RIF. 52 */ create(ParameterBlock paramBlock, RenderingHints renderHints)53 public RenderedImage create(ParameterBlock paramBlock, 54 RenderingHints renderHints) { 55 RenderedImage source = paramBlock.getRenderedSource(0); 56 float xTrans = paramBlock.getFloatParameter(0); 57 float yTrans = paramBlock.getFloatParameter(1); 58 Interpolation interp = (Interpolation) 59 paramBlock.getObjectParameter(2); 60 61 // Get ImageLayout from renderHints if any. 62 ImageLayout layout = RIFUtil.getImageLayoutHint(renderHints); 63 64 // If there is a layout hint, TranslateIntOpImage can't deal with it 65 if ((Math.abs(xTrans - (int)xTrans) < TOLERANCE) && 66 (Math.abs(yTrans - (int)yTrans) < TOLERANCE) && 67 layout == null) { 68 return new TranslateIntOpImage(source, 69 renderHints, 70 (int)xTrans, 71 (int)yTrans); 72 } else { 73 74 // Get TileCache from renderHints if any. 75 TileCache cache = RIFUtil.getTileCacheHint(renderHints); 76 77 // Get BorderExtender from renderHints if any. 78 BorderExtender extender = 79 RIFUtil.getBorderExtenderHint(renderHints); 80 81 // 82 // Call the Scale operation, since it encapsulates Translate 83 // and is better optimized than Affine. 84 // 85 float xScale = 1.0F; 86 float yScale = 1.0F; 87 SampleModel sm = source.getSampleModel(); 88 boolean isBinary = 89 (sm instanceof MultiPixelPackedSampleModel) && 90 (sm.getSampleSize(0) == 1) && 91 (sm.getDataType() == DataBuffer.TYPE_BYTE || 92 sm.getDataType() == DataBuffer.TYPE_USHORT || 93 sm.getDataType() == DataBuffer.TYPE_INT); 94 95 if (interp instanceof InterpolationNearest) 96 { 97 if (isBinary) 98 { 99 return new ScaleNearestBinaryOpImage(source, 100 extender, 101 renderHints, 102 layout, 103 xScale, 104 yScale, 105 xTrans, 106 yTrans, 107 interp); 108 } 109 else 110 { 111 return new ScaleNearestOpImage(source, 112 extender, 113 renderHints, 114 layout, 115 xScale, yScale, 116 xTrans, yTrans, 117 interp); 118 } 119 } 120 else 121 if (interp instanceof InterpolationBilinear) 122 { 123 if (isBinary) 124 { 125 return new ScaleBilinearBinaryOpImage(source, 126 extender, 127 renderHints, 128 layout, 129 xScale, 130 yScale, 131 xTrans, 132 yTrans, 133 interp); 134 } 135 else 136 { 137 return new ScaleBilinearOpImage(source, 138 extender, 139 renderHints, 140 layout, 141 xScale, yScale, 142 xTrans, yTrans, 143 interp); 144 } 145 } 146 else 147 if ((interp instanceof InterpolationBicubic) || 148 (interp instanceof InterpolationBicubic2)) 149 { 150 return new ScaleBicubicOpImage(source, 151 extender, 152 renderHints, 153 layout, 154 xScale, yScale, 155 xTrans, yTrans, 156 interp); 157 } 158 else 159 { 160 return new ScaleGeneralOpImage(source, extender, 161 renderHints, 162 layout, 163 xScale, yScale, 164 xTrans, yTrans, 165 interp); 166 } 167 } 168 } 169 170 /** 171 * Creates a new instance of <code>TranslateOpImage</code> 172 * in the renderable layer. This method satisfies the 173 * implementation of CRIF. 174 */ create(RenderContext renderContext, ParameterBlock paramBlock)175 public RenderedImage create(RenderContext renderContext, 176 ParameterBlock paramBlock) { 177 return paramBlock.getRenderedSource(0); 178 } 179 180 /** 181 * Maps the output RenderContext into the RenderContext for the ith 182 * source. 183 * This method satisfies the implementation of CRIF. 184 * 185 * @param i The index of the source image. 186 * @param renderContext The renderContext being applied to the operation. 187 * @param paramBlock The ParameterBlock containing the sources 188 * and the translation factors. 189 * @param image The RenderableImageOp from which this method 190 * was called. 191 */ mapRenderContext(int i, RenderContext renderContext, ParameterBlock paramBlock, RenderableImage image)192 public RenderContext mapRenderContext(int i, 193 RenderContext renderContext, 194 ParameterBlock paramBlock, 195 RenderableImage image) { 196 AffineTransform translate = new AffineTransform(); 197 translate.setToTranslation(paramBlock.getFloatParameter(0), 198 paramBlock.getFloatParameter(1)); 199 200 RenderContext RC = (RenderContext)renderContext.clone(); 201 AffineTransform usr2dev = RC.getTransform(); 202 usr2dev.concatenate(translate); 203 RC.setTransform(usr2dev); 204 return RC; 205 } 206 207 /** 208 * Gets the bounding box for output of <code>TranslateOpImage</code>. 209 * This method satisfies the implementation of CRIF. 210 */ getBounds2D(ParameterBlock paramBlock)211 public Rectangle2D getBounds2D(ParameterBlock paramBlock) { 212 RenderableImage source = paramBlock.getRenderableSource(0); 213 float xTrans = paramBlock.getFloatParameter(0); 214 float yTrans = paramBlock.getFloatParameter(1); 215 216 return new Rectangle2D.Float(source.getMinX() + xTrans, 217 source.getMinY() + yTrans, 218 source.getWidth(), 219 source.getHeight()); 220 } 221 } 222