1/* 2 This file is part of darktable, 3 copyright (c) 2012 ulrich pegelow. 4 5 darktable is free software: you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation, either version 3 of the License, or 8 (at your option) any later version. 9 10 darktable is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with darktable. If not, see <http://www.gnu.org/licenses/>. 17*/ 18 19#include "common.h" 20#include "colorspace.h" 21 22 23/* first step for soften module: generate overexposed image */ 24kernel void 25soften_overexposed(read_only image2d_t in, write_only image2d_t out, const int width, const int height, 26 const float saturation, const float brightness) 27{ 28 const int x = get_global_id(0); 29 const int y = get_global_id(1); 30 31 if(x >= width || y >= height) return; 32 33 float4 pixel = read_imagef(in, sampleri, (int2)(x, y)); 34 35 float4 hsl = RGB_2_HSL(pixel); 36 37 hsl.y = clamp(hsl.y * saturation, 0.0f, 1.0f); 38 hsl.z = clamp(hsl.z * brightness, 0.0f, 1.0f); 39 40 pixel = HSL_2_RGB(hsl); 41 42 write_imagef (out, (int2)(x, y), pixel); 43} 44 45/* horizontal gaussian blur */ 46kernel void 47soften_hblur(read_only image2d_t in, write_only image2d_t out, global const float *m, const int rad, 48 const int width, const int height, const int blocksize, local float4 *buffer) 49{ 50 const int lid = get_local_id(0); 51 const int lsz = get_local_size(0); 52 const int x = get_global_id(0); 53 const int y = get_global_id(1); 54 float4 pixel = (float4)0.0f; 55 56 /* read pixel and fill center part of buffer */ 57 pixel = read_imagef(in, sampleri, (int2)(x, y)); 58 buffer[rad + lid] = pixel; 59 60 /* left wing of buffer */ 61 for(int n=0; n <= rad/lsz; n++) 62 { 63 const int l = mad24(n, lsz, lid + 1); 64 if(l > rad) continue; 65 const int xx = mad24((int)get_group_id(0), lsz, -l); 66 buffer[rad - l] = read_imagef(in, sampleri, (int2)(xx, y)); 67 } 68 69 /* right wing of buffer */ 70 for(int n=0; n <= rad/lsz; n++) 71 { 72 const int r = mad24(n, lsz, lsz - lid); 73 if(r > rad) continue; 74 const int xx = mad24((int)get_group_id(0), lsz, lsz - 1 + r); 75 buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(xx, y)); 76 } 77 78 barrier(CLK_LOCAL_MEM_FENCE); 79 80 if(x >= width || y >= height) return; 81 82 buffer += lid + rad; 83 m += rad; 84 85 float4 sum = (float4)0.0f; 86 87 for (int i=-rad; i<=rad; i++) 88 { 89 sum += buffer[i] * m[i]; 90 } 91 92 pixel = sum; 93 write_imagef (out, (int2)(x, y), pixel); 94} 95 96 97/* vertical gaussian blur */ 98kernel void 99soften_vblur(read_only image2d_t in, write_only image2d_t out, global const float *m, const int rad, 100 const int width, const int height, const int blocksize, local float4 *buffer) 101{ 102 const int lid = get_local_id(1); 103 const int lsz = get_local_size(1); 104 const int x = get_global_id(0); 105 const int y = get_global_id(1); 106 float4 pixel = (float4)0.0f; 107 108 /* read pixel and fill center part of buffer */ 109 pixel = read_imagef(in, sampleri, (int2)(x, y)); 110 buffer[rad + lid] = pixel; 111 112 /* left wing of buffer */ 113 for(int n=0; n <= rad/lsz; n++) 114 { 115 const int l = mad24(n, lsz, lid + 1); 116 if(l > rad) continue; 117 const int yy = mad24((int)get_group_id(1), lsz, -l); 118 buffer[rad - l] = read_imagef(in, sampleri, (int2)(x, yy)); 119 } 120 121 /* right wing of buffer */ 122 for(int n=0; n <= rad/lsz; n++) 123 { 124 const int r = mad24(n, lsz, lsz - lid); 125 if(r > rad) continue; 126 const int yy = mad24((int)get_group_id(1), lsz, lsz - 1 + r); 127 buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(x, yy)); 128 } 129 130 barrier(CLK_LOCAL_MEM_FENCE); 131 132 if(x >= width || y >= height) return; 133 134 buffer += lid + rad; 135 m += rad; 136 137 float4 sum = (float4)0.0f; 138 139 for (int i=-rad; i<=rad; i++) 140 { 141 sum += buffer[i] * m[i]; 142 } 143 144 pixel = sum; 145 write_imagef (out, (int2)(x, y), pixel); 146} 147 148 149 150 151/* final step for soften module */ 152kernel void 153soften_mix(read_only image2d_t in_a, read_only image2d_t in_b, write_only image2d_t out, const int width, const int height, 154 const float amount) 155{ 156 const int x = get_global_id(0); 157 const int y = get_global_id(1); 158 159 if(x >= width || y >= height) return; 160 161 float4 original = read_imagef(in_a, sampleri, (int2)(x, y)); 162 float4 processed = read_imagef(in_b, sampleri, (int2)(x, y)); 163 164 float4 pixel = original * (1.0f - amount) + clamp(processed, (float4)0.0f, (float4)1.0f) * amount; 165 pixel.w = original.w; 166 167 write_imagef (out, (int2)(x, y), pixel); 168} 169 170 171