diff --git a/src/modules/evas/model_loaders/obj/evas_model_load_obj.c b/src/modules/evas/model_loaders/obj/evas_model_load_obj.c index 36977464ba..8f2b78a80f 100644 --- a/src/modules/evas/model_loaders/obj/evas_model_load_obj.c +++ b/src/modules/evas/model_loaders/obj/evas_model_load_obj.c @@ -37,29 +37,59 @@ struct _OBJ_Counts Eina_Bool existence_of_tex_point; }; -static inline char* -_file_to_buf(const char *file, long *length)//prepare text file for reading +typedef struct _OBJ_Loader { - FILE *file_for_print; - char *buf; - int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread" + Eina_File *file; + char *map; + int length; +} OBJ_Loader; - *length = 0; - file_for_print = fopen(file, "rb"); - if (!file_for_print) return NULL; - fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file - *length = ftell(file_for_print);//set current position of file_for_print - if (*length < 0) +static inline void +_obj_loader_fini(OBJ_Loader *loader) +{ + if (loader->map) { - fclose(file_for_print); - return NULL; + eina_file_map_free(loader->file, loader->map); + loader->map = NULL; } - buf = malloc(*length + 1); - fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file - unused = fread(buf, *length, 1, file_for_print); - fclose(file_for_print); - buf[*length] = '\0'; - return buf; + + if (loader->file) + { + eina_file_close(loader->file); + loader->file = NULL; + } +} + +static inline Eina_Bool +_obj_loader_init(OBJ_Loader *loader, const char *file) +{ + memset(loader, 0x00, sizeof(OBJ_Loader)); + + /* Open given file. */ + loader->file = eina_file_open(file, 0); + + if (loader->file == NULL) + { + ERR("Failed to open file %s\n", file); + goto error; + } + + /* Map the file. */ + loader->map = eina_file_map_all(loader->file, EINA_FILE_SEQUENTIAL); + + if (loader->map == NULL) + { + ERR("Failed to create map from file %s\n", file); + goto error; + } + + loader->length = eina_file_size_get(loader->file); + + return EINA_TRUE; + +error: + _obj_loader_fini(loader); + return EINA_FALSE; } /* create new counter */ @@ -107,11 +137,11 @@ _analyze_face_line(char * face_analyzer, } static inline OBJ_Counts -_count_elements(char *start, long length)//count elements of mesh in .obj +_count_elements(OBJ_Loader loader)//count elements of mesh in .obj { OBJ_Counts counts = _new_count_elements(); - char * current = start; + char * current = loader.map; int polygon_checker = -2;//polygons with n vertices can be represented as n-2 triangles Eina_Bool will_check_next_char = EINA_FALSE; Eina_Bool first_char_is_v = EINA_FALSE; @@ -120,7 +150,7 @@ _count_elements(char *start, long length)//count elements of mesh in .obj long i = 0; /* count elements of mesh in .obj */ - for (; length > i; i++) + for (; loader.length > i; i++) { if (will_check_next_char) { @@ -204,9 +234,9 @@ _count_elements(char *start, long length)//count elements of mesh in .obj void evas_model_load_file_obj(Evas_3D_Mesh *mesh, const char *file) { - long length, i; - char * start = _file_to_buf(file, &length); - OBJ_Counts counts = _count_elements(start, length);//count elements of mesh in .obj + long i; + OBJ_Counts counts;//count elements of mesh in .obj + OBJ_Loader loader; Eina_Bool will_check_next_char = EINA_FALSE; Eina_Bool first_char_is_v = EINA_FALSE; Eina_Bool first_char_is_f = EINA_FALSE; @@ -215,17 +245,26 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, const char *file) int j, k; char * current; + /* Initialize PLY loader */ + if (!_obj_loader_init(&loader, file)) + { + ERR("Failed to initialize PLY loader."); + return; + } + + counts = _count_elements(loader); + float *_vertices_obj = malloc(counts._vertex_counter * 3 * sizeof(float)); float *_normales_obj = malloc(counts._normal_counter * 3 * sizeof(float)); float *_tex_coords_obj = malloc(counts._texture_point_counter * 3 * sizeof(float)); /* triangle has 3 points, every point has 3(vertix, texture and normal) coord */ int *_triangles = malloc(counts._triangles_counter * 9 * sizeof(int)); - if ((start == NULL) || (_vertices_obj == NULL) || + if ((loader.map == NULL) || (_vertices_obj == NULL) || (_normales_obj == NULL) || (_tex_coords_obj == NULL) || (_triangles == NULL)) { ERR("Allocate memory is failed."); - free(start); + _obj_loader_fini(&loader); free(_vertices_obj); free(_normales_obj); free(_tex_coords_obj); @@ -233,11 +272,11 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, const char *file) return; } - current = start; + current = loader.map; i = 0; /* put data to arrays */ - for (; length > i; i++) + for (; loader.length > i; i++) { if (will_check_next_char) { @@ -337,7 +376,6 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, const char *file) } current++; } - free(start); /* prepare of mesh and take pointers to data which must be read */ eo_do(mesh, @@ -398,4 +436,5 @@ evas_model_load_file_obj(Evas_3D_Mesh *mesh, const char *file) { ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0); } + _obj_loader_fini(&loader); } diff --git a/src/modules/evas/model_loaders/ply/evas_model_load_ply.c b/src/modules/evas/model_loaders/ply/evas_model_load_ply.c index a294f6eb0a..45e28a0de3 100644 --- a/src/modules/evas/model_loaders/ply/evas_model_load_ply.c +++ b/src/modules/evas/model_loaders/ply/evas_model_load_ply.c @@ -24,24 +24,56 @@ struct _PLY_Header Eina_Bool existence_of_colors; }; -static inline char* -_file_to_buf(const char *file, long *length)//prepare text file for reading +typedef struct _PLY_Loader { - FILE *file_for_print; - char *buf; - int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread" + Eina_File *file; + char *map; +} PLY_Loader; - *length = 0; - file_for_print = fopen(file, "rb"); - if (!file_for_print) return NULL; - fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file - *length = ftell(file_for_print);//set current position of file_for_print - buf = malloc(*length + 1); - fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file - unused = fread(buf, *length, 1, file_for_print); - fclose(file_for_print); - buf[*length] = '\0'; - return buf; +static inline void +_ply_loader_fini(PLY_Loader *loader) +{ + if (loader->map) + { + eina_file_map_free(loader->file, loader->map); + loader->map = NULL; + } + + if (loader->file) + { + eina_file_close(loader->file); + loader->file = NULL; + } +} + +static inline Eina_Bool +_ply_loader_init(PLY_Loader *loader, const char *file) +{ + memset(loader, 0x00, sizeof(PLY_Loader)); + + /* Open given file. */ + loader->file = eina_file_open(file, 0); + + if (loader->file == NULL) + { + ERR("Failed to open file %s\n", file); + goto error; + } + + /* Map the file. */ + loader->map = eina_file_map_all(loader->file, EINA_FILE_SEQUENTIAL); + + if (loader->map == NULL) + { + ERR("Failed to create map from file %s\n", file); + goto error; + } + + return EINA_TRUE; + +error: + _ply_loader_fini(loader); + return EINA_FALSE; } /* create new header */ @@ -102,7 +134,7 @@ _read_data(float *array, int place, int count, char *current, float divider) } static inline PLY_Header -_read_header(char *start)//Check properties of mesh in .ply file. +_read_header(char *map)//Check properties of mesh in .ply file. { eina_init(); @@ -113,7 +145,7 @@ _read_header(char *start)//Check properties of mesh in .ply file. PLY_Header header; header = _new_ply_header(); - helping_pointer = eina_str_split(start, "vertex ", 0); + helping_pointer = eina_str_split(map, "vertex ", 0); if (helping_pointer == NULL) { @@ -124,7 +156,7 @@ _read_header(char *start)//Check properties of mesh in .ply file. sscanf(helping_pointer[1], "%d", &header.vertices_count); free(helping_pointer); - helping_pointer = eina_str_split(start, "end_header\n", 0); + helping_pointer = eina_str_split(map, "end_header\n", 0); if (helping_pointer == NULL) { @@ -164,7 +196,7 @@ _read_header(char *start)//Check properties of mesh in .ply file. free(helping_pointer); /* analyse flags used when file was saved in blender */ - helping_pointer = eina_str_split(start, "property float ", 0); + helping_pointer = eina_str_split(map, "property float ", 0); if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'x') && (helping_pointer[2] != NULL) && (*helping_pointer[2] == 'y') && @@ -185,7 +217,7 @@ _read_header(char *start)//Check properties of mesh in .ply file. (helping_pointer[5] != NULL) && (*helping_pointer[5] == 't')))) header.existence_of_texcoords = EINA_TRUE; - helping_pointer = eina_str_split(start, "property uchar ", 0); + helping_pointer = eina_str_split(map, "property uchar ", 0); if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'r') && (helping_pointer[2] != NULL) && (*helping_pointer[2] == 'g') && @@ -200,25 +232,25 @@ _read_header(char *start)//Check properties of mesh in .ply file. void evas_model_load_file_ply(Evas_3D_Mesh *mesh, const char *file) { - long length; Evas_3D_Mesh_Data *pd; int i = 0, j = 0, k = 0, count_of_triangles_in_line = 0; float *pos, *nor, *tex, *col; int stride_pos, stride_nor, stride_tex, stride_col; - char *start, *current; + char *current; PLY_Header header; - float *_vertices_ply = NULL, *_normals_ply = NULL, *_tex_coords_ply = NULL, *_colors_ply = NULL; + float *_vertices_ply = NULL, *_normals_ply = NULL; + float *_tex_coords_ply = NULL, *_colors_ply = NULL; char **helping_pointer; + PLY_Loader loader; - start = _file_to_buf(file, &length); - - if (start == NULL) + /* Initialize PLY loader */ + if (!_ply_loader_init(&loader, file)) { - ERR("Buffer is empty after preparation file for reading."); + ERR("Failed to initialize PLY loader."); return; } - header = _read_header(start); + header = _read_header(loader.map); if (!header.existence_of_geometries) { @@ -226,7 +258,7 @@ evas_model_load_file_ply(Evas_3D_Mesh *mesh, const char *file) return; } - helping_pointer = eina_str_split(start, "end_header\n", 0); + helping_pointer = eina_str_split(loader.map, "end_header\n", 0); if (helping_pointer == NULL) { @@ -252,7 +284,7 @@ evas_model_load_file_ply(Evas_3D_Mesh *mesh, const char *file) (_triangles == NULL)) { ERR("Allocate memory is failed."); - free(start); + _ply_loader_fini(&loader); free(_vertices_ply); free(_normals_ply); free(_tex_coords_ply); @@ -398,4 +430,6 @@ evas_model_load_file_ply(Evas_3D_Mesh *mesh, const char *file) { ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0); } + + _ply_loader_fini(&loader); }