Merging r46111 through r46136 from trunk into soc-2011-tomato
[blender.git] / source / blender / blenloader / intern / writefile.c
index dc5546d38dd1e2df46da47a32b493be22bd7a662..0cd57ee545d1f83d80ad1cc35e49dfb05941cb9d 100644 (file)
@@ -133,6 +133,7 @@ Any case: direct data is ALWAYS after the lib block
 #include "DNA_world_types.h"
 #include "DNA_windowmanager_types.h"
 #include "DNA_movieclip_types.h"
 #include "DNA_world_types.h"
 #include "DNA_windowmanager_types.h"
 #include "DNA_movieclip_types.h"
+#include "DNA_mask_types.h"
 
 #include "MEM_guardedalloc.h" // MEM_freeN
 #include "BLI_bitmap.h"
 
 #include "MEM_guardedalloc.h" // MEM_freeN
 #include "BLI_bitmap.h"
@@ -204,7 +205,7 @@ static WriteData *writedata_new(int file)
        return wd;
 }
 
        return wd;
 }
 
-static void writedata_do_write(WriteData *wd, void *mem, int memlen)
+static void writedata_do_write(WriteData *wd, const void *mem, int memlen)
 {
        if ((wd == NULL) || wd->error || (mem == NULL) || memlen < 1) return;
        if (wd->error) return;
 {
        if ((wd == NULL) || wd->error || (mem == NULL) || memlen < 1) return;
        if (wd->error) return;
@@ -239,7 +240,7 @@ static void writedata_free(WriteData *wd)
  
 #define MYWRITE_FLUSH          NULL
 
  
 #define MYWRITE_FLUSH          NULL
 
-static void mywrite( WriteData *wd, void *adr, int len)
+static void mywrite(WriteData *wd, const void *adr, int len)
 {
        if (wd->error) return;
 
 {
        if (wd->error) return;
 
@@ -265,7 +266,7 @@ static void mywrite( WriteData *wd, void *adr, int len)
                do {
                        int writelen= MIN2(len, MYWRITE_MAX_CHUNK);
                        writedata_do_write(wd, adr, writelen);
                do {
                        int writelen= MIN2(len, MYWRITE_MAX_CHUNK);
                        writedata_do_write(wd, adr, writelen);
-                       adr = (char*)adr + writelen;
+                       adr = (const char *)adr + writelen;
                        len -= writelen;
                } while (len > 0);
 
                        len -= writelen;
                } while (len > 0);
 
@@ -354,22 +355,22 @@ static void writestruct(WriteData *wd, int filecode, const char *structname, int
        mywrite(wd, adr, bh.len);
 }
 
        mywrite(wd, adr, bh.len);
 }
 
-static void writedata(WriteData *wd, int filecode, int len, void *adr) /* do not use for structs */
+static void writedata(WriteData *wd, int filecode, int len, const void *adr)  /* do not use for structs */
 {
        BHead bh;
 
        if (adr==NULL) return;
        if (len==0) return;
 
 {
        BHead bh;
 
        if (adr==NULL) return;
        if (len==0) return;
 
-       len+= 3;
-       len-= ( len % 4);
+       len += 3;
+       len -= (len % 4);
 
        /* init BHead */
 
        /* init BHead */
-       bh.code= filecode;
-       bh.old= adr;
-       bh.nr= 1;
-       bh.SDNAnr= 0;
-       bh.len= len;
+       bh.code   = filecode;
+       bh.old    = (void *)adr;  /* this is safe to cast from const */
+       bh.nr     = 1;
+       bh.SDNAnr = 0;
+       bh.len    = len;
 
        mywrite(wd, &bh, sizeof(BHead));
        if (len) mywrite(wd, adr, len);
 
        mywrite(wd, &bh, sizeof(BHead));
        if (len) mywrite(wd, adr, len);
@@ -488,7 +489,7 @@ static void write_fmodifiers(WriteData *wd, ListBase *fmodifiers)
                                        FMod_Python *data = (FMod_Python *)fcm->data;
                                        
                                        /* Write ID Properties -- and copy this comment EXACTLY for easy finding
                                        FMod_Python *data = (FMod_Python *)fcm->data;
                                        
                                        /* Write ID Properties -- and copy this comment EXACTLY for easy finding
-                                        of library blocks that implement this.*/
+                                        of library blocks that implement this.*/
                                        IDP_WriteProperty(data->prop, wd);
                                }
                                        break;
                                        IDP_WriteProperty(data->prop, wd);
                                }
                                        break;
@@ -757,24 +758,30 @@ static void current_screen_compat(Main *mainvar, bScreen **screen)
        *screen= (window)? window->screen: NULL;
 }
 
        *screen= (window)? window->screen: NULL;
 }
 
+typedef struct RenderInfo {
+       int sfra;
+       int efra;
+       char scene_name[MAX_ID_NAME - 2];
+} RenderInfo;
+
 static void write_renderinfo(WriteData *wd, Main *mainvar)             /* for renderdeamon */
 {
        bScreen *curscreen;
        Scene *sce;
 static void write_renderinfo(WriteData *wd, Main *mainvar)             /* for renderdeamon */
 {
        bScreen *curscreen;
        Scene *sce;
-       int data[8];
+       RenderInfo data;
 
        /* XXX in future, handle multiple windows with multiple screnes? */
        current_screen_compat(mainvar, &curscreen);
 
        for (sce= mainvar->scene.first; sce; sce= sce->id.next) {
                if (sce->id.lib==NULL  && ( sce==curscreen->scene || (sce->r.scemode & R_BG_RENDER)) ) {
 
        /* XXX in future, handle multiple windows with multiple screnes? */
        current_screen_compat(mainvar, &curscreen);
 
        for (sce= mainvar->scene.first; sce; sce= sce->id.next) {
                if (sce->id.lib==NULL  && ( sce==curscreen->scene || (sce->r.scemode & R_BG_RENDER)) ) {
-                       data[0]= sce->r.sfra;
-                       data[1]= sce->r.efra;
+                       data.sfra = sce->r.sfra;
+                       data.efra = sce->r.efra;
+                       memset(data.scene_name, 0, sizeof(data.scene_name));
 
 
-                       memset(data+2, 0, sizeof(int)*6);
-                       BLI_strncpy((char *)(data+2), sce->id.name+2, sizeof(sce->id.name)-2);
+                       BLI_strncpy(data.scene_name, sce->id.name + 2, sizeof(data.scene_name));
 
 
-                       writedata(wd, REND, 32, data);
+                       writedata(wd, REND, sizeof(data), &data);
                }
        }
 }
                }
        }
 }
@@ -831,7 +838,7 @@ static void write_boid_state(WriteData *wd, BoidState *state)
        writestruct(wd, DATA, "BoidState", 1, state);
 
        for (; rule; rule=rule->next) {
        writestruct(wd, DATA, "BoidState", 1, state);
 
        for (; rule; rule=rule->next) {
-               switch(rule->type) {
+               switch (rule->type) {
                        case eBoidRuleType_Goal:
                        case eBoidRuleType_Avoid:
                                writestruct(wd, DATA, "BoidRuleGoalAvoid", 1, rule);
                        case eBoidRuleType_Goal:
                        case eBoidRuleType_Avoid:
                                writestruct(wd, DATA, "BoidRuleGoalAvoid", 1, rule);
@@ -968,7 +975,7 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
                writestruct(wd, DATA, "ParticleSystem", 1, psys);
 
                if (psys->particles) {
                writestruct(wd, DATA, "ParticleSystem", 1, psys);
 
                if (psys->particles) {
-                       writestruct(wd, DATA, "ParticleData", psys->totpart ,psys->particles);
+                       writestruct(wd, DATA, "ParticleData", psys->totpartpsys->particles);
 
                        if (psys->particles->hair) {
                                ParticleData *pa = psys->particles;
 
                        if (psys->particles->hair) {
                                ParticleData *pa = psys->particles;
@@ -987,7 +994,7 @@ static void write_particlesystems(WriteData *wd, ListBase *particles)
                for (; pt; pt=pt->next)
                        writestruct(wd, DATA, "ParticleTarget", 1, pt);
 
                for (; pt; pt=pt->next)
                        writestruct(wd, DATA, "ParticleTarget", 1, pt);
 
-               if (psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchild ,psys->child);
+               if (psys->child) writestruct(wd, DATA, "ChildParticle", psys->totchildpsys->child);
 
                if (psys->clmd) {
                        writestruct(wd, DATA, "ClothModifierData", 1, psys->clmd);
 
                if (psys->clmd) {
                        writestruct(wd, DATA, "ClothModifierData", 1, psys->clmd);
@@ -1024,7 +1031,7 @@ static void write_sensors(WriteData *wd, ListBase *lb)
 
                writedata(wd, DATA, sizeof(void *)*sens->totlinks, sens->links);
 
 
                writedata(wd, DATA, sizeof(void *)*sens->totlinks, sens->links);
 
-               switch(sens->type) {
+               switch (sens->type) {
                case SENS_NEAR:
                        writestruct(wd, DATA, "bNearSensor", 1, sens->data);
                        break;
                case SENS_NEAR:
                        writestruct(wd, DATA, "bNearSensor", 1, sens->data);
                        break;
@@ -1085,7 +1092,7 @@ static void write_controllers(WriteData *wd, ListBase *lb)
 
                writedata(wd, DATA, sizeof(void *)*cont->totlinks, cont->links);
 
 
                writedata(wd, DATA, sizeof(void *)*cont->totlinks, cont->links);
 
-               switch(cont->type) {
+               switch (cont->type) {
                case CONT_EXPRESSION:
                        writestruct(wd, DATA, "bExpressionCont", 1, cont->data);
                        break;
                case CONT_EXPRESSION:
                        writestruct(wd, DATA, "bExpressionCont", 1, cont->data);
                        break;
@@ -1108,7 +1115,7 @@ static void write_actuators(WriteData *wd, ListBase *lb)
        while (act) {
                writestruct(wd, DATA, "bActuator", 1, act);
 
        while (act) {
                writestruct(wd, DATA, "bActuator", 1, act);
 
-               switch(act->type) {
+               switch (act->type) {
                case ACT_ACTION:
                case ACT_SHAPEACTION:
                        writestruct(wd, DATA, "bActionActuator", 1, act->data);
                case ACT_ACTION:
                case ACT_SHAPEACTION:
                        writestruct(wd, DATA, "bActionActuator", 1, act->data);
@@ -1212,7 +1219,7 @@ static void write_constraints(WriteData *wd, ListBase *conlist)
                                                writestruct(wd, DATA, "bConstraintTarget", 1, ct);
                                        
                                        /* Write ID Properties -- and copy this comment EXACTLY for easy finding
                                                writestruct(wd, DATA, "bConstraintTarget", 1, ct);
                                        
                                        /* Write ID Properties -- and copy this comment EXACTLY for easy finding
-                                        of library blocks that implement this.*/
+                                        of library blocks that implement this.*/
                                        IDP_WriteProperty(data->prop, wd);
                                }
                                        break;
                                        IDP_WriteProperty(data->prop, wd);
                                }
                                        break;
@@ -1244,7 +1251,7 @@ static void write_pose(WriteData *wd, bPose *pose)
        /* Write channels */
        for (chan=pose->chanbase.first; chan; chan=chan->next) {
                /* Write ID Properties -- and copy this comment EXACTLY for easy finding
        /* Write channels */
        for (chan=pose->chanbase.first; chan; chan=chan->next) {
                /* Write ID Properties -- and copy this comment EXACTLY for easy finding
-                of library blocks that implement this.*/
+                of library blocks that implement this.*/
                if (chan->prop)
                        IDP_WriteProperty(chan->prop, wd);
                
                if (chan->prop)
                        IDP_WriteProperty(chan->prop, wd);
                
@@ -1310,10 +1317,8 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                else if (md->type==eModifierType_Smoke) {
                        SmokeModifierData *smd = (SmokeModifierData*) md;
                        
                else if (md->type==eModifierType_Smoke) {
                        SmokeModifierData *smd = (SmokeModifierData*) md;
                        
-                       if (smd->type & MOD_SMOKE_TYPE_DOMAIN)
-                       {
-                               if (smd->domain)
-                               {
+                       if (smd->type & MOD_SMOKE_TYPE_DOMAIN) {
+                               if (smd->domain) {
                                        write_pointcaches(wd, &(smd->domain->ptcaches[0]));
 
                                        /* create fake pointcache so that old blender versions can read it */
                                        write_pointcaches(wd, &(smd->domain->ptcaches[0]));
 
                                        /* create fake pointcache so that old blender versions can read it */
@@ -1347,8 +1352,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                else if (md->type==eModifierType_DynamicPaint) {
                        DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
                        
                else if (md->type==eModifierType_DynamicPaint) {
                        DynamicPaintModifierData *pmd = (DynamicPaintModifierData*) md;
                        
-                       if (pmd->canvas)
-                       {
+                       if (pmd->canvas) {
                                DynamicPaintSurface *surface;
                                writestruct(wd, DATA, "DynamicPaintCanvasSettings", 1, pmd->canvas);
                                
                                DynamicPaintSurface *surface;
                                writestruct(wd, DATA, "DynamicPaintCanvasSettings", 1, pmd->canvas);
                                
@@ -1362,8 +1366,7 @@ static void write_modifiers(WriteData *wd, ListBase *modbase)
                                        writestruct(wd, DATA, "EffectorWeights", 1, surface->effector_weights);
                                }
                        }
                                        writestruct(wd, DATA, "EffectorWeights", 1, surface->effector_weights);
                                }
                        }
-                       if (pmd->brush)
-                       {
+                       if (pmd->brush) {
                                writestruct(wd, DATA, "DynamicPaintBrushSettings", 1, pmd->brush);
                                writestruct(wd, DATA, "ColorBand", 1, pmd->brush->paint_ramp);
                                writestruct(wd, DATA, "ColorBand", 1, pmd->brush->vel_ramp);
                                writestruct(wd, DATA, "DynamicPaintBrushSettings", 1, pmd->brush);
                                writestruct(wd, DATA, "ColorBand", 1, pmd->brush->paint_ramp);
                                writestruct(wd, DATA, "ColorBand", 1, pmd->brush->vel_ramp);
@@ -1417,8 +1420,8 @@ static void write_objects(WriteData *wd, ListBase *idbase)
                        /* write LibData */
                        writestruct(wd, ID_OB, "Object", 1, ob);
                        
                        /* write LibData */
                        writestruct(wd, ID_OB, "Object", 1, ob);
                        
-                       /*Write ID Properties -- and copy this comment EXACTLY for easy finding
-                         of library blocks that implement this.*/
+                       /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+                        * of library blocks that implement this.*/
                        if (ob->id.properties) IDP_WriteProperty(ob->id.properties, wd);
                        
                        if (ob->adt) write_animdata(wd, ob->adt);
                        if (ob->id.properties) IDP_WriteProperty(ob->id.properties, wd);
                        
                        if (ob->adt) write_animdata(wd, ob->adt);
@@ -1678,8 +1681,8 @@ static void write_customdata(WriteData *wd, ID *id, int count, CustomData *data,
                        CustomData_file_write_info(layer->type, &structname, &structnum);
                        if (structnum) {
                                /* when using partial visibility, the MEdge and MFace layers
                        CustomData_file_write_info(layer->type, &structname, &structnum);
                        if (structnum) {
                                /* when using partial visibility, the MEdge and MFace layers
-                                  are smaller than the original, so their type and count is
-                                  passed to make this work */
+                                * are smaller than the original, so their type and count is
+                                * passed to make this work */
                                if (layer->type != partial_type) datasize= structnum*count;
                                else datasize= structnum*partial_count;
 
                                if (layer->type != partial_type) datasize= structnum*count;
                                else datasize= structnum*partial_count;
 
@@ -1800,10 +1803,10 @@ static void write_meshs(WriteData *wd, ListBase *idbase)
                                write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, -1, 0);
                                write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, -1, 0);
                                /* harmless for older blender versioins but _not_ writing these keeps file size down */
                                write_customdata(wd, &mesh->id, mesh->totedge, &mesh->edata, -1, 0);
                                write_customdata(wd, &mesh->id, mesh->totface, &mesh->fdata, -1, 0);
                                /* harmless for older blender versioins but _not_ writing these keeps file size down */
-                               /*
+#if 0
                                write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0);
                                write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0);
                                write_customdata(wd, &mesh->id, mesh->totloop, &mesh->ldata, -1, 0);
                                write_customdata(wd, &mesh->id, mesh->totpoly, &mesh->pdata, -1, 0);
-                               */
+#endif
 
                                /* restore */
                                mesh->mpoly = backup_mesh.mpoly;
 
                                /* restore */
                                mesh->mpoly = backup_mesh.mpoly;
@@ -1961,10 +1964,10 @@ static void write_materials(WriteData *wd, ListBase *idbase)
                        /* write LibData */
                        writestruct(wd, ID_MA, "Material", 1, ma);
                        
                        /* write LibData */
                        writestruct(wd, ID_MA, "Material", 1, ma);
                        
-                       /*Write ID Properties -- and copy this comment EXACTLY for easy finding
-                         of library blocks that implement this.*/
-                       /*manually set head group property to IDP_GROUP, just in case it hadn't been
-                         set yet :) */
+                       /* Write ID Properties -- and copy this comment EXACTLY for easy finding
+                        * of library blocks that implement this.*/
+                       /* manually set head group property to IDP_GROUP, just in case it hadn't been
+                        * set yet :) */
                        if (ma->id.properties) IDP_WriteProperty(ma->id.properties, wd);
                        
                        if (ma->adt) write_animdata(wd, ma->adt);
                        if (ma->id.properties) IDP_WriteProperty(ma->id.properties, wd);
                        
                        if (ma->adt) write_animdata(wd, ma->adt);
@@ -2106,19 +2109,21 @@ static void write_scenes(WriteData *wd, ListBase *scebase)
                        
                        /* reset write flags too */
                        
                        
                        /* reset write flags too */
                        
-                       SEQ_BEGIN(ed, seq) {
+                       SEQ_BEGIN (ed, seq)
+                       {
                                if (seq->strip) seq->strip->done= 0;
                                writestruct(wd, DATA, "Sequence", 1, seq);
                        }
                        SEQ_END
                        
                                if (seq->strip) seq->strip->done= 0;
                                writestruct(wd, DATA, "Sequence", 1, seq);
                        }
                        SEQ_END
                        
-                       SEQ_BEGIN(ed, seq) {
+                       SEQ_BEGIN (ed, seq)
+                       {
                                if (seq->strip && seq->strip->done==0) {
                                        /* write strip with 'done' at 0 because readfile */
                                        
                                        if (seq->plugin) writestruct(wd, DATA, "PluginSeq", 1, seq->plugin);
                                        if (seq->effectdata) {
                                if (seq->strip && seq->strip->done==0) {
                                        /* write strip with 'done' at 0 because readfile */
                                        
                                        if (seq->plugin) writestruct(wd, DATA, "PluginSeq", 1, seq->plugin);
                                        if (seq->effectdata) {
-                                               switch(seq->type) {
+                                               switch (seq->type) {
                                                case SEQ_COLOR:
                                                        writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata);
                                                        break;
                                                case SEQ_COLOR:
                                                        writestruct(wd, DATA, "SolidColorVars", 1, seq->effectdata);
                                                        break;
@@ -2252,7 +2257,7 @@ static void write_region(WriteData *wd, ARegion *ar, int spacetype)
        writestruct(wd, DATA, "ARegion", 1, ar);
        
        if (ar->regiondata) {
        writestruct(wd, DATA, "ARegion", 1, ar);
        
        if (ar->regiondata) {
-               switch(spacetype) {
+               switch (spacetype) {
                        case SPACE_VIEW3D:
                                if (ar->regiontype==RGN_TYPE_WINDOW) {
                                        RegionView3D *rv3d= ar->regiondata;
                        case SPACE_VIEW3D:
                                if (ar->regiontype==RGN_TYPE_WINDOW) {
                                        RegionView3D *rv3d= ar->regiondata;
@@ -2468,7 +2473,7 @@ static void write_bone(WriteData *wd, Bone* bone)
        writestruct(wd, DATA, "Bone", 1, bone);
 
        /* Write ID Properties -- and copy this comment EXACTLY for easy finding
        writestruct(wd, DATA, "Bone", 1, bone);
 
        /* Write ID Properties -- and copy this comment EXACTLY for easy finding
-        of library blocks that implement this.*/
+        of library blocks that implement this.*/
        if (bone->prop)
                IDP_WriteProperty(bone->prop, wd);
        
        if (bone->prop)
                IDP_WriteProperty(bone->prop, wd);
        
@@ -2675,6 +2680,18 @@ static void write_movieTracks(WriteData *wd, ListBase *tracks)
        }
 }
 
        }
 }
 
+static void write_movieDopesheet(WriteData *wd, MovieTrackingDopesheet *dopesheet)
+{
+       MovieTrackingDopesheetChannel *channel;
+
+       channel = dopesheet->channels.first;
+       while (channel) {
+               writestruct(wd, DATA, "MovieTrackingDopesheetChannel", 1, channel);
+
+               channel = channel->next;
+       }
+}
+
 static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction *reconstruction)
 {
        if (reconstruction->camnr)
 static void write_movieReconstruction(WriteData *wd, MovieTrackingReconstruction *reconstruction)
 {
        if (reconstruction->camnr)
@@ -2707,6 +2724,8 @@ static void write_movieclips(WriteData *wd, ListBase *idbase)
 
                                object= object->next;
                        }
 
                                object= object->next;
                        }
+
+                       write_movieDopesheet(wd, &tracking->dopesheet);
                }
 
                clip= clip->id.next;
                }
 
                clip= clip->id.next;
@@ -2716,6 +2735,54 @@ static void write_movieclips(WriteData *wd, ListBase *idbase)
        mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
        mywrite(wd, MYWRITE_FLUSH, 0);
 }
 
+static void write_masks(WriteData *wd, ListBase *idbase)
+{
+       Mask *mask;
+
+       mask = idbase->first;
+       while (mask) {
+               if (mask->id.us > 0 || wd->current) {
+                       MaskShape *shape;
+
+                       writestruct(wd, ID_MSK, "Mask", 1, mask);
+
+                       if (mask->adt)
+                               write_animdata(wd, mask->adt);
+
+                       shape = mask->shapes.first;
+                       while (shape) {
+                               MaskSpline *spline;
+
+                               writestruct(wd, DATA, "MaskShape", 1, shape);
+
+                               spline = shape->splines.first;
+                               while (spline) {
+                                       int i;
+
+                                       writestruct(wd, DATA, "MaskSpline", 1, spline);
+                                       writestruct(wd, DATA, "MaskSplinePoint", spline->tot_point, spline->points);
+
+                                       for (i = 0; i < spline->tot_point; i++) {
+                                               MaskSplinePoint *point = &spline->points[i];
+
+                                               if (point->tot_uw)
+                                                       writestruct(wd, DATA, "MaskSplinePointUW", point->tot_uw, point->uw);
+                                       }
+
+                                       spline = spline->next;
+                               }
+
+                               shape = shape->next;
+                       }
+               }
+
+               mask = mask->id.next;
+       }
+
+       /* flush helps the compression for undo-save */
+       mywrite(wd, MYWRITE_FLUSH, 0);
+}
+
 /* context is usually defined by WM, two cases where no WM is available:
  * - for forward compatibility, curscreen has to be saved
  * - for undofile, curscene needs to be saved */
 /* context is usually defined by WM, two cases where no WM is available:
  * - for forward compatibility, curscreen has to be saved
  * - for undofile, curscene needs to be saved */
@@ -2764,7 +2831,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
  * second are an RGBA image (unsigned char)
  * note, this uses 'TEST' since new types will segfault on file load for older blender versions.
  */
  * second are an RGBA image (unsigned char)
  * note, this uses 'TEST' since new types will segfault on file load for older blender versions.
  */
-static void write_thumb(WriteData *wd, int *img)
+static void write_thumb(WriteData *wd, const int *img)
 {
        if (img)
                writedata(wd, TEST, (2 + img[0] * img[1]) * sizeof(int), img);
 {
        if (img)
                writedata(wd, TEST, (2 + img[0] * img[1]) * sizeof(int), img);
@@ -2772,7 +2839,7 @@ static void write_thumb(WriteData *wd, int *img)
 
 /* if MemFile * there's filesave to memory */
 static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFile *current, 
 
 /* if MemFile * there's filesave to memory */
 static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFile *current, 
-                                                        int write_user_block, int write_flags, int *thumb)
+                             int write_user_block, int write_flags, const int *thumb)
 {
        BHead bhead;
        ListBase mainlist;
 {
        BHead bhead;
        ListBase mainlist;
@@ -2800,6 +2867,7 @@ static int write_file_handle(Main *mainvar, int handle, MemFile *compare, MemFil
                write_screens  (wd, &mainvar->screen);
        }
        write_movieclips (wd, &mainvar->movieclip);
                write_screens  (wd, &mainvar->screen);
        }
        write_movieclips (wd, &mainvar->movieclip);
+       write_masks    (wd, &mainvar->mask);
        write_scenes   (wd, &mainvar->scene);
        write_curves   (wd, &mainvar->curve);
        write_mballs   (wd, &mainvar->mball);
        write_scenes   (wd, &mainvar->scene);
        write_curves   (wd, &mainvar->curve);
        write_mballs   (wd, &mainvar->mball);
@@ -2880,7 +2948,7 @@ static int do_history(const char *name, ReportList *reports)
 }
 
 /* return: success (1) */
 }
 
 /* return: success (1) */
-int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, int *thumb)
+int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportList *reports, const int *thumb)
 {
        char userfilename[FILE_MAX];
        char tempname[FILE_MAX+1];
 {
        char userfilename[FILE_MAX];
        char tempname[FILE_MAX+1];
@@ -2889,7 +2957,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
        /* open temporary file, so we preserve the original in case we crash */
        BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
 
        /* open temporary file, so we preserve the original in case we crash */
        BLI_snprintf(tempname, sizeof(tempname), "%s@", filepath);
 
-       file = BLI_open(tempname,O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
+       file = BLI_open(tempname, O_BINARY+O_WRONLY+O_CREAT+O_TRUNC, 0666);
        if (file == -1) {
                BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s.", tempname, strerror(errno));
                return 0;
        if (file == -1) {
                BKE_reportf(reports, RPT_ERROR, "Can't open file %s for writing: %s.", tempname, strerror(errno));
                return 0;
@@ -2927,7 +2995,7 @@ int BLO_write_file(Main *mainvar, const char *filepath, int write_flags, ReportL
                makeFilesRelative(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
 
        /* actual file writing */
                makeFilesRelative(mainvar, filepath, NULL); /* note, making relative to something OTHER then G.main->name */
 
        /* actual file writing */
-       err= write_file_handle(mainvar, file, NULL,NULL, write_user_block, write_flags, thumb);
+       err= write_file_handle(mainvar, file, NULL, NULL, write_user_block, write_flags, thumb);
        close(file);
 
        if (err) {
        close(file);
 
        if (err) {