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 package com.sun.scenario.effect.impl.sw.java;
  27 
  28 import com.sun.scenario.effect.FilterContext;
  29 import com.sun.scenario.effect.impl.EffectPeer;
  30 import com.sun.scenario.effect.impl.Renderer;
  31 import com.sun.scenario.effect.impl.state.RenderState;
  32 
  33 public abstract class JSWEffectPeer<T extends RenderState> extends EffectPeer<T> {
  34 
  35     protected JSWEffectPeer(FilterContext fctx, Renderer r, String uniqueName) {
  36         super(fctx, r, uniqueName);
  37     }
  38 
  39     protected final static int FVALS_A = 3;
  40     protected final static int FVALS_R = 0;
  41     protected final static int FVALS_G = 1;
  42     protected final static int FVALS_B = 2;
  43 
  44     protected final void laccum(int pixel, float mul, float fvals[]) {
  45         mul /= 255f;
  46         fvals[FVALS_R] += ((pixel >>  16) & 0xff) * mul;
  47         fvals[FVALS_G] += ((pixel >>   8) & 0xff) * mul;
  48         fvals[FVALS_B] += ((pixel       ) & 0xff) * mul;
  49         fvals[FVALS_A] += ((pixel >>> 24)       ) * mul;
  50     }
  51 
  52     protected final void lsample(int img[],
  53                                  float floc_x, float floc_y,
  54                                  int w, int h, int scan,
  55                                  float fvals[])
  56     {
  57         fvals[0] = 0f;
  58         fvals[1] = 0f;
  59         fvals[2] = 0f;
  60         fvals[3] = 0f;
  61         // If we subtract 0.5 then floc_xy could go negative and the
  62         // integer cast will not perform a true floor operation so
  63         // instead we add 0.5 and then iloc_xy will be off by 1
  64         floc_x = floc_x * w + 0.5f;
  65         floc_y = floc_y * h + 0.5f;
  66         int iloc_x = (int) floc_x;  // 0 <= iloc_x <= w
  67         int iloc_y = (int) floc_y;  // 0 <= iloc_y <= h
  68         // Note we test floc against 0 because iloc may have rounded the wrong way
  69         // for some numbers.  But, iloc values are valid for testing against w,h
  70         if (floc_x > 0 && floc_y > 0 && iloc_x <= w && iloc_y <= h) {
  71             floc_x -= iloc_x;   // now fractx
  72             floc_y -= iloc_y;   // now fracty
  73             // sample box from iloc_x-1,y-1 to iloc_x,y
  74             int offset = iloc_y * scan + iloc_x;
  75             float fract = floc_x * floc_y;
  76             if (iloc_y < h) {
  77                 if (iloc_x < w) {
  78                     laccum(img[offset], fract, fvals);
  79                 }
  80                 if (iloc_x > 0) {
  81                     laccum(img[offset-1], floc_y - fract, fvals);
  82                 }
  83             }
  84             if (iloc_y > 0) {
  85                 if (iloc_x < w) {
  86                     laccum(img[offset-scan], floc_x - fract, fvals);
  87                 }
  88                 if (iloc_x > 0) {
  89                     laccum(img[offset-scan-1], 1f - floc_x - floc_y + fract, fvals);
  90                 }
  91             }
  92         }
  93     }
  94 
  95     protected final void laccumsample(int img[],
  96                                       float fpix_x, float fpix_y,
  97                                       int w, int h, int scan,
  98                                       float factor, float fvals[])
  99     {
 100         factor *= 255f;
 101         // If we subtract 0.5 then floc_xy could go negative and the
 102         // integer cast will not perform a true floor operation so
 103         // instead we add 0.5 and then iloc_xy will be off by 1
 104         fpix_x = fpix_x + 0.5f;
 105         fpix_y = fpix_y + 0.5f;
 106         int ipix_x = (int) fpix_x;  // 0 <= ipix_x <= w
 107         int ipix_y = (int) fpix_y;  // 0 <= ipix_y <= h
 108         // Note we test fpix against 0 because ipix may have rounded the wrong way
 109         // for some numbers.  But, ipix values are valid for testing against w,h
 110         if (fpix_x > 0 && fpix_y > 0 && ipix_x <= w && ipix_y <= h) {
 111             fpix_x -= ipix_x;   // now fractx
 112             fpix_y -= ipix_y;   // now fracty
 113             // sample box from ipix_x-1,y-1 to ipix_x,y
 114             int offset = ipix_y * scan + ipix_x;
 115             float fract = fpix_x * fpix_y;
 116             if (ipix_y < h) {
 117                 if (ipix_x < w) {
 118                     laccum(img[offset], fract * factor, fvals);
 119                 }
 120                 if (ipix_x > 0) {
 121                     laccum(img[offset-1], (fpix_y - fract) * factor, fvals);
 122                 }
 123             }
 124             if (ipix_y > 0) {
 125                 if (ipix_x < w) {
 126                     laccum(img[offset-scan], (fpix_x - fract) * factor, fvals);
 127                 }
 128                 if (ipix_x > 0) {
 129                     laccum(img[offset-scan-1], (1f - fpix_x - fpix_y + fract) * factor, fvals);
 130                 }
 131             }
 132         }
 133     }
 134 
 135     protected final void faccum(float map[], int offset, float mul,
 136                                 float fvals[])
 137     {
 138         fvals[0] += map[offset  ] * mul;
 139         fvals[1] += map[offset+1] * mul;
 140         fvals[2] += map[offset+2] * mul;
 141         fvals[3] += map[offset+3] * mul;
 142     }
 143 
 144     protected final void fsample(float map[],
 145                                  float floc_x, float floc_y,
 146                                  int w, int h, int scan,
 147                                  float fvals[])
 148     {
 149         fvals[0] = 0f;
 150         fvals[1] = 0f;
 151         fvals[2] = 0f;
 152         fvals[3] = 0f;
 153         // If we subtract 0.5 then floc_xy could go negative and the
 154         // integer cast will not perform a true floor operation so
 155         // instead we add 0.5 and then iloc_xy will be off by 1
 156         floc_x = floc_x * w + 0.5f;
 157         floc_y = floc_y * h + 0.5f;
 158         int iloc_x = (int) floc_x;  // 0 <= iloc_x <= w
 159         int iloc_y = (int) floc_y;  // 0 <= iloc_y <= h
 160         // Note we test floc against 0 because iloc may have rounded the wrong way
 161         // for some numbers.  But, iloc values are valid for testing against w,h
 162         if (floc_x > 0 && floc_y > 0 && iloc_x <= w && iloc_y <= h) {
 163             floc_x -= iloc_x;   // now fractx
 164             floc_y -= iloc_y;   // now fracty
 165             // sample box from iloc_x-1,y-1 to iloc_x,y
 166             int offset = 4*(iloc_y * scan + iloc_x);
 167             float fract = floc_x * floc_y;
 168             if (iloc_y < h) {
 169                 if (iloc_x < w) {
 170                     faccum(map, offset, fract, fvals);
 171                 }
 172                 if (iloc_x > 0) {
 173                     faccum(map, offset-4, floc_y - fract, fvals);
 174                 }
 175             }
 176             if (iloc_y > 0) {
 177                 if (iloc_x < w) {
 178                     faccum(map, offset-scan*4, floc_x - fract, fvals);
 179                 }
 180                 if (iloc_x > 0) {
 181                     faccum(map, offset-scan*4-4, 1f - floc_x - floc_y + fract, fvals);
 182                 }
 183             }
 184         }
 185     }
 186 }