From d69daa57b9e7b962370cfc89dfe2c165eb005f4d Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Mon, 25 May 2015 14:15:29 +0200 Subject: [PATCH 01/13] Code clean-up --- src/base/image.cc | 264 ++++++++++++++++++++++------------------------ 1 file changed, 129 insertions(+), 135 deletions(-) diff --git a/src/base/image.cc b/src/base/image.cc index b79720443..953928877 100644 --- a/src/base/image.cc +++ b/src/base/image.cc @@ -1,5 +1,5 @@ /* - + */ /* @@ -33,11 +33,13 @@ #include #include "fileutils.hh" +//#include "pf_mkstemp.hh" #include "image.hh" #include "imageprocessor.hh" #include "pf_file_loader.hh" #include "../operations/convert2srgb.hh" #include "../operations/convertformat.hh" +//#include "../operations/gmic/gmic_untiled_op.hh" @@ -64,8 +66,8 @@ gint PF::image_rebuild_callback( gpointer data ) } return false; } - */ - + */ + image->clear_modified(); // Loop on pipelines, re-build and update @@ -88,12 +90,12 @@ gint PF::image_rebuild_callback( gpointer data ) PF::Image::Image(): - layer_manager( this ), - async( false ), - modified_flag( false ), - rebuilding( false ), - loaded( false ), - disable_update( false ) + layer_manager( this ), + async( false ), + modified_flag( false ), + rebuilding( false ), + loaded( false ), + disable_update( false ) { rebuild_mutex = vips_g_mutex_new(); //g_mutex_lock( rebuild_mutex ); @@ -152,17 +154,17 @@ void PF::Image::update( PF::Pipeline* target_pipeline, bool sync ) request.image = this; request.pipeline = target_pipeline; request.request = PF::IMAGE_REBUILD; - /* + /* if(area) { request.area.left = area->left; request.area.top = area->top; request.area.width = area->width; request.area.height = area->height; } else { - */ - request.area.width = request.area.height = 0; - //} - + */ + request.area.width = request.area.height = 0; + //} + if( sync ) g_mutex_lock( rebuild_mutex ); #ifndef NDEBUG std::cout<<"PF::Image::update(): submitting rebuild request..."<has_sinks()) ) continue; - } else { - // We only rebuild the target pipeline - if( pipeline != target_pipeline ) continue; - } + if( !target_pipeline) { + // We do not target a specific pipeline + // For the sake of performance, we only rebuild pipelines that have + // sinks attached to them, as otherwise the pipeline can be considered inactive + //if( !(pipeline->has_sinks()) ) continue; + } else { + // We only rebuild the target pipeline + if( pipeline != target_pipeline ) continue; + } #ifndef NDEBUG std::cout<<"PF::Image::do_update(): updating pipeline #"<get_nodes()[ni]; if( !node ) continue; if( !(node->image) ) { - std::cout<<" node #"<image<<")"<image<<")"<image<<") = "<image)->ref_count<& values ) + VipsImage** image, std::vector& values ) { - int left = (int)x-size/2; - int top = (int)y-size/2; - int width = size; - int height = size; - VipsRect area = {left, top, width, height}; + int left = (int)x-size/2; + int top = (int)y-size/2; + int width = size; + int height = size; + VipsRect area = {left, top, width, height}; if( PF::PhotoFlow::Instance().is_batch() ) { do_sample( layer_id, area ); } else { ProcessRequestInfo request; request.image = this; - request.layer_id = layer_id; + request.layer_id = layer_id; request.request = PF::IMAGE_SAMPLE; - request.area.left = area.left; - request.area.top = area.top; - request.area.width = area.width; - request.area.height = area.height; - + request.area.left = area.left; + request.area.top = area.top; + request.area.width = area.width; + request.area.height = area.height; + g_mutex_lock( sample_mutex ); //#ifndef NDEBUG std::cout<<"PF::Image::sample(): submitting sample request..."<Xsize, image->Ysize}; - VipsRect clipped; - vips_rect_intersectrect( &area, &all, &clipped ); - + // Now we have to process a small portion of the image + // to get the corresponding Lab values + VipsImage* spot; + VipsRect all = {0 ,0, image->Xsize, image->Ysize}; + VipsRect clipped; + vips_rect_intersectrect( &area, &all, &clipped ); + /* if( vips_crop( image, &spot, clipped.left, clipped.top, @@ -364,17 +366,17 @@ void PF::Image::do_sample( int layer_id, VipsRect& area ) return; } VipsRect rspot = {0 ,0, spot->Xsize, spot->Ysize}; - */ + */ spot = image; - VipsRect rspot = {clipped.left, clipped.top, clipped.width, clipped.height}; + VipsRect rspot = {clipped.left, clipped.top, clipped.width, clipped.height}; - //VipsImage* outimg = im_open( "spot_wb_img", "p" ); - //if (vips_sink_screen (spot, outimg, NULL, - // 64, 64, 1, + //VipsImage* outimg = im_open( "spot_wb_img", "p" ); + //if (vips_sink_screen (spot, outimg, NULL, + // 64, 64, 1, // 0, NULL, this)) - // return; - + // return; + PF::ProcessorBase* convert_format = new PF::Processor(); std::vector in; in.push_back( spot ); @@ -387,43 +389,43 @@ void PF::Image::do_sample( int layer_id, VipsRect& area ) return; } //PF_UNREF( spot, "Image::do_sample() spot unref" ) - //if( vips_sink_memory( spot ) ) - // return; + //if( vips_sink_memory( spot ) ) + // return; //PF_PRINT_REF( outimg, "Image::do_sample(): outimg refcount before vips_region_new()" ) - VipsRegion* region = vips_region_new( outimg ); - if (vips_region_prepare (region, &rspot)) { + VipsRegion* region = vips_region_new( outimg ); + if (vips_region_prepare (region, &rspot)) { std::cout<<"Image::do_sample(): vips_region_prepare() failed"<Bands; - float* p; - float avg[16]; + int row, col, b; + int line_size = clipped.width*image->Bands; + float* p; + float avg[16]; for( int i = 0; i < 16; i++ ) avg[i] = 0; - for( row = 0; row < clipped.height; row++ ) { - p = (float*)VIPS_REGION_ADDR( region, rspot.left, rspot.top+row ); + for( row = 0; row < clipped.height; row++ ) { + p = (float*)VIPS_REGION_ADDR( region, rspot.left, rspot.top+row ); std::cout<<"do_sample(): rspot.left="<get_par() && proc->get_par()->get_property( "file_name" ) ) @@ -588,7 +590,7 @@ bool PF::Image::open( std::string filename, std::string bckname ) limg->set_processor( proc ); limg->set_name( "RAW developer" ); layer_manager.get_layers().push_back( limg ); - */ + */ /* limg = layer_manager.new_layer(); @@ -596,7 +598,7 @@ bool PF::Image::open( std::string filename, std::string bckname ) limg->set_processor( proc ); limg->set_name( "RAW output" ); layer_manager.get_layers().push_back( limg ); - */ + */ } disable_update = false; @@ -604,6 +606,8 @@ bool PF::Image::open( std::string filename, std::string bckname ) //pf_image->signal_modified.connect( sigc::mem_fun(&imageArea, &ImageArea::update_image) ); //sleep(5); //update(); + + return true; } @@ -652,9 +656,9 @@ void PF::Image::export_merged( std::string filename ) ProcessRequestInfo request; request.image = this; request.request = PF::IMAGE_EXPORT; - request.area.width = request.area.height = 0; + request.area.width = request.area.height = 0; request.filename = filename; - + //#ifndef NDEBUG std::cout<<"PF::Image::export_merged(): locking mutex..."<get_output(); - VipsImage* outimg = image; + VipsImage* outimg = NULL; std::vector in; - /* - convert2srgb->get_par()->set_image_hints( image ); - convert2srgb->get_par()->set_format( pipeline->get_format() ); - in.clear(); in.push_back( image ); - VipsImage* srgbimg = convert2srgb->get_par()->build(in, 0, NULL, NULL, level ); - //g_object_unref( image ); - std::string msg = std::string("PF::Image::export_merged(") + filename + "), image"; - PF_UNREF( image, msg.c_str() ); - */ - VipsImage* srgbimg = image; - - outimg = srgbimg; - std::string msg; - if( ext == "jpg" || ext == "jpeg" ) { + if( ext == "jpg" || ext == "jpeg" ) { in.clear(); - in.push_back( srgbimg ); - convert_format->get_par()->set_image_hints( srgbimg ); + in.push_back( image ); + convert_format->get_par()->set_image_hints( image ); convert_format->get_par()->set_format( VIPS_FORMAT_UCHAR ); outimg = convert_format->get_par()->build( in, 0, NULL, NULL, level ); - //g_object_unref( srgbimg ); - // msg = std::string("PF::Image::export_merged(") + filename + "), srgbimg"; - //PF_UNREF( srgbimg, msg.c_str() ); - vips_image_write_to_file( outimg, filename.c_str(), NULL ); - } - - if( ext == "tif" || ext == "tiff" ) { + if( outimg ) { + vips_jpegsave( outimg, filename.c_str(), "Q", 100, NULL ); + } + } + + if( ext == "tif" || ext == "tiff" ) { in.clear(); - in.push_back( srgbimg ); - convert_format->get_par()->set_image_hints( srgbimg ); + in.push_back( image ); + convert_format->get_par()->set_image_hints( image ); convert_format->get_par()->set_format( VIPS_FORMAT_USHORT ); outimg = convert_format->get_par()->build( in, 0, NULL, NULL, level ); - //g_object_unref( srgbimg ); - //msg = std::string("PF::Image::export_merged(") + filename + "), srgbimg"; - //PF_UNREF( srgbimg, msg.c_str() ); - int predictor = 2; - vips_tiffsave( outimg, filename.c_str(), "compression", VIPS_FOREIGN_TIFF_COMPRESSION_DEFLATE, - "predictor", VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL, NULL ); - //vips_image_write_to_file( outimg, filename.c_str(), NULL ); - } - - //g_object_unref( outimg ); - msg = std::string("PF::Image::export_merged(") + filename + "), outimg"; - PF_UNREF( outimg, msg.c_str() ); + if( outimg ) { + int predictor = 2; + vips_tiffsave( outimg, filename.c_str(), "compression", VIPS_FOREIGN_TIFF_COMPRESSION_DEFLATE, + "predictor", VIPS_FOREIGN_TIFF_PREDICTOR_HORIZONTAL, NULL ); + //vips_image_write_to_file( outimg, filename.c_str(), NULL ); + } + } + /**/ + + if( outimg ) { + msg = std::string("PF::Image::export_merged(") + filename + "): outimg unref"; + PF_UNREF( outimg, msg.c_str() ); + } remove_pipeline( pipeline ); delete pipeline; layer_manager.reset_cache_buffers( PF_RENDER_NORMAL, true ); From 04fd48f841dfd43c23c95912ce2afc939ba3e97b Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Mon, 25 May 2015 14:16:06 +0200 Subject: [PATCH 02/13] Added RGB <-> HSL conversion --- src/base/color.cc | 48 +++++++++++++++++++++++++++++++++ src/base/color.hh | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 src/base/color.cc diff --git a/src/base/color.cc b/src/base/color.cc new file mode 100644 index 000000000..a2bfe8bd5 --- /dev/null +++ b/src/base/color.cc @@ -0,0 +1,48 @@ +/* + */ + +/* + + Copyright (C) 2014 Ferrero Andrea + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + */ + +/* + + These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ + + */ + + +#include "color.hh" + + + float PF::hsl_value( float n1, float n2, float hue) + { + float val; + + if( hue > 6.0 ) hue -= 6.0f; + else if( hue < 0 ) hue += 6.0f; + + if( hue < 1.0 ) val = n1 + (n2-n1)*hue; + else if( hue < 3.0 ) val = n2; + else if( hue < 4.0 ) val = n1 + (n2-n1)*(4.0f-hue); + else val = n1; + + return val; + } + diff --git a/src/base/color.hh b/src/base/color.hh index 668f2e96a..e7ed6df57 100644 --- a/src/base/color.hh +++ b/src/base/color.hh @@ -62,6 +62,7 @@ namespace PF out = static_cast( (in*FormatInfo::RANGE)-FormatInfo::MIN ); } + // template void rgb2hsv(const T& r, const T& g, const T& b, float& h, float& s, float& v) @@ -204,6 +205,9 @@ namespace PF R += Min; G += Min; B += Min; + if(R>1) R=1; else if(R<0) R=0; + if(G>1) G=1; else if(G<0) G=0; + if(B>1) B=1; else if(B<0) B=0; from_float(R, r); from_float(G, g); from_float(B, b); @@ -212,6 +216,71 @@ namespace PF + // + template + void rgb2hsl(const T& r, const T& g, const T& b, float& h, float& s, float& l) + { + float fr, fg, fb; to_float( r, fr ); to_float( g, fg ); to_float( b, fb ); + float min = MIN3(fr, fg, fb); + float max = MAX3(fr, fg, fb); + float sum = max+min; + float delta = max-min; + + l = sum/2.0f; + + s = h = 0; + + if( delta == 0 ) return; + + if( l <= 0.5 ) + s = (max-min)/sum; + else + s = (max-min)/(2.0f-max-min); + + if( fr == max ) h = (fg-fb)/delta; + else if( fg == max ) h = (fb-fr)/delta + 2.0f; + else if( fb == max ) h = (fr-fg)/delta + 4.0f; + h *= 60; + if( h < 0 ) h += 360; + } + + + + float hsl_value( float n1, float n2, float hue); + + // + template + void hsl2rgb( const float& h, const float& s, const float& l, T& r, T& g, T& b ) + { + int i; + float H = h/60.0f; + + if( s == 0 ) { + // achromatic (grey) + from_float( l, r ); + g = b = r; + return; + } + + float m1, m2; + if( l <= 0.5 ) + m2 = l * (s + 1); + else + m2 = l + s - l * s; + + m1 = l * 2.0f - m2; + + float fr = hsl_value( m1, m2, H + 2.0f ); + float fg = hsl_value( m1, m2, H ); + float fb = hsl_value( m1, m2, H - 2.0f ); + + from_float( fr, r ); + from_float( fg, g ); + from_float( fb, b ); + } + + + // Computes the luminance value of a given RGB triplet template T luminance(const T& r, const T& g, const T& b) From f3601c386af35e20ee61b8a704fa29a0c50aeebf Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Mon, 25 May 2015 14:18:13 +0200 Subject: [PATCH 03/13] Removed verbose console output --- src/gui/imagearea.cc | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/gui/imagearea.cc b/src/gui/imagearea.cc index c7e99360b..64d84d2c8 100644 --- a/src/gui/imagearea.cc +++ b/src/gui/imagearea.cc @@ -771,8 +771,11 @@ void PF::ImageArea::update( VipsRect* area ) VipsImage* image = NULL; if( display_merged || (active_layer<0) ) { image = get_pipeline()->get_output(); - //std::cout<<"ImageArea::update(): image->Bands="<Bands<BandFmt="<BandFmt<Bands="<Bands<BandFmt="<BandFmt<Xsize<<"x"<Ysize<Bands!=2) ) { PF_REF( image, "ImageArea::update(): merged image ref" ); } else { From c0d808f8339f934d886b2cde500074d26177bdc3 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Mon, 25 May 2015 14:22:16 +0200 Subject: [PATCH 04/13] Added filename widget in RAW loader configuration dialog --- src/gui/operation_config_dialog.cc | 3 +- src/gui/operations/raw_loader_config.cc | 129 ++++++++++++++++++++++++ src/gui/operations/raw_loader_config.hh | 63 ++++++++++++ src/operations/raw_loader.cc | 31 ++++-- 4 files changed, 219 insertions(+), 7 deletions(-) create mode 100644 src/gui/operations/raw_loader_config.cc create mode 100644 src/gui/operations/raw_loader_config.hh diff --git a/src/gui/operation_config_dialog.cc b/src/gui/operation_config_dialog.cc index 135d5c743..a7b5b3364 100644 --- a/src/gui/operation_config_dialog.cc +++ b/src/gui/operation_config_dialog.cc @@ -36,6 +36,7 @@ #include "../gui/operations/brightness_contrast_config.hh" #include "../gui/operations/hue_saturation_config.hh" #include "../gui/operations/imageread_config.hh" +#include "../gui/operations/raw_loader_config.hh" #include "../gui/operations/vips_operation_config.hh" #include "../gui/operations/clone_config.hh" #include "../gui/operations/crop_config.hh" @@ -543,7 +544,7 @@ PF::ProcessorBase* PF::new_operation_with_gui( std::string op_type, PF::Layer* c } else if( op_type == "raw_loader" ) { - dialog = new PF::OperationConfigDialog( current_layer, "RAW loader" ); + dialog = new PF::RawLoaderConfigDialog( current_layer ); } else if( op_type == "raw_developer" ) { diff --git a/src/gui/operations/raw_loader_config.cc b/src/gui/operations/raw_loader_config.cc new file mode 100644 index 000000000..dd1ed793b --- /dev/null +++ b/src/gui/operations/raw_loader_config.cc @@ -0,0 +1,129 @@ +/* + */ + +/* + + Copyright (C) 2014 Ferrero Andrea + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + */ + +/* + + These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ + + */ + +#include "../../operations/brightness_contrast.hh" + +#include "raw_loader_config.hh" + + +PF::RawLoaderConfigDialog::RawLoaderConfigDialog( PF::Layer* layer ): + OperationConfigDialog( layer, "Open a RAW image" ), + openButton(Gtk::Stock::OPEN) +{ + label.set_text( "RAW file name:" ); + + controlsBox.pack_start( label ); + controlsBox.pack_start( fileEntry ); + controlsBox.pack_start( openButton ); + + add_widget( controlsBox ); + + fileEntry.signal_activate(). + connect(sigc::mem_fun(*this, + &RawLoaderConfigDialog::on_filename_changed)); + openButton.signal_clicked().connect(sigc::mem_fun(*this, + &RawLoaderConfigDialog::on_button_open_clicked) ); +} + + +void PF::RawLoaderConfigDialog::on_filename_changed() +{ + if( get_layer() && get_layer()->get_image() && + get_layer()->get_processor() && + get_layer()->get_processor()->get_par() ) { + std::string filename = fileEntry.get_text(); + //std::cout<<"New image file name: "<(get_layer()->get_processor()->get_par()); + if( par && !filename.empty() ) { + par->set_file_name( filename ); + get_layer()->set_dirty( true ); + //std::cout<<" updating image"<get_image()->update(); + } + } +} + + +void PF::RawLoaderConfigDialog::open() +{ + if( get_layer() && get_layer()->get_image() && + get_layer()->get_processor() && + get_layer()->get_processor()->get_par() ) { + PF::RawLoaderPar* par = + dynamic_cast(get_layer()->get_processor()->get_par()); + if( par ) { + fileEntry.set_text( par->get_file_name() ); + //brightnessAdj.set_value( par->get_brightness() ); + //contrastAdj.set_value( par->get_contrast() ); + } + } + OperationConfigDialog::open(); +} + + + +void PF::RawLoaderConfigDialog::on_button_open_clicked() +{ + Gtk::FileChooserDialog dialog("Please choose a RAW file", + Gtk::FILE_CHOOSER_ACTION_OPEN); + dialog.set_transient_for(*this); + + //Add response buttons the the dialog: + dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); + dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); + + //Show the dialog and wait for a user response: + int result = dialog.run(); + + //Handle the response: + switch(result) { + case(Gtk::RESPONSE_OK): + { + std::cout << "Open clicked." << std::endl; + + //Notice that this is a std::string, not a Glib::ustring. + std::string filename = dialog.get_filename(); + std::cout << "File selected: " << filename << std::endl; + fileEntry.set_text( filename.c_str() ); + on_filename_changed(); + break; + } + case(Gtk::RESPONSE_CANCEL): + { + std::cout << "Cancel clicked." << std::endl; + break; + } + default: + { + std::cout << "Unexpected button clicked." << std::endl; + break; + } + } +} diff --git a/src/gui/operations/raw_loader_config.hh b/src/gui/operations/raw_loader_config.hh new file mode 100644 index 000000000..2648aacbc --- /dev/null +++ b/src/gui/operations/raw_loader_config.hh @@ -0,0 +1,63 @@ +/* + */ + +/* + + Copyright (C) 2014 Ferrero Andrea + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + */ + +/* + + These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ + + */ + +#ifndef RAW_LOADER_CONFIG_DIALOG_HH +#define RAW_LOADER_CONFIG_DIALOG_HH + +#include + +#include "../operation_config_dialog.hh" +#include "../../operations/raw_loader.hh" + + +namespace PF { + + class RawLoaderConfigDialog: public OperationConfigDialog +{ + //#ifdef GTKMM_2 + Gtk::HBox controlsBox; + + Gtk::Label label; + Gtk::Entry fileEntry; + Gtk::Button openButton; + //#endif + +public: + RawLoaderConfigDialog( Layer* l ); + + void on_button_open_clicked(); + + void on_filename_changed(); + + void open(); +}; + +} + +#endif diff --git a/src/operations/raw_loader.cc b/src/operations/raw_loader.cc index f2db1c9ba..d68e98a78 100644 --- a/src/operations/raw_loader.cc +++ b/src/operations/raw_loader.cc @@ -74,18 +74,37 @@ VipsImage* PF::RawLoaderPar::build(std::vector& in, int first, if( file_name.get().empty() ) return NULL; - if( raw_image ) - raw_image->unref(); + RawImage* new_raw_image = NULL; std::map::iterator i = raw_images.find( file_name.get() ); if( i == raw_images.end() ) { - raw_image = new RawImage( file_name.get() ); - raw_images.insert( make_pair(file_name.get(), raw_image) ); + std::cout<<"ImageReaderPar::build(): creating new RawImage for file "<second; - raw_image->ref(); + new_raw_image = i->second; + new_raw_image->ref(); } + + //if( raw_image ) std::cout<<"raw_image->get_nref(): "<get_nref()<get_nref(): "<get_nref()<unref(); + if( raw_image->get_nref() == 0 ) { + std::map::iterator i = + raw_images.find( file_name.get() ); + if( i != raw_images.end() ) + raw_images.erase( i ); + delete raw_image; + std::cout<<"ImageReaderPar::build(): raw_image deleted"< Date: Mon, 25 May 2015 14:25:04 +0200 Subject: [PATCH 05/13] Added digital watemarking based on G'MIC "watermark_fourier" filter --- src/gui/operations/gmic/configs.hh | 1 + .../gmic/new_gmic_operation_config.cc | 2 + .../gmic/watermark_fourier_config.cc | 68 +++++++++++ .../gmic/watermark_fourier_config.hh | 56 +++++++++ src/gui/operationstree.cc | 108 +++++++++--------- src/operations/gmic/new_gmic_operation.cc | 2 + src/operations/gmic/operations.hh | 1 + src/operations/gmic/watermark_fourier.cc | 95 +++++++++++++++ src/operations/gmic/watermark_fourier.hh | 79 +++++++++++++ 9 files changed, 359 insertions(+), 53 deletions(-) create mode 100644 src/gui/operations/gmic/watermark_fourier_config.cc create mode 100644 src/gui/operations/gmic/watermark_fourier_config.hh create mode 100644 src/operations/gmic/watermark_fourier.cc create mode 100644 src/operations/gmic/watermark_fourier.hh diff --git a/src/gui/operations/gmic/configs.hh b/src/gui/operations/gmic/configs.hh index 37c7eee7f..8a353167e 100644 --- a/src/gui/operations/gmic/configs.hh +++ b/src/gui/operations/gmic/configs.hh @@ -61,3 +61,4 @@ #include "sharpen_rl_config.hh" #include "split_details_config.hh" #include "transfer_colors_config.hh" +#include "watermark_fourier_config.hh" diff --git a/src/gui/operations/gmic/new_gmic_operation_config.cc b/src/gui/operations/gmic/new_gmic_operation_config.cc index 6d5c4c35d..e85e88192 100644 --- a/src/gui/operations/gmic/new_gmic_operation_config.cc +++ b/src/gui/operations/gmic/new_gmic_operation_config.cc @@ -99,6 +99,8 @@ PF::OperationConfigDialog* PF::new_gmic_operation_config( std::string op_type, P dialog = new PF::GmicSplitDetailsConfigDialog( current_layer ); } else if( op_type == "gmic_transfer_colors" ) { dialog = new PF::GmicTransferColorsConfigDialog( current_layer ); + } else if( op_type == "gmic_watermark_fourier" ) { + dialog = new PF::GmicWatermarkFourierConfigDialog( current_layer ); //insert new operations here } diff --git a/src/gui/operations/gmic/watermark_fourier_config.cc b/src/gui/operations/gmic/watermark_fourier_config.cc new file mode 100644 index 000000000..2daae1b6c --- /dev/null +++ b/src/gui/operations/gmic/watermark_fourier_config.cc @@ -0,0 +1,68 @@ +/* + */ + +/* + + Copyright (C) 2014 Ferrero Andrea + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + */ + +/* + + These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ + + */ + +#include "../../operations/gmic/watermark_fourier.hh" +#include "watermark_fourier_config.hh" + + +PF::GmicWatermarkFourierConfigDialog::GmicWatermarkFourierConfigDialog( PF::Layer* layer ): + OperationConfigDialog( layer, "Digital Watermark" ), + updateButton( "Update" ), + textBox( this, "text", "Text: ", "Watermark" ), + textsizeSlider( this, "text_size", "Text size: ", 53, 13, 128, 1, 5, 1 ) +{ + //add_widget( updateButton ); + add_widget( textBox ); + add_widget( textsizeSlider ); + + updateButton.signal_clicked().connect( sigc::mem_fun(this, &GmicWatermarkFourierConfigDialog::on_update) ); + + //fileEntry.signal_activate(). + // connect(sigc::mem_fun(*this, + // &GmicWatermarkFourierConfigDialog::on_filename_changed)); +} + + +void PF::GmicWatermarkFourierConfigDialog::on_update() +{ + if( get_layer() && get_layer()->get_image() && + get_layer()->get_processor() && + get_layer()->get_processor()->get_par() ) { + GmicWatermarkFourierPar* par = dynamic_cast( get_layer()->get_processor()->get_par() ); + if( !par ) return; + par->refresh(); + get_layer()->get_image()->lock(); + std::cout<<" updating image"<get_image()->update(); + get_layer()->get_image()->unlock(); + } +} + + + diff --git a/src/gui/operations/gmic/watermark_fourier_config.hh b/src/gui/operations/gmic/watermark_fourier_config.hh new file mode 100644 index 000000000..89d975be6 --- /dev/null +++ b/src/gui/operations/gmic/watermark_fourier_config.hh @@ -0,0 +1,56 @@ +/* + */ + +/* + + Copyright (C) 2014 Ferrero Andrea + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + */ + +/* + + These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ + + */ + +#ifndef WATERMARK_FOURIER_CONFIG_DIALOG_HH +#define WATERMARK_FOURIER_CONFIG_DIALOG_HH + +#include + +#include "../../operation_config_dialog.hh" + +#include "../../widgets/layerlist.hh" + + +namespace PF { + +class GmicWatermarkFourierConfigDialog: public OperationConfigDialog +{ + Gtk::Button updateButton; + TextBox textBox; + Slider textsizeSlider; + +public: + GmicWatermarkFourierConfigDialog( Layer* l ); + + void on_update(); +}; + +} + +#endif diff --git a/src/gui/operationstree.cc b/src/gui/operationstree.cc index 38a1f43a4..5118c8ab4 100644 --- a/src/gui/operationstree.cc +++ b/src/gui/operationstree.cc @@ -51,7 +51,7 @@ #include "../gui/operations/vips_operation_config.hh" #include "../gui/operations/clone_config.hh" #include "../gui/operations/curves_config.hh" -*/ + */ PF::OperationsTree::OperationsTree( ) { @@ -113,7 +113,7 @@ void PF::OperationsTreeWidget::on_selection_changed() buf->insert_at_cursor("Left-clicking on the graph with the mouse adds a new control point, while right-clicking on an existing "); buf->insert_at_cursor("control point deletes it. Control points can be moved by either dragging them with the moiuse, or by setting the corresponding input and output numerical values in the boxes below the graph."); } - */ + */ } } @@ -134,18 +134,18 @@ static void* collect_class( GType type ) if( depth == 2 && abstract ) { std::map< std::string, std::list >::iterator i = - vips_operations.find( klass->nickname ); + vips_operations.find( klass->nickname ); if(i == vips_operations.end() ) { vips_operations.insert( make_pair( std::string(klass->nickname), - std::list() ) ); + std::list() ) ); i = vips_operations.find( klass->nickname ); if(i == vips_operations.end() ) - return( NULL ); + return( NULL ); } vips_category = klass->nickname; } else if( depth >= 2 && !abstract ) { std::map< std::string, std::list >::iterator i = - vips_operations.find( vips_category ); + vips_operations.find( vips_category ); if(i == vips_operations.end() ) return( NULL ); @@ -156,33 +156,32 @@ static void* collect_class( GType type ) int nout = 0; VIPS_ARGUMENT_FOR_ALL( operation, - pspec, argument_class, argument_instance ) { - + pspec, argument_class, argument_instance ) { + g_assert( argument_instance ); - + if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) { - GType otype = G_PARAM_SPEC_VALUE_TYPE( pspec ); - const gchar* arg_name = g_param_spec_get_name( pspec ); - - if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) ) nout += 1; + GType otype = G_PARAM_SPEC_VALUE_TYPE( pspec ); + const gchar* arg_name = g_param_spec_get_name( pspec ); + + if( g_type_is_a( otype, VIPS_TYPE_IMAGE ) ) nout += 1; } } VIPS_ARGUMENT_FOR_ALL_END; - + std::cout<<"klass->nickname -> # of output images: "<second.push_back( klass->nickname ); } return( NULL ); - + } @@ -237,16 +236,16 @@ void PF::OperationsTree::add_op( Glib::ustring name, const std::string nik) //expand_all(); } -*/ + */ PF::OperationsTreeDialog::OperationsTreeDialog( Image* img, LayerWidget* lw ): - Gtk::Dialog("New Layer",true), - image( img ), - layer_widget( lw ) + Gtk::Dialog("New Layer",true), + image( img ), + layer_widget( lw ) { set_default_size(300,300); @@ -254,15 +253,15 @@ PF::OperationsTreeDialog::OperationsTreeDialog( Image* img, LayerWidget* lw ): add_button("Cancel",0); signal_response().connect( sigc::mem_fun(*this, - &OperationsTreeDialog::on_button_clicked) ); + &OperationsTreeDialog::on_button_clicked) ); //op_load_box.add( op_load ); notebook.append_page( op_load, "load" ); - notebook.append_page( op_raw, "raw" ); + //notebook.append_page( op_raw, "raw" ); //op_conv_box.add( op_conv ); - notebook.append_page( op_conv, "conv" ); + //notebook.append_page( op_conv, "conv" ); //op_color_box.add( op_color ); notebook.append_page( op_color, "color" ); @@ -273,17 +272,17 @@ PF::OperationsTreeDialog::OperationsTreeDialog( Image* img, LayerWidget* lw ): //op_geom_box.add( op_geom ); notebook.append_page( op_geom, "geom" ); -//#ifndef PF_DISABLE_GMIC + //#ifndef PF_DISABLE_GMIC //op_gmic_box.add( op_gmic ); notebook.append_page( op_gmic, "G'MIC" ); -//#endif + //#endif //op_misc_box.add( op_misc ); notebook.append_page( op_misc, "misc" ); op_load.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); - op_raw.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); - op_conv.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); + //op_raw.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); + //op_conv.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); op_color.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); op_detail.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); op_geom.get_tree().signal_row_activated().connect( sigc::mem_fun(*this, &PF::OperationsTreeDialog::on_row_activated) ); @@ -293,10 +292,11 @@ PF::OperationsTreeDialog::OperationsTreeDialog( Image* img, LayerWidget* lw ): op_load.get_tree().add_op( "Open image", "imageread" ); op_load.get_tree().add_op( "Open RAW image", "raw_loader" ); - op_raw.get_tree().add_op( "RAW developer", "raw_developer" ); + //op_raw.get_tree().add_op( "RAW developer", "raw_developer" ); + op_load.get_tree().add_op( "RAW developer", "raw_developer" ); - op_conv.get_tree().add_op( "Color profile conversion", "convert_colorspace" ); - op_conv.get_tree().add_op( "Lab conversion", "convert2lab" ); + //op_conv.get_tree().add_op( "Color profile conversion", "convert_colorspace" ); + //op_conv.get_tree().add_op( "Lab conversion", "convert2lab" ); op_color.get_tree().add_op( "Uniform Fill", "uniform"); op_color.get_tree().add_op( "Gradient", "gradient"); @@ -306,6 +306,7 @@ PF::OperationsTreeDialog::OperationsTreeDialog( Image* img, LayerWidget* lw ): op_color.get_tree().add_op( "Hue/Saturation", "hue_saturation" ); op_color.get_tree().add_op( "Curves", "curves" ); op_color.get_tree().add_op( "Channel Mixer", "channel_mixer" ); + op_color.get_tree().add_op( "Color profile conversion", "convert_colorspace" ); op_detail.get_tree().add_op( "Gaussian blur", "gaussblur" ); op_detail.get_tree().add_op( "Noise reduction", "denoise" ); @@ -316,7 +317,7 @@ PF::OperationsTreeDialog::OperationsTreeDialog( Image* img, LayerWidget* lw ): op_geom.get_tree().add_op( "Scale & rotate image", "scale" ); op_geom.get_tree().add_op( "Optical corrections (experimental)", "lensfun" ); -//#if !defined(__APPLE__) && !defined(__MACH__) + //#if !defined(__APPLE__) && !defined(__MACH__) #ifndef PF_DISABLE_GMIC //op_gmic.get_tree().add_op( "G'MIC Interpreter", "gmic" ); op_gmic.get_tree().add_op( "Dream Smoothing", "gmic_dream_smooth" ); @@ -349,11 +350,12 @@ PF::OperationsTreeDialog::OperationsTreeDialog( Image* img, LayerWidget* lw ): op_gmic.get_tree().add_op( "Tone mapping", "gmic_tone_mapping" ); op_gmic.get_tree().add_op( "Transfer colors [advanced]", "gmic_transfer_colors" ); #endif - - op_misc.get_tree().add_op( "Buffer layer", "buffer" ); - op_misc.get_tree().add_op( "Clone layer", "clone" ); + op_misc.get_tree().add_op( "Draw", "draw" ); op_misc.get_tree().add_op( "Clone stamp", "clone_stamp" ); + op_misc.get_tree().add_op( "Clone layer", "clone" ); + op_misc.get_tree().add_op( "Buffer layer", "buffer" ); + op_misc.get_tree().add_op( "Digital watermark", "gmic_watermark_fourier" ); get_vbox()->pack_start( notebook ); @@ -406,7 +408,7 @@ void PF::OperationsTreeDialog::on_row_activated( const Gtk::TreeModel::Path& pat //PF::OperationConfigUI* dialog = l->get_processor()->get_par()->get_config_ui(); //if(dialog) dialog->open(); } - */ + */ } @@ -422,25 +424,25 @@ void PF::OperationsTreeDialog::add_layer() case 0: op_tree = &(op_load.get_tree()); break; + //case 1: + // op_tree = &(op_raw.get_tree()); + // break; + //case 2: + // op_tree = &(op_conv.get_tree()); + // break; case 1: - op_tree = &(op_raw.get_tree()); - break; - case 2: - op_tree = &(op_conv.get_tree()); - break; - case 3: op_tree = &(op_color.get_tree()); break; - case 4: + case 2: op_tree = &(op_detail.get_tree()); break; - case 5: + case 3: op_tree = &(op_geom.get_tree()); break; - case 6: + case 4: op_tree = &(op_gmic.get_tree()); break; - case 7: + case 5: op_tree = &(op_misc.get_tree()); break; default: @@ -455,8 +457,8 @@ void PF::OperationsTreeDialog::add_layer() PF::OperationsTreeColumns& columns = op_tree->get_columns(); //std::cout<<"Adding layer of type \""<<(*iter)[columns.col_name]<<"\"" - // <<" ("<<(*iter)[columns.col_nickname]<<")"<get_layer_manager(); @@ -466,7 +468,7 @@ void PF::OperationsTreeDialog::add_layer() std::string op_type = (*iter)[columns.col_nickname]; PF::ProcessorBase* processor = - PF::PhotoFlow::Instance().new_operation( op_type.c_str(), layer ); + PF::PhotoFlow::Instance().new_operation( op_type.c_str(), layer ); if( !processor || !processor->get_par() ) return; PF::OperationConfigUI* ui = dynamic_cast( processor->get_par()->get_config_ui() ); @@ -521,7 +523,7 @@ void PF::OperationsTreeDialog::add_layer() vips_config->set_op( str.c_str() ); dialog = vips_config; } - */ + */ if( processor ) { layer_widget->add_layer( layer ); diff --git a/src/operations/gmic/new_gmic_operation.cc b/src/operations/gmic/new_gmic_operation.cc index b3d8c8f9b..dfe8b9708 100644 --- a/src/operations/gmic/new_gmic_operation.cc +++ b/src/operations/gmic/new_gmic_operation.cc @@ -97,6 +97,8 @@ PF::ProcessorBase* PF::new_gmic_operation( std::string op_type ) processor = new_gmic_split_details(); } else if( op_type == "gmic_transfer_colors" ) { processor = new_gmic_transfer_colors(); + } else if( op_type == "gmic_watermark_fourier" ) { + processor = new_gmic_watermark_fourier(); //insert new operations here } diff --git a/src/operations/gmic/operations.hh b/src/operations/gmic/operations.hh index 72aae1a4a..1eacebb63 100644 --- a/src/operations/gmic/operations.hh +++ b/src/operations/gmic/operations.hh @@ -64,6 +64,7 @@ namespace PF ProcessorBase* new_gmic_sharpen_rl(); ProcessorBase* new_gmic_split_details(); ProcessorBase* new_gmic_transfer_colors(); + ProcessorBase* new_gmic_watermark_fourier(); //insert new operations here ProcessorBase* new_gmic_operation( std::string op_type ); diff --git a/src/operations/gmic/watermark_fourier.cc b/src/operations/gmic/watermark_fourier.cc new file mode 100644 index 000000000..4364576b3 --- /dev/null +++ b/src/operations/gmic/watermark_fourier.cc @@ -0,0 +1,95 @@ +/* + */ + +/* + + Copyright (C) 2014 Ferrero Andrea + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + */ + +/* + + These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ + + */ + + +#include "gmic.hh" +#include "watermark_fourier.hh" + + + +PF::GmicWatermarkFourierPar::GmicWatermarkFourierPar(): + PF::GmicUntiledOperationPar(), + prop_text("text",this,""), + prop_text_size("text_size",this,33) +{ + set_cache_files_num(1); + set_type( "gmic_watermark_fourier"); +} + + +std::vector PF::GmicWatermarkFourierPar::build_many(std::vector& in, int first, + VipsImage* imap, VipsImage* omap, + unsigned int& level) +{ + VipsImage* srcimg = NULL; + if( in.size() > 0 ) srcimg = in[0]; + std::vector outvec; + if( !srcimg ) return outvec; + + if( get_render_mode() == PF_RENDER_PREVIEW ) { + PF_REF( srcimg, "GmicWatermarkFourierPar::build_many(): srcimg ref in preview render mode" ); + outvec.push_back( srcimg ); + return outvec; + } + + if( prop_text.get().empty() ) { + PF_REF( srcimg, "GmicWatermarkFourierPar::build_many(): srcimg ref with empty watermark" ); + outvec.push_back( srcimg ); + return outvec; + } + + update_raster_images(); + PF::RasterImage* raster_image = get_raster_image(0); + //if( !raster_image || (raster_image->get_file_name () != get_cache_file_name()) ) { + if( !raster_image ) { + std::string tempfile1 = save_image( srcimg, IM_BANDFMT_FLOAT ); + + std::string command = "-verbose + "; + command = command + "-input " + tempfile1 + " -mul 255 "; + command = command + "-watermark_fourier \"" + prop_text.get() + "\"," + prop_text_size.get_str(); + command = command + " -c 0,255 -div 255 -output " + get_cache_file_name(0) + ",float"; + + run_gmic( srcimg, command ); + + //unlink( tempfile1.c_str() ); + } + std::cout<<"GmicWatermarkFourierPar::build(): calling get_output()"<() ); +} diff --git a/src/operations/gmic/watermark_fourier.hh b/src/operations/gmic/watermark_fourier.hh new file mode 100644 index 000000000..507102414 --- /dev/null +++ b/src/operations/gmic/watermark_fourier.hh @@ -0,0 +1,79 @@ +/* + */ + +/* + + Copyright (C) 2014 Ferrero Andrea + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + + + */ + +/* + + These files are distributed with PhotoFlow - http://aferrero2707.github.io/PhotoFlow/ + + */ + +#ifndef GMIC_WATERMARK_FOURIER_H +#define GMIC_WATERMARK_FOURIER_H + + +#include "../base/processor.hh" + +#include "gmic_untiled_op.hh" + + +namespace PF +{ + + class GmicWatermarkFourierPar: public GmicUntiledOperationPar + { + Property prop_text; + Property prop_text_size; + + public: + GmicWatermarkFourierPar(); + ~GmicWatermarkFourierPar() { std::cout<<"~GmicWatermarkFourierPar() called."< build_many(std::vector& in, int first, + VipsImage* imap, VipsImage* omap, + unsigned int& level); + }; + + + + template < OP_TEMPLATE_DEF > + class GmicWatermarkFourierProc + { + public: + void render(VipsRegion** ireg, int n, int in_first, + VipsRegion* imap, VipsRegion* omap, + VipsRegion* oreg, OpParBase* par) + { + } + }; + + + + + ProcessorBase* new_gmic_watermark_fourier(); +} + +#endif + + From 8eaff27a0f09eb866044d5328acdc5d88914187e Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Mon, 25 May 2015 14:25:35 +0200 Subject: [PATCH 06/13] Removed verbose console output --- src/operations/fast_demosaic_algo.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/operations/fast_demosaic_algo.cc b/src/operations/fast_demosaic_algo.cc index 4d91df08f..32c4fb70b 100644 --- a/src/operations/fast_demosaic_algo.cc +++ b/src/operations/fast_demosaic_algo.cc @@ -132,9 +132,9 @@ void PF::fast_demosaic(VipsRegion** ir, int n, int in_first, PF::raw_pixel_t* ptr = ir ? (PF::raw_pixel_t*)VIPS_REGION_ADDR( ir[0], r_raw.left, y+r_raw.top ) : NULL; rawData.set_row( y+r_raw.top, ptr ); } - if( r_raw.left==0 && r_raw.top==0 ) { - std::cout<<"rawData[0][0] = "< Date: Mon, 25 May 2015 14:27:02 +0200 Subject: [PATCH 08/13] Added verbose console output --- src/operations/image_reader.cc | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/operations/image_reader.cc b/src/operations/image_reader.cc index c781a5cb9..d84df1b45 100644 --- a/src/operations/image_reader.cc +++ b/src/operations/image_reader.cc @@ -77,6 +77,9 @@ VipsImage* PF::ImageReaderPar::build(std::vector& in, int first, } //std::cout<<"ImageReaderPar::build(): raster_image="<<(void*)raster_image<get_nref(): "<get_nref()<get_nref(): "<get_nref()<unref(); //std::cout<<"ImageReaderPar::build(): raster_image->get_nref()="<get_nref()<& in, int first, if( !image ) return NULL; + /* { size_t exifsz; PF::exif_data_t* exif_data; @@ -110,6 +114,7 @@ VipsImage* PF::ImageReaderPar::build(std::vector& in, int first, //std::cout<<"ImageReaderPar::build(): exif_custom_data not found in image("< Date: Mon, 25 May 2015 14:27:27 +0200 Subject: [PATCH 09/13] Removed verbose console output --- src/operations/raw_image.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/operations/raw_image.cc b/src/operations/raw_image.cc index 92b9d933a..b840d2955 100644 --- a/src/operations/raw_image.cc +++ b/src/operations/raw_image.cc @@ -147,10 +147,10 @@ PF::RawImage::RawImage( const std::string f ): float val = raw_loader->imgdata.image[row_offset+col][color]; val /= raw_loader->imgdata.color.maximum; val *= 65535; - if( row==10 && col==11 ) { + //if( row==10 && col==11 ) { //std::cout<<"raw pixel @ (0,0): val="<<*fptr<<" c="<<(int)ptr[sizeof(float)]< Date: Mon, 25 May 2015 17:37:51 +0200 Subject: [PATCH 11/13] Fixed bug in Lab processing --- src/operations/brightness_contrast_proc_lab.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/operations/brightness_contrast_proc_lab.hh b/src/operations/brightness_contrast_proc_lab.hh index afeb74130..c38523676 100644 --- a/src/operations/brightness_contrast_proc_lab.hh +++ b/src/operations/brightness_contrast_proc_lab.hh @@ -11,6 +11,8 @@ class BrightnessContrastProc typename FormatInfo::SIGNED newval = (intensity*par->get_contrast()+1.0f)*val + intensity*par->get_brightness()*FormatInfo::RANGE + FormatInfo::HALF; clip(newval,pout[x]); + pout[x+1] = p[first][x+1]; + pout[x+2] = p[first][x+2]; } }; From f309b8cc7ac820ab681fc27e582334630c961bf3 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Mon, 25 May 2015 17:40:20 +0200 Subject: [PATCH 12/13] Fixed computation of saturation adjustment. Switched from HSV to HSL colorspace for interal computations. --- src/operations/hue_saturation.hh | 65 ++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 4 deletions(-) diff --git a/src/operations/hue_saturation.hh b/src/operations/hue_saturation.hh index ca230dc1e..623b312ca 100644 --- a/src/operations/hue_saturation.hh +++ b/src/operations/hue_saturation.hh @@ -94,7 +94,7 @@ namespace PF T* pin; T* pout; T R, G, B; - float h, s, v; + float h, s, v, l; int x, y; for( y = 0; y < height; y++ ) { @@ -105,7 +105,8 @@ namespace PF R = pin[x]; G = pin[x+1]; B = pin[x+2]; - rgb2hsv( R, G, B, h, s, v ); + //rgb2hsv( R, G, B, h, s, v ); + rgb2hsl( R, G, B, h, s, l ); //std::cout<<"in RGB: "< 360 ) h -= 360; else if( h < 0 ) h+= 360; - s += opar->get_saturation(); + s *= (1.0f+opar->get_saturation()); if( s < 0 ) s = 0; else if( s > 1 ) s = 1; - hsv2rgb2( h, s, v, R, G, B ); + //hsv2rgb2( h, s, v, R, G, B ); + hsl2rgb( h, s, l, R, G, B ); //std::cout<<"out RGB: "< + class HueSaturation< OP_TEMPLATE_IMP_CS_SPEC(PF_COLORSPACE_LAB) > + { + public: + void render(VipsRegion** ireg, int n, int in_first, + VipsRegion* imap, VipsRegion* omap, + VipsRegion* oreg, OpParBase* par) + { + HueSaturationPar* opar = dynamic_cast(par); + if( !opar ) return; + Rect *r = &oreg->valid; + int line_size = r->width * oreg->im->Bands; + //int width = r->width; + int height = r->height; + + T* pin; + T* pout; + typename PF::FormatInfo::SIGNED a, b; + int x, y; + + float sat = 1.0f; + if( opar->get_saturation() > 0 ) sat += opar->get_saturation(); + else { + sat -= opar->get_saturation(); + sat = 1.0f / sat; + } + + for( y = 0; y < height; y++ ) { + pin = (T*)VIPS_REGION_ADDR( ireg[in_first], r->left, r->top + y ); + pout = (T*)VIPS_REGION_ADDR( oreg, r->left, r->top + y ); + + for( x = 0; x < line_size; x+=3 ) { + a = pin[x+1]; + b = pin[x+2]; + + a -= PF::FormatInfo::HALF; + b -= PF::FormatInfo::HALF; + + a *= sat; + b *= sat; + + a += PF::FormatInfo::HALF; + b += PF::FormatInfo::HALF; + + pout[x] = pin[x]; + clip( a, pout[x+1] ); + clip( b, pout[x+2] ); + } + } + } + }; + + + ProcessorBase* new_hue_saturation(); } From e73bf99376d9e099e24dd87a14a3c945725c2f18 Mon Sep 17 00:00:00 2001 From: aferrero2707 Date: Mon, 25 May 2015 17:40:41 +0200 Subject: [PATCH 13/13] Bunped version to 0.1.1 --- CHANGELOG | 19 +++++++++++++++++++ VERSION | 3 +-- tools/bump_version.sh | 13 +++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) create mode 100755 tools/bump_version.sh diff --git a/CHANGELOG b/CHANGELOG index 09661d8d5..120e95503 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,3 +1,22 @@ +========================================= +Version 0.1.1 + +- Added file name widget to RAW loader dialog. This allows + to edit multiple RAW files simultaneously in the same image. + +- Added digital watermarking tool based on G'MIC "watermark_fourier" filter. + +- Modified Hue/saturation and brightess/contrast tools to work correctly also in Lab colorspace. +- Fixed computation of saturation adjustment. Now the saturation slider produces exactly the same + output as the equivalent tool in GIMP (except that computations are in 32-bits floating point + precision and are applied non-destructively). Internally, the hue/saturation tool now works + in the HSL colorspace like GIMP (instead of the HSV colorspace used before). + +- Moved "RAW developer" tool into "Load" tab and removed "raw" tab. +- Moved "Color profle conversion" tool into "Color" tab and removed "conv" tab. + +- Quality of Jpeg output set to "100". + ========================================= Version 0.1.0 diff --git a/VERSION b/VERSION index 49b49e48b..17e51c385 100644 --- a/VERSION +++ b/VERSION @@ -1,2 +1 @@ -0.1.0 - +0.1.1 diff --git a/tools/bump_version.sh b/tools/bump_version.sh new file mode 100755 index 000000000..3c80ebd49 --- /dev/null +++ b/tools/bump_version.sh @@ -0,0 +1,13 @@ +#! /bin/bash + +version="$1" + +echo "$version" > VERSION + +cp CHANGELOG /tmp/__CHANGELOG__ + +echo "=========================================" > CHANGELOG +echo "Version $version" >> CHANGELOG +echo "" >> CHANGELOG +cat /tmp/__CHANGELOG__ >> CHANGELOG +rm /tmp/__CHANGELOG__