001: /*
002: * $RCSfile: MlibScaleRIF.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:05 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.mlib;
013:
014: import java.awt.RenderingHints;
015: import java.awt.geom.AffineTransform;
016: import java.awt.image.DataBuffer;
017: import java.awt.image.MultiPixelPackedSampleModel;
018: import java.awt.image.RenderedImage;
019: import java.awt.image.SampleModel;
020: import java.awt.image.renderable.RenderedImageFactory;
021: import java.awt.image.renderable.ParameterBlock;
022: import javax.media.jai.BorderExtender;
023: import javax.media.jai.ImageLayout;
024: import javax.media.jai.Interpolation;
025: import javax.media.jai.InterpolationNearest;
026: import javax.media.jai.InterpolationBilinear;
027: import javax.media.jai.InterpolationBicubic;
028: import javax.media.jai.InterpolationBicubic2;
029: import javax.media.jai.InterpolationTable;
030: import java.util.Map;
031: import com.sun.media.jai.opimage.RIFUtil;
032: import com.sun.media.jai.opimage.TranslateIntOpImage;
033:
034: /**
035: * A <code>RIF</code> supporting the "Scale" operation in the
036: * rendered image mode using MediaLib.
037: *
038: * @see javax.media.jai.operator.ScaleDescriptor
039: * @see MlibScaleNearestOpImage
040: * @see MlibScaleBilinearOpImage
041: * @see MlibScaleBicubicOpImage
042: *
043: */
044: public class MlibScaleRIF implements RenderedImageFactory {
045:
046: private static final float TOLERANCE = 0.01F;
047:
048: /** Constructor. */
049: public MlibScaleRIF() {
050: }
051:
052: /**
053: * Creates a new instance of <code>MlibScaleOpImage</code> in
054: * the rendered image mode.
055: *
056: * @param args The source image, scale factors,
057: * and the <code>Interpolation</code>.
058: * @param hints May contain rendering hints and destination image layout.
059: */
060: public RenderedImage create(ParameterBlock args,
061: RenderingHints hints) {
062: /* Get ImageLayout and TileCache from RenderingHints. */
063: ImageLayout layout = RIFUtil.getImageLayoutHint(hints);
064:
065: Interpolation interp = (Interpolation) args
066: .getObjectParameter(4);
067:
068: RenderedImage source = args.getRenderedSource(0);
069:
070: if (!MediaLibAccessor.isMediaLibCompatible(args, layout)
071: || !MediaLibAccessor.hasSameNumBands(args, layout)
072: ||
073: // Medialib cannot deal with source image having tiles with any
074: // dimension greater than or equal to 32768
075: source.getTileWidth() >= 32768
076: || source.getTileHeight() >= 32768) {
077: return null;
078: }
079:
080: SampleModel sm = source.getSampleModel();
081: boolean isBilevel = (sm instanceof MultiPixelPackedSampleModel)
082: && (sm.getSampleSize(0) == 1)
083: && (sm.getDataType() == DataBuffer.TYPE_BYTE
084: || sm.getDataType() == DataBuffer.TYPE_USHORT || sm
085: .getDataType() == DataBuffer.TYPE_INT);
086: if (isBilevel) {
087: // Let Java code handle it, reformatting is slower
088: return null;
089: }
090:
091: // Get BorderExtender from hints if any.
092: BorderExtender extender = RIFUtil.getBorderExtenderHint(hints);
093:
094: float xScale = args.getFloatParameter(0);
095: float yScale = args.getFloatParameter(1);
096: float xTrans = args.getFloatParameter(2);
097: float yTrans = args.getFloatParameter(3);
098:
099: // Check and see if we are scaling by 1.0 in both x and y and no
100: // translations. If so call the copy operation.
101: if (xScale == 1.0F && yScale == 1.0F && xTrans == 0.0F
102: && yTrans == 0.0F) {
103: return new MlibCopyOpImage(source, hints, layout);
104: }
105:
106: // Check to see whether the operation specified is a pure
107: // integer translation. If so call translate
108: if (xScale == 1.0F && yScale == 1.0F
109: && (Math.abs(xTrans - (int) xTrans) < TOLERANCE)
110: && (Math.abs(yTrans - (int) yTrans) < TOLERANCE)
111: && layout == null) { // TranslateIntOpImage can't deal with ImageLayout hint
112: /* It's a integer translate. */
113: return new TranslateIntOpImage(source, hints, (int) xTrans,
114: (int) yTrans);
115: }
116:
117: if (interp instanceof InterpolationNearest) {
118: return new MlibScaleNearestOpImage(source, extender, hints,
119: layout, xScale, yScale, xTrans, yTrans, interp);
120: } else if (interp instanceof InterpolationBilinear) {
121: return new MlibScaleBilinearOpImage(source, extender,
122: hints, layout, xScale, yScale, xTrans, yTrans,
123: interp);
124: } else if (interp instanceof InterpolationBicubic
125: || interp instanceof InterpolationBicubic2) {
126: return new MlibScaleBicubicOpImage(source, extender, hints,
127: layout, xScale, yScale, xTrans, yTrans, interp);
128: } else if (interp instanceof InterpolationTable) {
129: return new MlibScaleTableOpImage(source, extender, hints,
130: layout, xScale, yScale, xTrans, yTrans, interp);
131: } else {
132: /* Other kinds of interpolation cannot be handled via mlib. */
133: return null;
134: }
135: }
136: }
|