#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/mman.h>

#include <linux/videodev.h>

#define ROWS  480
#define COLS  640
#define V4L_DEVICE "/dev/video0"


void capture(int bttvfd, struct video_mmap *mm)
{
  if(ioctl(bttvfd, VIDIOCMCAPTURE, mm) < 0)
    {
      perror("VIDIOCMCAPTURE");
      exit(-1);
    }
}

void sync(int bttvfd, struct video_mmap *mm)
{
  if(ioctl(bttvfd, VIDIOCSYNC, &(mm->frame)) < 0)
    {
      perror("VIDIOCSYNC");
      exit(-1);
    }
}


main()
{
  unsigned char *buf;
  int fd, i=0, j=0;
  struct video_channel vc;
  struct video_mmap mm;
  struct video_mbuf mbuf;

  FILE *pictureFile;

  /* open video device */
  fd=open(V4L_DEVICE, O_RDWR);
  if (fd <= 0)
    {
      perror("open");
      exit(-1);
    }
  
  /* get buffer information */
  if(ioctl(fd, VIDIOCGMBUF, &mbuf) < 0)
    {
      perror("VIDIOCMCAPTURE");
      exit(-1);
    }
 
  /* map buffers */
  buf = 
    mmap(0, mbuf.size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);


  if ((int)buf < 0)
    {
      perror("mmap");
      exit(-1);
    }

  /* set chanels */
  vc.channel=1;
  vc.norm=1;

  if(ioctl(fd, VIDIOCSCHAN, &vc) < 0)
    {
      perror("VIDIOCSCHAN");
      exit(-1);
    }
    
  /* set grab parameters */
  mm.frame  = 0;
  mm.height = ROWS;
  mm.width  = COLS;
  mm.format = VIDEO_PALETTE_RGB24;


  /* Capture a picture */
  printf("Write c and press return, to take the photograph\n");
  while(getchar() != 'c') {
    ;
  }

  capture(fd, &mm);
  sync(fd, &mm); 

  pictureFile = fopen("picture.bmp", "w");
  if(pictureFile == NULL) {
    printf("Couldn't open the picture-file");
    exit(0);
  }
  
  
  fprintf(pictureFile,"P6\n %d %d\n 255\n",COLS,ROWS);

  for(i=0;i<ROWS;i++)
    for(j=0;j<COLS;j++){
      fwrite(buf + (i * COLS + j)*3+2, 1, 1, pictureFile);
      fwrite(buf + (i * COLS + j)*3+1, 1, 1, pictureFile);
      fwrite(buf + (i * COLS + j)*3  , 1, 1, pictureFile);
    }
 
  close(pictureFile);
  munmap(buf, mbuf.size);
  close(fd);

}






