/*
* Copyright (c) 2009, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
/*
* This file was originally generated by JSLC
* and then hand edited for performance.
*/
package com.sun.scenario.effect.impl.sw.java;
import com.sun.scenario.effect.FilterContext;
import com.sun.scenario.effect.impl.Renderer;
public class JSWLinearConvolveShadowPeer extends JSWLinearConvolvePeer {
public JSWLinearConvolveShadowPeer(FilterContext fctx, Renderer r, String uniqueName) {
super(fctx, r, uniqueName);
}
private float[] getShadowColor() {
return getRenderState().getPassShadowColorComponents();
}
@Override
protected void filterVector(int dstPixels[], int dstw, int dsth, int dstscan,
int srcPixels[], int srcw, int srch, int srcscan,
float weights[], int count,
float srcx0, float srcy0,
float offsetx, float offsety,
float deltax, float deltay,
float dxcol, float dycol, float dxrow, float dyrow)
{
float shadowColor[] = getShadowColor();
int dstrow = 0;
// srcxy0 point at UL corner, shift them to center of 1st dest pixel:
srcx0 += (dxrow + dxcol) * 0.5f;
srcy0 += (dyrow + dycol) * 0.5f;
for (int dy = 0; dy < dsth; dy++) {
float srcx = srcx0;
float srcy = srcy0;
for (int dx = 0; dx < dstw; dx++) {
float sum = 0.0f;
float sampx = srcx + offsetx;
float sampy = srcy + offsety;
for (int i = 0; i < count; ++i) {
if (sampx >= 0 && sampy >= 0) {
int ix = (int) sampx;
int iy = (int) sampy;
if (ix < srcw && iy < srch) {
// TODO: Usine linear interpolation here... (RT-27388)
int argb = srcPixels[iy * srcscan + ix];
sum += (argb >>> 24) * weights[i];
}
}
sampx += deltax;
sampy += deltay;
}
sum = (sum < 0f) ? 0f : ((sum > 255f) ? 255f : sum);
dstPixels[dstrow + dx] = ((int) (shadowColor[0] * sum) << 16) |
((int) (shadowColor[1] * sum) << 8) |
((int) (shadowColor[2] * sum) ) |
((int) (shadowColor[3] * sum) << 24);
srcx += dxcol;
srcy += dycol;
}
srcx0 += dxrow;
srcy0 += dyrow;
dstrow += dstscan;
}
}
/*
* In the nomenclature of the argument list for this method, "row" refers
* to the coordinate which increments once for each new stream of single
* axis data that we are blurring in a single pass. And "col" refers to
* the other coordinate that increments along the row.
* Rows are horizontal in the first pass and vertical in the second pass.
* Cols are vice versa.
*/
@Override
protected void filterHV(int dstPixels[], int dstcols, int dstrows, int dcolinc, int drowinc,
int srcPixels[], int srccols, int srcrows, int scolinc, int srowinc,
float weights[])
{
float shadowColor[] = getShadowColor();
// avals stores the alpha values from the surrounding K pixels
// from x-r to x+r
int kernelSize = weights.length / 2;
float avals[] = new float[kernelSize];
int dstrow = 0;
int srcrow = 0;
int shadowRGBs[] = new int[256];
for (int i = 0; i < shadowRGBs.length; i++) {
shadowRGBs[i] = ((int) (shadowColor[0] * i) << 16) |
((int) (shadowColor[1] * i) << 8) |
((int) (shadowColor[2] * i) ) |
((int) (shadowColor[3] * i) << 24);
}
for (int r = 0; r < dstrows; r++) {
int dstoff = dstrow;
int srcoff = srcrow;
// Must clear out the array at the start of every line
// Might be able to rely on the fact that the previous line must
// have run out of data towards the end of the scan line, though.
for (int i = 0; i < avals.length; i++) {
avals[i] = 0f;
}
int koff = kernelSize;
for (int c = 0; c < dstcols; c++) {
// Load the data for this x location into the array.
avals[kernelSize - koff] =
((c < srccols) ? srcPixels[srcoff] : 0) >>> 24;
// Bump the koff to the next spot to align the coefficients.
if (--koff <= 0) {
koff += kernelSize;
}
float sum = -0.5f;
for (int i = 0; i < avals.length; i++) {
sum += avals[i] * weights[koff + i];
}
dstPixels[dstoff] =
((sum < 0f) ? 0
: ((sum >= 254f) ? shadowRGBs[255]
: shadowRGBs[((int) sum) + 1]));
dstoff += dcolinc;
srcoff += scolinc;
}
dstrow += drowinc;
srcrow += srowinc;
}
}
}