Index: src/graphics/image.cpp =================================================================== --- src/graphics/image.cpp (revision 12) +++ src/graphics/image.cpp (working copy) @@ -122,8 +122,8 @@ void Image::scale(float factor) { - for(int x=0; xAppend(Minimal_Open, _T("O&pen\tAlt-O"), _T("Open an Indigo Image")); + menuFile->Append(Minimal_Merge, _T("&Merge\tAlt-M"), _T("Merge an Indigo Image")); menuFile->Append(Minimal_SaveAsPNG, _T("S&ave As PNG\tAlt-S"), _T("Save as PNG")); - menuFile->Append(Minimal_SaveAsJPEG, _T("Save As JPEG"), _T("Save as JPEG")); + menuFile->Append(Minimal_SaveAsJPEG, _T("Save As JPEG\tAlt-J"), _T("Save as JPEG")); + menuFile->Append(Minimal_SaveAsIGI, _T("Save As IGI\tAlt-I"), _T("Save as IGI")); menuFile->Append(Minimal_Quit, _T("E&xit\tAlt-X"), _T("Quit this program")); // now append the freshly created menu to the menu bar... @@ -136,12 +150,12 @@ #if wxUSE_STATUSBAR // create a status bar just for fun (by default with 1 pane only) CreateStatusBar(2); - //SetStatusText(_T("Welcome to wxWindows!")); + SetStatusText(_T("Ready...")); #endif // wxUSE_STATUSBAR - const int BORDER_WIDTH = 4; + const int BORDER_WIDTH = 2; const wxSize MIN_SLIDER_SIZE(300, 30); const wxSize MIN_SLIDER_TEXT_SIZE(60, 30); @@ -167,154 +181,124 @@ //------------------------------------------------------------------------ //add controls //------------------------------------------------------------------------ - //wxBoxSizer* top_box_sizer = new wxBoxSizer(wxHORIZONTAL); - //wxBoxSizer* middle_box_sizer = new wxBoxSizer(wxHORIZONTAL); - //wxBoxSizer* bottom_box_sizer = new wxBoxSizer(wxHORIZONTAL); - + + //this is the main right hand side column of controls wxBoxSizer* vert_box_sizer = new wxBoxSizer(wxVERTICAL); + main_sizer->Add(vert_box_sizer, 0); - //wxGridSizer* grid_sizer = new wxGridSizer(2, 2); - //main_sizer->Add(grid_sizer); - //main_sizer->Add(top_box_sizer); - //main_sizer->Add(middle_box_sizer); - //main_sizer->Add(bottom_box_sizer); - - main_sizer->Add(vert_box_sizer); - - //top row buttons - { - wxBoxSizer* sizer1 = new wxBoxSizer(wxHORIZONTAL); - sizer1->Add(new wxButton(main_panel, UPDATE_BUTTON_ID, "Update Image"), 0, wxALL, BORDER_WIDTH); - sizer1->Add(autoupdate_checkbox = new wxCheckBox(main_panel, AUTOUPDATE_CHECKBOX_ID, "Auto"), 0, wxALL, BORDER_WIDTH); - sizer1->Add(new wxStaticText(main_panel, wxID_ANY, "Zoom Level: ")); - sizer1->Add(new wxButton(main_panel, ZOOM_100_BUTTON_ID, "100%")); - sizer1->Add(new wxButton(main_panel, ZOOM_50_BUTTON_ID, "50%")); - sizer1->Add(new wxButton(main_panel, ZOOM_25_BUTTON_ID, "25%")); - sizer1->Add(new wxButton(main_panel, ZOOM_12_BUTTON_ID, "12.5%")); - vert_box_sizer->Add(sizer1, 0, wxALL, BORDER_WIDTH); - } - //------------------------------------------------------------------------ - //Add whitepoint controls + //top row buttons - update, auto, zoom //------------------------------------------------------------------------ { - wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("White Balance")); - wxBoxSizer* sizer = new wxStaticBoxSizer(box, wxVERTICAL); - - vert_box_sizer->Add(sizer, - 1, // proportion - wxEXPAND | // make horizontally stretchable - wxALL, // and make border all around - BORDER_WIDTH); // set border width to 10 - - whitepoint_x_slider = new TechSlider("Whitepoint x", main_panel, sizer, 0.25f, 0.46f, 0.333f); - whitepoint_y_slider = new TechSlider("Whitepoint y", main_panel, sizer, 0.25f, 0.46f, 0.333f); - - - const wxString choices[] = {"E", "D50", "D55", "D65", "D75", "A", "B", "C", "9300", "F2", "F7", "F11"}; - - wxBoxSizer* choice_sizer = new wxBoxSizer(wxHORIZONTAL); - - wxStaticText* choice_label = new wxStaticText(main_panel, wxID_ANY, "Preset"); - choice_label->SetMinSize(MIN_SLIDER_TEXT_SIZE); + //the whole shebang + wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Display")); + wxBoxSizer* sizer = new wxStaticBoxSizer(box,wxHORIZONTAL); - wxChoice* listbox = new wxChoice(main_panel, WHITEPOINT_PRESET_CHOICE_ID, wxDefaultPosition, wxDefaultSize, 12, choices, - 0, wxDefaultValidator, "Preset"); + //auto + update grouped on top of each other + wxBoxSizer* sizer2 = new wxBoxSizer(wxVERTICAL); + sizer2->Add(autoupdate_checkbox = new wxCheckBox(main_panel, AUTOUPDATE_CHECKBOX_ID, "Auto"), 0, wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + sizer2->Add(new wxButton(main_panel, UPDATE_BUTTON_ID, "Update Image"), 0, wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + //add auto+update group to sizer + sizer->Add(sizer2, 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + + //group for label + button group + wxBoxSizer* sizer3 = new wxBoxSizer(wxVERTICAL); + sizer3->Add(new wxStaticText(main_panel, wxID_ANY, "Zoom Level: "),0,wxALIGN_CENTER_VERTICAL); + //button group + wxBoxSizer* sizer4 = new wxBoxSizer(wxHORIZONTAL); + sizer4->Add(new wxButton(main_panel, ZOOM_100_BUTTON_ID, "100%"), 0, wxALIGN_CENTER_VERTICAL); + sizer4->Add(new wxButton(main_panel, ZOOM_50_BUTTON_ID, "50%"), 0, wxALIGN_CENTER_VERTICAL); + sizer4->Add(new wxButton(main_panel, ZOOM_25_BUTTON_ID, "25%"), 0, wxALIGN_CENTER_VERTICAL); + sizer4->Add(new wxButton(main_panel, ZOOM_12_BUTTON_ID, "12.5%"), 0, wxALIGN_CENTER_VERTICAL); + //add buttons to label + button group + sizer3->Add(sizer4, 0, wxALL, BORDER_WIDTH); - choice_sizer->Add(choice_label, 0, wxALL, BORDER_WIDTH); - choice_sizer->Add(listbox, 0, wxALL, BORDER_WIDTH); - sizer->Add(choice_sizer); + //add label+button group to sizer + sizer->Add(sizer3, 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); - sizer->Add(new wxButton(main_panel, WHITEBALANCE_RESET_BUTTON_ID, "Reset"), 0, wxALL, BORDER_WIDTH); + //add sizer to main sizer + vert_box_sizer->Add(sizer, 0, wxEXPAND | wxALL, BORDER_WIDTH); } - + //------------------------------------------------------------------------ - //Add aberration controls + //2nd row buttons - merge IGI, save JPG, save PNG, save IGI //------------------------------------------------------------------------ { - wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Chromatic Aberration")); - wxBoxSizer* sizer = new wxStaticBoxSizer(box, wxVERTICAL); - - vert_box_sizer->Add(sizer, - 1, // - wxEXPAND | // make horizontally stretchable - wxALL, // and make border all around - BORDER_WIDTH); // set border width to 10 - - sizer->Add(aberration_checkbox = new wxCheckBox(main_panel, ABERRATION_CHECKBOX_ID, "Enabled"), 0, wxALL, BORDER_WIDTH); - - aberration_slider = new TechSlider("Amount", main_panel, sizer, 0.f, 0.1f, 0.01f); - - sizer->Add(new wxButton(main_panel, ABERRATION_RESET_BUTTON_ID, "Reset"), 0, wxALL, BORDER_WIDTH); + wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Input/Output")); + wxBoxSizer* sizer = new wxStaticBoxSizer(box,wxHORIZONTAL); + sizer->Add(new wxButton(main_panel, MERGE_BUTTON_ID, "Merge an IGI"), 0, wxALIGN_TOP, BORDER_WIDTH); + //add sizer group for jpeg quality + save + wxBoxSizer* sizer2 = new wxBoxSizer(wxVERTICAL); + sizer2->Add(new wxButton(main_panel, JPG_SAVE_BUTTON_ID, "Save JPG"), 0, wxEXPAND | wxALIGN_TOP, BORDER_WIDTH); + jpg_quality_ctrl = new wxSpinCtrl(main_panel, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, + wxSP_ARROW_KEYS, 1, 100, DEFAULT_JPG_QUALITY, "JPG Quality"); + sizer2->Add(jpg_quality_ctrl, 0, wxALL, BORDER_WIDTH); + sizer->Add(sizer2, 0, wxALL | wxALIGN_TOP, 0); //no border here + //add button for save png + sizer->Add(new wxButton(main_panel, PNG_SAVE_BUTTON_ID, "Save PNG"), 0, wxALIGN_TOP, BORDER_WIDTH); + //add button for save IGI + sizer->Add(new wxButton(main_panel, IGI_SAVE_BUTTON_ID, "Save IGI"), 0, wxALIGN_TOP, BORDER_WIDTH); + vert_box_sizer->Add(sizer, 0, wxEXPAND | wxALL, BORDER_WIDTH); } //------------------------------------------------------------------------ - //Add glare controls + //Add whitepoint controls //------------------------------------------------------------------------ { - wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Camera Glare")); + wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("White Balance")); wxBoxSizer* sizer = new wxStaticBoxSizer(box, wxVERTICAL); - vert_box_sizer->Add(sizer, - 0, // make not vertically stretchable - wxEXPAND | // make horizontally stretchable - wxALL, // and make border all around - BORDER_WIDTH); // set border width to 10 + const wxString choices[] = {"E", "D50", "D55", "D65", "D75", "A", "B", "C", "9300", "F2", "F7", "F11"}; - sizer->Add(glare_checkbox = new wxCheckBox(main_panel, GLARE_CHECKBOX_ID, "Enabled"), 0, wxALL, BORDER_WIDTH); + wxBoxSizer* choice_sizer = new wxBoxSizer(wxHORIZONTAL); - glare_amount_slider = new TechSlider("Weight", main_panel, sizer, 0.f, 0.3f, 0.03f); - glare_radius_slider = new TechSlider("Radius", main_panel, sizer, 0.f, 0.2f, 0.03f); + wxStaticText* choice_label = new wxStaticText(main_panel, wxID_ANY, "Preset"); + //choice_label->SetMinSize(MIN_SLIDER_TEXT_SIZE); - glare_num_blades_ctrl = new wxSpinCtrl(main_panel, GLARE_NUM_BLADES_CTRL_ID, "3", wxDefaultPosition, wxDefaultSize, - wxSP_ARROW_KEYS, 3, 100, DEFAULT_NUM_BLADES, "name"); - sizer->Add(glare_num_blades_ctrl, 0, wxALL, BORDER_WIDTH); + wxChoice* listbox = new wxChoice(main_panel, WHITEPOINT_PRESET_CHOICE_ID, wxDefaultPosition, wxDefaultSize, 12, choices, + 0, wxDefaultValidator, "Preset"); - sizer->Add(new wxButton(main_panel, GLARE_RESET_BUTTON_ID, "Reset"), 0, wxALL, BORDER_WIDTH); - } + choice_sizer->Add(choice_label, 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + choice_sizer->Add(listbox, 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + choice_sizer->Add(new wxButton(main_panel, WHITEBALANCE_RESET_BUTTON_ID, "Reset"), 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); - //------------------------------------------------------------------------ - //Add bloom controls - //------------------------------------------------------------------------ - { - wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Camera Bloom")); - wxBoxSizer* sizer = new wxStaticBoxSizer(box, wxVERTICAL); + sizer->Add(choice_sizer); + whitepoint_x_slider = new TechSlider("Whitepoint x", main_panel, sizer, 0.25f, 0.46f, 0.333f); + whitepoint_y_slider = new TechSlider("Whitepoint y", main_panel, sizer, 0.25f, 0.46f, 0.333f); + vert_box_sizer->Add(sizer, - 0, // make not vertically stretchable - wxEXPAND | // make horizontally stretchable + 0, // proportion + //wxEXPAND | // make horizontally stretchable wxALL, // and make border all around BORDER_WIDTH); // set border width to 10 - sizer->Add(bloom_checkbox = new wxCheckBox(main_panel, BLOOM_CHECKBOX_ID, "Enabled"), 0, wxALL, BORDER_WIDTH); - - bloom_weight_slider = new TechSlider("Weight", main_panel, sizer, 0.f, 0.8f, 0.1f); - bloom_radius_slider = new TechSlider("Radius", main_panel, sizer, 0.f, 0.2f, 0.01f); - - sizer->Add(new wxButton(main_panel, BLOOM_RESET_BUTTON_ID, "Reset"), 0, wxALL, BORDER_WIDTH); } - + //------------------------------------------------------------------------ //Add reinhard controls //------------------------------------------------------------------------ + { wxStaticBox* reinhardbox = new wxStaticBox(main_panel, wxID_ANY, _T("Reinhard Tone Mapping")); //sizer for laying out the sliders wxBoxSizer* reinhardbox_sizer = new wxStaticBoxSizer(reinhardbox, wxVERTICAL); - vert_box_sizer->Add(reinhardbox_sizer, + + reinhardbox_sizer->Add(new wxButton(main_panel, REINHARD_RESET_BUTTON_ID, "Reset"), 0, wxALL, BORDER_WIDTH); + + pre_scale_slider = new TechSlider("Pre-scale", main_panel, reinhardbox_sizer, 0.f, 10.f, 1.f); + post_scale_slider = new TechSlider("Post-scale", main_panel, reinhardbox_sizer, 0.f, 10.f, 1.f); + burn_slider = new TechSlider("Burn", main_panel, reinhardbox_sizer, 0.f, 10.f, 6.f); + + vert_box_sizer->Add(reinhardbox_sizer, 0, // make not vertically stretchable - wxEXPAND | // make horizontally stretchable + //wxEXPAND | // make horizontally stretchable wxALL, // and make border all around BORDER_WIDTH); // set border width to 10 + } - pre_scale_slider = new TechSlider("Pre-scale", main_panel, reinhardbox_sizer, 0.f, 10.f, 1.f); - post_scale_slider = new TechSlider("Post-scale", main_panel, reinhardbox_sizer, 0.f, 10.f, 1.f); - burn_slider = new TechSlider("Burn", main_panel, reinhardbox_sizer, 0.f, 10.f, 6.f); - - reinhardbox_sizer->Add(new wxButton(main_panel, REINHARD_RESET_BUTTON_ID, "Reset"), 0, wxALL, BORDER_WIDTH); - /* //------------------------------------------------------------------------ //linear @@ -331,7 +315,7 @@ //main_panel->SetSizer(top_box_sizer); // use the sizer for layout //linearboxsizer->Add(new wxStaticText(main_panel, wxID_ANY, "Scale")); - + linear_scale_slider = new TechSlider("Scale", main_panel, linearboxsizer, 0.f, 200.f, 2000.f); //wxSlider(); //linear_scale_slider->Create(main_panel, wxID_ANY, // 200, //value @@ -343,6 +327,86 @@ //------------------------------------------------------------------------ + //Add bloom controls + //------------------------------------------------------------------------ + { + wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Camera Bloom")); + wxBoxSizer* sizer = new wxStaticBoxSizer(box, wxVERTICAL); + + wxBoxSizer* sizer2 = new wxBoxSizer(wxHORIZONTAL); + + sizer2->Add(bloom_checkbox = new wxCheckBox(main_panel, BLOOM_CHECKBOX_ID, "Enabled"), 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + sizer2->Add(new wxButton(main_panel, BLOOM_RESET_BUTTON_ID, "Reset"), 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + + sizer->Add(sizer2, 0, wxALL, BORDER_WIDTH); + + bloom_weight_slider = new TechSlider("Weight", main_panel, sizer, 0.f, 0.8f, 0.1f); + bloom_radius_slider = new TechSlider("Radius", main_panel, sizer, 0.f, 0.2f, 0.01f); + + vert_box_sizer->Add(sizer, + 0, // make not vertically stretchable + //wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + BORDER_WIDTH); // set border width to 10 + } + + //------------------------------------------------------------------------ + //Add glare controls + //------------------------------------------------------------------------ + { + wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Camera Glare")); + wxBoxSizer* sizer = new wxStaticBoxSizer(box, wxVERTICAL); + + + + wxBoxSizer* choice_sizer = new wxBoxSizer(wxHORIZONTAL); + + choice_sizer->Add(glare_checkbox = new wxCheckBox(main_panel, GLARE_CHECKBOX_ID, "Enabled"), 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + glare_num_blades_ctrl = new wxSpinCtrl(main_panel, GLARE_NUM_BLADES_CTRL_ID, wxEmptyString, wxDefaultPosition, wxDefaultSize, + wxSP_ARROW_KEYS, 3, 100, DEFAULT_NUM_BLADES, "name"); + choice_sizer->Add(glare_num_blades_ctrl, 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + + choice_sizer->Add(new wxButton(main_panel, GLARE_RESET_BUTTON_ID, "Reset"), 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + + sizer->Add(choice_sizer); + + glare_amount_slider = new TechSlider("Weight", main_panel, sizer, 0.f, 0.3f, 0.03f); + glare_radius_slider = new TechSlider("Radius", main_panel, sizer, 0.f, 0.2f, 0.03f); + + vert_box_sizer->Add(sizer, + 0, // make not vertically stretchable + //wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + BORDER_WIDTH); // set border width to 10 + + } + + + //------------------------------------------------------------------------ + //Add aberration controls + //------------------------------------------------------------------------ + { + wxStaticBox* box = new wxStaticBox(main_panel, wxID_ANY, _T("Chromatic Aberration")); + wxBoxSizer* sizer = new wxStaticBoxSizer(box, wxVERTICAL); + + wxBoxSizer* sizer2 = new wxBoxSizer(wxHORIZONTAL); + + sizer2->Add(aberration_checkbox = new wxCheckBox(main_panel, ABERRATION_CHECKBOX_ID, "Enabled"), 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + sizer2->Add(new wxButton(main_panel, ABERRATION_RESET_BUTTON_ID, "Reset"), 0, wxALL | wxALIGN_CENTER_VERTICAL, BORDER_WIDTH); + + sizer->Add(sizer2, 0, wxALL, BORDER_WIDTH); + + aberration_slider = new TechSlider("Amount", main_panel, sizer, 0.f, 0.1f, 0.01f); + + vert_box_sizer->Add(sizer, + 0, // + //wxEXPAND | // make horizontally stretchable + wxALL, // and make border all around + BORDER_WIDTH); // set border width to 10 + } + + /* Removed log window, and sent log messages to the status bar + //------------------------------------------------------------------------ //log window //------------------------------------------------------------------------ log_window = new wxTextCtrl(main_panel, wxID_ANY, "", @@ -352,8 +416,8 @@ ); vert_box_sizer->Add(log_window); + */ - //main_sizer->SetMinSize(500, 500); @@ -425,8 +489,10 @@ EVT_MENU(Minimal_Quit, MainWindow::OnQuit) EVT_MENU(Minimal_About, MainWindow::OnAbout) EVT_MENU(Minimal_Open, MainWindow::OnOpen) + EVT_MENU(Minimal_Merge, MainWindow::OnMergeButton) EVT_MENU(Minimal_SaveAsPNG, MainWindow::SaveAsPNG) EVT_MENU(Minimal_SaveAsJPEG, MainWindow::SaveAsJPEG) + EVT_MENU(Minimal_SaveAsIGI, MainWindow::SaveAsIGI) EVT_SCROLL(MainWindow::OnSliderScroll) EVT_TIMER(TIMER_ID, MainWindow::OnTimer) @@ -452,9 +518,36 @@ EVT_SPINCTRL(GLARE_NUM_BLADES_CTRL_ID, MainWindow::OnNumBlades) EVT_BUTTON(UPDATE_BUTTON_ID, MainWindow::OnUpdateButton) + EVT_BUTTON(MERGE_BUTTON_ID, MainWindow::OnMergeButton) + EVT_BUTTON(JPG_SAVE_BUTTON_ID, MainWindow::SaveAsJPEG) + EVT_BUTTON(PNG_SAVE_BUTTON_ID, MainWindow::SaveAsPNG) + EVT_BUTTON(IGI_SAVE_BUTTON_ID, MainWindow::SaveAsIGI) END_EVENT_TABLE() +void MainWindow::OnMergeButton(wxCommandEvent& event) +{ + //just to check if there's an image loaded + computeDisplayImage(true); + if(display_image.getWidth() * display_image.getHeight() == 0) + return; + + wxFileDialog dialog(NULL, + "Select an Indigo Image File to merge",//msg + ".",//initial dir + "",//default file + "Indigo Image files (*.igi)|*.igi");//wildcard + + int result = dialog.ShowModal(); + + if(result == wxID_OK) + { + const std::string path(dialog.GetPath()); + + mergeIGI(path); + } +} + void MainWindow::OnUpdateButton(wxCommandEvent& event) { invalidateDisplayImage(); @@ -623,25 +716,25 @@ //------------------------------------------------------------------------ //load indigo image file //------------------------------------------------------------------------ - IndigoImage indigo_image; + //IndigoImage i_raw_image; try { - indigo_image.read(raw_image, path); + i_raw_image.read(raw_image, path); - super_sample_factor = indigo_image.header.supersample_factor; + super_sample_factor = i_raw_image.header.supersample_factor; //got_image = true; SetStatusText(_T("Loaded Image.")); log("Loaded Image '" + path + "'"); - log("width: " + toString(indigo_image.header.width / indigo_image.header.supersample_factor)); - log("height: " + toString(indigo_image.header.height / indigo_image.header.supersample_factor)); - log("supersample_factor: " + toString(indigo_image.header.supersample_factor)); - log("num_samples: " + toString(indigo_image.header.num_samples)); + log("width: " + toString(i_raw_image.header.width / i_raw_image.header.supersample_factor)); + log("height: " + toString(i_raw_image.header.height / i_raw_image.header.supersample_factor)); + log("supersample_factor: " + toString(i_raw_image.header.supersample_factor)); + log("num_samples: " + toString(i_raw_image.header.num_samples)); resetAllControls(); invalidateDisplayImage(); - this->SetTitle(std::string("Indigo Tone Mapper: " + path).c_str()); + //this->SetTitle(std::string("Indigo Tone Mapper: " + path).c_str()); } catch(IndigoImageExcep& e) { @@ -649,7 +742,43 @@ } } +void MainWindow::mergeIGI(const std::string& path) +{ + //------------------------------------------------------------------------ + //merge indigo image file into existing image buffer + //------------------------------------------------------------------------ + //IndigoImage i_merge_image; + try + { + i_merge_image.read(merge_image, path); + if (i_merge_image.header.supersample_factor != i_raw_image.header.supersample_factor) + throw IndigoImageExcep("File to merge doesn't have the same width"); + else if (i_merge_image.header.width != i_raw_image.header.width) + throw IndigoImageExcep("File to merge doesn't have the same width"); + else if (i_merge_image.header.height != i_raw_image.header.height) + throw IndigoImageExcep("File to merge doesn't have the same height"); + else + { + //do the merge operation + double total_samples = i_raw_image.header.num_samples + i_merge_image.header.num_samples; + raw_image.scale((float)(i_raw_image.header.num_samples/total_samples)); + merge_image.scale((float)(i_merge_image.header.num_samples/total_samples)); + + raw_image.addImage(merge_image,0,0); + + i_raw_image.header.num_samples = total_samples; + invalidateDisplayImage(); + SetStatusText(_T("Merged Image.")); + } + + } + catch(IndigoImageExcep& e) + { + wxMessageBox(std::string("Error while trying to merge image '" + path + "': " + e.what()).c_str()); + } +} + void MainWindow::computeDisplayImage(bool blocking) { debugLog("computeDisplayImage()"); @@ -808,7 +937,8 @@ void MainWindow::log(const std::string& s) { - log_window->AppendText(std::string(s + "\n").c_str()); + SetStatusText(_T(s)); + //log_window->AppendText(std::string(s + "\n").c_str()); } void MainWindow::debugLog(const std::string& s) @@ -816,7 +946,34 @@ //log(s); } +void MainWindow::SaveAsIGI(wxCommandEvent& event) +{ + //this is useful for saving an IGI after merging + //resume render with a merged IGI??! + + //NB this function saves the raw_image, not the + //tonemapped one. + + //just to check if there's an image loaded + computeDisplayImage(true); + if(display_image.getWidth() * display_image.getHeight() == 0) + return; + + wxFileDialog dialog(NULL, + "Save as IGI", + ".", + "out.igi", + "Indigo Image files (*.igi)|*.igi", + wxSAVE); + int result = dialog.ShowModal(); + + if(result == wxID_OK) + { + std::string path = (std::string)dialog.GetPath(); + i_raw_image.write(raw_image, i_raw_image.header.num_samples, i_raw_image.header.supersample_factor, path); + } +} void MainWindow::SaveAsPNG(wxCommandEvent& event) { @@ -866,7 +1023,7 @@ if(result == wxID_OK) { - wx_image.SetOption("quality", 90); + wx_image.SetOption("quality", jpg_quality_ctrl->GetValue()); wx_image.SaveFile(dialog.GetPath(), wxBITMAP_TYPE_JPEG); SetStatusText(_T("Image Saved.")); log("Image Saved."); Index: src/violet/MainWindow.h =================================================================== --- src/violet/MainWindow.h (revision 12) +++ src/violet/MainWindow.h (working copy) @@ -52,6 +52,7 @@ void log(const std::string& s); void loadIGI(const std::string& path); + void mergeIGI(const std::string& path); private: //Event handlers void OnQuit(wxCommandEvent& event); @@ -59,6 +60,7 @@ void OnOpen(wxCommandEvent& event); void SaveAsPNG(wxCommandEvent& event); void SaveAsJPEG(wxCommandEvent& event); + void SaveAsIGI(wxCommandEvent& event); void OnSize(wxSizeEvent& event); void OnSliderScroll(wxScrollEvent& event); @@ -71,6 +73,7 @@ void OnNumBlades(wxSpinEvent& event); void OnUpdateButton(wxCommandEvent& event); + void OnMergeButton(wxCommandEvent& event); // any class wishing to process wxWindows events must use this macro DECLARE_EVENT_TABLE() @@ -110,12 +113,14 @@ wxCheckBox* glare_checkbox; wxSpinCtrl* glare_num_blades_ctrl; + wxSpinCtrl* jpg_quality_ctrl; //float linear_scale; wxTimer timer; - wxTextCtrl* log_window; + //wxTextCtrl* log_window; + enum STATE { STATE_IDLING, @@ -128,8 +133,14 @@ bool need_recompute; bool quit_requested; + + //the raw data that we work from Image raw_image; + //the tonemapped image that we display/save Image display_image; + //another image that we can import and mergo into raw_image + Image merge_image; + ImageWindow* image_window; int super_sample_factor;