3333/* __builtin_clz available beginning with GCC 3.4 */
3434#elif __GNUC__ * 100 + __GNUC_MINOR__ >= 304
3535# define HAS_BUILTIN_CLZ
36+ /* _BitScanReverse available beginning with Visual Studio 2005 */
37+ #elif _MSC_VER >= 1400
38+ # include <intrin.h>
39+ # define HAS_BITSCANREVERSE
3640#endif
3741
3842int ZopfliGetDistExtraBits (int dist ) {
39- #ifdef HAS_BUILTIN_CLZ
4043 if (dist < 5 ) return 0 ;
44+ #ifdef HAS_BUILTIN_CLZ
4145 return (31 ^ __builtin_clz (dist - 1 )) - 1 ; /* log2(dist - 1) - 1 */
46+ #elif defined HAS_BITSCANREVERSE
47+ unsigned long l ;
48+ _BitScanReverse (& l , dist - 1 );
49+ return l - 1 ;
4250#else
43- if (dist < 5 ) return 0 ;
44- else if (dist < 9 ) return 1 ;
51+ if (dist < 9 ) return 1 ;
4552 else if (dist < 17 ) return 2 ;
4653 else if (dist < 33 ) return 3 ;
4754 else if (dist < 65 ) return 4 ;
@@ -65,6 +72,14 @@ int ZopfliGetDistExtraBitsValue(int dist) {
6572 int l = 31 ^ __builtin_clz (dist - 1 ); /* log2(dist - 1) */
6673 return (dist - (1 + (1 << l ))) & ((1 << (l - 1 )) - 1 );
6774 }
75+ #elif defined HAS_BITSCANREVERSE
76+ if (dist < 5 ) {
77+ return 0 ;
78+ } else {
79+ unsigned long l ;
80+ _BitScanReverse (& l , dist - 1 );
81+ return (dist - (1 + (1 << l ))) & ((1 << (l - 1 )) - 1 );
82+ }
6883#else
6984 if (dist < 5 ) return 0 ;
7085 else if (dist < 9 ) return (dist - 5 ) & 1 ;
@@ -92,6 +107,15 @@ int ZopfliGetDistSymbol(int dist) {
92107 int r = ((dist - 1 ) >> (l - 1 )) & 1 ;
93108 return l * 2 + r ;
94109 }
110+ #elif defined HAS_BITSCANREVERSE
111+ if (dist < 5 ) {
112+ return dist - 1 ;
113+ } else {
114+ unsigned long l ;
115+ _BitScanReverse (& l , dist - 1 );
116+ int r = ((dist - 1 ) >> (l - 1 )) & 1 ;
117+ return l * 2 + r ;
118+ }
95119#else
96120 if (dist < 193 ) {
97121 if (dist < 13 ) { /* dist 0..13. */
0 commit comments