summaryrefslogtreecommitdiffstats
path: root/awt/java/awt/image/AreaAveragingScaleFilter.java
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
committerThe Android Open Source Project <initial-contribution@android.com>2008-10-21 07:00:00 -0700
commit7c1b96a165f970a09ed239bb4fb3f1b0d8f2a407 (patch)
treedf5a6539447324de36e95b057d6b9f0361b7a250 /awt/java/awt/image/AreaAveragingScaleFilter.java
downloadframeworks_native-7c1b96a165f970a09ed239bb4fb3f1b0d8f2a407.zip
frameworks_native-7c1b96a165f970a09ed239bb4fb3f1b0d8f2a407.tar.gz
frameworks_native-7c1b96a165f970a09ed239bb4fb3f1b0d8f2a407.tar.bz2
Initial Contribution
Diffstat (limited to 'awt/java/awt/image/AreaAveragingScaleFilter.java')
-rw-r--r--awt/java/awt/image/AreaAveragingScaleFilter.java253
1 files changed, 253 insertions, 0 deletions
diff --git a/awt/java/awt/image/AreaAveragingScaleFilter.java b/awt/java/awt/image/AreaAveragingScaleFilter.java
new file mode 100644
index 0000000..f4933db
--- /dev/null
+++ b/awt/java/awt/image/AreaAveragingScaleFilter.java
@@ -0,0 +1,253 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+/**
+ * @author Igor V. Stolyarov
+ * @version $Revision$
+ */
+package java.awt.image;
+
+import java.util.Arrays;
+
+
+/**
+ * The AreaAveragingScaleFilter class scales the source image using
+ * area averaging algorithm. This algorithm provides a source image
+ * with a new image containing the resampled image.
+ */
+public class AreaAveragingScaleFilter extends ReplicateScaleFilter {
+
+ /** The Constant rgbCM. */
+ private static final ColorModel rgbCM = ColorModel.getRGBdefault();
+
+ /** The Constant averagingFlags. */
+ private static final int averagingFlags = (ImageConsumer.TOPDOWNLEFTRIGHT |
+ ImageConsumer.COMPLETESCANLINES);
+
+ /** The reset. */
+ private boolean reset = true; // Flag for used superclass filter
+
+ /** The inited. */
+ private boolean inited = false; // All data inited
+
+ /** The sum_r. */
+ private int sum_r[]; // Array for average Red samples
+
+ /** The sum_g. */
+ private int sum_g[]; // Array for average Green samples
+
+ /** The sum_b. */
+ private int sum_b[]; // Array for average Blue samples
+
+ /** The sum_a. */
+ private int sum_a[]; // Array for average Alpha samples
+
+ /** The buff. */
+ private int buff[]; // Stride buffer
+
+ /** The avg factor. */
+ private int avgFactor; // Global averaging factor
+
+ /** The cached dy. */
+ private int cachedDY; // Cached number of the destination scanline
+
+ /** The cached dv rest. */
+ private int cachedDVRest; // Cached value of rest src scanlines for sum
+ // pixel samples
+ // Because data if transfering by whole scanlines
+ // we are caching only Y coordinate values
+
+ /**
+ * Instantiates a new AreaAveragingScaleFilter object which scales
+ * a source image with the specified width and height.
+ *
+ * @param width the scaled width of the image.
+ * @param height the scaled height of the image.
+ */
+ public AreaAveragingScaleFilter(int width, int height) {
+ super(width, height);
+ }
+
+ @Override
+ public void setPixels(int x, int y, int w, int h, ColorModel model, int[] pixels, int off, int scansize) {
+ if(reset) {
+ super.setPixels(x, y, w, h, model, pixels, off, scansize);
+ } else {
+ setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+ }
+ }
+
+ @Override
+ public void setPixels(int x, int y, int w, int h, ColorModel model, byte[] pixels, int off, int scansize) {
+ if(reset) {
+ super.setPixels(x, y, w, h, model, pixels, off, scansize);
+ } else {
+ setFilteredPixels(x, y, w, h, model, pixels, off, scansize);
+ }
+ }
+
+ @Override
+ public void setHints(int hints) {
+ super.setHints(hints);
+ reset = ((hints & averagingFlags) != averagingFlags);
+ }
+
+ /**
+ * This method implements the Area Averaging Scale filter.
+ * The description of algorithm is presented in Java API Specification.
+ *
+ * Arrays sum_r, sum_g, sum_b, sum_a have length equals width of destination
+ * image. In each array's element is accumulating pixel's component values,
+ * proportional to the area which source pixels will occupy in destination
+ * image. Then that values will divide by Global averaging
+ * factor (area of the destination image) for receiving
+ * average values of destination pixels.
+ *
+ * @param x - Src pixels X coordinate
+ * @param y - Src pixels Y coordinate
+ * @param w - width of the area of Src pixels
+ * @param h - height of the area of Src pixels
+ * @param model - Color Model of Src pixels
+ * @param pixels - array of Src pixels
+ * @param off - offset into the Src pixels array
+ * @param scansize - length of scanline in the pixels array
+ */
+ private void setFilteredPixels(int x, int y, int w, int h, ColorModel model, Object pixels, int off, int scansize){
+ if(!inited){
+ initialize();
+ }
+
+ int srcX, srcY, dx, dy;
+ int svRest, dvRest, shRest, dhRest, vDif, hDif;
+
+ if(y == 0){
+ dy = 0;
+ dvRest = srcHeight;
+ }else{
+ dy = cachedDY;
+ dvRest = cachedDVRest;
+ }
+
+ srcY = y;
+ svRest = destHeight;
+
+ int srcOff = off;
+ while (srcY < y + h) {
+ if (svRest < dvRest) {
+ vDif = svRest;
+ } else {
+ vDif = dvRest;
+ }
+
+ srcX = 0;
+ dx = 0;
+ shRest = destWidth;
+ dhRest = srcWidth;
+ while (srcX < w) {
+ if (shRest < dhRest) {
+ hDif = shRest;
+ } else {
+ hDif = dhRest;
+ }
+ int avg = hDif * vDif; // calculation of contribution factor
+
+ int rgb, pix;
+ if (pixels instanceof int[]) {
+ pix = ((int[]) pixels)[srcOff + srcX];
+ } else {
+ pix = ((byte[]) pixels)[srcOff + srcX] & 0xff;
+ }
+
+ rgb = model.getRGB(pix);
+ int a = rgb >>> 24;
+ int r = (rgb >> 16) & 0xff;
+ int g = (rgb >> 8) & 0xff;
+ int b = rgb & 0xff;
+
+ // accumulating pixel's component values
+ sum_a[dx] += a * avg;
+ sum_r[dx] += r * avg;
+ sum_g[dx] += g * avg;
+ sum_b[dx] += b * avg;
+
+ shRest -= hDif;
+ dhRest -= hDif;
+
+ if (shRest == 0) {
+ srcX++;
+ shRest = destWidth;
+ }
+
+ if (dhRest == 0) {
+ dx++;
+ dhRest = srcWidth;
+ }
+ }
+
+ svRest -= vDif;
+ dvRest -= vDif;
+
+ if (svRest == 0) {
+ svRest = destHeight;
+ srcY++;
+ srcOff += scansize;
+ }
+
+ if (dvRest == 0) {
+ // averaging destination pixel's values
+ for(int i = 0; i < destWidth; i++){
+ int a = (sum_a[i] / avgFactor) & 0xff;
+ int r = (sum_r[i] / avgFactor) & 0xff;
+ int g = (sum_g[i] / avgFactor) & 0xff;
+ int b = (sum_b[i] / avgFactor) & 0xff;
+ int frgb = (a << 24) | (r << 16) | (g << 8) | b;
+ buff[i] = frgb;
+ }
+ consumer.setPixels(0, dy, destWidth, 1, rgbCM, buff, 0,
+ destWidth);
+ dy++;
+ dvRest = srcHeight;
+ Arrays.fill(sum_a, 0);
+ Arrays.fill(sum_r, 0);
+ Arrays.fill(sum_g, 0);
+ Arrays.fill(sum_b, 0);
+ }
+
+ }
+
+ cachedDY = dy;
+ cachedDVRest = dvRest;
+
+ }
+
+ /**
+ * Initialization of the auxiliary data.
+ */
+ private void initialize(){
+
+ sum_a = new int[destWidth];
+ sum_r = new int[destWidth];
+ sum_g = new int[destWidth];
+ sum_b = new int[destWidth];
+
+ buff = new int[destWidth];
+ outpixbuf = buff;
+ avgFactor = srcWidth * srcHeight;
+
+ inited = true;
+ }
+}
+