diff options
author | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-21 12:43:42 +0100 |
---|---|---|
committer | Reimar Döffinger <Reimar.Doeffinger@gmx.de> | 2012-01-21 16:35:11 +0100 |
commit | def19c9036834446f5ac56c22fbf257bd5de281a (patch) | |
tree | b7534af54c06367d52538628a5d82bb06f03d24c | |
parent | 523f676b51d8a2eaeb7d75ccdb0258d271430430 (diff) | |
download | ffmpeg-def19c9036834446f5ac56c22fbf257bd5de281a.tar.gz |
Unroll base64 decode loop.
Around 50% faster.
decode: 374139 -> 248852 decicycles
syntax check: 236955 -> 123854 decicycles
Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de>
-rw-r--r-- | libavutil/base64.c | 49 |
1 files changed, 36 insertions, 13 deletions
diff --git a/libavutil/base64.c b/libavutil/base64.c index 6eccd9c9a0..df0f6a3853 100644 --- a/libavutil/base64.c +++ b/libavutil/base64.c @@ -26,7 +26,6 @@ #include "common.h" #include "base64.h" -#include "avassert.h" #include "intreadwrite.h" /* ---------------- private code */ @@ -69,29 +68,53 @@ static const uint8_t map2[256] = 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, }; +#define BASE64_DEC_STEP(i) \ + bits = map2[in[i]]; \ + if (bits & 0x80) \ + goto out; \ + v = (v << 6) + bits; \ + if (i & 3) \ + *dst++ = v >> (6 - 2 * (i & 3)); \ + int av_base64_decode(uint8_t *out, const char *in_str, int out_size) { - int i, v; + int v; uint8_t *dst = out; uint8_t *end = out + out_size; // no sign extension const uint8_t *in = in_str; + unsigned bits = 0xff; v = 0; - for (i = 0; ; i++) { - unsigned bits = map2[in[i]]; - if (bits & 0x80) - return bits & 1 ? -1 : dst - out; - v = (v << 6) + bits; - if (i & 3) { - if (dst < end) { - *dst++ = v >> (6 - 2 * (i & 3)); - } + while (end - dst > 2) { + BASE64_DEC_STEP(0) + BASE64_DEC_STEP(1) + BASE64_DEC_STEP(2) + BASE64_DEC_STEP(3) + in += 4; + } + if (end - dst) { + BASE64_DEC_STEP(0) + BASE64_DEC_STEP(1) + if (end - dst) { + BASE64_DEC_STEP(2) + in++; } + in += 2; + } + while (1) { + BASE64_DEC_STEP(0) + in++; + BASE64_DEC_STEP(0) + in++; + BASE64_DEC_STEP(0) + in++; + BASE64_DEC_STEP(0) + in++; } - av_assert1(0); - return 0; +out: + return bits & 1 ? -1 : dst - out; } /***************************************************************************** |