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

📄 flt-smooth.c

📁 xawtv绝版源码
💻 C
字号:
/* * libng filter -- Smooth the image to reduce snow at bad TV receiption * * * Filter options * -------------- * * There are 2 options available that can be turned on and off separately. * * Smooth over time:    Calculate average of previous and current frame. *                      Longer filter lengths could improve static *                      images but would be unusable for movies and *                      require high CPU power. I found averaging of *                      2 frames the most useful filter. * * Smooth horizontally: For every pixel, the average of the actual colour *                      and the colour of the pixel to the left is displayed. * * * (c) 2002  Klaus Peichl <pei@freenet.de> (smoothing filter), *           Gerd Knorr <kraxel@bytesex.org> (framework) * */#include "config.h"#include <stdio.h>#include <stdlib.h>#include <pthread.h>#include "grab-ng.h"/* ------------------------------------------------------------------- */typedef struct {  struct ng_video_buf * pLastFrame;}SMOOTH_BUFFER;static int smoothTime = 1;static int smoothHorizontal = 1;static void inlineinvert_bytes(unsigned char *dst, unsigned char *src, int bytes){    while (bytes--)	*(dst++) = 0xff - *(src++);}#if 1/*  Fast 32-bit smoothing*/static void inlinesmooth_native_32bit(unsigned int *last,		    unsigned int *dst,		    unsigned int *src,		    int pixels){  unsigned int  old,new, old2,new2;  if (smoothTime && smoothHorizontal) {    /* Smoothing in time and horizontally */    old2 = *last;    new2 = *src;    while (pixels--) {      old = *last;      new = *src++;      *last++ = new;      /*	Fast averaging:	All 4 bytes (of which only 3 are used) can be averaged in one 32bit-word.	The lowest 2 bits of every colour are thrown away to avoid influences	between the colours.      */      *dst++ =	((new >> 2) & 0x3F3F3F3F) +	((new2 >> 2) & 0x3F3F3F3F) +	((old >> 2) & 0x3F3F3F3F) +	((old2 >> 2) & 0x3F3F3F3F);      old2 = old;      new2 = new;    }  }  else if (smoothTime) {    /* Smoothing in time only */    while (pixels--) {      old = *last;      new = *src++;      *last++ = new;      /*	Fast averaging:	All 4 bytes (of which only 3 are used) can be averaged in one 32bit-word.	The lowest bit of every colour is thrown away to avoid influences	between the colours.      */      *dst++ =	((new >> 1) & 0x7F7F7F7F) +	((old >> 1) & 0x7F7F7F7F);    }  }  else if (smoothHorizontal) {    /* Smooth horizontally only */    new2 = *src;    while (pixels--) {      new = *src++;      *last++ = new;      /*	Fast averaging:	All 4 bytes (of which only 3 are used) can be averaged in one 32bit-word.	The lowest bit of every colour is thrown away to avoid influences	between the colours.      */      *dst++ =	((new >> 1) & 0x7F7F7F7F) +	((new2 >> 1) & 0x7F7F7F7F);      new2 = new;    }  }  else {    /* No smoothing at all */    while (pixels--) {      new = *src++;      *last++ = new;      *dst++ = new;    }  }}#else/*  This is an alternative implementation of the above function  which does not throw away the lowest bits before addition.  It is derived from the byte-based 24-bit-function below but  processes 4 bytes for every pixel instead of 3.*/static void inlinesmooth_native_32bit(unsigned char *last,		    unsigned char *dst,		    unsigned char *src,		    int pixels){  unsigned char  oldR,newR, oldR2,newR2;  unsigned char  oldG,newG, oldG2,newG2;  unsigned char  oldB,newB, oldB2,newB2;  unsigned char  oldP,newP, oldP2,newP2;  if (smoothTime && smoothHorizontal) {    /* Smoothing in time and horizontally */    oldR2 = last[0];    oldG2 = last[1];    oldB2 = last[2];    oldP2 = last[3];    newR2 = src[0];    newG2 = src[1];    newB2 = src[2];    newP2 = src[3];    while (pixels--) {      oldR = *last;  newR = *src++;  *last++ = newR;      oldG = *last;  newG = *src++;  *last++ = newG;      oldB = *last;  newB = *src++;  *last++ = newB;      oldP = *last;  newP = *src++;  *last++ = newP;      *dst++ = (newR + oldR + newR2 + oldR2) / 4;      *dst++ = (newG + oldG + newG2 + oldG2) / 4;      *dst++ = (newB + oldB + newB2 + oldB2) / 4;      *dst++ = (newP + oldP + newP2 + oldP2) / 4;      oldR2 = oldR;      oldG2 = oldG;      oldB2 = oldB;      oldP2 = oldP;      newR2 = newR;      newG2 = newG;      newB2 = newB;      newP2 = newP;    }  }  else if (smoothTime) {    /* Smoothing in time only */    while (pixels--) {      oldR = *last;  newR = *src++;  *last++ = newR;      oldG = *last;  newG = *src++;  *last++ = newG;      oldB = *last;  newB = *src++;  *last++ = newB;      oldP = *last;  newP = *src++;  *last++ = newP;      *dst++ = (newR + oldR) / 2;      *dst++ = (newG + oldG) / 2;      *dst++ = (newB + oldB) / 2;      *dst++ = (newP + oldP) / 2;    }  }  else if (smoothHorizontal) {    /* Smooth horizontally only */    newR2 = src[0];    newG2 = src[1];    newB2 = src[2];    newP2 = src[3];    while (pixels--) {      newR = *src++;  *last++ = newR;      newG = *src++;  *last++ = newG;      newB = *src++;  *last++ = newB;      newP = *src++;  *last++ = newP;      *dst++ = (newR + newR2) / 2;      *dst++ = (newG + newG2) / 2;      *dst++ = (newB + newB2) / 2;      *dst++ = (newP + newP2) / 2;      newR2 = newR;      newG2 = newG;      newB2 = newB;      newP2 = newP;    }  }  else {    /* No smoothing at all */    while (pixels--) {      newR = *src++;  *last++ = newR;  *dst++ = newR;      newG = *src++;  *last++ = newG;  *dst++ = newG;      newB = *src++;  *last++ = newB;  *dst++ = newB;      newP = *src++;  *last++ = newP;  *dst++ = newP;    }  }}#endifstatic void inlinesmooth_native_24bit(unsigned char *last,		    unsigned char *dst,		    unsigned char *src,		    int pixels){  unsigned char  oldR,newR, oldR2,newR2;  unsigned char  oldG,newG, oldG2,newG2;  unsigned char  oldB,newB, oldB2,newB2;  if (smoothTime && smoothHorizontal) {    /* Smoothing in time and horizontally */    oldR2 = last[0];    oldG2 = last[1];    oldB2 = last[2];    newR2 = src[0];    newG2 = src[1];    newB2 = src[2];    while (pixels--) {      oldR = *last;  newR = *src++;  *last++ = newR;      oldG = *last;  newG = *src++;  *last++ = newG;      oldB = *last;  newB = *src++;  *last++ = newB;      *dst++ = (newR + oldR + newR2 + oldR2) / 4;      *dst++ = (newG + oldG + newG2 + oldG2) / 4;      *dst++ = (newB + oldB + newB2 + oldB2) / 4;      oldR2 = oldR;      oldG2 = oldG;      oldB2 = oldB;      newR2 = newR;      newG2 = newG;      newB2 = newB;    }  }  else if (smoothTime) {    /* Smoothing in time only */    while (pixels--) {      oldR = *last;  newR = *src++;  *last++ = newR;      oldG = *last;  newG = *src++;  *last++ = newG;      oldB = *last;  newB = *src++;  *last++ = newB;      *dst++ = (newR + oldR) / 2;      *dst++ = (newG + oldG) / 2;      *dst++ = (newB + oldB) / 2;    }  }  else if (smoothHorizontal) {    /* Smooth horizontally only */    newR2 = src[0];    newG2 = src[1];    newB2 = src[2];    while (pixels--) {      newR = *src++;  *last++ = newR;      newG = *src++;  *last++ = newG;      newB = *src++;  *last++ = newB;      *dst++ = (newR + newR2) / 2;      *dst++ = (newG + newG2) / 2;      *dst++ = (newB + newB2) / 2;      newR2 = newR;      newG2 = newG;      newB2 = newB;    }  }  else {    /* No smoothing at all */    while (pixels--) {      newR = *src++;  *last++ = newR;  *dst++ = newR;      newG = *src++;  *last++ = newG;  *dst++ = newG;      newB = *src++;  *last++ = newB;  *dst++ = newB;    }  }}static void inlinesmooth_native_16bit(unsigned short *last,		    unsigned short *dst,		    unsigned short *src,		    unsigned short maskR,		    unsigned short maskG,		    unsigned short maskB,		    int pixels){  unsigned short  old,new, old2,new2;  unsigned short  red,green,blue;  if (smoothTime && smoothHorizontal) {    /* Smoothing in time and horizontally */    old2 = *last;    new2 = *src;    while (pixels--) {      old = *last;      new = *src++;      *last++ = new;      red   = ( ((new & maskR) + (old & maskR) + (new2 & maskR) + (old2 & maskR))/4 ) & maskR;      green = ( ((new & maskG) + (old & maskG) + (new2 & maskG) + (old2 & maskG))/4 ) & maskG;      blue  = ( ((new & maskB) + (old & maskB) + (new2 & maskB) + (old2 & maskB))/4 ) & maskB;      *dst++ = red | green | blue;      old2 = old;      new2 = new;    }  }  else if (smoothTime) {    /* Smoothing in time only */    while (pixels--) {      old = *last;      new = *src++;      *last++ = new;      red   = ( ((new & maskR) + (old & maskR))/2 ) & maskR;      green = ( ((new & maskG) + (old & maskG))/2 ) & maskG;      blue  = ( ((new & maskB) + (old & maskB))/2 ) & maskB;      *dst++ = red | green | blue;    }  }  else if (smoothHorizontal) {    /* Smooth horizontally only */    new2 = *src;    while (pixels--) {      new = *src++;      *last++ = new;      red   = ( ((new & maskR) + (new2 & maskR))/2 ) & maskR;      green = ( ((new & maskG) + (new2 & maskG))/2 ) & maskG;      blue  = ( ((new & maskB) + (new2 & maskB))/2 ) & maskB;      *dst++ = red | green | blue;      new2 = new;    }  }  else {    /* No smoothing at all */    while (pixels--) {      new = *src++;      *last++ = new;      *dst++ = new;    }  }}/* ------------------------------------------------------------------- */static void *init(struct ng_video_fmt *out){    /* don't have to carry around status info */    static SMOOTH_BUFFER smooth_buffer;    smooth_buffer.pLastFrame = ng_malloc_video_buf(out, out->height * out->bytesperline);    return &smooth_buffer;}static struct ng_video_buf*frame(void *h, struct ng_video_buf *in){    SMOOTH_BUFFER *handle = h;    struct ng_video_buf *out;    unsigned char *dst;    unsigned char *src;    unsigned char *last;    unsigned int y,cnt;    out = ng_malloc_video_buf(&in->fmt, in->fmt.height * in->fmt.bytesperline);    out->info = in->info;    dst = out->data;    src = in->data;    last = handle->pLastFrame->data;    cnt = in->fmt.width * ng_vfmt_to_depth[in->fmt.fmtid] / 8;    for (y = 0; y < in->fmt.height; y++) {	switch (in->fmt.fmtid) {	case VIDEO_GRAY:	case VIDEO_BGR24:	case VIDEO_RGB24:	    smooth_native_24bit((unsigned char*)last,				(unsigned char*)dst,				(unsigned char*)src,				in->fmt.width);	    break;	case VIDEO_BGR32:	case VIDEO_RGB32:	case VIDEO_YUYV:	case VIDEO_UYVY:	    smooth_native_32bit((unsigned int*)last,				(unsigned int*)dst,				(unsigned int*)src,				in->fmt.width);	    break;	case VIDEO_RGB15_NATIVE:	    smooth_native_16bit((unsigned short*)last,				(unsigned short*)dst,				(unsigned short*)src,				0x7C00,  /* mask for red */				0x03E0,  /* mask for green */				0x001F,  /* mask for blue */				in->fmt.width);	    break;	case VIDEO_RGB16_NATIVE:	    smooth_native_16bit((unsigned short*)last,				(unsigned short*)dst,				(unsigned short*)src,				0xF800,  /* mask for red */				0x07E0,  /* mask for green */				0x001F,  /* mask for blue */				in->fmt.width);	    break;	}	dst += out->fmt.bytesperline;	src += in->fmt.bytesperline;	last += in->fmt.bytesperline;    }    ng_release_video_buf(in);    return out;}static void fini(void *handle){  ng_release_video_buf(handle);}static int read_attr(struct ng_attribute *attr){  int value;  switch (attr->id) {  case 0:    value = smoothTime;    break;  case 1:    value = smoothHorizontal;    break;  default:    value = 0;  }  return value;}static void write_attr(struct ng_attribute *attr, int value){  switch (attr->id) {  case 0:    smoothTime = value;    break;  case 1:    smoothHorizontal = value;    break;  }}/* ------------------------------------------------------------------- */static struct ng_attribute attrs[] = {    {	id:       0,	name:     "smooth over time",	type:     ATTR_TYPE_BOOL,	defval:   1,	read:     read_attr,	write:    write_attr,    },{	id:       1,	name:     "smooth horizontally",	type:     ATTR_TYPE_BOOL,	defval:   1,	read:     read_attr,	write:    write_attr,    },{	/* end of list */    }};static struct ng_filter filter = {    name:    "smooth",    attrs:   attrs,    fmts:    (1 << VIDEO_GRAY)         |    (1 << VIDEO_RGB15_NATIVE) |    (1 << VIDEO_RGB16_NATIVE) |    (1 << VIDEO_BGR24)        |    (1 << VIDEO_RGB24)        |    (1 << VIDEO_BGR32)        |    (1 << VIDEO_RGB32)        |    (1 << VIDEO_YUYV)         |    (1 << VIDEO_UYVY),    init:    init,    frame:   frame,    fini:    fini,};extern void ng_plugin_init(void);void ng_plugin_init(void){    ng_filter_register(NG_PLUGIN_MAGIC,__FILE__,&filter);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -