1/* 2 This file is part of darktable, 3 copyright (c) 2011 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 21 22/* This is highpass for Lab space. We only do invert/blur/mix on L and desaturate a and b */ 23 24kernel void 25highpass_invert(read_only image2d_t in, write_only image2d_t out, const int width, const int height) 26{ 27 const int x = get_global_id(0); 28 const int y = get_global_id(1); 29 30 if(x >= width || y >= height) return; 31 32 float4 pixel = read_imagef(in, sampleri, (int2)(x, y)); 33 pixel.x = clamp(100.0f - pixel.x, 0.0f, 100.0f); 34 write_imagef (out, (int2)(x, y), pixel); 35} 36 37 38kernel void 39highpass_hblur(read_only image2d_t in, write_only image2d_t out, global float *m, const int rad, 40 const int width, const int height, const int blocksize, local float *buffer) 41{ 42 const int lid = get_local_id(0); 43 const int lsz = get_local_size(0); 44 const int x = get_global_id(0); 45 const int y = get_global_id(1); 46 float4 pixel = (float4)0.0f; 47 48 /* read pixel and fill center part of buffer */ 49 pixel = read_imagef(in, sampleri, (int2)(x, y)); 50 buffer[rad + lid] = pixel.x; 51 52 /* left wing of buffer */ 53 for(int n=0; n <= rad/lsz; n++) 54 { 55 const int l = mad24(n, lsz, lid + 1); 56 if(l > rad) continue; 57 const int xx = mad24((int)get_group_id(0), lsz, -l); 58 buffer[rad - l] = read_imagef(in, sampleri, (int2)(xx, y)).x; 59 } 60 61 /* right wing of buffer */ 62 for(int n=0; n <= rad/lsz; n++) 63 { 64 const int r = mad24(n, lsz, lsz - lid); 65 if(r > rad) continue; 66 const int xx = mad24((int)get_group_id(0), lsz, lsz - 1 + r); 67 buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(xx, y)).x; 68 } 69 70 barrier(CLK_LOCAL_MEM_FENCE); 71 72 if(x >= width || y >= height) return; 73 74 buffer += lid + rad; 75 m += rad; 76 77 float sum = 0.0f; 78 79 for (int i=-rad; i<=rad; i++) 80 { 81 sum += buffer[i] * m[i]; 82 } 83 84 pixel.x = sum; 85 write_imagef (out, (int2)(x, y), pixel); 86} 87 88 89 90kernel void 91highpass_vblur(read_only image2d_t in, write_only image2d_t out, global float *m, const int rad, 92 const int width, const int height, const int blocksize, local float *buffer) 93{ 94 const int lid = get_local_id(1); 95 const int lsz = get_local_size(1); 96 const int x = get_global_id(0); 97 const int y = get_global_id(1); 98 float4 pixel = (float4)0.0f; 99 100 /* read pixel and fill center part of buffer */ 101 pixel = read_imagef(in, sampleri, (int2)(x, y)); 102 buffer[rad + lid] = pixel.x; 103 104 /* left wing of buffer */ 105 for(int n=0; n <= rad/lsz; n++) 106 { 107 const int l = mad24(n, lsz, lid + 1); 108 if(l > rad) continue; 109 const int yy = mad24((int)get_group_id(1), lsz, -l); 110 buffer[rad - l] = read_imagef(in, sampleri, (int2)(x, yy)).x; 111 } 112 113 /* right wing of buffer */ 114 for(int n=0; n <= rad/lsz; n++) 115 { 116 const int r = mad24(n, lsz, lsz - lid); 117 if(r > rad) continue; 118 const int yy = mad24((int)get_group_id(1), lsz, lsz - 1 + r); 119 buffer[rad + lsz - 1 + r] = read_imagef(in, sampleri, (int2)(x, yy)).x; 120 } 121 122 barrier(CLK_LOCAL_MEM_FENCE); 123 124 if(x >= width || y >= height) return; 125 126 buffer += lid + rad; 127 m += rad; 128 129 float sum = 0.0f; 130 131 for (int i=-rad; i<=rad; i++) 132 { 133 sum += buffer[i] * m[i]; 134 } 135 136 pixel.x = sum; 137 write_imagef (out, (int2)(x, y), pixel); 138} 139 140 141 142kernel void 143highpass_mix(read_only image2d_t in_a, read_only image2d_t in_b, write_only image2d_t out, 144 const int width, const int height, const float contrast_scale) 145{ 146 const int x = get_global_id(0); 147 const int y = get_global_id(1); 148 149 if(x >= width || y >= height) return; 150 151 float4 o = 0.0f; 152 float4 a = read_imagef(in_a, sampleri, (int2)(x, y)); 153 float4 b = read_imagef(in_b, sampleri, (int2)(x, y)); 154 float4 min = (float4)(0.0f, -128.0f, -128.0f, -INFINITY); 155 float4 max = (float4)(100.0f, 128.0f, 128.0f, INFINITY); 156 157 o.x = 50.0f+((0.5f * a.x + 0.5f * b.x) - 50.0f)*contrast_scale; 158 o.y = 0.0f; 159 o.z = 0.0f; 160 o.w = a.w; 161 162 write_imagef (out, (int2)(x, y), clamp(o, min, max)); 163} 164 165