Openholo  v4.0
Open Source Digital Holographic Library
ImgCodecOhc.cpp
Go to the documentation of this file.
1 /*M///////////////////////////////////////////////////////////////////////////////////////
2 //
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
4 //
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install, copy or use the software.
7 //
8 //
9 // License Agreement
10 // For Open Source Digital Holographic Library
11 //
12 // Openholo library is free software;
13 // you can redistribute it and/or modify it under the terms of the BSD 2-Clause license.
14 //
15 // Copyright (C) 2017-2024, Korea Electronics Technology Institute. All rights reserved.
16 // E-mail : contact.openholo@gmail.com
17 // Web : http://www.openholo.org
18 //
19 // Redistribution and use in source and binary forms, with or without modification,
20 // are permitted provided that the following conditions are met:
21 //
22 // 1. Redistribution's of source code must retain the above copyright notice,
23 // this list of conditions and the following disclaimer.
24 //
25 // 2. Redistribution's in binary form must reproduce the above copyright notice,
26 // this list of conditions and the following disclaimer in the documentation
27 // and/or other materials provided with the distribution.
28 //
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the copyright holder or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
39 //
40 // This software contains opensource software released under GNU Generic Public License,
41 // NVDIA Software License Agreement, or CUDA supplement to Software License Agreement.
42 // Check whether software you use contains licensed software.
43 //
44 //M*/
45 
46 #include "ImgCodecOhc.h"
47 
48 #define NOMINMAX // using std::numeric_limits<DataType>::max(), min() of <limits> instead of <minwindef.h>
49 
50 #include "sys.h"
51 #include <limits> // limit value of each data types
52 
53 
54 //hot key for call by this pointer
55 #define FHeader this->Header->fileHeader
56 #define FldInfo this->Header->fieldInfo
57 #define WavLeng this->Header->wavlenTable
58 
59 
60 /************************ OHC CODEC *****************************/
61 
63  this->initOHCheader();
64 }
65 
67  this->releaseOHCheader();
68  this->releaseFldData();
69  this->releaseCodeBuffer();
70 }
71 
72 oph::ImgCodecOhc::ImgCodecOhc(const std::string &_fname) {
73  this->initOHCheader();
74  this->setFileName(_fname);
75 }
76 
77 oph::ImgCodecOhc::ImgCodecOhc(const std::string &_fname, const ohcHeader &_Header) {
78  this->initOHCheader();
79  this->setFileName(_fname);
80  this->setOHCheader(_Header);
81 }
82 
84  if (this->Header != nullptr) {
85  delete this->Header;
86  this->Header = nullptr;
87  }
88 
89  this->Header = new ohcHeader();
90 }
91 
92 bool oph::ImgCodecOhc::setFileName(const std::string &_fname) {
93  this->fname = _fname;
94 
95  return true;
96 }
97 
99  if (this->Header != nullptr) {
100  delete this->Header;
101  this->Header = nullptr;
102  }
103 
104  this->Header = new ohcHeader(_Header);
105 
106  return true;
107 }
108 
110  if (this->Header == nullptr)
111  LOG("OHC CODEC : No Header Data.");
112  else
113  _Header = *(this->Header);
114 }
115 
116 void oph::ImgCodecOhc::getFieldInfo(ohcFieldInfoHeader &_FieldInfo, std::vector<double_t> &_wavlenTable) {
117  if (this->Header == nullptr)
118  LOG("OHC CODEC : No Header Data.");
119  else {
120  _FieldInfo = this->Header->fieldInfo;
121  _wavlenTable = this->Header->wavlenTable;
122  }
123 }
124 
126 {
127  oph::Field2Buffer(field_cmplx[wavelen_idx], cmplx_field);
128 }
129 
131 {
132  *cmplx_field = new OphComplexField[field_cmplx.size()];
133 
134  for (uint i = 0; i < field_cmplx.size(); i++)
135  {
136  (*cmplx_field)[i].resize(Header->fieldInfo.pxNumX, Header->fieldInfo.pxNumY);
137  //(*cmplx_field)[i].zeros();
138  (*cmplx_field)[i] = field_cmplx[i];
139  }
140 }
141 
143 {
144  if (*cmplx_field == nullptr)
145  *cmplx_field = new Complex<Real>*[field_cmplx.size()];
146 
147  for (uint i = 0; i < field_cmplx.size(); i++)
148  oph::Field2Buffer(field_cmplx[i], *cmplx_field + i);
149 }
150 
152  if (this->Header != nullptr) {
153  delete this->Header;
154  this->Header = nullptr;
155  }
156 }
157 
159  //delete[] this->buf;
160  if (this->buf_f32) {
161  delete[] this->buf_f32;
162  this->buf_f32 = nullptr;
163  }
164  if (this->buf_f64) {
165  delete[] this->buf_f64;
166  this->buf_f64 = nullptr;
167  }
168 }
169 
171  for (size_t i = 0; i < field_cmplx.size(); ++i) {
172  this->field_cmplx[i].release();
173  }
174  this->field_cmplx.clear();
175 }
176 
177 /************************ OHC Decoder *****************************/
178 
180  : ImgCodecOhc()
181 {
182 }
183 
184 oph::ImgDecoderOhc::ImgDecoderOhc(const std::string &_fname)
185  : ImgCodecOhc(_fname)
186 {
187 }
188 
189 oph::ImgDecoderOhc::ImgDecoderOhc(const std::string &_fname, const ohcHeader &_Header)
190  : ImgCodecOhc(_fname, _Header)
191 {
192 }
193 
195 {
196  this->releaseOHCheader();
197  this->releaseFldData();
198  this->releaseCodeBuffer();
199 }
200 
203 
204  for (size_t i = 0; i < field_ampli.size(); ++i) {
205  this->field_ampli[i].release();
206  }
207  this->field_ampli.clear();
208 
209  for (size_t i = 0; i < field_phase.size(); ++i) {
210  this->field_phase[i].release();
211  }
212  this->field_phase.clear();
213 
214  this->bLoadFile = false;
215 }
216 
218  if ((this->Header == nullptr) || !this->bLoadFile) {
219  LOG("OHC CODEC Error : No loaded data.");
220  return ivec2(-1, -1);
221  }
222  else
223  return ivec2(FldInfo.pxNumX, FldInfo.pxNumY);
224 }
225 
227  if ((this->Header == nullptr) || !this->bLoadFile) {
228  LOG("OHC CODEC Error : No loaded data.");
229  return vec2(-1., -1.);
230  }
231  else
232  return vec2(FldInfo.pxPitchX, FldInfo.pxPitchY);
233 }
234 
236  if ((this->Header == nullptr) || !this->bLoadFile) {
237  LOG("OHC CODEC Error : No loaded data.");
238  return LenUnit::Null;
239  }
240  else
241  return FldInfo.pitchUnit;
242 }
243 
245  if ((this->Header == nullptr) || !this->bLoadFile) {
246  LOG("OHC CODEC Error : No loaded data.");
247  return (uint)-1;
248  }
249  else
250  return FldInfo.wavlenNum;
251 }
252 
254  if ((this->Header == nullptr) || !this->bLoadFile) {
255  LOG("OHC CODEC Error : No loaded data.");
256  return ColorType::Null;
257  }
258  else
259  return FldInfo.clrType;
260 }
261 
263  if ((this->Header == nullptr) || !this->bLoadFile) {
264  LOG("OHC CODEC Error : No loaded data.");
265  return ColorArran::Null;
266  }
267  else
268  return FldInfo.clrArrange;
269 }
270 
272  if ((this->Header == nullptr) || !this->bLoadFile) {
273  LOG("OHC CODEC Error : No loaded data.");
274  return LenUnit::Null;
275  }
276  else
277  return FldInfo.wavlenUnit;
278 }
279 
281  if ((this->Header == nullptr) || !this->bLoadFile) {
282  LOG("OHC CODEC Error : No loaded data.");
283  return CompresType::Null;
284  }
285  else
286  return FldInfo.comprsType;
287 }
288 
289 void oph::ImgDecoderOhc::getWavelength(std::vector<double_t> &wavlen_array) {
290  if ((this->Header == nullptr) || !this->bLoadFile) {
291  LOG("OHC CODEC Error : No loaded data.");
292  return;
293  }
294  else
295  wavlen_array = WavLeng;
296 }
297 
298 void oph::ImgDecoderOhc::getLinkFilePath(std::vector<std::string> &linkFilePath_array) {
299  if ((this->Header == nullptr) || !this->bLoadFile) {
300  LOG("OHC CODEC Error : No loaded data.");
301  return;
302  }
303  else
304  linkFilePath_array = this->linkFilePath;
305 }
306 
308  this->File.open(this->fname, std::ios::in | std::ios::binary);
309 
310  bool isOpen = File.is_open();
311  if (this->File.is_open()) {
312  if (this->Header == nullptr)
313  this->Header = new ohcHeader();
314 
315 
316  // Read OHC File Header
317  File.read((char *)&FHeader.fileSignature, sizeof(FHeader.fileSignature));
318  if ((FHeader.fileSignature[0] != FMT_SIGN_OHC[0]) || (FHeader.fileSignature[1] != FMT_SIGN_OHC[1])) {
319  LOG("Not OHC File");
320  return false;
321  }
322  else {
323  File.seekg(ios::beg); // Move file pointer
324  File.read((char *)&FHeader, sizeof(FHeader));
325  printf("Reading Openholo Complex Field File...\n%s\n", fname.c_str());
326  printf("OHC File was made on OpenHolo version v%x.%x...\n", FHeader.fileVersionMajor, FHeader.fileVersionMinor);
327  }
328 
329  // Read Field Info Header
330  File.read((char *)&FldInfo, sizeof(FldInfo));
331  if (FldInfo.fldSize == 0) {
332  LOG("Error : No Field Data");
333  this->File.close();
334  return false;
335  }
336 
337  // Read Wavelength Table
338  for (uint n = 0; n < FldInfo.wavlenNum; ++n) {
339  double_t waveLength = 0.0;
340  File.read((char *)&waveLength, sizeof(waveLength));
341  WavLeng.push_back(waveLength);
342  }
343 
344  // Decoding Field Data
345  bool ok = false;
346  switch (FldInfo.cmplxFldType) {
347  case DataType::Float64:
348  case DataType::Float32:
349  ok = decodeFieldData();
350  break;
351  case DataType::CmprFmt:
352  LOG("Error : Compressed Image Format Decoding is Not Yet supported...");
353  this->File.close();
354  return false;
355  break;
356  default:
357  LOG("Error : Invalid Decoding Complex Field Data Type...");
358  this->File.close();
359  return false;
360  break;
361  }
362  //switch (FldInfo.cmplxFldType) {
363  //case DataType::Float64:
364  // ok = decodeFieldData<double_t>();
365  // break;
366  //case DataType::Float32:
367  // ok = decodeFieldData<float_t>();
368  // break;
369  //case DataType::Int8:
370  // ok = decodeFieldData<int8_t>();
371  // break;
372  //case DataType::Int16:
373  // ok = decodeFieldData<int16_t>();
374  // break;
375  //case DataType::Int32:
376  // ok = decodeFieldData<int32_t>();
377  // break;
378  //case DataType::Int64:
379  // ok = decodeFieldData<int64_t>();
380  // break;
381  //case DataType::Uint8:
382  // ok = decodeFieldData<uint8_t>();
383  // break;
384  //case DataType::Uint16:
385  // ok = decodeFieldData<uint16_t>();
386  // break;
387  //case DataType::Uint32:
388  // ok = decodeFieldData<uint32_t>();
389  // break;
390  //case DataType::Uint64:
391  // ok = decodeFieldData<uint64_t>();
392  // break;
393  //case DataType::CmprFmt:
394  // LOG("Error : Compressed Image Format Decoding is Not Yet supported...");
395  // this->File.close();
396  // return false;
397  // break;
398  //default:
399  // LOG("Error : Invalid Decoding Complex Field Data Type...");
400  // this->File.close();
401  // return false;
402  // break;
403  //}
404  ok = true;
405  this->bLoadFile = true;
406  this->File.close();
407  return ok;
408  }
409  else {
410  LOG("Error : Failed loading OHC file...");
411  return isOpen;
412  }
413 }
414 
416 {
417  if (field_cmplx.empty() != true) return;
418 
419  uint x = Header->fieldInfo.pxNumX;
420  uint y = Header->fieldInfo.pxNumY;
421  uint n_wav = Header->fieldInfo.wavlenNum;
422 
423  for (uint l = 0; l < n_wav; l++)
424  {
425  for (uint i = 0; i < x; i++)
426  {
427  for (uint j = 0; j < y; j++)
428  {
429  if (field_ampli.empty() != true) field_cmplx[l][i][j][_RE] = field_ampli[l][i][j];
430  if (field_phase.empty() != true) field_cmplx[l][i][j][_IM] = field_phase[l][i][j];
431  }
432  }
433  }
434 }
435 
437 {
438  int n_wavlens = FldInfo.wavlenNum;
439  int cols = FldInfo.pxNumX;
440  int rows = FldInfo.pxNumY;
441  int n_pixels = cols * rows;
442  ulonglong n_fields = n_pixels * n_wavlens;
443 
444  if (FldInfo.fldStore == FldStore::Null) FldInfo.fldStore = FldStore::Directly;
445 
446  int n_cmplxChnl = 0; // Is a data value Dual data(2) or Single data(1) ?
447 
448  switch (FldInfo.fldCodeType) {
449  case FldCodeType::RI: {
450  n_cmplxChnl = 2;
451  for (int w = 0; w < n_wavlens; ++w) {
452  OphComplexField data_field(cols, rows);
453  data_field.zeros();
454  this->field_cmplx.push_back(data_field);
455  }
456  break;
457  }
458  case FldCodeType::AP: {
459  n_cmplxChnl = 2;
460  for (int w = 0; w < n_wavlens; ++w) {
461  OphRealField data_field(cols, rows);
462  data_field.zeros();
463  this->field_ampli.push_back(data_field);
464  this->field_phase.push_back(data_field);
465  }
466  break;
467  }
468  case FldCodeType::AE: {
469  n_cmplxChnl = 1;
470  for (int w = 0; w < n_wavlens; ++w) {
471  OphRealField data_field(cols, rows);
472  data_field.zeros();
473  this->field_ampli.push_back(data_field);
474  }
475  break;
476  }
477  case FldCodeType::PE: {
478  n_cmplxChnl = 1;
479  for (int w = 0; w < n_wavlens; ++w) {
480  OphRealField data_field(cols, rows);
481  data_field.zeros();
482  this->field_phase.push_back(data_field);
483  }
484  break;
485  }
486  default: {
487  LOG("Error : Invalid Complex Field Encoding Type...\n");
488  return false;
489  }
490  }
491 
492  if (FldInfo.fldStore == FldStore::Directly) {
493  if (FldInfo.cmplxFldType == DataType::Float32) {
494  this->buf_f32 = new float[n_fields * n_cmplxChnl];
495  for (ulonglong i = 0; i < n_fields * n_cmplxChnl; i++)
496  this->File.read((char*)&this->buf_f32[i], sizeof(float));
497  }
498  else if (FldInfo.cmplxFldType == DataType::Float64) {
499  this->buf_f64 = new double[n_fields * n_cmplxChnl];
500  for (ulonglong i = 0; i < n_fields * n_cmplxChnl; i++)
501  this->File.read((char*)&this->buf_f64[i], sizeof(double));
502  }
503 
504  for (int x = 0; x < cols; ++x) {
505  for (int y = 0; y < rows; ++y) {
506  int idx = x * rows + y;
507 
508  for (int clrChnl = 0; clrChnl < n_wavlens; ++clrChnl) { // RGB is wavlenNum == 3
509  ulonglong idx_sqtlChnl = n_wavlens * idx + clrChnl;
510 
511  if (FldInfo.clrArrange == ColorArran::SeqtChanl) {
512  switch (FldInfo.fldCodeType) {
513  case FldCodeType::RI: {
514  if (FldInfo.cmplxFldType == DataType::Float32) {
515  this->field_cmplx[clrChnl][x][y][_RE] = *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields);
516  this->field_cmplx[clrChnl][x][y][_IM] = *(this->buf_f32 + idx_sqtlChnl + 1 * n_fields);
517  }
518  else if (FldInfo.cmplxFldType == DataType::Float64) {
519  this->field_cmplx[clrChnl][x][y][_RE] = *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields);
520  this->field_cmplx[clrChnl][x][y][_IM] = *(this->buf_f64 + idx_sqtlChnl + 1 * n_fields);
521  }
522  break;
523  }
524  case FldCodeType::AP: {
525  if (FldInfo.cmplxFldType == DataType::Float32) {
526  this->field_ampli[clrChnl][x][y] = *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields);
527  this->field_phase[clrChnl][x][y] = *(this->buf_f32 + idx_sqtlChnl + 1 * n_fields);
528  }
529  else if (FldInfo.cmplxFldType == DataType::Float64) {
530  this->field_ampli[clrChnl][x][y] = *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields);
531  this->field_phase[clrChnl][x][y] = *(this->buf_f64 + idx_sqtlChnl + 1 * n_fields);
532  }
533  break;
534  }
535  case FldCodeType::AE: {
536  if (FldInfo.cmplxFldType == DataType::Float32)
537  this->field_ampli[clrChnl][x][y] = *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields);
538  else if (FldInfo.cmplxFldType == DataType::Float64)
539  this->field_ampli[clrChnl][x][y] = *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields);
540  break;
541  }
542  case FldCodeType::PE: {
543  if (FldInfo.cmplxFldType == DataType::Float32)
544  this->field_phase[clrChnl][x][y] = *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields);
545  else if (FldInfo.cmplxFldType == DataType::Float64)
546  this->field_phase[clrChnl][x][y] = *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields);
547  break;
548  }
549  }
550  }
551  else if (FldInfo.clrArrange == ColorArran::EachChanl) {
552  ulonglong idx_eachChnl = idx + clrChnl * n_pixels;
553 
554  switch (FldInfo.fldCodeType) {
555  case FldCodeType::RI: {
556  if (FldInfo.cmplxFldType == DataType::Float32) {
557  this->field_cmplx[clrChnl][x][y][_RE] = *(this->buf_f32 + idx_eachChnl + 0 * n_fields);
558  this->field_cmplx[clrChnl][x][y][_IM] = *(this->buf_f32 + idx_eachChnl + 1 * n_fields);
559  }
560  else if (FldInfo.cmplxFldType == DataType::Float64) {
561  this->field_cmplx[clrChnl][x][y][_RE] = *(this->buf_f64 + idx_eachChnl + 0 * n_fields);
562  this->field_cmplx[clrChnl][x][y][_IM] = *(this->buf_f64 + idx_eachChnl + 1 * n_fields);
563  }
564  break;
565  }
566  case FldCodeType::AP: {
567  if (FldInfo.cmplxFldType == DataType::Float32) {
568  this->field_ampli[clrChnl][x][y] = *(this->buf_f32 + idx_eachChnl + 0 * n_fields);
569  this->field_phase[clrChnl][x][y] = *(this->buf_f32 + idx_eachChnl + 1 * n_fields);
570  }
571  else if (FldInfo.cmplxFldType == DataType::Float64) {
572  this->field_ampli[clrChnl][x][y] = *(this->buf_f64 + idx_eachChnl + 0 * n_fields);
573  this->field_phase[clrChnl][x][y] = *(this->buf_f64 + idx_eachChnl + 1 * n_fields);
574  }
575  break;
576  }
577  case FldCodeType::AE: {
578  if (FldInfo.cmplxFldType == DataType::Float32)
579  this->field_ampli[clrChnl][x][y] = *(this->buf_f32 + idx_eachChnl + 0 * n_fields);
580  else if (FldInfo.cmplxFldType == DataType::Float64)
581  this->field_ampli[clrChnl][x][y] = *(this->buf_f64 + idx_eachChnl + 0 * n_fields);
582  break;
583  }
584  case FldCodeType::PE: {
585  if (FldInfo.cmplxFldType == DataType::Float32)
586  this->field_phase[clrChnl][x][y] = *(this->buf_f32 + idx_eachChnl + 0 * n_fields);
587  else if (FldInfo.cmplxFldType == DataType::Float64)
588  this->field_phase[clrChnl][x][y] = *(this->buf_f64 + idx_eachChnl + 0 * n_fields);
589  break;
590  }
591  }
592  }
593  }
594  }
595  }
596  //fieldToComplex();
597  return true;
598  }
599  else if (FldInfo.fldStore == FldStore::LinkFile) {
600  LOG("Error : Link Image File Decoding is Not Yet supported...\n");
601  return false;
602  }
603  else {
604  LOG("Error : Invalid Field Data Store Type...\n");
605  return false;
606  }
607 }
608 
609 //template<typename T>
610 //bool oph::ImgDecoderOhc::decodeFieldData() {
611 // // Data Type Info for Decoding
612 // bool bIsInteger = std::numeric_limits<T>::is_integer; // only float, double, long double is false
613 // //bool bIsSigned = std::numeric_limits<T>::is_signed; // unsigned type is false, bool is too false.
614 // double max_T = (double)std::numeric_limits<T>::max();
615 // double min_T = (double)std::numeric_limits<T>::min();
616 //
617 // int n_wavlens = FldInfo.wavlenNum;
618 // int cols = FldInfo.pxNumX;
619 // int rows = FldInfo.pxNumY;
620 // int n_pixels = cols * rows;
621 // ulonglong n_fields = n_pixels * n_wavlens;
622 //
623 // int n_cmplxChnl = 0; // Is a data value Dual data(2) or Single data(1) ?
624 //
625 // switch (FldInfo.fldCodeType) {
626 // case FldCodeType::RI: {
627 // n_cmplxChnl = 2;
628 // for (int w = 0; w < n_wavlens; ++w) {
629 // OphComplexField data_field(cols, rows);
630 // data_field.zeros();
631 // this->field_cmplx.push_back(data_field);
632 // }
633 // break;
634 // }
635 // case FldCodeType::AP: {
636 // n_cmplxChnl = 2;
637 // for (int w = 0; w < n_wavlens; ++w) {
638 // OphRealField data_field(cols, rows);
639 // data_field.zeros();
640 // this->field_ampli.push_back(data_field);
641 // this->field_phase.push_back(data_field);
642 // }
643 // break;
644 // }
645 // case FldCodeType::AE: {
646 // n_cmplxChnl = 1;
647 // for (int w = 0; w < n_wavlens; ++w) {
648 // OphRealField data_field(cols, rows);
649 // data_field.zeros();
650 // this->field_ampli.push_back(data_field);
651 // }
652 // break;
653 // }
654 // case FldCodeType::PE: {
655 // n_cmplxChnl = 1;
656 // for (int w = 0; w < n_wavlens; ++w) {
657 // OphRealField data_field(cols, rows);
658 // data_field.zeros();
659 // this->field_phase.push_back(data_field);
660 // }
661 // break;
662 // }
663 // default: {
664 // LOG("Error : Invalid Complex Field Encoding Type...");
665 // return false;
666 // break;
667 // }
668 // }
669 //
670 // if (FldInfo.fldStore == FldStore::Directly) {
671 // this->buf = new T[n_fields * n_cmplxChnl];
672 // this->File.read((char*)&this->buf, FldInfo.fldSize);
673 //
674 // for (int y = 0; y < rows; ++y) {
675 // for (int x = 0; x < cols; ++x) {
676 // int idx = y * cols + x;
677 //
678 // for (int clrChnl = 0; clrChnl < n_wavlens; ++clrChnl) { // RGB is wavlenNum == 3
679 // ulonglong idx_sqtlChnl = n_wavlens * idx + clrChnl;
680 //
681 // if (FldInfo.clrArrange == ColorArran::SequentialRGB) {
682 // switch (FldInfo.fldCodeType) {
683 // case FldCodeType::RI: {
684 // if (!bIsInteger) { // floating type
685 // this->field_cmplx[clrChnl][x][y][_RE] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
686 // this->field_cmplx[clrChnl][x][y][_IM] = (Real)*((T*)this->buf + idx_sqtlChnl + 1 * n_fields);
687 // }
688 // else if (bIsInteger) { // integer type
689 // this->field_cmplx[clrChnl][x][y][_RE] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
690 // this->field_cmplx[clrChnl][x][y][_IM] = (Real)*((T*)this->buf + idx_sqtlChnl + 1 * n_fields);
691 // }
692 // break;
693 // }
694 // case FldCodeType::AP: {
695 // if (!bIsInteger) {
696 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
697 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 1 * n_fields);
698 // }
699 // else if (bIsInteger) {
700 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
701 //
702 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded)
703 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 1 * n_fields);
704 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
705 // Real phase = (Real)*((T*)this->buf + idx_sqtlChnl + 1 * n_fields);
706 // this->field_phase[clrChnl][x][y] = this->decodePhase<T>(phase, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
707 // }
708 // }
709 // break;
710 // }
711 // case FldCodeType::AE: {
712 // if (!bIsInteger)
713 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
714 // else if (bIsInteger)
715 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
716 // break;
717 // }
718 // case FldCodeType::PE: {
719 // if (!bIsInteger)
720 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
721 // else if (bIsInteger) {
722 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded)
723 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
724 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
725 // Real phase = (Real)*((T*)this->buf + idx_sqtlChnl + 0 * n_fields);
726 // this->field_phase[clrChnl][x][y] = this->decodePhase<T>(phase, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
727 // }
728 // }
729 // break;
730 // }
731 // }
732 // }
733 // else if (FldInfo.clrArrange == ColorArran::EachChannel) {
734 // ulonglong idx_eachChnl = idx + clrChnl * n_pixels;
735 //
736 // switch (FldInfo.fldCodeType) {
737 // case FldCodeType::RI: {
738 // if (!bIsInteger) { // floating type
739 // this->field_cmplx[clrChnl][x][y][_RE] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
740 // this->field_cmplx[clrChnl][x][y][_IM] = (Real)*((T*)this->buf + idx_eachChnl + 1 * n_fields);
741 // }
742 // else if (bIsInteger) { // integer type
743 // this->field_cmplx[clrChnl][x][y][_RE] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
744 // this->field_cmplx[clrChnl][x][y][_IM] = (Real)*((T*)this->buf + idx_eachChnl + 1 * n_fields);
745 // }
746 // break;
747 // }
748 // case FldCodeType::AP: {
749 // if (!bIsInteger) {
750 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
751 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 1 * n_fields);
752 // }
753 // else if (bIsInteger) {
754 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
755 //
756 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded)
757 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 1 * n_fields);
758 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
759 // Real phase = (Real)*((T*)this->buf + idx_eachChnl + 1 * n_fields);
760 // this->field_phase[clrChnl][x][y] = this->decodePhase<T>(phase, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
761 // }
762 // }
763 // break;
764 // }
765 // case FldCodeType::AE: {
766 // if (!bIsInteger)
767 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
768 // else if (bIsInteger)
769 // this->field_ampli[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
770 // break;
771 // }
772 // case FldCodeType::PE: {
773 // if (!bIsInteger)
774 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
775 // else if (bIsInteger) {
776 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded)
777 // this->field_phase[clrChnl][x][y] = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
778 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
779 // Real phase = (Real)*((T*)this->buf + idx_eachChnl + 0 * n_fields);
780 // this->field_phase[clrChnl][x][y] = this->decodePhase<T>(phase, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
781 // }
782 // }
783 // break;
784 // }
785 // }
786 // }
787 // }
788 // }
789 // }
790 // return true;
791 // }
792 // else if (FldInfo.fldStore == FldStore::LinkFile) {
793 // LOG("Error : Link Image File Decoding is Not Yet supported...");
794 // return false;
795 // }
796 // else {
797 // LOG("Error : Invalid Field Data Store Type...");
798 // return false;
799 // }
800 //}
801 
802 //template<typename T>
803 //Real oph::ImgDecoderOhc::decodePhase(const T phase, const Real min_p, const Real max_p, const double min_T, const double max_T) {
804 // // Normalize phase data type range to (0.0, 1.0)
805 // Real _phase = ((double)phase - min_T) / (max_T - min_T);
806 //
807 // // Mapping to (phaseCodeMin, phaseCodeMax)
808 // if (std::is_same<double, Real>::value)
809 // return (Real)(_phase*(max_p - min_p) + min_p)*M_PI;
810 // else if (std::is_same<float, Real>::value)
811 // return (Real)(_phase*(max_p - min_p) + min_p)*M_PI_F;
812 //}
813 
814 
815 /************************ OHC Encoder *****************************/
816 
818  : ImgCodecOhc()
819 {
820  initOHCheader();
821 }
822 
823 oph::ImgEncoderOhc::ImgEncoderOhc(const std::string &_fname, const ohcHeader &_Header)
824  : ImgCodecOhc(_fname, _Header)
825 {
826  initOHCheader();
827 }
828 
829 oph::ImgEncoderOhc::ImgEncoderOhc(const std::string &_fname)
830  : ImgCodecOhc(_fname)
831 {
832  initOHCheader();
833 }
834 
836 {
837  this->releaseOHCheader();
838  this->releaseFldData();
839  this->releaseCodeBuffer();
840 }
841 
843  if (this->Header != nullptr) {
844  delete this->Header;
845  this->Header = nullptr;
846  }
847 
848  this->Header = new ohcHeader();
849 
850  //Set Initial Header of Encoder
851  FHeader.fileSignature[0] = FMT_SIGN_OHC[0];
852  FHeader.fileSignature[1] = FMT_SIGN_OHC[1];
853  FHeader.fileVersionMajor = _OPH_LIB_VERSION_MAJOR_;
854  FHeader.fileVersionMinor = _OPH_LIB_VERSION_MINOR_;
855  FHeader.fileReserved1 = 0;
856  FHeader.fileReserved2 = 0;
857 
858  //Set Initial Complex Field Information for Encoder
859  FldInfo.headerSize = 0;
860  FldInfo.pitchUnit = LenUnit::Null;
861  FldInfo.wavlenNum = 0;
862  FldInfo.clrType = ColorType::MLT;
863  FldInfo.clrArrange = ColorArran::EachChanl;
864  FldInfo.wavlenUnit = LenUnit::m;
865  FldInfo.fldStore = FldStore::Directly;
866  FldInfo.fldCodeType = FldCodeType::RI;
867  FldInfo.bPhaseCode = BPhaseCode::NotEncoded;
868  FldInfo.phaseCodeMin = -1.0;
869  FldInfo.phaseCodeMax = 1.0;
870  FldInfo.comprsType = CompresType::Null;
871 
872  if (std::is_same<double, Real>::value)
873  FldInfo.cmplxFldType = DataType::Float64;
874  else if (std::is_same<float, Real>::value)
875  FldInfo.cmplxFldType = DataType::Float32;
876 }
877 
878 void oph::ImgEncoderOhc::setNumOfPixel(const uint _pxNumX, const uint _pxNumY) {
879  if (this->Header == nullptr) {
880  LOG("OHC CODEC Error : No header data.");
881  return;
882  }
883  else {
884  FldInfo.pxNumX = _pxNumX;
885  FldInfo.pxNumY = _pxNumY;
886  }
887 }
888 
890  if (this->Header == nullptr) {
891  LOG("OHC CODEC Error : No header data.");
892  return;
893  }
894  else {
895  FldInfo.pxNumX = _pxNum[_X];
896  FldInfo.pxNumY = _pxNum[_Y];
897  }
898 }
899 
900 void oph::ImgEncoderOhc::setPixelPitch(const double _pxPitchX, const double _pxPitchY, const LenUnit unit) {
901  if (this->Header == nullptr) {
902  LOG("OHC CODEC Error : No header data.");
903  return;
904  }
905  else {
906  FldInfo.pxPitchX = _pxPitchX;
907  FldInfo.pxPitchY = _pxPitchY;
908  FldInfo.pitchUnit = unit;
909  }
910 }
911 
912 void oph::ImgEncoderOhc::setPixelPitch(const vec2 _pxPitch, const LenUnit unit) {
913  if (this->Header == nullptr) {
914  LOG("OHC CODEC Error : No header data.");
915  return;
916  }
917  else {
918  FldInfo.pxPitchX = _pxPitch[_X];
919  FldInfo.pxPitchY = _pxPitch[_Y];
920  FldInfo.pitchUnit = unit;
921  }
922 }
923 
925  if (this->Header == nullptr) {
926  LOG("OHC CODEC Error : No header data.");
927  return;
928  }
929  else {
930  FldInfo.wavlenNum = n_wavlens;
931  }
932 }
933 
935  if (this->Header == nullptr) {
936  LOG("OHC CODEC Error : No header data.");
937  return;
938  }
939  else {
940  FldInfo.clrType = _clrType;
941  }
942 }
943 
945  if (this->Header == nullptr) {
946  LOG("OHC CODEC Error : No header data.");
947  return;
948  }
949  else {
950  FldInfo.clrArrange = _clrArrange;
951  }
952 }
953 
955  if (this->Header == nullptr) {
956  LOG("OHC CODEC Error : No header data.");
957  return;
958  }
959  else {
960  FldInfo.wavlenUnit = unit;
961  }
962 }
963 
964 //void oph::ImgEncoderOhc::setFieldEncoding(const FldStore _fldStore, const FldCodeType _fldCodeType, const DataType _cmplxFldType) {
965 void oph::ImgEncoderOhc::setFieldEncoding(const FldStore _fldStore, const FldCodeType _fldCodeType) {
966  if (this->Header == nullptr) {
967  LOG("OHC CODEC Error : No header data.");
968  return;
969  }
970  else {
971  FldInfo.fldStore = _fldStore;
972  FldInfo.fldCodeType = _fldCodeType;
973  //FldInfo.cmplxFldType = _cmplxFldType;
974  }
975 }
976 
977 void oph::ImgEncoderOhc::setPhaseEncoding(const BPhaseCode _bPhaseCode, const double _phaseCodeMin, const double _phaseCodeMax) {
978  if (this->Header == nullptr) {
979  LOG("OHC CODEC Error : No header data.");
980  return;
981  }
982  else {
983  FldInfo.bPhaseCode = _bPhaseCode;
984  FldInfo.phaseCodeMin = _phaseCodeMin;
985  FldInfo.phaseCodeMax = _phaseCodeMax;
986  }
987 }
988 
989 
990 void oph::ImgEncoderOhc::setPhaseEncoding(const BPhaseCode _bPhaseCode, const vec2 _phaseCodeRange) {
991  if (this->Header == nullptr) {
992  LOG("OHC CODEC Error : No header data.");
993  return;
994  }
995  else {
996  FldInfo.bPhaseCode = _bPhaseCode;
997  FldInfo.phaseCodeMin = _phaseCodeRange[0];
998  FldInfo.phaseCodeMax = _phaseCodeRange[1];
999  }
1000 }
1001 
1002 //void oph::ImgEncoderOhc::setCompressedFormatType(const CompresType _comprsType) {
1003 // if (this->Header == nullptr) {
1004 // LOG("OHC CODEC Error : No header data.");
1005 // return;
1006 // }
1007 // else {
1008 // FldInfo.comprsType = _comprsType;
1009 // }
1010 //}
1011 
1012 void oph::ImgEncoderOhc::setWavelength(const Real _wavlen, const LenUnit _unit) {
1013  this->addWavelength(_wavlen);
1014  this->setUnitOfWavlen(_unit);
1015 }
1016 
1018  this->addWavelength(wavlen);
1019  this->addComplexFieldData(data);
1020 }
1021 
1023  this->field_cmplx.push_back(data);
1024 }
1025 
1027 {
1028  if (data == nullptr) {
1029  LOG("not found Complex data");
1030  return;
1031  }
1032 
1033  ivec2 buffer_size = ivec2(this->Header->fieldInfo.pxNumX, this->Header->fieldInfo.pxNumY);
1034 
1035  OphComplexField complexField(buffer_size[_X], buffer_size[_Y]);
1036  Buffer2Field(data, complexField, buffer_size);
1037 
1038  this->field_cmplx.push_back(complexField);
1039 }
1040 
1041 
1043 {
1044  WavLeng.clear();
1045 }
1046 
1048 {
1049  WavLeng.push_back(wavlen);
1050  this->setNumOfWavlen((uint32_t)WavLeng.size());
1051 }
1052 
1053 //void oph::ImgEncoderOhc::addLinkFilePath(const std::string &path) {
1054 // this->linkFilePath.push_back(path);
1055 //}
1056 
1058 {
1059  this->File.open(this->fname, std::ios::out | std::ios::trunc | std::ios::binary);
1060 
1061  //FILE *fp;
1062  //fopen_s(&fp, this->fname.c_str(), "w");
1063  //if (fp == nullptr) return false;
1064 
1065  LOG("Saving...%s...", fname.c_str());
1066  auto start = CUR_TIME;
1067  //if (fp) {
1068  if (this->File.is_open()) {
1069  if (this->Header == nullptr) {
1070  //this->Header = new ohcHeader();
1071  this->initOHCheader();
1072  }
1073 
1074  // Encoding Field Data
1075  uint64_t dataSize = 0;
1076  switch (FldInfo.cmplxFldType) {
1077  case DataType::Float64:
1078  case DataType::Float32:
1079  dataSize = encodeFieldData();
1080  break;
1081  case DataType::CmprFmt:
1082  LOG("Error : Compressed Image Format Encoding is Not Yet supported...");
1083  //fclose(fp);
1084  this->File.close();
1085  return false;
1086  break;
1087  default:
1088  LOG("Error : Invalid Encoding Complex Field Data Type...");
1089  //fclose(fp);
1090  this->File.close();
1091  return false;
1092  break;
1093  }
1094  //switch (FldInfo.cmplxFldType) {
1095  //case DataType::Float64:
1096  // dataSize = encodeFieldData<double_t>();
1097  // break;
1098  //case DataType::Float32:
1099  // dataSize = encodeFieldData<float_t>();
1100  // break;
1101  //case DataType::Int8:
1102  // dataSize = encodeFieldData<int8_t>();
1103  // break;
1104  //case DataType::Int16:
1105  // dataSize = encodeFieldData<int16_t>();
1106  // break;
1107  //case DataType::Int32:
1108  // dataSize = encodeFieldData<int32_t>();
1109  // break;
1110  //case DataType::Int64:
1111  // dataSize = encodeFieldData<int64_t>();
1112  // break;
1113  //case DataType::Uint8:
1114  // dataSize = encodeFieldData<uint8_t>();
1115  // break;
1116  //case DataType::Uint16:
1117  // dataSize = encodeFieldData<uint16_t>();
1118  // break;
1119  //case DataType::Uint32:
1120  // dataSize = encodeFieldData<uint32_t>();
1121  // break;
1122  //case DataType::Uint64:
1123  // dataSize = encodeFieldData<uint64_t>();
1124  // break;
1125  //case DataType::CmprFmt:
1126  // LOG("Error : Compressed Image Format Encoding is Not Yet supported...");
1127  // //fclose(fp);
1128  // this->File.close();
1129  // return false;
1130  // break;
1131  //default:
1132  // LOG("Error : Invalid Encoding Complex Field Data Type...");
1133  // //fclose(fp);
1134  // this->File.close();
1135  // return false;
1136  // break;
1137  //}
1138 
1139  // Set data for Field Size
1140  uint64_t wavlenTableSize = FldInfo.wavlenNum * sizeof(double_t);
1141 
1142  if (dataSize == 0) {
1143  LOG("Error : No Field Data");
1144  //fclose(fp);
1145  this->File.close();
1146  return false;
1147  }
1148  else {
1149  if (FldInfo.cmplxFldType != DataType::CmprFmt)
1150  FldInfo.comprsType = CompresType::Null;
1151 
1152  FldInfo.headerSize = (uint32_t)(sizeof(ohcFieldInfoHeader) + wavlenTableSize);
1153  FldInfo.fldSize = dataSize;
1154  // Wrong size
1155  FHeader.fileSize = sizeof(ohcFileHeader) + FldInfo.headerSize + FldInfo.fldSize;
1156  FHeader.fileOffBytes = sizeof(ohcFileHeader) + FldInfo.headerSize;
1157  }
1158 
1159  // write File Header
1160  File.write((char *)&FHeader, sizeof(FHeader));
1161 
1162  // write Field Info Header
1163  File.write((char *)&FldInfo, sizeof(FldInfo));
1164 
1165  // write Wavelength Table
1166  for (uint n = 0; n < FldInfo.wavlenNum; ++n) {
1167  double_t waveLength = WavLeng[n];
1168  File.write((char*)&waveLength, sizeof(double_t));
1169  }
1170 
1171  // write Complex Field Data
1172  //fwrite(this->buf, 1, sizeof(dataSize), fp);
1173  if (FldInfo.cmplxFldType == DataType::Float32)
1174  {
1175  size_t dataTypeSize = sizeof(float);
1176  ulonglong maxIdx = dataSize / dataTypeSize;
1177  for (ulonglong i = 0; i < maxIdx; i++)
1178  File.write((char *)&buf_f32[i], dataTypeSize);
1179  }
1180  else if (FldInfo.cmplxFldType == DataType::Float64)
1181  {
1182  size_t dataTypeSize = sizeof(double);
1183  ulonglong maxIdx = dataSize / dataTypeSize;
1184  for (ulonglong i = 0; i < maxIdx; i++)
1185  File.write((char *)&buf_f64[i], dataTypeSize);
1186  }
1187  //this->File.write((char*)this->buf, sizeof(dataSize));
1188 
1189  //fclose(fp);
1190  this->File.close();
1191 
1192  auto end = CUR_TIME;
1193 
1194  auto during = ((std::chrono::duration<Real>)(end - start)).count();
1195 
1196  LOG("%.5lfsec...done\n", during);
1197  return true;
1198  }
1199  else {
1200  LOG("Error : Failed saving OHC file...");
1201  return false;
1202  }
1203 }
1204 
1206 {
1207  ulonglong dataSizeBytes = 0;
1208  int n_wavlens = FldInfo.wavlenNum;
1209  int cols = FldInfo.pxNumX;
1210  int rows = FldInfo.pxNumY;
1211  int n_pixels = cols * rows;
1212  ulonglong n_fields = n_pixels * n_wavlens;
1213 
1214  int n_cmplxChnl = 0; // Is a data value Dual data(2) or Single data(1) ?
1215  if ((FldInfo.fldCodeType == FldCodeType::AP) || (FldInfo.fldCodeType == FldCodeType::RI))
1216  n_cmplxChnl = 2;
1217  else if ((FldInfo.fldCodeType == FldCodeType::AE) || (FldInfo.fldCodeType == FldCodeType::PE))
1218  n_cmplxChnl = 1;
1219 
1220  if (FldInfo.fldStore == FldStore::Directly) {
1221  if (FldInfo.cmplxFldType == DataType::Float32) {
1222  dataSizeBytes = sizeof(float) * n_fields * n_cmplxChnl;
1223  this->buf_f32 = new float[n_fields * n_cmplxChnl];
1224  std::memset(this->buf_f32, 0, dataSizeBytes);
1225  }
1226  else if (FldInfo.cmplxFldType == DataType::Float64) {
1227  dataSizeBytes = sizeof(double) * n_fields * n_cmplxChnl;
1228  this->buf_f64 = new double[n_fields * n_cmplxChnl];
1229  std::memset(this->buf_f64, 0, dataSizeBytes);
1230  }
1231 
1232  for (int x = 0; x < cols; ++x) {
1233  for (int y = 0; y < rows; ++y) {
1234  int idx = x * rows + y;
1235 
1236  for (int clrChnl = 0; clrChnl < n_wavlens; ++clrChnl) { // RGB is wavlenNum == 3
1237  ulonglong idx_sqtlChnl = n_wavlens * idx + clrChnl;
1238 
1239  if (FldInfo.clrArrange == ColorArran::SeqtChanl) {
1240  switch (FldInfo.fldCodeType) {
1241  case FldCodeType::RI: {
1242  if (FldInfo.cmplxFldType == DataType::Float32) {
1243  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1244  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_RE];
1245  *(this->buf_f32 + idx_sqtlChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_IM];
1246  }
1247  else if (FldInfo.cmplxFldType == DataType::Float64) {
1248  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1249  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_RE];
1250  *(this->buf_f64 + idx_sqtlChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_IM];
1251  }
1252  break;
1253  }
1254  case FldCodeType::AP: {
1255  if (FldInfo.cmplxFldType == DataType::Float32) {
1256  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1257  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1258  *(this->buf_f32 + idx_sqtlChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1259  }
1260  else if (FldInfo.cmplxFldType == DataType::Float64) {
1261  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1262  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1263  *(this->buf_f64 + idx_sqtlChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1264  }
1265  break;
1266  }
1267  case FldCodeType::AE: {
1268  if (FldInfo.cmplxFldType == DataType::Float32) {
1269  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1270  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1271  }
1272  else if (FldInfo.cmplxFldType == DataType::Float64) {
1273  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1274  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1275  }
1276  break;
1277  }
1278  case FldCodeType::PE: {
1279  if (FldInfo.cmplxFldType == DataType::Float32) {
1280  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1281  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1282  }
1283  else if (FldInfo.cmplxFldType == DataType::Float64) {
1284  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1285  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1286  }
1287  break;
1288  }
1289  }
1290  }
1291  else if (FldInfo.clrArrange == ColorArran::EachChanl) {
1292  ulonglong idx_eachChnl = idx + clrChnl * n_pixels;
1293 
1294  switch (FldInfo.fldCodeType) {
1295  case FldCodeType::RI: {
1296  if (FldInfo.cmplxFldType == DataType::Float32) {
1297  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1298  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_RE];
1299  *(this->buf_f32 + idx_eachChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_IM];
1300  }
1301  else if (FldInfo.cmplxFldType == DataType::Float64) {
1302  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1303  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_RE];
1304  *(this->buf_f64 + idx_eachChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_IM];
1305  }
1306  break;
1307  }
1308  case FldCodeType::AP: {
1309  if (FldInfo.cmplxFldType == DataType::Float32) {
1310  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1311  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1312  *(this->buf_f32 + idx_eachChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1313  }
1314  else if (FldInfo.cmplxFldType == DataType::Float64) {
1315  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1316  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1317  *(this->buf_f64 + idx_eachChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1318  }
1319  break;
1320  }
1321  case FldCodeType::AE: {
1322  if (FldInfo.cmplxFldType == DataType::Float32) {
1323  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1324  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1325  }
1326  else if (FldInfo.cmplxFldType == DataType::Float64) {
1327  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1328  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1329  }
1330  break;
1331  }
1332  case FldCodeType::PE: {
1333  if (FldInfo.cmplxFldType == DataType::Float32) {
1334  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1335  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1336  }
1337  else if (FldInfo.cmplxFldType == DataType::Float64) {
1338  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1339  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1340  }
1341  break;
1342  }
1343  }
1344  }
1345  }
1346  }
1347  }
1348  return dataSizeBytes;
1349  }
1350  else if (FldInfo.fldStore == FldStore::LinkFile) {
1351  LOG("Error : Link Image File Encoding is Not Yet supported...");
1352  return dataSizeBytes;
1353  }
1354  else {
1355  LOG("Error : Invalid Field Data Store Type...");
1356  return 0;
1357  }
1358 }
1359 
1360 //template<typename T>
1361 //uint64_t oph::ImgEncoderOhc::encodeFieldData() {
1362 // // Data Type Info for Encoding
1363 // bool bIsInteger = std::numeric_limits<T>::is_integer; // only float, double, long double is false
1364 // //bool bIsSigned = std::numeric_limits<T>::is_signed; // unsigned type is false, bool is too false.
1365 // double max_T = (double)std::numeric_limits<T>::max();
1366 // double min_T = (double)std::numeric_limits<T>::min();
1367 //
1368 // ulonglong dataSizeBytes = 0;
1369 // int n_wavlens = FldInfo.wavlenNum;
1370 // int cols = FldInfo.pxNumX;
1371 // int rows = FldInfo.pxNumY;
1372 // int n_pixels = cols * rows;
1373 // ulonglong n_fields = n_pixels * n_wavlens;
1374 //
1375 // int n_cmplxChnl = 0; // Is a data value Dual data(2) or Single data(1) ?
1376 // if ((FldInfo.fldCodeType == FldCodeType::AP) || (FldInfo.fldCodeType == FldCodeType::RI))
1377 // n_cmplxChnl = 2;
1378 // else if ((FldInfo.fldCodeType == FldCodeType::AE) || (FldInfo.fldCodeType == FldCodeType::PE))
1379 // n_cmplxChnl = 1;
1380 //
1381 // if (FldInfo.fldStore == FldStore::Directly) {
1382 // dataSizeBytes = sizeof(T) * n_fields * n_cmplxChnl;
1383 // this->buf = new T[n_fields * n_cmplxChnl];
1384 // std::memset(this->buf, NULL, dataSizeBytes);
1385 //
1386 // for (int y = 0; y < rows; ++y) {
1387 // for (int x = 0; x < cols; ++x) {
1388 // int idx = y * cols + x;
1389 //
1390 // for (int clrChnl = 0; clrChnl < n_wavlens; ++clrChnl) { // RGB is wavlenNum == 3
1391 // ulonglong idx_sqtlChnl = n_wavlens * idx + clrChnl;
1392 //
1393 // if (FldInfo.clrArrange == ColorArran::SeqtChanl) {
1394 // switch (FldInfo.fldCodeType) {
1395 // case FldCodeType::RI: {
1396 // if (!bIsInteger) { // floating type
1397 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1398 // *(((T*)this->buf) + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1399 // *(((T*)this->buf) + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1400 // }
1401 // else if (bIsInteger) { // integer type
1402 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1403 // *(((T*)this->buf) + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1404 // *(((T*)this->buf) + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1405 // }
1406 // break;
1407 // }
1408 // case FldCodeType::AP: {
1409 // if (!bIsInteger) {
1410 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1411 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1412 // *((T*)this->buf + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1413 // }
1414 // else if (bIsInteger) {
1415 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1416 //
1417 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1418 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1419 // *((T*)this->buf + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1420 // }
1421 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1422 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1423 // *((T*)this->buf + idx_sqtlChnl + 1 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1424 // }
1425 // }
1426 // break;
1427 // }
1428 // case FldCodeType::AE: {
1429 // if (!bIsInteger) {
1430 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1431 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1432 // }
1433 // else if (bIsInteger) {
1434 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1435 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1436 // }
1437 // break;
1438 // }
1439 // case FldCodeType::PE: {
1440 // if (!bIsInteger) {
1441 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1442 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1443 // }
1444 // else if (bIsInteger) {
1445 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1446 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1447 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1448 // }
1449 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1450 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1451 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1452 // }
1453 // }
1454 // break;
1455 // }
1456 // }
1457 // }
1458 // else if (FldInfo.clrArrange == ColorArran::EachChanl) {
1459 // ulonglong idx_eachChnl = idx + clrChnl * n_pixels;
1460 //
1461 // switch (FldInfo.fldCodeType) {
1462 // case FldCodeType::RI: {
1463 // if (!bIsInteger) { // floating type
1464 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1465 // *(((T*)this->buf) + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1466 // *(((T*)this->buf) + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1467 // }
1468 // else if (bIsInteger) { // integer type
1469 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1470 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1471 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1472 // }
1473 // break;
1474 // }
1475 // case FldCodeType::AP: {
1476 // if (!bIsInteger) {
1477 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1478 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1479 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1480 // }
1481 // else if (bIsInteger) {
1482 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1483 //
1484 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1485 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1486 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1487 // }
1488 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1489 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1490 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1491 // }
1492 // }
1493 // break;
1494 // }
1495 // case FldCodeType::AE: {
1496 // if (!bIsInteger) {
1497 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1498 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1499 // }
1500 // else if (bIsInteger) {
1501 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1502 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1503 // }
1504 // break;
1505 // }
1506 // case FldCodeType::PE: {
1507 // if (!bIsInteger) {
1508 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1509 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1510 // }
1511 // else if (bIsInteger) {
1512 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1513 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1514 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1515 // }
1516 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1517 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1518 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1519 // }
1520 // }
1521 // break;
1522 // }
1523 // }
1524 // }
1525 // }
1526 // }
1527 // }
1528 // return dataSizeBytes;
1529 // }
1530 // else if (FldInfo.fldStore == FldStore::LinkFile) {
1531 // LOG("Error : Link Image File Encoding is Not Yet supported...");
1532 // return dataSizeBytes;
1533 // }
1534 // else {
1535 // LOG("Error : Invalid Field Data Store Type...");
1536 // return 0;
1537 // }
1538 //}
1539 //
1540 //template<typename T>
1541 //T oph::ImgEncoderOhc::encodePhase(const Real phase_angle, const Real min_p, const Real max_p, const double min_T, const double max_T) {
1542 // // Normalize phase (phaseCodeMin, phaseCodeMax) to (0.0, 1.0)
1543 // Real _phase;
1544 // if (std::is_same<double, Real>::value)
1545 // _phase = (phase_angle - min_p * M_PI) / ((max_p - min_p) * M_PI);
1546 // else if (std::is_same<float, Real>::value)
1547 // _phase = (phase_angle - min_p * M_PI_F) / ((max_p - min_p) * M_PI_F);
1548 //
1549 // // Mapping to data type range
1550 // return (T)(_phase * (max_T - min_T) + min_T);
1551 //}
uint64_t encodeFieldData()
virtual ~ImgEncoderOhc()
virtual void releaseFldData()
void setColorArrange(const ColorArran _clrArrange)
oph::ColorArran getColorArrange()
virtual void initOHCheader()
Definition: ImgCodecOhc.cpp:83
float Real
Definition: typedef.h:55
#define CUR_TIME
Definition: function.h:58
virtual ~ImgCodecOhc()=0
Definition: ImgCodecOhc.cpp:66
structure for 2-dimensional integer vector and its arithmetic.
Definition: ivec.h:66
matrix< T > & resize(int x, int y)
Definition: mat.h:117
#define _Y
Definition: define.h:96
#define _IM
Definition: complex.h:58
#define FldInfo
Definition: ImgCodecOhc.cpp:56
#define _OPH_LIB_VERSION_MAJOR_
Definition: include.h:49
void getLinkFilePath(std::vector< std::string > &linkFilePath_array)
void fieldToComplex(void)
void setFieldEncoding(const FldStore _fldStore, const FldCodeType _fldCodeType)
void getComplexFieldData(OphComplexField &cmplx_field, uint wavelen_idx)
Definition: ImgCodecOhc.h:74
unsigned long long ulonglong
Definition: typedef.h:67
oph::ColorType getColorType()
#define _X
Definition: define.h:92
#define FMT_SIGN_OHC
virtual ~ImgDecoderOhc()
bool setOHCheader(const oph::ohcHeader &_Header)
Definition: ImgCodecOhc.cpp:98
virtual void releaseFldData()
void addComplexFieldData(const OphComplexField &data)
void setNumOfWavlen(const uint n_wavlens)
void getFieldInfo(oph::ohcFieldInfoHeader &_FieldInfo, std::vector< double_t > &_wavlenTable)
#define _RE
Definition: complex.h:55
void setPhaseEncoding(const BPhaseCode _bPhaseCode, const double _phaseCodeMin, const double _phaseCodeMax)
void releaseCodeBuffer()
void addWavelength(const Real wavlen)
structure for 2-dimensional Real type vector and its arithmetic.
Definition: vec.h:66
matrix< T > & zeros(void)
Definition: mat.h:140
void Field2Buffer(matrix< T > &src, T **dst)
Definition: function.h:335
#define FHeader
Definition: ImgCodecOhc.cpp:55
bool setFileName(const std::string &_fname)
Definition: ImgCodecOhc.cpp:92
oph::LenUnit getUnitOfWavlen()
void setColorType(const ColorType _clrType)
void setPixelPitch(const double _pxPitchX, const double _pxPitchY, const LenUnit unit=LenUnit::m)
oph::LenUnit getPixelPitchUnit()
void setWavelength(const Real _wavlen, const LenUnit _unit=LenUnit::m)
void setNumOfPixel(const uint _pxNumX, const uint _pxNumY)
void setUnitOfWavlen(const LenUnit unit)
void getOHCheader(oph::ohcHeader &_Header)
w
Definition: Openholo.cpp:429
void Buffer2Field(const T *src, matrix< T > &dst, const ivec2 buffer_size)
Definition: function.h:350
#define _OPH_LIB_VERSION_MINOR_
Definition: include.h:50
oph::CompresType getCompressedFormatType()
void getWavelength(std::vector< double_t > &wavlen_array)
unsigned int uint
Definition: typedef.h:62
#define WavLeng
Definition: ImgCodecOhc.cpp:57
void addWavelengthNComplexFieldData(const Real wavlen, const OphComplexField &data)
vec2 unit(const vec2 &a)
Definition: vec.h:426