Blender V4.5
blo_core_bhead.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2025 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#include "BLI_filereader.h"
6
7#include "BLO_core_bhead.hh"
8
9static void switch_endian_bh4(BHead4 *bhead)
10{
11 /* the ID_.. codes */
12 if ((bhead->code & 0xFFFF) == 0) {
13 bhead->code >>= 16;
14 }
15
16 if (bhead->code != BLO_CODE_ENDB) {
20 }
21}
22
24{
25 /* The ID_* codes. */
26 if ((bhead->code & 0xFFFF) == 0) {
27 bhead->code >>= 16;
28 }
29
30 if (bhead->code != BLO_CODE_ENDB) {
34 }
35}
36
38{
39 /* The ID_* codes. */
40 if ((bhead->code & 0xFFFF) == 0) {
41 bhead->code >>= 16;
42 }
43
44 if (bhead->code != BLO_CODE_ENDB) {
48 }
49}
50
51static BHead bhead_from_bhead4(const BHead4 &bhead4)
52{
53 BHead bhead;
54 bhead.code = bhead4.code;
55 bhead.len = bhead4.len;
56 bhead.old = reinterpret_cast<const void *>(uintptr_t(bhead4.old));
57 bhead.SDNAnr = bhead4.SDNAnr;
58 bhead.nr = bhead4.nr;
59 return bhead;
60}
61
62static const void *old_ptr_from_uint64_ptr(const uint64_t ptr, const bool use_endian_swap)
63{
64 if constexpr (sizeof(void *) == 8) {
65 return reinterpret_cast<const void *>(ptr);
66 }
67 else {
68 return reinterpret_cast<const void *>(uintptr_t(uint32_from_uint64_ptr(ptr, use_endian_swap)));
69 }
70}
71
72static BHead bhead_from_small_bhead8(const SmallBHead8 &small_bhead8, const bool use_endian_swap)
73{
74 BHead bhead;
75 bhead.code = small_bhead8.code;
76 bhead.len = small_bhead8.len;
77 bhead.old = old_ptr_from_uint64_ptr(small_bhead8.old, use_endian_swap);
78 bhead.SDNAnr = small_bhead8.SDNAnr;
79 bhead.nr = small_bhead8.nr;
80 return bhead;
81}
82
83static BHead bhead_from_large_bhead8(const LargeBHead8 &large_bhead8, const bool use_endian_swap)
84{
85 BHead bhead;
86 bhead.code = large_bhead8.code;
87 bhead.len = large_bhead8.len;
88 bhead.old = old_ptr_from_uint64_ptr(large_bhead8.old, use_endian_swap);
89 bhead.SDNAnr = large_bhead8.SDNAnr;
90 bhead.nr = large_bhead8.nr;
91 return bhead;
92}
93
94std::optional<BHead> BLO_readfile_read_bhead(FileReader *file,
95 const BHeadType type,
96 const bool do_endian_swap)
97{
98 switch (type) {
99 case BHeadType::BHead4: {
100 BHead4 bhead4{};
101 bhead4.code = BLO_CODE_DATA;
102 const int64_t readsize = file->read(file, &bhead4, sizeof(bhead4));
103 if (readsize == sizeof(bhead4) || bhead4.code == BLO_CODE_ENDB) {
104 if (do_endian_swap) {
105 switch_endian_bh4(&bhead4);
106 }
107 return bhead_from_bhead4(bhead4);
108 }
109 break;
110 }
112 SmallBHead8 small_bhead8{};
113 small_bhead8.code = BLO_CODE_DATA;
114 const int64_t readsize = file->read(file, &small_bhead8, sizeof(small_bhead8));
115 if (readsize == sizeof(small_bhead8) || small_bhead8.code == BLO_CODE_ENDB) {
116 if (do_endian_swap) {
117 switch_endian_small_bh8(&small_bhead8);
118 }
119 return bhead_from_small_bhead8(small_bhead8, do_endian_swap);
120 }
121 break;
122 }
124 LargeBHead8 large_bhead8{};
125 large_bhead8.code = BLO_CODE_DATA;
126 const int64_t readsize = file->read(file, &large_bhead8, sizeof(large_bhead8));
127 if (readsize == sizeof(large_bhead8) || large_bhead8.code == BLO_CODE_ENDB) {
128 if (do_endian_swap) {
129 switch_endian_large_bh8(&large_bhead8);
130 }
131 return bhead_from_large_bhead8(large_bhead8, do_endian_swap);
132 }
133 break;
134 }
135 }
136 return std::nullopt;
137}
BLI_INLINE void BLI_endian_switch_int64(int64_t *val) ATTR_NONNULL(1)
BLI_INLINE void BLI_endian_switch_int32(int *val) ATTR_NONNULL(1)
Wrapper for reading from various sources (e.g. raw files, compressed files, memory....
uint32_t uint32_from_uint64_ptr(uint64_t ptr, const bool use_endian_swap)
@ BLO_CODE_ENDB
@ BLO_CODE_DATA
BHeadType
static BHead bhead_from_small_bhead8(const SmallBHead8 &small_bhead8, const bool use_endian_swap)
static void switch_endian_small_bh8(SmallBHead8 *bhead)
static const void * old_ptr_from_uint64_ptr(const uint64_t ptr, const bool use_endian_swap)
static BHead bhead_from_large_bhead8(const LargeBHead8 &large_bhead8, const bool use_endian_swap)
static BHead bhead_from_bhead4(const BHead4 &bhead4)
static void switch_endian_bh4(BHead4 *bhead)
static void switch_endian_large_bh8(LargeBHead8 *bhead)
std::optional< BHead > BLO_readfile_read_bhead(FileReader *file, const BHeadType type, const bool do_endian_swap)
long long int int64_t
unsigned long long int uint64_t
int64_t len
int64_t nr
const void * old
FileReaderReadFn read
PointerRNA * ptr
Definition wm_files.cc:4226