diff options
-rw-r--r-- | source/blender/blenkernel/BKE_library.h | 6 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_main.h | 14 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/library.c | 73 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_blend_defs.h | 2 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_readfile.h | 10 | ||||
-rw-r--r-- | source/blender/blenloader/BLO_writefile.h | 6 | ||||
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 107 | ||||
-rw-r--r-- | source/blender/blenloader/intern/writefile.c | 19 | ||||
-rw-r--r-- | source/blender/imbuf/intern/thumbs_blend.c | 109 | ||||
-rw-r--r-- | source/blender/windowmanager/intern/wm_files.c | 56 |
10 files changed, 270 insertions, 132 deletions
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h index 6ecc955e26c..5b12858fc7d 100644 --- a/source/blender/blenkernel/BKE_library.h +++ b/source/blender/blenkernel/BKE_library.h @@ -38,8 +38,10 @@ extern "C" { #include "BLI_compiler_attrs.h" +struct BlendThumbnail; struct ListBase; struct ID; +struct ImBuf; struct Main; struct Library; struct wmWindowManager; @@ -87,6 +89,10 @@ void BKE_main_free(struct Main *mainvar); void BKE_main_lock(struct Main *bmain); void BKE_main_unlock(struct Main *bmain); +struct BlendThumbnail *BKE_main_thumbnail_from_imbuf(struct Main *bmain, struct ImBuf *img); +struct ImBuf *BKE_main_thumbnail_to_imbuf(struct Main *bmain, struct BlendThumbnail *data); +void BKE_main_thumbnail_create(struct Main *bmain); + void BKE_main_id_tag_idcode(struct Main *mainvar, const short type, const bool tag); void BKE_main_id_tag_listbase(struct ListBase *lb, const bool tag); void BKE_main_id_tag_all(struct Main *mainvar, const bool tag); diff --git a/source/blender/blenkernel/BKE_main.h b/source/blender/blenkernel/BKE_main.h index ec654ea4b71..6a00961fbb3 100644 --- a/source/blender/blenkernel/BKE_main.h +++ b/source/blender/blenkernel/BKE_main.h @@ -50,6 +50,13 @@ struct EvaluationContext; struct Library; struct MainLock; +/* Blender thumbnail, as written on file (width, height, and data as char RGBA). */ +/* We pack pixel data after that struct. */ +typedef struct BlendThumbnail { + int width, height; + char rect[0]; +} BlendThumbnail; + typedef struct Main { struct Main *next, *prev; char name[1024]; /* 1024 = FILE_MAX */ @@ -58,6 +65,8 @@ typedef struct Main { uint64_t build_commit_timestamp; /* commit's timestamp from buildinfo */ char build_hash[16]; /* hash from buildinfo */ short recovered; /* indicate the main->name (file) is the recovered one */ + + BlendThumbnail *blen_thumb; struct Library *curlib; ListBase scene; @@ -109,7 +118,10 @@ typedef struct Main { #define MAIN_VERSION_OLDER(main, ver, subver) \ ((main)->versionfile < (ver) || (main->versionfile == (ver) && (main)->subversionfile < (subver))) - +#define BLEN_THUMB_SIZE 128 + +#define BLEN_THUMB_MEMSIZE(_x, _y) (sizeof(BlendThumbnail) + (size_t)((_x) * (_y)) * sizeof(int)) + #ifdef __cplusplus } #endif diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c index 8bb2864a604..1466cdfa921 100644 --- a/source/blender/blenkernel/intern/library.c +++ b/source/blender/blenkernel/intern/library.c @@ -119,6 +119,9 @@ #include "RNA_access.h" +#include "IMB_imbuf.h" +#include "IMB_imbuf_types.h" + #ifdef WITH_PYTHON #include "BPY_extern.h" #endif @@ -1097,6 +1100,8 @@ void BKE_main_free(Main *mainvar) ListBase *lbarray[MAX_LIBARRAY]; int a; + MEM_SAFE_FREE(mainvar->blen_thumb); + a = set_listbasepointers(mainvar, lbarray); while (a--) { ListBase *lb = lbarray[a]; @@ -1166,6 +1171,74 @@ void BKE_main_unlock(struct Main *bmain) BLI_spin_unlock((SpinLock *) bmain->lock); } +/** + * Generates a raw .blend file thumbnail data from given image. + * + * \param bmain If not NULL, also store generated data in this Main. + * \param img ImBuf image to generate thumbnail data from. + * \return The generated .blend file raw thumbnail data. + */ +BlendThumbnail *BKE_main_thumbnail_from_imbuf(Main *bmain, ImBuf *img) +{ + BlendThumbnail *data = NULL; + + if (bmain) { + MEM_SAFE_FREE(bmain->blen_thumb); + } + + if (img) { + const size_t sz = BLEN_THUMB_MEMSIZE(img->x, img->y); + data = MEM_mallocN(sz, __func__); + + IMB_rect_from_float(img); /* Just in case... */ + data->width = img->x; + data->height = img->y; + memcpy(data->rect, img->rect, sz - sizeof(*data)); + } + + if (bmain) { + bmain->blen_thumb = data; + } + return data; +} + +/** + * Generates an image from raw .blend file thumbnail \a data. + * + * \param bmain Use this bmain->blen_thumb data if given \a data is NULL. + * \param data Raw .blend file thumbnail data. + * \return An ImBuf from given data, or NULL if invalid. + */ +ImBuf *BKE_main_thumbnail_to_imbuf(Main *bmain, BlendThumbnail *data) +{ + ImBuf *img = NULL; + + if (!data && bmain) { + data = bmain->blen_thumb; + } + + if (data) { + /* Note: we cannot use IMB_allocFromBuffer(), since it tries to dupalloc passed buffer, which will fail + * here (we do not want to pass the first two ints!). */ + img = IMB_allocImBuf((unsigned int)data->width, (unsigned int)data->height, 32, IB_rect | IB_metadata); + memcpy(img->rect, data->rect, BLEN_THUMB_MEMSIZE(data->width, data->height) - sizeof(*data)); + } + + return img; +} + +/** + * Generates an empty (black) thumbnail for given Main. + */ +void BKE_main_thumbnail_create(struct Main *bmain) +{ + MEM_SAFE_FREE(bmain->blen_thumb); + + bmain->blen_thumb = MEM_callocN(BLEN_THUMB_MEMSIZE(BLEN_THUMB_SIZE, BLEN_THUMB_SIZE), __func__); + bmain->blen_thumb->width = BLEN_THUMB_SIZE; + bmain->blen_thumb->height = BLEN_THUMB_SIZE; +} + /* ***************** ID ************************ */ ID *BKE_libblock_find_name_ex(struct Main *bmain, const short type, const char *name) { diff --git a/source/blender/blenloader/BLO_blend_defs.h b/source/blender/blenloader/BLO_blend_defs.h index 44f0fa9aa53..a6b06a080cc 100644 --- a/source/blender/blenloader/BLO_blend_defs.h +++ b/source/blender/blenloader/BLO_blend_defs.h @@ -75,4 +75,6 @@ enum { ENDB = BLEND_MAKE_ID('E', 'N', 'D', 'B'), }; +#define BLEN_THUMB_MEMSIZE_FILE(_x, _y) (sizeof(int) * (size_t)(2 + (_x) * (_y))) + #endif /* __BLO_BLEND_DEFS_H__ */ diff --git a/source/blender/blenloader/BLO_readfile.h b/source/blender/blenloader/BLO_readfile.h index 5f881c0855c..77bdb99b54b 100644 --- a/source/blender/blenloader/BLO_readfile.h +++ b/source/blender/blenloader/BLO_readfile.h @@ -36,6 +36,7 @@ extern "C" { #endif +struct BlendThumbnail; struct bScreen; struct LinkNode; struct Main; @@ -278,6 +279,15 @@ void BLO_expand_main(void *fdhandle, struct Main *mainvar); void BLO_update_defaults_userpref_blend(void); void BLO_update_defaults_startup_blend(struct Main *mainvar); +/** + * Does a very light reading of given .blend file to extract its stored thumbnail. + * + * \param filepath The path of the file to extract thumbnail from. + * \return The raw thumbnail + * (MEM-allocated, as stored in file, use BKE_main_thumbnail_to_imbuf() to convert it to ImBuf image). + */ +struct BlendThumbnail *BLO_thumbnail_from_file(const char *filepath); + #ifdef __cplusplus } #endif diff --git a/source/blender/blenloader/BLO_writefile.h b/source/blender/blenloader/BLO_writefile.h index 7a8429afec0..0d66eb743aa 100644 --- a/source/blender/blenloader/BLO_writefile.h +++ b/source/blender/blenloader/BLO_writefile.h @@ -33,14 +33,14 @@ * \brief external writefile function prototypes. */ +struct BlendThumbnail; struct MemFile; struct Main; struct ReportList; -extern int BLO_write_file(struct Main *mainvar, const char *filepath, int write_flags, struct ReportList *reports, const int *thumb); +extern int BLO_write_file(struct Main *mainvar, const char *filepath, int write_flags, + struct ReportList *reports, const struct BlendThumbnail *thumb); extern int BLO_write_file_mem(struct Main *mainvar, struct MemFile *compare, struct MemFile *current, int write_flags); -#define BLEN_THUMB_SIZE 128 - #endif diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 6581fb3f3b7..ee07f2b09cf 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -917,6 +917,41 @@ static int read_file_dna(FileData *fd) return 0; } +static int *read_file_thumbnail(FileData *fd) +{ + BHead *bhead; + int *blend_thumb = NULL; + + for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) { + if (bhead->code == TEST) { + const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0; + int *data = (int *)(bhead + 1); + + if (bhead->len < (2 * sizeof(int))) { + break; + } + + if (do_endian_swap) { + BLI_endian_switch_int32(&data[0]); + BLI_endian_switch_int32(&data[1]); + } + + if (bhead->len < BLEN_THUMB_MEMSIZE_FILE(data[0], data[1])) { + break; + } + + blend_thumb = data; + break; + } + else if (bhead->code != REND) { + /* Thumbnail is stored in TEST immediately after first REND... */ + break; + } + } + + return blend_thumb; +} + static int fd_read_from_file(FileData *filedata, void *buffer, unsigned int size) { int readsize = read(filedata->filedes, buffer, size); @@ -1080,6 +1115,33 @@ FileData *blo_openblenderfile(const char *filepath, ReportList *reports) } } +/** + * Same as blo_openblenderfile(), but does not reads DNA data, only header. Use it for light access + * (e.g. thumbnail reading). + */ +static FileData *blo_openblenderfile_minimal(const char *filepath) +{ + gzFile gzfile; + errno = 0; + gzfile = BLI_gzopen(filepath, "rb"); + + if (gzfile != (gzFile)Z_NULL) { + FileData *fd = filedata_new(); + fd->gzfiledes = gzfile; + fd->read = fd_read_gzip_from_file; + + decode_blender_header(fd); + + if (fd->flags & FD_FLAGS_FILE_OK) { + return fd; + } + + blo_freefiledata(fd); + } + + return NULL; +} + static int fd_read_gzip_from_memory(FileData *filedata, void *buffer, unsigned int size) { int err; @@ -1290,6 +1352,33 @@ bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, cha return true; } +BlendThumbnail *BLO_thumbnail_from_file(const char *filepath) +{ + FileData *fd; + BlendThumbnail *data; + int *fd_data; + + fd = blo_openblenderfile_minimal(filepath); + fd_data = fd ? read_file_thumbnail(fd) : NULL; + + if (fd_data) { + const size_t sz = BLEN_THUMB_MEMSIZE(fd_data[0], fd_data[1]); + data = MEM_mallocN(sz, __func__); + + BLI_assert((sz - sizeof(*data)) == (BLEN_THUMB_MEMSIZE_FILE(fd_data[0], fd_data[1]) - (sizeof(*fd_data) * 2))); + data->width = fd_data[0]; + data->height = fd_data[1]; + memcpy(data->rect, &fd_data[2], sz - sizeof(*data)); + } + else { + data = NULL; + } + + blo_freefiledata(fd); + + return data; +} + /* ************** OLD POINTERS ******************* */ static void *newdataadr(FileData *fd, void *adr) /* only direct databocks */ @@ -8174,6 +8263,24 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) bfd->type = BLENFILETYPE_BLEND; BLI_strncpy(bfd->main->name, filepath, sizeof(bfd->main->name)); + if (G.background) { + /* We only read & store .blend thumbnail in background mode + * (because we cannot re-generate it, no OpenGL available). + */ + const int *data = read_file_thumbnail(fd); + + if (data) { + const size_t sz = BLEN_THUMB_MEMSIZE(data[0], data[1]); + bfd->main->blen_thumb = MEM_mallocN(sz, __func__); + + BLI_assert((sz - sizeof(*bfd->main->blen_thumb)) == + (BLEN_THUMB_MEMSIZE_FILE(data[0], data[1]) - (sizeof(*data) * 2))); + bfd->main->blen_thumb->width = data[0]; + bfd->main->blen_thumb->height = data[1]; + memcpy(bfd->main->blen_thumb->rect, &data[2], sz - sizeof(*bfd->main->blen_thumb)); + } + } + while (bhead) { switch (bhead->code) { case DATA: diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c index 2dfb100cc62..94f3237d919 100644 --- a/source/blender/blenloader/intern/writefile.c +++ b/source/blender/blenloader/intern/writefile.c @@ -3688,10 +3688,18 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar) * second are an RGBA image (unsigned char) * note, this uses 'TEST' since new types will segfault on file load for older blender versions. */ -static void write_thumb(WriteData *wd, const int *img) +static void write_thumb(WriteData *wd, const BlendThumbnail *thumb) { - if (img) - writedata(wd, TEST, (2 + img[0] * img[1]) * sizeof(int), img); + if (thumb) { + size_t sz = BLEN_THUMB_MEMSIZE_FILE(thumb->width, thumb->height); + int *img = alloca(sz); + + BLI_assert((sz - (sizeof(*img) * 2)) == (BLEN_THUMB_MEMSIZE(thumb->width, thumb->height) - sizeof(thumb))); + img[0] = thumb->width; + img[1] = thumb->height; + memcpy(&img[2], thumb->rect, sz - (sizeof(*img) * 2)); + writedata(wd, TEST, sz, img); + } } /* if MemFile * there's filesave to memory */ @@ -3699,7 +3707,7 @@ static int write_file_handle( Main *mainvar, WriteWrap *ww, MemFile *compare, MemFile *current, - int write_user_block, int write_flags, const int *thumb) + int write_user_block, int write_flags, const BlendThumbnail *thumb) { BHead bhead; ListBase mainlist; @@ -3831,7 +3839,8 @@ static bool do_history(const char *name, ReportList *reports) } /* return: success (1) */ -int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const int *thumb) +int BLO_write_file( + Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const BlendThumbnail *thumb) { char tempname[FILE_MAX+1]; int err, write_user_block; diff --git a/source/blender/imbuf/intern/thumbs_blend.c b/source/blender/imbuf/intern/thumbs_blend.c index 17d9f3d0735..b5c6deb6b01 100644 --- a/source/blender/imbuf/intern/thumbs_blend.c +++ b/source/blender/imbuf/intern/thumbs_blend.c @@ -28,8 +28,6 @@ #include <stdlib.h> #include <string.h> -#include "zlib.h" - #include "BLI_utildefines.h" #include "BLI_endian_switch.h" #include "BLI_fileops.h" @@ -41,6 +39,8 @@ #include "BKE_global.h" #include "BKE_idcode.h" #include "BKE_icons.h" +#include "BKE_library.h" +#include "BKE_main.h" #include "DNA_ID.h" /* For preview images... */ @@ -48,97 +48,20 @@ #include "IMB_imbuf.h" #include "IMB_thumbs.h" -/* extracts the thumbnail from between the 'REND' and the 'GLOB' - * chunks of the header, don't use typical blend loader because its too slow */ - -static ImBuf *loadblend_thumb(gzFile gzfile) -{ - char buf[12]; - int bhead[24 / sizeof(int)]; /* max size on 64bit */ - char endian, pointer_size; - char endian_switch; - int sizeof_bhead; - - /* read the blend file header */ - if (gzread(gzfile, buf, 12) != 12) - return NULL; - if (!STREQLEN(buf, "BLENDER", 7)) - return NULL; - - if (buf[7] == '-') - pointer_size = 8; - else if (buf[7] == '_') - pointer_size = 4; - else - return NULL; - - sizeof_bhead = 16 + pointer_size; - - if (buf[8] == 'V') - endian = B_ENDIAN; /* big: PPC */ - else if (buf[8] == 'v') - endian = L_ENDIAN; /* little: x86 */ - else - return NULL; - - endian_switch = ((ENDIAN_ORDER != endian)) ? 1 : 0; - - while (gzread(gzfile, bhead, sizeof_bhead) == sizeof_bhead) { - if (endian_switch) - BLI_endian_switch_int32(&bhead[1]); /* length */ - - if (bhead[0] == REND) { - gzseek(gzfile, bhead[1], SEEK_CUR); /* skip to the next */ - } - else { - break; - } - } - - /* using 'TEST' since new names segfault when loading in old blenders */ - if (bhead[0] == TEST) { - ImBuf *img = NULL; - int size[2]; - - if (gzread(gzfile, size, sizeof(size)) != sizeof(size)) - return NULL; - - if (endian_switch) { - BLI_endian_switch_int32(&size[0]); - BLI_endian_switch_int32(&size[1]); - } - /* length */ - bhead[1] -= sizeof(int) * 2; - - /* inconsistent image size, quit early */ - if (bhead[1] != size[0] * size[1] * sizeof(int)) - return NULL; - - /* finally malloc and read the data */ - img = IMB_allocImBuf(size[0], size[1], 32, IB_rect | IB_metadata); - - if (gzread(gzfile, img->rect, bhead[1]) != bhead[1]) { - IMB_freeImBuf(img); - img = NULL; - } - - return img; - } - - return NULL; -} +#include "MEM_guardedalloc.h" ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const char *blen_id) { + ImBuf *ima = NULL; + if (blen_group && blen_id) { LinkNode *ln, *names, *lp, *previews = NULL; struct BlendHandle *libfiledata = BLO_blendhandle_from_file(blen_path, NULL); - ImBuf *ima = NULL; int idcode = BKE_idcode_from_name(blen_group); int i, nprevs, nnames; if (libfiledata == NULL) { - return NULL; + return ima; } /* Note: we should handle all previews for a same group at once, would avoid reopening .blend file @@ -180,25 +103,19 @@ ImBuf *IMB_thumb_load_blend(const char *blen_path, const char *blen_group, const BLI_linklist_free(previews, BKE_previewimg_freefunc); BLI_linklist_free(names, free); - return ima; } else { - gzFile gzfile; - /* not necessarily a gzip */ - gzfile = BLI_gzopen(blen_path, "rb"); + BlendThumbnail *data; - if (NULL == gzfile) { - return NULL; - } - else { - ImBuf *img = loadblend_thumb(gzfile); - - /* read ok! */ - gzclose(gzfile); + data = BLO_thumbnail_from_file(blen_path); + ima = BKE_main_thumbnail_to_imbuf(NULL, data); - return img; + if (data) { + MEM_freeN(data); } } + + return ima; } /* add a fake passepartout overlay to a byte buffer, use for blend file thumbnails */ diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c index a4f69b24351..6927e2dbc14 100644 --- a/source/blender/windowmanager/intern/wm_files.c +++ b/source/blender/windowmanager/intern/wm_files.c @@ -76,6 +76,7 @@ #include "BKE_context.h" #include "BKE_depsgraph.h" #include "BKE_global.h" +#include "BKE_library.h" #include "BKE_main.h" #include "BKE_packedFile.h" #include "BKE_report.h" @@ -864,11 +865,11 @@ static void wm_history_file_update(void) /* screen can be NULL */ -static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) +static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, BlendThumbnail **thumb_pt) { /* will be scaled down, but gives some nice oversampling */ ImBuf *ibuf; - int *thumb; + BlendThumbnail *thumb; char err_out[256] = "unknown"; /* screen if no camera found */ @@ -876,7 +877,11 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) ARegion *ar = NULL; View3D *v3d = NULL; - *thumb_pt = NULL; + /* In case we are given a valid thumbnail data, just generate image from it. */ + if (*thumb_pt) { + thumb = *thumb_pt; + return BKE_main_thumbnail_to_imbuf(NULL, thumb); + } /* scene can be NULL if running a script at startup and calling the save operator */ if (G.background || scene == NULL) @@ -914,13 +919,7 @@ static ImBuf *blend_file_thumb(Scene *scene, bScreen *screen, int **thumb_pt) /* add pretty overlay */ IMB_thumb_overlay_blend(ibuf->rect, ibuf->x, ibuf->y, aspect); - /* first write into thumb buffer */ - thumb = MEM_mallocN(((2 + (BLEN_THUMB_SIZE * BLEN_THUMB_SIZE))) * sizeof(int), "write_file thumb"); - - thumb[0] = BLEN_THUMB_SIZE; - thumb[1] = BLEN_THUMB_SIZE; - - memcpy(thumb + 2, ibuf->rect, BLEN_THUMB_SIZE * BLEN_THUMB_SIZE * sizeof(int)); + thumb = BKE_main_thumbnail_from_imbuf(NULL, ibuf); } else { /* '*thumb_pt' needs to stay NULL to prevent a bad thumbnail from being handled */ @@ -959,25 +958,26 @@ int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList * { Library *li; int len; - int *thumb = NULL; + int ret = -1; + BlendThumbnail *thumb, *main_thumb; ImBuf *ibuf_thumb = NULL; len = strlen(filepath); if (len == 0) { BKE_report(reports, RPT_ERROR, "Path is empty, cannot save"); - return -1; + return ret; } if (len >= FILE_MAX) { BKE_report(reports, RPT_ERROR, "Path too long, cannot save"); - return -1; + return ret; } /* Check if file write permission is ok */ if (BLI_exists(filepath) && !BLI_file_is_writable(filepath)) { BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath); - return -1; + return ret; } /* note: used to replace the file extension (to ensure '.blend'), @@ -988,18 +988,21 @@ int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList * for (li = G.main->library.first; li; li = li->id.next) { if (BLI_path_cmp(li->filepath, filepath) == 0) { BKE_reportf(reports, RPT_ERROR, "Cannot overwrite used library '%.240s'", filepath); - return -1; + return ret; } } + /* Call pre-save callbacks befores writing preview, that way you can generate custom file thumbnail... */ + BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); + /* blend file thumbnail */ /* save before exit_editmode, otherwise derivedmeshes for shared data corrupt #27765) */ + /* Main now can store a .blend thumbnail, usefull for background mode or thumbnail customization. */ + main_thumb = thumb = CTX_data_main(C)->blen_thumb; if ((U.flag & USER_SAVE_PREVIEWS) && BLI_thread_is_main()) { ibuf_thumb = blend_file_thumb(CTX_data_scene(C), CTX_wm_screen(C), &thumb); } - BLI_callback_exec(G.main, NULL, BLI_CB_EVT_SAVE_PRE); - /* operator now handles overwrite checks */ if (G.fileflags & G_AUTOPACK) { @@ -1044,22 +1047,21 @@ int wm_file_write(bContext *C, const char *filepath, int fileflags, ReportList * if (ibuf_thumb) { IMB_thumb_delete(filepath, THB_FAIL); /* without this a failed thumb overrides */ ibuf_thumb = IMB_thumb_create(filepath, THB_LARGE, THB_SOURCE_BLEND, ibuf_thumb); - IMB_freeImBuf(ibuf_thumb); } - if (thumb) MEM_freeN(thumb); + ret = 0; /* Success. */ } - else { - if (ibuf_thumb) IMB_freeImBuf(ibuf_thumb); - if (thumb) MEM_freeN(thumb); - - WM_cursor_wait(0); - return -1; + + if (ibuf_thumb) { + IMB_freeImBuf(ibuf_thumb); + } + if (thumb && thumb != main_thumb) { + MEM_freeN(thumb); } WM_cursor_wait(0); - - return 0; + + return ret; } /** |