001: /*
002: * $RCSfile: SubsampleBinaryToGrayCRIF.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:44 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.opimage;
013:
014: import java.awt.RenderingHints;
015: import java.awt.geom.AffineTransform;
016: import java.awt.geom.Rectangle2D;
017: import java.awt.image.DataBuffer;
018: import java.awt.image.MultiPixelPackedSampleModel;
019: import java.awt.image.RenderedImage;
020: import java.awt.image.SampleModel;
021: import java.awt.image.renderable.RenderedImageFactory;
022: import java.awt.image.renderable.RenderContext;
023: import java.awt.image.renderable.ParameterBlock;
024: import java.awt.image.renderable.RenderableImage;
025: import javax.media.jai.CRIFImpl;
026: import javax.media.jai.BorderExtender;
027: import javax.media.jai.ImageLayout;
028: import java.util.Map;
029:
030: /**
031: * @see SubsampleBinaryToGrayOpImage
032: */
033: public class SubsampleBinaryToGrayCRIF extends CRIFImpl {
034:
035: /** Constructor. */
036: public SubsampleBinaryToGrayCRIF() {
037: super ("subsamplebinarytogray");
038: }
039:
040: /**
041: * Creates a new instance of SubsampleBinaryToGrayOpImage in the rendered layer.
042: * This method satisfies the implementation of RIF.
043: *
044: * @param paramBlock The source image, the X and Y scale factor
045: */
046: public RenderedImage create(ParameterBlock paramBlock,
047: RenderingHints renderHints) {
048: // Get ImageLayout from renderHints if any.
049: ImageLayout layout = RIFUtil.getImageLayoutHint(renderHints);
050:
051: // Get BorderExtender from renderHints if any.
052: BorderExtender extender = RIFUtil
053: .getBorderExtenderHint(renderHints);
054:
055: RenderedImage source = paramBlock.getRenderedSource(0);
056: float xScale = paramBlock.getFloatParameter(0);
057: float yScale = paramBlock.getFloatParameter(1);
058:
059: // Check and see if we are scaling by 1.0 in both x and y and no
060: // translations. If so call the copy operation.
061: if (xScale == 1.0F && yScale == 1.0F) {
062: return new CopyOpImage(source, renderHints, layout);
063: }
064:
065: // The image is assumed to have
066: // a MultiPixelPackedSampleModel and a byte, ushort,
067: // or int DataBuffer we can access the pixel data directly.
068: // Note that there is a potential loophole that has not been
069: // resolved by Java2D as to whether the underlying DataBuffer
070: // must be of one of the standard types. Here we make the
071: // assumption that it will be -- we can't check without
072: // forcing an actual tile to be computed.
073: //
074: SampleModel sm = source.getSampleModel();
075: if ((sm instanceof MultiPixelPackedSampleModel)
076: && (sm.getSampleSize(0) == 1)
077: && (sm.getDataType() == DataBuffer.TYPE_BYTE
078: || sm.getDataType() == DataBuffer.TYPE_USHORT || sm
079: .getDataType() == DataBuffer.TYPE_INT)) {
080:
081: int srcWidth = source.getWidth();
082: int srcHeight = source.getHeight();
083: float floatTol = .1F * Math.min(xScale
084: / (srcWidth * xScale + 1.0F), yScale
085: / (srcHeight * yScale + 1.0F));
086: int invScale = (int) Math.round(1.0F / xScale);
087: if (Math.abs((float) invScale - 1.0F / xScale) < floatTol
088: && Math.abs((float) invScale - 1.0F / yScale) < floatTol) {
089: switch (invScale) {
090: case 2:
091: return new SubsampleBinaryToGray2x2OpImage(source,
092: layout, renderHints);
093: case 4:
094: return new SubsampleBinaryToGray4x4OpImage(source,
095: layout, renderHints);
096: default:
097: break;
098: }
099: }
100: return new SubsampleBinaryToGrayOpImage(source, layout,
101: renderHints, xScale, yScale);
102:
103: } else {
104: throw new IllegalArgumentException(JaiI18N
105: .getString("SubsampleBinaryToGray3"));
106: }
107: }
108:
109: /**
110: * Creates a new instance of <code>AffineOpImage</code>
111: * in the renderable layer. This method satisfies the
112: * implementation of CRIF.
113: */
114: public RenderedImage create(RenderContext renderContext,
115: ParameterBlock paramBlock) {
116: return paramBlock.getRenderedSource(0);
117: }
118:
119: /**
120: * Maps the output RenderContext into the RenderContext for the ith
121: * source.
122: * This method satisfies the implementation of CRIF.
123: *
124: * @param i The index of the source image.
125: * @param renderContext The renderContext being applied to the operation.
126: * @param paramBlock The ParameterBlock containing the sources
127: * and the translation factors.
128: * @param image The RenderableImageOp from which this method
129: * was called.
130: */
131: public RenderContext mapRenderContext(int i,
132: RenderContext renderContext, ParameterBlock paramBlock,
133: RenderableImage image) {
134:
135: float scale_x = paramBlock.getFloatParameter(0);
136: float scale_y = paramBlock.getFloatParameter(1);
137:
138: AffineTransform scale = new AffineTransform(scale_x, 0.0, 0.0,
139: scale_y, 0.0, 0.0);
140:
141: RenderContext RC = (RenderContext) renderContext.clone();
142: AffineTransform usr2dev = RC.getTransform();
143: usr2dev.concatenate(scale);
144: RC.setTransform(usr2dev);
145: return RC;
146: }
147:
148: /**
149: * Gets the bounding box for the output of <code>SubsampleBinaryToGrayOpImage</code>.
150: * This method satisfies the implementation of CRIF.
151: */
152: public Rectangle2D getBounds2D(ParameterBlock paramBlock) {
153:
154: RenderableImage source = paramBlock.getRenderableSource(0);
155:
156: float scale_x = paramBlock.getFloatParameter(0);
157: float scale_y = paramBlock.getFloatParameter(1);
158:
159: // Get the source dimensions
160: float x0 = (float) source.getMinX();
161: float y0 = (float) source.getMinY();
162: float w = (float) source.getWidth();
163: float h = (float) source.getHeight();
164:
165: // Forward map the source using x0, y0, w and h
166: float d_x0 = x0 * scale_x;
167: float d_y0 = y0 * scale_y;
168: float d_w = w * scale_x;
169: float d_h = h * scale_y;
170:
171: // debugging
172: // System.out.println("*** CRIF getBounds2D() ");
173:
174: return new Rectangle2D.Float(d_x0, d_y0, d_w, d_h);
175: }
176:
177: }
|