001: /*
002: * $RCSfile: CopyOpImage.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:20 $
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.WritableRaster;
019: import java.awt.image.renderable.ParameterBlock;
020: import javax.media.jai.ImageLayout;
021: import javax.media.jai.JAI;
022: import javax.media.jai.PointOpImage;
023: import javax.media.jai.OpImage;
024: import javax.media.jai.RasterAccessor;
025: import javax.media.jai.RasterFormatTag;
026: import java.util.Hashtable;
027: import java.util.Map;
028:
029: // import com.sun.media.jai.test.OpImageTester;
030:
031: /**
032: * An OpImage class that copies an image from source to dest.
033: *
034: */
035: public final class CopyOpImage extends PointOpImage {
036:
037: /**
038: * Constructs an CopyOpImage. The image dimensions are copied
039: * from the source image. The tile grid layout, SampleModel, and
040: * ColorModel may optionally be specified by an ImageLayout object.
041: *
042: * @param source a RenderedImage.
043: * @param layout an ImageLayout optionally containing the tile
044: * grid layout, SampleModel, and ColorModel, or null.
045: */
046: public CopyOpImage(RenderedImage source, Map config,
047: ImageLayout layout) {
048: super (source, layout, config, true);
049: }
050:
051: /**
052: * Adds the pixel values of a rectangle with a given constant.
053: * The sources are cobbled.
054: *
055: * @param sources an array of sources, guarantee to provide all
056: * necessary source data for computing the rectangle.
057: * @param dest a tile that contains the rectangle to be computed.
058: * @param destRect the rectangle within this OpImage to be processed.
059: */
060: protected void computeRect(Raster[] sources, WritableRaster dest,
061: Rectangle destRect) {
062: // Retrieve format tags.
063: RasterFormatTag[] formatTags = getFormatTags();
064:
065: Raster source = sources[0];
066: Rectangle srcRect = mapDestRect(destRect, 0);
067:
068: RasterAccessor srcAccessor = new RasterAccessor(source,
069: srcRect, formatTags[0], getSourceImage(0)
070: .getColorModel());
071:
072: RasterAccessor dstAccessor = new RasterAccessor(dest, destRect,
073: formatTags[1], getColorModel());
074:
075: if (dstAccessor.isBinary()) {
076: byte[] srcBits = srcAccessor.getBinaryDataArray();
077: byte[] dstBits = dstAccessor.getBinaryDataArray();
078:
079: System.arraycopy(srcBits, 0, dstBits, 0, dstBits.length);
080:
081: dstAccessor.copyBinaryDataToRaster();
082: } else {
083: switch (dstAccessor.getDataType()) {
084: case DataBuffer.TYPE_BYTE:
085: byteLoop(srcAccessor, dstAccessor);
086: break;
087: case DataBuffer.TYPE_SHORT:
088: case DataBuffer.TYPE_USHORT:
089: shortLoop(srcAccessor, dstAccessor);
090: break;
091: case DataBuffer.TYPE_INT:
092: intLoop(srcAccessor, dstAccessor);
093: break;
094: case DataBuffer.TYPE_FLOAT:
095: floatLoop(srcAccessor, dstAccessor);
096: break;
097: case DataBuffer.TYPE_DOUBLE:
098: doubleLoop(srcAccessor, dstAccessor);
099: break;
100: default:
101: String className = this .getClass().getName();
102: throw new RuntimeException(JaiI18N
103: .getString("Convolve3x3OpImage1"));
104: }
105:
106: // If the RasterAccessor object set up a temporary buffer for the
107: // op to write to, tell the RasterAccessor to write that data
108: // to the raster no that we're done with it.
109: if (dstAccessor.isDataCopy()) {
110: dstAccessor.clampDataArrays();
111: dstAccessor.copyDataToRaster();
112: }
113: }
114: }
115:
116: private void byteLoop(RasterAccessor src, RasterAccessor dst) {
117: int dwidth = dst.getWidth();
118: int dheight = dst.getHeight();
119: int dnumBands = dst.getNumBands();
120:
121: byte dstDataArrays[][] = dst.getByteDataArrays();
122: int dstBandOffsets[] = dst.getBandOffsets();
123: int dstPixelStride = dst.getPixelStride();
124: int dstScanlineStride = dst.getScanlineStride();
125:
126: byte srcDataArrays[][] = src.getByteDataArrays();
127: int srcBandOffsets[] = src.getBandOffsets();
128: int srcPixelStride = src.getPixelStride();
129: int srcScanlineStride = src.getScanlineStride();
130:
131: for (int k = 0; k < dnumBands; k++) {
132: byte dstData[] = dstDataArrays[k];
133: byte srcData[] = srcDataArrays[k];
134: int srcScanlineOffset = srcBandOffsets[k];
135: int dstScanlineOffset = dstBandOffsets[k];
136: for (int j = 0; j < dheight; j++) {
137: int srcPixelOffset = srcScanlineOffset;
138: int dstPixelOffset = dstScanlineOffset;
139: for (int i = 0; i < dwidth; i++) {
140: dstData[dstPixelOffset] = srcData[srcPixelOffset];
141: srcPixelOffset += srcPixelStride;
142: dstPixelOffset += dstPixelStride;
143: }
144: srcScanlineOffset += srcScanlineStride;
145: dstScanlineOffset += dstScanlineStride;
146: }
147: }
148: }
149:
150: private void shortLoop(RasterAccessor src, RasterAccessor dst) {
151: int dwidth = dst.getWidth();
152: int dheight = dst.getHeight();
153: int dnumBands = dst.getNumBands();
154:
155: short dstDataArrays[][] = dst.getShortDataArrays();
156: int dstBandOffsets[] = dst.getBandOffsets();
157: int dstPixelStride = dst.getPixelStride();
158: int dstScanlineStride = dst.getScanlineStride();
159:
160: short srcDataArrays[][] = src.getShortDataArrays();
161: int srcBandOffsets[] = src.getBandOffsets();
162: int srcPixelStride = src.getPixelStride();
163: int srcScanlineStride = src.getScanlineStride();
164:
165: for (int k = 0; k < dnumBands; k++) {
166: short dstData[] = dstDataArrays[k];
167: short srcData[] = srcDataArrays[k];
168: int srcScanlineOffset = srcBandOffsets[k];
169: int dstScanlineOffset = dstBandOffsets[k];
170: for (int j = 0; j < dheight; j++) {
171: int srcPixelOffset = srcScanlineOffset;
172: int dstPixelOffset = dstScanlineOffset;
173: for (int i = 0; i < dwidth; i++) {
174: dstData[dstPixelOffset] = srcData[srcPixelOffset];
175: srcPixelOffset += srcPixelStride;
176: dstPixelOffset += dstPixelStride;
177: }
178: srcScanlineOffset += srcScanlineStride;
179: dstScanlineOffset += dstScanlineStride;
180: }
181: }
182: }
183:
184: // identical to byteLoops, except datatypes have changed. clumsy,
185: // but there's no other way in Java
186: private void intLoop(RasterAccessor src, RasterAccessor dst) {
187: int dwidth = dst.getWidth();
188: int dheight = dst.getHeight();
189: int dnumBands = dst.getNumBands();
190:
191: int dstDataArrays[][] = dst.getIntDataArrays();
192: int dstBandOffsets[] = dst.getBandOffsets();
193: int dstPixelStride = dst.getPixelStride();
194: int dstScanlineStride = dst.getScanlineStride();
195:
196: int srcDataArrays[][] = src.getIntDataArrays();
197: int srcBandOffsets[] = src.getBandOffsets();
198: int srcPixelStride = src.getPixelStride();
199: int srcScanlineStride = src.getScanlineStride();
200:
201: for (int k = 0; k < dnumBands; k++) {
202: int dstData[] = dstDataArrays[k];
203: int srcData[] = srcDataArrays[k];
204: int srcScanlineOffset = srcBandOffsets[k];
205: int dstScanlineOffset = dstBandOffsets[k];
206: for (int j = 0; j < dheight; j++) {
207: int srcPixelOffset = srcScanlineOffset;
208: int dstPixelOffset = dstScanlineOffset;
209: for (int i = 0; i < dwidth; i++) {
210: dstData[dstPixelOffset] = srcData[srcPixelOffset];
211: srcPixelOffset += srcPixelStride;
212: dstPixelOffset += dstPixelStride;
213: }
214: srcScanlineOffset += srcScanlineStride;
215: dstScanlineOffset += dstScanlineStride;
216: }
217: }
218: }
219:
220: private void floatLoop(RasterAccessor src, RasterAccessor dst) {
221: int dwidth = dst.getWidth();
222: int dheight = dst.getHeight();
223: int dnumBands = dst.getNumBands();
224:
225: float dstDataArrays[][] = dst.getFloatDataArrays();
226: int dstBandOffsets[] = dst.getBandOffsets();
227: int dstPixelStride = dst.getPixelStride();
228: int dstScanlineStride = dst.getScanlineStride();
229:
230: float srcDataArrays[][] = src.getFloatDataArrays();
231: int srcBandOffsets[] = src.getBandOffsets();
232: int srcPixelStride = src.getPixelStride();
233: int srcScanlineStride = src.getScanlineStride();
234:
235: for (int k = 0; k < dnumBands; k++) {
236: float dstData[] = dstDataArrays[k];
237: float srcData[] = srcDataArrays[k];
238: int srcScanlineOffset = srcBandOffsets[k];
239: int dstScanlineOffset = dstBandOffsets[k];
240: for (int j = 0; j < dheight; j++) {
241: int srcPixelOffset = srcScanlineOffset;
242: int dstPixelOffset = dstScanlineOffset;
243: for (int i = 0; i < dwidth; i++) {
244: dstData[dstPixelOffset] = srcData[srcPixelOffset];
245: srcPixelOffset += srcPixelStride;
246: dstPixelOffset += dstPixelStride;
247: }
248: srcScanlineOffset += srcScanlineStride;
249: dstScanlineOffset += dstScanlineStride;
250: }
251: }
252: }
253:
254: private void doubleLoop(RasterAccessor src, RasterAccessor dst) {
255: int dwidth = dst.getWidth();
256: int dheight = dst.getHeight();
257: int dnumBands = dst.getNumBands();
258:
259: double dstDataArrays[][] = dst.getDoubleDataArrays();
260: int dstBandOffsets[] = dst.getBandOffsets();
261: int dstPixelStride = dst.getPixelStride();
262: int dstScanlineStride = dst.getScanlineStride();
263:
264: double srcDataArrays[][] = src.getDoubleDataArrays();
265: int srcBandOffsets[] = src.getBandOffsets();
266: int srcPixelStride = src.getPixelStride();
267: int srcScanlineStride = src.getScanlineStride();
268:
269: for (int k = 0; k < dnumBands; k++) {
270: double dstData[] = dstDataArrays[k];
271: double srcData[] = srcDataArrays[k];
272: int srcScanlineOffset = srcBandOffsets[k];
273: int dstScanlineOffset = dstBandOffsets[k];
274: for (int j = 0; j < dheight; j++) {
275: int srcPixelOffset = srcScanlineOffset;
276: int dstPixelOffset = dstScanlineOffset;
277: for (int i = 0; i < dwidth; i++) {
278: dstData[dstPixelOffset] = srcData[srcPixelOffset];
279: srcPixelOffset += srcPixelStride;
280: dstPixelOffset += dstPixelStride;
281: }
282: srcScanlineOffset += srcScanlineStride;
283: dstScanlineOffset += dstScanlineStride;
284: }
285: }
286: }
287:
288: // public static OpImage createTestImage(OpImageTester oit) {
289: // return new CopyOpImage(oit.getSource(), null,
290: // new ImageLayout(oit.getSource()));
291: // }
292:
293: // // Calls a method on OpImage that uses introspection, to make this
294: // // class, discover it's createTestImage() call, call it and then
295: // // benchmark the performance of the created OpImage chain.
296: // public static void main(String args[]) {
297: // String classname = "com.sun.media.jai.opimage.CopyOpImage";
298: // OpImageTester.performDiagnostics(classname,args);
299: // }
300: }
|