001: /*
002: * $RCSfile: MlibMaxFilterOpImage.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:59 $
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.OpImage;
026: import javax.media.jai.RasterAccessor;
027: import java.util.Map;
028: import javax.media.jai.operator.MaxFilterDescriptor;
029: import javax.media.jai.operator.MaxFilterShape;
030: import com.sun.medialib.mlib.*;
031:
032: /**
033: * An OpImage class that subclasses will use to perform
034: * MaxFiltering with specific masks.
035: *
036: * @see javax.media.jai.operator.MaxFilterDescriptor
037: *
038: */
039: final class MlibMaxFilterOpImage extends AreaOpImage {
040:
041: protected int maskType; //XXX using media lib's type for MEDIAN operator!!
042: protected int maskSize;
043:
044: /**
045: * Creates a MlibMaxFilterOpImage given an image source, an
046: * optional BorderExtender, a maskType and maskSize. The image
047: * dimensions are derived the source image. The tile grid layout,
048: * SampleModel, and ColorModel may optionally be specified by an
049: * ImageLayout object.
050: *
051: * @param source a RenderedImage.
052: * @param extender a BorderExtender, or null.
053: * @param layout an ImageLayout optionally containing the tile grid layout,
054: * SampleModel, and ColorModel, or null.
055: * @param maskType the filter mask type.
056: * @param maskSize the filter mask size.
057: */
058: public MlibMaxFilterOpImage(RenderedImage source,
059: BorderExtender extender, Map config, ImageLayout layout,
060: MaxFilterShape maskType, int maskSize) {
061: super (source, layout, config, true, extender,
062: (maskSize - 1) / 2, (maskSize - 1) / 2, (maskSize / 2),
063: (maskSize / 2));
064: this .maskType = mapToMlibMaskType(maskType);
065: this .maskSize = maskSize;
066: }
067:
068: private static int mapToMlibMaskType(MaxFilterShape maskType) {
069: if (maskType.equals(MaxFilterDescriptor.MAX_MASK_SQUARE)) {
070: return Constants.MLIB_MEDIAN_MASK_RECT;
071: } else if (maskType.equals(MaxFilterDescriptor.MAX_MASK_PLUS)) {
072: return Constants.MLIB_MEDIAN_MASK_PLUS;
073: } else if (maskType.equals(MaxFilterDescriptor.MAX_MASK_X)) {
074: return Constants.MLIB_MEDIAN_MASK_X;
075: } else if (maskType
076: .equals(MaxFilterDescriptor.MAX_MASK_SQUARE_SEPARABLE)) {
077: return Constants.MLIB_MEDIAN_MASK_RECT_SEPARABLE;
078: }
079: throw new RuntimeException(JaiI18N
080: .getString("MaxFilterOpImage0"));
081: }
082:
083: /**
084: * Performs median filtering on a specified rectangle. The sources are
085: * cobbled.
086: *
087: * @param sources an array of source Rasters, guaranteed to provide all
088: * necessary source data for computing the output.
089: * @param dest a WritableRaster tile containing the area to be computed.
090: * @param destRect the rectangle within dest to be processed.
091: */
092: protected void computeRect(Raster[] sources, WritableRaster dest,
093: Rectangle destRect) {
094: Raster source = sources[0];
095: Rectangle srcRect = mapDestRect(destRect, 0);
096:
097: int formatTag = MediaLibAccessor.findCompatibleTag(sources,
098: dest);
099:
100: MediaLibAccessor srcAccessor = new MediaLibAccessor(source,
101: srcRect, formatTag);
102: MediaLibAccessor dstAccessor = new MediaLibAccessor(dest,
103: destRect, formatTag);
104: int numBands = getSampleModel().getNumBands();
105:
106: int cmask = (1 << numBands) - 1;
107: mediaLibImage[] srcML = srcAccessor.getMediaLibImages();
108: mediaLibImage[] dstML = dstAccessor.getMediaLibImages();
109:
110: for (int i = 0; i < dstML.length; i++) {
111: switch (dstAccessor.getDataType()) {
112: case DataBuffer.TYPE_BYTE:
113: case DataBuffer.TYPE_USHORT:
114: case DataBuffer.TYPE_SHORT:
115: case DataBuffer.TYPE_INT:
116: if (maskSize == 3) {
117: // Call appropriate Medialib accelerated function
118: Image.MaxFilter3x3(dstML[i], srcML[i]);
119: } else if (maskSize == 5) {
120: // Call appropriate Medialib accelerated function
121: Image.MaxFilter5x5(dstML[i], srcML[i]);
122: } else if (maskSize == 7) {
123: // Call appropriate Medialib accelerated function
124: Image.MaxFilter7x7(dstML[i], srcML[i]);
125: }
126:
127: break;
128: case DataBuffer.TYPE_FLOAT:
129: case DataBuffer.TYPE_DOUBLE:
130: if (maskSize == 3) {
131: // Call appropriate Medialib accelerated function
132: Image.MaxFilter3x3_Fp(dstML[i], srcML[i]);
133: } else if (maskSize == 5) {
134: // Call appropriate Medialib accelerated function
135: Image.MaxFilter5x5_Fp(dstML[i], srcML[i]);
136: } else if (maskSize == 7) {
137: // Call appropriate Medialib accelerated function
138: Image.MaxFilter7x7_Fp(dstML[i], srcML[i]);
139: }
140: break;
141: default:
142: String className = this .getClass().getName();
143: throw new RuntimeException(JaiI18N
144: .getString("Generic2"));
145: }
146: }
147:
148: if (dstAccessor.isDataCopy()) {
149: dstAccessor.copyDataToRaster();
150: }
151: }
152: }
|