Blender  V2.93
Classes | Macros
writefile.c File Reference
#include <fcntl.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "BLI_utildefines.h"
#include "DNA_collection_types.h"
#include "DNA_fileglobal_types.h"
#include "DNA_genfile.h"
#include "DNA_sdna_types.h"
#include "BLI_bitmap.h"
#include "BLI_blenlib.h"
#include "BLI_mempool.h"
#include "MEM_guardedalloc.h"
#include "BKE_blender_version.h"
#include "BKE_bpath.h"
#include "BKE_global.h"
#include "BKE_idprop.h"
#include "BKE_idtype.h"
#include "BKE_layer.h"
#include "BKE_lib_id.h"
#include "BKE_lib_override.h"
#include "BKE_main.h"
#include "BKE_node.h"
#include "BKE_packedFile.h"
#include "BKE_report.h"
#include "BKE_workspace.h"
#include "BLO_blend_defs.h"
#include "BLO_blend_validate.h"
#include "BLO_read_write.h"
#include "BLO_readfile.h"
#include "BLO_undofile.h"
#include "BLO_writefile.h"
#include "readfile.h"
#include <errno.h>

Go to the source code of this file.

Classes

struct  WriteWrap
 
struct  WriteData
 
struct  BlendWriter
 
struct  RenderInfo
 

Macros

#define DNA_DEPRECATED_ALLOW
 
#define U   (*((const UserDef *)&U))
 
#define MYWRITE_BUFFER_SIZE   (MEM_SIZE_OPTIMAL(1 << 17)) /* 128kb */
 
#define MYWRITE_MAX_CHUNK   (MEM_SIZE_OPTIMAL(1 << 15)) /* ~32kb */
 
#define ID_BUFFER_STATIC_SIZE   8192
 

Functions

Local Writing API 'mywrite'
static void mywrite_flush (WriteData *wd)
 
static void mywrite (WriteData *wd, const void *adr, size_t len)
 
static WriteDatamywrite_begin (WriteWrap *ww, MemFile *compare, MemFile *current)
 
static bool mywrite_end (WriteData *wd)
 
static void mywrite_id_begin (WriteData *wd, ID *id)
 
static void mywrite_id_end (WriteData *wd, ID *UNUSED(id))
 
File Writing (Private)
static bool write_file_handle (Main *mainvar, WriteWrap *ww, MemFile *compare, MemFile *current, int write_flags, bool use_userdef, const BlendThumbnail *thumb)
 
static bool do_history (const char *name, ReportList *reports)
 
File Writing (Public)
bool BLO_write_file (Main *mainvar, const char *filepath, const int write_flags, const struct BlendFileWriteParams *params, ReportList *reports)
 
bool BLO_write_file_mem (Main *mainvar, MemFile *compare, MemFile *current, int write_flags)
 
void BLO_write_raw (BlendWriter *writer, size_t size_in_bytes, const void *data_ptr)
 
void BLO_write_struct_by_name (BlendWriter *writer, const char *struct_name, const void *data_ptr)
 
void BLO_write_struct_array_by_name (BlendWriter *writer, const char *struct_name, int array_size, const void *data_ptr)
 
void BLO_write_struct_by_id (BlendWriter *writer, int struct_id, const void *data_ptr)
 
void BLO_write_struct_at_address_by_id (BlendWriter *writer, int struct_id, const void *address, const void *data_ptr)
 
void BLO_write_struct_at_address_by_id_with_filecode (BlendWriter *writer, int filecode, int struct_id, const void *address, const void *data_ptr)
 
void BLO_write_struct_array_by_id (BlendWriter *writer, int struct_id, int array_size, const void *data_ptr)
 
void BLO_write_struct_array_at_address_by_id (BlendWriter *writer, int struct_id, int array_size, const void *address, const void *data_ptr)
 
void BLO_write_struct_list_by_id (BlendWriter *writer, int struct_id, ListBase *list)
 
void BLO_write_struct_list_by_name (BlendWriter *writer, const char *struct_name, ListBase *list)
 
