Big Endian Support Removal.

This commit implements #125759.

It removes:
* Blender does not build on big endian systems anymore.
* Support for opening blendfiles written from a big endian system is
  removed.

It keeps:
* Support to generate thumbnails from big endian blendfiles.
* BE support in `extern` or `intern` libraries, including Cycles.
* Support to open big endian versions of third party file formats:
  - PLY files.
  - Some image files (cineon, ...).

Pull Request: https://projects.blender.org/blender/blender/pulls/140138
This commit is contained in:
Bastien Montagne 2025-06-12 10:37:47 +02:00 committed by Bastien Montagne
parent 05d0391ed6
commit bc80ef136e
44 changed files with 438 additions and 651 deletions

View File

@ -1631,32 +1631,16 @@ if(FIRST_RUN)
endif()
endif()
# set the endian define
if(MSVC)
# For some reason this fails on MSVC.
add_definitions(-D__LITTLE_ENDIAN__)
# OSX-Note: as we do cross-compiling with specific set architecture,
# endianness-detection and auto-setting is counterproductive
# so we just set endianness according CMAKE_OSX_ARCHITECTURES
elseif(CMAKE_OSX_ARCHITECTURES MATCHES i386 OR
CMAKE_OSX_ARCHITECTURES MATCHES x86_64 OR
CMAKE_OSX_ARCHITECTURES MATCHES arm64)
add_definitions(-D__LITTLE_ENDIAN__)
elseif(CMAKE_OSX_ARCHITECTURES MATCHES ppc OR CMAKE_OSX_ARCHITECTURES MATCHES ppc64)
add_definitions(-D__BIG_ENDIAN__)
# Test endianness and set the endian define.
include(TestBigEndian)
test_big_endian(_SYSTEM_BIG_ENDIAN)
if(_SYSTEM_BIG_ENDIAN)
message(FATAL_ERROR "Blender does not support building on Big Endian systems" )
else()
include(TestBigEndian)
test_big_endian(_SYSTEM_BIG_ENDIAN)
if(_SYSTEM_BIG_ENDIAN)
add_definitions(-D__BIG_ENDIAN__)
else()
add_definitions(-D__LITTLE_ENDIAN__)
endif()
unset(_SYSTEM_BIG_ENDIAN)
add_definitions(-D__LITTLE_ENDIAN__)
endif()
unset(_SYSTEM_BIG_ENDIAN)
if(WITH_IMAGE_OPENJPEG)
# Special handling of Windows platform where openjpeg is always static.
if(WIN32)

View File

@ -174,11 +174,8 @@ static const char *check_memlist(const MemHead *memh);
/* locally used defines */
/* --------------------------------------------------------------------- */
#ifdef __BIG_ENDIAN__
# define MAKE_ID(a, b, c, d) (int(a) << 24 | int(b) << 16 | (c) << 8 | (d))
#else
# define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
#endif
/* NOTE: this is endianness-sensitive. */
#define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
#define MEMTAG1 MAKE_ID('M', 'E', 'M', 'O')
#define MEMTAG2 MAKE_ID('R', 'Y', 'B', 'L')

View File

