1 /*
   2  * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 /*
  27  * This file was originally generated by JSLC
  28  * and then hand edited for performance.
  29  */
  30 
  31 package com.sun.scenario.effect.impl.sw.java;
  32 
  33 import com.sun.scenario.effect.FilterContext;
  34 import com.sun.scenario.effect.impl.Renderer;
  35 
  36 public class JSWLinearConvolveShadowPeer extends JSWLinearConvolvePeer {
  37     public JSWLinearConvolveShadowPeer(FilterContext fctx, Renderer r, String uniqueName) {
  38         super(fctx, r, uniqueName);
  39     }
  40 
  41     private float[] getShadowColor() {
  42         return getKernel().getShadowColorComponents(getPass());
  43     }
  44 
  45     @Override
  46     protected void filterVector(int dstPixels[], int dstw, int dsth, int dstscan,
  47                                 int srcPixels[], int srcw, int srch, int srcscan,
  48                                 float weights[], int count,
  49                                 float srcx0, float srcy0,
  50                                 float offsetx, float offsety,
  51                                 float deltax, float deltay,
  52                                 float dxcol, float dycol, float dxrow, float dyrow)
  53     {
  54         float shadowColor[] = getShadowColor();
  55 
  56         int dstrow = 0;
  57         // srcxy0 point at UL corner, shift them to center of 1st dest pixel:
  58         srcx0 += (dxrow + dxcol) * 0.5f;
  59         srcy0 += (dyrow + dycol) * 0.5f;
  60         for (int dy = 0; dy < dsth; dy++) {
  61             float srcx = srcx0;
  62             float srcy = srcy0;
  63             for (int dx = 0; dx < dstw; dx++) {
  64                 float sum = 0.0f;
  65                 float sampx = srcx + offsetx;
  66                 float sampy = srcy + offsety;
  67                 for (int i = 0; i < count; ++i) {
  68                     if (sampx >= 0 && sampy >= 0) {
  69                         int ix = (int) sampx;
  70                         int iy = (int) sampy;
  71                         if (ix < srcw && iy < srch) {
  72                             // TODO: Usine linear interpolation here... (RT-27388)
  73                             int argb = srcPixels[iy * srcscan + ix];
  74                             sum += (argb >>> 24) * weights[i];
  75                         }
  76                     }
  77                     sampx += deltax;
  78                     sampy += deltay;
  79                 }
  80                 sum = (sum < 0f) ? 0f : ((sum > 255f) ? 255f : sum);
  81                 dstPixels[dstrow + dx] = ((int) (shadowColor[0] * sum) << 16) |
  82                                          ((int) (shadowColor[1] * sum) <<  8) |
  83                                          ((int) (shadowColor[2] * sum)      ) |
  84                                          ((int) (shadowColor[3] * sum) << 24);
  85                 srcx += dxcol;
  86                 srcy += dycol;
  87             }
  88             srcx0 += dxrow;
  89             srcy0 += dyrow;
  90             dstrow += dstscan;
  91         }
  92     }
  93 
  94     /**
  95      * In the nomenclature of the argument list for this method, "row" refers
  96      * to the coordinate which increments once for each new stream of single
  97      * axis data that we are blurring in a single pass.  And "col" refers to
  98      * the other coordinate that increments along the row.
  99      * Rows are horizontal in the first pass and vertical in the second pass.
 100      * Cols are vice versa.
 101      */
 102     @Override
 103     protected void filterHV(int dstPixels[], int dstcols, int dstrows, int dcolinc, int drowinc,
 104                             int srcPixels[], int srccols, int srcrows, int scolinc, int srowinc,
 105                             float weights[])
 106     {
 107         float shadowColor[] = getShadowColor();
 108 
 109         // avals stores the alpha values from the surrounding K pixels
 110         // from x-r to x+r
 111         int kernelSize = weights.length / 2;
 112         float avals[] = new float[kernelSize];
 113         int dstrow = 0;
 114         int srcrow = 0;
 115         int shadowRGBs[] = new int[256];
 116         for (int i = 0; i < shadowRGBs.length; i++) {
 117             shadowRGBs[i] = ((int) (shadowColor[0] * i) << 16) |
 118                             ((int) (shadowColor[1] * i) <<  8) |
 119                             ((int) (shadowColor[2] * i)      ) |
 120                             ((int) (shadowColor[3] * i) << 24);
 121         }
 122         for (int r = 0; r < dstrows; r++) {
 123             int dstoff = dstrow;
 124             int srcoff = srcrow;
 125             // Must clear out the array at the start of every line
 126             // Might be able to rely on the fact that the previous line must
 127             // have run out of data towards the end of the scan line, though.
 128             for (int i = 0; i < avals.length; i++) {
 129                 avals[i] = 0f;
 130             }
 131             int koff = kernelSize;
 132             for (int c = 0; c < dstcols; c++) {
 133                 // Load the data for this x location into the array.
 134                 avals[kernelSize - koff] =
 135                     ((c < srccols) ? srcPixels[srcoff] : 0) >>> 24;
 136                 // Bump the koff to the next spot to align the coefficients.
 137                 if (--koff <= 0) {
 138                     koff += kernelSize;
 139                 }
 140                 float sum = -0.5f;
 141                 for (int i = 0; i < avals.length; i++) {
 142                     sum += avals[i] * weights[koff + i];
 143                 }
 144                 dstPixels[dstoff] =
 145                     ((sum < 0f) ? 0
 146                      : ((sum >= 254f) ? shadowRGBs[255]
 147                         : shadowRGBs[((int) sum) + 1]));
 148                 dstoff += dcolinc;
 149                 srcoff += scolinc;
 150             }
 151             dstrow += drowinc;
 152             srcrow += srowinc;
 153         }
 154     }
 155 }