void blo_write_id_struct (BlendWriter *writer, int struct_id, const void *id_address, const ID *id)
 
int BLO_get_struct_id_by_name (BlendWriter *writer, const char *struct_name)
 
void BLO_write_int32_array (BlendWriter *writer, uint num, const int32_t *data_ptr)
 
void BLO_write_uint32_array (BlendWriter *writer, uint num, const uint32_t *data_ptr)
 
void BLO_write_float_array (BlendWriter *writer, uint num, const float *data_ptr)
 
void BLO_write_double_array (BlendWriter *writer, uint num, const double *data_ptr)
 
void BLO_write_pointer_array (BlendWriter *writer, uint num, const void *data_ptr)
 
void BLO_write_float3_array (BlendWriter *writer, uint num, const float *data_ptr)
 
void BLO_write_string (BlendWriter *writer, const char *data_ptr)
 
bool BLO_write_is_undo (BlendWriter *writer)
 

Internal Write Wrapper's (Abstracts Compression)

Use if we want to store how many bytes have been written to the file.

#define FILE_HANDLE(ww)   (ww)->_user_data.file_handle
 
#define FILE_HANDLE(ww)   (ww)->_user_data.gz_handle
 
enum  eWriteWrapType { WW_WRAP_NONE = 1 , WW_WRAP_ZLIB }
 
typedef struct WriteWrap WriteWrap
 
static bool ww_open_none (WriteWrap *ww, const char *filepath)
 
static bool ww_close_none (WriteWrap *ww)
 
static size_t ww_write_none (WriteWrap *ww, const char *buf, size_t buf_len)
 
static bool ww_open_zlib (WriteWrap *ww, const char *filepath)
 
static bool ww_close_zlib (WriteWrap *ww)
 
static size_t ww_write_zlib (WriteWrap *ww, const char *buf, size_t buf_len)
 
static void ww_handle_init (eWriteWrapType ww_type, WriteWrap *r_ww)
 

Generic DNA File Writing

#define writestruct_at_address(wd, filecode, struct_id, nr, adr, data)    writestruct_at_address_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), nr, adr, data)
 
#define writestruct(wd, filecode, struct_id, nr, adr)    writestruct_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), nr, adr)
 
#define writelist(wd, filecode, struct_id, lb)    writelist_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), lb)
 
static void writestruct_at_address_nr (WriteData *wd, int filecode, const int struct_nr, int nr, const void *adr, const void *data)
 
static void writestruct_nr (WriteData *wd, int filecode, const int struct_nr, int nr, const void *adr)
 
static void writedata (WriteData *wd, int filecode, size_t len, const void *adr)
 
static void writelist_nr (WriteData *wd, int filecode, const int struct_nr, const ListBase *lb)
 

Write Data Type & Functions

typedef struct BlendWriter BlendWriter
 
static WriteDatawritedata_new (WriteWrap *ww)
 
static void writedata_do_write (WriteData *wd, const void *mem, size_t memlen)
 
static void writedata_free (WriteData *wd)
 

Typed DNA File Writing

These functions are used by blender's .blend system for file saving/loading.

typedef struct RenderInfo RenderInfo
 
static void current_screen_compat (Main *mainvar, bool use_active_win, bScreen **r_screen, Scene **r_scene, ViewLayer **r_view_layer)
 
static void write_renderinfo (WriteData *wd, Main *mainvar)
 
static void write_keymapitem (BlendWriter *writer, const wmKeyMapItem *kmi)
 
static void write_userdef (BlendWriter *writer, const UserDef *userdef)
 
static void write_libraries (WriteData *wd, Main *main)
 
static void write_global (WriteData *wd, int fileflags, Main *mainvar)
 
static void write_thumb (WriteData *wd, const BlendThumbnail *thumb)
 

Macro Definition Documentation

◆ DNA_DEPRECATED_ALLOW

#define DNA_DEPRECATED_ALLOW

FILE FORMAT

IFF-style structure (but not IFF compatible!)

Start file:

