File: icswrite.c

package info (click to toggle)
libics 1.7.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 5,196 kB
  • sloc: ansic: 8,873; sh: 4,461; cpp: 770; makefile: 148
file content (146 lines) | stat: -rw-r--r-- 4,424 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
/* ICSWRITE   Writes a numeric array to an ICS file.
 *     ICSWRITE(A,FILENAME,COMPRESS) writes the numeric data
 *     in A to an ICS image file named FILENAME. If COMPRESS
 *     is non-zero the data will be written compressed.
 *
 *     Known limitations:
 *        - Complex data is not written.
 *
 * Copyright (C) 2000-2007 Cris Luengo and others
 */

/* For MATLAB 7.2 and older, uncomment the following line: */
/* typedef int mwSize; */

#include "mex.h"
#include <string.h>
#include "libics.h"
#define ERROR_MESSAGE_LEN 2048

void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]) {
   ICS* ip;
   Ics_DataType dt;
   int ndims;
   const mwSize* mx_dims;
   size_t dims[ICS_MAXDIM];
   ptrdiff_t strides[ICS_MAXDIM];
   size_t bufsize;
   void* buf;
   Ics_Error retval;
   mxClassID class;
   char filename[ICS_MAXPATHLEN];
   int elemsize, compress = 0;
   int ii;
   size_t tmp;
   char errormessage[ERROR_MESSAGE_LEN];

   if (strcmp (ICSLIB_VERSION, IcsGetLibVersion ()))
      mexErrMsgTxt ("Linking against the wrong version of the library.");

   /* There should be no output arguments. */
   if (nlhs > 0)
      mexErrMsgTxt ("Too many output arguments.");

   /* There should be two or three input arguments. */
   if (nrhs > 3)
      mexErrMsgTxt ("Too many input arguments.");
   if (nrhs < 2)
      mexErrMsgTxt ("Not enough input arguments.");

   /* First input argument. */
   class = mxGetClassID (prhs[0]);
   switch (class) {
      case mxDOUBLE_CLASS:
         dt = Ics_real64;
         elemsize = 8;
         break;
      case mxSINGLE_CLASS:
         dt = Ics_real32;
         elemsize = 4;
         break;
      case mxINT8_CLASS:
         dt = Ics_sint8;
         elemsize = 1;
         break;
      case mxUINT8_CLASS:
         dt = Ics_uint8;
         elemsize = 1;
         break;
      case mxINT16_CLASS:
         dt = Ics_sint16;
         elemsize = 2;
         break;
      case mxUINT16_CLASS:
         dt = Ics_uint16;
         elemsize = 2;
         break;
      case mxINT32_CLASS:
         dt = Ics_sint32;
         elemsize = 4;
         break;
      case mxUINT32_CLASS:
         dt = Ics_uint32;
         elemsize = 4;
         break;
      default:
         mexErrMsgTxt ("Input array should be numeric.");
   }
   if (mxIsComplex (prhs[0]))
      mexErrMsgTxt ("Cannot write complex data (I'm too lazy).");
   buf = mxGetData (prhs[0]);
   ndims = (int)mxGetNumberOfDimensions (prhs[0]);
   mx_dims = mxGetDimensions (prhs[0]);
   for (ii=0;ii<ndims;ii++)
      dims[ii] = (size_t)(mx_dims[ii]);
   strides[0] = 1;
   for (ii=1;ii<ndims;ii++)
      strides[ii] = strides[ii-1]*dims[ii-1];
   if (ndims>1) {
      /* This is to swap the first two dimensions; MATLAB does y-x-z indexing. */
      tmp = dims[0];
      dims[0] = dims[1];
      dims[1] = tmp;
      strides[0] = dims[1];
      strides[1] = 1;
   }
   bufsize = mxGetNumberOfElements (prhs[0]) * elemsize;

   /* Second input argument. */
   filename[0] = '\0';
   if (mxGetString (prhs[1], filename, ICS_MAXPATHLEN)) {
      if (filename[0] == '\0')
         mexErrMsgTxt ("FILENAME should be a character array.");
      else
         mexErrMsgTxt ("The given filename is too long.");
   }

   /* Third input argument. */
   if (nrhs > 2) {
      /* No checking whatsoever! */
      compress = (mxGetScalar (prhs[2]) != 0);
   }

   /* Now we know everything we need to write the data. */
   retval = IcsOpen (&ip, filename, "w1");
   if (retval != IcsErr_Ok) {
      snprintf (errormessage, ERROR_MESSAGE_LEN, "Couldn't open the file for writing: %s", IcsGetErrorText (retval));
      mexErrMsgTxt (errormessage);
   }
   IcsSetLayout (ip, dt, ndims, dims);
   retval = IcsGuessScilType (ip);
   if (retval == IcsErr_NoScilType)
      mexWarnMsgTxt ("Couldn't create a SCIL_TYPE string.");
   retval = IcsSetDataWithStrides (ip, buf, bufsize, strides, ndims);
   if (retval != IcsErr_Ok) {
      snprintf (errormessage, ERROR_MESSAGE_LEN, "Failed to set the data: %s", IcsGetErrorText (retval));
      mexErrMsgTxt (errormessage);
   }
   if (compress)
      IcsSetCompression (ip, IcsCompr_gzip, 0);
   IcsAddHistory (ip, "software", "ICSWRITE under MATLAB with libics");
   retval = IcsClose (ip);
   if (retval != IcsErr_Ok) {
      snprintf (errormessage, ERROR_MESSAGE_LEN, "Failed to create the ICS file: %s", IcsGetErrorText (retval));
      mexErrMsgTxt (errormessage);
   }
}