From 78dd7a41e6cae41db799c68af013cc1271797c8b Mon Sep 17 00:00:00 2001 From: JunsuChoi Date: Fri, 8 Mar 2024 14:37:07 +0900 Subject: [PATCH] loader/webp: Remove WEBP_FORCE_ALIGNED and use memcpy() instead The google's libwebp source uses aligned memory access. This patch is that applies the two commits below to our static lib code. refer to: [Remove WEBP_FORCE_ALIGNED and use memcpy() instead] https://github.com/webmproject/libwebp/commit/3884972e3f9ae887e0c16ca342851eff3ae67485 [bit_reader.c: s/VP8L_USE_UNALIGNED_LOAD/VP8L_USE_FAST_LOAD/] https://github.com/webmproject/libwebp/commit/ac49e4e4dc05d6dcd4083aaa41965713e42c1c35 source : https://chromium.googlesource.com/webm/libwebp/+/refs/heads/main/src/utils/bit_reader_inl_utils.h#80 related issue: https://github.com/thorvg/thorvg/issues/2006 --- src/loaders/webp/utils/bit_reader.cpp | 10 +++++----- src/loaders/webp/utils/bit_reader_inl.h | 10 +++------- src/loaders/webp/utils/utils.h | 12 ++++++++++++ 3 files changed, 20 insertions(+), 12 deletions(-) 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