From fb928482b4ac820d665bd100d1b767bc8660bc06 Mon Sep 17 00:00:00 2001 From: iabdalkader Date: Sun, 16 Mar 2014 22:24:47 +0200 Subject: [PATCH] Add grayscale median --- src/img/median.c | 150 +++++++++++++++++++++++++++++++++++------------ 1 file changed, 114 insertions(+), 36 deletions(-) diff --git a/src/img/median.c b/src/img/median.c index 097f21dd2..b8bc95d6e 100644 --- a/src/img/median.c +++ b/src/img/median.c @@ -22,46 +22,61 @@ typedef struct { int n; - int r[32]; - int g[64]; - int b[32]; -} color_histo_t; + union { + int h[2]; + struct { + int r[32]; + int g[64]; + int b[32]; + }; + }; +} histo_t; -void del_pixels(image_t * im, int row, int col, int size, color_histo_t *h) +void del_pixels(image_t * im, int row, int col, int size, histo_t *h) { - int i; - uint16_t c; - - if (col < 0 || col >= im->w) return; - for (i = row - size; i <= row + size && i < im->h; i++) { - if (i < 0) continue; - c = SWAP(((uint16_t*)im->pixels)[i*im->w+col]); - h->r[R(c)]--; - h->g[G(c)]--; - h->b[B(c)]--; - h->n--; + if (im->bpp==1) { + for (int i = row - size; i <= row + size && i < im->h; i++) { + if (i < 0) continue; + h->h[im->pixels[i*im->w+col]]--; + h->n--; + } + } else { + for (int i = row - size; i <= row + size && i < im->h; i++) { + if (i < 0) continue; + uint16_t c = SWAP(((uint16_t*)im->pixels)[i*im->w+col]); + h->r[R(c)]--; + h->g[G(c)]--; + h->b[B(c)]--; + h->n--; + } } } -void add_pixels(image_t * im, int row, int col, int size, color_histo_t *h) +void add_pixels(image_t * im, int row, int col, int size, histo_t *h) { - int i; - uint16_t c; - - if (col < 0 || col >= im->w) return; - for (i = row - size; i <= row + size && i < im->h; i++) { - if (i < 0) continue; - c = SWAP(((uint16_t*)im->pixels)[i*im->w+col]); - h->r[R(c)]++; - h->g[G(c)]++; - h->b[B(c)]++; - h->n++; + if (im->bpp==1) { + for (int i = row - size; i <= row + size && i < im->h; i++) { + if (i < 0) continue; + h->h[im->pixels[i*im->w+col]]++; + h->n++; + } + } else { + for (int i = row - size; i <= row + size && i < im->h; i++) { + if (i < 0) continue; + uint16_t c = SWAP(((uint16_t*)im->pixels)[i*im->w+col]); + h->r[R(c)]++; + h->g[G(c)]++; + h->b[B(c)]++; + h->n++; + } } } -void init_histo(image_t *im, int row, int size, color_histo_t *h) +void init_histo(image_t *im, int row, int size, histo_t *h) { - memset(h, 0, sizeof(color_histo_t)); + //memset(h, 0, sizeof(histo_t)); + h->n = 0; + h->h[0] = h->h[1]=0; for (int j = 0; j < size && j < im->w; j++) { add_pixels(im, row, j, size, h); } @@ -74,13 +89,15 @@ uint16_t median(const int *x, int n) return i; } -void imlib_median_filter(image_t *in, int size) + +void median_filter_rgb(image_t *in, int size) { uint16_t r,g,b; - color_histo_t *h = xalloc(sizeof(*h)); - uint16_t *data = (uint16_t*) (in->data+(in->w * in->h*2)); + int k_rows = size+1; + histo_t *h = xalloc(sizeof(*h)); + uint16_t *data = xalloc(in->w * k_rows * sizeof(*data)); - for (int row = 0; rowh; row ++) { + for (int row = 0; rowh; row++) { for (int col = 0; colw; col++) { if (!col) { init_histo(in, row, size, h); @@ -91,9 +108,70 @@ void imlib_median_filter(image_t *in, int size) r = median(h->r, h->n); g = median(h->g, h->n); b = median(h->b, h->n); - data[row*in->w+col] = SWAP(((r << 11) | (g << 5) | b)); + data[(row%k_rows)*in->w+col] = SWAP(((r << 11) | (g << 5) | b)); + } + if ((row+1)%k_rows==0) { + memcpy((uint16_t*)in->data+((row/k_rows)*k_rows*in->w), data, (k_rows*in->w*sizeof(*data))); } } - memcpy(in->data, data, (in->w*in->h*2)); + xfree(h); + xfree(data); +} + +#if 0 +void median_filter_gs(image_t *in, int size) +{ + histo_t *h = xalloc(sizeof(*h)); + uint8_t *data = (uint8_t*) (in->data+(in->w * in->h*2)); + + for (int row = 0; rowh; row ++) { + for (int col = 0; colw; col++) { + if (!col) { + init_histo(in, row, size, h); + } else { + del_pixels(in, row, col - size, size, h); + add_pixels(in, row, col + size, size, h); + } + data[row*in->w+col]=(uint8_t)median(h->h, h->n); + } + } + memcpy(in->data, data, (in->w*in->h)); + +} +#else +void median_filter_gs(image_t *in, int size) +{ + int k_rows = (2*size+1)*2; + histo_t *h = xalloc(sizeof(*h)); + uint8_t *data = xalloc(in->w * k_rows * sizeof(*data)); + + for (int row = 0; rowh; row ++) { + for (int col = 0; colw; col++) { + if (!col) { + init_histo(in, row, size, h); + } else if ((col-size) > 0 && (col+size) < in->w) { + del_pixels(in, row, col - size, size, h); + add_pixels(in, row, col + size, size, h); + } + data[(row%k_rows)*in->w+col] = (uint8_t)median(h->h, h->n); + } + if ((row+1)%k_rows==0) { + memcpy(in->data+((row/k_rows)*k_rows*in->w), data, (k_rows*in->w*sizeof(*data))); + } + } + + xfree(h); + xfree(data); +} +#endif + +void imlib_median_filter(image_t *in, int size) +{ + if (in->bpp == 1) { + //median_filter_test(in, size); + median_filter_gs(in, size); + } else { + median_filter_rgb(in, size); + } }