Fix for two proxy + undo related crashes:
[blender.git] / source / blender / blenloader / intern / readblenentry.c
index 8c7fd8de05317c19ed806a50f2f483d2621b5775..e4bc6e3abb208b8e07ce0a82dee5bbbccc0ebaac 100644 (file)
@@ -1,15 +1,12 @@
 /**
  * $Id$
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -27,7 +24,7 @@
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  * .blend file reading entry point
  */
 
 #include "DNA_space_types.h"
 #include "DNA_userdef_types.h"
 #include "DNA_ID.h"
+#include "DNA_material_types.h"
 
 #include "BKE_utildefines.h" // for ENDB
 
 #include "BKE_main.h"
+#include "BKE_global.h"
 #include "BKE_library.h" // for free_main
 
 #include "BLO_readfile.h"
 #include "BLO_undofile.h"
 
 #include "readfile.h"
+#include "genfile.h"
 
 #include "BLO_readblenfile.h"
 
+#include "BLO_sys_types.h" // needed for intptr_t
+
        /**
         * IDType stuff, I plan to move this
         * out into its own file + prefix, and
@@ -81,6 +83,7 @@ typedef struct {
 static IDType idtypes[]= {
        { ID_AC,                "Action",       IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_AR,                "Armature", IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_BR,                "Brush",        IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_CA,                "Camera",       IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_CU,                "Curve",        IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_GR,                "Group",        IDTYPE_FLAGS_ISLINKABLE}, 
@@ -95,8 +98,8 @@ static IDType idtypes[]= {
        { ID_MA,                "Material", IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_MB,                "Metaball", IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_ME,                "Mesh",         IDTYPE_FLAGS_ISLINKABLE}, 
+       { ID_NT,                "NodeTree",     IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_OB,                "Object",       IDTYPE_FLAGS_ISLINKABLE}, 
-       { ID_SAMPLE,    "Sample",       0}, 
        { ID_SCE,               "Scene",        IDTYPE_FLAGS_ISLINKABLE}, 
        { ID_SCR,               "Screen",       0}, 
        { ID_SEQ,               "Sequence",     0}, 
@@ -192,7 +195,7 @@ void BLO_blendhandle_print_sizes(BlendHandle *bh, void *fp)
                        buf[2]= buf[2]?buf[2]:' ';
                        buf[3]= buf[3]?buf[3]:' ';
                        
-                       fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, bhead->len+sizeof(BHead));
+                       fprintf(fp, "['%.4s', '%s', %d, %ld ], \n", buf, name, bhead->nr, (intptr_t)bhead->len+sizeof(BHead));
                }
        }
        fprintf(fp, "]\n");
@@ -206,9 +209,9 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype)
 
        for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
                if (bhead->code==ofblocktype) {
-                       ID *id= (ID*) (bhead+1);
+                       char *idname= bhead_id_name(fd, bhead);
                        
-                       BLI_linklist_prepend(&names, strdup(id->name+2));
+                       BLI_linklist_prepend(&names, strdup(idname+2));
                } else if (bhead->code==ENDB)
                        break;
        }
@@ -216,6 +219,70 @@ LinkNode *BLO_blendhandle_get_datablock_names(BlendHandle *bh, int ofblocktype)
        return names;
 }
 
+LinkNode *BLO_blendhandle_get_previews(BlendHandle *bh, int ofblocktype) 
+{
+       FileData *fd= (FileData*) bh;
+       LinkNode *previews= NULL;
+       BHead *bhead;
+       int looking=0;
+       int npreviews = 0;
+       PreviewImage* prv = NULL;
+       PreviewImage* new_prv = NULL;
+       
+       for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
+               if (bhead->code==ofblocktype) {
+                       ID *id= (ID*) (bhead+1);
+                       if ( (GS(id->name) == ID_MA) || (GS(id->name) == ID_TE)) {
+                               new_prv = MEM_callocN(sizeof(PreviewImage), "newpreview");
+                               BLI_linklist_prepend(&previews, new_prv);
+                               looking = 1;
+                       }
+               } else if (bhead->code==DATA) {
+                       if (looking) {
+                               if (bhead->SDNAnr == dna_findstruct_nr(fd->filesdna, "PreviewImage") ) {
+                                       prv = (PreviewImage*) (bhead+1);
+                                       npreviews = 0;                          
+                                       memcpy(new_prv, prv, sizeof(PreviewImage));
+                                       if (prv->rect[0]) {
+                                               unsigned int *rect = NULL;
+                                               int rectlen = 0;
+                                               new_prv->rect[0] = MEM_callocN(new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int), "prvrect");
+                                               bhead= blo_nextbhead(fd, bhead);
+                                               rect = (unsigned int*)(bhead+1);
+                                               rectlen = new_prv->w[0]*new_prv->h[0]*sizeof(unsigned int);
+                                               memcpy(new_prv->rect[0], rect, bhead->len);                                     
+                                       } else {
+                                               new_prv->rect[0] = NULL;
+                                       }
+                                       
+                                       if (prv->rect[1]) {
+                                               unsigned int *rect = NULL;
+                                               int rectlen = 0;
+                                               new_prv->rect[1] = MEM_callocN(new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int), "prvrect");
+                                               bhead= blo_nextbhead(fd, bhead);
+                                               rect = (unsigned int*)(bhead+1);
+                                               rectlen = new_prv->w[1]*new_prv->h[1]*sizeof(unsigned int);                                     
+                                               memcpy(new_prv->rect[1], rect, bhead->len);                                                     
+                                       } else {
+                                               new_prv->rect[1] = NULL;
+                                       }
+                               }
+                       }
+               } else if (bhead->code==ENDB) {
+                       break;
+               } else if (bhead->code==DATA) {
+                       /* DATA blocks between IDBlock and Preview */
+               } else {
+                       looking = 0;
+                       new_prv = NULL;
+                       prv = NULL;
+               }
+               
+       }
+       
+       return previews;
+}
+
 LinkNode *BLO_blendhandle_get_linkable_groups(BlendHandle *bh) 
 {
        FileData *fd= (FileData*) bh;
@@ -261,7 +328,7 @@ BlendFileData *BLO_read_from_file(char *file, BlendReadError *error_r)
                bfd= blo_read_file_internal(fd, error_r);
                if (bfd) {
                        bfd->type= BLENFILETYPE_BLEND;
-                       strcpy(bfd->main->name, file);
+                       strncpy(bfd->main->name, file, sizeof(bfd->main->name)-1);
                }
                blo_freefiledata(fd);                   
        }
