/* 4. PREFIX/evas/modules/ */ void evas_module_paths_init(void) { char *libdir, *path; /* 1. ~/.evas/modules/ */ path = eina_module_environment_path_get("HOME", "/.evas/modules"); evas_module_paths = _evas_module_append(evas_module_paths, path); /* 2. $(EVAS_MODULE_DIR)/evas/modules/ */ path = eina_module_environment_path_get("EVAS_MODULES_DIR", "/evas/modules"); if (eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path)) free(path); else evas_module_paths = _evas_module_append(evas_module_paths, path); /* 3. libevas.so/../evas/modules/ */ libdir = (char *)_evas_module_libdir_get(); if (!libdir) path = eina_module_symbol_path_get(evas_module_paths_init, "/evas/modules"); else { path = malloc(strlen(libdir) + strlen("/evas/modules") + 1); if (path) { strcpy(path, libdir); strcat(path, "/evas/modules"); } } if (eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path)) free(path); else evas_module_paths = _evas_module_append(evas_module_paths, path); /* 4. PREFIX/lib/evas/modules/ */ #ifndef _MSC_VER path = PACKAGE_LIB_DIR "/evas/modules"; if (!eina_list_search_unsorted(evas_module_paths, (Eina_Compare_Cb) strcmp, path)) { path = strdup(path); if (path) evas_module_paths = _evas_module_append(evas_module_paths, path); } #endif }
static Eina_Bool _load(Eina_File *ef, const char *key, Evas_Image_Property *prop, Evas_Image_Load_Opts *opts, void *pixels, int *error, Eina_Bool get_data) { Eina_Bool res = EINA_FALSE; int w = 0, h = 0, alpha = 0; const char *dot1 = NULL, *dot2 = NULL, *end, *p; char *cmd = NULL, decoders[3][128], buf[4096]; char *loader = "/evas/utils/evas_image_loader"; char *img_loader = NULL; const char *libdir; // eg $libdir/evas/generic_loaders int cmd_len, len, decoders_num = 0, try_count = 0; int read_data = 0; char *tmpfname = NULL, *shmfname = NULL; DATA32 *body; FILE *f = NULL; libdir = _evas_module_libdir_get(); cmd_len = strlen(libdir); cmd_len += strlen(loader); img_loader = alloca(cmd_len + 1); strcpy(img_loader, libdir); strcat(img_loader, loader); // params excluding file, key and loadopts cmd_len += 1024; cmd_len += strlen(eina_file_filename_get(ef)) * 2; if (key) cmd_len += strlen(key) * 2; cmd = alloca(cmd_len + 1); len = strlen(eina_file_filename_get(ef)); if (len < 1) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } end = eina_file_filename_get(ef) + len; for (p = end - 1; p >= eina_file_filename_get(ef); p--) { if ((!dot1) && (*p == '.')) dot1 = p; else if ((!dot2) && (*p == '.')) dot2 = p; else if ((dot1) && (dot2)) break; } if (dot2) { // double extn not too long if (((end - dot2) <= 10) && (!illegal_char(dot2))) { strncpy(&(decoders[decoders_num][0]), img_loader, 127); decoders[decoders_num][127] = 0; dotcat(&(decoders[decoders_num][0]), dot2); decoders_num++; } // single extn not too long if (((end - dot1) <= 5) && (!illegal_char(dot1))) { strncpy(&(decoders[decoders_num][0]), img_loader, 127); decoders[decoders_num][127] = 0; dotcat(&(decoders[decoders_num][0]), dot1); decoders_num++; } strncpy(decoders[decoders_num], img_loader, 127); decoders[decoders_num][127] = 0; decoders_num++; } else if (dot1) { // single extn not too long if (((end - dot1) <= 5) && (!illegal_char(dot1))) { strncpy(&(decoders[decoders_num][0]), img_loader, 127); decoders[decoders_num][127] = 0; dotcat(&(decoders[decoders_num][0]), dot1); decoders_num++; } strncpy(decoders[decoders_num], img_loader, 127); decoders[decoders_num][127] = 0; decoders_num++; } else { strncpy(decoders[decoders_num], img_loader, 127); decoders[decoders_num][127] = 0; decoders_num++; } for (try_count = 0; try_count < decoders_num; try_count++) { // FIXME: strcats could be more efficient, not that it matters much // here as we are about to build a cmd to exec via a shell that // will interpret shell stuff and path hunt that will then exec the // program itself that will dynamically link that will again // parse the arguments and finally do something... if (access(decoders[try_count], X_OK)) continue; strcpy(cmd, decoders[try_count]); strcat(cmd, " "); // filename first arg len = strlen(cmd); escape_copy(eina_file_filename_get(ef), cmd + len); if (!get_data) { strcat(cmd, " -head "); } if (key) { strcat(cmd, " -key "); len = strlen(cmd); escape_copy(key, cmd + len); } if (opts->scale_down_by > 1) { strcat(cmd, " -opt-scale-down-by "); snprintf(buf, sizeof(buf), "%i", opts->scale_down_by); strcat(cmd, buf); } if (opts->dpi > 0.0) { strcat(cmd, " -opt-dpi "); snprintf(buf, sizeof(buf), "%i", (int)(opts->dpi * 1000.0)); strcat(cmd, buf); } if ((opts->w > 0) && (opts->h > 0)) { strcat(cmd, " -opt-size "); snprintf(buf, sizeof(buf), "%i %i", opts->w, opts->h); strcat(cmd, buf); } f = popen(cmd, "r"); if (f) break; } if (!f) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } while (fgets(buf, sizeof(buf), f)) { len = strlen(buf); if (len > 0) { if (buf[len - 1] == '\n') buf[len - 1] = 0; if (!strncmp(buf, "size ", 5)) { int tw = 0, th = 0; len = sscanf(buf, "%*s %i %i", &tw, &th); if (len == 2) { if ((tw > 0) && (th > 0)) { w = tw; h = th; } } } else if (!strncmp(buf, "alpha ", 6)) { int ta; len = sscanf(buf, "%*s %i", &ta); if (len == 1) { alpha = ta; } } else if (!strncmp(buf, "tmpfile ", 8)) { tmpfname = buf + 8; goto getdata; } #ifdef HAVE_SHM_OPEN else if (!strncmp(buf, "shmfile ", 8)) { shmfname = buf + 8; goto getdata; } #endif else if (!strncmp(buf, "data", 4)) { read_data = 1; goto getdata; } else if (!strncmp(buf, "done", 4)) { read_data = 2; goto getdata; } } } getdata: if ((!read_data) && (!tmpfname) && (!shmfname)) { *error = EVAS_LOAD_ERROR_CORRUPT_FILE; goto on_error; } if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || IMG_TOO_BIG(w, h)) { *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto on_error; } if (!get_data) { if (alpha) prop->alpha = 1; prop->w = w; prop->h = h; } else { if ((int)prop->w != w || (int)prop->h != h) { *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto on_error; } body = pixels; if ((tmpfname) || (shmfname)) { int fd = -1; // open if (tmpfname) fd = open(tmpfname, O_RDONLY, S_IRUSR); #ifdef HAVE_SHM_OPEN else if (shmfname) fd = shm_open(shmfname, O_RDONLY, S_IRUSR); #endif if (fd >= 0) { void *addr; eina_mmap_safety_enabled_set(EINA_TRUE); // mmap addr = mmap(NULL, w * h * sizeof(DATA32), PROT_READ, MAP_SHARED, fd, 0); if (addr != MAP_FAILED) { memcpy(body, addr, w * h * sizeof(DATA32)); munmap(addr, w * h * sizeof(DATA32)); } // close if (tmpfname) { close(fd); unlink(tmpfname); } #ifdef HAVE_SHM_OPEN else if (shmfname) { close(fd); shm_unlink(shmfname); } #endif } else { *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto on_error; } } else if (read_data) { if (fread(body, w * h * sizeof(DATA32), 1, f) != 1) { *error = EVAS_LOAD_ERROR_CORRUPT_FILE; goto on_error; } } } res = EINA_TRUE; *error = EVAS_LOAD_ERROR_NONE; on_error: if (f) pclose(f); return res; }