`BLENDER_V100`  `12` bytes  (version 1.00 is just an example).
                `V` = big endian, `v` = little endian.
                `_` = 4 byte pointer, `-` = 8 byte pointer.

data-blocks: (also see struct BHead).

`bh.code`       `char[4]` see `BLO_blend_defs.h` for a list of known types.
`bh.len`        `int32` length data after BHead in bytes.
`bh.old`        `void *` old pointer (the address at the time of writing the file).
`bh.SDNAnr`     `int32` struct index of structs stored in DNA1 data.
`bh.nr`         `int32` in case of array: number of structs.
data
...
...

Almost all data in Blender are structures. Each struct saved gets a BHead header. With BHead the struct can be linked again and compared with #StructDNA.

WRITE

Preferred writing order: (not really a must, but why would you do it random?) Any case: direct data is ALWAYS after the lib block.

(Local file data)

  • for each LibBlock
    • write LibBlock
    • write associated direct data (External file data)
  • per library
    • write library block
    • per LibBlock
      • write the ID of LibBlock
  • write TEST (RenderInfo struct. 128x128 blend file preview is optional).
  • write GLOB (FileGlobal struct) (some global vars).
  • write DNA1 (SDNA struct)
  • write USER (UserDef struct) if filename is ~/.config/blender/X.XX/config/startup.blend.

Definition at line 94 of file writefile.c.

◆ FILE_HANDLE [1/2]

#define FILE_HANDLE (   ww)    (ww)->_user_data.file_handle

Definition at line 196 of file writefile.c.

◆ FILE_HANDLE [2/2]

#define FILE_HANDLE (   ww)    (ww)->_user_data.gz_handle

Definition at line 196 of file writefile.c.

◆ ID_BUFFER_STATIC_SIZE

#define ID_BUFFER_STATIC_SIZE   8192

◆ MYWRITE_BUFFER_SIZE

#define MYWRITE_BUFFER_SIZE   (MEM_SIZE_OPTIMAL(1 << 17)) /* 128kb */

Definition at line 137 of file writefile.c.

◆ MYWRITE_MAX_CHUNK

#define MYWRITE_MAX_CHUNK   (MEM_SIZE_OPTIMAL(1 << 15)) /* ~32kb */

Definition at line 138 of file writefile.c.

◆ U

#define U   (*((const UserDef *)&U))

Definition at line 132 of file writefile.c.

◆ writelist

#define writelist (   wd,
  filecode,
  struct_id,
  lb 
)     writelist_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), lb)

Definition at line 598 of file writefile.c.

◆ writestruct

#define writestruct (   wd,
  filecode,
  struct_id,
  nr,
  adr 
)     writestruct_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), nr, adr)

Definition at line 595 of file writefile.c.

◆ writestruct_at_address

#define writestruct_at_address (   wd,
  filecode,
  struct_id,
  nr,
  adr,
  data 
)     writestruct_at_address_nr(wd, filecode, SDNA_TYPE_FROM_STRUCT(struct_id), nr, adr, data)

Definition at line 592 of file writefile.c.

Typedef Documentation

◆ BlendWriter

typedef struct BlendWriter BlendWriter

◆ RenderInfo

typedef struct RenderInfo RenderInfo

◆ WriteWrap

typedef struct WriteWrap WriteWrap

Definition at line 1 of file writefile.c.

Enumeration Type Documentation

◆ eWriteWrapType

Enumerator
WW_WRAP_NONE 
WW_WRAP_ZLIB 

Definition at line 147 of file writefile.c.

Function Documentation

◆ BLO_get_struct_id_by_name()

int BLO_get_struct_id_by_name ( BlendWriter writer,
const char *  struct_name 
)

◆ BLO_write_double_array()

void BLO_write_double_array ( BlendWriter writer,
uint  num,
const double data_ptr 
)

Definition at line 1383 of file writefile.c.

References BLO_write_raw().

◆ BLO_write_file()

bool BLO_write_file ( Main mainvar,
const char *  filepath,
const int  write_flags,
const struct BlendFileWriteParams params,
ReportList reports 
)

