content: /*
   * Copyright (C) 2012 CyberAgent
   *
   * 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 jp.co.cyberagent.android.gpuimage;
  
  /**
   * A more generalized 9x9 Gaussian blur filter
   * blurSize value ranging from 0.0 on up, with a default of 1.0
   */
  public class GPUImageGaussianBlurFilter extends GPUImageTwoPassTextureSamplingFilter {
      public static final String VERTEX_SHADER =
              "attribute vec4 position;\n" +
                      "attribute vec4 inputTextureCoordinate;\n" +
                      "\n" +
                      "const int GAUSSIAN_SAMPLES = 9;\n" +
                      "\n" +
                      "uniform float texelWidthOffset;\n" +
                      "uniform float texelHeightOffset;\n" +
                      "\n" +
                      "varying vec2 textureCoordinate;\n" +
                      "varying vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n" +
                      "\n" +
                      "void main()\n" +
                      "{\n" +
                      "	gl_Position = position;\n" +
                      "	textureCoordinate = inputTextureCoordinate.xy;\n" +
                      "	\n" +
                      "	// Calculate the positions for the blur\n" +
                      "	int multiplier = 0;\n" +
                      "	vec2 blurStep;\n" +
                      "   vec2 singleStepOffset = vec2(texelHeightOffset, texelWidthOffset);\n" +
                      "    \n" +
                      "	for (int i = 0; i < GAUSSIAN_SAMPLES; i++)\n" +
                      "   {\n" +
                      "		multiplier = (i - ((GAUSSIAN_SAMPLES - 1) / 2));\n" +
                      "       // Blur in x (horizontal)\n" +
                      "       blurStep = float(multiplier) * singleStepOffset;\n" +
                      "		blurCoordinates[i] = inputTextureCoordinate.xy + blurStep;\n" +
                      "	}\n" +
                      "}\n";
  
      public static final String FRAGMENT_SHADER =
              "uniform sampler2D inputImageTexture;\n" +
                      "\n" +
                      "const lowp int GAUSSIAN_SAMPLES = 9;\n" +
                      "\n" +
                      "varying highp vec2 textureCoordinate;\n" +
                      "varying highp vec2 blurCoordinates[GAUSSIAN_SAMPLES];\n" +
                      "\n" +
                      "void main()\n" +
                      "{\n" +
                      "	lowp vec3 sum = vec3(0.0);\n" +
                      "   lowp vec4 fragColor=texture2D(inputImageTexture,textureCoordinate);\n" +
                      "	\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[0]).rgb * 0.05;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[1]).rgb * 0.09;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[2]).rgb * 0.12;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[3]).rgb * 0.15;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[4]).rgb * 0.18;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[5]).rgb * 0.15;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[6]).rgb * 0.12;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[7]).rgb * 0.09;\n" +
                      "    sum += texture2D(inputImageTexture, blurCoordinates[8]).rgb * 0.05;\n" +
                      "\n" +
                      "	gl_FragColor = vec4(sum,fragColor.a);\n" +
                      "}";
  
      protected float mBlurSize = 1f;
  
      public GPUImageGaussianBlurFilter() {
          this(1f);
      }
  
      public GPUImageGaussianBlurFilter(float blurSize) {
          super(VERTEX_SHADER, FRAGMENT_SHADER, VERTEX_SHADER, FRAGMENT_SHADER);
          mBlurSize = blurSize;
      }
  
      @Override
      public float getVerticalTexelOffsetRatio() {
          return mBlurSize;
      }
  
      @Override
      public float getHorizontalTexelOffsetRatio() {
          return mBlurSize;
      }
  
      /**
       * A multiplier for the blur size, ranging from 0.0 on up, with a default of 1.0
       *
       * @param blurSize from 0.0 on up, default 1.0
       */
      public void setBlurSize(float blurSize) {
          mBlurSize = blurSize;
          runOnDraw(new Runnable() {
              @Override
              public void run() {
                  initTexelOffsets();
              }
          });
      }
  }
  