📄 show.c
字号:
/***************************************************************************** * * show.c - Logitech QuickCam Express Viewer / Debug utility * * Copyright (C) 2000 Georg Acher (acher@in.tum.de) * Copyright (C) 2000 Mark Cave-Ayland (mca198@ecs.soton.ac.uk) * Copyright (C) 2002 Tuukka Toivonen (tuukkat@ee.oulu.fi) * * Requires quickcam-module (with V4L interface) and USB support! * *****************************************************************************//* Note: this program is meant only for debugging. It contains very ugly code *//* Streamformat, as delivered by the camera driver: Raw image data for Bayer-RGB-matrix: G R for even rows B G for odd rows*/#include <X11/Xlib.h>#include <X11/Xutil.h>#include <X11/Xos.h>#include <X11/extensions/XShm.h>#include <sys/types.h>#include <sys/ipc.h>#include <sys/shm.h>#include <stdlib.h>#include <stdio.h>#include <sys/types.h>#include <sys/stat.h>#include <fcntl.h>#include <sys/ioctl.h>#include <errno.h>#include <inttypes.h>#include <unistd.h>#define DUMPDATA 0 /* If using this, set DUMPDATA also in quickcam.h */#define NOKERNEL#define COMPRESS 1#define PARANOID 1#define PDEBUG(fmt, args...) do { printf("quickcam: " fmt, ## args); printf("\n"); } while(0)#define POISON_VAL 0x00#define POISON(x)//#define PDEBUG(fmt, args...)#define kmalloc(size, gfp) malloc(size)#define kfree(ptr) free(ptr)typedef uint8_t u8;typedef uint16_t u16;typedef uint32_t u32;typedef int16_t s16;typedef int32_t s32;#define FALSE 0#define TRUE (!FALSE)#define MAX(a,b) ((a)>(b)?(a):(b))#define MIN(a,b) ((a)<(b)?(a):(b))#define CLIP(a,low,high) MAX((low),MIN((high),(a)))#define BIT(x) (1<<(x))struct qc_mjpeg_data { int depth; /* Bits per pixel in the final RGB image: 16 or 24 */ u8 *encV; /* Temporary buffers for holding YUV image data */ u8 *encU; u8 *encY; /* yuv2rgb private data */ void *table; void *table_rV[256]; void *table_gU[256]; int table_gV[256]; void *table_bU[256]; void (*yuv2rgb_func)(struct qc_mjpeg_data *, u8 *, u8 *, u8 *, u8 *, void *, void *, int);};int qcdebug = 0;#define IDEBUG_INIT(x)#define IDEBUG_EXIT(x)#define IDEBUG_TEST(x)#define DEBUGLOGIC 1#define PRINTK(...)#include "qc-mjpeg.c"#include "videodev2.h"#include "quickcam.h"#define max(a,b) ((a)>(b)?(a):(b))#define min(a,b) ((a)<(b)?(a):(b))GC gc;GC gc1,gcn;Window win;Font font;Display *dpy=0;int screen;Pixmap buffer;int scrnW2,scrnH2;unsigned short flags = 0;char *text;XColor colors[16];XImage* img;char *s;XShmSegmentInfo shminfo;int depth;int bypp;// Other stuffunsigned char SENSOR_ADDR;char buf[32768];int po;int shutter_val=0x80;int gain=0xc0;int white_balance=0;static inline unsigned long long rdtsc(void){ unsigned int lo, hi; asm volatile ( "rdtsc\n" : "=a" (lo), "=d" (hi) ); return ((unsigned long long)(hi) << 32) | (lo);}int tulos;/* Supposedly fast division routine: according to my benchmarking, slow, don't use */static inline unsigned int fastdiv(unsigned int dividend, unsigned int divisor) { unsigned int result; asm const( "shrl $16,%%edx\n" "\tdivw %3\n" : "=a" (result) /* %0 Outputs */ : "a" (dividend), /* %1 Inputs, divident to both EAX and EDX */ "d" (dividend), /* %2 Inputs */ "q" (divisor) ); /* %3 */ return result;}unsigned int testi(unsigned int dividend, unsigned int divisor) { tulos = fastdiv(dividend,divisor); return tulos;}#define LUT_RED 0#define LUT_GREEN 256#define LUT_BLUE 512#define LUT_SIZE (3*256)static unsigned char lut[LUT_SIZE];void bayer_to_rgb_noip_asm(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp);/* Bayer image size must be even horizontally and vertically *//* 10834 clocks */static unsigned char bayer_midvalue(unsigned char *bay, int bay_line, unsigned int columns, unsigned int rows){ static const unsigned int stepsize = 8; unsigned char *cur_bay; unsigned int sum = 0; int column_cnt; int row_cnt; columns /= stepsize*2; rows /= stepsize*2; row_cnt = rows; do { column_cnt = columns; cur_bay = bay; do { sum += cur_bay[0] + cur_bay[1] + cur_bay[bay_line]; /* R + G + B */ cur_bay += 2*stepsize; } while (--column_cnt > 0); bay += 2*stepsize*bay_line; } while (--row_cnt > 0); sum /= 3 * columns * rows; return sum;}/* 89422 clocks */static void bayer_equalize(unsigned char *bay, int bay_line, unsigned int columns, unsigned int rows, unsigned char *lut){ static const unsigned int stepsize = 4; unsigned short red_cnt[256], green_cnt[256], blue_cnt[256]; unsigned int red_sum, green_sum, blue_sum; unsigned int red_tot, green_tot, blue_tot; unsigned char *cur_bay; int i, column_cnt, row_cnt; memset(red_cnt, 0, sizeof(red_cnt)); memset(green_cnt, 0, sizeof(green_cnt)); memset(blue_cnt, 0, sizeof(blue_cnt)); columns /= 2*stepsize; rows /= 2*stepsize; /* Compute histogram */ row_cnt = rows; do { column_cnt = columns; cur_bay = bay; do { green_cnt[cur_bay[0]]++; red_cnt [cur_bay[1]]++; blue_cnt [cur_bay[bay_line]]++; green_cnt[cur_bay[bay_line+1]]++; cur_bay += 2*stepsize; } while (--column_cnt > 0); bay += 2*stepsize*bay_line; } while (--row_cnt > 0); /* Compute lookup table based on the histogram */ red_tot = columns * rows; /* Total number of pixels of each primary color */ green_tot = red_tot * 2; blue_tot = red_tot; red_sum = 0; green_sum = 0; blue_sum = 0; for (i=0; i<256; i++) { lut[LUT_RED + i] = 255 * red_sum / red_tot; lut[LUT_GREEN + i] = 255 * green_sum / green_tot; lut[LUT_BLUE + i] = 255 * blue_sum / blue_tot; red_sum += red_cnt[i]; green_sum += green_cnt[i]; blue_sum += blue_cnt[i]; }}/* Apply the look-up table to the Bayer image data *//* 391721-437413 PII, 295471 PIII */static void bayer_lut(unsigned char *bay, int bay_line, unsigned int columns, unsigned int rows, unsigned char *lut){ unsigned char *cur_bay; unsigned int total_columns; total_columns = columns / 2; /* Number of 2x2 bayer blocks */ rows /= 2; do { columns = total_columns; cur_bay = bay; do { cur_bay[0] = lut[LUT_GREEN + cur_bay[0]]; cur_bay[1] = lut[LUT_RED + cur_bay[1]]; cur_bay += 2; } while (--columns); bay += bay_line; columns = total_columns; cur_bay = bay; do { cur_bay[0] = lut[LUT_BLUE + cur_bay[0]]; cur_bay[1] = lut[LUT_GREEN + cur_bay[1]]; cur_bay += 2; } while (--columns); bay += bay_line; } while (--rows);}/* * Convert Bayer image data to RGB, 24 bpp * * Camera is G1R1 G2R2 G3R3... * B4G4 B5G5 B6G6... * Video is B4G1R1 B4G1R1 * B4G4R1 B4G4R1*/static inline void write_rgb(void *addr, int bpp, unsigned char r, unsigned char g, unsigned char b){ if (bpp==4) { /* Negate to disabled */ *(unsigned int *)addr = (unsigned int)r << 16 | (unsigned int)g << 8 | (unsigned int)b; } else { unsigned char *addr2 = (unsigned char *)addr; addr2[0] = b; addr2[1] = g; addr2[2] = r; }}/* With interpolation: 9367700-9491271 clocks *//* Without interpolation: 8767177-8930714 *//* static void quickcam_parse_data(struct usb_quickcam *quickcam, int curframe)*//* Original routine from quickcam.c *//* No interpolation *//* 2391747-2653574 clocks */static inline void bayer_to_rgb_noip(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, int columns, int rows, int bpp){ unsigned char *cur_bay, *cur_rgb; int bay_line2, rgb_line2; int total_columns; /* Process 2 lines and rows per each iteration */ total_columns = columns >> 1; rows >>= 1; bay_line2 = 2*bay_line; rgb_line2 = 2*rgb_line; do { cur_bay = bay; cur_rgb = rgb; columns = total_columns; do { write_rgb(cur_rgb+0, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); write_rgb(cur_rgb+bpp, bpp, cur_bay[1], cur_bay[0], cur_bay[bay_line]); write_rgb(cur_rgb+rgb_line, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); write_rgb(cur_rgb+rgb_line+bpp, bpp, cur_bay[1], cur_bay[bay_line+1], cur_bay[bay_line]); cur_bay += 2; cur_rgb += 2*bpp; } while (--columns); bay += bay_line2; rgb += rgb_line2; } while (--rows);} /* Interpolate R,G,B horizontally. columns must be even */static inline void bayer_to_rgb_horip(unsigned char *bay, int bay_line, unsigned char *rgb, int rgb_line, unsigned int columns, unsigned int rows, int bpp) { unsigned char *cur_bay, *cur_rgb; int bay_line2, rgb_line2; int total_columns; unsigned char red, green, blue; unsigned int column_cnt, row_cnt; /* Process 2 lines and rows per each iteration */ total_columns = (columns-2) / 2; row_cnt = rows / 2; bay_line2 = 2*bay_line; rgb_line2 = 2*rgb_line; do { write_rgb(rgb+0, bpp, bay[1], bay[0], bay[bay_line]); write_rgb(rgb+rgb_line, bpp, bay[1], bay[0], bay[bay_line]); cur_bay = bay + 1; cur_rgb = rgb + bpp; column_cnt = total_columns; do { green = ((unsigned int)cur_bay[-1]+cur_bay[1]) / 2; blue = ((unsigned int)cur_bay[bay_line-1]+cur_bay[bay_line+1]) / 2; write_rgb(cur_rgb+0, bpp, cur_bay[0], green, blue); red = ((unsigned int)cur_bay[0]+cur_bay[2]) / 2; write_rgb(cur_rgb+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); green = ((unsigned int)cur_bay[bay_line]+cur_bay[bay_line+2]) / 2; write_rgb(cur_rgb+rgb_line, bpp, cur_bay[0], cur_bay[bay_line], blue); write_rgb(cur_rgb+rgb_line+bpp, bpp, red, cur_bay[1], cur_bay[bay_line+1]); cur_bay += 2; cur_rgb += 2*bpp; } while (--column_cnt); write_rgb(cur_rgb+0, bpp, cur_bay[0], cur_bay[-1], cur_bay[bay_line-1]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -