001: /*
002: * $RCSfile: TranslateIntOpImage.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:46 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.opimage;
013:
014: import java.awt.Point;
015: import java.awt.Rectangle;
016: import java.awt.RenderingHints;
017: import java.awt.image.Raster;
018: import java.awt.image.RenderedImage;
019: import java.util.Map;
020: import java.util.Vector;
021: import javax.media.jai.ImageLayout;
022: import javax.media.jai.JAI;
023: import javax.media.jai.OpImage;
024:
025: /**
026: * An OpImage to translate an image by in integral number of pixels.
027: *
028: * <p> The translation is accomplished by simply shifting the tile
029: * grid.
030: */
031: public final class TranslateIntOpImage extends OpImage {
032:
033: private int transX;
034: private int transY;
035:
036: private static ImageLayout layoutHelper(RenderedImage source,
037: int transX, int transY) {
038:
039: ImageLayout layout = new ImageLayout(source.getMinX() + transX,
040: source.getMinY() + transY, source.getWidth(), source
041: .getHeight(), source.getTileGridXOffset()
042: + transX, source.getTileGridYOffset() + transY,
043: source.getTileWidth(), source.getTileHeight(), source
044: .getSampleModel(), source.getColorModel());
045: return layout;
046: }
047:
048: // Since this operation does not touch the data at all, we do not need
049: // to expand the IndexColorModel
050: private static Map configHelper(Map configuration) {
051:
052: Map config;
053: if (configuration == null) {
054:
055: config = new RenderingHints(
056: JAI.KEY_REPLACE_INDEX_COLOR_MODEL, Boolean.FALSE);
057: } else {
058:
059: config = configuration;
060:
061: if (!(config.containsKey(JAI.KEY_REPLACE_INDEX_COLOR_MODEL))) {
062:
063: RenderingHints hints = (RenderingHints) configuration;
064: config = (RenderingHints) hints.clone();
065: config.put(JAI.KEY_REPLACE_INDEX_COLOR_MODEL,
066: Boolean.FALSE);
067: config.remove(JAI.KEY_TILE_CACHE);
068:
069: } else if (config.containsKey(JAI.KEY_TILE_CACHE)) {
070:
071: RenderingHints hints = (RenderingHints) configuration;
072: config = (RenderingHints) hints.clone();
073: config.remove(JAI.KEY_TILE_CACHE);
074: }
075: }
076:
077: return config;
078: }
079:
080: /**
081: * Construct an TranslateIntOpImage.
082: *
083: * @param source a RenderedImage.
084: * @param config Configurable attributes of the image including
085: * configuration variables indexed by
086: * <code>RenderingHints.Key</code>s and image properties indexed
087: * by <code>String</code>s or <code>CaselessStringKey</code>s.
088: * This is simply forwarded to the superclass constructor.
089: * @param transX the number of pixels of horizontal translation.
090: * @param transY the number of pixels of vertical translation.
091: */
092: public TranslateIntOpImage(RenderedImage source, Map config,
093: int transX, int transY) {
094: super (vectorize(source), layoutHelper(source, transX, transY),
095: configHelper(config), false);
096: this .transX = transX;
097: this .transY = transY;
098: }
099:
100: /**
101: * Returns <code>false</code> as <code>computeTile()</code> invocations
102: * return child <code>Raster</code>s of the <code>RenderedImage</code>
103: * source and are therefore not unique objects in the global sense.
104: */
105: public boolean computesUniqueTiles() {
106: return false;
107: }
108:
109: /**
110: * Override computeTile() simply to invoke getTile(). Required
111: * so that the TileScheduler may invoke computeTile().
112: */
113: public Raster computeTile(int tileX, int tileY) {
114: return getTile(tileX, tileY);
115: }
116:
117: /**
118: * Get a tile.
119: *
120: * @param tileX The X index of the tile.
121: * @param tileY The Y index of the tile.
122: */
123: public Raster getTile(int tileX, int tileY) {
124: Raster tile = getSource(0).getTile(tileX, tileY);
125:
126: if (tile == null)
127: return null;
128:
129: return tile.createTranslatedChild(tileXToX(tileX),
130: tileYToY(tileY));
131: }
132:
133: /**
134: * Returns a conservative estimate of the destination region that
135: * can potentially be affected by the pixels of a rectangle of a
136: * given source.
137: *
138: * @param sourceRect the Rectangle in source coordinates.
139: * @param sourceIndex the index of the source image.
140: * @return a Rectangle indicating the potentially affected
141: * destination region. or null if the region is unknown.
142: * @throws IllegalArgumentException if the source index is
143: * negative or greater than that of the last source.
144: * @throws IllegalArgumentException if sourceRect is null.
145: */
146: public Rectangle mapSourceRect(Rectangle sourceRect, int sourceIndex) {
147:
148: if (sourceRect == null) {
149: throw new IllegalArgumentException(JaiI18N
150: .getString("Generic0"));
151: }
152:
153: if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
154: throw new IllegalArgumentException(JaiI18N
155: .getString("TranslateIntOpImage0"));
156: }
157:
158: Rectangle r = new Rectangle(sourceRect);
159: r.translate(transX, transY);
160: return r;
161: }
162:
163: /**
164: * Returns a conservative estimate of the region of a specified
165: * source that is required in order to compute the pixels of a
166: * given destination rectangle.
167: *
168: * @param destRect the Rectangle in destination coordinates.
169: * @param sourceIndex the index of the source image.
170: * @return a Rectangle indicating the required source region.
171: * @throws IllegalArgumentException if the source index is
172: * negative or greater than that of the last source.
173: * @throws IllegalArgumentException if destRect is null.
174: */
175: public Rectangle mapDestRect(Rectangle destRect, int sourceIndex) {
176:
177: if (destRect == null) {
178: throw new IllegalArgumentException(JaiI18N
179: .getString("Generic0"));
180: }
181:
182: if (sourceIndex < 0 || sourceIndex >= getNumSources()) {
183: throw new IllegalArgumentException(JaiI18N
184: .getString("TranslateIntOpImage0"));
185: }
186:
187: Rectangle r = new Rectangle(destRect);
188: r.translate(-transX, -transY);
189: return r;
190: }
191: }
|