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

COVERAGE SUMMARY FOR SOURCE FILE [ThresholdDifferenceBlurOpImage.java]

nameclass, %method, %block, %line, %
ThresholdDifferenceBlurOpImage.java0%   (0/1)0%   (0/4)0%   (0/440)0%   (0/97)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ThresholdDifferenceBlurOpImage0%   (0/1)0%   (0/4)0%   (0/440)0%   (0/97)
<static initializer> 0%   (0/1)0%   (0/15)0%   (0/1)
ThresholdDifferenceBlurOpImage (RenderedImage, BorderExtender, Map, ImageLayo... 0%   (0/1)0%   (0/30)0%   (0/6)
byteLoop (RasterAccessor, RasterAccessor): void 0%   (0/1)0%   (0/336)0%   (0/77)
computeRect (Raster [], WritableRaster, Rectangle): void 0%   (0/1)0%   (0/59)0%   (0/13)

1/*
2 *  $RCSfile: ThresholdDifferenceBlurOpImage.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 difference gaussian blur on a source image.
40 *
41 * @see    Convolution
42 */
43final class ThresholdDifferenceBlurOpImage extends AreaOpImage
44{
45 
46    /**
47     *  The kernel with which to do the convolve 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 ConvolveOpImage given a ParameterBlock containing the image source and pre-rotated
60     *  convolution kernel. The image dimensions are derived from the source image. The tile grid
61     *  layout, SampleModel, and ColorModel may optionally be specified by an ImageLayout object.
62     *
63     * @param  source     a RenderedImage.
64     * @param  extender   a BorderExtender, or null.
65     * @param  config     Description of the parameter
66     * @param  layout     an ImageLayout optionally containing the tile grid layout, SampleModel,
67     *      and ColorModel, or null.
68     * @param  kernel     the pre-rotated convolution KernelJAI.
69     * @param  threshold  Description of the parameter
70     */
71    public ThresholdDifferenceBlurOpImage(RenderedImage source,
72            BorderExtender extender,
73            Map config,
74            ImageLayout layout,
75            KernelJAI kernel,
76            int threshold) {
77        super(source,
78                layout,
79                config,
80                true,
81                extender,
82                kernel.getLeftPadding(),
83                kernel.getRightPadding(),
84                kernel.getTopPadding(),
85                kernel.getBottomPadding());
86 
87        this.kernel = kernel;
88        kw = kernel.getWidth();
89        kh = kernel.getHeight();
90        this.threshold = threshold;
91    }
92 
93    /**
94     *  Performs threshold gaussian blur on a specified rectangle. The sources are cobbled. The
95     *  target pixel is only blurred if (R+G+B/3) > threshold.
96     *
97     * @param  sources   an array of source Rasters, guaranteed to provide all necessary source data
98     *      for computing the output.
99     * @param  dest      a WritableRaster tile containing the area to be computed.
100     * @param  destRect  the rectangle within dest to be processed.
101     */
102    protected void computeRect(Raster[] sources,
103            WritableRaster dest,
104            Rectangle destRect) {
105        // Retrieve format tags.
106        RasterFormatTag[] formatTags = getFormatTags();
107 
108        Raster source = sources[0];
109        Rectangle srcRect = mapDestRect(destRect, 0);
110 
111        RasterAccessor srcAccessor =
112                new RasterAccessor(source, srcRect,
113                formatTags[0], getSourceImage(0).getColorModel());
114        RasterAccessor dstAccessor =
115                new RasterAccessor(dest, destRect,
116                formatTags[1], getColorModel());
117 
118        switch (dstAccessor.getDataType()) {
119            case DataBuffer.TYPE_BYTE:
120                byteLoop(srcAccessor, dstAccessor);
121                break;
122            default:
123                assert false : "Byte Type Only!";
124        }
125 
126        // If the RasterAccessor object set up a temporary buffer for the
127        // op to write to, tell the RasterAccessor to write that data
128        // to the raster now that we're done with it.
129        if (dstAccessor.isDataCopy()) {
130            dstAccessor.clampDataArrays();
131            dstAccessor.copyDataToRaster();
132        }
133    }
134 
135    private void byteLoop(RasterAccessor src, RasterAccessor dst) {
136        int dwidth = dst.getWidth();
137        int dheight = dst.getHeight();
138        int dnumBands = dst.getNumBands();
139 
140        int swidth = src.getWidth();
141        int sheight = src.getHeight();
142        int snumBands = src.getNumBands();
143 
144        int wShift = (swidth - dwidth) / 2;
145        int hShift = (sheight - dheight) / 2;
146 
147        float[] kdata = kernel.getKernelData();
148 
149        byte dstDataArrays[][] = dst.getByteDataArrays();
150        int dstBandOffsets[] = dst.getBandOffsets();
151        int dstPixelStride = dst.getPixelStride();
152        int dstScanlineStride = dst.getScanlineStride();
153 
154        byte srcDataArrays[][] = src.getByteDataArrays();
155        int srcBandOffsets[] = src.getBandOffsets();
156        int srcPixelStride = src.getPixelStride();
157        int srcScanlineStride = src.getScanlineStride();
158        int spShift = hShift * srcScanlineStride + wShift * srcPixelStride;
159 
160        int workArray[][] = new int[sheight][swidth];
161        int min = 10000;
162        int max = -10000;
163 
164        for (int i = 0; i < sheight; i++) {
165            int tmp;
166 
167            for (int j = 0; j < swidth; j++) {
168                for (int k = 0; k < snumBands; k++) {
169 
170                    tmp = srcDataArrays[k][i * srcScanlineStride + j * srcPixelStride];
171                    tmp = (tmp < 0 ? tmp + 255 : tmp);
172                    workArray[i][j] += tmp;
173 
174                    if (tmp < min) {
175                        min = tmp;
176                    }
177                    if (tmp > max) {
178                        max = tmp;
179                    }
180                }
181                workArray[i][j] /= snumBands;
182            }
183        }
184 
185        int threshold2 = threshold + 255 - max;
186 
187        for (int k = 0; k < dnumBands; k++) {
188            byte dstData[] = dstDataArrays[k];
189            byte srcData[] = srcDataArrays[k];
190            int srcScanlineOffset = srcBandOffsets[k];
191            int dstScanlineOffset = dstBandOffsets[k];
192 
193            for (int j = 0; j < dheight; j++) {
194                int srcPixelOffset = srcScanlineOffset;
195                int dstPixelOffset = dstScanlineOffset;
196                float f = 0;
197                float weight = 0;
198                int kernelVerticalOffset = 0;
199                int imageVerticalOffset = srcPixelOffset;
200                int imageOffset = imageVerticalOffset;
201                int tmp;
202                int val;
203 
204                for (int i = 0; i < dwidth; i++) {
205                    if (workArray[j + hShift][i + wShift] < threshold2) {
206                        dstData[dstPixelOffset] = srcData[srcPixelOffset + spShift];
207                        srcPixelOffset += srcPixelStride;
208                        dstPixelOffset += dstPixelStride;
209                        continue;
210                    }
211 
212                    f = 0;
213                    weight = 0;
214                    kernelVerticalOffset = 0;
215                    imageVerticalOffset = srcPixelOffset;
216 
217                    for (int u = 0; u < kh; u++) {
218                        imageOffset = imageVerticalOffset;
219                        for (int v = 0; v < kw; v++) {
220                            tmp = srcData[imageOffset];
221                            tmp = (tmp < 0 ? tmp + 255 : tmp);
222                            f += tmp * kdata[kernelVerticalOffset + v];
223                            weight += kdata[kernelVerticalOffset + v];
224                            imageOffset += srcPixelStride;
225                        }
226                        kernelVerticalOffset += kw;
227                        imageVerticalOffset += srcScanlineStride;
228                    }
229 
230                    val = (int) (f / weight);
231 
232                    if (val < 0) {
233                        val = 0;
234                    } else if (val > 255) {
235                        val = 255;
236                    }
237                    dstData[dstPixelOffset] = (byte) val;
238                    srcPixelOffset += srcPixelStride;
239                    dstPixelOffset += dstPixelStride;
240                }
241                srcScanlineOffset += srcScanlineStride;
242                dstScanlineOffset += dstScanlineStride;
243            }
244        }
245        //System.err.println("min2: "+min+" max: "+max);
246        //System.err.println("Done3: "+skip/3+" "+hit/3);
247    }
248}

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