001: /*
002: * $RCSfile: SeparableConvolveOpImage.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:43 $
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.RasterAccessor;
026: import javax.media.jai.RasterFormatTag;
027: import javax.media.jai.KernelJAI;
028: import javax.media.jai.OpImage;
029: import java.util.Map;
030:
031: // import com.sun.media.jai.test.OpImageTester;
032:
033: /**
034: * An OpImage class to perform separable convolve on a source image.
035: *
036: *
037: */
038: final class SeparableConvolveOpImage extends AreaOpImage {
039:
040: static int byteLoopCounter = 0;
041:
042: protected KernelJAI kernel;
043: protected int kw, kh, kx, ky;
044:
045: protected float hValues[];
046: protected float vValues[];
047: protected float hTables[][];
048:
049: /**
050: * Creates a SeparableConvoveOpImage on the source
051: * with the given pre-rotated kernel. The image dimensions are
052: * derived the source image. The tile grid layout, SampleModel, and
053: * ColorModel may optionally be specified by an ImageLayout
054: * object.
055: *
056: * @param source a RenderedImage.
057: * @param extender a BorderExtender, or null.
058: * @param layout an ImageLayout optionally containing the tile grid layout,
059: * SampleModel, and ColorModel, or null.
060: * @param kernel a pre-rotated convolution kernel
061: */
062: public SeparableConvolveOpImage(RenderedImage source,
063: BorderExtender extender, Map config, ImageLayout layout,
064: KernelJAI kernel) {
065: super (source, layout, config, true, extender, kernel
066: .getLeftPadding(), kernel.getRightPadding(), kernel
067: .getTopPadding(), kernel.getBottomPadding());
068:
069: this .kernel = kernel;
070: kw = kernel.getWidth();
071: kh = kernel.getHeight();
072: kx = kernel.getXOrigin();
073: ky = kernel.getYOrigin();
074: hValues = kernel.getHorizontalKernelData();
075: vValues = kernel.getVerticalKernelData();
076:
077: if (sampleModel.getDataType() == DataBuffer.TYPE_BYTE) {
078: hTables = new float[hValues.length][256];
079: for (int i = 0; i < hValues.length; i++) {
080: float k = hValues[i];
081: for (int j = 0; j < 256; j++) {
082: byte b = (byte) j;
083: float f = (float) j;
084: hTables[i][b + 128] = k * f;
085: }
086: }
087: }
088: }
089:
090: /**
091: * Performs convolution on a specified rectangle. The sources are
092: * cobbled.
093: *
094: * @param sources an array of source Rasters, guaranteed to provide all
095: * necessary source data for computing the output.
096: * @param dest a WritableRaster tile containing the area to be computed.
097: * @param destRect the rectangle within dest to be processed.
098: */
099: protected void computeRect(Raster[] sources, WritableRaster dest,
100: Rectangle destRect) {
101: // Retrieve format tags.
102: RasterFormatTag[] formatTags = getFormatTags();
103:
104: Raster source = sources[0];
105: Rectangle srcRect = mapDestRect(destRect, 0);
106:
107: RasterAccessor srcAccessor = new RasterAccessor(source,
108: srcRect, formatTags[0], getSource(0).getColorModel());
109: RasterAccessor dstAccessor = new RasterAccessor(dest, destRect,
110: formatTags[1], this .getColorModel());
111:
112: switch (dstAccessor.getDataType()) {
113: case DataBuffer.TYPE_BYTE:
114: byteLoop(srcAccessor, dstAccessor);
115: break;
116: case DataBuffer.TYPE_INT:
117: intLoop(srcAccessor, dstAccessor);
118: break;
119: case DataBuffer.TYPE_SHORT:
120: shortLoop(srcAccessor, dstAccessor);
121: break;
122: case DataBuffer.TYPE_USHORT:
123: ushortLoop(srcAccessor, dstAccessor);
124: break;
125: case DataBuffer.TYPE_FLOAT:
126: floatLoop(srcAccessor, dstAccessor);
127: break;
128: case DataBuffer.TYPE_DOUBLE:
129: doubleLoop(srcAccessor, dstAccessor);
130: break;
131:
132: default:
133: }
134:
135: // If the RasterAccessor object set up a temporary buffer for the
136: // op to write to, tell the RasterAccessor to write that data
137: // to the raster no that we're done with it.
138: if (dstAccessor.isDataCopy()) {
139: dstAccessor.clampDataArrays();
140: dstAccessor.copyDataToRaster();
141: }
142: }
143:
144: protected void byteLoop(RasterAccessor src, RasterAccessor dst) {
145: int dwidth = dst.getWidth();
146: int dheight = dst.getHeight();
147: int dnumBands = dst.getNumBands();
148:
149: byte dstDataArrays[][] = dst.getByteDataArrays();
150: int dstBandOffsets[] = dst.getBandOffsets();
151: int dstPixelStride = dst.getPixelStride();
152: int dstScanlineStride = dst.getScanlineStride();
153:
154: byte srcDataArrays[][] = src.getByteDataArrays();
155: int srcBandOffsets[] = src.getBandOffsets();
156: int srcPixelStride = src.getPixelStride();
157: int srcScanlineStride = src.getScanlineStride();
158:
159: float tmpBuffer[] = new float[kh * dwidth];
160: int tmpBufferSize = kh * dwidth;
161:
162: for (int k = 0; k < dnumBands; k++) {
163: byte dstData[] = dstDataArrays[k];
164: byte srcData[] = srcDataArrays[k];
165: int srcScanlineOffset = srcBandOffsets[k];
166: int dstScanlineOffset = dstBandOffsets[k];
167:
168: int revolver = 0;
169: int kvRevolver = 0; // to match kernel vValues
170: for (int j = 0; j < kh - 1; j++) {
171: int srcPixelOffset = srcScanlineOffset;
172:
173: for (int i = 0; i < dwidth; i++) {
174: int imageOffset = srcPixelOffset;
175: float f = 0.0f;
176: for (int v = 0; v < kw; v++) {
177: f += hTables[v][srcData[imageOffset] + 128];
178: imageOffset += srcPixelStride;
179: }
180: tmpBuffer[revolver + i] = f;
181: srcPixelOffset += srcPixelStride;
182: }
183: revolver += dwidth;
184: srcScanlineOffset += srcScanlineStride;
185: }
186:
187: // srcScanlineStride already bumped by
188: // kh-1*scanlineStride
189: for (int j = 0; j < dheight; j++) {
190: int srcPixelOffset = srcScanlineOffset;
191: int dstPixelOffset = dstScanlineOffset;
192:
193: for (int i = 0; i < dwidth; i++) {
194: int imageOffset = srcPixelOffset;
195: float f = 0.0f;
196: for (int v = 0; v < kw; v++) {
197: f += hTables[v][srcData[imageOffset] + 128];
198: imageOffset += srcPixelStride;
199: }
200: tmpBuffer[revolver + i] = f;
201:
202: f = 0.5f;
203: // int a = 0;
204: // The vertical kernel must revolve as well
205: int b = kvRevolver + i;
206: for (int a = 0; a < kh; a++) {
207: f += tmpBuffer[b] * vValues[a];
208: b += dwidth;
209: if (b >= tmpBufferSize)
210: b -= tmpBufferSize;
211: }
212:
213: int val = (int) f;
214: if (val < 0) {
215: val = 0;
216: } else if (val > 255) {
217: val = 255;
218: }
219:
220: dstData[dstPixelOffset] = (byte) val;
221: srcPixelOffset += srcPixelStride;
222: dstPixelOffset += dstPixelStride;
223: }
224:
225: revolver += dwidth;
226: if (revolver == tmpBufferSize) {
227: revolver = 0;
228: }
229: kvRevolver += dwidth;
230: if (kvRevolver == tmpBufferSize) {
231: kvRevolver = 0;
232: }
233: srcScanlineOffset += srcScanlineStride;
234: dstScanlineOffset += dstScanlineStride;
235: }
236: }
237: }
238:
239: protected void shortLoop(RasterAccessor src, RasterAccessor dst) {
240: int dwidth = dst.getWidth();
241: int dheight = dst.getHeight();
242: int dnumBands = dst.getNumBands();
243:
244: short dstDataArrays[][] = dst.getShortDataArrays();
245: int dstBandOffsets[] = dst.getBandOffsets();
246: int dstPixelStride = dst.getPixelStride();
247: int dstScanlineStride = dst.getScanlineStride();
248:
249: short srcDataArrays[][] = src.getShortDataArrays();
250: int srcBandOffsets[] = src.getBandOffsets();
251: int srcPixelStride = src.getPixelStride();
252: int srcScanlineStride = src.getScanlineStride();
253:
254: float tmpBuffer[] = new float[kh * dwidth];
255: int tmpBufferSize = kh * dwidth;
256:
257: for (int k = 0; k < dnumBands; k++) {
258: short dstData[] = dstDataArrays[k];
259: short srcData[] = srcDataArrays[k];
260: int srcScanlineOffset = srcBandOffsets[k];
261: int dstScanlineOffset = dstBandOffsets[k];
262:
263: int revolver = 0;
264: int kvRevolver = 0; // to match kernel vValues
265: for (int j = 0; j < kh - 1; j++) {
266: int srcPixelOffset = srcScanlineOffset;
267:
268: for (int i = 0; i < dwidth; i++) {
269: int imageOffset = srcPixelOffset;
270: float f = 0.0f;
271: for (int v = 0; v < kw; v++) {
272: f += (srcData[imageOffset]) * hValues[v];
273: imageOffset += srcPixelStride;
274: }
275: tmpBuffer[revolver + i] = f;
276: srcPixelOffset += srcPixelStride;
277: }
278: revolver += dwidth;
279: srcScanlineOffset += srcScanlineStride;
280: }
281:
282: // srcScanlineStride already bumped by
283: // kh-1*scanlineStride
284:
285: for (int j = 0; j < dheight; j++) {
286: int srcPixelOffset = srcScanlineOffset;
287: int dstPixelOffset = dstScanlineOffset;
288:
289: for (int i = 0; i < dwidth; i++) {
290: int imageOffset = srcPixelOffset;
291: float f = 0.0f;
292: for (int v = 0; v < kw; v++) {
293: f += (srcData[imageOffset]) * hValues[v];
294: imageOffset += srcPixelStride;
295: }
296: tmpBuffer[revolver + i] = f;
297:
298: f = 0.5f;
299: int b = kvRevolver + i;
300: for (int a = 0; a < kh; a++) {
301: f += tmpBuffer[b] * vValues[a];
302: b += dwidth;
303: if (b >= tmpBufferSize)
304: b -= tmpBufferSize;
305: }
306:
307: int val = (int) f;
308: if (val < Short.MIN_VALUE) {
309: val = Short.MIN_VALUE;
310: } else if (val > Short.MAX_VALUE) {
311: val = Short.MAX_VALUE;
312: }
313:
314: dstData[dstPixelOffset] = (short) val;
315: srcPixelOffset += srcPixelStride;
316: dstPixelOffset += dstPixelStride;
317: }
318: revolver += dwidth;
319:
320: if (revolver == tmpBufferSize) {
321: revolver = 0;
322: }
323: kvRevolver += dwidth;
324: if (kvRevolver == tmpBufferSize) {
325: kvRevolver = 0;
326: }
327:
328: srcScanlineOffset += srcScanlineStride;
329: dstScanlineOffset += dstScanlineStride;
330: }
331: }
332:
333: }
334:
335: protected void ushortLoop(RasterAccessor src, RasterAccessor dst) {
336: int dwidth = dst.getWidth();
337: int dheight = dst.getHeight();
338: int dnumBands = dst.getNumBands();
339:
340: short dstDataArrays[][] = dst.getShortDataArrays();
341: int dstBandOffsets[] = dst.getBandOffsets();
342: int dstPixelStride = dst.getPixelStride();
343: int dstScanlineStride = dst.getScanlineStride();
344:
345: short srcDataArrays[][] = src.getShortDataArrays();
346: int srcBandOffsets[] = src.getBandOffsets();
347: int srcPixelStride = src.getPixelStride();
348: int srcScanlineStride = src.getScanlineStride();
349: float tmpBuffer[] = new float[kh * dwidth];
350: int tmpBufferSize = kh * dwidth;
351:
352: for (int k = 0; k < dnumBands; k++) {
353: short dstData[] = dstDataArrays[k];
354: short srcData[] = srcDataArrays[k];
355: int srcScanlineOffset = srcBandOffsets[k];
356: int dstScanlineOffset = dstBandOffsets[k];
357:
358: int revolver = 0;
359: int kvRevolver = 0; // to match kernel vValues
360: for (int j = 0; j < kh - 1; j++) {
361: int srcPixelOffset = srcScanlineOffset;
362:
363: for (int i = 0; i < dwidth; i++) {
364: int imageOffset = srcPixelOffset;
365: float f = 0.0f;
366: for (int v = 0; v < kw; v++) {
367: f += (srcData[imageOffset] & 0xffff)
368: * hValues[v];
369: imageOffset += srcPixelStride;
370: }
371: tmpBuffer[revolver + i] = f;
372: srcPixelOffset += srcPixelStride;
373: }
374: revolver += dwidth;
375: srcScanlineOffset += srcScanlineStride;
376: }
377:
378: // srcScanlineStride already bumped by
379: // kh-1*scanlineStride
380:
381: for (int j = 0; j < dheight; j++) {
382: int srcPixelOffset = srcScanlineOffset;
383: int dstPixelOffset = dstScanlineOffset;
384:
385: for (int i = 0; i < dwidth; i++) {
386: int imageOffset = srcPixelOffset;
387: float f = 0.0f;
388: for (int v = 0; v < kw; v++) {
389: f += (srcData[imageOffset] & 0xffff)
390: * hValues[v];
391: imageOffset += srcPixelStride;
392: }
393: tmpBuffer[revolver + i] = f;
394:
395: f = 0.5f;
396:
397: int b = kvRevolver + i;
398: for (int a = 0; a < kh; a++) {
399: f += tmpBuffer[b] * vValues[a];
400: b += dwidth;
401: if (b >= tmpBufferSize)
402: b -= tmpBufferSize;
403: }
404:
405: int val = (int) f;
406: if (val < 0) {
407: val = 0;
408: } else if (val > 0xffff) {
409: val = 0xffff;
410: }
411:
412: dstData[dstPixelOffset] = (short) val;
413: srcPixelOffset += srcPixelStride;
414: dstPixelOffset += dstPixelStride;
415: }
416: revolver += dwidth;
417: if (revolver == tmpBufferSize) {
418: revolver = 0;
419: }
420: kvRevolver += dwidth;
421: if (kvRevolver == tmpBufferSize) {
422: kvRevolver = 0;
423: }
424: srcScanlineOffset += srcScanlineStride;
425: dstScanlineOffset += dstScanlineStride;
426: }
427: }
428: }
429:
430: protected void intLoop(RasterAccessor src, RasterAccessor dst) {
431: int dwidth = dst.getWidth();
432: int dheight = dst.getHeight();
433: int dnumBands = dst.getNumBands();
434:
435: int dstDataArrays[][] = dst.getIntDataArrays();
436: int dstBandOffsets[] = dst.getBandOffsets();
437: int dstPixelStride = dst.getPixelStride();
438: int dstScanlineStride = dst.getScanlineStride();
439:
440: int srcDataArrays[][] = src.getIntDataArrays();
441: int srcBandOffsets[] = src.getBandOffsets();
442: int srcPixelStride = src.getPixelStride();
443: int srcScanlineStride = src.getScanlineStride();
444:
445: float tmpBuffer[] = new float[kh * dwidth];
446: int tmpBufferSize = kh * dwidth;
447:
448: for (int k = 0; k < dnumBands; k++) {
449: int dstData[] = dstDataArrays[k];
450: int srcData[] = srcDataArrays[k];
451: int srcScanlineOffset = srcBandOffsets[k];
452: int dstScanlineOffset = dstBandOffsets[k];
453:
454: int revolver = 0;
455: int kvRevolver = 0; // to match kernel vValues
456: for (int j = 0; j < kh - 1; j++) {
457: int srcPixelOffset = srcScanlineOffset;
458:
459: for (int i = 0; i < dwidth; i++) {
460: int imageOffset = srcPixelOffset;
461: float f = 0.0f;
462: for (int v = 0; v < kw; v++) {
463: f += (srcData[imageOffset]) * hValues[v];
464: imageOffset += srcPixelStride;
465: }
466: tmpBuffer[revolver + i] = f;
467: srcPixelOffset += srcPixelStride;
468: }
469: revolver += dwidth;
470: srcScanlineOffset += srcScanlineStride;
471: }
472:
473: // srcScanlineStride already bumped by
474: // kh-1*scanlineStride
475: for (int j = 0; j < dheight; j++) {
476: int srcPixelOffset = srcScanlineOffset;
477: int dstPixelOffset = dstScanlineOffset;
478:
479: for (int i = 0; i < dwidth; i++) {
480: int imageOffset = srcPixelOffset;
481: float f = 0.0f;
482: for (int v = 0; v < kw; v++) {
483: f += (srcData[imageOffset]) * hValues[v];
484: imageOffset += srcPixelStride;
485: }
486: tmpBuffer[revolver + i] = f;
487:
488: f = 0.5f;
489:
490: int b = kvRevolver + i;
491: for (int a = 0; a < kh; a++) {
492: f += tmpBuffer[b] * vValues[a];
493: b += dwidth;
494: if (b >= tmpBufferSize)
495: b -= tmpBufferSize;
496: }
497:
498: int val = (int) f;
499:
500: dstData[dstPixelOffset] = val;
501: srcPixelOffset += srcPixelStride;
502: dstPixelOffset += dstPixelStride;
503: }
504: revolver += dwidth;
505: if (revolver == tmpBufferSize) {
506: revolver = 0;
507: }
508: kvRevolver += dwidth;
509: if (kvRevolver == tmpBufferSize) {
510: kvRevolver = 0;
511: }
512: srcScanlineOffset += srcScanlineStride;
513: dstScanlineOffset += dstScanlineStride;
514: }
515: }
516:
517: }
518:
519: protected void floatLoop(RasterAccessor src, RasterAccessor dst) {
520: int dwidth = dst.getWidth();
521: int dheight = dst.getHeight();
522: int dnumBands = dst.getNumBands();
523:
524: float dstDataArrays[][] = dst.getFloatDataArrays();
525: int dstBandOffsets[] = dst.getBandOffsets();
526: int dstPixelStride = dst.getPixelStride();
527: int dstScanlineStride = dst.getScanlineStride();
528:
529: float srcDataArrays[][] = src.getFloatDataArrays();
530: int srcBandOffsets[] = src.getBandOffsets();
531: int srcPixelStride = src.getPixelStride();
532: int srcScanlineStride = src.getScanlineStride();
533:
534: float tmpBuffer[] = new float[kh * dwidth];
535: int tmpBufferSize = kh * dwidth;
536:
537: for (int k = 0; k < dnumBands; k++) {
538: float dstData[] = dstDataArrays[k];
539: float srcData[] = srcDataArrays[k];
540: int srcScanlineOffset = srcBandOffsets[k];
541: int dstScanlineOffset = dstBandOffsets[k];
542:
543: int revolver = 0;
544: int kvRevolver = 0; // to match kernel vValues
545: for (int j = 0; j < kh - 1; j++) {
546: int srcPixelOffset = srcScanlineOffset;
547:
548: for (int i = 0; i < dwidth; i++) {
549: int imageOffset = srcPixelOffset;
550: float f = 0.0f;
551: for (int v = 0; v < kw; v++) {
552: f += (srcData[imageOffset]) * hValues[v];
553: imageOffset += srcPixelStride;
554: }
555: tmpBuffer[revolver + i] = f;
556: srcPixelOffset += srcPixelStride;
557: }
558: revolver += dwidth;
559: srcScanlineOffset += srcScanlineStride;
560: }
561:
562: // srcScanlineStride already bumped by
563: // kh-1*scanlineStride
564:
565: for (int j = 0; j < dheight; j++) {
566: int srcPixelOffset = srcScanlineOffset;
567: int dstPixelOffset = dstScanlineOffset;
568:
569: for (int i = 0; i < dwidth; i++) {
570: int imageOffset = srcPixelOffset;
571: float f = 0.0f;
572: for (int v = 0; v < kw; v++) {
573: f += (srcData[imageOffset]) * hValues[v];
574: imageOffset += srcPixelStride;
575: }
576: tmpBuffer[revolver + i] = f;
577:
578: f = 0.0f;
579:
580: int b = kvRevolver + i;
581: for (int a = 0; a < kh; a++) {
582: f += tmpBuffer[b] * vValues[a];
583: b += dwidth;
584: if (b >= tmpBufferSize)
585: b -= tmpBufferSize;
586: }
587:
588: dstData[dstPixelOffset] = f;
589: srcPixelOffset += srcPixelStride;
590: dstPixelOffset += dstPixelStride;
591: }
592: revolver += dwidth;
593: if (revolver == tmpBufferSize) {
594: revolver = 0;
595: }
596: kvRevolver += dwidth;
597: if (kvRevolver == tmpBufferSize) {
598: kvRevolver = 0;
599: }
600: srcScanlineOffset += srcScanlineStride;
601: dstScanlineOffset += dstScanlineStride;
602: }
603: }
604: }
605:
606: protected void doubleLoop(RasterAccessor src, RasterAccessor dst) {
607: int dwidth = dst.getWidth();
608: int dheight = dst.getHeight();
609: int dnumBands = dst.getNumBands();
610:
611: double dstDataArrays[][] = dst.getDoubleDataArrays();
612: int dstBandOffsets[] = dst.getBandOffsets();
613: int dstPixelStride = dst.getPixelStride();
614: int dstScanlineStride = dst.getScanlineStride();
615:
616: double srcDataArrays[][] = src.getDoubleDataArrays();
617: int srcBandOffsets[] = src.getBandOffsets();
618: int srcPixelStride = src.getPixelStride();
619: int srcScanlineStride = src.getScanlineStride();
620:
621: double tmpBuffer[] = new double[kh * dwidth];
622: int tmpBufferSize = kh * dwidth;
623:
624: for (int k = 0; k < dnumBands; k++) {
625: double dstData[] = dstDataArrays[k];
626: double srcData[] = srcDataArrays[k];
627: int srcScanlineOffset = srcBandOffsets[k];
628: int dstScanlineOffset = dstBandOffsets[k];
629:
630: int revolver = 0;
631: int kvRevolver = 0; // to match kernel vValues
632: for (int j = 0; j < kh - 1; j++) {
633: int srcPixelOffset = srcScanlineOffset;
634:
635: for (int i = 0; i < dwidth; i++) {
636: int imageOffset = srcPixelOffset;
637: double f = 0.0;
638: for (int v = 0; v < kw; v++) {
639: f += (srcData[imageOffset]) * hValues[v];
640: imageOffset += srcPixelStride;
641: }
642: tmpBuffer[revolver + i] = f;
643: srcPixelOffset += srcPixelStride;
644: }
645: revolver += dwidth;
646: srcScanlineOffset += srcScanlineStride;
647: }
648:
649: // srcScanlineStride already bumped by
650: // kh-1*scanlineStride
651:
652: for (int j = 0; j < dheight; j++) {
653: int srcPixelOffset = srcScanlineOffset;
654: int dstPixelOffset = dstScanlineOffset;
655:
656: for (int i = 0; i < dwidth; i++) {
657: int imageOffset = srcPixelOffset;
658: double f = 0.0;
659: for (int v = 0; v < kw; v++) {
660: f += (srcData[imageOffset]) * hValues[v];
661: imageOffset += srcPixelStride;
662: }
663: tmpBuffer[revolver + i] = f;
664:
665: f = 0.0;
666:
667: int b = kvRevolver + i;
668: for (int a = 0; a < kh; a++) {
669: f += tmpBuffer[b] * vValues[a];
670: b += dwidth;
671: if (b >= tmpBufferSize)
672: b -= tmpBufferSize;
673: }
674:
675: dstData[dstPixelOffset] = f;
676: srcPixelOffset += srcPixelStride;
677: dstPixelOffset += dstPixelStride;
678: }
679: revolver += dwidth;
680: if (revolver == tmpBufferSize) {
681: revolver = 0;
682: }
683: kvRevolver += dwidth;
684: if (kvRevolver == tmpBufferSize) {
685: kvRevolver = 0;
686: }
687: srcScanlineOffset += srcScanlineStride;
688: dstScanlineOffset += dstScanlineStride;
689: }
690: }
691: }
692:
693: // public static OpImage createTestImage(OpImageTester oit) {
694: // float data[] = {0.05f,0.10f,0.05f,
695: // 0.10f,0.20f,0.10f,
696: // 0.05f,0.10f,0.05f};
697: // KernelJAI kJAI = new KernelJAI(3,3,1,1,data);
698: // return new SeparableConvolveOpImage(oit.getSource(), null, null,
699: // new ImageLayout(oit.getSource()),
700: // kJAI);
701: // }
702:
703: // public static void main(String args[]) {
704: // String classname = "com.sun.media.jai.opimage.SeparableConvolveOpImage";
705: // OpImageTester.performDiagnostics(classname,args);
706: // }
707: }
|