part 1 of cleaning up my little array macro library to be a formal API. also removed...
[blender.git] / source / blender / blenkernel / intern / packedFile.c
index 991b4a8c840242413804405b20b17f985e7f9004..0de97b9c703733efe9b158826466a0b40e75be12 100644 (file)
@@ -3,15 +3,12 @@
  *
  * $Id$
  *
- * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ * ***** BEGIN GPL LICENSE BLOCK *****
  *
  * This program is free software; you can redistribute it and/or
  * modify it under the terms of the GNU General Public License
  * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version. The Blender
- * Foundation also sells licenses for use in proprietary software under
- * the Blender License.  See http://www.blender.org/BL/ for information
- * about this.
+ * of the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  *
  * Contributor(s): none yet.
  *
- * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ * ***** END GPL LICENSE BLOCK *****
  */
 
 #include <stdio.h>
 #include <fcntl.h>
 #include <sys/stat.h>
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #ifndef WIN32 
 #include <unistd.h>
 #else
 #include "DNA_sound_types.h"
 #include "DNA_vfont_types.h"
 #include "DNA_packedFile_types.h"
-
+#include "DNA_scene_types.h"
 
 #include "BLI_blenlib.h"
 
 #include "BKE_utildefines.h"
-#include "BKE_bad_level_calls.h"
-
 #include "BKE_global.h"
 #include "BKE_main.h"
-
 #include "BKE_screen.h"
-
 #include "BKE_sound.h"
-//#include "sound.h"
-
 #include "BKE_image.h"
 #include "BKE_font.h"
 #include "BKE_packedFile.h"
+#include "BKE_report.h"
+
+#ifdef _WIN32
+#define open _open
+#define close _close
+#define read _read
+#define write _write
+#endif
 
-int seekPackedFile(PackedFile * pf, int offset, int whence)
+
+int seekPackedFile(PackedFile *pf, int offset, int whence)
 {
        int oldseek = -1, seek = 0;
 
@@ -96,12 +101,12 @@ int seekPackedFile(PackedFile * pf, int offset, int whence)
        return(oldseek);
 }
        
-void rewindPackedFile(PackedFile * pf)
+void rewindPackedFile(PackedFile *pf)
 {
        seekPackedFile(pf, 0, SEEK_SET);
 }
 
