- re-wrote image exporting function renaming it from BKE_export_image to BKE_get_imag...
authorArystanbek Dyussenov <arystan.d@gmail.com>
Mon, 3 Aug 2009 12:02:40 +0000 (12:02 +0000)
committerArystanbek Dyussenov <arystan.d@gmail.com>
Mon, 3 Aug 2009 12:02:40 +0000 (12:02 +0000)
files but only manipulates paths. It produces both ablsolute and relative paths. COLLADA exporter can now use it.
- re-wrote unit test for it, this is now more compact and readable
- RNA API Image.get_export_path takes a boolean arg to indicate whether a relative or absolute path should be returned. Python scripts
can now use it.

source/blender/blenkernel/BKE_image.h
source/blender/blenkernel/intern/image.c
source/blender/makesrna/intern/rna_image_api.c
source/creator/tests/alltest.c

index 052f7738f2b087e6fa1e5a141008722692f43a6a..56c58cdc6bfbd73391200cf775cf505e45a89c4d 100644 (file)
@@ -156,8 +156,7 @@ struct Image *BKE_image_copy(struct Image *ima);
 void BKE_image_merge(struct Image *dest, struct Image *source);
 
 /* copy image file to a directory rebuilding subdirectory structure */
-int BKE_export_image(struct Image *im, const char *dest_dir, char *out_path, int out_path_len);
-
+int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size);
 
 #ifdef __cplusplus
 }
index f0b29f766ec020a07187392c5ee7695b4482ea78..276d79b7e327ea1b8c74133eff23391b53cb961f 100644 (file)
@@ -2117,41 +2117,51 @@ void BKE_image_user_calc_imanr(ImageUser *iuser, int cfra, int fieldnr)
 }
 
 /*
-  Copy an image to destination directory rebuilding subdirectory structure if needed.
-  Target image path is written to out_path.
-  Returns 1 on success, 0 otherwise.
+  Produce image export path.
+
+  Fails returning 0 if image filename is empty or if destination path
+  matches image path (i.e. both are the same file).
+
+  Trailing slash in dest_dir is optional.
 
   Logic:
 
-  - if an image is "below" current .blend file directory, rebuild the same dir structure in dest_dir
+  - if an image is "below" current .blend file directory, rebuild the
+    same dir structure in dest_dir
 
-  For example //textures/foo/bar.png becomes [dest_dir]/textures/foo/bar.png.
+  For example //textures/foo/bar.png becomes
+  [dest_dir]/textures/foo/bar.png.
 
-  - if an image is not "below" current .blend file directory, disregard it's path and copy it in the
-  same directory where 3D file goes.
+  - if an image is not "below" current .blend file directory,
+  disregard it's path and copy it in the same directory where 3D file
+  goes.
 
   For example //../foo/bar.png becomes [dest_dir]/bar.png.
 
   This logic will help ensure that all image paths are relative and
   that a user gets his images in one place. It'll also provide
   consistent behaviour across exporters.
-
  */