@@ -287,18 +354,49 @@ BlendFileData *BLO_read_from_memory(void *mem, int memsize, BlendReadError *erro
        return bfd;     
 }
 
-BlendFileData *BLO_read_from_memfile(MemFile *memfile, BlendReadError *error_r) 
+BlendFileData *BLO_read_from_memfile(const char *filename, MemFile *memfile, BlendReadError *error_r) 
 {
        BlendFileData *bfd = NULL;
        FileData *fd;
-               
+       ListBase mainlist;
+       
        fd = blo_openblendermemfile(memfile, error_r);
        if (fd) {
+               strcpy(fd->filename, filename);
+               
+               /* clear ob->proxy_from pointers in G.main */
+               blo_clear_proxy_pointers_from_lib(fd);
+
+               /* separate libraries from G.main */
+               blo_split_main(&mainlist, G.main);
+               /* add the library pointers in oldmap lookup */
+               blo_add_library_pointer_map(&mainlist, fd);
+               
+               /* 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);
+               
+               /* move libraries from G.main to new main */
+               if(bfd && mainlist.first!=mainlist.last) {
+                       
+                       /* Library structs themselves */
+                       bfd->main->library= G.main->library;
+                       G.main->library.first= G.main->library.last= NULL;
+                       
+                       /* add the Library mainlist to the new main */
+                       BLI_remlink(&mainlist, G.main);
+                       BLI_addhead(&mainlist, bfd->main);
+               }
+               blo_join_main(&mainlist);
+               
                blo_freefiledata(fd);                   
        }