Exemplo n.º 1
0
void mxSetImagData(mxArray *array_ptr, void *data_ptr)
{
    if (mxIsChar(array_ptr))
    {
        ((types::String *)array_ptr)->setImg((wchar_t **)data_ptr);
    }
    else if (mxIsDouble(array_ptr))
    {
        ((types::Double *)array_ptr)->setImg((double *)data_ptr);
    }
    else if (mxIsInt8(array_ptr))
    {
        ((types::Int8 *)array_ptr)->setImg((char *)data_ptr);
    }
    else if (mxIsInt16(array_ptr))
    {
        ((types::Int16 *)array_ptr)->setImg((short *)data_ptr);
    }
    else if (mxIsInt32(array_ptr))
    {
        ((types::Int32 *)array_ptr)->setImg((int *)data_ptr);
    }
    else if (mxIsInt64(array_ptr))
    {
        ((types::Int64 *)array_ptr)->setImg((long long *)data_ptr);
    }
    else if (mxIsLogical(array_ptr))
    {
        ((types::Bool *)array_ptr)->setImg((int *)data_ptr);
    }
    else if (mxIsUint8(array_ptr))
    {
        ((types::UInt8 *)array_ptr)->setImg((unsigned char *)data_ptr);
    }
    else if (mxIsUint16(array_ptr))
    {
        ((types::UInt16 *)array_ptr)->setImg((unsigned short *)data_ptr);
    }
    else if (mxIsUint32(array_ptr))
    {
        ((types::UInt32 *)array_ptr)->setImg((unsigned int *)data_ptr);
    }
    else if (mxIsUint64(array_ptr))
    {
        ((types::UInt64 *)array_ptr)->setImg((unsigned long long *) data_ptr);
    }
}
Exemplo n.º 2
0
static void get_map_dat(int i, const mxArray *ptr, MAPTYPE *maps)
{
    mxArray *tmp;
    double *pr;
    int num_dims, j, t, dtype = 0;
    const mwSize *dims;
    unsigned char *dptr;

    tmp=mxGetField(ptr,i,"dat");
    if (tmp == (mxArray *)0)
    {
        free_maps(maps,i);
        mexErrMsgTxt("Cant find dat.");
    }
    if      (mxIsDouble(tmp)) dtype = SPM_DOUBLE;
    else if (mxIsSingle(tmp)) dtype = SPM_FLOAT;
    else if (mxIsInt32 (tmp)) dtype = SPM_SIGNED_INT;
    else if (mxIsUint32(tmp)) dtype = SPM_UNSIGNED_INT;
    else if (mxIsInt16 (tmp)) dtype = SPM_SIGNED_SHORT;
    else if (mxIsUint16(tmp)) dtype = SPM_UNSIGNED_SHORT;
    else if (mxIsInt8  (tmp)) dtype = SPM_SIGNED_CHAR;
    else if (mxIsUint8 (tmp)) dtype = SPM_UNSIGNED_CHAR;
    else
    {
        free_maps(maps,i);
        mexErrMsgTxt("Unknown volume datatype.");
    }
    dptr  = (unsigned char *)mxGetPr(tmp);

    num_dims = mxGetNumberOfDimensions(tmp);
    if (num_dims > 3)
    {
        free_maps(maps,i);
        mexErrMsgTxt("Too many dimensions.");
    }
    dims     = mxGetDimensions(tmp);
    for(j=0; j<num_dims; j++)
        maps[i].dim[j]=dims[j];
    for(j=num_dims; j<3; j++)
        maps[i].dim[j]=1;
    tmp=mxGetField(ptr,i,"dim");
    if (tmp != (mxArray *)0)
    {
        if (mxGetM(tmp)*mxGetN(tmp) != 3)
        {
            free_maps(maps,i);
            mexErrMsgTxt("Wrong sized dim.");
        }
        pr = mxGetPr(tmp);
        if (maps[i].dim[0] != (mwSize)fabs(pr[0]) ||
            maps[i].dim[1] != (mwSize)fabs(pr[1]) ||
            maps[i].dim[2] != (mwSize)fabs(pr[2]))
        {
            free_maps(maps,i);
            mexErrMsgTxt("Incompatible volume dimensions in dim.");
        }
    }
    tmp=mxGetField(ptr,i,"dt");
    if (tmp != (mxArray *)0)
    {
        if (mxGetM(tmp)*mxGetN(tmp) != 1 && mxGetM(tmp)*mxGetN(tmp) != 2)
        {
            free_maps(maps,i);
            mexErrMsgTxt("Wrong sized dt.");
        }
        pr = mxGetPr(tmp);
        if (dtype != (int)fabs(pr[0]))
        {
            free_maps(maps,i);
            mexErrMsgTxt("Incompatible datatype in dt.");
        }
    }

    maps[i].addr      = 0;
    maps[i].len       = 0;
    maps[i].dtype  = dtype;
    maps[i].data   = (void  **)mxCalloc(maps[i].dim[2],sizeof(void *));
    maps[i].scale  = (double *)mxCalloc(maps[i].dim[2],sizeof(double));
    maps[i].offset = (double *)mxCalloc(maps[i].dim[2],sizeof(double));

    t   = maps[i].dim[0]*maps[i].dim[1]*get_datasize(maps[i].dtype)/8;
    tmp = mxGetField(ptr,i,"pinfo");
    if (tmp != (mxArray *)0)
    {
        if ((mxGetM(tmp) != 2 && mxGetM(tmp) != 3) || (mxGetN(tmp) != 1 && mxGetN(tmp) != maps[i].dim[2]))
        {
            free_maps(maps,i+1);
            mexErrMsgTxt("Wrong sized pinfo.");
        }
        if (mxGetM(tmp) == 3 && mxGetPr(tmp)[2] != 0)
        {
            free_maps(maps,i+1);
            mexErrMsgTxt("pinfo(3) must equal 0 to read dat field.");
        }
        pr = mxGetPr(tmp);
        if (mxGetN(tmp) == 1)
            for(j=0; j<maps[i].dim[2]; j++)
            {
                maps[i].scale[j]  = pr[0];
                maps[i].offset[j] = pr[1];
                maps[i].data[j]   = &(dptr[j*t]);
            }
        else
            for(j=0; j<maps[i].dim[2]; j++)
            {
                maps[i].scale[j]  = pr[0+j*2];
                maps[i].offset[j] = pr[1+j*2];
                maps[i].data[j]   = &(dptr[j*t]);
            }
    }
    else
        for(j=0; j<maps[i].dim[2]; j++)
        {
            maps[i].scale[j]  = 1.0;
            maps[i].offset[j] = 0.0;
            maps[i].data[j]   = &(dptr[j*t]);
        }
    tmp=mxGetField(ptr,i,"mat");
    if (tmp != (mxArray *)0)
    {
        if (mxGetM(tmp) != 4 || mxGetN(tmp) != 4)
        {
            free_maps(maps,i+1);
            mexErrMsgTxt("Wrong sized mat.");
        }
        pr = mxGetPr(tmp);
        for(j=0; j<16; j++)
            maps[i].mat[j] = pr[j];
    }
    else
    {
        for(j=0; j<16; j++)
            maps[i].mat[j] = 0.0;
        for(j=0; j<4; j++)
            maps[i].mat[j + j*4] = 1.0;
    }
}
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[]
                )
{
	/* Declare */
	int *dl_ch_estimates_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*dl_ch_estimates_ext_i[NB_ANTENNAS_RX*NB_ANTENNAS_TX],*Heff0,*Heff1,*rho10,*rho10_out,*dl_ch_rho_ext[NB_ANTENNAS_RX*NB_ANTENNAS_TX];	
	unsigned int nb_re_per_symbol, nb_re_per_frame;
	unsigned char output_shift, symbol;		
	LTE_DL_FRAME_PARMS *frame_parms;	
	mxArray *tmp;
	
	/* Check proper input and output. */
	if(nrhs!=4)
		mexErrMsgTxt("4 inputs required.");
	else if(nlhs > 1)
		mexErrMsgTxt("Too many output arguments.");
	else if(!mxIsStruct(prhs[2]))
		mexErrMsgTxt("Third input must be a structure.");
		
	if(!mxIsInt16(prhs[0]))
		mexErrMsgTxt("First argument must belong to Int16 class.");
	
	if(!mxIsInt16(prhs[1]))
		mexErrMsgTxt("Second argument must belong to Int16 class.");
			
	/* Allocate input */	
	Heff0 = (int*) mxGetData(prhs[0]);
	Heff1 = (int*) mxGetData(prhs[1]);	
	symbol = (unsigned char) mxGetScalar(prhs[3]);
				
	tmp = mxGetField(prhs[2],0,"log2_maxh");
	if (tmp == NULL) {
		mexErrMsgTxt("Non-existing field 'log2_maxh' in input argument 3.");
	} else {
		output_shift = (unsigned char) mxGetScalar(tmp);
	}
	tmp = mxGetField(prhs[2],0,"nb_re_per_frame");
	if (tmp == NULL) {
		mexErrMsgTxt("Non-existing field 'nb_re_per_frame' in input argument 3.");
	} else {
		nb_re_per_frame = (unsigned int) mxGetScalar(tmp);
	}    
			
	// Create a LTE_DL_FRAME_PARMS structure and assign required params
	frame_parms = calloc(1,sizeof(LTE_DL_FRAME_PARMS));
	tmp = mxGetField(prhs[2],0,"nb_rb");
	if (tmp == NULL) {
		mexErrMsgTxt("Non-existing field 'nb_rb' in input argument 3.");
	} else {
		frame_parms->N_RB_DL = (unsigned char) mxGetScalar(tmp);
	}
	tmp = mxGetField(prhs[2],0,"nb_antennas_rx");
	if (tmp == NULL) {
		mexErrMsgTxt("Non-existing field 'nb_antennas_rx' in input argument 3.");
	} else {
		frame_parms->nb_antennas_rx = (unsigned char) mxGetScalar(tmp);
	}
	tmp = mxGetField(prhs[2],0,"Ncp");
	if (tmp == NULL) {
		mexErrMsgTxt("Non-existing field 'Ncp' in input argument 3.");
	} else {
		frame_parms->Ncp = (unsigned char) mxGetScalar(tmp);
	}
			
	nb_re_per_symbol = frame_parms->N_RB_DL*12;		
				
	/* Allocate Output */
	plhs[0] = mxCreateNumericMatrix(2*nb_re_per_symbol,NB_ANTENNAS_RX*NB_ANTENNAS_TX, mxINT16_CLASS, mxREAL);	
 	rho10_out = (int*) mxGetPr(plhs[0]);
		
	rho10 = (int*) mxCalloc(nb_re_per_frame*NB_ANTENNAS_RX*NB_ANTENNAS_TX, sizeof(int));
	
	dl_ch_rho_ext[0] = rho10;
	dl_ch_rho_ext[1] = &rho10[nb_re_per_frame];
	dl_ch_rho_ext[2] = &rho10[2*nb_re_per_frame];
    dl_ch_rho_ext[3] = &rho10[3*nb_re_per_frame];
        
    dl_ch_estimates_ext[0] = Heff0;
    dl_ch_estimates_ext[1] = &Heff0[nb_re_per_frame];
    dl_ch_estimates_ext[2] = &Heff0[2*nb_re_per_frame];
    dl_ch_estimates_ext[3] = &Heff0[3*nb_re_per_frame];
    
    dl_ch_estimates_ext_i[0] = Heff1;
    dl_ch_estimates_ext_i[1] = &Heff1[nb_re_per_frame];
    dl_ch_estimates_ext_i[2] = &Heff1[2*nb_re_per_frame];
    dl_ch_estimates_ext_i[3] = &Heff1[3*nb_re_per_frame];

        
    /* Algo */  	
	dlsch_dual_stream_correlation(frame_parms,
			                      symbol,
			                      frame_parms->N_RB_DL,
				                  dl_ch_estimates_ext,
				                  dl_ch_estimates_ext_i,
				                  dl_ch_rho_ext,
				                  output_shift);
		
	
	memcpy(rho10_out,&dl_ch_rho_ext[0][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
	memcpy(&rho10_out[nb_re_per_symbol],&dl_ch_rho_ext[1][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
	memcpy(&rho10_out[2*nb_re_per_symbol],&dl_ch_rho_ext[2][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
	memcpy(&rho10_out[3*nb_re_per_symbol],&dl_ch_rho_ext[3][symbol*frame_parms->N_RB_DL*12],nb_re_per_symbol<<2);
	
	/* free */
	free(frame_parms);
	mxFree(rho10);
}
Exemplo n.º 4
0
//-------------------------------------------------------------------
void mexFunction(int POutputCount,  mxArray* POutput[], int PInputCount, const mxArray *PInputs[])
{
    	const int	*SZ;	    
    	double* 	LInput;
    	double* 	LInputI;
    	double* 	LOutputSum;
    	double* 	LOutputSumI;
    	double* 	LOutputCount;
    	double* 	LOutputSum2;
    	double* 	LOutputSum4;
    	double  	x, x2;
    	unsigned long   LCount, LCountI;
    	double  	LSum, LSum2, LSum4;

    	unsigned	DIM = 0; 
    	unsigned long	D1, D2, D3; 	// NN; 	//  	
    	unsigned    	ND, ND2;	// number of dimensions: input, output
    	unsigned long	ix1, ix2;	// index to input and output
    	unsigned    	j, k, l;	// running indices 
    	int 		*SZ2;		// size of output 	    


	// check for proper number of input and output arguments
	if ((PInputCount <= 0) || (PInputCount > 2))
	        mexErrMsgTxt("SumSkipNan.MEX requires 1 or 2 arguments.");
	if (POutputCount > 4)
	        mexErrMsgTxt("SumSkipNan.MEX has 1 to 4 output arguments.");

	// get 1st argument
	if(mxIsDouble(PInputs[0]))
		LInput  = mxGetPr(PInputs[0]);
	else 	
		mexErrMsgTxt("First argument must be DOUBLE.");

	if(mxIsLogical(PInputs[0]))
		LInput  = (double*)mxGetLogicals(PInputs[0]);
	else if(mxIsNumeric(PInputs[0]))
		LInput  = mxGetPr(PInputs[0]);
	else if(mxIsSparse(PInputs[0]))
		LInput  = mxGetPr(PInputs[0]);
	else if(mxIsInt8(PInputs[0]))
		LInput  = (double *)mxGetData(PInputs[0]);
	else if(mxIsUint8(PInputs[0]))
		LInput  = (double *)mxGetData(PInputs[0]);
	else if(mxIsInt16(PInputs[0]))
		LInput  = (double *)mxGetData(PInputs[0]);
	else if(mxIsUint16(PInputs[0]))
		LInput  = (double *)mxGetData(PInputs[0]);
	else if(mxIsInt32(PInputs[0]))
		LInput  = (double *)mxGetData(PInputs[0]);
	else if(mxIsUint32(PInputs[0]))
		LInput  = (double *)mxGetData(PInputs[0]);
	else
		mexErrMsgTxt("First argument must be NUMERIC.");

	if(mxIsComplex(PInputs[0]))
		LInputI = mxGetPi(PInputs[0]);
	if(mxIsComplex(PInputs[0]) & (POutputCount > 3))
	        mexErrMsgTxt("More than 3 output arguments only supported for REAL data ");

    	// get 2nd argument
    	if  (PInputCount == 2){
 	       	switch (mxGetNumberOfElements(PInputs[1])) {
		case 0: x = 0.0; 		// accept empty element
			break;
		case 1: x = (mxIsNumeric(PInputs[1]) ? mxGetScalar(PInputs[1]) : -1.0); 
			break;
		default:x = -1.0;		// invalid 
		}
		if ((x < 0) || (x > 65535) || (x != floor(x))) 
			mexErrMsgTxt("Error SUMSKIPNAN.MEX: DIM-argument must be a positive integer scalar");

		DIM = (unsigned)floor(x);	
	}

	// get size 
    	ND = mxGetNumberOfDimensions(PInputs[0]);	
    	// NN = mxGetNumberOfElements(PInputs[0]);
    	SZ = mxGetDimensions(PInputs[0]);		

	// if DIM==0 (undefined), look for first dimension with more than 1 element. 
	for (k = 0; (DIM < 1) && (k < ND); k++) 
		if (SZ[k]>1) DIM = k+1;
	
	if (DIM < 1) DIM=1;		// in case DIM is still undefined 

	ND2 = (ND>DIM ? ND : DIM);	// number of dimensions of output 

	SZ2 = (int*)mxCalloc(ND2, sizeof(int)); // allocate memory for output size

	for (j=0; j<ND; j++)		// copy size of input;  
		SZ2[j] = SZ[j]; 	
	for (j=ND; j<ND2; j++)		// in case DIM > ND, add extra elements 1 
		SZ2[j] = 1; 	

    	for (j=0, D1=1; j<DIM-1; D1=D1*SZ2[j++]); 	// D1 is the number of elements between two elements along dimension  DIM  
	D2 = SZ2[DIM-1];		// D2 contains the size along dimension DIM 	
    	for (j=DIM, D3=1;  j<ND; D3=D3*SZ2[j++]); 	// D3 is the number of blocks containing D1*D2 elements 

	SZ2[DIM-1] = 1;		// size of output is same as size of input but SZ(DIM)=1;

	    // create outputs
	#define TYP mxDOUBLE_CLASS

	if(mxIsComplex(PInputs[0]))
	{	POutput[0] = mxCreateNumericArray(ND2, SZ2, TYP, mxCOMPLEX);
		LOutputSum = mxGetPr(POutput[0]);
		LOutputSumI= mxGetPi(POutput[0]);
    	}
	else 
	{	POutput[0] = mxCreateNumericArray(ND2, SZ2, TYP, mxREAL);
		LOutputSum = mxGetPr(POutput[0]);
    	}

    	if (POutputCount >= 2){
		POutput[1] = mxCreateNumericArray(ND2, SZ2, TYP, mxREAL);
        	LOutputCount = mxGetPr(POutput[1]);
    	}
    	if (POutputCount >= 3){
		POutput[2] = mxCreateNumericArray(ND2, SZ2, TYP, mxREAL);
        	LOutputSum2  = mxGetPr(POutput[2]);
    	}
    	if (POutputCount >= 4){
		POutput[3] = mxCreateNumericArray(ND2, SZ2, TYP, mxREAL);
        	LOutputSum4  = mxGetPr(POutput[3]);
    	}

	mxFree(SZ2);

	// OUTER LOOP: along dimensions > DIM
	for (l = 0; l<D3; l++) 	
    	{
		ix2 =   l*D1;	// index for output 
		ix1 = ix2*D2;	// index for input 

		// Inner LOOP: along dimensions < DIM
		for (k = 0; k<D1; k++, ix1++, ix2++) 	
		{
		        LCount = 0;
			LSum   = 0.0;
			LSum2  = 0.0;
			LSum4  = 0.0;
	        	    		
			// LOOP  along dimension DIM
	    		for (j=0; j<D2; j++) 	
			{
				x = LInput[ix1 + j*D1];
        	        	if (!mxIsNaN(x))
				{
					LCount++; 
					LSum += x; 
					x2 = x*x;
					LSum2 += x2; 
					LSum4 += x2*x2; 
				}
			}
			LOutputSum[ix2] = LSum;
            		if (POutputCount >= 2)
                		LOutputCount[ix2] = (double)LCount;
            		if (POutputCount >= 3)
                		LOutputSum2[ix2] = LSum2;
            		if (POutputCount >= 4)
                		LOutputSum4[ix2] = LSum4;

			if(mxIsComplex(PInputs[0]))
			{
				LSum = 0.0;	
	    			LCountI = 0;
				LSum2  = 0.0;
				for (j=0; j<D2; j++) 	
				{
					x = LInputI[ix1 + j*D1];
        	        		if (!mxIsNaN(x))
					{
						LCountI++; 
						LSum  += x; 
						LSum2 += x*x; 
					}
				}
				LOutputSumI[ix2] = LSum;
				if (LCount != LCountI)
			            	mexErrMsgTxt("Number of NaNs is different for REAL and IMAG part");
	            		if (POutputCount >= 3)
        	        		LOutputSum2[ix2] += LSum2;
			}
		}
	}
}
Exemplo n.º 5
0
int isFunctionHandle( const mxArray* const M )
{
	if ( M == NULL )
		return 0;

	if ( mxIsCell(M) )
		return 0;

	if ( mxIsChar(M) )
		return 0;

	if ( mxIsComplex(M) )
		return 0;

	if ( mxIsDouble(M) )
		return 0;

	if ( mxIsEmpty(M) )
		return 0;

	if ( mxIsInt8(M) )
		return 0;

	if ( mxIsInt16(M) )
		return 0;

	if ( mxIsInt32(M) )
		return 0;

	if ( mxIsLogical(M) )
		return 0;

	if ( mxIsLogicalScalar(M) )
		return 0;

	if ( mxIsLogicalScalarTrue(M) )
		return 0;

	if ( mxIsNumeric(M) )
		return 0;

	if ( mxIsSingle(M) )
		return 0;

	if ( mxIsSparse(M) )
		return 0;

	if ( mxIsStruct(M) )
		return 0;

	if ( mxIsUint8(M) )
		return 0;

	if ( mxIsUint16(M) )
		return 0;

	if ( mxIsUint32(M) )
		return 0;

	// assume to be a function handle iff it is nothing else
	return 1;
}
Image Matlab2ViLi(const mxArray *In) {

Image Res;
int Type;
int i, j, k;

if (mxIsUint8(In)) {
      Type = IM_BYTE;
} else if (mxIsInt16(In)) {
      Type = IM_SHORT;
} else if (mxIsUint32(In)) {
      Type = IM_LONG;
} else if (mxIsDouble(In)||mxIsSingle(In)) {
		if (mxIsComplex(In)) {
	   	Type = IM_COMPLEX;
		}
		else {
		   Type = IM_FLOAT;
		}
} else {
      mexErrMsgTxt("Array type not supported");
}
      
if (mxGetNumberOfDimensions(In) == 2) {
      Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], 1, 1, GRID_RECT);
} else if ( (mxGetNumberOfDimensions(In) == 3) && (mxGetDimensions(In)[2] == 3)) {
         Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], 1,  mxGetDimensions(In)[2], GRID_RECT);
} else if ( (mxGetNumberOfDimensions(In) == 3) && (mxGetDimensions(In)[2] != 3)) {
         Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], mxGetDimensions(In)[2], 1, GRID_RECT);
} else if (mxGetNumberOfDimensions(In) == 4) {
         Res = NewImage("from MATLAB", Type, mxGetDimensions(In)[1], mxGetDimensions(In)[0], mxGetDimensions(In)[2], mxGetDimensions(In)[3], GRID_RECT);
} else {
     mexErrMsgTxt("Dimensions not supported");
}

switch(Type) {
      case IM_BYTE:
			{
         unsigned char *pIn, *pRes;
         pRes = (unsigned char *) Res->Data;
         pIn = (unsigned char *) mxGetData(In);
			/* Copia transponiendo filas y columnas */
			for (k=0; k<Res->NPlanes * Res->NChannels; k++) {
				for (j=0; j<Res->NCol; j++) {
					for (i=0; i<Res->NLin; i++) {
						pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] =
							pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
					}
				}
			}
			}
         break;
      case IM_SHORT:
			{
         short *pIn, *pRes;
         pRes = (short *) Res->Data;
         pIn = (short *) mxGetData(In);
			/* Copia transponiendo filas y columnas */
			for (k=0; k<Res->NPlanes * Res->NChannels; k++) {
				for (j=0; j<Res->NCol; j++) {
					for (i=0; i<Res->NLin; i++) {
						pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] =
							pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
					}
				}
			}
			}
         break;
      case IM_LONG:
			{
         unsigned long *pIn, *pRes;
         pRes = (unsigned long *) Res->Data;
         pIn = (unsigned long *) mxGetData(In);
			/* Copia transponiendo filas y columnas */
			for (k=0; k<Res->NPlanes * Res->NChannels; k++) {
				for (j=0; j<Res->NCol; j++) {
					for (i=0; i<Res->NLin; i++) {
						pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] =
							pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
					}
				}
			}
			}
         break;
      case IM_FLOAT:
			{
			float *pRes;
         	pRes = (float *) Res->Data;
         	if (mxIsSingle(In)){
	        	float *pIn;
         		pIn = (float *) mxGetData(In);
				/* Copia transponiendo filas y columnas */
				for (k=0; k<Res->NPlanes * Res->NChannels; k++) {
					for (j=0; j<Res->NCol; j++) {
						for (i=0; i<Res->NLin; i++) {
							pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] =
								(float) pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
						}
					}
				}
			} else {
	        	double *pIn;
         		pIn = (double *) mxGetData(In);
				/* Copia transponiendo filas y columnas */
				for (k=0; k<Res->NPlanes * Res->NChannels; k++) {
					for (j=0; j<Res->NCol; j++) {
						for (i=0; i<Res->NLin; i++) {
							pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin] =
								(float) pIn[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
						}
					}
				}
			}
			}
         break;
		case IM_COMPLEX:
			{
			Complex *pRes;
	        pRes = (Complex *) Res->Data;
           	if (mxIsSingle(In)){
	        	float *pInR, *pInI;
	    	    pInR = mxGetPr(In);
	        	pInI = mxGetPi(In);
	
				/* Copia transponiendo filas y columnas */
				for (k=0; k<Res->NPlanes * Res->NChannels; k++) {
					for (j=0; j<Res->NCol; j++) {
						for (i=0; i<Res->NLin; i++) {
							pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Re =
								(float) pInR[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
							pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Im =
								(float) pInI[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
						}
					}
				}
			} else {
	        	double *pInR, *pInI;
	    	    pInR = mxGetPr(In);
	        	pInI = mxGetPi(In);
	
				/* Copia transponiendo filas y columnas */
				for (k=0; k<Res->NPlanes * Res->NChannels; k++) {
					for (j=0; j<Res->NCol; j++) {
						for (i=0; i<Res->NLin; i++) {
							pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Re =
								(float) pInR[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
							pRes[ j + i * Res->NCol + k * Res->NCol * Res->NLin].Im =
								(float) pInI[ i + j * Res->NLin + k * Res->NCol * Res->NLin];
						}
					}
				}
			}
			}
         break;
	
}
   
return Res;
}
Exemplo n.º 7
0
//=============================================================================
// MexFile::exec
//=============================================================================
void MexFile::exec (int nlhs, mxArray ** plhs, int nrhs, mxArray ** prhs)
{
#if !defined(WIN32)
    // check initialization
    if (MexFile::initialized == 0 && MexFile::init() == kError) {
        ::mexErrMsgTxt("initialization failed");
        //-- no <return> needed here (done by mexErrMsgTxt)
    }
#endif

    //- check num of input arg - at least 1 arg expected (cmd-id).
    if (nrhs == 0) {
        ::mexErrMsgTxt("no input argument specified");
    }

    //- check first arg - must be a 16 bits integer (func_id).
    if (mxIsInt16(prhs[0]) == false) {
        ::mexErrMsgTxt("first mex function argument must be a 16 bits integer");
    }

    //- get cmd_id
    short cmd_id = *(static_cast<short*>(::mxGetData(prhs[0])));

    //- store mex function in/out arguments for later retrieval
    MEX_ARGS->set(nlhs, plhs, nrhs, prhs);

    //- reset global error code and stack
    if (cmd_id != MexFile::ERROR_CODE && cmd_id != MexFile::ERROR_STACK) {
        MEX_UTILS->reset_error();
    }

    try
    {
        //- exec cmd
        switch (cmd_id)
        {
        //-- MEX_VERSION
        case MexFile::MEX_VERSION:
            MexFile::version();
            break;
        //-- TANGO_VERSION
        case MexFile::TANGO_VERSION:
            TANGO_BINDING->tango_version();
            break;
        //-- EXPORT_ERROR_CODE
        case MexFile::ERROR_CODE:
            MEX_UTILS->error_code();
            break;
        //-- EXPORT_ERROR_STACK
        case MexFile::ERROR_STACK:
            MEX_UTILS->error_stack();
            break;
        //-- OPEN_DEVICE
        case MexFile::OPEN_DEVICE:
            TANGO_BINDING->open_device();
            break;
        //-- CLOSE_DEVICE
        case MexFile::CLOSE_DEVICE:
            TANGO_BINDING->close_device();
            break;
        //-- COMMAND_INOUT
        case MexFile::COMMAND_INOUT:
            TANGO_BINDING->command_inout();
            break;
        //-- COMMAND_INOUT_ASYNCH
        case MexFile::COMMAND_INOUT_ASYNCH:
            TANGO_BINDING->command_inout_asynch();
            break;
        //-- COMMAND_INOUT_REPLY
        case MexFile::COMMAND_INOUT_REPLY:
            TANGO_BINDING->command_inout_reply();
            break;
        //-- READ_ATTRIBUTE
        case MexFile::READ_ATTRIBUTE:
            TANGO_BINDING->read_attribute();
            break;
        //-- READ_ATTRIBUTE_ASYNCH
        case MexFile::READ_ATTRIBUTE_ASYNCH:
            TANGO_BINDING->read_attribute_asynch();
            break;
        //-- READ_ATTRIBUTE_REPLY
        case MexFile::READ_ATTRIBUTE_REPLY:
            TANGO_BINDING->read_attribute_reply();
            break;
        //-- READ_ATTRIBUTES
        case MexFile::READ_ATTRIBUTES:
            TANGO_BINDING->read_attributes();
            break;
        //-- READ_ATTRIBUTES_ASYNCH
        case MexFile::READ_ATTRIBUTES_ASYNCH:
            TANGO_BINDING->read_attributes_asynch();
            break;
        //-- READ_ATTRIBUTES_REPLY
        case MexFile::READ_ATTRIBUTES_REPLY:
            TANGO_BINDING->read_attributes_reply();
            break;
        //-- WRITE_ATTRIBUTE
        case MexFile::WRITE_ATTRIBUTE:
            TANGO_BINDING->write_attribute();
            break;
        //-- WRITE_ATTRIBUTE_ASYNCH
        case MexFile::WRITE_ATTRIBUTE_ASYNCH:
            TANGO_BINDING->write_attribute_asynch();
            break;
        //-- WRITE_ATTRIBUTE_REPLY
        case MexFile::WRITE_ATTRIBUTE_REPLY:
            TANGO_BINDING->write_attribute_reply();
            break;
        //-- WRITE_ATTRIBUTES
        case MexFile::WRITE_ATTRIBUTES:
            TANGO_BINDING->write_attributes();
            break;
        //-- WRITE_ATTRIBUTES_ASYNCH
        case MexFile::WRITE_ATTRIBUTES_ASYNCH:
            TANGO_BINDING->write_attributes_asynch();
            break;
        //-- WRITE_ATTRIBUTES_REPLY
        case MexFile::WRITE_ATTRIBUTES_REPLY:
            TANGO_BINDING->write_attributes_reply();
            break;
        //-- STATUS
        case MexFile::STATUS:
            TANGO_BINDING->status();
            break;
        //-- PING
        case MexFile::PING:
            TANGO_BINDING->ping();
            break;
        //-- INFO
        case MexFile::INFO:
            TANGO_BINDING->info();
            break;
        //-- STATE
        case MexFile::STATE:
            TANGO_BINDING->state();
            break;
        //-- DESCRIPTION
        case MexFile::DESCRIPTION:
            TANGO_BINDING->description();
            break;
        //-- ADMIN_NAME
        case MexFile::ADMIN_NAME:
            TANGO_BINDING->admin_name();
            break;
        //-- GET_ATTR_CONFIG
        case MexFile::GET_ATTR_CONFIG:
            TANGO_BINDING->get_attr_config();
            break;
        //-- SET_ATTR_CONFIG
        case MexFile::SET_ATTR_CONFIG:
            TANGO_BINDING->set_attr_config();
            break;
        //-- BLACK_BOX
        case MexFile::BLACK_BOX:
            TANGO_BINDING->black_box();
            break;
        //-- CMD_LIST_QUERY
        case MexFile::CMD_LIST_QUERY:
            TANGO_BINDING->command_list_query();
            break;
        //-- CMD_QUERY
        case MexFile::CMD_QUERY:
            TANGO_BINDING->command_query();
            break;
        //-- SET_TIMEOUT
        case MexFile::SET_TIMEOUT:
            TANGO_BINDING->set_timeout();
            break;
        //-- GET_TIMEOUT
        case MexFile::GET_TIMEOUT:
            TANGO_BINDING->get_timeout();
            break;
        //-- SET_SOURCE
        case MexFile::SET_SOURCE:
            TANGO_BINDING->set_source();
            break;
        //-- GET_SOURCE
        case MexFile::GET_SOURCE:
            TANGO_BINDING->get_source();
            break;
        //-- COMMAND_HISTORY
        case MexFile::COMMAND_HISTORY:
            TANGO_BINDING->command_history();
            break;
        //-- ATTRIBUTE_LIST
        case ATTRIBUTE_LIST:
            TANGO_BINDING->get_attribute_list();
            break;
        //-- ATTRIBUTE_HISTORY
        case MexFile::ATTRIBUTE_HISTORY:
            TANGO_BINDING->attribute_history();
            break;
        //-- POLLING_STATUS
        case MexFile::POLLING_STATUS:
            TANGO_BINDING->polling_status();
            break;
        //-- IS_CMD_POLLED
        case MexFile::IS_CMD_POLLED:
            TANGO_BINDING->is_command_polled();
            break;
        //-- IS_ATTR_POLLED
        case MexFile::IS_ATTR_POLLED:
            TANGO_BINDING->is_attribute_polled();
            break;
        //-- POLL_CMD
        case MexFile::POLL_CMD:
            TANGO_BINDING->poll_command();
            break;
        //-- POLL_ATTR
        case MexFile::POLL_ATTR:
            TANGO_BINDING->poll_attribute();
            break;
        //-- STOP_POLL_CMD
        case MexFile::STOP_POLL_CMD:
            TANGO_BINDING->stop_poll_command();
            break;
        //-- STOP_POLL_ATTR
        case MexFile::STOP_POLL_ATTR:
            TANGO_BINDING->stop_poll_attribute();
            break;
        //-- GET_CMD_POLL_PERIOD
        case MexFile::GET_CMD_POLL_PERIOD:
            TANGO_BINDING->get_command_poll_period();
            break;
        //-- GET_ATTR_POLL_PERIOD
        case MexFile::GET_ATTR_POLL_PERIOD:
            TANGO_BINDING->get_attribute_poll_period();
            break;
        //-- IDL_VERSION
        case IDL_VERSION:
            TANGO_BINDING->get_idl_version();
            break;
        //-- GET_PROPERTIES
        case GET_PROPERTIES:
            TANGO_BINDING->get_properties();
            break;
        //-- PUT_PROPERTIES
        case PUT_PROPERTIES:
            TANGO_BINDING->put_properties();
            break;
        //-- DEL_PROPERTIES
        case DEL_PROPERTIES:
            TANGO_BINDING->del_properties();
            break;
        //-- GET_PROPERTY
        case GET_PROPERTY:
            TANGO_BINDING->get_property();
            break;
        //-- PUT_PROPERTY
        case PUT_PROPERTY:
            TANGO_BINDING->put_property();
            break;
        //-- DEL_PROPERTY
        case DEL_PROPERTY:
            TANGO_BINDING->del_property();
            break;
        //-- GROUP_CREATE
        case GROUP_CREATE:
            TANGO_BINDING->group_create();
            break;
        //-- GROUP_KILL:
        case GROUP_KILL:
            TANGO_BINDING->group_kill();
            break;
        //-- GROUP_ADD:
        case GROUP_ADD:
            TANGO_BINDING->group_add();
            break;
        //-- GROUP_REMOVE:
        case GROUP_REMOVE:
            TANGO_BINDING->group_remove();
            break;
        //-- GROUP_GETID:
        case GROUP_GETID:
            TANGO_BINDING->group_id();
            break;
        //-- GROUP_CMD_INOUT_ASYNCH:
        case GROUP_CMD_INOUT_ASYNCH:
            TANGO_BINDING->group_command_inout_asynch();
            break;
        //-- GROUP_CMD_INOUT_REPLY:
        case GROUP_CMD_INOUT_REPLY:
            TANGO_BINDING->group_command_inout_reply();
            break;
        //-- GROUP_DUMP:
        case GROUP_DUMP:
            TANGO_BINDING->group_dump();
            break;
        //-- GROUP_PING:
        case GROUP_PING:
            TANGO_BINDING->group_ping();
            break;
        //-- GROUP_SIZE:
        case GROUP_SIZE:
            TANGO_BINDING->group_size();
            break;
        //-- GROUP_CONTAINS:
        case GROUP_CONTAINS:
            TANGO_BINDING->group_contains();
            break;
        //-- GROUP_WRITE_ATTRIBUTE_ASYNCH:
        case GROUP_WRITE_ATTRIBUTE_ASYNCH:
            TANGO_BINDING->group_write_attribute_asynch();
            break;
        //-- GROUP_WRITE_ATTRIBUTE_REPLY:
        case GROUP_WRITE_ATTRIBUTE_REPLY:
            TANGO_BINDING->group_write_attribute_reply();
            break;
        //-- GROUP_READ_ATTRIBUTE_ASYNCH:
        case GROUP_READ_ATTRIBUTE_ASYNCH:
            TANGO_BINDING->group_read_attribute_asynch();
            break;
        //-- GROUP_READ_ATTRIBUTE_REPLY:
        case GROUP_READ_ATTRIBUTE_REPLY:
            TANGO_BINDING->group_read_attribute_reply();
            break;
        //-- GROUP_READ_ATTRIBUTES_ASYNCH:
        case GROUP_READ_ATTRIBUTES_ASYNCH:
            TANGO_BINDING->group_read_attributes_asynch();
            break;
        //-- GROUP_READ_ATTRIBUTES_REPLY:
        case GROUP_READ_ATTRIBUTES_REPLY:
            TANGO_BINDING->group_read_attributes_reply();
            break;
        //-- GROUP_ENABLE_DEVICE:
        case GROUP_ENABLE_DEVICE:
            TANGO_BINDING->group_enable_device();
            break;
        //-- GROUP_DISABLE_DEVICE:
        case GROUP_DISABLE_DEVICE:
            TANGO_BINDING->group_disable_device();
            break;
        //-- ENABLE_V1_COMPATIBILITY:
        case ENABLE_V1_COMPATIBILITY:
            TANGO_BINDING->enable_v1_compatibility();
            break;
        //-- DISABLE_V1_COMPATIBILITY:
        case DISABLE_V1_COMPATIBILITY:
            TANGO_BINDING->disable_v1_compatibility();
            break;
        //-- GROUP_SET_TIMEOUT_MSECS:
        case GROUP_SET_TIMEOUT_MSECS:
            TANGO_BINDING->group_set_timeout_msecs();
            break;
        //-- GROUP_DEVICE_LIST:
        case GROUP_DEVICE_LIST:
            TANGO_BINDING->group_device_list();
            break;
        //- DEFAULT
        default:
            MEX_UTILS->set_error("invalid command tag specified",
                                 "unknown command tag",
                                 "mexFunction");
            SET_DEFAULT_PRHS(-1);
            break;
        }
    }
    catch (const Tango::DevFailed &dv) {
        MEX_UTILS->set_error(dv);
        MEX_UTILS->push_error((const char*)"exception caught",
                              (const char*)"Tango::DevFailed exception caught",
                              (const char*)"MexFile::exec");
        SET_DEFAULT_PRHS(-1);
    }
    catch (...) {
        MEX_UTILS->set_error((const char*)"unknown exception caught",
                             (const char*)"unknown exception caught",
                             (const char*)"MexFile::exec");
        SET_DEFAULT_PRHS(-1);
    }
}
Exemplo n.º 8
0
int mxSetDimensions(mxArray *array_ptr, const int *dims, int ndim)
{
    if (mxIsCell(array_ptr))
    {
        ((types::Cell *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsChar(array_ptr))
    {
        ((types::String *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsDouble(array_ptr))
    {
        ((types::Double *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsSparse(array_ptr))
    {
        //TODO
    }
    else if (mxIsInt8(array_ptr))
    {
        ((types::Int8 *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsInt16(array_ptr))
    {
        ((types::Int16 *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsInt32(array_ptr))
    {
        ((types::Int32 *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsInt64(array_ptr))
    {
        ((types::Int64 *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsLogical(array_ptr))
    {
        ((types::Bool *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsStruct(array_ptr))
    {
        ((types::Struct *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsUint8(array_ptr))
    {
        ((types::UInt8 *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsUint16(array_ptr))
    {
        ((types::UInt16 *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsUint32(array_ptr))
    {
        ((types::UInt32 *)array_ptr)->resize((int *)dims, ndim);
    }
    else if (mxIsUint64(array_ptr))
    {
        ((types::UInt64 *)array_ptr)->resize((int *)dims, ndim);
    }

    return 0;
}
Exemplo n.º 9
0
int mxIsClass(const mxArray *ptr, const char *name)
{
    if (strcmp(name, "cell") == 0)
    {
        return mxIsCell(ptr);
    }
    if (strcmp(name, "char") == 0)
    {
        return mxIsChar(ptr);
    }
    if (strcmp(name, "double") == 0)
    {
        return mxIsDouble(ptr);
    }
    if (strcmp(name, "int8") == 0)
    {
        return mxIsInt8(ptr);
    }
    if (strcmp(name, "int16") == 0)
    {
        return mxIsInt16(ptr);
    }
    if (strcmp(name, "int32") == 0)
    {
        return mxIsInt32(ptr);
    }
    if (strcmp(name, "int64") == 0)
    {
        return mxIsInt64(ptr);
    }
    if (strcmp(name, "logical") == 0)
    {
        return mxIsLogical(ptr);
    }
    if (strcmp(name, "single") == 0)
    {
        return mxIsSingle(ptr);
    }
    if (strcmp(name, "struct") == 0)
    {
        return mxIsStruct(ptr);
    }
    if (strcmp(name, "uint8") == 0)
    {
        return mxIsUint8(ptr);
    }
    if (strcmp(name, "uint16") == 0)
    {
        return mxIsUint16(ptr);
    }
    if (strcmp(name, "uint32") == 0)
    {
        return mxIsUint32(ptr);
    }
    if (strcmp(name, "uint64") == 0)
    {
        return mxIsUint64(ptr);
    }
    // TODO: how to handle <class_name> and <class_id>?
    return 0;
}
Exemplo n.º 10
0
int mxIsNumeric(const mxArray *ptr)
{
    return mxIsDouble(ptr) || mxIsSingle(ptr) ||
           mxIsInt8(ptr) || mxIsUint8(ptr) ||
           mxIsInt16(ptr) || mxIsUint16(ptr) || mxIsInt32(ptr) || mxIsUint32(ptr) || mxIsInt64(ptr) || mxIsUint64(ptr);
}
Exemplo n.º 11
0
/// get type of current argument (does not increment argument counter)
IFType CMatlabInterface::get_argument_type()
{
	const mxArray* arg=m_rhs[m_rhs_counter];
	ASSERT(arg);

	if (mxIsSparse(arg))
	{
		if (mxIsUint8(arg))
			return SPARSE_BYTE;
		if (mxIsChar(arg))
			return SPARSE_CHAR;
		if (mxIsInt32(arg))
			return SPARSE_INT;
		if (mxIsDouble(arg))
			return SPARSE_REAL;
		if (mxIsInt16(arg))
			return SPARSE_SHORT;
		if (mxIsSingle(arg))
			return SPARSE_SHORTREAL;
		if (mxIsUint16(arg))
			return SPARSE_WORD;

		return UNDEFINED;
	}

	if (mxIsInt32(arg))
		return DENSE_INT;
	if (mxIsDouble(arg))
		return DENSE_REAL;
	if (mxIsInt16(arg))
		return DENSE_SHORT;
	if (mxIsSingle(arg))
		return DENSE_SHORTREAL;
	if (mxIsUint16(arg))
		return DENSE_WORD;

	if (mxIsChar(arg))
		return STRING_CHAR;
	if (mxIsUint8(arg))
		return STRING_BYTE;

	if (mxIsCell(arg))
	{
		const mxArray* cell=mxGetCell(arg, 0);
		if (cell && mxGetM(cell)==1)
		{
			if (mxIsUint8(cell))
				return STRING_BYTE;
			if (mxIsChar(cell))
				return STRING_CHAR;
			if (mxIsInt32(cell))
				return STRING_INT;
			if (mxIsInt16(cell))
				return STRING_SHORT;
			if (mxIsUint16(cell))
				return STRING_WORD;
		}
	}

	return UNDEFINED;
}
Exemplo n.º 12
0
void mexFunction( int nlhs, mxArray *plhs[],
                  int nrhs, const mxArray *prhs[])
{
    int n, nw, t;
    int16_T *yr, *yi, *xr, *xi, *wr, *wi;
    int Wfraclen;
    int16_T lowerbnd, upperbnd;
    double* nshifts;
    int isWComplex = mxIsComplex(W_IN);

    if (nrhs != N_INPUTS) mexErrMsgTxt("Wrong number of input arguments." USAGE);
    if (nlhs > N_OUTPUTS) mexErrMsgTxt("Too many output arguments." USAGE);

    if (!mxIsInt16(X_IN)) mexErrMsgTxt("X must be int16.");
    if (!mxIsInt16(W_IN)) mexErrMsgTxt("W must be int16.");

    n  = mxGetNumberOfElements(X_IN);
    t = log2(n);  /* n = 2^t */
    nw = mxGetNumberOfElements(W_IN);

    Y_OUT = mxDuplicateArray(X_IN);
    NSHIFTS_OUT = mxCreateScalarDouble(0.0);
    if (n<=1) return;
    nshifts = mxGetPr(NSHIFTS_OUT);

    if (!isPowerOfTwo(n)) {
        mexErrMsgTxt("The length of X must be a power of two.");
    }
    if (nw != (n-1)) {
        mexErrMsgTxt("The length of the twiddle factor vector "
                     "must be one less than the length of the input data.");
    }

    if (!mxIsComplex(X_IN)) {
        /* Grow imaginary part. */
        int16_T* yi = mxCalloc(n,sizeof(int16_T));
        mxSetImagData(Y_OUT, yi);
    }

    /* Overwrite a copy of the input data for the output */
    xr = (int16_T*)mxGetData    ( Y_OUT );
    xi = (int16_T*)mxGetImagData( Y_OUT );

    wr = (int16_T*)mxGetData    ( W_IN );

    if (isWComplex==1) {
        wi = (int16_T*)mxGetImagData( W_IN );
    }  else {
        wi = mxCalloc(n,sizeof(int16_T));
    }
    
    Wfraclen = (int)mxGetScalar( WFRACTIONLENGTH_IN );
    lowerbnd = (int16_T)mxGetScalar( XLOWERBOUND_IN     );
    upperbnd = (int16_T)mxGetScalar( XUPPERBOUND_IN     );

    fi_c_radix2fft_blockfloatingpoint(xr, xi, wr, wi, n, nw, t, Wfraclen, lowerbnd, upperbnd, nshifts);

    if (isWComplex==0) {
        mxFree(wi);
    }
}
Exemplo n.º 13
0
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {

	int i, j, nx, ny, n_read = 0, n_points = 0, one_or_zero;
	int n_output = 0, n_fields, n_pts, ii, jj, GMT_pad[4];
	
	int error = FALSE, suppress = FALSE, node = FALSE, z_only = FALSE;
	int is_double = FALSE, is_single = FALSE, is_int32 = FALSE, is_int16 = FALSE;
	int is_uint16 = FALSE, is_uint8 = FALSE, is_int8 = FALSE;
	int free_copy = TRUE, need_padding = FALSE, row_maj = FALSE;
	
	double value, west, east, south, north, threshold = 1.0, i_dx, i_dy, half, *in, *out;
	float *f;

	int	i2, argc = 0, nc_h, nr_h, mx, n_arg_no_char = 0, *i_4, interpolant = BCR_BICUBIC;
	short int *i_2;
	unsigned short int *ui_2;
	char	**argv, *i_1;
	unsigned char *ui_1;
	float	*z_4;
	double	*pdata_d, *z_8, *head;
	
	struct GRD_HEADER grd;
	struct GMT_EDGEINFO edgeinfo;
	struct GMT_BCR bcr;

	argc = nrhs;
	for (i = 0; i < nrhs; i++) {		/* Check input to find how many arguments are of type char */
		if(!mxIsChar(prhs[i])) {
			argc--;
			n_arg_no_char++;	/* Number of arguments that have a type other than char */
		}
	}
	argc++;			/* to account for the program's name to be inserted in argv[0] */

	/* get the length of the input string */
	argv = (char **)mxCalloc(argc, sizeof(char *));
	argv[0] = "grdtrack_m";
	for (i = 1; i < argc; i++)
		argv[i] = (char *)mxArrayToString(prhs[i+n_arg_no_char-1]);

	west = east = south = north = 0.0;
	
	GMT_boundcond_init (&edgeinfo);

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
			
				case 'R':
					error += decode_R (argv[i], &west, &east, &south, &north);
					break;
				case 'L':
					if (argv[i][2]) {
						error += GMT_boundcond_parse (&edgeinfo, &argv[i][2]);
						/*if (edgeinfo.gn) {
							GMT_io.in_col_type[0] = GMT_io.out_col_type[0] = GMT_IS_LON;
							GMT_io.in_col_type[1] = GMT_io.out_col_type[1] = GMT_IS_LAT;
						}*/
					}
					/*else {
						GMT_io.in_col_type[0] = GMT_io.out_col_type[0] = GMT_IS_LON;
						GMT_io.in_col_type[1] = GMT_io.out_col_type[1] = GMT_IS_LAT;
					}*/
					break;
				case 'N':
					node = TRUE;
					break;
				case 'Q':
					interpolant = BCR_BILINEAR;
					threshold = (argv[i][2]) ? atof (&argv[i][2]) : 1.0;
					break;
				case 'S':
					suppress = TRUE;
					break;
				case 'Z':
					z_only = TRUE;
					break;
				default:
					error = TRUE;
					break;
			}
		}
	}
	
	if (argc == 1 || error) {
		mexPrintf ("grdtrack - Sampling of a 2-D gridded netCDF grdfile along 1-D trackline\n\n");
		mexPrintf ("usage: out = grdtrack_m(grd,head,xydata, ['-L<flag>'], ['-N']\n"); 
		mexPrintf ("\t['-Q[<value>]'], ['-R<west/east/south/north>[r]'] ['-S'] ['-Z'] ['-f[i|o]<colinfo>']\n");
				
		mexPrintf ("\t<xydata> is an multicolumn array with (lon,lat) in the first two columns\n");
		mexPrintf ("\n\tOPTIONS:\n");
		mexPrintf ("\t-L sets boundary conditions.  <flag> can be either\n");
		mexPrintf ("\t   g for geographic boundary conditions\n");
		mexPrintf ("\t   or one or both of\n");
		mexPrintf ("\t   x for periodic boundary conditions on x\n");
		mexPrintf ("\t   y for periodic boundary conditions on y\n");
		mexPrintf ("\t-N Report value at nearest node instead of interpolating\n");
		mexPrintf ("\t-Q Quick mode, use bilinear rather than bicubic interpolation.\n");
		mexPrintf ("\t   Optionally, append <value> in the 0 < value <= 1 range.\n");
		mexPrintf ("\t   [Default = 1 requires all 4 nodes to be non-NaN.], <value> = 0.5\n");
		mexPrintf ("\t   will interpolate about 1/2 way from a non-NaN to a NaN node, while\n");
		mexPrintf ("\t   0.1 will go about 90%% of the way, etc.\n");
		mexPrintf ("\t-R specifies a subregion [Default is old region]\n");
		mexPrintf ("\t-S Suppress output when result equals NaN\n");
		mexPrintf ("\t-Z only output z-values [Default gives all columns]\n");
		mexPrintf ("\n\tSECRET INFO:\n");
		mexPrintf ("\t   When input points are inside the outer skirt of 2 rows and columns of\n");
		mexPrintf ("\t   the 2-D grid we don't need to set boundary conditions and as\n");
		mexPrintf ("\t   such we can use the input array without further to C order\n");
		mexPrintf ("\t   conversion (to row major). This save a lot of memory and execution\n");
		mexPrintf ("\t   time. However, this possibility works only when input 2-D array is\n");
		mexPrintf ("\t   of tipe SINGLE (though the computations are all done in doubles).\n");
		mexPrintf ("\t   The other cases request using a temporary array of size (M+2)x(N+2)\n");
		return;
	}

	if (threshold <= 0.0 || threshold > 1.0) {
		mexPrintf ("GRDTRACK_M SYNTAX ERROR -Q:  threshold must be in <0,1] range\n");
		error++;
	}
	if (error) return;

	if (nlhs == 0) {
		mexPrintf("ERROR: Must provide an output.\n");
		return;
	}

	/* Find out in which data type was given the input array */
	if (mxIsDouble(prhs[0])) {
		z_8 = mxGetPr(prhs[0]);
		is_double = TRUE;
	}
	else if (mxIsSingle(prhs[0])) {
		z_4 = mxGetData(prhs[0]);
		is_single = TRUE;
	}
	else if (mxIsInt32(prhs[0])) {
		i_4 = mxGetData(prhs[0]);
		is_int32 = TRUE;
	}
	else if (mxIsInt16(prhs[0])) {
		i_2 = mxGetData(prhs[0]);
		is_int16 = TRUE;
	}
	else if (mxIsUint16(prhs[0])) {
		ui_2 = mxGetData(prhs[0]);
		is_uint16 = TRUE;
	}
	else if (mxIsUint8(prhs[0])) {
		ui_1 = mxGetData(prhs[0]);
		is_uint8 = TRUE;
	}
	else if (mxIsInt8(prhs[0])) {
		i_1 = mxGetData(prhs[0]);
		is_int8 = TRUE;
	}
	else {
		mexPrintf("GRDTRACK ERROR: Unknown input data type.\n");
		mexErrMsgTxt("Valid types are:double, single, Int32, Int16, UInt16, UInt8 and Int8.\n");
	}

	nx = mxGetN (prhs[0]);
	ny = mxGetM (prhs[0]);
	if (!mxIsNumeric(prhs[0]) || ny < 2 || nx < 2)
		mexErrMsgTxt("First argument must contain a decent array\n");

	nc_h = mxGetN (prhs[1]);
	nr_h = mxGetM (prhs[1]);
	if (!mxIsNumeric(prhs[1]) || nr_h > 1 || nc_h < 9)
		mexErrMsgTxt("Second argument must contain a valid header of the input array.\n");
	
	head  = mxGetPr(prhs[1]);		/* Get header info */

	/* Check that thirth argument contains at least a mx2 table */
	n_pts = mxGetM (prhs[2]);
	n_fields = mxGetN(prhs[2]);
	if (!mxIsNumeric(prhs[2]) || (n_fields < 2))
		mexErrMsgTxt("GRDTRACK ERROR: thirth argument must contain the x,y positions where to interpolate.\n");
	if (z_only)
		n_fields = 0;

	/* Read the interpolation points and convert them to double */
	if (mxIsDouble(prhs[2]))
		in = mxGetPr(prhs[2]);
	else if (mxIsSingle(prhs[2]))
		in = mxGetData(prhs[2]);

	grd.x_min = head[0];	grd.x_max = head[1];
	grd.y_min = head[2];	grd.y_max = head[3];
	grd.z_min = head[4];	grd.z_max = head[5];
	grd.x_inc = head[7];	grd.y_inc = head[8];
	grd.nx = nx;			grd.ny = ny;
	grd.node_offset = irint(head[6]);
	mx = nx + 4;

	if (west == east) {	/* No subset asked for */
		west = grd.x_min;
		east = grd.x_max;
		south = grd.y_min;
		north = grd.y_max;
	}
	one_or_zero = (grd.node_offset) ? 0 : 1;
	half = (grd.node_offset) ? 0.5 : 0.0;
	nx = irint ( (east - west) / grd.x_inc) + one_or_zero;
	ny = irint ( (north - south) / grd.y_inc) + one_or_zero;
	i_dx = 1.0 / grd.x_inc;
	i_dy = 1.0 / grd.y_inc;

	if (!node) {
		/* If we don't have any point inside the two outer row/columns
		   there is no need to set boundary conditions plus all the extra
		   ovehead that it implies. So check it out here. */
		int n;
		double this_xmin, this_xmax, this_ymin, this_ymax;
		n = (interpolant == BCR_BILINEAR) ? 1 : 2;
		this_xmin = grd.x_min + n * grd.x_inc;
		this_xmax = grd.x_max - n * grd.x_inc;
		this_ymin = grd.y_min + n * grd.y_inc;
		this_ymax = grd.y_max - n * grd.y_inc;
		for (i = 0; i < n_pts; i++) {
			if (in[i] < this_xmin || in[i] > this_xmax) {
				need_padding = TRUE;
				break;
			}
			if (in[i+n_pts] < this_ymin || in[i+n_pts] > this_ymax) {
				need_padding = TRUE;
				break;
			}
		}
	}

#if original_GMT_code
	need_padding = TRUE;
#endif

	if (need_padding) row_maj = TRUE;	/* Here we have to use the old row major code */

	if (!need_padding) {		/* We can use the column major order of the Matlab array */

		if (!is_single)
			f = mxCalloc (nx * ny, sizeof (float));

		if (is_double) 
			for (j = 0; j < nx*ny; j++) f[j] = (float)z_8[j];

		else if (is_single) {
			f = z_4;
			free_copy = FALSE;	/* Signal that we shouldn't free f */
		}

		else if (is_int32)
			for (j = 0; j < nx*ny; j++) f[j] = (float)i_4[j];

		else if (is_int16)
			for (j = 0; j < nx*ny; j++) f[j] = (float)i_2[j];

		else if (is_uint16)
			for (j = 0; j < nx*ny; j++) f[j] = (float)ui_2[j];

		else if (is_uint8)
			for (j = 0; j < nx*ny; j++) f[j] = (float)ui_1[j];

		else if (is_int8)
			for (j = 0; j < nx*ny; j++) f[j] = (float)i_1[j];

		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 0;
	}

	else {

		f = mxCalloc ((nx+4)*(ny+4), sizeof (float));

		/* Transpose from Matlab orientation to gmt grd orientation */
		if (is_double) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)z_8[j*ny+i];
			}
		}
		else if (is_single) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = z_4[j*ny+i];
			}
		}
		else if (is_int32) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)i_4[j*ny+i];
			}
		}
		else if (is_int16) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
			ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)i_2[j*ny+i];
			}
		}
		else if (is_uint16) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)ui_2[j*ny+i];
			}
		}
		else if (is_uint8) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)ui_1[j*ny+i];
			}
		}
		else if (is_int8) {
			for (i = 0, i2 = ny - 1; i < ny; i++, i2--) {
				ii = (i2 + 2)*mx + 2;
				for (j = 0; j < nx; j++) f[ii + j] = (float)i_1[j*ny+i];
			}
		}

		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

		GMT_boundcond_param_prep (&grd, &edgeinfo);
	}
	
	/*project_info.w = west;	project_info.e = east;
	project_info.s = south;	project_info.n = north;*/
	
	/* Initialize bcr structure:  */

	GMT_bcr_init (&grd, GMT_pad, interpolant, threshold, &bcr);

	if (need_padding)
		/* Set boundary conditions  */
		GMT_boundcond_set (&grd, &edgeinfo, GMT_pad, f);
	
	if ((out = mxCalloc(n_pts * (n_fields+1), sizeof (double))) == 0)
		mexErrMsgTxt("GRDTRACK ERROR: Could not allocate memory\n");

	for (i = 0; i < n_pts; i++) {
		while ( (mxIsNaN(in[i]) || mxIsNaN(in[i+n_pts])) && !z_only) {
			for (j = 0; j < n_fields; j++) out[j*n_pts+i] = in[j*n_pts+i];
			out[j*n_pts+i] = mxGetNaN();
			i++;
		}

		/* If point is outside grd area, shift it using periodicity or skip if not periodic. */
		while ( (in[i+n_pts] < grd.y_min) && (edgeinfo.nyp > 0) ) in[i+n_pts] += (grd.y_inc * edgeinfo.nyp);
		if (in[i+n_pts] < grd.y_min) continue;

		while ( (in[i+n_pts] > grd.y_max) && (edgeinfo.nyp > 0) ) in[i+n_pts] -= (grd.y_inc * edgeinfo.nyp);
		if (in[i+n_pts] > grd.y_max) continue;

		while ( (in[i] < grd.x_min) && (edgeinfo.nxp > 0) ) in[i] += (grd.x_inc * edgeinfo.nxp);
		if (in[i] < grd.x_min) continue;

		while ( (in[i] > grd.x_max) && (edgeinfo.nxp > 0) ) in[i] -= (grd.x_inc * edgeinfo.nxp);
		if (in[i] > grd.x_max) continue;
		
		if (node) {
			ii = irint ((in[i] - grd.x_min) * i_dx - half) + one_or_zero;
			jj = irint ((grd.y_max - in[i+n_pts]) * i_dy - half) + one_or_zero;
			value = f[(jj+GMT_pad[3])*mx+ii+GMT_pad[0]];
		}
		else
			value = GMT_get_bcr_z(&grd, in[i], in[i+n_pts], f, &edgeinfo, &bcr, row_maj);

		if (suppress && mxIsNaN (value)) continue;

		if (z_only) {	/* Simply print out value */
			out[i] = value;
		}
		else {	/* Simply copy other columns, append value, and output */
			for (j = 0; j < n_fields; j++) out[j*n_pts+i] = in[j*n_pts+i];
			out[j*n_pts+i] = value;
		}
	}

	/*if (!(!need_padding && !is_single)) {
		mexPrintf("Merda vou Friar %d\t%d\n", need_padding, is_single);
		mxFree((void *)f);
	}*/
	if (free_copy)
		mxFree((void *)f);

	plhs[0] = mxCreateDoubleMatrix (n_pts,n_fields+1, mxREAL);
	pdata_d = mxGetPr(plhs[0]);
	memcpy(pdata_d, out, n_pts*(n_fields+1)*8);
	mxFree(out);
}
Exemplo n.º 14
0
/* Matlab Gateway routine */
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
	int	nXYSize;
	double	adfGeoTransform[6] = {0,1,0,0,0,1}, adfDstGeoTransform[6];
	char	*pszSRS_WKT = NULL;
	char	**papszWarpOptions = NULL;
	GDALDatasetH	hSrcDS, hDstDS;
	GDALDriverH	hDriver;
	GDALRasterBandH hBand;
	GDALColorTableH	hColorTable = NULL;
	OGRSpatialReference oSrcSRS, oDstSRS; 
	GDALResampleAlg	interpMethod = GRA_NearestNeighbour;
	GDALTransformerFunc pfnTransformer = NULL;
	CPLErr		eErr;
	GDAL_GCP	*pasGCPs = NULL;
	static int runed_once = FALSE;	/* It will be set to true if reaches end of main */

	const int *dim_array;
	int	nx, ny, i, j, m, n, c, nBands, registration = 1;
	int	n_dims, typeCLASS, nBytes;
	char	*pszSrcSRS = NULL, *pszSrcWKT = NULL;
	char	*pszDstSRS = NULL, *pszDstWKT = NULL;
	void	*in_data;
	mxArray	*mx_ptr;

	unsigned char *tmpByte, *outByte;
	unsigned short int *tmpUI16, *outUI16;
	short int *tmpI16, *outI16;
	int	*tmpI32, *outI32;
	int	nPixels=0, nLines=0, nForceWidth=0, nForceHeight=0;
	int	nGCPCount = 0, nOrder = 0;
	unsigned int *tmpUI32, *outUI32;
	float	*tmpF32, *outF32;
	double	*tmpF64, *outF64, *ptr_d;
	double	dfMinX=0, dfMaxX=0, dfMinY=0, dfMaxY=0, dfResX=0, dfResY=0;
	double	adfExtent[4];
	double	dfXRes=0.0, dfYRes=0.0;
	double	dfWarpMemoryLimit = 0.0;
	double	*pdfDstNodata = NULL; 
	char	**papszMetadataOptions = NULL;
	char	*tmp, *txt;


	if (nrhs == 2 && mxIsStruct(prhs[1])) {
		mx_ptr = mxGetField(prhs[1], 0, "ULx");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'ULx' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[0] = *ptr_d;

		mx_ptr = mxGetField(prhs[1], 0, "Xinc");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'Xinc' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[1] = *ptr_d;

		mx_ptr = mxGetField(prhs[1], 0, "ULy");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'ULy' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[3] = *ptr_d;

		mx_ptr = mxGetField(prhs[1], 0, "Yinc");
		if (mx_ptr == NULL)
			mexErrMsgTxt("GDALWARP 'Yinc' field not provided");
		ptr_d = mxGetPr(mx_ptr);
		adfGeoTransform[5] = -*ptr_d;

		/* -------- See for resolution requests ------------ */
		mx_ptr = mxGetField(prhs[1], 0, "t_size");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			if (mxGetN(mx_ptr) == 2) {
				nForceWidth  = (int)ptr_d[0];
				nForceHeight = (int)ptr_d[1];
			}
			else if (mxGetN(mx_ptr) == 1) {	/* pick max(nrow,ncol) */
				if (mxGetM(prhs[0]) > getNK(prhs[0],1))
					nForceHeight = mxGetM(prhs[0]);
				else
					nForceWidth  = getNK(prhs[0], 1);
			}
			else {
				nForceHeight = mxGetM(prhs[0]);
				nForceWidth  = getNK(prhs[0], 1);
			}
		}

		mx_ptr = mxGetField(prhs[1], 0, "t_res");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			if (mxGetN(mx_ptr) == 2) {
				dfXRes = ptr_d[0];
				dfYRes = ptr_d[1];
			}
			else if (mxGetN(mx_ptr) == 1) {
				dfXRes = dfYRes = ptr_d[0];
			}
		}
		/* -------------------------------------------------- */

		/* -------- Change Warping cache size?  ------------ */
		mx_ptr = mxGetField(prhs[1], 0, "wm");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			dfWarpMemoryLimit = *ptr_d * 1024 * 1024;
		}
		/* -------------------------------------------------- */

		/* -------- Have a nodata value order? -------------- */
		mx_ptr = mxGetField(prhs[1], 0, "nodata");
		if (mx_ptr != NULL) {
			pdfDstNodata = mxGetPr(mx_ptr);
		}
		/* -------------------------------------------------- */

		/* -------- See for projection stuff ---------------- */
		mx_ptr = mxGetField(prhs[1], 0, "SrcProjSRS");
		if (mx_ptr != NULL)
			pszSrcSRS = (char *)mxArrayToString(mx_ptr);

		mx_ptr = mxGetField(prhs[1], 0, "SrcProjWKT");
		if (mx_ptr != NULL)
			pszSrcWKT = (char *)mxArrayToString(mx_ptr);

		mx_ptr = mxGetField(prhs[1], 0, "DstProjSRS");
		if (mx_ptr != NULL)
			pszDstSRS = (char *)mxArrayToString(mx_ptr);

		mx_ptr = mxGetField(prhs[1], 0, "DstProjWKT");
		if (mx_ptr != NULL)
			pszDstWKT = (char *)mxArrayToString(mx_ptr);
		/* -------------------------------------------------- */

		/* -------- Do we have GCPs? ----------------------- */
		mx_ptr = mxGetField(prhs[1], 0, "gcp");
		if (mx_ptr != NULL) {
			nGCPCount = mxGetM(mx_ptr);
			if (mxGetN(mx_ptr) != 4)
				mexErrMsgTxt("GDALWARP: GCPs must be a Mx4 array");
			ptr_d = mxGetPr(mx_ptr);
			pasGCPs = (GDAL_GCP *) mxCalloc( nGCPCount, sizeof(GDAL_GCP) );
			GDALInitGCPs( 1, pasGCPs + nGCPCount - 1 );
			for (i = 0; i < nGCPCount; i++) {
				pasGCPs[i].dfGCPPixel = ptr_d[i];
				pasGCPs[i].dfGCPLine = ptr_d[i+nGCPCount];
				pasGCPs[i].dfGCPX = ptr_d[i+2*nGCPCount];
				pasGCPs[i].dfGCPY = ptr_d[i+3*nGCPCount];
				pasGCPs[i].dfGCPZ = 0;
			}
		}
			/* ---- Have we an order request? --- */
		mx_ptr = mxGetField(prhs[1], 0, "order");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			nOrder = (int)*ptr_d;
			if (nOrder != -1 || nOrder != 0 || nOrder != 1 || nOrder != 2 || nOrder != 3)
				nOrder = 0;
		}
		/* -------------------------------------------------- */

		mx_ptr = mxGetField(prhs[1], 0, "ResampleAlg");
		if (mx_ptr != NULL) {
			txt = (char *)mxArrayToString(mx_ptr);
			if (!strcmp(txt,"nearest"))
				interpMethod = GRA_NearestNeighbour;
			else if (!strcmp(txt,"bilinear"))
				interpMethod = GRA_Bilinear;
			else if (!strcmp(txt,"cubic") || !strcmp(txt,"bicubic"))
				interpMethod = GRA_Cubic;
			else if (!strcmp(txt,"spline"))
				interpMethod = GRA_CubicSpline;
		}

		/* If grid limits were in grid registration, convert them to pixel reg */
		mx_ptr = mxGetField(prhs[1], 0, "Reg");
		if (mx_ptr != NULL) {
			ptr_d = mxGetPr(mx_ptr);
			registration = (int)ptr_d[0];
		}

		if (registration == 0) {
			adfGeoTransform[0] -= adfGeoTransform[1]/2.;
			adfGeoTransform[3] -= adfGeoTransform[5]/2.;
		}
	}
	else {
		mexPrintf("Usage: B = gdalwarp_mex(IMG,HDR_STRUCT)\n\n");
		mexPrintf("\tIMG -> is a Mx2 or Mx3 array with an grid/image data to reproject\n");
		mexPrintf("\tHDR_STRUCT -> is a structure with the following fields:\n");
		mexPrintf("\t\t'ULx' X coordinate of the uper left corner\n");
		mexPrintf("\t\t'ULy' Y coordinate of the uper left corner\n");
		mexPrintf("\t\t'Xinc' distance between columns in target grid/image coordinates\n");
		mexPrintf("\t\t'Yinc' distance between rows in target grid/image coordinates\n");
		mexPrintf("\t\t'SrcProjSRS', 'SrcProjWKT' -> Source projection string\n");
		mexPrintf("\t\t'DstProjSRS', 'DstProjWKT' -> Target projection string\n");
		mexPrintf("\t\t\tSRS stands for a string of the type used by proj4\n");
		mexPrintf("\t\t\tWKT stands for a string on the 'Well Known Text' format\n\n");
		mexPrintf("\t\t\tIf one of the Src or Dst fields is absent a GEOGRAPHIC WGS84 is assumed\n");
		mexPrintf("\nOPTIONS\n");
		mexPrintf("\t\t'gcp' a [Mx4] array with Ground Control Points\n");
		mexPrintf("\t\t't_size' a [width height] vector to set output file size in pixels\n");
		mexPrintf("\t\t't_res' a [xres yres] vector to set output file resolution (in target georeferenced units)\n");
		mexPrintf("\t\t'wm' amount of memory (in megabytes) that the warp API is allowed to use for caching\n");
		mexPrintf("\t\t'nodata' Set nodata values for output bands.\n");
		mexPrintf("\t\t'ResampleAlg' To set up the algorithm used during warp operation. Options are: \n");
		mexPrintf("\t\t\t'nearest' Use nearest neighbour resampling (default, fastest algorithm, worst interpolation quality).\n");
		mexPrintf("\t\t\t'bilinear' Use bilinear resampling.\n");
		mexPrintf("\t\t\t'cubic' Use cubic resampling.\n");
		mexPrintf("\t\t\t'spline' Use cubic spline resampling.\n\n");

		if (!runed_once)		/* Do next call only at first time this MEX is loaded */
			GDALAllRegister();

        	mexPrintf( "The following format drivers are configured and support Create() method:\n" );
        	for( i = 0; i < GDALGetDriverCount(); i++ ) {
			hDriver = GDALGetDriver(i);
			if( GDALGetMetadataItem( hDriver, GDAL_DCAP_CREATE, NULL ) != NULL)
				mexPrintf("%s: %s\n", GDALGetDriverShortName(hDriver), 
							GDALGetDriverLongName(hDriver));
		}
		return;
	}

	n_dims = mxGetNumberOfDimensions(prhs[0]);
	dim_array=mxGetDimensions(prhs[0]);
	ny = dim_array[0];
	nx = dim_array[1];
	nBands = dim_array[2];

	if (n_dims == 2)	/* Otherwise it would stay undefined */
		nBands = 1;

	/* Find out in which data type was given the input array */
	if (mxIsUint8(prhs[0])) {
		typeCLASS = GDT_Byte;		nBytes = 1;
		outByte = (unsigned char *)mxMalloc (nx*ny * sizeof(unsigned char));
	}
	else if (mxIsUint16(prhs[0])) {
		typeCLASS = GDT_UInt16;		nBytes = 2;
		outUI16 = (unsigned short int *)mxMalloc (nx*ny * sizeof(short int));
	}
	else if (mxIsInt16(prhs[0])) {
		typeCLASS = GDT_Int16;		nBytes = 2;
		outI16 = (short int *)mxMalloc (nx*ny * sizeof(short int));
	}
	else if (mxIsInt32(prhs[0])) {
		typeCLASS = GDT_Int32;		nBytes = 4;
		outI32 = (int *)mxMalloc (nx*ny * sizeof(int));
	}
	else if (mxIsUint32(prhs[0])) {
		typeCLASS = GDT_UInt32;		nBytes = 4;
		outUI32 = (unsigned int *)mxMalloc (nx*ny * sizeof(int));
	}
	else if (mxIsSingle(prhs[0])) {
		typeCLASS = GDT_Float32;	nBytes = 4;
		outF32 = (float *)mxMalloc (nx*ny * sizeof(float));
	}
	else if (mxIsDouble(prhs[0])) {
		typeCLASS = GDT_Float64;	nBytes = 8;
		outF64 = (double *)mxMalloc (nx*ny * sizeof(double));
	}
	else
		mexErrMsgTxt("GDALWARP Unknown input data class!");


	in_data = (void *)mxGetData(prhs[0]);

	if (!runed_once)		/* Do next call only at first time this MEX is loaded */
		GDALAllRegister();

	hDriver = GDALGetDriverByName( "MEM" ); 

	hSrcDS = GDALCreate( hDriver, "mem", nx, ny, nBands, (GDALDataType)typeCLASS, NULL );
	if (hSrcDS == NULL) {
		mexPrintf ("GDALOpen failed - %d\n%s\n", CPLGetLastErrorNo(), CPLGetLastErrorMsg());
		return;
	}
	GDALSetGeoTransform( hSrcDS, adfGeoTransform ); 

	/* ---------- Set the Source projection ---------------------------- */
	/* If it was not provided assume it is Geog WGS84 */
	if (pszSrcSRS == NULL && pszSrcWKT == NULL)
		oSrcSRS.SetWellKnownGeogCS( "WGS84" ); 
	else if (pszSrcWKT != NULL)
		oSrcSRS.importFromWkt( &pszSrcWKT );

	else {
		if( oSrcSRS.SetFromUserInput( pszSrcSRS ) != OGRERR_NONE )
			mexErrMsgTxt("GDAL_WARP_MEX: Translating source SRS failed.");
	}
	if (pszSrcWKT == NULL)
		oSrcSRS.exportToWkt( &pszSrcWKT );

	GDALSetProjection( hSrcDS, pszSrcWKT );	
	//pszSrcWKT = (char *)GDALGetProjectionRef( hSrcDS );
	CPLAssert( pszSrcWKT != NULL && strlen(pszSrcWKT) > 0 );
	/* ------------------------------------------------------------------ */


	/* -------------- Copy input data into the hSrcDS dataset ----------- */
	for (i = 1; i <= nBands; i++) {
		hBand = GDALGetRasterBand( hSrcDS, i ); 
		nXYSize = (i-1)*nx*ny;
		switch( typeCLASS ) {
			case GDT_Byte:
			 	tmpByte = (unsigned char *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outByte[c++] = tmpByte[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outByte, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_UInt16:
			 	tmpUI16 = (unsigned short int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outUI16[c++] = tmpUI16[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outUI16, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Int16:
			 	tmpI16 = (short int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outI16[c++] = tmpI16[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outI16, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_UInt32:
			 	tmpUI32 = (unsigned int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outUI32[c++] = tmpUI32[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outUI32, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Int32:
			 	tmpI32 = (int *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outI32[c++] = tmpI32[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outI32, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Float32:
			 	tmpF32 = (float *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outF32[c++] = tmpF32[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outF32, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
			case GDT_Float64:
			 	tmpF64 = (double *)in_data;	
				for (m = ny-1, c = 0; m >= 0; m--) for (n = 0; n < nx; n++)
					outF64[c++] = tmpF64[m + n*ny + nXYSize];
				GDALRasterIO( hBand, GF_Write, 0, 0, nx, ny,outF64, nx, ny, (GDALDataType)typeCLASS, 0, 0 );
				break;
		}
	}

	/* ---------- Set up the Target coordinate system ------------------- */
	/* If it was not provided assume it is Geog WGS84 */
	CPLErrorReset();
	if (pszDstSRS == NULL && pszDstWKT == NULL)
		oDstSRS.SetWellKnownGeogCS( "WGS84" ); 
	else if (pszDstWKT != NULL)
		oDstSRS.importFromWkt( &pszDstWKT );
	else {
		if( oDstSRS.SetFromUserInput( pszDstSRS ) != OGRERR_NONE )
			mexErrMsgTxt("GDAL_WARP_MEX: Translating target SRS failed.");
	}
	if (pszDstWKT == NULL)
		oDstSRS.exportToWkt( &pszDstWKT );
	/* ------------------------------------------------------------------ */

	if ( nGCPCount != 0 ) {
		if (GDALSetGCPs(hSrcDS, nGCPCount, pasGCPs, "") != CE_None)
			mexPrintf("GDALWARP WARNING: writing GCPs failed.\n");
	}

	/* Create a transformer that maps from source pixel/line coordinates
	   to destination georeferenced coordinates (not destination pixel line) 
	   We do that by omitting the destination dataset handle (setting it to NULL). */

	void *hTransformArg;

	hTransformArg = GDALCreateGenImgProjTransformer(hSrcDS, pszSrcWKT, NULL, pszDstWKT, 
											nGCPCount == 0 ? FALSE : TRUE, 0, nOrder);
	if( hTransformArg == NULL )
		mexErrMsgTxt("GDALTRANSFORM: Generating transformer failed.");

	GDALTransformerInfo *psInfo = (GDALTransformerInfo*)hTransformArg;

	/* -------------------------------------------------------------------------- */
	/*      Get approximate output georeferenced bounds and resolution for file
	/* -------------------------------------------------------------------------- */
	if (GDALSuggestedWarpOutput2(hSrcDS, GDALGenImgProjTransform, hTransformArg, 
	                             adfDstGeoTransform, &nPixels, &nLines, adfExtent,
	                             0) != CE_None ) {
	    GDALClose(hSrcDS);
		mexErrMsgTxt("GDALWARP: GDALSuggestedWarpOutput2 failed.");
	}

	if (CPLGetConfigOption( "CHECK_WITH_INVERT_PROJ", NULL ) == NULL) {
		double MinX = adfExtent[0];
		double MaxX = adfExtent[2];
		double MaxY = adfExtent[3];
		double MinY = adfExtent[1];
		int bSuccess = TRUE;
            
		/* Check that the the edges of the target image are in the validity area */
		/* of the target projection */
#define N_STEPS 20
		for (i = 0; i <= N_STEPS && bSuccess; i++) {
			for (j = 0; j <= N_STEPS && bSuccess; j++) {
				double dfRatioI = i * 1.0 / N_STEPS;
				double dfRatioJ = j * 1.0 / N_STEPS;
				double expected_x = (1 - dfRatioI) * MinX + dfRatioI * MaxX;
				double expected_y = (1 - dfRatioJ) * MinY + dfRatioJ * MaxY;
				double x = expected_x;
				double y = expected_y;
				double z = 0;
				/* Target SRS coordinates to source image pixel coordinates */
				if (!psInfo->pfnTransform(hTransformArg, TRUE, 1, &x, &y, &z, &bSuccess) || !bSuccess)
					bSuccess = FALSE;
				/* Source image pixel coordinates to target SRS coordinates */
				if (!psInfo->pfnTransform(hTransformArg, FALSE, 1, &x, &y, &z, &bSuccess) || !bSuccess)
					bSuccess = FALSE;
				if (fabs(x - expected_x) > (MaxX - MinX) / nPixels ||
					fabs(y - expected_y) > (MaxY - MinY) / nLines)
					bSuccess = FALSE;
			}
		}
            
		/* If not, retry with CHECK_WITH_INVERT_PROJ=TRUE that forces ogrct.cpp */
		/* to check the consistency of each requested projection result with the */
		/* invert projection */
		if (!bSuccess) {
			CPLSetConfigOption( "CHECK_WITH_INVERT_PROJ", "TRUE" );
			CPLDebug("WARP", "Recompute out extent with CHECK_WITH_INVERT_PROJ=TRUE");

			if (GDALSuggestedWarpOutput2(hSrcDS, GDALGenImgProjTransform, hTransformArg, 
			                             adfDstGeoTransform, &nPixels, &nLines, adfExtent,
			                              0) != CE_None ) {
			    GDALClose(hSrcDS);
				mexErrMsgTxt("GDALWARO: GDALSuggestedWarpOutput2 failed.");
			}
		}
	}

	/* -------------------------------------------------------------------- */
	/*      Expand the working bounds to include this region, ensure the    */
	/*      working resolution is no more than this resolution.             */
	/* -------------------------------------------------------------------- */
	if( dfMaxX == 0.0 && dfMinX == 0.0 ) {
		dfMinX = adfExtent[0];
		dfMaxX = adfExtent[2];
		dfMaxY = adfExtent[3];
		dfMinY = adfExtent[1];
		dfResX = adfDstGeoTransform[1];
		dfResY = ABS(adfDstGeoTransform[5]);
	}
	else {
		dfMinX = MIN(dfMinX,adfExtent[0]);
		dfMaxX = MAX(dfMaxX,adfExtent[2]);
		dfMaxY = MAX(dfMaxY,adfExtent[3]);
		dfMinY = MIN(dfMinY,adfExtent[1]);
		dfResX = MIN(dfResX,adfDstGeoTransform[1]);
		dfResY = MIN(dfResY,ABS(adfDstGeoTransform[5]));
	}

	GDALDestroyGenImgProjTransformer( hTransformArg );

	/* -------------------------------------------------------------------- */
	/*      Turn the suggested region into a geotransform and suggested     */
	/*      number of pixels and lines.                                     */
	/* -------------------------------------------------------------------- */

	adfDstGeoTransform[0] = dfMinX;
	adfDstGeoTransform[1] = dfResX;
	adfDstGeoTransform[2] = 0.0;
	adfDstGeoTransform[3] = dfMaxY;
	adfDstGeoTransform[4] = 0.0;
	adfDstGeoTransform[5] = -1 * dfResY;

	nPixels = (int) ((dfMaxX - dfMinX) / dfResX + 0.5);
	nLines  = (int) ((dfMaxY - dfMinY) / dfResY + 0.5);

	/* -------------------------------------------------------------------- */
	/*      Did the user override some parameters?                          */
	/* -------------------------------------------------------------------- */
	if( dfXRes != 0.0 && dfYRes != 0.0 ) {
		dfMinX = adfDstGeoTransform[0];
		dfMaxX = adfDstGeoTransform[0] + adfDstGeoTransform[1] * nPixels;
		dfMaxY = adfDstGeoTransform[3];
		dfMinY = adfDstGeoTransform[3] + adfDstGeoTransform[5] * nLines;

		nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
		nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);
		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;
	}
	else if( nForceWidth != 0 && nForceHeight != 0 ) {
		dfXRes = (dfMaxX - dfMinX) / nForceWidth;
		dfYRes = (dfMaxY - dfMinY) / nForceHeight;

		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;

		nPixels = nForceWidth;
		nLines = nForceHeight;
	}
	else if( nForceWidth != 0) {
		dfXRes = (dfMaxX - dfMinX) / nForceWidth;
		dfYRes = dfXRes;

		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;

		nPixels = nForceWidth;
		nLines = (int) ((dfMaxY - dfMinY + (dfYRes/2.0)) / dfYRes);
	}
	else if( nForceHeight != 0) {
		dfYRes = (dfMaxY - dfMinY) / nForceHeight;
		dfXRes = dfYRes;

		adfDstGeoTransform[0] = dfMinX;
		adfDstGeoTransform[3] = dfMaxY;
		adfDstGeoTransform[1] = dfXRes;
		adfDstGeoTransform[5] = -dfYRes;

		nPixels = (int) ((dfMaxX - dfMinX + (dfXRes/2.0)) / dfXRes);
		nLines = nForceHeight;
	}

	/* --------------------- Create the output --------------------------- */
	hDstDS = GDALCreate( hDriver, "mem", nPixels, nLines, 
			GDALGetRasterCount(hSrcDS), (GDALDataType)typeCLASS, NULL );
    
	CPLAssert( hDstDS != NULL );

	/* -------------- Write out the projection definition ---------------- */
	GDALSetProjection( hDstDS, pszDstWKT );
	GDALSetGeoTransform( hDstDS, adfDstGeoTransform );

	/* --------------------- Setup warp options -------------------------- */
	GDALWarpOptions *psWO = GDALCreateWarpOptions();

	psWO->hSrcDS = hSrcDS;
	psWO->hDstDS = hDstDS;

	psWO->nBandCount = nBands;
	psWO->panSrcBands = (int *) CPLMalloc(psWO->nBandCount * sizeof(int) );
	psWO->panDstBands = (int *) CPLMalloc(psWO->nBandCount * sizeof(int) );
	for( i = 0; i < nBands; i++ ) {
		psWO->panSrcBands[i] = i+1;
		psWO->panDstBands[i] = i+1;
	}

	if( dfWarpMemoryLimit != 0.0 )
		psWO->dfWarpMemoryLimit = dfWarpMemoryLimit;

	/* --------------------- Setup the Resampling Algo ------------------- */
	psWO->eResampleAlg = interpMethod;


	/* --------------------- Setup NODATA options ------------------------ */
	papszWarpOptions = CSLSetNameValue(papszWarpOptions, "INIT_DEST", "NO_DATA" );

	if ( pdfDstNodata == NULL && (typeCLASS == GDT_Float32 || typeCLASS == GDT_Float64) ) {
		pdfDstNodata = (double *) mxCalloc((size_t)1, sizeof(double));
		*pdfDstNodata = mxGetNaN();
	}
	else if (pdfDstNodata != NULL) {
#define CLAMP(val,type,minval,maxval) \
    do { if (val < minval) { val = minval; } \
    else if (val > maxval) { val = maxval; } \
    else if (val != (type)val) { val = (type)(val + 0.5); } } \
    while(0)
		switch( typeCLASS ) {
			case GDT_Byte:
				CLAMP(pdfDstNodata[0], GByte, 0.0, 255.0);
				break;
			case GDT_UInt16:
				CLAMP(pdfDstNodata[0], GInt16, -32768.0, 32767.0);
				break;
			case GDT_Int16:
				CLAMP(pdfDstNodata[0], GUInt16, 0.0, 65535.0);
				break;
			case GDT_UInt32:
				CLAMP(pdfDstNodata[0], GInt32, -2147483648.0, 2147483647.0);
				break;
			case GDT_Int32:
				CLAMP(pdfDstNodata[0], GUInt32, 0.0, 4294967295.0);
				break;
			default:
				break;
		}
	}

	psWO->papszWarpOptions = CSLDuplicate(papszWarpOptions);

	if (pdfDstNodata != NULL) {
		psWO->padfDstNoDataReal = (double *) CPLMalloc(psWO->nBandCount*sizeof(double));
		psWO->padfDstNoDataImag = (double *) CPLMalloc(psWO->nBandCount*sizeof(double));
		for (i = 0; i < nBands; i++) {
                        psWO->padfDstNoDataReal[i] = pdfDstNodata[0];
                        psWO->padfDstNoDataImag[i] = 0.0;
			GDALSetRasterNoDataValue( GDALGetRasterBand(hDstDS, i+1), pdfDstNodata[0]);
		}
	}

	/* ------------ Establish reprojection transformer ------------------- */
	psWO->pTransformerArg = GDALCreateGenImgProjTransformer( hSrcDS, GDALGetProjectionRef(hSrcDS), 
							hDstDS, GDALGetProjectionRef(hDstDS), 
							nGCPCount == 0 ? FALSE : TRUE, 0.0, nOrder );
	psWO->pfnTransformer = GDALGenImgProjTransform;

	/* ----------- Initialize and execute the warp operation ------------- */
	GDALWarpOperation oOperation;

	oOperation.Initialize( psWO );
	eErr = oOperation.ChunkAndWarpImage( 0, 0, GDALGetRasterXSize( hDstDS ),
						GDALGetRasterYSize( hDstDS ) );
	CPLAssert( eErr == CE_None );

	GDALDestroyGenImgProjTransformer( psWO->pTransformerArg );
	GDALDestroyWarpOptions( psWO );
	GDALClose( hSrcDS );

	/* ------------ Free memory used to fill the hSrcDS dataset ---------- */
	switch( typeCLASS ) {
		case GDT_Byte:		mxFree((void *)outByte);	break;
		case GDT_UInt16:	mxFree((void *)outUI16);	break; 
		case GDT_Int16:		mxFree((void *)outI16);		break; 
		case GDT_UInt32:	mxFree((void *)outUI32);	break; 
		case GDT_Int32:		mxFree((void *)outI32);		break; 
		case GDT_Float32:	mxFree((void *)outF32);		break; 
		case GDT_Float64:	mxFree((void *)outF64);		break; 
	}

	int out_dims[3];
	out_dims[0] = nLines;
	out_dims[1] = nPixels;
	out_dims[2] = nBands;
	plhs[0] = mxCreateNumericArray (n_dims,out_dims,mxGetClassID(prhs[0]), mxREAL);
	tmp = (char *)mxCalloc(nPixels * nLines, nBytes);

	/* ------ Allocate memory to be used in filling the hDstDS dataset ---- */
	switch( typeCLASS ) {
		case GDT_Byte:
			outByte = (unsigned char *)mxGetData(plhs[0]);		break;
		case GDT_UInt16:
			outUI16 = (unsigned short int *)mxGetData(plhs[0]);	break;
		case GDT_Int16:
			outI16 = (short int *)mxGetData(plhs[0]);		break;
		case GDT_UInt32:
			outUI32 = (unsigned int *)mxGetData(plhs[0]);		break;
		case GDT_Int32:
			outI32 = (int *)mxGetData(plhs[0]);			break;
		case GDT_Float32:
			outF32 = (float *)mxGetData(plhs[0]);			break;
		case GDT_Float64:
			outF64 = (double *)mxGetData(plhs[0]);			break;
	}

	/* ----------- Copy the output hSrcDS dataset data into plhs  ---------- */
	for (i = 1; i <= nBands; i++) {
		hBand = GDALGetRasterBand( hDstDS, i ); 
		GDALRasterIO( hBand, GF_Read, 0, 0, nPixels, nLines, tmp, nPixels, nLines,
				(GDALDataType)typeCLASS, 0, 0 );
		nXYSize = (i-1) * nPixels * nLines;
		switch( typeCLASS ) {
			case GDT_Byte:
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outByte[m + n*nLines + nXYSize] = tmp[c++];
				break;
			case GDT_UInt16:
				tmpUI16 = (GUInt16 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outUI16[m + n*nLines + nXYSize] = tmpUI16[c++];
				break;
			case GDT_Int16:
				tmpI16 = (GInt16 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outI16[m + n*nLines + nXYSize] = tmpI16[c++];
				break;
			case GDT_UInt32:
				tmpUI32 = (GUInt32 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outUI32[m + n*nLines + nXYSize] = tmpUI32[c++];
				break;
			case GDT_Int32:
				tmpI32 = (GInt32 *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outI32[m + n*nLines + nXYSize] = tmpI32[c++];
				break;
			case GDT_Float32:
				tmpF32 = (float *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outF32[m + n*nLines + nXYSize] = tmpF32[c++];
				break;
			case GDT_Float64:
				tmpF64 = (double *) tmp;
				for (m = nLines-1, c = 0; m >= 0; m--) for (n = 0; n < nPixels; n++)
					outF64[m + n*nLines + nXYSize] = tmpF64[c++];
				break;
		}
	}

	mxFree(tmp);
	if (nGCPCount) {
		GDALDeinitGCPs( nGCPCount, pasGCPs );	/* makes this mex crash in the next call - Is it still true??? */
		mxFree((void *) pasGCPs );
	}

	if (nlhs == 2)
		plhs[1] = populate_metadata_struct (hDstDS, 1);

	runed_once = TRUE;	/* Signals that next call won't need to call GDALAllRegister() again */

	/*GDALDestroyDriverManager();
	OGRFree(pszDstWKT);*/
	GDALClose( hDstDS );
	CSLDestroy( papszWarpOptions );
	if (pszDstWKT && strlen(pszDstWKT) > 1 ) OGRFree(pszDstWKT);	
	if (pszSrcWKT && strlen(pszSrcWKT) > 1 ) OGRFree(pszSrcWKT);
}