/*
 *  IVCCLIB: Intel Video Capture Card Library
 *  by Jeff Norris, jnorris@alum.mit.edu
 *  
 *  File: m_observer.c
 *
 *  Description: This file is compiled with ivcc_m_observer.c into 
 *  m_observer.mexlx.  attachgrabber.m calls this function to begin
 *  the grabbing process.  This file is extremely similar to a typical 
 *  IVCCLIB C observer-- it simply takes the image and passes it into
 *  Matlab instead of processing it here.  As greater performance is
 *  desired, functionality implemented in matlab can be gradually moved
 *  into the gotframe function in this file.
 *
 */


#define COFFSET (NUM_ROWS/2)*(NUM_COLS/2)
#include <math.h>
#include <mex.h>
#include <sys/signal.h>
#include "grabber.h"
#include "m_ivccsetup.h"

/* Needed for interface with Matlab */
mxArray *rhs[1];
mxArray *lhs[1];

/* Name of the function in Matlab to pass the images to */
char cbname[20];

/* This is the callback, it is called each time a new frame
   is captured.  It passes the image into matlab after arranging
   it so that it is in the right format. */
void gotframe(int signum, char* mmbuf)
{  
  long row,col, destinc;
  unsigned char* dest;
  double *ret;
  
  if (quit != 0)
    return;
  
  dest = (unsigned char*)mxGetPr(rhs[0]);
  /* copy the data into place-- copy every other row and every
     other column to downsample to 320x240.  Also swap the byte
     order so that it's RGB */
  destinc = 0;
  for (row = 0; row < NUM_ROWS*NUM_COLS*4; row += 2*NUM_COLS*4)
    {
      for (col = 0; col<NUM_COLS*4; col+=8)
	{
	  dest[destinc            ] = mmbuf[row+col+2];
	  dest[destinc + COFFSET  ] = mmbuf[row+col+1];
	  dest[destinc + 2*COFFSET] = mmbuf[row+col];
	  destinc++;
	}
    }

  /* Send the image into matlab */
  mexCallMATLAB(1, lhs, 1, rhs, cbname);
  /*  If you want to return a value from Matlab, uncomment the
      following code 
  */
  /* 
     ret = mxGetPr(lhs[0]);
  */
  return;
}

/* This is the function that is called from Matlab to start the
   capturing process.  
*/
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
{ 
  int dim[3] = {NUM_COLS/2, NUM_ROWS/2,3};
  int pid, *gnum, len;
  double *temp;
  quit =0;

  if (nrhs != 2)
    {
      mexPrintf("USAGE:\n\nattachgrabber grabbernum callbackname\n");
      return;
    }
  temp = mxGetData(prhs[0]);
  *gnum = (int)(*temp);
  len = mxGetN(prhs[1]);
  mxGetString(prhs[1], cbname, len+1);
  
  rhs[0] = mxCreateNumericArray(3, dim, mxUINT8_CLASS, mxREAL);
  
  /* set up observer */
  observersetup();
  attachgrabber(*gnum, &gotframe);
  printf("Grabber #%d supplying images to callback %s.\n", *gnum, cbname);
  
  /* Just stay in this loop and process frame arrival signals */
  while (quit==0)
    pause();

  return;
}


