static Eina_Bool evas_image_load_file_head_eet(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error) { int alpha, compression, quality, lossy; unsigned int w, h; Eet_File *ef; int ok; Eina_Bool res = EINA_FALSE; if (!key) { *error = CSERVE2_DOES_NOT_EXIST; return EINA_FALSE; } ef = eet_open((char *)file, EET_FILE_MODE_READ); if (!ef) { *error = CSERVE2_DOES_NOT_EXIST; return EINA_FALSE; } ok = eet_data_image_header_read(ef, key, &w, &h, &alpha, &compression, &quality, &lossy); if (!ok) { *error = CSERVE2_DOES_NOT_EXIST; goto on_error; } if (IMG_TOO_BIG(w, h)) { *error = CSERVE2_RESOURCE_ALLOCATION_FAILED; goto on_error; } if (alpha) ilp->alpha = 1; ilp->w = w; ilp->h = h; res = EINA_TRUE; *error = CSERVE2_NONE; on_error: eet_close(ef); return res; }
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; }
Eina_Bool evas_image_load_file_data_eet(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error) { unsigned int w, h; int alpha, compression, quality, lossy, ok; Eet_File *ef; DATA32 *body, *p, *end, *data; DATA32 nas = 0; Eina_Bool res = EINA_FALSE; if (!key) { *error = CSERVE2_DOES_NOT_EXIST; return EINA_FALSE; } ef = eet_open(file, EET_FILE_MODE_READ); if (!ef) { *error = CSERVE2_DOES_NOT_EXIST; return EINA_FALSE; } ok = eet_data_image_header_read(ef, key, &w, &h, &alpha, &compression, &quality, &lossy); if (IMG_TOO_BIG(w, h)) { *error = CSERVE2_RESOURCE_ALLOCATION_FAILED; goto on_error; } if (!ok) { *error = CSERVE2_DOES_NOT_EXIST; goto on_error; } data = ilp->buffer; if (!data) { *error = CSERVE2_RESOURCE_ALLOCATION_FAILED; goto on_error; } ok = eet_data_image_read_to_surface(ef, key, 0, 0, data, w, h, w * 4, &alpha, &compression, &quality, &lossy); if (!ok) { *error = CSERVE2_GENERIC; goto on_error; } if (alpha) { ilp->alpha = 1; body = ilp->buffer; end = body + (w * h); for (p = body; p < end; p++) { DATA32 r, g, b, a; a = A_VAL(p); r = R_VAL(p); g = G_VAL(p); b = B_VAL(p); if ((a == 0) || (a == 255)) nas++; if (r > a) r = a; if (g > a) g = a; if (b > a) b = a; *p = ARGB_JOIN(a, r, g, b); } if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (w * h)) ilp->alpha_sparse = 1; } *error = CSERVE2_NONE; res = EINA_TRUE; on_error: eet_close(ef); return res; }
Eina_Bool evas_image_load_file_data_eet(Image_Entry *ie, const char *file, const char *key, int *error) { unsigned int w, h; int alpha, compression, quality, lossy, ok; Eet_File *ef; DATA32 *body, *p, *end; DATA32 nas = 0; Eina_Bool res = EINA_FALSE; if (!key) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } if (ie->flags.loaded) { *error = EVAS_LOAD_ERROR_NONE; return EINA_TRUE; } ef = eet_open(file, EET_FILE_MODE_READ); if (!ef) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } ok = eet_data_image_header_read(ef, key, &w, &h, &alpha, &compression, &quality, &lossy); if (IMG_TOO_BIG(w, h)) { *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; goto on_error; } if (!ok) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; goto on_error; } evas_cache_image_surface_alloc(ie, w, h); ok = eet_data_image_read_to_surface(ef, key, 0, 0, evas_cache_image_pixels(ie), w, h, w * 4, &alpha, &compression, &quality, &lossy); if (!ok) { *error = EVAS_LOAD_ERROR_GENERIC; goto on_error; } if (alpha) { ie->flags.alpha = 1; body = evas_cache_image_pixels(ie); end = body +(w * h); for (p = body; p < end; p++) { DATA32 r, g, b, a; a = A_VAL(p); r = R_VAL(p); g = G_VAL(p); b = B_VAL(p); if ((a == 0) || (a == 255)) nas++; if (r > a) r = a; if (g > a) g = a; if (b > a) b = a; *p = ARGB_JOIN(a, r, g, b); } if ((ALPHA_SPARSE_INV_FRACTION * nas) >= (ie->w * ie->h)) ie->flags.alpha_sparse = 1; } // result is already premultiplied now if u compile with edje // evas_common_image_premul(im); *error = EVAS_LOAD_ERROR_NONE; res = EINA_TRUE; on_error: eet_close(ef); return res; }
static Eina_Bool evas_image_load_file_head_ico(Evas_Img_Load_Params *ilp, const char *file, const char *key, int *error) { Eina_File *f; void *map = NULL; size_t position = 0; unsigned short word; unsigned char byte; int wanted_w = 0, wanted_h = 0, w, h, cols, i, planes = 0, bpp = 0, pdelta, search = -1, have_choice = 0, hasa = 1; unsigned int bmoffset, bmsize, fsize; unsigned short reserved, type, count; struct { int pdelta; int w, h; int cols; int bpp, planes; int hot_x, hot_y; unsigned int bmoffset, bmsize; } chosen = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; f = eina_file_open(file, EINA_FALSE); if (!f) { *error = EVAS_LOAD_ERROR_DOES_NOT_EXIST; return EINA_FALSE; } *error = EVAS_LOAD_ERROR_UNKNOWN_FORMAT; fsize = eina_file_size_get(f); if (fsize < (6 + 16 + 40)) goto close_file; map = eina_file_map_all(f, EINA_FILE_SEQUENTIAL); if (!map) goto close_file; // key: // NULL == highest res // biggest == highest res // smallest == lowest res // // smaller == next size SMALLER than load opts WxH (if possible) // bigger == next size BIGGER than load opts WxH (if possible) // more ? search = BIGGEST; if ((ilp->opts.w > 0) && (ilp->opts.h > 0)) { wanted_w = ilp->opts.w; wanted_h = ilp->opts.h; search = SMALLER; } if (!read_ushort(map, fsize, &position, &reserved)) goto close_file; if (!read_ushort(map, fsize, &position, &type)) goto close_file; if (!read_ushort(map, fsize, &position, &count)) goto close_file; if (!((reserved == 0) && ((type == ICON) || (type == CURSOR)) && (count > 0))) goto close_file; *error = EVAS_LOAD_ERROR_CORRUPT_FILE; if (key) { if (!strcmp(key, "biggest")) { wanted_w = 0; wanted_h = 0; search = BIGGEST; chosen.pdelta = 0; } else if (!strcmp(key, "smallest")) { wanted_w = 1; wanted_h = 1; search = SMALLEST; chosen.pdelta = 0x7fffffff; } else if (!strcmp(key, "smaller")) { chosen.pdelta = 0x7fffffff; search = SMALLER; } else if (!strcmp(key, "bigger")) { chosen.pdelta = 0x7fffffff; search = BIGGER; } } for (i = 0; i < count; i++) { unsigned char tw = 0, th = 0, tcols = 0; if (!read_uchar(map, fsize, &position, &tw)) goto close_file; w = tw; if (w <= 0) w = 256; if (!read_uchar(map, fsize, &position, &th)) goto close_file; h = th; if (h <= 0) h = 256; if (!read_uchar(map, fsize, &position, &tcols)) goto close_file; cols = tcols; if (cols <= 0) cols = 256; if (!read_uchar(map, fsize, &position, &byte)) goto close_file; if (!read_ushort(map, fsize, &position, &word)) goto close_file; if (type == CURSOR) planes = word; //else hot_x = word; if (!read_ushort(map, fsize, &position, &word)) goto close_file; if (type == CURSOR) bpp = word; //else hot_y = word; if (!read_uint(map, fsize, &position, &bmsize)) goto close_file; if (!read_uint(map, fsize, &position, &bmoffset)) goto close_file; if ((bmsize <= 0) || (bmoffset <= 0) || (bmoffset >= fsize)) goto close_file; if (search == BIGGEST) { pdelta = w * h; if ((!have_choice) || ((pdelta >= chosen.pdelta) && (((bpp >= 3) && (bpp >= chosen.bpp)) || ((bpp < 3) && (cols >= chosen.cols))))) { have_choice = 1; chosen.pdelta = pdelta; chosen.w = w; chosen.h = h; chosen.cols = cols; chosen.bpp = bpp; chosen.planes = planes; chosen.bmsize = bmsize; chosen.bmoffset = bmoffset; } } else { if (search == SMALLEST) { pdelta = w * h; if ((!have_choice) || ((pdelta <= chosen.pdelta) && (((bpp >= 3) && (bpp >= chosen.bpp)) || ((bpp < 3) && (cols >= chosen.cols))))) { have_choice = 1; chosen.pdelta = pdelta; chosen.w = w; chosen.h = h; chosen.cols = cols; chosen.bpp = bpp; chosen.planes = planes; chosen.bmsize = bmsize; chosen.bmoffset = bmoffset; } } else if (search == SMALLER) { pdelta = (wanted_w * wanted_h) - (w * h); if ((!have_choice) || ((w <= wanted_w) && (h <= wanted_h) && (pdelta <= chosen.pdelta) && (((bpp >= 3) && (bpp >= chosen.bpp)) || ((bpp < 3) && (cols >= chosen.cols))))) { have_choice = 1; if (pdelta < 0) pdelta = 0x7fffffff; chosen.pdelta = pdelta; chosen.w = w; chosen.h = h; chosen.cols = cols; chosen.bpp = bpp; chosen.planes = planes; chosen.bmsize = bmsize; chosen.bmoffset = bmoffset; } } else if (search == BIGGER) { pdelta = (w * h) - (wanted_w * wanted_h); if ((!have_choice) || ((w >= wanted_w) && (h >= wanted_h) && (pdelta <= chosen.pdelta) && (((bpp >= 3) && (bpp >= chosen.bpp)) || ((bpp < 3) && (cols >= chosen.cols))))) { have_choice = 1; if (pdelta < 0) pdelta = 0x7fffffff; chosen.pdelta = pdelta; chosen.w = w; chosen.h = h; chosen.cols = cols; chosen.bpp = bpp; chosen.planes = planes; chosen.bmsize = bmsize; chosen.bmoffset = bmoffset; } } } } if (chosen.bmoffset == 0) goto close_file; position = chosen.bmoffset; w = chosen.w; h = chosen.h; if ((w > 256) || (h > 256)) goto close_file; if ((w < 1) || (h < 1) || (w > IMG_MAX_SIZE) || (h > IMG_MAX_SIZE) || IMG_TOO_BIG(w, h)) { if (IMG_TOO_BIG(w, h)) *error = EVAS_LOAD_ERROR_RESOURCE_ALLOCATION_FAILED; else *error = EVAS_LOAD_ERROR_GENERIC; goto close_file; } ilp->w = w; ilp->h = h; if (hasa) ilp->alpha = 1; eina_file_map_free(f, map); eina_file_close(f); *error = EVAS_LOAD_ERROR_NONE; return EINA_TRUE; close_file: if (map) eina_file_map_free(f, map); eina_file_close(f); return EINA_FALSE; }