⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 filter.c

📁 linux下开源图片codec
💻 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 + -