13 class Array2dFileLabel
17 Array2dFileLabel (const Array2dFileLabel&);
18 Array2dFileLabel& operator= (const Array2dFileLabel&);
30 mutable string m_strDate;
32 static const int L_EMPTY = 0;
33 static const int L_HISTORY = 1;
34 static const int L_USER = 2;
38 Array2dFileLabel(const char* const str, double ctime = 0.);
40 Array2dFileLabel(const int type, const char* const str, double ctime = 0.);
44 const string& getLabelString (void) const
45 { return m_strLabel; }
47 kfloat64 getCalcTime (void) const
48 { return m_calcTime; }
50 kfloat64 getLabelType (void) const
51 { return m_labelType; }
53 string& setLabelString (const char* const str)
54 { m_strLabel = str; return (m_strLabel); }
56 string& setLabelString (const string& str)
57 { m_strLabel = str; return (m_strLabel); }
59 const string& getDateString () const;
77 bool headerWrite (void);
79 bool headerRead (void);
81 bool arrayDataRead (void);
83 bool labelSeek (unsigned int label_num);
86 kuint16 axis_increment_known;
87 kfloat64 mIncX, mIncY;
88 kuint16 axis_extent_known;
89 kfloat64 mMinX, mMaxX, mMinY, mMaxY;
90 kfloat64 mOffsetPV, mScalePV;
95 Array2dFile (const Array2dFile&);
96 Array2dFile& operator= (const Array2dFile&);
102 static const int INT8 = 1;
103 static const int UINT8 = 2;
104 static const int INT16 = 3;
105 static const int UINT16 = 4;
106 static const int INT32 = 5;
107 static const int UINT32 = 6;
108 static const int FLOAT32 = 7;
109 static const int FLOAT64 = 8;
111 Array2dFile (unsigned int nx, unsigned int ny);
112 Array2dFile (const char* const filename);
113 Array2dFile (const char* const filename, unsigned int nx, unsigned int ny);
116 unsigned int getNumLabels (void) const
117 { return num_labels; }
119 bool labelRead (Array2dFileLabel& label, unsigned int label_num);
121 void labelAdd (const Array2dFileLabel& label);
123 void labelAdd (const char* const m_strLabel, double calc_time=0.);
125 void labelAdd (int type, const char* const m_strLabel, double calc_time=0.);
127 void labelsCopy (Array2dFile& file, const char* const idStr = NULL);
129 void fileClose (void);
131 void setPixelType (int type)
132 { mPixelType = type; }
134 kuint32 nx (void) const
137 kuint32 ny (void) const
140 void setAxisIncrement (double mIncX, double mIncY);
142 void setAxisExtent (double mMinX, double mMaxX, double mMinY, double mMaxY);
144 void getPixelValueRange (T& pvmin, T& pvmax) const;
146 void doPixelOffsetScale (double offset, double scale);
148 T** getArray (void) const
149 { return (array.getArray()); }
151 bool arrayDataWrite (void);
153 void arrayDataClear (void);
155 bool fileRead (void);
157 bool fileCreate (void);
159 const string& GetFilename (void) const
165 Array2dFile<T>::Array2dFile (unsigned int x, unsigned int y)
170 array.initSetSize(mNX, mNY);
174 Array2dFile<T>::Array2dFile (const char * const str, unsigned int x, unsigned int y)
180 array.initSetSize(mNX, mNY);
184 Array2dFile<T>::Array2dFile (const char * const str)
192 Array2dFile<T>::init (void)
194 mPixelSize = sizeof(T);
195 signature = ('I' * 256 + 'F');
201 axis_increment_known = false;
202 axis_extent_known = false;
204 mMinX = mMaxX = mMinY = mMaxY = 0;
210 const type_info& t_id = typeid(T);
211 cout << t_id.name() << endl;
212 const type_info& comp_id = typeid(T);
215 mPixelType = FLOAT64;
216 else if (t_id == typeid(kfloat32))
217 mPixelType = FLOAT32;
218 else if (t_id == typeid(kint32))
220 else if (t_id == typeid(kuint32))
222 else if (t_id == typeid(kint16))
224 else if (t_id == typeid(kuint16))
226 else if (t_id == typeid(kint8))
228 else if (t_id == typeid(kuint8))
234 bHeaderWritten = false;
235 bDataWritten = false;
239 Array2dFile<T>::~Array2dFile (void)
247 Array2dFile<T>::fileClose (void)
258 Array2dFile<T>::fileCreate (void)
260 // io = new iostream(filename, ios::out | ios::in | ios::trunc | io::binary);
261 if ((file_id = open (filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
262 sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", filename.c_str());
271 Array2dFile<T>::fileRead (void)
273 // io = new iostream(filename, ios::out | ios::in | io::binary);
274 if ((file_id = open (filename.c_str(), O_RDONLY | O_BINARY)) < 0) {
275 sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", filename.c_str());
281 array.initSetSize(mNX, mNY);
290 Array2dFile<T>::setAxisIncrement (double incX, double incY)
292 axis_increment_known = true;
299 Array2dFile<T>::setAxisExtent (double minX, double maxX, double minY, double maxY)
301 axis_extent_known = true;
310 Array2dFile<T>::getPixelValueRange (T& pvmin, T& pvmax) const
312 T** da = array.getArray();
314 pvmax = pvmin = da[0][0];
315 for (int ix = 0; ix < mNX; ix++)
316 for (int iy = 0; iy < mNY; iy++)
317 if (pvmax < da[ix][iy])
319 else if (pvmin > da[ix][iy])
326 Array2dFile<T>::doPixelOffsetScale (double offset, double scale)
328 T** ad = array.getArray();
333 for (unsigned int ix = 0; ix < mNX; ix++)
334 for (unsigned int iy = 0; iy < mNY; iy++)
335 ad[ix][iy] = (ad[ix][iy] - offset) * scale;
341 Array2dFile<T>::headerRead (void)
344 sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
348 lseek (file_id, 0, SEEK_SET);
349 kuint16 file_signature;
350 kuint16 file_mPixelSize;
351 kuint16 file_mPixelType;
353 read_nint16 (&headersize, file_id);
354 read_nint16 (&file_signature, file_id);
355 read_nint16 (&num_labels, file_id);
356 read_nint16 (&file_mPixelType, file_id);
357 read_nint16 (&file_mPixelSize, file_id);
358 read_nint32 (&mNX, file_id);
359 read_nint32 (&mNY, file_id);
360 read_nint16 (&axis_increment_known, file_id);
361 read_nfloat64 (&mIncX, file_id);
362 read_nfloat64 (&mIncY, file_id);
363 read_nint16 (&axis_extent_known, file_id);
364 read_nfloat64 (&mMinX, file_id);
365 read_nfloat64 (&mMaxX, file_id);
366 read_nfloat64 (&mMinY, file_id);
367 read_nfloat64 (&mMaxY, file_id);
368 read_nfloat64 (&mOffsetPV, file_id);
369 read_nfloat64 (&mScalePV, file_id);
371 int read_headersize = lseek (file_id, 0, SEEK_CUR);
372 if (read_headersize != headersize) {
373 sys_error (ERR_WARNING, "Read headersize %d != file headersize %d", read_headersize, headersize);
376 if (file_signature != signature) {
377 sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, signature);
380 if (file_mPixelType != mPixelType) {
381 sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_mPixelType, mPixelType);
384 if (file_mPixelSize != mPixelSize) {
385 sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_mPixelSize, mPixelSize);
394 Array2dFile<T>::headerWrite (void)
397 sys_error (ERR_WARNING, "Tried to write header with file closed");
401 lseek (file_id, 0, SEEK_SET);
402 write_nint16 (&headersize, file_id);
403 write_nint16 (&signature, file_id);
404 write_nint16 (&num_labels, file_id);
405 write_nint16 (&mPixelType, file_id);
406 write_nint16 (&mPixelSize, file_id);
407 write_nint32 (&mNX, file_id);
408 write_nint32 (&mNY, file_id);
409 write_nint16 (&axis_increment_known, file_id);
410 write_nfloat64 (&mIncX, file_id);
411 write_nfloat64 (&mIncY, file_id);
412 write_nint16 (&axis_extent_known, file_id);
413 write_nfloat64 (&mMinX, file_id);
414 write_nfloat64 (&mMaxX, file_id);
415 write_nfloat64 (&mMinY, file_id);
416 write_nfloat64 (&mMaxY, file_id);
417 write_nfloat64 (&mOffsetPV, file_id);
418 write_nfloat64 (&mScalePV, file_id);
420 headersize = lseek (file_id, 0, SEEK_CUR);
421 lseek (file_id, 0, SEEK_SET);
422 write_nint16 (&headersize, file_id);
429 Array2dFile<T>::arrayDataWrite (void)
432 sys_error (ERR_WARNING, "Tried to arrayDataWrite with file_id < 0");
436 T** da = array.getArray();
440 lseek (file_id, headersize, SEEK_SET);
441 for (unsigned int ix = 0; ix < mNX; ix++)
442 for (unsigned int iy = 0; iy < mNY; iy++) {
443 T value = da[ix][iy];
444 ConvertReverseNetworkOrder (&value, sizeof(T));
445 write (file_id, &value, mPixelSize);
453 Array2dFile<T>::arrayDataRead (void)
456 sys_error (ERR_WARNING, "Tried to arrayDataRead with file_id < 0");
460 T** da = array.getArray();
464 lseek (file_id, headersize, SEEK_SET);
466 for (int ix = 0; ix < mNX; ix++)
467 for (unsigned int iy = 0; iy < mNY; iy++) {
468 read (file_id, &pixelBuffer, mPixelSize);
469 ConvertReverseNetworkOrder (&pixelBuffer, sizeof(T));
470 da[ix][iy] = pixelBuffer;
478 Array2dFile<T>::labelSeek (unsigned int label_num)
480 if (label_num > num_labels) {
481 sys_error (ERR_WARNING, "label_num %d > num_labels %d [labelSeek]");
485 if (array.getArray() == NULL) { // Could not have written data if array not allocated
486 sys_error (ERR_WARNING, "array == NULL [labelSeek]");
490 off_t pos = headersize + array.sizeofArray();
491 if (lseek (file_id, pos, SEEK_SET) != pos) {
492 sys_error (ERR_WARNING, "Can't seek to end of data array");
496 for (int i = 0; i < label_num; i++)
498 pos += 22; // Skip to string length
499 if (lseek (file_id, pos, SEEK_SET) != pos) {
500 sys_error (ERR_WARNING, "Can't seek to string length");
504 read_nint16 (&strlength, file_id);
505 pos += 2 + strlength; // Skip label string length + data
506 if (lseek (file_id, pos, SEEK_SET) != pos) {
507 sys_error (ERR_WARNING, "Can't seek past label string");
517 Array2dFile<T>::labelRead (Array2dFileLabel& label, unsigned int label_num)
519 if (label_num >= num_labels) {
520 sys_error (ERR_WARNING, "Trying to read past number of labels [labelRead]");
524 if (! labelSeek (label_num)) {
525 sys_error (ERR_WARNING, "Error calling labelSeek");
529 read_nint16 (&label.m_labelType, file_id);
530 read_nint16 (&label.m_year, file_id);
531 read_nint16 (&label.m_month, file_id);
532 read_nint16 (&label.m_day, file_id);
533 read_nint16 (&label.m_hour, file_id);
534 read_nint16 (&label.m_minute, file_id);
535 read_nint16 (&label.m_second, file_id);
536 read_nfloat64 (&label.m_calcTime, file_id);
539 read_nint16 (&strlength, file_id);
540 char str [strlength+1];
541 read (file_id, str, strlength);
543 label.m_strLabel = str;
551 Array2dFile<T>::labelAdd (const char* const lstr, double calc_time=0.)
553 labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time);
558 Array2dFile<T>::labelAdd (int type, const char* const lstr, double calc_time=0.)
560 Array2dFileLabel label (type, lstr, calc_time);
567 Array2dFile<T>::labelAdd (const Array2dFileLabel& label)
569 labelSeek (num_labels);
571 write_nint16 (&label.m_labelType, file_id);
572 write_nint16 (&label.m_year, file_id);
573 write_nint16 (&label.m_month, file_id);
574 write_nint16 (&label.m_day, file_id);
575 write_nint16 (&label.m_hour, file_id);
576 write_nint16 (&label.m_minute, file_id);
577 write_nint16 (&label.m_second, file_id);
578 write_nfloat64 (&label.m_calcTime, file_id);
579 kuint16 strlength = label.m_strLabel.length();
580 write_nint16 (&strlength, file_id);
581 write (file_id, static_cast<const void*>(label.m_strLabel.c_str()), strlength);
591 Array2dFile<T>::labelsCopy (Array2dFile& copyFile, const char* const idStr)
594 for (int i = 0; i < copyFile.getNumLabels(); i++) {
596 copyFile.labelRead (l, i);
597 string lstr = l.getLabelString();
599 l.setLabelString (lstr);
606 Array2dFile<T>::arrayDataClear (void)
608 T** v = array.getArray();
610 for (unsigned int ix = 0; ix < mNX; ix++)
611 for (unsigned int iy = 0; iy < mNY; iy++)
621 class F32Image : public Array2dFile<kfloat32>
624 F32Image (const char* const fname, unsigned int nx, unsigned int ny)
625 : Array2dFile<kfloat32>::Array2dFile (fname, nx, ny)
627 setPixelType (FLOAT32);
630 F32Image (unsigned int nx, unsigned int ny)
631 : Array2dFile<kfloat32>::Array2dFile (nx, ny)
633 setPixelType (FLOAT32);
636 F32Image (const char* const fname)
637 : Array2dFile<kfloat32>::Array2dFile (fname)
639 setPixelType (FLOAT32);
643 MPI::Datatype getMPIDataType (void) const
644 { return MPI::FLOAT; }
649 class F64Image : public Array2dFile<kfloat64>
653 F64Image (const char* const fname, unsigned int nx, unsigned int ny)
654 : Array2dFile<kfloat64>::Array2dFile (fname, nx, ny)
656 setPixelType (FLOAT64);
659 F64Image (unsigned int nx, unsigned int ny)
660 : Array2dFile<kfloat64>::Array2dFile (nx, ny)
662 setPixelType (FLOAT64);
665 F64Image (const char* const fname)
666 : Array2dFile<kfloat64>::Array2dFile (fname)
668 setPixelType (FLOAT64);
672 MPI::Datatype getMPIDataType (void) const
673 { return MPI::DOUBLE; }
677 #define IMAGEFILE_64_BITS 1
678 #ifdef IMAGEFILE_64_BITS
679 typedef F64Image ImageFile;
680 typedef kfloat64 ImageFileValue;
681 typedef kfloat64* ImageFileColumn;
682 typedef kfloat64** ImageFileArray;
684 typedef F32Image ImageFile;
685 typedef kfloat32 ImageFileValue;
686 typedef kfloat32* ImageFileColumn;
687 typedef kfloat32** ImageFileArray;