get rid of fixed-size arrays and allocate the points and curve arrays
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. svn path=/trunk/; revision=24995
This commit is contained in:
parent
96645da002
commit
f4378d6237
13
ChangeLog
13
ChangeLog
@ -1,3 +1,16 @@
|
||||
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.
|
||||
|
||||
2008-02-28 Michael Natterer <mitch@gimp.org>
|
||||
|
||||
* cursors/Makefile.am
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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__ */
|
||||
|
@ -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);
|
||||
|
@ -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]);
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user