1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package android.filterpacks.imageproc;
18
19import android.filterfw.core.Filter;
20import android.filterfw.core.FilterContext;
21import android.filterfw.core.Frame;
22import android.filterfw.core.FrameFormat;
23import android.filterfw.core.GenerateFieldPort;
24import android.filterfw.core.MutableFrameFormat;
25import android.filterfw.core.ShaderProgram;
26import android.filterfw.format.ImageFormat;
27import android.filterfw.geometry.Point;
28import android.filterfw.geometry.Quad;
29
30/**
31 * The FixedRotationFilter rotates the input image clockwise, it only accepts
32 * 4 rotation angles: 0, 90, 180, 270
33 * @hide
34 */
35public class FixedRotationFilter extends Filter {
36
37    @GenerateFieldPort(name = "rotation", hasDefault = true)
38    private int mRotation = 0;
39
40    private ShaderProgram mProgram = null;
41
42    public FixedRotationFilter(String name) {
43        super(name);
44    }
45
46    @Override
47    public void setupPorts() {
48        addMaskedInputPort("image", ImageFormat.create(ImageFormat.COLORSPACE_RGBA,
49                                                       FrameFormat.TARGET_GPU));
50        addOutputBasedOnInput("image", "image");
51    }
52
53    @Override
54    public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) {
55        return inputFormat;
56    }
57
58    @Override
59    public void process(FilterContext context) {
60        Frame input = pullInput("image");
61        if (mRotation == 0) {
62            pushOutput("image", input);
63            return;
64        }
65        FrameFormat inputFormat = input.getFormat();
66
67        // Create program if not created already
68        if (mProgram == null) {
69            mProgram = ShaderProgram.createIdentity(context);
70        }
71        MutableFrameFormat outputFormat = inputFormat.mutableCopy();
72        int width = inputFormat.getWidth();
73        int height = inputFormat.getHeight();
74        Point p1 = new Point(0.0f, 0.0f);
75        Point p2 = new Point(1.0f, 0.0f);
76        Point p3 = new Point(0.0f, 1.0f);
77        Point p4 = new Point(1.0f, 1.0f);
78        Quad sourceRegion;
79        switch (((int)Math.round(mRotation / 90f)) % 4) {
80            case 1:
81                sourceRegion = new Quad(p3,p1,p4,p2);
82                outputFormat.setDimensions(height, width);
83                break;
84            case 2:
85                sourceRegion = new Quad(p4,p3,p2,p1);
86                break;
87            case 3:
88                sourceRegion = new Quad(p2,p4,p1,p3);
89                outputFormat.setDimensions(height, width);
90                break;
91            case 0:
92            default:
93                sourceRegion = new Quad(p1,p2,p3,p4);
94                break;
95        }
96        // Create output frame
97        Frame output = context.getFrameManager().newFrame(outputFormat);
98
99        // Set the source region
100        mProgram.setSourceRegion(sourceRegion);
101
102        // Process
103        mProgram.process(input, output);
104
105        // Push output
106        pushOutput("image", output);
107
108        // Release pushed frame
109        output.release();
110    }
111}
112