/*
compile with:
mex cvReadImage.cpp -I"C:\Program Files\OpenCV-2.2.0\release64\include" -I"C:\Program Files\OpenCV-2.2.0\release64\include\opencv" -L"C:\Program Files\OpenCV-2.2.0\release64\bin" -L"C:\Program Files\OpenCV-2.2.0\release64\lib" -lopencv_core220d -lopencv_highgui220d -lopencv_video220d -lopencv_ml220d -lopencv_legacy220d -lopencv_imgproc220d
*/

////////////////////////////////////////////////////////////////////////
//
//cvReadImage.cpp
//
// This is a simple, introductory OpenCV program. The program reads an
// image from a file and returns it to Matlab
//
////////////////////////////////////////////////////////////////////////
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>

#include "mex.h"

//using namespace cv;

void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]){

if (nrhs < 1)
{
mexErrMsgTxt("At least one input required.");
}
if (nlhs > 1)
{
mexErrMsgTxt("Too many output arguments");
}

IplImage* img = 0;

//passing strings in mex isn't so easy....
/* Input must be a string. */
if (mxIsChar(prhs[0]) != 1)
	mexErrMsgTxt("Input must be a string.");
int buflen = (mxGetM(prhs[0]) * mxGetN(prhs[0])) + 1;
char *name = (char*) mxCalloc(buflen, sizeof(char));
int status = mxGetString(prhs[0], name, buflen);
if (status != 0) 
    mexWarnMsgTxt("Not enough space. String is truncated.");

//if the second input is present, is the flag of cvLoadImage: 0=grayscale, anything else rgb
int flagRGB = 0;//if not specified: grayscale
if(nrhs>=2)
	//flagRGB = 0;
//else
{
	if (!mxIsNumeric(prhs[1]))
		mexErrMsgTxt("Second parameter must be a number.");
	flagRGB = (int) *mxGetPr(prhs[1]);
}
	
int height,width,step,channels;
uchar *data;
int i,j,k;
uchar* out_ptr;

//check if the image file exists:
FILE* f = fopen(name, "r");
if(f==NULL)
	mexErrMsgTxt("Requested image does not exists or you do not have permissions to read it.");

// load an image
img=cvLoadImage(name,flagRGB);
if(!img){
	printf("Could not load image file: %s\n",name);
	exit(0);
}
// get the image data
height    = img->height;
width     = img->width;
step      = img->widthStep;
channels  = img->nChannels;
data      = (uchar *)img->imageData;

int dims[3] = {height, width, channels};
plhs[0] = mxCreateNumericArray(3, dims, mxUINT8_CLASS, mxREAL);
out_ptr = (uchar*) mxGetPr(plhs[0]);
//for(i=0;i<height;i++) for(j=0;j<width;j++) for(k=0;k<channels;k++)
for(i=0;i<height;i++)
{
	for(j=0;j<width;j++)
		for(k=0;k<channels;k++)
		{
		//note: j*height+i is needed because matlab store data in cols then rows
		//and (channels-k-1) because matlab stores in BGR
		out_ptr[j*height+i+(channels-k-1)*(height*width)]=(uchar) data[i*step+j*channels+k];
		}
	//printf("\n");
}
//justWork(img);
// release the image
cvReleaseImage(&img );
return;
}