📄 saa7113h_api.c
字号:
return -EIO; }#endif } else { ret = read(cam_fd, cam_buf, cam_buf_size); if(ret<0) { fprintf(stderr, "read camera fail!%d\n", ret); return -EIO; } //fprintf(stdout, "read %d bytes\n", i); } rgb24 = (format&RGB_FMT_MSK)==RGB24_FLAG; format &= ~RGB_FMT_MSK; if(format>=SUB_WIN_NUMBER) return -EINVAL; *win = sub_win_pos[format]; if(rgb24) convert_rgb24_image(buf, format, win); else convert_rgb16_image(buf, format, win); return 0;}#define YCbCrtoR(Y,Cb,Cr) (1000*Y + 1371*(Cr-128))/1000#define YCbCrtoG(Y,Cb,Cr) (1000*Y - 336*(Cb-128) - 698*(Cr-128))/1000#define YCbCrtoB(Y,Cb,Cr) (1000*Y + 1732*(Cb-128))/1000#define min(x1, x2) (((x1)<(x2))?(x1):(x2))/*static __inline __u32 Conv_YCbCr_Rgb(__u8 y0, __u8 y1, __u8 cb0, __u8 cr0){ // bit order is // YCbCr = [Cr0 Y1 Cb0 Y0], RGB=[R1,G1,B1,R0,G0,B0]. int r0, g0, b0, r1, g1, b1; __u16 rgb0, rgb1; __u32 rgb; #if 1 r0 = YCbCrtoR(y0, cb0, cr0); g0 = YCbCrtoG(y0, cb0, cr0); b0 = YCbCrtoB(y0, cb0, cr0); r1 = YCbCrtoR(y1, cb0, cr0); g1 = YCbCrtoG(y1, cb0, cr0); b1 = YCbCrtoB(y1, cb0, cr0); #endif if (r0>255 ) r0 = 255; if (r0<0) r0 = 0; if (g0>255 ) g0 = 255; if (g0<0) g0 = 0; if (b0>255 ) b0 = 255; if (b0<0) b0 = 0; if (r1>255 ) r1 = 255; if (r1<0) r1 = 0; if (g1>255 ) g1 = 255; if (g1<0) g1 = 0; if (b1>255 ) b1 = 255; if (b1<0) b1 = 0; // 5:6:5 16bit format rgb0 = (((__u16)r0>>3)<<11) | (((__u16)g0>>2)<<5) | (((__u16)b0>>3)<<0); //RGB565. rgb1 = (((__u16)r1>>3)<<11) | (((__u16)g1>>2)<<5) | (((__u16)b1>>3)<<0); //RGB565. rgb = (rgb1<<16) | rgb0; return(rgb);}*/static __inline __u32 Conv_YCbCr_Rgb16(__u8 y0, __u8 cb0, __u8 cr0, __u8 y1, __u8 cb1, __u8 cr1){ // bit order is // YCbCr = [Cr0 Y1 Cb0 Y0], RGB=[R1,G1,B1,R0,G0,B0]. int r0, g0, b0, r1, g1, b1; __u16 rgb0, rgb1; __u32 rgb; r0 = YCbCrtoR(y0, cb0, cr0); g0 = YCbCrtoG(y0, cb0, cr0); b0 = YCbCrtoB(y0, cb0, cr0); r1 = YCbCrtoR(y1, cb1, cr1); g1 = YCbCrtoG(y1, cb1, cr1); b1 = YCbCrtoB(y1, cb1, cr1); if (r0>255 ) r0 = 255; if (r0<0) r0 = 0; if (g0>255 ) g0 = 255; if (g0<0) g0 = 0; if (b0>255 ) b0 = 255; if (b0<0) b0 = 0; if (r1>255 ) r1 = 255; if (r1<0) r1 = 0; if (g1>255 ) g1 = 255; if (g1<0) g1 = 0; if (b1>255 ) b1 = 255; if (b1<0) b1 = 0; // 5:6:5 16bit format rgb0 = (((__u16)r0>>3)<<11) | (((__u16)g0>>2)<<5) | (((__u16)b0>>3)<<0); //RGB565. rgb1 = (((__u16)r1>>3)<<11) | (((__u16)g1>>2)<<5) | (((__u16)b1>>3)<<0); //RGB565. rgb = (rgb1<<16) | rgb0; return(rgb);}static __inline __u32 Conv_YCbCr_Rgb24(__u8 y, __u8 cb, __u8 cr){ int r, g, b; r = YCbCrtoR(y, cb, cr); g = YCbCrtoG(y, cb, cr); b = YCbCrtoB(y, cb, cr); if (r>255 ) r = 255; if (r<0) r = 0; if (g>255 ) g = 255; if (g<0) g = 0; if (b>255 ) b = 255; if (b<0) b = 0; return (r<<16) | (g<<8) | b; //RGB888.}static __inline void convert_rgb16_image(void *buf, int format, cam_window_t *win){ __u32 rgb_data; __u16 x, y, w, h, i, j; __u32 **buf32 = buf; __u16 x_skip = win->x_ratio; __u16 y_skip = win->y_ratio; w = win->width; h = win->height; for(y=win->y0, j=0; j<h; ) { for(x=win->x0, i=0; i<w; ) { rgb_data = Conv_YCbCr_Rgb16(line_y[y][x], line_cb[y][x/2], line_cr[y][x/2], line_y[y][x+x_skip], line_cb[y][(x+x_skip)/2], line_cr[y][(x+x_skip)/2]); buf32[j][i/2] = rgb_data; x += 2 * x_skip; i += 2; } y += y_skip; j += 1; }}static __inline void convert_rgb24_image(void *buf, int format, cam_window_t *win){ __u32 rgb_data; __u16 x, y, w, h, i, j;// char *buf8 = ((void **)buf)[0]; char **buf8 = buf; __u16 x_skip = win->x_ratio; __u16 y_skip = win->y_ratio; w = win->width; h = win->height; for(y=win->y0, j=0; j<h; ) { for(x=win->x0, i=0; i<w; ) { rgb_data = Conv_YCbCr_Rgb24(line_y[y][x], line_cb[y][x/2], line_cr[y][x/2]); buf8[j][i*3] = rgb_data>>16; buf8[j][i*3+1] = rgb_data>>8; buf8[j][i*3+2] = rgb_data; x += x_skip; i += 1; rgb_data = Conv_YCbCr_Rgb24(line_y[y][x], line_cb[y][x/2], line_cr[y][x/2]); buf8[j][i*3] = rgb_data>>16; buf8[j][i*3+1] = rgb_data>>8; buf8[j][i*3+2] = rgb_data; x += x_skip; i += 1; } y += y_skip; j += 1; }}#ifndef GLOBAL#define GLOBAL //defined in jmorecfg.h#endifGLOBAL(void)write_JPEG_file (char *filename, int quality, unsigned short width, unsigned short height){ struct jpeg_compress_struct cinfo; struct jpeg_error_mgr jerr; /* More stuff */ FILE * outfile; /* target file */ JSAMPROW row_pointer[1]; /* pointer to JSAMPLE row[s] */ int row_stride; /* physical row width in image buffer */ cinfo.err = jpeg_std_error(&jerr); /* Now we can initialize the JPEG compression object. */ jpeg_create_compress(&cinfo); if ((outfile = fopen(filename, "wb")) == NULL) { fprintf(stderr, "can't open %s\n", filename); exit(1); } jpeg_stdio_dest(&cinfo, outfile); cinfo.image_width = width; /* image width and height, in pixels */ cinfo.image_height = height; cinfo.input_components = 3; /* # of color components per pixel */ cinfo.in_color_space = JCS_RGB; /* colorspace of input image */ jpeg_set_defaults(&cinfo); jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */); jpeg_start_compress(&cinfo, TRUE); row_stride = width * 3; /* JSAMPLEs per row in image_buffer */ while (cinfo.next_scanline < cinfo.image_height) { row_pointer[0] = & image_buffer[cinfo.next_scanline * row_stride]; (void) jpeg_write_scanlines(&cinfo, row_pointer, 1); } /* Step 6: Finish compression */ jpeg_finish_compress(&cinfo); /* After finish_compress, we can close the output file. */ fclose(outfile); jpeg_destroy_compress(&cinfo); /* And we're done! */}int camera_save_picture(int win_idx, char *name, int quality){ int ret; cam_window_t cam_win; if(cam_win_p!=(sub_win_pos + win_idx)) { int i; if(win_idx>=SUB_WIN_NUMBER) { return -EINVAL; } cam_win_p = sub_win_pos + win_idx; for(i=0; i<cam_win_p->width; i++) image_line[i] = image_buffer + 3 * i * cam_win_p->width; fprintf(stdout, "set image width %d, height %d\n", cam_win_p->width, cam_win_p->height); } ret = camera_output_lines(image_line, win_idx | RGB24_FLAG, &cam_win); if(ret==0) { write_JPEG_file(name, quality, cam_win_p->width, cam_win_p->height); } return ret;}/*************************************************************/int capture_img_init(void){ int rdfd; rdfd = camera_open(S3C2440A); if(rdfd>=0) {/* cam_window_t cam_win; // user defined window cam_win.x0 = 40; cam_win.y0 = 72; cam_win.x1 = 680; cam_win.y1 = 552; cam_win.x_ratio = 2; cam_win.y_ratio = 2; camera_set_window(&cam_win);*/ camera_start(CAMERA_VIDEO); //video } return rdfd;}int capture_img_destroy(void){ camera_stop(); camera_close(); return 0;}int capture_img_bymode(int win_idx, int *w, int *h){ int ret; fd_set rfds; cam_window_t cam_win; struct timeval tv; if(cam_fd<0) return -ENODEV; ret = camera_get_window(win_idx, &cam_win); if(ret) return ret; *w = cam_win.width; *h = cam_win.height; FD_ZERO(&rfds); //FD_SET(0, &rfds); FD_SET(cam_fd, &rfds); if(camera_capture()<0) return -EIO; tv.tv_sec = 3; tv.tv_usec = 0; select(cam_fd+1, &rfds, NULL, NULL, &tv); if(FD_ISSET(cam_fd, &rfds)) { fprintf(stdout, "camera input\n"); if(camera_save_picture(win_idx, "jpgfile.jpg", 75)<0) { fprintf(stderr, "capture fail!\n"); return -EIO; } } else { fprintf(stderr, "wait timeout, break...\n"); return -EIO; } return 0;}/*************************************************************/static int fb_fd = -1;static int fb_xres;static int fb_yres;static int fb_bpp;static char *fb_buf = NULL;static int fb_buf_size;static char *fb_line[1024];static int open_fb(void);static int close_fb(void);static void fill_screen(int color){ int x, y; for(y=0; y<fb_yres; y++) for(x=0; x<fb_xres; x++) ((__u16 *)fb_buf)[y*fb_xres+x] = color;// memset(fb_buf, 0, fb_buf_size);}static int open_fb(void){ int i; struct fb_var_screeninfo vinfo; struct fb_fix_screeninfo finfo; fb_fd = open("/dev/fb0", O_RDWR); if (fb_fd < 0) { fb_fd = open("/dev/fb/0", O_RDWR); if(fb_fd<0) { fprintf(stderr, "fail to open framebuffer device!\n"); return -ENODEV; } } // Get fixed screen information if (ioctl(fb_fd, FBIOGET_FSCREENINFO, &finfo)) { fprintf(stderr, "fail to get framebuffer device fixed information!\n"); close_fb(); return -EIO; } // Get variable screen information if (ioctl(fb_fd, FBIOGET_VSCREENINFO, &vinfo)) { fprintf(stderr, "fail to get variable information!\n"); close_fb(); return -EIO; } fprintf(stdout, "w:%4d, h:%4d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel ); fb_xres = vinfo.xres; fb_yres = vinfo.yres; fb_bpp = vinfo.bits_per_pixel; fb_buf_size = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8; fb_buf = (char *)mmap(0, fb_buf_size, PROT_READ | PROT_WRITE, MAP_SHARED, fb_fd, 0); if ((int)fb_buf==-1) { fprintf(stderr, "fail to map framebuffer device!\n"); fb_buf = NULL; close_fb(); return -ENOMEM; } for(i=0; i<vinfo.yres; i++) fb_line[i] = fb_buf + i * vinfo.xres * vinfo.bits_per_pixel / 8;// printf("fb base %08x\n", fb_line[0]); fill_screen(0); return fb_fd;}static int close_fb(void){ if(fb_fd>=0) { if(fb_buf!=NULL) munmap(fb_buf, fb_buf_size); fb_buf = NULL; close(fb_fd); fb_fd = -1; } return 0;}/*************************************************************/#ifdef MAIN_TEST#if 1static int change_window(int win_fmt, cam_window_t *win){ if(camera_get_window(win_fmt, win)) return 0; fprintf(stdout, "set window format %d:\n", win_fmt); fprintf(stdout, "x0=%d, y0=%d, x1=%d, y1=%d, real width=%d, height=%d\n", win->x0, win->y0, win->x1, win->y1, win->width, win->height); fill_screen(0x001f); return win->width<=fb_xres && win->height<=fb_yres;}int main(int argc, char *argv[]){ int rdfd; fd_set rfds; cam_window_t cam_win; struct timeval tv; struct termios tio; int c_lflag; int show, cnt, win_fmt; if(open_fb()<0) { return -1; } rdfd = camera_open(S3C2440A); if(rdfd<0) { close_fb(); return -1; } //puts("press enter to start...\n"); //getchar(); if(tcgetattr(0, &tio)<0) { fprintf(stderr, "tcgetattr fail!\n"); goto fail; } else { c_lflag = tio.c_lflag; tio.c_lflag &= ~(ICANON | ECHO); if(tcsetattr(0, TCSAFLUSH, &tio)<0) { fprintf(stderr, "tcsetattr fail!\n"); goto fail; } }/* // user defined window cam_win.x0 = 40; cam_win.y0 = 72; cam_win.x1 = 680; cam_win.y1 = 552; cam_win.x_ratio = 2; cam_win.y_ratio = 2; camera_set_window(&cam_win);*/ win_fmt = SUBWIN_M; if(argc>1) win_fmt = atoi(argv[1]); show = change_window(win_fmt, &cam_win); cnt = 0; fprintf(stdout, "now start capture...\n"); fprintf(stdout, "press Esc key to exit, 'c' to save picture, '+'/'-' to switch window\n"); FD_ZERO(&rfds); //FD_SET(0, &rfds); //FD_SET(rdfd, &rfds); camera_start(CAMERA_VIDEO); //video while(1) { if(camera_capture()<0) break; //FD_ZERO(&rfds); FD_SET(0, &rfds); FD_SET(rdfd, &rfds); tv.tv_sec = 3; tv.tv_usec = 0; select(rdfd+1, &rfds, NULL, NULL, &tv); if(FD_ISSET(0, &rfds)) { char cmd; //fprintf(stdout, "stdin input\n"); if(read(0, &cmd, 1)<0) { fprintf(stderr, "read stdin fail!\n"); break; } //fprintf(stdout, "0x%4x\n", cmd); if(cmd=='+') { win_fmt++; if(win_fmt>WINDOW_INDEX_LAST) win_fmt = 0; show = change_window(win_fmt, &cam_win); } else if(cmd=='-') { win_fmt--; if(win_fmt<0) win_fmt = WINDOW_INDEX_LAST; show = change_window(win_fmt, &cam_win); } else if(cmd=='i'||cmd=='I') { } else if(cmd=='j'||cmd=='J') { if(win_fmt==SUBWIN_USER) { camera_get_window(SUBWIN_USER, &cam_win); if(cam_win.x0>=2){ cam_win.x0 -= 2; cam_win.x1 -= 2; camera_set_window(&cam_win); show = change_window(win_fmt, &cam_win); } } } else if(cmd=='k'||cmd=='K') { } else if(cmd=='l'||cmd=='L') { if(win_fmt==SUBWIN_USER) { camera_get_window(SUBWIN_USER, &cam_win); if(cam_win.x1<=718){ cam_win.x0 += 2; cam_win.x1 += 2; camera_set_window(&cam_win); show = change_window(win_fmt, &cam_win); } } } else if(cmd=='d'||cmd=='D') { // show = !show; // fprintf(stdout, "%s display\n", show?"enable":"disable"); } else if(cmd=='c'||cmd=='C') { fprintf(stdout, "save picture...\n"); if(camera_save_picture(win_fmt, "image.jpg", 75)<0) fprintf(stdout, "fail!\n"); } else if(cmd==0x1b) //Esc break; } else if(FD_ISSET(rdfd, &rfds)) { //fprintf(stdout, "camera input\n"); if(show) { if(camera_output_lines(fb_line, win_fmt, &cam_win)<0) break; cnt++; } } else { fprintf(stdout, "wait timeout, break...\n"); break; } } camera_stop(); tio.c_lflag = c_lflag; tcsetattr(0, TCSAFLUSH, &tio);fail: camera_close(); close_fb(); return 0;}#elseint main(int argc, char *argv[]){ int ch, w, h, m; if(capture_img_init()<0) { puts("innitialize camera fail!"); return -1; } m = WINDOW_SCALE2; while(1) { puts("Press Esc to exit, 'm' to switch window mode, 'c' to capture image..."); ch = getchar(); if(ch==0x1b) { puts("exit..."); break; } if(ch=='c'||ch=='C') { if(capture_img_bymode(m, &w, &h)) { puts("save picture fail!"); break; } printf("get image w:%d, h:%d.\n", w, h); } else if(ch=='m'||ch=='M') { if(m==WINDOW_SCALE2) m = WINDOW_FULL; else m = WINDOW_SCALE2; printf("switch to %s window mode.\n", (m==SUBWIN_M)?"small":"large"); } } capture_img_destroy(); return 0;}#endif#endif /* MAIN_TEST */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -