001: /*
002: * $RCSfile: RectIterFallback.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:55:43 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.iterator;
013:
014: import java.awt.Rectangle;
015: import java.awt.image.DataBuffer;
016: import java.awt.image.Raster;
017: import java.awt.image.RenderedImage;
018: import java.awt.image.SampleModel;
019: import javax.media.jai.PlanarImage;
020: import javax.media.jai.iterator.RectIter;
021:
022: /**
023: * @since EA2
024: */
025: public class RectIterFallback implements RectIter {
026:
027: /** The source image. */
028: protected RenderedImage im;
029:
030: /** The iterator bouning rectangle. */
031: protected Rectangle bounds;
032:
033: /** The SampleModel for the tiles of the source image. */
034: protected SampleModel sampleModel;
035:
036: /** The number of bands of the source image. */
037: protected int numBands;
038:
039: /** The width of tiles in the source image. */
040: protected int tileWidth;
041:
042: /** The height of tiles in the source image. */
043: protected int tileHeight;
044:
045: /** The X offset of the source image tile grid. */
046: protected int tileGridXOffset;
047:
048: /** The Y offset of the source image tile grid. */
049: protected int tileGridYOffset;
050:
051: /** The tile index of the leftmost column in the iterator's bounds. */
052: protected int startTileX;
053:
054: /** The tile index of the topmost row in the iterator's bounds. */
055: protected int startTileY;
056:
057: /** The (inclusive) smallest X coordinate of the current tile. */
058: protected int tileXStart;
059:
060: /** The (inclusive) largest X coordinate of the current tile. */
061: protected int tileXEnd;
062:
063: /** The (inclusive) smallest Y coordinate of the current tile. */
064: protected int tileYStart;
065:
066: /** The (inclusive) largest Y coordinate of the current tile. */
067: protected int tileYEnd;
068:
069: /** The next leftwards tile or image boundary. */
070: protected int prevXBoundary;
071:
072: /** The next rightwards tile or image boundary. */
073: protected int nextXBoundary;
074:
075: /** The next upwards tile or image boundary. */
076: protected int prevYBoundary;
077:
078: /** The next downwards tile or image boundary. */
079: protected int nextYBoundary;
080:
081: /** The X index of the current tile. */
082: protected int tileX;
083:
084: /** The Y index of the current tile. */
085: protected int tileY;
086:
087: /** The (inclusive) largest X coordinate of the bounding rectangle. */
088: protected int lastX;
089:
090: /** The (inclusive) largest Y coordinate of the bounding rectangle. */
091: protected int lastY;
092:
093: /** The current X pixel position. */
094: protected int x;
095:
096: /** The current Y pixel position. */
097: protected int y;
098:
099: /** The current X pixel position minus the sample model translation . */
100: protected int localX;
101:
102: /** The current Y pixel position minus the sample model translation . */
103: protected int localY;
104:
105: /** The X translation factor of the SampleModel of the current tile. */
106: protected int sampleModelTranslateX = 0;
107:
108: /** The X translation factor of the SampleModel of the current tile. */
109: protected int sampleModelTranslateY = 0;
110:
111: /** The current band offset. */
112: protected int b;
113:
114: /** The DataBuffer of the current tile. */
115: protected DataBuffer dataBuffer = null;
116:
117: public RectIterFallback(RenderedImage im, Rectangle bounds) {
118: this .im = im;
119: this .bounds = bounds;
120:
121: this .sampleModel = im.getSampleModel();
122: this .numBands = sampleModel.getNumBands();
123:
124: this .tileGridXOffset = im.getTileGridXOffset();
125: this .tileGridYOffset = im.getTileGridYOffset();
126: this .tileWidth = im.getTileWidth();
127: this .tileHeight = im.getTileHeight();
128:
129: this .startTileX = PlanarImage.XToTileX(bounds.x,
130: tileGridXOffset, tileWidth);
131: this .startTileY = PlanarImage.YToTileY(bounds.y,
132: tileGridYOffset, tileHeight);
133:
134: this .tileX = startTileX;
135: this .tileY = startTileY;
136:
137: this .lastX = bounds.x + bounds.width - 1;
138: this .lastY = bounds.y + bounds.height - 1;
139:
140: localX = x = bounds.x;
141: localY = y = bounds.y;
142: b = 0;
143:
144: setTileXBounds();
145: setTileYBounds();
146: setDataBuffer();
147: }
148:
149: protected final void setTileXBounds() {
150: tileXStart = tileX * tileWidth + tileGridXOffset;
151: tileXEnd = tileXStart + tileWidth - 1;
152:
153: prevXBoundary = Math.max(tileXStart, bounds.x);
154: nextXBoundary = Math.min(tileXEnd, lastX);
155: }
156:
157: protected final void setTileYBounds() {
158: tileYStart = tileY * tileHeight + tileGridYOffset;
159: tileYEnd = tileYStart + tileHeight - 1;
160:
161: prevYBoundary = Math.max(tileYStart, bounds.y);
162: nextYBoundary = Math.min(tileYEnd, lastY);
163: }
164:
165: protected void setDataBuffer() {
166: Raster tile = im.getTile(tileX, tileY);
167: this .dataBuffer = tile.getDataBuffer();
168:
169: int newSampleModelTranslateX = tile.getSampleModelTranslateX();
170: int newSampleModelTranslateY = tile.getSampleModelTranslateY();
171: localX += sampleModelTranslateX - newSampleModelTranslateX;
172: localY += sampleModelTranslateY - newSampleModelTranslateY;
173:
174: this .sampleModelTranslateX = newSampleModelTranslateX;
175: this .sampleModelTranslateY = newSampleModelTranslateY;
176: }
177:
178: public void startLines() {
179: y = bounds.y;
180: localY = y - sampleModelTranslateY;
181: tileY = startTileY;
182: setTileYBounds();
183: setDataBuffer();
184: }
185:
186: public void nextLine() {
187: ++y;
188: ++localY;
189: }
190:
191: public void jumpLines(int num) {
192: int jumpY = y + num;
193: if (jumpY < bounds.y || jumpY > lastY) {
194: // Jumped outside the image.
195: throw new IndexOutOfBoundsException(JaiI18N
196: .getString("RectIterFallback1"));
197: }
198:
199: y = jumpY;
200: localY += num;
201:
202: if (y < prevYBoundary || y > nextYBoundary) {
203: this .tileY = PlanarImage.YToTileY(y, tileGridYOffset,
204: tileHeight);
205: setTileYBounds();
206: setDataBuffer();
207: }
208: }
209:
210: public boolean finishedLines() {
211: if (y > nextYBoundary) {
212: if (y > lastY) {
213: return true;
214: } else {
215: ++tileY;
216: tileYStart += tileHeight;
217: tileYEnd += tileHeight;
218: prevYBoundary = Math.max(tileYStart, bounds.y);
219: nextYBoundary = Math.min(tileYEnd, lastY);
220:
221: setDataBuffer();
222: return false;
223: }
224: } else {
225: return false;
226: }
227: }
228:
229: public boolean nextLineDone() {
230: nextLine();
231: return finishedLines();
232: }
233:
234: public void startPixels() {
235: x = bounds.x;
236: localX = x - sampleModelTranslateX;
237: tileX = startTileX;
238: setTileXBounds();
239: setDataBuffer();
240: }
241:
242: public void nextPixel() {
243: ++x;
244: ++localX;
245: }
246:
247: public void jumpPixels(int num) {
248: int jumpX = x + num;
249: if (jumpX < bounds.x || jumpX > lastX) {
250: // Jumped outside the image.
251: throw new IndexOutOfBoundsException(JaiI18N
252: .getString("RectIterFallback0"));
253: }
254:
255: x = jumpX;
256: localX += num;
257:
258: if (x < prevXBoundary || x > nextXBoundary) {
259: this .tileX = PlanarImage.XToTileX(x, tileGridXOffset,
260: tileWidth);
261: setTileXBounds();
262: setDataBuffer();
263: }
264: }
265:
266: public boolean finishedPixels() {
267: if (x > nextXBoundary) {
268: if (x > lastX) {
269: return true;
270: } else {
271: ++tileX;
272: tileXStart += tileWidth;
273: tileXEnd += tileWidth;
274: prevXBoundary = Math.max(tileXStart, bounds.x);
275: nextXBoundary = Math.min(tileXEnd, lastX);
276: setDataBuffer();
277: return false;
278: }
279: } else {
280: return false;
281: }
282: }
283:
284: public boolean nextPixelDone() {
285: nextPixel();
286: return finishedPixels();
287: }
288:
289: public void startBands() {
290: b = 0;
291: }
292:
293: public void nextBand() {
294: ++b;
295: }
296:
297: public boolean nextBandDone() {
298: nextBand();
299: return finishedBands();
300: }
301:
302: public boolean finishedBands() {
303: return b >= numBands;
304: }
305:
306: public int getSample() {
307: return sampleModel.getSample(localX, localY, b, dataBuffer);
308: }
309:
310: public int getSample(int b) {
311: return sampleModel.getSample(localX, localY, b, dataBuffer);
312: }
313:
314: public float getSampleFloat() {
315: return sampleModel
316: .getSampleFloat(localX, localY, b, dataBuffer);
317: }
318:
319: public float getSampleFloat(int b) {
320: return sampleModel
321: .getSampleFloat(localX, localY, b, dataBuffer);
322: }
323:
324: public double getSampleDouble() {
325: return sampleModel.getSampleDouble(localX, localY, b,
326: dataBuffer);
327: }
328:
329: public double getSampleDouble(int b) {
330: return sampleModel.getSampleDouble(localX, localY, b,
331: dataBuffer);
332: }
333:
334: public int[] getPixel(int[] iArray) {
335: return sampleModel.getPixel(localX, localY, iArray, dataBuffer);
336: }
337:
338: public float[] getPixel(float[] fArray) {
339: return sampleModel.getPixel(localX, localY, fArray, dataBuffer);
340: }
341:
342: public double[] getPixel(double[] dArray) {
343: return sampleModel.getPixel(localX, localY, dArray, dataBuffer);
344: }
345: }
|