◆ BLO_write_file_mem()

bool BLO_write_file_mem ( Main mainvar,
MemFile compare,
MemFile current,
int  write_flags 
)
Returns
Success.

Definition at line 1276 of file writefile.c.

References err, NULL, and write_file_handle().

Referenced by BKE_memfile_undo_encode().

◆ BLO_write_float3_array()

void BLO_write_float3_array ( BlendWriter writer,
uint  num,
const float data_ptr 
)

Definition at line 1393 of file writefile.c.

References BLO_write_raw().

Referenced by blendWrite(), and write_mdisps().

◆ BLO_write_float_array()

void BLO_write_float_array ( BlendWriter writer,
uint  num,
const float data_ptr 
)

◆ blo_write_id_struct()

void blo_write_id_struct ( BlendWriter writer,
int  struct_id,
const void *  id_address,
const ID id 
)

Definition at line 1357 of file writefile.c.

References GS, id, ID::name, BlendWriter::wd, and writestruct_at_address_nr().

◆ BLO_write_int32_array()

void BLO_write_int32_array ( BlendWriter writer,
uint  num,
const int32_t data_ptr 
)

Definition at line 1368 of file writefile.c.

References BLO_write_raw().

Referenced by blendWrite().

◆ BLO_write_is_undo()

bool BLO_write_is_undo ( BlendWriter writer)

◆ BLO_write_pointer_array()

void BLO_write_pointer_array ( BlendWriter writer,
uint  num,
const void *  data_ptr 
)

◆ BLO_write_raw()

void BLO_write_raw ( BlendWriter writer,
size_t  size_in_bytes,
const void *  data_ptr 
)

◆ BLO_write_string()

void BLO_write_string ( BlendWriter writer,
const char *  data_ptr 
)

◆ BLO_write_struct_array_at_address_by_id()

void BLO_write_struct_array_at_address_by_id ( BlendWriter writer,
int  struct_id,
int  array_size,
const void *  address,
const void *  data_ptr 
)

Definition at line 1336 of file writefile.c.

References DATA, BlendWriter::wd, and writestruct_at_address_nr().

◆ BLO_write_struct_array_by_id()

void BLO_write_struct_array_by_id ( BlendWriter writer,
int  struct_id,
int  array_size,
const void *  data_ptr 
)

Definition at line 1328 of file writefile.c.

References DATA, BlendWriter::wd, and writestruct_nr().

Referenced by BLO_write_struct_array_by_name().

◆ BLO_write_struct_array_by_name()

void BLO_write_struct_array_by_name ( BlendWriter writer,
const char *  struct_name,
int  array_size,
const void *  data_ptr 
)

◆ BLO_write_struct_at_address_by_id()

void BLO_write_struct_at_address_by_id ( BlendWriter writer,
int  struct_id,
const void *  address,
const void *  data_ptr 
)

Definition at line 1314 of file writefile.c.

References BLO_write_struct_at_address_by_id_with_filecode(), and DATA.

◆ BLO_write_struct_at_address_by_id_with_filecode()

void BLO_write_struct_at_address_by_id_with_filecode ( BlendWriter writer,
int  filecode,
int  struct_id,
const void *  address,
const void *  data_ptr 
)

Definition at line 1322 of file writefile.c.

References BlendWriter::wd, and writestruct_at_address_nr().

Referenced by BLO_write_struct_at_address_by_id().

◆ BLO_write_struct_by_id()

void BLO_write_struct_by_id ( BlendWriter writer,
int  struct_id,
const void *  data_ptr 
)

◆ BLO_write_struct_by_name()

void BLO_write_struct_by_name ( BlendWriter writer,
const char *  struct_name,
const void *  data_ptr 
)

◆ BLO_write_struct_list_by_id()

void BLO_write_struct_list_by_id ( BlendWriter writer,
int  struct_id,
ListBase list 
)

Definition at line 1342 of file writefile.c.

References DATA, BlendWriter::wd, and writelist_nr().

Referenced by BLO_write_struct_list_by_name().

