Openholo  v1.1
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 
125 void oph::ImgCodecOhc::getComplexFieldData(Complex<Real>** cmplx_field, uint wavelen_idx)
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 
142 void oph::ImgCodecOhc::getComplexFieldData(Complex<Real>*** cmplx_field)
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 (int 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 (int i = 0; i < field_ampli.size(); ++i) {
205  this->field_ampli[i].release();
206  }
207  this->field_ampli.clear();
208 
209  for (int 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 
405  this->bLoadFile = true;
406  this->File.close();
407  return true;
408  }
409  else {
410  LOG("Error : Failed loading OHC file...");
411  return false;
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 
889 void oph::ImgEncoderOhc::setNumOfPixel(const ivec2 _pxNum) {
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 
1026 void oph::ImgEncoderOhc::addComplexFieldData(const Complex<Real>* data)
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  this->File.open(this->fname, std::ios::out | std::ios::trunc | std::ios::binary);
1059 
1060  //FILE *fp;
1061  //fopen_s(&fp, this->fname.c_str(), "w");
1062  //if (fp == nullptr) return false;
1063 
1064  LOG("Saving...%s...", fname.c_str());
1065  auto start = CUR_TIME;
1066  //if (fp) {
1067  if (this->File.is_open()) {
1068  if (this->Header == nullptr) {
1069  //this->Header = new ohcHeader();
1070  this->initOHCheader();
1071  }
1072 
1073  // Encoding Field Data
1074  uint64_t dataSize = 0;
1075  switch (FldInfo.cmplxFldType) {
1076  case DataType::Float64:
1077  case DataType::Float32:
1078  dataSize = encodeFieldData();
1079  break;
1080  case DataType::CmprFmt:
1081  LOG("Error : Compressed Image Format Encoding is Not Yet supported...");
1082  //fclose(fp);
1083  this->File.close();
1084  return false;
1085  break;
1086  default:
1087  LOG("Error : Invalid Encoding Complex Field Data Type...");
1088  //fclose(fp);
1089  this->File.close();
1090  return false;
1091  break;
1092  }
1093  //switch (FldInfo.cmplxFldType) {
1094  //case DataType::Float64:
1095  // dataSize = encodeFieldData<double_t>();
1096  // break;
1097  //case DataType::Float32:
1098  // dataSize = encodeFieldData<float_t>();
1099  // break;
1100  //case DataType::Int8:
1101  // dataSize = encodeFieldData<int8_t>();
1102  // break;
1103  //case DataType::Int16:
1104  // dataSize = encodeFieldData<int16_t>();
1105  // break;
1106  //case DataType::Int32:
1107  // dataSize = encodeFieldData<int32_t>();
1108  // break;
1109  //case DataType::Int64:
1110  // dataSize = encodeFieldData<int64_t>();
1111  // break;
1112  //case DataType::Uint8:
1113  // dataSize = encodeFieldData<uint8_t>();
1114  // break;
1115  //case DataType::Uint16:
1116  // dataSize = encodeFieldData<uint16_t>();
1117  // break;
1118  //case DataType::Uint32:
1119  // dataSize = encodeFieldData<uint32_t>();
1120  // break;
1121  //case DataType::Uint64:
1122  // dataSize = encodeFieldData<uint64_t>();
1123  // break;
1124  //case DataType::CmprFmt:
1125  // LOG("Error : Compressed Image Format Encoding is Not Yet supported...");
1126  // //fclose(fp);
1127  // this->File.close();
1128  // return false;
1129  // break;
1130  //default:
1131  // LOG("Error : Invalid Encoding Complex Field Data Type...");
1132  // //fclose(fp);
1133  // this->File.close();
1134  // return false;
1135  // break;
1136  //}
1137 
1138  // Set data for Field Size
1139  uint64_t wavlenTableSize = FldInfo.wavlenNum * sizeof(double_t);
1140 
1141  if (dataSize == 0) {
1142  LOG("Error : No Field Data");
1143  //fclose(fp);
1144  this->File.close();
1145  return false;
1146  }
1147  else {
1148  if (FldInfo.cmplxFldType != DataType::CmprFmt)
1149  FldInfo.comprsType = CompresType::Null;
1150 
1151  FldInfo.headerSize = (uint32_t)(sizeof(ohcFieldInfoHeader) + wavlenTableSize);
1152  FldInfo.fldSize = dataSize;
1153  // Wrong size
1154  FHeader.fileSize = sizeof(ohcFileHeader) + FldInfo.headerSize + FldInfo.fldSize;
1155  FHeader.fileOffBytes = sizeof(ohcFileHeader) + FldInfo.headerSize;
1156  }
1157 
1158  // write File Header
1159  File.write((char *)&FHeader, sizeof(FHeader));
1160 
1161  // write Field Info Header
1162  File.write((char *)&FldInfo, sizeof(FldInfo));
1163 
1164  // write Wavelength Table
1165  for (uint n = 0; n < FldInfo.wavlenNum; ++n) {
1166  double_t waveLength = WavLeng[n];
1167  File.write((char*)&waveLength, sizeof(double_t));
1168  }
1169 
1170  // write Complex Field Data
1171  //fwrite(this->buf, 1, sizeof(dataSize), fp);
1172  if (FldInfo.cmplxFldType == DataType::Float32)
1173  {
1174  size_t dataTypeSize = sizeof(float);
1175  ulonglong maxIdx = dataSize / dataTypeSize;
1176  for (ulonglong i = 0; i < maxIdx; i++)
1177  File.write((char *)&buf_f32[i], dataTypeSize);
1178  }
1179  else if (FldInfo.cmplxFldType == DataType::Float64)
1180  {
1181  size_t dataTypeSize = sizeof(double);
1182  ulonglong maxIdx = dataSize / dataTypeSize;
1183  for (ulonglong i = 0; i < maxIdx; i++)
1184  File.write((char *)&buf_f64[i], dataTypeSize);
1185  }
1186  //this->File.write((char*)this->buf, sizeof(dataSize));
1187 
1188  //fclose(fp);
1189  this->File.close();
1190 
1191  auto end = CUR_TIME;
1192 
1193  auto during = ((std::chrono::duration<Real>)(end - start)).count();
1194 
1195  LOG("%.5lfsec...done\n", during);
1196  return true;
1197  }
1198  else {
1199  LOG("Error : Failed saving OHC file...");
1200  return false;
1201  }
1202 }
1203 
1205 {
1206  ulonglong dataSizeBytes = 0;
1207  int n_wavlens = FldInfo.wavlenNum;
1208  int cols = FldInfo.pxNumX;
1209  int rows = FldInfo.pxNumY;
1210  int n_pixels = cols * rows;
1211  ulonglong n_fields = n_pixels * n_wavlens;
1212 
1213  int n_cmplxChnl = 0; // Is a data value Dual data(2) or Single data(1) ?
1214  if ((FldInfo.fldCodeType == FldCodeType::AP) || (FldInfo.fldCodeType == FldCodeType::RI))
1215  n_cmplxChnl = 2;
1216  else if ((FldInfo.fldCodeType == FldCodeType::AE) || (FldInfo.fldCodeType == FldCodeType::PE))
1217  n_cmplxChnl = 1;
1218 
1219  if (FldInfo.fldStore == FldStore::Directly) {
1220  if (FldInfo.cmplxFldType == DataType::Float32) {
1221  dataSizeBytes = sizeof(float) * n_fields * n_cmplxChnl;
1222  this->buf_f32 = new float[n_fields * n_cmplxChnl];
1223  std::memset(this->buf_f32, NULL, dataSizeBytes);
1224  }
1225  else if (FldInfo.cmplxFldType == DataType::Float64) {
1226  dataSizeBytes = sizeof(double) * n_fields * n_cmplxChnl;
1227  this->buf_f64 = new double[n_fields * n_cmplxChnl];
1228  std::memset(this->buf_f64, NULL, dataSizeBytes);
1229  }
1230 
1231  for (int x = 0; x < cols; ++x) {
1232  for (int y = 0; y < rows; ++y) {
1233  int idx = x * rows + y;
1234 
1235  for (int clrChnl = 0; clrChnl < n_wavlens; ++clrChnl) { // RGB is wavlenNum == 3
1236  ulonglong idx_sqtlChnl = n_wavlens * idx + clrChnl;
1237 
1238  if (FldInfo.clrArrange == ColorArran::SeqtChanl) {
1239  switch (FldInfo.fldCodeType) {
1240  case FldCodeType::RI: {
1241  if (FldInfo.cmplxFldType == DataType::Float32) {
1242  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1243  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_RE];
1244  *(this->buf_f32 + idx_sqtlChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_IM];
1245  }
1246  else if (FldInfo.cmplxFldType == DataType::Float64) {
1247  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1248  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_RE];
1249  *(this->buf_f64 + idx_sqtlChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_IM];
1250  }
1251  break;
1252  }
1253  case FldCodeType::AP: {
1254  if (FldInfo.cmplxFldType == DataType::Float32) {
1255  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1256  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1257  *(this->buf_f32 + idx_sqtlChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1258  }
1259  else if (FldInfo.cmplxFldType == DataType::Float64) {
1260  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1261  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1262  *(this->buf_f64 + idx_sqtlChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1263  }
1264  break;
1265  }
1266  case FldCodeType::AE: {
1267  if (FldInfo.cmplxFldType == DataType::Float32) {
1268  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1269  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1270  }
1271  else if (FldInfo.cmplxFldType == DataType::Float64) {
1272  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1273  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1274  }
1275  break;
1276  }
1277  case FldCodeType::PE: {
1278  if (FldInfo.cmplxFldType == DataType::Float32) {
1279  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1280  *(this->buf_f32 + idx_sqtlChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1281  }
1282  else if (FldInfo.cmplxFldType == DataType::Float64) {
1283  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1284  *(this->buf_f64 + idx_sqtlChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1285  }
1286  break;
1287  }
1288  }
1289  }
1290  else if (FldInfo.clrArrange == ColorArran::EachChanl) {
1291  ulonglong idx_eachChnl = idx + clrChnl * n_pixels;
1292 
1293  switch (FldInfo.fldCodeType) {
1294  case FldCodeType::RI: {
1295  if (FldInfo.cmplxFldType == DataType::Float32) {
1296  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1297  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_RE];
1298  *(this->buf_f32 + idx_eachChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y][_IM];
1299  }
1300  else if (FldInfo.cmplxFldType == DataType::Float64) {
1301  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1302  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_RE];
1303  *(this->buf_f64 + idx_eachChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y][_IM];
1304  }
1305  break;
1306  }
1307  case FldCodeType::AP: {
1308  if (FldInfo.cmplxFldType == DataType::Float32) {
1309  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1310  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1311  *(this->buf_f32 + idx_eachChnl + 1 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1312  }
1313  else if (FldInfo.cmplxFldType == DataType::Float64) {
1314  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1315  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1316  *(this->buf_f64 + idx_eachChnl + 1 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1317  }
1318  break;
1319  }
1320  case FldCodeType::AE: {
1321  if (FldInfo.cmplxFldType == DataType::Float32) {
1322  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1323  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].mag();
1324  }
1325  else if (FldInfo.cmplxFldType == DataType::Float64) {
1326  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1327  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].mag();
1328  }
1329  break;
1330  }
1331  case FldCodeType::PE: {
1332  if (FldInfo.cmplxFldType == DataType::Float32) {
1333  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1334  *(this->buf_f32 + idx_eachChnl + 0 * n_fields) = (float)this->field_cmplx[clrChnl][x][y].angle();
1335  }
1336  else if (FldInfo.cmplxFldType == DataType::Float64) {
1337  setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1338  *(this->buf_f64 + idx_eachChnl + 0 * n_fields) = (double)this->field_cmplx[clrChnl][x][y].angle();
1339  }
1340  break;
1341  }
1342  }
1343  }
1344  }
1345  }
1346  }
1347  return dataSizeBytes;
1348  }
1349  else if (FldInfo.fldStore == FldStore::LinkFile) {
1350  LOG("Error : Link Image File Encoding is Not Yet supported...");
1351  return dataSizeBytes;
1352  }
1353  else {
1354  LOG("Error : Invalid Field Data Store Type...");
1355  return 0;
1356  }
1357 }
1358 
1359 //template<typename T>
1360 //uint64_t oph::ImgEncoderOhc::encodeFieldData() {
1361 // // Data Type Info for Encoding
1362 // bool bIsInteger = std::numeric_limits<T>::is_integer; // only float, double, long double is false
1363 // //bool bIsSigned = std::numeric_limits<T>::is_signed; // unsigned type is false, bool is too false.
1364 // double max_T = (double)std::numeric_limits<T>::max();
1365 // double min_T = (double)std::numeric_limits<T>::min();
1366 //
1367 // ulonglong dataSizeBytes = 0;
1368 // int n_wavlens = FldInfo.wavlenNum;
1369 // int cols = FldInfo.pxNumX;
1370 // int rows = FldInfo.pxNumY;
1371 // int n_pixels = cols * rows;
1372 // ulonglong n_fields = n_pixels * n_wavlens;
1373 //
1374 // int n_cmplxChnl = 0; // Is a data value Dual data(2) or Single data(1) ?
1375 // if ((FldInfo.fldCodeType == FldCodeType::AP) || (FldInfo.fldCodeType == FldCodeType::RI))
1376 // n_cmplxChnl = 2;
1377 // else if ((FldInfo.fldCodeType == FldCodeType::AE) || (FldInfo.fldCodeType == FldCodeType::PE))
1378 // n_cmplxChnl = 1;
1379 //
1380 // if (FldInfo.fldStore == FldStore::Directly) {
1381 // dataSizeBytes = sizeof(T) * n_fields * n_cmplxChnl;
1382 // this->buf = new T[n_fields * n_cmplxChnl];
1383 // std::memset(this->buf, NULL, dataSizeBytes);
1384 //
1385 // for (int y = 0; y < rows; ++y) {
1386 // for (int x = 0; x < cols; ++x) {
1387 // int idx = y * cols + x;
1388 //
1389 // for (int clrChnl = 0; clrChnl < n_wavlens; ++clrChnl) { // RGB is wavlenNum == 3
1390 // ulonglong idx_sqtlChnl = n_wavlens * idx + clrChnl;
1391 //
1392 // if (FldInfo.clrArrange == ColorArran::SeqtChanl) {
1393 // switch (FldInfo.fldCodeType) {
1394 // case FldCodeType::RI: {
1395 // if (!bIsInteger) { // floating type
1396 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1397 // *(((T*)this->buf) + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1398 // *(((T*)this->buf) + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1399 // }
1400 // else if (bIsInteger) { // integer type
1401 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1402 // *(((T*)this->buf) + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1403 // *(((T*)this->buf) + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1404 // }
1405 // break;
1406 // }
1407 // case FldCodeType::AP: {
1408 // if (!bIsInteger) {
1409 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1410 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1411 // *((T*)this->buf + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1412 // }
1413 // else if (bIsInteger) {
1414 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1415 //
1416 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1417 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1418 // *((T*)this->buf + idx_sqtlChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1419 // }
1420 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1421 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1422 // *((T*)this->buf + idx_sqtlChnl + 1 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1423 // }
1424 // }
1425 // break;
1426 // }
1427 // case FldCodeType::AE: {
1428 // if (!bIsInteger) {
1429 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1430 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1431 // }
1432 // else if (bIsInteger) {
1433 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1434 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1435 // }
1436 // break;
1437 // }
1438 // case FldCodeType::PE: {
1439 // if (!bIsInteger) {
1440 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1441 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1442 // }
1443 // else if (bIsInteger) {
1444 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1445 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1446 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1447 // }
1448 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1449 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1450 // *((T*)this->buf + idx_sqtlChnl + 0 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1451 // }
1452 // }
1453 // break;
1454 // }
1455 // }
1456 // }
1457 // else if (FldInfo.clrArrange == ColorArran::EachChanl) {
1458 // ulonglong idx_eachChnl = idx + clrChnl * n_pixels;
1459 //
1460 // switch (FldInfo.fldCodeType) {
1461 // case FldCodeType::RI: {
1462 // if (!bIsInteger) { // floating type
1463 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1464 // *(((T*)this->buf) + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1465 // *(((T*)this->buf) + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1466 // }
1467 // else if (bIsInteger) { // integer type
1468 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1469 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_RE];
1470 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y][_IM];
1471 // }
1472 // break;
1473 // }
1474 // case FldCodeType::AP: {
1475 // if (!bIsInteger) {
1476 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1477 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1478 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1479 // }
1480 // else if (bIsInteger) {
1481 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1482 //
1483 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1484 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1485 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1486 // }
1487 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1488 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1489 // *((T*)this->buf + idx_eachChnl + 1 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1490 // }
1491 // }
1492 // break;
1493 // }
1494 // case FldCodeType::AE: {
1495 // if (!bIsInteger) {
1496 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1497 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1498 // }
1499 // else if (bIsInteger) {
1500 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1501 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].mag();
1502 // }
1503 // break;
1504 // }
1505 // case FldCodeType::PE: {
1506 // if (!bIsInteger) {
1507 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1508 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1509 // }
1510 // else if (bIsInteger) {
1511 // if (FldInfo.bPhaseCode == BPhaseCode::NotEncoded) {
1512 // setPhaseEncoding(BPhaseCode::NotEncoded, -1.0, 1.0);
1513 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = (T)this->field_cmplx[clrChnl][x][y].angle();
1514 // }
1515 // else if (FldInfo.bPhaseCode == BPhaseCode::Encoded) {
1516 // Real angle = this->field_cmplx[clrChnl][x][y].angle(); //atan2 : return -3.141592(-1.*PI) ~ 3.141592(1.*PI)
1517 // *((T*)this->buf + idx_eachChnl + 0 * n_fields) = this->encodePhase<T>(angle, FldInfo.phaseCodeMin, FldInfo.phaseCodeMax, min_T, max_T);
1518 // }
1519 // }
1520 // break;
1521 // }
1522 // }
1523 // }
1524 // }
1525 // }
1526 // }
1527 // return dataSizeBytes;
1528 // }
1529 // else if (FldInfo.fldStore == FldStore::LinkFile) {
1530 // LOG("Error : Link Image File Encoding is Not Yet supported...");
1531 // return dataSizeBytes;
1532 // }
1533 // else {
1534 // LOG("Error : Invalid Field Data Store Type...");
1535 // return 0;
1536 // }
1537 //}
1538 //
1539 //template<typename T>
1540 //T oph::ImgEncoderOhc::encodePhase(const Real phase_angle, const Real min_p, const Real max_p, const double min_T, const double max_T) {
1541 // // Normalize phase (phaseCodeMin, phaseCodeMax) to (0.0, 1.0)
1542 // Real _phase;
1543 // if (std::is_same<double, Real>::value)
1544 // _phase = (phase_angle - min_p * M_PI) / ((max_p - min_p) * M_PI);
1545 // else if (std::is_same<float, Real>::value)
1546 // _phase = (phase_angle - min_p * M_PI_F) / ((max_p - min_p) * M_PI_F);
1547 //
1548 // // Mapping to data type range
1549 // return (T)(_phase * (max_T - min_T) + min_T);
1550 //}
uint64_t encodeFieldData()
oph::matrix< Complex< Real > > OphComplexField
Definition: mat.h:421
#define _OPH_LIB_VERSION_MAJOR_
Definition: include.h:49
#define _IM
Definition: complex.h:57
virtual ~ImgEncoderOhc()
virtual void releaseFldData()
void setColorArrange(const ColorArran _clrArrange)
ColorArran getColorArrange()
virtual void initOHCheader()
Definition: ImgCodecOhc.cpp:83
bool setOHCheader(const ohcHeader &_Header)
Definition: ImgCodecOhc.cpp:98
virtual ~ImgCodecOhc()=0
Definition: ImgCodecOhc.cpp:66
#define _Y
Definition: define.h:84
void getFieldInfo(ohcFieldInfoHeader &_FieldInfo, std::vector< double_t > &_wavlenTable)
void getOHCheader(ohcHeader &_Header)
#define FMT_SIGN_OHC
#define _RE
Definition: complex.h:54
#define FldInfo
Definition: ImgCodecOhc.cpp:56
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:81
unsigned long long ulonglong
Definition: typedef.h:67
ColorType getColorType()
virtual ~ImgDecoderOhc()
virtual void releaseFldData()
void addComplexFieldData(const OphComplexField &data)
#define CUR_TIME
Definition: function.h:58
void setNumOfWavlen(const uint n_wavlens)
#define _OPH_LIB_VERSION_MINOR_
Definition: include.h:50
void setPhaseEncoding(const BPhaseCode _bPhaseCode, const double _phaseCodeMin, const double _phaseCodeMax)
void releaseCodeBuffer()
oph::matrix< Real > OphRealField
Definition: mat.h:419
void addWavelength(const Real wavlen)
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
LenUnit getUnitOfWavlen()
void setColorType(const ColorType _clrType)
void setPixelPitch(const double _pxPitchX, const double _pxPitchY, const LenUnit unit=LenUnit::m)
LenUnit getPixelPitchUnit()
void setWavelength(const Real _wavlen, const LenUnit _unit=LenUnit::m)
void setNumOfPixel(const uint _pxNumX, const uint _pxNumY)
float Real
Definition: typedef.h:55
void setUnitOfWavlen(const LenUnit unit)
void Buffer2Field(const T *src, matrix< T > &dst, const ivec2 buffer_size)
Definition: function.h:350
#define _X
Definition: define.h:80
CompresType getCompressedFormatType()
void getWavelength(std::vector< double_t > &wavlen_array)
int w
Definition: 2D-RS.py:16
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