KJB
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
matlab.h
Go to the documentation of this file.
1 // matlab.h - utilities to interface matlab and c/c++ via files
3 // Author: Doron Tal, based on code originally written by Bruce Fischl.
4 // Date created: June, 1995
5 //
6 // C++ header file with inlined code that reads and writes from C/C++
7 // Buffers (float or unigned char) into .mat files, which in turn can
8 // be read by Matlab. This is the only file you need.
9 
10 #ifndef _MATLAB_H
11 #define _MATLAB_H
12 
13 /*
14  * Kobus: We have run into trouble with 32 bit centric code in this
15  * distribution. I have changed some long's to kjb_int32's. The immediate
16  * problem is that the segmentation maps can get written out as 64 bit integers.
17 */
18 #include "l/l_sys_def.h"
19 
20 #include "wrap_dtlib_cpp/img.h"
21 #include <stdio.h>
22 #include <string.h>
23 
24 // CONSTANTS
25 
26 #define MAX_CHARS 2000 /* max characters allowed per filename/mat-variable */
27 
28 // MATLAB CONSTANTS
29 
30 // thousands digit
31 #define MACH_PC 0
32 #define MACH_MOTOROLA 1
33 #define MACH_VAXD 2
34 #define MACH_VADG 3
35 #define MACH_CRAY 4
36 
37 // hundreds digit is always 0
38 
39 // tens digit
40 #define TYPE_FLOAT 1
41 #define TYPE_LONG 2
42 #define TYPE_BYTE 5
43 #define TYPE_DOUBLE 0
44 #define TYPE_SHORT 3
45 #define TYPE_USHORT 4
46 
47 // ones digit
48 #define MATRIX_NUM 0
49 #define MATRIX_TEXT 1
50 #define MATRIX_SPARSE 2
51 
52 
53 #warning "[Code police] Do not put 'using namespace' in global scope of header."
54 using namespace kjb_c;
55 
56 
57 namespace DTLib {
58 
60  // INTERFACE: prototypes
62 
63  // read/write buffer
64 
65  // ***TODO*** NEED COMMENTS HERE!
66  template <class T>
67  T* ReadBufferFromMatfile(const char* strFilename,
68  T* pBuffer, int& Width, int& Height);
69 
70  template <class T>
71  bool WriteBufferToMatfile(T* pBuffer, const int Width,
72  const int Height, const char* strMatName,
73  const char* strFilename);
74 
75  // read/write image (CImg object)
76  template <class T>
77  bool ReadMatfile(CImg<T>* pInImg, const char* strFilename);
78 
79  void ReadMatheader(const char* strFilename);
80 
81  template <class T>
82  bool WriteMatfile(CImg<T>& InImg,
83  const char* strMatname,
84  const char* strFilename);
85 
86  template <class T>
87  bool WriteMatfile(CImg<T>& InImg, const char* strMatname);
88 
89  // read/write image-sequence (CImgVec object)
90  template <class T>
91  bool ReadMatfiles(CImgVec<T>& InVec, const char *strPrefix);
92  template <class T>
93  bool WriteMatfiles(CImgVec<T>& InVec, const char *strPrefix);
94  template <class T>
95  bool WriteMatfiles(const vector<CImg<T>*>& InVec, const char *strPrefix);
96 
98  // END OF INTERFACE
100 
102  // matlab-specific definitions:
104 
105  typedef struct
106  {
107  int type ;
108  int mrows ;
109  int ncols ;
110  int imagf ;
111  int namlen ;
112  } MATFILE ;
113 
114  // overloaded 'type' field number parser acc. to input type
115 
116  inline int MatlabTypeID(float* pBuffer) { return TYPE_FLOAT; }
117  inline int MatlabTypeID(unsigned char* pBuffer) { return TYPE_BYTE; }
118 
119  /*
120  inline int MatlabTypeID(int* pBuffer) { return TYPE_LONG; }
121  inline int MatlabTypeID(long* pBuffer) { return TYPE_LONG; }
122  */
123  inline int MatlabTypeID(int* pBuffer) { return TYPE_LONG; }
124 
126  // IMPLEMENTATION:
128 
130  // allocates new Buffer only if pBuffer is null, and in that case, it
131  // writes into Width & Height the correct Values.
132  // if pBuffer is not null,
133  template <class T>
134  T* ReadBufferFromMatfile(const char* strFilename,
135  T* pBuffer, int& Width, int& Height)
136  {
137  FILE *pF;
138  if ((pF = fopen(strFilename, "rb")) == NULL) {
139  return NULL;
140  }
141 
142  MATFILE matfile;
143  if (fread(&matfile, 1, sizeof(MATFILE), pF) !=
144  (unsigned int)sizeof(MATFILE)) {
145  fclose(pF);
146  return NULL;
147  }
148 
149  char name[MAX_CHARS];
150  if (fread(name, sizeof(char), matfile.namlen, pF) !=
151  (unsigned int)matfile.namlen) {
152  fclose(pF);
153  return NULL;
154  }
155 
156  const int W = matfile.ncols;
157  const int H = matfile.mrows;
158 
159  if (pBuffer == NULL) {
160  Width = W; // modify for output
161  Height = H; // modify for output
162  pBuffer = new T[Width*Height];
163  }
164  // read matrix
165  const int EltSize = sizeof(T);
166  for (int x = 0; x < W; x++)
167  for (int y = 0; y < H; y++) {
168  T Val;
169  if (fread(&Val, 1, EltSize, pF) != (unsigned int)EltSize)
170  return NULL;
171  *(pBuffer+y*W+x) = Val;
172  } // for y
173  fclose(pF);
174  return pBuffer;
175  }
176 
178 
179  template <class T>
180  bool WriteBufferToMatfile(T* pBuffer, const int Width,
181  const int Height, const char* strMatName,
182  const char* strFilename)
183  {
184  MATFILE matfile;
185  char strType[32];
186  sprintf(strType, "%d0%d%d", MACH_PC, MatlabTypeID(pBuffer),MATRIX_NUM);
187  matfile.type = atoi(strType);
188  matfile.ncols = Width;
189  matfile.mrows = Height;
190  matfile.imagf = 0 ; // no complex for now
191  matfile.namlen = strlen(strMatName)+1 ;
192 
193  FILE *pF;
194  if ((pF = fopen(strFilename, "wb")) == NULL)
195  return false;
196 
197  if(fwrite(&matfile, 1, sizeof(MATFILE), pF) !=
198  (unsigned int)sizeof(MATFILE)) {
199  fclose(pF);
200  return false;
201  }
202  if (fwrite(strMatName, 1, (int)matfile.namlen, pF) !=
203  (unsigned int)matfile.namlen) {
204  fclose(pF);
205  return false;
206  }
207  // write matllab matrix in column order
208  const int EltSize = sizeof(T);
209  for (int x = 0; x < Width; x++)
210  for (int y = 0; y < Height; y++)
211  if (fwrite(pBuffer+y*Width+x, 1, EltSize, pF) !=
212  (unsigned int)EltSize)
213  return false;
214  fclose(pF);
215  return true;
216  }
217 
219  // assumes you know the type of the file you're reading and that the
220  // current Img is preallocated
221 
222  // float version
223  template <class T>
224  bool ReadMatfile(CImg<T>& InImg, const char* strFilename)
225  {
226  if (strlen(strFilename) == 0) return false;
227 
228  char* strFopenName = NULL;
229  if (!strstr(strFilename, ".mat")) {
230  // doesn't contain extension, add it
231  char strFullFilename[MAX_CHARS];
232  sprintf(strFullFilename, "%s.mat", strFilename);
233  strFopenName = (char*)strFullFilename;
234  }
235  else strFopenName = (char*)strFilename;
236 
237  CImg<T>* pImg = &InImg;
238  if (pImg == NULL) return false;
239 
240  int Width = 0, Height = 0;
241  T *pBuffer =
242  ReadBufferFromMatfile(strFopenName, InImg.pBuffer(), Width,Height);
243  if (pBuffer == NULL) return false;
244 
245  if (InImg.IsEmpty()) {
246  InImg.Set_pBuffer(pBuffer, Width, Height);
247  }
248 
249  return true;
250  }
251 
253 
254  template <class T>
255  bool WriteMatfile(CImg<T>& InImg,
256  const char* strMatname,
257  const char* strFilename)
258  {
259  return WriteBufferToMatfile(InImg.pBuffer(),
260  InImg.Width(), InImg.Height(),
261  strMatname, strFilename);
262  }
263 
264  // same as WriteMatfile above, but no need to supply two strings
265 
266  template <class T>
267  bool WriteMatfile(CImg<T>& InImg, const char* strMatname)
268  {
269  char strFilename[MAX_CHARS];
270  sprintf(strFilename, "%s.mat", strMatname);
271  return WriteMatfile(InImg, strMatname, strFilename);
272  }
273 
275 
276  // ignores ROI
277 
278  template <class T>
279  bool ReadMatfiles(CImgVec<T>& InVec, const char *strPrefix)
280  {
281  char strFname[MAX_CHARS];
282 
283  // count how many files
284  FILE *pF;
285  int nFrames;
286 
287  for (nFrames = 0; ; nFrames++) {
288  if (nFrames < 10) sprintf(strFname, "%s_00%d.mat", strPrefix,
289  nFrames);
290  else if (nFrames < 100) sprintf(strFname, "%s_0%d.mat",
291  strPrefix, nFrames);
292  else sprintf(strFname, "%s_%d.mat", strPrefix, nFrames);
293  if ((pF = fopen(strFname, "r")) == NULL) break;
294  else fclose(pF);
295  } // for (int nFrames = 0; ; i++) {
296  if (nFrames == 0) return false;
297 
298  // read in first file to get Width & Height
299  CImg<T> tmpImg;
300  sprintf(strFname, "%s_000.mat", strPrefix);
301  if (!ReadMatfile(tmpImg, strFname)) return false;
302 
303  if (InVec.IsEmpty()) {
304  InVec.Allocate(nFrames, tmpImg.Width(), tmpImg.Height());
305  }
306 
307  for (int i = 0; i < InVec.nFrames(); i++) {
308  if (i < 10) sprintf(strFname, "%s_00%d.mat", strPrefix, i);
309  else if (i < 100) sprintf(strFname, "%s_0%d.mat", strPrefix, i);
310  else sprintf(strFname, "%s_%d.mat", strPrefix, i);
311  if (!ReadMatfile(*(InVec.GetImg(i)), strFname)) return false;
312  }
313  return true;
314  }
315 
317 
318  template <class T>
319  bool WriteMatfiles(CImgVec<T>& InVec, const char *strPrefix)
320  {
321  char strFilename[MAX_CHARS];
322  char strMatName[MAX_CHARS];
323  for (int i = 0; i < InVec.nFrames(); i++) {
324  if (i < 10) sprintf(strMatName, "%s_00%d", strPrefix, i);
325  else if (i < 100) sprintf(strMatName, "%s_0%d", strPrefix, i);
326  else sprintf(strMatName, "%s_%d", strPrefix, i);
327  sprintf(strFilename, "%s.mat", strMatName);
328  if (!WriteMatfile(*(InVec.GetImg(i)), strMatName, strFilename))
329  return false;
330  }
331  return true;
332  }
333 
335 
336  template <class T>
337  bool WriteMatfiles(const vector<CImg<T>*>& InVec, const char *strPrefix)
338  {
339  char strFilename[MAX_CHARS];
340  char strMatName[MAX_CHARS];
341  const int nFrames = InVec.size();
342  for (int i = 0; i < nFrames; i++) {
343  if (i < 10) sprintf(strMatName, "%s_00%d", strPrefix, i);
344  else if (i < 100) sprintf(strMatName, "%s_0%d", strPrefix, i);
345  else sprintf(strMatName, "%s_%d", strPrefix, i);
346  sprintf(strFilename, "%s.mat", strMatName);
347  if (!WriteMatfile(*(InVec[i]), strMatName, strFilename))
348  return false;
349  }
350  return true;
351  }
352 
353 } // namespace DTLib;
354 
355 #endif /* #ifndef _MATLAB_H */
#define TYPE_LONG
Definition: matlab.h:41
T * ReadBufferFromMatfile(const char *strFilename, T *pBuffer, int &Width, int &Height)
Definition: matlab.h:134
int namlen
Definition: matlab.h:111
bool ReadMatfile(CImg< T > &InImg, const char *strFilename)
Definition: matlab.h:224
bool WriteBufferToMatfile(T *pBuffer, const int Width, const int Height, const char *strMatName, const char *strFilename)
Definition: matlab.h:180
end fclose(fid)
#define MAX_CHARS
Definition: matlab.h:26
bool WriteMatfile(CImg< T > &InImg, const char *strMatname)
Definition: matlab.h:267
void ReadMatheader(const char *strFilename)
Definition: img.h:51
#define TYPE_FLOAT
Definition: matlab.h:40
int Width() const
Definition: img.h:135
#define TYPE_BYTE
Definition: matlab.h:42
Definition: matlab.h:105
bool WriteMatfiles(const vector< CImg< T > * > &InVec, const char *strPrefix)
Definition: matlab.h:337
x
Definition: APPgetLargeConnectedEdges.m:100
#define MACH_PC
Definition: matlab.h:31
int MatlabTypeID(int *pBuffer)
Definition: matlab.h:123
int ncols
Definition: matlab.h:109
bool ReadMatfiles(CImgVec< T > &InVec, const char *strPrefix)
Definition: matlab.h:279
Definition: img.h:42
int type
Definition: matlab.h:107
int Height() const
Definition: img.h:138
#define W(X)
Definition: Wide.h:45
int imagf
Definition: matlab.h:110
bool Allocate(const int nFrames, const int Width, const int Height, bool bZero=false)
Definition: img.h:2450
int mrows
Definition: matlab.h:108
get the indices of edges in each direction for i
Definition: APPgetLargeConnectedEdges.m:48
void Set_pBuffer(const T *pBuf, const int Width, const int Height, const bool bCopy=false)
IMPLEMENTATION.
Definition: img.h:592
bool IsEmpty()
Definition: img.h:2504
T * pBuffer()
Definition: img.h:148
bool IsEmpty()
Definition: img.h:190
#define MATRIX_NUM
Definition: matlab.h:48
int nFrames()
Definition: img.h:534
CImg< T > * GetImg(const int &i)
Definition: img.h:539