001: /*
002: * $RCSfile: MlibGradientOpImage.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:55:57 $
010: * $State: Exp $
011: */
012: package com.sun.media.jai.mlib;
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.KernelJAI;
026: import javax.media.jai.OpImage;
027: import java.util.Map;
028: import com.sun.medialib.mlib.*;
029:
030: // import com.sun.media.jai.test.OpImageTester;
031:
032: /**
033: * An OpImage class to perform Gradient operation on a source image.
034: *
035: * <p> The Kernels cannot be bigger in any dimension than the image data.
036: *
037: *
038: * @see KernelJAI
039: */
040: final class MlibGradientOpImage extends AreaOpImage {
041:
042: /**
043: * The orthogonal kernels with which to do the Gradient operation.
044: */
045: protected KernelJAI kernel_h, kernel_v;
046:
047: /** Kernel variables. */
048: private int kh, kw, kx, ky;
049: float kernel_h_data[], kernel_v_data[];
050:
051: /** Local copy of kernel's data */
052: double dbl_kh_data[], dbl_kv_data[];
053:
054: /**
055: * Creates a MlibGradientOpImage given the image source and
056: * the pair of orthogonal gradient kernels. The image dimensions are
057: * derived from the source image. The tile grid layout,
058: * SampleModel, and ColorModel may optionally be specified by an
059: * ImageLayout object.
060: *
061: * @param source a RenderedImage.
062: * @param extender a BorderExtender, or null.
063:
064: * @param layout an ImageLayout optionally containing the tile grid layout,
065: * SampleModel, and ColorModel, or null.
066: * @param kernel_h the horizontal kernel
067: * @param kernel_v the vertical kernel
068: */
069: public MlibGradientOpImage(RenderedImage source,
070: BorderExtender extender, Map config, ImageLayout layout,
071: KernelJAI kernel_h, KernelJAI kernel_v) {
072: super (source, layout, config, true, extender, kernel_h
073: .getLeftPadding(), kernel_h.getRightPadding(), kernel_h
074: .getTopPadding(), kernel_h.getBottomPadding());
075:
076: this .kernel_h = kernel_h;
077: this .kernel_v = kernel_v;
078:
079: //
080: // At this point both kernels should be of same width & height
081: // so it's enough to get the information from one of them
082: //
083: kw = kernel_h.getWidth();
084: kh = kernel_h.getHeight();
085:
086: //
087: // center of kernels
088: //
089: kx = kw / 2;
090: ky = kh / 2;
091:
092: //
093: // Get the kernel data into local double arrays
094: //
095: kernel_h_data = kernel_h.getKernelData();
096: kernel_v_data = kernel_v.getKernelData();
097: int count = kw * kh;
098: dbl_kh_data = new double[count];
099: dbl_kv_data = new double[count];
100: for (int i = 0; i < count; i++) {
101: dbl_kh_data[i] = (double) kernel_h_data[i];
102: dbl_kv_data[i] = (double) kernel_v_data[i];
103: }
104: }
105:
106: /**
107: * Performs Gradient on a specified rectangle. The sources are cobbled.
108: *
109: * @param sources an array of source Rasters, guaranteed to provide all
110: * necessary source data for computing the output.
111: * @param dest a WritableRaster tile containing the area to be computed.
112: * @param destRect the rectangle within dest to be processed.
113: */
114: protected void computeRect(Raster[] sources, WritableRaster dest,
115: Rectangle destRect) {
116: Raster source = sources[0];
117: Rectangle srcRect = mapDestRect(destRect, 0);
118:
119: int formatTag = MediaLibAccessor.findCompatibleTag(sources,
120: dest);
121:
122: MediaLibAccessor srcAccessor = new MediaLibAccessor(source,
123: srcRect, formatTag);
124: MediaLibAccessor dstAccessor = new MediaLibAccessor(dest,
125: destRect, formatTag);
126: int numBands = getSampleModel().getNumBands();
127:
128: mediaLibImage[] srcML = srcAccessor.getMediaLibImages();
129: mediaLibImage[] dstML = dstAccessor.getMediaLibImages();
130: for (int i = 0; i < dstML.length; i++) {
131: switch (dstAccessor.getDataType()) {
132: case DataBuffer.TYPE_BYTE:
133: case DataBuffer.TYPE_USHORT:
134: case DataBuffer.TYPE_SHORT:
135: case DataBuffer.TYPE_INT:
136: Image.GradientMxN(dstML[i], srcML[i], dbl_kh_data,
137: dbl_kv_data, kw, kh, kx, ky,
138: ((1 << numBands) - 1),
139: Constants.MLIB_EDGE_DST_NO_WRITE);
140: break;
141:
142: case DataBuffer.TYPE_FLOAT:
143: case DataBuffer.TYPE_DOUBLE:
144: Image.GradientMxN_Fp(dstML[i], srcML[i], dbl_kh_data,
145: dbl_kv_data, kw, kh, kx, ky,
146: ((1 << numBands) - 1),
147: Constants.MLIB_EDGE_DST_NO_WRITE);
148: break;
149:
150: default:
151: String className = this .getClass().getName();
152: throw new RuntimeException(JaiI18N
153: .getString("Generic2"));
154: }
155: }
156:
157: if (dstAccessor.isDataCopy()) {
158: dstAccessor.copyDataToRaster();
159: }
160: }
161:
162: // public static OpImage createTestImage(OpImageTester oit) {
163: // float data_h[] = {-1.0f, -2.0f, -1.0f,
164: // 0.0f, 0.0f, 0.0f,
165: // 1.0f, 2.0f, 1.0f};
166: // float data_v[] = {-1.0f, 0.0f, 1.0f,
167: // -2.0f, 0.0f, 2.0f,
168: // -1.0f, 0.0f, 1.0f};
169:
170: // KernelJAI kern_h = new KernelJAI(3,3,data_h);
171: // KernelJAI kern_v = new KernelJAI(3,3,data_v);
172:
173: // return new MlibGradientOpImage(oit.getSource(), null, null,
174: // new ImageLayout(oit.getSource()),
175: // kern_h, kern_v);
176: // }
177:
178: // public static void main (String args[]) {
179: // String classname = "com.sun.media.jai.mlib.MlibGradientOpImage";
180: // OpImageTester.performDiagnostics(classname,args);
181: // }
182: }
|