OSDN Git Service

Added a FixedRotationFilter.
authorWei Hua <whua@google.com>
Thu, 1 Sep 2011 00:07:53 +0000 (17:07 -0700)
committerWei Hua <whua@google.com>
Thu, 1 Sep 2011 00:07:53 +0000 (17:07 -0700)
bug: 5221073
RotationFilter is used for dealing the 4 orientations of the device.
Fixed ToPackedGrayFilter to correctly resize the image
if aspect ratio needs to be kept.

Change-Id: Idd3c26ae2ec12b64f7d040a301a87c619fe146e3

mca/filterpacks/imageproc/java/FixedRotationFilter.java [new file with mode: 0644]
mca/filterpacks/imageproc/java/ToPackedGrayFilter.java

diff --git a/mca/filterpacks/imageproc/java/FixedRotationFilter.java b/mca/filterpacks/imageproc/java/FixedRotationFilter.java
new file mode 100644 (file)
index 0000000..73b733d
--- /dev/null
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2011 The Android Open Source Project
+ *
+ * Licensed 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.
+ */
+
+package android.filterpacks.imageproc;
+
+import android.filterfw.core.Filter;
+import android.filterfw.core.FilterContext;
+import android.filterfw.core.Frame;
+import android.filterfw.core.FrameFormat;
+import android.filterfw.core.GenerateFieldPort;
+import android.filterfw.core.MutableFrameFormat;
+import android.filterfw.core.Program;
+import android.filterfw.core.ShaderProgram;
+import android.filterfw.format.ImageFormat;
+import android.filterfw.geometry.Point;
+import android.filterfw.geometry.Quad;
+
+/**
+ * The FixedRotationFilter rotates the input image clockwise, it only accepts
+ * 4 rotation angles: 0, 90, 180, 270
+ * @hide
+ */
+public class FixedRotationFilter extends Filter {
+
+    @GenerateFieldPort(name = "rotation")
+    private int mRotation = 0;
+
+    private ShaderProgram mProgram = null;
+
+    public FixedRotationFilter(String name) {
+        super(name);
+    }
+
+    @Override
+    public void setupPorts() {
+        addMaskedInputPort("image", ImageFormat.create(ImageFormat.COLORSPACE_RGBA,
+                                                       FrameFormat.TARGET_GPU));
+        addOutputBasedOnInput("image", "image");
+    }
+
+    @Override
+    public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) {
+        return inputFormat;
+    }
+
+    @Override
+    public void process(FilterContext context) {
+        Frame input = pullInput("image");
+        if (mRotation == 0) {
+            pushOutput("image", input);
+            return;
+        }
+        FrameFormat inputFormat = input.getFormat();
+
+        // Create program if not created already
+        if (mProgram == null) {
+            mProgram = ShaderProgram.createIdentity(context);
+        }
+        MutableFrameFormat outputFormat = inputFormat.mutableCopy();
+        int width = inputFormat.getWidth();
+        int height = inputFormat.getHeight();
+        Point p1 = new Point(0.0f, 0.0f);
+        Point p2 = new Point(1.0f, 0.0f);
+        Point p3 = new Point(0.0f, 1.0f);
+        Point p4 = new Point(1.0f, 1.0f);
+        Quad sourceRegion;
+        switch (mRotation) {
+            case 90:
+                sourceRegion = new Quad(p3,p1,p4,p2);
+                outputFormat.setDimensions(height, width);
+                break;
+            case 180:
+                sourceRegion = new Quad(p4,p3,p2,p1);
+                break;
+            case 270:
+                sourceRegion = new Quad(p2,p4,p1,p3);
+                outputFormat.setDimensions(height, width);
+                break;
+            default: // no rotation
+                sourceRegion = new Quad(p1,p2,p3,p4);
+                break;
+        }
+        // Create output frame
+        Frame output = context.getFrameManager().newFrame(outputFormat);
+
+        // Set the source region
+        mProgram.setSourceRegion(sourceRegion);
+
+        // Process
+        mProgram.process(input, output);
+
+        // Push output
+        pushOutput("image", output);
+
+        // Release pushed frame
+        output.release();
+    }
+}
index 16b3e0b..3489dd4 100644 (file)
@@ -29,6 +29,7 @@ import android.filterfw.format.ImageFormat;
 
 import android.util.Log;
 
+import java.lang.Math;
 /**
  * @hide
  */
@@ -73,26 +74,37 @@ public class ToPackedGrayFilter extends Filter {
         return convertInputFormat(inputFormat);
     }
 
-    private void checkOutputDimensions() {
-        if (mOWidth % 4 != 0) {
-            throw new RuntimeException("Output width not divisible by four: " + mOWidth);
-        }
-        if (mOWidth <= 0 || mOHeight <= 0) {
-            throw new RuntimeException("Invalid output dimensions: " + mOWidth + " " + mOHeight);
+    private void checkOutputDimensions(int outputWidth, int outputHeight) {
+        if (outputWidth <= 0 || outputHeight <= 0) {
+            throw new RuntimeException("Invalid output dimensions: " +
+                                       outputWidth + " " + outputHeight);
         }
     }
 
     private FrameFormat convertInputFormat(FrameFormat inputFormat) {
+        int ow = mOWidth;
+        int oh = mOHeight;
+        int w = inputFormat.getWidth();
+        int h = inputFormat.getHeight();
         if (mOWidth == FrameFormat.SIZE_UNSPECIFIED) {
-            mOWidth = inputFormat.getWidth();
+            ow = w;
         }
         if (mOHeight == FrameFormat.SIZE_UNSPECIFIED) {
-            mOHeight = inputFormat.getHeight();
+            oh = h;
         }
         if (mKeepAspectRatio) {
-            mOHeight = mOWidth * inputFormat.getHeight() / inputFormat.getWidth();
+            // if keep aspect ratio, use the bigger dimension to determine the
+            // final output size
+            if (w > h) {
+                ow = Math.max(ow, oh);
+                oh = ow * h / w;
+            } else {
+                oh = Math.max(ow, oh);
+                ow = oh * w / h;
+            }
         }
-        return ImageFormat.create(mOWidth, mOHeight,
+        ow = (ow / 4) * 4; // ensure width is multiply of 4
+        return ImageFormat.create(ow, oh,
                                   ImageFormat.COLORSPACE_GRAY,
                                   FrameFormat.TARGET_NATIVE);
     }
@@ -107,12 +119,14 @@ public class ToPackedGrayFilter extends Filter {
         Frame input = pullInput("image");
         FrameFormat inputFormat = input.getFormat();
         FrameFormat outputFormat = convertInputFormat(inputFormat);
-        checkOutputDimensions();
-        mProgram.setHostValue("pix_stride", 1.0f / mOWidth);
+        int ow = outputFormat.getWidth();
+        int oh = outputFormat.getHeight();
+        checkOutputDimensions(ow, oh);
+        mProgram.setHostValue("pix_stride", 1.0f / ow);
 
         // Do the RGBA to luminance conversion.
         MutableFrameFormat tempFrameFormat = inputFormat.mutableCopy();
-        tempFrameFormat.setDimensions(mOWidth / 4, mOHeight);
+        tempFrameFormat.setDimensions(ow / 4, oh);
         Frame temp = context.getFrameManager().newFrame(tempFrameFormat);
         mProgram.process(input, temp);