Skip to content
This repository was archived by the owner on Oct 14, 2025. It is now read-only.

Commit 86cdb4c

Browse files
committed
Utilize _BitScanReverse in Visual Studio
_BitScanReverse is documented here: https://msdn.microsoft.com/en-us/library/fbxyd7zd.aspx This improves speed of a VS2015 x64 build by more than 10%.
1 parent 0dfa6eb commit 86cdb4c

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

src/zopfli/symbols.h

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -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. */
3842
static 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

Comments
 (0)