Cleanup in BLO API: rename 'append' funcs to 'link', since none do append, but only...
[blender.git] / source / blender / blenloader / intern / readfile.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation
23  *
24  * ***** END GPL LICENSE BLOCK *****
25  *
26  */
27
28 /** \file blender/blenloader/intern/readfile.c
29  *  \ingroup blenloader
30  */
31
32
33 #include "zlib.h"
34
35 #include <limits.h>
36 #include <stdio.h> // for printf fopen fwrite fclose sprintf FILE
37 #include <stdlib.h> // for getenv atoi
38 #include <stddef.h> // for offsetof
39 #include <fcntl.h> // for open
40 #include <string.h> // for strrchr strncmp strstr
41 #include <math.h> // for fabs
42 #include <stdarg.h> /* for va_start/end */
43 #include <time.h> /* for gmtime */
44
45 #include "BLI_utildefines.h"
46 #ifndef WIN32
47 #  include <unistd.h> // for read close
48 #else
49 #  include <io.h> // for open close read
50 #  include "winsock2.h"
51 #  include "BLI_winstuff.h"
52 #endif
53
54 /* allow readfile to use deprecated functionality */
55 #define DNA_DEPRECATED_ALLOW
56
57 #include "DNA_anim_types.h"
58 #include "DNA_armature_types.h"
59 #include "DNA_actuator_types.h"
60 #include "DNA_brush_types.h"
61 #include "DNA_camera_types.h"
62 #include "DNA_cloth_types.h"
63 #include "DNA_controller_types.h"
64 #include "DNA_constraint_types.h"
65 #include "DNA_dynamicpaint_types.h"
66 #include "DNA_effect_types.h"
67 #include "DNA_fileglobal_types.h"
68 #include "DNA_genfile.h"
69 #include "DNA_group_types.h"
70 #include "DNA_gpencil_types.h"
71 #include "DNA_ipo_types.h"
72 #include "DNA_key_types.h"
73 #include "DNA_lattice_types.h"
74 #include "DNA_lamp_types.h"
75 #include "DNA_linestyle_types.h"
76 #include "DNA_meta_types.h"
77 #include "DNA_material_types.h"
78 #include "DNA_mesh_types.h"
79 #include "DNA_meshdata_types.h"
80 #include "DNA_nla_types.h"
81 #include "DNA_node_types.h"
82 #include "DNA_object_fluidsim.h" // NT
83 #include "DNA_object_types.h"
84 #include "DNA_packedFile_types.h"
85 #include "DNA_particle_types.h"
86 #include "DNA_property_types.h"
87 #include "DNA_rigidbody_types.h"
88 #include "DNA_text_types.h"
89 #include "DNA_view3d_types.h"
90 #include "DNA_screen_types.h"
91 #include "DNA_sensor_types.h"
92 #include "DNA_sdna_types.h"
93 #include "DNA_scene_types.h"
94 #include "DNA_sequence_types.h"
95 #include "DNA_smoke_types.h"
96 #include "DNA_speaker_types.h"
97 #include "DNA_sound_types.h"
98 #include "DNA_space_types.h"
99 #include "DNA_vfont_types.h"
100 #include "DNA_world_types.h"
101 #include "DNA_movieclip_types.h"
102 #include "DNA_mask_types.h"
103
104 #include "MEM_guardedalloc.h"
105
106 #include "BLI_endian_switch.h"
107 #include "BLI_blenlib.h"
108 #include "BLI_math.h"
109 #include "BLI_threads.h"
110 #include "BLI_mempool.h"
111
112 #include "BLT_translation.h"
113
114 #include "BKE_action.h"
115 #include "BKE_armature.h"
116 #include "BKE_brush.h"
117 #include "BKE_cloth.h"
118 #include "BKE_constraint.h"
119 #include "BKE_context.h"
120 #include "BKE_curve.h"
121 #include "BKE_depsgraph.h"
122 #include "BKE_effect.h"
123 #include "BKE_fcurve.h"
124 #include "BKE_global.h" // for G
125 #include "BKE_group.h"
126 #include "BKE_library.h" // for which_libbase
127 #include "BKE_library_query.h"
128 #include "BKE_idcode.h"
129 #include "BKE_material.h"
130 #include "BKE_main.h" // for Main
131 #include "BKE_mesh.h" // for ME_ defines (patching)
132 #include "BKE_modifier.h"
133 #include "BKE_multires.h"
134 #include "BKE_node.h" // for tree type defines
135 #include "BKE_object.h"
136 #include "BKE_paint.h"
137 #include "BKE_particle.h"
138 #include "BKE_pointcache.h"
139 #include "BKE_report.h"
140 #include "BKE_sca.h" // for init_actuator
141 #include "BKE_scene.h"
142 #include "BKE_screen.h"
143 #include "BKE_sequencer.h"
144 #include "BKE_outliner_treehash.h"
145 #include "BKE_sound.h"
146
147
148 #include "NOD_common.h"
149 #include "NOD_socket.h"
150
151 #include "BLO_readfile.h"
152 #include "BLO_undofile.h"
153 #include "BLO_blend_defs.h"
154
155 #include "RE_engine.h"
156
157 #include "readfile.h"
158
159
160 #include <errno.h>
161
162 /*
163  * Remark: still a weak point is the newaddress() function, that doesnt solve reading from
164  * multiple files at the same time
165  *
166  * (added remark: oh, i thought that was solved? will look at that... (ton)
167  *
168  * READ
169  * - Existing Library (Main) push or free
170  * - allocate new Main
171  * - load file
172  * - read SDNA
173  * - for each LibBlock
174  *     - read LibBlock
175  *     - if a Library
176  *         - make a new Main
177  *         - attach ID's to it
178  *     - else
179  *         - read associated 'direct data'
180  *         - link direct data (internal and to LibBlock)
181  * - read FileGlobal
182  * - read USER data, only when indicated (file is ~/X.XX/startup.blend)
183  * - free file
184  * - per Library (per Main)
185  *     - read file
186  *     - read SDNA
187  *     - find LibBlocks and attach IDs to Main
188  *         - if external LibBlock
189  *             - search all Main's
190  *                 - or it's already read,
191  *                 - or not read yet
192  *                 - or make new Main
193  *     - per LibBlock
194  *         - read recursive
195  *         - read associated direct data
196  *         - link direct data (internal and to LibBlock)
197  *     - free file
198  * - per Library with unread LibBlocks
199  *     - read file
200  *     - read SDNA
201  *     - per LibBlock
202  *                - read recursive
203  *                - read associated direct data
204  *                - link direct data (internal and to LibBlock)
205  *         - free file
206  * - join all Mains
207  * - link all LibBlocks and indirect pointers to libblocks
208  * - initialize FileGlobal and copy pointers to Global
209  */
210
211 /* use GHash for BHead name-based lookups (speeds up linking) */
212 #define USE_GHASH_BHEAD
213
214 /***/
215
216 typedef struct OldNew {
217         void *old, *newp;
218         int nr;
219 } OldNew;
220
221 typedef struct OldNewMap {
222         OldNew *entries;
223         int nentries, entriessize;
224         int sorted;
225         int lasthit;
226 } OldNewMap;
227
228
229 /* local prototypes */
230 static void *read_struct(FileData *fd, BHead *bh, const char *blockname);
231 static void direct_link_modifiers(FileData *fd, ListBase *lb);
232 static void convert_tface_mt(FileData *fd, Main *main);
233 static BHead *find_bhead_from_code_name(FileData *fd, const short idcode, const char *name);
234 static BHead *find_bhead_from_idname(FileData *fd, const char *idname);
235
236 /* this function ensures that reports are printed,
237  * in the case of libraray linking errors this is important!
238  *
239  * bit kludge but better then doubling up on prints,
240  * we could alternatively have a versions of a report function which forces printing - campbell
241  */
242
243 void blo_reportf_wrap(ReportList *reports, ReportType type, const char *format, ...)
244 {
245         char fixed_buf[1024]; /* should be long enough */
246         
247         va_list args;
248         
249         va_start(args, format);
250         vsnprintf(fixed_buf, sizeof(fixed_buf), format, args);
251         va_end(args);
252         
253         fixed_buf[sizeof(fixed_buf) - 1] = '\0';
254         
255         BKE_report(reports, type, fixed_buf);
256         
257         if (G.background == 0) {
258                 printf("%s\n", fixed_buf);
259         }
260 }
261
262 /* for reporting linking messages */
263 static const char *library_parent_filepath(Library *lib)
264 {
265         return lib->parent ? lib->parent->filepath : "<direct>";
266 }
267
268 static OldNewMap *oldnewmap_new(void) 
269 {
270         OldNewMap *onm= MEM_callocN(sizeof(*onm), "OldNewMap");
271         
272         onm->entriessize = 1024;
273         onm->entries = MEM_mallocN(sizeof(*onm->entries)*onm->entriessize, "OldNewMap.entries");
274         
275         return onm;
276 }
277
278 static int verg_oldnewmap(const void *v1, const void *v2)
279 {
280         const struct OldNew *x1=v1, *x2=v2;
281         
282         if (x1->old > x2->old) return 1;
283         else if (x1->old < x2->old) return -1;
284         return 0;
285 }
286
287
288 static void oldnewmap_sort(FileData *fd) 
289 {
290         qsort(fd->libmap->entries, fd->libmap->nentries, sizeof(OldNew), verg_oldnewmap);
291         fd->libmap->sorted = 1;
292 }
293
294 /* nr is zero for data, and ID code for libdata */
295 static void oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr) 
296 {
297         OldNew *entry;
298         
299         if (oldaddr==NULL || newaddr==NULL) return;
300         
301         if (UNLIKELY(onm->nentries == onm->entriessize)) {
302                 onm->entriessize *= 2;
303                 onm->entries = MEM_reallocN(onm->entries, sizeof(*onm->entries) * onm->entriessize);
304         }
305
306         entry = &onm->entries[onm->nentries++];
307         entry->old = oldaddr;
308         entry->newp = newaddr;
309         entry->nr = nr;
310 }
311
312 void blo_do_versions_oldnewmap_insert(OldNewMap *onm, void *oldaddr, void *newaddr, int nr)
313 {
314         oldnewmap_insert(onm, oldaddr, newaddr, nr);
315 }
316
317 /**
318  * Do a full search (no state).
319  *
320  * \param lasthit: Use as a reference position to avoid a full search
321  * from either end of the array, giving more efficient lookups.
322  *
323  * \note This would seem an ideal case for hash or btree lookups.
324  * However the data is written in-order, using the \a lasthit will normally avoid calling this function.
325  * Creating a btree/hash structure adds overhead for the common-case to optimize the corner-case
326  * (since most entries will never be retrieved).
327  * So just keep full lookups as a fall-back.
328  */
329 static int oldnewmap_lookup_entry_full(const OldNewMap *onm, const void *addr, int lasthit)
330 {
331         const int nentries = onm->nentries;
332         const OldNew *entries = onm->entries;
333         int i;
334
335         /* search relative to lasthit where possible */
336         if (lasthit >= 0 && lasthit < nentries) {
337
338                 /* search forwards */
339                 i = lasthit;
340                 while (++i != nentries) {
341                         if (entries[i].old == addr) {
342                                 return i;
343                         }
344                 }
345
346                 /* search backwards */
347                 i = lasthit + 1;
348                 while (i--) {
349                         if (entries[i].old == addr) {
350                                 return i;
351                         }
352                 }
353         }
354         else {
355                 /* search backwards (full) */
356                 i = nentries;
357                 while (i--) {
358                         if (entries[i].old == addr) {
359                                 return i;
360                         }
361                 }
362         }
363
364         return -1;
365 }
366
367 static void *oldnewmap_lookup_and_inc(OldNewMap *onm, void *addr, bool increase_users) 
368 {
369         int i;
370         
371         if (addr == NULL) return NULL;
372         
373         if (onm->lasthit < onm->nentries-1) {
374                 OldNew *entry = &onm->entries[++onm->lasthit];
375                 
376                 if (entry->old == addr) {
377                         if (increase_users)
378                                 entry->nr++;
379                         return entry->newp;
380                 }
381         }
382         
383         i = oldnewmap_lookup_entry_full(onm, addr, onm->lasthit);
384         if (i != -1) {
385                 OldNew *entry = &onm->entries[i];
386                 BLI_assert(entry->old == addr);
387                 onm->lasthit = i;
388                 if (increase_users)
389                         entry->nr++;
390                 return entry->newp;
391         }
392         
393         return NULL;
394 }
395
396 /* for libdata, nr has ID code, no increment */
397 static void *oldnewmap_liblookup(OldNewMap *onm, void *addr, void *lib)
398 {
399         if (addr == NULL) {
400                 return NULL;
401         }
402
403         /* lasthit works fine for non-libdata, linking there is done in same sequence as writing */
404         if (onm->sorted) {
405                 OldNew entry_s, *entry;
406
407                 entry_s.old = addr;
408
409                 entry = bsearch(&entry_s, onm->entries, onm->nentries, sizeof(OldNew), verg_oldnewmap);
410                 if (entry) {
411                         ID *id = entry->newp;
412
413                         if (id && (!lib || id->lib)) {
414                                 return id;
415                         }
416                 }
417         }
418         else {
419                 /* note, this can be a bottle neck when loading some files */
420                 const int i = oldnewmap_lookup_entry_full(onm, addr, -1);
421                 if (i != -1) {
422                         OldNew *entry = &onm->entries[i];
423                         ID *id = entry->newp;
424                         BLI_assert(entry->old == addr);
425                         if (id && (!lib || id->lib)) {
426                                 return id;
427                         }
428                 }
429         }
430
431         return NULL;
432 }
433
434 static void oldnewmap_free_unused(OldNewMap *onm) 
435 {
436         int i;
437
438         for (i = 0; i < onm->nentries; i++) {
439                 OldNew *entry = &onm->entries[i];
440                 if (entry->nr == 0) {
441                         MEM_freeN(entry->newp);
442                         entry->newp = NULL;
443                 }
444         }
445 }
446
447 static void oldnewmap_clear(OldNewMap *onm) 
448 {
449         onm->nentries = 0;
450         onm->lasthit = 0;
451 }
452
453 static void oldnewmap_free(OldNewMap *onm) 
454 {
455         MEM_freeN(onm->entries);
456         MEM_freeN(onm);
457 }
458
459 /***/
460
461 static void read_libraries(FileData *basefd, ListBase *mainlist);
462
463 /* ************ help functions ***************** */
464
465 static void add_main_to_main(Main *mainvar, Main *from)
466 {
467         ListBase *lbarray[MAX_LIBARRAY], *fromarray[MAX_LIBARRAY];
468         int a;
469         
470         set_listbasepointers(mainvar, lbarray);
471         a = set_listbasepointers(from, fromarray);
472         while (a--) {
473                 BLI_movelisttolist(lbarray[a], fromarray[a]);
474         }
475 }
476
477 void blo_join_main(ListBase *mainlist)
478 {
479         Main *tojoin, *mainl;
480         
481         mainl = mainlist->first;
482         while ((tojoin = mainl->next)) {
483                 add_main_to_main(mainl, tojoin);
484                 BLI_remlink(mainlist, tojoin);
485                 BKE_main_free(tojoin);
486         }
487 }
488
489 static void split_libdata(ListBase *lb, Main *first)
490 {
491         ListBase *lbn;
492         ID *id, *idnext;
493         Main *mainvar;
494         
495         id = lb->first;
496         while (id) {
497                 idnext = id->next;
498                 if (id->lib) {
499                         mainvar = first;
500                         while (mainvar) {
501                                 if (mainvar->curlib == id->lib) {
502                                         lbn= which_libbase(mainvar, GS(id->name));
503                                         BLI_remlink(lb, id);
504                                         BLI_addtail(lbn, id);
505                                         break;
506                                 }
507                                 mainvar = mainvar->next;
508                         }
509                         if (mainvar == NULL) printf("error split_libdata\n");
510                 }
511                 id = idnext;
512         }
513 }
514
515 void blo_split_main(ListBase *mainlist, Main *main)
516 {
517         ListBase *lbarray[MAX_LIBARRAY];
518         Library *lib;
519         int i;
520         
521         mainlist->first = mainlist->last = main;
522         main->next = NULL;
523         
524         if (BLI_listbase_is_empty(&main->library))
525                 return;
526         
527         for (lib = main->library.first; lib; lib = lib->id.next) {
528                 Main *libmain = BKE_main_new();
529                 libmain->curlib = lib;
530                 BLI_addtail(mainlist, libmain);
531         }
532         
533         i = set_listbasepointers(main, lbarray);
534         while (i--)
535                 split_libdata(lbarray[i], main->next);
536 }
537
538 static void read_file_version(FileData *fd, Main *main)
539 {
540         BHead *bhead;
541         
542         for (bhead= blo_firstbhead(fd); bhead; bhead= blo_nextbhead(fd, bhead)) {
543                 if (bhead->code == GLOB) {
544                         FileGlobal *fg= read_struct(fd, bhead, "Global");
545                         if (fg) {
546                                 main->subversionfile= fg->subversion;
547                                 main->minversionfile= fg->minversion;
548                                 main->minsubversionfile= fg->minsubversion;
549                                 MEM_freeN(fg);
550                         }
551                         else if (bhead->code == ENDB)
552                                 break;
553                 }
554         }
555 }
556
557 #ifdef USE_GHASH_BHEAD
558 static void read_file_bhead_idname_map_create(FileData *fd)
559 {
560         BHead *bhead;
561
562         /* dummy values */
563         bool is_link = false;
564         int code_prev = ENDB;
565         unsigned int reserve = 0;
566
567         for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
568                 if (code_prev != bhead->code) {
569                         code_prev = bhead->code;
570                         is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
571                 }
572
573                 if (is_link) {
574                         reserve += 1;
575                 }
576         }
577
578         BLI_assert(fd->bhead_idname_hash == NULL);
579
580         fd->bhead_idname_hash = BLI_ghash_str_new_ex(__func__, reserve);
581
582         for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
583                 if (code_prev != bhead->code) {
584                         code_prev = bhead->code;
585                         is_link = BKE_idcode_is_valid(code_prev) ? BKE_idcode_is_linkable(code_prev) : false;
586                 }
587
588                 if (is_link) {
589                         BLI_ghash_insert(fd->bhead_idname_hash, (void *)bhead_id_name(fd, bhead), bhead);
590                 }
591         }
592 }
593 #endif
594
595
596 static Main *blo_find_main(FileData *fd, const char *filepath, const char *relabase)
597 {
598         ListBase *mainlist = fd->mainlist;
599         Main *m;
600         Library *lib;
601         char name1[FILE_MAX];
602         
603         BLI_strncpy(name1, filepath, sizeof(name1));
604         BLI_cleanup_path(relabase, name1);
605         
606 //      printf("blo_find_main: relabase  %s\n", relabase);
607 //      printf("blo_find_main: original in  %s\n", filepath);
608 //      printf("blo_find_main: converted to %s\n", name1);
609         
610         for (m = mainlist->first; m; m = m->next) {
611                 const char *libname = (m->curlib) ? m->curlib->filepath : m->name;
612                 
613                 if (BLI_path_cmp(name1, libname) == 0) {
614                         if (G.debug & G_DEBUG) printf("blo_find_main: found library %s\n", libname);
615                         return m;
616                 }
617         }
618         
619         m = BKE_main_new();
620         BLI_addtail(mainlist, m);
621         
622         /* Add library datablock itself to 'main' Main, since libraries are **never** linked data.
623          * Fixes bug where you could end with all ID_LI datablocks having the same name... */
624         lib = BKE_libblock_alloc(mainlist->first, ID_LI, "Lib");
625         BLI_strncpy(lib->name, filepath, sizeof(lib->name));
626         BLI_strncpy(lib->filepath, name1, sizeof(lib->filepath));
627         
628         m->curlib = lib;
629         
630         read_file_version(fd, m);
631         
632         if (G.debug & G_DEBUG) printf("blo_find_main: added new lib %s\n", filepath);
633         return m;
634 }
635
636
637 /* ************ FILE PARSING ****************** */
638
639 static void switch_endian_bh4(BHead4 *bhead)
640 {
641         /* the ID_.. codes */
642         if ((bhead->code & 0xFFFF)==0) bhead->code >>= 16;
643         
644         if (bhead->code != ENDB) {
645                 BLI_endian_switch_int32(&bhead->len);
646                 BLI_endian_switch_int32(&bhead->SDNAnr);
647                 BLI_endian_switch_int32(&bhead->nr);
648         }
649 }
650
651 static void switch_endian_bh8(BHead8 *bhead)
652 {
653         /* the ID_.. codes */
654         if ((bhead->code & 0xFFFF)==0) bhead->code >>= 16;
655         
656         if (bhead->code != ENDB) {
657                 BLI_endian_switch_int32(&bhead->len);
658                 BLI_endian_switch_int32(&bhead->SDNAnr);
659                 BLI_endian_switch_int32(&bhead->nr);
660         }
661 }
662
663 static void bh4_from_bh8(BHead *bhead, BHead8 *bhead8, int do_endian_swap)
664 {
665         BHead4 *bhead4 = (BHead4 *) bhead;
666         int64_t old;
667
668         bhead4->code = bhead8->code;
669         bhead4->len = bhead8->len;
670
671         if (bhead4->code != ENDB) {
672                 /* perform a endian swap on 64bit pointers, otherwise the pointer might map to zero
673                  * 0x0000000000000000000012345678 would become 0x12345678000000000000000000000000
674                  */
675                 if (do_endian_swap) {
676                         BLI_endian_switch_int64(&bhead8->old);
677                 }
678                 
679                 /* this patch is to avoid a long long being read from not-eight aligned positions
680                  * is necessary on any modern 64bit architecture) */
681                 memcpy(&old, &bhead8->old, 8);
682                 bhead4->old = (int) (old >> 3);
683                 
684                 bhead4->SDNAnr = bhead8->SDNAnr;
685                 bhead4->nr = bhead8->nr;
686         }
687 }
688
689 static void bh8_from_bh4(BHead *bhead, BHead4 *bhead4)
690 {
691         BHead8 *bhead8 = (BHead8 *) bhead;
692         
693         bhead8->code = bhead4->code;
694         bhead8->len = bhead4->len;
695         
696         if (bhead8->code != ENDB) {
697                 bhead8->old = bhead4->old;
698                 bhead8->SDNAnr = bhead4->SDNAnr;
699                 bhead8->nr= bhead4->nr;
700         }
701 }
702
703 static BHeadN *get_bhead(FileData *fd)
704 {
705         BHeadN *new_bhead = NULL;
706         int readsize;
707         
708         if (fd) {
709                 if (!fd->eof) {
710                         /* initializing to zero isn't strictly needed but shuts valgrind up
711                          * since uninitialized memory gets compared */
712                         BHead8 bhead8 = {0};
713                         BHead4 bhead4 = {0};
714                         BHead  bhead = {0};
715                         
716                         /* First read the bhead structure.
717                          * Depending on the platform the file was written on this can
718                          * be a big or little endian BHead4 or BHead8 structure.
719                          *
720                          * As usual 'ENDB' (the last *partial* bhead of the file)
721                          * needs some special handling. We don't want to EOF just yet.
722                          */
723                         if (fd->flags & FD_FLAGS_FILE_POINTSIZE_IS_4) {
724                                 bhead4.code = DATA;
725                                 readsize = fd->read(fd, &bhead4, sizeof(bhead4));
726                                 
727                                 if (readsize == sizeof(bhead4) || bhead4.code == ENDB) {
728                                         if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
729                                                 switch_endian_bh4(&bhead4);
730                                         }
731                                         
732                                         if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
733                                                 bh8_from_bh4(&bhead, &bhead4);
734                                         }
735                                         else {
736                                                 memcpy(&bhead, &bhead4, sizeof(bhead));
737                                         }
738                                 }
739                                 else {
740                                         fd->eof = 1;
741                                         bhead.len= 0;
742                                 }
743                         }
744                         else {
745                                 bhead8.code = DATA;
746                                 readsize = fd->read(fd, &bhead8, sizeof(bhead8));
747                                 
748                                 if (readsize == sizeof(bhead8) || bhead8.code == ENDB) {
749                                         if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
750                                                 switch_endian_bh8(&bhead8);
751                                         }
752                                         
753                                         if (fd->flags & FD_FLAGS_POINTSIZE_DIFFERS) {
754                                                 bh4_from_bh8(&bhead, &bhead8, (fd->flags & FD_FLAGS_SWITCH_ENDIAN));
755                                         }
756                                         else {
757                                                 memcpy(&bhead, &bhead8, sizeof(bhead));
758                                         }
759                                 }
760                                 else {
761                                         fd->eof = 1;
762                                         bhead.len= 0;
763                                 }
764                         }
765                         
766                         /* make sure people are not trying to pass bad blend files */
767                         if (bhead.len < 0) fd->eof = 1;
768                         
769                         /* bhead now contains the (converted) bhead structure. Now read
770                          * the associated data and put everything in a BHeadN (creative naming !)
771                          */
772                         if (!fd->eof) {
773                                 new_bhead = MEM_mallocN(sizeof(BHeadN) + bhead.len, "new_bhead");
774                                 if (new_bhead) {
775                                         new_bhead->next = new_bhead->prev = NULL;
776                                         new_bhead->bhead = bhead;
777                                         
778                                         readsize = fd->read(fd, new_bhead + 1, bhead.len);
779                                         
780                                         if (readsize != bhead.len) {
781                                                 fd->eof = 1;
782                                                 MEM_freeN(new_bhead);
783                                                 new_bhead = NULL;
784                                         }
785                                 }
786                                 else {
787                                         fd->eof = 1;
788                                 }
789                         }
790                 }
791         }
792
793         /* We've read a new block. Now add it to the list
794          * of blocks.
795          */
796         if (new_bhead) {
797                 BLI_addtail(&fd->listbase, new_bhead);
798         }
799         
800         return(new_bhead);
801 }
802
803 BHead *blo_firstbhead(FileData *fd)
804 {
805         BHeadN *new_bhead;
806         BHead *bhead = NULL;
807         
808         /* Rewind the file
809          * Read in a new block if necessary
810          */
811         new_bhead = fd->listbase.first;
812         if (new_bhead == NULL) {
813                 new_bhead = get_bhead(fd);
814         }
815         
816         if (new_bhead) {
817                 bhead = &new_bhead->bhead;
818         }
819         
820         return(bhead);
821 }
822
823 BHead *blo_prevbhead(FileData *UNUSED(fd), BHead *thisblock)
824 {
825         BHeadN *bheadn = (BHeadN *)POINTER_OFFSET(thisblock, -offsetof(BHeadN, bhead));
826         BHeadN *prev = bheadn->prev;
827         
828         return (prev) ? &prev->bhead : NULL;
829 }
830
831 BHead *blo_nextbhead(FileData *fd, BHead *thisblock)
832 {
833         BHeadN *new_bhead = NULL;
834         BHead *bhead = NULL;
835         
836         if (thisblock) {
837                 /* bhead is actually a sub part of BHeadN
838                  * We calculate the BHeadN pointer from the BHead pointer below */
839                 new_bhead = (BHeadN *)POINTER_OFFSET(thisblock, -offsetof(BHeadN, bhead));
840                 
841                 /* get the next BHeadN. If it doesn't exist we read in the next one */
842                 new_bhead = new_bhead->next;
843                 if (new_bhead == NULL) {
844                         new_bhead = get_bhead(fd);
845                 }
846         }
847         
848         if (new_bhead) {
849                 /* here we do the reverse:
850                  * go from the BHeadN pointer to the BHead pointer */
851                 bhead = &new_bhead->bhead;
852         }
853         
854         return(bhead);
855 }
856
857 /* Warning! Caller's responsability to ensure given bhead **is** and ID one! */
858 const char *bhead_id_name(const FileData *fd, const BHead *bhead)
859 {
860         return (const char *)POINTER_OFFSET(bhead, sizeof(*bhead) + fd->id_name_offs);
861 }
862
863 static void decode_blender_header(FileData *fd)
864 {
865         char header[SIZEOFBLENDERHEADER], num[4];
866         int readsize;
867         
868         /* read in the header data */
869         readsize = fd->read(fd, header, sizeof(header));
870         
871         if (readsize == sizeof(header)) {
872                 if (STREQLEN(header, "BLENDER", 7)) {
873                         int remove_this_endian_test = 1;
874                         
875                         fd->flags |= FD_FLAGS_FILE_OK;
876                         
877                         /* what size are pointers in the file ? */
878                         if (header[7]=='_') {
879                                 fd->flags |= FD_FLAGS_FILE_POINTSIZE_IS_4;
880                                 if (sizeof(void *) != 4) {
881                                         fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
882                                 }
883                         }
884                         else {
885                                 if (sizeof(void *) != 8) {
886                                         fd->flags |= FD_FLAGS_POINTSIZE_DIFFERS;
887                                 }
888                         }
889                         
890                         /* is the file saved in a different endian
891                          * than we need ?
892                          */
893                         if (((((char *)&remove_this_endian_test)[0] == 1) ? L_ENDIAN : B_ENDIAN) != ((header[8] == 'v') ? L_ENDIAN : B_ENDIAN)) {
894                                 fd->flags |= FD_FLAGS_SWITCH_ENDIAN;
895                         }
896                         
897                         /* get the version number */
898                         memcpy(num, header + 9, 3);
899                         num[3] = 0;
900                         fd->fileversion = atoi(num);
901                 }
902         }
903 }
904
905 static int read_file_dna(FileData *fd)
906 {
907         BHead *bhead;
908         
909         for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
910                 if (bhead->code == DNA1) {
911                         const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
912                         
913                         fd->filesdna = DNA_sdna_from_data(&bhead[1], bhead->len, do_endian_swap);
914                         if (fd->filesdna) {
915                                 fd->compflags = DNA_struct_get_compareflags(fd->filesdna, fd->memsdna);
916                                 /* used to retrieve ID names from (bhead+1) */
917                                 fd->id_name_offs = DNA_elem_offset(fd->filesdna, "ID", "char", "name[]");
918                         }
919                         
920                         return 1;
921                 }
922                 else if (bhead->code == ENDB)
923                         break;
924         }
925         
926         return 0;
927 }
928
929 static int *read_file_thumbnail(FileData *fd)
930 {
931         BHead *bhead;
932         int *blend_thumb = NULL;
933
934         for (bhead = blo_firstbhead(fd); bhead; bhead = blo_nextbhead(fd, bhead)) {
935                 if (bhead->code == TEST) {
936                         const bool do_endian_swap = (fd->flags & FD_FLAGS_SWITCH_ENDIAN) != 0;
937                         int *data = (int *)(bhead + 1);
938
939                         if (bhead->len < (2 * sizeof(int))) {
940                                 break;
941                         }
942
943                         if (do_endian_swap) {
944                                 BLI_endian_switch_int32(&data[0]);
945                                 BLI_endian_switch_int32(&data[1]);
946                         }
947
948                         if (bhead->len < BLEN_THUMB_MEMSIZE_FILE(data[0], data[1])) {
949                                 break;
950                         }
951
952                         blend_thumb = data;
953                         break;
954                 }
955                 else if (bhead->code != REND) {
956                         /* Thumbnail is stored in TEST immediately after first REND... */
957                         break;
958                 }
959         }
960
961         return blend_thumb;
962 }
963
964 static int fd_read_from_file(FileData *filedata, void *buffer, unsigned int size)
965 {
966         int readsize = read(filedata->filedes, buffer, size);
967         
968         if (readsize < 0) {
969                 readsize = EOF;
970         }
971         else {
972                 filedata->seek += readsize;
973         }
974         
975         return readsize;
976 }
977
978 static int fd_read_gzip_from_file(FileData *filedata, void *buffer, unsigned int size)
979 {
980         int readsize = gzread(filedata->gzfiledes, buffer, size);
981         
982         if (readsize < 0) {
983                 readsize = EOF;
984         }
985         else {
986                 filedata->seek += readsize;
987         }
988         
989         return (readsize);
990 }
991
992 static int fd_read_from_memory(FileData *filedata, void *buffer, unsigned int size)
993 {
994         /* don't read more bytes then there are available in the buffer */
995         int readsize = (int)MIN2(size, (unsigned int)(filedata->buffersize - filedata->seek));
996         
997         memcpy(buffer, filedata->buffer + filedata->seek, readsize);
998         filedata->seek += readsize;
999         
1000         return (readsize);
1001 }
1002
1003 static int fd_read_from_memfile(FileData *filedata, void *buffer, unsigned int size)
1004 {
1005         static unsigned int seek = (1<<30);     /* the current position */
1006         static unsigned int offset = 0;         /* size of previous chunks */
1007         static MemFileChunk *chunk = NULL;
1008         unsigned int chunkoffset, readsize, totread;
1009         
1010         if (size == 0) return 0;
1011         
1012         if (seek != (unsigned int)filedata->seek) {
1013                 chunk = filedata->memfile->chunks.first;
1014                 seek = 0;
1015                 
1016                 while (chunk) {
1017                         if (seek + chunk->size > (unsigned) filedata->seek) break;
1018                         seek += chunk->size;
1019                         chunk = chunk->next;
1020                 }
1021                 offset = seek;
1022                 seek = filedata->seek;
1023         }
1024         
1025         if (chunk) {
1026                 totread = 0;
1027                 
1028                 do {
1029                         /* first check if it's on the end if current chunk */
1030                         if (seek-offset == chunk->size) {
1031                                 offset += chunk->size;
1032                                 chunk = chunk->next;
1033                         }
1034                         
1035                         /* debug, should never happen */
1036                         if (chunk == NULL) {
1037                                 printf("illegal read, chunk zero\n");
1038                                 return 0;
1039                         }
1040                         
1041                         chunkoffset = seek-offset;
1042                         readsize = size-totread;
1043                         
1044                         /* data can be spread over multiple chunks, so clamp size
1045                          * to within this chunk, and then it will read further in
1046                          * the next chunk */
1047                         if (chunkoffset+readsize > chunk->size)
1048                                 readsize= chunk->size-chunkoffset;
1049                         
1050                         memcpy(POINTER_OFFSET(buffer, totread), chunk->buf + chunkoffset, readsize);
1051                         totread += readsize;
1052                         filedata->seek += readsize;
1053                         seek += readsize;
1054                 } while (totread < size);
1055                 
1056                 return totread;
1057         }
1058         
1059         return 0;
1060 }
1061
1062 static FileData *filedata_new(void)
1063 {
1064         FileData *fd = MEM_callocN(sizeof(FileData), "FileData");
1065         
1066         fd->filedes = -1;
1067         fd->gzfiledes = NULL;
1068         
1069         /* XXX, this doesn't need to be done all the time,
1070          * but it keeps us re-entrant,  remove once we have
1071          * a lib that provides a nice lock. - zr
1072          */
1073         fd->memsdna = DNA_sdna_from_data(DNAstr, DNAlen, false);
1074         
1075         fd->datamap = oldnewmap_new();
1076         fd->globmap = oldnewmap_new();
1077         fd->libmap = oldnewmap_new();
1078         
1079         return fd;
1080 }
1081
1082 static FileData *blo_decode_and_check(FileData *fd, ReportList *reports)
1083 {
1084         decode_blender_header(fd);
1085         
1086         if (fd->flags & FD_FLAGS_FILE_OK) {
1087                 if (!read_file_dna(fd)) {
1088                         BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', incomplete", fd->relabase);
1089                         blo_freefiledata(fd);
1090                         fd = NULL;
1091                 }
1092         }
1093         else {
1094                 BKE_reportf(reports, RPT_ERROR, "Failed to read blend file '%s', not a blend file", fd->relabase);
1095                 blo_freefiledata(fd);
1096                 fd = NULL;
1097         }
1098         
1099         return fd;
1100 }
1101
1102 /* cannot be called with relative paths anymore! */
1103 /* on each new library added, it now checks for the current FileData and expands relativeness */
1104 FileData *blo_openblenderfile(const char *filepath, ReportList *reports)
1105 {
1106         gzFile gzfile;
1107         errno = 0;
1108         gzfile = BLI_gzopen(filepath, "rb");
1109         
1110         if (gzfile == (gzFile)Z_NULL) {
1111                 BKE_reportf(reports, RPT_WARNING, "Unable to open '%s': %s",
1112                             filepath, errno ? strerror(errno) : TIP_("unknown error reading file"));
1113                 return NULL;
1114         }
1115         else {
1116                 FileData *fd = filedata_new();
1117                 fd->gzfiledes = gzfile;
1118                 fd->read = fd_read_gzip_from_file;
1119                 
1120                 /* needed for library_append and read_libraries */
1121                 BLI_strncpy(fd->relabase, filepath, sizeof(fd->relabase));
1122                 
1123                 return blo_decode_and_check(fd, reports);
1124         }
1125 }
1126
1127 /**
1128  * Same as blo_openblenderfile(), but does not reads DNA data, only header. Use it for light access
1129  * (e.g. thumbnail reading).
1130  */
1131 static FileData *blo_openblenderfile_minimal(const char *filepath)
1132 {
1133         gzFile gzfile;
1134         errno = 0;
1135         gzfile = BLI_gzopen(filepath, "rb");
1136
1137         if (gzfile != (gzFile)Z_NULL) {
1138                 FileData *fd = filedata_new();
1139                 fd->gzfiledes = gzfile;
1140                 fd->read = fd_read_gzip_from_file;
1141
1142                 decode_blender_header(fd);
1143
1144                 if (fd->flags & FD_FLAGS_FILE_OK) {
1145                         return fd;
1146                 }
1147
1148                 blo_freefiledata(fd);
1149         }
1150
1151         return NULL;
1152 }
1153
1154 static int fd_read_gzip_from_memory(FileData *filedata, void *buffer, unsigned int size)
1155 {
1156         int err;
1157
1158         filedata->strm.next_out = (Bytef *) buffer;
1159         filedata->strm.avail_out = size;
1160
1161         // Inflate another chunk.
1162         err = inflate (&filedata->strm, Z_SYNC_FLUSH);
1163
1164         if (err == Z_STREAM_END) {
1165                 return 0;
1166         }
1167         else if (err != Z_OK) {
1168                 printf("fd_read_gzip_from_memory: zlib error\n");
1169                 return 0;
1170         }
1171
1172         filedata->seek += size;
1173
1174         return (size);
1175 }
1176
1177 static int fd_read_gzip_from_memory_init(FileData *fd)
1178 {
1179
1180         fd->strm.next_in = (Bytef *) fd->buffer;
1181         fd->strm.avail_in = fd->buffersize;
1182         fd->strm.total_out = 0;
1183         fd->strm.zalloc = Z_NULL;
1184         fd->strm.zfree = Z_NULL;
1185         
1186         if (inflateInit2(&fd->strm, (16+MAX_WBITS)) != Z_OK)
1187                 return 0;
1188
1189         fd->read = fd_read_gzip_from_memory;
1190         
1191         return 1;
1192 }
1193
1194 FileData *blo_openblendermemory(const void *mem, int memsize, ReportList *reports)
1195 {
1196         if (!mem || memsize<SIZEOFBLENDERHEADER) {
1197                 BKE_report(reports, RPT_WARNING, (mem) ? TIP_("Unable to read"): TIP_("Unable to open"));
1198                 return NULL;
1199         }
1200         else {
1201                 FileData *fd = filedata_new();
1202                 const char *cp = mem;
1203                 
1204                 fd->buffer = mem;
1205                 fd->buffersize = memsize;
1206                 
1207                 /* test if gzip */
1208                 if (cp[0] == 0x1f && cp[1] == 0x8b) {
1209                         if (0 == fd_read_gzip_from_memory_init(fd)) {
1210                                 blo_freefiledata(fd);
1211                                 return NULL;
1212                         }
1213                 }
1214                 else
1215                         fd->read = fd_read_from_memory;
1216                         
1217                 fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
1218
1219                 return blo_decode_and_check(fd, reports);
1220         }
1221 }
1222
1223 FileData *blo_openblendermemfile(MemFile *memfile, ReportList *reports)
1224 {
1225         if (!memfile) {
1226                 BKE_report(reports, RPT_WARNING, "Unable to open blend <memory>");
1227                 return NULL;
1228         }
1229         else {
1230                 FileData *fd = filedata_new();
1231                 fd->memfile = memfile;
1232                 
1233                 fd->read = fd_read_from_memfile;
1234                 fd->flags |= FD_FLAGS_NOT_MY_BUFFER;
1235                 
1236                 return blo_decode_and_check(fd, reports);
1237         }
1238 }
1239
1240
1241 void blo_freefiledata(FileData *fd)
1242 {
1243         if (fd) {
1244                 if (fd->filedes != -1) {
1245                         close(fd->filedes);
1246                 }
1247                 
1248                 if (fd->gzfiledes != NULL) {
1249                         gzclose(fd->gzfiledes);
1250                 }
1251                 
1252                 if (fd->strm.next_in) {
1253                         if (inflateEnd (&fd->strm) != Z_OK) {
1254                                 printf("close gzip stream error\n");
1255                         }
1256                 }
1257                 
1258                 if (fd->buffer && !(fd->flags & FD_FLAGS_NOT_MY_BUFFER)) {
1259                         MEM_freeN((void *)fd->buffer);
1260                         fd->buffer = NULL;
1261                 }
1262                 
1263                 // Free all BHeadN data blocks
1264                 BLI_freelistN(&fd->listbase);
1265                 
1266                 if (fd->memsdna)
1267                         DNA_sdna_free(fd->memsdna);
1268                 if (fd->filesdna)
1269                         DNA_sdna_free(fd->filesdna);
1270                 if (fd->compflags)
1271                         MEM_freeN(fd->compflags);
1272                 
1273                 if (fd->datamap)
1274                         oldnewmap_free(fd->datamap);
1275                 if (fd->globmap)
1276                         oldnewmap_free(fd->globmap);
1277                 if (fd->imamap)
1278                         oldnewmap_free(fd->imamap);
1279                 if (fd->movieclipmap)
1280                         oldnewmap_free(fd->movieclipmap);
1281                 if (fd->soundmap)
1282                         oldnewmap_free(fd->soundmap);
1283                 if (fd->packedmap)
1284                         oldnewmap_free(fd->packedmap);
1285                 if (fd->libmap && !(fd->flags & FD_FLAGS_NOT_MY_LIBMAP))
1286                         oldnewmap_free(fd->libmap);
1287                 if (fd->bheadmap)
1288                         MEM_freeN(fd->bheadmap);
1289                 
1290 #ifdef USE_GHASH_BHEAD
1291                 if (fd->bhead_idname_hash) {
1292                         BLI_ghash_free(fd->bhead_idname_hash, NULL, NULL);
1293                 }
1294 #endif
1295
1296                 MEM_freeN(fd);
1297         }
1298 }
1299
1300 /* ************ DIV ****************** */
1301
1302 bool BLO_has_bfile_extension(const char *str)
1303 {
1304         const char *ext_test[4] = {".blend", ".ble", ".blend.gz", NULL};
1305         return BLI_testextensie_array(str, ext_test);
1306 }
1307
1308 bool BLO_library_path_explode(const char *path, char *r_dir, char **r_group, char **r_name)
1309 {
1310         /* We might get some data names with slashes, so we have to go up in path until we find blend file itself,
1311          * then we now next path item is group, and everything else is data name. */
1312         char *slash = NULL, *prev_slash = NULL, c = '\0';
1313
1314         r_dir[0] = '\0';
1315         if (r_group) {
1316                 *r_group = NULL;
1317         }
1318         if (r_name) {
1319                 *r_name = NULL;
1320         }
1321
1322         /* if path leads to an existing directory, we can be sure we're not (in) a library */
1323         if (BLI_is_dir(path)) {
1324                 return false;
1325         }
1326
1327         strcpy(r_dir, path);
1328
1329         while ((slash = (char *)BLI_last_slash(r_dir))) {
1330                 char tc = *slash;
1331                 *slash = '\0';
1332                 if (BLO_has_bfile_extension(r_dir)) {
1333                         break;
1334                 }
1335
1336                 if (prev_slash) {
1337                         *prev_slash = c;
1338                 }
1339                 prev_slash = slash;
1340                 c = tc;
1341         }
1342
1343         if (!slash) {
1344                 return false;
1345         }
1346
1347         if (slash[1] != '\0') {
1348                 BLI_assert(strlen(slash + 1) < BLO_GROUP_MAX);
1349                 if (r_group) {
1350                         *r_group = slash + 1;
1351                 }
1352         }
1353
1354         if (prev_slash && (prev_slash[1] != '\0')) {
1355                 BLI_assert(strlen(prev_slash + 1) < MAX_ID_NAME - 2);
1356                 if (r_name) {
1357                         *r_name = prev_slash + 1;
1358                 }
1359         }
1360
1361         return true;
1362 }
1363
1364 BlendThumbnail *BLO_thumbnail_from_file(const char *filepath)
1365 {
1366         FileData *fd;
1367         BlendThumbnail *data;
1368         int *fd_data;
1369
1370         fd = blo_openblenderfile_minimal(filepath);
1371         fd_data = fd ? read_file_thumbnail(fd) : NULL;
1372
1373         if (fd_data) {
1374                 const size_t sz = BLEN_THUMB_MEMSIZE(fd_data[0], fd_data[1]);
1375                 data = MEM_mallocN(sz, __func__);
1376
1377                 BLI_assert((sz - sizeof(*data)) == (BLEN_THUMB_MEMSIZE_FILE(fd_data[0], fd_data[1]) - (sizeof(*fd_data) * 2)));
1378                 data->width = fd_data[0];
1379                 data->height = fd_data[1];
1380                 memcpy(data->rect, &fd_data[2], sz - sizeof(*data));
1381         }
1382         else {
1383                 data = NULL;
1384         }
1385
1386         blo_freefiledata(fd);
1387
1388         return data;
1389 }
1390
1391 /* ************** OLD POINTERS ******************* */
1392
1393 static void *newdataadr(FileData *fd, void *adr)                /* only direct databocks */
1394 {
1395         return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
1396 }
1397
1398 /* This is a special version of newdataadr() which allows us to keep lasthit of
1399  * map unchanged. In certain cases this makes file loading time significantly
1400  * faster.
1401  *
1402  * Use this function in cases like restoring pointer from one list element to
1403  * another list element, but keep lasthit value so we can continue restoring
1404  * pointers efficiently.
1405  *
1406  * Example of this could be found in direct_link_fcurves() which restores the
1407  * fcurve group pointer and keeps lasthit optimal for linking all further
1408  * fcurves.
1409  */
1410 static void *newdataadr_ex(FileData *fd, void *adr, bool increase_lasthit)              /* only direct databocks */
1411 {
1412         if (increase_lasthit) {
1413                 return newdataadr(fd, adr);
1414         }
1415         else {
1416                 int lasthit = fd->datamap->lasthit;
1417                 void *newadr = newdataadr(fd, adr);
1418                 fd->datamap->lasthit = lasthit;
1419                 return newadr;
1420         }
1421 }
1422
1423 static void *newdataadr_no_us(FileData *fd, void *adr)          /* only direct databocks */
1424 {
1425         return oldnewmap_lookup_and_inc(fd->datamap, adr, false);
1426 }
1427
1428 static void *newglobadr(FileData *fd, void *adr)            /* direct datablocks with global linking */
1429 {
1430         return oldnewmap_lookup_and_inc(fd->globmap, adr, true);
1431 }
1432
1433 static void *newimaadr(FileData *fd, void *adr)             /* used to restore image data after undo */
1434 {
1435         if (fd->imamap && adr)
1436                 return oldnewmap_lookup_and_inc(fd->imamap, adr, true);
1437         return NULL;
1438 }
1439
1440 static void *newmclipadr(FileData *fd, void *adr)      /* used to restore movie clip data after undo */
1441 {
1442         if (fd->movieclipmap && adr)
1443                 return oldnewmap_lookup_and_inc(fd->movieclipmap, adr, true);
1444         return NULL;
1445 }
1446
1447 static void *newsoundadr(FileData *fd, void *adr)      /* used to restore sound data after undo */
1448 {
1449         if (fd->soundmap && adr)
1450                 return oldnewmap_lookup_and_inc(fd->soundmap, adr, true);
1451         return NULL;
1452 }
1453
1454 static void *newpackedadr(FileData *fd, void *adr)      /* used to restore packed data after undo */
1455 {
1456         if (fd->packedmap && adr)
1457                 return oldnewmap_lookup_and_inc(fd->packedmap, adr, true);
1458         
1459         return oldnewmap_lookup_and_inc(fd->datamap, adr, true);
1460 }
1461
1462
1463 static void *newlibadr(FileData *fd, void *lib, void *adr)              /* only lib data */
1464 {
1465         return oldnewmap_liblookup(fd->libmap, adr, lib);
1466 }
1467
1468 void *blo_do_versions_newlibadr(FileData *fd, void *lib, void *adr)             /* only lib data */
1469 {
1470         return newlibadr(fd, lib, adr);
1471 }
1472
1473 static void *newlibadr_us(FileData *fd, void *lib, void *adr)   /* increases user number */
1474 {
1475         ID *id = newlibadr(fd, lib, adr);
1476         
1477         if (id)
1478                 id->us++;
1479         
1480         return id;
1481 }
1482
1483 void *blo_do_versions_newlibadr_us(FileData *fd, void *lib, void *adr)  /* increases user number */
1484 {
1485         return newlibadr_us(fd, lib, adr);
1486 }
1487
1488 static void change_idid_adr_fd(FileData *fd, void *old, void *new)
1489 {
1490         int i;
1491         
1492         for (i = 0; i < fd->libmap->nentries; i++) {
1493                 OldNew *entry = &fd->libmap->entries[i];
1494                 
1495                 if (old==entry->newp && entry->nr==ID_ID) {
1496                         entry->newp = new;
1497                         if (new) entry->nr = GS( ((ID *)new)->name );
1498                 }
1499         }
1500 }
1501
1502 static void change_idid_adr(ListBase *mainlist, FileData *basefd, void *old, void *new)
1503 {
1504         Main *mainptr;
1505         
1506         for (mainptr = mainlist->first; mainptr; mainptr = mainptr->next) {
1507                 FileData *fd;
1508                 
1509                 if (mainptr->curlib)
1510                         fd = mainptr->curlib->filedata;
1511                 else
1512                         fd = basefd;
1513                 
1514                 if (fd) {
1515                         change_idid_adr_fd(fd, old, new);
1516                 }
1517         }
1518 }
1519
1520 /* lib linked proxy objects point to our local data, we need
1521  * to clear that pointer before reading the undo memfile since
1522  * the object might be removed, it is set again in reading
1523  * if the local object still exists */
1524 void blo_clear_proxy_pointers_from_lib(Main *oldmain)
1525 {
1526         Object *ob = oldmain->object.first;
1527         
1528         for (; ob; ob= ob->id.next) {
1529                 if (ob->id.lib)
1530                         ob->proxy_from = NULL;
1531         }
1532 }
1533
1534 void blo_make_image_pointer_map(FileData *fd, Main *oldmain)
1535 {
1536         Image *ima = oldmain->image.first;
1537         Scene *sce = oldmain->scene.first;
1538         int a;
1539         
1540         fd->imamap = oldnewmap_new();
1541         
1542         for (; ima; ima = ima->id.next) {
1543                 if (ima->cache)
1544                         oldnewmap_insert(fd->imamap, ima->cache, ima->cache, 0);
1545                 if (ima->gputexture)
1546                         oldnewmap_insert(fd->imamap, ima->gputexture, ima->gputexture, 0);
1547                 if (ima->rr)
1548                         oldnewmap_insert(fd->imamap, ima->rr, ima->rr, 0);
1549                 for (a=0; a < IMA_MAX_RENDER_SLOT; a++)
1550                         if (ima->renders[a])
1551                                 oldnewmap_insert(fd->imamap, ima->renders[a], ima->renders[a], 0);
1552         }
1553         for (; sce; sce = sce->id.next) {
1554                 if (sce->nodetree && sce->nodetree->previews) {
1555                         bNodeInstanceHashIterator iter;
1556                         NODE_INSTANCE_HASH_ITER(iter, sce->nodetree->previews) {
1557                                 bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
1558                                 oldnewmap_insert(fd->imamap, preview, preview, 0);
1559                         }
1560                 }
1561         }
1562 }
1563
1564 /* set old main image ibufs to zero if it has been restored */
1565 /* this works because freeing old main only happens after this call */
1566 void blo_end_image_pointer_map(FileData *fd, Main *oldmain)
1567 {
1568         OldNew *entry = fd->imamap->entries;
1569         Image *ima = oldmain->image.first;
1570         Scene *sce = oldmain->scene.first;
1571         int i;
1572         
1573         /* used entries were restored, so we put them to zero */
1574         for (i = 0; i < fd->imamap->nentries; i++, entry++) {
1575                 if (entry->nr > 0)
1576                         entry->newp = NULL;
1577         }
1578         
1579         for (; ima; ima = ima->id.next) {
1580                 ima->cache = newimaadr(fd, ima->cache);
1581                 if (ima->cache == NULL) {
1582                         ima->bindcode = 0;
1583                         ima->tpageflag &= ~IMA_GLBIND_IS_DATA;
1584                         ima->gputexture = NULL;
1585                         ima->rr = NULL;
1586                 }
1587                 for (i = 0; i < IMA_MAX_RENDER_SLOT; i++)
1588                         ima->renders[i] = newimaadr(fd, ima->renders[i]);
1589                 
1590                 ima->gputexture = newimaadr(fd, ima->gputexture);
1591                 ima->rr = newimaadr(fd, ima->rr);
1592         }
1593         for (; sce; sce = sce->id.next) {
1594                 if (sce->nodetree && sce->nodetree->previews) {
1595                         bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews");
1596                         bNodeInstanceHashIterator iter;
1597                         
1598                         /* reconstruct the preview hash, only using remaining pointers */
1599                         NODE_INSTANCE_HASH_ITER(iter, sce->nodetree->previews) {
1600                                 bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
1601                                 if (preview) {
1602                                         bNodePreview *new_preview = newimaadr(fd, preview);
1603                                         if (new_preview) {
1604                                                 bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
1605                                                 BKE_node_instance_hash_insert(new_previews, key, new_preview);
1606                                         }
1607                                 }
1608                         }
1609                         BKE_node_instance_hash_free(sce->nodetree->previews, NULL);
1610                         sce->nodetree->previews = new_previews;
1611                 }
1612         }
1613 }
1614
1615 void blo_make_movieclip_pointer_map(FileData *fd, Main *oldmain)
1616 {
1617         MovieClip *clip = oldmain->movieclip.first;
1618         Scene *sce = oldmain->scene.first;
1619         
1620         fd->movieclipmap = oldnewmap_new();
1621         
1622         for (; clip; clip = clip->id.next) {
1623                 if (clip->cache)
1624                         oldnewmap_insert(fd->movieclipmap, clip->cache, clip->cache, 0);
1625                 
1626                 if (clip->tracking.camera.intrinsics)
1627                         oldnewmap_insert(fd->movieclipmap, clip->tracking.camera.intrinsics, clip->tracking.camera.intrinsics, 0);
1628         }
1629         
1630         for (; sce; sce = sce->id.next) {
1631                 if (sce->nodetree) {
1632                         bNode *node;
1633                         for (node = sce->nodetree->nodes.first; node; node = node->next)
1634                                 if (node->type == CMP_NODE_MOVIEDISTORTION)
1635                                         oldnewmap_insert(fd->movieclipmap, node->storage, node->storage, 0);
1636                 }
1637         }
1638 }
1639
1640 /* set old main movie clips caches to zero if it has been restored */
1641 /* this works because freeing old main only happens after this call */
1642 void blo_end_movieclip_pointer_map(FileData *fd, Main *oldmain)
1643 {
1644         OldNew *entry = fd->movieclipmap->entries;
1645         MovieClip *clip = oldmain->movieclip.first;
1646         Scene *sce = oldmain->scene.first;
1647         int i;
1648         
1649         /* used entries were restored, so we put them to zero */
1650         for (i=0; i < fd->movieclipmap->nentries; i++, entry++) {
1651                 if (entry->nr > 0)
1652                         entry->newp = NULL;
1653         }
1654         
1655         for (; clip; clip = clip->id.next) {
1656                 clip->cache = newmclipadr(fd, clip->cache);
1657                 clip->tracking.camera.intrinsics = newmclipadr(fd, clip->tracking.camera.intrinsics);
1658         }
1659         
1660         for (; sce; sce = sce->id.next) {
1661                 if (sce->nodetree) {
1662                         bNode *node;
1663                         for (node = sce->nodetree->nodes.first; node; node = node->next)
1664                                 if (node->type == CMP_NODE_MOVIEDISTORTION)
1665                                         node->storage = newmclipadr(fd, node->storage);
1666                 }
1667         }
1668 }
1669
1670 void blo_make_sound_pointer_map(FileData *fd, Main *oldmain)
1671 {
1672         bSound *sound = oldmain->sound.first;
1673         
1674         fd->soundmap = oldnewmap_new();
1675         
1676         for (; sound; sound = sound->id.next) {
1677                 if (sound->waveform)
1678                         oldnewmap_insert(fd->soundmap, sound->waveform, sound->waveform, 0);                    
1679         }
1680 }
1681
1682 /* set old main sound caches to zero if it has been restored */
1683 /* this works because freeing old main only happens after this call */
1684 void blo_end_sound_pointer_map(FileData *fd, Main *oldmain)
1685 {
1686         OldNew *entry = fd->soundmap->entries;
1687         bSound *sound = oldmain->sound.first;
1688         int i;
1689         
1690         /* used entries were restored, so we put them to zero */
1691         for (i = 0; i < fd->soundmap->nentries; i++, entry++) {
1692                 if (entry->nr > 0)
1693                         entry->newp = NULL;
1694         }
1695         
1696         for (; sound; sound = sound->id.next) {
1697                 sound->waveform = newsoundadr(fd, sound->waveform);
1698         }
1699 }
1700
1701 /* XXX disabled this feature - packed files also belong in temp saves and quit.blend, to make restore work */
1702
1703 static void insert_packedmap(FileData *fd, PackedFile *pf)
1704 {
1705         oldnewmap_insert(fd->packedmap, pf, pf, 0);
1706         oldnewmap_insert(fd->packedmap, pf->data, pf->data, 0);
1707 }
1708
1709 void blo_make_packed_pointer_map(FileData *fd, Main *oldmain)
1710 {
1711         Image *ima;
1712         VFont *vfont;
1713         bSound *sound;
1714         Library *lib;
1715         
1716         fd->packedmap = oldnewmap_new();
1717         
1718         for (ima = oldmain->image.first; ima; ima = ima->id.next) {
1719                 ImagePackedFile *imapf;
1720
1721                 if (ima->packedfile)
1722                         insert_packedmap(fd, ima->packedfile);
1723
1724                 for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next)
1725                         if (imapf->packedfile)
1726                                 insert_packedmap(fd, imapf->packedfile);
1727         }
1728                         
1729         for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
1730                 if (vfont->packedfile)
1731                         insert_packedmap(fd, vfont->packedfile);
1732         
1733         for (sound = oldmain->sound.first; sound; sound = sound->id.next)
1734                 if (sound->packedfile)
1735                         insert_packedmap(fd, sound->packedfile);
1736         
1737         for (lib = oldmain->library.first; lib; lib = lib->id.next)
1738                 if (lib->packedfile)
1739                         insert_packedmap(fd, lib->packedfile);
1740
1741 }
1742
1743 /* set old main packed data to zero if it has been restored */
1744 /* this works because freeing old main only happens after this call */
1745 void blo_end_packed_pointer_map(FileData *fd, Main *oldmain)
1746 {
1747         Image *ima;
1748         VFont *vfont;
1749         bSound *sound;
1750         Library *lib;
1751         OldNew *entry = fd->packedmap->entries;
1752         int i;
1753         
1754         /* used entries were restored, so we put them to zero */
1755         for (i=0; i < fd->packedmap->nentries; i++, entry++) {
1756                 if (entry->nr > 0)
1757                         entry->newp = NULL;
1758         }
1759         
1760         for (ima = oldmain->image.first; ima; ima = ima->id.next) {
1761                 ImagePackedFile *imapf;
1762
1763                 ima->packedfile = newpackedadr(fd, ima->packedfile);
1764
1765                 for (imapf = ima->packedfiles.first; imapf; imapf = imapf->next)
1766                         imapf->packedfile = newpackedadr(fd, imapf->packedfile);
1767         }
1768         
1769         for (vfont = oldmain->vfont.first; vfont; vfont = vfont->id.next)
1770                 vfont->packedfile = newpackedadr(fd, vfont->packedfile);
1771
1772         for (sound = oldmain->sound.first; sound; sound = sound->id.next)
1773                 sound->packedfile = newpackedadr(fd, sound->packedfile);
1774                 
1775         for (lib = oldmain->library.first; lib; lib = lib->id.next)
1776                 lib->packedfile = newpackedadr(fd, lib->packedfile);
1777 }
1778
1779
1780 /* undo file support: add all library pointers in lookup */
1781 void blo_add_library_pointer_map(ListBase *old_mainlist, FileData *fd)
1782 {
1783         Main *ptr = old_mainlist->first;
1784         ListBase *lbarray[MAX_LIBARRAY];
1785         
1786         for (ptr = ptr->next; ptr; ptr = ptr->next) {
1787                 int i = set_listbasepointers(ptr, lbarray);
1788                 while (i--) {
1789                         ID *id;
1790                         for (id = lbarray[i]->first; id; id = id->next)
1791                                 oldnewmap_insert(fd->libmap, id, id, GS(id->name));
1792                 }
1793         }
1794
1795         fd->old_mainlist = old_mainlist;
1796 }
1797
1798
1799 /* ********** END OLD POINTERS ****************** */
1800 /* ********** READ FILE ****************** */
1801
1802 static void switch_endian_structs(struct SDNA *filesdna, BHead *bhead)
1803 {
1804         int blocksize, nblocks;
1805         char *data;
1806         
1807         data = (char *)(bhead+1);
1808         blocksize = filesdna->typelens[ filesdna->structs[bhead->SDNAnr][0] ];
1809         
1810         nblocks = bhead->nr;
1811         while (nblocks--) {
1812                 DNA_struct_switch_endian(filesdna, bhead->SDNAnr, data);
1813                 
1814                 data += blocksize;
1815         }
1816 }
1817
1818 static void *read_struct(FileData *fd, BHead *bh, const char *blockname)
1819 {
1820         void *temp = NULL;
1821         
1822         if (bh->len) {
1823                 /* switch is based on file dna */
1824                 if (bh->SDNAnr && (fd->flags & FD_FLAGS_SWITCH_ENDIAN))
1825                         switch_endian_structs(fd->filesdna, bh);
1826                 
1827                 if (fd->compflags[bh->SDNAnr]) {        /* flag==0: doesn't exist anymore */
1828                         if (fd->compflags[bh->SDNAnr] == 2) {
1829                                 temp = DNA_struct_reconstruct(fd->memsdna, fd->filesdna, fd->compflags, bh->SDNAnr, bh->nr, (bh+1));
1830                         }
1831                         else {
1832                                 temp = MEM_mallocN(bh->len, blockname);
1833                                 memcpy(temp, (bh+1), bh->len);
1834                         }
1835                 }
1836         }
1837
1838         return temp;
1839 }
1840
1841 typedef void (*link_list_cb)(FileData *fd, void *data);
1842
1843 static void link_list_ex(FileData *fd, ListBase *lb, link_list_cb callback)             /* only direct data */
1844 {
1845         Link *ln, *prev;
1846         
1847         if (BLI_listbase_is_empty(lb)) return;
1848         
1849         lb->first = newdataadr(fd, lb->first);
1850         if (callback != NULL) {
1851                 callback(fd, lb->first);
1852         }
1853         ln = lb->first;
1854         prev = NULL;
1855         while (ln) {
1856                 ln->next = newdataadr(fd, ln->next);
1857                 if (ln->next != NULL && callback != NULL) {
1858                         callback(fd, ln->next);
1859                 }
1860                 ln->prev = prev;
1861                 prev = ln;
1862                 ln = ln->next;
1863         }
1864         lb->last = prev;
1865 }
1866
1867 static void link_list(FileData *fd, ListBase *lb)               /* only direct data */
1868 {
1869         link_list_ex(fd, lb, NULL);
1870 }
1871
1872 static void link_glob_list(FileData *fd, ListBase *lb)          /* for glob data */
1873 {
1874         Link *ln, *prev;
1875         void *poin;
1876
1877         if (BLI_listbase_is_empty(lb)) return;
1878         poin = newdataadr(fd, lb->first);
1879         if (lb->first) {
1880                 oldnewmap_insert(fd->globmap, lb->first, poin, 0);
1881         }
1882         lb->first = poin;
1883         
1884         ln = lb->first;
1885         prev = NULL;
1886         while (ln) {
1887                 poin = newdataadr(fd, ln->next);
1888                 if (ln->next) {
1889                         oldnewmap_insert(fd->globmap, ln->next, poin, 0);
1890                 }
1891                 ln->next = poin;
1892                 ln->prev = prev;
1893                 prev = ln;
1894                 ln = ln->next;
1895         }
1896         lb->last = prev;
1897 }
1898
1899 static void test_pointer_array(FileData *fd, void **mat)
1900 {
1901         int64_t *lpoin, *lmat;
1902         int *ipoin, *imat;
1903         size_t len;
1904
1905                 /* manually convert the pointer array in
1906                  * the old dna format to a pointer array in
1907                  * the new dna format.
1908                  */
1909         if (*mat) {
1910                 len = MEM_allocN_len(*mat)/fd->filesdna->pointerlen;
1911                         
1912                 if (fd->filesdna->pointerlen==8 && fd->memsdna->pointerlen==4) {
1913                         ipoin=imat= MEM_mallocN(len * 4, "newmatar");
1914                         lpoin= *mat;
1915                         
1916                         while (len-- > 0) {
1917                                 if ((fd->flags & FD_FLAGS_SWITCH_ENDIAN))
1918                                         BLI_endian_switch_int64(lpoin);
1919                                 *ipoin = (int)((*lpoin) >> 3);
1920                                 ipoin++;
1921                                 lpoin++;
1922                         }
1923                         MEM_freeN(*mat);
1924                         *mat = imat;
1925                 }
1926                 
1927                 if (fd->filesdna->pointerlen==4 && fd->memsdna->pointerlen==8) {
1928                         lpoin = lmat = MEM_mallocN(len * 8, "newmatar");
1929                         ipoin = *mat;
1930                         
1931                         while (len-- > 0) {
1932                                 *lpoin = *ipoin;
1933                                 ipoin++;
1934                                 lpoin++;
1935                         }
1936                         MEM_freeN(*mat);
1937                         *mat= lmat;
1938                 }
1939         }
1940 }
1941
1942 /* ************ READ ID Properties *************** */
1943
1944 static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
1945 static void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
1946
1947 static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData *fd)
1948 {
1949         IDProperty *array;
1950         int i;
1951         
1952         /* since we didn't save the extra buffer, set totallen to len */
1953         prop->totallen = prop->len;
1954         prop->data.pointer = newdataadr(fd, prop->data.pointer);
1955
1956         array = (IDProperty *)prop->data.pointer;
1957         
1958         /* note!, idp-arrays didn't exist in 2.4x, so the pointer will be cleared
1959          * theres not really anything we can do to correct this, at least don't crash */
1960         if (array == NULL) {
1961                 prop->len = 0;
1962                 prop->totallen = 0;
1963         }
1964         
1965         
1966         for (i = 0; i < prop->len; i++)
1967                 IDP_DirectLinkProperty(&array[i], switch_endian, fd);
1968 }
1969
1970 static void IDP_DirectLinkArray(IDProperty *prop, int switch_endian, FileData *fd)
1971 {
1972         IDProperty **array;
1973         int i;
1974         
1975         /* since we didn't save the extra buffer, set totallen to len */
1976         prop->totallen = prop->len;
1977         prop->data.pointer = newdataadr(fd, prop->data.pointer);
1978         
1979         if (prop->subtype == IDP_GROUP) {
1980                 test_pointer_array(fd, prop->data.pointer);
1981                 array = prop->data.pointer;
1982                 
1983                 for (i = 0; i < prop->len; i++)
1984                         IDP_DirectLinkProperty(array[i], switch_endian, fd);
1985         }
1986         else if (prop->subtype == IDP_DOUBLE) {
1987                 if (switch_endian) {
1988                         BLI_endian_switch_double_array(prop->data.pointer, prop->len);
1989                 }
1990         }
1991         else {
1992                 if (switch_endian) {
1993                         /* also used for floats */
1994                         BLI_endian_switch_int32_array(prop->data.pointer, prop->len);
1995                 }
1996         }
1997 }
1998
1999 static void IDP_DirectLinkString(IDProperty *prop, FileData *fd)
2000 {
2001         /*since we didn't save the extra string buffer, set totallen to len.*/
2002         prop->totallen = prop->len;
2003         prop->data.pointer = newdataadr(fd, prop->data.pointer);
2004 }
2005
2006 static void IDP_DirectLinkGroup(IDProperty *prop, int switch_endian, FileData *fd)
2007 {
2008         ListBase *lb = &prop->data.group;
2009         IDProperty *loop;
2010         
2011         link_list(fd, lb);
2012         
2013         /*Link child id properties now*/
2014         for (loop=prop->data.group.first; loop; loop=loop->next) {
2015                 IDP_DirectLinkProperty(loop, switch_endian, fd);
2016         }
2017 }
2018
2019 static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd)
2020 {
2021         switch (prop->type) {
2022                 case IDP_GROUP:
2023                         IDP_DirectLinkGroup(prop, switch_endian, fd);
2024                         break;
2025                 case IDP_STRING:
2026                         IDP_DirectLinkString(prop, fd);
2027                         break;
2028                 case IDP_ARRAY:
2029                         IDP_DirectLinkArray(prop, switch_endian, fd);
2030                         break;
2031                 case IDP_IDPARRAY:
2032                         IDP_DirectLinkIDPArray(prop, switch_endian, fd);
2033                         break;
2034                 case IDP_DOUBLE:
2035                         /* erg, stupid doubles.  since I'm storing them
2036                          * in the same field as int val; val2 in the
2037                          * IDPropertyData struct, they have to deal with
2038                          * endianness specifically
2039                          *
2040                          * in theory, val and val2 would've already been swapped
2041                          * if switch_endian is true, so we have to first unswap
2042                          * them then reswap them as a single 64-bit entity.
2043                          */
2044                         
2045                         if (switch_endian) {
2046                                 BLI_endian_switch_int32(&prop->data.val);
2047                                 BLI_endian_switch_int32(&prop->data.val2);
2048                                 BLI_endian_switch_int64((int64_t *)&prop->data.val);
2049                         }
2050                         
2051                         break;
2052         }
2053 }
2054
2055 #define IDP_DirectLinkGroup_OrFree(prop, switch_endian, fd) \
2056        _IDP_DirectLinkGroup_OrFree(prop, switch_endian, fd, __func__)
2057
2058 static void _IDP_DirectLinkGroup_OrFree(IDProperty **prop, int switch_endian, FileData *fd,
2059                                         const char *caller_func_id)
2060 {
2061         if (*prop) {
2062                 if ((*prop)->type == IDP_GROUP) {
2063                         IDP_DirectLinkGroup(*prop, switch_endian, fd);
2064                 }
2065                 else {
2066                         /* corrupt file! */
2067                         printf("%s: found non group data, freeing type %d!\n",
2068                                caller_func_id, (*prop)->type);
2069                         /* don't risk id, data's likely corrupt. */
2070                         // IDP_FreeProperty(*prop);
2071                         *prop = NULL;
2072                 }
2073         }
2074 }
2075
2076 /* stub function */
2077 static void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endian), FileData *UNUSED(fd))
2078 {
2079 }
2080
2081 /* ************ READ IMAGE PREVIEW *************** */
2082
2083 static PreviewImage *direct_link_preview_image(FileData *fd, PreviewImage *old_prv)
2084 {
2085         PreviewImage *prv = newdataadr(fd, old_prv);
2086         
2087         if (prv) {
2088                 int i;
2089                 for (i = 0; i < NUM_ICON_SIZES; ++i) {
2090                         if (prv->rect[i]) {
2091                                 prv->rect[i] = newdataadr(fd, prv->rect[i]);
2092                         }
2093                         prv->gputexture[i] = NULL;
2094                 }
2095         }
2096         
2097         return prv;
2098 }
2099
2100 /* ************ READ ID *************** */
2101
2102 static void direct_link_id(FileData *fd, ID *id)
2103 {
2104         /*link direct data of ID properties*/
2105         if (id->properties) {
2106                 id->properties = newdataadr(fd, id->properties);
2107                 /* this case means the data was written incorrectly, it should not happen */
2108                 IDP_DirectLinkGroup_OrFree(&id->properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2109         }
2110 }
2111
2112 /* ************ READ CurveMapping *************** */
2113
2114 /* cuma itself has been read! */
2115 static void direct_link_curvemapping(FileData *fd, CurveMapping *cumap)
2116 {
2117         int a;
2118         
2119         /* flag seems to be able to hang? Maybe old files... not bad to clear anyway */
2120         cumap->flag &= ~CUMA_PREMULLED;
2121         
2122         for (a = 0; a < CM_TOT; a++) {
2123                 cumap->cm[a].curve = newdataadr(fd, cumap->cm[a].curve);
2124                 cumap->cm[a].table = NULL;
2125                 cumap->cm[a].premultable = NULL;
2126         }
2127 }
2128
2129 /* ************ READ Brush *************** */
2130 /* library brush linking after fileread */
2131 static void lib_link_brush(FileData *fd, Main *main)
2132 {
2133         Brush *brush;
2134         
2135         /* only link ID pointers */
2136         for (brush = main->brush.first; brush; brush = brush->id.next) {
2137                 if (brush->id.flag & LIB_NEED_LINK) {
2138                         brush->id.flag -= LIB_NEED_LINK;
2139                         
2140                         brush->mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mtex.tex);
2141                         brush->mask_mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mask_mtex.tex);
2142                         brush->clone.image = newlibadr_us(fd, brush->id.lib, brush->clone.image);
2143                         brush->paint_curve = newlibadr_us(fd, brush->id.lib, brush->paint_curve);
2144                 }
2145         }
2146 }
2147
2148 static void direct_link_brush(FileData *fd, Brush *brush)
2149 {
2150         /* brush itself has been read */
2151
2152         /* fallof curve */
2153         brush->curve = newdataadr(fd, brush->curve);
2154         brush->gradient = newdataadr(fd, brush->gradient);
2155
2156         if (brush->curve)
2157                 direct_link_curvemapping(fd, brush->curve);
2158         else
2159                 BKE_brush_curve_preset(brush, CURVE_PRESET_SHARP);
2160
2161         brush->preview = NULL;
2162         brush->icon_imbuf = NULL;
2163 }
2164
2165 /* ************ READ Palette *************** */
2166 static void lib_link_palette(FileData *UNUSED(fd), Main *main)
2167 {
2168         Palette *palette;
2169
2170         /* only link ID pointers */
2171         for (palette = main->palettes.first; palette; palette = palette->id.next) {
2172                 if (palette->id.flag & LIB_NEED_LINK) {
2173                         palette->id.flag -= LIB_NEED_LINK;
2174                 }
2175         }
2176 }
2177
2178 static void direct_link_palette(FileData *fd, Palette *palette)
2179 {
2180         /* palette itself has been read */
2181         link_list(fd, &palette->colors);
2182 }
2183
2184 static void lib_link_paint_curve(FileData *UNUSED(fd), Main *main)
2185 {
2186         PaintCurve *pc;
2187
2188         /* only link ID pointers */
2189         for (pc = main->paintcurves.first; pc; pc = pc->id.next) {
2190                 if (pc->id.flag & LIB_NEED_LINK) {
2191                         pc->id.flag -= LIB_NEED_LINK;
2192                 }
2193         }
2194 }
2195
2196 static void direct_link_paint_curve(FileData *fd, PaintCurve *pc)
2197 {
2198         pc->points = newdataadr(fd, pc->points);
2199 }
2200
2201
2202 static void direct_link_script(FileData *UNUSED(fd), Script *script)
2203 {
2204         script->id.us = 1;
2205         SCRIPT_SET_NULL(script);
2206 }
2207
2208
2209 /* ************ READ PACKEDFILE *************** */
2210
2211 static PackedFile *direct_link_packedfile(FileData *fd, PackedFile *oldpf)
2212 {
2213         PackedFile *pf = newpackedadr(fd, oldpf);
2214
2215         if (pf) {
2216                 pf->data = newpackedadr(fd, pf->data);
2217         }
2218         
2219         return pf;
2220 }
2221
2222 /* ************ READ ANIMATION STUFF ***************** */
2223
2224 /* Legacy Data Support (for Version Patching) ----------------------------- */
2225
2226 // XXX deprecated - old animation system
2227 static void lib_link_ipo(FileData *fd, Main *main)
2228 {
2229         Ipo *ipo;
2230         
2231         for (ipo = main->ipo.first; ipo; ipo = ipo->id.next) {
2232                 if (ipo->id.flag & LIB_NEED_LINK) {
2233                         IpoCurve *icu;
2234                         for (icu = ipo->curve.first; icu; icu = icu->next) {
2235                                 if (icu->driver)
2236                                         icu->driver->ob = newlibadr(fd, ipo->id.lib, icu->driver->ob);
2237                         }
2238                         ipo->id.flag -= LIB_NEED_LINK;
2239                 }
2240         }
2241 }
2242
2243 // XXX deprecated - old animation system
2244 static void direct_link_ipo(FileData *fd, Ipo *ipo)
2245 {
2246         IpoCurve *icu;
2247
2248         link_list(fd, &(ipo->curve));
2249         
2250         for (icu = ipo->curve.first; icu; icu = icu->next) {
2251                 icu->bezt = newdataadr(fd, icu->bezt);
2252                 icu->bp = newdataadr(fd, icu->bp);
2253                 icu->driver = newdataadr(fd, icu->driver);
2254         }
2255 }
2256
2257 // XXX deprecated - old animation system
2258 static void lib_link_nlastrips(FileData *fd, ID *id, ListBase *striplist)
2259 {
2260         bActionStrip *strip;
2261         bActionModifier *amod;
2262         
2263         for (strip=striplist->first; strip; strip=strip->next) {
2264                 strip->object = newlibadr(fd, id->lib, strip->object);
2265                 strip->act = newlibadr_us(fd, id->lib, strip->act);
2266                 strip->ipo = newlibadr(fd, id->lib, strip->ipo);
2267                 for (amod = strip->modifiers.first; amod; amod = amod->next)
2268                         amod->ob = newlibadr(fd, id->lib, amod->ob);
2269         }
2270 }
2271
2272 // XXX deprecated - old animation system
2273 static void direct_link_nlastrips(FileData *fd, ListBase *strips)
2274 {
2275         bActionStrip *strip;
2276         
2277         link_list(fd, strips);
2278         
2279         for (strip = strips->first; strip; strip = strip->next)
2280                 link_list(fd, &strip->modifiers);
2281 }
2282
2283 // XXX deprecated - old animation system
2284 static void lib_link_constraint_channels(FileData *fd, ID *id, ListBase *chanbase)
2285 {
2286         bConstraintChannel *chan;
2287
2288         for (chan=chanbase->first; chan; chan=chan->next) {
2289                 chan->ipo = newlibadr_us(fd, id->lib, chan->ipo);
2290         }
2291 }
2292
2293 /* Data Linking ----------------------------- */
2294
2295 static void lib_link_fmodifiers(FileData *fd, ID *id, ListBase *list)
2296 {
2297         FModifier *fcm;
2298         
2299         for (fcm = list->first; fcm; fcm = fcm->next) {
2300                 /* data for specific modifiers */
2301                 switch (fcm->type) {
2302                         case FMODIFIER_TYPE_PYTHON:
2303                         {
2304                                 FMod_Python *data = (FMod_Python *)fcm->data;
2305                                 data->script = newlibadr(fd, id->lib, data->script);
2306
2307                                 break;
2308                         }
2309                 }
2310         }
2311 }
2312
2313 static void lib_link_fcurves(FileData *fd, ID *id, ListBase *list) 
2314 {
2315         FCurve *fcu;
2316         
2317         if (list == NULL)
2318                 return;
2319         
2320         /* relink ID-block references... */
2321         for (fcu = list->first; fcu; fcu = fcu->next) {
2322                 /* driver data */
2323                 if (fcu->driver) {
2324                         ChannelDriver *driver = fcu->driver;
2325                         DriverVar *dvar;
2326                         
2327                         for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
2328                                 DRIVER_TARGETS_LOOPER(dvar)
2329                                 {
2330                                         /* only relink if still used */
2331                                         if (tarIndex < dvar->num_targets)
2332                                                 dtar->id = newlibadr(fd, id->lib, dtar->id); 
2333                                         else
2334                                                 dtar->id = NULL;
2335                                 }
2336                                 DRIVER_TARGETS_LOOPER_END
2337                         }
2338                 }
2339                 
2340                 /* modifiers */
2341                 lib_link_fmodifiers(fd, id, &fcu->modifiers);
2342         }
2343 }
2344
2345
2346 /* NOTE: this assumes that link_list has already been called on the list */
2347 static void direct_link_fmodifiers(FileData *fd, ListBase *list)
2348 {
2349         FModifier *fcm;
2350         
2351         for (fcm = list->first; fcm; fcm = fcm->next) {
2352                 /* relink general data */
2353                 fcm->data  = newdataadr(fd, fcm->data);
2354                 
2355                 /* do relinking of data for specific types */
2356                 switch (fcm->type) {
2357                         case FMODIFIER_TYPE_GENERATOR:
2358                         {
2359                                 FMod_Generator *data = (FMod_Generator *)fcm->data;
2360                                 
2361                                 data->coefficients = newdataadr(fd, data->coefficients);
2362                                 
2363                                 if (fd->flags & FD_FLAGS_SWITCH_ENDIAN) {
2364                                         BLI_endian_switch_float_array(data->coefficients, data->arraysize);
2365                                 }
2366
2367                                 break;
2368                         }
2369                         case FMODIFIER_TYPE_ENVELOPE:
2370                         {
2371                                 FMod_Envelope *data=  (FMod_Envelope *)fcm->data;
2372                                 
2373                                 data->data= newdataadr(fd, data->data);
2374
2375                                 break;
2376                         }
2377                         case FMODIFIER_TYPE_PYTHON:
2378                         {
2379                                 FMod_Python *data = (FMod_Python *)fcm->data;
2380                                 
2381                                 data->prop = newdataadr(fd, data->prop);
2382                                 IDP_DirectLinkGroup_OrFree(&data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2383
2384                                 break;
2385                         }
2386                 }
2387         }
2388 }
2389
2390 /* NOTE: this assumes that link_list has already been called on the list */
2391 static void direct_link_fcurves(FileData *fd, ListBase *list)
2392 {
2393         FCurve *fcu;
2394         
2395         /* link F-Curve data to F-Curve again (non ID-libs) */
2396         for (fcu = list->first; fcu; fcu = fcu->next) {
2397                 /* curve data */
2398                 fcu->bezt = newdataadr(fd, fcu->bezt);
2399                 fcu->fpt = newdataadr(fd, fcu->fpt);
2400                 
2401                 /* rna path */
2402                 fcu->rna_path = newdataadr(fd, fcu->rna_path);
2403                 
2404                 /* group */
2405                 fcu->grp = newdataadr_ex(fd, fcu->grp, false);
2406                 
2407                 /* clear disabled flag - allows disabled drivers to be tried again ([#32155]),
2408                  * but also means that another method for "reviving disabled F-Curves" exists
2409                  */
2410                 fcu->flag &= ~FCURVE_DISABLED;
2411                 
2412                 /* driver */
2413                 fcu->driver= newdataadr(fd, fcu->driver);
2414                 if (fcu->driver) {
2415                         ChannelDriver *driver= fcu->driver;
2416                         DriverVar *dvar;
2417                         
2418                         /* compiled expression data will need to be regenerated (old pointer may still be set here) */
2419                         driver->expr_comp = NULL;
2420                         
2421                         /* give the driver a fresh chance - the operating environment may be different now 
2422                          * (addons, etc. may be different) so the driver namespace may be sane now [#32155]
2423                          */
2424                         driver->flag &= ~DRIVER_FLAG_INVALID;
2425                         
2426                         /* relink variables, targets and their paths */
2427                         link_list(fd, &driver->variables);
2428                         for (dvar= driver->variables.first; dvar; dvar= dvar->next) {
2429                                 DRIVER_TARGETS_LOOPER(dvar)
2430                                 {
2431                                         /* only relink the targets being used */
2432                                         if (tarIndex < dvar->num_targets)
2433                                                 dtar->rna_path = newdataadr(fd, dtar->rna_path);
2434                                         else
2435                                                 dtar->rna_path = NULL;
2436                                 }
2437                                 DRIVER_TARGETS_LOOPER_END
2438                         }
2439                 }
2440                 
2441                 /* modifiers */
2442                 link_list(fd, &fcu->modifiers);
2443                 direct_link_fmodifiers(fd, &fcu->modifiers);
2444         }
2445 }
2446
2447
2448 static void lib_link_action(FileData *fd, Main *main)
2449 {
2450         bAction *act;
2451         bActionChannel *chan;
2452
2453         for (act = main->action.first; act; act = act->id.next) {
2454                 if (act->id.flag & LIB_NEED_LINK) {
2455                         act->id.flag -= LIB_NEED_LINK;
2456                         
2457 // XXX deprecated - old animation system <<<
2458                         for (chan=act->chanbase.first; chan; chan=chan->next) {
2459                                 chan->ipo = newlibadr_us(fd, act->id.lib, chan->ipo);
2460                                 lib_link_constraint_channels(fd, &act->id, &chan->constraintChannels);
2461                         }
2462 // >>> XXX deprecated - old animation system
2463                         
2464                         lib_link_fcurves(fd, &act->id, &act->curves);
2465                 }
2466         }
2467 }
2468
2469 static void direct_link_action(FileData *fd, bAction *act)
2470 {
2471         bActionChannel *achan; // XXX deprecated - old animation system
2472         bActionGroup *agrp;
2473
2474         link_list(fd, &act->curves);
2475         link_list(fd, &act->chanbase); // XXX deprecated - old animation system
2476         link_list(fd, &act->groups);
2477         link_list(fd, &act->markers);
2478
2479 // XXX deprecated - old animation system <<<
2480         for (achan = act->chanbase.first; achan; achan=achan->next) {
2481                 achan->grp = newdataadr(fd, achan->grp);
2482                 
2483                 link_list(fd, &achan->constraintChannels);
2484         }
2485 // >>> XXX deprecated - old animation system
2486
2487         direct_link_fcurves(fd, &act->curves);
2488         
2489         for (agrp = act->groups.first; agrp; agrp= agrp->next) {
2490                 agrp->channels.first= newdataadr(fd, agrp->channels.first);
2491                 agrp->channels.last= newdataadr(fd, agrp->channels.last);
2492         }
2493 }
2494
2495 static void lib_link_nladata_strips(FileData *fd, ID *id, ListBase *list)
2496 {
2497         NlaStrip *strip;
2498         
2499         for (strip = list->first; strip; strip = strip->next) {
2500                 /* check strip's children */
2501                 lib_link_nladata_strips(fd, id, &strip->strips);
2502                 
2503                 /* check strip's F-Curves */
2504                 lib_link_fcurves(fd, id, &strip->fcurves);
2505                 
2506                 /* reassign the counted-reference to action */
2507                 strip->act = newlibadr_us(fd, id->lib, strip->act);
2508                 
2509                 /* fix action id-root (i.e. if it comes from a pre 2.57 .blend file) */
2510                 if ((strip->act) && (strip->act->idroot == 0))
2511                         strip->act->idroot = GS(id->name);
2512         }
2513 }
2514
2515 static void lib_link_nladata(FileData *fd, ID *id, ListBase *list)
2516 {
2517         NlaTrack *nlt;
2518         
2519         /* we only care about the NLA strips inside the tracks */
2520         for (nlt = list->first; nlt; nlt = nlt->next) {
2521                 lib_link_nladata_strips(fd, id, &nlt->strips);
2522         }
2523 }
2524
2525 /* This handles Animato NLA-Strips linking 
2526  * NOTE: this assumes that link_list has already been called on the list 
2527  */
2528 static void direct_link_nladata_strips(FileData *fd, ListBase *list)
2529 {
2530         NlaStrip *strip;
2531         
2532         for (strip = list->first; strip; strip = strip->next) {
2533                 /* strip's child strips */
2534                 link_list(fd, &strip->strips);
2535                 direct_link_nladata_strips(fd, &strip->strips);
2536                 
2537                 /* strip's F-Curves */
2538                 link_list(fd, &strip->fcurves);
2539                 direct_link_fcurves(fd, &strip->fcurves);
2540                 
2541                 /* strip's F-Modifiers */
2542                 link_list(fd, &strip->modifiers);
2543                 direct_link_fmodifiers(fd, &strip->modifiers);
2544         }
2545 }
2546
2547 /* NOTE: this assumes that link_list has already been called on the list */
2548 static void direct_link_nladata(FileData *fd, ListBase *list)
2549 {
2550         NlaTrack *nlt;
2551         
2552         for (nlt = list->first; nlt; nlt = nlt->next) {
2553                 /* relink list of strips */
2554                 link_list(fd, &nlt->strips);
2555                 
2556                 /* relink strip data */
2557                 direct_link_nladata_strips(fd, &nlt->strips);
2558         }
2559 }
2560
2561 /* ------- */
2562
2563 static void lib_link_keyingsets(FileData *fd, ID *id, ListBase *list)
2564 {
2565         KeyingSet *ks;
2566         KS_Path *ksp;
2567         
2568         /* here, we're only interested in the ID pointer stored in some of the paths */
2569         for (ks = list->first; ks; ks = ks->next) {
2570                 for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
2571                         ksp->id= newlibadr(fd, id->lib, ksp->id); 
2572                 }
2573         }
2574 }
2575
2576 /* NOTE: this assumes that link_list has already been called on the list */
2577 static void direct_link_keyingsets(FileData *fd, ListBase *list)
2578 {
2579         KeyingSet *ks;
2580         KS_Path *ksp;
2581         
2582         /* link KeyingSet data to KeyingSet again (non ID-libs) */
2583         for (ks = list->first; ks; ks = ks->next) {
2584                 /* paths */
2585                 link_list(fd, &ks->paths);
2586                 
2587                 for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
2588                         /* rna path */
2589                         ksp->rna_path= newdataadr(fd, ksp->rna_path);
2590                 }
2591         }
2592 }
2593
2594 /* ------- */
2595
2596 static void lib_link_animdata(FileData *fd, ID *id, AnimData *adt)
2597 {
2598         if (adt == NULL)
2599                 return;
2600         
2601         /* link action data */
2602         adt->action= newlibadr_us(fd, id->lib, adt->action);
2603         adt->tmpact= newlibadr_us(fd, id->lib, adt->tmpact);
2604         
2605         /* fix action id-roots (i.e. if they come from a pre 2.57 .blend file) */
2606         if ((adt->action) && (adt->action->idroot == 0))
2607                 adt->action->idroot = GS(id->name);
2608         if ((adt->tmpact) && (adt->tmpact->idroot == 0))
2609                 adt->tmpact->idroot = GS(id->name);
2610         
2611         /* link drivers */
2612         lib_link_fcurves(fd, id, &adt->drivers);
2613         
2614         /* overrides don't have lib-link for now, so no need to do anything */
2615         
2616         /* link NLA-data */
2617         lib_link_nladata(fd, id, &adt->nla_tracks);
2618 }
2619
2620 static void direct_link_animdata(FileData *fd, AnimData *adt)
2621 {
2622         /* NOTE: must have called newdataadr already before doing this... */
2623         if (adt == NULL)
2624                 return;
2625         
2626         /* link drivers */
2627         link_list(fd, &adt->drivers);
2628         direct_link_fcurves(fd, &adt->drivers);
2629         
2630         /* link overrides */
2631         // TODO...
2632         
2633         /* link NLA-data */
2634         link_list(fd, &adt->nla_tracks);
2635         direct_link_nladata(fd, &adt->nla_tracks);
2636         
2637         /* relink active track/strip - even though strictly speaking this should only be used
2638          * if we're in 'tweaking mode', we need to be able to have this loaded back for
2639          * undo, but also since users may not exit tweakmode before saving (#24535)
2640          */
2641         // TODO: it's not really nice that anyone should be able to save the file in this
2642         //              state, but it's going to be too hard to enforce this single case...
2643         adt->act_track = newdataadr(fd, adt->act_track);
2644         adt->actstrip = newdataadr(fd, adt->actstrip);
2645 }       
2646
2647 /* ************ READ MOTION PATHS *************** */
2648
2649 /* direct data for cache */
2650 static void direct_link_motionpath(FileData *fd, bMotionPath *mpath)
2651 {
2652         /* sanity check */
2653         if (mpath == NULL)
2654                 return;
2655         
2656         /* relink points cache */
2657         mpath->points = newdataadr(fd, mpath->points);
2658 }
2659
2660 /* ************ READ NODE TREE *************** */
2661
2662 static void lib_link_node_socket(FileData *fd, ID *UNUSED(id), bNodeSocket *sock)
2663 {
2664         /* Link ID Properties -- and copy this comment EXACTLY for easy finding
2665          * of library blocks that implement this.*/
2666         if (sock->prop)
2667                 IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2668 }
2669
2670 /* singe node tree (also used for material/scene trees), ntree is not NULL */
2671 static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree)
2672 {
2673         bNode *node;
2674         bNodeSocket *sock;
2675         
2676         if (ntree->adt) lib_link_animdata(fd, &ntree->id, ntree->adt);
2677         
2678         ntree->gpd = newlibadr_us(fd, id->lib, ntree->gpd);
2679         
2680         for (node = ntree->nodes.first; node; node = node->next) {
2681                 /* Link ID Properties -- and copy this comment EXACTLY for easy finding
2682                  * of library blocks that implement this.*/
2683                 if (node->prop)
2684                         IDP_LibLinkProperty(node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2685                 
2686                 node->id= newlibadr_us(fd, id->lib, node->id);
2687
2688                 for (sock = node->inputs.first; sock; sock = sock->next)
2689                         lib_link_node_socket(fd, id, sock);
2690                 for (sock = node->outputs.first; sock; sock = sock->next)
2691                         lib_link_node_socket(fd, id, sock);
2692         }
2693         
2694         for (sock = ntree->inputs.first; sock; sock = sock->next)
2695                 lib_link_node_socket(fd, id, sock);
2696         for (sock = ntree->outputs.first; sock; sock = sock->next)
2697                 lib_link_node_socket(fd, id, sock);
2698 }
2699
2700 /* library ntree linking after fileread */
2701 static void lib_link_nodetree(FileData *fd, Main *main)
2702 {
2703         bNodeTree *ntree;
2704         
2705         /* only link ID pointers */
2706         for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
2707                 if (ntree->id.flag & LIB_NEED_LINK) {
2708                         ntree->id.flag -= LIB_NEED_LINK;
2709                         lib_link_ntree(fd, &ntree->id, ntree);
2710                 }
2711         }
2712 }
2713
2714 /* get node tree stored locally in other IDs */
2715 static bNodeTree *nodetree_from_id(ID *id)
2716 {
2717         if (!id)
2718                 return NULL;
2719         switch (GS(id->name)) {
2720                 case ID_SCE: return ((Scene *)id)->nodetree;
2721                 case ID_MA: return ((Material *)id)->nodetree;
2722                 case ID_WO: return ((World *)id)->nodetree;
2723                 case ID_LA: return ((Lamp *)id)->nodetree;
2724                 case ID_TE: return ((Tex *)id)->nodetree;
2725                 case ID_LS: return ((FreestyleLineStyle *)id)->nodetree;
2726         }
2727         return NULL;
2728 }
2729
2730 /* updates group node socket identifier so that
2731  * external links to/from the group node are preserved.
2732  */
2733 static void lib_node_do_versions_group_indices(bNode *gnode)
2734 {
2735         bNodeTree *ngroup = (bNodeTree*)gnode->id;
2736         bNodeSocket *sock;
2737         bNodeLink *link;
2738         
2739         for (sock=gnode->outputs.first; sock; sock = sock->next) {
2740                 int old_index = sock->to_index;
2741                 
2742                 for (link = ngroup->links.first; link; link = link->next) {
2743                         if (link->tonode == NULL && link->fromsock->own_index == old_index) {
2744                                 strcpy(sock->identifier, link->fromsock->identifier);
2745                                 /* deprecated */
2746                                 sock->own_index = link->fromsock->own_index;
2747                                 sock->to_index = 0;
2748                                 sock->groupsock = NULL;
2749                         }
2750                 }
2751         }
2752         for (sock=gnode->inputs.first; sock; sock = sock->next) {
2753                 int old_index = sock->to_index;
2754                 
2755                 for (link = ngroup->links.first; link; link = link->next) {
2756                         if (link->fromnode == NULL && link->tosock->own_index == old_index) {
2757                                 strcpy(sock->identifier, link->tosock->identifier);
2758                                 /* deprecated */
2759                                 sock->own_index = link->tosock->own_index;
2760                                 sock->to_index = 0;
2761                                 sock->groupsock = NULL;
2762                         }
2763                 }
2764         }
2765 }
2766
2767 /* verify types for nodes and groups, all data has to be read */
2768 /* open = 0: appending/linking, open = 1: open new file (need to clean out dynamic
2769  * typedefs */
2770 static void lib_verify_nodetree(Main *main, int UNUSED(open))
2771 {
2772         bNodeTree *ntree;
2773         
2774         /* this crashes blender on undo/redo */
2775 #if 0
2776                 if (open == 1) {
2777                         reinit_nodesystem();
2778                 }
2779 #endif
2780         
2781         /* set node->typeinfo pointers */
2782         FOREACH_NODETREE(main, ntree, id) {
2783                 ntreeSetTypes(NULL, ntree);
2784         } FOREACH_NODETREE_END
2785         
2786         /* verify static socket templates */
2787         FOREACH_NODETREE(main, ntree, id) {
2788                 bNode *node;
2789                 for (node=ntree->nodes.first; node; node=node->next)
2790                         node_verify_socket_templates(ntree, node);
2791         } FOREACH_NODETREE_END
2792         
2793         {
2794                 bool has_old_groups = false;
2795                 /* XXX this should actually be part of do_versions, but since we need
2796                  * finished library linking, it is not possible there. Instead in do_versions
2797                  * we have set the NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2 flag, so at this point we can do the
2798                  * actual group node updates.
2799                  */
2800                 for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
2801                         if (ntree->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2)
2802                                 has_old_groups = 1;
2803                 }
2804                 
2805                 if (has_old_groups) {
2806                         FOREACH_NODETREE(main, ntree, id) {
2807                                 /* updates external links for all group nodes in a tree */
2808                                 bNode *node;
2809                                 for (node = ntree->nodes.first; node; node = node->next) {
2810                                         if (node->type == NODE_GROUP) {
2811                                                 bNodeTree *ngroup = (bNodeTree*)node->id;
2812                                                 if (ngroup && (ngroup->flag & NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2))
2813                                                         lib_node_do_versions_group_indices(node);
2814                                         }
2815                                 }
2816                         } FOREACH_NODETREE_END
2817                 }
2818                 
2819                 for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next)
2820                         ntree->flag &= ~NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2;
2821         }
2822         
2823         {
2824                 /* Convert the previously used ntree->inputs/ntree->outputs lists to interface nodes.
2825                  * Pre 2.56.2 node trees automatically have all unlinked sockets exposed already
2826                  * (see NTREE_DO_VERSIONS_GROUP_EXPOSE_2_56_2).
2827                  *
2828                  * XXX this should actually be part of do_versions,
2829                  * but needs valid typeinfo pointers to create interface nodes.
2830                  *
2831                  * Note: theoretically only needed in node groups (main->nodetree),
2832                  * but due to a temporary bug such links could have been added in all trees,
2833                  * so have to clean up all of them ...
2834                  */
2835                 
2836                 FOREACH_NODETREE(main, ntree, id) {
2837                         if (ntree->flag & NTREE_DO_VERSIONS_CUSTOMNODES_GROUP) {
2838                                 bNode *input_node = NULL, *output_node = NULL;
2839                                 int num_inputs = 0, num_outputs = 0;
2840                                 bNodeLink *link, *next_link;
2841                                 /* Only create new interface nodes for actual older files.
2842                                  * New file versions already have input/output nodes with duplicate links,
2843                                  * in that case just remove the invalid links.
2844                                  */
2845                                 const bool create_io_nodes = (ntree->flag & NTREE_DO_VERSIONS_CUSTOMNODES_GROUP_CREATE_INTERFACE) != 0;
2846                                 
2847                                 float input_locx = 1000000.0f, input_locy = 0.0f;
2848                                 float output_locx = -1000000.0f, output_locy = 0.0f;
2849                                 /* rough guess, not nice but we don't have access to UI constants here ... */
2850                                 static const float offsetx = 42 + 3*20 + 20;
2851                                 /*static const float offsety = 0.0f;*/
2852                                 
2853                                 if (create_io_nodes) {
2854                                         if (ntree->inputs.first)
2855                                                 input_node = nodeAddStaticNode(NULL, ntree, NODE_GROUP_INPUT);
2856                                         
2857                                         if (ntree->outputs.first)
2858                                                 output_node = nodeAddStaticNode(NULL, ntree, NODE_GROUP_OUTPUT);
2859                                 }
2860                                 
2861                                 /* Redirect links from/to the node tree interface to input/output node.
2862                                  * If the fromnode/tonode pointers are NULL, this means a link from/to
2863                                  * the ntree interface sockets, which need to be redirected to new interface nodes.
2864                                  */
2865                                 for (link = ntree->links.first; link; link = next_link) {
2866                                         bool free_link = false;
2867                                         next_link = link->next;
2868                                         
2869                                         if (link->fromnode == NULL) {
2870                                                 if (input_node) {
2871                                                         link->fromnode = input_node;
2872                                                         link->fromsock = node_group_input_find_socket(input_node, link->fromsock->identifier);
2873                                                         ++num_inputs;
2874                                                         
2875                                                         if (link->tonode) {
2876                                                                 if (input_locx > link->tonode->locx - offsetx)
2877                                                                         input_locx = link->tonode->locx - offsetx;
2878                                                                 input_locy += link->tonode->locy;
2879                                                         }
2880                                                 }
2881                                                 else {
2882                                                         free_link = true;
2883                                                 }
2884                                         }
2885                                         
2886                                         if (link->tonode == NULL) {
2887                                                 if (output_node) {
2888                                                         link->tonode = output_node;
2889                                                         link->tosock = node_group_output_find_socket(output_node, link->tosock->identifier);
2890                                                         ++num_outputs;
2891                                                         
2892                                                         if (link->fromnode) {
2893                                                                 if (output_locx < link->fromnode->locx + offsetx)
2894                                                                         output_locx = link->fromnode->locx + offsetx;
2895                                                                 output_locy += link->fromnode->locy;
2896                                                         }
2897                                                 }
2898                                                 else {
2899                                                         free_link = true;
2900                                                 }
2901                                         }
2902                                         
2903                                         if (free_link)
2904                                                 nodeRemLink(ntree, link);
2905                                 }
2906                                 
2907                                 if (num_inputs > 0) {
2908                                         input_locy /= num_inputs;
2909                                         input_node->locx = input_locx;
2910                                         input_node->locy = input_locy;
2911                                 }
2912                                 if (num_outputs > 0) {
2913                                         output_locy /= num_outputs;
2914                                         output_node->locx = output_locx;
2915                                         output_node->locy = output_locy;
2916                                 }
2917                                 
2918                                 /* clear do_versions flags */
2919                                 ntree->flag &= ~(NTREE_DO_VERSIONS_CUSTOMNODES_GROUP | NTREE_DO_VERSIONS_CUSTOMNODES_GROUP_CREATE_INTERFACE);
2920                         }
2921                 }
2922                 FOREACH_NODETREE_END
2923         }
2924         
2925         /* verify all group user nodes */
2926         for (ntree = main->nodetree.first; ntree; ntree = ntree->id.next) {
2927                 ntreeVerifyNodes(main, &ntree->id);
2928         }
2929         
2930         /* make update calls where necessary */
2931         {
2932                 FOREACH_NODETREE(main, ntree, id) {
2933                         /* make an update call for the tree */
2934                         ntreeUpdateTree(main, ntree);
2935                 } FOREACH_NODETREE_END
2936         }
2937 }
2938
2939 static void direct_link_node_socket(FileData *fd, bNodeSocket *sock)
2940 {
2941         sock->prop = newdataadr(fd, sock->prop);
2942         IDP_DirectLinkGroup_OrFree(&sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2943         
2944         sock->link = newdataadr(fd, sock->link);
2945         sock->typeinfo = NULL;
2946         sock->storage = newdataadr(fd, sock->storage);
2947         sock->default_value = newdataadr(fd, sock->default_value);
2948         sock->cache = NULL;
2949 }
2950
2951 /* ntree itself has been read! */
2952 static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
2953 {
2954         /* note: writing and reading goes in sync, for speed */
2955         bNode *node;
2956         bNodeSocket *sock;
2957         bNodeLink *link;
2958         
2959         ntree->init = 0;                /* to set callbacks and force setting types */
2960         ntree->is_updating = false;
2961         ntree->typeinfo= NULL;
2962         ntree->interface_type = NULL;
2963         
2964         ntree->progress = NULL;
2965         ntree->execdata = NULL;
2966         ntree->duplilock = NULL;
2967
2968         ntree->adt = newdataadr(fd, ntree->adt);
2969         direct_link_animdata(fd, ntree->adt);
2970         
2971         ntree->id.flag &= ~(LIB_ID_RECALC|LIB_ID_RECALC_DATA);
2972
2973         link_list(fd, &ntree->nodes);
2974         for (node = ntree->nodes.first; node; node = node->next) {
2975                 node->typeinfo = NULL;
2976                 
2977                 link_list(fd, &node->inputs);
2978                 link_list(fd, &node->outputs);
2979                 
2980                 node->prop = newdataadr(fd, node->prop);
2981                 IDP_DirectLinkGroup_OrFree(&node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
2982                 
2983                 link_list(fd, &node->internal_links);
2984                 for (link = node->internal_links.first; link; link = link->next) {
2985                         link->fromnode = newdataadr(fd, link->fromnode);
2986                         link->fromsock = newdataadr(fd, link->fromsock);
2987                         link->tonode = newdataadr(fd, link->tonode);
2988                         link->tosock = newdataadr(fd, link->tosock);
2989                 }
2990                 
2991                 if (node->type == CMP_NODE_MOVIEDISTORTION) {
2992                         node->storage = newmclipadr(fd, node->storage);
2993                 }
2994                 else {
2995                         node->storage = newdataadr(fd, node->storage);
2996                 }
2997                 
2998                 if (node->storage) {
2999                         /* could be handlerized at some point */
3000                         if (ntree->type==NTREE_SHADER) {
3001                                 if (node->type==SH_NODE_CURVE_VEC || node->type==SH_NODE_CURVE_RGB) {
3002                                         direct_link_curvemapping(fd, node->storage);
3003                                 }
3004                                 else if (node->type==SH_NODE_SCRIPT) {
3005                                         NodeShaderScript *nss = (NodeShaderScript *) node->storage;
3006                                         nss->bytecode = newdataadr(fd, nss->bytecode);
3007                                 }
3008                         }
3009                         else if (ntree->type==NTREE_COMPOSIT) {
3010                                 if (ELEM(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT))
3011                                         direct_link_curvemapping(fd, node->storage);
3012                                 else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
3013                                         ((ImageUser *)node->storage)->ok = 1;
3014                         }
3015                         else if ( ntree->type==NTREE_TEXTURE) {
3016                                 if (node->type==TEX_NODE_CURVE_RGB || node->type==TEX_NODE_CURVE_TIME)
3017                                         direct_link_curvemapping(fd, node->storage);
3018                                 else if (node->type==TEX_NODE_IMAGE)
3019                                         ((ImageUser *)node->storage)->ok = 1;
3020                         }
3021                 }
3022         }
3023         link_list(fd, &ntree->links);
3024         
3025         /* and we connect the rest */
3026         for (node = ntree->nodes.first; node; node = node->next) {
3027                 node->parent = newdataadr(fd, node->parent);
3028                 node->lasty = 0;
3029                 
3030                 for (sock = node->inputs.first; sock; sock = sock->next)
3031                         direct_link_node_socket(fd, sock);
3032                 for (sock = node->outputs.first; sock; sock = sock->next)
3033                         direct_link_node_socket(fd, sock);
3034         }
3035         
3036         /* interface socket lists */
3037         link_list(fd, &ntree->inputs);
3038         link_list(fd, &ntree->outputs);
3039         for (sock = ntree->inputs.first; sock; sock = sock->next)
3040                 direct_link_node_socket(fd, sock);
3041         for (sock = ntree->outputs.first; sock; sock = sock->next)
3042                 direct_link_node_socket(fd, sock);
3043         
3044         for (link = ntree->links.first; link; link= link->next) {
3045                 link->fromnode = newdataadr(fd, link->fromnode);
3046                 link->tonode = newdataadr(fd, link->tonode);
3047                 link->fromsock = newdataadr(fd, link->fromsock);
3048                 link->tosock = newdataadr(fd, link->tosock);
3049         }
3050         
3051 #if 0
3052         if (ntree->previews) {
3053                 bNodeInstanceHash *new_previews = BKE_node_instance_hash_new("node previews");
3054                 bNodeInstanceHashIterator iter;
3055                 
3056                 NODE_INSTANCE_HASH_ITER(iter, ntree->previews) {
3057                         bNodePreview *preview = BKE_node_instance_hash_iterator_get_value(&iter);
3058                         if (preview) {
3059                                 bNodePreview *new_preview = newimaadr(fd, preview);
3060                                 if (new_preview) {
3061                                         bNodeInstanceKey key = BKE_node_instance_hash_iterator_get_key(&iter);
3062                                         BKE_node_instance_hash_insert(new_previews, key, new_preview);
3063                                 }
3064                         }
3065                 }
3066                 BKE_node_instance_hash_free(ntree->previews, NULL);
3067                 ntree->previews = new_previews;
3068         }
3069 #else
3070         /* XXX TODO */
3071         ntree->previews = NULL;
3072 #endif
3073         
3074         /* type verification is in lib-link */
3075 }
3076
3077 /* ************ READ ARMATURE ***************** */
3078
3079 /* temp struct used to transport needed info to lib_link_constraint_cb() */
3080 typedef struct tConstraintLinkData {
3081         FileData *fd;
3082         ID *id;
3083 } tConstraintLinkData;
3084 /* callback function used to relink constraint ID-links */
3085 static void lib_link_constraint_cb(bConstraint *UNUSED(con), ID **idpoin, bool is_reference, void *userdata)
3086 {
3087         tConstraintLinkData *cld= (tConstraintLinkData *)userdata;
3088         
3089         /* for reference types, we need to increment the usercounts on load... */
3090         if (is_reference) {
3091                 /* reference type - with usercount */
3092                 *idpoin = newlibadr_us(cld->fd, cld->id->lib, *idpoin);
3093         }
3094         else {
3095                 /* target type - no usercount needed */
3096                 *idpoin = newlibadr(cld->fd, cld->id->lib, *idpoin);
3097         }
3098 }
3099
3100 static void lib_link_constraints(FileData *fd, ID *id, ListBase *conlist)
3101 {
3102         tConstraintLinkData cld;
3103         bConstraint *con;
3104         
3105         /* legacy fixes */
3106         for (con = conlist->first; con; con=con->next) {
3107                 /* patch for error introduced by changing constraints (dunno how) */
3108                 /* if con->data type changes, dna cannot resolve the pointer! (ton) */
3109                 if (con->data == NULL) {
3110                         con->type = CONSTRAINT_TYPE_NULL;
3111                 }
3112                 /* own ipo, all constraints have it */
3113                 con->ipo = newlibadr_us(fd, id->lib, con->ipo); // XXX deprecated - old animation system
3114         }
3115         
3116         /* relink all ID-blocks used by the constraints */
3117         cld.fd = fd;
3118         cld.id = id;
3119         
3120         BKE_constraints_id_loop(conlist, lib_link_constraint_cb, &cld);
3121 }
3122
3123 static void direct_link_constraints(FileData *fd, ListBase *lb)
3124 {
3125         bConstraint *con;
3126         
3127         link_list(fd, lb);
3128         for (con=lb->first; con; con=con->next) {
3129                 con->data = newdataadr(fd, con->data);
3130                 
3131                 switch (con->type) {
3132                         case CONSTRAINT_TYPE_PYTHON:
3133                         {
3134                                 bPythonConstraint *data= con->data;
3135                                 
3136                                 link_list(fd, &data->targets);
3137                                 
3138                                 data->prop = newdataadr(fd, data->prop);
3139                                 IDP_DirectLinkGroup_OrFree(&data->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
3140                                 break;
3141                         }
3142                         case CONSTRAINT_TYPE_SPLINEIK:
3143                         {
3144                                 bSplineIKConstraint *data= con->data;
3145
3146                                 data->points= newdataadr(fd, data->points);
3147                                 break;
3148                         }
3149                         case CONSTRAINT_TYPE_KINEMATIC:
3150                         {
3151                                 bKinematicConstraint *data = con->data;
3152
3153                                 con->lin_error = 0.f;
3154                                 con->rot_error = 0.f;
3155
3156                                 /* version patch for runtime flag, was not cleared in some case */
3157                                 data->flag &= ~CONSTRAINT_IK_AUTO;
3158                                 break;
3159                         }
3160                         case CONSTRAINT_TYPE_CHILDOF:
3161                         {
3162                                 /* XXX version patch, in older code this flag wasn't always set, and is inherent to type */
3163                                 if (con->ownspace == CONSTRAINT_SPACE_POSE)
3164                                         con->flag |= CONSTRAINT_SPACEONCE;
3165                                 break;
3166                         }
3167                 }
3168         }
3169 }
3170
3171 static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
3172 {
3173         bPoseChannel *pchan;
3174         bArmature *arm = ob->data;
3175         int rebuild = 0;
3176         
3177         if (!pose || !arm)
3178                 return;
3179         
3180         /* always rebuild to match proxy or lib changes, but on Undo */
3181         if (fd->memfile == NULL)
3182                 if (ob->proxy || (ob->id.lib==NULL && arm->id.lib))