[gimp] app: modified and moved gegl operation testing to operations/tests



commit 1edb18c30ac212201c17e05e8deab1c13bd79178
Author: Ville Sokk <ville sokk gmail com>
Date:   Thu Jun 14 20:18:42 2012 +0300

    app: modified and moved gegl operation testing to operations/tests

 app/operations/Makefile.am                         |    1 +
 app/operations/gimpoperationnormalmode.c           |   18 ++-
 app/operations/gimpoperationsoftlightmode.c        |   18 ++
 app/operations/tests/.gitignore                    |    6 +
 app/operations/tests/Makefile.am                   |  100 +++++++++++
 app/operations/tests/data/A.png                    |  Bin 0 -> 40239 bytes
 app/operations/tests/data/B.png                    |  Bin 0 -> 40239 bytes
 .../tests/data}/blending-test-A.png                |  Bin 3117 -> 3117 bytes
 .../tests/data}/blending-test-B.png                |  Bin 2034 -> 2034 bytes
 app/operations/tests/data/normal-mode.png          |  Bin 0 -> 9912 bytes
 app/operations/tests/data/soft-light-mode.png      |  Bin 0 -> 40239 bytes
 app/{ => operations}/tests/test-operations.c       |  179 ++++++++++++++------
 app/tests/files/normal-mode.png                    |  Bin 40239 -> 0 bytes
 app/tests/files/normal-mode.xml                    |   15 --
 configure.ac                                       |    1 +
 15 files changed, 272 insertions(+), 66 deletions(-)
---
diff --git a/app/operations/Makefile.am b/app/operations/Makefile.am
index c4f5159..59b8b3a 100644
--- a/app/operations/Makefile.am
+++ b/app/operations/Makefile.am
@@ -1,4 +1,5 @@
 ## Process this file with automake to produce Makefile.in
+SUBDIRS = tests
 
 AM_CPPFLAGS = \
 	-DG_LOG_DOMAIN=\"Gimp-Operations\"
diff --git a/app/operations/gimpoperationnormalmode.c b/app/operations/gimpoperationnormalmode.c
index d5f69af..6be2a1f 100644
--- a/app/operations/gimpoperationnormalmode.c
+++ b/app/operations/gimpoperationnormalmode.c
@@ -48,6 +48,22 @@ G_DEFINE_TYPE (GimpOperationNormalMode, gimp_operation_normal_mode,
 
 #define parent_class gimp_operation_normal_mode_parent_class
 
+static const gchar* reference_xml = "<?xml version='1.0' encoding='UTF-8'?>"
+"<gegl>"
+"<node operation='gimp:normal-mode'>"
+"  <node operation='gegl:load'>"
+"    <params>"
+"      <param name='path'>blending-test-B.png</param>"
+"    </params>"
+"  </node>"
+"</node>"
+"<node operation='gegl:load'>"
+"  <params>"
+"    <param name='path'>blending-test-A.png</param>"
+"  </params>"
+"</node>"
+"</gegl>";
+
 
 static void
 gimp_operation_normal_mode_class_init (GimpOperationNormalModeClass *klass)
@@ -62,7 +78,7 @@ gimp_operation_normal_mode_class_init (GimpOperationNormalModeClass *klass)
                                  "name",                  "gimp:normal-mode",
                                  "description",           "GIMP normal mode operation",
                                  "reference-image",       "normal-mode.png",
-                                 "reference-composition", "normal-mode.xml",
+                                 "reference-composition", reference_xml,
                                  NULL);
 
   operation_class->process     = gimp_operation_normal_parent_process;
