Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenloader/intern/readblenentry.c9
-rw-r--r--source/blender/blenloader/intern/readfile.c60
-rw-r--r--source/blender/blenloader/intern/readfile.h5
-rw-r--r--source/blender/src/drawmesh.c2
4 files changed, 69 insertions, 7 deletions
diff --git a/source/blender/blenloader/intern/readblenentry.c b/source/blender/blenloader/intern/readblenentry.c
index 4e3c674c2f5..17549485025 100644
--- a/source/blender/blenloader/intern/readblenentry.c
+++ b/source/blender/blenloader/intern/readblenentry.c
@@ -289,6 +289,7 @@ BlendFileData *BLO_read_from_memory(void *mem, int memsize, BlendReadError *erro
return bfd;
}
+
BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, BlendReadError *error_r)
{
BlendFileData *bfd = NULL;
@@ -297,11 +298,19 @@ BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, Ble
fd = blo_openblendermemfile(memfile, error_r);
if (fd) {
strcpy(fd->filename, filename);
+
+ /* makes lookup of existing images in G.main */
+ blo_make_image_pointer_map(fd);
+
bfd= blo_read_file_internal(fd, error_r);
if (bfd) {
bfd->type= BLENFILETYPE_BLEND;
strcpy(bfd->main->name, "");
}
+
+ /* ensures relinked images are not freed */
+ blo_end_image_pointer_map(fd);
+
blo_freefiledata(fd);
}
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 594bfba0e92..969a0c71ebb 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -983,6 +983,8 @@ void blo_freefiledata(FileData *fd)
oldnewmap_free(fd->datamap);
if (fd->globmap)
oldnewmap_free(fd->globmap);
+ if (fd->imamap)
+ oldnewmap_free(fd->imamap);
if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
oldnewmap_free(fd->libmap);
@@ -1009,6 +1011,14 @@ static void *newglobadr(FileData *fd, void *adr) /* direct datablocks with glob
return oldnewmap_lookup_and_inc(fd->globmap, adr);
}
+static void *newimaadr(FileData *fd, void *adr) /* used to restore image data after undo */
+{
+ if(fd->imamap && adr)
+ return oldnewmap_lookup_and_inc(fd->imamap, adr);
+ return NULL;
+}
+
+
static void *newlibadr(FileData *fd, void *lib, void *adr) /* only lib data */
{
return oldnewmap_liblookup(fd->libmap, adr, lib);
@@ -1056,6 +1066,42 @@ static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, voi
}
}
+/* assumed; G.main still exists */
+void blo_make_image_pointer_map(FileData *fd)
+{
+ Image *ima= G.main->image.first;
+
+ fd->imamap= oldnewmap_new();
+
+ for(;ima; ima= ima->id.next) {
+ if(ima->ibuf)
+ oldnewmap_insert(fd->imamap, ima->ibuf, ima->ibuf, 0);
+ }
+}
+
+/* set G.main image ibufs to zero if it has been restored */
+void blo_end_image_pointer_map(FileData *fd)
+{
+ OldNew *entry= fd->imamap->entries;
+ Image *ima= G.main->image.first;
+ int i;
+
+ /* used entries were restored, so we put them to zero */
+ for (i=0; i<fd->imamap->nentries; i++, entry++) {
+ if (entry->nr>0)
+ entry->newp= NULL;
+ }
+
+ for(;ima; ima= ima->id.next) {
+ if(ima->ibuf) {
+ ima->ibuf= newimaadr(fd, ima->ibuf);
+ /* this mirrors direct_link_image */
+ if(ima->ibuf==NULL)
+ ima->bindcode= 0;
+ }
+ }
+}
+
/* ********** END OLD POINTERS ****************** */
/* ********** READ FILE ****************** */
@@ -1977,12 +2023,16 @@ static void lib_link_image(FileData *fd, Main *main)
static void direct_link_image(FileData *fd, Image *ima)
{
- ima->ibuf= NULL;
- ima->anim= NULL;
+ /* for undo system, pointers could be restored */
+ ima->ibuf= newimaadr(fd, ima->ibuf);
+ /* if restored, we keep the binded opengl index */
+ if(ima->ibuf==NULL)
+ ima->bindcode= 0;
+
memset(ima->mipmap, 0, sizeof(ima->mipmap));
- ima->repbind= 0;
- ima->bindcode= 0;
-
+ ima->anim= NULL;
+ ima->repbind= NULL;
+
ima->packedfile = direct_link_packedfile(fd, ima->packedfile);
ima->preview = direct_link_preview_image(fd, ima->preview);
ima->ok= 1;
diff --git a/source/blender/blenloader/intern/readfile.h b/source/blender/blenloader/intern/readfile.h
index efdfa9f76bf..a0f42769762 100644
--- a/source/blender/blenloader/intern/readfile.h
+++ b/source/blender/blenloader/intern/readfile.h
@@ -73,6 +73,7 @@ typedef struct FileData {
struct OldNewMap *datamap;
struct OldNewMap *globmap;
struct OldNewMap *libmap;
+ struct OldNewMap *imamap;
ListBase mainlist;
@@ -108,8 +109,10 @@ FileData *blo_openblenderfile( char *name, BlendReadError *error_r);
FileData *blo_openblendermemory( void *buffer, int buffersize, BlendReadError *error_r);
FileData *blo_openblendermemfile(struct MemFile *memfile, BlendReadError *error_r);
-void blo_freefiledata( FileData *fd);
+void blo_make_image_pointer_map(FileData *fd);
+void blo_end_image_pointer_map(FileData *fd);
+void blo_freefiledata( FileData *fd);
BHead *blo_firstbhead(FileData *fd);
BHead *blo_nextbhead(FileData *fd, BHead *thisblock);
diff --git a/source/blender/src/drawmesh.c b/source/blender/src/drawmesh.c
index 83ffa6f44d8..727a6ae744e 100644
--- a/source/blender/src/drawmesh.c
+++ b/source/blender/src/drawmesh.c
@@ -474,7 +474,7 @@ void free_realtime_image(Image *ima)
glDeleteTextures(ima->totbind, (GLuint *)ima->repbind);
MEM_freeN(ima->repbind);
- ima->repbind= 0;
+ ima->repbind= NULL;
}
}