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 18package android.filterpacks.imageproc; 19 20import android.filterfw.core.Filter; 21import android.filterfw.core.FilterContext; 22import android.filterfw.core.Frame; 23import android.filterfw.core.FrameFormat; 24import android.filterfw.core.GenerateFieldPort; 25import android.filterfw.core.GLFrame; 26import android.filterfw.core.KeyValueMap; 27import android.filterfw.core.MutableFrameFormat; 28import android.filterfw.core.NativeProgram; 29import android.filterfw.core.NativeFrame; 30import android.filterfw.core.Program; 31import android.filterfw.core.ShaderProgram; 32import android.filterfw.format.ImageFormat; 33 34import android.opengl.GLES20; 35 36/** 37 * @hide 38 */ 39public class ResizeFilter extends Filter { 40 41 @GenerateFieldPort(name = "owidth") 42 private int mOWidth; 43 @GenerateFieldPort(name = "oheight") 44 private int mOHeight; 45 @GenerateFieldPort(name = "keepAspectRatio", hasDefault = true) 46 private boolean mKeepAspectRatio = false; 47 @GenerateFieldPort(name = "generateMipMap", hasDefault = true) 48 private boolean mGenerateMipMap = false; 49 50 private Program mProgram; 51 private FrameFormat mLastFormat = null; 52 53 private MutableFrameFormat mOutputFormat; 54 private int mInputChannels; 55 56 public ResizeFilter(String name) { 57 super(name); 58 } 59 60 @Override 61 public void setupPorts() { 62 addMaskedInputPort("image", ImageFormat.create(ImageFormat.COLORSPACE_RGBA)); 63 addOutputBasedOnInput("image", "image"); 64 } 65 66 @Override 67 public FrameFormat getOutputFormat(String portName, FrameFormat inputFormat) { 68 return inputFormat; 69 } 70 71 protected void createProgram(FilterContext context, FrameFormat format) { 72 if (mLastFormat != null && mLastFormat.getTarget() == format.getTarget()) return; 73 mLastFormat = format; 74 switch (format.getTarget()) { 75 case FrameFormat.TARGET_NATIVE: 76 throw new RuntimeException("Native ResizeFilter not implemented yet!"); 77 78 79 case FrameFormat.TARGET_GPU: 80 ShaderProgram prog = ShaderProgram.createIdentity(context); 81 mProgram = prog; 82 break; 83 84 default: 85 throw new RuntimeException("ResizeFilter could not create suitable program!"); 86 } 87 } 88 @Override 89 public void process(FilterContext env) { 90 // Get input frame 91 Frame input = pullInput("image"); 92 createProgram(env, input.getFormat()); 93 94 // Create output frame 95 MutableFrameFormat outputFormat = input.getFormat().mutableCopy(); 96 if (mKeepAspectRatio) { 97 FrameFormat inputFormat = input.getFormat(); 98 mOHeight = mOWidth * inputFormat.getHeight() / inputFormat.getWidth(); 99 } 100 outputFormat.setDimensions(mOWidth, mOHeight); 101 Frame output = env.getFrameManager().newFrame(outputFormat); 102 103 // Process 104 if (mGenerateMipMap) { 105 GLFrame mipmapped = (GLFrame)env.getFrameManager().newFrame(input.getFormat()); 106 mipmapped.setTextureParameter(GLES20.GL_TEXTURE_MIN_FILTER, 107 GLES20.GL_LINEAR_MIPMAP_NEAREST); 108 mipmapped.setDataFromFrame(input); 109 mipmapped.generateMipMap(); 110 mProgram.process(mipmapped, output); 111 mipmapped.release(); 112 } else { 113 mProgram.process(input, output); 114 } 115 116 // Push output 117 pushOutput("image", output); 118 119 // Release pushed frame 120 output.release(); 121 } 122 123 124} 125