diff --git a/app/operations/gimpoperationsoftlightmode.c b/app/operations/gimpoperationsoftlightmode.c
index 2ef2f91..b7dc5b7 100644
--- a/app/operations/gimpoperationsoftlightmode.c
+++ b/app/operations/gimpoperationsoftlightmode.c
@@ -43,6 +43,22 @@ static gboolean gimp_operation_softlight_mode_process (GeglOperation       *oper
 G_DEFINE_TYPE (GimpOperationSoftlightMode, gimp_operation_softlight_mode,
                GIMP_TYPE_OPERATION_POINT_LAYER_MODE)
 
+static const gchar* reference_xml = "<?xml version='1.0' encoding='UTF-8'?>"
+"<gegl>"
+"<node operation='gimp:softlight-mode'>"
+"  <node operation='gegl:load'>"
+"    <params>"
+"      <param name='path'>B.png</param>"
+"    </params>"
+"  </node>"
+"</node>"
+"<node operation='gegl:load'>"
+"  <params>"
+"    <param name='path'>A.png</param>"
+"  </params>"
+"</node>"
+"</gegl>";
+
 
 static void
 gimp_operation_softlight_mode_class_init (GimpOperationSoftlightModeClass *klass)
@@ -56,6 +72,8 @@ gimp_operation_softlight_mode_class_init (GimpOperationSoftlightModeClass *klass
   gegl_operation_class_set_keys (operation_class,
                                  "name",        "gimp:softlight-mode",
                                  "description", "GIMP softlight mode operation",
+                                 "reference-image", "soft-light-mode.png",
+                                 "reference-composition", reference_xml,
                                  NULL);
 
   operation_class->prepare = gimp_operation_softlight_mode_prepare;
diff --git a/app/operations/tests/.gitignore b/app/operations/tests/.gitignore
new file mode 100644
index 0000000..c96891f
--- /dev/null
+++ b/app/operations/tests/.gitignore
@@ -0,0 +1,6 @@
+.deps
+.libs
+/output
+Makefile
+Makefile.in
+test-operations*
\ No newline at end of file
diff --git a/app/operations/tests/Makefile.am b/app/operations/tests/Makefile.am
new file mode 100644
index 0000000..ac62f03
--- /dev/null
+++ b/app/operations/tests/Makefile.am
@@ -0,0 +1,100 @@
+TESTS = test-operations
+
+EXTRA_PROGRAMS = $(TESTS)
+CLEANFILES = $(EXTRA_PROGRAMS)
+
+$(TESTS): operations-output
+
+libgimpbase = $(top_builddir)/libgimpbase/libgimpbase-$(GIMP_API_VERSION).la
+libgimpconfig = $(top_builddir)/libgimpconfig/libgimpconfig-$(GIMP_API_VERSION).la
+libgimpcolor = $(top_builddir)/libgimpcolor/libgimpcolor-$(GIMP_API_VERSION).la
+libgimpmath = $(top_builddir)/libgimpmath/libgimpmath-$(GIMP_API_VERSION).la
+libgimpmodule = $(top_builddir)/libgimpmodule/libgimpmodule-$(GIMP_API_VERSION).la
+libgimpwidgets = $(top_builddir)/libgimpwidgets/libgimpwidgets-$(GIMP_API_VERSION).la
+libgimpthumb = $(top_builddir)/libgimpthumb/libgimpthumb-$(GIMP_API_VERSION).la
+
+AM_CPPFLAGS = \
+	-I$(top_srcdir)		\
+	-I$(top_srcdir)/app	\
+	$(PANGOCAIRO_CFLAGS)	\
+	$(GTK_CFLAGS)		\
+	$(DBUS_GLIB_CFLAGS)	\
+	$(GEGL_CFLAGS)		\
+	-I$(includedir)
+
+# We need this due to circular dependencies, see more detailed
+# comments about it in app/Makefile.am
+AM_LDFLAGS = \
+	-Wl,-u,$(SYMPREFIX)xcf_init				\
+	-Wl,-u,$(SYMPREFIX)base_init				\
+	-Wl,-u,$(SYMPREFIX)internal_procs_init			\
+	-Wl,-u,$(SYMPREFIX)gimp_plug_in_manager_restore		\
+	-Wl,-u,$(SYMPREFIX)gimp_pdb_compat_param_spec		\
+	-Wl,-u,$(SYMPREFIX)gui_init				\
+	-Wl,-u,$(SYMPREFIX)plug_in_icc_profile_apply_rgb	\
+	-Wl,-u,$(SYMPREFIX)gimp_image_map_config_get_type	\
+	-Wl,-u,$(SYMPREFIX)gimp_vectors_undo_get_type		\
+	-Wl,-u,$(SYMPREFIX)gimp_vectors_mod_undo_get_type	\
+	-Wl,-u,$(SYMPREFIX)gimp_vectors_prop_undo_get_type	\
+	-Wl,-u,$(SYMPREFIX)actions_init				\
+	-Wl,-u,$(SYMPREFIX)gimp_error_dialog_new		\
+	-Wl,-u,$(SYMPREFIX)menus_save				\
+	-Wl,-u,$(SYMPREFIX)gimp_tools_save			\
+	-Wl,-u,$(SYMPREFIX)gimp_curve_map_pixels		\
+	-Wl,-u,$(SYMPREFIX)gimp_image_base_type			\
+	-Wl,-u,$(SYMPREFIX)gimp_param_spec_duplicate		\
+	-Wl,-u,$(SYMPREFIX)gimp_lebl_dialog
+
+# Note that we have some duplicate entries here too to work around
+# circular dependencies and systems on the same architectural layer as
+# an alternative to LDFLAGS above
+LDADD = \
+	$(top_builddir)/app/dialogs/preferences-dialog.o	\
+	$(top_builddir)/app/gui/libappgui.a			\
+	$(top_builddir)/app/tools/libapptools.a			\
+	$(top_builddir)/app/dialogs/libappdialogs.a		\
+	$(top_builddir)/app/menus/libappmenus.a			\
+	$(top_builddir)/app/actions/libappactions.a		\
+	$(top_builddir)/app/dialogs/libappdialogs.a		\
+	$(top_builddir)/app/display/libappdisplay.a		\
+	$(top_builddir)/app/widgets/libappwidgets.a		\
+	$(top_builddir)/app/xcf/libappxcf.a			\
+	$(top_builddir)/app/pdb/libappinternal-procs.a		\
+	$(top_builddir)/app/pdb/libapppdb.a			\
+	$(top_builddir)/app/plug-in/libappplug-in.a		\
+	$(top_builddir)/app/vectors/libappvectors.a		\
+	$(top_builddir)/app/core/libappcore.a			\
+	$(top_builddir)/app/file/libappfile.a			\
+	$(top_builddir)/app/text/libapptext.a			\
+	$(top_builddir)/app/paint/libapppaint.a			\
+	$(top_builddir)/app/config/libappconfig.a		\
+	$(top_builddir)/app/paint-funcs/libapppaint-funcs.a	\
+	$(top_builddir)/app/base/libappbase.a			\
+	$(top_builddir)/app/libapp.a				\
+	$(top_builddir)/app/gegl/libappgegl.a			\
+	$(top_builddir)/app/operations/libappoperations.a	\
+	$(libgimpwidgets)					\
+	$(libgimpconfig)					\
+	$(libgimpmath)						\
+	$(libgimpthumb)						\
+	$(libgimpcolor)						\
+	$(libgimpmodule)					\
+	$(libgimpbase)						\
+	$(GIMPICONRC)						\
+	$(GTK_LIBS)						\
+	$(DBUS_GLIB_LIBS)					\
+	$(GDK_PIXBUF_LIBS)					\
+	$(FREETYPE_LIBS)					\
+	$(FONTCONFIG_LIBS)					\
+	$(PANGOCAIRO_LIBS)					\
+	$(CAIRO_LIBS)						\
+	$(GEGL_LIBS)						\
+	$(GLIB_LIBS)						\
+	$(INTLLIBS)						\
+	$(RT_LIBS)
+
+operations-output:
+	mkdir -p operations-output
+
+clean-local:
+	rm -rf operations-output
diff --git a/app/operations/tests/data/A.png b/app/operations/tests/data/A.png
new file mode 100644
index 0000000..636d81d
Binary files /dev/null and b/app/operations/tests/data/A.png differ
diff --git a/app/operations/tests/data/B.png b/app/operations/tests/data/B.png
new file mode 100644
index 0000000..7a251f8
Binary files /dev/null and b/app/operations/tests/data/B.png differ
diff --git a/app/tests/files/blending-test-A.png b/app/operations/tests/data/blending-test-A.png
similarity index 100%
rename from app/tests/files/blending-test-A.png
rename to app/operations/tests/data/blending-test-A.png
diff --git a/app/tests/files/blending-test-B.png b/app/operations/tests/data/blending-test-B.png
similarity index 100%
rename from app/tests/files/blending-test-B.png
rename to app/operations/tests/data/blending-test-B.png
diff --git a/app/operations/tests/data/normal-mode.png b/app/operations/tests/data/normal-mode.png
new file mode 100644
index 0000000..e4de9d2
Binary files /dev/null and b/app/operations/tests/data/normal-mode.png differ
diff --git a/app/operations/tests/data/soft-light-mode.png b/app/operations/tests/data/soft-light-mode.png
new file mode 100644
index 0000000..d2e7b46
Binary files /dev/null and b/app/operations/tests/data/soft-light-mode.png differ
diff --git a/app/tests/test-operations.c b/app/operations/tests/test-operations.c
similarity index 66%
rename from app/tests/test-operations.c
rename to app/operations/tests/test-operations.c
index ef05ab4..469d5e6 100644
--- a/app/tests/test-operations.c
+++ b/app/operations/tests/test-operations.c
@@ -27,16 +27,111 @@
 
 #include "app/operations/gimp-operations.h"
 
-#define DATA_DIR "files"
-#define OUTPUT_DIR "operations-output"
+#define DATA_DIR "data"
+#define OUTPUT_DIR "output"
+#define PI M_PI
 
 
-static inline gfloat
-square (gfloat x)
+static inline gdouble
+square (gdouble x)
 {
   return x * x;
 }
 
+static gdouble
+cie76 (gfloat *src1,
+       gfloat *src2)
+{
+  return sqrt (square (src1[0] - src2[0]) +
+               square (src1[1] - src2[1]) +
+               square (src1[2] - src2[2]));
+}
+
+static gdouble
+cie94 (gfloat* src1,
+       gfloat* src2)
+{
+  gdouble L1, L2, a1, b1, a2, b2, C1, C2, dL, dC, dH, dE;
+
+  L1 = src1[0];
+  a1 = src1[1];
+  b1 = src1[2];
+  L2 = src2[0];
+  a2 = src2[1];
+  b2 = src2[2];
+  dL = L1 - L2;
+  C1 = sqrt (square (a1) + square (b1));
+  C2 = sqrt (square (a2) + square (b2));
+  dC = C1 - C2;
+  dH = sqrt (square (a1 - a2) + square (b1 - b2) - square (dC));
+  dE = sqrt (square (dL) + square (dC / (1 + 0.045 * C1)) + square (dH / (1 + 0.015 * C1)));
+
+  return dE;
+}
+
+/*
+ * CIE 2000 delta E colour comparison
+ */
+static gdouble
+delta_e (gfloat* src1,
+         gfloat* src2)
+{
+  gdouble L1, L2, a1, a2, b1, b2, La_, C1, C2, Ca, G, a1_, a2_, C1_,
+    C2_, Ca_, h1_, h2_, Ha_, T, dh_, dL_, dC_, dH_, Sl, Sc, Sh, dPhi,
+    Rc, Rt, dE, tmp;
+
+  L1 = src1[0];
+  L2 = src2[0];
+  a1 = src1[1];
+  a2 = src2[1];
+  b1 = src1[2];
+  b2 = src2[2];
+
+  La_ = (L1 + L2) / 2.0;
+  C1 = sqrt (square (a1) + square (b1));
+  C2 = sqrt (square (a2) + square (b2));
+  Ca = (C1 + C2) / 2.0;
+  tmp = pow (Ca, 7);
+  G = (1 - sqrt (tmp / (tmp + pow (25, 7)))) / 2.0;
+  a1_ = a1 * (1 + G);
+  a2_ = a2 * (1 + G);
+  C1_ = sqrt (square (a1_) + square (b1));
+  C2_ = sqrt (square (a2_) + square (b2));
+  Ca_ = (C1_ + C2_) / 2.0;
+  tmp = atan2 (b1, a1_) * 180 / PI;
+  h1_ = (tmp >= 0.0) ? tmp : tmp + 360;
+  tmp = atan2 (b2, a2_) * 180 / PI;
+  h2_ = (tmp >= 0) ? tmp: tmp + 360;
+  tmp = abs (h1_ - h2_);
+  Ha_ = (tmp > 180) ? (h1_ + h2_ + 360) / 2.0 : (h1_ + h2_) / 2.0;
+  T = 1 - 0.17 * cos ((Ha_ - 30) * PI / 180) +
+    0.24 * cos ((Ha_ * 2) * PI / 180) +
+    0.32 * cos ((Ha_ * 3 + 6) * PI / 180) -
+    0.2 * cos ((Ha_ * 4 - 63) * PI / 180);
+  if (tmp <= 180)
+    dh_ = h2_ - h1_;
+  else if (tmp > 180 && h2_ <= h1_)
+    dh_ = h2_ - h1_ + 360;
+  else
+    dh_ = h2_ - h1_ - 360;
+  dL_ = L2 - L1;
+  dC_ = C2_ - C1_;
+  dH_ = 2 * sqrt (C1_ * C2_) * sin (dh_ / 2.0 * PI / 180);
+  tmp = square (La_ - 50);
+  Sl = 1 + 0.015 * tmp / sqrt (20 + tmp);
+  Sc = 1 + 0.045 * Ca_;
+  Sh = 1 + 0.015 * Ca_ * T;
+  dPhi = 30 * exp (-square ((Ha_ - 275) / 25.0));
+  tmp = pow (Ca_, 7);
+  Rc = 2 * sqrt (tmp / (tmp + pow (25, 7)));
+  Rt = -Rc * sin (2 * dPhi * PI / 180);
+
+  dE = sqrt (square (dL_ / Sl) + square (dC_ / Sc) +
+             square (dH_ / Sh) + Rt * dC_ * dH_ / Sc / Sh);
+
+  return dE;
+}
+
 /*
  * image comparison function from GEGL
  */
@@ -109,13 +204,11 @@ image_compare (gchar *composition_path,
      b = bufB;
      d = debug;
 
-     for (i=0; i<pixels; i++)
+     for (i=0; i < pixels; i++)
        {
-         gdouble diff = sqrt (square (a[0]-b[0])+
-                              square (a[1]-b[1])+
-                              square (a[2]-b[2])
-                              /*+square (a[3]-b[3])*/);
-         if (diff >= 0.01)
+         gdouble diff = delta_e (a, b);
+
+         if (diff >= 0.1)
            {
              wrong_pixels++;
              diffsum += diff;
@@ -143,11 +236,9 @@ image_compare (gchar *composition_path,
      if (wrong_pixels)
        for (i = 0; i < pixels; i++)
          {
-           gdouble diff = sqrt (square (a[0]-b[0])+
-                                square (a[1]-b[1])+
-                                square (a[2]-b[2])
-                                /*+square (a[3]-b[3])*/);
-           if (diff >= 0.01)
+           gdouble diff = delta_e (a, b);
+
+           if (diff >= 0.1)
              {
                d[0] = (100-a[0])/100.0*64+32;
                d[1] = (diff/max_diff * 255);
@@ -168,8 +259,12 @@ image_compare (gchar *composition_path,
      gegl_buffer_linear_close (bufferB, bufB);
      gegl_buffer_linear_close (debug_buf, debug);
 
-     if (max_diff >= 0.1)
+     if (max_diff > 1.5)
        {
+         GeglNode *graph, *sink;
+         gchar    *debug_path;
+         gint      ext_length;
+
          g_print ("\nBuffers differ\n"
                   "  wrong pixels   : %i/%i (%2.2f%%)\n"
                   "  max Îe         : %2.3f\n"
@@ -179,24 +274,20 @@ image_compare (gchar *composition_path,
                   diffsum/wrong_pixels,
                   diffsum/pixels);
 
-         result = FALSE;
+         debug_path = g_malloc (strlen (composition_path)+16);
+         ext_length = strlen (strrchr (composition_path, '.'));
 
-         if (max_diff > 1.5)
-           {
-             GeglNode *graph, *sink;
-             gchar    *debug_path = g_malloc (strlen (composition_path)+16);
-             gint      ext_length = strlen (strrchr (composition_path, '.'));
-
-             memcpy (debug_path, composition_path, strlen (composition_path)+1);
-             memcpy (debug_path + strlen(composition_path)-ext_length, "-diff.png", 11);
-             graph = gegl_graph (sink=gegl_node ("gegl:png-save",
-                                                 "path", debug_path, NULL,
-                                                 gegl_node ("gegl:buffer-source",
-                                                            "buffer", debug_buf, NULL)));
-             gegl_node_process (sink);
-             g_object_unref (graph);
-             g_object_unref (debug_buf);
-           }
+         memcpy (debug_path, composition_path, strlen (composition_path)+1);
+         memcpy (debug_path + strlen(composition_path)-ext_length, "-diff.png", 11);
+         graph = gegl_graph (sink=gegl_node ("gegl:png-save",
+                                             "path", debug_path, NULL,
+                                             gegl_node ("gegl:buffer-source",
+                                                        "buffer", debug_buf, NULL)));
+         gegl_node_process (sink);
+         g_object_unref (graph);
+         g_object_unref (debug_buf);
+
+         result = FALSE;
        }
   }
 
@@ -235,20 +326,14 @@ process_operations (GType type)
       if (image && xml)
         {
           gchar    *root        = g_get_current_dir ();
+          gchar    *xml_root    = g_build_path (G_DIR_SEPARATOR_S, root, DATA_DIR, NULL);
           gchar    *image_path  = g_build_path (G_DIR_SEPARATOR_S, root, DATA_DIR, image, NULL);
-          gchar    *xml_path    = g_build_path (G_DIR_SEPARATOR_S, root, DATA_DIR, xml, NULL);
           gchar    *output_path = g_build_path (G_DIR_SEPARATOR_S, root, OUTPUT_DIR, image, NULL);
           GeglNode *composition, *output;
 
           g_printf ("%s: ", gegl_operation_class_get_key (operation_class, "name"));
 
-          if (!g_file_test (xml_path, G_FILE_TEST_EXISTS))
-            {
-              g_printerr ("\nCan't locate %s\n", xml_path);
-              result = FALSE;
-            }
-
-          composition = gegl_node_new_from_file (xml_path);
+          composition = gegl_node_new_from_xml (xml, xml_root);
           if (!composition)
             {
               g_printerr ("\nComposition graph is flawed\n");
@@ -266,19 +351,19 @@ process_operations (GType type)
               if (image_compare (output_path, image_path))
                 {
                   g_printf ("PASS\n");
-                  result = TRUE;
+                  result = result && TRUE;
                 }
               else
                 {
                   g_printf ("FAIL\n");
-                  result = FALSE;
+                  result = result && FALSE;
                 }
             }
 
           g_object_unref (composition);
           g_free (root);
+          g_free (xml_root);
           g_free (image_path);
-          g_free (xml_path);
           g_free (output_path);
         }
 
@@ -290,12 +375,6 @@ process_operations (GType type)
   return result;
 }
 
-/**
- * test_operations:
- *
- * Test GIMP's GEGL operations that supply a reference image
- * and composition xml.
- **/
 static void
 test_operations (void)
 {
diff --git a/configure.ac b/configure.ac
index 5d90983..c6f5ed0 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2159,6 +2159,7 @@ app/base/Makefile
 app/config/Makefile
 app/core/Makefile
 app/operations/Makefile
+app/operations/tests/Makefile
 app/gegl/Makefile
 app/dialogs/Makefile
 app/display/Makefile



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]