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))