diff --git a/src/zopfli/symbols.h b/src/zopfli/symbols.h index b49df06c..d2db9622 100644 --- a/src/zopfli/symbols.h +++ b/src/zopfli/symbols.h @@ -32,16 +32,23 @@ Utilities for using the lz77 symbols of the deflate spec. /* __builtin_clz available beginning with GCC 3.4 */ #elif __GNUC__ * 100 + __GNUC_MINOR__ >= 304 # define ZOPFLI_HAS_BUILTIN_CLZ +/* _BitScanReverse available beginning with Visual Studio 2005 */ +#elif _MSC_VER >= 1400 +# include +# define ZOPFLI_HAS_BITSCANREVERSE #endif /* Gets the amount of extra bits for the given dist, cfr. the DEFLATE spec. */ static int ZopfliGetDistExtraBits(int dist) { -#ifdef ZOPFLI_HAS_BUILTIN_CLZ if (dist < 5) return 0; +#ifdef ZOPFLI_HAS_BUILTIN_CLZ return (31 ^ __builtin_clz(dist - 1)) - 1; /* log2(dist - 1) - 1 */ +#elif defined ZOPFLI_HAS_BITSCANREVERSE + unsigned long l; + _BitScanReverse(&l, dist - 1); + return l - 1; #else - if (dist < 5) return 0; - else if (dist < 9) return 1; + if (dist < 9) return 1; else if (dist < 17) return 2; else if (dist < 33) return 3; else if (dist < 65) return 4; @@ -66,6 +73,14 @@ static int ZopfliGetDistExtraBitsValue(int dist) { int l = 31 ^ __builtin_clz(dist - 1); /* log2(dist - 1) */ return (dist - (1 + (1 << l))) & ((1 << (l - 1)) - 1); } +#elif defined ZOPFLI_HAS_BITSCANREVERSE + if (dist < 5) { + return 0; + } else { + unsigned long l; + _BitScanReverse(&l, dist - 1); + return (dist - (1 + (1 << l))) & ((1 << (l - 1)) - 1); + } #else if (dist < 5) return 0; else if (dist < 9) return (dist - 5) & 1; @@ -94,6 +109,15 @@ static int ZopfliGetDistSymbol(int dist) { int r = ((dist - 1) >> (l - 1)) & 1; return l * 2 + r; } +#elif defined ZOPFLI_HAS_BITSCANREVERSE + if (dist < 5) { + return dist - 1; + } else { + unsigned long l; + _BitScanReverse(&l, dist - 1); + int r = ((dist - 1) >> (l - 1)) & 1; + return l * 2 + r; + } #else if (dist < 193) { if (dist < 13) { /* dist 0..13. */