Hugintrunk  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
PanoOutputDialog.cpp
Go to the documentation of this file.
1 // -*- c-basic-offset: 4 -*-
2 
11 /* This 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  * Lesser 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 "hugin/PanoOutputDialog.h"
28 #include "base_wx/wxPlatform.h"
29 #include "panoinc.h"
30 
31 #include "hugin/huginApp.h"
32 #include "base_wx/platform.h"
33 #include "base_wx/wxutils.h"
34 #include "hugin/config_defaults.h"
37 
38 PanoOutputDialog::PanoOutputDialog(wxWindow *parent, HuginBase::Panorama& pano, GuiLevel guiLevel) : m_pano(pano), m_aspect(0)
39 {
40  // load our children. some children might need special
41  // initialization. this will be done later.
42  wxXmlResource::Get()->LoadDialog(this, parent, "pano_output_dialog");
43 
44  //set parameters
45  wxConfigBase * cfg = wxConfigBase::Get();
46  //position
47  hugin_utils::RestoreFramePositionOnly(this, "PanoOutputDialog");
48  // get number of stacks and exposure layers
49  m_guiLevel=guiLevel;
53  // set initial width
55  wxConfigBase* config = wxConfigBase::Get();
56  if (m_newOpt.fovCalcSupported(m_newOpt.getProjection()))
57  {
58  // calc optimal size of pano, only of projection is supported
59  // otherwise use current width as start point
60  long opt_width = hugin_utils::roundi(HuginBase::CalculateOptimalScale::calcOptimalScale(m_pano) * m_newOpt.getWidth());
61  double sizeFactor = HUGIN_ASS_PANO_DOWNSIZE_FACTOR;
62  config->Read("/Assistant/panoDownsizeFactor", &sizeFactor, HUGIN_ASS_PANO_DOWNSIZE_FACTOR);
63  m_newOpt.setWidth(hugin_utils::floori(sizeFactor*opt_width), true);
64  };
65  m_initalWidth=m_newOpt.getWidth();
66  m_initalROIWidth=m_newOpt.getROI().width();
67  m_aspect=(double)m_newOpt.getROI().height()/m_newOpt.getROI().width();
68  m_edit_width=XRCCTRL(*this, "output_width", wxSpinCtrl);
69  m_edit_height=XRCCTRL(*this, "output_height", wxSpinCtrl);
70  m_edit_width->SetValue(m_newOpt.getROI().width());
71  m_edit_height->SetValue(m_newOpt.getROI().height());
72 
73  //LDR output format, as in preferences set
74  int i = config->Read("/output/jpeg_quality",HUGIN_JPEG_QUALITY);
75  XRCCTRL(*this, "output_jpeg_quality", wxSpinCtrl)->SetValue(i);
76  i=config->Read("/output/tiff_compression", HUGIN_TIFF_COMPRESSION);
77  XRCCTRL(*this, "output_tiff_compression", wxChoice)->SetSelection(i);
78  i=config->Read("/output/ldr_format", HUGIN_LDR_OUTPUT_FORMAT);
79  XRCCTRL(*this, "output_ldr_format", wxChoice)->SetSelection(i);
80  //HDR output format, as in project given
81  if (m_newOpt.outputImageTypeHDR == "exr")
82  {
83  XRCCTRL(*this, "output_hdr_format", wxChoice)->SetSelection(0);
84  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->SetSelection(2);
85  }
86  else
87  {
88  XRCCTRL(*this, "output_hdr_format", wxChoice)->SetSelection(1);
89  if (m_newOpt.outputImageTypeHDRCompression == "PACKBITS")
90  {
91  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->SetSelection(1);
92  }
93  else
94  {
95  if (m_newOpt.outputImageTypeHDRCompression == "LZW")
96  {
97  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->SetSelection(2);
98  }
99  else
100  {
101  if (m_newOpt.outputImageTypeHDRCompression == "DEFLATE")
102  {
103  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->SetSelection(3);
104  }
105  else
106  {
107  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->SetSelection(0);
108  };
109  };
110  };
111  };
113  wxCommandEvent dummy;
114  OnOutputChanged(dummy);
115  OnLDRFormatChanged(dummy);
116  OnHDRFormatChanged(dummy);
117  // bind event handler
118  Bind(wxEVT_CHECKBOX, &PanoOutputDialog::OnOutputChanged, this, XRCID("output_normal"));
119  Bind(wxEVT_CHECKBOX, &PanoOutputDialog::OnOutputChanged, this, XRCID("output_fused_blended"));
120  Bind(wxEVT_CHECKBOX, &PanoOutputDialog::OnOutputChanged, this, XRCID("output_blended_fused"));
121  Bind(wxEVT_CHECKBOX, &PanoOutputDialog::OnOutputChanged, this, XRCID("output_hdr"));
122  Bind(wxEVT_CHOICE, &PanoOutputDialog::OnLDRFormatChanged, this, XRCID("output_ldr_format"));
123  Bind(wxEVT_CHOICE, &PanoOutputDialog::OnHDRFormatChanged, this, XRCID("output_hdr_format"));
124  Bind(wxEVT_SPINCTRL, &PanoOutputDialog::OnWidthChanged, this, XRCID("output_width"));
125  Bind(wxEVT_SPINCTRL, &PanoOutputDialog::OnHeightChanged, this, XRCID("output_height"));
126  Bind(wxEVT_BUTTON, &PanoOutputDialog::OnOk, this, wxID_OK);
127 
128 };
129 
131 {
132  hugin_utils::StoreFramePositionOnly(this, "PanoOutputDialog");
133  wxConfigBase::Get()->Flush();
134 };
135 
137 {
138  // check, if hdr images
139  wxFileName file1(wxString(m_pano.getImage(0).getFilename().c_str(), HUGIN_CONV_FILENAME));
140  wxString ext1=file1.GetExt().Lower();
141  if(ext1 == ".hdr" || ext1 == ".exr" || ext1=="hdr" || ext1=="exr")
142  {
143  XRCCTRL(*this, "output_normal", wxCheckBox)->SetValue(true);
144  XRCCTRL(*this, "output_normal", wxCheckBox)->Enable(true);
145  XRCCTRL(*this, "output_normal_bitmap", wxStaticBitmap)->Enable(true);
146  return;
147  }
148  //hide hdr controls for simple interface
150  {
151  XRCCTRL(*this, "output_hdr", wxCheckBox)->Hide();
152  XRCCTRL(*this, "output_hdr_bitmap", wxStaticBitmap)->Hide();
153  XRCCTRL(*this, "output_hdr_format_label", wxStaticText)->Hide();
154  XRCCTRL(*this, "output_hdr_format", wxChoice)->Hide();
155  XRCCTRL(*this, "output_hdr_compression_label", wxStaticText)->Hide();
156  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->Hide();
157  Layout();
158  GetSizer()->Fit(this);
159  };
160  //single image or normal panorama, enable only normal output
161  if(m_pano.getNrOfImages()==1 || m_stacks.size() >= 0.7 * m_pano.getNrOfImages())
162  {
163  XRCCTRL(*this, "output_normal", wxCheckBox)->SetValue(true);
164  XRCCTRL(*this, "output_normal", wxCheckBox)->Enable(true);
165  XRCCTRL(*this, "output_normal_bitmap", wxStaticBitmap)->Enable(true);
166  if(m_pano.getNrOfImages()==1 || m_stacks.size()==m_pano.getNrOfImages())
167  {
168  return;
169  };
170  };
171  XRCCTRL(*this, "output_fused_blended", wxCheckBox)->Enable(true);
172  XRCCTRL(*this, "output_fused_blended_bitmap", wxStaticBitmap)->Enable(true);
173  XRCCTRL(*this, "output_blended_fused", wxCheckBox)->Enable(true);
174  XRCCTRL(*this, "output_blended_fused_bitmap", wxStaticBitmap)->Enable(true);
176  {
177  XRCCTRL(*this, "output_hdr", wxCheckBox)->Enable(true);
178  XRCCTRL(*this, "output_hdr_bitmap", wxStaticBitmap)->Enable(true);
179  };
180  if(m_pano.getNrOfImages() % m_stacks.size() == 0)
181  {
182  XRCCTRL(*this, "output_fused_blended", wxCheckBox)->SetValue(true);
183  }
184  else
185  {
186  if(m_exposureLayers.size()==1)
187  {
188  XRCCTRL(*this, "output_normal", wxCheckBox)->SetValue(true);
189  XRCCTRL(*this, "output_normal", wxCheckBox)->Enable(true);
190  XRCCTRL(*this, "output_normal_bitmap", wxStaticBitmap)->Enable(true);
191  }
192  else
193  {
194  XRCCTRL(*this, "output_blended_fused", wxCheckBox)->SetValue(true);
195  };
196  };
197 };
198 
199 void PanoOutputDialog::OnOk(wxCommandEvent & e)
200 {
201  bool output_normal=XRCCTRL(*this, "output_normal", wxCheckBox)->GetValue();
202  bool output_fused_blended=XRCCTRL(*this, "output_fused_blended", wxCheckBox)->GetValue();
203  bool output_blended_fused=XRCCTRL(*this, "output_blended_fused", wxCheckBox)->GetValue();
204  bool output_hdr=XRCCTRL(*this, "output_hdr", wxCheckBox)->GetValue();
205  bool keep_intermediate=XRCCTRL(*this, "output_keep_intermediate", wxCheckBox)->GetValue();
206  //normal output
207  m_newOpt.outputLDRBlended=output_normal;
208  m_newOpt.outputLDRLayers=output_normal && keep_intermediate;
209  //fused stacks, then blended
210  m_newOpt.outputLDRExposureBlended=output_fused_blended;
211  m_newOpt.outputLDRExposureRemapped=(output_fused_blended || output_blended_fused) && keep_intermediate;
212  m_newOpt.outputLDRStacks=output_fused_blended && keep_intermediate;
213  // blended exposure layers, then fused
214  m_newOpt.outputLDRExposureLayersFused=output_blended_fused;
215  m_newOpt.outputLDRExposureLayers=output_blended_fused && keep_intermediate;
216  // HDR output
217  m_newOpt.outputHDRBlended=output_hdr;
218  m_newOpt.outputHDRLayers=output_hdr && keep_intermediate;
219  m_newOpt.outputHDRStacks=output_hdr && keep_intermediate;
220  // read compression
221  if(output_normal || output_fused_blended || output_blended_fused)
222  {
223  if(m_newOpt.outputImageType=="jpg")
224  {
225  m_newOpt.quality=XRCCTRL(*this, "output_jpeg_quality", wxSpinCtrl)->GetValue();
226  }
227  else
228  {
229  if(m_newOpt.outputImageType=="tif")
230  {
231  switch(XRCCTRL(*this, "output_tiff_compression", wxChoice)->GetSelection())
232  {
233  case 0:
234  default:
236  m_newOpt.tiffCompression = "NONE";
237  break;
238  case 1:
240  m_newOpt.tiffCompression = "PACKBITS";
241  break;
242  case 2:
244  m_newOpt.tiffCompression = "LZW";
245  break;
246  case 3:
248  m_newOpt.tiffCompression = "DEFLATE";
249  break;
250  };
251  };
252  };
253  };
254  //HDR compression
255  if(output_hdr)
256  {
257  if(m_newOpt.outputImageTypeHDR=="tif")
258  {
259  switch(XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->GetSelection())
260  {
261  case 0:
262  default:
264  break;
265  case 1:
267  break;
268  case 2:
270  break;
271  case 3:
273  break;
274  };
275  };
276  }
277  // canvas size
278  double scale=m_edit_width->GetValue()/m_initalROIWidth;
280  //some checks to prevent some rounding errors, only for cropped outputs
282  {
283  if(m_newOpt.getROI().width()<m_edit_width->GetValue() || m_newOpt.getROI().height()<m_edit_height->GetValue())
284  {
285  m_newOpt.setWidth(m_newOpt.getWidth()+1, true);
286  };
287  vigra::Rect2D roi=m_newOpt.getROI();
288  if(roi.width()>m_edit_width->GetValue() || roi.height()>m_edit_height->GetValue())
289  {
290  roi.setSize(m_edit_width->GetValue(), m_edit_height->GetValue());
291  m_newOpt.setROI(roi);
292  };
293  };
294  //send Ok
295  EndModal(wxID_OK);
296 };
297 
298 void PanoOutputDialog::OnOutputChanged(wxCommandEvent & e)
299 {
300  bool output_normal=XRCCTRL(*this, "output_normal", wxCheckBox)->GetValue();
301  bool output_fused_blended=XRCCTRL(*this, "output_fused_blended", wxCheckBox)->GetValue();
302  bool output_blended_fused=XRCCTRL(*this, "output_blended_fused", wxCheckBox)->GetValue();
303  bool output_hdr=XRCCTRL(*this, "output_hdr", wxCheckBox)->GetValue();
304  //enable Ok only if at least one option is enabled
305  XRCCTRL(*this, "wxID_OK", wxButton)->Enable(output_normal || output_fused_blended || output_blended_fused || output_hdr);
306  XRCCTRL(*this, "output_ldr_format_label", wxStaticText)->Enable(output_normal || output_fused_blended || output_blended_fused);
307  XRCCTRL(*this, "output_ldr_format", wxChoice)->Enable(output_normal || output_fused_blended || output_blended_fused);
308  XRCCTRL(*this, "output_ldr_compression_label", wxStaticText)->Enable(output_normal || output_fused_blended || output_blended_fused);
309  XRCCTRL(*this, "output_jpeg_quality", wxSpinCtrl)->Enable(output_normal || output_fused_blended || output_blended_fused);
310  XRCCTRL(*this, "output_tiff_compression", wxChoice)->Enable(output_normal || output_fused_blended || output_blended_fused);
311  XRCCTRL(*this, "output_hdr_format_label", wxStaticText)->Enable(output_hdr);
312  XRCCTRL(*this, "output_hdr_format", wxChoice)->Enable(output_hdr);
313  XRCCTRL(*this, "output_hdr_compression_label", wxStaticText)->Enable(output_hdr);
314  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->Enable(output_hdr);
315  GetSizer()->Layout();
316 };
317 
318 void PanoOutputDialog::OnLDRFormatChanged(wxCommandEvent & e)
319 {
320  int sel = XRCCTRL(*this, "output_ldr_format", wxChoice)->GetSelection();
321  switch (sel)
322  {
323  case 1:
324  m_newOpt.outputImageType ="jpg";
325  XRCCTRL(*this, "output_ldr_compression_label", wxStaticText)->Show();
326  XRCCTRL(*this, "output_ldr_compression_label", wxStaticText)->SetLabel(_("Quality:"));
327  XRCCTRL(*this, "output_jpeg_quality", wxSpinCtrl)->Show();
328  XRCCTRL(*this, "output_tiff_compression", wxChoice)->Hide();
329  break;
330  case 2:
331  m_newOpt.outputImageType ="png";
332  XRCCTRL(*this, "output_ldr_compression_label", wxStaticText)->Hide();
333  XRCCTRL(*this, "output_jpeg_quality", wxSpinCtrl)->Hide();
334  XRCCTRL(*this, "output_tiff_compression", wxChoice)->Hide();
335  break;
336  default:
337  case 0:
338  m_newOpt.outputImageType ="tif";
339  XRCCTRL(*this, "output_ldr_compression_label", wxStaticText)->Show();
340  XRCCTRL(*this, "output_ldr_compression_label", wxStaticText)->SetLabel(_("Compression:"));
341  XRCCTRL(*this, "output_jpeg_quality", wxSpinCtrl)->Hide();
342  XRCCTRL(*this, "output_tiff_compression", wxChoice)->Show();
343  break;
344  };
345  GetSizer()->Layout();
346 };
347 
348 
349 void PanoOutputDialog::OnHDRFormatChanged(wxCommandEvent & e)
350 {
351  int sel = XRCCTRL(*this, "output_hdr_format", wxChoice)->GetSelection();
352  switch (sel)
353  {
354  case 1:
356  XRCCTRL(*this, "output_hdr_compression_label", wxStaticText)->Show();
357  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->Show();
358  break;
359  case 0:
360  default:
362  XRCCTRL(*this, "output_hdr_compression_label", wxStaticText)->Hide();
363  XRCCTRL(*this, "output_hdr_tiff_compression", wxChoice)->Hide();
364  break;
365  };
366  GetSizer()->Layout();
367 };
368 
369 void PanoOutputDialog::OnWidthChanged(wxSpinEvent & e)
370 {
371  if(m_aspect>0)
372  {
373  m_edit_height->SetValue(m_edit_width->GetValue()*m_aspect);
374  };
375 };
376 
378 {
379  if(m_aspect>0)
380  {
381  m_edit_width->SetValue(m_edit_height->GetValue()/m_aspect);
382  };
383 };
int floori(double x)
Definition: hugin_math.h:65
std::vector< UIntSet > getHDRStacks(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output stacks
Definition: LayerStacks.cpp:35
implementation of huginApp Class
declaration of functions to handle stacks and layers
std::vector< UIntSet > getExposureLayers(const PanoramaData &pano, UIntSet allImgs, PanoramaOptions opts)
returns vector of set of output exposure layers
Definition: LayerStacks.cpp:96
~PanoOutputDialog()
destructor, save position
int roundi(T x)
Definition: hugin_math.h:73
bool outputLDRLayers
save remapped layers (LDR)
#define HUGIN_CONV_FILENAME
Definition: platform.h:40
void OnHeightChanged(wxSpinEvent &e)
height changed
#define HUGIN_JPEG_QUALITY
std::string outputImageTypeHDRCompression
bool outputHDRLayers
save remapped layers (HDR)
UIntSet getImagesinROI(const PanoramaData &pano, const UIntSet activeImages)
returns set of images which are visible in output ROI
include file for the hugin project
wxSpinCtrl * m_edit_height
void OnOk(wxCommandEvent &e)
Saves current state of all checkboxes when closing dialog with Ok.
std::string outputImageTypeCompression
bool outputLDRExposureBlended
&lt; save exposure fused stacks (no exposure adjustment)
HuginBase::Panorama & m_pano
std::set< unsigned int > UIntSet
Definition: PanoramaData.h:51
const vigra::Rect2D & getROI() const
Model for a panorama.
Definition: Panorama.h:152
bool outputLDRBlended
save blended panorama (LDR)
std::size_t getNrOfImages() const
number of images.
Definition: Panorama.h:205
Definition of PanoOutputDialog class.
static double calcOptimalScale(PanoramaData &panorama)
bool outputHDRBlended
save blended panorama (HDR)
std::vector< HuginBase::UIntSet > m_exposureLayers
#define HUGIN_TIFF_COMPRESSION
wxSpinCtrl * m_edit_width
void setROI(const vigra::Rect2D &val)
#define HUGIN_LDR_OUTPUT_FORMAT
UIntSet getActiveImages() const
get active images
Definition: Panorama.cpp:1585
std::vector< HuginBase::UIntSet > m_stacks
bool outputLDRExposureLayers
save blended exposure layers, do not perform fusion (no exposure adjustment)
unsigned int getWidth() const
const PanoramaOptions & getOptions() const
returns the options for this panorama
Definition: Panorama.h:481
bool outputLDRExposureRemapped
save remapped layers (no exposure adjustment)
bool outputLDRExposureLayersFused
save blended exposure layers which are then fused (no exposure adjustment)
void OnHDRFormatChanged(wxCommandEvent &e)
HDR format changed.
HuginBase::PanoramaOptions m_newOpt
#define HUGIN_ASS_PANO_DOWNSIZE_FACTOR
platform/compiler specific stuff.
PanoOutputDialog(wxWindow *parent, HuginBase::Panorama &pano, GuiLevel guiLevel)
Constructor, read from xrc ressource; restore last uses settings, size and position.
const SrcPanoImage & getImage(std::size_t nr) const
get a panorama image, counting starts with 0
Definition: Panorama.h:211
GuiLevel
Definition: GuiLevel.h:31
bool outputHDRStacks
save image stacks (HDR)
void OnLDRFormatChanged(wxCommandEvent &e)
LDR format changed.
void StoreFramePositionOnly(wxTopLevelWindow *frame, const wxString &basename)
Definition: wxutils.cpp:163
void OnWidthChanged(wxSpinEvent &e)
width changed
void OnOutputChanged(wxCommandEvent &e)
enabled Ok button and LDR/HDR format settings depeding on selected output settings ...
void setWidth(unsigned int w, bool keepView=true)
set panorama width keep the HFOV, if keepView=true
void RestoreFramePositionOnly(wxTopLevelWindow *frame, const wxString &basename)
Definition: wxutils.cpp:143