001: /*
002: * $RCSfile: NotOpImage.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:37 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.opimage;
013:
014: import javax.media.jai.ColormapOpImage;
015: import java.awt.Rectangle;
016: import java.awt.image.DataBuffer;
017: import java.awt.image.Raster;
018: import java.awt.image.RenderedImage;
019: import java.awt.image.SampleModel;
020: import java.awt.image.WritableRaster;
021: import javax.media.jai.ImageLayout;
022: import javax.media.jai.OpImage;
023: import javax.media.jai.RasterAccessor;
024: import javax.media.jai.RasterFormatTag;
025: import java.util.Map;
026:
027: // import com.sun.media.jai.test.OpImageTester;
028:
029: /**
030: * An <code>OpImage</code> implementing the "Not" operation as
031: * described in <code>javax.media.jai.operator.NotDescriptor</code>.
032: *
033: * <p>This <code>OpImage</code> performs a logical "not" operation on
034: * the the pixel values of the source image on a per-band basis.
035: *
036: * <p>The value of the pixel (x, y) in the destination image is defined as:
037: * <pre>
038: * for (b = 0; b < numBands; b++) {
039: * dst[y][x][b] = ~(src[y][x][b]);
040: * }
041: * </pre>
042: *
043: * The data type <code>byte</code> is treated as unsigned, with maximum
044: * value as 255 and minimum value as 0.
045: *
046: * @since EA2
047: * @see javax.media.jai.operator.NotDescriptor
048: * @see NotCRIF
049: *
050: */
051: final class NotOpImage extends ColormapOpImage {
052:
053: /**
054: * Constructs an <code>NotOpImage</code>.
055: *
056: * @param source The source image.
057: * @param layout The destination image layout.
058: */
059: public NotOpImage(RenderedImage source, Map config,
060: ImageLayout layout) {
061: super (source, layout, config, true);
062:
063: // Set flag to permit in-place operation.
064: permitInPlaceOperation();
065:
066: // Initialize the colormap if necessary.
067: initializeColormapOperation();
068: }
069:
070: /**
071: * Transform the colormap according to the rescaling parameters.
072: */
073: protected void transformColormap(byte[][] colormap) {
074:
075: for (int b = 0; b < 3; b++) {
076: byte[] map = colormap[b];
077: int mapSize = map.length;
078:
079: for (int i = 0; i < mapSize; i++) {
080: map[i] = (byte) (~map[i]);
081: }
082: }
083: }
084:
085: /**
086: * Nots the pixel values of the source image within a specified
087: * 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: /* For ColormapOpImage, srcRect = destRect. */
100: RasterAccessor src = new RasterAccessor(sources[0], destRect,
101: formatTags[0], getSource(0).getColorModel());
102: RasterAccessor dst = new RasterAccessor(dest, destRect,
103: formatTags[1], getColorModel());
104:
105: if (dst.isBinary()) {
106: byte[] srcBits = src.getBinaryDataArray();
107: byte[] dstBits = dst.getBinaryDataArray();
108:
109: int length = dstBits.length;
110: for (int i = 0; i < length; i++) {
111: dstBits[i] = (byte) (~(srcBits[i]));
112: }
113:
114: dst.copyBinaryDataToRaster();
115:
116: return;
117: }
118:
119: int srcLineStride = src.getScanlineStride();
120: int srcPixelStride = src.getPixelStride();
121: int[] srcBandOffsets = src.getBandOffsets();
122:
123: int dstNumBands = dst.getNumBands();
124: int dstWidth = dst.getWidth();
125: int dstHeight = dst.getHeight();
126: int dstLineStride = dst.getScanlineStride();
127: int dstPixelStride = dst.getPixelStride();
128: int[] dstBandOffsets = dst.getBandOffsets();
129:
130: switch (dst.getDataType()) {
131:
132: case DataBuffer.TYPE_BYTE:
133: byteLoop(dstNumBands, dstWidth, dstHeight, srcLineStride,
134: srcPixelStride, srcBandOffsets, src
135: .getByteDataArrays(), dstLineStride,
136: dstPixelStride, dstBandOffsets, dst
137: .getByteDataArrays());
138: break;
139:
140: case DataBuffer.TYPE_USHORT:
141: case DataBuffer.TYPE_SHORT:
142: shortLoop(dstNumBands, dstWidth, dstHeight, srcLineStride,
143: srcPixelStride, srcBandOffsets, src
144: .getShortDataArrays(), dstLineStride,
145: dstPixelStride, dstBandOffsets, dst
146: .getShortDataArrays());
147: break;
148:
149: case DataBuffer.TYPE_INT:
150: intLoop(dstNumBands, dstWidth, dstHeight, srcLineStride,
151: srcPixelStride, srcBandOffsets, src
152: .getIntDataArrays(), dstLineStride,
153: dstPixelStride, dstBandOffsets, dst
154: .getIntDataArrays());
155: break;
156: }
157:
158: dst.copyDataToRaster();
159: }
160:
161: private void byteLoop(int dstNumBands, int dstWidth, int dstHeight,
162: int srcLineStride, int srcPixelStride,
163: int[] srcBandOffsets, byte[][] srcData, int dstLineStride,
164: int dstPixelStride, int[] dstBandOffsets, byte[][] dstData) {
165:
166: for (int b = 0; b < dstNumBands; b++) {
167: byte[] s = srcData[b];
168: byte[] d = dstData[b];
169: int srcLineOffset = srcBandOffsets[b];
170: int dstLineOffset = dstBandOffsets[b];
171:
172: for (int h = 0; h < dstHeight; h++) {
173: int srcPixelOffset = srcLineOffset;
174: int dstPixelOffset = dstLineOffset;
175: srcLineOffset += srcLineStride;
176: dstLineOffset += dstLineStride;
177:
178: for (int w = 0; w < dstWidth; w++) {
179: d[dstPixelOffset] = (byte) (~(s[srcPixelOffset]));
180: srcPixelOffset += srcPixelStride;
181: dstPixelOffset += dstPixelStride;
182: }
183: }
184: }
185: }
186:
187: private void shortLoop(int dstNumBands, int dstWidth,
188: int dstHeight, int srcLineStride, int srcPixelStride,
189: int[] srcBandOffsets, short[][] srcData, int dstLineStride,
190: int dstPixelStride, int[] dstBandOffsets, short[][] dstData) {
191:
192: for (int b = 0; b < dstNumBands; b++) {
193: short[] s = srcData[b];
194: short[] d = dstData[b];
195: int srcLineOffset = srcBandOffsets[b];
196: int dstLineOffset = dstBandOffsets[b];
197:
198: for (int h = 0; h < dstHeight; h++) {
199: int srcPixelOffset = srcLineOffset;
200: int dstPixelOffset = dstLineOffset;
201: srcLineOffset += srcLineStride;
202: dstLineOffset += dstLineStride;
203:
204: for (int w = 0; w < dstWidth; w++) {
205: d[dstPixelOffset] = (short) (~(s[srcPixelOffset]));
206: srcPixelOffset += srcPixelStride;
207: dstPixelOffset += dstPixelStride;
208: }
209: }
210: }
211: }
212:
213: private void intLoop(int dstNumBands, int dstWidth, int dstHeight,
214: int srcLineStride, int srcPixelStride,
215: int[] srcBandOffsets, int[][] srcData, int dstLineStride,
216: int dstPixelStride, int[] dstBandOffsets, int[][] dstData) {
217:
218: for (int b = 0; b < dstNumBands; b++) {
219: int[] s = srcData[b];
220: int[] d = dstData[b];
221: int srcLineOffset = srcBandOffsets[b];
222: int dstLineOffset = dstBandOffsets[b];
223:
224: for (int h = 0; h < dstHeight; h++) {
225: int srcPixelOffset = srcLineOffset;
226: int dstPixelOffset = dstLineOffset;
227: srcLineOffset += srcLineStride;
228: dstLineOffset += dstLineStride;
229:
230: for (int w = 0; w < dstWidth; w++) {
231: d[dstPixelOffset] = ~(s[srcPixelOffset]);
232: srcPixelOffset += srcPixelStride;
233: dstPixelOffset += dstPixelStride;
234: }
235: }
236: }
237: }
238:
239: // public static void main(String args[]) {
240: // System.out.println("NotOpImage Test");
241: // ImageLayout layout;
242: // OpImage src, dst;
243: // Rectangle rect = new Rectangle(0, 0, 5, 5);
244:
245: // System.out.println("1. PixelInterleaved byte 3-band");
246: // layout = OpImageTester.createImageLayout(
247: // 0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, false);
248: // src = OpImageTester.createRandomOpImage(layout);
249: // dst = new NotOpImage(src, null, null);
250: // OpImageTester.testOpImage(dst, rect);
251: // OpImageTester.timeOpImage(dst, 10);
252:
253: // System.out.println("2. Banded byte 3-band");
254: // layout = OpImageTester.createImageLayout(
255: // 0, 0, 800, 800, 0, 0, 200, 200, DataBuffer.TYPE_BYTE, 3, true);
256: // src = OpImageTester.createRandomOpImage(layout);
257: // dst = new NotOpImage(src, null, null);
258: // OpImageTester.testOpImage(dst, rect);
259: // OpImageTester.timeOpImage(dst, 10);
260:
261: // System.out.println("3. PixelInterleaved int 3-band");
262: // layout = OpImageTester.createImageLayout(
263: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_INT, 3, false);
264: // src = OpImageTester.createRandomOpImage(layout);
265: // dst = new NotOpImage(src, null, null);
266: // OpImageTester.testOpImage(dst, rect);
267: // OpImageTester.timeOpImage(dst, 10);
268:
269: // System.out.println("4. Banded int 3-band");
270: // layout = OpImageTester.createImageLayout(
271: // 0, 0, 512, 512, 0, 0, 200, 200, DataBuffer.TYPE_INT, 3, true);
272: // src = OpImageTester.createRandomOpImage(layout);
273: // dst = new NotOpImage(src, null, null);
274: // OpImageTester.testOpImage(dst, rect);
275: // OpImageTester.timeOpImage(dst, 10);
276: // }
277: }
|