001: /*
002: * $RCSfile: AddCollectionOpImage.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:11 $
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 java.util.Collection;
021: import java.util.Iterator;
022: import java.util.Vector;
023: import javax.media.jai.ImageLayout;
024: import javax.media.jai.OpImage;
025: import javax.media.jai.PointOpImage;
026: import javax.media.jai.RasterAccessor;
027: import javax.media.jai.RasterFormatTag;
028: import javax.media.jai.RenderedOp;
029: import java.util.Map;
030: import com.sun.media.jai.util.ImageUtil;
031:
032: /**
033: * An <code>OpImage</code> implementing the "AddCollection" operation.
034: *
035: * @see javax.media.jai.operator.AddCollectionDescriptor
036: * @see AddCollectionCRIF
037: *
038: *
039: * @since EA3
040: */
041: final class AddCollectionOpImage extends PointOpImage {
042:
043: private byte[][] byteTable = null;
044:
045: private synchronized void initByteTable() {
046:
047: if (byteTable != null) {
048: return;
049: }
050:
051: /* Initialize byteTable. */
052: byteTable = new byte[0x100][0x100];
053: for (int j = 0; j < 0x100; j++) {
054: byte[] t = byteTable[j];
055: for (int i = 0; i < 0x100; i++) {
056: t[i] = ImageUtil.clampBytePositive(j + i);
057: }
058: }
059: }
060:
061: /**
062: * Constructor.
063: *
064: * @param sources A collection of rendered images to be added.
065: * @param layout The destination image layout.
066: */
067: public AddCollectionOpImage(Collection sources, Map config,
068: ImageLayout layout) {
069: super (vectorize(sources), layout, config, true);
070: }
071:
072: /** Put the rendered images in a vector. */
073: private static Vector vectorize(Collection sources) {
074: if (sources instanceof Vector) {
075: return (Vector) sources;
076: } else {
077: Vector v = new Vector(sources.size());
078: Iterator iter = sources.iterator();
079: while (iter.hasNext()) {
080: v.add(iter.next());
081: }
082: return v;
083: }
084: }
085:
086: /**
087: * Adds the pixel values of the source images within a specified rectangle.
088: *
089: * @param sources Cobbled sources, guaranteed to provide all the
090: * source data necessary for computing the rectangle.
091: * @param dest The tile containing the rectangle to be computed.
092: * @param destRect The rectangle within the tile to be computed.
093: */
094: protected void computeRect(Raster[] sources, WritableRaster dest,
095: Rectangle destRect) {
096: // Retrieve format tags.
097: RasterFormatTag[] formatTags = getFormatTags();
098:
099: int numSrcs = getNumSources();
100:
101: RasterAccessor dst = new RasterAccessor(dest, destRect,
102: formatTags[numSrcs], getColorModel());
103:
104: RasterAccessor[] srcs = new RasterAccessor[numSrcs];
105: for (int i = 0; i < numSrcs; i++) {
106: Rectangle srcRect = mapDestRect(destRect, i);
107: srcs[i] = new RasterAccessor(sources[i], srcRect,
108: formatTags[i], getSourceImage(i).getColorModel());
109: }
110:
111: switch (dst.getDataType()) {
112: case DataBuffer.TYPE_BYTE:
113: computeRectByte(srcs, dst);
114: break;
115: case DataBuffer.TYPE_USHORT:
116: computeRectUShort(srcs, dst);
117: break;
118: case DataBuffer.TYPE_SHORT:
119: computeRectShort(srcs, dst);
120: break;
121: case DataBuffer.TYPE_INT:
122: computeRectInt(srcs, dst);
123: break;
124: case DataBuffer.TYPE_FLOAT:
125: computeRectFloat(srcs, dst);
126: break;
127: case DataBuffer.TYPE_DOUBLE:
128: computeRectDouble(srcs, dst);
129: break;
130: }
131:
132: if (dst.needsClamping()) {
133: /* Further clamp down to underlying raster data type. */
134: dst.clampDataArrays();
135: }
136: dst.copyDataToRaster();
137: }
138:
139: private void computeRectByte(RasterAccessor[] srcs,
140: RasterAccessor dst) {
141: initByteTable();
142:
143: int dstWidth = dst.getWidth();
144: int dstHeight = dst.getHeight();
145: int dstBands = dst.getNumBands();
146:
147: int dstLineStride = dst.getScanlineStride();
148: int dstPixelStride = dst.getPixelStride();
149: int[] dstBandOffsets = dst.getBandOffsets();
150: byte[][] dstData = dst.getByteDataArrays();
151:
152: int numSrcs = getNumSources();
153:
154: for (int i = 0; i < numSrcs; i++) {
155: RasterAccessor src = srcs[i];
156: int srcLineStride = src.getScanlineStride();
157: int srcPixelStride = src.getPixelStride();
158: int[] srcBandOffsets = src.getBandOffsets();
159: byte[][] srcData = src.getByteDataArrays();
160:
161: for (int b = 0; b < dstBands; b++) {
162: int dstLineOffset = dstBandOffsets[b];
163: int srcLineOffset = srcBandOffsets[b];
164:
165: byte[] d = dstData[b];
166: byte[] s = srcData[b];
167:
168: for (int h = 0; h < dstHeight; h++) {
169: int dstPixelOffset = dstLineOffset;
170: int srcPixelOffset = srcLineOffset;
171:
172: dstLineOffset += dstLineStride;
173: srcLineOffset += srcLineStride;
174:
175: for (int w = 0; w < dstWidth; w++) {
176: d[dstPixelOffset] = byteTable[d[dstPixelOffset] & 0xff][s[srcPixelOffset] & 0xff];
177:
178: dstPixelOffset += dstPixelStride;
179: srcPixelOffset += srcPixelStride;
180: }
181: }
182: }
183: }
184: }
185:
186: private void computeRectUShort(RasterAccessor[] srcs,
187: RasterAccessor dst) {
188: int dstWidth = dst.getWidth();
189: int dstHeight = dst.getHeight();
190: int dstBands = dst.getNumBands();
191:
192: int dstLineStride = dst.getScanlineStride();
193: int dstPixelStride = dst.getPixelStride();
194: int[] dstBandOffsets = dst.getBandOffsets();
195: short[][] dstData = dst.getShortDataArrays();
196:
197: int numSrcs = getNumSources();
198:
199: for (int i = 0; i < numSrcs; i++) {
200: RasterAccessor src = srcs[i];
201: int srcLineStride = src.getScanlineStride();
202: int srcPixelStride = src.getPixelStride();
203: int[] srcBandOffsets = src.getBandOffsets();
204: short[][] srcData = src.getShortDataArrays();
205:
206: for (int b = 0; b < dstBands; b++) {
207: int dstLineOffset = dstBandOffsets[b];
208: int srcLineOffset = srcBandOffsets[b];
209:
210: short[] d = dstData[b];
211: short[] s = srcData[b];
212:
213: for (int h = 0; h < dstHeight; h++) {
214: int dstPixelOffset = dstLineOffset;
215: int srcPixelOffset = srcLineOffset;
216:
217: dstLineOffset += dstLineStride;
218: srcLineOffset += srcLineStride;
219:
220: for (int w = 0; w < dstWidth; w++) {
221: d[dstPixelOffset] = ImageUtil
222: .clampUShortPositive((d[dstPixelOffset] & 0xffff)
223: + (s[srcPixelOffset] & 0xffff));
224:
225: dstPixelOffset += dstPixelStride;
226: srcPixelOffset += srcPixelStride;
227: }
228: }
229: }
230: }
231: }
232:
233: private void computeRectShort(RasterAccessor[] srcs,
234: RasterAccessor dst) {
235: int dstWidth = dst.getWidth();
236: int dstHeight = dst.getHeight();
237: int dstBands = dst.getNumBands();
238:
239: int dstLineStride = dst.getScanlineStride();
240: int dstPixelStride = dst.getPixelStride();
241: int[] dstBandOffsets = dst.getBandOffsets();
242: short[][] dstData = dst.getShortDataArrays();
243:
244: int numSrcs = getNumSources();
245:
246: for (int i = 0; i < numSrcs; i++) {
247: RasterAccessor src = srcs[i];
248: int srcLineStride = src.getScanlineStride();
249: int srcPixelStride = src.getPixelStride();
250: int[] srcBandOffsets = src.getBandOffsets();
251: short[][] srcData = src.getShortDataArrays();
252:
253: for (int b = 0; b < dstBands; b++) {
254: int dstLineOffset = dstBandOffsets[b];
255: int srcLineOffset = srcBandOffsets[b];
256:
257: short[] d = dstData[b];
258: short[] s = srcData[b];
259:
260: for (int h = 0; h < dstHeight; h++) {
261: int dstPixelOffset = dstLineOffset;
262: int srcPixelOffset = srcLineOffset;
263:
264: dstLineOffset += dstLineStride;
265: srcLineOffset += srcLineStride;
266:
267: for (int w = 0; w < dstWidth; w++) {
268: d[dstPixelOffset] = ImageUtil
269: .clampShort(d[dstPixelOffset]
270: + s[srcPixelOffset]);
271:
272: dstPixelOffset += dstPixelStride;
273: srcPixelOffset += srcPixelStride;
274: }
275: }
276: }
277: }
278: }
279:
280: private void computeRectInt(RasterAccessor[] srcs,
281: RasterAccessor dst) {
282: int dstWidth = dst.getWidth();
283: int dstHeight = dst.getHeight();
284: int dstBands = dst.getNumBands();
285:
286: int dstLineStride = dst.getScanlineStride();
287: int dstPixelStride = dst.getPixelStride();
288: int[] dstBandOffsets = dst.getBandOffsets();
289: int[][] dstData = dst.getIntDataArrays();
290:
291: int numSrcs = getNumSources();
292:
293: for (int i = 0; i < numSrcs; i++) {
294: RasterAccessor src = srcs[i];
295: int srcLineStride = src.getScanlineStride();
296: int srcPixelStride = src.getPixelStride();
297: int[] srcBandOffsets = src.getBandOffsets();
298: int[][] srcData = src.getIntDataArrays();
299:
300: for (int b = 0; b < dstBands; b++) {
301: int dstLineOffset = dstBandOffsets[b];
302: int srcLineOffset = srcBandOffsets[b];
303:
304: int[] d = dstData[b];
305: int[] s = srcData[b];
306:
307: for (int h = 0; h < dstHeight; h++) {
308: int dstPixelOffset = dstLineOffset;
309: int srcPixelOffset = srcLineOffset;
310:
311: dstLineOffset += dstLineStride;
312: srcLineOffset += srcLineStride;
313:
314: for (int w = 0; w < dstWidth; w++) {
315: d[dstPixelOffset] = ImageUtil
316: .clampInt((long) d[dstPixelOffset]
317: + (long) s[srcPixelOffset]);
318:
319: dstPixelOffset += dstPixelStride;
320: srcPixelOffset += srcPixelStride;
321: }
322: }
323: }
324: }
325: }
326:
327: private void computeRectFloat(RasterAccessor[] srcs,
328: RasterAccessor dst) {
329: int dstWidth = dst.getWidth();
330: int dstHeight = dst.getHeight();
331: int dstBands = dst.getNumBands();
332:
333: int dstLineStride = dst.getScanlineStride();
334: int dstPixelStride = dst.getPixelStride();
335: int[] dstBandOffsets = dst.getBandOffsets();
336: float[][] dstData = dst.getFloatDataArrays();
337:
338: int numSrcs = getNumSources();
339:
340: for (int i = 0; i < numSrcs; i++) {
341: RasterAccessor src = srcs[i];
342: int srcLineStride = src.getScanlineStride();
343: int srcPixelStride = src.getPixelStride();
344: int[] srcBandOffsets = src.getBandOffsets();
345: float[][] srcData = src.getFloatDataArrays();
346:
347: for (int b = 0; b < dstBands; b++) {
348: int dstLineOffset = dstBandOffsets[b];
349: int srcLineOffset = srcBandOffsets[b];
350:
351: float[] d = dstData[b];
352: float[] s = srcData[b];
353:
354: for (int h = 0; h < dstHeight; h++) {
355: int dstPixelOffset = dstLineOffset;
356: int srcPixelOffset = srcLineOffset;
357:
358: dstLineOffset += dstLineStride;
359: srcLineOffset += srcLineStride;
360:
361: for (int w = 0; w < dstWidth; w++) {
362: d[dstPixelOffset] = ImageUtil
363: .clampFloat((double) d[dstPixelOffset]
364: + (double) s[srcPixelOffset]);
365:
366: dstPixelOffset += dstPixelStride;
367: srcPixelOffset += srcPixelStride;
368: }
369: }
370: }
371: }
372: }
373:
374: private void computeRectDouble(RasterAccessor[] srcs,
375: RasterAccessor dst) {
376: int dstWidth = dst.getWidth();
377: int dstHeight = dst.getHeight();
378: int dstBands = dst.getNumBands();
379:
380: int dstLineStride = dst.getScanlineStride();
381: int dstPixelStride = dst.getPixelStride();
382: int[] dstBandOffsets = dst.getBandOffsets();
383: double[][] dstData = dst.getDoubleDataArrays();
384:
385: int numSrcs = getNumSources();
386:
387: for (int i = 0; i < numSrcs; i++) {
388: RasterAccessor src = srcs[i];
389: int srcLineStride = src.getScanlineStride();
390: int srcPixelStride = src.getPixelStride();
391: int[] srcBandOffsets = src.getBandOffsets();
392: double[][] srcData = src.getDoubleDataArrays();
393:
394: for (int b = 0; b < dstBands; b++) {
395: int dstLineOffset = dstBandOffsets[b];
396: int srcLineOffset = srcBandOffsets[b];
397:
398: double[] d = dstData[b];
399: double[] s = srcData[b];
400:
401: for (int h = 0; h < dstHeight; h++) {
402: int dstPixelOffset = dstLineOffset;
403: int srcPixelOffset = srcLineOffset;
404:
405: dstLineOffset += dstLineStride;
406: srcLineOffset += srcLineStride;
407:
408: for (int w = 0; w < dstWidth; w++) {
409: d[dstPixelOffset] = d[dstPixelOffset]
410: + s[srcPixelOffset];
411:
412: dstPixelOffset += dstPixelStride;
413: srcPixelOffset += srcPixelStride;
414: }
415: }
416: }
417: }
418: }
419: }
|