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