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); } }
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); }
//------------------------------------------------------------------- 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; } } } }
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; }
//============================================================================= // 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); } }
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; }
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; }
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); }
/// 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; }
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); } }
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); }
/* 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); }