OB.DAAC Logo
NASA Logo
Ocean Color Science Software

ocssw V2022
OutFile.cpp
Go to the documentation of this file.
1 #include <xtiffio.h>
2 #include <geo_normalize.h>
3 
4 #include "OutFile.h"
5 
6 #include <stdio.h>
7 #include <iostream>
8 #include <math.h>
9 #include <genutils.h>
10 #include <timeutils.h>
11 #include <nc4utils.h>
12 #include <string>
13 #include <float.h>
14 #include <regex>
15 
16 #include <hdf.h>
17 #include <mfhdf.h>
18 
19 #include <boost/algorithm/string/trim.hpp>
20 #include <boost/algorithm/string/case_conv.hpp>
21 #include <boost/algorithm/string/predicate.hpp>
22 #include <boost/algorithm/string.hpp>
23 
24 #include <geo_tiffp.h>
25 
26 using namespace std;
27 
28 //------------------------------------------------------------------------------
29 // OutFile::ProductStuff
30 //------------------------------------------------------------------------------
31 
33  const productInfo_t* productInfo) {
34  this->width = width;
35  this->productInfo = allocateProductInfo();
36  copyProductInfo(this->productInfo, productInfo);
37  dataStorage = UByteDS;
38  scaleType = Linear;
39  scale = 1.0;
40  offset = 0.0;
41  minOutputVal = 0;
42  maxOutputVal = 255;
43  minVal = minOutputVal;
44  maxVal = maxOutputVal;
45  missingValue = fillPix;
46  lineData = (double*) allocateMemory(width * sizeof (double),
47  "OutFile::ProductStuff::lineData");
48 }
49 
51  width = pStuff.width;
52  productInfo = allocateProductInfo();
53  copyProductInfo(productInfo, pStuff.productInfo);
54  dataStorage = pStuff.dataStorage;
55  scaleType = pStuff.scaleType;
56  scale = pStuff.scale;
57  offset = pStuff.offset;
58  minOutputVal = pStuff.minOutputVal;
59  maxOutputVal = pStuff.maxOutputVal;
60  minVal = pStuff.minVal;
61  maxVal = pStuff.maxVal;
62  missingValue = pStuff.missingValue;
63  lineData = (double*) allocateMemory(width * sizeof (double),
64  "OutFile::ProductStuff::lineData");
65 }
66 
68  freeProductInfo(productInfo);
69  free(lineData);
70 }
71 
79  ScaleType scaleType) {
80  this->scaleType = scaleType;
81  minVal = min;
82  maxVal = max;
83  switch (scaleType) {
84  case Linear:
85  offset = min;
86  scale = (max - offset) / (maxOutputVal - minOutputVal);
87  break;
88  case Log:
89  offset = log10(min);
90  scale = (log10(max) - offset) / (maxOutputVal - minOutputVal);
91  break;
92  case ArcTan:
93  offset = min;
94  scale = max;
95  minVal = calcPhysicalVal(minOutputVal);
96  maxVal = calcPhysicalVal(maxOutputVal);
97  break;
98  default:
99  printf("-E- OutFile::setScale - invalid scaleType = %d\n",
100  (int) scaleType);
101  exit(EXIT_FAILURE);
102  }
103 }
104 
106  ScaleType scaleType, double minOutput, double maxOutput) {
107  minOutputVal = minOutput;
108  maxOutputVal = maxOutput;
109  setScale(min, max, scaleType);
110 }
111 
119  ScaleType scaleType) {
120  this->scaleType = scaleType;
121  this->scale = scale;
122  this->offset = offset;
123 
124  // have to set these so calcPhysicalVal does not limit the physical val
125  minVal = 0 - FLT_MAX;
126  maxVal = FLT_MAX;
127  minVal = calcPhysicalVal(minOutputVal);
128  maxVal = calcPhysicalVal(maxOutputVal);
129 }
130 
132  ScaleType scaleType, double minOutput, double maxOutput) {
133  minOutputVal = minOutput;
134  maxOutputVal = maxOutput;
135  setScaleOffset(scale, offset, scaleType);
136 }
137 
139  double outVal;
140 
141  if (val == badPixelValue)
142  return missingValue;
143 
144  if (val == landPixelValue)
145  return landPix;
146 
147  // don't scale if output type is floating point
148  if (dataStorage == FloatDS || dataStorage == DoubleDS)
149  return val;
150 
151  switch (scaleType) {
152  case Linear:
153  outVal = (val - offset) / scale;
154  break;
155  case Log:
156  if (val < 0)
157  return minOutputVal;
158  else
159  outVal = (log10(val) - offset) / scale;
160  break;
161  case ArcTan:
162  outVal = scale * ((atan(0.5 * val - offset) / atan(offset)) + 1);
163  break;
164  default:
165  printf("-E- OutFile::ProductStuff::calcOutputVal - invalid scaleType = %d\n",
166  (int) scaleType);
167  exit(EXIT_FAILURE);
168  }
169 
170  if (outVal < minOutputVal)
171  return minOutputVal;
172  if (outVal > maxOutputVal)
173  return maxOutputVal;
174  return outVal;
175 }
176 
178  double physicalVal;
179 
180  if (val == missingValue)
181  return badPixelValue;
182 
183  // don't scale if out output type is floating point
184  if (dataStorage == FloatDS || dataStorage == DoubleDS)
185  return val;
186 
187  switch (scaleType) {
188  case Linear:
189  physicalVal = val * scale + offset;
190  break;
191  case Log:
192  physicalVal = pow(10, val * scale + offset);
193  break;
194  case ArcTan:
195  physicalVal = (tan((val / scale - 1) * atan(offset)) + offset) / 0.5;
196  break;
197  default:
198  printf("-E- OutFile::ProductStuff::calcPhysicalVal - invalid scaleType = %d\n",
199  (int) scaleType);
200  exit(EXIT_FAILURE);
201  }
202 
203  if (physicalVal < minVal)
204  return minVal;
205  if (physicalVal > maxVal)
206  return maxVal;
207  return physicalVal;
208 }
209 
210 void OutFile::ProductStuff::calcOutputLineVals(void* lineBuffer) const {
211  switch (dataStorage) {
212  case ByteDS:
213  for (int i = 0; i < width; i++)
214  ((int8_t*) lineBuffer)[i] = round(calcOutputVal(lineData[i]));
215  break;
216  case UByteDS:
217  for (int i = 0; i < width; i++)
218  ((uint8_t*) lineBuffer)[i] = round(calcOutputVal(lineData[i]));
219  break;
220  case ShortDS:
221  for (int i = 0; i < width; i++)
222  ((int16_t*) lineBuffer)[i] = round(calcOutputVal(lineData[i]));
223  break;
224  case UShortDS:
225  for (int i = 0; i < width; i++)
226  ((uint16_t*) lineBuffer)[i] = round(calcOutputVal(lineData[i]));
227  break;
228  case IntDS:
229  for (int i = 0; i < width; i++)
230  ((int32_t*) lineBuffer)[i] = round(calcOutputVal(lineData[i]));
231  break;
232  case UIntDS:
233  for (int i = 0; i < width; i++)
234  ((uint32_t*) lineBuffer)[i] = round(calcOutputVal(lineData[i]));
235  break;
236  case FloatDS:
237  for (int i = 0; i < width; i++)
238  ((float*) lineBuffer)[i] = lineData[i];
239  break;
240  case DoubleDS:
241  for (int i = 0; i < width; i++)
242  ((double*) lineBuffer)[i] = lineData[i];
243  break;
244  default:
245  printf("-E- OutFile::ProductStuff::calcOutputLineVals - unrecognized data type = %d\n",
246  dataStorage);
247  exit(EXIT_FAILURE);
248  }
249 }
250 
251 //------------------------------------------------------------------------------
252 // OutFile
253 //------------------------------------------------------------------------------
254 
256  width = 0;
257  height = 0;
258  qualityData = NULL;
259  currentLine = 0;
260  colorType = Grayscale;
261  fileMinVal = DBL_MAX;
262  fileMaxVal = 0 - DBL_MAX;
263  resolution = 0;
264  deflate = 0;
265  fullLatLon = LatLon2D;
266  latData = NULL;
267  lonData = NULL;
268 
269  red = (uint8_t*) allocateMemory(256, "red");
270  green = (uint8_t*) allocateMemory(256, "green");
271  blue = (uint8_t*) allocateMemory(256, "blue");
272 
273  // init to grayscale
274  for (int i = 0; i < 256; i++) {
275  red[i] = i;
276  green[i] = i;
277  blue[i] = i;
278  }
279  rgb_land = (uint8_t*) allocateMemory(3, "rgb_land");
280  rgb_land[0] = 160;
281  rgb_land[1] = 82;
282  rgb_land[3] = 45;
283  transparent = false;
284 
285  metaData = (meta_l3bType*) allocateMemory(sizeof(meta_l3bType),
286  "OutFile::metaData");
287  metaData->north = 90.0;
288  metaData->south = -90.0;
289  metaData->east = 180.0;
290  metaData->west = -180.0;
291 
292  mapProjection = "Undefined";
293 }
294 
296  free(red);
297  free(green);
298  free(blue);
299  free(rgb_land);
300  for (size_t i = 0; i < productStuff.size(); i++) {
301  delete productStuff[i];
302  }
303  productStuff.clear();
304  free(metaData);
305  if (qualityData)
306  free(qualityData);
307 }
308 
310  switch(productStuff[prod]->scaleType) {
311  case Log: return "Log";
312  case Linear: return "Linear";
313  case ArcTan: return "ArcTan";
314  }
315  return "Linear";
316 }
317 
318 void OutFile::setSize(int32_t width, int32_t height) {
319  this->width = width;
320  this->height = height;
321  if (qualityData) {
322  free(qualityData);
323  qualityData = (uint8_t*) allocateMemory(width, "OutFile::qualityData");
324  }
325  currentLine = 0;
326 
327  for (size_t i = 0; i < productStuff.size(); i++) {
328  delete productStuff[i];
329  }
330  productStuff.clear();
331 }
332 
333 int32_t OutFile::getWidth() const {
334  return width;
335 }
336 
337 int32_t OutFile::getHeight() const {
338  return height;
339 }
340 
341 void OutFile::setFileName(string fileName) {
342  this->fileName = fileName;
343 }
344 
345 void OutFile::setPixel(int32_t x, double val, int32_t prod) {
346  if (x < 0 || x >= width) {
347  fprintf(stderr,
348  "-E- OutFile::setPixel - x=%d is not within range, width=%d.\n",
349  x, width);
350  exit(EXIT_FAILURE);
351  }
352  productStuff[prod]->lineData[x] = val;
353  if (val > fileMaxVal)
354  fileMaxVal = val;
355  if (val < fileMinVal)
356  fileMinVal = val;
357 }
358 
359 void OutFile::setPixelRGB(int32_t x, float red, float green, float blue) {
360  fprintf(stderr,
361  "-E- OutFile::setPixelRGB - RGB not implemented with this file type.\n");
362  exit(EXIT_FAILURE);
363 }
364 
366  transparent = true;
367 }
368 
369 void OutFile::setQuality(int32_t x, uint8_t val) {
370  if (x < 0 || x >= width) {
371  fprintf(stderr,
372  "-E- OutFile::setQuality - x=%d is not within range, width=%d.\n",
373  x, width);
374  exit(EXIT_FAILURE);
375  }
376  if (!qualityData) {
377  fprintf(stderr, "-E- OutFile::setQuality - qualityData id NULL.\n");
378  exit(EXIT_FAILURE);
379  }
380  qualityData[x] = val;
381 }
382 
383 void OutFile::landPixel(int32_t x) {
384  if (x < 0 || x >= width) {
385  fprintf(stderr,
386  "-E- OutFile::landPixel - x=%d is not within range, width=%d.\n",
387  x, width);
388  exit(EXIT_FAILURE);
389  }
390  for (size_t prod = 0; prod < productStuff.size(); prod++)
391  productStuff[prod]->lineData[x] = landPixelValue;
392  if (qualityData)
393  qualityData[x] = qualityUnused;
394 }
395 
396 void OutFile::fillPixel(int32_t x) {
397  if (x < 0 || x >= width) {
398  fprintf(stderr,
399  "-E- OutFile::fillPixel - x=%d is not within range, width=%d.\n",
400  x, width);
401  exit(EXIT_FAILURE);
402  }
403  for (size_t prod = 0; prod < productStuff.size(); prod++)
404  productStuff[prod]->lineData[x] = badPixelValue;
405  if (qualityData)
406  qualityData[x] = qualityUnused;
407 }
408 
409 void OutFile::missingPixel(int32_t x) {
410  if (x < 0 || x >= width) {
411  fprintf(stderr,
412  "-E- OutFile::missingPixel - x=%d is not within range, width=%d.\n",
413  x, width);
414  exit(EXIT_FAILURE);
415  }
416  for (size_t prod = 0; prod < productStuff.size(); prod++)
417  productStuff[prod]->lineData[x] = badPixelValue;
418  if (qualityData)
419  qualityData[x] = qualityUnused;
420 }
421 
422 void OutFile::setLatLon(double* lat, double* lon) {
423  if (fullLatLon == LatLon2D) {
424  // NcVar::putVar takes care of converting double to float
425  if (not latData)
426  latData = lat;
427  if (not lonData)
428  lonData = lon;
429  }
430 }
431 
432 bool OutFile::setPalette(const char* paletteName, bool applyMask) {
433  char* dataRoot;
434  string paletteFileName;
435  short r[256], g[256], b[256];
436 
437  if ((dataRoot = getenv("OCDATAROOT")) == NULL) {
438  printf("OCDATAROOT environment variable is not defined.\n");
439  return (EXIT_FAILURE);
440  }
441  paletteFileName = dataRoot;
442  paletteFileName += "/common/palette/";
443  paletteFileName += paletteName;
444  paletteFileName += ".pal";
445 
446  if (getlut_file((char*) paletteFileName.c_str(), r, g, b)) {
447  fprintf(stderr, "Error reading palette file %s\n",
448  paletteFileName.c_str());
449  return false;
450  }
451  if (applyMask) {
452  r[landPix] = rgb_land[0];
453  g[landPix] = rgb_land[1];
454  b[landPix] = rgb_land[2];
455  r[fillPix] = 0;
456  g[fillPix] = 0;
457  b[fillPix] = 0;
458  }
459  for (int i = 0; i < 256; i++) {
460  red[i] = r[i];
461  green[i] = g[i];
462  blue[i] = b[i];
463  }
464 
465  return true;
466 }
467 
468 void OutFile::setLandRGB(const char* rgb_land_string) {
469  vector<string> rgb;
470  boost::split(rgb, rgb_land_string, boost::is_any_of(","));
471 
472  rgb_land[0] = std::stoi(rgb[0]);
473  rgb_land[1] = std::stoi(rgb[1]);
474  rgb_land[2] = std::stoi(rgb[2]);
475 }
476 
478  *this->metaData = *metaData;
479 }
480 
486 int32_t OutFile::addProduct(productInfo_t* productInfo) {
487  ProductStuff* stuff = new ProductStuff(width, productInfo);
488 
489  // setup display scaling
490  if (!strcmp(productInfo->displayScale, "linear"))
491  stuff->setScale(productInfo->displayMin, productInfo->displayMax,
492  Linear);
493  else if (!strcmp(productInfo->displayScale, "log"))
494  stuff->setScale(productInfo->displayMin, productInfo->displayMax, Log);
495  else if (!strcmp(productInfo->displayScale, "arctan"))
496  stuff->setScale(productInfo->displayMin, productInfo->displayMax,
497  ArcTan);
498  else {
499  printf("-E- OutFile::addProduct - invalid displayScale = %s\n",
500  productInfo->displayScale);
501  exit(EXIT_FAILURE);
502  }
503 
504  productStuff.push_back(stuff);
505  return productStuff.size() - 1;
506 }
507 
508 int32_t OutFile::addProductNonDisplay(productInfo_t* productInfo) {
509  ProductStuff* stuff = new ProductStuff(width, productInfo);
510 
511  if (!strcmp(productInfo->dataType, "byte")) {
512  stuff->dataStorage = ByteDS;
513  stuff->minOutputVal = SCHAR_MIN;
514  stuff->maxOutputVal = SCHAR_MAX;
515  } else if (!strcmp(productInfo->dataType, "ubyte")) {
516  stuff->dataStorage = UByteDS;
517  stuff->minOutputVal = 0;
518  stuff->maxOutputVal = UCHAR_MAX;
519  } else if (!strcmp(productInfo->dataType, "short")) {
520  stuff->dataStorage = ShortDS;
521  stuff->minOutputVal = SHRT_MIN;
522  stuff->maxOutputVal = SHRT_MAX;
523  } else if (!strcmp(productInfo->dataType, "ushort")) {
524  stuff->dataStorage = UShortDS;
525  stuff->minOutputVal = 0;
526  stuff->maxOutputVal = USHRT_MAX;
527  } else if (!strcmp(productInfo->dataType, "int")) {
528  stuff->dataStorage = IntDS;
529  stuff->minOutputVal = INT_MIN;
530  stuff->maxOutputVal = INT_MAX;
531  } else if (!strcmp(productInfo->dataType, "uint")) {
532  stuff->dataStorage = UIntDS;
533  stuff->minOutputVal = 0;
534  stuff->maxOutputVal = UINT_MAX;
535  } else if (!strcmp(productInfo->dataType, "float")) {
536  stuff->dataStorage = FloatDS;
537  stuff->minOutputVal = 0;
538  stuff->maxOutputVal = 0;
539  } else if (!strcmp(productInfo->dataType, "double")) {
540  stuff->dataStorage = DoubleDS;
541  stuff->minOutputVal = 0;
542  stuff->maxOutputVal = 0;
543  } else {
544  printf("-E- OutFile::addProductNonDisplay - invalid data type = %s\n",
545  productInfo->dataType);
546  exit(EXIT_FAILURE);
547  }
548 
549  // setup scaling
550  stuff->setScaleOffset(productInfo->scaleFactor, productInfo->addOffset,
551  Linear);
552  stuff->missingValue = productInfo->fillValue;
553 
554  productStuff.push_back(stuff);
555  return productStuff.size() - 1;
556 }
557 
558 void OutFile::setMapProjection(string projection) {
559  mapProjection = projection;
560 }
561 
562 void OutFile::setProj4Info(string projStr, double minX, double maxY) {
563  proj4String = projStr;
564 
565  for (int i = 0; i < 6; i++)
566  tiepoints[i] = 0;
567  tiepoints[3] = minX;
568  tiepoints[4] = maxY;
569 
570  pixscale[0] = resolution;
571  pixscale[1] = resolution;
572  pixscale[2] = 0;
573 }
574 
575 void OutFile::setNumFilledPixels(int32_t num) {
576  if (metaData) {
577  metaData->data_bins = num;
578  }
579 }
580 
582  if (metaData)
583  return metaData->data_bins;
584  else
585  return -1;
586 }
587 
589  if (metaData) {
590  float numPix = width * height;
591  return metaData->data_bins / numPix * 100.0;
592  } else
593  return -1;
594 }
595 
597  fileMinVal = DBL_MAX;
598  fileMaxVal = 0 - DBL_MAX;
599 }
600 
601 void OutFile::setResolution(string resolutionStr) {
602  resolution = string2resolution(resolutionStr);
603 }
604 
606  if (val) {
607  // if width is not set yet allocate some dummy memory to flag we want
608  // to do SST quality processing.
609  if (width <= 0) {
610  if (!qualityData)
611  qualityData = (uint8_t*) allocateMemory(2,
612  "OutFile::qualityData");
613  } else {
614  if (qualityData)
615  free(qualityData);
616  qualityData = (uint8_t*) allocateMemory(width,
617  "OutFile::qualityData");
618  }
619  } else {
620  if (qualityData) {
621  free(qualityData);
622  qualityData = NULL;
623  }
624  }
625 }
626 
628  if (qualityData)
629  return true;
630  else
631  return false;
632 }
633 
634 //------------------------------------------------------------------------------
635 // OutFile_pgm
636 //------------------------------------------------------------------------------
637 
639  OutFile() {
640  outfp = NULL;
641  fileData = NULL;
642 }
643 
645  if (outfp)
646  fclose(outfp);
647  if (fileData)
648  free(fileData);
649 }
650 
651 void OutFile_pgm::setSize(int32_t width, int32_t height) {
653  if (fileData)
654  free(fileData);
655  fileData = (uint8_t*) allocateMemory(width, "OutFile_pgm::fileData");
656 }
657 
659  outfp = fopen(fileName.c_str(), "w");
660  if (!outfp)
661  return false;
662 
663  /* Write pgm header */
664  fprintf(outfp, "P5\n");
665  fprintf(outfp, "%d %d\n", width, height);
666  fprintf(outfp, "255\n");
667 
668  return true;
669 }
670 
672  for (int i = 0; i < width; i++)
673  fileData[i] = (uint8_t) productStuff[0]->calcOutputVal(
674  productStuff[0]->lineData[i]);
675  fwrite(fileData, 1, width, outfp);
676  currentLine++;
677 }
678 
680  fclose(outfp);
681  outfp = NULL;
682  return true;
683 }
684 
685 //------------------------------------------------------------------------------
686 // OutFile_ppm
687 //------------------------------------------------------------------------------
688 
689 void OutFile_ppm::setSize(int32_t width, int32_t height) {
691  if (fileData)
692  free(fileData);
693  fileData = (uint8_t*) allocateMemory(width * 3, "OutFile_ppm::fileData");
694 }
695 
697  outfp = fopen(fileName.c_str(), "w");
698  if (!outfp)
699  return false;
700 
701  /*
702  * Write ppm file header
703  */
704  fprintf(outfp, "P6\n");
705  fprintf(outfp, "%d %d\n", width, height);
706  fprintf(outfp, "255\n");
707 
708  return true;
709 }
710 
712  int j = 0;
713  for (int i = 0; i < width; i++) {
714  uint8_t val = (uint8_t) round(
715  productStuff[0]->calcOutputVal(productStuff[0]->lineData[i]));
716  fileData[j++] = red[val];
717  fileData[j++] = green[val];
718  fileData[j++] = blue[val];
719  }
720  fwrite(fileData, 1, width * 3, outfp);
721  currentLine++;
722 }
723 
724 //------------------------------------------------------------------------------
725 // OutFile_ppm_rgb
726 //------------------------------------------------------------------------------
727 
729  OutFile() {
730  outfp = NULL;
731  fileData = NULL;
732 }
733 
735  if (outfp)
736  fclose(outfp);
737  if (fileData)
738  free(fileData);
739 }
740 
741 void OutFile_ppm_rgb::setSize(int32_t width, int32_t height) {
743  if (fileData)
744  free(fileData);
745  fileData = (uint8_t*) allocateMemory(width * 3,
746  "OutFile_ppm_rgb::fileData");
747 }
748 
750  outfp = fopen(fileName.c_str(), "w");
751  if (!outfp)
752  return false;
753 
754  /*
755  * Write ppm file header
756  */
757  fprintf(outfp, "P6\n");
758  fprintf(outfp, "%d %d\n", width, height);
759  fprintf(outfp, "255\n");
760  return true;
761 }
762 
764  fclose(outfp);
765  outfp = NULL;
766  return true;
767 }
768 
769 void OutFile_ppm_rgb::setPixel(int32_t x, double val, int32_t prod) {
770  fprintf(stderr,
771  "-E- OutFile_ppm_rgb::setPixel - only RGB is implemented with this file type.\n");
772  exit(EXIT_FAILURE);
773 }
774 
775 void OutFile_ppm_rgb::setPixelRGB(int32_t x, float red, float green,
776  float blue) {
777  if (x < 0 || x >= width) {
778  fprintf(stderr,
779  "-E- OutFile_ppm_rgb::setPixel - x=%d is not within range, width=%d.\n",
780  x, width);
781  exit(EXIT_FAILURE);
782  }
783 
784  uint8_t *ptr = fileData + x * 3;
785 
786  *ptr = round(productStuff[0]->calcOutputVal(red));
787  ptr++;
788  *ptr = round(productStuff[0]->calcOutputVal(green));
789  ptr++;
790  *ptr = round(productStuff[0]->calcOutputVal(blue));
791 
792  // do this to keep the file min/max reasonable
793  if (red > fileMaxVal)
794  fileMaxVal = red;
795  if (red < fileMinVal)
796  fileMinVal = red;
797 }
798 
800  if (x < 0 || x >= width) {
801  fprintf(stderr,
802  "-E- OutFile_ppm_rgb::landPixel - x=%d is not within range, width=%d.\n",
803  x, width);
804  exit(EXIT_FAILURE);
805  }
806  uint8_t *ptr = fileData + x * 3;
807  *ptr = landPix;
808  ptr++;
809  *ptr = landPix;
810  ptr++;
811  *ptr = landPix;
812 }
813 
815  if (x < 0 || x >= width) {
816  fprintf(stderr,
817  "-E- OutFile_ppm_rgb::fillPixel - x=%d is not within range, width=%d.\n",
818  x, width);
819  exit(EXIT_FAILURE);
820  }
821  uint8_t *ptr = fileData + x * 3;
822  *ptr = fillPix;
823  ptr++;
824  *ptr = fillPix;
825  ptr++;
826  *ptr = fillPix;
827 }
828 
830  if (x < 0 || x >= width) {
831  fprintf(stderr,
832  "-E- OutFile_ppm_rgb::missingPixel - x=%d is not within range, width=%d.\n",
833  x, width);
834  exit(EXIT_FAILURE);
835  }
836  uint8_t *ptr = fileData + x * 3;
837  *ptr = fillPix;
838  ptr++;
839  *ptr = fillPix;
840  ptr++;
841  *ptr = fillPix;
842 }
843 
845  fwrite(fileData, 1, width * 3, outfp);
846  currentLine++;
847 }
848 
849 //------------------------------------------------------------------------------
850 // OutFile_png
851 //------------------------------------------------------------------------------
852 
854  OutFile() {
855  isColor = color;
856  outfp = NULL;
857  fileData = NULL;
858  info_ptr = NULL;
859  png_ptr = NULL;
860  num_text = 10;
861 }
862 
864  if (outfp)
865  fclose(outfp);
866  if (fileData)
867  free(fileData);
868 }
869 
870 void OutFile_png::setSize(int32_t width, int32_t height) {
872  if (fileData)
873  free(fileData);
874  fileData = (uint8_t*) allocateMemory(width, "OutFile_png::fileData");
875 }
876 
878  outfp = fopen(fileName.c_str(), "w");
879  if (!outfp)
880  return false;
881 
882  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
883  if (!png_ptr) {
884  fprintf(stderr, "-E- Unable to create PNG write structure.\n");
885  exit(EXIT_FAILURE);
886  }
887 
888  info_ptr = png_create_info_struct(png_ptr);
889  if (!info_ptr) {
890  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
891  fprintf(stderr, "-E- Unable to create PNG info structure.\n");
892  exit(EXIT_FAILURE);
893  }
894  if (setjmp(png_jmpbuf(png_ptr))) {
895  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
896  fprintf(stderr, "-E- Unable to call PNG setjmp().\n");
897  exit(EXIT_FAILURE);
898  }
899  png_init_io(png_ptr, outfp);
900 
901  png_text text_ptr[num_text];
902  text_ptr[0].key = "projString";
903  text_ptr[0].text = const_cast<char*>(proj4String.c_str());
904  text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
905  text_ptr[1].key = "resolution";
906  text_ptr[1].text = const_cast<char*>(std::to_string(resolution).c_str());
907  text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
908  text_ptr[2].key = "north";
909  text_ptr[2].text = const_cast<char*>(std::to_string(metaData->north).c_str());
910  text_ptr[2].compression = PNG_TEXT_COMPRESSION_NONE;
911  text_ptr[3].key = "south";
912  text_ptr[3].text = const_cast<char*>(std::to_string(metaData->south).c_str());
913  text_ptr[3].compression = PNG_TEXT_COMPRESSION_NONE;
914  text_ptr[4].key = "east";
915  text_ptr[4].text = const_cast<char*>(std::to_string(metaData->east).c_str());
916  text_ptr[4].compression = PNG_TEXT_COMPRESSION_NONE;
917  text_ptr[5].key = "west";
918  text_ptr[5].text = const_cast<char*>(std::to_string(metaData->west).c_str());
919  text_ptr[5].compression = PNG_TEXT_COMPRESSION_NONE;
920  text_ptr[6].key = "minX";
921  text_ptr[6].text = const_cast<char*>(std::to_string(tiepoints[3]).c_str());
922  text_ptr[6].compression = PNG_TEXT_COMPRESSION_NONE;
923  text_ptr[7].key = "maxY";
924  text_ptr[7].text = const_cast<char*>(std::to_string(tiepoints[4]).c_str());
925  text_ptr[7].compression = PNG_TEXT_COMPRESSION_NONE;
926  text_ptr[8].key = "height";
927  text_ptr[8].text = const_cast<char*>(std::to_string(height).c_str());
928  text_ptr[8].compression = PNG_TEXT_COMPRESSION_NONE;
929  text_ptr[9].key = "width";
930  text_ptr[9].text = const_cast<char*>(std::to_string(width).c_str());
931  text_ptr[9].compression = PNG_TEXT_COMPRESSION_NONE;
932  png_set_text (png_ptr, info_ptr, text_ptr, num_text);
933 
934  if (isColor) {
935 
936  // color palette
937  png_set_IHDR(png_ptr, info_ptr, width, height, 8,
938  PNG_COLOR_TYPE_PALETTE, PNG_INTERLACE_NONE,
939  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
940 
941  uint8_t pal[256 * 3];
942  for (int i = 0; i < 256; i++) {
943  pal[i * 3] = red[i];
944  pal[i * 3 + 1] = green[i];
945  pal[i * 3 + 2] = blue[i];
946  }
947  png_set_PLTE(png_ptr, info_ptr, (png_const_colorp) pal, 256);
948 
949  if(transparent) {
950  uint8_t transPal[256];
951  for(int i = 0; i < 255; i++) {
952  transPal[i] = 255;
953  }
954  transPal[255] = 0;
955  png_set_tRNS(png_ptr, info_ptr, transPal, 256, NULL);
956  }
957  } else {
958 
959  // Grayscale
960  png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_GRAY,
961  PNG_INTERLACE_NONE,
962  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
963  }
964  png_write_info(png_ptr, info_ptr);
965 
966  return true;
967 }
968 
970  for (int i = 0; i < width; i++)
971  fileData[i] = (uint8_t) round(
972  productStuff[0]->calcOutputVal(productStuff[0]->lineData[i]));
973  png_write_row(png_ptr, (png_bytep) fileData);
974  currentLine++;
975 }
976 
978  png_write_end(png_ptr, info_ptr);
979  png_destroy_write_struct(&png_ptr, &info_ptr);
980 
981  fclose(outfp);
982  outfp = NULL;
983  return true;
984 }
985 
986 //------------------------------------------------------------------------------
987 // OutFile_png_rgb
988 //------------------------------------------------------------------------------
989 
991  OutFile() {
992  outfp = NULL;
993  fileData = NULL;
994  info_ptr = NULL;
995  png_ptr = NULL;
996  num_text = 10;
997 }
998 
1000  if (outfp)
1001  fclose(outfp);
1002  if (fileData)
1003  free(fileData);
1004 }
1005 
1006 void OutFile_png_rgb::setSize(int32_t width, int32_t height) {
1008  if (fileData)
1009  free(fileData);
1010  int samplesPerPixel = 3;
1011  if(transparent)
1012  samplesPerPixel = 4;
1013  fileData = (uint8_t*) allocateMemory(width * samplesPerPixel,
1014  "OutFile_png_rgb::fileData");
1015 }
1016 
1018  outfp = fopen(fileName.c_str(), "w");
1019  if (!outfp)
1020  return false;
1021 
1022  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
1023  if (!png_ptr) {
1024  fprintf(stderr, "-E- Unable to create PNG write structure.\n");
1025  exit(EXIT_FAILURE);
1026  }
1027 
1028  info_ptr = png_create_info_struct(png_ptr);
1029  if (!info_ptr) {
1030  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
1031  fprintf(stderr, "-E- Unable to create PNG info structure.\n");
1032  exit(EXIT_FAILURE);
1033  }
1034  if (setjmp(png_jmpbuf(png_ptr))) {
1035  png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
1036  fprintf(stderr, "-E- Unable to call PNG setjmp().\n");
1037  exit(EXIT_FAILURE);
1038  }
1039  png_init_io(png_ptr, outfp);
1040 
1041  png_text text_ptr[num_text];
1042  text_ptr[0].key = "projString";
1043  text_ptr[0].text = const_cast<char*>(proj4String.c_str());
1044  text_ptr[0].compression = PNG_TEXT_COMPRESSION_NONE;
1045  text_ptr[1].key = "resolution";
1046  text_ptr[1].text = const_cast<char*>(std::to_string(resolution).c_str());
1047  text_ptr[1].compression = PNG_TEXT_COMPRESSION_NONE;
1048  text_ptr[2].key = "north";
1049  text_ptr[2].text = const_cast<char*>(std::to_string(metaData->north).c_str());
1050  text_ptr[2].compression = PNG_TEXT_COMPRESSION_NONE;
1051  text_ptr[3].key = "south";
1052  text_ptr[3].text = const_cast<char*>(std::to_string(metaData->south).c_str());
1053  text_ptr[3].compression = PNG_TEXT_COMPRESSION_NONE;
1054  text_ptr[4].key = "east";
1055  text_ptr[4].text = const_cast<char*>(std::to_string(metaData->east).c_str());
1056  text_ptr[4].compression = PNG_TEXT_COMPRESSION_NONE;
1057  text_ptr[5].key = "west";
1058  text_ptr[5].text = const_cast<char*>(std::to_string(metaData->west).c_str());
1059  text_ptr[5].compression = PNG_TEXT_COMPRESSION_NONE;
1060  text_ptr[6].key = "minX";
1061  text_ptr[6].text = const_cast<char*>(std::to_string(tiepoints[3]).c_str());
1062  text_ptr[6].compression = PNG_TEXT_COMPRESSION_NONE;
1063  text_ptr[7].key = "maxY";
1064  text_ptr[7].text = const_cast<char*>(std::to_string(tiepoints[4]).c_str());
1065  text_ptr[7].compression = PNG_TEXT_COMPRESSION_NONE;
1066  text_ptr[8].key = "height";
1067  text_ptr[8].text = const_cast<char*>(std::to_string(height).c_str());
1068  text_ptr[8].compression = PNG_TEXT_COMPRESSION_NONE;
1069  text_ptr[9].key = "width";
1070  text_ptr[9].text = const_cast<char*>(std::to_string(width).c_str());
1071  text_ptr[9].compression = PNG_TEXT_COMPRESSION_NONE;
1072  png_set_text (png_ptr, info_ptr, text_ptr, num_text);
1073 
1074  if(transparent)
1075  png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA,
1076  PNG_INTERLACE_NONE,
1077  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1078  else
1079  png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGB,
1080  PNG_INTERLACE_NONE,
1081  PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
1082  png_write_info(png_ptr, info_ptr);
1083 
1084  return true;
1085 }
1086 
1088  if (setjmp(png_jmpbuf(png_ptr))) {
1089  fprintf(stderr,
1090  "-E- OutFile_png_rgb::close - Unable to call PNG setjmp().\n");
1091  exit(EXIT_FAILURE);
1092  }
1093  png_write_end(png_ptr, info_ptr);
1094  png_destroy_write_struct(&png_ptr, &info_ptr);
1095 
1096  fclose(outfp);
1097  outfp = NULL;
1098  return true;
1099 }
1100 
1101 void OutFile_png_rgb::setPixel(int32_t x, double val, int32_t prod) {
1102  fprintf(stderr,
1103  "-E- OutFile_png_rgb::setPixel - only RGB is implemented with this file type.\n");
1104  exit(EXIT_FAILURE);
1105 }
1106 
1107 void OutFile_png_rgb::setPixelRGB(int32_t x, float red, float green,
1108  float blue) {
1109  if (x < 0 || x >= width) {
1110  fprintf(stderr,
1111  "-E- OutFile_png_rgb::setPixel - x=%d is not within range, width=%d.\n",
1112  x, width);
1113  exit(EXIT_FAILURE);
1114  }
1115 
1116  int samplesPerPixel = 3;
1117  if(transparent)
1118  samplesPerPixel = 4;
1119  uint8_t *ptr = fileData + x * samplesPerPixel;
1120 
1121  *ptr = round(productStuff[0]->calcOutputVal(red));
1122  ptr++;
1123  *ptr = round(productStuff[0]->calcOutputVal(green));
1124  ptr++;
1125  *ptr = round(productStuff[0]->calcOutputVal(blue));
1126  if(transparent) {
1127  ptr++;
1128  if (red == badPixelValue || green == badPixelValue || blue == badPixelValue) {
1129  *ptr = 0; // transparent
1130  } else {
1131  *ptr = 255;
1132  }
1133  }
1134 
1135  // do this to keep the file min/max reasonable
1136  if (red > fileMaxVal)
1137  fileMaxVal = red;
1138  if (red < fileMinVal)
1139  fileMinVal = red;
1140 }
1141 
1143  if (x < 0 || x >= width) {
1144  fprintf(stderr,
1145  "-E- OutFile_png_rgb::landPixel - x=%d is not within range, width=%d.\n",
1146  x, width);
1147  exit(EXIT_FAILURE);
1148  }
1149  int samplesPerPixel = 3;
1150  if(transparent)
1151  samplesPerPixel = 4;
1152  uint8_t *ptr = fileData + x * samplesPerPixel;
1153  *ptr = landPix;
1154  ptr++;
1155  *ptr = landPix;
1156  ptr++;
1157  *ptr = landPix;
1158  if(transparent) {
1159  ptr++;
1160  *ptr = 255;
1161  }
1162 
1163 
1164 }
1165 
1167  if (x < 0 || x >= width) {
1168  fprintf(stderr,
1169  "-E- OutFile_png_rgb::fillPixel - x=%d is not within range, width=%d.\n",
1170  x, width);
1171  exit(EXIT_FAILURE);
1172  }
1173  int samplesPerPixel = 3;
1174  if(transparent)
1175  samplesPerPixel = 4;
1176  uint8_t *ptr = fileData + x * samplesPerPixel;
1177  *ptr = fillPix;
1178  ptr++;
1179  *ptr = fillPix;
1180  ptr++;
1181  *ptr = fillPix;
1182  if(transparent) {
1183  ptr++;
1184  *ptr = 0;
1185  }
1186 }
1187 
1189  if (x < 0 || x >= width) {
1190  fprintf(stderr,
1191  "-E- OutFile_png_rgb::missingPixel - x=%d is not within range, width=%d.\n",
1192  x, width);
1193  exit(EXIT_FAILURE);
1194  }
1195  int samplesPerPixel = 3;
1196  if(transparent)
1197  samplesPerPixel = 4;
1198  uint8_t *ptr = fileData + x * samplesPerPixel;
1199  *ptr = fillPix;
1200  ptr++;
1201  *ptr = fillPix;
1202  ptr++;
1203  *ptr = fillPix;
1204  if(transparent) {
1205  ptr++;
1206  *ptr = 0;
1207  }
1208 }
1209 
1211 
1212  if (setjmp(png_jmpbuf(png_ptr))) {
1213  fprintf(stderr,
1214  "-E- OutFile_png_rgb::writeLine - Unable to call PNG setjmp().\n");
1215  exit(EXIT_FAILURE);
1216  }
1217 
1218  png_write_row(png_ptr, (png_bytep) fileData);
1219  currentLine++;
1220 }
1221 
1222 //------------------------------------------------------------------------------
1223 // OutFile_tiff
1224 //------------------------------------------------------------------------------
1225 
1227  close();
1228 }
1229 
1231  currentLine = 0;
1232 
1233  // open TIFF file
1234  tiff = XTIFFOpen(fileName.c_str(), "w");
1235  if (tiff == NULL) {
1236  cerr << "-E- Could not open outgoing TIFF image" << endl;
1237  exit(EXIT_FAILURE);
1238  }
1239 
1240  // extend the TIFF tags to write pversion
1241  ttag_t TIFFTAG_GDALMetadata = 42112;
1242  static const TIFFFieldInfo xtiffFieldInfo[] = {
1243  { TIFFTAG_GDALMetadata, -1, -1, TIFF_ASCII, FIELD_CUSTOM, TRUE, FALSE, "GDALMetadata" }
1244  };
1245  TIFFMergeFieldInfo(tiff, xtiffFieldInfo, 1);
1246  std::string tagVal = "<GDALMetadata>\n <Item name=\"OBPG_version\">";
1247  tagVal += metaData->pversion;
1248  tagVal += "</Item>\n";
1249  tagVal += "</GDALMetadata>\n";
1250  TIFFSetField(tiff, TIFFTAG_GDALMetadata, tagVal.c_str());
1251 
1252  TIFFSetField(tiff, TIFFTAG_IMAGEWIDTH, width);
1253  TIFFSetField(tiff, TIFFTAG_IMAGELENGTH, height);
1254  TIFFSetField(tiff, TIFFTAG_PLANARCONFIG, PLANARCONFIG_CONTIG);
1255  TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_LZW);
1256  TIFFSetField(tiff, TIFFTAG_PREDICTOR, PREDICTOR_NONE);
1257  TIFFSetField(tiff, TIFFTAG_ROWSPERSTRIP, height);
1258 
1259  // open GeoTIFF interface
1260  bool hasGeotiffInfo = false;
1261  gtif = GTIFNew(tiff);
1262  if (gtif == NULL) {
1263  cerr << "-E- Could not create geoTIFF structure" << endl;
1264  exit(EXIT_FAILURE);
1265  }
1266 
1267  // define GeoTIFF keys for lat/lon projection
1268  if (mapProjection == "Equidistant Cylindrical" ||
1269  mapProjection == "PlateCarree") {
1270 
1271  double north, south, east, west;
1272  if (metaData) {
1273  north = metaData->north;
1274  south = metaData->south;
1275  east = metaData->east;
1276  west = metaData->west;
1277  } else {
1278  north = 90.0;
1279  south = -90.0;
1280  east = 180.0;
1281  west = -180.0;
1282  }
1283 
1284  // pixel width, height in degrees
1285  pixscale[0] = (east - west) / width;
1286  pixscale[1] = (north - south) / height;
1287 
1288  // top left corner pixel lat, lon
1289  for (int i = 0; i < 6; i++)
1290  tiepoints[i] = 0;
1291  tiepoints[3] = west;
1292  tiepoints[4] = north;
1293 
1294  GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
1295  GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT, 1, GCS_WGS_84);
1296  hasGeotiffInfo = true;
1297  }
1298  // otherwise, parse the proj4 string
1299  else
1300  hasGeotiffInfo = (GTIFSetFromProj4(gtif, proj4String.c_str()));
1301 
1302  if(!hasGeotiffInfo) {
1303  if(proj4String.find("EPSG:") != string::npos)
1304  hasGeotiffInfo = true;
1305  }
1306 
1307  if (hasGeotiffInfo) {
1308 
1309  // write GeoTIFF keys
1310  GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
1311  static const std::string & epsg_regex_str{"EPSG:(\\d+)\\b" };
1312  static const std::regex epsg_regex{epsg_regex_str};
1313  std::smatch matches;
1314  if (std::regex_search(proj4String, matches, epsg_regex)) {
1315  unsigned short epsg = std::stoi(matches[1]);
1316  GTIFKeySet(gtif,ProjectedCSTypeGeoKey, TYPE_SHORT, 1, epsg);
1317  }
1318  GTIFWriteKeys(gtif);
1319 
1320  // write GeoTIFF tags in map units
1321  TIFFSetField(tiff, GTIFF_PIXELSCALE, 3, pixscale);
1322  TIFFSetField(tiff, GTIFF_TIEPOINTS, 6, tiepoints);
1323  }
1324 
1325  // define colormap
1326  setTiffColor();
1327  return true;
1328 }
1329 
1331  if (gtif) {
1332  GTIFFree(gtif);
1333  XTIFFClose(tiff);
1334  tiff = NULL;
1335  gtif = NULL;
1336  }
1337  return true;
1338 }
1339 
1340 //----- OutFile_tiff_color -----
1341 
1343  if (fileData)
1344  free(fileData);
1345 }
1346 
1347 void OutFile_tiff_color::setSize(int32_t width, int32_t height) {
1349  if (fileData)
1350  free(fileData);
1351 
1352  // if transparent we need to use RGBA mode instead of indexed color map
1353  if (transparent) {
1354  fileData = (uint8_t*) allocateMemory(width * 4,
1355  "OutFile_tiff_color::fileData");
1356  } else {
1357  fileData = (uint8_t*) allocateMemory(width, "OutFile_tiff_color::fileData");
1358  }
1359 }
1360 
1362  if(transparent) {
1363  for (int i = 0; i < width; i++) {
1364 
1365  uint8_t *ptr = fileData + i * 4;
1366 
1367  uint8_t alpha = 255; // opaque
1368 
1369  uint8_t scaledVal = (uint8_t) round(
1370  productStuff[0]->calcOutputVal(productStuff[0]->lineData[i]));
1371  if (productStuff[0]->lineData[i] == badPixelValue) {
1372  alpha = 0; // transparent
1373  }
1374  *ptr = red[scaledVal];
1375  ptr++;
1376  *ptr = green[scaledVal];
1377  ptr++;
1378  *ptr = blue[scaledVal];
1379  ptr++;
1380  *ptr = alpha;
1381  }
1382  } else {
1383  for (int i = 0; i < width; i++)
1384  fileData[i] = (uint8_t) round(
1385  productStuff[0]->calcOutputVal(productStuff[0]->lineData[i]));
1386  }
1387 
1388  if (TIFFWriteScanline(tiff, (void*) fileData, currentLine) == 0) {
1389  cerr << "-E- Could not write TIFF image line " << currentLine << endl;
1390  exit(EXIT_FAILURE);
1391  }
1392 
1393  currentLine++;
1394 }
1395 
1397  if(transparent) {
1398  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
1399  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
1400  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4);
1401  uint16_t out[1];
1402  out[0] = EXTRASAMPLE_ASSOCALPHA;
1403  TIFFSetField(tiff, TIFFTAG_EXTRASAMPLES, 1, &out);
1404  TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
1405  } else {
1406  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_PALETTE);
1407  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
1408  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
1409 
1410  int ncolors = 256; // convert bytes to short
1411  uint16_t* rr = (uint16_t*) malloc(ncolors * sizeof(uint16_t));
1412  uint16_t* gg = (uint16_t*) malloc(ncolors * sizeof(uint16_t));
1413  uint16_t* bb = (uint16_t*) malloc(ncolors * sizeof(uint16_t));
1414  if (rr == NULL || gg == NULL || bb == NULL) {
1415  cerr << "-E- Could not allocate memory for TIFF color map" << endl;
1416  exit(EXIT_FAILURE);
1417  }
1418  for (int i = 0; i < ncolors; i++) {
1419  rr[i] = red[i] << 8;
1420  gg[i] = green[i] << 8;
1421  bb[i] = blue[i] << 8;
1422  }
1423  TIFFSetField(tiff, TIFFTAG_COLORMAP, rr, gg, bb);
1424  free(rr);
1425  free(gg);
1426  free(bb);
1427  }
1428 }
1429 
1430 //----- OutFile_tiff_gray -----
1431 
1433  if (fileData)
1434  free(fileData);
1435 }
1436 
1437 void OutFile_tiff_gray::setSize(int32_t width, int32_t height) {
1439  if (fileData)
1440  free(fileData);
1441  fileData = (float*) allocateMemory(width * sizeof(float),
1442  "OutFile_tiff_gray::fileData");
1443 }
1444 
1446  for (int i = 0; i < width; i++)
1447  fileData[i] = productStuff[0]->lineData[i];
1448 
1449  if (TIFFWriteScanline(tiff, (void*) fileData, currentLine) == 0) {
1450  cerr << "-E- Could not write TIFF image line " << currentLine << endl;
1451  exit(EXIT_FAILURE);
1452  }
1453  currentLine++;
1454 }
1455 
1457  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_MINISBLACK);
1458  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 32);
1459  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 1);
1460  TIFFSetField(tiff, TIFFTAG_SAMPLEFORMAT, SAMPLEFORMAT_IEEEFP);
1461 }
1462 
1463 //----- OutFile_tiff_rgb -----
1464 
1466  if (fileData)
1467  free(fileData);
1468 }
1469 
1470 void OutFile_tiff_rgb::setSize(int32_t width, int32_t height) {
1472  if (fileData)
1473  free(fileData);
1474  if (transparent) {
1475  fileData = (uint8_t*) allocateMemory(width * 4,
1476  "OutFile_tiff_rgb::fileData");
1477  } else {
1478  fileData = (uint8_t*) allocateMemory(width * 3,
1479  "OutFile_tiff_rgb::fileData");
1480  }
1481 }
1482 
1484  if (TIFFWriteScanline(tiff, (void*) fileData, currentLine) == 0) {
1485  cerr << "-E- Could not write TIFF image line " << currentLine << endl;
1486  exit(EXIT_FAILURE);
1487  }
1488  currentLine++;
1489 }
1490 
1492  TIFFSetField(tiff, TIFFTAG_PHOTOMETRIC, PHOTOMETRIC_RGB);
1493  TIFFSetField(tiff, TIFFTAG_BITSPERSAMPLE, 8);
1494  if (transparent) {
1495  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 4);
1496  } else {
1497  TIFFSetField(tiff, TIFFTAG_SAMPLESPERPIXEL, 3);
1498  }
1499  TIFFSetField(tiff, TIFFTAG_COMPRESSION, COMPRESSION_DEFLATE);
1500 }
1501 
1502 void OutFile_tiff_rgb::setPixel(int32_t x, double val, int32_t prod) {
1503  if (x < 0 || x >= width) {
1504  fprintf(stderr,
1505  "-E- OutFile_tiff_rgb::setPixel - x=%d is not within range, width=%d.\n",
1506  x, width);
1507  exit(EXIT_FAILURE);
1508  }
1509 
1510  uint8_t samplesPerPixel = 3;
1511  if (transparent){
1512  samplesPerPixel = 4;
1513  }
1514  uint8_t *ptr = fileData + x * samplesPerPixel;
1515 
1516  uint8_t alpha = 255; // opaque
1517 
1518  uint8_t scaledVal = round(productStuff[0]->calcOutputVal(val));
1519  if (val == badPixelValue) {
1520  alpha = 0; // transparent
1521  }
1522  *ptr = red[scaledVal];
1523  ptr++;
1524  *ptr = green[scaledVal];
1525  ptr++;
1526  *ptr = blue[scaledVal];
1527  if (transparent) {
1528  ptr++;
1529  *ptr = alpha;
1530  }
1531 }
1532 
1533 void OutFile_tiff_rgb::setPixelRGB(int32_t x, float red, float green,
1534  float blue) {
1535  if (x < 0 || x >= width) {
1536  fprintf(stderr,
1537  "-E- OutFile_tiff_rgb::setPixel - x=%d is not within range, width=%d.\n",
1538  x, width);
1539  exit(EXIT_FAILURE);
1540  }
1541 
1542  uint8_t alpha = 255; // opaque
1543 
1544  uint8_t samplesPerPixel = 3;
1545  if (transparent){
1546  samplesPerPixel = 4;
1547  }
1548  uint8_t *ptr = fileData + x * samplesPerPixel;
1549 
1550  *ptr = round(productStuff[0]->calcOutputVal(red));
1551  ptr++;
1552  *ptr = round(productStuff[0]->calcOutputVal(green));
1553  ptr++;
1554  *ptr = round(productStuff[0]->calcOutputVal(blue));
1555  if (transparent) {
1556  if (red == badPixelValue || green == badPixelValue || blue == badPixelValue) {
1557  alpha = 0; // transparent
1558  }
1559  ptr++;
1560  *ptr = alpha;
1561  }
1562 
1563  if (red > fileMaxVal) // keep file min/max reasonable
1564  fileMaxVal = red;
1565  if (red < fileMinVal)
1566  fileMinVal = red;
1567 }
1568 
1570  if (x < 0 || x >= width) {
1571  fprintf(stderr,
1572  "-E- OutFile_tiff_rgb::landPixel - x=%d is not within range, width=%d.\n",
1573  x, width);
1574  exit(EXIT_FAILURE);
1575  }
1576 
1577  uint8_t samplesPerPixel = 3;
1578  if (transparent){
1579  samplesPerPixel = 4;
1580  }
1581  uint8_t *ptr = fileData + x * samplesPerPixel;
1582  *ptr = landPix;
1583  ptr++;
1584  *ptr = landPix;
1585  ptr++;
1586  *ptr = landPix;
1587  if (transparent) {
1588  ptr++;
1589  *ptr = 255;
1590  }
1591 
1592 }
1593 
1595  if (x < 0 || x >= width) {
1596  fprintf(stderr,
1597  "-E- OutFile_tiff_rgb::fillPixel - x=%d is not within range, width=%d.\n",
1598  x, width);
1599  exit(EXIT_FAILURE);
1600  }
1601 
1602  uint8_t samplesPerPixel = 3;
1603  if (transparent){
1604  samplesPerPixel = 4;
1605  }
1606  uint8_t *ptr = fileData + x * samplesPerPixel;
1607  *ptr = fillPix;
1608  ptr++;
1609  *ptr = fillPix;
1610  ptr++;
1611  *ptr = fillPix;
1612  if (transparent) {
1613  ptr++;
1614  *ptr = 0;
1615  }
1616 }
1617 
1619  if (x < 0 || x >= width) {
1620  fprintf(stderr,
1621  "-E- OutFile_tiff_rgb::missingPixel - x=%d is not within range, width=%d.\n",
1622  x, width);
1623  exit(EXIT_FAILURE);
1624  }
1625 
1626  uint8_t samplesPerPixel = 3;
1627  if (transparent){
1628  samplesPerPixel = 4;
1629  }
1630  uint8_t *ptr = fileData + x * samplesPerPixel;
1631  *ptr = fillPix;
1632  ptr++;
1633  *ptr = fillPix;
1634  ptr++;
1635  *ptr = fillPix;
1636  if (transparent) {
1637  ptr++;
1638  *ptr = 0;
1639  }
1640 }
1641 
1642 //------------------------------------------------------------------------------
1643 // OutFile_hdf4
1644 //------------------------------------------------------------------------------
1645 
1647  OutFile() {
1648  fileData = NULL;
1649  sdfid = -1;
1650  sdsid = -1;
1651  quality_sdsid = -1;
1652  hdfDataType = DFNT_FLOAT32;
1653 }
1654 
1656  if (fileData)
1657  free(fileData);
1658 }
1659 
1660 void OutFile_hdf4::setSize(int32_t width, int32_t height) {
1662  if (fileData)
1663  free(fileData);
1664  fileData = NULL;
1665 }
1666 
1668  const char* tmpStr;
1669  float tmpFloat;
1670  int32_t tmpInt32;
1671 
1672  currentLine = 0;
1673 
1674  sdfid = SDstart(fileName.c_str(), DFACC_CREATE);
1675 
1676  if (sdfid < 0) {
1677  printf("-E- Could not create HDF4 file %s\n", fileName.c_str());
1678  exit(EXIT_FAILURE);
1679  }
1680 
1682 
1683  string prodName;
1684  size_t pos = fileName.find_last_of('/');
1685  if (pos == string::npos)
1686  prodName = fileName;
1687  else
1688  prodName = fileName.substr(pos + 1);
1689  DPTB(SDsetattr(sdfid, "Product Name", DFNT_CHAR, prodName.size() + 1, (VOIDP) prodName.c_str()));
1690  DPTB(SDsetattr(sdfid, "Sensor Name", DFNT_CHAR, strlen(metaData->sensor_name) + 1, (VOIDP) metaData->sensor_name));
1691  DPTB(SDsetattr(sdfid, "Sensor", DFNT_CHAR, strlen(metaData->sensor) + 1, (VOIDP) metaData->sensor));
1692  DPTB(SDsetattr(sdfid, "Title", DFNT_CHAR, strlen(metaData->title) + 1, (VOIDP) metaData->title));
1693  DPTB(SDsetattr(sdfid, "Data Center", DFNT_CHAR, strlen(metaData->data_center) + 1, (VOIDP) metaData->data_center));
1694  DPTB(SDsetattr(sdfid, "Station Name", DFNT_CHAR, strlen(metaData->station) + 1, (VOIDP) metaData->station));
1695  DPTB(SDsetattr(sdfid, "Station Latitude", DFNT_FLOAT32, 1, (VOIDP) & metaData->station_lat));
1696  DPTB(SDsetattr(sdfid, "Station Longitude", DFNT_FLOAT32, 1, (VOIDP) & metaData->station_lon));
1697  DPTB(SDsetattr(sdfid, "Mission", DFNT_CHAR, strlen(metaData->mission) + 1, (VOIDP) metaData->mission));
1698  DPTB(SDsetattr(sdfid, "Mission Characteristics", DFNT_CHAR, strlen(metaData->mission_char) + 1, (VOIDP) metaData->mission_char));
1699  DPTB(SDsetattr(sdfid, "Sensor Characteristics", DFNT_CHAR, strlen(metaData->sensor_char) + 1, (VOIDP) metaData->sensor_char));
1700  DPTB(SDsetattr(sdfid, "Product Type", DFNT_CHAR, strlen(metaData->prod_type) + 1, (VOIDP) metaData->prod_type));
1701  DPTB(SDsetattr(sdfid, "Processing Version", DFNT_CHAR, strlen(metaData->pversion) + 1, (VOIDP) metaData->pversion));
1702  DPTB(SDsetattr(sdfid, "Software Name", DFNT_CHAR, strlen(metaData->soft_name) + 1, (VOIDP) metaData->soft_name));
1703  DPTB(SDsetattr(sdfid, "Software Version", DFNT_CHAR, strlen(metaData->soft_ver) + 1, (VOIDP) metaData->soft_ver));
1704  DPTB(SDsetattr(sdfid, "Processing Time", DFNT_CHAR, strlen(metaData->ptime) + 1, (VOIDP) metaData->ptime));
1705  DPTB(SDsetattr(sdfid, "Input Files", DFNT_CHAR, strlen(metaData->infiles) + 1, (VOIDP) metaData->infiles));
1706  DPTB(SDsetattr(sdfid, "Processing Control", DFNT_CHAR, strlen(metaData->proc_con) + 1, (VOIDP) metaData->proc_con));
1707  DPTB(SDsetattr(sdfid, "Input Parameters", DFNT_CHAR, strlen(metaData->input_parms) + 1, (VOIDP) metaData->input_parms));
1708  DPTB(SDsetattr(sdfid, "L2 Flag Names", DFNT_CHAR, strlen(metaData->flag_names) + 1, (VOIDP) metaData->flag_names));
1709 
1710  short syear, sday, eyear, eday;
1711  double ssec, esec;
1712  int32_t smsec, emsec;
1713  unix2yds(metaData->startTime, &syear, &sday, &ssec);
1714  smsec = (int32_t) (ssec * 1000.0);
1715  unix2yds(metaData->endTime, &eyear, &eday, &esec);
1716  emsec = (int32_t) (esec * 1000.0);
1717  DPTB(SDsetattr(sdfid, "Period Start Year", DFNT_INT16, 1, (VOIDP) & syear));
1718  DPTB(SDsetattr(sdfid, "Period Start Day", DFNT_INT16, 1, (VOIDP) & sday));
1719  DPTB(SDsetattr(sdfid, "Period End Year", DFNT_INT16, 1, (VOIDP) & eyear));
1720  DPTB(SDsetattr(sdfid, "Period End Day", DFNT_INT16, 1, (VOIDP) & eday));
1721  tmpStr = ydhmsf(metaData->startTime, 'G');
1722  DPTB(SDsetattr(sdfid, "Start Time", DFNT_CHAR, strlen(tmpStr) + 1, (VOIDP) tmpStr));
1723  tmpStr = ydhmsf(metaData->endTime, 'G');
1724  DPTB(SDsetattr(sdfid, "End Time", DFNT_CHAR, strlen(tmpStr) + 1, (VOIDP) tmpStr));
1725  DPTB(SDsetattr(sdfid, "Start Year", DFNT_INT16, 1, (VOIDP) & syear));
1726  DPTB(SDsetattr(sdfid, "Start Day", DFNT_INT16, 1, (VOIDP) & sday));
1727  DPTB(SDsetattr(sdfid, "Start Millisec", DFNT_INT32, 1, (VOIDP) & smsec));
1728  DPTB(SDsetattr(sdfid, "End Year", DFNT_INT16, 1, (VOIDP) & eyear));
1729  DPTB(SDsetattr(sdfid, "End Day", DFNT_INT16, 1, (VOIDP) & eday));
1730  DPTB(SDsetattr(sdfid, "End Millisec", DFNT_INT32, 1, (VOIDP) & emsec));
1731 
1732  DPTB(SDsetattr(sdfid, "Start Orbit", DFNT_INT32, 1, (VOIDP) & metaData->start_orb));
1733  DPTB(SDsetattr(sdfid, "End Orbit", DFNT_INT32, 1, (VOIDP) & metaData->end_orb));
1734  DPTB(SDsetattr(sdfid, "Orbit", DFNT_INT32, 1, (VOIDP) & metaData->orbit));
1735  DPTB(SDsetattr(sdfid, "Map Projection", DFNT_CHAR, mapProjection.size() + 1, mapProjection.c_str()));
1736  DPTB(SDsetattr(sdfid, "Latitude Units", DFNT_CHAR, 14, (VOIDP) "degrees North"));
1737  DPTB(SDsetattr(sdfid, "Longitude Units", DFNT_CHAR, 13, (VOIDP) "degrees East"));
1738  DPTB(SDsetattr(sdfid, "Northernmost Latitude", DFNT_FLOAT32, 1, (VOIDP) & metaData->north));
1739  DPTB(SDsetattr(sdfid, "Southernmost Latitude", DFNT_FLOAT32, 1, (VOIDP) & metaData->south));
1740  DPTB(SDsetattr(sdfid, "Westernmost Longitude", DFNT_FLOAT32, 1, (VOIDP) & metaData->west));
1741  DPTB(SDsetattr(sdfid, "Easternmost Longitude", DFNT_FLOAT32, 1, (VOIDP) & metaData->east));
1742 
1743  float latStep = (metaData->north - metaData->south) / (float) getHeight();
1744  DPTB(SDsetattr(sdfid, "Latitude Step", DFNT_FLOAT32, 1, (VOIDP) & latStep));
1745  float lonStep;
1746  if (metaData->east < metaData->west)
1747  lonStep = (360 + metaData->east - metaData->west) / (float) getWidth();
1748  else
1749  lonStep = (metaData->east - metaData->west) / (float) getWidth();
1750  DPTB(SDsetattr(sdfid, "Longitude Step", DFNT_FLOAT32, 1, (VOIDP) & lonStep));
1751 
1752  tmpFloat = metaData->south + latStep / 2.0;
1753  DPTB(SDsetattr(sdfid, "SW Point Latitude", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1754  tmpFloat = metaData->west + lonStep / 2.0;
1755  DPTB(SDsetattr(sdfid, "SW Point Longitude", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1756 
1757  tmpInt32 = metaData->data_bins;
1758  DPTB(SDsetattr(sdfid, "Data Bins", DFNT_INT32, 1, (VOIDP) &tmpInt32));
1759 
1760  tmpInt32 = getHeight();
1761  DPTB(SDsetattr(sdfid, "Number of Lines", DFNT_INT32, 1, (VOIDP) & tmpInt32));
1762  tmpInt32 = getWidth();
1763  DPTB(SDsetattr(sdfid, "Number of Columns", DFNT_INT32, 1, (VOIDP) & tmpInt32));
1764  DPTB(SDsetattr(sdfid, "Parameter", DFNT_CHAR, strlen(productStuff[0]->productInfo->description) + 1, (VOIDP) productStuff[0]->productInfo->description));
1765  DPTB(SDsetattr(sdfid, "Measure", DFNT_CHAR, 5, (VOIDP) "Mean"));
1766  DPTB(SDsetattr(sdfid, "Units", DFNT_CHAR, strlen(productStuff[0]->productInfo->units) + 1, (VOIDP) productStuff[0]->productInfo->units));
1767 
1768  // we only use linear scaling for data storage
1769  tmpStr = "linear";
1770  DPTB(SDsetattr(sdfid, "Scaling", DFNT_CHAR, strlen(tmpStr) + 1, (VOIDP) tmpStr));
1771  tmpStr = "(Slope*l3m_data) + Intercept = Parameter value";
1772  DPTB(SDsetattr(sdfid, "Scaling Equation", DFNT_CHAR, strlen(tmpStr) + 1, (VOIDP) tmpStr));
1773 
1774  float tmpScale;
1775  float tmpOffset;
1776  const char* imageScalingApplied;
1777 
1778  switch (productStuff[0]->dataStorage) {
1779  case FloatDS:
1780  case DoubleDS:
1781  tmpScale = 1.0;
1782  tmpOffset = 0.0;
1783  imageScalingApplied = "No";
1784  break;
1785  default:
1786  tmpScale = productStuff[0]->scale;
1787  tmpOffset = productStuff[0]->offset;
1788  if (tmpScale == 1.0 && tmpOffset == 0.0)
1789  imageScalingApplied = "No";
1790  else
1791  imageScalingApplied = "Yes";
1792  }
1793 
1794  DPTB(SDsetattr(sdfid, "Slope", DFNT_FLOAT32, 1, (VOIDP) & tmpScale));
1795  DPTB(SDsetattr(sdfid, "Intercept", DFNT_FLOAT32, 1, (VOIDP) & tmpOffset));
1796 
1797  tmpFloat = productStuff[0]->productInfo->validMin;
1798  DPTB(SDsetattr(sdfid, "Data Minimum", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1799  tmpFloat = productStuff[0]->productInfo->validMax;
1800  DPTB(SDsetattr(sdfid, "Data Maximum", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1801  tmpFloat = productStuff[0]->productInfo->displayMin;
1802  DPTB(SDsetattr(sdfid, "Suggested Image Scaling Minimum", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1803  tmpFloat = productStuff[0]->productInfo->displayMax;
1804  DPTB(SDsetattr(sdfid, "Suggested Image Scaling Maximum", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1805 
1806  tmpStr = strdup(productStuff[0]->productInfo->displayScale);
1807  upcase((char*) tmpStr);
1808  DPTB(SDsetattr(sdfid, "Suggested Image Scaling Type", DFNT_CHAR, strlen(tmpStr) + 1, (VOIDP) tmpStr));
1809  free((void*) tmpStr);
1810 
1811  DPTB(SDsetattr(sdfid, "Suggested Image Scaling Applied", DFNT_CHAR, strlen(imageScalingApplied) + 1, (VOIDP) imageScalingApplied));
1812  DPTB(SDsetattr(sdfid, "_lastModified", DFNT_CHAR, strlen(metaData->ptime) + 1, (VOIDP) metaData->ptime));
1813 
1814  // delete file data
1815  if (fileData) {
1816  free(fileData);
1817  fileData = NULL;
1818  }
1819 
1820  int32_t dims[2];
1821  dims[0] = height;
1822  dims[1] = width;
1823 
1824  if (!strcmp(productStuff[0]->productInfo->dataType, "byte")) {
1825  hdfDataType = DFNT_INT8;
1826  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1827  int8_t tmp = productStuff[0]->missingValue;
1828  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1829  fileData = allocateMemory(width * sizeof(int8_t),
1830  "OutFile_hdf4::open fileData");
1831  } else if (!strcmp(productStuff[0]->productInfo->dataType, "ubyte")) {
1832  hdfDataType = DFNT_UINT8;
1833  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1834  uint8_t tmp = productStuff[0]->missingValue;
1835  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1836  fileData = allocateMemory(width * sizeof(uint8_t),
1837  "OutFile_hdf4::open fileData");
1838  } else if (!strcmp(productStuff[0]->productInfo->dataType, "short")) {
1839  hdfDataType = DFNT_INT16;
1840  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1841  int16_t tmp = productStuff[0]->missingValue;
1842  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1843  fileData = allocateMemory(width * sizeof(int16_t),
1844  "OutFile_hdf4::open fileData");
1845  } else if (!strcmp(productStuff[0]->productInfo->dataType, "ushort")) {
1846  hdfDataType = DFNT_UINT16;
1847  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1848  uint16_t tmp = productStuff[0]->missingValue;
1849  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1850  fileData = allocateMemory(width * sizeof(uint16_t),
1851  "OutFile_hdf4::open fileData");
1852  } else if (!strcmp(productStuff[0]->productInfo->dataType, "int")) {
1853  hdfDataType = DFNT_INT32;
1854  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1855  int32_t tmp = productStuff[0]->missingValue;
1856  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1857  fileData = allocateMemory(width * sizeof(int32_t),
1858  "OutFile_hdf4::open fileData");
1859  } else if (!strcmp(productStuff[0]->productInfo->dataType, "uint")) {
1860  hdfDataType = DFNT_UINT32;
1861  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1862  uint32_t tmp = productStuff[0]->missingValue;
1863  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1864  fileData = allocateMemory(width * sizeof(uint32_t),
1865  "OutFile_hdf4::open fileData");
1866  } else if (!strcmp(productStuff[0]->productInfo->dataType, "float")) {
1867  hdfDataType = DFNT_FLOAT32;
1868  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1869  float tmp = productStuff[0]->missingValue;
1870  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1871  fileData = allocateMemory(width * sizeof(float),
1872  "OutFile_hdf4::open fileData");
1873  } else if (!strcmp(productStuff[0]->productInfo->dataType, "double")) {
1874  hdfDataType = DFNT_FLOAT64;
1875  sdsid = SDcreate(sdfid, "l3m_data", hdfDataType, 2, dims);
1876  double tmp = productStuff[0]->missingValue;
1877  DPTB(SDsetattr(sdsid, "Fill", hdfDataType, 1, (VOIDP ) &tmp));
1878  fileData = allocateMemory(width * sizeof(double),
1879  "OutFile_hdf4::open fileData");
1880  } else {
1881  printf("-E- Data type %s, not supported\n",
1882  productStuff[0]->productInfo->dataType);
1883  exit(EXIT_FAILURE);
1884  }
1885 
1886  tmpStr = "linear";
1887  DPTB(SDsetattr(sdsid, "Scaling", DFNT_CHAR, strlen(tmpStr) + 1, (VOIDP) tmpStr));
1888  tmpStr = "(Slope*l3m_data) + Intercept = Parameter value";
1889  DPTB(SDsetattr(sdsid, "Scaling Equation", DFNT_CHAR, strlen(tmpStr) + 1, (VOIDP) tmpStr));
1890  DPTB(SDsetattr(sdsid, "Slope", DFNT_FLOAT32, 1, (VOIDP) & tmpScale));
1891  DPTB(SDsetattr(sdsid, "Intercept", DFNT_FLOAT32, 1, (VOIDP) & tmpOffset));
1892 
1893  // create the SST quality data set
1894  if (qualityData) {
1895  quality_sdsid = SDcreate(sdfid, "l3m_qual", DFNT_UINT8, 2, dims);
1896  int32_t validRange[2];
1897  validRange[0] = 0;
1898  validRange[1] = 2;
1899  DPTB(SDsetattr(quality_sdsid, "valid_range", DFNT_INT32, 2, (VOIDP) validRange));
1900  }
1901 
1902  return true;
1903 }
1904 
1906 
1907  productStuff[0]->calcOutputLineVals(fileData);
1908 
1909  int32_t start[2];
1910  int32_t count[2];
1911 
1912  start[0] = currentLine;
1913  start[1] = 0;
1914  count[0] = 1;
1915  count[1] = width;
1916 
1917  if ((SDwritedata(sdsid, start, NULL, count, (VOIDP) fileData)) < 0) {
1918  printf("\n-E- OutFile_hdf4::writeLine(): SDwritedata unsuccessful\n");
1919  exit(EXIT_FAILURE);
1920  }
1921 
1922  if (qualityData) {
1923  if ((SDwritedata(quality_sdsid, start, NULL, count, (VOIDP) qualityData))
1924  < 0) {
1925  printf("\n-E- OutFile_hdf4::writeLine(): SDwritedata unsuccessful\n");
1926  exit(EXIT_FAILURE);
1927  }
1928  }
1929 
1930  currentLine++;
1931 }
1932 
1934 
1935  if (fileData) {
1936  free(fileData);
1937  fileData = NULL;
1938  }
1939 
1940  if (metaData) {
1941  int32_t tmpInt = metaData->data_bins;
1942  DPTB(SDsetattr(sdfid, "Data Bins", DFNT_INT32, 1, (VOIDP) &tmpInt));
1943  }
1944  float tmpFloat = getFileMinVal();
1945  DPTB(SDsetattr(sdfid, "Data Minimum", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1946  tmpFloat = getFileMaxVal();
1947  DPTB(SDsetattr(sdfid, "Data Maximum", DFNT_FLOAT32, 1, (VOIDP) & tmpFloat));
1948 
1949  if (qualityData) {
1950  SDendaccess(quality_sdsid);
1951  quality_sdsid = -1;
1952  }
1953  SDendaccess(sdsid);
1954  sdsid = -1;
1955  SDend(sdfid);
1956  sdfid = -1;
1957 
1958  /*-----------------------------------------------------------------------*/
1959  /* write map_palette */
1960 
1961  // make sure a palette has been loaded
1962  if (red && green && blue) {
1963  uint8_t data[768];
1964  int j = 0;
1965  for (int i = 0; i < 256; i++) {
1966  data[j++] = red[i];
1967  data[j++] = green[i];
1968  data[j++] = blue[i];
1969  }
1970 
1971  if ((DFPaddpal(fileName.c_str(), (VOIDP) data)) < 0) {
1972  printf("-E- OutFile_hdf4::close - Error writing map_palette.\n");
1973  return false;
1974  }
1975 
1976  uint16_t pal_ref;
1977  if ((pal_ref = DFPlastref()) > 0) {
1978  if ((DFANputlabel(fileName.c_str(), DFTAG_IP8, pal_ref,
1979  (char*) "palette")) < 0) {
1980  printf("-E- OutFile_hdf4::close - Error writing palette label\n");
1981  return false;
1982  }
1983  }
1984  }
1985  return true;
1986 }
1987 
1988 int32_t OutFile_hdf4::addProduct(productInfo_t* productInfo) {
1989  return addProductNonDisplay(productInfo);
1990 }
1991 
1992 //------------------------------------------------------------------------------
1993 // OutFile_netcdf4
1994 //------------------------------------------------------------------------------
1995 
1996 using namespace netCDF;
1997 
1999  OutFile() {
2000  ncFile = NULL;
2001  fileData = NULL;
2002 }
2003 
2005  if (fileData) {
2006  free(fileData);
2007  fileData = NULL;
2008  }
2009 }
2010 
2011 void OutFile_netcdf4::setSize(int32_t width, int32_t height) {
2013  if (fileData) {
2014  free(fileData);
2015  fileData = NULL;
2016  }
2017 }
2018 
2020  const char* tmpStr;
2021  currentLine = 0;
2022 
2023  try {
2024 
2025  // open file
2026  ncFile = new NcFile(fileName.c_str(), NcFile::replace);
2027 
2028  // write global metadata
2029  string prodName;
2030  size_t pos = fileName.find_last_of('/');
2031  if (pos == string::npos)
2032  prodName = fileName;
2033  else
2034  prodName = fileName.substr(pos + 1);
2035  ncFile->putAtt("product_name", prodName.c_str());
2036 
2037  ncFile->putAtt("instrument", metaData->sensor);
2038  std::string source = "satellite observations from ";
2039  source += metaData->sensor;
2040  ncFile->putAtt("title", metaData->title);
2041  ncFile->putAtt("project", PROJECT);
2042 
2043  if (strcmp(metaData->mission, "") != 0) {
2044  ncFile->putAtt("platform", metaData->mission);
2045  source += "-";
2046  source += metaData->mission;
2047  }
2048  ncFile->putAtt("source", source);
2049 
2050  ncFile->putAtt("temporal_range", metaData->prod_type);
2051  ncFile->putAtt("processing_version", metaData->pversion);
2052 
2054  ncFile->putAtt("date_created", metaData->ptime);
2055  ncFile->putAtt("history", metaData->proc_con);
2056 
2057 
2058  ncFile->putAtt("l2_flag_names", metaData->flag_names);
2059 
2060  ncFile->putAtt("time_coverage_start",
2062  ncFile->putAtt("time_coverage_end",
2063  unix2isodate(metaData->endTime, 'G'));
2064  ncFile->putAtt("start_orbit_number", ncInt, metaData->start_orb);
2065  ncFile->putAtt("end_orbit_number", ncInt, metaData->end_orb);
2066  ncFile->putAtt("map_projection", mapProjection.c_str());
2067 
2068  ncFile->putAtt("latitude_units", metaData->lat_units);
2069  ncFile->putAtt("longitude_units", metaData->lon_units);
2070 
2071  ncFile->putAtt("northernmost_latitude", ncFloat, metaData->north);
2072  ncFile->putAtt("southernmost_latitude", ncFloat, metaData->south);
2073  ncFile->putAtt("westernmost_longitude", ncFloat, metaData->west);
2074  ncFile->putAtt("easternmost_longitude", ncFloat, metaData->east);
2075  ncFile->putAtt("geospatial_lat_max", ncFloat, metaData->north);
2076  ncFile->putAtt("geospatial_lat_min", ncFloat, metaData->south);
2077  ncFile->putAtt("geospatial_lon_max", ncFloat, metaData->east);
2078  ncFile->putAtt("geospatial_lon_min", ncFloat, metaData->west);
2079 
2080  double latStep = (metaData->north - metaData->south)
2081  / (float) getHeight();
2082  double lonStep;
2083  if (metaData->east < metaData->west)
2084  lonStep = (360 + metaData->east - metaData->west)
2085  / (float) getWidth();
2086  else
2087  lonStep = (metaData->east - metaData->west) / (float) getWidth();
2088  ncFile->putAtt("latitude_step", ncFloat, latStep);
2089  ncFile->putAtt("longitude_step", ncFloat, lonStep);
2090  ncFile->putAtt("sw_point_latitude", ncFloat,
2091  metaData->south + latStep / 2.0);
2092  ncFile->putAtt("sw_point_longitude", ncFloat,
2093  metaData->west + lonStep / 2.0);
2094 
2095  string resolutionStr = resolution2string(resolution);
2096  ncFile->putAtt("spatialResolution", resolutionStr);
2097  ncFile->putAtt("geospatial_lon_resolution", resolutionStr);
2098  ncFile->putAtt("geospatial_lat_resolution", resolutionStr);
2099  ncFile->putAtt("geospatial_lat_units", metaData->lat_units);
2100  ncFile->putAtt("geospatial_lon_units", metaData->lon_units);
2101 
2102  ncFile->putAtt("number_of_lines", ncInt, height);
2103  ncFile->putAtt("number_of_columns", ncInt, width);
2104  ncFile->putAtt("measure", "Mean"); // FIXME
2105 
2106  ncFile->putAtt("suggested_image_scaling_minimum", ncFloat,
2107  productStuff[0]->productInfo->displayMin);
2108  ncFile->putAtt("suggested_image_scaling_maximum", ncFloat,
2109  productStuff[0]->productInfo->displayMax);
2110  if (!strcmp(productStuff[0]->productInfo->displayScale, "log"))
2111  tmpStr = "LOG";
2112  else if (!strcmp(productStuff[0]->productInfo->displayScale, "arctan"))
2113  tmpStr = "ATAN";
2114  else
2115  tmpStr = "LINEAR";
2116  ncFile->putAtt("suggested_image_scaling_type", tmpStr);
2117  ncFile->putAtt("suggested_image_scaling_applied", "No");
2118 
2119  ncFile->putAtt("_lastModified", metaData->ptime);
2120  ncFile->putAtt("Conventions", "CF-1.6 ACDD-1.3");
2121  ncFile->putAtt("institution", INSTITUTION);
2122  ncFile->putAtt("standard_name_vocabulary", STDNAME_VOCABULARY);
2123  ncFile->putAtt("naming_authority", NAMING_AUTHORITY);
2124 
2125  // create id
2126  string id = metaData->pversion;
2127  if(id == "Unspecified") {
2128  id = "L3/";
2129  } else {
2130  id += "/L3/";
2131  }
2132  id += metaData->product_name;
2133  ncFile->putAtt("id", id);
2134 
2135  ncFile->putAtt("license", LICENSE);
2136  ncFile->putAtt("creator_name", CREATOR_NAME);
2137  ncFile->putAtt("publisher_name", PUBLISHER_NAME);
2138  ncFile->putAtt("creator_email", CREATOR_EMAIL);
2139  ncFile->putAtt("publisher_email", PUBLISHER_EMAIL);
2140  ncFile->putAtt("creator_url", CREATOR_URL);
2141  ncFile->putAtt("publisher_url", PUBLISHER_URL);
2142 
2143  ncFile->putAtt("processing_level", "L3 Mapped");
2144  ncFile->putAtt("cdm_data_type", "grid"); // deprecated?
2145  if (proj4String.length() > 0)
2146  ncFile->putAtt("proj4_string", proj4String);
2147 
2148  // Some missions have DOIs
2149  if(clo_isSet(optionList, "suite")) {
2150  const char* doiStr = getDOI(metaData->mission, metaData->sensor, "L3M",
2151  clo_getString(optionList, "suite"),
2152  clo_getString(optionList, "pversion"));
2153  if (doiStr) {
2154  ncFile->putAtt("identifier_product_doi_authority", "http://dx.doi.org");
2155  ncFile->putAtt("identifier_product_doi", doiStr);
2156  }
2157  const char* keywordStr = getGCMDKeywords(clo_getString(optionList, "suite"));
2158  if(keywordStr) {
2159  ncFile->putAtt("keywords", keywordStr);
2160  ncFile->putAtt("keywords_vocabulary", KEYWORDS_VOCABULARY);
2161  }
2162  } // suite was set
2163 
2164  // create group: processing_control
2165  NcGroup grp1 = ncFile->addGroup("processing_control");
2166  grp1.putAtt("software_name", metaData->soft_name);
2167  grp1.putAtt("software_version", metaData->soft_ver);
2168  if ((tmpStr = strrchr(metaData->infiles, '/')) != NULL)
2169  tmpStr++;
2170  else
2171  tmpStr = metaData->infiles;
2172  grp1.putAtt("input_sources", tmpStr);
2173  grp1.putAtt("l2_flag_names", metaData->flag_names);
2174 
2175  // create sub-group: input_parameters
2176  NcGroup grp2 = grp1.addGroup("input_parameters");
2177  char buf[2048];
2178  char *end_str;
2179  char *token = strtok_r(metaData->input_parms, "|", &end_str);
2180  while (token != NULL) {
2181  char *end_token;
2182  strcpy(buf, token);
2183  char *name = strtok_r(token, "=", &end_token);
2184  for (uint32_t i = 0; i < strlen(name); i++) {
2185  if (name[i] == ' ') {
2186  name[i] = 0;
2187  break;
2188  }
2189  }
2190  char* val = strtok_r(NULL, "|", &end_token);
2191  if(val == NULL)
2192  val = "";
2193  strcpy(buf, val);
2194  grp2.putAtt(name, buf);
2195  token = strtok_r(NULL, "|", &end_str);
2196  }
2197 
2198  // Define dimensions and coordinate variables
2199  vector<NcDim> dimIds;
2200  string coordinates;
2201 
2202  if (mapProjection == "Equidistant Cylindrical" // SMI
2203  || mapProjection == "PlateCarree"
2204  || (proj4String.find("+proj=eqc") != string::npos) ) {
2205  dimIds.push_back(ncFile->addDim("lat", height));
2206  dimIds.push_back(ncFile->addDim("lon", width));
2207  if(fullLatLon != LatLonOff)
2208  fullLatLon = LatLon1D;
2209  } else {
2210  dimIds.push_back(ncFile->addDim("y", height));
2211  dimIds.push_back(ncFile->addDim("x", width));
2212  if (fullLatLon != LatLonOff) {
2213  fullLatLon = LatLon2D;
2214  coordinates = "lat lon";
2215  }
2216  }
2217 
2218  // Define variables
2219  size_t dataSize = 1;
2220  for (size_t prodNum = 0; prodNum < productStuff.size(); prodNum++) {
2221 
2222  // determine maximum product size
2223  NcType varDataType = getDataType(productStuff[prodNum]->dataStorage);
2224  dataSize = std::max(dataSize, varDataType.getSize());
2225 
2226  // create variable
2227  productInfo_t* pInfo = productStuff[prodNum]->productInfo;
2228  NcVar var = createProduct(pInfo, varDataType, dimIds);
2229  initCompression(var);
2230  prodVars.push_back(var);
2231 
2232  // add display info
2233  var.putAtt("display_scale", pInfo->displayScale);
2234  var.putAtt("display_min", ncFloat, pInfo->displayMin);
2235  var.putAtt("display_max", ncFloat, pInfo->displayMax);
2236 
2237  // specify coordinates as needed
2238  if (coordinates.length() > 0)
2239  var.putAtt("coordinates", coordinates);
2240 
2241  } // for prodNum
2242 
2243  // allocate buffer big enough for one line of the largest data type
2244  if (fileData)
2245  free(fileData);
2246  fileData = allocateMemory(width * dataSize, "OutFile_netcdf4::open fileData");
2247 
2248  // add the quality variable
2249  if (qualityData) {
2250  productInfo_t* qInfo = allocateProductInfo();
2251  if (qualityName.empty()) {
2252  qualityName = (string) "qual_"
2253  + getProductNameFull(productStuff[0]->productInfo);
2254  }
2255  if (!findProductInfo(qualityName.c_str(), metaData->sensorID, qInfo)) {
2256  cerr << "-E- OutFile_netcdf4::open - cannot find product "
2257  << qualityName << " in product.xml" << endl;
2258  exit(EXIT_FAILURE);
2259  }
2260  qInfo->fillValue = NC_FILL_UBYTE;
2261  qualVar = createProduct(qInfo, ncUbyte, dimIds);
2262  initCompression(qualVar);
2263  freeProductInfo(qInfo);
2264  }
2265 
2266  // add latitude and longitude variables
2267 
2268  productInfo_t* latInfo = allocateProductInfo();
2269  if (!findProductInfo("lat", metaData->sensorID, latInfo)) {
2270  cerr << "-E- OutFile_netcdf4::open - "
2271  "cannot find \"lat\" in product.xml" << endl;
2272  exit(EXIT_FAILURE);
2273  }
2274  productInfo_t* lonInfo = allocateProductInfo();
2275  if (!findProductInfo("lon", metaData->sensorID, lonInfo)) {
2276  cerr << "-E- OutFile_netcdf4::open - "
2277  "cannot find \"lon\" in product.xml" << endl;
2278  exit(EXIT_FAILURE);
2279  }
2280 
2281  if(fullLatLon == LatLon1D) {
2282 
2283  float* latarray = (float*) allocateMemory(getHeight() * sizeof (float),
2284  "latarray");
2285  for (int i = 0; i < getHeight(); i++)
2286  latarray[i] = metaData->north - latStep * i - latStep / 2.0;
2287  vector<NcDim> latDim; latDim.push_back(dimIds[0]);
2288  NcVar lat = createProduct(latInfo, ncFloat, latDim);
2289  lat.putVar(latarray);
2290  free(latarray);
2291 
2292  float* lonarray = (float*) allocateMemory(getWidth() * sizeof (float),
2293  "lonarray");
2294  for (int i = 0; i < getWidth(); i++)
2295  lonarray[i] = metaData->west + lonStep * i + lonStep / 2.0;
2296  vector<NcDim> lonDim; lonDim.push_back(dimIds[1]);
2297  NcVar lon = createProduct(lonInfo, ncFloat, lonDim);
2298  lon.putVar(lonarray);
2299  free(lonarray);
2300  } else if (fullLatLon == LatLon2D) {
2301  latVar = createProduct(latInfo, ncFloat, dimIds);
2302  lonVar = createProduct(lonInfo, ncFloat, dimIds);
2303  initCompression(latVar);
2304  initCompression(lonVar);
2305  }
2306 
2307  freeProductInfo(latInfo);
2308  freeProductInfo(lonInfo);
2309 
2310  // store palette
2311  if (red && green && blue) {
2312  uint8_t data[768];
2313  int j = 0;
2314  for (int i = 0; i < 256; i++) {
2315  data[j++] = red[i];
2316  data[j++] = green[i];
2317  data[j++] = blue[i];
2318  }
2319  vector<NcDim> dimIds;
2320  dimIds.push_back(ncFile->addDim("rgb", 3));
2321  dimIds.push_back(ncFile->addDim("eightbitcolor", 256));
2322  NcVar var = ncFile->addVar("palette", ncUbyte, dimIds);
2323  var.putVar(data);
2324  }
2325 
2326  } catch (std::exception const & e) {
2327  cerr << "Exception: " << e.what() << endl;
2328  }
2329 
2330  return true;
2331 }
2332 
2334  vector<size_t> start(2);
2335  vector<size_t> count(2);
2336  start[0] = currentLine;
2337  start[1] = 0;
2338  count[0] = 1;
2339  count[1] = width;
2340 
2341  // calculate and write one line of data for each product
2342  for (size_t prodNum = 0; prodNum < productStuff.size(); prodNum++) {
2343  productStuff[prodNum]->calcOutputLineVals(fileData);
2344  prodVars[prodNum].putVar(start, count, fileData);
2345  }
2346 
2347  // write quality data for this line
2348  if (qualityData) {
2349  qualVar.putVar(start, count, qualityData);
2350  }
2351 
2352  // write lat, lon for this line
2353  if (fullLatLon == LatLon2D) {
2354  if (latData)
2355  latVar.putVar(start, count, latData);
2356  if (lonData)
2357  lonVar.putVar(start, count, lonData);
2358  }
2359 
2360  currentLine++;
2361 }
2362 
2364 
2365  if (metaData) {
2366  ncFile->putAtt("data_bins", ncInt64, metaData->data_bins);
2367  if (metaData->data_bins <= 0) {
2368  ncFile->putAtt("data_minimum", ncFloat, 0.0);
2369  ncFile->putAtt("data_maximum", ncFloat, 0.0);
2370  } else {
2371  ncFile->putAtt("data_minimum", ncFloat, (float) getFileMinVal());
2372  ncFile->putAtt("data_maximum", ncFloat, (float) getFileMaxVal());
2373  }
2374  }
2375  ncFile->close();
2376  prodVars.clear();
2377 
2378  if (fileData) {
2379  free(fileData);
2380  fileData = NULL;
2381  }
2382  if (qualityData) {
2383  free(qualityData);
2384  qualityData = NULL;
2385  }
2386 
2387  return true;
2388 }
2389 
2390 int32_t OutFile_netcdf4::addProduct(productInfo_t* productInfo) {
2391  return addProductNonDisplay(productInfo);
2392 }
2393 
2394 void OutFile_netcdf4::initCompression(NcVar var) {
2395 
2396  // if deflate level below 0 then don't deflate
2397  if (getDeflate() < 1)
2398  return;
2399 
2400  vector<NcDim> dims = var.getDims();
2401  vector<size_t> chunksize;
2402  /*
2403  * vary chunk size based on dimensions
2404  * looking to keep the chunks around 32Kb, hopefully no larger than 200Kb
2405  */
2406  size_t newchunk;
2407  for (size_t i = 0; i < dims.size(); i++) {
2408  // Try to keep as few chunks as possible per scan line
2409  if (dims[i].getSize() < 1000) {
2410  newchunk = floor(dims[i].getSize() / 3) + 1;
2411  } else {
2412  newchunk = floor(dims[i].getSize() / 100) + 1;
2413  if (newchunk > 1500) {
2414  newchunk = floor(dims[i].getSize() / 250) + 1;
2415  if (newchunk > 40)
2416  newchunk = 40;
2417  }
2418  }
2419  chunksize.push_back(newchunk);
2420  }
2421 
2422  var.setChunking(NcVar::nc_CHUNKED, chunksize);
2423  var.setCompression(true, true, getDeflate());
2424 }
2425 
2426 
2427 NcVar OutFile_netcdf4::createProduct(productInfo_t* pInfo,
2428  const NcType& ncType,
2429  const std::vector<netCDF::NcDim> ncDim) {
2430 
2431  // create variable
2432  NcVar var = ncFile->addVar(getProductNameFull(pInfo), ncType, ncDim);
2433 
2434  // add standard metadata
2435  if (pInfo->description)
2436  var.putAtt("long_name", pInfo->description);
2437  if (pInfo->scaleFactor != 1.0 || pInfo->addOffset != 0.0) {
2438  var.putAtt("scale_factor", ncFloat, pInfo->scaleFactor);
2439  var.putAtt("add_offset", ncFloat, pInfo->addOffset);
2440  }
2441  if (pInfo->units != NULL && strcmp(pInfo->units, "dimensionless") != 0)
2442  var.putAtt("units", pInfo->units);
2443  if (pInfo->standardName != NULL && strcmp(pInfo->standardName, "") != 0)
2444  var.putAtt("standard_name", pInfo->standardName);
2445  try {
2446  if (pInfo->fillValue)
2447  var.putAtt("_FillValue", ncType, pInfo->fillValue);
2448  } catch (std::exception const & e) {
2449  cerr << "FillValue exception: " << e.what() << endl;
2450  }
2451  if (pInfo->validMin || pInfo->validMax) {
2452  var.putAtt("valid_min", ncType,
2453  (pInfo->validMin - pInfo->addOffset)/pInfo->scaleFactor);
2454  var.putAtt("valid_max", ncType,
2455  (pInfo->validMax - pInfo->addOffset)/pInfo->scaleFactor);
2456  }
2457  if (pInfo->reference != NULL && strcmp(pInfo->reference, "") != 0)
2458  var.putAtt("reference", pInfo->reference);
2459  if (pInfo->comment != NULL && strcmp(pInfo->comment, "") != 0)
2460  var.putAtt("comment", pInfo->comment);
2461 
2462  return var;
2463 }
2464 
2465 NcType OutFile_netcdf4::getDataType(DataStorage dataStorage) {
2466  switch (dataStorage) {
2467  case ByteDS : return NC_BYTE; // ncByte
2468  case UByteDS : return NC_UBYTE; // ncUbyte
2469  case ShortDS : return NC_SHORT; // ncShort
2470  case UShortDS: return NC_USHORT; // ncUshort
2471  case IntDS : return NC_INT; // ncInt
2472  case UIntDS : return NC_UINT; // ncUint
2473  case FloatDS : return NC_FLOAT; // ncFloat
2474  case DoubleDS: return NC_DOUBLE; // ncDouble
2475  default:
2476  cerr << "-E- OutFile_netcdf4::getDataType - illegal data storage type = "
2477  << dataStorage << endl;
2478  exit(EXIT_FAILURE);
2479  }
2480 }
char * ydhmsf(double dtime, char zone)
Definition: ydhmsf.c:12
virtual void fillPixel(int32_t x)
Definition: OutFile.cpp:814
virtual void setMetaData(meta_l3bType *metaData)
Definition: OutFile.cpp:477
virtual void writeLine()
Definition: OutFile.cpp:1483
virtual bool open()
Definition: OutFile.cpp:1667
char product_name[SM_ATTRSZ]
Definition: meta_l3b.h:16
int r
Definition: decode_rs.h:73
virtual void setPixel(int32_t x, double val, int32_t prod=0)
Definition: OutFile.cpp:345
virtual bool close()
Definition: OutFile.cpp:1087
void red(int iz1, int iz2, int jz1, int jz2, int jm1, int jm2, int jmf, int ic1, int jc1, int jcf, int kc, float ***c, float **s)
int16 eday
Definition: l1_czcs_hdf.c:17
virtual int addProductNonDisplay(productInfo_t *productInfo)
Definition: OutFile.cpp:508
virtual bool open()
Definition: OutFile.cpp:658
std::string qualityName
Definition: OutFile.h:111
void setScaleOffset(double scale, double offset, ScaleType scaleType)
Definition: OutFile.cpp:118
void freeProductInfo(productInfo_t *info)
int j
Definition: decode_rs.h:73
const char * getGCMDKeywords(const char *suite)
char * clo_getString(clo_optionList_t *list, const char *key)
Definition: clo.c:1357
virtual bool open()
Definition: OutFile.cpp:749
virtual void writeLine()
Definition: OutFile.cpp:1361
virtual void landPixel(int32_t x)
Definition: OutFile.cpp:383
GNU GENERAL PUBLIC LICENSE June Inc< https:Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software;it applies also to any other work released this way by its authors. You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software(and charge for them if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs, and that you know you can do these things. To protect your rights, we need to prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it:responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. Developers that use the GNU GPL protect your rights with two steps:(1) assert copyright on the software, and(2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution(with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that(1) displays an appropriate copyright notice, and(2) tells the user that there is no warranty for the work(except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that(a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and(b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component(kernel, window system, and so on) of the specific operating system(if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and(for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work 's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed;section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work 's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey verbatim copies of the Program 's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice;keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code;keep intact all notices of the absence of any warranty;and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions:a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices;however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation 's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways:a) Convey the object code in, or embodied in, a physical product(including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product(including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either(1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or(2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place(gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server(operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either(1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or(2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term(regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product(for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented(and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it.(Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may(if authorized by the copyright holders of that material) supplement the terms of this License with terms:a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License;or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it;or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version;or d) Limiting the use for publicity purposes of names of licensors or authors of the material;or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks;or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material(or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions;the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License(including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated(a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and(b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License(for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party 's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation(including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor 's "contributor version". A contributor 's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor 's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent(such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either(1) cause the Corresponding Source to be so available, or(2) arrange to deprive yourself of the benefit of the patent license for this particular work, or(3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient 's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license(a) in connection with copies of the covered work conveyed by you(or copies made from those copies), or(b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If conditions are imposed on you(whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy 's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively state the exclusion of warranty;and each file should have at least the "copyright" line and a pointer to where the full notice is found.< one line to give the program 's name and a brief idea of what it does. > Copyright(C)< year >< name of author > This program is free software without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE See the GNU General Public License for more details You should have received a copy of the GNU General Public License along with this program If not
Definition: LICENSE.txt:635
char station[SM_ATTRSZ]
Definition: meta_l3b.h:25
virtual void setPixelRGB(int32_t x, float red, float green, float blue)
Definition: OutFile.cpp:359
virtual int32_t getHeight() const
Definition: OutFile.cpp:337
These are used to scale the SD before writing it to the HDF4 file The default is and which means the product is not scaled at all Since the product is usually stored as a float inside of this is a way to write the float out as a integer l2prod min
FILE * outfp
Definition: OutFile.h:248
void calcOutputLineVals(void *lineBuffer) const
Definition: OutFile.cpp:210
virtual void writeLine()
Definition: OutFile.cpp:844
virtual int addProduct(productInfo_t *productInfo)
Definition: OutFile.cpp:1988
#define STDNAME_VOCABULARY
Definition: OutFile.h:30
virtual void writeLine()
Definition: OutFile.cpp:711
virtual void resetFileMinMax()
Definition: OutFile.cpp:596
char infiles[LG_ATTRSZ]
Definition: meta_l3b.h:38
void * allocateMemory(size_t numBytes, const char *name)
Definition: allocateMemory.c:7
#define FALSE
Definition: rice.h:164
virtual void missingPixel(int32_t x)
Definition: OutFile.cpp:409
#define NULL
Definition: decode_rs.h:63
double * latData
Definition: OutFile.h:123
char mission[SM_ATTRSZ]
Definition: meta_l3b.h:21
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude resolving resolving GSFcd00179 Corrected handling of fill values for[Sensor|Solar][Zenith|Azimuth] resolving MODxl01751 Changed to validate LUT version against a value retrieved from the resolving MODxl02056 Changed to calculate Solar Diffuser angles without adjustment for estimated post launch changes in the MODIS orientation relative to incidentally resolving defects MODxl01766 Also resolves MODxl01947 Changed to ignore fill values in SCI_ABNORM and SCI_STATE rather than treating them as resolving MODxl01780 Changed to use spacecraft ancillary data to recognise when the mirror encoder data is being set by side A or side B and to change calculations accordingly This removes the need for seperate LUTs for Side A and Side B data it makes the new LUTs incompatible with older versions of the and vice versa Also resolves MODxl01685 A more robust GRing algorithm is being which will create a non default GRing anytime there s even a single geolocated pixel in a granule Removed obsolete messages from seed as required for compatibility with version of the SDP toolkit Corrected test output file names to end in out
Definition: HISTORY.txt:422
std::string fileName
Definition: OutFile.h:107
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:2011
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that resolution
Definition: HISTORY.txt:188
@ ByteDS
Definition: OutFile.h:56
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:741
@ LatLonOff
Definition: OutFile.h:64
virtual void writeLine()
Definition: OutFile.cpp:671
char sensor_char[SM_ATTRSZ]
Definition: meta_l3b.h:24
#define PUBLISHER_URL
Definition: OutFile.h:37
double * lonData
Definition: OutFile.h:124
virtual void writeLine()
Definition: OutFile.cpp:969
int32_t start_orb
Definition: meta_l3b.h:42
char input_parms[LG_ATTRSZ]
Definition: meta_l3b.h:36
virtual ~OutFile_tiff_rgb()
Definition: OutFile.cpp:1465
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:1347
std::string mapProjection
Definition: OutFile.h:133
int clo_isSet(clo_optionList_t *list, const char *key)
Definition: clo.c:2270
float32 * pos
Definition: l1_czcs_hdf.c:35
#define TRUE
Definition: rice.h:165
ScaleType
Definition: OutFile.h:51
float * lat
virtual bool getQualityProcessing()
Definition: OutFile.cpp:627
int16 eyear
Definition: l1_czcs_hdf.c:17
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT32
std::vector< ProductStuff * > productStuff
Definition: OutFile.h:139
double calcOutputVal(double val) const
Definition: OutFile.cpp:138
virtual std::string getScaleTypeString(int32_t prod=0)
Definition: OutFile.cpp:309
int syear
Definition: l1_czcs_hdf.c:15
#define CREATOR_EMAIL
Definition: OutFile.h:32
string prodName
Definition: l3mapgen.cpp:55
@ IntDS
Definition: OutFile.h:56
virtual void writeLine()
Definition: OutFile.cpp:2333
ScaleType scaleType
Definition: OutFile.h:73
@ FloatDS
Definition: OutFile.h:56
virtual void landPixel(int32_t x)
Definition: OutFile.cpp:799
char flag_names[SM_ATTRSZ]
Definition: meta_l3b.h:37
double fileMaxVal
Definition: OutFile.h:118
double calcPhysicalVal(double val) const
Definition: OutFile.cpp:177
bool applyMask
Definition: l3mapgen.cpp:63
#define NAMING_AUTHORITY
Definition: OutFile.h:25
int32 smsec
Definition: l1_czcs_hdf.c:16
virtual bool close()
Definition: OutFile.cpp:679
@ string
virtual void fillPixel(int32_t x)
Definition: OutFile.cpp:396
TIFF * tiff
Definition: OutFile.h:335
uint8_t * qualityData
Definition: OutFile.h:112
#define LICENSE
Definition: OutFile.h:24
virtual void landPixel(int32_t x)
Definition: OutFile.cpp:1569
virtual ~OutFile_hdf4()
Definition: OutFile.cpp:1655
#define PUBLISHER_EMAIL
Definition: OutFile.h:36
virtual void fillPixel(int32_t x)
Definition: OutFile.cpp:1166
virtual void setMapProjection(std::string projection)
Definition: OutFile.cpp:558
int sday
Definition: l1_czcs_hdf.c:15
#define DPTB(function)
Definition: passthebuck.h:24
int32_t height
Definition: OutFile.h:109
float station_lon
Definition: meta_l3b.h:27
uint8_t * fileData
Definition: OutFile.h:249
uint8_t * blue
Definition: OutFile.h:128
double fileMinVal
Definition: OutFile.h:117
virtual void setLandRGB(const char *rgb_land_string)
Definition: OutFile.cpp:468
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:318
virtual void setPixel(int32_t x, double val, int32_t prod=0)
Definition: OutFile.cpp:769
#define PUBLISHER_NAME
Definition: OutFile.h:35
char sensor[SM_ATTRSZ]
Definition: meta_l3b.h:23
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:689
virtual ~OutFile_ppm_rgb()
Definition: OutFile.cpp:734
char lon_units[SM_ATTRSZ]
Definition: meta_l3b.h:45
data_t tmp
Definition: decode_rs.h:74
virtual void setTiffColor()=0
GTIF * gtif
Definition: OutFile.h:336
double endTime
Definition: meta_l3b.h:40
double resolution
Definition: OutFile.h:119
virtual ~OutFile_tiff_gray()
Definition: OutFile.cpp:1432
productInfo_t * allocateProductInfo()
void get_time(char *pr_time)
Definition: get_time.c:28
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:1660
virtual bool open()
Definition: OutFile.cpp:2019
char * strdup(const char *)
char prod_type[SM_ATTRSZ]
Definition: meta_l3b.h:29
void setScale(double min, double max, ScaleType scaleType)
Definition: OutFile.cpp:78
virtual void setResolution(std::string resolutionStr)
virtual bool setPalette(const char *paletteName, bool applyMask)
Definition: OutFile.cpp:432
virtual void missingPixel(int32_t x)
Definition: OutFile.cpp:1188
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:870
double string2resolution(std::string resolutionStr)
static constexpr double badPixelValue
Definition: OutFile.h:104
virtual int addProduct(productInfo_t *productInfo)
Definition: OutFile.cpp:2390
@ LatLon1D
Definition: OutFile.h:64
#define INSTITUTION
Definition: OutFile.h:23
virtual float getPercentFilledPixels()
Definition: OutFile.cpp:588
char data_center[SM_ATTRSZ]
Definition: meta_l3b.h:20
virtual void fillPixel(int32_t x)
Definition: OutFile.cpp:1594
virtual double getFileMinVal()
Definition: OutFile.h:200
#define CREATOR_NAME
Definition: OutFile.h:31
virtual void missingPixel(int32_t x)
Definition: OutFile.cpp:829
virtual ~OutFile_png()
Definition: OutFile.cpp:863
std::string proj4String
Definition: OutFile.h:135
virtual int32_t getNumFilledPixels()
Definition: OutFile.cpp:581
@ DoubleDS
Definition: OutFile.h:56
virtual void writeLine()
Definition: OutFile.cpp:1445
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:1437
virtual ~OutFile_tiff()
Definition: OutFile.cpp:1226
void unix2yds(double usec, short *year, short *day, double *secs)
double tiepoints[6]
Definition: OutFile.h:136
virtual void writeLine()
Definition: OutFile.cpp:1210
virtual void setPixelRGB(int32_t x, float red, float green, float blue)
Definition: OutFile.cpp:1533
virtual bool close()
Definition: OutFile.cpp:763
@ landPix
Definition: OutFile.h:60
#define KEYWORDS_VOCABULARY
Definition: OutFile.h:26
virtual void setTiffColor()
Definition: OutFile.cpp:1396
virtual void missingPixel(int32_t x)
Definition: OutFile.cpp:1618
virtual ~OutFile_tiff_color()
Definition: OutFile.cpp:1342
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_INT16
float north
Definition: meta_l3b.h:49
std::string resolution2string(double resolution)
LatLonType fullLatLon
Definition: OutFile.h:122
virtual void setQuality(int32_t x, uint8_t val)
Definition: OutFile.cpp:369
char title[SM_ATTRSZ]
Definition: meta_l3b.h:17
no change in intended resolving MODur00064 Corrected handling of bad ephemeris attitude data
Definition: HISTORY.txt:356
virtual bool open()
Definition: OutFile.cpp:1017
virtual bool open()
Definition: OutFile.cpp:1230
virtual bool open()
Definition: OutFile.cpp:877
@ ShortDS
Definition: OutFile.h:56
virtual bool close()
Definition: OutFile.cpp:2363
float west
Definition: meta_l3b.h:52
int sensorID
Definition: meta_l3b.h:18
virtual ~OutFile_png_rgb()
Definition: OutFile.cpp:999
int findProductInfo(const char *productName, int sensorId, productInfo_t *info)
data_t b[NROOTS+1]
Definition: decode_rs.h:77
int32_t orbit
Definition: meta_l3b.h:41
int getlut_file(char *lut_file, short *rlut, short *glut, short *blut)
Definition: getlut_file.c:8
const char * getDOI(const char *platform, const char *sensor, const char *level, const char *suite, const char *version)
Definition: getDOI.cpp:16
int32 emsec
Definition: l1_czcs_hdf.c:18
double pixscale[3]
Definition: OutFile.h:137
virtual ~OutFile_pgm()
Definition: OutFile.cpp:644
virtual void setTransparency()
Definition: OutFile.cpp:365
char lat_units[SM_ATTRSZ]
Definition: meta_l3b.h:44
virtual void setTiffColor()
Definition: OutFile.cpp:1456
uint8_t * green
Definition: OutFile.h:127
virtual void setLatLon(double *lat, double *lon)
Definition: OutFile.cpp:422
float south
Definition: meta_l3b.h:50
char * upcase(char *instr)
Definition: upcase.c:10
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:1470
char proc_con[MD_ATTRSZ]
Definition: meta_l3b.h:35
OutFile_png(bool color)
Definition: OutFile.cpp:853
virtual void setPixel(int32_t x, double val, int32_t prod=0)
Definition: OutFile.cpp:1101
char * getProductNameFull(productInfo_t *info)
DataStorage dataStorage
Definition: OutFile.h:72
virtual bool close()
Definition: OutFile.cpp:1933
virtual void setPixelRGB(int32_t x, float red, float green, float blue)
Definition: OutFile.cpp:1107
#define CREATOR_URL
Definition: OutFile.h:33
this program makes no use of any feature of the SDP Toolkit that could generate such a then geolocation is calculated at that and then aggregated up to Resolved feature request Bug by adding three new int8 SDSs for each high resolution offsets between the high resolution geolocation and a bi linear interpolation extrapolation of the positions This can be used to reconstruct the high resolution geolocation Resolved Bug by delaying cumulation of gflags until after validation of derived products Resolved Bug by setting Latitude and Longitude to the correct fill resolving to support Near Real Time because they may be unnecessary if use of entrained ephemeris and attitude data is turned resolving bug report Corrected to filter out Aqua attitude records with missing status helping resolve bug MOD_PR03 will still correctly write scan and pixel data that does not depend upon the start time
Definition: HISTORY.txt:248
double startTime
Definition: meta_l3b.h:39
char soft_ver[SM_ATTRSZ]
Definition: meta_l3b.h:33
void copyProductInfo(productInfo_t *dest, const productInfo_t *src)
char * unix2isodate(double dtime, char zone)
Definition: unix2isodate.c:10
virtual void setQualityProcessing(bool val)
Definition: OutFile.cpp:605
char mission_char[SM_ATTRSZ]
Definition: meta_l3b.h:22
@ fillPix
Definition: OutFile.h:60
ProductStuff(int32_t width, const productInfo_t *productInfo)
Definition: OutFile.cpp:32
clo_optionList_t * optionList
Definition: l2qc_viirs.cpp:39
virtual ~OutFile_netcdf4()
Definition: OutFile.cpp:2004
virtual int32_t getWidth() const
Definition: OutFile.cpp:333
#define PROJECT
Definition: OutFile.h:34
virtual void setPixelRGB(int32_t x, float red, float green, float blue)
Definition: OutFile.cpp:775
void setProj4Info(std::string projStr, double minX, double maxY)
Definition: OutFile.cpp:562
float * lon
char ptime[SM_ATTRSZ]
Definition: meta_l3b.h:34
virtual void setTiffColor()
Definition: OutFile.cpp:1491
bool transparent
Definition: OutFile.h:130
#define DBL_MAX
Definition: make_L3_v1.1.c:60
@ UByteDS
Definition: OutFile.h:56
virtual void landPixel(int32_t x)
Definition: OutFile.cpp:1142
char pversion[SM_ATTRSZ]
Definition: meta_l3b.h:30
l2prod offset
HDF4 data type of the output SDS Default is DFNT_FLOAT32 Common types used DFNT_FLOAT32
virtual void setPixel(int32_t x, double val, int32_t prod=0)
Definition: OutFile.cpp:1502
virtual bool open()
Definition: OutFile.cpp:696
virtual ~OutFile()
Definition: OutFile.cpp:295
meta_l3bType * metaData
Definition: OutFile.h:132
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:1006
virtual void setSize(int32_t width, int32_t height)
Definition: OutFile.cpp:651
float east
Definition: meta_l3b.h:51
@ UShortDS
Definition: OutFile.h:56
int64_t data_bins
Definition: meta_l3b.h:46
virtual int getDeflate()
Definition: OutFile.h:230
uint32_t currentLine
Definition: OutFile.h:113
@ LatLon2D
Definition: OutFile.h:64
int32_t width
Definition: OutFile.h:108
virtual bool close()
Definition: OutFile.cpp:1330
virtual bool close()
Definition: OutFile.cpp:977
char sensor_name[SM_ATTRSZ]
Definition: meta_l3b.h:19
int i
Definition: decode_rs.h:71
OutFile()
Definition: OutFile.cpp:255
virtual void setFileName(std::string fileName)
Definition: OutFile.cpp:341
msiBandIdx val
Definition: l1c_msi.cpp:34
How many dimensions is the output array Default is Not sure if anything above will work correctly strcpy(l2prod->title, "no title yet")
int32_t end_orb
Definition: meta_l3b.h:43
virtual void setNumFilledPixels(int32_t num)
Definition: OutFile.cpp:575
uint8_t * red
Definition: OutFile.h:126
char soft_name[SM_ATTRSZ]
Definition: meta_l3b.h:32
virtual double getFileMaxVal()
Definition: OutFile.h:204
float station_lat
Definition: meta_l3b.h:26
productInfo_t * productInfo
Definition: OutFile.h:71
l2prod max
@ UIntDS
Definition: OutFile.h:56
virtual int32_t addProduct(productInfo_t *productInfo)
Definition: OutFile.cpp:486
virtual void writeLine()
Definition: OutFile.cpp:1905
int count
Definition: decode_rs.h:79