1 /*
2  * Copyright (C) 2014 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 #pragma version(1)
17 #pragma rs java_package_name(com.example.android.hdrviewfinder)
18 #pragma rs_fp_relaxed
19 
20 rs_allocation gCurrentFrame;
21 rs_allocation gPrevFrame;
22 
23 int gCutPointX = 0;
24 int gDoMerge = 0;
25 int gFrameCounter = 0;
26 
27 uchar4 __attribute__((kernel)) mergeHdrFrames(uchar4 prevPixel, uint32_t x, uint32_t y) {
28 
29     // Read in pixel values from latest frame - YUV color space
30 
31     uchar4 curPixel;
32     curPixel.r = rsGetElementAtYuv_uchar_Y(gCurrentFrame, x, y);
33     curPixel.g = rsGetElementAtYuv_uchar_U(gCurrentFrame, x, y);
34     curPixel.b = rsGetElementAtYuv_uchar_V(gCurrentFrame, x, y);
35     curPixel.a = 255;
36 
37     uchar4 mergedPixel;
38     if (gDoMerge == 1) {
39         // Complex HDR fusion technique
40         mergedPixel = curPixel / 2 + prevPixel / 2;
41 
42         /* Experimental color saturation boosting merge
43         mergedPixel.r = curPixel.r / 2 + prevPixel.r / 2;
44 
45         uchar saturationCurrent = abs(curPixel.g - 128) + abs(curPixel.b - 128);
46         uchar saturationPrev = abs(prevPixel.g - 128) + abs(prevPixel.b - 128);
47         mergedPixel.g = saturationCurrent > saturationPrev ? curPixel.g : prevPixel.g;
48         mergedPixel.b = saturationCurrent > saturationPrev ? curPixel.b : prevPixel.b;
49         */
50     } else if (gCutPointX > 0) {
51         // Composite side by side
52         mergedPixel = ((x < gCutPointX) ^ (gFrameCounter & 0x1)) ?
53                 curPixel : prevPixel;
54     } else {
55         // Straight passthrough
56         mergedPixel = curPixel;
57     }
58 
59     // Convert YUV to RGB, JFIF transform with fixed-point math
60     // R = Y + 1.402 * (V - 128)
61     // G = Y - 0.34414 * (U - 128) - 0.71414 * (V - 128)
62     // B = Y + 1.772 * (U - 128)
63 
64     int4 rgb;
65     rgb.r = mergedPixel.r +
66             mergedPixel.b * 1436 / 1024 - 179;
67     rgb.g = mergedPixel.r -
68             mergedPixel.g * 46549 / 131072 + 44 -
69             mergedPixel.b * 93604 / 131072 + 91;
70     rgb.b = mergedPixel.r +
71             mergedPixel.g * 1814 / 1024 - 227;
72     rgb.a = 255;
73 
74     // Store current pixel for next frame
75     rsSetElementAt_uchar4(gPrevFrame, curPixel, x, y);
76 
77     // Write out merged HDR result
78     uchar4 out = convert_uchar4(clamp(rgb, 0, 255));
79 
80     return out;
81 }
82