summaryrefslogtreecommitdiff
path: root/apps/plugins/pictureflow.c
diff options
context:
space:
mode:
authorAndrew Mahone <andrew.mahone@gmail.com>2009-01-30 03:40:16 +0000
committerAndrew Mahone <andrew.mahone@gmail.com>2009-01-30 03:40:16 +0000
commit78409ff50c16d89ba5931f0a57b45ac1f5367573 (patch)
tree4dce5108bc83e49a1b1f72ec098e61b39f01513d /apps/plugins/pictureflow.c
parent8751b94e48dcb6cb72bd916b5a7b2c23d7410cdf (diff)
downloadrockbox-78409ff50c16d89ba5931f0a57b45ac1f5367573.tar.gz
rockbox-78409ff50c16d89ba5931f0a57b45ac1f5367573.zip
remove 64-bit math from fdiv in pictureflow.c, replacing it with limited pre-shifting of input values
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@19886 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/pictureflow.c')
-rw-r--r--apps/plugins/pictureflow.c71
1 files changed, 63 insertions, 8 deletions
diff --git a/apps/plugins/pictureflow.c b/apps/plugins/pictureflow.c
index 665ef9576f..025d1e6be2 100644
--- a/apps/plugins/pictureflow.c
+++ b/apps/plugins/pictureflow.c
@@ -337,17 +337,73 @@ static inline PFreal fmul(PFreal a, PFreal b)
337 return (a*b) >> PFREAL_SHIFT; 337 return (a*b) >> PFREAL_SHIFT;
338} 338}
339 339
340/* There are some precision issues when not using (long long) which in turn 340/* ARMv5+ have a clz instruction. So do most modern desktop processors, and the
341 takes very long to compute... I guess the best solution would be to optimize 341 * simulator doesn't need to be as concerned about savings for inlining a calls
342 the computations so it only requires a single long */ 342 * to a clz function.
343static inline PFreal fdiv(PFreal num, PFreal den) 343 */
344#if defined(SIMULATOR) || (defined(CPU_ARM) && (ARM_ARCH > 4))
345static inline int clz(uint32_t v)
344{ 346{
345 long long p = (long long) (num) << (PFREAL_SHIFT * 2); 347 return __builtin_clz(v);
346 long long q = p / (long long) den; 348}
347 long long r = q >> PFREAL_SHIFT;
348 349
350/* Otherwise, use our clz, which can be inlined */
351#else
352/* This clz is based on the log2(n) implementation at
353 * http://graphics.stanford.edu/~seander/bithacks.html#IntegerLog
354 */
355static inline int clz(uint32_t v)
356{
357 uint32_t r = 31;
358 if (v > 0x8000)
359 {
360 v >>= 16;
361 r -= 16;
362 }
363 if (v & 0xff00)
364 {
365 v >>= 8;
366 r -= 8;
367 }
368 if (v & 0xf0)
369 {
370 v >>= 4;
371 r -= 4;
372 }
373 if (v & 0xc)
374 {
375 v >>= 2;
376 r -= 2;
377 }
378 if (v & 2)
379 r -= 1;
349 return r; 380 return r;
350} 381}
382#endif
383
384/* Return the maximum possible left shift for a signed int32, without
385 * overflow
386 */
387static inline int allowed_shift(int32_t val)
388{
389 uint32_t uval = val ^ (val >> 31);
390 if (!uval)
391 return 31;
392 else
393 return clz(uval) - 1;
394}
395
396/* Calculate num/den, with the result shifted left by PFREAL_SHIFT, by shifting
397 * num and den before dividing.
398 */
399static inline PFreal fdiv(PFreal num, PFreal den)
400{
401 int shift = allowed_shift(num);
402 shift = MIN(PFREAL_SHIFT, shift);
403 num <<= shift;
404 den >>= PFREAL_SHIFT - shift;
405 return num / den;
406}
351 407
352#define fmin(a,b) (((a) < (b)) ? (a) : (b)) 408#define fmin(a,b) (((a) < (b)) ? (a) : (b))
353#define fmax(a,b) (((a) > (b)) ? (a) : (b)) 409#define fmax(a,b) (((a) > (b)) ? (a) : (b))
@@ -579,7 +635,6 @@ int create_track_index(const int slide_index)
579 return (track_count > 0) ? 0 : -1; 635 return (track_count > 0) ? 0 : -1;
580} 636}
581 637
582
583/** 638/**
584 Determine filename of the album art for the given slide_index and 639 Determine filename of the album art for the given slide_index and
585 store the result in buf. 640 store the result in buf.