◆ BLO_write_struct_list_by_name()

void BLO_write_struct_list_by_name ( BlendWriter writer,
const char *  struct_name,
ListBase list 
)

◆ BLO_write_uint32_array()

void BLO_write_uint32_array ( BlendWriter writer,
uint  num,
const uint32_t data_ptr 
)

Definition at line 1373 of file writefile.c.

References BLO_write_raw().

Referenced by BKE_previewimg_blend_write(), and blendWrite().

◆ current_screen_compat()

static void current_screen_compat ( Main mainvar,
bool  use_active_win,
bScreen **  r_screen,
Scene **  r_scene,
ViewLayer **  r_view_layer 
)
static

Take care using 'use_active_win', since we wont want the currently active window to change which scene renders (currently only used for undo).

Definition at line 613 of file writefile.c.

References wmWindow::active, BKE_view_layer_find(), BKE_workspace_active_screen_get(), ListBase::first, wmWindow::next, NULL, wmWindow::scene, wmWindow::view_layer_name, wmWindowManager::windows, Main::wm, and wmWindow::workspace_hook.

Referenced by write_global(), and write_renderinfo().

◆ do_history()

static bool do_history ( const char *  name,
ReportList reports 
)
static

◆ mywrite()

static void mywrite ( WriteData wd,
const void *  adr,
size_t  len 
)
static

Low level WRITE(2) wrapper that buffers data

Parameters
adrPointer to new chunk of data
lenLength of new chunk of data

Definition at line 356 of file writefile.c.

References BLI_assert, WriteData::buf, WriteData::buf_used_len, WriteData::error, len, MIN2, MYWRITE_BUFFER_SIZE, MYWRITE_MAX_CHUNK, NULL, UNLIKELY, and writedata_do_write().

Referenced by write_file_handle(), writedata(), and writestruct_at_address_nr().

◆ mywrite_begin()

static WriteData* mywrite_begin ( WriteWrap ww,
MemFile compare,
MemFile current 
)
static

BeGiN initializer for mywrite

Parameters
wwFile write wrapper.
comparePrevious memory file (can be NULL).
currentThe current memory file (can be NULL).
Warning
Talks to other functions with global parameters

Definition at line 412 of file writefile.c.

References BLO_memfile_write_init(), WriteData::mem, NULL, WriteData::use_memfile, and writedata_new().

Referenced by write_file_handle().

◆ mywrite_end()

static bool mywrite_end ( WriteData wd)
static

END the mywrite wrapper

Returns
1 if write failed
unknown global variable otherwise
Warning
Talks to other functions with global parameters

Definition at line 430 of file writefile.c.

References BLO_memfile_write_finalize(), WriteData::buf, WriteData::buf_used_len, err, WriteData::error, WriteData::mem, WriteData::use_memfile, writedata_do_write(), and writedata_free().

Referenced by write_file_handle().

◆ mywrite_flush()

static void mywrite_flush ( WriteData wd)
static

Flush helps the de-duplicating memory for undo-save by logically segmenting data, so differences in one part of memory won't cause unrelated data to be duplicated.

Definition at line 343 of file writefile.c.

References WriteData::buf, WriteData::buf_used_len, and writedata_do_write().

Referenced by mywrite_id_end(), write_file_handle(), and write_libraries().

◆ mywrite_id_begin()

static void mywrite_id_begin ( WriteData wd,
ID id 
)
static

◆ mywrite_id_end()

static void mywrite_id_end ( WriteData wd,
ID UNUSEDid 
)
static

Start writing of data related to a single ID.

Only does something when storing an undo step.

Definition at line 482 of file writefile.c.

References MemFileWriteData::current_id_session_uuid, MAIN_ID_SESSION_UUID_UNSET, WriteData::mem, mywrite_flush(), and WriteData::use_memfile.

Referenced by write_file_handle().

◆ write_file_handle()

static bool write_file_handle ( Main mainvar,
WriteWrap ww,
MemFile compare,
MemFile current,
int  write_flags,
bool  use_userdef,
const BlendThumbnail thumb 
)
static

