12 class Array2dFileLabel
16 Array2dFileLabel (const Array2dFileLabel&);
17 Array2dFileLabel& operator= (const Array2dFileLabel&);
29 mutable string m_strDate;
31 static const int L_EMPTY = 0;
32 static const int L_HISTORY = 1;
33 static const int L_USER = 2;
37 Array2dFileLabel(const char* const str, double ctime = 0.);
39 Array2dFileLabel(const int type, const char* const str, double ctime = 0.);
43 const string& getLabelString (void) const
44 { return m_strLabel; }
46 kfloat64 getCalcTime (void) const
47 { return m_calcTime; }
49 kfloat64 getLabelType (void) const
50 { return m_labelType; }
52 string& setLabelString (const char* const str)
53 { m_strLabel = str; return (m_strLabel); }
55 string& setLabelString (const string& str)
56 { m_strLabel = str; return (m_strLabel); }
58 const string& getDateString () const;
76 bool headerWrite (void);
78 bool headerRead (void);
80 bool arrayDataRead (void);
82 bool labelSeek (unsigned int label_num);
85 kuint16 axis_increment_known;
86 kfloat64 mIncX, mIncY;
87 kuint16 axis_extent_known;
88 kfloat64 mMinX, mMaxX, mMinY, mMaxY;
89 kfloat64 mOffsetPV, mScalePV;
94 Array2dFile (const Array2dFile&);
95 Array2dFile& operator= (const Array2dFile&);
101 static const int INT8 = 1;
102 static const int UINT8 = 2;
103 static const int INT16 = 3;
104 static const int UINT16 = 4;
105 static const int INT32 = 5;
106 static const int UINT32 = 6;
107 static const int FLOAT32 = 7;
108 static const int FLOAT64 = 8;
110 Array2dFile (unsigned int nx, unsigned int ny);
111 Array2dFile (const char* const filename);
112 Array2dFile (const char* const filename, unsigned int nx, unsigned int ny);
115 unsigned int getNumLabels (void) const
116 { return num_labels; }
118 bool labelRead (Array2dFileLabel& label, unsigned int label_num);
120 void labelAdd (const Array2dFileLabel& label);
122 void labelAdd (const char* const m_strLabel, double calc_time=0.);
124 void labelAdd (int type, const char* const m_strLabel, double calc_time=0.);
126 void labelsCopy (Array2dFile& file, const char* const idStr = NULL);
128 void fileClose (void);
130 void setPixelType (int type)
131 { mPixelType = type; }
133 kuint32 nx (void) const
136 kuint32 ny (void) const
139 void setAxisIncrement (double mIncX, double mIncY);
141 void setAxisExtent (double mMinX, double mMaxX, double mMinY, double mMaxY);
143 void getPixelValueRange (T& pvmin, T& pvmax) const;
145 void doPixelOffsetScale (double offset, double scale);
147 T** getArray (void) const
148 { return (array.getArray()); }
150 bool arrayDataWrite (void);
152 void arrayDataClear (void);
154 bool fileRead (void);
156 bool fileCreate (void);
158 const string& GetFilename (void) const
164 Array2dFile<T>::Array2dFile (unsigned int x, unsigned int y)
169 array.initSetSize(mNX, mNY);
173 Array2dFile<T>::Array2dFile (const char * const str, unsigned int x, unsigned int y)
179 array.initSetSize(mNX, mNY);
183 Array2dFile<T>::Array2dFile (const char * const str)
191 Array2dFile<T>::init (void)
193 mPixelSize = sizeof(T);
194 signature = ('I' * 256 + 'F');
200 axis_increment_known = false;
201 axis_extent_known = false;
203 mMinX = mMaxX = mMinY = mMaxY = 0;
209 const type_info& t_id = typeid(T);
210 cout << t_id.name() << endl;
211 const type_info& comp_id = typeid(T);
214 mPixelType = FLOAT64;
215 else if (t_id == typeid(kfloat32))
216 mPixelType = FLOAT32;
217 else if (t_id == typeid(kint32))
219 else if (t_id == typeid(kuint32))
221 else if (t_id == typeid(kint16))
223 else if (t_id == typeid(kuint16))
225 else if (t_id == typeid(kint8))
227 else if (t_id == typeid(kuint8))
233 bHeaderWritten = false;
234 bDataWritten = false;
238 Array2dFile<T>::~Array2dFile (void)
246 Array2dFile<T>::fileClose (void)
257 Array2dFile<T>::fileCreate (void)
259 // io = new iostream(filename, ios::out | ios::in | ios::trunc | io::binary);
260 if ((file_id = open (filename.c_str(), O_RDWR | O_CREAT | O_TRUNC | O_BINARY, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH)) < 0) {
261 sys_error (ERR_WARNING, "Error opening file %s for writing [fileCreate]", filename.c_str());
270 Array2dFile<T>::fileRead (void)
272 // io = new iostream(filename, ios::out | ios::in | io::binary);
273 if ((file_id = open (filename.c_str(), O_RDONLY | O_BINARY)) < 0) {
274 sys_error (ERR_WARNING, "Unable to open file %s [fileRead]", filename.c_str());
280 array.initSetSize(mNX, mNY);
289 Array2dFile<T>::setAxisIncrement (double incX, double incY)
291 axis_increment_known = true;
298 Array2dFile<T>::setAxisExtent (double minX, double maxX, double minY, double maxY)
300 axis_extent_known = true;
309 Array2dFile<T>::getPixelValueRange (T& pvmin, T& pvmax) const
311 T** da = array.getArray();
313 pvmax = pvmin = da[0][0];
314 for (int ix = 0; ix < mNX; ix++)
315 for (int iy = 0; iy < mNY; iy++)
316 if (pvmax < da[ix][iy])
318 else if (pvmin > da[ix][iy])
325 Array2dFile<T>::doPixelOffsetScale (double offset, double scale)
327 T** ad = array.getArray();
332 for (unsigned int ix = 0; ix < mNX; ix++)
333 for (unsigned int iy = 0; iy < mNY; iy++)
334 ad[ix][iy] = (ad[ix][iy] - offset) * scale;
340 Array2dFile<T>::headerRead (void)
343 sys_error (ERR_WARNING, "Tried to read header with file closed [headerRead]");
347 lseek (file_id, 0, SEEK_SET);
348 kuint16 file_signature;
349 kuint16 file_mPixelSize;
350 kuint16 file_mPixelType;
352 read_nint16 (&headersize, file_id);
353 read_nint16 (&file_signature, file_id);
354 read_nint16 (&num_labels, file_id);
355 read_nint16 (&file_mPixelType, file_id);
356 read_nint16 (&file_mPixelSize, file_id);
357 read_nint32 (&mNX, file_id);
358 read_nint32 (&mNY, file_id);
359 read_nint16 (&axis_increment_known, file_id);
360 read_nfloat64 (&mIncX, file_id);
361 read_nfloat64 (&mIncY, file_id);
362 read_nint16 (&axis_extent_known, file_id);
363 read_nfloat64 (&mMinX, file_id);
364 read_nfloat64 (&mMaxX, file_id);
365 read_nfloat64 (&mMinY, file_id);
366 read_nfloat64 (&mMaxY, file_id);
367 read_nfloat64 (&mOffsetPV, file_id);
368 read_nfloat64 (&mScalePV, file_id);
370 int read_headersize = lseek (file_id, 0, SEEK_CUR);
371 if (read_headersize != headersize) {
372 sys_error (ERR_WARNING, "Read headersize %d != file headersize %d", read_headersize, headersize);
375 if (file_signature != signature) {
376 sys_error (ERR_WARNING, "File signature %d != true signature %d", file_signature, signature);
379 if (file_mPixelType != mPixelType) {
380 sys_error (ERR_WARNING, "File pixel type %d != class pixel type %d", file_mPixelType, mPixelType);
383 if (file_mPixelSize != mPixelSize) {
384 sys_error (ERR_WARNING, "File pixel size %d != class pixel size %d", file_mPixelSize, mPixelSize);
393 Array2dFile<T>::headerWrite (void)
396 sys_error (ERR_WARNING, "Tried to write header with file closed");
400 lseek (file_id, 0, SEEK_SET);
401 write_nint16 (&headersize, file_id);
402 write_nint16 (&signature, file_id);
403 write_nint16 (&num_labels, file_id);
404 write_nint16 (&mPixelType, file_id);
405 write_nint16 (&mPixelSize, file_id);
406 write_nint32 (&mNX, file_id);
407 write_nint32 (&mNY, file_id);
408 write_nint16 (&axis_increment_known, file_id);
409 write_nfloat64 (&mIncX, file_id);
410 write_nfloat64 (&mIncY, file_id);
411 write_nint16 (&axis_extent_known, file_id);
412 write_nfloat64 (&mMinX, file_id);
413 write_nfloat64 (&mMaxX, file_id);
414 write_nfloat64 (&mMinY, file_id);
415 write_nfloat64 (&mMaxY, file_id);
416 write_nfloat64 (&mOffsetPV, file_id);
417 write_nfloat64 (&mScalePV, file_id);
419 headersize = lseek (file_id, 0, SEEK_CUR);
420 lseek (file_id, 0, SEEK_SET);
421 write_nint16 (&headersize, file_id);
428 Array2dFile<T>::arrayDataWrite (void)
431 sys_error (ERR_WARNING, "Tried to arrayDataWrite with file_id < 0");
435 T** da = array.getArray();
439 lseek (file_id, headersize, SEEK_SET);
440 for (unsigned int ix = 0; ix < mNX; ix++)
441 for (unsigned int iy = 0; iy < mNY; iy++) {
442 T value = da[ix][iy];
443 ConvertReverseNetworkOrder (&value, sizeof(T));
444 write (file_id, &value, mPixelSize);
452 Array2dFile<T>::arrayDataRead (void)
455 sys_error (ERR_WARNING, "Tried to arrayDataRead with file_id < 0");
459 T** da = array.getArray();
463 lseek (file_id, headersize, SEEK_SET);
465 for (int ix = 0; ix < mNX; ix++)
466 for (unsigned int iy = 0; iy < mNY; iy++) {
467 read (file_id, &pixelBuffer, mPixelSize);
468 ConvertReverseNetworkOrder (&pixelBuffer, sizeof(T));
469 da[ix][iy] = pixelBuffer;
477 Array2dFile<T>::labelSeek (unsigned int label_num)
479 if (label_num > num_labels) {
480 sys_error (ERR_WARNING, "label_num %d > num_labels %d [labelSeek]");
484 if (array.getArray() == NULL) { // Could not have written data if array not allocated
485 sys_error (ERR_WARNING, "array == NULL [labelSeek]");
489 off_t pos = headersize + array.sizeofArray();
490 if (lseek (file_id, pos, SEEK_SET) != pos) {
491 sys_error (ERR_WARNING, "Can't seek to end of data array");
495 for (int i = 0; i < label_num; i++)
497 pos += 22; // Skip to string length
498 if (lseek (file_id, pos, SEEK_SET) != pos) {
499 sys_error (ERR_WARNING, "Can't seek to string length");
503 read_nint16 (&strlength, file_id);
504 pos += 2 + strlength; // Skip label string length + data
505 if (lseek (file_id, pos, SEEK_SET) != pos) {
506 sys_error (ERR_WARNING, "Can't seek past label string");
516 Array2dFile<T>::labelRead (Array2dFileLabel& label, unsigned int label_num)
518 if (label_num >= num_labels) {
519 sys_error (ERR_WARNING, "Trying to read past number of labels [labelRead]");
523 if (! labelSeek (label_num)) {
524 sys_error (ERR_WARNING, "Error calling labelSeek");
528 read_nint16 (&label.m_labelType, file_id);
529 read_nint16 (&label.m_year, file_id);
530 read_nint16 (&label.m_month, file_id);
531 read_nint16 (&label.m_day, file_id);
532 read_nint16 (&label.m_hour, file_id);
533 read_nint16 (&label.m_minute, file_id);
534 read_nint16 (&label.m_second, file_id);
535 read_nfloat64 (&label.m_calcTime, file_id);
538 read_nint16 (&strlength, file_id);
539 char str [strlength+1];
540 read (file_id, str, strlength);
542 label.m_strLabel = str;
550 Array2dFile<T>::labelAdd (const char* const lstr, double calc_time=0.)
552 labelAdd (Array2dFileLabel::L_HISTORY, lstr, calc_time);
557 Array2dFile<T>::labelAdd (int type, const char* const lstr, double calc_time=0.)
559 Array2dFileLabel label (type, lstr, calc_time);
566 Array2dFile<T>::labelAdd (const Array2dFileLabel& label)
568 labelSeek (num_labels);
570 write_nint16 (&label.m_labelType, file_id);
571 write_nint16 (&label.m_year, file_id);
572 write_nint16 (&label.m_month, file_id);
573 write_nint16 (&label.m_day, file_id);
574 write_nint16 (&label.m_hour, file_id);
575 write_nint16 (&label.m_minute, file_id);
576 write_nint16 (&label.m_second, file_id);
577 write_nfloat64 (&label.m_calcTime, file_id);
578 kuint16 strlength = label.m_strLabel.length();
579 write_nint16 (&strlength, file_id);
580 write (file_id, static_cast<const void*>(label.m_strLabel.c_str()), strlength);
590 Array2dFile<T>::labelsCopy (Array2dFile& copyFile, const char* const idStr)
593 for (int i = 0; i < copyFile.getNumLabels(); i++) {
595 copyFile.labelRead (l, i);
596 string lstr = l.getLabelString();
598 l.setLabelString (lstr);
605 Array2dFile<T>::arrayDataClear (void)
607 T** v = array.getArray();
609 for (unsigned int ix = 0; ix < mNX; ix++)
610 for (unsigned int iy = 0; iy < mNY; iy++)
620 class F32Image : public Array2dFile<kfloat32>
623 F32Image (const char* const fname, unsigned int nx, unsigned int ny)
624 : Array2dFile<kfloat32>::Array2dFile (fname, nx, ny)
626 setPixelType (FLOAT32);
629 F32Image (unsigned int nx, unsigned int ny)
630 : Array2dFile<kfloat32>::Array2dFile (nx, ny)
632 setPixelType (FLOAT32);
635 F32Image (const char* const fname)
636 : Array2dFile<kfloat32>::Array2dFile (fname)
638 setPixelType (FLOAT32);
642 MPI::Datatype getMPIDataType (void) const
643 { return MPI::FLOAT; }
648 class F64Image : public Array2dFile<kfloat64>
652 F64Image (const char* const fname, unsigned int nx, unsigned int ny)
653 : Array2dFile<kfloat64>::Array2dFile (fname, nx, ny)
655 setPixelType (FLOAT64);
658 F64Image (unsigned int nx, unsigned int ny)
659 : Array2dFile<kfloat64>::Array2dFile (nx, ny)
661 setPixelType (FLOAT64);
664 F64Image (const char* const fname)
665 : Array2dFile<kfloat64>::Array2dFile (fname)
667 setPixelType (FLOAT64);
671 MPI::Datatype getMPIDataType (void) const
672 { return MPI::DOUBLE; }
676 #define IMAGEFILE_64_BITS 1
677 #ifdef IMAGEFILE_64_BITS
678 typedef F64Image ImageFile;
679 typedef kfloat64 ImageFileValue;
680 typedef kfloat64* ImageFileColumn;
681 typedef kfloat64** ImageFileArray;
683 typedef F32Image ImageFile;
684 typedef kfloat32 ImageFileValue;
685 typedef kfloat32* ImageFileColumn;
686 typedef kfloat32** ImageFileArray;