-int readPackedFile(PackedFile * pf, void * data, int size)
+int readPackedFile(PackedFile *pf, void *data, int size)
 { 
        if ((pf != NULL) && (size >= 0) && (data != NULL)) {
                if (size + pf->seek > pf->size) {
@@ -122,80 +127,68 @@ int readPackedFile(PackedFile * pf, void * data, int size)
        return(size);
 }
 
-int countPackedFiles()
+int countPackedFiles(Main *bmain)
 {
-       int count = 0;
        Image *ima;
        VFont *vf;
-       bSample *sample;
+       bSound *sound;
+       int count = 0;
        
        // let's check if there are packed files...
-       ima = G.main->image.first;
-       while (ima) {
-               if (ima->packedfile) {
+       for(ima=bmain->image.first; ima; ima=ima->id.next)
+               if(ima->packedfile)
                        count++;
-               }
-               ima= ima->id.next;
-       }
 
-       vf = G.main->vfont.first;
-       while (vf) {
-               if (vf->packedfile) {
+       for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+               if(vf->packedfile)
                        count++;
-               }
-               vf = vf->id.next;
-       }
 
-       sample = samples->first;
-       while (sample) {
-               if (sample->packedfile) {
+       for(sound=bmain->sound.first; sound; sound=sound->id.next)
+               if(sound->packedfile)
                        count++;
-               }
-               sample = sample->id.next;
-       }
 
-       return(count);
+       return count;
 }
 
-void freePackedFile(PackedFile * pf)
+void freePackedFile(PackedFile *pf)
 {
-       if (pf) {
+       if(pf) {
                MEM_freeN(pf->data);
                MEM_freeN(pf);
-       } else {
-               printf("freePackedFile: Trying to free a NULL pointer\n");
        }
+       else
+               printf("freePackedFile: Trying to free a NULL pointer\n");
 }
        
-PackedFile * newPackedFileMemory(void *mem, int memlen)
+PackedFile *newPackedFileMemory(void *mem, int memlen)
 {
-       PackedFile * pf = MEM_callocN(sizeof(*pf), "PackedFile");
+       PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile");
        pf->data = mem;
        pf->size = memlen;
        
        return pf;
 }
 
-PackedFile * newPackedFile(char * filename)
+PackedFile *newPackedFile(ReportList *reports, char *filename)
 {
-       PackedFile * pf = NULL;
+       PackedFile *pf = NULL;
        int file, filelen;
        char name[FILE_MAXDIR+FILE_MAXFILE];
-       void * data;
+       void *data;
        
-       waitcursor(1);
+       //XXX waitcursor(1);
        
        // convert relative filenames to absolute filenames
        
        strcpy(name, filename);
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        // open the file
        // and create a PackedFile structure
 
        file= open(name, O_BINARY|O_RDONLY);
        if (file <= 0) {
-               // error("Can't open file: %s", name);
+               BKE_reportf(reports, RPT_ERROR, "Can't open file: %s", name);
        } else {
                filelen = BLI_filesize(file);
 
@@ -213,41 +206,28 @@ PackedFile * newPackedFile(char * filename)
                close(file);
        }
 
-       waitcursor(0);
+       //XXX waitcursor(0);
                
        return (pf);
 }
 
-void packAll()
+void packAll(Main *bmain, ReportList *reports)
 {
        Image *ima;
        VFont *vf;
-       bSample *sample;
-       
-       ima = G.main->image.first;
-       while (ima) {
-               if (ima->packedfile == NULL) {
-                       ima->packedfile = newPackedFile(ima->name);
-               }
-               ima= ima->id.next;
-       }
-       
-       vf = G.main->vfont.first;
-       while (vf) {
-               if (vf->packedfile == NULL) {
-                       vf->packedfile = newPackedFile(vf->name);
-               }
-               vf = vf->id.next;
-       }
+       bSound *sound;
 
+       for(ima=bmain->image.first; ima; ima=ima->id.next)
+               if(ima->packedfile == NULL)
+                       ima->packedfile = newPackedFile(reports, ima->name);
 
-       sample = samples->first;
-       while (sample) {
-               if (sample->packedfile == NULL) {
-                       sound_set_packedfile(sample, newPackedFile(sample->name));
-               }
-               sample = sample->id.next;
-       }
+       for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+               if(vf->packedfile == NULL)
+                       vf->packedfile = newPackedFile(reports, vf->name);
+
+       for(sound=bmain->sound.first; sound; sound=sound->id.next)
+               if(sound->packedfile == NULL)
+                       sound->packedfile = newPackedFile(reports, sound->name);
 }
 
 
@@ -256,10 +236,10 @@ void packAll()
 // attempt to create a function that generates an unique filename
 // this will work when all funtions in fileops.c understand relative filenames...
 
-char * find_new_name(char * name)
+static char *find_new_name(char *name)
 {
        char tempname[FILE_MAXDIR + FILE_MAXFILE];
-       char * newname;
+       char *newname;
        
        if (fop_exists(name)) {
                for (number = 1; number <= 999; number++) {
@@ -278,18 +258,18 @@ char * find_new_name(char * name)
        
 */
 
-int writePackedFile(char * filename, PackedFile *pf)
+int writePackedFile(ReportList *reports, char *filename, PackedFile *pf, int guimode)
 {
        int file, number, remove_tmp = FALSE;
        int ret_value = RET_OK;
        char name[FILE_MAXDIR + FILE_MAXFILE];
        char tempname[FILE_MAXDIR + FILE_MAXFILE];
-/*     void * data; */
+/*     void *data; */
        
-       waitcursor(1);
+       if (guimode); //XXX  waitcursor(1);
        
        strcpy(name, filename);
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        if (BLI_exists(name)) {
                for (number = 1; number <= 999; number++) {
@@ -304,33 +284,33 @@ int writePackedFile(char * filename, PackedFile *pf)
        }
        
        // make sure the path to the file exists...
-       RE_make_existing_file(name);
+       BLI_make_existing_file(name);
        
        file = open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666);
        if (file >= 0) {
                if (write(file, pf->data, pf->size) != pf->size) {
-                       error("Error writing file: %s", name);
+                       BKE_reportf(reports, RPT_ERROR, "Error writing file: %s", name);
                        ret_value = RET_ERROR;
                }
                close(file);
        } else {
-               error("Error creating file: %s", name);
+               BKE_reportf(reports, RPT_ERROR, "Error creating file: %s", name);
                ret_value = RET_ERROR;
        }
        
        if (remove_tmp) {
                if (ret_value == RET_ERROR) {
-                       if (BLI_rename(tempname, name) == RET_ERROR) {
-                               error("Error restoring tempfile. Check files: '%s' '%s'", tempname, name);
+                       if (BLI_rename(tempname, name) != 0) {
+                               BKE_reportf(reports, RPT_ERROR, "Error restoring tempfile. Check files: '%s' '%s'", tempname, name);
                        }
                } else {
-                       if (BLI_delete(tempname, 0, 0) == RET_ERROR) {
-                               error("Error deleting '%s' (ignored)");
+                       if (BLI_delete(tempname, 0, 0) != 0) {
+                               BKE_reportf(reports, RPT_ERROR, "Error deleting '%s' (ignored)", tempname);
                        }
                }
        }
        
-       waitcursor(0);
+       if(guimode); //XXX waitcursor(0);
 
        return (ret_value);
 }
@@ -346,7 +326,7 @@ PF_NOFILE           - the original file doens't exist
 
 */
 
-int checkPackedFile(char * filename, PackedFile * pf)
+int checkPackedFile(char *filename, PackedFile *pf)
 {
        struct stat st;
        int ret_val, i, len, file;
@@ -354,7 +334,7 @@ int checkPackedFile(char * filename, PackedFile * pf)
        char name[FILE_MAXDIR + FILE_MAXFILE];
        
        strcpy(name, filename);
-       BLI_convertstringcode(name, G.sce, G.scene->r.cfra);
+       BLI_convertstringcode(name, G.sce);
        
        if (stat(name, &st)) {
                ret_val = PF_NOFILE;
@@ -386,6 +366,8 @@ int checkPackedFile(char * filename, PackedFile * pf)
                                        }
                                }
                        }
+                       
+                       close(file);
                }
        }
        
@@ -394,72 +376,28 @@ int checkPackedFile(char * filename, PackedFile * pf)
 
 /*
 
-unpackFile() looks at the existing files (abs_name, local_name) and a packed file.
-If how == PF_ASK it offers the user a couple of options what to do with the packed file.
+   unpackFile() looks at the existing files (abs_name, local_name) and a packed file.
 
-It returns a char * to the existing file name / new file name or NULL when
+It returns a char *to the existing file name / new file name or NULL when
 there was an error or when the user desides to cancel the operation.
 
 */
 
-char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
+char *unpackFile(ReportList *reports, char *abs_name, char *local_name, PackedFile *pf, int how)
 {
-       char menu[6 * (FILE_MAXDIR + FILE_MAXFILE + 100)];
-       char line[FILE_MAXDIR + FILE_MAXFILE + 100];
-       char * newname = NULL, * temp = NULL;
+       char *newname = NULL, *temp = NULL;
        
        // char newabs[FILE_MAXDIR + FILE_MAXFILE];
        // char newlocal[FILE_MAXDIR + FILE_MAXFILE];
        
        if (pf != NULL) {
-               if (how == PF_ASK) {
-                       strcpy(menu, "UnPack file%t");
-                       
-                       if (strcmp(abs_name, local_name)) {
-                               switch (checkPackedFile(local_name, pf)) {
-                                       case PF_NOFILE:
-                                               sprintf(line, "|Create %s%%x%d", local_name, PF_WRITE_LOCAL);
-                                               strcat(menu, line);
-                                               break;
-                                       case PF_EQUAL:
-                                               sprintf(line, "|Use %s (identical)%%x%d", local_name, PF_USE_LOCAL);
-                                               strcat(menu, line);
-                                               break;
-                                       case PF_DIFFERS:
-                                               sprintf(line, "|Use %s (differs)%%x%d", local_name, PF_USE_LOCAL);
-                                               strcat(menu, line);
-                                               sprintf(line, "|Overwrite %s%%x%d", local_name, PF_WRITE_LOCAL);
-                                               strcat(menu, line);
-                                               break;
-                               }
-                               // sprintf(line, "|%%x%d", PF_INVALID);
-                               // strcat(menu, line);
-                       }
-                       
-                       switch (checkPackedFile(abs_name, pf)) {
-                               case PF_NOFILE:
-                                       sprintf(line, "|Create %s%%x%d", abs_name, PF_WRITE_ORIGINAL);
-                                       strcat(menu, line);
-                                       break;
-                               case PF_EQUAL:
-                                       sprintf(line, "|Use %s (identical)%%x%d", abs_name, PF_USE_ORIGINAL);
-                                       strcat(menu, line);
-                                       break;
-                               case PF_DIFFERS:
-                                       sprintf(line, "|Use %s (differs)%%x%d", abs_name, PF_USE_ORIGINAL);
-                                       strcat(menu, line);
-                                       sprintf(line, "|Overwrite %s%%x%d", abs_name, PF_WRITE_ORIGINAL);
-                                       strcat(menu, line);
-                                       break;
-                       }
-                       
-                       how = pupmenu(menu);
-               }
-               
                switch (how) {
                        case -1:
                        case PF_KEEP:
                                break;
+                       case PF_REMOVE:
+                               temp= abs_name;
+                               break;
                        case PF_USE_LOCAL:
                                // if file exists use it
                                if (BLI_exists(local_name)) {
@@ -468,7 +406,7 @@ char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
                                }
                                // else fall through and create it
                        case PF_WRITE_LOCAL:
-                               if (writePackedFile(local_name, pf) == RET_OK) {
+                               if (writePackedFile(reports, local_name, pf, 1) == RET_OK) {
                                        temp = local_name;
                                }
                                break;
@@ -480,7 +418,7 @@ char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
                                }
                                // else fall through and create it
                        case PF_WRITE_ORIGINAL:
-                               if (writePackedFile(abs_name, pf) == RET_OK) {
+                               if (writePackedFile(reports, abs_name, pf, 1) == RET_OK) {
                                        temp = abs_name;
                                }
                                break;
@@ -499,10 +437,10 @@ char * unpackFile(char * abs_name, char * local_name, PackedFile * pf, int how)
 }
 
 
-int unpackVFont(VFont * vfont, int how)
+int unpackVFont(ReportList *reports, VFont *vfont, int how)
 {
        char localname[FILE_MAXDIR + FILE_MAXFILE], fi[FILE_MAXFILE];
-       char * newname;
+       char *newname;
        int ret_value = RET_ERROR;
        
        if (vfont != NULL) {
@@ -511,7 +449,7 @@ int unpackVFont(VFont * vfont, int how)
                
                sprintf(localname, "//fonts/%s", fi);
                
-               newname = unpackFile(vfont->name, localname, vfont->packedfile, how);
+               newname = unpackFile(reports, vfont->name, localname, vfont->packedfile, how);
                if (newname != NULL) {
                        ret_value = RET_OK;
                        freePackedFile(vfont->packedfile);
@@ -524,57 +462,26 @@ int unpackVFont(VFont * vfont, int how)
        return (ret_value);
 }
 
-/*
-create_local_name() creates a relative (starting with //) name.
-Because it is allowed to have /'s and \'s in blenderobject names
-we have to remove these first.
-*/
-
-
-void create_local_name(char *localname, char *prefix, char *filename)
+int unpackSound(ReportList *reports, bSound *sound, int how)
 {
-       char tempname[FILE_MAXDIR + FILE_MAXFILE];
-       int i, len;
-
-       strcpy(tempname, filename);
-       len = strlen(tempname);
-
-       for (i = 0; i < len ; i++) {
-               switch (tempname[i])
-               {
-               case '/':
-               case '\\':
-               case ' ':
-                       tempname[i] = '_';
-                       break;
-               }
-       }
-
-       strcpy(localname, prefix);
-       strcat(localname, tempname);
-}
+       char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
+       char *newname;
+       int ret_value = RET_ERROR;
 
+       if (sound != NULL) {
+               strcpy(localname, sound->name);
+               BLI_splitdirstring(localname, fi);
+               sprintf(localname, "//sounds/%s", fi);
 
-int unpackSample(bSample *sample, int how)
-{
-       char localname[FILE_MAXDIR + FILE_MAXFILE];
-       char * newname;
-       int ret_value = RET_ERROR;
-       PackedFile *pf;
-       
-       if (sample != NULL) {
-               create_local_name(localname, "//samples/", sample->id.name + 2);
-               
-               newname = unpackFile(sample->name, localname, sample->packedfile, how);
+               newname = unpackFile(reports, sound->name, localname, sound->packedfile, how);
                if (newname != NULL) {
-                       strcpy(sample->name, newname);
+                       strcpy(sound->name, newname);
                        MEM_freeN(newname);
 
-                       pf = sample->packedfile;
-                       // because samples and sounds can point to the
-                       // same packedfile we have to check them all
-                       sound_set_packedfile(sample, NULL);
-                       freePackedFile(pf);
+                       freePackedFile(sound->packedfile);
+                       sound->packedfile = 0;
+
+                       sound_load(NULL, sound);
 
                        ret_value = RET_OK;
                }
@@ -583,56 +490,47 @@ int unpackSample(bSample *sample, int how)
        return(ret_value);
 }
 
-int unpackImage(Image * ima, int how)
+int unpackImage(ReportList *reports, Image *ima, int how)
 {
-       char localname[FILE_MAXDIR + FILE_MAXFILE];
-       char * newname;
+       char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
+       char *newname;
        int ret_value = RET_ERROR;
        
        if (ima != NULL) {
-               create_local_name(localname, "//textures/", ima->id.name + 2);
-               
-               newname = unpackFile(ima->name, localname, ima->packedfile, how);
+               strcpy(localname, ima->name);
+               BLI_splitdirstring(localname, fi);
+               sprintf(localname, "//textures/%s", fi);
+                       
+               newname = unpackFile(reports, ima->name, localname, ima->packedfile, how);
                if (newname != NULL) {
                        ret_value = RET_OK;
                        freePackedFile(ima->packedfile);
-                       ima->packedfile = 0;
+                       ima->packedfile = NULL;
                        strcpy(ima->name, newname);
                        MEM_freeN(newname);
-                       free_image_buffers(ima);
+                       BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
                }
        }
        
        return(ret_value);
 }
 
-void unpackAll(int how)
+void unpackAll(Main *bmain, ReportList *reports, int how)
 {
        Image *ima;
        VFont *vf;
-       bSample *sample;
-               
-       ima = G.main->image.first;
-       while (ima) {
-               if (ima->packedfile) {
-                       unpackImage(ima, how);
-               }
-               ima= ima->id.next;
-       }
-       
-       vf = G.main->vfont.first;
-       while (vf) {
-               if (vf->packedfile) {
-                       unpackVFont(vf, how);
-               }
-               vf = vf->id.next;
-       }
+       bSound *sound;
 
-       sample = samples->first;
-       while (sample) {
-               if (sample->packedfile) {
-                       unpackSample(sample, how);
-               }
-               sample = sample->id.next;
-       }
+       for(ima=bmain->image.first; ima; ima=ima->id.next)
+               if(ima->packedfile)
+                       unpackImage(reports, ima, how);
+
+       for(vf=bmain->vfont.first; vf; vf=vf->id.next)
+               if(vf->packedfile)
+                       unpackVFont(reports, vf, how);
+
+       for(sound=bmain->sound.first; sound; sound=sound->id.next)
+               if(sound->packedfile)
+                       unpackSound(reports, sound, how);
 }
+