diff --git a/ChangeLog b/ChangeLog index 647707e48c..51e6e1c447 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,16 @@ +2008-02-28 Michael Natterer + + * 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. + 2008-02-28 Michael Natterer * cursors/Makefile.am diff --git a/app/core/gimpcurve.c b/app/core/gimpcurve.c index df8e456e8f..377fc7d3ca 100644 --- a/app/core/gimpcurve.c +++ b/app/core/gimpcurve.c @@ -38,8 +38,10 @@ enum { PROP_0, PROP_CURVE_TYPE, + PROP_N_POINTS, PROP_POINTS, - PROP_CURVE + PROP_N_SAMPLES, + PROP_SAMPLES }; @@ -81,6 +83,11 @@ static void gimp_curve_dirty (GimpData *data); 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_curve_class_init (GimpCurveClass *klass) 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 @@ gimp_curve_class_init (GimpCurveClass *klass) static void gimp_curve_init (GimpCurve *curve) { - gimp_curve_reset (curve, TRUE); } static void @@ -150,6 +168,18 @@ gimp_curve_finalize (GObject *object) { 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_property (GObject *object, 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 @@ gimp_curve_get_property (GObject *object, 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 @@ gimp_curve_get_memsize (GimpObject *object, 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 @@ gimp_curve_reset (GimpCurve *curve, 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 < 256; i++) - curve->curve[i] = (gdouble) i / 255.0; + for (i = 0; i < curve->n_samples; i++) + curve->samples[i] = (gdouble) i / (gdouble) (curve->n_samples - 1); - for (i = 0; i < GIMP_CURVE_NUM_POINTS; i++) + g_object_notify (G_OBJECT (curve), "samples"); + + 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 @@ gimp_curve_set_curve_type (GimpCurve *curve, 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 <= 8; i++) + for (i = 0; i < curve->n_points; i++) { - gint32 index = CLAMP0255 (i * 32); + curve->points[i].x = -1; + curve->points[i].y = -1; + } - curve->points[i * 2].x = (gdouble) index / 255.0; - curve->points[i * 2].y = curve->curve[index]; + /* pick some points from the curve and make them control + * points + */ + n_points = CLAMP (9, curve->n_points / 2, curve->n_points); + + for (i = 0; i < n_points; i++) + { + gint sample = i * (curve->n_samples - 1) / (n_points - 1); + gint point = i * (curve->n_points - 1) / (n_points - 1); + + 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 @@ gimp_curve_get_curve_type (GimpCurve *curve) 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 @@ gimp_curve_get_closest_point (GimpCurve *curve, 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 @@ gimp_curve_get_closest_point (GimpCurve *curve, } } - 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 @@ gimp_curve_set_point (GimpCurve *curve, 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 @@ gimp_curve_move_point (GimpCurve *curve, 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 @@ gimp_curve_get_point (GimpCurve *curve, 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 @@ gimp_curve_set_curve (GimpCurve *curve, 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 @@ gimp_curve_map (GimpCurve *curve, 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 @@ gimp_curve_map (GimpCurve *curve, 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 @@ static void 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 @@ gimp_curve_calculate (GimpCurve *curve) 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 @@ gimp_curve_calculate (GimpCurve *curve) 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 @@ gimp_curve_plot (GimpCurve *curve, 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 @@ gimp_curve_plot (GimpCurve *curve, * 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); } } diff --git a/app/core/gimpcurve.h b/app/core/gimpcurve.h index b2e2efe38c..4578aa5014 100644 --- a/app/core/gimpcurve.h +++ b/app/core/gimpcurve.h @@ -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 @@ struct _GimpCurve 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 @@ void gimp_curve_set_curve_type (GimpCurve *curve, 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 gimp_curve_map (GimpCurve *curve, gdouble x); void gimp_curve_get_uchar (GimpCurve *curve, - guchar *dest_array); + gint n_samples, + guchar *samples); #endif /* __GIMP_CURVE_H__ */ diff --git a/app/core/gimpdrawable-curves.c b/app/core/gimpdrawable-curves.c index a8d3c9cdab..54cfca6fa7 100644 --- a/app/core/gimpdrawable-curves.c +++ b/app/core/gimpdrawable-curves.c @@ -80,10 +80,15 @@ gimp_drawable_curves_spline (GimpDrawable *drawable, 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); diff --git a/app/gegl/gimpcurvesconfig.c b/app/gegl/gimpcurvesconfig.c index d9b5a3ad8a..eb74baf8b7 100644 --- a/app/gegl/gimpcurvesconfig.c +++ b/app/gegl/gimpcurvesconfig.c @@ -201,9 +201,9 @@ gimp_curves_config_set_property (GObject *object, 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 @@ gimp_curves_config_equal (GimpConfig *a, 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_curves_config_copy (GimpConfig *src, { 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_curves_config_reset_channel (GimpCurvesConfig *config) 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 @@ gimp_curves_config_load_cruft (GimpCurvesConfig *config, 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 @@ gimp_curves_config_load_cruft (GimpCurvesConfig *config, 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_curves_config_load_cruft (GimpCurvesConfig *config, 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 @@ gimp_curves_config_save_cruft (GimpCurvesConfig *config, if (curve->curve_type == GIMP_CURVE_FREE) { - /* pick representative points from the curve and make them - * control points - */ - for (j = 0; j <= 8; j++) - { - gint32 index = CLAMP0255 (j * 32); + gint n_points; - curve->points[j * 2].x = (gdouble) index / 255.0; - curve->points[j * 2].y = curve->curve[index]; + 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 + */ + n_points = CLAMP (9, curve->n_points / 2, curve->n_points); + + for (j = 0; j < n_points; j++) + { + gint sample = j * (curve->n_samples - 1) / (n_points - 1); + gint point = j * (curve->n_points - 1) / (n_points - 1); + + 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 @@ gimp_curves_config_to_cruft (GimpCurvesConfig *config, 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]); } } diff --git a/app/tools/gimpcurvestool.c b/app/tools/gimpcurvestool.c index 04f49a5dc3..ed5388fc2b 100644 --- a/app/tools/gimpcurvestool.c +++ b/app/tools/gimpcurvestool.c @@ -637,7 +637,7 @@ gimp_curves_tool_config_notify (GObject *object, 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 @@ gimp_curves_tool_config_notify (GObject *object, 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); diff --git a/app/widgets/gimpcurveview.c b/app/widgets/gimpcurveview.c index 41f32d4231..2e9ae3a40b 100644 --- a/app/widgets/gimpcurveview.c +++ b/app/widgets/gimpcurveview.c @@ -394,7 +394,7 @@ gimp_curve_view_expose (GtkWidget *widget, 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 @@ gimp_curve_view_expose (GtkWidget *widget, 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 @@ gimp_curve_view_button_press (GtkWidget *widget, } 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 @@ gimp_curve_view_motion_notify (GtkWidget *widget, 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 @@ gimp_curve_view_motion_notify (GtkWidget *widget, 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 @@ gimp_curve_view_motion_notify (GtkWidget *widget, 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 @@ gimp_curve_view_key_press (GtkWidget *widget, 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);