aboutsummaryrefslogtreecommitdiff
path: root/src/utils/bit_reader.h
diff options
context:
space:
mode:
authorVikas Arora <vikasa@google.com>2013-01-29 16:19:32 -0800
committerVikas Arora <vikasa@google.com>2013-02-06 12:42:45 -0800
commit4b2196c929b70f2cdc1c2556580d349db89356d8 (patch)
tree579254d51f66d5554655598d8e2d24d9732d955d /src/utils/bit_reader.h
parent276905dd9bf0cffd7e04c78c95f2c1057275d5bd (diff)
downloadwebp-4b2196c929b70f2cdc1c2556580d349db89356d8.tar.gz
Sync libwebp with head#I6ecefe33
Also added ARM/NEON code for decoder/encoder modules. Change-Id: Ic8028037c94c1191c193d881b799a961b476138e
Diffstat (limited to 'src/utils/bit_reader.h')
-rw-r--r--src/utils/bit_reader.h38
1 files changed, 30 insertions, 8 deletions
diff --git a/src/utils/bit_reader.h b/src/utils/bit_reader.h
index 11a40a55..a9c32436 100644
--- a/src/utils/bit_reader.h
+++ b/src/utils/bit_reader.h
@@ -24,11 +24,28 @@
extern "C" {
#endif
-#define BITS 32 // can be 32, 16 or 8
+//------------------------------------------------------------------------------
+// BITS can be either 32, 24, 16 or 8.
+// Pick values that fit natural register size.
+
+#if defined(__i386__) || defined(_M_IX86) // x86 32bit
+#define BITS 16
+#elif defined(__arm__) || defined(_M_ARM) // ARM
+#define BITS 8
+#else // reasonable default
+#define BITS 32
+#endif
+
+//------------------------------------------------------------------------------
+// Derived types and constants
+
#define MASK ((((bit_t)1) << (BITS)) - 1)
#if (BITS == 32)
typedef uint64_t bit_t; // natural register type
typedef uint32_t lbit_t; // natural type for memory I/O
+#elif (BITS == 24)
+typedef uint32_t bit_t;
+typedef uint32_t lbit_t;
#elif (BITS == 16)
typedef uint32_t bit_t;
typedef uint16_t lbit_t;
@@ -38,7 +55,7 @@ typedef uint8_t lbit_t;
#endif
//------------------------------------------------------------------------------
-// Bitreader and code-tree reader
+// Bitreader
typedef struct VP8BitReader VP8BitReader;
struct VP8BitReader {
@@ -80,21 +97,26 @@ static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) {
lbit_t in_bits = *(lbit_t*)br->buf_;
br->buf_ += (BITS) >> 3;
#if !defined(__BIG_ENDIAN__)
-#if (BITS == 32)
+#if (BITS == 32) || (BITS == 24)
#if defined(__i386__) || defined(__x86_64__)
__asm__ volatile("bswap %k0" : "=r"(in_bits) : "0"(in_bits));
- bits = (bit_t)in_bits; // 32b -> 64b zero-extension
+ bits = (bit_t)in_bits; // 24b/32b -> 32b/64b zero-extension
#elif defined(_MSC_VER)
bits = _byteswap_ulong(in_bits);
#else
bits = (bit_t)(in_bits >> 24) | ((in_bits >> 8) & 0xff00)
| ((in_bits << 8) & 0xff0000) | (in_bits << 24);
#endif // x86
+#if (BITS == 24)
+ bits >>= 8;
+#endif
#elif (BITS == 16)
// gcc will recognize a 'rorw $8, ...' here:
bits = (bit_t)(in_bits >> 8) | ((in_bits & 0xff) << 8);
+#else // BITS == 8
+ bits = (bit_t)in_bits;
#endif
-#else // LITTLE_ENDIAN
+#else // BIG_ENDIAN
bits = (bit_t)in_bits;
#endif
br->value_ |= bits << br->missing_;
@@ -121,7 +143,7 @@ static WEBP_INLINE int VP8BitUpdate(VP8BitReader* const br, bit_t split) {
static WEBP_INLINE void VP8Shift(VP8BitReader* const br) {
// range_ is in [0..127] interval here.
- const int idx = br->range_ >> (BITS);
+ const bit_t idx = br->range_ >> (BITS);
const int shift = kVP8Log2Range[idx];
br->range_ = kVP8NewRange[idx];
br->value_ <<= shift;
@@ -149,7 +171,7 @@ static WEBP_INLINE int VP8GetSigned(VP8BitReader* const br, int v) {
// -----------------------------------------------------------------------------
-// Bitreader
+// Bitreader for lossless format
typedef struct {
uint64_t val_;
@@ -182,7 +204,7 @@ uint32_t VP8LReadOneBit(VP8LBitReader* const br);
// 32 times after the last VP8LFillBitWindow. Any subsequent calls
// (without VP8LFillBitWindow) will return invalid data.
static WEBP_INLINE uint32_t VP8LReadOneBitUnsafe(VP8LBitReader* const br) {
- const uint32_t val = (br->val_ >> br->bit_pos_) & 1;
+ const uint32_t val = (uint32_t)((br->val_ >> br->bit_pos_) & 1);
++br->bit_pos_;
return val;
}