tavli
diff src/image.cc @ 23:3e6430028d54
slot highlghting
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Wed, 08 Jul 2015 02:31:36 +0300 |
parents | c2a2069a49ec |
children |
line diff
1.1 --- a/src/image.cc Tue Jul 07 21:56:37 2015 +0300 1.2 +++ b/src/image.cc Wed Jul 08 02:31:36 2015 +0300 1.3 @@ -1,4 +1,5 @@ 1.4 #include <string.h> 1.5 +#include <alloca.h> 1.6 #include "opengl.h" 1.7 #include "image.h" 1.8 #include "imago2.h" 1.9 @@ -233,6 +234,119 @@ 1.10 return true; 1.11 } 1.12 1.13 +void convolve_horiz_image(Image *dest, float *kern, int ksz, float scale) 1.14 +{ 1.15 + if((ksz & 1) == 0) { 1.16 + fprintf(stderr, "%s: kernel size (%d) must be odd, skipping last value\n", __FUNCTION__, ksz); 1.17 + --ksz; 1.18 + } 1.19 + if(scale == 0.0) { 1.20 + // calculate scale factor 1.21 + float sum = 0.0; 1.22 + for(int i=0; i<ksz; i++) { 1.23 + sum += kern[i]; 1.24 + } 1.25 + scale = 1.0 / sum; 1.26 + } 1.27 + int krad = ksz / 2; 1.28 + float *buf = (float*)alloca(dest->width * 4 * sizeof *buf); 1.29 + unsigned char *sptr = dest->pixels; 1.30 + 1.31 + for(int i=0; i<dest->height; i++) { 1.32 + float *bptr = buf; 1.33 + for(int j=0; j<dest->width * 4; j++) { 1.34 + *bptr++ = (float)(sptr[j] / 255.0); 1.35 + } 1.36 + 1.37 + for(int j=0; j<dest->width; j++) { 1.38 + float col[] = {0, 0, 0, 0}; 1.39 + 1.40 + for(int k=0; k<ksz; k++) { 1.41 + int idx = j + k - krad; 1.42 + if(idx < 0) idx = 0; 1.43 + if(idx >= dest->width) idx = dest->width - 1; 1.44 + 1.45 + col[0] += buf[idx * 4] * kern[k]; 1.46 + col[1] += buf[idx * 4 + 1] * kern[k]; 1.47 + col[2] += buf[idx * 4 + 2] * kern[k]; 1.48 + col[3] += buf[idx * 4 + 3] * kern[k]; 1.49 + } 1.50 + 1.51 + int ri = (int)(col[0] * scale * 255.0); 1.52 + int gi = (int)(col[1] * scale * 255.0); 1.53 + int bi = (int)(col[2] * scale * 255.0); 1.54 + int ai = (int)(col[3] * scale * 255.0); 1.55 + 1.56 + sptr[0] = ri < 0 ? 0 : (ri > 255 ? 255 : ri); 1.57 + sptr[1] = gi < 0 ? 0 : (gi > 255 ? 255 : gi); 1.58 + sptr[2] = bi < 0 ? 0 : (bi > 255 ? 255 : bi); 1.59 + sptr[3] = ai < 0 ? 0 : (ai > 255 ? 255 : ai); 1.60 + sptr += 4; 1.61 + } 1.62 + } 1.63 + 1.64 + dest->invalidate_texture(); 1.65 +} 1.66 + 1.67 +void convolve_vert_image(Image *dest, float *kern, int ksz, float scale) 1.68 +{ 1.69 + if((ksz & 1) == 0) { 1.70 + fprintf(stderr, "%s: kernel size (%d) must be odd, skipping last value\n", __FUNCTION__, ksz); 1.71 + --ksz; 1.72 + } 1.73 + if(scale == 0.0) { 1.74 + // calculate scale factor 1.75 + float sum = 0.0; 1.76 + for(int i=0; i<ksz; i++) { 1.77 + sum += kern[i]; 1.78 + } 1.79 + scale = 1.0 / sum; 1.80 + } 1.81 + int krad = ksz / 2; 1.82 + float *buf = (float*)alloca(dest->height * 4 * sizeof *buf); 1.83 + unsigned char *sptr = dest->pixels; 1.84 + 1.85 + for(int i=0; i<dest->width; i++) { 1.86 + float *bptr = buf; 1.87 + sptr = dest->pixels + i * 4; 1.88 + 1.89 + for(int j=0; j<dest->height; j++) { 1.90 + for(int k=0; k<4; k++) { 1.91 + *bptr++ = (float)(sptr[k] / 255.0); 1.92 + } 1.93 + sptr += dest->width * 4; 1.94 + } 1.95 + 1.96 + sptr = dest->pixels + i * 4; 1.97 + 1.98 + for(int j=0; j<dest->height; j++) { 1.99 + float col[] = {0, 0, 0, 0}; 1.100 + 1.101 + for(int k=0; k<ksz; k++) { 1.102 + int idx = j + k - krad; 1.103 + if(idx < 0) idx = 0; 1.104 + if(idx >= dest->height) idx = dest->height - 1; 1.105 + 1.106 + col[0] += buf[idx * 4] * kern[k]; 1.107 + col[1] += buf[idx * 4 + 1] * kern[k]; 1.108 + col[2] += buf[idx * 4 + 2] * kern[k]; 1.109 + col[3] += buf[idx * 4 + 3] * kern[k]; 1.110 + } 1.111 + 1.112 + int ri = (int)(col[0] * scale * 255.0); 1.113 + int gi = (int)(col[1] * scale * 255.0); 1.114 + int bi = (int)(col[2] * scale * 255.0); 1.115 + int ai = (int)(col[3] * scale * 255.0); 1.116 + 1.117 + sptr[0] = ri < 0 ? 0 : (ri > 255 ? 255 : ri); 1.118 + sptr[1] = gi < 0 ? 0 : (gi > 255 ? 255 : gi); 1.119 + sptr[2] = bi < 0 ? 0 : (bi > 255 ? 255 : bi); 1.120 + sptr[3] = ai < 0 ? 0 : (ai > 255 ? 255 : ai); 1.121 + sptr += dest->width * 4; 1.122 + } 1.123 + } 1.124 +} 1.125 + 1.126 static unsigned int next_pow2(unsigned int x) 1.127 { 1.128 x--;