📄 filter.c
字号:
#include <stdio.h>#include <stdlib.h>#include <math.h>#include <string.h>#include "loader.h"#include "filter.h"/* ----------------------------------------------------------------------- */static voidop_grayscale(struct ida_image *src, struct ida_rect *rect, unsigned char *dst, int line, void *data){ unsigned char *scanline; int i,g; scanline = src->data + line * src->i.width * 3; memcpy(dst,scanline,src->i.width * 3); if (line < rect->y1 || line >= rect->y2) return; dst += 3*rect->x1; scanline += 3*rect->x1; for (i = rect->x1; i < rect->x2; i++) { g = (scanline[0]*30 + scanline[1]*59+scanline[2]*11)/100; dst[0] = g; dst[1] = g; dst[2] = g; scanline += 3; dst += 3; }}/* ----------------------------------------------------------------------- */struct op_3x3_handle { struct op_3x3_parm filter; int *linebuf;};static void*op_3x3_init(struct ida_image *src, struct ida_rect *rect, struct ida_image_info *i, void *parm){ struct op_3x3_parm *args = parm; struct op_3x3_handle *h; h = malloc(sizeof(*h)); memcpy(&h->filter,args,sizeof(*args)); h->linebuf = malloc(sizeof(int)*3*(src->i.width)); *i = src->i; return h;}static int inlineop_3x3_calc_pixel(struct op_3x3_parm *p, unsigned char *s1, unsigned char *s2, unsigned char *s3){ int val = 0; val += p->f1[0] * s1[0]; val += p->f1[1] * s1[3]; val += p->f1[2] * s1[6]; val += p->f2[0] * s2[0]; val += p->f2[1] * s2[3]; val += p->f2[2] * s2[6]; val += p->f3[0] * s3[0]; val += p->f3[1] * s3[3]; val += p->f3[2] * s3[6]; if (p->mul && p->div) val = val * p->mul / p->div; val += p->add; return val;}static voidop_3x3_calc_line(struct ida_image *src, struct ida_rect *rect, int *dst, unsigned int line, struct op_3x3_parm *p){ unsigned char b1[9],b2[9],b3[9]; unsigned char *s1,*s2,*s3; unsigned int i,left,right; s1 = src->data + (line-1) * src->i.width * 3; s2 = src->data + line * src->i.width * 3; s3 = src->data + (line+1) * src->i.width * 3; if (0 == line) s1 = src->data + line * src->i.width * 3; if (src->i.height-1 == line) s3 = src->data + line * src->i.width * 3; left = rect->x1; right = rect->x2; if (0 == left) { /* left border special case: dup first col */ memcpy(b1,s1,3); memcpy(b2,s2,3); memcpy(b3,s3,3); memcpy(b1+3,s1,6); memcpy(b2+3,s2,6); memcpy(b3+3,s3,6); dst[0] = op_3x3_calc_pixel(p,b1,b2,b3); dst[1] = op_3x3_calc_pixel(p,b1+1,b2+1,b3+1); dst[2] = op_3x3_calc_pixel(p,b1+2,b2+2,b3+2); left++; } if (src->i.width == right) { /* right border */ memcpy(b1,s1+src->i.width*3-6,6); memcpy(b2,s2+src->i.width*3-6,6); memcpy(b3,s3+src->i.width*3-6,6); memcpy(b1+3,s1+src->i.width*3-3,3); memcpy(b2+3,s2+src->i.width*3-3,3); memcpy(b3+3,s3+src->i.width*3-3,3); dst[src->i.width*3-3] = op_3x3_calc_pixel(p,b1,b2,b3); dst[src->i.width*3-2] = op_3x3_calc_pixel(p,b1+1,b2+1,b3+1); dst[src->i.width*3-1] = op_3x3_calc_pixel(p,b1+2,b2+2,b3+2); right--; } dst += 3*left; s1 += 3*(left-1); s2 += 3*(left-1); s3 += 3*(left-1); for (i = left; i < right; i++) { dst[0] = op_3x3_calc_pixel(p,s1++,s2++,s3++); dst[1] = op_3x3_calc_pixel(p,s1++,s2++,s3++); dst[2] = op_3x3_calc_pixel(p,s1++,s2++,s3++); dst += 3; }}static voidop_3x3_clip_line(unsigned char *dst, int *src, int left, int right){ int i,val; src += left*3; dst += left*3; for (i = left*3; i < right*3; i++) { val = *(src++); if (val < 0) val = 0; if (val > 255) val = 255; *(dst++) = val; }}static voidop_3x3_work(struct ida_image *src, struct ida_rect *rect, unsigned char *dst, int line, void *data){ struct op_3x3_handle *h = data; unsigned char *scanline; scanline = src->data + line * src->i.width * 3; memcpy(dst,scanline,src->i.width * 3); if (line < rect->y1 || line >= rect->y2) return; op_3x3_calc_line(src,rect,h->linebuf,line,&h->filter); op_3x3_clip_line(dst,h->linebuf,rect->x1,rect->x2);}static voidop_3x3_free(void *data){ struct op_3x3_handle *h = data; free(h->linebuf); free(h);} /* ----------------------------------------------------------------------- */struct op_sharpe_handle { int factor; int *linebuf;};static void*op_sharpe_init(struct ida_image *src, struct ida_rect *rect, struct ida_image_info *i, void *parm){ struct op_sharpe_parm *args = parm; struct op_sharpe_handle *h; h = malloc(sizeof(*h)); h->factor = args->factor; h->linebuf = malloc(sizeof(int)*3*(src->i.width)); *i = src->i; return h;}static voidop_sharpe_work(struct ida_image *src, struct ida_rect *rect, unsigned char *dst, int line, void *data){ static struct op_3x3_parm laplace = { f1: { 1, 1, 1 }, f2: { 1, -8, 1 }, f3: { 1, 1, 1 }, }; struct op_sharpe_handle *h = data; unsigned char *scanline; int i; scanline = src->data + line * src->i.width * 3; memcpy(dst,scanline,src->i.width * 3); if (line < rect->y1 || line >= rect->y2) return; op_3x3_calc_line(src,rect,h->linebuf,line,&laplace); for (i = rect->x1*3; i < rect->x2*3; i++) h->linebuf[i] = scanline[i] - h->linebuf[i] * h->factor / 256; op_3x3_clip_line(dst,h->linebuf,rect->x1,rect->x2);}static voidop_sharpe_free(void *data){ struct op_sharpe_handle *h = data; free(h->linebuf); free(h);}/* ----------------------------------------------------------------------- */struct op_resize_state { float xscale,yscale,inleft; float *rowbuf; unsigned int width,height,srcrow;};static void*op_resize_init(struct ida_image *src, struct ida_rect *rect, struct ida_image_info *i, void *parm){ struct op_resize_parm *args = parm; struct op_resize_state *h; h = malloc(sizeof(*h)); h->width = args->width; h->height = args->height; h->xscale = (float)args->width/src->i.width; h->yscale = (float)args->height/src->i.height; h->rowbuf = malloc(src->i.width * 3 * sizeof(float)); h->srcrow = 0; h->inleft = 1; *i = src->i; i->width = args->width; i->height = args->height; i->dpi = args->dpi; return h;}static voidop_resize_work(struct ida_image *src, struct ida_rect *rect, unsigned char *dst, int line, void *data){ struct op_resize_state *h = data; float outleft,left,weight,d0,d1,d2; unsigned char *csrcline; float *fsrcline; unsigned int i,sx,dx; /* scale y */ memset(h->rowbuf, 0, src->i.width * 3 * sizeof(float)); outleft = 1/h->yscale; while (outleft > 0 && h->srcrow < src->i.height) { if (outleft < h->inleft) { weight = outleft * h->yscale; h->inleft -= outleft; outleft = 0; } else { weight = h->inleft * h->yscale; outleft -= h->inleft; h->inleft = 0; }#if 0 if (debug) fprintf(stderr,"y: %6.2f%%: %d/%d => %d/%d\n", weight*100,h->srcrow,src->height,line,h->height);#endif csrcline = src->data + h->srcrow * src->i.width * 3; for (i = 0; i < src->i.width * 3; i++) h->rowbuf[i] += (float)csrcline[i] * weight; if (0 == h->inleft) { h->inleft = 1; h->srcrow++; } } /* scale x */ left = 1; fsrcline = h->rowbuf; for (sx = 0, dx = 0; dx < h->width; dx++) { d0 = d1 = d2 = 0; outleft = 1/h->xscale; while (outleft > 0 && dx < h->width && sx < src->i.width) { if (outleft < left) { weight = outleft * h->xscale; left -= outleft; outleft = 0; } else { weight = left * h->xscale; outleft -= left; left = 0; }#if 0 if (debug) fprintf(stderr," x: %6.2f%%: %d/%d => %d/%d\n", weight*100,sx,src->width,dx,h->width);#endif d0 += fsrcline[3*sx+0] * weight; d1 += fsrcline[3*sx+1] * weight; d2 += fsrcline[3*sx+2] * weight; if (0 == left) { left = 1; sx++; } } dst[0] = d0; dst[1] = d1; dst[2] = d2; dst += 3; }}static voidop_resize_done(void *data){ struct op_resize_state *h = data; free(h->rowbuf); free(h);} /* ----------------------------------------------------------------------- */struct op_rotate_state { float angle,sina,cosa; struct ida_rect calc; int cx,cy;};static void*op_rotate_init(struct ida_image *src, struct ida_rect *rect, struct ida_image_info *i, void *parm){ struct op_rotate_parm *args = parm; struct op_rotate_state *h; float diag; h = malloc(sizeof(*h)); h->angle = args->angle * 2 * M_PI / 360; h->sina = sin(h->angle); h->cosa = cos(h->angle); h->cx = (rect->x2 - rect->x1) / 2 + rect->x1; h->cy = (rect->y2 - rect->y1) / 2 + rect->y1; /* the area we have to process (worst case: 45
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -