001: /*
002: * $RCSfile: AddOpImage.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:12 $
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.Raster;
017: import java.awt.image.RenderedImage;
018: import java.awt.image.SampleModel;
019: import java.awt.image.WritableRaster;
020: import javax.media.jai.ImageLayout;
021: import javax.media.jai.OpImage;
022: import javax.media.jai.PointOpImage;
023: import javax.media.jai.RasterAccessor;
024: import javax.media.jai.RasterFormatTag;
025: import javax.media.jai.RasterFactory;
026: import javax.media.jai.TileCache;
027: import java.util.Map;
028: import com.sun.media.jai.util.ImageUtil;
029: import com.sun.media.jai.util.JDKWorkarounds;
030:
031: /// import com.sun.media.jai.test.OpImageTester;
032:
033: /**
034: * An <code>OpImage</code> implementing the "Add" operation as
035: * described in <code>javax.media.jai.operator.AddDescriptor</code>.
036: *
037: * <p>This <code>OpImage</code> adds the pixel values of two source
038: * images on a per-band basis. In case the two source images have different
039: * number of bands, the number of bands for the destination image is the
040: * smaller band number of the two source images. That is
041: * <code>dstNumBands = Math.min(src1NumBands, src2NumBands)</code>.
042: * In case the two source images have different data types, the data type
043: * for the destination image is the higher data type of the two source
044: * images.
045: *
046: * <p>The value of the pixel (x, y) in the destination image is defined as:
047: * <pre>
048: * for (b = 0; b < numBands; b++) {
049: * dst[y][x][b] = src1[y][x][b] + src2[y][x][b];
050: * }
051: * </pre>
052: *
053: * <p>If the result of the addition overflows/underflows the
054: * maximum/minimum value supported by the destination image, then it
055: * will be clamped to the maximum/minimum value respectively. The
056: * data type <code>byte</code> is treated as unsigned, with maximum
057: * value as 255 and minimum value as 0.
058: *
059: * @see javax.media.jai.operator.AddDescriptor
060: * @see AddCRIF
061: *
062: */
063: final class AddOpImage extends PointOpImage {
064:
065: /* Source 1 band increment */
066: private int s1bd = 1;
067:
068: /* Source 2 band increment */
069: private int s2bd = 1;
070:
071: /* Bilevel data flag. */
072: private boolean areBinarySampleModels = false;
073:
074: /**
075: * Constructs an <code>AddOpImage</code>.
076: *
077: * <p>The <code>layout</code> parameter may optionally contains the
078: * tile grid layout, sample model, and/or color model. The image
079: * dimension is determined by the intersection of the bounding boxes
080: * of the two source images.
081: *
082: * <p>The image layout of the first source image, <code>source1</code>,
083: * is used as the fall-back for the image layout of the destination
084: * image. Any layout parameters not specified in the <code>layout</code>
085: * argument are set to the same value as that of <code>source1</code>.
086: *
087: * @param source1 The first source image.
088: * @param source2 The second source image.
089: * @param layout The destination image layout.
090: */
091: public AddOpImage(RenderedImage source1, RenderedImage source2,
092: Map config, ImageLayout layout) {
093: super (source1, source2, layout, config, true);
094:
095: if (ImageUtil.isBinary(getSampleModel())
096: && ImageUtil.isBinary(source1.getSampleModel())
097: && ImageUtil.isBinary(source2.getSampleModel())) {
098: // Binary processing case: RasterAccessor
099: areBinarySampleModels = true;
100: } else {
101: // Get the source band counts.
102: int numBands1 = source1.getSampleModel().getNumBands();
103: int numBands2 = source2.getSampleModel().getNumBands();
104:
105: // Handle the special case of adding a single band image to
106: // each band of a multi-band image.
107: int numBandsDst;
108: if (layout != null
109: && layout.isValid(ImageLayout.SAMPLE_MODEL_MASK)) {
110: SampleModel sm = layout.getSampleModel(null);
111: numBandsDst = sm.getNumBands();
112:
113: // One of the sources must be single-banded and the other must
114: // have at most the number of bands in the SampleModel hint.
115: if (numBandsDst > 1
116: && ((numBands1 == 1 && numBands2 > 1) || (numBands2 == 1 && numBands1 > 1))) {
117: // Clamp the destination band count to the number of
118: // bands in the multi-band source.
119: numBandsDst = Math.min(Math.max(numBands1,
120: numBands2), numBandsDst);
121:
122: // Create a new SampleModel if necessary.
123: if (numBandsDst != sampleModel.getNumBands()) {
124: sampleModel = RasterFactory
125: .createComponentSampleModel(sm,
126: sampleModel.getTransferType(),
127: sampleModel.getWidth(),
128: sampleModel.getHeight(),
129: numBandsDst);
130:
131: if (colorModel != null
132: && !JDKWorkarounds
133: .areCompatibleDataModels(
134: sampleModel, colorModel)) {
135: colorModel = ImageUtil
136: .getCompatibleColorModel(
137: sampleModel, config);
138: }
139: }
140:
141: // Set the source band increments.
142: s1bd = numBands1 == 1 ? 0 : 1;
143: s2bd = numBands2 == 1 ? 0 : 1;
144: }
145: }
146: }
147:
148: // Set flag to permit in-place operation.
149: permitInPlaceOperation();
150: }
151:
152: /**
153: * Adds the pixel values of two source images within a specified
154: * rectangle.
155: *
156: * @param sources Cobbled sources, guaranteed to provide all the
157: * source data necessary for computing the rectangle.
158: * @param dest The tile containing the rectangle to be computed.
159: * @param destRect The rectangle within the tile to be computed.
160: */
161: protected void computeRect(Raster[] sources, WritableRaster dest,
162: Rectangle destRect) {
163: if (areBinarySampleModels) {
164: // Retrieve format tags.
165: RasterFormatTag[] formatTags = getFormatTags();
166:
167: // For PointOpImage, srcRect = destRect.
168: RasterAccessor s1 = new RasterAccessor(sources[0],
169: destRect, formatTags[0], getSourceImage(0)
170: .getColorModel());
171: RasterAccessor s2 = new RasterAccessor(sources[1],
172: destRect, formatTags[1], getSourceImage(1)
173: .getColorModel());
174: RasterAccessor d = new RasterAccessor(dest, destRect,
175: formatTags[2], getColorModel());
176:
177: if (d.isBinary()) {
178: byte[] src1Bits = s1.getBinaryDataArray();
179: byte[] src2Bits = s2.getBinaryDataArray();
180: byte[] dstBits = d.getBinaryDataArray();
181:
182: int length = dstBits.length;
183: for (int i = 0; i < length; i++) {
184: // "Add" is equivalent to "Or" when 1+1 is clamped to 1.
185: dstBits[i] = (byte) (src1Bits[i] | src2Bits[i]);
186: }
187:
188: d.copyBinaryDataToRaster();
189:
190: return;
191: }
192: }
193:
194: // Retrieve format tags.
195: RasterFormatTag[] formatTags = getFormatTags();
196:
197: RasterAccessor s1 = new RasterAccessor(sources[0], destRect,
198: formatTags[0], getSourceImage(0).getColorModel());
199: RasterAccessor s2 = new RasterAccessor(sources[1], destRect,
200: formatTags[1], getSourceImage(1).getColorModel());
201: RasterAccessor d = new RasterAccessor(dest, destRect,
202: formatTags[2], getColorModel());
203:
204: switch (d.getDataType()) {
205: case DataBuffer.TYPE_BYTE:
206: computeRectByte(s1, s2, d);
207: break;
208: case DataBuffer.TYPE_USHORT:
209: computeRectUShort(s1, s2, d);
210: break;
211: case DataBuffer.TYPE_SHORT:
212: computeRectShort(s1, s2, d);
213: break;
214: case DataBuffer.TYPE_INT:
215: computeRectInt(s1, s2, d);
216: break;
217: case DataBuffer.TYPE_FLOAT:
218: computeRectFloat(s1, s2, d);
219: break;
220: case DataBuffer.TYPE_DOUBLE:
221: computeRectDouble(s1, s2, d);
222: break;
223: }
224:
225: if (d.needsClamping()) {
226: d.clampDataArrays();
227: }
228: d.copyDataToRaster();
229: }
230:
231: private void computeRectByte(RasterAccessor src1,
232: RasterAccessor src2, RasterAccessor dst) {
233: int s1LineStride = src1.getScanlineStride();
234: int s1PixelStride = src1.getPixelStride();
235: int[] s1BandOffsets = src1.getBandOffsets();
236: byte[][] s1Data = src1.getByteDataArrays();
237:
238: int s2LineStride = src2.getScanlineStride();
239: int s2PixelStride = src2.getPixelStride();
240: int[] s2BandOffsets = src2.getBandOffsets();
241: byte[][] s2Data = src2.getByteDataArrays();
242:
243: int dwidth = dst.getWidth();
244: int dheight = dst.getHeight();
245: int bands = dst.getNumBands();
246: int dLineStride = dst.getScanlineStride();
247: int dPixelStride = dst.getPixelStride();
248: int[] dBandOffsets = dst.getBandOffsets();
249: byte[][] dData = dst.getByteDataArrays();
250:
251: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
252: byte[] s1 = s1Data[s1b];
253: byte[] s2 = s2Data[s2b];
254: byte[] d = dData[b];
255:
256: int s1LineOffset = s1BandOffsets[s1b];
257: int s2LineOffset = s2BandOffsets[s2b];
258: int dLineOffset = dBandOffsets[b];
259:
260: for (int h = 0; h < dheight; h++) {
261: int s1PixelOffset = s1LineOffset;
262: int s2PixelOffset = s2LineOffset;
263: int dPixelOffset = dLineOffset;
264:
265: s1LineOffset += s1LineStride;
266: s2LineOffset += s2LineStride;
267: dLineOffset += dLineStride;
268:
269: int sum = 0;
270: for (int w = 0; w < dwidth; w++) {
271: //
272: // The next two lines are a fast way to do
273: // an add with saturation on U8 elements.
274: // It eliminates the need to do clamping.
275: //
276: sum = (s1[s1PixelOffset] & 0xFF)
277: + (s2[s2PixelOffset] & 0xFF);
278: d[dPixelOffset] = (byte) ((((sum << 23) >> 31) | sum) & 0xFF);
279:
280: s1PixelOffset += s1PixelStride;
281: s2PixelOffset += s2PixelStride;
282: dPixelOffset += dPixelStride;
283: }
284: }
285: }
286: }
287:
288: private void computeRectUShort(RasterAccessor src1,
289: RasterAccessor src2, RasterAccessor dst) {
290: int s1LineStride = src1.getScanlineStride();
291: int s1PixelStride = src1.getPixelStride();
292: int[] s1BandOffsets = src1.getBandOffsets();
293: short[][] s1Data = src1.getShortDataArrays();
294:
295: int s2LineStride = src2.getScanlineStride();
296: int s2PixelStride = src2.getPixelStride();
297: int[] s2BandOffsets = src2.getBandOffsets();
298: short[][] s2Data = src2.getShortDataArrays();
299:
300: int dwidth = dst.getWidth();
301: int dheight = dst.getHeight();
302: int bands = dst.getNumBands();
303: int dLineStride = dst.getScanlineStride();
304: int dPixelStride = dst.getPixelStride();
305: int[] dBandOffsets = dst.getBandOffsets();
306: short[][] dData = dst.getShortDataArrays();
307:
308: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
309: short[] s1 = s1Data[s1b];
310: short[] s2 = s2Data[s2b];
311: short[] d = dData[b];
312:
313: int s1LineOffset = s1BandOffsets[s1b];
314: int s2LineOffset = s2BandOffsets[s2b];
315: int dLineOffset = dBandOffsets[b];
316:
317: for (int h = 0; h < dheight; h++) {
318: int s1PixelOffset = s1LineOffset;
319: int s2PixelOffset = s2LineOffset;
320: int dPixelOffset = dLineOffset;
321:
322: s1LineOffset += s1LineStride;
323: s2LineOffset += s2LineStride;
324: dLineOffset += dLineStride;
325:
326: for (int w = 0; w < dwidth; w++) {
327: d[dPixelOffset] = ImageUtil
328: .clampUShortPositive((int) (s1[s1PixelOffset] & 0xFFFF)
329: + (int) (s2[s2PixelOffset] & 0xFFFF));
330:
331: s1PixelOffset += s1PixelStride;
332: s2PixelOffset += s2PixelStride;
333: dPixelOffset += dPixelStride;
334: }
335: }
336: }
337: }
338:
339: private void computeRectShort(RasterAccessor src1,
340: RasterAccessor src2, RasterAccessor dst) {
341: int s1LineStride = src1.getScanlineStride();
342: int s1PixelStride = src1.getPixelStride();
343: int[] s1BandOffsets = src1.getBandOffsets();
344: short[][] s1Data = src1.getShortDataArrays();
345:
346: int s2LineStride = src2.getScanlineStride();
347: int s2PixelStride = src2.getPixelStride();
348: int[] s2BandOffsets = src2.getBandOffsets();
349: short[][] s2Data = src2.getShortDataArrays();
350:
351: int dwidth = dst.getWidth();
352: int dheight = dst.getHeight();
353: int bands = dst.getNumBands();
354: int dLineStride = dst.getScanlineStride();
355: int dPixelStride = dst.getPixelStride();
356: int[] dBandOffsets = dst.getBandOffsets();
357: short[][] dData = dst.getShortDataArrays();
358:
359: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
360: short[] s1 = s1Data[s1b];
361: short[] s2 = s2Data[s2b];
362: short[] d = dData[b];
363:
364: int s1LineOffset = s1BandOffsets[s1b];
365: int s2LineOffset = s2BandOffsets[s2b];
366: int dLineOffset = dBandOffsets[b];
367:
368: for (int h = 0; h < dheight; h++) {
369: int s1PixelOffset = s1LineOffset;
370: int s2PixelOffset = s2LineOffset;
371: int dPixelOffset = dLineOffset;
372:
373: s1LineOffset += s1LineStride;
374: s2LineOffset += s2LineStride;
375: dLineOffset += dLineStride;
376:
377: for (int w = 0; w < dwidth; w++) {
378: d[dPixelOffset] = ImageUtil
379: .clampShort((int) s1[s1PixelOffset]
380: + (int) s2[s2PixelOffset]);
381:
382: s1PixelOffset += s1PixelStride;
383: s2PixelOffset += s2PixelStride;
384: dPixelOffset += dPixelStride;
385: }
386: }
387: }
388: }
389:
390: private void computeRectInt(RasterAccessor src1,
391: RasterAccessor src2, RasterAccessor dst) {
392: int s1LineStride = src1.getScanlineStride();
393: int s1PixelStride = src1.getPixelStride();
394: int[] s1BandOffsets = src1.getBandOffsets();
395: int[][] s1Data = src1.getIntDataArrays();
396:
397: int s2LineStride = src2.getScanlineStride();
398: int s2PixelStride = src2.getPixelStride();
399: int[] s2BandOffsets = src2.getBandOffsets();
400: int[][] s2Data = src2.getIntDataArrays();
401:
402: int dwidth = dst.getWidth();
403: int dheight = dst.getHeight();
404: int bands = dst.getNumBands();
405: int dLineStride = dst.getScanlineStride();
406: int dPixelStride = dst.getPixelStride();
407: int[] dBandOffsets = dst.getBandOffsets();
408: int[][] dData = dst.getIntDataArrays();
409:
410: /*
411: * The destination data type may be any of the integral data types.
412: * The "clamp" function must clamp to the appropriate range for
413: * that data type.
414: */
415: switch (sampleModel.getTransferType()) {
416: case DataBuffer.TYPE_BYTE:
417: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
418: int[] s1 = s1Data[s1b];
419: int[] s2 = s2Data[s2b];
420: int[] d = dData[b];
421:
422: int s1LineOffset = s1BandOffsets[s1b];
423: int s2LineOffset = s2BandOffsets[s2b];
424: int dLineOffset = dBandOffsets[b];
425:
426: for (int h = 0; h < dheight; h++) {
427: int s1PixelOffset = s1LineOffset;
428: int s2PixelOffset = s2LineOffset;
429: int dPixelOffset = dLineOffset;
430:
431: s1LineOffset += s1LineStride;
432: s2LineOffset += s2LineStride;
433: dLineOffset += dLineStride;
434:
435: int sum = 0;
436: for (int w = 0; w < dwidth; w++) {
437: //
438: // The next two lines are a fast way to do
439: // an add with saturation on U8 elements.
440: // It eliminates the need to do clamping.
441: //
442: sum = (s1[s1PixelOffset] & 0xFF)
443: + (s2[s2PixelOffset] & 0xFF);
444: d[dPixelOffset] = ((((sum << 23) >> 31) | sum) & 0xFF);
445:
446: s1PixelOffset += s1PixelStride;
447: s2PixelOffset += s2PixelStride;
448: dPixelOffset += dPixelStride;
449: }
450: }
451: }
452: break;
453:
454: case DataBuffer.TYPE_USHORT:
455: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
456: int[] s1 = s1Data[s1b];
457: int[] s2 = s2Data[s2b];
458: int[] d = dData[b];
459:
460: int s1LineOffset = s1BandOffsets[s1b];
461: int s2LineOffset = s2BandOffsets[s2b];
462: int dLineOffset = dBandOffsets[b];
463:
464: for (int h = 0; h < dheight; h++) {
465: int s1PixelOffset = s1LineOffset;
466: int s2PixelOffset = s2LineOffset;
467: int dPixelOffset = dLineOffset;
468:
469: s1LineOffset += s1LineStride;
470: s2LineOffset += s2LineStride;
471: dLineOffset += dLineStride;
472:
473: for (int w = 0; w < dwidth; w++) {
474: d[dPixelOffset] = ImageUtil
475: .clampUShortPositive((int) (s1[s1PixelOffset] & 0xFFFF)
476: + (int) (s2[s2PixelOffset] & 0xFFFF));
477:
478: s1PixelOffset += s1PixelStride;
479: s2PixelOffset += s2PixelStride;
480: dPixelOffset += dPixelStride;
481: }
482: }
483: }
484: break;
485:
486: case DataBuffer.TYPE_SHORT:
487: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
488: int[] s1 = s1Data[s1b];
489: int[] s2 = s2Data[s2b];
490: int[] d = dData[b];
491:
492: int s1LineOffset = s1BandOffsets[s1b];
493: int s2LineOffset = s2BandOffsets[s2b];
494: int dLineOffset = dBandOffsets[b];
495:
496: for (int h = 0; h < dheight; h++) {
497: int s1PixelOffset = s1LineOffset;
498: int s2PixelOffset = s2LineOffset;
499: int dPixelOffset = dLineOffset;
500:
501: s1LineOffset += s1LineStride;
502: s2LineOffset += s2LineStride;
503: dLineOffset += dLineStride;
504:
505: for (int w = 0; w < dwidth; w++) {
506: d[dPixelOffset] = ImageUtil
507: .clampShort((int) s1[s1PixelOffset]
508: + (int) s2[s2PixelOffset]);
509:
510: s1PixelOffset += s1PixelStride;
511: s2PixelOffset += s2PixelStride;
512: dPixelOffset += dPixelStride;
513: }
514: }
515: }
516: break;
517:
518: case DataBuffer.TYPE_INT:
519: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
520: int[] s1 = s1Data[s1b];
521: int[] s2 = s2Data[s2b];
522: int[] d = dData[b];
523:
524: int s1LineOffset = s1BandOffsets[s1b];
525: int s2LineOffset = s2BandOffsets[s2b];
526: int dLineOffset = dBandOffsets[b];
527:
528: for (int h = 0; h < dheight; h++) {
529: int s1PixelOffset = s1LineOffset;
530: int s2PixelOffset = s2LineOffset;
531: int dPixelOffset = dLineOffset;
532:
533: s1LineOffset += s1LineStride;
534: s2LineOffset += s2LineStride;
535: dLineOffset += dLineStride;
536:
537: for (int w = 0; w < dwidth; w++) {
538: d[dPixelOffset] = ImageUtil
539: .clampInt((long) s1[s1PixelOffset]
540: + (long) s2[s2PixelOffset]);
541:
542: s1PixelOffset += s1PixelStride;
543: s2PixelOffset += s2PixelStride;
544: dPixelOffset += dPixelStride;
545: }
546: }
547: }
548: break;
549: }
550: }
551:
552: private void computeRectFloat(RasterAccessor src1,
553: RasterAccessor src2, RasterAccessor dst) {
554: int s1LineStride = src1.getScanlineStride();
555: int s1PixelStride = src1.getPixelStride();
556: int[] s1BandOffsets = src1.getBandOffsets();
557: float[][] s1Data = src1.getFloatDataArrays();
558:
559: int s2LineStride = src2.getScanlineStride();
560: int s2PixelStride = src2.getPixelStride();
561: int[] s2BandOffsets = src2.getBandOffsets();
562: float[][] s2Data = src2.getFloatDataArrays();
563:
564: int dwidth = dst.getWidth();
565: int dheight = dst.getHeight();
566: int bands = dst.getNumBands();
567: int dLineStride = dst.getScanlineStride();
568: int dPixelStride = dst.getPixelStride();
569: int[] dBandOffsets = dst.getBandOffsets();
570: float[][] dData = dst.getFloatDataArrays();
571:
572: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
573: float[] s1 = s1Data[s1b];
574: float[] s2 = s2Data[s2b];
575: float[] d = dData[b];
576:
577: int s1LineOffset = s1BandOffsets[s1b];
578: int s2LineOffset = s2BandOffsets[s2b];
579: int dLineOffset = dBandOffsets[b];
580:
581: for (int h = 0; h < dheight; h++) {
582: int s1PixelOffset = s1LineOffset;
583: int s2PixelOffset = s2LineOffset;
584: int dPixelOffset = dLineOffset;
585:
586: s1LineOffset += s1LineStride;
587: s2LineOffset += s2LineStride;
588: dLineOffset += dLineStride;
589:
590: for (int w = 0; w < dwidth; w++) {
591: d[dPixelOffset] = s1[s1PixelOffset]
592: + s2[s2PixelOffset];
593:
594: s1PixelOffset += s1PixelStride;
595: s2PixelOffset += s2PixelStride;
596: dPixelOffset += dPixelStride;
597: }
598: }
599: }
600: }
601:
602: private void computeRectDouble(RasterAccessor src1,
603: RasterAccessor src2, RasterAccessor dst) {
604: int s1LineStride = src1.getScanlineStride();
605: int s1PixelStride = src1.getPixelStride();
606: int[] s1BandOffsets = src1.getBandOffsets();
607: double[][] s1Data = src1.getDoubleDataArrays();
608:
609: int s2LineStride = src2.getScanlineStride();
610: int s2PixelStride = src2.getPixelStride();
611: int[] s2BandOffsets = src2.getBandOffsets();
612: double[][] s2Data = src2.getDoubleDataArrays();
613:
614: int dwidth = dst.getWidth();
615: int dheight = dst.getHeight();
616: int bands = dst.getNumBands();
617: int dLineStride = dst.getScanlineStride();
618: int dPixelStride = dst.getPixelStride();
619: int[] dBandOffsets = dst.getBandOffsets();
620: double[][] dData = dst.getDoubleDataArrays();
621:
622: for (int b = 0, s1b = 0, s2b = 0; b < bands; b++, s1b += s1bd, s2b += s2bd) {
623: double[] s1 = s1Data[s1b];
624: double[] s2 = s2Data[s2b];
625: double[] d = dData[b];
626:
627: int s1LineOffset = s1BandOffsets[s1b];
628: int s2LineOffset = s2BandOffsets[s2b];
629: int dLineOffset = dBandOffsets[b];
630:
631: for (int h = 0; h < dheight; h++) {
632: int s1PixelOffset = s1LineOffset;
633: int s2PixelOffset = s2LineOffset;
634: int dPixelOffset = dLineOffset;
635:
636: s1LineOffset += s1LineStride;
637: s2LineOffset += s2LineStride;
638: dLineOffset += dLineStride;
639:
640: for (int w = 0; w < dwidth; w++) {
641: d[dPixelOffset] = s1[s1PixelOffset]
642: + s2[s2PixelOffset];
643:
644: s1PixelOffset += s1PixelStride;
645: s2PixelOffset += s2PixelStride;
646: dPixelOffset += dPixelStride;
647: }
648: }
649: }
650: }
651:
652: // public static void main(String args[]) {
653: // System.out.println("AddOpImage Test");
654: // ImageLayout layout;
655: // OpImage src1, src2, dst;
656: // Rectangle rect = new Rectangle(0, 0, 5, 5);
657:
658: // System.out.println("1. PixelInterleaved byte 3-band");
659: // layout = OpImageTester.createImageLayout(
660: // 0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, false);
661: // src1 = OpImageTester.createRandomOpImage(layout);
662: // src2 = OpImageTester.createRandomOpImage(layout);
663: // dst = new AddOpImage(src1, src2, null, null);
664: // OpImageTester.testOpImage(dst, rect);
665: // OpImageTester.timeOpImage(dst, 10);
666:
667: // System.out.println("2. Banded byte 3-band");
668: // layout = OpImageTester.createImageLayout(
669: // 0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, true);
670: // src1 = OpImageTester.createRandomOpImage(layout);
671: // src2 = OpImageTester.createRandomOpImage(layout);
672: // dst = new AddOpImage(src1, src2, null, null);
673: // OpImageTester.testOpImage(dst, rect);
674: // OpImageTester.timeOpImage(dst, 10);
675:
676: // System.out.println("3. PixelInterleaved int 3-band");
677: // layout = OpImageTester.createImageLayout(
678: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_INT, 3, false);
679: // src1 = OpImageTester.createRandomOpImage(layout);
680: // src2 = OpImageTester.createRandomOpImage(layout);
681: // dst = new AddOpImage(src1, src2, null, null);
682: // OpImageTester.testOpImage(dst, rect);
683: // OpImageTester.timeOpImage(dst, 10);
684:
685: // System.out.println("4. Banded int 3-band");
686: // layout = OpImageTester.createImageLayout(
687: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_INT, 3, true);
688: // src1 = OpImageTester.createRandomOpImage(layout);
689: // src2 = OpImageTester.createRandomOpImage(layout);
690: // dst = new AddOpImage(src1, src2, null, null);
691: // OpImageTester.testOpImage(dst, rect);
692: // OpImageTester.timeOpImage(dst, 10);
693:
694: // System.out.println("5. PixelInterleaved float 3-band");
695: // layout = OpImageTester.createImageLayout(
696: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_FLOAT, 3, false);
697: // src1 = OpImageTester.createRandomOpImage(layout);
698: // src2 = OpImageTester.createRandomOpImage(layout);
699: // dst = new AddOpImage(src1, src2, null, null);
700: // OpImageTester.testOpImage(dst, rect);
701: // OpImageTester.timeOpImage(dst, 10);
702:
703: // System.out.println("6. Banded float 3-band");
704: // layout = OpImageTester.createImageLayout(
705: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_FLOAT, 3, true);
706: // src1 = OpImageTester.createRandomOpImage(layout);
707: // src2 = OpImageTester.createRandomOpImage(layout);
708: // dst = new AddOpImage(src1, src2, null, null);
709: // OpImageTester.testOpImage(dst, rect);
710: // OpImageTester.timeOpImage(dst, 10);
711:
712: // System.out.println("7. PixelInterleaved double 3-band");
713: // layout = OpImageTester.createImageLayout(
714: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_DOUBLE, 3, false);
715: // src1 = OpImageTester.createRandomOpImage(layout);
716: // src2 = OpImageTester.createRandomOpImage(layout);
717: // dst = new AddOpImage(src1, src2, null, null);
718: // OpImageTester.testOpImage(dst, rect);
719: // OpImageTester.timeOpImage(dst, 10);
720:
721: // System.out.println("8. Banded double 3-band");
722: // layout = OpImageTester.createImageLayout(
723: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_DOUBLE, 3, true);
724: // src1 = OpImageTester.createRandomOpImage(layout);
725: // src2 = OpImageTester.createRandomOpImage(layout);
726: // dst = new AddOpImage(src1, src2, null, null);
727: // OpImageTester.testOpImage(dst, rect);
728: // OpImageTester.timeOpImage(dst, 10);
729: // }
730: }
|