68 # include "winsock2.h"
79 #define DNA_DEPRECATED_ALLOW
125 #define U (*((const UserDef *)&U))
130 #define MEM_BUFFER_SIZE (MEM_SIZE_OPTIMAL(1 << 17))
131 #define MEM_CHUNK_SIZE (MEM_SIZE_OPTIMAL(1 << 15))
133 #define ZSTD_BUFFER_SIZE (1 << 21)
134 #define ZSTD_CHUNK_SIZE (1 << 20)
136 #define ZSTD_COMPRESSION_LEVEL 3
224 size_t out_buf_len = ZSTD_compressBound(
task->size);
225 void *out_buf =
MEM_mallocN(out_buf_len,
"Zstd out buffer");
226 size_t out_size = ZSTD_compress(
237 if (ZSTD_isError(out_size)) {
278 #ifdef __BIG_ENDIAN__
301 const uint32_t frame_size = num_frames * 8 + 9;
312 const char flags = 0;
339 memcpy(
task->data, buf, buf_len);
340 task->size = buf_len;
371 memset(r_ww, 0,
sizeof(*r_ww));
412 #ifdef USE_WRITE_DATA_LEN
462 if ((wd ==
NULL) || wd->
error || (mem ==
NULL) || memlen < 1) {
466 if (memlen > INT_MAX) {
480 if (wd->
ww->
write(wd->
ww, mem, memlen) != memlen) {
528 #ifdef USE_WRITE_DATA_LEN
529 wd->write_len +=
len;
547 adr = (
const char *)adr + writelen;
577 if (current !=
NULL) {
624 (prev_memchunk !=
NULL &&
660 WriteData *wd,
int filecode,
const int struct_nr,
int nr,
const void *adr,
const void *
data)
664 BLI_assert(struct_nr > 0 && struct_nr < SDNA_TYPE_MAX);
689 WriteData *wd,
int filecode,
const int struct_nr,
int nr,
const void *adr)
709 len = (
len + 3) & ~((
size_t)3);
734 static void writelist_id(
WriteData *wd,
int filecode,
const char *structname,
const ListBase *lb)
740 if (struct_nr == -1) {
741 printf(
"error: can't find SDNA code <%s>\n", structname);
753 #define writestruct_at_address(wd, filecode, struct_id, nr, adr, data) \
754 writestruct_at_address_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), nr, adr, data)
756 #define writestruct(wd, filecode, struct_id, nr, adr) \
757 writestruct_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), nr, adr)
759 #define writelist(wd, filecode, struct_id, lb) \
760 writelist_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), lb)
788 if (use_active_win) {
797 if (window ==
NULL) {
807 *r_scene = (window) ? window->
scene :
NULL;
836 data.sfra = sce->r.sfra;
837 data.efra = sce->r.efra;
838 memset(
data.scene_name, 0,
sizeof(
data.scene_name));
868 if (kmdi->remove_item) {
871 if (kmdi->add_item) {
944 if (
main->curlib &&
main->curlib->packedfile) {
954 while (!found_one && tot--) {
955 for (
id = lbarray[tot]->first;
id;
id =
id->
next) {
973 void *runtime_name_data =
main->curlib->runtime.name_map;
974 main->curlib->runtime.name_map =
NULL;
980 main->curlib->runtime.name_map = runtime_name_data;
982 if (
main->curlib->packedfile) {
991 for (
id = lbarray[
a]->first;
id;
id =
id->
next) {
997 "Data-block '%s' from lib '%s' is not linkable, but is flagged as "
1000 main->curlib->filepath_abs);
1025 memset(fg.
_pad, 0,
sizeof(fg.
_pad));
1046 memcpy(fg.
subvstr, subvstr, 4);
1051 #ifdef WITH_BUILDINFO
1105 (
sizeof(
void *) == 8) ?
'-' :
'_',
1123 #define ID_BUFFER_STATIC_SIZE 8192
1127 Main *bmain = mainvar;
1139 void *id_buffer = id_buffer_static;
1141 const size_t idtype_struct_size = id_type->
struct_size;
1144 "ID maximum buffer size (%d bytes) is not big enough to fit IDs of type %s, "
1145 "which needs %lu bytes",
1149 id_buffer =
MEM_mallocN(idtype_struct_size, __func__);
1152 for (;
id;
id =
id->
next) {
1166 const bool do_override = !
ELEM(override_storage,
NULL, bmain) &&
1177 id->recalc_up_to_undo_push =
id->recalc_after_undo_push;
1178 id->recalc_after_undo_push = 0;
1181 if (nodetree !=
NULL) {
1197 memcpy(id_buffer,
id, idtype_struct_size);
1200 ((
ID *)id_buffer)->tag = 0;
1201 ((
ID *)id_buffer)->us = 0;
1202 ((
ID *)id_buffer)->icon_id = 0;
1206 ((
ID *)id_buffer)->prev =
NULL;
1207 ((
ID *)id_buffer)->next =
NULL;
1210 ((
ID *)id_buffer)->orig_id =
NULL;
1211 ((
ID *)id_buffer)->newid =
NULL;
1215 ((
ID *)id_buffer)->py_instance =
NULL;
1228 if (id_buffer != id_buffer_static) {
1234 }
while ((bmain != override_storage) && (bmain = override_storage));
1236 if (override_storage) {
1238 override_storage =
NULL;
1258 memset(&bhead, 0,
sizeof(
BHead));
1272 int hisnr =
U.versions;
1274 if (
U.versions == 0) {
1278 if (strlen(name) < 2) {
1284 BLI_snprintf(tempname1,
sizeof(tempname1),
"%s%d", name, hisnr - 1);
1286 BLI_snprintf(tempname2,
sizeof(tempname2),
"%s%d", name, hisnr);
1298 BLI_snprintf(tempname1,
sizeof(tempname1),
"%s%d", name, hisnr);
1316 const char *filepath,
1317 const int write_flags,
1328 const bool use_save_versions =
params->use_save_versions;
1329 const bool use_save_as_copy =
params->use_save_as_copy;
1330 const bool use_userdef =
params->use_userdef;
1332 const bool relbase_valid = (mainvar->
filepath[0] !=
'\0');
1335 void *path_list_backup =
NULL;
1340 BKE_report(reports,
RPT_INFO,
"Checking sanity of current .blend file *BEFORE* save to disk");
1346 BLI_snprintf(tempname,
sizeof(tempname),
"%s@", filepath);
1350 if (ww.
open(&ww, tempname) ==
false) {
1352 reports,
RPT_ERROR,
"Cannot open file %s for writing: %s", tempname, strerror(errno));
1358 if (relbase_valid ==
false) {
1367 if (relbase_valid ==
false) {
1377 if (relbase_valid) {
1389 if (relbase_valid && (
BLI_path_cmp(dir_dst, dir_src) == 0)) {
1395 if (relbase_valid ==
false) {
1406 char mainvar_filepath_orig[
FILE_MAX];
1415 switch (remap_mode) {
1458 if (use_save_versions) {
1459 const bool err_hist =
do_history(filepath, reports);
1472 BKE_report(reports,
RPT_INFO,
"Checking sanity of current .blend file *AFTER* save to disk");
1481 bool use_userdef =
false;
1484 mainvar,
NULL, compare, current, write_flags, use_userdef,
NULL);
1500 const char *struct_name,
1502 const void *data_ptr)
1519 const void *address,
1520 const void *data_ptr)
1526 BlendWriter *writer,
int filecode,
int struct_id,
const void *address,
const void *data_ptr)
1534 const void *data_ptr)
1540 BlendWriter *writer,
int struct_id,
int array_size,
const void *address,
const void *data_ptr)
1583 BLO_write_raw(writer,
sizeof(
float) * (
size_t)num, data_ptr);
1588 BLO_write_raw(writer,
sizeof(
double) * (
size_t)num, data_ptr);
1593 BLO_write_raw(writer,
sizeof(
void *) * (
size_t)num, data_ptr);
1598 BLO_write_raw(writer,
sizeof(
float[3]) * (
size_t)num, data_ptr);
1603 if (data_ptr !=
NULL) {
#define BLENDER_FILE_SUBVERSION
#define BLENDER_FILE_MIN_VERSION
#define BLENDER_FILE_VERSION
#define BLENDER_FILE_MIN_SUBVERSION
void BKE_bpath_relative_rebase(struct Main *bmain, const char *basedir_src, const char *basedir_dst, struct ReportList *reports)
void BKE_bpath_relative_convert(struct Main *bmain, const char *basedir, struct ReportList *reports)
void * BKE_bpath_list_backup(struct Main *bmain, eBPathForeachFlag flag)
void BKE_bpath_list_restore(struct Main *bmain, eBPathForeachFlag flag, void *path_list_handle)
@ BKE_BPATH_FOREACH_PATH_SKIP_LINKED
@ BKE_BPATH_FOREACH_PATH_SKIP_MULTIFILE
void BKE_bpath_list_free(void *path_list_handle)
void BKE_bpath_absolute_convert(struct Main *bmain, const char *basedir, struct ReportList *reports)
#define G_FILE_FLAG_ALL_RUNTIME
void IDP_BlendWrite(struct BlendWriter *writer, const struct IDProperty *prop)
bool BKE_idtype_idcode_is_linkable(short idcode)
const struct IDTypeInfo * BKE_idtype_get_info_from_id(const struct ID *id)
struct ViewLayer * BKE_view_layer_find(const struct Scene *scene, const char *layer_name)
void BKE_id_blend_write(struct BlendWriter *writer, struct ID *id)
#define MAIN_ID_SESSION_UUID_UNSET
void BKE_lib_override_library_operations_store_finalize(OverrideLibraryStorage *override_storage)
void BKE_lib_override_library_operations_store_end(OverrideLibraryStorage *override_storage, struct ID *local)
struct ID * BKE_lib_override_library_operations_store_start(struct Main *bmain, OverrideLibraryStorage *override_storage, struct ID *local)
OverrideLibraryStorage * BKE_lib_override_library_operations_store_init(void)
int set_listbasepointers(struct Main *main, struct ListBase *lb[])
struct bNodeTree * ntreeFromID(struct ID *id)
void BKE_packedfile_blend_write(struct BlendWriter *writer, struct PackedFile *pf)
void BKE_reportf(ReportList *reports, eReportType type, const char *format,...) ATTR_PRINTF_FORMAT(3
void BKE_report(ReportList *reports, eReportType type, const char *message)
struct bScreen * BKE_workspace_active_screen_get(const struct WorkSpaceInstanceHook *hook) GETTER_ATTRS
#define BLI_assert_unreachable()
#define BLI_assert_msg(a, msg)
BLI_INLINE void BLI_endian_switch_uint32(unsigned int *val) ATTR_NONNULL(1)
int BLI_exists(const char *path) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
int BLI_rename(const char *from, const char *to) ATTR_NONNULL()
int BLI_open(const char *filepath, int oflag, int pmode) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Single link-list utility macros. (header only api).
#define LISTBASE_FOREACH(type, var, list)
void void BLI_freelistN(struct ListBase *listbase) ATTR_NONNULL(1)
void BLI_addtail(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
void BLI_remlink(struct ListBase *listbase, void *vlink) ATTR_NONNULL(1)
int BLI_listbase_count(const struct ListBase *listbase) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
MINLINE int max_ii(int a, int b)
void BLI_split_dir_part(const char *string, char *dir, size_t dirlen)
bool BLI_path_is_rel(const char *path) ATTR_NONNULL() ATTR_WARN_UNUSED_RESULT
void BLI_path_normalize(const char *relabase, char *path) ATTR_NONNULL(2)
bool BLI_path_is_abs_from_cwd(const char *path) ATTR_NONNULL(1) ATTR_WARN_UNUSED_RESULT
#define STRNCPY(dst, src)
char * BLI_strncpy(char *__restrict dst, const char *__restrict src, size_t maxncpy) ATTR_NONNULL()
size_t BLI_snprintf(char *__restrict dst, size_t maxncpy, const char *__restrict format,...) ATTR_NONNULL(1
void BLI_condition_notify_all(ThreadCondition *cond)
void BLI_mutex_end(ThreadMutex *mutex)
void BLI_threadpool_remove(struct ListBase *threadbase, void *callerdata)
void BLI_condition_wait(ThreadCondition *cond, ThreadMutex *mutex)
void BLI_threadpool_init(struct ListBase *threadbase, void *(*do_thread)(void *), int tot)
void BLI_mutex_init(ThreadMutex *mutex)
pthread_cond_t ThreadCondition
void BLI_condition_end(ThreadCondition *cond)
int BLI_system_thread_count(void)
void BLI_threadpool_end(struct ListBase *threadbase)
void BLI_condition_init(ThreadCondition *cond)
void BLI_mutex_lock(ThreadMutex *mutex)
void BLI_mutex_unlock(ThreadMutex *mutex)
int BLI_available_threads(struct ListBase *threadbase)
void BLI_threadpool_insert(struct ListBase *threadbase, void *callerdata)
pthread_mutex_t ThreadMutex
#define POINTER_FROM_UINT(i)
Compatibility-like things for windows.
defines for blend-file codes.
#define BLEN_THUMB_MEMSIZE_FILE(_x, _y)
Utilities ensuring .blend file (i.e. Main) is in valid state during write and/or read process.
bool BLO_main_validate_shapekeys(struct Main *bmain, struct ReportList *reports)
bool BLO_main_validate_libraries(struct Main *bmain, struct ReportList *reports)
#define BLO_write_struct(writer, struct_name, data_ptr)
external readfile function prototypes.
void BLO_memfile_chunk_add(MemFileWriteData *mem_data, const char *buf, size_t size)
void BLO_memfile_write_init(MemFileWriteData *mem_data, MemFile *written_memfile, MemFile *reference_memfile)
void BLO_memfile_write_finalize(MemFileWriteData *mem_data)
external writefile.c function prototypes.
@ BLO_WRITE_PATH_REMAP_NONE
@ BLO_WRITE_PATH_REMAP_RELATIVE_ALL
@ BLO_WRITE_PATH_REMAP_ABSOLUTE
@ BLO_WRITE_PATH_REMAP_RELATIVE
#define CLOG_ERROR(clg_ref,...)
#define CLOG_INFO(clg_ref, level,...)
#define ID_IS_OVERRIDE_LIBRARY_REAL(_id)
#define ID_IS_LINKED(_id)
@ LIB_TAG_NO_USER_REFCOUNT
#define ID_LINK_PLACEHOLDER
Object groups, one object can be in many groups at once.
blenloader genfile private function prototypes
int DNA_struct_find_nr(const struct SDNA *sdna, const char *str)
const struct SDNA * DNA_sdna_current_get(void)
@ USER_MENU_TYPE_OPERATOR
Read Guarded memory(de)allocation.
int main(int argc, char *argv[])
ulong build_commit_timestamp
ccl_global float * buffer
void(* MEM_freeN)(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_mallocN)(size_t len, const char *str)
bool remove(void *owner, const AttributeIDRef &attribute_id)
struct blender::compositor::@179::@181 task
SymEdge< T > * prev(const SymEdge< T > *se)
static void WriteData(png_structp png_ptr, png_bytep data, png_size_t length)
void blo_split_main(ListBase *mainlist, Main *main)
void blo_join_main(ListBase *mainlist)
struct ViewLayer * cur_view_layer
uint64_t build_commit_timestamp
struct bScreen * curscreen
IDTypeBlendWriteFunction blend_write
int recalc_after_undo_push
unsigned int session_uuid
int recalc_up_to_undo_push
struct GHash * id_session_uuid_mapping
MemFileChunk * reference_current_chunk
uint current_id_session_uuid
char scene_name[MAX_ID_NAME - 2]
struct Collection * master_collection
struct ListBase user_keymaps
struct ListBase autoexec_paths
struct ListBase user_keyconfig_prefs
struct ListBase user_menus
struct ListBase asset_libraries
struct WriteData::@137 buffer
bool(* close)(WriteWrap *ww)
size_t(* write)(WriteWrap *ww, const char *data, size_t data_len)
bool(* open)(WriteWrap *ww, const char *filepath)
ThreadCondition condition
struct WriteWrap::@136 zstd
uint32_t uncompressed_size
struct ZstdWriteBlockTask * next
struct WorkSpaceInstanceHook * workspace_hook
void BLO_write_double_array(BlendWriter *writer, uint num, const double *data_ptr)
void BLO_write_uint32_array(BlendWriter *writer, uint num, const uint32_t *data_ptr)
struct ZstdFrame ZstdFrame
static void mywrite_id_begin(WriteData *wd, ID *id)
#define ZSTD_COMPRESSION_LEVEL
static void write_thumb(WriteData *wd, const BlendThumbnail *thumb)
static WriteData * mywrite_begin(WriteWrap *ww, MemFile *compare, MemFile *current)
#define writestruct(wd, filecode, struct_id, nr, adr)
void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr)
static void writelist_nr(WriteData *wd, int filecode, const int struct_nr, const ListBase *lb)
void BLO_write_struct_at_address_by_id_with_filecode(BlendWriter *writer, int filecode, int struct_id, const void *address, const void *data_ptr)
static void writestruct_at_address_nr(WriteData *wd, int filecode, const int struct_nr, int nr, const void *adr, const void *data)
static bool ww_open_none(WriteWrap *ww, const char *filepath)
bool BLO_write_file(Main *mainvar, const char *filepath, const int write_flags, const struct BlendFileWriteParams *params, ReportList *reports)
void BLO_write_struct_by_name(BlendWriter *writer, const char *struct_name, const void *data_ptr)
static void writedata_free(WriteData *wd)
void BLO_write_int32_array(BlendWriter *writer, uint num, const int32_t *data_ptr)
static void write_keymapitem(BlendWriter *writer, const wmKeyMapItem *kmi)
static size_t ww_write_none(WriteWrap *ww, const char *buf, size_t buf_len)
void blo_write_id_struct(BlendWriter *writer, int struct_id, const void *id_address, const ID *id)
struct BlendWriter BlendWriter
static void write_renderinfo(WriteData *wd, Main *mainvar)
static void write_userdef(BlendWriter *writer, const UserDef *userdef)
static void write_libraries(WriteData *wd, Main *main)
static size_t ww_write_zstd(WriteWrap *ww, const char *buf, size_t buf_len)
#define ID_BUFFER_STATIC_SIZE
static bool ww_open_zstd(WriteWrap *ww, const char *filepath)
void BLO_write_struct_array_by_id(BlendWriter *writer, int struct_id, int array_size, const void *data_ptr)
static void * zstd_write_task(void *userdata)
static void write_global(WriteData *wd, int fileflags, Main *mainvar)
static bool ww_close_zstd(WriteWrap *ww)
static void zstd_write_seekable_frames(WriteWrap *ww)
static WriteData * writedata_new(WriteWrap *ww)
void BLO_write_struct_list_by_id(BlendWriter *writer, int struct_id, ListBase *list)
static void writestruct_nr(WriteData *wd, int filecode, const int struct_nr, int nr, const void *adr)
void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr)
void BLO_write_string(BlendWriter *writer, const char *data_ptr)
static void ww_handle_init(eWriteWrapType ww_type, WriteWrap *r_ww)
int BLO_get_struct_id_by_name(BlendWriter *writer, const char *struct_name)
void BLO_write_struct_array_by_name(BlendWriter *writer, const char *struct_name, int array_size, const void *data_ptr)
static bool mywrite_end(WriteData *wd)
static void mywrite_flush(WriteData *wd)
static bool do_history(const char *name, ReportList *reports)
static void writedata(WriteData *wd, int filecode, size_t len, const void *adr)
void BLO_write_raw(BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
void BLO_write_struct_at_address_by_id(BlendWriter *writer, int struct_id, const void *address, const void *data_ptr)
static void current_screen_compat(Main *mainvar, bool use_active_win, bScreen **r_screen, Scene **r_scene, ViewLayer **r_view_layer)
void BLO_write_struct_array_at_address_by_id(BlendWriter *writer, int struct_id, int array_size, const void *address, const void *data_ptr)
static void writedata_do_write(WriteData *wd, const void *mem, size_t memlen)
bool BLO_write_is_undo(BlendWriter *writer)
static void mywrite(WriteData *wd, const void *adr, size_t len)
bool BLO_write_file_mem(Main *mainvar, MemFile *compare, MemFile *current, int write_flags)
static void mywrite_id_end(WriteData *wd, ID *UNUSED(id))
static bool ww_close_none(WriteWrap *ww)
static bool write_file_handle(Main *mainvar, WriteWrap *ww, MemFile *compare, MemFile *current, int write_flags, bool use_userdef, const BlendThumbnail *thumb)
void BLO_write_struct_by_id(BlendWriter *writer, int struct_id, const void *data_ptr)
void BLO_write_struct_list_by_name(BlendWriter *writer, const char *struct_name, ListBase *list)
static void zstd_write_u32_le(WriteWrap *ww, uint32_t val)
void BLO_write_pointer_array(BlendWriter *writer, uint num, const void *data_ptr)
struct RenderInfo RenderInfo