📄 filters.c
字号:
/*********************************************************************
* webcam_server *
* *
* (c) 2002 Donn Morrison donn@donn.dyndns.org *
* *
* code used from Gerd Knorr's xawtv (libng) *
* - and - *
* Cory Lueninghoener's gqcam *
* *
* waits for connections from a viewer and sends *
* jpeg encoded captures as a live video feed *
* *
*********************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <semaphore.h>
#include <jpeglib.h>
#include <jerror.h>
#include <semaphore.h>
#include <pthread.h>
#include <string.h>
#include <linux/videodev.h>
#include "webcam_server.h"
#include "filters.h"
#include "jdatabuf.h"
#define COMPARE_RGB(x,y) ((x.r == y.r && x.g == y.g && x.b == y.b))
/*-----------------------------------------------------------
image processing procedures
image2jpeg: encodes raw image to jpeg
add_text: adds a caption to the image
swap_rgb24: RGB->RBG
fliph: flips the image horizontally
flipv: flips vertically
-----------------------------------------------------------*/
int image2jpeg(struct image *img, char **jpeg_data, int quality)
{
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
int i, size;
int w, h;
unsigned char *line;
w = img->width;
h = img->height;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_buff_dest(&cinfo);
cinfo.image_width = w;
cinfo.image_height = h;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
jpeg_set_defaults(&cinfo);
jpeg_set_quality(&cinfo, quality, TRUE);
jpeg_start_compress(&cinfo, TRUE);
for (i = 0, line = img->buf; i < h; i++, line += w*3)
jpeg_write_scanlines(&cinfo, &line, 1);
jpeg_finish_compress(&cinfo);
size = get_jpeg_size(&cinfo);
/* this memory must be freed elsewhere */
(*jpeg_data) = (char *)malloc(size);
if(!(*jpeg_data))
{
jpeg_destroy_compress(&cinfo);
jpeg_buff_free(&cinfo);
return -1;
}
memcpy(*jpeg_data, ((my_dest_ptr)cinfo.dest)->buffer, size);
jpeg_destroy_compress(&cinfo);
jpeg_buff_free(&cinfo);
return size;
}
/* Gerd Knorr */
#define CHAR_HEIGHT 11
#define CHAR_WIDTH 6
#define CHAR_START 4
#include "font_6x11.h"
//void add_text(struct image *img, char *text, struct RGB fg, struct RGB bg, struct RGB trans, int xpos, int ypos)
void swap_rgb24(struct image* img)
{
char c;
char *p = img->buf;
int i = img->bufsize/3;
while (--i) {
c = p[0]; p[0] = p[2]; p[2] = c;
p += 3;
}
}
void adjust_gamma(struct image* img, int corr)
{
int i=img->bufsize;
char *p = img->buf;
while(--i)
{
if(corr > 0)
{
if(p[0] + corr <= 255)
p[0] += corr;
else
p[0] = 255;
}
else
{
if(p[0] + corr >= 0)
p[0] += corr;
else
p[0] = 0;
}
p++;
}
}
void rotate_image(struct image *img, int rot)
{
static unsigned char * rotimg = NULL;
char *in = img->buf;
int wp, hp;
int top=0, left=0, bottom, right;
int i, j;
int w = img->width;
int ow = img->width;
int oh = img->height;
if (rotimg == NULL && (rotimg = (char*)malloc(ow*oh*3)) == NULL ) {
perror("rotate_image()");
return;
}
switch ( rot ) {
default:
case 0:
for (j = 0; j < oh; j++) {
int ir = (j+top)*w+left;
int or = j*ow;
for (i = 0; i < ow; i++) {
rotimg[3*(or + i)] = in[3*(ir+i)];
rotimg[3*(or + i)+1] = in[3*(ir+i)+1];
rotimg[3*(or + i)+2] = in[3*(ir+i)+2];
}
}
wp = ow;
hp = oh;
break;
case 1:
for (i = 0; i < ow; i++) {
int rr = (ow-1-i)*oh;
int ic = i+left;
for (j = 0; j < oh; j++) {
rotimg[3*(rr+j)] = in[3*((j+top)*w+ic)];
rotimg[3*(rr+j)+1] = in[3*((j+top)*w+ic)+1];
rotimg[3*(rr+j)+2] = in[3*((j+top)*w+ic)+2];
}
}
wp = oh;
hp = ow;
break;
case 2:
for (j = 0; j < oh; j++) {
int ir = (j+top)*w;
for (i = 0; i < ow; i++) {
rotimg[3*((oh-1-j)*ow + (ow-1-i))] = in[3*(ir+i+left)];
rotimg[3*((oh-1-j)*ow + (ow-1-i))+1] = in[3*(ir+i+left)+1];
rotimg[3*((oh-1-j)*ow + (ow-1-i))+2] = in[3*(ir+i+left)+2];
}
}
wp = ow;
hp = oh;
break;
case 3:
for (i = 0; i < ow; i++) {
int rr = i*oh;
int ic = i+left;
rr += oh-1;
for (j = 0; j < oh; j++) {
rotimg[3*(rr-j)] = in[3*((j+top)*w+ic)];
rotimg[3*(rr-j)+1] = in[3*((j+top)*w+ic)+1];
rotimg[3*(rr-j)+2] = in[3*((j+top)*w+ic)+2];
}
}
wp = oh;
hp = ow;
break;
}
memcpy(in, rotimg, ow*oh*3);
img->width = wp;
img->height = hp;
}
int compare_images(unsigned char *last, unsigned char *current, int width, int height)
{
unsigned char *p1 = last;
unsigned char *p2 = current;
int avg, diff, max, i = width*height*3;
for (max = 0, avg = 0; --i; p1++,p2++) {
diff = (*p1 < *p2) ? (*p2 - *p1) : (*p1 - *p2);
avg += diff;
if (diff > max)
max = diff;
}
avg = avg / width / height;
fprintf(stderr,"compare: max=%d,avg=%d\n",max,avg);
/* return avg */
return max;
}
void fliph(struct image *img)
{
int i,j;
char *dest = NULL;
char *srcline, *destline;
dest = (char *)malloc(img->width * img->height * 3);
if(!dest)
return;
for(i=0;i<img->height;i++)
{
srcline = img->buf + i*3*img->width;
destline = dest + i*3*img->width + 3*(img->width-1);
for(j=0;j<img->width;j++)
{
memcpy(destline, srcline, 3);
srcline += 3;
destline -= 3;
}
}
memcpy(img->buf, dest, img->width * img->height * 3);
free(dest);
}
void flipv(struct image *img)
{
int i;
char *dest = NULL;
char *srcline, *destline;
dest = (char *)malloc(img->width * img->height * 3);
if(!dest)
return;
for(i=0;i<img->height;i++)
{
srcline = img->buf + i*img->width*3;
destline = dest + (img->height-i)*img->width*3 - img->width*3;
memcpy(destline, srcline, img->width*3);
}
memcpy(img->buf, dest, img->width * img->height * 3);
free(dest);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -