gimp r24995 - in trunk: . app/core app/gegl app/tools app/widgets



Author: mitch
Date: Thu Feb 28 12:34:46 2008
New Revision: 24995
URL: http://svn.gnome.org/viewvc/gimp?rev=24995&view=rev

Log:
2008-02-28  Michael Natterer  <mitch gimp org>

	* app/core/gimpcurve.[ch]: get rid of fixed-size arrays and
	allocate the points and curve arrays dynamically. Added "n-points"
	and "n-samples" CONSTRUCT_ONLY properties. Renamed member "curve"
	to "samples". Lots of code changes to work with dynamic limits
	rather than 17 and 256.

	* app/core/gimpdrawable-curves.c
	* app/gegl/gimpcurvesconfig.c
	* app/tools/gimpcurvestool.c
	* app/widgets/gimpcurveview.c: changed accordingly.



Modified:
   trunk/ChangeLog
   trunk/app/core/gimpcurve.c
   trunk/app/core/gimpcurve.h
   trunk/app/core/gimpdrawable-curves.c
   trunk/app/gegl/gimpcurvesconfig.c
   trunk/app/tools/gimpcurvestool.c
   trunk/app/widgets/gimpcurveview.c

Modified: trunk/app/core/gimpcurve.c
==============================================================================
--- trunk/app/core/gimpcurve.c	(original)
+++ trunk/app/core/gimpcurve.c	Thu Feb 28 12:34:46 2008
@@ -38,8 +38,10 @@
 {
   PROP_0,
   PROP_CURVE_TYPE,
+  PROP_N_POINTS,
   PROP_POINTS,
-  PROP_CURVE
+  PROP_N_SAMPLES,
+  PROP_SAMPLES
 };
 
 
@@ -81,6 +83,11 @@
 static gchar    * gimp_curve_get_extension    (GimpData      *data);
 static GimpData * gimp_curve_duplicate        (GimpData      *data);
 
+static void       gimp_curve_set_n_points     (GimpCurve     *curve,
+                                               gint           n_points);
+static void       gimp_curve_set_n_samples    (GimpCurve     *curve,
+                                               gint           n_samples);
+
 static void       gimp_curve_calculate        (GimpCurve     *curve);
 static void       gimp_curve_plot             (GimpCurve     *curve,
                                                gint           p1,
@@ -126,14 +133,26 @@
                                                       GIMP_PARAM_READWRITE |
                                                       G_PARAM_CONSTRUCT));
 
+  g_object_class_install_property (object_class, PROP_N_POINTS,
+                                   g_param_spec_int ("n-points", NULL, NULL,
+                                                     17, 17, 17,
+                                                     GIMP_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT_ONLY));
+
   g_object_class_install_property (object_class, PROP_POINTS,
                                    g_param_spec_boolean ("points", NULL, NULL,
                                                          FALSE,
                                                          GIMP_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT));
 
-  g_object_class_install_property (object_class, PROP_CURVE,
-                                   g_param_spec_boolean ("curve", NULL, NULL,
+  g_object_class_install_property (object_class, PROP_N_SAMPLES,
+                                   g_param_spec_int ("n-samples", NULL, NULL,
+                                                     256, 256, 256,
+                                                     GIMP_PARAM_READWRITE |
+                                                     G_PARAM_CONSTRUCT_ONLY));
+
+  g_object_class_install_property (object_class, PROP_SAMPLES,
+                                   g_param_spec_boolean ("samples", NULL, NULL,
                                                          FALSE,
                                                          GIMP_PARAM_READWRITE |
                                                          G_PARAM_CONSTRUCT));
@@ -142,7 +161,6 @@
 static void
 gimp_curve_init (GimpCurve *curve)
 {
-  gimp_curve_reset (curve, TRUE);
 }
 
 static void
@@ -150,6 +168,18 @@
 {
   GimpCurve *curve = GIMP_CURVE (object);
 
+  if (curve->points)
+    {
+      g_free (curve->points);
+      curve->points = NULL;
+    }
+
+  if (curve->samples)
+    {
+      g_free (curve->samples);
+      curve->samples = NULL;
+    }
+
   G_OBJECT_CLASS (parent_class)->finalize (object);
 }
 
@@ -167,8 +197,18 @@
       gimp_curve_set_curve_type (curve, g_value_get_enum (value));
       break;
 
+    case PROP_N_POINTS:
+      gimp_curve_set_n_points (curve, g_value_get_int (value));
+      break;
+
     case PROP_POINTS:
-    case PROP_CURVE:
+      break;
+
+    case PROP_N_SAMPLES:
+      gimp_curve_set_n_samples (curve, g_value_get_int (value));
+      break;
+
+    case PROP_SAMPLES:
       break;
 
     default:
@@ -191,8 +231,18 @@
       g_value_set_enum (value, curve->curve_type);
       break;
 
+    case PROP_N_POINTS:
+      g_value_set_int (value, curve->n_points);
+      break;
+
     case PROP_POINTS:
-    case PROP_CURVE:
+      break;
+
+    case PROP_N_SAMPLES:
+      g_value_set_int (value, curve->n_samples);
+      break;
+
+    case PROP_SAMPLES:
       break;
 
     default:
@@ -208,6 +258,9 @@
   GimpCurve *curve   = GIMP_CURVE (object);
   gint64     memsize = 0;
 
+  memsize += curve->n_points  * sizeof (GimpVector2);
+  memsize += curve->n_samples * sizeof (gdouble);
+
   return memsize + GIMP_OBJECT_CLASS (parent_class)->get_memsize (object,
                                                                   gui_size);
 }
@@ -327,30 +380,32 @@
 
   g_return_if_fail (GIMP_IS_CURVE (curve));
 
-  if (reset_type)
-    curve->curve_type = GIMP_CURVE_SMOOTH;
+  g_object_freeze_notify (G_OBJECT (curve));
+
+  for (i = 0; i < curve->n_samples; i++)
+    curve->samples[i] = (gdouble) i / (gdouble) (curve->n_samples - 1);
 
-  for (i = 0; i < 256; i++)
-    curve->curve[i] = (gdouble) i / 255.0;
+  g_object_notify (G_OBJECT (curve), "samples");
 
-  for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+  curve->points[0].x = 0.0;
+  curve->points[0].y = 0.0;
+
+  for (i = 1; i < curve->n_points - 1; i++)
     {
       curve->points[i].x = -1.0;
       curve->points[i].y = -1.0;
     }
 
-  curve->points[0].x  = 0.0;
-  curve->points[0].y  = 0.0;
-  curve->points[GIMP_CURVE_NUM_POINTS - 1].x = 1.0;
-  curve->points[GIMP_CURVE_NUM_POINTS - 1].y = 1.0;
-
-  g_object_freeze_notify (G_OBJECT (curve));
+  curve->points[curve->n_points - 1].x = 1.0;
+  curve->points[curve->n_points - 1].y = 1.0;
 
   g_object_notify (G_OBJECT (curve), "points");
-  g_object_notify (G_OBJECT (curve), "curve");
 
   if (reset_type)
-    g_object_notify (G_OBJECT (curve), "curve-type");
+    {
+      curve->curve_type = GIMP_CURVE_SMOOTH;
+      g_object_notify (G_OBJECT (curve), "curve-type");
+    }
 
   g_object_thaw_notify (G_OBJECT (curve));
 
@@ -371,17 +426,28 @@
 
       if (curve_type == GIMP_CURVE_SMOOTH)
         {
+          gint n_points;
           gint i;
 
-          /*  pick representative points from the curve and make them
-           *  control points
+          for (i = 0; i < curve->n_points; i++)
+            {
+              curve->points[i].x = -1;
+              curve->points[i].y = -1;
+            }
+
+          /*  pick some points from the curve and make them control
+           *  points
            */
-          for (i = 0; i <= 8; i++)
+          n_points = CLAMP (9, curve->n_points / 2, curve->n_points);
+
+          for (i = 0; i < n_points; i++)
             {
-              gint32 index = CLAMP0255 (i * 32);
+              gint sample = i * (curve->n_samples - 1) / (n_points - 1);
+              gint point  = i * (curve->n_points  - 1) / (n_points - 1);
 
-              curve->points[i * 2].x = (gdouble) index / 255.0;
-              curve->points[i * 2].y = curve->curve[index];
+              curve->points[point].x = ((gdouble) sample /
+                                        (gdouble) (curve->n_samples - 1));
+              curve->points[point].y = curve->samples[sample];
             }
 
           g_object_notify (G_OBJECT (curve), "points");
@@ -403,7 +469,82 @@
   return curve->curve_type;
 }
 
-#define MIN_DISTANCE (8.0 / 255.0)
+static void
+gimp_curve_set_n_points (GimpCurve *curve,
+                         gint       n_points)
+{
+  g_return_if_fail (GIMP_IS_CURVE (curve));
+
+  if (n_points != curve->n_points)
+    {
+      gint i;
+
+      g_object_freeze_notify (G_OBJECT (curve));
+
+      curve->n_points = n_points;
+      g_object_notify (G_OBJECT (curve), "n-points");
+
+      curve->points = g_renew (GimpVector2, curve->points, curve->n_points);
+
+      curve->points[0].x = 0.0;
+      curve->points[0].y = 0.0;
+
+      for (i = 1; i < curve->n_points - 1; i++)
+        {
+          curve->points[i].x = -1.0;
+          curve->points[i].y = -1.0;
+        }
+
+      curve->points[curve->n_points - 1].x = 1.0;
+      curve->points[curve->n_points - 1].y = 1.0;
+
+      g_object_notify (G_OBJECT (curve), "points");
+
+      g_object_thaw_notify (G_OBJECT (curve));
+    }
+}
+
+gint
+gimp_curve_get_n_points (GimpCurve *curve)
+{
+  g_return_val_if_fail (GIMP_IS_CURVE (curve), 0);
+
+  return curve->n_points;
+}
+
+static void
+gimp_curve_set_n_samples (GimpCurve *curve,
+                          gint       n_samples)
+{
+  g_return_if_fail (GIMP_IS_CURVE (curve));
+
+  if (n_samples != curve->n_samples)
+    {
+      gint i;
+
+      g_object_freeze_notify (G_OBJECT (curve));
+
+      curve->n_samples = n_samples;
+      g_object_notify (G_OBJECT (curve), "n-samples");
+
+      curve->samples = g_renew (gdouble, curve->samples, curve->n_samples);
+
+      for (i = 0; i < curve->n_samples; i++)
+        curve->samples[i] = (gdouble) i / (gdouble) (curve->n_samples - 1);
+
+      g_object_notify (G_OBJECT (curve), "samples");
+
+      g_object_thaw_notify (G_OBJECT (curve));
+    }
+}
+
+gint
+gimp_curve_get_n_samples (GimpCurve *curve)
+{
+  g_return_val_if_fail (GIMP_IS_CURVE (curve), 0);
+
+  return curve->n_samples;
+}
 
 gint
 gimp_curve_get_closest_point (GimpCurve *curve,
@@ -415,7 +556,7 @@
 
   g_return_val_if_fail (GIMP_IS_CURVE (curve), 0);
 
-  for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+  for (i = 0; i < curve->n_points; i++)
     {
       if (curve->points[i].x >= 0.0 &&
           fabs (x - curve->points[i].x) < distance)
@@ -425,8 +566,8 @@
         }
     }
 
-  if (distance > MIN_DISTANCE)
-    closest_point = ((gint) (x * 255.999) + 8) / 16;
+  if (distance > (1.0 / (curve->n_points * 2.0)))
+    closest_point = ROUND (x * (gdouble) (curve->n_points - 1));
 
   return closest_point;
 }
@@ -438,7 +579,7 @@
                       gdouble    y)
 {
   g_return_if_fail (GIMP_IS_CURVE (curve));
-  g_return_if_fail (point >= 0 && point < GIMP_CURVE_NUM_POINTS);
+  g_return_if_fail (point >= 0 && point < curve->n_points);
   g_return_if_fail (x == -1.0 || (x >= 0 && x <= 1.0));
   g_return_if_fail (y == -1.0 || (y >= 0 && y <= 1.0));
 
@@ -463,7 +604,7 @@
                        gdouble    y)
 {
   g_return_if_fail (GIMP_IS_CURVE (curve));
-  g_return_if_fail (point >= 0 && point < GIMP_CURVE_NUM_POINTS);
+  g_return_if_fail (point >= 0 && point < curve->n_points);
   g_return_if_fail (y >= 0 && y <= 1.0);
 
   if (curve->curve_type == GIMP_CURVE_FREE)
@@ -487,7 +628,7 @@
                       gdouble   *y)
 {
   g_return_if_fail (GIMP_IS_CURVE (curve));
-  g_return_if_fail (point >= 0 && point < GIMP_CURVE_NUM_POINTS);
+  g_return_if_fail (point >= 0 && point < curve->n_points);
 
   if (curve->curve_type == GIMP_CURVE_FREE)
     return;
@@ -510,9 +651,9 @@
 
   g_object_freeze_notify (G_OBJECT (curve));
 
-  curve->curve[(gint) (x * 255.999)] = y;
+  curve->samples[ROUND (x * (gdouble) (curve->n_samples - 1))] = y;
 
-  g_object_notify (G_OBJECT (curve), "curve");
+  g_object_notify (G_OBJECT (curve), "samples");
 
   g_object_thaw_notify (G_OBJECT (curve));
 
@@ -529,19 +670,19 @@
 
   if (x < 0.0)
     {
-      value = curve->curve[0];
+      value = curve->samples[0];
     }
   else if (x >= 1.0)
     {
-      value = curve->curve[255];
+      value = curve->samples[curve->n_samples - 1];
     }
   else /* interpolate the curve */
     {
-      gint    index = floor (x * 255.0);
-      gdouble f     = x * 255.0 - index;
+      gint    index = floor (x * (gdouble) (curve->n_samples - 1));
+      gdouble f     = x * (gdouble) (curve->n_samples - 1) - index;
 
-      value = ((1.0 - f) * curve->curve[index    ] +
-                      f  * curve->curve[index + 1]);
+      value = ((1.0 - f) * curve->samples[index    ] +
+                      f  * curve->samples[index + 1]);
     }
 
   return value;
@@ -549,15 +690,20 @@
 
 void
 gimp_curve_get_uchar (GimpCurve *curve,
-                      guchar    *dest_array)
+                      gint       n_samples,
+                      guchar    *samples)
 {
   gint i;
 
   g_return_if_fail (GIMP_IS_CURVE (curve));
-  g_return_if_fail (dest_array != NULL);
+#ifdef __GNUC__
+#warning: FIXME: support n_samples != curve->n_samples
+#endif
+  g_return_if_fail (n_samples == curve->n_samples);
+  g_return_if_fail (samples != NULL);
 
-  for (i = 0; i < 256; i++)
-    dest_array[i] = curve->curve[i] * 255.999;
+  for (i = 0; i < curve->n_samples; i++)
+    samples[i] = curve->samples[i] * 255.999;
 }
 
 
@@ -567,7 +713,7 @@
 gimp_curve_calculate (GimpCurve *curve)
 {
   gint i;
-  gint points[GIMP_CURVE_NUM_POINTS];
+  gint points[curve->n_points];
   gint num_pts;
   gint p1, p2, p3, p4;
 
@@ -579,18 +725,27 @@
     case GIMP_CURVE_SMOOTH:
       /*  cycle through the curves  */
       num_pts = 0;
-      for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+      for (i = 0; i < curve->n_points; i++)
         if (curve->points[i].x >= 0.0)
           points[num_pts++] = i;
 
       /*  Initialize boundary curve points */
       if (num_pts != 0)
         {
-          for (i = 0; i < (gint) (curve->points[points[0]].x * 255.999); i++)
-            curve->curve[i] = curve->points[points[0]].y;
+          GimpVector2 point;
+          gint        boundary;
 
-          for (i = (gint) (curve->points[points[num_pts - 1]].x * 255.999); i < 256; i++)
-            curve->curve[i] = curve->points[points[num_pts - 1]].y;
+          point    = curve->points[points[0]];
+          boundary = ROUND (point.x * (gdouble) (curve->n_samples - 1));
+
+          for (i = 0; i < boundary; i++)
+            curve->samples[i] = point.y;
+
+          point    = curve->points[points[num_pts - 1]];
+          boundary = ROUND (point.x * (gdouble) (curve->n_samples - 1));
+
+          for (i = boundary; i < curve->n_samples; i++)
+            curve->samples[i] = point.y;
         }
 
       for (i = 0; i < num_pts - 1; i++)
@@ -609,10 +764,10 @@
           gdouble x = curve->points[points[i]].x;
           gdouble y = curve->points[points[i]].y;
 
-          curve->curve[(gint) (x * 255.999)] = y;
+          curve->samples[ROUND (x * (gdouble) (curve->n_samples - 1))] = y;
         }
 
-      g_object_notify (G_OBJECT (curve), "curve");
+      g_object_notify (G_OBJECT (curve), "samples");
       break;
 
     case GIMP_CURVE_FREE:
@@ -640,7 +795,6 @@
   gdouble x0, x3;
   gdouble y0, y1, y2, y3;
   gdouble dx, dy;
-  gdouble y, t;
   gdouble slope;
 
   /* the outer control points for the bezier curve. */
@@ -714,14 +868,19 @@
    * finally calculate the y(t) values for the given bezier values. We can
    * use homogenously distributed values for t, since x(t) increases linearily.
    */
-  for (i = 0; i <= (gint) (dx * 255.999); i++)
+  for (i = 0; i <= ROUND (dx * (gdouble) (curve->n_samples - 1)); i++)
     {
-      t = i / dx / 255.0;
+      gdouble y, t;
+      gint    index;
+
+      t = i / dx / (gdouble) (curve->n_samples - 1);
       y =     y0 * (1-t) * (1-t) * (1-t) +
           3 * y1 * (1-t) * (1-t) * t     +
           3 * y2 * (1-t) * t     * t     +
               y3 * t     * t     * t;
 
-      curve->curve[(gint) (x0 * 255.999) + i] = CLAMP (y, 0.0, 1.0);
+      index = ROUND (x0 * (gdouble) (curve->n_samples - 1)) + i;
+
+      curve->samples[index] = CLAMP (y, 0.0, 1.0);
     }
 }

Modified: trunk/app/core/gimpcurve.h
==============================================================================
--- trunk/app/core/gimpcurve.h	(original)
+++ trunk/app/core/gimpcurve.h	Thu Feb 28 12:34:46 2008
@@ -24,9 +24,6 @@
 #include "libgimpmath/gimpvector.h"
 
 
-#define GIMP_CURVE_NUM_POINTS 17 /* TODO: get rid of this limit */
-
-
 #define GIMP_TYPE_CURVE            (gimp_curve_get_type ())
 #define GIMP_CURVE(obj)            (G_TYPE_CHECK_INSTANCE_CAST ((obj), GIMP_TYPE_CURVE, GimpCurve))
 #define GIMP_CURVE_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), GIMP_TYPE_CURVE, GimpCurveClass))
@@ -43,8 +40,11 @@
 
   GimpCurveType  curve_type;
 
-  GimpVector2    points[GIMP_CURVE_NUM_POINTS];
-  gdouble        curve[256];
+  gint           n_points;
+  GimpVector2   *points;
+
+  gint           n_samples;
+  gdouble       *samples;
 };
 
 struct _GimpCurveClass
@@ -65,6 +65,9 @@
                                               GimpCurveType  curve_type);
 GimpCurveType   gimp_curve_get_curve_type    (GimpCurve     *curve);
 
+gint            gimp_curve_get_n_points      (GimpCurve     *curve);
+gint            gimp_curve_get_n_samples     (GimpCurve     *curve);
+
 gint            gimp_curve_get_closest_point (GimpCurve     *curve,
                                               gdouble        x);
 
@@ -88,7 +91,8 @@
                                               gdouble        x);
 
 void            gimp_curve_get_uchar         (GimpCurve     *curve,
-                                              guchar        *dest_array);
+                                              gint           n_samples,
+                                              guchar        *samples);
 
 
 #endif /* __GIMP_CURVE_H__ */

Modified: trunk/app/core/gimpdrawable-curves.c
==============================================================================
--- trunk/app/core/gimpdrawable-curves.c	(original)
+++ trunk/app/core/gimpdrawable-curves.c	Thu Feb 28 12:34:46 2008
@@ -80,10 +80,15 @@
 
   gimp_data_freeze (GIMP_DATA (curve));
 
+#ifdef __GNUC__
+#warning FIXME: create a curves object with the right number of points
+#endif
   /*  unset the last point  */
-  gimp_curve_set_point (curve, GIMP_CURVE_NUM_POINTS - 1, -1, -1);
+  gimp_curve_set_point (curve, curve->n_points - 1, -1, -1);
 
-  for (i = 0; i < n_points / 2; i++)
+  n_points = MIN (n_points / 2, curve->n_points);
+
+  for (i = 0; i < n_points; i++)
     gimp_curve_set_point (curve, i,
                           (gdouble) points[i * 2]     / 255.0,
                           (gdouble) points[i * 2 + 1] / 255.0);

Modified: trunk/app/gegl/gimpcurvesconfig.c
==============================================================================
--- trunk/app/gegl/gimpcurvesconfig.c	(original)
+++ trunk/app/gegl/gimpcurvesconfig.c	Thu Feb 28 12:34:46 2008
@@ -201,9 +201,9 @@
             gimp_config_sync (G_OBJECT (src_curve), G_OBJECT (dest_curve), 0);
 
             memcpy (dest_curve->points, src_curve->points,
-                    sizeof (src_curve->points));
-            memcpy (dest_curve->curve, src_curve->curve,
-                    sizeof (src_curve->curve));
+                    sizeof (GimpVector2) * src_curve->n_points);
+            memcpy (dest_curve->samples, src_curve->samples,
+                    sizeof (gdouble) * src_curve->n_samples);
           }
       }
       break;
@@ -235,9 +235,9 @@
             return FALSE;
 
           if (memcmp (a_curve->points, b_curve->points,
-                      sizeof (b_curve->points)) ||
-              memcmp (a_curve->curve, b_curve->curve,
-                      sizeof (b_curve->curve)))
+                      sizeof (GimpVector2) * b_curve->n_points) ||
+              memcmp (a_curve->samples, b_curve->samples,
+                      sizeof (gdouble) * b_curve->n_samples))
             return FALSE;
         }
       else if (a_curve || b_curve)
@@ -288,10 +288,10 @@
         {
           gimp_config_sync (G_OBJECT (src_curve), G_OBJECT (dest_curve), 0);
 
-          memcpy (dest_curve->points,
-                  src_curve->points, sizeof (src_curve->points));
-          memcpy (dest_curve->curve,
-                  src_curve->curve, sizeof (src_curve->curve));
+          memcpy (dest_curve->points, src_curve->points,
+                  sizeof (GimpVector2) * src_curve->n_points);
+          memcpy (dest_curve->samples, src_curve->samples,
+                  sizeof (gdouble) * src_curve->n_samples);
         }
     }
 
@@ -322,6 +322,8 @@
   gimp_curve_reset (config->curve[config->channel], TRUE);
 }
 
+#define GIMP_CURVE_N_CRUFT_POINTS 17
+
 gboolean
 gimp_curves_config_load_cruft (GimpCurvesConfig  *config,
                                gpointer           fp,
@@ -331,8 +333,8 @@
   gint   i, j;
   gint   fields;
   gchar  buf[50];
-  gint   index[5][GIMP_CURVE_NUM_POINTS];
-  gint   value[5][GIMP_CURVE_NUM_POINTS];
+  gint   index[5][GIMP_CURVE_N_CRUFT_POINTS];
+  gint   value[5][GIMP_CURVE_N_CRUFT_POINTS];
 
   g_return_val_if_fail (GIMP_IS_CURVES_CONFIG (config), FALSE);
   g_return_val_if_fail (file != NULL, FALSE);
@@ -348,7 +350,7 @@
 
   for (i = 0; i < 5; i++)
     {
-      for (j = 0; j < GIMP_CURVE_NUM_POINTS; j++)
+      for (j = 0; j < GIMP_CURVE_N_CRUFT_POINTS; j++)
         {
           fields = fscanf (file, "%d %d ", &index[i][j], &value[i][j]);
           if (fields != 2)
@@ -372,7 +374,7 @@
 
       gimp_curve_set_curve_type (curve, GIMP_CURVE_SMOOTH);
 
-      for (j = 0; j < GIMP_CURVE_NUM_POINTS; j++)
+      for (j = 0; j < GIMP_CURVE_N_CRUFT_POINTS; j++)
         gimp_curve_set_point (curve, j,
                               (gdouble) index[i][j] / 255.0,
                               (gdouble) value[i][j] / 255.0);
@@ -404,27 +406,46 @@
 
       if (curve->curve_type == GIMP_CURVE_FREE)
         {
-          /* pick representative points from the curve and make them
-           * control points
+          gint n_points;
+
+          for (j = 0; j < curve->n_points; j++)
+            {
+              curve->points[j].x = -1;
+              curve->points[j].y = -1;
+            }
+
+          /* pick some points from the curve and make them control
+           * points
            */
-          for (j = 0; j <= 8; j++)
+          n_points = CLAMP (9, curve->n_points / 2, curve->n_points);
+
+          for (j = 0; j < n_points; j++)
             {
-              gint32 index = CLAMP0255 (j * 32);
+              gint sample = j * (curve->n_samples - 1) / (n_points - 1);
+              gint point  = j * (curve->n_points  - 1) / (n_points - 1);
 
-              curve->points[j * 2].x = (gdouble) index / 255.0;
-              curve->points[j * 2].y = curve->curve[index];
+              curve->points[point].x = ((gdouble) sample /
+                                        (gdouble) (curve->n_samples - 1));
+              curve->points[point].y = curve->samples[sample];
             }
         }
 
-      for (j = 0; j < GIMP_CURVE_NUM_POINTS; j++)
+      for (j = 0; j < curve->n_points; j++)
         {
           gdouble x, y;
 
           gimp_curve_get_point (curve, j, &x, &y);
 
-          fprintf (file, "%d %d ",
-                   (gint) (x * 255.999),
-                   (gint) (y * 255.999));
+          if (x < 0.0 || y < 0.0)
+            {
+              fprintf (file, "%d %d ", -1, -1);
+            }
+          else
+            {
+              fprintf (file, "%d %d ",
+                       (gint) (x * 255.999),
+                       (gint) (y * 255.999));
+            }
         }
 
       fprintf (file, "\n");
@@ -451,12 +472,14 @@
        channel++)
     {
       gimp_curve_get_uchar (config->curve[channel],
+                            sizeof (cruft->curve[channel]),
                             cruft->curve[channel]);
     }
 
   if (! is_color)
     {
       gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_ALPHA],
+                            sizeof (cruft->curve[1]),
                             cruft->curve[1]);
     }
 }

Modified: trunk/app/tools/gimpcurvestool.c
==============================================================================
--- trunk/app/tools/gimpcurvestool.c	(original)
+++ trunk/app/tools/gimpcurvestool.c	Thu Feb 28 12:34:46 2008
@@ -637,7 +637,7 @@
         case GIMP_HISTOGRAM_VALUE:
         case GIMP_HISTOGRAM_ALPHA:
         case GIMP_HISTOGRAM_RGB:
-          gimp_curve_get_uchar (curve, r);
+          gimp_curve_get_uchar (curve, sizeof (r), r);
 
           gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->xrange),
                                       r, r, r);
@@ -646,9 +646,12 @@
         case GIMP_HISTOGRAM_RED:
         case GIMP_HISTOGRAM_GREEN:
         case GIMP_HISTOGRAM_BLUE:
-          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_RED],   r);
-          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_GREEN], g);
-          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_BLUE],  b);
+          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_RED],
+                                sizeof (r), r);
+          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_GREEN],
+                                sizeof (g), g);
+          gimp_curve_get_uchar (config->curve[GIMP_HISTOGRAM_BLUE],
+                                sizeof (b), b);
 
           gimp_color_bar_set_buffers (GIMP_COLOR_BAR (tool->xrange),
                                       r, g, b);

Modified: trunk/app/widgets/gimpcurveview.c
==============================================================================
--- trunk/app/widgets/gimpcurveview.c	(original)
+++ trunk/app/widgets/gimpcurveview.c	Thu Feb 28 12:34:46 2008
@@ -394,7 +394,7 @@
       gdk_cairo_set_source_color (cr, &style->text[GTK_STATE_NORMAL]);
 
       /*  Draw the unselected points  */
-      for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++)
+      for (i = 0; i < view->curve->n_points; i++)
         {
           if (i == view->selected)
             continue;
@@ -481,7 +481,7 @@
       cairo_stroke (cr);
 
       g_snprintf (buf, sizeof (buf), "x:%3d y:%3d",
-                  (gint) (view->cursor_x * 255.999),
+                  (gint) (view->cursor_x         * 255.999),
                   (gint) ((1.0 - view->cursor_y) * 255.999));
       pango_layout_set_text (view->cursor_layout, buf, -1);
 
@@ -567,7 +567,7 @@
         }
 
       view->rightmost = 2.0;
-      for (i = closest_point + 1; i < GIMP_CURVE_NUM_POINTS; i++)
+      for (i = closest_point + 1; i < curve->n_points; i++)
         {
           gdouble point_x;
 
@@ -667,7 +667,9 @@
 
           if (x > view->leftmost && x < view->rightmost)
             {
-              closest_point = ((gint) (x * 255.999) + 8) / 16;
+              gint n_points = gimp_curve_get_n_points (curve);
+
+              closest_point = ROUND (x * (gdouble) (n_points - 1));
 
               gimp_curve_get_point (curve, closest_point, &point_x, NULL);
 
@@ -684,6 +686,7 @@
     case GIMP_CURVE_FREE:
       if (view->grabbed)
         {
+          gint    n_samples = gimp_curve_get_n_samples (curve);
           gdouble x1, x2;
           gdouble y1, y2;
 
@@ -704,14 +707,19 @@
 
           if (x2 != x1)
             {
+              gint from = ROUND (x1 * (gdouble) (n_samples - 1));
+              gint to   = ROUND (x2 * (gdouble) (n_samples - 1));
               gint i;
 
               gimp_data_freeze (GIMP_DATA (curve));
 
-              for (i = (gint) (x1 * 255.999); i <= (gint) (x2 * 255.999); i++)
-                gimp_curve_set_curve (curve,
-                                      (gdouble) i / 255.0,
-                                      1.0 - (y1 + ((y2 - y1) * ((gdouble) i / 255.0 - x1)) / (x2 - x1)));
+              for (i = from; i <= to; i++)
+                {
+                  gdouble xpos = (gdouble) i / (gdouble) (n_samples - 1);
+                  gdouble ypos = (y1 + ((y2 - y1) * (xpos - x1)) / (x2 - x1));
+
+                  gimp_curve_set_curve (curve, xpos, 1.0 - ypos);
+                }
 
               gimp_data_thaw (GIMP_DATA (curve));
             }
@@ -783,7 +791,7 @@
       break;
 
     case GDK_Right:
-      for (i = i + 1; i < GIMP_CURVE_NUM_POINTS && ! retval; i++)
+      for (i = i + 1; i < curve->n_points && ! retval; i++)
         {
           gimp_curve_get_point (curve, i, &x, NULL);
 



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