-int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_path_len)
+int BKE_get_image_export_path(struct Image *im, const char *dest_dir, char *abs, int abs_size, char *rel, int rel_size)
 {
        char path[FILE_MAX];
        char dir[FILE_MAX];
        char base[FILE_MAX];
        char blend_dir[FILE_MAX];       /* directory, where current .blend file resides */
        char dest_path[FILE_MAX];
+       char rel_dir[FILE_MAX];
        int len;
 
-       out_path[0]= 0;
+       if (abs)
+               abs[0]= 0;
+
+       if (rel)
+               rel[0]= 0;
 
        BLI_split_dirfile_basic(G.sce, blend_dir, NULL);
 
-       if (!strcmp(im->name, "") || im->type != IMA_TYPE_IMAGE) {
-               if (G.f & G_DEBUG) printf("invalid image type\n");
+       if (!strlen(im->name)) {
+               if (G.f & G_DEBUG) printf("Invalid image type.\n");
                return 0;
        }
 
@@ -2160,61 +2170,48 @@ int BKE_export_image(Image *im, const char *dest_dir, char *out_path, int out_pa
        /* expand "//" in filename and get absolute path */
        BLI_convertstringcode(path, G.sce);
 
-       /* proceed only if image file exists */
-       if (!BLI_exists(path)) {
-               if (G.f & G_DEBUG) printf("%s doesn't exist\n", path);
-               return 0;
-       }
-
        /* get the directory part */
        BLI_split_dirfile_basic(path, dir, base);
 
        len= strlen(blend_dir);
 
+       rel_dir[0] = 0;
+
        /* if image is "below" current .blend file directory */
        if (!strncmp(path, blend_dir, len)) {
 
                /* if image is _in_ current .blend file directory */
                if (!strcmp(dir, blend_dir)) {
-                       /* copy to dest_dir */
                        BLI_join_dirfile(dest_path, dest_dir, base);
                }
                /* "below" */
                else {
-                       char rel[FILE_MAX];
-
                        /* rel = image_path_dir - blend_dir */
-                       BLI_strncpy(rel, dir + len, sizeof(rel));
-                               
-                       BLI_join_dirfile(dest_path, dest_dir, rel);
-
-                       /* build identical directory structure under dest_dir */
-                       BLI_recurdir_fileops(dest_path);
+                       BLI_strncpy(rel_dir, dir + len, sizeof(rel_dir));
 
+                       BLI_join_dirfile(dest_path, dest_dir, rel_dir);
                        BLI_join_dirfile(dest_path, dest_path, base);
                }
                        
        }
        /* image is out of current directory */
        else {
-               /* copy to dest_dir */
                BLI_join_dirfile(dest_path, dest_dir, base);
        }
 
-       if (G.f & G_DEBUG) printf("copying %s to %s\n", path, dest_path);
-
-       /* only copy if paths differ */
-       if (strcmp(path, dest_path)) {
-               if (BLI_copy_fileops(path, dest_path) != 0) {
-                       if (G.f & G_DEBUG) printf("couldn't copy %s to %s\n", path, dest_path);
-                       return 0;
-               }
-       }
-       else if (G.f & G_DEBUG){
-               printf("%s and %s are the same file\n", path, dest_path);
+       /* only return 1 if paths differ */
+       if (!strcmp(path, dest_path)) {
+               if (G.f & G_DEBUG) printf("%s and %s are the same file\n", path, dest_path);
+               return 0;
        }
 
-       BLI_strncpy(out_path, dest_path, out_path_len);
+       if (abs)
+               BLI_strncpy(abs, dest_path, abs_size);
+
+       if (rel) {
+               strncat(rel, rel_dir, rel_size);
+               strncat(rel, base, rel_size);
+       }
 
        return 1;
 }
index 42ee2b64c7aed858043f10dd0ad46cef689373f7..20770ef29571495ae05cde7985797a84dbdd518c 100644 (file)
 #include "BKE_utildefines.h"
 #include "BKE_image.h"
 
-static char *rna_Image_export(Image *image, char *dest_dir)
+static char *rna_Image_get_export_path(Image *image, char *dest_dir, int rel)
 {
        int length = FILE_MAX;
        char *path= MEM_callocN(length, "image file path");
 
-       if (!BKE_export_image(image, dest_dir, path, length)) {
+       if (!BKE_get_image_export_path(image, dest_dir, rel ? NULL : path, length, rel ? path : NULL, length )) {
                MEM_freeN(path);
                return NULL;
        }
@@ -61,11 +61,13 @@ void RNA_api_image(StructRNA *srna)
        FunctionRNA *func;
        PropertyRNA *parm;
 
-       func= RNA_def_function(srna, "export", "rna_Image_export");
-       RNA_def_function_ui_description(func, "Copy image file to a directory rebuilding subdirectory structure.");
+       func= RNA_def_function(srna, "export", "rna_Image_get_export_path");
+       RNA_def_function_ui_description(func, "Produce image export path.");
        parm= RNA_def_string(func, "dest_dir", "", 0, "", "Destination directory.");
        RNA_def_property_flag(parm, PROP_REQUIRED);
-       parm= RNA_def_string(func, "path", "", 0, "", "Absolute file path of copied image.");
+       parm= RNA_def_boolean(func, "get_rel_path", 1, "", "Return relative path if True.");
+       RNA_def_property_flag(parm, PROP_REQUIRED);
+       parm= RNA_def_string(func, "path", "", 0, "", "Absolute export path.");
        RNA_def_function_return(func, parm);
 }
 
index 8bb2b1a9bb0ed60cfba92c2f15934b4d012090d9..99e0d2f5b2687e01cab91306bd829bb2e86cc9c3 100644 (file)
 char bprogname[FILE_MAXDIR+FILE_MAXFILE];
 char btempdir[FILE_MAXDIR+FILE_MAXFILE];
 
+typedef struct ImageTestResult {
+       char *path;
+       char *rel;
+       int ret;
+} ImageTestResult;
+
 typedef struct ImageTestData {
        char *path; /* image filename */
-       char *expect_path; /* file path that we expect */
-       int type; /* image type */
-       int ret;  /* expected function return value */
-       int create_file; /* whether the file should be created */
+       ImageTestResult result[10];
 } ImageTestData;
 
-/* recursively deletes a directory only if it is under /tmp */
-static void delete_only_tmp(char *path, int dir) {
-#ifdef WIN32
-#else
-       if (!strncmp(path, "/tmp/", 5) && BLI_exists(path)) {
-               BLI_delete(path, dir, 1);
-       }
-#endif
-}
-
-static void touch_only_tmp(char *path) {
-#ifdef WIN32
-#else
-       if (!strncmp(path, "/tmp/", 5)) {
-               BLI_touch(path);
-       }
-#endif
-}
-
 /* check that BKE_copy_images manipulates paths correctly */
 START_TEST(test_copy_images)
 {
        char **dir;
        ImageTestData *test;
+       int i,j;
 
-       /* XXX Windows not tested */    
 #ifdef WIN32
-       static ImageTestData test_data[] = {
-               {"//bar/image.png", "C:\\Temp\\bar\\image.png"},
-               /* TODO add more */
-               {NULL, NULL},
-       };
-       
-       BLI_strncpy(G.sce, "C:\\Temp\untitled.blend", sizeof(G.sce));
+       /* TBD... */
 #else
        /*
          XXX are these paths possible in image->name?:
@@ -70,77 +48,100 @@ START_TEST(test_copy_images)
 
          if so, BKE_copy_images currently doesn't support them!
         */
+
+       const char *blend_dir = "/home/user/foo";
+       char *dest_dir[] = {"/home/user/", "/home/user", "/home/user/export/", "/home/user/foo/", NULL};
+
        static ImageTestData test_data[] = {
-               {"//bar/image.png", "/tmp/blender/dest/bar/image.png", IMA_TYPE_IMAGE, 1, 1},
-               {"//image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1},
-               {"//textures/test/foo/bar/image.png", "/tmp/blender/dest/textures/test/foo/bar/image.png", IMA_TYPE_IMAGE, 1, 1},
-               {"//textures/test/foo/bar/image.png", "", IMA_TYPE_MULTILAYER, 0, 1},
-               {"//./foo/bar/image.png", "/tmp/blender/dest/foo/bar/image.png", IMA_TYPE_IMAGE, 1, 1},
-               {"//../foo/bar/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1},
-               {"/tmp/blender/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1},
-               /* expecting it to return 1 when src and dest are the same file */
-               {"/tmp/blender/foo/bar/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1},
-               {"/tmp/blender/dest/image.png", "/tmp/blender/dest/image.png", IMA_TYPE_IMAGE, 1, 1},
-               /* expecting empty path and 0 return value for non-existing files */
-               {"/tmp/blender/src/file-not-created", "", IMA_TYPE_IMAGE, 0, 0},
-               {"", "", IMA_TYPE_IMAGE, 0, 0},
-               {NULL, NULL},
-       };
 
-       char *dest_dir[] = {"/tmp/blender/dest/", "/tmp/blender/dest", NULL};
-       const char *blend_dir = "/tmp/blender/src";
+               /* image path | [expected output path | corresponding relative path | expected return value] */
+
+               /* relative, 0 level deep */
+               {"//image.png", {{"/home/user/image.png", "image.png", 1},
+                                                {"/home/user/image.png", "image.png", 1},
+                                                {"/home/user/export/image.png", "image.png", 1},
+                                                {"", "", 0},}},
+
+               /* relative, 1 level deep */
+               {"//bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1},
+                                                        {"/home/user/bar/image.png", "bar/image.png", 1},
+                                                        {"/home/user/export/bar/image.png", "bar/image.png", 1},
+                                                        {"", "", 0},}},
+
+               /* relative, 2 level deep */
+               {"//bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1},
+                                                                {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1},
+                                                                {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1},
+                                                                {"", "", 0},}},
+
+               /* absolute, not under .blend dir */
+               {"/home/user/bar/image.png", {{"/home/user/image.png", "image.png", 1},
+                                                                         {"/home/user/image.png", "image.png", 1},
+                                                                         {"/home/user/export/image.png", "image.png", 1},
+                                                                         {"/home/user/foo/image.png", "image.png", 1},}},
+
+               /* absolute, under .blend dir, 0 level deep */
+               {"/home/user/foo/image.png", {{"/home/user/image.png", "image.png", 1},
+                                                                         {"/home/user/image.png", "image.png", 1},
+                                                                         {"/home/user/export/image.png", "image.png", 1},
+                                                                         {"", "", 0},}},
+
+               /* absolute, under .blend dir, 1 level deep */
+               {"/home/user/foo/bar/image.png", {{"/home/user/bar/image.png", "bar/image.png", 1},
+                                                                                 {"/home/user/bar/image.png", "bar/image.png", 1},
+                                                                                 {"/home/user/export/bar/image.png", "bar/image.png", 1},
+                                                                                 {"", "", 0},}},
+
+               /* absolute, under .blend dir, 2 level deep */
+               {"/home/user/foo/bar/foo/image.png", {{"/home/user/bar/foo/image.png", "bar/foo/image.png", 1},
+                                                                                         {"/home/user/bar/foo/image.png", "bar/foo/image.png", 1},
+                                                                                         {"/home/user/export/bar/foo/image.png", "bar/foo/image.png", 1},
+                                                                                         {"", "", 0},}},
+
+               /* empty image path, don't let these pass! */
+               {"", {{"", 0},
+                         {"", 0},
+                         {"", 0}}},
+
+               {NULL},
+       };
        
        /* substitute G.sce */
        BLI_snprintf(G.sce, sizeof(G.sce), "%s/untitled.blend", blend_dir);
 #endif
 
-       /* only delete files/directories under /tmp/ ! */
-       delete_only_tmp(blend_dir, 1);
-
-       for (dir = dest_dir; *dir; dir++) {
-               delete_only_tmp(*dir, 1);
-       }
-
-       /* create files */
-       BLI_recurdir_fileops(blend_dir);
-
-       /* create fake empty source files */
-       for (test= &test_data[0]; test->path; test++) {
-               char dir[FILE_MAX];
-               char path[FILE_MAX];
-
-               if (!test->create_file) continue;
-
-               /* expand "//" */
-               BLI_strncpy(path, test->path, sizeof(path));
-               BLI_convertstringcode(path, G.sce);
-
-               /* create a directory */
-               BLI_split_dirfile_basic(path, dir, NULL);
-               BLI_recurdir_fileops(dir);
-
-               /* create a file */
-               touch_only_tmp(path);
-       }
-
-       for (dir = dest_dir; *dir; dir++) {
+       for (dir= dest_dir, i= 0; *dir; dir++, i++) {
                for (test= &test_data[0]; test->path; test++) {
                        Image image;
                        char path[FILE_MAX];
+                       char rel[FILE_MAX];
                        char part[200];
                        int ret;
 
                        BLI_strncpy(image.name, test->path, sizeof(image.name));
-                       image.type= test->type;
 
-                       ret= BKE_export_image(&image, *dir, path, sizeof(path));
+                       /* passing NULL as abs path or rel path or both shouldn't break it */
+                       int abs_rel_null[][2]= {{0, 0}, {1, 0}, {0, 1}, {1, 1}, {-1}};
+
+                       for (j= 0; abs_rel_null[j][0] != -1; j++) {
+
+                               int *is_null= abs_rel_null[j];
+
+                               ret= BKE_get_image_export_path(&image, *dir,
+                                                                                          is_null[0] ? NULL : path, sizeof(path),
+                                                                                          is_null[1] ? NULL : rel, sizeof(rel));
+
+                               BLI_snprintf(part, sizeof(part), "For image at %s (output abs path is %s, rel path is %s)",
+                                                        test->path, is_null[0] ? "NULL" : "non-NULL", is_null[1] ? "NULL" : "non-NULL");
+
+                               /* we should get what we expect */
+                               ImageTestResult *res= &test->result[i];
+                               fail_if(ret != res->ret, "%s, expected to return %d got %d.", part, res->ret, ret);
 
-                       /* check if we got correct output */
-                       BLI_snprintf(part, sizeof(part), "For image with filename %s and type %d", test->path, test->type);
-                       fail_if(ret != test->ret, "%s, expected %d as return value got %d.", part, test->ret, ret);
-                       fail_if(strcmp(path, test->expect_path), "%s, expected path %s got \"%s\".", part, test->expect_path, path);
-                       if (test->ret == ret && ret == 1) {
-                               fail_if(!BLI_exists(test->expect_path), "%s, expected %s to be created.", part, test->expect_path);
+                               if (!is_null[0] && res->path)
+                                       fail_if(strcmp(path, res->path), "%s, expected absolute path \"%s\" got \"%s\".", part, res->path, path);
+                               if (!is_null[1] && res->rel)
+                                       fail_if(strcmp(rel, res->rel), "%s, expected relative path \"%s\" got \"%s\".", part, res->rel, rel);
                        }
                }
        }
@@ -149,10 +150,10 @@ END_TEST
 
 static Suite *image_suite(void)
 {
-       Suite *s = suite_create("Image");
+       Suite *s= suite_create("Image");
 
        /* Core test case */
-       TCase *tc_core = tcase_create("Core");
+       TCase *tc_core= tcase_create("Core");
        tcase_add_test(tc_core, test_copy_images);
        suite_add_tcase(s, tc_core);
 
@@ -162,8 +163,8 @@ static Suite *image_suite(void)
 int run_tests()
 {
        int totfail;
-       Suite *s = image_suite();
-       SRunner *sr = srunner_create(s);
+       Suite *s= image_suite();
+       SRunner *sr= srunner_create(s);
 
        /* run tests */
        srunner_run_all(sr, CK_VERBOSE);