Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- // TCap v0.1
- // (C) Thomas Hargrove
- // http://toonarchive.com/tcap
- /***************************************************************************
- * *
- * This program is free software; you can redistribute it and/or modify *
- * it under the terms of the GNU General Public License as published by *
- * the Free Software Foundation; either version 2 of the License, or *
- * (at your option) any later version. *
- * *
- ***************************************************************************/
- // SDL and bluescreen by Kevin
- #include <unistd.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <sys/ioctl.h>
- #include <sys/mman.h>
- #include <errno.h>
- #include <libv4l1-videodev.h>
- #include "record.h"
- #include <SDL.h>
- #include <png.h>
- #include <SDL/SDL_image.h>
- static struct video_capability capability;
- static int fd = -1;
- static struct video_mbuf gb_buffers = { 2*WIDTH*HEIGHT*3, 0, {0,WIDTH*HEIGHT*3 }};
- static char *map = NULL;
- static struct video_mmap my_buf;
- struct video_channel vch;
- //#define WIDTH 960
- //#define HEIGHT 720
- #define p(x) printf("%s",x);
- static char *map;
- #define OUTFILE "screenshot-"
- SDL_Surface *screen;
- SDL_Surface *offscreen;
- SDL_Event event;
- /* Copies map to screen, then updates the screen */
- void copytoscreen(char* tmap, int startRecord, int count) {
- offscreen = SDL_CreateRGBSurfaceFrom((void *) tmap, WIDTH, HEIGHT, 24, WIDTH*3, 0x0000FF, 0x00FF00, 0xFF0000, 0x000000);
- if ( startRecord )
- {
- char temp[10];
- char outfileCur[32768];
- sprintf(temp, "%d", count);
- strcpy(outfileCur,OUTFILE);
- strcat(outfileCur,temp);
- strcat(outfileCur,".png");
- if( png_save_surface(outfileCur, offscreen) < 0 ) exit(-1);
- }
- SDL_BlitSurface(offscreen, NULL, screen, NULL);
- SDL_UpdateRect(screen, 0, 0, 0, 0);
- SDL_FreeSurface(offscreen);
- }
- int main(int argc, char *argv[])
- {
- char my_video_dev[100] = "/dev/video0";
- // --------------------------------------------------------------------------
- // Get the v4l capture set up
- // --------------------------------------------------------------------------
- if (-1 == (fd = open(my_video_dev, O_RDWR))) {
- printf("Error opening device: %s\n", my_video_dev);
- return(-1);
- }
- if (-1 == ioctl(fd,VIDIOCGCAP,&capability)) {
- printf("Error: ioctl(fd,VIDIOCGCAP,&capability)\n");
- return(-2);
- }
- vch.channel = 0;
- vch.norm = VIDEO_MODE_PAL;
- if(-1 == ioctl(fd, VIDIOCSCHAN,&vch)) {
- perror("Setting channel\n");
- return(-3);
- }
- fcntl(fd,F_SETFD,FD_CLOEXEC);
- if (-1 == ioctl(fd,VIDIOCGMBUF,&gb_buffers)) {
- printf("Error: Error getting buffers\n");
- return(-4);
- }
- map = mmap(0,gb_buffers.size,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
- if (map == NULL) {
- printf("Error: Mmap returned NULL\n");
- return(-5);
- }
- // Set up out capture to use the correct resolution
- my_buf.width = WIDTH;
- my_buf.height = HEIGHT;
- my_buf.format = VIDEO_PALETTE_RGB24;
- // Tell the capture card to fill frame 0
- my_buf.frame = 0;
- if (-1 == ioctl(fd, VIDIOCMCAPTURE, &my_buf)) {
- printf("Error: Grabber chip can't sync (no station tuned in?)\n");
- return(-6);
- }
- int done = 0;
- // --------------------------------------------------------------------------
- // Set up out video output
- // --------------------------------------------------------------------------
- SDL_Init(SDL_INIT_VIDEO);
- screen = SDL_SetVideoMode(WIDTH, HEIGHT, 16, SDL_SWSURFACE);
- if ( screen == NULL ) {
- printf(stderr, "Couldn't set 640x480x8 video mode: %s\n",
- SDL_GetError());
- exit(1);
- }
- SDL_WM_SetCaption("", NULL);
- char *background;
- int subtract=0;
- int capBackground=0;
- int haveBackground=0;
- int startRecord=0;
- int x,y,z,d;
- int frame=0;
- background=malloc((WIDTH*HEIGHT*3)*FRAMES);
- while ( ! done ) {
- while (SDL_PollEvent(&event))
- {
- switch(event.type)
- {
- case SDL_KEYDOWN:
- switch( event.key.keysym.sym ){
- case SDLK_ESCAPE: done =1; break;
- case SDLK_b: capBackground=1; break;
- case SDLK_s:
- subtract=!subtract;
- break;
- case SDLK_r:
- startRecord=!startRecord;
- break;
- default:
- break;
- }
- break;
- case SDL_QUIT: done = 1; break;
- }
- }
- my_buf.frame = 1;
- if (-1 == ioctl(fd, VIDIOCMCAPTURE, &my_buf)) {
- printf("Error: Grabber chip can't sync (no station tuned in?)\n");
- done=1;
- }
- copytoscreen(map,0,0);
- my_buf.frame = 0;
- if (-1 == ioctl(fd, VIDIOCSYNC, &my_buf.frame)) {
- printf("Error on sync!\n");
- done=1;
- }
- if ( capBackground )
- {
- printf("Capturing background\n");
- while ( capBackground < FRAMES+1 )
- {
- my_buf.frame = 1;
- if (-1 == ioctl(fd, VIDIOCMCAPTURE, &my_buf)) {
- printf("Error: Grabber chip can't sync (no station tuned in?)\n");
- done=1;
- }
- my_buf.frame = 0;
- if (-1 == ioctl(fd, VIDIOCSYNC, &my_buf.frame)) {
- printf("Error on sync!\n");
- done=1;
- }
- memcpy(background+((capBackground-1)*WIDTH*HEIGHT*3),map,WIDTH*HEIGHT*3);
- capBackground++;
- }
- haveBackground=1;
- capBackground=0;
- }
- if ( ( subtract ) && ( haveBackground ) )
- {
- //printf("Subtracting background\n");
- for(x=0; x<WIDTH*HEIGHT*3*FRAMES; x=x+3)
- {
- if (( (int)background[x] > (int)map[x%(WIDTH*HEIGHT*3)]-VARIATION/2 ) && ( (int)background[x] < (int)map[x%(WIDTH*HEIGHT*3)]+VARIATION/2 ))
- {
- if (( (int)background[x+1] > (int)map[(x+1)%(WIDTH*HEIGHT*3)]-VARIATION/2 ) && ( (int)background[x+1] < (int)map[(x+1)%(WIDTH*HEIGHT*3)]+VARIATION/2 ))
- {
- if (( (int)background[x+2] > (int)map[(x+2)%(WIDTH*HEIGHT*3)]-VARIATION/2 ) && ( (int)background[x+2] < (int)map[(x+2)%(WIDTH*HEIGHT*3)]+VARIATION/2 ))
- {
- map[(x)%(WIDTH*HEIGHT*3)] = (char)0;
- map[(x+1)%(WIDTH*HEIGHT*3)] = (char)0;
- map[(x+2)%(WIDTH*HEIGHT*3)] = (char)255;
- }
- }
- }
- }
- }
- if (startRecord )
- {
- frame++;
- }
- copytoscreen(map,startRecord,frame);
- }
- SDL_Quit();
- return EXIT_SUCCESS;
- }
- static int png_colortype_from_surface(SDL_Surface *surface)
- {
- int colortype = PNG_COLOR_MASK_COLOR; /* grayscale not supported */
- if (surface->format->palette)
- colortype |= PNG_COLOR_MASK_PALETTE;
- else if (surface->format->Amask)
- colortype |= PNG_COLOR_MASK_ALPHA;
- return colortype;
- }
- void png_user_warn(png_structp ctx, png_const_charp str)
- {
- fprintf(stderr, "libpng: warning: %s\n", str);
- }
- void png_user_error(png_structp ctx, png_const_charp str)
- {
- fprintf(stderr, "libpng: error: %s\n", str);
- }
- int png_save_surface(char *filename, SDL_Surface *surf)
- {
- FILE *fp;
- png_structp png_ptr;
- png_infop info_ptr;
- int i, colortype;
- png_bytep *row_pointers;
- /* Opening output file */
- fp = fopen(filename, "wb");
- if (fp == NULL) {
- perror("fopen error");
- return -1;
- }
- /* Initializing png structures and callbacks */
- png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
- NULL, png_user_error, png_user_warn);
- if (png_ptr == NULL) {
- printf("png_create_write_struct error!\n");
- return -1;
- }
- info_ptr = png_create_info_struct(png_ptr);
- if (info_ptr == NULL) {
- png_destroy_write_struct(&png_ptr, (png_infopp)NULL);
- printf("png_create_info_struct error!\n");
- exit(-1);
- }
- if (setjmp(png_jmpbuf(png_ptr))) {
- png_destroy_write_struct(&png_ptr, &info_ptr);
- fclose(fp);
- exit(-1);
- }
- png_init_io(png_ptr, fp);
- colortype = png_colortype_from_surface(surf);
- png_set_IHDR(png_ptr, info_ptr, surf->w, surf->h, 8, colortype, PNG_INTERLACE_NONE,
- PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
- /* Writing the image */
- png_write_info(png_ptr, info_ptr);
- png_set_packing(png_ptr);
- row_pointers = (png_bytep*) malloc(sizeof(png_bytep)*surf->h);
- for (i = 0; i < surf->h; i++)
- row_pointers[i] = (png_bytep)(Uint8 *)surf->pixels + i*surf->pitch;
- png_write_image(png_ptr, row_pointers);
- png_write_end(png_ptr, info_ptr);
- /* Cleaning out... */
- free(row_pointers);
- png_destroy_write_struct(&png_ptr, &info_ptr);
- fclose(fp);
- return 0;
- }
Add Comment
Please, Sign In to add comment