Cleanup: Remove more #if 0 blocks
[blender.git] / source / blender / blenkernel / intern / packedFile.c
index 5a02d92..8d7a832 100644 (file)
@@ -34,7 +34,7 @@
 #include <fcntl.h>
 #include <sys/stat.h>
 
-#ifndef WIN32 
+#ifndef WIN32
 #include <unistd.h>
 #else
 #include <io.h>
 #include "BKE_report.h"
 #include "BKE_sound.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 oldseek = -1, seek = 0;
@@ -85,6 +77,7 @@ int seekPackedFile(PackedFile *pf, int offset, int whence)
                                break;
                        default:
                                oldseek = -1;
+                               break;
                }
                if (seek < 0) {
                        seek = 0;
@@ -97,14 +90,14 @@ int seekPackedFile(PackedFile *pf, int offset, int whence)
 
        return(oldseek);
 }
-       
+
 void rewindPackedFile(PackedFile *pf)
 {
        seekPackedFile(pf, 0, SEEK_SET);
 }
 
 int readPackedFile(PackedFile *pf, void *data, int size)
-{ 
+{
        if ((pf != NULL) && (size >= 0) && (data != NULL)) {
                if (size + pf->seek > pf->size) {
                        size = pf->size - pf->seek;
@@ -132,11 +125,11 @@ int countPackedFiles(Main *bmain)
        VFont *vf;
        bSound *sound;
        int count = 0;
-       
+
        /* let's check if there are packed files... */
        for (ima = bmain->image.first; ima; ima = ima->id.next)
-               if (ima->packedfile)
-                       count++;
+               if (BKE_image_has_packedfile(ima))
+                       count ++;
 
        for (vf = bmain->vfont.first; vf; vf = vf->id.next)
                if (vf->packedfile)
@@ -174,7 +167,7 @@ PackedFile *newPackedFileMemory(void *mem, int memlen)
        PackedFile *pf = MEM_callocN(sizeof(*pf), "PackedFile");
        pf->data = mem;
        pf->size = memlen;
-       
+
        return pf;
 }
 
@@ -184,14 +177,14 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
        int file, filelen;
        char name[FILE_MAX];
        void *data;
-       
+
        /* render result has no filename and can be ignored
         * any other files with no name can be ignored too */
        if (filename[0] == '\0')
                return NULL;
 
        //XXX waitcursor(1);
-       
+
        /* convert relative filenames to absolute filenames */
 
        BLI_strncpy(name, filename, sizeof(name));
@@ -201,7 +194,7 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
         * and create a PackedFile structure */
 
        file = BLI_open(name, O_BINARY | O_RDONLY, 0);
-       if (file <= 0) {
+       if (file == -1) {
                BKE_reportf(reports, RPT_ERROR, "Unable to pack file, source path '%s' not found", name);
        }
        else {
@@ -218,30 +211,33 @@ PackedFile *newPackedFile(ReportList *reports, const char *filename, const char
                if (read(file, data, filelen) == filelen) {
                        pf = newPackedFileMemory(data, filelen);
                }
+               else {
+                       MEM_freeN(data);
+               }
 
                close(file);
        }
 
        //XXX waitcursor(0);
-               
+
        return (pf);
 }
 
 /* no libraries for now */
-void packAll(Main *bmain, ReportList *reports)
+void packAll(Main *bmain, ReportList *reports, bool verbose)
 {
        Image *ima;
        VFont *vfont;
        bSound *sound;
        int tot = 0;
-       
+
        for (ima = bmain->image.first; ima; ima = ima->id.next) {
-               if (ima->packedfile == NULL && ima->id.lib == NULL) {
+               if (BKE_image_has_packedfile(ima) == false && !ID_IS_LINKED(ima)) {
                        if (ima->source == IMA_SRC_FILE) {
-                               ima->packedfile = newPackedFile(reports, ima->name, ID_BLEND_PATH(bmain, &ima->id));
+                               BKE_image_packfiles(reports, ima, ID_BLEND_PATH(bmain, &ima->id));
                                tot ++;
                        }
-                       else if (ELEM(ima->source, IMA_SRC_SEQUENCE, IMA_SRC_MOVIE)) {
+                       else if (BKE_image_is_animated(ima) && verbose) {
                                BKE_reportf(reports, RPT_WARNING, "Image '%s' skipped, movies and image sequences not supported",
                                            ima->id.name + 2);
                        }
@@ -249,98 +245,72 @@ void packAll(Main *bmain, ReportList *reports)
        }
 
        for (vfont = bmain->vfont.first; vfont; vfont = vfont->id.next) {
-               if (vfont->packedfile == NULL && vfont->id.lib == NULL && BKE_vfont_is_builtin(vfont) == FALSE) {
-                       vfont->packedfile = newPackedFile(reports, vfont->name, bmain->name);
+               if (vfont->packedfile == NULL && !ID_IS_LINKED(vfont) && BKE_vfont_is_builtin(vfont) == false) {
+                       vfont->packedfile = newPackedFile(reports, vfont->name, BKE_main_blendfile_path(bmain));
                        tot ++;
                }
        }
 
        for (sound = bmain->sound.first; sound; sound = sound->id.next) {
-               if (sound->packedfile == NULL && sound->id.lib == NULL) {
-                       sound->packedfile = newPackedFile(reports, sound->name, bmain->name);
+               if (sound->packedfile == NULL && !ID_IS_LINKED(sound)) {
+                       sound->packedfile = newPackedFile(reports, sound->name, BKE_main_blendfile_path(bmain));
                        tot++;
                }
        }
-       
-       if (tot == 0)
-               BKE_report(reports, RPT_INFO, "No files have been packed");
-       else
-               BKE_reportf(reports, RPT_INFO, "Packed %d files", tot);
-
 
+       if (tot > 0)
+               BKE_reportf(reports, RPT_INFO, "Packed %d files", tot);
+       else if (verbose)
+               BKE_report(reports, RPT_INFO, "No new files have been packed");
 }
 
-
-#if 0
-
-// attempt to create a function that generates an unique filename
-// this will work when all funtions in fileops.c understand relative filenames...
-
-static char *find_new_name(char *name)
-{
-       char tempname[FILE_MAX];
-       char *newname;
-       size_t len;
-       
-       if (fop_exists(name)) {
-               for (number = 1; number <= 999; number++) {
-                       BLI_snprintf(tempname, sizeof(tempname), "%s.%03d", name, number);
-                       if (!fop_exists(tempname)) {
-                               break;
-                       }
-               }
-       }
-       len = strlen(tempname) + 1;
-       newname = MEM_mallocN(len, "find_new_name");
-       memcpy(newname, tempname, len * sizeof(char));
-       return newname;
-}
-#endif
-
-int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, int guimode)
+int writePackedFile(
+        ReportList *reports, const char *ref_file_name, const char *filename, PackedFile *pf, const bool guimode)
 {
-       int file, number, remove_tmp = FALSE;
+       int file, number;
        int ret_value = RET_OK;
+       bool remove_tmp = false;
        char name[FILE_MAX];
        char tempname[FILE_MAX];
 /*      void *data; */
-       
+
        if (guimode) {} //XXX  waitcursor(1);
-       
+
        BLI_strncpy(name, filename, sizeof(name));
-       BLI_path_abs(name, G.main->name);
-       
+       BLI_path_abs(name, ref_file_name);
+
        if (BLI_exists(name)) {
                for (number = 1; number <= 999; number++) {
                        BLI_snprintf(tempname, sizeof(tempname), "%s.%03d_", name, number);
                        if (!BLI_exists(tempname)) {
                                if (BLI_copy(name, tempname) == RET_OK) {
-                                       remove_tmp = TRUE;
+                                       remove_tmp = true;
                                }
                                break;
                        }
                }
        }
-       
+
        /* make sure the path to the file exists... */
        BLI_make_existing_file(name);
-       
+
        file = BLI_open(name, O_BINARY + O_WRONLY + O_CREAT + O_TRUNC, 0666);
-       if (file >= 0) {
+       if (file == -1) {
+               BKE_reportf(reports, RPT_ERROR, "Error creating file '%s'", name);
+               ret_value = RET_ERROR;
+       }
+       else {
                if (write(file, pf->data, pf->size) != pf->size) {
                        BKE_reportf(reports, RPT_ERROR, "Error writing file '%s'", name);
                        ret_value = RET_ERROR;
                }
-               else
+               else {
                        BKE_reportf(reports, RPT_INFO, "Saved packed file to: %s", name);
-               
+               }
+
                close(file);
        }
-       else {
-               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) != 0) {
@@ -353,32 +323,31 @@ int writePackedFile(ReportList *reports, const char *filename, PackedFile *pf, i
                        }
                }
        }
-       
+
        if (guimode) {} //XXX waitcursor(0);
 
        return (ret_value);
 }
-       
-/*
+
+/**
  * This function compares a packed file to a 'real' file.
  * It returns an integer indicating if:
  *
- * PF_EQUAL            - the packed file and original file are identical
- * PF_DIFFERENT        - the packed file and original file differ
- * PF_NOFILE   - the original file doens't exist
+ * - PF_EQUAL:     the packed file and original file are identical
+ * - PF_DIFFERENT: the packed file and original file differ
+ * - PF_NOFILE:    the original file doesn't exist
  */
-
-int checkPackedFile(const char *filename, PackedFile *pf)
+int checkPackedFile(const char *ref_file_name, const char *filename, PackedFile *pf)
 {
-       struct stat st;
+       BLI_stat_t st;
        int ret_val, i, len, file;
        char buf[4096];
        char name[FILE_MAX];
-       
+
        BLI_strncpy(name, filename, sizeof(name));
-       BLI_path_abs(name, G.main->name);
-       
-       if (stat(name, &st)) {
+       BLI_path_abs(name, ref_file_name);
+
+       if (BLI_stat(name, &st) == -1) {
                ret_val = PF_NOFILE;
        }
        else if (st.st_size != pf->size) {
@@ -388,7 +357,7 @@ int checkPackedFile(const char *filename, PackedFile *pf)
                /* we'll have to compare the two... */
 
                file = BLI_open(name, O_BINARY | O_RDONLY, 0);
-               if (file < 0) {
+               if (file == -1) {
                        ret_val = PF_NOFILE;
                }
                else {
@@ -412,28 +381,29 @@ int checkPackedFile(const char *filename, PackedFile *pf)
                                        }
                                }
                        }
-                       
+
                        close(file);
                }
        }
-       
+
        return(ret_val);
 }
 
-/* unpackFile() looks at the existing files (abs_name, local_name) and a 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
  * there was an error or when the user decides to cancel the operation.
+ *
+ * \warning 'abs_name' may be relative still! (use a "//" prefix) be sure to run #BLI_path_abs on it first.
  */
-
-char *unpackFile(ReportList *reports, const char *abs_name, const char *local_name, PackedFile *pf, int how)
+char *unpackFile(
+        ReportList *reports, const char *ref_file_name,
+        const char *abs_name, const char *local_name, PackedFile *pf, int how)
 {
        char *newname = NULL;
        const char *temp = NULL;
-       
-       // char newabs[FILE_MAX];
-       // char newlocal[FILE_MAX];
-       
+
        if (pf != NULL) {
                switch (how) {
                        case -1:
@@ -443,27 +413,43 @@ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_na
                                temp = abs_name;
                                break;
                        case PF_USE_LOCAL:
+                       {
+                               char temp_abs[FILE_MAX];
+
+                               BLI_strncpy(temp_abs, local_name, sizeof(temp_abs));
+                               BLI_path_abs(temp_abs, ref_file_name);
+
                                /* if file exists use it */
-                               if (BLI_exists(local_name)) {
+                               if (BLI_exists(temp_abs)) {
                                        temp = local_name;
                                        break;
                                }
-                       /* else fall through and create it */
+                               /* else create it */
+                               ATTR_FALLTHROUGH;
+                       }
                        case PF_WRITE_LOCAL:
-                               if (writePackedFile(reports, local_name, pf, 1) == RET_OK) {
+                               if (writePackedFile(reports, ref_file_name, local_name, pf, 1) == RET_OK) {
                                        temp = local_name;
                                }
                                break;
                        case PF_USE_ORIGINAL:
+                       {
+                               char temp_abs[FILE_MAX];
+
+                               BLI_strncpy(temp_abs, abs_name, sizeof(temp_abs));
+                               BLI_path_abs(temp_abs, ref_file_name);
+
                                /* if file exists use it */
-                               if (BLI_exists(abs_name)) {
+                               if (BLI_exists(temp_abs)) {
                                        BKE_reportf(reports, RPT_INFO, "Use existing file (instead of packed): %s", abs_name);
                                        temp = abs_name;
                                        break;
                                }
-                       /* else fall through and create it */
+                               /* else create it */
+                               ATTR_FALLTHROUGH;
+                       }
                        case PF_WRITE_ORIGINAL:
-                               if (writePackedFile(reports, abs_name, pf, 1) == RET_OK) {
+                               if (writePackedFile(reports, ref_file_name, abs_name, pf, 1) == RET_OK) {
                                        temp = abs_name;
                                }
                                break;
@@ -471,26 +457,65 @@ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_na
                                printf("unpackFile: unknown return_value %d\n", how);
                                break;
                }
-               
+
                if (temp) {
                        newname = BLI_strdup(temp);
                }
        }
-       
+
        return newname;
 }
 
+static void unpack_generate_paths(
+        const char *name, ID *id, char *r_abspath, char *r_relpath, size_t abspathlen, size_t relpathlen)
+{
+       char tempname[FILE_MAX];
+       char tempdir[FILE_MAXDIR];
+
+       BLI_split_dirfile(name, tempdir, tempname, sizeof(tempdir), sizeof(tempname));
+
+       if (tempname[0] == '\0') {
+               /* Note: we do not have any real way to re-create extension out of data... */
+               BLI_strncpy(tempname, id->name + 2, sizeof(tempname));
+               printf("%s\n", tempname);
+               BLI_filename_make_safe(tempname);
+               printf("%s\n", tempname);
+       }
+
+       if (tempdir[0] == '\0') {
+               /* Fallback to relative dir. */
+               BLI_strncpy(tempdir, "//", sizeof(tempdir));
+       }
+
+       switch (GS(id->name)) {
+               case ID_VF:
+                       BLI_snprintf(r_relpath, relpathlen, "//fonts/%s", tempname);
+                       break;
+               case ID_SO:
+                       BLI_snprintf(r_relpath, relpathlen, "//sounds/%s", tempname);
+                       break;
+               case ID_IM:
+                       BLI_snprintf(r_relpath, relpathlen, "//textures/%s", tempname);
+                       break;
+               default:
+                       break;
+       }
 
-int unpackVFont(ReportList *reports, VFont *vfont, int how)
+       {
+               size_t len = BLI_strncpy_rlen(r_abspath, tempdir, abspathlen);
+               BLI_strncpy(r_abspath + len, tempname, abspathlen - len);
+       }
+}
+
+int unpackVFont(Main *bmain, ReportList *reports, VFont *vfont, int how)
 {
-       char localname[FILE_MAX], fi[FILE_MAXFILE];
+       char localname[FILE_MAX], absname[FILE_MAX];
        char *newname;
        int ret_value = RET_ERROR;
-       
+
        if (vfont != NULL) {
-               BLI_split_file_part(vfont->name, fi, sizeof(fi));
-               BLI_snprintf(localname, sizeof(localname), "//fonts/%s", fi);
-               newname = unpackFile(reports, vfont->name, localname, vfont->packedfile, how);
+               unpack_generate_paths(vfont->name, (ID *)vfont, absname, localname, sizeof(absname), sizeof(localname));
+               newname = unpackFile(reports, BKE_main_blendfile_path(bmain), absname, localname, vfont->packedfile, how);
                if (newname != NULL) {
                        ret_value = RET_OK;
                        freePackedFile(vfont->packedfile);
@@ -499,20 +524,19 @@ int unpackVFont(ReportList *reports, VFont *vfont, int how)
                        MEM_freeN(newname);
                }
        }
-       
+
        return (ret_value);
 }
 
 int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
 {
-       char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
+       char localname[FILE_MAX], absname[FILE_MAX];
        char *newname;
        int ret_value = RET_ERROR;
 
        if (sound != NULL) {
-               BLI_split_file_part(sound->name, fi, sizeof(fi));
-               BLI_snprintf(localname, sizeof(localname), "//sounds/%s", fi);
-               newname = unpackFile(reports, sound->name, localname, sound->packedfile, how);
+               unpack_generate_paths(sound->name, (ID *)sound, absname, localname, sizeof(absname), sizeof(localname));
+               newname = unpackFile(reports, BKE_main_blendfile_path(bmain), absname, localname, sound->packedfile, how);
                if (newname != NULL) {
                        BLI_strncpy(sound->name, newname, sizeof(sound->name));
                        MEM_freeN(newname);
@@ -520,35 +544,60 @@ int unpackSound(Main *bmain, ReportList *reports, bSound *sound, int how)
                        freePackedFile(sound->packedfile);
                        sound->packedfile = NULL;
 
-                       sound_load(bmain, sound);
+                       BKE_sound_load(bmain, sound);
 
                        ret_value = RET_OK;
                }
        }
-       
+
        return(ret_value);
 }
 
-int unpackImage(ReportList *reports, Image *ima, int how)
+int unpackImage(Main *bmain, ReportList *reports, Image *ima, int how)
 {
-       char localname[FILE_MAXDIR + FILE_MAX], fi[FILE_MAX];
-       char *newname;
        int ret_value = RET_ERROR;
-       
-       if (ima != NULL && ima->name[0]) {
-               BLI_split_file_part(ima->name, fi, sizeof(fi));
-               BLI_snprintf(localname, sizeof(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 = NULL;
-                       BLI_strncpy(ima->name, newname, sizeof(ima->name));
-                       MEM_freeN(newname);
-                       BKE_image_signal(ima, NULL, IMA_SIGNAL_RELOAD);
+
+       if (ima != NULL) {
+               while (ima->packedfiles.last) {
+                       char localname[FILE_MAX], absname[FILE_MAX];
+                       char *newname;
+                       ImagePackedFile *imapf = ima->packedfiles.last;
+
+                       unpack_generate_paths(imapf->filepath, (ID *)ima, absname, localname, sizeof(absname), sizeof(localname));
+                       newname = unpackFile(reports, BKE_main_blendfile_path(bmain), absname, localname, imapf->packedfile, how);
+
+                       if (newname != NULL) {
+                               ImageView *iv;
+
+                               ret_value = ret_value == RET_ERROR ? RET_ERROR : RET_OK;
+                               freePackedFile(imapf->packedfile);
+                               imapf->packedfile = NULL;
+
+                               /* update the new corresponding view filepath */
+                               iv = BLI_findstring(&ima->views, imapf->filepath, offsetof(ImageView, filepath));
+                               if (iv) {
+                                       BLI_strncpy(iv->filepath, newname, sizeof(imapf->filepath));
+                               }
+
+                               /* keep the new name in the image for non-pack specific reasons */
+                               if (how != PF_REMOVE) {
+                                       BLI_strncpy(ima->name, newname, sizeof(imapf->filepath));
+                               }
+                               MEM_freeN(newname);
+                       }
+                       else {
+                               ret_value = RET_ERROR;
+                       }
+
+                       BLI_remlink(&ima->packedfiles, imapf);
+                       MEM_freeN(imapf);
                }
        }
-       
+
+       if (ret_value == RET_OK) {
+               BKE_image_signal(bmain, ima, NULL, IMA_SIGNAL_RELOAD);
+       }
+
        return(ret_value);
 }
 
@@ -557,16 +606,16 @@ int unpackLibraries(Main *bmain, ReportList *reports)
        Library *lib;
        char *newname;
        int ret_value = RET_ERROR;
-       
+
        for (lib = bmain->library.first; lib; lib = lib->id.next) {
                if (lib->packedfile && lib->name[0]) {
-                       
-                       newname = unpackFile(reports, lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
+
+                       newname = unpackFile(reports, BKE_main_blendfile_path(bmain), lib->filepath, lib->filepath, lib->packedfile, PF_WRITE_ORIGINAL);
                        if (newname != NULL) {
                                ret_value = RET_OK;
-                               
+
                                printf("Unpacked .blend library: %s\n", newname);
-                               
+
                                freePackedFile(lib->packedfile);
                                lib->packedfile = NULL;
 
@@ -574,27 +623,27 @@ int unpackLibraries(Main *bmain, ReportList *reports)
                        }
                }
        }
-       
+
        return(ret_value);
 }
 
 void packLibraries(Main *bmain, ReportList *reports)
 {
        Library *lib;
-       
+
        /* test for relativenss */
        for (lib = bmain->library.first; lib; lib = lib->id.next)
                if (!BLI_path_is_rel(lib->name))
                        break;
-       
+
        if (lib) {
                BKE_reportf(reports, RPT_ERROR, "Cannot pack absolute file: '%s'", lib->name);
                return;
        }
-       
+
        for (lib = bmain->library.first; lib; lib = lib->id.next)
                if (lib->packedfile == NULL)
-                       lib->packedfile = newPackedFile(reports, lib->name, bmain->name);
+                       lib->packedfile = newPackedFile(reports, lib->name, BKE_main_blendfile_path(bmain));
 }
 
 void unpackAll(Main *bmain, ReportList *reports, int how)
@@ -604,12 +653,12 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
        bSound *sound;
 
        for (ima = bmain->image.first; ima; ima = ima->id.next)
-               if (ima->packedfile)
-                       unpackImage(reports, ima, how);
+               if (BKE_image_has_packedfile(ima))
+                       unpackImage(bmain, reports, ima, how);
 
        for (vf = bmain->vfont.first; vf; vf = vf->id.next)
                if (vf->packedfile)
-                       unpackVFont(reports, vf, how);
+                       unpackVFont(bmain, reports, vf, how);
 
        for (sound = bmain->sound.first; sound; sound = sound->id.next)
                if (sound->packedfile)
@@ -619,21 +668,29 @@ void unpackAll(Main *bmain, ReportList *reports, int how)
 /* ID should be not NULL, return 1 if there's a packed file */
 bool BKE_pack_check(ID *id)
 {
-       if (GS(id->name) == ID_IM) {
-               Image *ima = (Image *)id;
-               return ima->packedfile != NULL;
-       }
-       if (GS(id->name) == ID_VF) {
-               VFont *vf = (VFont *)id;
-               return vf->packedfile != NULL;
-       }
-       if (GS(id->name) == ID_SO) {
-               bSound *snd = (bSound *)id;
-               return snd->packedfile != NULL;
-       }
-       if (GS(id->name) == ID_LI) {
-               Library *li = (Library *)id;
-               return li->packedfile != NULL;
+       switch (GS(id->name)) {
+               case ID_IM:
+               {
+                       Image *ima = (Image *)id;
+                       return BKE_image_has_packedfile(ima);
+               }
+               case ID_VF:
+               {
+                       VFont *vf = (VFont *)id;
+                       return vf->packedfile != NULL;
+               }
+               case ID_SO:
+               {
+                       bSound *snd = (bSound *)id;
+                       return snd->packedfile != NULL;
+               }
+               case ID_LI:
+               {
+                       Library *li = (Library *)id;
+                       return li->packedfile != NULL;
+               }
+               default:
+                       break;
        }
        return false;
 }
@@ -641,23 +698,38 @@ bool BKE_pack_check(ID *id)
 /* ID should be not NULL */
 void BKE_unpack_id(Main *bmain, ID *id, ReportList *reports, int how)
 {
-       if (GS(id->name) == ID_IM) {
-               Image *ima = (Image *)id;
-               if (ima->packedfile)
-                       unpackImage(reports, ima, how);
-       }
-       if (GS(id->name) == ID_VF) {
-               VFont *vf = (VFont *)id;
-               if (vf->packedfile)
-                       unpackVFont(reports, vf, how);
-       }
-       if (GS(id->name) == ID_SO) {
-               bSound *snd = (bSound *)id;
-               if (snd->packedfile)
-                       unpackSound(bmain, reports, snd, how);
-       }
-       if (GS(id->name) == ID_LI) {
-               Library *li = (Library *)id;
-               BKE_reportf(reports, RPT_ERROR, "Cannot unpack individual Library file, '%s'", li->name);
+       switch (GS(id->name)) {
+               case ID_IM:
+               {
+                       Image *ima = (Image *)id;
+                       if (BKE_image_has_packedfile(ima)) {
+                               unpackImage(bmain, reports, ima, how);
+                       }
+                       break;
+               }
+               case ID_VF:
+               {
+                       VFont *vf = (VFont *)id;
+                       if (vf->packedfile) {
+                               unpackVFont(bmain, reports, vf, how);
+                       }
+                       break;
+               }
+               case ID_SO:
+               {
+                       bSound *snd = (bSound *)id;
+                       if (snd->packedfile) {
+                               unpackSound(bmain, reports, snd, how);
+                       }
+                       break;
+               }
+               case ID_LI:
+               {
+                       Library *li = (Library *)id;
+                       BKE_reportf(reports, RPT_ERROR, "Cannot unpack individual Library file, '%s'", li->name);
+                       break;
+               }
+               default:
+                       break;
        }
 }