001: /*
002: * $RCSfile: MinFilterXOpImage.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:35 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.opimage;
013:
014: import java.awt.Rectangle;
015: import java.awt.image.DataBuffer;
016: import java.awt.image.SampleModel;
017: import java.awt.image.Raster;
018: import java.awt.image.RenderedImage;
019: import java.awt.image.WritableRaster;
020: import java.awt.image.renderable.ParameterBlock;
021: import java.awt.image.renderable.RenderedImageFactory;
022: import javax.media.jai.AreaOpImage;
023: import javax.media.jai.BorderExtender;
024: import javax.media.jai.ImageLayout;
025: import javax.media.jai.OpImage;
026: import javax.media.jai.RasterAccessor;
027: import java.util.Map;
028: import javax.media.jai.operator.MinFilterDescriptor;
029:
030: // import com.sun.media.jai.test.OpImageTester;
031:
032: /**
033: * An OpImage class to perform min filtering on a source image.
034: *
035: */
036: final class MinFilterXOpImage extends MinFilterOpImage {
037:
038: /**
039: * Creates a MinFilterXOpImage with the given source and
040: * maskSize. The image dimensions are derived from the source
041: * image. The tile grid layout, SampleModel, and ColorModel may
042: * optionally be specified by an ImageLayout object.
043: *
044: * @param source a RenderedImage.
045: * @param extender a BorderExtender, or null.
046: * @param layout an ImageLayout optionally containing the tile grid layout,
047: * SampleModel, and ColorModel, or null.
048: */
049: public MinFilterXOpImage(RenderedImage source,
050: BorderExtender extender, Map config, ImageLayout layout,
051: int maskSize) {
052: super (source, extender, config, layout,
053: MinFilterDescriptor.MIN_MASK_PLUS, maskSize);
054: }
055:
056: protected void byteLoop(RasterAccessor src, RasterAccessor dst,
057: int filterSize) {
058: int dwidth = dst.getWidth();
059: int dheight = dst.getHeight();
060: int dnumBands = dst.getNumBands();
061:
062: byte dstDataArrays[][] = dst.getByteDataArrays();
063: int dstBandOffsets[] = dst.getBandOffsets();
064: int dstPixelStride = dst.getPixelStride();
065: int dstScanlineStride = dst.getScanlineStride();
066:
067: byte srcDataArrays[][] = src.getByteDataArrays();
068: int srcBandOffsets[] = src.getBandOffsets();
069: int srcPixelStride = src.getPixelStride();
070: int srcScanlineStride = src.getScanlineStride();
071: int scanPlusPixelStride = srcScanlineStride + srcPixelStride;
072: int scanMinusPixelStride = srcScanlineStride - srcPixelStride;
073: int topRightOffset = srcPixelStride * (filterSize - 1);
074:
075: int minval, val;
076: int wp = filterSize;
077: int offset = filterSize / 2;
078:
079: for (int k = 0; k < dnumBands; k++) {
080: byte dstData[] = dstDataArrays[k];
081: byte srcData[] = srcDataArrays[k];
082: int srcScanlineOffset = srcBandOffsets[k];
083: int dstScanlineOffset = dstBandOffsets[k];
084: for (int j = 0; j < dheight; j++) {
085: int srcPixelOffset = srcScanlineOffset;
086: int dstPixelOffset = dstScanlineOffset;
087:
088: for (int i = 0; i < dwidth; i++) {
089: minval = Integer.MAX_VALUE;
090:
091: // figure out where the top left of the X starts
092: int imageOffset = srcPixelOffset;
093: for (int u = 0; u < wp; u++) {
094: val = (int) (srcData[imageOffset] & 0xff);
095: imageOffset += scanPlusPixelStride;
096: minval = (val < minval) ? val : minval;
097: }
098:
099: // figure out where the top right of the X starts
100: imageOffset = srcPixelOffset + topRightOffset;
101:
102: for (int v = 0; v < wp; v++) {
103: val = (int) (srcData[imageOffset] & 0xff);
104: imageOffset += scanMinusPixelStride;
105: minval = (val < minval) ? val : minval;
106: }
107:
108: dstData[dstPixelOffset] = (byte) minval;
109: srcPixelOffset += srcPixelStride;
110: dstPixelOffset += dstPixelStride;
111: }
112: srcScanlineOffset += srcScanlineStride;
113: dstScanlineOffset += dstScanlineStride;
114: }
115: }
116: }
117:
118: protected void shortLoop(RasterAccessor src, RasterAccessor dst,
119: int filterSize) {
120: int dwidth = dst.getWidth();
121: int dheight = dst.getHeight();
122: int dnumBands = dst.getNumBands();
123:
124: short dstDataArrays[][] = dst.getShortDataArrays();
125: int dstBandOffsets[] = dst.getBandOffsets();
126: int dstPixelStride = dst.getPixelStride();
127: int dstScanlineStride = dst.getScanlineStride();
128:
129: short srcDataArrays[][] = src.getShortDataArrays();
130: int srcBandOffsets[] = src.getBandOffsets();
131: int srcPixelStride = src.getPixelStride();
132: int srcScanlineStride = src.getScanlineStride();
133: int scanPlusPixelStride = srcScanlineStride + srcPixelStride;
134: int scanMinusPixelStride = srcScanlineStride - srcPixelStride;
135: int topRightOffset = srcPixelStride * (filterSize - 1);
136:
137: int minval, val;
138: int wp = filterSize;
139: int offset = filterSize / 2;
140:
141: for (int k = 0; k < dnumBands; k++) {
142: short dstData[] = dstDataArrays[k];
143: short srcData[] = srcDataArrays[k];
144: int srcScanlineOffset = srcBandOffsets[k];
145: int dstScanlineOffset = dstBandOffsets[k];
146: for (int j = 0; j < dheight; j++) {
147: int srcPixelOffset = srcScanlineOffset;
148: int dstPixelOffset = dstScanlineOffset;
149:
150: for (int i = 0; i < dwidth; i++) {
151: minval = Integer.MAX_VALUE;
152:
153: // figure out where the top left of the X starts
154: int imageOffset = srcPixelOffset;
155: for (int u = 0; u < wp; u++) {
156: val = (int) (srcData[imageOffset]);
157: imageOffset += scanPlusPixelStride;
158: minval = (val < minval) ? val : minval;
159: }
160:
161: // figure out where the top right of the X starts
162: imageOffset = srcPixelOffset + topRightOffset;
163:
164: for (int v = 0; v < wp; v++) {
165: val = (int) (srcData[imageOffset]);
166: imageOffset += scanMinusPixelStride;
167: minval = (val < minval) ? val : minval;
168: }
169:
170: dstData[dstPixelOffset] = (short) minval;
171: srcPixelOffset += srcPixelStride;
172: dstPixelOffset += dstPixelStride;
173: }
174: srcScanlineOffset += srcScanlineStride;
175: dstScanlineOffset += dstScanlineStride;
176: }
177: }
178: }
179:
180: protected void ushortLoop(RasterAccessor src, RasterAccessor dst,
181: int filterSize) {
182: int dwidth = dst.getWidth();
183: int dheight = dst.getHeight();
184: int dnumBands = dst.getNumBands();
185:
186: short dstDataArrays[][] = dst.getShortDataArrays();
187: int dstBandOffsets[] = dst.getBandOffsets();
188: int dstPixelStride = dst.getPixelStride();
189: int dstScanlineStride = dst.getScanlineStride();
190:
191: short srcDataArrays[][] = src.getShortDataArrays();
192: int srcBandOffsets[] = src.getBandOffsets();
193: int srcPixelStride = src.getPixelStride();
194: int srcScanlineStride = src.getScanlineStride();
195: int scanPlusPixelStride = srcScanlineStride + srcPixelStride;
196: int scanMinusPixelStride = srcScanlineStride - srcPixelStride;
197: int topRightOffset = srcPixelStride * (filterSize - 1);
198:
199: int minval, val;
200: int wp = filterSize;
201: int offset = filterSize / 2;
202:
203: for (int k = 0; k < dnumBands; k++) {
204: short dstData[] = dstDataArrays[k];
205: short srcData[] = srcDataArrays[k];
206: int srcScanlineOffset = srcBandOffsets[k];
207: int dstScanlineOffset = dstBandOffsets[k];
208: for (int j = 0; j < dheight; j++) {
209: int srcPixelOffset = srcScanlineOffset;
210: int dstPixelOffset = dstScanlineOffset;
211:
212: for (int i = 0; i < dwidth; i++) {
213: minval = Integer.MAX_VALUE;
214:
215: // figure out where the top left of the X starts
216: int imageOffset = srcPixelOffset;
217: for (int u = 0; u < wp; u++) {
218: val = (int) (srcData[imageOffset] & 0xffff);
219: imageOffset += scanPlusPixelStride;
220: minval = (val < minval) ? val : minval;
221: }
222:
223: // figure out where the top right of the X starts
224: imageOffset = srcPixelOffset + topRightOffset;
225:
226: for (int v = 0; v < wp; v++) {
227: val = (int) (srcData[imageOffset] & 0xffff);
228: imageOffset += scanMinusPixelStride;
229: minval = (val < minval) ? val : minval;
230: }
231:
232: dstData[dstPixelOffset] = (short) minval;
233: srcPixelOffset += srcPixelStride;
234: dstPixelOffset += dstPixelStride;
235: }
236: srcScanlineOffset += srcScanlineStride;
237: dstScanlineOffset += dstScanlineStride;
238: }
239: }
240: }
241:
242: protected void intLoop(RasterAccessor src, RasterAccessor dst,
243: int filterSize) {
244: int dwidth = dst.getWidth();
245: int dheight = dst.getHeight();
246: int dnumBands = dst.getNumBands();
247:
248: int dstDataArrays[][] = dst.getIntDataArrays();
249: int dstBandOffsets[] = dst.getBandOffsets();
250: int dstPixelStride = dst.getPixelStride();
251: int dstScanlineStride = dst.getScanlineStride();
252:
253: int srcDataArrays[][] = src.getIntDataArrays();
254: int srcBandOffsets[] = src.getBandOffsets();
255: int srcPixelStride = src.getPixelStride();
256: int srcScanlineStride = src.getScanlineStride();
257: int scanPlusPixelStride = srcScanlineStride + srcPixelStride;
258: int scanMinusPixelStride = srcScanlineStride - srcPixelStride;
259: int topRightOffset = srcPixelStride * (filterSize - 1);
260:
261: int minval, val;
262: int wp = filterSize;
263: int offset = filterSize / 2;
264:
265: for (int k = 0; k < dnumBands; k++) {
266: int dstData[] = dstDataArrays[k];
267: int srcData[] = srcDataArrays[k];
268: int srcScanlineOffset = srcBandOffsets[k];
269: int dstScanlineOffset = dstBandOffsets[k];
270: for (int j = 0; j < dheight; j++) {
271: int srcPixelOffset = srcScanlineOffset;
272: int dstPixelOffset = dstScanlineOffset;
273:
274: for (int i = 0; i < dwidth; i++) {
275: minval = Integer.MAX_VALUE;
276:
277: // figure out where the top left of the X starts
278: int imageOffset = srcPixelOffset;
279: for (int u = 0; u < wp; u++) {
280: val = srcData[imageOffset];
281: imageOffset += scanPlusPixelStride;
282: minval = (val < minval) ? val : minval;
283: }
284:
285: // figure out where the top right of the X starts
286: imageOffset = srcPixelOffset + topRightOffset;
287:
288: for (int v = 0; v < wp; v++) {
289: val = srcData[imageOffset];
290: imageOffset += scanMinusPixelStride;
291: minval = (val < minval) ? val : minval;
292: }
293:
294: dstData[dstPixelOffset] = minval;
295: srcPixelOffset += srcPixelStride;
296: dstPixelOffset += dstPixelStride;
297: }
298: srcScanlineOffset += srcScanlineStride;
299: dstScanlineOffset += dstScanlineStride;
300: }
301: }
302: }
303:
304: protected void floatLoop(RasterAccessor src, RasterAccessor dst,
305: int filterSize) {
306: int dwidth = dst.getWidth();
307: int dheight = dst.getHeight();
308: int dnumBands = dst.getNumBands();
309:
310: float dstDataArrays[][] = dst.getFloatDataArrays();
311: int dstBandOffsets[] = dst.getBandOffsets();
312: int dstPixelStride = dst.getPixelStride();
313: int dstScanlineStride = dst.getScanlineStride();
314:
315: float srcDataArrays[][] = src.getFloatDataArrays();
316: int srcBandOffsets[] = src.getBandOffsets();
317: int srcPixelStride = src.getPixelStride();
318: int srcScanlineStride = src.getScanlineStride();
319: int scanPlusPixelStride = srcScanlineStride + srcPixelStride;
320: int scanMinusPixelStride = srcScanlineStride - srcPixelStride;
321: int topRightOffset = srcPixelStride * (filterSize - 1);
322:
323: float minval, val;
324: int wp = filterSize;
325: int offset = filterSize / 2;
326:
327: for (int k = 0; k < dnumBands; k++) {
328: float dstData[] = dstDataArrays[k];
329: float srcData[] = srcDataArrays[k];
330: int srcScanlineOffset = srcBandOffsets[k];
331: int dstScanlineOffset = dstBandOffsets[k];
332: for (int j = 0; j < dheight; j++) {
333: int srcPixelOffset = srcScanlineOffset;
334: int dstPixelOffset = dstScanlineOffset;
335:
336: for (int i = 0; i < dwidth; i++) {
337: minval = Float.MAX_VALUE;
338:
339: // figure out where the top left of the X starts
340: int imageOffset = srcPixelOffset;
341: for (int u = 0; u < wp; u++) {
342: val = srcData[imageOffset];
343: imageOffset += scanPlusPixelStride;
344: minval = (val < minval) ? val : minval;
345: }
346:
347: // figure out where the top right of the X starts
348: imageOffset = srcPixelOffset + topRightOffset;
349:
350: for (int v = 0; v < wp; v++) {
351: val = srcData[imageOffset];
352: imageOffset += scanMinusPixelStride;
353: minval = (val < minval) ? val : minval;
354: }
355:
356: dstData[dstPixelOffset] = minval;
357: srcPixelOffset += srcPixelStride;
358: dstPixelOffset += dstPixelStride;
359: }
360: srcScanlineOffset += srcScanlineStride;
361: dstScanlineOffset += dstScanlineStride;
362: }
363: }
364: }
365:
366: protected void doubleLoop(RasterAccessor src, RasterAccessor dst,
367: int filterSize) {
368: int dwidth = dst.getWidth();
369: int dheight = dst.getHeight();
370: int dnumBands = dst.getNumBands();
371:
372: double dstDataArrays[][] = dst.getDoubleDataArrays();
373: int dstBandOffsets[] = dst.getBandOffsets();
374: int dstPixelStride = dst.getPixelStride();
375: int dstScanlineStride = dst.getScanlineStride();
376:
377: double srcDataArrays[][] = src.getDoubleDataArrays();
378: int srcBandOffsets[] = src.getBandOffsets();
379: int srcPixelStride = src.getPixelStride();
380: int srcScanlineStride = src.getScanlineStride();
381: int scanPlusPixelStride = srcScanlineStride + srcPixelStride;
382: int scanMinusPixelStride = srcScanlineStride - srcPixelStride;
383: int topRightOffset = srcPixelStride * (filterSize - 1);
384:
385: double minval, val;
386: int wp = filterSize;
387: int offset = filterSize / 2;
388:
389: for (int k = 0; k < dnumBands; k++) {
390: double dstData[] = dstDataArrays[k];
391: double srcData[] = srcDataArrays[k];
392: int srcScanlineOffset = srcBandOffsets[k];
393: int dstScanlineOffset = dstBandOffsets[k];
394: for (int j = 0; j < dheight; j++) {
395: int srcPixelOffset = srcScanlineOffset;
396: int dstPixelOffset = dstScanlineOffset;
397:
398: for (int i = 0; i < dwidth; i++) {
399: minval = Double.MAX_VALUE;
400:
401: // figure out where the top left of the X starts
402: int imageOffset = srcPixelOffset;
403: for (int u = 0; u < wp; u++) {
404: val = srcData[imageOffset];
405: imageOffset += scanPlusPixelStride;
406: minval = (val < minval) ? val : minval;
407: }
408:
409: // figure out where the top right of the X starts
410: imageOffset = srcPixelOffset + topRightOffset;
411:
412: for (int v = 0; v < wp; v++) {
413: val = srcData[imageOffset];
414: imageOffset += scanMinusPixelStride;
415: minval = (val < minval) ? val : minval;
416: }
417:
418: dstData[dstPixelOffset] = minval;
419: srcPixelOffset += srcPixelStride;
420: dstPixelOffset += dstPixelStride;
421: }
422: srcScanlineOffset += srcScanlineStride;
423: dstScanlineOffset += dstScanlineStride;
424: }
425: }
426: }
427:
428: // public static OpImage createTestImage(OpImageTester oit) {
429: // return new MinFilterXOpImage(oit.getSource(), null, null,
430: // new ImageLayout(oit.getSource()),
431: // 3);
432: // }
433: }
|