@ -14,13 +14,9 @@
/* clang-format off */
#ifdef __LITTLE_ENDIAN__
# define RGBA(c) {((c) >> 24) & 0xff, ((c) >> 16) & 0xff, ((c) >> 8) & 0xff, (c) & 0xff}
# define RGB(c) {((c) >> 16) & 0xff, ((c) >> 8) & 0xff, (c) & 0xff}
#else
# define RGBA(c) {(c) & 0xff, ((c) >> 8) & 0xff, ((c) >> 16) & 0xff, ((c) >> 24) & 0xff}
# define RGB(c) {(c) & 0xff, ((c) >> 8) & 0xff, ((c) >> 16) & 0xff}
#endif
/* NOTE: this is endianness-sensitive. */
#define RGBA(c) {((c) >> 24) & 0xff, ((c) >> 16) & 0xff, ((c) >> 8) & 0xff, (c) & 0xff}
#define RGB(c) {((c) >> 16) & 0xff, ((c) >> 8) & 0xff, (c) & 0xff}
const bTheme U_theme_default = {
.name = "Default",

View File

@ -45,10 +45,5 @@ std::optional<blender::Vector<uint8_t>> blendthumb_create_png_data_from_thumb(
eThumbStatus blendthumb_create_thumb_from_file(FileReader *rawfile, Thumbnail *thumb);
/* INTEGER CODES */
#ifdef __BIG_ENDIAN__
/* Big Endian */
# define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
#else
/* Little Endian */
# define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))
#endif
/* NOTE: this is endianness-sensitive. */
#define MAKE_ID(a, b, c, d) ((int)(d) << 24 | (int)(c) << 16 | (b) << 8 | (a))

View File

@ -14,7 +14,6 @@
#include "BLI_alloca.h"
#include "BLI_endian_defines.h"
#include "BLI_endian_switch.h"
#include "BLI_fileops.h"
#include "BLI_filereader.h"
#include "BLI_string.h"
@ -24,6 +23,8 @@
#include "blendthumb.hh"
BLI_STATIC_ASSERT(ENDIAN_ORDER == L_ENDIAN, "Blender only builds on little endian systems")
static void thumb_data_vertical_flip(Thumbnail *thumb)
{
uint32_t *rect = (uint32_t *)thumb->data.data();
@ -43,13 +44,12 @@ static void thumb_data_vertical_flip(Thumbnail *thumb)
free(line);
}
static int32_t bytes_to_native_i32(const uint8_t bytes[4], bool endian_switch)
static int32_t bytes_to_native_i32(const uint8_t bytes[4])
{
int32_t data;
memcpy(&data, bytes, 4);
if (endian_switch) {
BLI_endian_switch_int32(&data);
}
/* NOTE: this is endianness-sensitive. */
/* PNG is always little-endian, and would require switching on a big-endian system. */
return data;
}
@ -84,12 +84,11 @@ static eThumbStatus blendthumb_extract_from_file_impl(FileReader *file,
Thumbnail *thumb,
const BlenderHeader &header)
{
const bool endian_switch = header.endian != ENDIAN_ORDER;
BLI_assert(header.endian == L_ENDIAN);
/* Iterate over file blocks until we find the thumbnail or run out of data. */
while (true) {
/* Read next BHead. */
const std::optional<BHead> bhead = BLO_readfile_read_bhead(
file, header.bhead_type(), endian_switch);
const std::optional<BHead> bhead = BLO_readfile_read_bhead(file, header.bhead_type());
if (!bhead.has_value()) {
/* File has ended. */
return BT_INVALID_THUMB;
@ -104,8 +103,8 @@ static eThumbStatus blendthumb_extract_from_file_impl(FileReader *file,
if (!file_read(file, shape, sizeof(shape))) {
return BT_INVALID_THUMB;
}
thumb->width = bytes_to_native_i32(&shape[0], endian_switch);
thumb->height = bytes_to_native_i32(&shape[4], endian_switch);
thumb->width = bytes_to_native_i32(&shape[0]);
thumb->height = bytes_to_native_i32(&shape[4]);
/* Verify that image dimensions and data size make sense. */
size_t data_size = bhead->len - sizeof(shape);
@ -190,6 +189,13 @@ eThumbStatus blendthumb_create_thumb_from_file(FileReader *rawfile, Thumbnail *t
return BT_EARLY_VERSION;
}
/* Check if the file was written from a big-endian build. */
if (header.endian != L_ENDIAN) {
file->close(file);
return BT_INVALID_FILE;
}
BLI_assert(header.endian == ENDIAN_ORDER);
/* Read the thumbnail. */
eThumbStatus err = blendthumb_extract_from_file_impl(file, thumb, header);
file->close(file);

View File

@ -21,9 +21,9 @@
static void png_extend_native_int32(blender::Vector<uint8_t> &output, int32_t data)
{
if (ENDIAN_ORDER == L_ENDIAN) {
BLI_endian_switch_int32(&data);
}
/* NOTE: this is endianness-sensitive. */
/* PNG is big-endian, its values need to be switched on little-endian systems. */
BLI_endian_switch_int32(&data);
output.extend_unchecked(blender::Span((uint8_t *)&data, 4));
}

View File

@ -24,7 +24,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BLI_endian_switch.h"
#include "BLI_ghash.h"
#include "BLI_listbase.h"
#include "BLI_math_color.h"
@ -671,12 +670,11 @@ static void read_slots(BlendDataReader *reader, animrig::Action &action)
for (int i = 0; i < action.slot_array_num; i++) {
BLO_read_struct(reader, ActionSlot, &action.slot_array[i]);
/* Undo generic endian switching, as the ID type values are not numerically the same between
* little and big endian machines. Due to the way they are defined, they are always in the same
* byte order, regardless of hardware/platform endianness. */
if (BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int16(&action.slot_array[i]->idtype);
}
/* NOTE: this is endianness-sensitive. */
/* In case of required endian switching, this code would have to undo the generic endian
* switching, as the ID type values are not numerically the same between little and big endian
* machines. Due to the way they are defined, they are always in the same byte order,
* regardless of hardware/platform endianness. */
action.slot_array[i]->wrap().blend_read_post();
}
@ -686,12 +684,10 @@ static void action_blend_read_data(BlendDataReader *reader, ID *id)
{
animrig::Action &action = reinterpret_cast<bAction *>(id)->wrap();
/* Undo generic endian switching (careful, only the two least significant bytes of the int32 must
* be swapped back here, since this value is actually an int16). */
if (BLO_read_requires_endian_switch(reader)) {
bAction *act = reinterpret_cast<bAction *>(id);
BLI_endian_switch_int16(reinterpret_cast<short *>(&act->idroot));
}
/* NOTE: this is endianness-sensitive. */
/* In case of required endianness switching, this code would need to undo the generic endian
* switching (careful, only the two least significant bytes of the int32 must be swapped back
* here, since this value is actually an int16). */
read_strip_keyframe_data_array(reader, action);
read_layers(reader, action);

View File

@ -15,7 +15,6 @@
#include "BKE_volume.hh"
#include "BLI_endian_defines.h"
#include "BLI_endian_switch.h"
#include "BLI_listbase.h"
#include "BLI_math_matrix_types.hh"
#include "BLI_path_utils.hh"
@ -289,11 +288,8 @@ std::optional<ImplicitSharingInfoAndData> BlobReadSharing::read_shared(
static StringRefNull get_endian_io_name(const int endian)
{
if (endian == L_ENDIAN) {
return "little";
}
BLI_assert(endian == B_ENDIAN);
return "big";
BLI_assert(endian == L_ENDIAN);
return "little";
}
static StringRefNull get_domain_io_name(const AttrDomain domain)
@ -329,7 +325,7 @@ static std::optional<eCustomDataType> get_data_type_from_io_name(const StringRef
}
/**
* Write the data and remember which endianness the data had.
* Write the data, always in little endian.
*/
static std::shared_ptr<DictionaryValue> write_blob_raw_data_with_endian(
BlobWriter &blob_writer,
@ -338,14 +334,14 @@ static std::shared_ptr<DictionaryValue> write_blob_raw_data_with_endian(
const int64_t size_in_bytes)
{
auto io_data = blob_sharing.write_deduplicated(blob_writer, data, size_in_bytes);
if (ENDIAN_ORDER == B_ENDIAN) {
io_data->append_str("endian", get_endian_io_name(ENDIAN_ORDER));
}
BLI_STATIC_ASSERT(ENDIAN_ORDER == L_ENDIAN, "Blender only builds on little endian systems")
return io_data;
}
/**
* Read data of an into an array and optionally perform an endian switch if necessary.
* Read data of an into an array.
*
* \returns True if sucessful, false if reading fails, or endian switch would be needed.
*/
[[nodiscard]] static bool read_blob_raw_data_with_endian(const BlobReader &blob_reader,
const DictionaryValue &io_data,
@ -367,21 +363,9 @@ static std::shared_ptr<DictionaryValue> write_blob_raw_data_with_endian(
const StringRefNull current_endian = get_endian_io_name(ENDIAN_ORDER);
const bool need_endian_switch = stored_endian != current_endian;
if (need_endian_switch) {
switch (element_size) {
case 1:
break;
case 2:
BLI_endian_switch_uint16_array(static_cast<uint16_t *>(r_data), elements_num);
break;
case 4:
BLI_endian_switch_uint32_array(static_cast<uint32_t *>(r_data), elements_num);
break;
case 8:
BLI_endian_switch_uint64_array(static_cast<uint64_t *>(r_data), elements_num);
break;
default:
return false;
}
/* NOTE: this is endianness-sensitive. */
/* Blender only builds on little endian systems, and reads little endian data here. */
return false;
}
return true;
}

View File

@ -13,7 +13,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_endian_defines.h"
#include "BLI_endian_switch.h"
#include "BLI_fileops.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
@ -78,7 +77,6 @@ struct CDataFile {
FILE *readf;
FILE *writef;
int switchendian;
size_t dataoffset;
};
@ -86,11 +84,8 @@ struct CDataFile {
static int cdf_endian()
{
if (ENDIAN_ORDER == L_ENDIAN) {
return CDF_ENDIAN_LITTLE;
}
return CDF_ENDIAN_BIG;
BLI_STATIC_ASSERT(ENDIAN_ORDER == L_ENDIAN, "Blender only builds on little endian systems")
return CDF_ENDIAN_LITTLE;
}
CDataFile *cdf_create(int type)
@ -138,15 +133,14 @@ static bool cdf_read_header(CDataFile *cdf)
if (header->version > CDF_VERSION) {
return false;
}
if (header->endian != cdf_endian()) {
return false;
}
cdf->switchendian = header->endian != cdf_endian();
header->endian = cdf_endian();
if (cdf->switchendian) {
BLI_endian_switch_int32(&header->type);
BLI_endian_switch_int32(&header->totlayer);
BLI_endian_switch_int32(&header->structbytes);
}
/* NOTE: this is endianness-sensitive.
* Some non-char `header` data would need to be switched. */
if (!ELEM(header->type, CDF_TYPE_IMAGE, CDF_TYPE_MESH)) {
return false;
@ -165,12 +159,8 @@ static bool cdf_read_header(CDataFile *cdf)
return false;
}
if (cdf->switchendian) {
BLI_endian_switch_int32(&image->width);
BLI_endian_switch_int32(&image->height);
BLI_endian_switch_int32(&image->tile_size);
BLI_endian_switch_int32(&image->structbytes);
}
/* NOTE: this is endianness-sensitive.
* Some non-char `image` data would need to be switched. */
offset += image->structbytes;
image->structbytes = sizeof(CDataFileImageHeader);
@ -181,9 +171,8 @@ static bool cdf_read_header(CDataFile *cdf)
return false;
}
if (cdf->switchendian) {
BLI_endian_switch_int32(&mesh->structbytes);
}
/* NOTE: this is endianness-sensitive.
* Some non-char `mesh` data would need to be switched. */
offset += mesh->structbytes;
mesh->structbytes = sizeof(CDataFileMeshHeader);
@ -207,12 +196,8 @@ static bool cdf_read_header(CDataFile *cdf)
return false;
}
if (cdf->switchendian) {
BLI_endian_switch_int32(&layer->type);
BLI_endian_switch_int32(&layer->datatype);
BLI_endian_switch_uint64(&layer->datasize);
BLI_endian_switch_int32(&layer->structbytes);
}
/* NOTE: this is endianness-sensitive.
* Some non-char `layer` data would need to be switched. */
if (layer->datatype != CDF_DATA_FLOAT) {
return false;
@ -319,10 +304,8 @@ bool cdf_read_data(CDataFile *cdf, uint size, void *data)
return false;
}
/* switch endian if necessary */
if (cdf->switchendian) {
BLI_endian_switch_float_array(static_cast<float *>(data), size / sizeof(float));
}
/* NOTE: this is endianness-sensitive.
* `data` would need to be switched. */
return true;
}

View File

@ -15,7 +15,6 @@
#include <fmt/format.h>
#include "BLI_endian_switch.h"
#include "BLI_listbase.h"
#include "BLI_math_base.h"
#include "BLI_set.hh"
@ -1621,18 +1620,12 @@ static void IDP_DirectLinkProperty(IDProperty *prop, BlendDataReader *reader)
IDP_DirectLinkIDPArray(prop, reader);
break;
case IDP_DOUBLE:
/* Workaround for doubles.
* They are stored in the same field as `int val, val2` in the #IDPropertyData struct,
* they have to deal with endianness specifically.
/* NOTE: this is endianness-sensitive. */
/* Doubles are stored in the same field as `int val, val2` in the #IDPropertyData struct.
*
* In theory, val and val2 would've already been swapped
* if switch_endian is true, so we have to first un-swap
* them then re-swap them as a single 64-bit entity. */
if (BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int32(&prop->data.val);
BLI_endian_switch_int32(&prop->data.val2);
BLI_endian_switch_int64((int64_t *)&prop->data.val);
}
* In case of endianness switching, `val` and `val2` would have already been switched by the
* generic reading code, so they would need to be first un-switched individually, and then
* re-switched as a single 64-bit entity. */
break;
case IDP_INT:
case IDP_FLOAT:

View File

@ -37,7 +37,6 @@
#include "DNA_world_types.h"
#include "BLI_dynstr.h"
#include "BLI_endian_switch.h"
#include "BLI_listbase.h"
#include "BLI_string.h"
#include "BLI_string_utils.hh"
@ -126,38 +125,15 @@ static void ipo_blend_read_data(BlendDataReader *reader, ID *id)
BLO_read_struct_list(reader, IpoCurve, &(ipo->curve));
/* NOTE: this is endianness-sensitive.
* Not clear why, but endianness switching was undone here for some data?
* That 'undo switching' code appeared to be heavily broken in 4.x code actually, performing
* switch on `ipo` data as part of the loop on `icu`'s, among other obvious mistakes. */
LISTBASE_FOREACH (IpoCurve *, icu, &ipo->curve) {
BLO_read_struct_array(reader, BezTriple, icu->totvert, &icu->bezt);
BLO_read_struct_array(reader, BPoint, icu->totvert, &icu->bp);
BLO_read_struct(reader, IpoDriver, &icu->driver);
/* Undo generic endian switching. */
if (BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int16(&icu->blocktype);
if (icu->driver != nullptr) {
/* Undo generic endian switching. */
if (BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int16(&icu->blocktype);
if (icu->driver != nullptr) {
BLI_endian_switch_int16(&icu->driver->blocktype);
}
}
}
/* Undo generic endian switching. */
if (BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int16(&ipo->blocktype);
if (icu->driver != nullptr) {
BLI_endian_switch_int16(&icu->driver->blocktype);
}
}
}
}
/* Undo generic endian switching. */
if (BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int16(&ipo->blocktype);
}
}

View File

@ -14,7 +14,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_endian_switch.h"
#include "BLI_listbase.h"
#include "BLI_math_matrix.h"
#include "BLI_math_vector.h"
@ -151,33 +150,6 @@ static void shapekey_blend_write(BlendWriter *writer, ID *id, const void *id_add
#define IPO_BEZTRIPLE 100
#define IPO_BPOINT 101
static void switch_endian_keyblock(Key *key, KeyBlock *kb)
{
int elemsize = key->elemsize;
char *data = static_cast<char *>(kb->data);
for (int a = 0; a < kb->totelem; a++) {
const char *cp = key->elemstr;
char *poin = data;
while (cp[0]) { /* cp[0] == amount */
switch (cp[1]) { /* cp[1] = type */
case IPO_FLOAT:
case IPO_BPOINT:
case IPO_BEZTRIPLE: {
int b = cp[0];
BLI_endian_switch_float_array((float *)poin, b);
poin += sizeof(float) * b;
break;
}
}
cp += 2;
}
data += elemsize;
}
}
static void shapekey_blend_read_data(BlendDataReader *reader, ID *id)
{
Key *key = (Key *)id;
@ -188,9 +160,9 @@ static void shapekey_blend_read_data(BlendDataReader *reader, ID *id)
LISTBASE_FOREACH (KeyBlock *, kb, &key->block) {
BLO_read_data_address(reader, &kb->data);
if (BLO_read_requires_endian_switch(reader)) {
switch_endian_keyblock(key, kb);
}
/* NOTE: this is endianness-sensitive. */
/* Keyblock data would need specific endian switching depending of the exact type of data it
* contain. */
}
}

View File

@ -21,7 +21,6 @@
#include "DNA_object_types.h"
#include "BLI_bounds.hh"
#include "BLI_endian_switch.h"
#include "BLI_hash.h"
#include "BLI_implicit_sharing.hh"
#include "BLI_index_range.hh"
@ -430,12 +429,9 @@ static void mesh_blend_read_data(BlendDataReader *reader, ID *id)
mesh->totselect = 0;
}
if (BLO_read_requires_endian_switch(reader) && mesh->tface) {
TFace *tf = mesh->tface;
for (int i = 0; i < mesh->totface_legacy; i++, tf++) {
BLI_endian_switch_uint32_array(tf->col, 4);
}
}
/* NOTE: this is endianness-sensitive. */
/* Each legacy TFace would need to undo the automatic DNA switch of its array of four uint32_t
* RGBA colors. */
}
IDTypeInfo IDType_ID_ME = {

View File

@ -987,6 +987,7 @@ void BKE_packedfile_blend_read(BlendDataReader *reader, PackedFile **pf_p, Strin
if (pf == nullptr) {
return;
}
/* NOTE: this is endianness-sensitive. */
/* NOTE: there is no way to handle endianness switch here. */
pf->sharing_info = BLO_read_shared(reader, &pf->data, [&]() {
BLO_read_data_address(reader, &pf->data);

View File

@ -46,19 +46,11 @@
#endif
/* NOTE: copied from BLO_core_bhead.hh, don't use here because we're in BLI. */
#ifdef __BIG_ENDIAN__
/* Big Endian */
# define MAKE_ID(a, b, c, d) ((int)(a) << 24 | (int)(b) << 16 | (c) << 8 | (d))
# define MAKE_ID_8(a, b, c, d, e, f, g, h) \
((int64_t)(a) << 56 | (int64_t)(b) << 48 | (int64_t)(c) << 40 | (int64_t)(d) << 32 | \
(int64_t)(e) << 24 | (int64_t)(f) << 16 | (int64_t)(g) << 8 | (h))
#else
/* Little Endian */
# define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
# define MAKE_ID_8(a, b, c, d, e, f, g, h) \
(int64_t(h) << 56 | int64_t(g) << 48 | int64_t(f) << 40 | int64_t(e) << 32 | \
int64_t(d) << 24 | int64_t(c) << 16 | int64_t(b) << 8 | (a))
#endif
/* NOTE: this is endianness-sensitive. */
#define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
#define MAKE_ID_8(a, b, c, d, e, f, g, h) \
(int64_t(h) << 56 | int64_t(g) << 48 | int64_t(f) << 40 | int64_t(e) << 32 | int64_t(d) << 24 | \
int64_t(c) << 16 | int64_t(b) << 8 | (a))
/**
* Important that this value is an is _not_ aligned with `sizeof(void *)`.

View File

@ -13,10 +13,6 @@
#include "BLI_fileops.hh"
#include "BLI_filereader.h"
#ifdef __BIG_ENDIAN__
# include "BLI_endian_switch.h"
#endif
#include "MEM_guardedalloc.h"
struct ZstdReader {
@ -43,9 +39,8 @@ static bool zstd_read_u32(FileReader *base, uint32_t *val)
if (base->read(base, val, sizeof(uint32_t)) != sizeof(uint32_t)) {
return false;
}
#ifdef __BIG_ENDIAN__
BLI_endian_switch_uint32(val);
#endif
/* NOTE: this is endianness-sensitive.
* `val` would need to be switched on a big endian system. */
return true;
}

View File

@ -70,11 +70,8 @@ struct md5_ctx {
md5_uint32 D;
};
#ifdef __BIG_ENDIAN__
# define SWAP(n) (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
#else
# define SWAP(n) (n)
#endif
/* NOTE: this is endianness-sensitive. */
#define SWAP(n) (n)
/* This array contains the bytes used to pad the buffer to the next 64-byte boundary.
* (RFC 1321, 3.1: Step 1) */

View File

@ -721,11 +721,8 @@ static ushort hipart(const float f)
tmp.f = f;
#ifdef __BIG_ENDIAN__
return tmp.us[0];
#else
/* NOTE: this is endianness-sensitive. */
return tmp.us[1];
#endif
}
static float index_to_float(const ushort i)
@ -748,13 +745,9 @@ static float index_to_float(const ushort i)
return -FLT_MAX;
}
#ifdef __BIG_ENDIAN__
tmp.us[0] = i;
tmp.us[1] = 0x8000;
#else
/* NOTE: this is endianness-sensitive. */
tmp.us[0] = 0x8000;
tmp.us[1] = i;
#endif
return tmp.f;
}

View File

@ -108,11 +108,8 @@ MINLINE unsigned short to_srgb_table_lookup(const float f)
unsigned short us[2];
} tmp;
tmp.f = f;
# ifdef __BIG_ENDIAN__
return BLI_color_to_srgb_table[tmp.us[0]];
# else
/* NOTE: this is endianness-sensitive. */
return BLI_color_to_srgb_table[tmp.us[1]];
# endif
}
MINLINE void linearrgb_to_srgb_ushort4(unsigned short srgb[4], const float linear[4])

View File

@ -391,12 +391,9 @@ void RandomNumberGenerator::get_bytes(MutableSpan<char> r_bytes)
int64_t i = 0;
while (i != trim_len) {
BLI_assert(i < trim_len);
#ifdef __BIG_ENDIAN__
for (int64_t j = (rand_stride + mask_bytes) - 1; j != mask_bytes - 1; j--)
#else
for (int64_t j = 0; j != rand_stride; j++)
#endif
{
/* NOTE: this is endianness-sensitive.
* Big Endian needs to iterate in reverse, with a `mask_bytes - 1` offset. */
for (int64_t j = 0; j != rand_stride; j++) {
r_bytes[i++] = data_src[j];
}
this->step();

View File

@ -26,6 +26,8 @@ TEST(BLI_build_config, Endian)
#if defined(__BIG_ENDIAN__)
static_assert(ARCH_CPU_BIG_ENDIAN);
static_assert(!ARCH_CPU_LITTLE_ENDIAN);
/* Blender does not build on big endian systems. */
static_assert(0);
#endif
#if defined(__LITTLE_ENDIAN__)
static_assert(!ARCH_CPU_BIG_ENDIAN);

View File

@ -19,11 +19,9 @@ TEST(hash_mm2a, MM2ABasic)
BLI_hash_mm2a_init(&mm2, 0);
BLI_hash_mm2a_add(&mm2, (const uchar *)data, strlen(data));
#ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* On BE systems, the expected value would be 959283772. */
EXPECT_EQ(BLI_hash_mm2a_end(&mm2), 1633988145);
#else
EXPECT_EQ(BLI_hash_mm2a_end(&mm2), 959283772);
#endif
}
TEST(hash_mm2a, MM2AConcatenateStrings)
@ -43,11 +41,9 @@ TEST(hash_mm2a, MM2AConcatenateStrings)
hash = BLI_hash_mm2a_end(&mm2);
BLI_hash_mm2a_init(&mm2, 0);
BLI_hash_mm2a_add(&mm2, (const uchar *)data123, strlen(data123));
#ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* On BE systems, the expected value would be 2604964730. */
EXPECT_EQ(hash, 1545105348);
#else
EXPECT_EQ(hash, 2604964730);
#endif
EXPECT_EQ(BLI_hash_mm2a_end(&mm2), hash);
}
@ -66,11 +62,8 @@ TEST(hash_mm2a, MM2AIntegers)
hash = BLI_hash_mm2a_end(&mm2);
BLI_hash_mm2a_init(&mm2, 0);
BLI_hash_mm2a_add(&mm2, (const uchar *)ints, sizeof(ints));
/* Yes, same hash here on little and big endian. */
#ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* Actually, same hash here on little and big endian. */
EXPECT_EQ(hash, 405493096);
#else
EXPECT_EQ(hash, 405493096);
#endif
EXPECT_EQ(BLI_hash_mm2a_end(&mm2), hash);
}

View File

@ -369,7 +369,6 @@ const blender::ImplicitSharingInfo *BLO_read_shared(
}
int BLO_read_fileversion_get(BlendDataReader *reader);
bool BLO_read_requires_endian_switch(BlendDataReader *reader);
bool BLO_read_data_is_undo(BlendDataReader *reader);
void BLO_read_data_globmap_add(BlendDataReader *reader, void *oldaddr, void *newaddr);
void BLO_read_glob_list(BlendDataReader *reader, ListBase *list);

View File

@ -623,12 +623,11 @@ struct BlendLibReader {
static BHeadN *get_bhead(FileData *fd)
{
BHeadN *new_bhead = nullptr;
const bool do_endian_swap = fd->flags & FD_FLAGS_SWITCH_ENDIAN;
if (fd) {
if (!fd->is_eof) {
std::optional<BHead> bhead_opt = BLO_readfile_read_bhead(
fd->file, fd->blender_header.bhead_type(), do_endian_swap);
std::optional<BHead> bhead_opt = BLO_readfile_read_bhead(fd->file,
fd->blender_header.bhead_type());
BHead *bhead = nullptr;
if (!bhead_opt.has_value()) {
fd->is_eof = true;
@ -884,10 +883,9 @@ static bool read_file_dna(FileData *fd, const char **r_error_message)
subversion = atoi(num);
}
else if (bhead->code == BLO_CODE_DNA1) {
const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
BLI_assert((fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
const bool do_alias = false; /* Postpone until after #blo_do_versions_dna runs. */
fd->filesdna = DNA_sdna_from_data(
&bhead[1], bhead->len, do_endian_swap, true, do_alias, r_error_message);
fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, true, do_alias, r_error_message);
if (fd->filesdna) {
blo_do_versions_dna(fd->filesdna, fd->fileversion, subversion);
/* Allow aliased lookups (must be after version patching DNA). */
@ -1200,7 +1198,18 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
{
read_blender_header(fd);
if (fd->flags & FD_FLAGS_FILE_OK) {
if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
BLI_STATIC_ASSERT(ENDIAN_ORDER == L_ENDIAN, "Blender only builds on little endian systems")
BKE_reportf(reports,
RPT_ERROR,
"Blend file '%s' created by a Big Endian version of Blender, support for "
"these files has been removed in Blender 5.0, use an older version of Blender "
"to open and convert it.",
fd->relabase);
blo_filedata_free(fd);
fd = nullptr;
}
else if (fd->flags & FD_FLAGS_FILE_OK) {
const char *error_message = nullptr;
if (read_file_dna(fd, &error_message) == false) {
BKE_reportf(
@ -1212,22 +1221,6 @@ static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
blo_filedata_free(fd);
fd = nullptr;
}
else if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
if (ENDIAN_ORDER == L_ENDIAN) {
if (!BKE_reports_print_test(reports, RPT_WARNING)) {
CLOG_WARN(
&LOG,
"Blend file '%s' created by a Big Endian version of Blender, support for these "
"files will be removed in Blender 5.0",
fd->relabase);
}
BKE_reportf(reports,
RPT_WARNING,
"Blend file '%s' created by a Big Endian version of Blender, support for "
"these files will be removed in Blender 5.0",
fd->relabase);
}
}
}
else if (fd->flags & FD_FLAGS_FILE_FUTURE) {
BKE_reportf(
@ -1784,23 +1777,6 @@ void blo_cache_storage_end(FileData *fd)
/** \name DNA Struct Loading
* \{ */
static void switch_endian_structs(const SDNA *filesdna, BHead *bhead)
{
int blocksize, nblocks;
char *data;
data = (char *)(bhead + 1);
blocksize = DNA_struct_size(filesdna, bhead->SDNAnr);
nblocks = bhead->nr;
while (nblocks--) {
DNA_struct_switch_endian(filesdna, bhead->SDNAnr, data);
data += blocksize;
}
}
/**
* Generate the final allocation string reference for read blocks of data. If \a blockname is
* given, use it as 'owner block' info, otherwise use the id type index to get that info.
@ -1897,6 +1873,7 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname, const i
*
* NOTE: raw data (aka #SDNA_RAW_DATA_STRUCT_INDEX #SDNAnr) is not handled here, it's up to
* the calling code to manage this. */
BLI_assert((fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
BLI_STATIC_ASSERT(SDNA_RAW_DATA_STRUCT_INDEX == 0, "'raw data' SDNA struct index should be 0")
if (bh->SDNAnr > SDNA_RAW_DATA_STRUCT_INDEX && (fd->flags & FD_FLAGS_SWITCH_ENDIAN)) {
#ifdef USE_BHEAD_READ_ON_DEMAND
@ -1908,7 +1885,6 @@ static void *read_struct(FileData *fd, BHead *bh, const char *blockname, const i
}
}
#endif
switch_endian_structs(fd->filesdna, bh);
}
if (fd->compflags[bh->SDNAnr] != SDNA_CMP_REMOVED) {
@ -4764,6 +4740,8 @@ static void library_link_end(Main *mainl, FileData **fd, const int flag, ReportL
/* FIXME This is extremely bad design, #library_link_end should probably _always_ free the file
* data? */
if ((*fd)->flags & FD_FLAGS_SWITCH_ENDIAN) {
/* Big Endian blendfiles are not supported for linking. */
BLI_assert_unreachable();
blo_filedata_free(*fd);
*fd = nullptr;
}
@ -5229,11 +5207,6 @@ int BLO_read_fileversion_get(BlendDataReader *reader)
return reader->fd->fileversion;
}
bool BLO_read_requires_endian_switch(BlendDataReader *reader)
{
return (reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
}
void BLO_read_struct_list_with_size(BlendDataReader *reader,
const size_t expected_elem_size,
ListBase *list)
@ -5277,40 +5250,28 @@ void BLO_read_int16_array(BlendDataReader *reader, const int64_t array_size, int
{
*ptr_p = reinterpret_cast<int16_t *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(int16_t) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int16_array(*ptr_p, array_size);
}
BLI_assert((reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
}
void BLO_read_int32_array(BlendDataReader *reader, const int64_t array_size, int32_t **ptr_p)
{
*ptr_p = reinterpret_cast<int32_t *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(int32_t) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_int32_array(*ptr_p, array_size);
}
BLI_assert((reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
}
void BLO_read_uint32_array(BlendDataReader *reader, const int64_t array_size, uint32_t **ptr_p)
{
*ptr_p = reinterpret_cast<uint32_t *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(uint32_t) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_uint32_array(*ptr_p, array_size);
}
BLI_assert((reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
}
void BLO_read_float_array(BlendDataReader *reader, const int64_t array_size, float **ptr_p)
{
*ptr_p = reinterpret_cast<float *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(float) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_float_array(*ptr_p, array_size);
}
BLI_assert((reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
}
void BLO_read_float3_array(BlendDataReader *reader, const int64_t array_size, float **ptr_p)
@ -5322,10 +5283,7 @@ void BLO_read_double_array(BlendDataReader *reader, const int64_t array_size, do
{
*ptr_p = reinterpret_cast<double *>(
BLO_read_struct_array_with_size(reader, *((void **)ptr_p), sizeof(double) * array_size));
if (*ptr_p && BLO_read_requires_endian_switch(reader)) {
BLI_endian_switch_double_array(*ptr_p, array_size);
}
BLI_assert((reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
}
void BLO_read_string(BlendDataReader *reader, char **ptr_p)
@ -5362,9 +5320,9 @@ static void convert_pointer_array_64_to_32(BlendDataReader *reader,
const uint64_t *src,
uint32_t *dst)
{
const bool use_endian_swap = BLO_read_requires_endian_switch(reader);
BLI_assert((reader->fd->flags & FD_FLAGS_SWITCH_ENDIAN) == 0);
for (int i = 0; i < array_size; i++) {
dst[i] = uint32_from_uint64_ptr(src[i], use_endian_swap);
dst[i] = uint32_from_uint64_ptr(src[i]);
}
}

View File

@ -12,12 +12,13 @@
*
* IFF-style structure (but not IFF compatible!)
*
* Start file:
* <pre>
* `BLENDER_V100` `12` bytes (version 1.00 is just an example).
* `V` = big endian, `v` = little endian.
* `_` = 4 byte pointer, `-` = 8 byte pointer.
* </pre>
* Start of the file:
*
* Historic Blendfiles (pre-Blender 5.0):
* `BLENDER_V100` : Fixed 12 bytes length. See #BLEND_FILE_FORMAT_VERSION_0 for details.
*
* Current Blendfiles (Blender 5.0 and later):
* `BLENDER17-01v0500`: Variable bytes length. See #BLEND_FILE_FORMAT_VERSION_1 for details.
*
* data-blocks: (also see struct #BHead).
* <pre>
@ -92,7 +93,6 @@
#include "DNA_userdef_types.h"
#include "BLI_endian_defines.h"
#include "BLI_endian_switch.h"
#include "BLI_fileops.hh"
#include "BLI_implicit_sharing.hh"
#include "BLI_math_base.h"
@ -312,9 +312,9 @@ bool ZstdWriteWrap::open(const char *filepath)
void ZstdWriteWrap::write_u32_le(uint32_t val)
{
if (ENDIAN_ORDER == B_ENDIAN) {
BLI_endian_switch_uint32(&val);
}
/* NOTE: this is endianness-sensitive.
* This value must always be written as little-endian. */
BLI_assert(ENDIAN_ORDER == L_ENDIAN);
base_wrap.write(&val, sizeof(uint32_t));
}
@ -1380,7 +1380,7 @@ static std::string get_blend_file_header()
}
const char pointer_size_char = sizeof(void *) == 8 ? '-' : '_';
const char endian_char = ENDIAN_ORDER == B_ENDIAN ? 'V' : 'v';
const char endian_char = 'v';
/* Legacy blend file header format. */
std::stringstream ss;

View File

@ -111,9 +111,7 @@ enum {
*
* \return The next #BHEad or #std::nullopt if the file is exhausted.
*/
std::optional<BHead> BLO_readfile_read_bhead(FileReader *file,
BHeadType type,
bool do_endian_swap);
std::optional<BHead> BLO_readfile_read_bhead(FileReader *file, BHeadType type);
/**
* Converts a BHead.old pointer from 64 to 32 bit. This can't work in the general case, but only
@ -121,12 +119,11 @@ std::optional<BHead> BLO_readfile_read_bhead(FileReader *file,
* pointers will map to the same, which will break things later on. There is no way to check for
* that here unfortunately.
*/
inline uint32_t uint32_from_uint64_ptr(uint64_t ptr, const bool use_endian_swap)
inline uint32_t uint32_from_uint64_ptr(uint64_t ptr)
{
if (use_endian_swap) {
/* Do endian switch so that the resulting pointer is not all 0. */
BLI_endian_switch_uint64(&ptr);
}
/* NOTE: this is endianness-sensitive. */
/* Switching endianess would be required to reduce the risk of two different 64bits pointers
* generating the same 32bits value. */
/* Behavior has to match #cast_pointer_64_to_32. */
ptr >>= 3;
return uint32_t(ptr);

View File

@ -6,48 +6,6 @@
#include "BLO_core_bhead.hh"
static void switch_endian_bh4(BHead4 *bhead)
{
/* the ID_.. codes */
if ((bhead->code & 0xFFFF) == 0) {
bhead->code >>= 16;
}
if (bhead->code != BLO_CODE_ENDB) {
BLI_endian_switch_int32(&bhead->len);
BLI_endian_switch_int32(&bhead->SDNAnr);
BLI_endian_switch_int32(&bhead->nr);
}
}
static void switch_endian_small_bh8(SmallBHead8 *bhead)
{
/* The ID_* codes. */
if ((bhead->code & 0xFFFF) == 0) {
bhead->code >>= 16;
}
if (bhead->code != BLO_CODE_ENDB) {
BLI_endian_switch_int32(&bhead->len);
BLI_endian_switch_int32(&bhead->SDNAnr);
BLI_endian_switch_int32(&bhead->nr);
}
}
static void switch_endian_large_bh8(LargeBHead8 *bhead)
{
/* The ID_* codes. */
if ((bhead->code & 0xFFFF) == 0) {
bhead->code >>= 16;
}
if (bhead->code != BLO_CODE_ENDB) {
BLI_endian_switch_int64(&bhead->len);
BLI_endian_switch_int32(&bhead->SDNAnr);
BLI_endian_switch_int64(&bhead->nr);
}
}
static BHead bhead_from_bhead4(const BHead4 &bhead4)
{
BHead bhead;
@ -59,51 +17,49 @@ static BHead bhead_from_bhead4(const BHead4 &bhead4)
return bhead;
}
static const void *old_ptr_from_uint64_ptr(const uint64_t ptr, const bool use_endian_swap)
static const void *old_ptr_from_uint64_ptr(const uint64_t ptr)
{
if constexpr (sizeof(void *) == 8) {
return reinterpret_cast<const void *>(ptr);
}
else {
return reinterpret_cast<const void *>(uintptr_t(uint32_from_uint64_ptr(ptr, use_endian_swap)));
return reinterpret_cast<const void *>(uintptr_t(uint32_from_uint64_ptr(ptr)));
}
}
static BHead bhead_from_small_bhead8(const SmallBHead8 &small_bhead8, const bool use_endian_swap)
static BHead bhead_from_small_bhead8(const SmallBHead8 &small_bhead8)
{
BHead bhead;
bhead.code = small_bhead8.code;
bhead.len = small_bhead8.len;
bhead.old = old_ptr_from_uint64_ptr(small_bhead8.old, use_endian_swap);
bhead.old = old_ptr_from_uint64_ptr(small_bhead8.old);
bhead.SDNAnr = small_bhead8.SDNAnr;
bhead.nr = small_bhead8.nr;
return bhead;
}
static BHead bhead_from_large_bhead8(const LargeBHead8 &large_bhead8, const bool use_endian_swap)
static BHead bhead_from_large_bhead8(const LargeBHead8 &large_bhead8)
{
BHead bhead;
bhead.code = large_bhead8.code;
bhead.len = large_bhead8.len;
bhead.old = old_ptr_from_uint64_ptr(large_bhead8.old, use_endian_swap);
bhead.old = old_ptr_from_uint64_ptr(large_bhead8.old);
bhead.SDNAnr = large_bhead8.SDNAnr;
bhead.nr = large_bhead8.nr;
return bhead;
}
std::optional<BHead> BLO_readfile_read_bhead(FileReader *file,
const BHeadType type,
const bool do_endian_swap)
std::optional<BHead> BLO_readfile_read_bhead(FileReader *file, const BHeadType type)
{
/* NOTE: this is endianness-sensitive. */
/* The various BHead data below would need to be switched if the read blend-file was saved from a
* system using a different endianness. */
switch (type) {
case BHeadType::BHead4: {
BHead4 bhead4{};
bhead4.code = BLO_CODE_DATA;
const int64_t readsize = file->read(file, &bhead4, sizeof(bhead4));
if (readsize == sizeof(bhead4) || bhead4.code == BLO_CODE_ENDB) {
if (do_endian_swap) {
switch_endian_bh4(&bhead4);
}
return bhead_from_bhead4(bhead4);
}
break;
@ -113,10 +69,7 @@ std::optional<BHead> BLO_readfile_read_bhead(FileReader *file,
small_bhead8.code = BLO_CODE_DATA;
const int64_t readsize = file->read(file, &small_bhead8, sizeof(small_bhead8));
if (readsize == sizeof(small_bhead8) || small_bhead8.code == BLO_CODE_ENDB) {
if (do_endian_swap) {
switch_endian_small_bh8(&small_bhead8);
}
return bhead_from_small_bhead8(small_bhead8, do_endian_swap);
return bhead_from_small_bhead8(small_bhead8);
}
break;
}
@ -125,10 +78,7 @@ std::optional<BHead> BLO_readfile_read_bhead(FileReader *file,
large_bhead8.code = BLO_CODE_DATA;
const int64_t readsize = file->read(file, &large_bhead8, sizeof(large_bhead8));
if (readsize == sizeof(large_bhead8) || large_bhead8.code == BLO_CODE_ENDB) {
if (do_endian_swap) {
switch_endian_large_bh8(&large_bhead8);
}
return bhead_from_large_bhead8(large_bhead8, do_endian_swap);
return bhead_from_large_bhead8(large_bhead8);
}
break;
}

View File

@ -63,11 +63,9 @@ class Precompute {
file.open(std::string(name) + ".pfm");
file << "PF\n";
file << n_x * n_z << " " << n_y * n_w << "\n";
#ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive.
* Big endian system would have needed `1.0` value instead. */
file << "-1.0\n";
#else
file << "1.0\n";
#endif
file.close();
/* Write binary float content. */

View File

@ -740,13 +740,10 @@ cache_end:
union {
uint32_t as_u32;
struct {
#ifdef __BIG_ENDIAN__
uint16_t ob;
uint16_t bone;
#else
/* NOTE: this is endianness-sensitive.
* In Big Endian the order of these two variable would have to be inverted. */
uint16_t bone;
uint16_t ob;
#endif
};
} offset, test, best;
} cycle_order;

View File

@ -38,10 +38,6 @@
#include "BLT_translation.hh"
#ifdef __BIG_ENDIAN__
# include "BLI_endian_switch.h"
#endif
#include "BKE_action.hh"
#include "BKE_armature.hh"
#include "BKE_attribute.hh"
@ -2238,14 +2234,11 @@ static int gpu_select_buffer_depth_id_cmp(const void *sel_a_p, const void *sel_b
}
/* Depths match, sort by id. */
/* NOTE: this is endianness-sensitive.
* GPUSelectResult values are always expected to be little-endian. */
uint sel_a = a->id;
uint sel_b = b->id;
#ifdef __BIG_ENDIAN__
BLI_endian_switch_uint32(&sel_a);
BLI_endian_switch_uint32(&sel_b);
#endif
if (sel_a < sel_b) {
return -1;
}
@ -4225,14 +4218,11 @@ static bool do_armature_box_select(const ViewContext *vc, const rcti *rect, cons
*/
static int gpu_bone_select_buffer_cmp(const void *sel_a_p, const void *sel_b_p)
{
/* NOTE: this is endianness-sensitive.
* GPUSelectResult values are always expected to be little-endian. */
uint sel_a = ((GPUSelectResult *)sel_a_p)->id;
uint sel_b = ((GPUSelectResult *)sel_b_p)->id;
#ifdef __BIG_ENDIAN__
BLI_endian_switch_uint32(&sel_a);
BLI_endian_switch_uint32(&sel_b);
#endif
if (sel_a < sel_b) {
return -1;
}

View File

@ -21,10 +21,6 @@
#include "BLI_path_utils.hh"
#include "BLI_string.h"
#ifdef __BIG_ENDIAN__
# include "BLI_endian_switch.h"
#endif
OIIO_NAMESPACE_USING
using namespace blender::imbuf;
@ -307,13 +303,11 @@ static void LoadDXTCImage(ImBuf *ibuf, Filesystem::IOMemReader &mem_reader)
* we've made it this far. */
uint32_t flags = 0;
mem_reader.pread(&flags, sizeof(uint32_t), 8);
/* NOTE: this is endianness-sensitive. */
/* `ibuf->dds_data.nummipmaps` is always expected to be little-endian. */
mem_reader.pread(&ibuf->dds_data.nummipmaps, sizeof(uint32_t), 28);
mem_reader.pread(&ibuf->dds_data.fourcc, sizeof(uint32_t), 84);
#ifdef __BIG_ENDIAN__
BLI_endian_switch_uint32(&ibuf->dds_data.nummipmaps);
#endif
const uint32_t DDSD_MIPMAPCOUNT = 0x00020000U;
if ((flags & DDSD_MIPMAPCOUNT) == 0) {
ibuf->dds_data.nummipmaps = 1;

View File

@ -83,7 +83,9 @@ static MovieIndexBuilder *index_builder_create(const char *filepath)
fprintf(rv->fp,
"%s%c%.3d",
binary_header_str,
(ENDIAN_ORDER == B_ENDIAN) ? 'V' : 'v',
/* NOTE: this is endianness-sensitive.
* On Big Endian system 'V' must be used instead of 'v'. */
'v',
INDEX_FILE_VERSION);
return rv;
@ -179,7 +181,10 @@ static MovieIndex *movie_index_open(const char *filepath)
return nullptr;
}
if ((ENDIAN_ORDER == B_ENDIAN) != (header[8] == 'V')) {
/* NOTE: this is endianness-sensitive. */
BLI_assert(ELEM(header[8], 'v', 'V'));
const int16_t file_endianness = (header[8] == 'v') ? L_ENDIAN : B_ENDIAN;
if (file_endianness == B_ENDIAN) {
for (int64_t i = 0; i < num_entries; i++) {
BLI_endian_switch_int32(&idx->entries[i].frameno);
BLI_endian_switch_uint64(&idx->entries[i].seek_pos_pts);

View File

@ -21,7 +21,6 @@
# include "MEM_guardedalloc.h"
# include "BLI_endian_defines.h"
# include "BLI_fileops.h"
# include "BLI_math_base.h"
# include "BLI_path_utils.hh"
@ -254,30 +253,15 @@ static AVFrame *generate_video_frame(MovieWriter *context, const ImBuf *image)
}
}
else {
/* Byte image: flip the image vertically, possibly with endian
* conversion. */
/* Byte image: flip the image vertically. */
const size_t linesize_src = rgb_frame->width * 4;
for (int y = 0; y < height; y++) {
uint8_t *target = rgb_frame->data[0] + linesize_dst * (height - y - 1);
const uint8_t *src = pixels + linesize_src * y;
# if ENDIAN_ORDER == L_ENDIAN
/* NOTE: this is endianness-sensitive. */
/* The target buffer is always expected to conaint little-endian RGBA values. */
memcpy(target, src, linesize_src);
# elif ENDIAN_ORDER == B_ENDIAN
const uint8_t *end = src + linesize_src;
while (src != end) {
target[3] = src[0];
target[2] = src[1];
target[1] = src[2];
target[0] = src[3];
target += 4;
src += 4;
}
# else
# error ENDIAN_ORDER should either be L_ENDIAN or B_ENDIAN.
# endif
}
}

View File

@ -97,14 +97,8 @@ typedef enum eIDPropertyFlag {
* The tags represent types! This is a dirty way of enabling RTTI. The
* sig_byte end endian defines aren't really used much.
*/
#ifdef __BIG_ENDIAN__
/* big endian */
# define MAKE_ID2(c, d) ((c) << 8 | (d))
#else
/* little endian */
# define MAKE_ID2(c, d) ((d) << 8 | (c))
#endif
/* NOTE: this is endianness-sensitive. */
#define MAKE_ID2(c, d) ((d) << 8 | (c))
/**
* ID from database.

View File

@ -24,10 +24,11 @@ extern const int DNAlen;
/**
* Primitive (non-struct, non-pointer/function/array) types,
*
* NOTE: this is endianness-sensitive.
* \warning Don't change these values!
* Currently changes here will work on native endianness,
* however #DNA_struct_switch_endian currently checks these
* hard-coded values against those from old files.
* Currently changes here will work on native endianness, however before 5.0,
* #DNA_struct_switch_endian used to check these hard-coded values against those from old files.
*/
typedef enum eSDNA_Type {
SDNA_TYPE_CHAR = 0,
@ -61,8 +62,7 @@ enum eSDNA_StructCompare {
/* Struct has disappeared
* (values of this struct type will not be loaded by the current Blender) */
SDNA_CMP_REMOVED = 0,
/* Struct is the same
* (can be loaded with straight memory copy after any necessary endian conversion) */
/* Struct is the same (can be loaded with straight memory copy). */
SDNA_CMP_EQUAL = 1,
/* Struct is different in some way
* (needs to be copied/converted field by field) */
@ -74,12 +74,8 @@ enum eSDNA_StructCompare {
/**
* Constructs and returns a decoded SDNA structure from the given encoded SDNA data block.
*/
struct SDNA *DNA_sdna_from_data(const void *data,
int data_len,
bool do_endian_swap,
bool data_alloc,
bool do_alias,
const char **r_error_message);
struct SDNA *DNA_sdna_from_data(
const void *data, int data_len, bool data_alloc, bool do_alias, const char **r_error_message);
void DNA_sdna_free(struct SDNA *sdna);
/* Access for current Blender versions SDNA. */
@ -137,14 +133,6 @@ bool DNA_struct_member_exists_without_alias(const struct SDNA *sdna,
const char *vartype,
const char *name);
/**
* Does endian swapping on the fields of a struct value.
*
* \param sdna: SDNA of the struct_nr belongs to
* \param struct_nr: Index of struct info within sdna
* \param data: Struct data that is to be converted
*/
void DNA_struct_switch_endian(const struct SDNA *sdna, int struct_index, char *data);
/**
* Constructs and returns an array of byte flags with one element for each struct in oldsdna,
* indicating how it compares to newsdna.

View File

@ -53,7 +53,6 @@ set(BLENLIB_SRC
../../blenlib/intern/BLI_linklist.cc
../../blenlib/intern/BLI_memarena.cc
../../blenlib/intern/BLI_mempool.cc
../../blenlib/intern/endian_switch.cc
../../blenlib/intern/listbase.cc
../../blenlib/intern/string.cc

View File

@ -69,7 +69,6 @@
#include "MEM_guardedalloc.h"
#include "BLI_endian_switch.h"
#include "BLI_math_base.h"
#include "BLI_math_rotation.h"
#include "BLI_utildefines.h"

View File

@ -23,7 +23,6 @@
#include "MEM_guardedalloc.h" /* for MEM_freeN MEM_mallocN MEM_callocN */
#include "BLI_endian_switch.h"
#include "BLI_ghash.h"
#include "BLI_index_range.hh"
#include "BLI_math_matrix_types.hh"
@ -42,8 +41,8 @@
* - if you want a struct not to be in DNA file: add two hash marks above it `(#<enter>#<enter>)`.
*
* Structure DNA data is added to each blender file and to each executable, this to detect
* in .blend files new variables in structs, changed array sizes, etc. It's also used for
* converting endian and pointer size (32-64 bits)
* in .blend files new variables in structs, changed array sizes, etc. It is also used for
* converting pointer size (32-64 bits) (and it used to be to handle endianness).
* As an extra, Python uses a call to detect run-time the contents of a blender struct.
*
* Create a structDNA: only needed when one of the input include (.h) files change.
@ -95,7 +94,6 @@
* - array (`vec[3]`) to float struct (`vec3f`).
*
* DONE:
* - Endian compatibility.
* - Pointer conversion (32-64 bits).
*
* IMPORTANT:
@ -117,13 +115,9 @@
* always check blender running from a console.
*/
#ifdef __BIG_ENDIAN__
/* Big Endian */
# define MAKE_ID(a, b, c, d) (int(a) << 24 | int(b) << 16 | (c) << 8 | (d))
#else
/* NOTE: this is endianness-sensitive. */
/* Little Endian */
# define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
#endif
#define MAKE_ID(a, b, c, d) (int(d) << 24 | int(c) << 16 | (b) << 8 | (a))
/* ************************* DIV ********************** */
@ -322,7 +316,7 @@ BLI_INLINE const char *pad_up_4(const char *ptr)
/**
* In sdna->data the data, now we convert that to something understandable
*/
static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error_message)
static bool init_structDNA(SDNA *sdna, const char **r_error_message)
{
int member_index_gravity_fix = -1;
@ -358,10 +352,8 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
if (*data == MAKE_ID('N', 'A', 'M', 'E')) {
data++;
/* NOTE: this is endianness-sensitive. */
sdna->members_num = *data;
if (do_endian_swap) {
BLI_endian_switch_int32(&sdna->members_num);
}
sdna->members_num_alloc = sdna->members_num;
data++;
@ -398,10 +390,8 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
if (*data == MAKE_ID('T', 'Y', 'P', 'E')) {
data++;
/* NOTE: this is endianness-sensitive. */
sdna->types_num = *data;
if (do_endian_swap) {
BLI_endian_switch_int32(&sdna->types_num);
}
data++;
sdna->types = MEM_calloc_arrayN<const char *>(sdna->types_num, "sdnatypes");
@ -428,13 +418,10 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
short *sp;
if (*data == MAKE_ID('T', 'L', 'E', 'N')) {
data++;
/* NOTE: this is endianness-sensitive. */
sp = (short *)data;
sdna->types_size = sp;
if (do_endian_swap) {
BLI_endian_switch_int16_array(sp, sdna->types_num);
}
sp += sdna->types_num;
}
if (!sdna->types_size) {
@ -451,10 +438,8 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
if (*data == MAKE_ID('S', 'T', 'R', 'C')) {
data++;
/* NOTE: this is endianness-sensitive. */
sdna->structs_num = *data;
if (do_endian_swap) {
BLI_endian_switch_int32(&sdna->structs_num);
}
data++;
sdna->structs = MEM_calloc_arrayN<SDNA_Struct *>(sdna->structs_num, "sdnastrcs");
@ -468,19 +453,10 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
blender::Set<short> struct_indices;
sp = (short *)data;
for (int struct_index = 0; struct_index < sdna->structs_num; struct_index++) {
/* NOTE: this is endianness-sensitive. */
SDNA_Struct *struct_info = (SDNA_Struct *)sp;
sdna->structs[struct_index] = struct_info;
if (do_endian_swap) {
BLI_endian_switch_int16(&struct_info->type_index);
BLI_endian_switch_int16(&struct_info->members_num);
for (short a = 0; a < struct_info->members_num; a++) {
SDNA_StructMember *member = &struct_info->members[a];
BLI_endian_switch_int16(&member->type_index);
BLI_endian_switch_int16(&member->member_index);
}
}
if (!struct_indices.add(struct_info->type_index)) {
*r_error_message = "Invalid duplicate struct type index in SDNA file";
return false;
@ -572,7 +548,6 @@ static bool init_structDNA(SDNA *sdna, bool do_endian_swap, const char **r_error
SDNA *DNA_sdna_from_data(const void *data,
const int data_len,
bool do_endian_swap,
bool data_alloc,
const bool do_alias,
const char **r_error_message)
@ -591,7 +566,7 @@ SDNA *DNA_sdna_from_data(const void *data,
}
sdna->data_alloc = data_alloc;
if (init_structDNA(sdna, do_endian_swap, &error_message)) {
if (init_structDNA(sdna, &error_message)) {
if (do_alias) {
DNA_sdna_alias_data_ensure_structs_map(sdna);
}
@ -618,7 +593,7 @@ static SDNA *g_sdna = nullptr;
void DNA_sdna_current_init()
{
g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, true, nullptr);
g_sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, true, nullptr);
}
const SDNA *DNA_sdna_current_get()
@ -755,7 +730,8 @@ const char *DNA_struct_get_compareflags(const SDNA *oldsdna, const SDNA *newsdna
* - `struct Link` never needed DNA-versioning.
*
* NOTE: This may have been broken in BE/LE conversion cases, however this endianness handling
* code have likely been dead/never used in practice for many years now.
* code have likely been dead/never used in practice for many years, and has been removed in
* Blender 5.0.
*/
BLI_STATIC_ASSERT(SDNA_RAW_DATA_STRUCT_INDEX == 0, "'raw data' SDNA struct index should be 0")
compare_flags[SDNA_RAW_DATA_STRUCT_INDEX] = SDNA_CMP_EQUAL;
@ -1115,74 +1091,6 @@ static int get_member_size_in_bytes(const SDNA *sdna, const SDNA_StructMember *m
return type_size * array_length;
}
void DNA_struct_switch_endian(const SDNA *sdna, int struct_index, char *data)
{
if (struct_index == -1) {
return;
}
const SDNA_Struct *struct_info = sdna->structs[struct_index];
int offset_in_bytes = 0;
for (int member_index = 0; member_index < struct_info->members_num; member_index++) {
const SDNA_StructMember *member = &struct_info->members[member_index];
const eStructMemberCategory member_category = get_struct_member_category(sdna, member);
char *member_data = data + offset_in_bytes;
const char *member_type_name = sdna->types[member->type_index];
const int member_array_length = sdna->members_array_num[member->member_index];
switch (member_category) {
case STRUCT_MEMBER_CATEGORY_STRUCT: {
const int substruct_size = sdna->types_size[member->type_index];
const int substruct_index = DNA_struct_find_index_without_alias(sdna, member_type_name);
BLI_assert(substruct_index != -1);
for (int a = 0; a < member_array_length; a++) {
DNA_struct_switch_endian(sdna, substruct_index, member_data + a * substruct_size);
}
break;
}
case STRUCT_MEMBER_CATEGORY_PRIMITIVE: {
switch (member->type_index) {
case SDNA_TYPE_SHORT:
case SDNA_TYPE_USHORT: {
BLI_endian_switch_int16_array((int16_t *)member_data, member_array_length);
break;
}
case SDNA_TYPE_INT:
case SDNA_TYPE_FLOAT: {
/* NOTE: intentionally ignore `long/ulong`, because these could be 4 or 8 bytes.
* Fortunately, we only use these types for runtime variables and only once for a
* struct type that is no longer used. */
BLI_endian_switch_int32_array((int32_t *)member_data, member_array_length);
break;
}
case SDNA_TYPE_INT64:
case SDNA_TYPE_UINT64:
case SDNA_TYPE_DOUBLE: {
BLI_endian_switch_int64_array((int64_t *)member_data, member_array_length);
break;
}
default: {
break;
}
}
break;
}
case STRUCT_MEMBER_CATEGORY_POINTER: {
/* See `readfile.cc` (#uint32_from_uint64_ptr swap endian argument),
* this is only done when reducing the size of a pointer from 4 to 8. */
if (sizeof(void *) < 8) {
if (sdna->pointer_size == 8) {
BLI_endian_switch_uint64_array((uint64_t *)member_data, member_array_length);
}
}
break;
}
}
offset_in_bytes += get_member_size_in_bytes(sdna, member);
}
}
enum eReconstructStepType {
RECONSTRUCT_STEP_MEMCPY,
RECONSTRUCT_STEP_CAST_PRIMITIVE,

View File

@ -707,7 +707,7 @@ BlenderRNA *RNA_create()
/* We need both alias and static (on-disk) DNA names. */
const bool do_alias = true;
DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, false, do_alias, &error_message);
DefRNA.sdna = DNA_sdna_from_data(DNAstr, DNAlen, false, do_alias, &error_message);
if (DefRNA.sdna == nullptr) {
CLOG_ERROR(&LOG, "Failed to decode SDNA: %s.", error_message);
DefRNA.error = true;

View File

@ -11,11 +11,9 @@
#include <cstdio>
#include <cstring>
#include "BLI_endian_switch.h"
#include "BLI_fileops.h"
#include "BLI_math_base.h"
#ifdef __LITTLE_ENDIAN__
# include "BLI_endian_switch.h"
#endif
#ifdef WIN32
# include "BLI_winstuff.h"
#endif
@ -41,9 +39,9 @@ static bool meshcache_read_mdd_head(FILE *fp,
return false;
}
#ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* MDD is big-endian, its values need to be switched on little-endian systems. */
BLI_endian_switch_int32_array((int *)mdd_head, 2);
#endif
if (mdd_head->verts_tot != verts_tot) {
*r_err_str = RPT_("Vertex count mismatch");
@ -104,9 +102,10 @@ static bool meshcache_read_mdd_range_from_time(FILE *fp,
errno = 0;
for (i = 0; i < mdd_head.frame_tot; i++) {
frames_num_read += fread(&f_time, sizeof(float), 1, fp);
#ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* MDD is big-endian, its values need to be switched on little-endian systems. */
BLI_endian_switch_float(&f_time);
#endif
if (f_time >= time) {
frames_num_expect = i + 1;
break;
@ -169,11 +168,11 @@ bool MOD_meshcache_read_mdd_index(FILE *fp,
for (i = mdd_head.verts_tot; i != 0; i--, vco += 3) {
verts_read_num += fread(vco, sizeof(float[3]), 1, fp);
# ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* MDD is big-endian, its values need to be switched on little-endian systems. */
BLI_endian_switch_float(vco + 0);
BLI_endian_switch_float(vco + 1);
BLI_endian_switch_float(vco + 2);
# endif /* __LITTLE_ENDIAN__ */
}
#else
/* no blending */
@ -181,9 +180,9 @@ bool MOD_meshcache_read_mdd_index(FILE *fp,
*r_err_str = errno ? strerror(errno) : RPT_("Failed to read frame");
return false;
}
# ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* MDD is big-endian, its values need to be switched on little-endian systems. */
BLI_endian_switch_float_array(vertexCos[0], mdd_head.verts_tot * 3);
# endif
#endif
}
else {
@ -194,11 +193,11 @@ bool MOD_meshcache_read_mdd_index(FILE *fp,
float tvec[3];
verts_read_num += fread(tvec, sizeof(float[3]), 1, fp);
#ifdef __LITTLE_ENDIAN__
/* NOTE: this is endianness-sensitive. */
/* MDD is big-endian, its values need to be switched on little-endian systems. */
BLI_endian_switch_float(tvec + 0);
BLI_endian_switch_float(tvec + 1);
BLI_endian_switch_float(tvec + 2);
#endif
vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);

View File

@ -14,9 +14,6 @@
#include "BLI_utildefines.h"
#include "BLI_fileops.h"
#ifdef __BIG_ENDIAN__
# include "BLI_endian_switch.h"
#endif
#ifdef WIN32
# include "BLI_winstuff.h"
@ -52,10 +49,9 @@ static bool meshcache_read_pc2_head(FILE *fp,
return false;
}
#ifdef __BIG_ENDIAN__
BLI_endian_switch_int32_array(&pc2_head->file_version,
(sizeof(*pc2_head) - sizeof(pc2_head->header)) / sizeof(int));
#endif
/* NOTE: this is endianness-sensitive. */
/* The pc2_head->file_version and following values would need to be switched on big-endian
* systems. */
if (pc2_head->verts_tot != verts_tot) {
*r_err_str = RPT_("Vertex count mismatch");
@ -150,11 +146,8 @@ bool MOD_meshcache_read_pc2_index(FILE *fp,
for (i = pc2_head.verts_tot; i != 0; i--, vco += 3) {
verts_read_num += fread(vco, sizeof(float[3]), 1, fp);
#ifdef __BIG_ENDIAN__
BLI_endian_switch_float(vco + 0);
BLI_endian_switch_float(vco + 1);
BLI_endian_switch_float(vco + 2);
#endif /* __BIG_ENDIAN__ */
/* NOTE: this is endianness-sensitive. */
/* The `vco` values would need to be switched on big-endian systems. */
}
}
else {
@ -165,11 +158,8 @@ bool MOD_meshcache_read_pc2_index(FILE *fp,
float tvec[3];
verts_read_num += fread(tvec, sizeof(float[3]), 1, fp);
#ifdef __BIG_ENDIAN__
BLI_endian_switch_float(tvec + 0);
BLI_endian_switch_float(tvec + 1);
BLI_endian_switch_float(tvec + 2);
#endif /* __BIG_ENDIAN__ */
/* NOTE: this is endianness-sensitive. */
/* The `tvec` values would need to be switched on big-endian systems. */
vco[0] = (vco[0] * ifactor) + (tvec[0] * factor);
vco[1] = (vco[1] * ifactor) + (tvec[1] * factor);

View File

@ -39,11 +39,8 @@ short euler_order_from_string(const char *str, const char *error_prefix)
{
if (str[0] && str[1] && str[2] && str[3] == '\0') {
#ifdef __LITTLE_ENDIAN__
# define MAKE_ID3(a, b, c) ((a) | ((b) << 8) | ((c) << 16))
#else
# define MAKE_ID3(a, b, c) (((a) << 24) | ((b) << 16) | ((c) << 8))
#endif
/* NOTE: this is endianness-sensitive. */
#define MAKE_ID3(a, b, c) ((a) | ((b) << 8) | ((c) << 16))
switch (*((const PY_INT32_T *)str)) {
case MAKE_ID3('X', 'Y', 'Z'):

View File

@ -28,6 +28,7 @@
#include "DNA_genfile.h"
#include "BLI_endian_defines.h"
#include "BLI_fftw.hh"
#include "BLI_string.h"
#include "BLI_system.h"
@ -98,6 +99,8 @@
#include "creator_intern.h" /* Own include. */
BLI_STATIC_ASSERT(ENDIAN_ORDER == L_ENDIAN, "Blender only builds on little endian systems")
/* -------------------------------------------------------------------- */
/** \name Local Defines
* \{ */

View File

@ -31,30 +31,205 @@ class TestBlendFileOpenAllTestFiles(TestHelper):
# Each file in this list should either be the source of a bug report,
# or removed from tests repo.
self.excluded_paths = {
# tests/modifier_stack/explode_modifier.blend
# modifier_stack/explode_modifier.blend
# BLI_assert failed: source/blender/blenlib/BLI_ordered_edge.hh:41, operator==(), at 'e1.v_low < e1.v_high'
"explode_modifier.blend",
# tests/depsgraph/deg_anim_camera_dof_driving_material.blend
# depsgraph/deg_anim_camera_dof_driving_material.blend
# ERROR (bke.fcurve):
# source/blender/blenkernel/intern/fcurve_driver.cc:188 dtar_get_prop_val:
# Driver Evaluation Error: cannot resolve target for OBCamera ->
# data.dof_distance
"deg_anim_camera_dof_driving_material.blend",
# tests/depsgraph/deg_driver_shapekey_same_datablock.blend
# depsgraph/deg_driver_shapekey_same_datablock.blend
# Error: Not freed memory blocks: 4, total unfreed memory 0.000427 MB
"deg_driver_shapekey_same_datablock.blend",
# tests/physics/fluidsim.blend
# physics/fluidsim.blend
# Error: Not freed memory blocks: 3, total unfreed memory 0.003548 MB
"fluidsim.blend",
# tests/opengl/ram_glsl.blend
# opengl/ram_glsl.blend
# Error: Not freed memory blocks: 4, total unfreed memory 0.000427 MB
"ram_glsl.blend",
}
# Some files are expected to be invalid.
# This mapping stores filenames as keys, and expected error message as value.
self.invalid_paths = {
# animation/driver-object-eyes.blend
# File generated from a big endian build of Blender.
"driver-object-eyes.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# modeling/faceselectmode.blend
# File generated from a big endian build of Blender.
"faceselectmode.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# modeling/weight-paint_test.blend
# File generated from a big endian build of Blender.
"weight-paint_test.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/1.62/glass.blend
# File generated from a big endian build of Blender.
"glass.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/1.62/room.blend
# File generated from a big endian build of Blender.
"room.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/1.69/s-mesh.blend
# File generated from a big endian build of Blender.
"s-mesh.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/1.70/escher.blend
# File generated from a big endian build of Blender.
"escher.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/1.98/egypt.blend
# File generated from a big endian build of Blender.
"egypt.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.25/FroggyPacked.blend
# File generated from a big endian build of Blender.
"FroggyPacked.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.30/CtrlObject.blend
# File generated from a big endian build of Blender.
"CtrlObject.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.30/demofile.blend
# File generated from a big endian build of Blender.
"demofile.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.30/dolphin.blend
# File generated from a big endian build of Blender.
"dolphin.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.30/mball.blend
# File generated from a big endian build of Blender.
"mball.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.30/motor9.blend
# File generated from a big endian build of Blender.
"motor9.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.30/relative.blend
# File generated from a big endian build of Blender.
"relative.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/Raptor.blend
# File generated from a big endian build of Blender.
"Raptor.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/allselect.blend
# File generated from a big endian build of Blender.
"allselect.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/arealight.blend
# File generated from a big endian build of Blender.
"arealight.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/hairball.blend
# File generated from a big endian build of Blender.
"hairball.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/luxo.blend
# File generated from a big endian build of Blender.
"luxo.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/monkey_cornelius.blend
# File generated from a big endian build of Blender.
"monkey_cornelius.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/refract_monkey.blend
# File generated from a big endian build of Blender.
"refract_monkey.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.31/robo.blend
# File generated from a big endian build of Blender.
"robo.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.34/flippedmatrixes.blend
# File generated from a big endian build of Blender.
"flippedmatrixes.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.34/lostride.blend
# File generated from a big endian build of Blender.
"lostride.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.34/tapercurve.blend
# File generated from a big endian build of Blender.
"tapercurve.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.36/pathdist.blend
# File generated from a big endian build of Blender.
"pathdist.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
# io_tests/blend_big_endian/2.76/bird_sintel.blend
# File generated from a big endian build of Blender.
"bird_sintel.blend": (
(OSError, RuntimeError),
"created by a Big Endian version of Blender, support for these files has been removed in Blender 5.0"
),
}
# Directories to exclude relative to `./tests/files/`.
self.excluded_dirs = ()
@ -102,6 +277,18 @@ class TestBlendFileOpenAllTestFiles(TestHelper):
return True
return False
def invalid_path_exception_process(self, bfp, exception):
expected_failure = self.invalid_paths.get(os.path.basename(bfp), None)
if not expected_failure:
raise exception
# Check expected exception type(s).
if not isinstance(exception, expected_failure[0]):
raise exception
# Check expected exception (partial) message.
if expected_failure[1] not in str(exception):
raise exception
print(f"\tExpected failure: '{exception}'", flush=True)
def test_open(self):
for bfp in self.blendfile_paths:
if self.skip_path_check(bfp):
@ -109,7 +296,10 @@ class TestBlendFileOpenAllTestFiles(TestHelper):
if not self.args.is_quiet:
print(f"Trying to open {bfp}", flush=True)
bpy.ops.wm.read_homefile(use_empty=True, use_factory_startup=True)
bpy.ops.wm.open_mainfile(filepath=bfp, load_ui=False)
try:
bpy.ops.wm.open_mainfile(filepath=bfp, load_ui=False)
except BaseException as e:
self.invalid_path_exception_process(bfp, e)
def link_append(self, do_link):
operation_name = "link" if do_link else "append"
@ -117,15 +307,18 @@ class TestBlendFileOpenAllTestFiles(TestHelper):
if self.skip_path_check(bfp):
continue
bpy.ops.wm.read_homefile(use_empty=True, use_factory_startup=True)
with bpy.data.libraries.load(bfp, link=do_link) as (lib_in, lib_out):
if len(lib_in.collections):
if not self.args.is_quiet:
print(f"Trying to {operation_name} {bfp}/Collection/{lib_in.collections[0]}", flush=True)
lib_out.collections.append(lib_in.collections[0])
elif len(lib_in.objects):
if not self.args.is_quiet:
print(f"Trying to {operation_name} {bfp}/Object/{lib_in.objects[0]}", flush=True)
lib_out.objects.append(lib_in.objects[0])
try:
with bpy.data.libraries.load(bfp, link=do_link) as (lib_in, lib_out):
if len(lib_in.collections):
if not self.args.is_quiet:
print(f"Trying to {operation_name} {bfp}/Collection/{lib_in.collections[0]}", flush=True)
lib_out.collections.append(lib_in.collections[0])
elif len(lib_in.objects):
if not self.args.is_quiet:
print(f"Trying to {operation_name} {bfp}/Object/{lib_in.objects[0]}", flush=True)
lib_out.objects.append(lib_in.objects[0])
except BaseException as e:
self.invalid_path_exception_process(bfp, e)
def test_link(self):
self.link_append(do_link=True)