EMMA Coverage Report (generated Sun Apr 20 22:38:01 CEST 2008)
[all classes][net.sf.jomic.tools]

COVERAGE SUMMARY FOR SOURCE FILE [ThresholdBlurOpImage.java]

nameclass, %method, %block, %line, %
ThresholdBlurOpImage.java0%   (0/1)0%   (0/4)0%   (0/336)0%   (0/70)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ThresholdBlurOpImage0%   (0/1)0%   (0/4)0%   (0/336)0%   (0/70)
<static initializer> 0%   (0/1)0%   (0/15)0%   (0/1)
ThresholdBlurOpImage (RenderedImage, BorderExtender, Map, ImageLayout, Kernel... 0%   (0/1)0%   (0/30)0%   (0/6)
byteLoop (RasterAccessor, RasterAccessor): void 0%   (0/1)0%   (0/232)0%   (0/50)
computeRect (Raster [], WritableRaster, Rectangle): void 0%   (0/1)0%   (0/59)0%   (0/13)

1/*
2 *  $RCSfile: ThresholdBlurOpImage.java $
3 *
4 *  Copyright (c) 2007 Jeremiah Spaulding
5 *
6 *  This program is free software; you can redistribute it and/or modify
7 *  it under the terms of the GNU General Public License as published by
8 *  the Free Software Foundation; either version 2 of the License, or
9 *  (at your option) any later version.
10 *
11 *  This program is distributed in the hope that it will be useful,
12 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *  GNU General Public License for more details.
15 *
16 *  You should have received a copy of the GNU General Public License
17 *  along with this program; if not, write to the Free Software
18 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 *
20 *  $Revision: 1.0 $
21 *  $Date: 2007/07/15 00:00:00 $
22 */
23package net.sf.jomic.tools;
24 
25import java.awt.Rectangle;
26import java.awt.image.DataBuffer;
27import java.awt.image.Raster;
28import java.awt.image.RenderedImage;
29import java.awt.image.WritableRaster;
30import javax.media.jai.AreaOpImage;
31import javax.media.jai.BorderExtender;
32import javax.media.jai.ImageLayout;
33import javax.media.jai.KernelJAI;
34import javax.media.jai.RasterAccessor;
35import javax.media.jai.RasterFormatTag;
36import java.util.Map;
37 
38/**
39 *  An OpImage class to perform threshold bounded gaussian blur on a source image.
40 *
41 * @see    Convolution
42 */
43final class ThresholdBlurOpImage extends AreaOpImage
44{
45 
46    /**
47     *  The kernel with which to do the operation.
48     */
49    protected KernelJAI kernel;
50 
51    /**
52     *  Kernel variables.
53     */
54    private int kw, kh;
55 
56    private int threshold;
57 
58    /**
59     *  Creates a ThresholdBlurOpImage given a ParameterBlock containing the image source and
60     *  pre-rotated convolution kernel. The image dimensions are derived from the source image. The
61     *  tile grid layout, SampleModel, and ColorModel may optionally be specified by an ImageLayout
62     *  object.
63     *
64     * @param  source     a RenderedImage.
65     * @param  extender   a BorderExtender, or null.
66     * @param  config     Description of the parameter
67     * @param  layout     an ImageLayout optionally containing the tile grid layout, SampleModel,
68     *      and ColorModel, or null.
69     * @param  kernel     the pre-rotated convolution KernelJAI.
70     * @param  threshold  the user-set threshold.
71     */
72    public ThresholdBlurOpImage(RenderedImage source,
73            BorderExtender extender,
74            Map config,
75            ImageLayout layout,
76            KernelJAI kernel,
77            int threshold) {
78        super(source,
79                layout,
80                config,
81                true,
82                extender,
83                kernel.getLeftPadding(),
84                kernel.getRightPadding(),
85                kernel.getTopPadding(),
86                kernel.getBottomPadding());
87 
88        this.kernel = kernel;
89        kw = kernel.getWidth();
90        kh = kernel.getHeight();
91        this.threshold = threshold;
92    }
93 
94    /**
95     *  Performs threshold gaussian blur on a specified rectangle. The sources are cobbled. When
96     *  blurring the target pixel, only other pixels under the kernel whose difference from the
97     *  target pixel is within THRESHOLD are considered.
98     *
99     * @param  sources   an array of source Rasters, guaranteed to provide all necessary source data
100     *      for computing the output.
101     * @param  dest      a WritableRaster tile containing the area to be computed.
102     * @param  destRect  the rectangle within dest to be processed.
103     */
104    protected void computeRect(Raster[] sources,
105            WritableRaster dest,
106            Rectangle destRect) {
107        // Retrieve format tags.
108        RasterFormatTag[] formatTags = getFormatTags();
109 
110        Raster source = sources[0];
111        Rectangle srcRect = mapDestRect(destRect, 0);
112 
113        RasterAccessor srcAccessor =
114                new RasterAccessor(source, srcRect,
115                formatTags[0], getSourceImage(0).getColorModel());
116        RasterAccessor dstAccessor =
117                new RasterAccessor(dest, destRect,
118                formatTags[1], getColorModel());
119 
120        switch (dstAccessor.getDataType()) {
121            case DataBuffer.TYPE_BYTE:
122                byteLoop(srcAccessor, dstAccessor);
123                break;
124            default:
125                assert false : "Byte Type Only!";
126        }
127 
128        // If the RasterAccessor object set up a temporary buffer for the
129        // op to write to, tell the RasterAccessor to write that data
130        // to the raster now that we're done with it.
131        if (dstAccessor.isDataCopy()) {
132            dstAccessor.clampDataArrays();
133            dstAccessor.copyDataToRaster();
134        }
135    }
136 
137    private void byteLoop(RasterAccessor src, RasterAccessor dst) {
138        int dwidth = dst.getWidth();
139        int dheight = dst.getHeight();
140        int dnumBands = dst.getNumBands();
141 
142        float[] kdata = kernel.getKernelData();
143 
144        byte dstDataArrays[][] = dst.getByteDataArrays();
145        int dstBandOffsets[] = dst.getBandOffsets();
146        int dstPixelStride = dst.getPixelStride();
147        int dstScanlineStride = dst.getScanlineStride();
148 
149        byte srcDataArrays[][] = src.getByteDataArrays();
150        int srcBandOffsets[] = src.getBandOffsets();
151        int srcPixelStride = src.getPixelStride();
152        int srcScanlineStride = src.getScanlineStride();
153        int toMiddle = (kw / 2 * srcPixelStride) + (kh / 2 * srcScanlineStride);
154 
155        for (int k = 0; k < dnumBands; k++) {
156            byte dstData[] = dstDataArrays[k];
157            byte srcData[] = srcDataArrays[k];
158            int srcScanlineOffset = srcBandOffsets[k];
159            int dstScanlineOffset = dstBandOffsets[k];
160 
161            for (int j = 0; j < dheight; j++) {
162                int srcPixelOffset = srcScanlineOffset;
163                int dstPixelOffset = dstScanlineOffset;
164 
165                for (int i = 0; i < dwidth; i++) {
166                    byte origPixel = srcData[srcPixelOffset + toMiddle];
167                    float f = 0;
168                    float weight = 0;
169                    int kernelVerticalOffset = 0;
170                    int imageVerticalOffset = srcPixelOffset;
171                    int imageOffset = imageVerticalOffset;
172 
173                    for (int u = 0; u < kh; u++) {
174                        imageOffset = imageVerticalOffset;
175                        for (int v = 0; v < kw; v++) {
176                            if ((origPixel >= srcData[imageOffset] && (origPixel - srcData[imageOffset]) < threshold) ||
177                                    (origPixel < srcData[imageOffset] && (srcData[imageOffset] - origPixel) < threshold)) {
178                                f += (srcData[imageOffset] & 0xff) * kdata[kernelVerticalOffset + v];
179                                weight += kdata[kernelVerticalOffset + v];
180                            }
181                            imageOffset += srcPixelStride;
182                        }
183                        kernelVerticalOffset += kw;
184                        imageVerticalOffset += srcScanlineStride;
185                    }
186 
187                    int val;
188 
189                    if (weight == 0) {
190                        val = origPixel;
191                    } else {
192                        val = (int) (f / weight);
193                    }
194 
195                    if (val < 0) {
196                        val = 0;
197                    } else if (val > 255) {
198                        val = 255;
199                    }
200                    dstData[dstPixelOffset] = (byte) val;
201                    srcPixelOffset += srcPixelStride;
202                    dstPixelOffset += dstPixelStride;
203                }
204                srcScanlineOffset += srcScanlineStride;
205                dstScanlineOffset += dstScanlineStride;
206            }
207        }
208    }
209}

[all classes][net.sf.jomic.tools]
EMMA 2.0.4217 (C) Vladimir Roubtsov