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*/