@@ -32,16 +32,23 @@ Utilities for using the lz77 symbols of the deflate spec.
3232/* __builtin_clz available beginning with GCC 3.4 */
3333#elif __GNUC__ * 100 + __GNUC_MINOR__ >= 304
3434# define ZOPFLI_HAS_BUILTIN_CLZ
35+ /* _BitScanReverse available beginning with Visual Studio 2005 */
36+ #elif _MSC_VER >= 1400
37+ # include <intrin.h>
38+ # define ZOPFLI_HAS_BITSCANREVERSE
3539#endif
3640
3741/* Gets the amount of extra bits for the given dist, cfr. the DEFLATE spec. */
3842static int ZopfliGetDistExtraBits (int dist ) {
39- #ifdef ZOPFLI_HAS_BUILTIN_CLZ
4043 if (dist < 5 ) return 0 ;
44+ #ifdef ZOPFLI_HAS_BUILTIN_CLZ
4145 return (31 ^ __builtin_clz (dist - 1 )) - 1 ; /* log2(dist - 1) - 1 */
46+ #elif defined ZOPFLI_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 ;
@@ -66,6 +73,14 @@ static int ZopfliGetDistExtraBitsValue(int dist) {
6673 int l = 31 ^ __builtin_clz (dist - 1 ); /* log2(dist - 1) */
6774 return (dist - (1 + (1 << l ))) & ((1 << (l - 1 )) - 1 );
6875 }
76+ #elif defined ZOPFLI_HAS_BITSCANREVERSE
77+ if (dist < 5 ) {
78+ return 0 ;
79+ } else {
80+ unsigned long l ;
81+ _BitScanReverse (& l , dist - 1 );
82+ return (dist - (1 + (1 << l ))) & ((1 << (l - 1 )) - 1 );
83+ }
6984#else
7085 if (dist < 5 ) return 0 ;
7186 else if (dist < 9 ) return (dist - 5 ) & 1 ;
@@ -94,6 +109,15 @@ static int ZopfliGetDistSymbol(int dist) {
94109 int r = ((dist - 1 ) >> (l - 1 )) & 1 ;
95110 return l * 2 + r ;
96111 }
112+ #elif defined ZOPFLI_HAS_BITSCANREVERSE
113+ if (dist < 5 ) {
114+ return dist - 1 ;
115+ } else {
116+ unsigned long l ;
117+ _BitScanReverse (& l , dist - 1 );
118+ int r = ((dist - 1 ) >> (l - 1 )) & 1 ;
119+ return l * 2 + r ;
120+ }
97121#else
98122 if (dist < 193 ) {
99123 if (dist < 13 ) { /* dist 0..13. */
0 commit comments