1e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford/*
2e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * Copyright (C) 2012 Unknown
3e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *
4e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * Licensed under the Apache License, Version 2.0 (the "License");
5e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * you may not use this file except in compliance with the License.
6e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * You may obtain a copy of the License at
7e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *
8e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *      http://www.apache.org/licenses/LICENSE-2.0
9e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford *
10e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * Unless required by applicable law or agreed to in writing, software
11e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * distributed under the License is distributed on an "AS IS" BASIS,
12e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * See the License for the specific language governing permissions and
14e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford * limitations under the License.
15e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford */
16e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
17e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford#pragma version(1)
18e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford#pragma rs java_package_name(com.android.gallery3d.filtershow.filters)
19e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
20e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford#define MAX_POINTS 16
21e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
22e162b032fe387eabbd69d367dae6fe7003e850a1John Hoforduint32_t inputWidth;
23e162b032fe387eabbd69d367dae6fe7003e850a1John Hoforduint32_t inputHeight;
24e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordstatic const float Rf = 0.2999f;
25e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordstatic const float Gf = 0.587f;
26e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordstatic const float Bf = 0.114f;
27e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford//static const float size_scale = 0.01f;
28e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
29e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordtypedef struct {
30e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    rs_matrix3x3 colorMatrix;
31e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    float rgbOff;
32e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    float dx;
33e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    float dy;
34e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    float off;
35e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford} UPointData;
36e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint mNumberOfLines;
37e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford// input data
38e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordbool mask[MAX_POINTS];
39e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint xPos1[MAX_POINTS];
40e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint yPos1[MAX_POINTS];
41e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint xPos2[MAX_POINTS];
42e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint yPos2[MAX_POINTS];
43e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint size[MAX_POINTS];
44e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint brightness[MAX_POINTS];
45e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint contrast[MAX_POINTS];
46e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordint saturation[MAX_POINTS];
47e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
48e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford// generated data
49e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordstatic UPointData grads[MAX_POINTS];
50e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
51e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordvoid setupGradParams() {
52e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    int k = 0;
53e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    for (int i = 0; i < MAX_POINTS; i++) {
54e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      if (!mask[i]) {
55e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford         continue;
56e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      }
57e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float x1 = xPos1[i];
58e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float y1 = yPos1[i];
59e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float x2 = xPos2[i];
60e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float y2 = yPos2[i];
61e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
62e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float denom = (y2 * y2 - 2 * y1 * y2 + x2 * x2 - 2 * x1 * x2 + y1 * y1 + x1 * x1);
63e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      if (denom == 0) {
64e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford         continue;
65e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      }
66e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      grads[k].dy = (y1 - y2) / denom;
67e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      grads[k].dx = (x1 - x2) / denom;
68e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      grads[k].off = (y2 * y2 + x2 * x2 - x1 * x2 - y1 * y2) / denom;
69e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
70e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float S = 1+saturation[i]/100.f;
71e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float MS = 1-S;
72e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float Rt = Rf * MS;
73e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float Gt = Gf * MS;
74e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float Bt = Bf * MS;
75e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
76e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float b = 1+brightness[i]/100.f;
77e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      float c = 1+contrast[i]/100.f;
78e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      b *= c;
79e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      grads[k].rgbOff = .5f - c/2.f;
80e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 0, 0, b * (Rt + S));
81e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 1, 0, b * Gt);
82e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 2, 0, b * Bt);
83e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 0, 1, b * Rt);
84e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 1, 1, b * (Gt + S));
85e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 2, 1, b * Bt);
86e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 0, 2, b * Rt);
87e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 1, 2, b * Gt);
88e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      rsMatrixSet(&grads[i].colorMatrix, 2, 2, b * (Bt + S));
89e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
90e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford      k++;
91e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
92e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    mNumberOfLines = k;
93e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford}
94e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
95e162b032fe387eabbd69d367dae6fe7003e850a1John Hofordvoid init() {
96e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
97e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford}
98e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
99e162b032fe387eabbd69d367dae6fe7003e850a1John Hoforduchar4 __attribute__((kernel)) selectiveAdjust(const uchar4 in, uint32_t x,
100e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    uint32_t y) {
101e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    float4 pixel = rsUnpackColor8888(in);
102e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
103e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    float4 wsum = pixel;
104e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    wsum.a = 0.f;
105e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    for (int i = 0; i < mNumberOfLines; i++) {
106e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        UPointData* grad = &grads[i];
107e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        float t = clamp(x*grad->dx+y*grad->dy+grad->off,0.f,1.0f);
108e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford        wsum.xyz = wsum.xyz*(1-t)+
109e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford            t*(rsMatrixMultiply(&grad->colorMatrix ,wsum.xyz)+grad->rgbOff);
110e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
111e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    }
112e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
113e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    pixel.rgb = wsum.rgb;
114e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    pixel.a = 1.0f;
115e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
116e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    uchar4 out = rsPackColorTo8888(clamp(pixel, 0.f, 1.0f));
117e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford    return out;
118e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford}
119e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
120e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
121e162b032fe387eabbd69d367dae6fe7003e850a1John Hoford
122