◆ write_global()

static void write_global ( WriteData wd,
int  fileflags,
Main mainvar 
)
static

◆ write_keymapitem()

static void write_keymapitem ( BlendWriter writer,
const wmKeyMapItem kmi 
)
static

Definition at line 686 of file writefile.c.

References BLO_write_struct, IDP_BlendWrite(), and wmKeyMapItem::properties.

Referenced by write_userdef().

◆ write_libraries()

static void write_libraries ( WriteData wd,
Main main 
)
static

◆ write_renderinfo()

static void write_renderinfo ( WriteData wd,
Main mainvar 
)
static

This was originally added for the historic render-daemon feature, now write because it can be easily extracted without reading the whole blend file.

See: release/scripts/modules/blend_render_info.py

Definition at line 663 of file writefile.c.

References BLI_strncpy(), current_screen_compat(), data, LISTBASE_FOREACH, NULL, R_BG_RENDER, REND, Main::scenes, and writedata().

Referenced by write_file_handle().

◆ write_thumb()

static void write_thumb ( WriteData wd,
const BlendThumbnail thumb 
)
static

◆ write_userdef()

static void write_userdef ( BlendWriter writer,
const UserDef userdef 
)
static

◆ writedata()

static void writedata ( WriteData wd,
int  filecode,
size_t  len,
const void *  adr 
)
static

◆ writedata_do_write()

static void writedata_do_write ( WriteData wd,
const void *  mem,
size_t  memlen 
)
static

◆ writedata_free()

static void writedata_free ( WriteData wd)
static

Definition at line 325 of file writefile.c.

References WriteData::buf, and MEM_freeN.

Referenced by mywrite_end().

◆ writedata_new()

static WriteData* writedata_new ( WriteWrap ww)
static

◆ writelist_nr()

static void writelist_nr ( WriteData wd,
int  filecode,
const int  struct_nr,
const ListBase lb 
)
static

Definition at line 562 of file writefile.c.

References ListBase::first, Link::next, and writestruct_nr().

Referenced by BLO_write_struct_list_by_id().

◆ writestruct_at_address_nr()

static void writestruct_at_address_nr ( WriteData wd,
int  filecode,
const int  struct_nr,
int  nr,
const void *  adr,
const void *  data 
)
static

◆ writestruct_nr()

static void writestruct_nr ( WriteData wd,
int  filecode,
const int  struct_nr,
int  nr,
const void *  adr 
)
static

◆ ww_close_none()

static bool ww_close_none ( WriteWrap ww)
static

Definition at line 185 of file writefile.c.

References FILE_HANDLE.

Referenced by ww_handle_init().

◆ ww_close_zlib()

static bool ww_close_zlib ( WriteWrap ww)
static

Definition at line 211 of file writefile.c.

References FILE_HANDLE.

Referenced by ww_handle_init().

◆ ww_handle_init()

static void ww_handle_init ( eWriteWrapType  ww_type,
WriteWrap r_ww 
)
static

◆ ww_open_none()

static bool ww_open_none ( WriteWrap ww,
const char *  filepath 
)
static

Definition at line 172 of file writefile.c.

References BLI_open(), file, FILE_HANDLE, and O_BINARY.

Referenced by ww_handle_init().

◆ ww_open_zlib()

static bool ww_open_zlib ( WriteWrap ww,
const char *  filepath 
)
static

Definition at line 198 of file writefile.c.

References BLI_gzopen(), file, and FILE_HANDLE.

Referenced by ww_handle_init().

◆ ww_write_none()

static size_t ww_write_none ( WriteWrap ww,
const char *  buf,
size_t  buf_len 
)
static

Definition at line 189 of file writefile.c.

References FILE_HANDLE.

Referenced by ww_handle_init().

◆ ww_write_zlib()

static size_t ww_write_zlib ( WriteWrap ww,
const char *  buf,
size_t  buf_len 
)
static

Definition at line 215 of file writefile.c.

References FILE_HANDLE.

Referenced by ww_handle_init().