diff --git a/apps/plugins/pictureflow.c b/apps/plugins/pictureflow.c
index 665ef95..10713d0 100644
--- a/apps/plugins/pictureflow.c
+++ b/apps/plugins/pictureflow.c
@@ -24,6 +24,7 @@
****************************************************************************/

#include "plugin.h"
+#include <inttypes.h>
#include <albumart.h>
#include "lib/pluginlib_actions.h"
#include "lib/helper.h"
@@ -337,16 +338,64 @@ static inline PFreal fmul(PFreal a, PFreal b)
return (a*b) >> PFREAL_SHIFT;
}

+#define MASK_TOP_N(bits) ((uint32_t)(((1ull << 32) - 1) << (32-(bits))))
+/* Shift val as far left as possible without overflow, up to max places,
+ * reducing places by the number of places shifted.
+ */
+static inline void max_shift_left(int32_t *val, int *places)
+{
+ uint32_t uval = abs(*val);
+ bool s = uval == (uint32_t)*val;
+ if(*places >= 16 && !(MASK_TOP_N(17) & uval))
+ {
+ uval <<= 16;
+ *places -= 16;
+ }
+ if(*places >= 8 && !(MASK_TOP_N(9) & uval))
+ {
+ uval <<= 8;
+ *places -= 8;
+ }
+ if(*places >= 4 && !(MASK_TOP_N(5) & uval))
+ {
+ uval <<= 4;
+ *places -= 4;
+ }
+ if(*places >= 2 && !(MASK_TOP_N(3) & uval))
+ {
+ uval <<= 2;
+ *places -= 2;
+ }
+ if(*places && !(MASK_TOP_N(2) & uval))
+ {
+ uval <<= 1;
+ *places -= 1;
+ }
+ *val = s ? uval : -uval;
+}
+
+/* Return the maximum possible left shift for a signed int32, without
+ * overflow
+ */
+unsigned int allowed_shift(int32_t val)
+{
+ uint32_t uval = abs(val);
+ if (!uval)
+ return 32;
+ else
+ return __builtin_clz(uval) - 1;
+}
+
/* There are some precision issues when not using (long long) which in turn
takes very long to compute... I guess the best solution would be to optimize
the computations so it only requires a single long */
-static inline PFreal fdiv(PFreal num, PFreal den)
+PFreal fdiv(PFreal num, PFreal den)
{
- long long p = (long long) (num) << (PFREAL_SHIFT * 2);
- long long q = p / (long long) den;
- long long r = q >> PFREAL_SHIFT;
-
- return r;
+// int shift = MIN(allowed_shift(num), PFREAL_SHIFT);
+ int places = PFREAL_SHIFT;
+ max_shift_left(&num, &places);
+ den >>= places;
+ return num / den;
}

#define fmin(a,b) (((a) < (b)) ? (a) : (b))