1/*
2 * Copyright (C) 2013 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#include "shared.rsh"
18
19#pragma rs_fp_relaxed
20
21rs_allocation mInput;
22
23rs_allocation mInY;
24rs_allocation mInU;
25rs_allocation mInV;
26
27static uchar4 yuvToRGBA4(uchar y, uchar u, uchar v) {
28    short Y = ((short)y) - 16;
29    short U = ((short)u) - 128;
30    short V = ((short)v) - 128;
31
32    short4 p;
33    p.x = (Y * 298 + V * 409 + 128) >> 8;
34    p.y = (Y * 298 - U * 100 - V * 208 + 128) >> 8;
35    p.z = (Y * 298 + U * 516 + 128) >> 8;
36    p.w = 255;
37    if(p.x < 0) {
38        p.x = 0;
39    }
40    if(p.x > 255) {
41        p.x = 255;
42    }
43    if(p.y < 0) {
44        p.y = 0;
45    }
46    if(p.y > 255) {
47        p.y = 255;
48    }
49    if(p.z < 0) {
50        p.z = 0;
51    }
52    if(p.z > 255) {
53        p.z = 255;
54    }
55
56    return (uchar4){p.x, p.y, p.z, p.w};
57}
58
59static float4 yuvToRGBA_f4(uchar y, uchar u, uchar v) {
60    float4 yuv_U_values = {0.f, -0.392f * 0.003921569f, +2.02 * 0.003921569f, 0.f};
61    float4 yuv_V_values = {1.603f * 0.003921569f, -0.815f * 0.003921569f, 0.f, 0.f};
62
63    float4 color = (float)y * 0.003921569f;
64    float4 fU = ((float)u) - 128.f;
65    float4 fV = ((float)v) - 128.f;
66
67    color += fU * yuv_U_values;
68    color += fV * yuv_V_values;
69    color = clamp(color, 0.f, 1.f);
70    return color;
71}
72
73void makeRef(rs_allocation ay, rs_allocation au, rs_allocation av, rs_allocation aout) {
74    uint32_t w = rsAllocationGetDimX(ay);
75    uint32_t h = rsAllocationGetDimY(ay);
76
77    for (int y = 0; y < h; y++) {
78        //rsDebug("y", y);
79        for (int x = 0; x < w; x++) {
80
81            int py = rsGetElementAt_uchar(ay, x, y);
82            int pu = rsGetElementAt_uchar(au, x >> 1, y >> 1);
83            int pv = rsGetElementAt_uchar(av, x >> 1, y >> 1);
84
85            //rsDebug("py", py);
86            //rsDebug(" u", pu);
87            //rsDebug(" v", pv);
88
89            uchar4 rgb = yuvToRGBA4(py, pu, pv);
90            //rsDebug("  ", rgb);
91
92            rsSetElementAt_uchar4(aout, rgb, x, y);
93        }
94    }
95}
96
97void makeRef_f4(rs_allocation ay, rs_allocation au, rs_allocation av, rs_allocation aout) {
98    uint32_t w = rsAllocationGetDimX(ay);
99    uint32_t h = rsAllocationGetDimY(ay);
100
101    for (int y = 0; y < h; y++) {
102        //rsDebug("y", y);
103        for (int x = 0; x < w; x++) {
104
105            uchar py = rsGetElementAt_uchar(ay, x, y);
106            uchar pu = rsGetElementAt_uchar(au, x >> 1, y >> 1);
107            uchar pv = rsGetElementAt_uchar(av, x >> 1, y >> 1);
108
109            //rsDebug("py", py);
110            //rsDebug(" u", pu);
111            //rsDebug(" v", pv);
112
113            float4 rgb = yuvToRGBA_f4(py, pu, pv);
114            //rsDebug("  ", rgb);
115
116            rsSetElementAt_float4(aout, rgb, x, y);
117        }
118    }
119}
120
121uchar4 __attribute__((kernel)) cvt(uint32_t x, uint32_t y) {
122
123    uchar py = rsGetElementAtYuv_uchar_Y(mInput, x, y);
124    uchar pu = rsGetElementAtYuv_uchar_U(mInput, x, y);
125    uchar pv = rsGetElementAtYuv_uchar_V(mInput, x, y);
126
127    //rsDebug("py2", py);
128    //rsDebug(" u2", pu);
129    //rsDebug(" v2", pv);
130
131    return yuvToRGBA4(py, pu, pv);
132}
133
134float4 __attribute__((kernel)) cvt_f4(uint32_t x, uint32_t y) {
135
136    uchar py = rsGetElementAtYuv_uchar_Y(mInput, x, y);
137    uchar pu = rsGetElementAtYuv_uchar_U(mInput, x, y);
138    uchar pv = rsGetElementAtYuv_uchar_V(mInput, x, y);
139
140    //rsDebug("py2", py);
141    //rsDebug(" u2", pu);
142    //rsDebug(" v2", pv);
143
144    return rsYuvToRGBA_float4(py, pu, pv);
145}
146
147