Hugin trunk 0.1
Loading...
Searching...
No Matches
RawImport.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/RawImport.h"
28#include "panoinc.h"
29#include "base_wx/platform.h"
31#include "base_wx/wxutils.h"
32#include "hugin/huginApp.h"
35#ifdef _WIN32
36// workaround for a conflict between exiv2 and wxWidgets/CMake built
37#define HAVE_PID_T 1
38#endif
39#include <exiv2/exiv2.hpp>
40#ifdef __WXMSW__
41#include <wx/msw/registry.h>
42#endif
43
46{
47public:
48 RawImport(wxString ConfigExePath) { m_exe = wxConfig::Get()->Read(ConfigExePath, ""); };
50 virtual wxString GetImageExtension() { return wxString("tif"); }
52 virtual bool ProcessAdditionalParameters(wxDialog* dlg) { return true; }
54 virtual bool SupportsOverwrite() { return true; }
57 bool CheckExe(wxDialog* dlg)
58 {
59 if (m_exe.IsEmpty())
60 {
62 };
64 if (exePath.IsAbsolute())
65 {
66 if (exePath.FileExists())
67 {
68 m_exe = exePath.GetFullPath();
69 return true;
70 }
71 else
72 {
73 hugin_utils::HuginMessageBox(wxString::Format(_("Executable \"%s\" not found.\nPlease specify a valid executable in preferences."), exePath.GetFullPath()),
74 _("Hugin"), wxOK | wxICON_INFORMATION, dlg);
75 return false;
76 };
77 };
79#ifdef __WXMSW__
80 pathlist.Add(huginApp::Get()->GetUtilsBinDir());
81#endif
82 pathlist.AddEnvList("PATH");
83 m_exe = pathlist.FindAbsoluteValidPath(exePath.GetFullPath());
84 if (m_exe.IsEmpty())
85 {
86 hugin_utils::HuginMessageBox(wxString::Format(_("Executable \"%s\" not found in PATH.\nPlease specify a valid executable in preferences."), exePath.GetFullPath()),
87 _("Hugin"), wxOK | wxICON_INFORMATION, dlg);
88 return false;
89 };
90 return true;
91 };
101 virtual void AddAdditionalPanoramaCommand(std::vector<PanoCommand::PanoCommand*>& cmds, HuginBase::Panorama* pano, const int oldImageCount, const int addedImageCount) {};
102protected:
104 virtual wxString GetDefaultExe() { return wxEmptyString; };
106};
107
110{
111public:
112 DCRawImport() : RawImport("/RawImportDialog/dcrawExe") {};
113 wxString GetImageExtension() override { return wxString("tiff"); }
114 bool ProcessAdditionalParameters(wxDialog* dlg) override
115 {
116 m_additionalParameters = XRCCTRL(*dlg, "raw_dcraw_parameter", wxTextCtrl)->GetValue().Trim(true).Trim(false);
117 return true;
118 };
120 {
122 wxString args(" -w -v -4 -T ");
123 if (!m_additionalParameters.IsEmpty())
124 {
125 args.Append(m_additionalParameters);
126 args.Append(" ");
127 };
129 queue->push_back(new HuginQueue::NormalCommand(m_exe, args, wxString::Format(_("Executing: %s %s"), m_exe, args)));
130 args.Empty();
131 args.Append("-overwrite_original -tagsfromfile ");
133 args.Append(" -all:all ");
134 args.Append(HuginQueue::wxEscapeFilename(imageFilename));
135 queue->push_back(new HuginQueue::OptionalCommand(HuginQueue::GetExternalProgram(wxConfig::Get(), huginApp::Get()->GetUtilsBinDir(), "exiftool"), args, wxString::Format(_("Updating EXIF data for %s"), imageFilename)));
136 return queue;
137 };
139 {
140 for (auto& s : output)
141 {
142 int pos = s.Find("multipliers");
143 if (pos >= 0)
144 {
145 m_wb = "-r " + s.Mid(pos + 12);
146 return true;
147 };
148 };
149 return false;
150 };
152 {
154 wxConfigBase* config = wxConfig::Get();
156 for (size_t i = 0; i < rawFilenames.size(); ++i)
157 {
158 wxString args(m_wb);
159 args.Append(" -v -4 -T ");
160 if (!m_additionalParameters.IsEmpty())
161 {
162 args.Append(m_additionalParameters);
163 args.Append(" ");
164 };
166 queue->push_back(new HuginQueue::NormalCommand(m_exe, args,wxString::Format(_("Executing: %s %s"), m_exe, args)));
167 args.Empty();
168 args.Append("-overwrite_original -tagsfromfile ");
170 args.Append(" -all:all ");
172 queue->push_back(new HuginQueue::OptionalCommand(HuginQueue::GetExternalProgram(config, binDir, "exiftool"), args, wxString::Format(_("Updating EXIF data for %s"), imageFilenames[i])));
173 }
174 return queue;
175 };
176 void AddAdditionalPanoramaCommand(std::vector<PanoCommand::PanoCommand*>& cmds, HuginBase::Panorama* pano, const int oldImageCount, const int addedImageCount) override
177 {
178 // set response to linear for newly added images
181 cmds.push_back(new PanoCommand::ChangeImageResponseTypeCmd(*pano, imgs, HuginBase::SrcPanoImage::RESPONSE_LINEAR));
182 };
183protected:
185 {
186#ifdef _WIN32
187 return "dcraw.exe";
188#else
189 return "dcraw";
190#endif
191 };
192private:
195};
196
199{
200public:
201 RTRawImport() : RawImport("/RawImportDialog/RTExe") {};
202 bool ProcessAdditionalParameters(wxDialog* dlg) override
203 {
204 m_processingProfile = XRCCTRL(*dlg, "raw_rt_processing_profile", wxTextCtrl)->GetValue().Trim(true).Trim(false);
205 if (!m_processingProfile.IsEmpty() && !wxFileName::FileExists(m_processingProfile))
206 {
207 hugin_utils::HuginMessageBox(wxString::Format(_("Processing profile \"%s\" not found.\nPlease specify a valid file or leave field empty for default settings."), m_processingProfile),
208 _("Hugin"), wxOK | wxICON_INFORMATION, dlg);
209 return false;
210 }
211 return true;
212 };
214 {
216 wxString args("-O " + HuginQueue::wxEscapeFilename(imageFilename));
217 if (m_processingProfile.IsEmpty())
218 {
219 args.Append(" -d");
220 }
221 else
222 {
224 };
225 // apply some special settings, especially disable all crop and rotation settings
226 args.Append(" -s -p " + HuginQueue::wxEscapeFilename(
227 wxString(std::string(hugin_utils::GetDataDir() + "hugin_rt.pp3").c_str(), HUGIN_CONV_FILENAME)));
228 args.Append(" -b16 -tz -Y -c ");
230 m_usedProcessingProfile = imageFilename + ".pp3";
231 queue->push_back(new HuginQueue::NormalCommand(m_exe, args, wxString::Format(_("Executing: %s %s"), m_exe, args)));
232 return queue;
233 };
235 {
236 // we need to change the WB setting in the processing profile so the white balance of the reference image
237 // is used and not the stored WB from each individual image
239 config.Write("/White Balance/Setting", "Custom");
240 config.Flush();
241 return true;
242 };
244 {
246 for (size_t i = 0; i < rawFilenames.size(); ++i)
247 {
250 args.Append(" -b16 -tz -Y -c ");
252 queue->push_back(new HuginQueue::NormalCommand(m_exe, args, wxString::Format(_("Executing: %s %s"), m_exe, args)));
253 }
254 return queue;
255 };
256protected:
258 {
259#ifdef __WXMSW__
260 // try reading installed version from registry
261 // works only with RT 5.5 and above
262 wxRegKey regkey(wxRegKey::HKLM, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\rawtherapee-cli.exe");
263 wxString prog;
264 if (regkey.HasValue(wxEmptyString) && regkey.QueryRawValue(wxEmptyString, prog))
265 {
266 if (wxFileName::FileExists(prog))
267 {
268 return prog;
269 };
270 }
271 else
272 {
273 // now check if installed for current user only
274 wxRegKey regkeyUser(wxRegKey::HKCU, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\rawtherapee-cli.exe");
275 wxString prog;
276 if (regkeyUser.HasValue(wxEmptyString) && regkeyUser.QueryRawValue(wxEmptyString, prog))
277 {
278 if (wxFileName::FileExists(prog))
279 {
280 return prog;
281 };
282 };
283 };
284 // nothing found in registry, return default name
285 return "rawtherapee-cli.exe";
286#elif defined __WXMAC__
287 return "/Applications/RawTherapee.app/Contents/MacOS/rawtherapee-cli";
288#else
289 return "rawtherapee-cli";
290#endif
291 };
292private:
295};
296
299{
300public:
301 DarkTableRawImport() : RawImport("/RawImportDialog/DarktableExe") {}
303 {
304 // destructor, clean up generated files;
305 if (!m_usedSettings.IsEmpty())
306 {
308 };
309 }
310 bool SupportsOverwrite() override { return false; }
312 {
314 wxString args(" --verbose ");
316 args.Append(" ");
317#ifdef __WXMSW__
318 // darktable has problems with Windows paths as output
319 // so change separator before
320 wxString file(imageFilename);
321 file.Replace("\\", "/", true);
322 args.Append(HuginQueue::wxEscapeFilename(file));
323#else
324 args.Append(HuginQueue::wxEscapeFilename(imageFilename));
325#endif
326 // switch --bpp does not work, so using this strange workaround
327 args.Append(" --core --conf plugins/imageio/format/tiff/bpp=16");
328 m_refImage = imageFilename;
329 queue->push_back(new HuginQueue::NormalCommand(m_exe, args, wxString::Format(_("Executing: %s %s"), m_exe, args)));
330 return queue;
331 };
333 {
334 // extract XMP package for converted reference image and store in temp
335#if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,27,99)
336 Exiv2::Image::UniquePtr image;
337#else
338 Exiv2::Image::AutoPtr image;
339#endif
340 try
341 {
342 image = Exiv2::ImageFactory::open(std::string(m_refImage.mb_str(HUGIN_CONV_FILENAME)));
343 }
344 catch (const Exiv2::Error& e)
345 {
346 std::cerr << "Exiv2: Error reading metadata (" << e.what() << ")" << std::endl;
347 return false;
348 }
349 try
350 {
351 image->readMetadata();
352 }
353 catch (const Exiv2::Error& e)
354 {
355 std::cerr << "Caught Exiv2 exception " << e.what() << std::endl;
356 return false;
357 };
358 m_usedSettings = wxFileName::CreateTempFileName("hugdt");
359#if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,27,99)
360 Exiv2::Image::UniquePtr image2;
361#else
362 Exiv2::Image::AutoPtr image2;
363#endif
364 try
365 {
366 image2 = Exiv2::ImageFactory::create(Exiv2::ImageType::xmp, std::string(m_usedSettings.mb_str(HUGIN_CONV_FILENAME)));
367 }
368 catch (const Exiv2::Error& e)
369 {
370 std::cerr << "Exiv2: Error creating temp xmp file (" << e.what() << ")" << std::endl;
371 return false;
372 }
373 image2->setXmpData(image->xmpData());
374 image2->writeMetadata();
375 return true;
376 };
378 {
380 for (size_t i = 0; i < rawFilenames.size(); ++i)
381 {
382 wxString args("--verbose ");
384 args.Append(" ");
386 args.Append(" ");
387#ifdef __WXMSW__
388 // darktable has problems with Windows paths as output
389 // so change separator before
391 file.Replace("\\", "/", true);
392 args.Append(HuginQueue::wxEscapeFilename(file));
393#else
395#endif
396 // switch --bpp does not work, so using this strange workaround
397 args.Append(" --core --conf plugins/imageio/format/tiff/bpp=16");
398 queue->push_back(new HuginQueue::NormalCommand(m_exe, args, wxString::Format(_("Executing: %s %s"), m_exe, args)));
399 }
400 return queue;
401 };
402protected:
404 {
405#ifdef __WXMSW__
406 // try reading installed version from registry
407 wxRegKey regkey(wxRegKey::HKLM, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\darktable-cli.exe");
408 wxString prog;
409 if (regkey.HasValue(wxEmptyString) && regkey.QueryRawValue(wxEmptyString, prog))
410 {
411 if (wxFileName::FileExists(prog))
412 {
413 return prog;
414 }
415 }
416 else
417 {
418 // now check if installed for current user only
419 wxRegKey regkeyUser(wxRegKey::HKCU, "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\darktable-cli.exe");
420 wxString prog;
421 if (regkeyUser.HasValue(wxEmptyString) && regkeyUser.QueryRawValue(wxEmptyString, prog))
422 {
423 if (wxFileName::FileExists(prog))
424 {
425 return prog;
426 };
427 };
428 };
429 // nothing found in registry, return default name
430 return "darktable-cli.exe";
431#elif defined __WXMAC__
432 return "/Applications/darktable.app/Contents/MacOS/darktable-cli";
433#else
434 return "darktable-cli";
435#endif
436 };
437private:
440};
441
442
444class RawImportProgress :public wxDialog
445{
446public:
447 RawImportProgress(wxWindow * parent, std::shared_ptr<RawImport>& converter, const wxArrayString& rawImages, const wxArrayString& images, const int refImg) :
450 {
451 DEBUG_ASSERT(m_rawImages.size() > 0);
452 DEBUG_ASSERT(m_rawImages.size() == m_images.size());
453 if (m_refImg < 0)
454 {
455 m_refImg = 0;
456 };
457 if (m_refImg >= m_rawImages.size())
458 {
459 m_refImg = 0;
460 };
462 m_progressPanel = new MyExecPanel(this);
463 topsizer->Add(m_progressPanel, 1, wxEXPAND | wxALL, 2);
464
467 bottomsizer->Add(m_progress, 1, wxEXPAND | wxALL, 10);
468 m_cancelButton = new wxButton(this, wxID_CANCEL, _("Cancel"));
469 bottomsizer->Add(m_cancelButton, 0, wxALL, 10);
471 topsizer->Add(bottomsizer, 0, wxEXPAND);
473 hugin_utils::RestoreFramePosition(this, "RawImportProgress");
476 };
478 {
479 hugin_utils::StoreFramePosition(this, "RawImportProgress");
480 }
481
482protected:
484 {
485 if (e.GetExitCode() == 0)
486 {
487 if (!m_converter->ProcessReferenceOutput(m_progressPanel->GetLogAsArrayString()))
488 {
489 hugin_utils::HuginMessageBox(_("Could not process the output of reference image.\nFurther processed images will not have a consistent white balance."),
490 _("Hugin"), wxOK | wxICON_INFORMATION, this);
491
492 };
494 m_progress->SetValue(hugin_utils::roundi(100.0 / m_images.size()));
496 rawFiles.RemoveAt(m_refImg);
497 if (rawFiles.IsEmpty())
498 {
499 // copy log to clipboard if preference is set
500 if (wxConfigBase::Get()->Read("CopyLogToClipboard", 0l) == 1l)
501 {
503 };
505 }
506 else
507 {
509 imgFiles.RemoveAt(m_refImg);
511 m_progressPanel->ExecQueue(m_converter->GetCmdQueueForImport(rawFiles, imgFiles));
512 };
513 }
514 else
515 {
516 m_isRunning = false;
517 m_cancelButton->SetLabel(_("Close"));
518 };
519 };
521 {
522 if (e.GetExitCode() == 0)
523 {
524 // copy log to clipboard if preference is set
525 if (wxConfigBase::Get()->Read("CopyLogToClipboard", 0l) == 1l)
526 {
528 };
530 }
531 else
532 {
533 m_isRunning = false;
534 m_cancelButton->SetLabel(_("Close"));
535 };
536 };
537 void OnProgress(wxCommandEvent& event)
538 {
539 if (event.GetInt() >= 0)
540 {
541 m_progress->SetValue(hugin_utils::roundi((1 + event.GetInt() / 100.0f * (m_images.size() - 1)) * 100.0f / m_images.size()));
542 };
543 };
544 void OnCancel(wxCommandEvent & event)
545 {
546 if (m_isRunning)
547 {
549 m_isRunning = false;
550 }
551 else
552 {
554 };
555 };
557 {
558 // start processing reference image
561 }
562
563private:
564 std::shared_ptr<RawImport> m_converter;
571};
572
573RawImportDialog::RawImportDialog(wxWindow *parent, HuginBase::Panorama* pano, std::vector<std::string>& rawFiles)
574{
575 // load our children. some children might need special
576 // initialization. this will be done later.
577 wxXmlResource::Get()->LoadDialog(this, parent, "import_raw_dialog");
578
579 hugin_utils::RestoreFramePosition(this, "RawImportDialog");
580 wxConfigBase* config = wxConfig::Get();
581 // dcraw
582 wxString s = config->Read("/RawImportDialog/dcrawParameter", "");
583 XRCCTRL(*this, "raw_dcraw_parameter", wxTextCtrl)->SetValue(s);
584
585 // RT processing profile
586 s = config->Read("/RawImportDialog/RTProcessingProfile", "");
587 wxTextCtrl* ctrl = XRCCTRL(*this, "raw_rt_processing_profile", wxTextCtrl);
588 ctrl->SetValue(s);
589 ctrl->AutoCompleteFileNames();
590 // read last used converter
591 const long converter = config->Read("/RawImportDialog/Converter", 0l);
592 switch (converter)
593 {
594 default:
595 case 0:
596 XRCCTRL(*this, "raw_rb_dcraw", wxRadioButton)->SetValue(true);
597 break;
598 case 1:
599 XRCCTRL(*this, "raw_rb_rt", wxRadioButton)->SetValue(true);
600 break;
601 case 2:
602 XRCCTRL(*this, "raw_rb_darktable", wxRadioButton)->SetValue(true);
603 break;
604 };
605 wxCommandEvent dummy;
607
608 m_pano=pano;
609 for (auto& file : rawFiles)
610 {
611 m_rawImages.Add(wxString(file.c_str(), HUGIN_CONV_FILENAME));
612 };
613 Bind(wxEVT_BUTTON, &RawImportDialog::OnSelectRTProcessingProfile, this, XRCID("raw_rt_processing_profile_select"));
616 Bind(wxEVT_RADIOBUTTON, &RawImportDialog::OnRawConverterSelected, this, XRCID("raw_rb_darktable"));
618};
619
624
629
631{
634 std::string camera;
635 for (auto& file : m_rawImages)
636 {
637 // check that all images are from the same camera
638#if defined EXIV2_VERSION && EXIV2_TEST_VERSION(0,27,99)
639#if defined EXV_ENABLE_BMFF && !EXIV2_TEST_VERSION(0,28,3)
640 // enable BMFF option if available, necessary for Canon CR3 files
641 // only needed for exiv2 version <0.28.3
642 // in higher version this function is deprecated
643 Exiv2::enableBMFF();
644#endif
645 Exiv2::Image::UniquePtr image;
646#else
647 Exiv2::Image::AutoPtr image;
648#endif
649 try
650 {
651 image = Exiv2::ImageFactory::open(std::string(file.mb_str(HUGIN_CONV_FILENAME)));
652 }
653 catch (const Exiv2::Error& e)
654 {
655 std::cerr << "Exiv2: Error reading metadata (" << e.what() << ")" << std::endl;
656 errorReadingFile.push_back(file);
657 continue;
658 }
659
660 try
661 {
662 image->readMetadata();
663 }
664 catch (const Exiv2::Error& e)
665 {
666 std::cerr << "Caught Exiv2 exception '" << e.what() << "' for file " << file << std::endl;
667 errorReadingFile.push_back(file);
668 };
669 Exiv2::ExifData &exifData = image->exifData();
670 if (exifData.empty())
671 {
672 errorReadingFile.push_back(file);
673 continue;
674 };
675 std::string cam;
676 auto make = Exiv2::make(exifData);
677 if (make != exifData.end() && make->count())
678 {
679 cam = make->toString();
680 };
681 auto model = Exiv2::model(exifData);
682 if (model != exifData.end() && model->count())
683 {
684 cam += "|" + model->toString();
685 };
686 if (camera.empty())
687 {
688 camera = cam;
689 }
690 else
691 {
692 if (cam != camera)
693 {
694 differentCam.push_back(file);
695 continue;
696 };
697 };
698 };
699 if (!errorReadingFile.IsEmpty())
700 {
701 wxDialog dlg;
702 wxXmlResource::Get()->LoadDialog(&dlg, this, "dlg_warning_filename");
703 dlg.SetLabel(_("Warning: Read error"));
704 XRCCTRL(dlg, "dlg_warning_text", wxStaticText)->SetLabel(_("The following files will be skipped because the metadata of these files could not read."));
705 XRCCTRL(dlg, "dlg_warning_list", wxListBox)->Append(errorReadingFile);
706 dlg.Fit();
707 dlg.CenterOnScreen();
708 dlg.ShowModal();
709 for (auto& file : errorReadingFile)
710 {
711 m_rawImages.Remove(file);
712 };
713 if (m_rawImages.IsEmpty())
714 {
715 return false;
716 };
717 };
718 if (differentCam.IsEmpty())
719 {
721 return true;
722 }
723 else
724 {
725 wxDialog dlg;
726 wxXmlResource::Get()->LoadDialog(&dlg, this, "dlg_warning_filename");
727 dlg.SetLabel(_("Warning: raw images from different cameras"));
728 XRCCTRL(dlg, "dlg_warning_text", wxStaticText)->SetLabel(_("The following images were shot with different camera than the other one.\nThe raw import works only for images from the same cam."));
729 XRCCTRL(dlg, "dlg_warning_list", wxListBox)->Append(differentCam);
730 dlg.Fit();
731 dlg.CenterOnScreen();
732 dlg.ShowModal();
733 return false;
734 };
735};
736
737void RawImportDialog::OnOk(wxCommandEvent & e)
738{
739 std::shared_ptr<RawImport> rawConverter;
740 long rawConverterInt;
741 if (XRCCTRL(*this, "raw_rb_dcraw", wxRadioButton)->GetValue())
742 {
743 rawConverter = std::make_shared<DCRawImport>();
744 rawConverterInt = 0;
745 }
746 else
747 {
748 if (XRCCTRL(*this, "raw_rb_rt", wxRadioButton)->GetValue())
749 {
750 rawConverter = std::make_shared<RTRawImport>();
751 rawConverterInt = 1;
752 }
753 else
754 {
755 rawConverter = std::make_shared<DarkTableRawImport>();
756 rawConverterInt = 2;
757 };
758 };
759 // check if given program is available
760 if (!rawConverter->CheckExe(this))
761 {
762 return;
763 }
764 // check additional parameters
765 if (!rawConverter->ProcessAdditionalParameters(this))
766 {
767 return;
768 };
769 {
770 // check if image files already exists
771 m_images.clear();
773 for (auto& img : m_rawImages)
774 {
775 wxFileName newImage(img);
776 newImage.SetExt(rawConverter->GetImageExtension());
777 m_images.push_back(newImage.GetFullPath());
778 if (newImage.FileExists())
779 {
780 existingImages.push_back(newImage.GetFullPath());
781 };
782 };
783 if (!existingImages.IsEmpty())
784 {
785 wxDialog dlg;
786 wxXmlResource::Get()->LoadDialog(&dlg, this, "dlg_warning_overwrite");
787 XRCCTRL(dlg, "dlg_overwrite_list", wxListBox)->Append(existingImages);
788 dlg.Fit();
789 dlg.CenterOnScreen();
790 if (dlg.ShowModal() != wxID_OK)
791 {
792 return;
793 };
794 };
795 if (!rawConverter->SupportsOverwrite())
796 {
797 // raw converter does not support overwritting
798 // so delete the file explicit before
799 for (auto& img : existingImages)
800 {
801 wxRemoveFile(img);
802 };
803 };
804 };
805 RawImportProgress dlg(this, rawConverter, m_rawImages, m_images, XRCCTRL(*this, "raw_choice_wb", wxChoice)->GetSelection());
806 if (dlg.ShowModal() == wxID_OK)
807 {
808 // save settings for next call
809 wxConfigBase* config = wxConfig::Get();
810 config->Write("/RawImportDialog/Converter", rawConverterInt);
811 config->Write("/RawImportDialog/dcrawParameter", XRCCTRL(*this, "raw_dcraw_parameter", wxTextCtrl)->GetValue().Trim(true).Trim(false));
812 config->Write("/RawImportDialog/RTProcessingProfile", XRCCTRL(*this, "raw_rt_processing_profile", wxTextCtrl)->GetValue());
813 config->Flush();
814 // check if all files were generated
815 std::vector<std::string> files;
816 bool missingFiles = false;
817 for (auto& img:m_images)
818 {
819 if (wxFileName::FileExists(img))
820 {
821 files.push_back(std::string(img.mb_str(HUGIN_CONV_FILENAME)));
822 }
823 else
824 {
825 missingFiles = true;
826 };
827 };
828 if (missingFiles || files.empty())
829 {
830 hugin_utils::HuginMessageBox(_("At least one raw images was not successfully converted.\nThis image(s) will be skipped"),
831 _("Hugin"), wxOK | wxICON_INFORMATION, this);
832 };
833 if (files.empty())
834 {
835 return;
836 };
837 // now build PanoCommand and store it
838 std::vector<PanoCommand::PanoCommand*> cmds;
839 cmds.push_back(new PanoCommand::wxAddImagesCmd(*m_pano, files));
840 rawConverter->AddAdditionalPanoramaCommand(cmds, m_pano, m_pano->getNrOfImages(), files.size());
842 m_cmd->setName("import raw images");
843 // close dialog
845 return;
846 };
848}
849
851{
852 wxTextCtrl* input = XRCCTRL(*this, "raw_rt_processing_profile", wxTextCtrl);
853 wxFileDialog dlg(this, _("Select default RT processing profile"), "", input->GetValue(), _("RT processing profile|*.pp3"), wxFD_OPEN, wxDefaultPosition);
854 if (dlg.ShowModal() == wxID_OK)
855 {
856 input->SetValue(dlg.GetPath());
857 }
858}
859
861{
862 enum Converter {
863 DCRAW,
866 } rawConverter;
867 if (XRCCTRL(*this, "raw_rb_dcraw", wxRadioButton)->GetValue())
868 {
869 rawConverter = Converter::DCRAW;
870 }
871 else
872 {
873 if (XRCCTRL(*this, "raw_rb_rt", wxRadioButton)->GetValue())
874 {
875 rawConverter = Converter::RAWTHERAPEE;
876 }
877 else
878 {
879 rawConverter = Converter::DARKTABLE;
880 };
881 };
882 XRCCTRL(*this, "raw_dcraw_text", wxStaticText)->Enable(rawConverter == Converter::DCRAW);
883 XRCCTRL(*this, "raw_dcraw_parameter", wxTextCtrl)->Enable(rawConverter == Converter::DCRAW);
884 XRCCTRL(*this, "raw_rt_text", wxStaticText)->Enable(rawConverter == Converter::RAWTHERAPEE);
885 XRCCTRL(*this, "raw_rt_processing_profile", wxTextCtrl)->Enable(rawConverter == Converter::RAWTHERAPEE);
886 XRCCTRL(*this, "raw_rt_processing_profile_select", wxButton)->Enable(rawConverter == Converter::RAWTHERAPEE);
887};
888
890{
891 wxChoice* choice = XRCCTRL(*this, "raw_choice_wb", wxChoice);
892 for (int i=0; i<m_rawImages.size();++i)
893 {
894 const wxFileName file(m_rawImages[i]);
895 choice->Append(file.GetFullName());
896 };
897 choice->SetSelection(0);
898};
899
Definition of dialog and functions to import RAW images to project file.
special class for raw import with dcraw
HuginQueue::CommandQueue * GetCmdQueueForImport(const wxArrayString &rawFilenames, const wxArrayString &imageFilenames) override
return commands for processing of all other images with white balance read by RawImport::ProcessRefer...
void AddAdditionalPanoramaCommand(std::vector< PanoCommand::PanoCommand * > &cmds, HuginBase::Panorama *pano, const int oldImageCount, const int addedImageCount) override
add additional PanoCommand::PanoCommand to vector if needed hint: we need to pass old and new image n...
wxString GetImageExtension() override
image extension of converted files
HuginQueue::CommandQueue * GetCmdQueueForReference(const wxString &rawFilename, const wxString &imageFilename) override
return command for processing of reference image
wxString m_additionalParameters
bool ProcessReferenceOutput(const wxArrayString &output) override
read output of processing of reference image to read in white balance of reference image
wxString m_wb
bool ProcessAdditionalParameters(wxDialog *dlg) override
reads additional parameters from dialog into class
wxString GetDefaultExe() override
returns the default name of the executable
special class for Darktable raw import
HuginQueue::CommandQueue * GetCmdQueueForImport(const wxArrayString &rawFilenames, const wxArrayString &imageFilenames) override
return commands for processing of all other images with white balance read by RawImport::ProcessRefer...
HuginQueue::CommandQueue * GetCmdQueueForReference(const wxString &rawFilename, const wxString &imageFilename) override
return command for processing of reference image
bool ProcessReferenceOutput(const wxArrayString &output) override
read output of processing of reference image to read in white balance of reference image
wxString GetDefaultExe() override
returns the default name of the executable
wxString m_usedSettings
bool SupportsOverwrite() override
return true if program supports overwritting output, otherwise false
@ RESPONSE_LINEAR
linear response
Model for a panorama.
Definition Panorama.h:153
std::size_t getNrOfImages() const
number of images.
Definition Panorama.h:205
normal command for queue, processing is stopped if an error occurred in program
Definition Executor.h:38
optional command for queue, processing of queue is always continued, also if an error occurred
Definition Executor.h:54
void CopyLogToClipboard()
copy the content of the log window into the clipboard
int ExecQueue(HuginQueue::CommandQueue *queue)
wxArrayString GetLogAsArrayString()
returns the output
PanoCommand to combine other PanoCommands.
Definition PanoCommand.h:40
Base class for all panorama commands.
Definition Command.h:39
virtual void setName(const std::string &newName)
sets the name for the command
Definition Command.cpp:88
add image(s) to a panorama
class for RawTherapee raw import
bool ProcessAdditionalParameters(wxDialog *dlg) override
reads additional parameters from dialog into class
wxString GetDefaultExe() override
returns the default name of the executable
wxString m_processingProfile
bool ProcessReferenceOutput(const wxArrayString &output) override
read output of processing of reference image to read in white balance of reference image
HuginQueue::CommandQueue * GetCmdQueueForReference(const wxString &rawFilename, const wxString &imageFilename) override
return command for processing of reference image
wxString m_usedProcessingProfile
HuginQueue::CommandQueue * GetCmdQueueForImport(const wxArrayString &rawFilenames, const wxArrayString &imageFilenames) override
return commands for processing of all other images with white balance read by RawImport::ProcessRefer...
bool CheckRawFiles()
return true, if all raw files are from the same camera
void OnSelectRTProcessingProfile(wxCommandEvent &e)
PanoCommand::PanoCommand * m_cmd
Definition RawImport.h:58
PanoCommand::PanoCommand * GetPanoCommand()
return PanoCommand for adding converted raw files to Panorama
void OnRawConverterSelected(wxCommandEvent &e)
void OnOk(wxCommandEvent &e)
called when dialog is finished and does the conversion
wxArrayString m_images
Definition RawImport.h:57
RawImportDialog(wxWindow *parent, HuginBase::Panorama *pano, std::vector< std::string > &rawFiles)
Constructor, read from xrc ressource; restore last uses settings and position.
~RawImportDialog()
destructor, saves position
void FillImageChoice()
fill list with image names
HuginBase::Panorama * m_pano
Definition RawImport.h:55
wxArrayString m_rawImages
Definition RawImport.h:56
dialog class for showing progress of raw import
void OnProcessTerminate(wxProcessEvent &e)
wxButton * m_cancelButton
virtual ~RawImportProgress()
MyExecPanel * m_progressPanel
RawImportProgress(wxWindow *parent, std::shared_ptr< RawImport > &converter, const wxArrayString &rawImages, const wxArrayString &images, const int refImg)
wxArrayString m_rawImages
std::shared_ptr< RawImport > m_converter
void OnInitDialog(wxInitDialogEvent &e)
void OnCancel(wxCommandEvent &event)
wxArrayString m_images
void OnProcessReferenceTerminate(wxProcessEvent &e)
wxGauge * m_progress
void OnProgress(wxCommandEvent &event)
base class for implementation of Raw import functions
Definition RawImport.cpp:46
RawImport(wxString ConfigExePath)
Definition RawImport.cpp:48
bool CheckExe(wxDialog *dlg)
checks if valid executable was given in dialog either absolute path or when relative path is given ch...
Definition RawImport.cpp:57
virtual bool ProcessAdditionalParameters(wxDialog *dlg)
reads additional parameters from dialog into class
Definition RawImport.cpp:52
virtual void AddAdditionalPanoramaCommand(std::vector< PanoCommand::PanoCommand * > &cmds, HuginBase::Panorama *pano, const int oldImageCount, const int addedImageCount)
add additional PanoCommand::PanoCommand to vector if needed hint: we need to pass old and new image n...
virtual HuginQueue::CommandQueue * GetCmdQueueForImport(const wxArrayString &rawFilenames, const wxArrayString &imageFilenames)=0
return commands for processing of all other images with white balance read by RawImport::ProcessRefer...
virtual bool ProcessReferenceOutput(const wxArrayString &output)=0
read output of processing of reference image to read in white balance of reference image
virtual wxString GetImageExtension()
image extension of converted files
Definition RawImport.cpp:50
virtual wxString GetDefaultExe()
returns the default name of the executable
wxString m_exe
virtual HuginQueue::CommandQueue * GetCmdQueueForReference(const wxString &rawFilename, const wxString &imageFilename)=0
return command for processing of reference image
virtual bool SupportsOverwrite()
return true if program supports overwritting output, otherwise false
Definition RawImport.cpp:54
const wxString & GetUtilsBinDir()
Definition huginApp.h:109
static huginApp * Get()
hack.. kind of a pseudo singleton...
Definition huginApp.cpp:651
implementation of huginApp Class
#define HUGIN_CONV_FILENAME
Definition platform.h:40
#define DEBUG_ASSERT(cond)
Definition utils.h:80
std::set< unsigned int > UIntSet
str wxEscapeFilename(const str &arg)
special escaping routine for CommandQueues
Definition Executor.h:79
wxString GetExternalProgram(wxConfigBase *config, const wxString &bindir, const wxString &name)
return path and name of external program, which can be overwritten by the user
Definition Executor.cpp:148
std::vector< NormalCommand * > CommandQueue
Definition Executor.h:61
int HuginMessageBox(const wxString &message, const wxString &caption, int style, wxWindow *parent)
Definition wxutils.cpp:176
std::string GetDataDir()
returns the full path to the data directory
Definition utils.cpp:441
int roundi(T x)
Definition hugin_math.h:73
void StoreFramePosition(wxTopLevelWindow *frame, const wxString &basename, const bool ignoreMaximize)
Definition wxutils.cpp:106
void RestoreFramePosition(wxTopLevelWindow *frame, const wxString &basename, const bool ignoreMaximize)
Definition wxutils.cpp:67
include file for the hugin project
void fill_set(_Container &c, typename _Container::key_type begin, typename _Container::key_type end)
Definition stl_utils.h:81
std::vector< deghosting::BImagePtr > threshold(const std::vector< deghosting::FImagePtr > &inputImages, const double threshold, const uint16_t flags)
Threshold function used for creating alpha masks for images.
Definition threshold.h:41
wxwindows specific panorama commands