From 57b624ac96ad10bf641eea4f6e275b73f9bdcb5a Mon Sep 17 00:00:00 2001
From: Santanu Sinha
Date: Fri, 4 Sep 2009 12:39:57 +0530
Subject: [PATCH] Modifications in editing infrastructure
This patch introduces solang to GEGL. That is the primal infrastrutural change. Others are just supportive changes. Some operations have been added as proof of concept.
+ Introduction of GEGL based editing engine
+ Introduction of editing toolbar
+ Introduction of histogram in properties and editing
+ Introduction of cursor changer
+ Added the following editing operation:
Scaling (Pixbuf based)
Brightness (Gegl based)
Contrast (Gegl based)
Saturation (Pixbuf based)
---
configure.ac | 3 +
data/edit-toolbar.ui | 47 +++++
data/solang-editor.ui | 21 ++-
data/solang-thumbnail-popup.ui | 2 +-
data/solang.ui | 5 +
src/Makefile.am | 1 +
src/application/Makefile.am | 8 +-
src/application/application.cpp | 2 +
src/application/main-window.cpp | 30 +++-
src/application/main-window.h | 16 ++-
src/application/main.cpp | 24 +++
src/attribute/property-manager.cpp | 6 +
src/attribute/property-manager.h | 3 +
src/common/Makefile.am | 8 +
src/common/cursor-changer.h | 34 +++
src/common/histogram-viewer.cpp | 179 +++++++++++++++++
src/common/histogram-viewer.h | 84 ++++++++
src/common/histogram.cpp | 323 ++++++++++++++++++++++++++++++
src/common/histogram.h | 75 +++++++
src/common/progress-observer.cpp | 2 +
src/common/types.h | 16 ++
src/edit-engine/Makefile.am | 45 ++++
src/edit-engine/brightness-operation.cpp | 62 ++++++
src/edit-engine/brightness-operation.h | 52 +++++
src/edit-engine/buffer.cpp | 210 +++++++++++++++++++
src/edit-engine/buffer.h | 100 +++++++++
src/edit-engine/contrast-operation.cpp | 63 ++++++
src/edit-engine/contrast-operation.h | 52 +++++
src/edit-engine/desaturate-operation.cpp | 64 ++++++
src/edit-engine/desaturate-operation.h | 52 +++++
src/edit-engine/edit-engine.cpp | 89 ++++++++
src/edit-engine/edit-engine.h | 77 +++++++
src/edit-engine/edit-types.h | 41 ++++
src/edit-engine/edit-utils.h | 45 ++++
src/edit-engine/filter.cpp | 76 +++++++
src/edit-engine/filter.h | 76 +++++++
src/edit-engine/flip-operation.cpp | 64 ++++++
src/edit-engine/flip-operation.h | 59 ++++++
src/edit-engine/load-file.cpp | 61 ++++++
src/edit-engine/load-file.h | 50 +++++
src/edit-engine/operation.cpp | 107 ++++++++++
src/edit-engine/operation.h | 53 +++++
src/edit-engine/scale-operation.cpp | 64 ++++++
src/edit-engine/scale-operation.h | 52 +++++
src/editor/Makefile.am | 30 +++-
src/editor/brightness-widget.cpp | 62 ++++++
src/editor/brightness-widget.h | 33 +++
src/editor/contrast-widget.cpp | 63 ++++++
src/editor/contrast-widget.h | 33 +++
src/editor/desaturate-widget.cpp | 52 +++++
src/editor/desaturate-widget.h | 33 +++
src/editor/desaturate.cpp | 88 ++++++++
src/editor/desaturate.h | 48 +++++
src/editor/edit-action-widget.cpp | 36 ++++
src/editor/edit-action-widget.h | 39 ++++
src/editor/editable-photo.cpp | 62 ++++++-
src/editor/editable-photo.h | 29 ++-
src/editor/editor-toolbar.cpp | 52 +++++
src/editor/editor-toolbar.h | 58 ++++++
src/editor/editor.cpp | 96 ++++++++-
src/editor/editor.h | 32 +++
src/editor/flip-widget.cpp | 63 ++++++
src/editor/flip-widget.h | 49 +++++
src/editor/gegl-operation.cpp | 94 +++++++++
src/editor/gegl-operation.h | 51 +++++
src/editor/rotate-widget.cpp | 63 ++++++
src/editor/rotate-widget.h | 49 +++++
src/editor/scale-widget.cpp | 52 +++++
src/editor/scale-widget.h | 33 +++
src/editor/scale.cpp | 70 +++++++
src/editor/scale.h | 48 +++++
src/editor/stock-button.cpp | 21 ++
src/editor/stock-button.h | 22 ++
src/renderer/Makefile.am | 3 +
src/renderer/editor-renderer.cpp | 133 +++++++++++--
src/renderer/editor-renderer.h | 12 +-
76 files changed, 4064 insertions(+), 48 deletions(-)
create mode 100644 data/edit-toolbar.ui
create mode 100644 src/common/cursor-changer.h
create mode 100644 src/common/histogram-viewer.cpp
create mode 100644 src/common/histogram-viewer.h
create mode 100644 src/common/histogram.cpp
create mode 100644 src/common/histogram.h
create mode 100644 src/edit-engine/Makefile.am
create mode 100644 src/edit-engine/brightness-operation.cpp
create mode 100644 src/edit-engine/brightness-operation.h
create mode 100644 src/edit-engine/buffer.cpp
create mode 100644 src/edit-engine/buffer.h
create mode 100644 src/edit-engine/contrast-operation.cpp
create mode 100644 src/edit-engine/contrast-operation.h
create mode 100644 src/edit-engine/desaturate-operation.cpp
create mode 100644 src/edit-engine/desaturate-operation.h
create mode 100644 src/edit-engine/edit-engine.cpp
create mode 100644 src/edit-engine/edit-engine.h
create mode 100644 src/edit-engine/edit-types.h
create mode 100644 src/edit-engine/edit-utils.h
create mode 100644 src/edit-engine/filter.cpp
create mode 100644 src/edit-engine/filter.h
create mode 100644 src/edit-engine/flip-operation.cpp
create mode 100644 src/edit-engine/flip-operation.h
create mode 100644 src/edit-engine/load-file.cpp
create mode 100644 src/edit-engine/load-file.h
create mode 100644 src/edit-engine/operation.cpp
create mode 100644 src/edit-engine/operation.h
create mode 100644 src/edit-engine/scale-operation.cpp
create mode 100644 src/edit-engine/scale-operation.h
create mode 100644 src/editor/brightness-widget.cpp
create mode 100644 src/editor/brightness-widget.h
create mode 100644 src/editor/contrast-widget.cpp
create mode 100644 src/editor/contrast-widget.h
create mode 100644 src/editor/desaturate-widget.cpp
create mode 100644 src/editor/desaturate-widget.h
create mode 100644 src/editor/desaturate.cpp
create mode 100644 src/editor/desaturate.h
create mode 100644 src/editor/edit-action-widget.cpp
create mode 100644 src/editor/edit-action-widget.h
create mode 100644 src/editor/editor-toolbar.cpp
create mode 100644 src/editor/editor-toolbar.h
create mode 100644 src/editor/flip-widget.cpp
create mode 100644 src/editor/flip-widget.h
create mode 100644 src/editor/gegl-operation.cpp
create mode 100644 src/editor/gegl-operation.h
create mode 100644 src/editor/rotate-widget.cpp
create mode 100644 src/editor/rotate-widget.h
create mode 100644 src/editor/scale-widget.cpp
create mode 100644 src/editor/scale-widget.h
create mode 100644 src/editor/scale.cpp
create mode 100644 src/editor/scale.h
create mode 100644 src/editor/stock-button.cpp
create mode 100644 src/editor/stock-button.h
diff --git a/configure.ac b/configure.ac
index b2a9aff..7a6edf6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -36,6 +36,8 @@ PKG_CHECK_MODULES(GTKMM, [gtkmm-2.4 >= 2.8])
PKG_CHECK_MODULES(SIGC, [sigc++-2.0])
PKG_CHECK_MODULES(SOUP, [libsoup-2.4])
PKG_CHECK_MODULES(WEBKIT, [webkit-1.0])
+PKG_CHECK_MODULES(BABL, [babl])
+PKG_CHECK_MODULES(GEGL, [gegl])
AC_OUTPUT([
@@ -46,6 +48,7 @@ src/application/Makefile
src/attribute/Makefile
src/common/Makefile
src/database/Makefile
+src/edit-engine/Makefile
src/editor/Makefile
src/exporter/Makefile
src/importer/Makefile
diff --git a/data/edit-toolbar.ui b/data/edit-toolbar.ui
new file mode 100644
index 0000000..d8abde1
--- /dev/null
+++ b/data/edit-toolbar.ui
@@ -0,0 +1,47 @@
+
+
+
+
+
+
+
+
diff --git a/data/solang-editor.ui b/data/solang-editor.ui
index dbc97c0..b61a171 100644
--- a/data/solang-editor.ui
+++ b/data/solang-editor.ui
@@ -11,12 +11,29 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/data/solang-thumbnail-popup.ui b/data/solang-thumbnail-popup.ui
index df99480..55b68e3 100644
--- a/data/solang-thumbnail-popup.ui
+++ b/data/solang-thumbnail-popup.ui
@@ -5,7 +5,7 @@
-
+
diff --git a/data/solang.ui b/data/solang.ui
index 224e100..c8d00c8 100644
--- a/data/solang.ui
+++ b/data/solang.ui
@@ -40,4 +40,9 @@
+
+
+
+
+
diff --git a/src/Makefile.am b/src/Makefile.am
index 23a9f08..e2e380b 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -2,6 +2,7 @@ SUBDIRS = \
attribute \
common \
database \
+ edit-engine \
editor \
exporter \
importer \
diff --git a/src/application/Makefile.am b/src/application/Makefile.am
index 0c2577f..ddd844b 100644
--- a/src/application/Makefile.am
+++ b/src/application/Makefile.am
@@ -23,6 +23,7 @@ solang_LDADD = \
$(top_builddir)/src/database/libdatabase.la \
$(top_builddir)/src/common/libcommon.la \
$(top_builddir)/src/editor/libeditor.la \
+ $(top_builddir)/src/edit-engine/libeditengine.la \
$(EXIV2_LIBS) \
$(FLICKCURL_LIBS) \
$(GPHOTO2_LIBS) \
@@ -35,7 +36,9 @@ solang_LDADD = \
$(GIOMM_LIBS) \
$(GLIBMM_LIBS) \
$(GDL_LIBS) \
- $(SIGC_LIBS)
+ $(SIGC_LIBS) \
+ $(BABL_LIBS) \
+ $(GEGL_LIBS)
AM_CPPFLAGS = \
-DPACKAGE_LOCALE_DIR=\""${datadir}/locale"\" \
@@ -62,7 +65,8 @@ AM_CPPFLAGS = \
$(GIOMM_CFLAGS) \
$(GLIBMM_CFLAGS) \
$(GDL_CFLAGS) \
- $(SIGC_CFLAGS)
+ $(SIGC_CFLAGS) \
+ $(GEGL_CFLAGS)
AM_CXXFLAGS = \
-Wall
diff --git a/src/application/application.cpp b/src/application/application.cpp
index 3abfdf4..7a3b559 100644
--- a/src/application/application.cpp
+++ b/src/application/application.cpp
@@ -349,6 +349,8 @@ Application::init() throw()
mainWindow_.init();
+ mainWindow_.connect_progress( engine_.get_default_observer() );
+
initEnd_.emit(*this);
}
diff --git a/src/application/main-window.cpp b/src/application/main-window.cpp
index 1323465..be544c5 100644
--- a/src/application/main-window.cpp
+++ b/src/application/main-window.cpp
@@ -29,6 +29,7 @@
#include
#include "main-window.h"
+#include "progress-observer.h"
namespace Solang
{
@@ -51,7 +52,7 @@ class Docker :
const GdlDockPlacement placement) throw();
Docker(const Docker & source) throw();
-
+
~Docker() throw();
Docker &
@@ -191,6 +192,8 @@ MainWindow::MainWindow() throw() :
spinnerToolItem_(),
hBox_(false, 6),
statusBar_(),
+ progress_(),
+ observer_(),
dock_(gdl_dock_new()),
dockBar_(gdl_dock_bar_new(GDL_DOCK(dock_))),
layout_(gdl_dock_layout_new(GDL_DOCK(dock_))),
@@ -272,6 +275,8 @@ MainWindow::MainWindow() throw() :
if (NULL != tool_bar)
{
+ tool_bar->set_toolbar_style( Gtk::TOOLBAR_ICONS );
+ //We don't need no stinkin' text :-P
gtk_separator_tool_item_set_draw(separatorToolItem_.gobj(),
FALSE);
separatorToolItem_.set_expand(true);
@@ -289,6 +294,7 @@ MainWindow::MainWindow() throw() :
statusBar_.set_has_resize_grip(true);
vBox_.pack_start(statusBar_, Gtk::PACK_SHRINK, 0);
+ statusBar_.pack_start( progress_, Gtk::PACK_EXPAND_WIDGET, 0);
show_all_children();
}
@@ -654,7 +660,7 @@ MainWindow::on_delete_event(GdkEventAny * event)
bool return_value = Gtk::Window::on_delete_event(event);
hide();
- return return_value;
+ return return_value;
}
void
@@ -679,4 +685,24 @@ MainWindow::set_busy(bool busy) throw()
spinnerToolItem_.set_spinning(busy);
}
+void
+MainWindow::connect_progress( const ProgressObserverPtr &observer ) throw()
+{
+ observer_ = observer;
+ progress_.set_fraction( 0.0L );
+ observer_->progress().connect( sigc::mem_fun(*this,
+ &MainWindow::handle_progress_event) );
+}
+
+void
+MainWindow::handle_progress_event() throw()
+{
+ double percentage =
+ static_cast(
+ observer_->get_current_events())
+ / static_cast(
+ observer_->get_num_events()) ;
+ progress_.set_fraction( percentage );
+}
+
} // namespace Solang
diff --git a/src/application/main-window.h b/src/application/main-window.h
index e74a3f8..c562823 100644
--- a/src/application/main-window.h
+++ b/src/application/main-window.h
@@ -37,7 +37,7 @@ class MainWindow :
{
public:
MainWindow() throw();
-
+
virtual
~MainWindow() throw();
@@ -68,6 +68,11 @@ class MainWindow :
void
set_busy(bool busy) throw();
+ void
+ connect_progress(
+ const ProgressObserverPtr &observer ) throw();
+
+
protected:
std::string
get_user_layout_file() throw();
@@ -91,6 +96,9 @@ class MainWindow :
virtual bool
on_delete_event(GdkEventAny * event);
+ void
+ handle_progress_event() throw();
+
ActionGroupPtr actionGroup_;
UIManagerPtr uiManager_;
@@ -107,8 +115,12 @@ class MainWindow :
Gtk::Statusbar statusBar_;
+ Gtk::ProgressBar progress_;
+
+ ProgressObserverPtr observer_;
+
GtkWidget * const dock_;
-
+
GtkWidget * const dockBar_;
GdlDockLayout * const layout_;
diff --git a/src/application/main.cpp b/src/application/main.cpp
index 8f21b90..d368d83 100644
--- a/src/application/main.cpp
+++ b/src/application/main.cpp
@@ -24,6 +24,7 @@
#include
#include
+#include
#include
#include
#include
@@ -46,6 +47,7 @@ main(int argc, char *argv[])
Glib::thread_init();
Gio::init();
Gnome::Gda::init(PACKAGE_NAME, PACKAGE_VERSION, argc, argv);
+ gegl_init( &argc, &argv );
if (0 != flickcurl_init())
{
@@ -57,6 +59,28 @@ main(int argc, char *argv[])
Glib::set_application_name(_(PACKAGE_NAME));
Gtk::Main kit(argc, argv, true);
+ GeglConfig *pConfig = gegl_config();
+ {
+ GValue cacheSize = {0};
+ g_value_init( &cacheSize, G_TYPE_INT );
+ g_value_set_int( &cacheSize, 102400 );
+ g_object_set_property( (GObject *)pConfig, "cache-size", &cacheSize );
+ g_value_unset( &cacheSize );
+ }
+ {
+ GValue quality = {0};
+ g_value_init( &quality, G_TYPE_DOUBLE );
+ g_value_set_double( &quality, 0.1 );
+ g_object_set_property( (GObject *)pConfig, "quality", &quality );
+ g_value_unset( &quality );
+ }
+ {
+ GValue swap = {0};
+ g_value_init( &swap, G_TYPE_STRING );
+ g_value_set_string( &swap, "/tmp" );
+ g_object_set_property( (GObject *)pConfig, "swap", &swap );
+ g_value_unset( &swap );
+ }
Solang::Application application(argc, argv);
application.init();
diff --git a/src/attribute/property-manager.cpp b/src/attribute/property-manager.cpp
index c9cc705..905fd53 100644
--- a/src/attribute/property-manager.cpp
+++ b/src/attribute/property-manager.cpp
@@ -51,6 +51,8 @@ PropertyManager::PropertyManager() throw() :
vBox_(false, 6),
basicInfo_(),
basicExifView_(),
+ histBox_(),
+ histogram_(),
signalRendererChanged_()
{
dockItem_ = gdl_dock_item_new_with_stock(dockItemName_.c_str(),
@@ -64,7 +66,10 @@ PropertyManager::PropertyManager() throw() :
Gtk::POLICY_AUTOMATIC);
basicInfo_.add(basicExifView_);
+ histBox_.pack_start( histogram_, Gtk::PACK_SHRINK, 6 );
+
noteBook_.append_page( vBox_, _("Basic") );
+ noteBook_.append_page( histBox_, _("Histogram") );
vBox_.pack_start( basicInfo_, Gtk::PACK_EXPAND_WIDGET,0 );
}
@@ -174,6 +179,7 @@ PropertyManager::on_selection_changed() throw()
return;
basicExifView_.populate( (*photos.begin())->get_exif_data() );
+ histogram_.set((*photos.begin())->get_thumbnail_buffer());
return;
}
diff --git a/src/attribute/property-manager.h b/src/attribute/property-manager.h
index ed25f61..f1d7230 100644
--- a/src/attribute/property-manager.h
+++ b/src/attribute/property-manager.h
@@ -27,6 +27,7 @@
#include "plugin.h"
#include "basic-exif-view.h"
+#include "histogram-viewer.h"
namespace Solang
{
@@ -96,6 +97,8 @@ protected:
Gtk::VBox vBox_;
Gtk::ScrolledWindow basicInfo_;
BasicExifView basicExifView_;
+ Gtk::VBox histBox_;
+ HistogramViewer histogram_;
sigc::connection signalRendererChanged_;
diff --git a/src/common/Makefile.am b/src/common/Makefile.am
index a08ab86..d39ef74 100644
--- a/src/common/Makefile.am
+++ b/src/common/Makefile.am
@@ -3,10 +3,15 @@ noinst_LTLIBRARIES = libcommon.la
libcommon_la_SOURCES = \
content-type-repo.cpp \
content-type-repo.h \
+ cursor-changer.h \
error.cpp \
error.h \
flickr-context.cpp \
flickr-context.h \
+ histogram-viewer.cpp \
+ histogram-viewer.h \
+ histogram.cpp \
+ histogram.h \
id-base.h \
id-repo.cpp \
id-repo.h \
@@ -54,6 +59,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/src/attribute \
-I$(top_srcdir)/src/common \
-I$(top_srcdir)/src/database \
+ -I$(top_srcdir)/src/edit-engine \
-I$(top_srcdir)/src/importer \
-I$(top_srcdir)/src/renderer \
-I$(top_srcdir)/src/storage \
@@ -65,6 +71,8 @@ AM_CPPFLAGS = \
$(GIOMM_CFLAGS) \
$(GLIBMM_CFLAGS) \
$(GDL_CFLAGS) \
+ $(GEGL_CFLAGS) \
+ $(BABL_CFLAGS) \
$(SIGC_CFLAGS)
AM_CXXFLAGS = \
diff --git a/src/common/cursor-changer.h b/src/common/cursor-changer.h
new file mode 100644
index 0000000..c48ba70
--- /dev/null
+++ b/src/common/cursor-changer.h
@@ -0,0 +1,34 @@
+#ifndef SOLANG_CURSOR_CHANGER_H
+#define SOLANG_CURSOR_CHANGER_H
+
+namespace Solang
+{
+
+class CursorChanger
+{
+ public:
+ CursorChanger(Gtk::Widget &widget)
+ :widget_( widget )
+ {
+ widget_.get_window()->set_cursor(
+ Gdk::Cursor( widget_.get_display(),
+ Gdk::WATCH ) );
+ widget_.set_sensitive( false );
+ }
+
+ ~CursorChanger()
+ {
+ widget_.get_window()->set_cursor();
+ widget_.set_sensitive( true );
+ }
+
+
+ private:
+ Gtk::Widget &widget_;
+
+};
+
+}
+
+#endif //SOLANG_CURSOR_CHANGER_H
+
diff --git a/src/common/histogram-viewer.cpp b/src/common/histogram-viewer.cpp
new file mode 100644
index 0000000..6cec06e
--- /dev/null
+++ b/src/common/histogram-viewer.cpp
@@ -0,0 +1,179 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif //HAVE_CONFIG_H
+
+#include
+
+#include "histogram-viewer.h"
+
+namespace Solang
+{
+
+HistogramViewer::HistogramViewer( bool autoupdate )
+ :histogram_(),
+ width_( 192 ),
+ height_( 144 ),
+ image_(),
+ histogramView_(),
+ hbType_(),
+ lblType_( _("Type") ),
+ typeCols_(),
+ typeStore_( Gtk::ListStore::create( typeCols_ ) ),
+ cmbType_(),
+ hbChannels_(),
+ lblChannels_( _("Channels") ),
+ channelCols_(),
+ channelStore_( Gtk::ListStore::create( channelCols_ ) ),
+ cmbChannels_(),
+ autoupdate_( true )
+{
+ hbType_.pack_start( lblType_, Gtk::PACK_SHRINK, 6 );
+ hbType_.pack_start( cmbType_, Gtk::PACK_EXPAND_WIDGET, 6 );
+ pack_start( hbType_, Gtk::PACK_EXPAND_WIDGET, 6);
+
+ histogramView_.set_size_request( 192, 144 );
+ pack_start(histogramView_, Gtk::PACK_EXPAND_WIDGET, 6);
+
+ hbChannels_.pack_start( lblChannels_, Gtk::PACK_SHRINK, 6 );
+ hbChannels_.pack_end( cmbChannels_, Gtk::PACK_EXPAND_WIDGET, 6 );
+ pack_start( hbChannels_, Gtk::PACK_SHRINK, 6 );
+
+ cmbType_.set_model( typeStore_ );
+ cmbType_.pack_start( typeCols_.name_ );
+ cmbChannels_.set_model( channelStore_ );
+ cmbChannels_.pack_start( channelCols_.name_ );
+ //Types
+ {
+ Gtk::TreeModel::Row row = *(typeStore_->append());
+ row[ typeCols_.type_ ] = Histogram::LINEAR;
+ row[ typeCols_.name_ ] = _("Linear") ;
+ }
+ {
+ Gtk::TreeModel::Row row = *(typeStore_->append());
+ row[ typeCols_.type_ ] = Histogram::LOGARITHMIC;
+ row[ typeCols_.name_ ] = _("Logarithmic") ;
+ }
+ cmbType_.set_active( 0 );
+
+ //Channels
+ {
+ Gtk::TreeModel::Row row = *(channelStore_->append());
+ row[ channelCols_.channel_ ] = Histogram::RGB;
+ row[ channelCols_.name_ ] = _("RGB") ;
+ }
+ {
+ Gtk::TreeModel::Row row = *(channelStore_->append());
+ row[ channelCols_.channel_ ] = Histogram::RED;
+ row[ channelCols_.name_ ] = _("Red") ;
+ }
+ {
+ Gtk::TreeModel::Row row = *(channelStore_->append());
+ row[ channelCols_.channel_ ] = Histogram::GREEN;
+ row[ channelCols_.name_ ] = _("Green") ;
+ }
+ {
+ Gtk::TreeModel::Row row = *(channelStore_->append());
+ row[ channelCols_.channel_ ] = Histogram::BLUE;
+ row[ channelCols_.name_ ] = _("Blue") ;
+ }
+ cmbChannels_.set_active( 0 );
+
+ cmbType_.signal_changed().connect(
+ sigc::mem_fun( *this, &HistogramViewer::update ) );
+ cmbChannels_.signal_changed().connect(
+ sigc::mem_fun( *this, &HistogramViewer::update ) );
+ show_all_children();
+ signal_size_request().connect(
+ sigc::mem_fun( *this,
+ &HistogramViewer::size_changed ));
+ update();
+}
+
+HistogramViewer::~HistogramViewer()
+{
+}
+
+void
+HistogramViewer::set( const Glib::RefPtr &image )
+{
+ image_ = image;
+ if( image_ )
+ {
+ Histogram::DataBuffer imageData;
+ imageData.data_ = image_->get_pixels();
+ imageData.bitsPerChannel_ = image_->get_bits_per_sample();
+ imageData.numChannels_ = image_->get_n_channels();
+ imageData.width_ = image_->get_width();
+ imageData.height_ = image_->get_height();
+ imageData.rowstride_ = image_->get_rowstride();
+ histogram_.createData( imageData );
+ }
+ if( true == autoupdate_ )
+ update();
+}
+
+void
+HistogramViewer::set_auto_update( bool autoupdate )
+{
+ autoupdate_ = autoupdate;
+}
+
+void
+HistogramViewer::update()
+{
+ Gtk::TreeModel::const_iterator typeI
+ = cmbType_.get_active();
+ Gtk::TreeModel::Row typeR = (*typeI);
+ Histogram::Type type = typeR[ typeCols_.type_ ];
+ Gtk::TreeModel::const_iterator channelI
+ = cmbChannels_.get_active();
+ Gtk::TreeModel::Row channelR = (*channelI);
+ Histogram::Channel channel
+ = channelR[ channelCols_.channel_ ];
+ Glib::RefPtr pixbuf
+ = histogram_.get_pixbuf( type, width_, height_, channel );
+ histogramView_.set( pixbuf );
+ return;
+}
+void
+HistogramViewer::on_size_request( Gtk::Requisition *requisition )
+{
+ gint64 oldWidth = get_width();
+ gint64 oldHeight = get_height();
+ Gtk::VBox::on_size_request( requisition );
+#if 0
+ gint64 width = width_ + requisition->width - oldWidth;
+ gint64 height = height_ + requisition->height - oldHeight;
+ width_ = (width > 0 ) ? width : width_;
+ height_ = (height > 0 ) ? height : height_;
+#endif
+ //if( width_ > 0 && height_ > 0 )
+ // histogramView_.set_size_request( width_, height_ );
+ width_ = requisition->width;
+// height_ = requisition->height;
+#if 0
+ freeze_child_notify();
+ Glib::RefPtr buffer
+ = histogramView_.get_pixbuf();
+ if( !buffer )
+ return;
+ histogramView_.set( buffer->scale_simple( width_, height_,
+ Gdk::INTERP_HYPER ) );
+ thaw_child_notify();
+#endif
+ //update();
+}
+
+void
+HistogramViewer::size_changed(Gtk::Requisition *req)
+{
+#if 0
+ int width = req->width;
+ int height = get_height();
+ width_ = width;
+ //update();
+#endif
+
+}
+
+} //namespace Solang
diff --git a/src/common/histogram-viewer.h b/src/common/histogram-viewer.h
new file mode 100644
index 0000000..fd43751
--- /dev/null
+++ b/src/common/histogram-viewer.h
@@ -0,0 +1,84 @@
+#ifndef SOLANG_HISTOGRAM_VIEWER_H
+#define SOLANG_HISTOGRAM_VIEWER_H
+
+#include
+#include "histogram.h"
+
+namespace Solang
+{
+
+class HistogramViewer
+ : public Gtk::VBox
+{
+ private:
+ class TypeSelectColumns
+ : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+
+ TypeSelectColumns()
+ {
+ add( type_ );
+ add( name_ );
+ }
+
+ Gtk::TreeModelColumn type_;
+ Gtk::TreeModelColumn name_;
+ };
+ class ChannelSelectColumns
+ : public Gtk::TreeModel::ColumnRecord
+ {
+ public:
+
+ ChannelSelectColumns()
+ {
+ add( channel_ );
+ add( name_ );
+ }
+
+ Gtk::TreeModelColumn channel_;
+ Gtk::TreeModelColumn name_;
+ };
+
+
+ public:
+ HistogramViewer( bool autoupdate = false );
+ ~HistogramViewer();
+
+ void
+ set( const Glib::RefPtr &image );
+
+ void
+ set_auto_update( bool autoupdate = true );
+
+ void
+ update(); //Not required if autoupdate is set
+
+ private:
+ void
+ on_size_request(Gtk::Requisition *req);
+ void
+ size_changed(Gtk::Requisition *req);
+
+ Histogram histogram_;
+ gsize width_;
+ gsize height_;
+ Glib::RefPtr image_;
+ Gtk::Image histogramView_;
+ Gtk::HBox hbType_;
+ Gtk::Label lblType_;
+ TypeSelectColumns typeCols_;
+ Glib::RefPtr typeStore_;
+ Gtk::ComboBox cmbType_;
+ Gtk::HBox hbChannels_;
+ Gtk::Label lblChannels_;
+ ChannelSelectColumns channelCols_;
+ Glib::RefPtr channelStore_;
+ Gtk::ComboBox cmbChannels_;
+ bool autoupdate_;
+
+};
+
+} //namespace Solang
+
+#endif //SOLANG_HISTOGRAM_VIEWER_H
diff --git a/src/common/histogram.cpp b/src/common/histogram.cpp
new file mode 100644
index 0000000..caa1edb
--- /dev/null
+++ b/src/common/histogram.cpp
@@ -0,0 +1,323 @@
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+#include
+
+#include "histogram.h"
+
+namespace Solang
+{
+
+Histogram::Histogram()
+ :data_(NULL),
+ maxLevel_(0),
+ buffer_()
+{
+ max[0]=max[1]=max[2]=0;
+}
+
+Histogram::~Histogram()
+{
+ cleanup();
+}
+
+void
+Histogram::createData( const Histogram::DataBuffer &data )
+{
+ if( NULL != data_ )
+ cleanup();
+ buffer_ = data;
+ //Buffer is a 2D data-buffer
+ //Rows = 2^bitsPerChannel (256 for 8bit)
+ //Columns = 5 (R,G,B,A,Value)
+ gsize levels = 1 << data.bitsPerChannel_;
+ gsize channels = data.numChannels_;
+ gsize rowStride = data.rowstride_;
+ data_ = g_new0( guint32 *, channels );
+ for(guint channel = 0; channel < channels; channel++ )
+ {
+ data_[ channel ] = g_new0( guint32, levels );
+ ::bzero( data_[ channel ], levels * sizeof(guint32) );
+ }
+ guint8 *pixelData = data.data_;
+
+ //Buffer is created
+ guint8 *line = pixelData;
+ for( gsize i = 0; i < data.height_; i ++ )
+ {
+ guint8 *pixel = line;
+ line += rowStride;
+ for( gsize j = 0; j < data.width_; j ++ )
+ {
+ data_[ RED ][ pixel[ RED ] ]++;
+ data_[ GREEN ][ pixel[ GREEN ] ]++;
+ data_[ BLUE ][ pixel[ BLUE ] ]++;
+ pixel += data.numChannels_;
+ }
+ }
+
+ max[RED]=max[GREEN]=max[BLUE]=0;
+ for( gsize i = 0; i < levels; i++ )
+ {
+ guint32 r = data_[ RED ][ i ];
+ guint32 g = data_[ GREEN ][ i ];
+ guint32 b = data_[ BLUE ][ i ];
+ max[RED] = ( max[RED] < r )?r:max[RED];
+ max[GREEN] = ( max[GREEN] < g )?g:max[GREEN];
+ max[BLUE] = ( max[BLUE]< b )?b:max[BLUE];
+ }
+ guint64 total = 0L;
+ for( gsize i = 0; i < channels; i++ )
+ {
+ for( gsize j = 0; j < levels; j++ )
+ {
+ maxLevel_ = ( maxLevel_ < data_[ i ][ j ] )
+ ? data_[ i ][ j ] : maxLevel_;
+ total += data_[ i ][ j ];
+ }
+ }
+}
+
+Glib::RefPtr
+Histogram::get_pixbuf( Type type, gsize width, gsize height,
+ Channel channel ) throw()
+{
+ if( Histogram::LINEAR == type )
+ {
+ return get_linear_histogram( width, height, channel );
+ }
+ return get_logarithmic_histogram(
+ width, height, channel );
+}
+
+Glib::RefPtr
+Histogram::get_logarithmic_histogram(
+ gsize resultWidth, gsize resultHeight,
+ Histogram::Channel resultChannel) throw()
+{
+ gsize maxLevel = 1 << buffer_.bitsPerChannel_;
+ gsize width = maxLevel;
+ gsize height = maxLevel;
+ guint8 *pixels = g_new0( guint8, width * height * 3);
+ memset( pixels, 0x28, 3 * width * height ); //dark grey
+
+ //Grid lines
+ for( guint32 i = 0; i < width; i += 64 )
+ {
+ for( guint32 j = 0; j < height; j+=4 )
+ {
+ guint8 *fill = ( pixels + ( i + j * width ) * 3 );
+ fill[ RED ] = fill[ GREEN ] = fill[ BLUE ] = 0x73;
+ }
+ }
+ for( guint32 i = 0; i < width; i +=4 )
+ {
+ for( guint32 j = 0; j < height; j+=64 )
+ {
+ guint8 *fill = ( pixels + ( i + j * width ) * 3 );
+ fill[ RED ] = fill[ GREEN ] = fill[ BLUE ] = 0x73;
+ }
+ }
+ if( !data_ )
+ {
+ Glib::RefPtr buf
+ = Gdk::Pixbuf::create_from_data(
+ (guint8 *)pixels,
+ Gdk::COLORSPACE_RGB,
+ false,
+ 8,
+ width,
+ height,
+ 3 * width )->flip( false )->
+ add_alpha(false, 0, 0, 0)->scale_simple(
+ resultWidth, resultHeight,
+ Gdk::INTERP_HYPER);
+ if( pixels )
+ g_free( pixels );
+
+ return buf;
+ }
+
+ for( gsize i = 0; i < maxLevel; i++ )
+ {
+ //we have to set rgb and A for each pixel
+ // and we are going L2R
+
+ //Considering we use only RGB channels
+ guint8 channel = 0;
+ guint32 maxVal = 0;
+ for( ; channel < 3; channel++ )
+ {
+ double level = (double)data_[ channel ][ i ];
+ double logLvl = (level>0)?log(level):0.0;
+ double logMax = (max[channel]>0)?log((double)max[channel]):1.0;
+ guint32 normLvl = (guint32)((double)( logLvl/logMax) * (double)(height-1));
+ maxVal = ( maxVal < normLvl ) ? normLvl : maxVal;
+ if( RGB == resultChannel
+ || channel == resultChannel )
+ {
+ for( gsize j = 0; j <= normLvl; j++ )
+ {
+ Pixel *fill = (Pixel *)(
+ pixels + (i + j * width)*3);
+ fill->channels_[ channel ]
+ |= (j + 2 > normLvl ) ? 0xFF : 0xAA;
+ }
+ }
+ }
+
+ //Demarkate value channel
+ for(guint32 j = maxVal - ((maxVal > 0 )?1:0);
+ j <= maxVal; j++ )
+ {
+ guint8 *fill = (pixels + (i + j * width)*3);
+ fill[ RED ] = fill[ GREEN ] = fill[ BLUE ] = 0xFF;
+ }
+ }
+
+ Glib::RefPtr buf
+ = Gdk::Pixbuf::create_from_data(
+ (guint8 *)pixels,
+ Gdk::COLORSPACE_RGB,
+ false,
+ 8,
+ width,
+ height,
+ 3 * width )->flip( false )->
+ add_alpha(false, 0, 0, 0)->scale_simple(
+ resultWidth, resultHeight,
+ Gdk::INTERP_HYPER);
+ if( pixels )
+ g_free( pixels );
+
+ return buf;
+
+}
+
+Glib::RefPtr
+Histogram::get_linear_histogram(
+ gsize resultWidth, gsize resultHeight,
+ Histogram::Channel resultChannel) throw()
+{
+ gsize maxLevel = 1 << buffer_.bitsPerChannel_;
+ gsize width = maxLevel;
+ gsize height = maxLevel;
+ guint8 *pixels = g_new0( guint8, width * height * 3);
+ memset( pixels, 0x28, 3 * width * height ); //dark grey
+
+ //Grid lines
+ for( guint32 i = 0; i < width; i += 64 )
+ {
+ for( guint32 j = 0; j < height; j+=4 )
+ {
+ guint8 *fill = ( pixels + ( i + j * width ) * 3 );
+ fill[ RED ] = fill[ GREEN ] = fill[ BLUE ] = 0x73;
+ }
+ }
+ for( guint32 i = 0; i < width; i +=4 )
+ {
+ for( guint32 j = 0; j < height; j+=64 )
+ {
+ guint8 *fill = ( pixels + ( i + j * width ) * 3 );
+ fill[ RED ] = fill[ GREEN ] = fill[ BLUE ] = 0x73;
+ }
+ }
+ if( !data_ )
+ {
+ Glib::RefPtr buf
+ = Gdk::Pixbuf::create_from_data(
+ (guint8 *)pixels,
+ Gdk::COLORSPACE_RGB,
+ false,
+ 8,
+ width,
+ height,
+ 3 * width )->flip( false )->
+ add_alpha(false, 0, 0, 0)->scale_simple(
+ resultWidth, resultHeight,
+ Gdk::INTERP_HYPER);
+ if( pixels )
+ g_free( pixels );
+
+ return buf;
+ }
+
+ for( gsize i = 0; i < maxLevel; i++ )
+ {
+ //we have to set rgb and A for each pixel
+ // and we are going L2R
+
+ //Considering we use only RGB channels
+ guint8 channel = 0;
+ guint32 maxVal = 0;
+ for( ; channel < 3; channel++ )
+ {
+ double level = (double)data_[ channel ][ i ];
+ guint32 normLvl = (guint32)((double)( level/maxLevel_ ) * (double)(height-1));
+ maxVal = ( maxVal < normLvl ) ? normLvl : maxVal;
+ if( RGB == resultChannel
+ || channel == resultChannel )
+ {
+ for( gsize j = 0; j <= normLvl; j++ )
+ {
+ Pixel *fill = (Pixel *)(
+ pixels + (i + j * width)*3);
+ fill->channels_[ channel ]
+ |= (j + 2 > normLvl ) ? 0xFF : 0xAA;
+ }
+ }
+ }
+
+ //Demarkate value channel
+ for(guint32 j = maxVal - ((maxVal > 0 )?1:0);
+ j <= maxVal; j++ )
+ {
+ guint8 *fill = (pixels + (i + j * width)*3);
+ fill[ RED ] = fill[ GREEN ] = fill[ BLUE ] = 0xFF;
+ }
+ }
+
+ Glib::RefPtr buf
+ = Gdk::Pixbuf::create_from_data(
+ (guint8 *)pixels,
+ Gdk::COLORSPACE_RGB,
+ false,
+ 8,
+ width,
+ height,
+ 3 * width )->flip( false )->
+ add_alpha(false, 0, 0, 0)->scale_simple(
+ resultWidth, resultHeight,
+ Gdk::INTERP_HYPER);
+ if( pixels )
+ g_free( pixels );
+
+ return buf;
+
+}
+
+void
+Histogram::cleanup()
+{
+ max[ RED ] = max[ GREEN ] = max[ BLUE ] = 0;
+ maxLevel_ = 0;
+ if( data_ )
+ {
+ gsize channels = buffer_.numChannels_;
+ for( gsize i = 0; i < channels; i++ )
+ {
+ if( data_[ i ] )
+ g_free( data_[ i ] );
+ }
+ g_free( data_ );
+ data_ = NULL;
+ }
+}
+
+} //namespace Solang
diff --git a/src/common/histogram.h b/src/common/histogram.h
new file mode 100644
index 0000000..5043355
--- /dev/null
+++ b/src/common/histogram.h
@@ -0,0 +1,75 @@
+#ifndef SOLANG_HISTOGRAM_H
+#define SOLANG_HISTOGRAM_H
+
+#include
+#include "types.h"
+
+namespace Solang
+{
+
+class Histogram
+{
+ public:
+ enum Channel
+ {
+ RED = 0,
+ GREEN,
+ BLUE,
+ RGB,
+ //ALPHA,
+ //VALUE
+ };
+ enum Type
+ {
+ LINEAR,
+ LOGARITHMIC
+ };
+
+ struct DataBuffer
+ {
+ guint8 *data_;
+ gsize size_;
+ guint8 bitsPerChannel_;
+ guint8 numChannels_;
+ gsize width_;
+ gsize height_;
+ gsize rowstride_;
+ };
+
+ Histogram( );
+ ~Histogram();
+
+ void
+ createData( const DataBuffer &data );
+
+ Glib::RefPtr
+ get_pixbuf( Type type, gsize width, gsize height,
+ Channel channel = RGB ) throw();
+
+ private:
+ Glib::RefPtr
+ get_logarithmic_histogram(
+ gsize width, gsize height,
+ Channel resultChannel ) throw();
+
+ Glib::RefPtr
+ get_linear_histogram(
+ gsize width, gsize height,
+ Channel resultChannel ) throw();
+
+ void
+ cleanup();
+
+ struct Pixel
+ {
+ guint8 channels_[3];
+ };
+ guint32 **data_;
+ guint32 max[3];
+ guint32 maxLevel_;
+ DataBuffer buffer_;
+
+};
+
+} //namespace Solang
+#endif //SOLANG_HISTOGRAM_H
diff --git a/src/common/progress-observer.cpp b/src/common/progress-observer.cpp
index 2f66b1c..ad23a34 100644
--- a/src/common/progress-observer.cpp
+++ b/src/common/progress-observer.cpp
@@ -75,6 +75,7 @@ ProgressObserver::set_current_events(guint64 current_events) throw()
{
Glib::Mutex::Lock lock(mutex_);
currentEvents_ = current_events;
+ progress_.emit();
}
void
@@ -112,6 +113,7 @@ ProgressObserver::reset() throw()
currentEvents_ = 0;
numEvents_ = 0;
stop_ = false;
+ progress_.emit();
}
} // namespace Solang
diff --git a/src/common/types.h b/src/common/types.h
index d89b705..a5d241e 100644
--- a/src/common/types.h
+++ b/src/common/types.h
@@ -152,6 +152,8 @@ class ProgressDialog;
typedef Glib::RefPtr ConstProgressDialogPtr;
typedef Glib::RefPtr ProgressDialogPtr;
+typedef Glib::RefPtr DispatcherPtr;
+
class ProgressObserver;
typedef std::tr1::shared_ptr
ConstProgressObserverPtr;
@@ -254,6 +256,20 @@ typedef std::vector TreePathList;
typedef Glib::RefPtr ConstUIManagerPtr;
typedef Glib::RefPtr UIManagerPtr;
+//Editing engine
+class Buffer;
+typedef std::tr1::shared_ptr BufferPtr;
+
+class EditEngine;
+typedef EditEngine *EditEnginePtr;
+
+class Filter;
+typedef std::tr1::shared_ptr FilterPtr;
+
+class Operation;
+typedef std::tr1::shared_ptr OperationPtr;
+
+
} // namespace Solang
#endif // SOLANG_TYPES_H
diff --git a/src/edit-engine/Makefile.am b/src/edit-engine/Makefile.am
new file mode 100644
index 0000000..08a0eb4
--- /dev/null
+++ b/src/edit-engine/Makefile.am
@@ -0,0 +1,45 @@
+noinst_LTLIBRARIES = libeditengine.la
+
+libeditengine_la_SOURCES = \
+ brightness-operation.cpp \
+ brightness-operation.h \
+ contrast-operation.cpp \
+ contrast-operation.h \
+ buffer.cpp \
+ buffer.h \
+ edit-types.h \
+ edit-engine.h \
+ edit-engine.cpp \
+ filter.cpp \
+ filter.h \
+ flip-operation.cpp \
+ flip-operation.h \
+ load-file.cpp \
+ load-file.h \
+ operation.cpp \
+ operation.h \
+ scale-operation.cpp \
+ scale-operation.h
+
+AM_CPPFLAGS = \
+ -DPACKAGE_LOCALE_DIR=\""${datadir}/locale"\" \
+ -DPACKAGE_SRC_DIR=\""$(srcdir)"\" \
+ -DPACKAGE_DATA_DIR=\""$(datadir)"\" \
+ -I$(top_builddir) \
+ -I$(top_srcdir)/src/application \
+ -I$(top_srcdir)/src/common \
+ -I$(top_srcdir)/src/edit-engine \
+ -I$(top_srcdir)/src/renderer \
+ $(SOLANG_CFLAGS) \
+ $(CAIROMM_CFLAGS) \
+ $(EXIV2_CFLAGS) \
+ $(GTKMM_CFLAGS) \
+ $(GDAMM_CFLAGS) \
+ $(GIOMM_CFLAGS) \
+ $(GLIBMM_CFLAGS) \
+ $(GDL_CFLAGS) \
+ $(GEGL_CFLAGS) \
+ $(SIGC_CFLAGS)
+
+AM_CXXFLAGS = \
+ -Wall
diff --git a/src/edit-engine/brightness-operation.cpp b/src/edit-engine/brightness-operation.cpp
new file mode 100644
index 0000000..94d89f6
--- /dev/null
+++ b/src/edit-engine/brightness-operation.cpp
@@ -0,0 +1,62 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2009 Santanu Sinha
+ *
+ * Solang 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.
+ *
+ * Solang 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 .
+ */
+
+#ifndef HAVE_CONFIG_H
+#include "config.h"
+#endif //HAVE_CONFIG_H
+
+#include
+#include
+
+#include "edit-engine.h"
+#include "brightness-operation.h"
+
+namespace Solang
+{
+
+BrightnessOperation::BrightnessOperation( const EditEnginePtr &engine,
+ double fraction )
+ :Filter( engine ),
+ fraction_( fraction )
+{
+ GeglNodePtr pAction = gegl_node_new_child(
+ get_engine()->get_root_node(),
+ "operation", "gegl:brightness-contrast",
+ "brightness", fraction,
+ NULL);
+ set_execution_node( pAction );
+}
+
+BrightnessOperation::~BrightnessOperation() throw()
+{
+}
+
+Glib::ustring
+BrightnessOperation::get_name() const throw()
+{
+ return _("Brightness");
+}
+
+Glib::ustring
+BrightnessOperation::get_description() const throw()
+{
+ return _("Brighten image");
+}
+
+
+} //namespace Solang
diff --git a/src/edit-engine/brightness-operation.h b/src/edit-engine/brightness-operation.h
new file mode 100644
index 0000000..f20606a
--- /dev/null
+++ b/src/edit-engine/brightness-operation.h
@@ -0,0 +1,52 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2009 Santanu Sinha
+ *
+ * Solang 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.
+ *
+ * Solang 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 .
+ */
+
+#include "filter.h"
+
+#ifndef SOLANG_BRIGHTNESS_OPERATION_H
+#define SOLANG_BRIGHTNESS_OPERATION_H
+
+namespace Solang
+{
+
+class BrightnessOperation
+ : public Filter
+{
+ public:
+ BrightnessOperation( const EditEnginePtr &engine,
+ double fraction );
+
+ BrightnessOperation( const EditEnginePtr &engine,
+ const Glib::ustring &xmlPath );
+
+ ~BrightnessOperation() throw();
+
+ virtual Glib::ustring
+ get_name() const throw();
+
+ virtual Glib::ustring
+ get_description() const throw();
+
+ private:
+ double fraction_;
+};
+
+
+}//namespace Solang
+
+#endif //SOLANG_BRIGHTNESS_OPERATION_H
diff --git a/src/edit-engine/buffer.cpp b/src/edit-engine/buffer.cpp
new file mode 100644
index 0000000..1854a32
--- /dev/null
+++ b/src/edit-engine/buffer.cpp
@@ -0,0 +1,210 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 4; tab-width: 4 -*- */
+/*
+ * Copyright (C) 2009 Santanu Sinha
+ *
+ * Solang 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.
+ *
+ * Solang 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 .
+ */
+
+#ifndef HAVE_CONFIG_H
+#include "config.h"
+#endif //HAVE_CONFIG_H
+
+extern "C"
+{
+#include
+}
+
+#include
+#include
+#include
+#include
+#include
+
+#include "buffer.h"
+#include "edit-engine.h"
+#include "edit-utils.h"
+#include "progress-observer.h"
+
+
+namespace Solang
+{
+
+
+EditBits Buffer::BITS_ = EDIT_8_BITS;
+
+Buffer::Buffer()
+ :buffer_( NULL ),
+ refresh_()
+{
+}
+
+Buffer::Buffer( const GeglBufferPtr &buffer )
+ :buffer_( buffer ),
+ refresh_()
+{
+}
+
+Buffer::Buffer( const GeglRectangle &rect )
+ :buffer_( NULL ),
+ refresh_()
+{
+ buffer_ = create_buffer( rect );
+}
+
+Buffer::Buffer( const Buffer &rhs )
+ :buffer_( rhs.buffer_ ),
+ refresh_()
+{
+}
+
+Buffer::~Buffer()
+{
+ if( buffer_ )
+ gegl_buffer_destroy( buffer_ );
+ buffer_ = NULL;
+}
+
+Buffer &
+Buffer::operator =( const Buffer & rhs )
+{
+ if( this != &rhs )
+ {
+ set_buffer( rhs.buffer_ );
+ }
+ return *this;
+}
+
+PixbufPtr
+Buffer::get_pixbuf() throw()
+{
+ //The steps to do this are:
+ //1. create Cairo surface from buffer
+ //2. create pixmap from surface
+ //3. put pixmap in pixbuf
+ //Step 1:
+ //const Babl *fmt= get_babl_format_from_cairo();
+ const guint8 channels = 3;
+ gint width = gegl_buffer_get_width( buffer_ );
+ gint height = gegl_buffer_get_height( buffer_ );
+ gpointer dataBuffer = g_new0 (guint8, gegl_buffer_get_pixel_count (buffer_) * channels);
+ bzero( dataBuffer, gegl_buffer_get_pixel_count (buffer_) * channels);
+ gegl_buffer_get( buffer_, //buffer
+ 1.0, //scale
+ NULL, //extent .. we want the full thing
+ babl_format("RGB u8"), //color
+ dataBuffer, //pointer to buffer
+ channels * width ); //rowstride
+#if 0
+ Glib::RefPtr pixmap
+ = Gdk::Pixmap::create(
+ Glib::RefPtr(),
+ width, height, 32 );
+ Cairo::RefPtr context
+ = pixmap->create_cairo_context();
+ context->set_source( surface, 0, 0 );
+ context->paint();
+#endif
+ std::cout<<"Here"<(dataBuffer),
+ //buffer
+ Gdk::COLORSPACE_RGB, //Colorspace
+ false, //has alpha channel
+ 8, //bits per sample
+ width,
+ height,
+ channels * width ); //rowstride
+ //= num channels * width
+}
+
+GeglBufferPtr
+Buffer::create_buffer(const GeglRectangle &rect)
+{
+ return gegl_buffer_new(
+ &rect, babl_format (
+ (EDIT_16_BITS == Buffer::BITS_ )
+ ?"RGB u16":"RGB u8"));
+}
+
+void
+Buffer::set_buffer( const GeglBufferPtr &buffer )
+{
+ buffer_ = buffer;
+ refresh_.emit();
+}
+
+void
+Buffer::open_image_file( const Glib::ustring &path,
+ EditEnginePtr engine )
+{
+ if( buffer_ )
+ {
+ refresh_.emit();
+ return;
+ }
+ std::cout<<"Open: "<get_root_node(),
+ "operation", "gegl:load",
+ "path", path.c_str(),
+ NULL);
+ GeglRectangle rect = gegl_node_get_bounding_box( pAction );
+ GeglBufferPtr pBuf = NULL;
+ GeglNodePtr pOut = gegl_node_new_child(
+ engine->get_root_node(),
+ "operation", "gegl:save-buffer",
+ "buffer", &pBuf,
+ NULL);
+ gegl_node_link_many( pAction, pOut, NULL );
+
+ GeglProcessor *processor
+ = gegl_node_new_processor (pOut, &rect);
+ double progress = 0.0;
+ ProgressObserverPtr obs = engine->get_observer();
+ obs->set_num_events( 100 );
+ obs->set_event_description( _("Running Filter") );
+
+ while ( gegl_processor_work (processor, &progress) )
+ {
+ obs->set_current_events( progress * 100.0 );
+ std::cout<<"Prog: "<