controller: fixes int overflow with properties that span +-INT_MAX
authorAdrian Pardini <publico@tangopardo.com.ar>
Wed, 7 Aug 2013 17:17:28 +0000 (14:17 -0300)
committerSebastian Dröge <slomo@circular-chaos.org>
Thu, 8 Aug 2013 10:31:49 +0000 (12:31 +0200)
When the range for a property is defined as -INT_MAX-1 .. INT_MAX, like
the xpos in a videomixer the following expression in the macro
definitions of convert_g_value_to_##type (and the equivalent in
convert_value_to_##type)

v = pspec->minimum + (g##type) ROUNDING_OP ((pspec->maximum - pspec->minimum) * s);

are converted to:

v = -2147483648 + (g##type) ROUNDING_OP ((2147483647 - -2147483648) * s);

(2147483647 - -2147483648) overflows to -1 and the net result is:

v = -2147483648 + (g##type) ROUNDING_OP (-1 * s);

so v only takes the values -2147483648 for s == 0 and 2147483647
for s == 1.

Rewriting the expression as minimum*(1-s) + maximum*s gives the correct
result in this case.

https://bugzilla.gnome.org//show_bug.cgi?id=705630

libs/gst/controller/gstdirectcontrolbinding.c

index b7d06bc..ca173b0 100644 (file)
@@ -85,7 +85,7 @@ convert_g_value_to_##type (GstDirectControlBinding *self, gdouble s, GValue *d)
   g##type v; \
   \
   s = CLAMP (s, 0.0, 1.0); \
-  v = pspec->minimum + (g##type) ROUNDING_OP ((pspec->maximum - pspec->minimum) * s); \
+  v = (g##type) ROUNDING_OP (pspec->minimum * (1-s)) + (g##type) ROUNDING_OP (pspec->maximum * s); \
   g_value_set_##type (d, v); \
 } \
 \
@@ -96,7 +96,7 @@ convert_value_to_##type (GstDirectControlBinding *self, gdouble s, gpointer d_)
   g##type *d = (g##type *)d_; \
   \
   s = CLAMP (s, 0.0, 1.0); \
-  *d = pspec->minimum + (g##type) ROUNDING_OP ((pspec->maximum - pspec->minimum) * s); \
+  *d = (g##type) ROUNDING_OP (pspec->minimum * (1-s)) + (g##type) ROUNDING_OP (pspec->maximum * s); \
 }