acid-drop- Hacking the planet from a LilyGo T-Deck using custom firmware |
git clone git://git.acid.vegas/acid-drop.git |
Log | Files | Refs | Archive | README | LICENSE |
lv_draw_sdl_stack_blur.c (8235B)
1 /** 2 * @file lv_draw_sdl_stack_blur.c 3 * 4 */ 5 6 /********************* 7 * INCLUDES 8 *********************/ 9 #include "lv_draw_sdl_stack_blur.h" 10 11 #if LV_USE_GPU_SDL 12 /********************* 13 * DEFINES 14 *********************/ 15 16 /********************** 17 * TYPEDEFS 18 **********************/ 19 20 /********************** 21 * STATIC PROTOTYPES 22 **********************/ 23 24 static void 25 stack_blur_job(lv_opa_t * src, unsigned int w, unsigned int h, unsigned int radius, int cores, int core, int step); 26 27 /********************** 28 * STATIC VARIABLES 29 **********************/ 30 31 // Based heavily on http://vitiy.info/Code/stackblur.cpp 32 // See http://vitiy.info/stackblur-algorithm-multi-threaded-blur-for-cpp/ 33 // Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com> 34 35 static unsigned short const stackblur_mul[255] = { 36 512, 512, 456, 512, 328, 456, 335, 512, 405, 328, 271, 456, 388, 335, 292, 512, 37 454, 405, 364, 328, 298, 271, 496, 456, 420, 388, 360, 335, 312, 292, 273, 512, 38 482, 454, 428, 405, 383, 364, 345, 328, 312, 298, 284, 271, 259, 496, 475, 456, 39 437, 420, 404, 388, 374, 360, 347, 335, 323, 312, 302, 292, 282, 273, 265, 512, 40 497, 482, 468, 454, 441, 428, 417, 405, 394, 383, 373, 364, 354, 345, 337, 328, 41 320, 312, 305, 298, 291, 284, 278, 271, 265, 259, 507, 496, 485, 475, 465, 456, 42 446, 437, 428, 420, 412, 404, 396, 388, 381, 374, 367, 360, 354, 347, 341, 335, 43 329, 323, 318, 312, 307, 302, 297, 292, 287, 282, 278, 273, 269, 265, 261, 512, 44 505, 497, 489, 482, 475, 468, 461, 454, 447, 441, 435, 428, 422, 417, 411, 405, 45 399, 394, 389, 383, 378, 373, 368, 364, 359, 354, 350, 345, 341, 337, 332, 328, 46 324, 320, 316, 312, 309, 305, 301, 298, 294, 291, 287, 284, 281, 278, 274, 271, 47 268, 265, 262, 259, 257, 507, 501, 496, 491, 485, 480, 475, 470, 465, 460, 456, 48 451, 446, 442, 437, 433, 428, 424, 420, 416, 412, 408, 404, 400, 396, 392, 388, 49 385, 381, 377, 374, 370, 367, 363, 360, 357, 354, 350, 347, 344, 341, 338, 335, 50 332, 329, 326, 323, 320, 318, 315, 312, 310, 307, 304, 302, 299, 297, 294, 292, 51 289, 287, 285, 282, 280, 278, 275, 273, 271, 269, 267, 265, 263, 261, 259 52 }; 53 54 static unsigned char const stackblur_shr[255] = { 55 9, 11, 12, 13, 13, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 17, 56 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 18, 19, 57 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 19, 20, 20, 20, 58 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 21, 59 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 60 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 61 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 62 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 63 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 64 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 65 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, 66 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 67 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 68 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 69 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 70 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24 71 }; 72 73 /********************** 74 * MACROS 75 **********************/ 76 77 /********************** 78 * GLOBAL FUNCTIONS 79 **********************/ 80 81 void lv_stack_blur_grayscale(lv_opa_t * buf, uint16_t w, uint16_t h, uint16_t r) 82 { 83 stack_blur_job(buf, w, h, r, 1, 0, 1); 84 stack_blur_job(buf, w, h, r, 1, 0, 2); 85 } 86 87 /********************** 88 * STATIC FUNCTIONS 89 **********************/ 90 91 static void stack_blur_job(lv_opa_t * src, unsigned int w, unsigned int h, unsigned int radius, int cores, int core, 92 int step) 93 { 94 if(radius < 2 || radius > 254) { 95 /* Silently ignore bad radius */ 96 return; 97 } 98 99 unsigned int x, y, xp, yp, i; 100 unsigned int sp; 101 unsigned int stack_start; 102 unsigned char * stack_ptr; 103 104 lv_opa_t * src_ptr; 105 lv_opa_t * dst_ptr; 106 107 unsigned long sum_r; 108 unsigned long sum_in_r; 109 unsigned long sum_out_r; 110 111 unsigned int wm = w - 1; 112 unsigned int hm = h - 1; 113 unsigned int stride = w; 114 unsigned int div = (radius * 2) + 1; 115 unsigned int mul_sum = stackblur_mul[radius]; 116 unsigned char shr_sum = stackblur_shr[radius]; 117 unsigned char stack[254 * 2 + 1]; 118 119 if(step == 1) { 120 unsigned int minY = core * h / cores; 121 unsigned int maxY = (core + 1) * h / cores; 122 123 for(y = minY; y < maxY; y++) { 124 sum_r = 125 sum_in_r = 126 sum_out_r = 0; 127 128 src_ptr = src + stride * y; // start of line (0,y) 129 130 for(i = 0; i <= radius; i++) { 131 stack_ptr = &stack[i]; 132 stack_ptr[0] = src_ptr[0]; 133 sum_r += src_ptr[0] * (i + 1); 134 sum_out_r += src_ptr[0]; 135 } 136 137 138 for(i = 1; i <= radius; i++) { 139 if(i <= wm) src_ptr += 1; 140 stack_ptr = &stack[i + radius]; 141 stack_ptr[0] = src_ptr[0]; 142 sum_r += src_ptr[0] * (radius + 1 - i); 143 sum_in_r += src_ptr[0]; 144 } 145 146 147 sp = radius; 148 xp = radius; 149 if(xp > wm) xp = wm; 150 src_ptr = src + (xp + y * w); // img.pix_ptr(xp, y); 151 dst_ptr = src + y * stride; // img.pix_ptr(0, y); 152 for(x = 0; x < w; x++) { 153 dst_ptr[0] = LV_CLAMP((sum_r * mul_sum) >> shr_sum, 0, 255); 154 dst_ptr += 1; 155 156 sum_r -= sum_out_r; 157 158 stack_start = sp + div - radius; 159 if(stack_start >= div) stack_start -= div; 160 stack_ptr = &stack[stack_start]; 161 162 sum_out_r -= stack_ptr[0]; 163 164 if(xp < wm) { 165 src_ptr += 1; 166 ++xp; 167 } 168 169 stack_ptr[0] = src_ptr[0]; 170 171 sum_in_r += src_ptr[0]; 172 sum_r += sum_in_r; 173 174 ++sp; 175 if(sp >= div) sp = 0; 176 stack_ptr = &stack[sp]; 177 178 sum_out_r += stack_ptr[0]; 179 sum_in_r -= stack_ptr[0]; 180 } 181 182 } 183 } 184 185 // step 2 186 if(step == 2) { 187 unsigned int minX = core * w / cores; 188 unsigned int maxX = (core + 1) * w / cores; 189 190 for(x = minX; x < maxX; x++) { 191 sum_r = 192 sum_in_r = 193 sum_out_r = 0; 194 195 src_ptr = src + x; // x,0 196 for(i = 0; i <= radius; i++) { 197 stack_ptr = &stack[i]; 198 stack_ptr[0] = src_ptr[0]; 199 sum_r += src_ptr[0] * (i + 1); 200 sum_out_r += src_ptr[0]; 201 } 202 for(i = 1; i <= radius; i++) { 203 if(i <= hm) src_ptr += stride; // +stride 204 205 stack_ptr = &stack[i + radius]; 206 stack_ptr[0] = src_ptr[0]; 207 sum_r += src_ptr[0] * (radius + 1 - i); 208 sum_in_r += src_ptr[0]; 209 } 210 211 sp = radius; 212 yp = radius; 213 if(yp > hm) yp = hm; 214 src_ptr = src + (x + yp * w); // img.pix_ptr(x, yp); 215 dst_ptr = src + x; // img.pix_ptr(x, 0); 216 for(y = 0; y < h; y++) { 217 dst_ptr[0] = LV_CLAMP((sum_r * mul_sum) >> shr_sum, 0, 255); 218 dst_ptr += stride; 219 220 sum_r -= sum_out_r; 221 222 stack_start = sp + div - radius; 223 if(stack_start >= div) stack_start -= div; 224 stack_ptr = &stack[stack_start]; 225 226 sum_out_r -= stack_ptr[0]; 227 228 if(yp < hm) { 229 src_ptr += stride; // stride 230 ++yp; 231 } 232 233 stack_ptr[0] = src_ptr[0]; 234 235 sum_in_r += src_ptr[0]; 236 sum_r += sum_in_r; 237 238 ++sp; 239 if(sp >= div) sp = 0; 240 stack_ptr = &stack[sp]; 241 242 sum_out_r += stack_ptr[0]; 243 sum_in_r -= stack_ptr[0]; 244 } 245 } 246 } 247 } 248 249 #endif /*LV_USE_GPU_SDL*/