Home | History | Annotate | Download | only in imageproc
      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 
     17 package android.filterpacks.imageproc;
     18 
     19 import android.filterfw.core.Filter;
     20 import android.filterfw.core.FilterContext;
     21 import android.filterfw.core.Frame;
     22 import android.filterfw.core.FrameFormat;
     23 import android.filterfw.core.GenerateFieldPort;
     24 import android.filterfw.core.KeyValueMap;
     25 import android.filterfw.core.NativeProgram;
     26 import android.filterfw.core.NativeFrame;
     27 import android.filterfw.core.Program;
     28 import android.filterfw.core.ShaderProgram;
     29 import android.filterfw.format.ImageFormat;
     30 import android.filterpacks.imageproc.ImageCombineFilter;
     31 import android.graphics.Bitmap;
     32 
     33 import android.util.Log;
     34 
     35 /**
     36  * @hide
     37  */
     38 public class BitmapOverlayFilter extends Filter {
     39 
     40     @GenerateFieldPort(name = "bitmap")
     41     private Bitmap mBitmap;
     42 
     43     @GenerateFieldPort(name = "tile_size", hasDefault = true)
     44     private int mTileSize = 640;
     45 
     46     private Program mProgram;
     47     private Frame mFrame;
     48 
     49     private int mTarget = FrameFormat.TARGET_UNSPECIFIED;
     50 
     51     private final String mOverlayShader =
     52             "precision mediump float;\n" +
     53             "uniform sampler2D tex_sampler_0;\n" +
     54             "uniform sampler2D tex_sampler_1;\n" +
     55             "varying vec2 v_texcoord;\n" +
     56             "void main() {\n" +
     57             "  vec4 original = texture2D(tex_sampler_0, v_texcoord);\n" +
     58             "  vec4 mask = texture2D(tex_sampler_1, v_texcoord);\n" +
     59             "  gl_FragColor = vec4(original.rgb * (1.0 - mask.a) + mask.rgb, 1.0);\n" +
     60             "}\n";
     61 
     62     public BitmapOverlayFilter(String name) {
     63         super(name);
     64     }
     65 
     66     @Override
     67     public void setupPorts() {
     68         addMaskedInputPort("image", ImageFormat.create(ImageFormat.COLORSPACE_RGBA));
     69         addOutputBasedOnInput("image", "image");
     70     }
     71 
     72     @Override
     73     public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) {
     74         return inputFormat;
     75     }
     76 
     77     public void initProgram(FilterContext context, int target) {
     78         switch (target) {
     79             case FrameFormat.TARGET_GPU:
     80                 ShaderProgram shaderProgram = new ShaderProgram(context, mOverlayShader);
     81                 shaderProgram.setMaximumTileSize(mTileSize);
     82                 mProgram = shaderProgram;
     83                 break;
     84 
     85             default:
     86                 throw new RuntimeException("Filter FisheyeFilter does not support frames of " +
     87                     "target " + target + "!");
     88         }
     89         mTarget = target;
     90     }
     91 
     92     @Override
     93     public void tearDown(FilterContext context) {
     94         if (mFrame != null) {
     95             mFrame.release();
     96             mFrame = null;
     97         }
     98     }
     99 
    100     @Override
    101     public void process(FilterContext context) {
    102         // Get input frame
    103         Frame input = pullInput("image");
    104         FrameFormat inputFormat = input.getFormat();
    105 
    106         // Create output frame
    107         Frame output = context.getFrameManager().newFrame(inputFormat);
    108 
    109         // Create program if not created already
    110         if (mProgram == null || inputFormat.getTarget() != mTarget) {
    111             initProgram(context, inputFormat.getTarget());
    112         }
    113 
    114         if (mBitmap != null) {
    115             Frame frame = createBitmapFrame(context);
    116             // Process
    117             Frame[] inputs = {input, frame};
    118             mProgram.process(inputs, output);
    119 
    120             frame.release();
    121         } else {
    122             output.setDataFromFrame(input);
    123         }
    124 
    125         // Push output
    126         pushOutput("image", output);
    127 
    128         // Release pushed frame
    129         output.release();
    130     }
    131 
    132     private Frame createBitmapFrame(FilterContext context) {
    133         FrameFormat format = ImageFormat.create(mBitmap.getWidth(),
    134                                                 mBitmap.getHeight(),
    135                                                 ImageFormat.COLORSPACE_RGBA,
    136                                                 FrameFormat.TARGET_GPU);
    137 
    138         Frame frame = context.getFrameManager().newFrame(format);
    139         frame.setBitmap(mBitmap);
    140 
    141         mBitmap.recycle();
    142         mBitmap = null;
    143 
    144         return frame;
    145     }
    146 }
    147