diff --git a/src/loaders/webp/utils/bit_reader.cpp b/src/loaders/webp/utils/bit_reader.cpp index a268c646..84c5c46b 100644 --- a/src/loaders/webp/utils/bit_reader.cpp +++ b/src/loaders/webp/utils/bit_reader.cpp @@ -16,6 +16,7 @@ #endif #include "./bit_reader_inl.h" +#include "./utils.h" //------------------------------------------------------------------------------ // VP8BitReader @@ -109,11 +110,10 @@ int32_t VP8GetSignedValue(VP8BitReader* const br, int bits) { #define VP8L_LOG8_WBITS 4 // Number of bytes needed to store VP8L_WBITS bits. -#if !defined(WEBP_FORCE_ALIGNED) && \ - (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \ +#if (defined(__arm__) || defined(_M_ARM) || defined(__aarch64__) || \ defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64__) || defined(_M_X64)) -#define VP8L_USE_UNALIGNED_LOAD +#define VP8L_USE_FAST_LOAD #endif static const uint32_t kBitMask[VP8L_MAX_NUM_BIT_READ + 1] = { @@ -183,13 +183,13 @@ void VP8LDoFillBitWindow(VP8LBitReader* const br) { assert(br->bit_pos_ >= VP8L_WBITS); // TODO(jzern): given the fixed read size it may be possible to force // alignment in this block. -#if defined(VP8L_USE_UNALIGNED_LOAD) +#if defined(VP8L_USE_FAST_LOAD) if (br->pos_ + sizeof(br->val_) < br->len_) { br->val_ >>= VP8L_WBITS; br->bit_pos_ -= VP8L_WBITS; // The expression below needs a little-endian arch to work correctly. // This gives a large speedup for decoding speed. - br->val_ |= (vp8l_val_t)*(const uint32_t*)(br->buf_ + br->pos_) << + br->val_ |= (vp8l_val_t)HToLE32(WebPMemToUint32(br->buf_ + br->pos_)) << (VP8L_LBITS - VP8L_WBITS); br->pos_ += VP8L_LOG8_WBITS; return; diff --git a/src/loaders/webp/utils/bit_reader_inl.h b/src/loaders/webp/utils/bit_reader_inl.h index 1f79c941..aa317119 100644 --- a/src/loaders/webp/utils/bit_reader_inl.h +++ b/src/loaders/webp/utils/bit_reader_inl.h @@ -20,9 +20,7 @@ #include "../webp/config.h" #endif -#ifdef WEBP_FORCE_ALIGNED #include // memcpy -#endif #include "../dsp/dsp.h" #include "./bit_reader.h" @@ -61,10 +59,7 @@ static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) { if (br->buf_ + sizeof(lbit_t) <= br->buf_end_) { // convert memory type to register type (with some zero'ing!) bit_t bits; -#if defined(WEBP_FORCE_ALIGNED) - lbit_t in_bits; - memcpy(&in_bits, br->buf_, sizeof(in_bits)); -#elif defined(WEBP_USE_MIPS32) +#if defined(WEBP_USE_MIPS32) // This is needed because of un-aligned read. lbit_t in_bits; lbit_t* p_buf_ = (lbit_t*)br->buf_; @@ -79,7 +74,8 @@ static WEBP_INLINE void VP8LoadNewBytes(VP8BitReader* const br) { : "memory", "at" ); #else - const lbit_t in_bits = *(const lbit_t*)br->buf_; + lbit_t in_bits; + memcpy(&in_bits, br->buf_, sizeof(in_bits)); #endif br->buf_ += BITS >> 3; #if !defined(WORDS_BIGENDIAN) diff --git a/src/loaders/webp/utils/utils.h b/src/loaders/webp/utils/utils.h index 3dba9427..29331d23 100644 --- a/src/loaders/webp/utils/utils.h +++ b/src/loaders/webp/utils/utils.h @@ -59,6 +59,18 @@ static WEBP_INLINE int BitsLog2Floor(uint32_t n) { } #endif +//------------------------------------------------------------------------------ +//------------------------------------------------------------------------------ +// Alignment + +#include +// memcpy() is the safe way of moving potentially unaligned 32b memory. +static WEBP_INLINE uint32_t WebPMemToUint32(const uint8_t* const ptr) { + uint32_t A; + memcpy(&A, ptr, sizeof(A)); + return A; +} + //------------------------------------------------------------------------------ #ifdef __cplusplus