1 #include <string.h>
2 #include "mex.h"
3 
4 #include <segyio/segy.h>
5 #include "segyutil.h"
6 
createPLHSStruct()7 mxArray *createPLHSStruct() {
8     int nfields = 11;
9     const char *fnames[nfields];
10 
11     fnames[0] = "filename";
12     fnames[1] = "sample_format";
13     fnames[2] = "crossline_indexes";
14     fnames[3] = "inline_indexes";
15     fnames[4] = "sample_indexes";
16     fnames[5] = "trace_sorting_format";
17     fnames[6] = "offset_count";
18     fnames[7] = "first_trace_pos";
19     fnames[8] = "il_stride";
20     fnames[9] = "xl_stride";
21     fnames[10] = "trace_bsize";
22 
23     mxArray *plhs = mxCreateStructMatrix(1,1,nfields,fnames);
24 
25     return plhs;
26 }
27 
28 
checkInputOutputSizes(int nlhs,int nrhs)29 void checkInputOutputSizes(int nlhs, int nrhs ) {
30 
31     /* check for proper number of arguments */
32     if(nrhs!=5) {
33         mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nrhs","Four inputs required.");
34     }
35     if(nlhs!=1) {
36         mexErrMsgIdAndTxt("MyToolbox:arrayProduct:nlhs","One output required.");
37     }
38 
39 }
40 
checkInputOutput(int nlhs,mxArray ** plhs,int nrhs,const mxArray ** prhs)41 void checkInputOutput(int nlhs, mxArray **plhs,
42                       int nrhs, const mxArray **prhs) {
43 
44     checkInputOutputSizes(nlhs, nrhs);
45 
46     /* First input must be a string */
47     if ( mxIsChar(prhs[0]) != 1) {
48         mexErrMsgIdAndTxt("SegyIo:segyspec:inputNotString",
49                           "Input must be a string.");
50     }
51 
52     /* First input must be a row vector */
53     if (mxGetM(prhs[0])!=1) {
54         mexErrMsgIdAndTxt("SegyIo:segyspec:inputNotVector",
55                           "Input must be a row vector.");
56     }
57 
58     /* make sure the second input argument is int */
59     if( !mxIsNumeric(prhs[1]) ||
60         mxGetNumberOfElements(prhs[1])!=1 ) {
61         mexErrMsgIdAndTxt("SegyIo:segyspec:notScalar","Input multiplier must be a numeric.");
62     }
63 
64     /* make sure the third input argument is int */
65     if( !mxIsNumeric(prhs[2]) ||
66         mxGetNumberOfElements(prhs[2])!=1 ) {
67         mexErrMsgIdAndTxt("SegyIo:segyspec:notScalar","Input multiplier must be a numeric.");
68     }
69 
70     /* make sure the fourth input argument is double */
71     if( !mxIsDouble(prhs[3]) ||
72         mxGetNumberOfElements(prhs[3])!=1 ) {
73         mexErrMsgIdAndTxt("SegyIo:segyspec:notScalar","Input multiplier must be a double.");
74     }
75 
76     /* make sure the fifth input argument is double */
77     if( !mxIsDouble(prhs[4]) ||
78         mxGetNumberOfElements(prhs[4])!=1 ) {
79         mexErrMsgIdAndTxt("SegyIo:segyspec:notScalar","Input multiplier must be a double.");
80     }
81 
82 
83 }
84 
85 /* The gateway function */
mexFunction(int nlhs,mxArray * plhs[],int nrhs,const mxArray * prhs[])86 void mexFunction( int nlhs, mxArray *plhs[],
87                   int nrhs, const mxArray *prhs[]) {
88 
89     plhs[0] = createPLHSStruct();
90 
91     checkInputOutput(nlhs, plhs, nrhs, prhs);
92     char *filename = mxArrayToString(prhs[0]);
93 
94     int il = (int)mxGetScalar(prhs[1]);
95     int xl = (int)mxGetScalar(prhs[2]);
96     double t0 = mxGetScalar(prhs[3]);
97     double dt = mxGetScalar(prhs[4]);
98 
99     SegySpec spec;
100     int errc = segyCreateSpec(&spec, filename, il, xl, t0 * 1000.0, dt);
101     if (errc != 0) {
102         goto FAILURE;
103     }
104     mxSetFieldByNumber(plhs[0], 0, 0, mxCreateString(spec.filename));
105 
106     mxSetFieldByNumber(plhs[0], 0, 1, mxCreateDoubleScalar(spec.sample_format));
107 
108     mxArray *crossline_indexes = mxCreateDoubleMatrix(spec.crossline_count, 1, mxREAL);
109     double *crossline_indexes_ptr = mxGetPr(crossline_indexes);
110     for (int i = 0; i < spec.crossline_count; i++) {
111         crossline_indexes_ptr[i] = spec.crossline_indexes[i];
112     }
113     mxSetFieldByNumber(plhs[0], 0, 2, crossline_indexes);
114 
115     mxArray *inline_indexes = mxCreateDoubleMatrix(spec.inline_count, 1, mxREAL);
116     double *inline_indexes_ptr = mxGetPr(inline_indexes);
117     for (int i = 0; i < spec.inline_count; i++) {
118         inline_indexes_ptr[i] = spec.inline_indexes[i];
119     }
120     mxSetFieldByNumber(plhs[0], 0, 3, inline_indexes);
121 
122     mxArray *mx_sample_indexes = mxCreateDoubleMatrix(spec.sample_count,1, mxREAL);
123     double *mx_sample_indexes_ptr = mxGetPr(mx_sample_indexes);
124     for (int i = 0; i < spec.sample_count; i++) {
125         mx_sample_indexes_ptr[i] = spec.sample_indices[i];
126     }
127     mxSetFieldByNumber(plhs[0], 0, 4, mx_sample_indexes);
128 
129     mxSetFieldByNumber(plhs[0], 0, 5, mxCreateDoubleScalar(spec.trace_sorting_format));
130     mxSetFieldByNumber(plhs[0], 0, 6, mxCreateDoubleScalar(spec.offset_count));
131     mxSetFieldByNumber(plhs[0], 0, 7, mxCreateDoubleScalar(spec.first_trace_pos));
132     mxSetFieldByNumber(plhs[0], 0, 8, mxCreateDoubleScalar(spec.il_stride));
133     mxSetFieldByNumber(plhs[0], 0, 9, mxCreateDoubleScalar(spec.xl_stride));
134     mxSetFieldByNumber(plhs[0], 0, 10, mxCreateDoubleScalar(spec.trace_bsize));
135 
136     if (spec.crossline_indexes != NULL)
137         free(spec.crossline_indexes);
138     if (spec.inline_indexes != NULL)
139         free(spec.inline_indexes);
140     free(spec.sample_indices);
141     if (spec.filename != NULL)
142         free(spec.filename);
143     mxFree(filename);
144 
145     return;
146 
147     FAILURE:
148     {
149         int nfields = 1;
150         const char *fnames[nfields];
151         fnames[0] = "error";
152         plhs[0] = mxCreateStructMatrix(0,0, nfields, fnames);
153     }
154     mxFree(filename);
155 
156 }
157