diff --git a/src/core/openjph/ojph_mem.h b/src/core/openjph/ojph_mem.h index 599f36d..d9f22b5 100644 --- a/src/core/openjph/ojph_mem.h +++ b/src/core/openjph/ojph_mem.h @@ -245,11 +245,19 @@ namespace ojph { private: struct stores_list { + // Payload (coded_lists + bitstream) must start at a multiple of 16 bytes. + // Otherwise coded_lists::buf can be 4 mod 8, which causes misalignment + // on 32-bit architectures. So round sizeof(stores_list) to next + // multiple of 16. + static constexpr ui32 stores_list_size16() + { + return (ui32) ((sizeof (stores_list) + 15u) & ~15u); + } stores_list(ui32 available_bytes) { this->next_store = NULL; this->orig_size = this->available = available_bytes; - this->orig_data = this->data = (ui8*)this + sizeof(stores_list); + this->orig_data = this->data = (ui8*)this + stores_list_size16(); } void restart() { @@ -259,7 +267,7 @@ namespace ojph { } static ui32 eval_store_bytes(ui32 available_bytes) { // calculates how many bytes need to be allocated - return available_bytes + (ui32)sizeof(stores_list); + return available_bytes + stores_list_size16(); } stores_list *next_store; ui8 *orig_data, *data; diff --git a/src/core/others/ojph_mem.cpp b/src/core/others/ojph_mem.cpp index fcb9e63..ca7a561 100644 --- a/src/core/others/ojph_mem.cpp +++ b/src/core/others/ojph_mem.cpp @@ -112,7 +112,10 @@ namespace ojph { //////////////////////////////////////////////////////////////////////////// void mem_elastic_allocator::get_buffer(ui32 needed_bytes, coded_lists* &p) { - ui32 extended_bytes = needed_bytes + (ui32)sizeof(coded_lists); + // Round up so each coded_lists (and coded_lists::buf) stays 16-byte aligned + // within the store; avoids alignment fault on 32-bit architectures + ui32 raw = needed_bytes + (ui32)sizeof (coded_lists); + ui32 extended_bytes = (raw + 15u) & ~15u; if (store == NULL) cur_store = store = allocate(&store, extended_bytes);