Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PanoOptionsFromIni.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
11 /* This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public
13  * License as published by the Free Software Foundation; either
14  * version 2 of the License, or (at your option) any later version.
15  *
16  * This software is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19  * General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public
22  * License along with this software. If not, see
23  * <http://www.gnu.org/licenses/>.
24  *
25  */
26 
27 #include "PanoOptionsFromIni.h"
28 #include "IniParser.h"
29 #include <cmath>
37 
38 // helper struct to pass information about the whole panorama to the condition checks
40 {
41  double HFOV = 0;
42  double VFOV = 0;
43  std::string filename;
44  std::string path;
45 };
46 
47 // cache to store projection names
48 static std::vector<std::string> projectionNames;
49 static std::map<HuginBase::BaseSrcPanoImage::Projection, std::string> lensTypeNames;
51 {
52  // cache list of projection names
53  const int nP = panoProjectionFormatCount();
54  projectionNames.resize(nP);
55  for (int n = 0; n < nP; ++n)
56  {
57  pano_projection_features proj;
58  if (panoProjectionFeaturesQuery(n, &proj))
59  {
60  projectionNames[n] = hugin_utils::tolower(std::string(proj.name));
61  };
62  };
63  // populate lens type map
64  lensTypeNames[HuginBase::SrcPanoImage::RECTILINEAR] = "rectilinear";
65  lensTypeNames[HuginBase::SrcPanoImage::PANORAMIC] = "cylindrical";
66  lensTypeNames[HuginBase::SrcPanoImage::CIRCULAR_FISHEYE] = "fisheye";
67  lensTypeNames[HuginBase::SrcPanoImage::FULL_FRAME_FISHEYE] = "full frame fisheye";
68  lensTypeNames[HuginBase::SrcPanoImage::EQUIRECTANGULAR] = "equirectangular";
69  lensTypeNames[HuginBase::SrcPanoImage::FISHEYE_ORTHOGRAPHIC] = "orthographic";
70  lensTypeNames[HuginBase::SrcPanoImage::FISHEYE_STEREOGRAPHIC] = "stereographic";
71  lensTypeNames[HuginBase::SrcPanoImage::FISHEYE_EQUISOLID] = "equisolid";
72  lensTypeNames[HuginBase::SrcPanoImage::FISHEYE_THOBY] = "fisheye thoby";
73 }
74 
76 bool CheckString(const std::string& variable, const std::string& operatorString, const std::string& value)
77 {
78  if (operatorString == "==")
79  {
80  return variable == value;
81  };
82  if (operatorString == "!=" || operatorString == "<>")
83  {
84  return variable != value;
85  };
86  if (operatorString == "=~")
87  {
88  // variable contains value
89  return variable.find(value) != std::string::npos;
90  };
91  if (operatorString == "!~")
92  {
93  // variable does not contain value
94  return variable.find(value) == std::string::npos;
95  };
96  std::cerr << "Invalid operator \"" << operatorString << "\"" << std::endl;
97  return false;
98 }
99 
101 template<class Number>
102 bool CheckNumber(const Number variable, const std::string& operatorString, const Number value)
103 {
104  if (operatorString == "==")
105  {
106  return variable == value;
107  };
108  if (operatorString == "!=" || operatorString == "<>")
109  {
110  return variable != value;
111  };
112  if (operatorString == "<")
113  {
114  return variable < value;
115  };
116  if (operatorString == "<=")
117  {
118  return variable <= value;
119  };
120  if (operatorString == ">")
121  {
122  return variable > value;
123  };
124  if (operatorString == ">=")
125  {
126  return variable >= value;
127  };
128  std::cerr << "Invalid operator \"" << operatorString << "\"" << std::endl;
129  return false;
130 }
131 
133 bool CheckInt(const int variable, const std::string& operatorString, const std::string& stringValue)
134 {
135  int value;
136  if (!hugin_utils::stringToInt(stringValue, value))
137  {
138  std::cerr << "Invalid number \"" << stringValue << "\"" << std::endl;
139  return false;
140  };
141  return CheckNumber<int>(variable, operatorString, value);
142 }
143 
145 bool CheckDouble(const double variable, const std::string& operatorString, const std::string& stringValue)
146 {
147  double value;
148  if (!hugin_utils::stringToDouble(stringValue, value))
149  {
150  std::cerr << "Invalid number \"" << stringValue << "\"" << std::endl;
151  return false;
152  };
153  return CheckNumber<double>(variable, operatorString, value);
154 }
155 
157 bool CheckCondition(const std::string& condition, const HuginBase::Panorama& pano, const PanoProperties& panoProps)
158 {
159  size_t pos = condition.find_first_of("=<>!~");
160  if (pos != std::string::npos)
161  {
162  // operator found
163  const std::string variable = condition.substr(0, pos);
164  std::string operatorString;
165  std::string value;
166  size_t pos2 = condition.find_first_not_of("=<>!~", pos);
167  if (pos2 != std::string::npos)
168  {
169  // value after operator found, extract operator and value
170  operatorString = condition.substr(pos, pos2 - pos);
171  value = condition.substr(pos2);
172  if (value.empty())
173  {
174  // empty value
175  std::cerr << "Missing value in comparison \"" << condition << "\"." << std::endl;
176  return false;
177  };
178  // now do the comparison of the different variables
179  if (variable == "CameraModel")
180  {
181  return CheckString(pano.getImage(0).getExifModel(), operatorString, value);
182  };
183  if (variable == "CameraMaker")
184  {
185  return CheckString(pano.getImage(0).getExifMake(), operatorString, value);
186  };
187  if (variable == "Lens")
188  {
189  return CheckString(pano.getImage(0).getExifLens(), operatorString, value);
190  };
191  if (variable == "HFOV")
192  {
193  return CheckDouble(pano.getImage(0).getHFOV(), operatorString, value);
194  };
195  if (variable == "LensType")
196  {
197  if (projectionNames.empty())
198  {
199  // make sure projection names are read from libpano
201  };
202  return CheckString(lensTypeNames[pano.getImage(0).getProjection()], operatorString, hugin_utils::tolower(value));
203  };
204  if (variable == "Focallength")
205  {
206  return CheckDouble(pano.getImage(0).getExifFocalLength(), operatorString, value);
207  };
208  if (variable == "Focallength35mm")
209  {
210  return CheckDouble(pano.getImage(0).getExifFocalLength(), operatorString, value);
211  };
212  if (variable == "Filename")
213  {
214  return CheckString(panoProps.filename, operatorString, value);
215  };
216  if (variable == "Path")
217  {
218  return CheckString(panoProps.path, operatorString, value);
219  };
220  if (variable == "ImageCount")
221  {
222  return CheckInt(pano.getNrOfImages(), operatorString, value);
223  };
224  if (variable == "PanoHFOV")
225  {
226  return CheckDouble(panoProps.HFOV, operatorString, value);
227  };
228  if (variable == "PanoVFOV")
229  {
230  return CheckDouble(panoProps.VFOV, operatorString, value);
231  };
232  };
233  };
234  return false;
235 }
236 
237 void SetProjection(const std::string& projectionString, HuginBase::PanoramaOptions& options)
238 {
239  if (projectionNames.empty())
240  {
242  };
243  // now compare strings
244  for (int i = 0; i < projectionNames.size(); ++i)
245  {
246  if (projectionNames[i] == projectionString)
247  {
248  std::cout << "Setting projection to " << projectionString << std::endl;
249  options.setProjection(static_cast<HuginBase::PanoramaOptions::ProjectionFormat>(i));
250  break;
251  };
252  };
253 }
254 
255 void SetFOV(const std::string& fov, HuginBase::Panorama& pano, HuginBase::PanoramaOptions& options)
256 {
257  if (fov == "auto")
258  {
259  std::cout << "Fit panorama field of view to best size" << std::endl;
260  HuginBase::Panorama tempPano = pano.duplicate();
261  tempPano.setOptions(options);
262  HuginBase::CalculateFitPanorama fitPano(tempPano);
263  fitPano.run();
264  options.setHFOV(fitPano.getResultHorizontalFOV());
265  options.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
266  std::cout << "Setting field of view to " << options.getHFOV() << " x " << options.getVFOV() << std::endl;
267  }
268  else
269  {
270  double newHFOV = 0.0;
271  double newVFOV = 0.0;
272  const int n = sscanf(fov.c_str(), "%lfx%lf", &newHFOV, &newVFOV);
273  if ((n == 1 || n == 2) && newHFOV > 0.0)
274  {
275  options.setHFOV(newHFOV);
276  if (options.fovCalcSupported(options.getProjection()) && newVFOV > 0)
277  {
278  options.setVFOV(newVFOV);
279  };
280  std::cout << "Setting field of view to " << options.getHFOV() << " x " << options.getVFOV() << std::endl;
281  };
282  };
283 }
284 
285 void SetCanvas(const std::string& canvas, HuginBase::Panorama& pano, HuginBase::PanoramaOptions& options)
286 {
287  if (canvas == "auto" || canvas.back() == '%')
288  {
289  int scale = 100;
290  if (canvas.back() == '%')
291  {
292  if (!hugin_utils::stringToInt(canvas.substr(0, canvas.length() - 1), scale))
293  {
294  std::cout << "Invalid scale factor \"" << canvas << "\" for canvas" << std::endl;
295  scale = 0;
296  };
297  };
298  if (scale > 0)
299  {
300  std::cout << "Calculate optimal size of panorama" << std::endl;
301  HuginBase::Panorama tempPano = pano.duplicate();
302  tempPano.setOptions(options);
304  options.setWidth(hugin_utils::roundi(options.getWidth() * s * scale / 100), true);
305  std::cout << "Setting canvas size to " << options.getWidth() << " x " << options.getHeight() << std::endl;
306  };
307  }
308  else
309  {
310  int width = 0;
311  int height = 0;
312  int n = sscanf(canvas.c_str(), "%dx%d", &width, &height);
313  if (n == 2 && width > 0 && height > 0)
314  {
315  options.setWidth(width);
316  options.setHeight(height);
317  std::cout << "Setting canvas size to " << options.getWidth() << " x " << options.getHeight() << std::endl;
318  }
319  else
320  {
321  std::cerr << "Could not parse canvas size \"" << canvas << "\"." << std::endl;
322  };
323  };
324 }
325 
326 void SetCrop(const std::string& cropString, HuginBase::Panorama& pano, HuginBase::PanoramaOptions& options)
327 {
328  if (cropString == "auto" || cropString == "autohdr" || cropString == "autooutside")
329  {
330  std::cout << "Searching for best crop rectangle" << std::endl;
332  // we need to apply the current options before calculation of crop
333  HuginBase::Panorama tempPano = pano.duplicate();
334  tempPano.setOptions(options);
335  vigra::Rect2D roi;
336 
337  if (cropString == "autooutside")
338  {
339  HuginBase::CalculateOptimalROIOutside cropPano(tempPano, &dummy);
340  cropPano.run();
341  roi = cropPano.getResultOptimalROI();
342  }
343  else
344  {
345  HuginBase::CalculateOptimalROI cropPano(tempPano, &dummy);
346  if (cropString == "autohdr")
347  {
348  cropPano.setStacks(getHDRStacks(pano, pano.getActiveImages(), options));
349  }
350  cropPano.run();
351  roi = cropPano.getResultOptimalROI();
352  };
353  //set the ROI - fail if the right/bottom is zero, meaning all zero
354  if (!roi.isEmpty())
355  {
356  options.setROI(roi);
357  std::cout << "Set crop size to " << roi.left() << "," << roi.top() << "," << roi.right() << "," << roi.bottom() << std::endl;
358  }
359  else
360  {
361  std::cerr << "Could not find best crop rectangle" << std::endl;
362  }
363  }
364  else
365  {
366  if (cropString.back() == '%')
367  {
368  // relative crop
369  double left, right, top, bottom;
370  const int n = sscanf(cropString.substr(0, cropString.length() - 1).c_str(), "%lf,%lf,%lf,%lf", &left, &right, &top, &bottom);
371  bool validCrop = false;
372  if (n == 4 && right > left && bottom > top && left >= 0.0 && top >= 0.0 && right <= 100.0 && bottom <= 100.0)
373  {
374  // check values, 0..100 %
375  options.setROI(vigra::Rect2D(options.getWidth() * left / 100.0, options.getHeight() * top / 100.0,
376  options.getWidth() * right / 100.0, options.getHeight() * bottom / 100.0));
377  std::cout << "Set crop size to " << options.getROI().left() << "," << options.getROI().top() << "," <<
378  options.getROI().right() << "," << options.getROI().bottom() << std::endl;
379  validCrop = true;
380  };
381  if (!validCrop)
382  {
383  std::cerr << "Invalid crop area \"" << cropString << "\"" << std::endl;
384  };
385  }
386  else
387  {
388  // absolute crop
389  int left, right, top, bottom;
390  int n = sscanf(cropString.c_str(), "%d,%d,%d,%d", &left, &right, &top, &bottom);
391  bool validCrop = false;
392  if (n == 4 && right > left && bottom > top && left >= 0 && top >= 0)
393  {
394  options.setROI(vigra::Rect2D(left, top, right, bottom));
395  std::cout << "Set crop size to " << options.getROI().left() << "," << options.getROI().top() << "," <<
396  options.getROI().right() << "," << options.getROI().bottom() << std::endl;
397  validCrop = true;
398  };
399  if (!validCrop)
400  {
401  std::cerr << "Invalid crop area \"" << cropString << "\"" << std::endl;
402  };
403  };
404  };
405 }
406 
407 void SetExposure(const std::string& exposure, HuginBase::Panorama& pano, HuginBase::PanoramaOptions& options)
408 {
409  if (exposure == "auto")
410  {
412  std::cout << "Setting output exposure value to " << options.outputExposureValue << std::endl;
413  }
414  else
415  {
416  if (!exposure.empty() && exposure.front() == 'r')
417  {
418  double exposureValue;
419  if (hugin_utils::stringToDouble(exposure.substr(1), exposureValue))
420  {
421  options.outputExposureValue += exposureValue;
422  std::cout << "Setting output exposure value to " << options.outputExposureValue << std::endl;
423  }
424  else
425  {
426  std::cerr << "Value \"" << exposure << "\" is not a valid exposure value." << std::endl;
427  };
428  }
429  else
430  {
431  double exposureValue;
432  if (hugin_utils::stringToDouble(exposure, exposureValue))
433  {
434  options.outputExposureValue = exposureValue;
435  std::cout << "Setting output exposure value to " << options.outputExposureValue << std::endl;
436  }
437  else
438  {
439  std::cerr << "Value \"" << exposure << "\" is not a valid exposure value." << std::endl;
440  };
441  };
442  };
443 }
444 
445 void SetOutputType(const std::string& outputType, HuginBase::PanoramaOptions& options)
446 {
447  const std::vector<std::string> outputStrings = hugin_utils::SplitString(outputType, ",");
448  if (!outputStrings.empty())
449  {
450  // reset all output
451  // final pano
452  options.outputLDRBlended = false;
453  options.outputLDRExposureBlended = false;
454  options.outputLDRExposureLayersFused = false;
455  options.outputHDRBlended = false;
456  // remapped images
457  options.outputLDRLayers = false;
458  options.outputLDRExposureRemapped = false;
459  options.outputHDRLayers = false;
460  // stacks
461  options.outputLDRStacks = false;
462  options.outputHDRStacks = false;
463  // exposure layers
464  options.outputLDRExposureLayers = false;
465  for (const auto& output : outputStrings)
466  {
467  const std::string s = hugin_utils::StrTrim(output);
468  if (s == "NORMAL" || s == "N")
469  {
470  options.outputLDRBlended = true;
471  std::cout << "Activate output of normal panorama." << std::endl;
472  continue;
473  };
474  if (s == "STACKSFUSEDBLENDED" || s == "FB")
475  {
476  options.outputLDRExposureBlended = true;
477  std::cout << "Activate output of LDR panorama: Exposure fused from stacks." << std::endl;
478  continue;
479  };
480  if (s == "EXPOSURELAYERSFUSED" || s == "BF")
481  {
482  options.outputLDRExposureLayersFused = true;
483  std::cout << "Activate output of LDR panorama: Exposure fused from any arrangement." << std::endl;
484  continue;
485  };
486  if (s == "HDR")
487  {
488  options.outputHDRBlended = true;
489  std::cout << "Activate output of hdr panorama." << std::endl;
490  continue;
491  };
492  // single remapped images
493  if (s == "REMAP")
494  {
495  options.outputLDRLayers = true;
496  std::cout << "Activate output of remapped, exposure corrected images." << std::endl;
497  continue;
498  };
499  if (s == "REMAPORIG")
500  {
501  options.outputLDRExposureRemapped = true;
502  std::cout << "Activate output of remapped images with unmodified exposure." << std::endl;
503  continue;
504  };
505  if (s == "HDRREMAP")
506  {
507  options.outputHDRLayers = true;
508  std::cout << "Activate output of remapped hdr images." << std::endl;
509  continue;
510  };
511  //stacks
512  if (s == "FUSEDSTACKS")
513  {
514  options.outputLDRStacks = true;
515  std::cout << "Activate output of exposure fused stacks." << std::endl;
516  continue;
517  };
518  if (s == "HDRSTACKS")
519  {
520  options.outputHDRStacks = true;
521  std::cout << "Activate output of HDR stacks." << std::endl;
522  continue;
523  };
524  //exposure layers
525  if (s == "EXPOSURELAYERS")
526  {
527  options.outputLDRExposureLayers = true;
528  std::cout << "Activate output of exposure layers." << std::endl;
529  continue;
530  };
531  std::cerr << "Unknown parameter \"" << s << "\" found in Output-type." << std::endl
532  << "Ignoring this parameter." << std::endl;
533  };
534  };
535 }
536 
537 void SetLDRCompression(const std::string ldrCompression, HuginBase::PanoramaOptions& options)
538 {
539  if (options.outputImageType == "tif")
540  {
541  if (ldrCompression == "NONE" || ldrCompression == "PACKBITS" || ldrCompression == "LZW" || ldrCompression == "DEFLATE")
542  {
543  options.outputImageTypeCompression = ldrCompression;
544  std::cout << "Setting TIF compression to \"" << ldrCompression << "\"." << std::endl;
545  options.tiffCompression = ldrCompression;
546  }
547  else
548  {
549  std::cout << "LDR compression \"" << ldrCompression << "\" is not a valid compression value for TIF files." << std::endl;
550  }
551  }
552  else
553  {
554  if (options.outputImageType == "jpg")
555  {
556  int quality = 0;
557  quality = atoi(ldrCompression.c_str());
558  if (quality != 0)
559  {
560  if (quality > 0 && quality <= 100)
561  {
562  options.quality = quality;
563  std::cout << "Setting JPEG quality to " << quality << "." << std::endl;
564  }
565  else
566  {
567  std::cerr << "Given value for JPEG quality is outside the valid range 1..100." << std::endl;
568  };
569  }
570  else
571  {
572  std::cerr << "Could not parse \"" << ldrCompression << "\" as a valid JPEG quality number." << std::endl;
573  };
574  }
575  else
576  {
577  if (options.outputImageType == "png")
578  {
579  std::cerr << "Setting compression for PNG images is not supported." << std::endl;
580  }
581  else
582  {
583  // this should never happen
584  std::cerr << "Unknown image format" << std::endl;
585  };
586  };
587  };
588 }
589 
590 void SetHDRCompression(const std::string hdrCompression, HuginBase::PanoramaOptions& options)
591 {
592  if (options.outputImageTypeHDR == "tif")
593  {
594  if (hdrCompression == "NONE" || hdrCompression == "PACKBITS" || hdrCompression == "LZW" || hdrCompression == "DEFLATE")
595  {
596  options.outputImageTypeHDRCompression = hdrCompression;
597  std::cout << "Setting HDR-TIF compression to \"" << hdrCompression << "\"." << std::endl;
598  }
599  else
600  {
601  std::cerr << "HDR compression \"" << hdrCompression << "\" is not a valid compression value for TIF files." << std::endl;
602  }
603  }
604  else
605  {
606  if (options.outputImageTypeHDR == "exr")
607  {
608  std::cerr << "Setting compression for EXR images is not supported." << std::endl;
609  }
610  else
611  {
612  // this should never happen
613  std::cerr << "Unknown HDR image format" << std::endl;
614  };
615  };
616 }
617 
619 void ProcessSection(const IniParser& iniParser, const std::string& section, HuginBase::Panorama& pano, HuginBase::PanoramaOptions& options, const PanoProperties& panoProps)
620 {
621  const std::vector<std::string> keys = iniParser.GetKeys(section);
622  if (!keys.empty())
623  {
624  bool isConditionFullfilled = true;
625  for (const auto& key : keys)
626  {
627  // check if conidition if fullfilled
628  if (key.compare(0, 9, "Condition") == 0)
629  {
630  isConditionFullfilled = isConditionFullfilled && CheckCondition(iniParser.GetKey(section, key, std::string()), pano, panoProps);
631  if (!isConditionFullfilled)
632  {
633  // one condition is not fulfilled, we don't need to check the other one
634  break;
635  };
636  };
637  };
638  if (isConditionFullfilled)
639  {
640  std::cout << "Applying settings from \"" << section << "\"" << std::endl;
641  // condition is fullfilled, now do all wished settings
642  if (iniParser.HasKey(section, "Projection"))
643  {
644  // projection
645  const std::string projection = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "Projection", std::string())));
646  if (!projection.empty())
647  {
648  SetProjection(projection, options);
649  };
650  };
651  if (iniParser.HasKey(section, "FOV"))
652  {
653  // field of view
654  const std::string fov = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "FOV", std::string())));
655  if (!fov.empty())
656  {
657  SetFOV(fov, pano, options);
658  };
659  };
660  if (iniParser.HasKey(section, "Canvas"))
661  {
662  const std::string canvas = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "Canvas", std::string())));
663  if (!canvas.empty())
664  {
665  SetCanvas(canvas, pano, options);
666  };
667  };
668  if (iniParser.HasKey(section, "Crop"))
669  {
670  const std::string cropString = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "Crop", std::string())));
671  if (!cropString.empty())
672  {
673  SetCrop(cropString, pano, options);
674  };
675  };
676  if (iniParser.HasKey(section, "OutputExposure"))
677  {
678  // output exposure
679  const std::string exposure = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "OutputExposure", std::string())));
680  if (!exposure.empty())
681  {
682  SetExposure(exposure, pano, options);
683  };
684  };
685  if (iniParser.HasKey(section, "OutputType"))
686  {
687  const std::string outputType = hugin_utils::toupper(hugin_utils::StrTrim(iniParser.GetKey(section, "OutputType", std::string())));
688  SetOutputType(outputType, options);
689  };
690  if (iniParser.HasKey(section, "Blender"))
691  {
692  const std::string blender = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "Blender", std::string())));
693  if (blender == "enblend")
694  {
696  std::cout << "Setting blender type to \"ENBLEND\"." << std::endl;
697  }
698  else
699  {
700  if (blender == "internal" || blender == "verdandi")
701  {
703  std::cout << "Setting blender type to \"INTERNAL\"." << std::endl;
704  }
705  else
706  {
707  std::cerr << "Blender \"" << blender << "\" is not a valid blender ." << std::endl
708  << "Ignoring parameter." << std::endl;
709  };
710  };
711  };
712  if (iniParser.HasKey(section, "BlenderArgs"))
713  {
714  const std::string blenderArgs = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "BlenderArgs", std::string())));
715  switch (options.blendMode)
716  {
718  options.enblendOptions = blenderArgs;
719  std::cout << "Setting enblend arguments to " << blenderArgs << std::endl;
720  break;
722  options.verdandiOptions = blenderArgs;
723  std::cout << "Setting verdandi arguments to " << blenderArgs << std::endl;
724  break;
725  default:
726  std::cout << "Unknown blender in pto file." << std::endl;
727  break;
728  };
729  };
730  if (iniParser.HasKey(section, "LDRFileType"))
731  {
732  const std::string ldrFileType = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "LDRFileType", std::string())));
733  if (!ldrFileType.empty())
734  {
735  if (ldrFileType == "jpg" || ldrFileType == "png" || ldrFileType == "tif")
736  {
737  options.outputImageType = ldrFileType;
738  std::cout << "Setting ldr output to filetype \"" << ldrFileType << "\"." << std::endl;
739  }
740  else
741  {
742  std::cerr << "LDR file format \"" << ldrFileType << "\" is not a valid LDR output filetype." << std::endl;
743  };
744  };
745  };
746  if (iniParser.HasKey(section, "LDRCompression"))
747  {
748  const std::string ldrCompression = hugin_utils::toupper(hugin_utils::StrTrim(iniParser.GetKey(section, "LDRCompression", std::string())));
749  SetLDRCompression(ldrCompression, options);
750  };
751  if (iniParser.HasKey(section, "HDRFileType"))
752  {
753  const std::string hdrFileType = hugin_utils::tolower(hugin_utils::StrTrim(iniParser.GetKey(section, "HDRFileType", std::string())));
754  if (!hdrFileType.empty())
755  {
756  if (hdrFileType == "exr" || hdrFileType == "tif")
757  {
758  options.outputImageTypeHDR = hdrFileType;
759  std::cout << "Setting hdr output to filetype \"" << hdrFileType << "\"." << std::endl;
760  }
761  else
762  {
763  std::cerr << "HDR file format \"" << hdrFileType << "\" is not a valid HDR output filetype." << std::endl;
764  };
765  };
766  };
767  if (iniParser.HasKey(section, "HDRCompression"))
768  {
769  const std::string hdrCompression = hugin_utils::toupper(hugin_utils::StrTrim(iniParser.GetKey(section, "HDRCompression", std::string())));
770  SetHDRCompression(hdrCompression, options);
771  };
772  }
773  else
774  {
775  std::cout << "Ignoring settings from \"" << section << "\" because condition is not fulfilled." << std::endl;
776  };
777  };
778 }
779 
781 {
782  HuginBase::PanoramaOptions options=pano.getOptions();
783  if (pano.getNrOfImages() == 0)
784  {
785  return options;
786  };
787  IniParser iniParser;
788  iniParser.Read(iniFile);
789  // read EXIF data for first image
790  HuginBase::SrcPanoImage image0 = pano.getImage(0);
791  image0.readEXIF();
792  pano.setSrcImage(0, image0);
793  // calculate fov for whole pano
794  PanoProperties panoProps;
795  {
796  HuginBase::CalculateFitPanorama fitPano(pano);
797  fitPano.run();
798  HuginBase::PanoramaOptions generalOptions(options);
799  generalOptions.setHFOV(fitPano.getResultHorizontalFOV());
800  generalOptions.setHeight(hugin_utils::roundi(fitPano.getResultHeight()));
801  panoProps.HFOV = generalOptions.getHFOV();
802  panoProps.VFOV = generalOptions.getVFOV();
803  // store some more variables
804  const std::string filename = hugin_utils::GetAbsoluteFilename(pano.getImage(0).getFilename());
805  panoProps.filename = hugin_utils::stripPath(filename);
806  panoProps.path = hugin_utils::getPathPrefix(filename);
807  }
808  // now read settings from ini file
809  const std::vector<std::string> sections = iniParser.GetSections();
810  if (!sections.empty())
811  {
812  for (const auto& section : sections)
813  {
814  // now process current section
815  ProcessSection(iniParser, section, pano, options, panoProps);
816  };
817  };
818  return options;
819 }
PanoramaOptions::ProjectionFormat getProjection() const
std::vector< UIntSet > getHDRStacks(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output stacks
Definition: LayerStacks.cpp:35
Dummy progress display, without output.
declaration of functions to handle stacks and layers
void SetOutputType(const std::string &outputType, HuginBase::PanoramaOptions &options)
bool CheckCondition(const std::string &condition, const HuginBase::Panorama &pano, const PanoProperties &panoProps)
check if given condition is fulfilled by given panorama and PanoProperties
void setHeight(unsigned int h)
set panorama height
int roundi(T x)
Definition: hugin_math.h:73
bool CheckInt(const int variable, const std::string &operatorString, const std::string &stringValue)
check if given integer matches the condition (operator and value)
std::string StrTrim(const std::string &str)
remove trailing and leading white spaces and tabs
Definition: utils.cpp:208
static double calcMeanExposure(const PanoramaData &pano)
bool outputLDRLayers
save remapped layers (LDR)
bool fovCalcSupported(ProjectionFormat f) const
true, if FOV calcuations are supported for projection f
bool HasKey(const std::string &section, const std::string &key) const
Checks if given section/key exists.
Definition: IniParser.cpp:87
std::string outputImageTypeHDRCompression
bool outputHDRLayers
save remapped layers (HDR)
void SetFOV(const std::string &fov, HuginBase::Panorama &pano, HuginBase::PanoramaOptions &options)
unsigned int getHeight() const
get panorama height
HuginBase::PanoramaOptions ReadPanoramaOptionsFromIni(const std::string &iniFile, HuginBase::Panorama &pano)
read settings from given ini file and apply wished settings if they are applicable ...
std::vector< std::string > GetKeys(const std::string &section) const
returns a vector of all know keys in given section
Definition: IniParser.cpp:168
virtual void run()
runs the algorithm.
std::string outputImageTypeCompression
std::string toupper(const std::string &s)
Definition: stl_utils.h:59
bool outputLDRExposureBlended
&lt; save exposure fused stacks (no exposure adjustment)
reads and parse an ini file
Panorama duplicate() const
duplicate the panorama
Definition: Panorama.cpp:1653
void setStacks(std::vector< UIntSet > hdr_stacks)
sets the stack vector
static std::vector< std::string > projectionNames
const vigra::Rect2D & getROI() const
Model for a panorama.
Definition: Panorama.h:152
bool outputLDRBlended
save blended panorama (LDR)
std::string getPathPrefix(const std::string &filename)
Get the path to a filename.
Definition: utils.cpp:184
std::string GetAbsoluteFilename(const std::string &filename)
returns the full absolute filename
Definition: utils.cpp:368
std::vector< std::string > GetSections() const
returns a vector of all know sections
Definition: IniParser.cpp:157
void ProcessSection(const IniParser &iniParser, const std::string &section, HuginBase::Panorama &pano, HuginBase::PanoramaOptions &options, const PanoProperties &panoProps)
process the given section, check if all conditions are fulfilled and if so apply all wished settings ...
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
bool CheckString(const std::string &variable, const std::string &operatorString, const std::string &value)
check if given string matches the value with the corresponding operator
static double calcOptimalScale(PanoramaData &panorama)
virtual vigra::Rect2D getResultOptimalROI()
return the ROI structure?, for now area
virtual double getResultHeight()
Definition: FitPanorama.h:75
bool outputHDRBlended
save blended panorama (HDR)
void SetProjection(const std::string &projectionString, HuginBase::PanoramaOptions &options)
bool stringToInt(const std::string &s, int &val)
convert string to integer value, returns true, if sucessful
Definition: utils.cpp:264
bool stringToDouble(const STR &str_, double &dest)
convert a string to a double, ignore localisation.
Definition: utils.h:114
void setROI(const vigra::Rect2D &val)
std::string GetKey(const std::string &section, const std::string &key, const std::string &defaultValue) const
returns the value of the given section/key or default value if it does not exists ...
Definition: IniParser.cpp:100
UIntSet getActiveImages() const
get active images
Definition: Panorama.cpp:1585
void SetCanvas(const std::string &canvas, HuginBase::Panorama &pano, HuginBase::PanoramaOptions &options)
bool outputLDRExposureLayers
save blended exposure layers, do not perform fusion (no exposure adjustment)
void setHFOV(double h, bool keepView=true)
set the horizontal field of view.
unsigned int getWidth() const
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
bool CheckNumber(const Number variable, const std::string &operatorString, const Number value)
general number comparison function
virtual double getResultHorizontalFOV()
Definition: FitPanorama.h:68
virtual vigra::Rect2D getResultOptimalROI()
returns the found crop rect
void ReadProjectionNames()
bool outputLDRExposureRemapped
save remapped layers (no exposure adjustment)
void SetHDRCompression(const std::string hdrCompression, HuginBase::PanoramaOptions &options)
bool outputLDRExposureLayersFused
save blended exposure layers which are then fused (no exposure adjustment)
int Read(const std::string &file)
Reads the given ini file.
Definition: IniParser.cpp:34
bool readEXIF()
try to fill out information about the image, by examining the exif data
static std::map< HuginBase::BaseSrcPanoImage::Projection, std::string > lensTypeNames
void SetCrop(const std::string &cropString, HuginBase::Panorama &pano, HuginBase::PanoramaOptions &options)
read settings from ini file and apply only applicable values
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
void setOptions(const PanoramaOptions &opt)
set new output settings This is not used directly for optimizing/stiching, but it can be feed into ru...
Definition: Panorama.cpp:1531
void setSrcImage(unsigned int nr, const SrcPanoImage &img)
set input image parameters
std::vector< std::string > SplitString(const std::string &s, const std::string &sep)
split string s at given sep, returns vector of strings
Definition: utils.cpp:294
All variables of a source image.
Definition: SrcPanoImage.h:194
void setProjection(ProjectionFormat f)
set the Projection format and adjust the hfov/vfov if nessecary
Panorama image options.
bool outputHDRStacks
save image stacks (HDR)
void SetLDRCompression(const std::string ldrCompression, HuginBase::PanoramaOptions &options)
BlendingMechanism blendMode
bool CheckDouble(const double variable, const std::string &operatorString, const std::string &stringValue)
check if given double matches the condition (operator and value)
std::string tolower(const std::string &s)
convert a string to lowercase
Definition: stl_utils.h:49
void SetExposure(const std::string &exposure, HuginBase::Panorama &pano, HuginBase::PanoramaOptions &options)
std::string stripPath(const std::string &filename)
remove the path of a filename (mainly useful for gui display of filenames)
Definition: utils.cpp:160
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
A simple parser for ini files, it implements only some basic features.
Definition: IniParser.h:37