1 2 #pragma version(1) 3 #pragma rs java_package_name(com.android.rs.livepreview) 4 //#pragma rs_fp_relaxed 5 6 static int gWidth; 7 static int gHeight; 8 static uchar crossProcess_tableR[256]; 9 static uchar crossProcess_tableG[256]; 10 static uchar crossProcess_tableB[256]; 11 static uchar vignette_table[512]; 12 13 14 static float4 crossProcess(float4 color) { 15 float4 ncolor = 0.f; 16 float v; 17 18 if (color.r < 0.5f) { 19 v = color.r; 20 ncolor.r = 4.0f * v * v * v; 21 } else { 22 v = 1.0f - color.r; 23 ncolor.r = 1.0f - (4.0f * v * v * v); 24 } 25 26 if (color.g < 0.5f) { 27 v = color.g; 28 ncolor.g = 2.0f * v * v; 29 } else { 30 v = 1.0f - color.g; 31 ncolor.g = 1.0f - (2.0f * v * v); 32 } 33 34 ncolor.b = color.b * 0.5f + 0.25f; 35 ncolor.a = color.a; 36 return ncolor; 37 } 38 39 static uchar4 crossProcess_i(uchar4 color) { 40 uchar4 ncolor = color; 41 ncolor.r = crossProcess_tableR[color.r]; 42 ncolor.g = crossProcess_tableG[color.g]; 43 ncolor.b = crossProcess_tableB[color.b]; 44 return ncolor; 45 } 46 47 48 float temp = 0.2f; 49 static float4 colortemp(float4 color) { 50 float4 new_color = color; 51 float4 t = color * ((float4)1.0f - color) * temp; 52 53 new_color.r = color.r + t.r; 54 new_color.b = color.b - t.b; 55 if (temp > 0.0f) { 56 color.g = color.g + t.g * 0.25f; 57 } 58 float max_value = max(new_color.r, max(new_color.g, new_color.b)); 59 if (max_value > 1.0f) { 60 new_color /= max_value; 61 } 62 63 return new_color; 64 } 65 66 67 static float vignette_dist_mod; 68 int2 vignette_half_dims; 69 static uchar4 vignette(uchar4 color, uint32_t x, uint32_t y) { 70 int2 xy = {x, y}; 71 xy -= vignette_half_dims; 72 xy *= xy; 73 74 float d = vignette_dist_mod * (xy.x + xy.y); 75 ushort4 c = convert_ushort4(color); 76 c *= vignette_table[(int)d]; 77 c >>= (ushort4)8; 78 return convert_uchar4(c); 79 } 80 81 void root(const uchar4 *in, uchar4 *out, uint32_t x, uint32_t y) { 82 uchar4 p; 83 p = crossProcess_i(*in); 84 p = vignette(p, x, y); 85 86 out->rgba = p; 87 out->a = 0xff; 88 } 89 90 float vignetteScale = 0.5f; 91 float vignetteShade = 0.85f; 92 93 static void precompute() { 94 for(int i=0; i <256; i++) { 95 float4 f = ((float)i) / 255.f; 96 float4 res = crossProcess(f); 97 res = colortemp(res); 98 crossProcess_tableR[i] = (uchar)(res.r * 255.f); 99 crossProcess_tableG[i] = (uchar)(res.g * 255.f); 100 crossProcess_tableB[i] = (uchar)(res.b * 255.f); 101 } 102 103 for(int i=0; i <512; i++) { 104 const float slope = 20.0f; 105 float f = ((float)i) / 511.f; 106 107 float range = 1.30f - sqrt(vignetteScale) * 0.7f; 108 float lumen = vignetteShade / (1.0f + exp((sqrt(f) - range) * slope)) + (1.0f - vignetteShade); 109 lumen = clamp(lumen, 0.f, 1.f); 110 111 vignette_table[i] = (uchar)(lumen * 255.f + 0.5f); 112 } 113 } 114 115 void init() { 116 precompute(); 117 } 118 119 void setSize(int w, int h) { 120 gWidth = w; 121 gHeight = h; 122 vignette_half_dims = (int2){w / 2, h / 2}; 123 vignette_dist_mod = 512.f; 124 vignette_dist_mod /= (float)(w*w + h*h) / 4.f; 125 126 } 127