kwo pushed a commit to branch master. http://git.enlightenment.org/legacy/imlib2.git/commit/?id=164e628951835e410ab59e855e2a398da9e61621
commit 164e628951835e410ab59e855e2a398da9e61621 Author: Kim Woelders <[email protected]> Date: Tue Sep 28 09:12:40 2021 +0200 LBM loader: Use mmap() for loading --- src/modules/loaders/loader_lbm.c | 81 ++++++++++++++++++---------------------- 1 file changed, 37 insertions(+), 44 deletions(-) diff --git a/src/modules/loaders/loader_lbm.c b/src/modules/loaders/loader_lbm.c index 0f27485..752b344 100644 --- a/src/modules/loaders/loader_lbm.c +++ b/src/modules/loaders/loader_lbm.c @@ -13,6 +13,8 @@ #include "loader_common.h" +#include <sys/mman.h> + #define DBG_PFX "LDR-lbm" #define L2RLONG(a) ((((int)((a)[0]) & 0xff) << 24) + (((int)((a)[1]) & 0xff) << 16) + (((int)((a)[2]) & 0xff) << 8) + ((int)((a)[3]) & 0xff)) @@ -20,7 +22,7 @@ typedef struct { int size; - unsigned char *data; + const unsigned char *data; } CHUNK; typedef struct { @@ -30,6 +32,7 @@ typedef struct { CHUNK ctbl; CHUNK sham; CHUNK body; + unsigned char *cmap_alloc; /* Modified colormap */ int depth; int mask; @@ -49,41 +52,28 @@ typedef struct { static void freeilbm(ILBM * ilbm) { - if (ilbm->bmhd.data) - free(ilbm->bmhd.data); - if (ilbm->camg.data) - free(ilbm->camg.data); - if (ilbm->cmap.data) - free(ilbm->cmap.data); - if (ilbm->ctbl.data) - free(ilbm->ctbl.data); - if (ilbm->sham.data) - free(ilbm->sham.data); - if (ilbm->body.data) - free(ilbm->body.data); - - memset(ilbm, 0, sizeof(*ilbm)); + free(ilbm->cmap_alloc); } +#define mm_check(p) ((const unsigned char *)(p) <= fptr + size) + /*------------------------------------------------------------------------------ * Reads the given chunks out of a file, returns 0 if the file had a problem. * * Format FORMsizeILBMtag.size....tag.size....tag.size.... *------------------------------------------------------------------------------*/ static int -loadchunks(FILE * f, ILBM * ilbm, int full) +loadchunks(const unsigned char *fptr, unsigned int size, ILBM * ilbm, int full) { CHUNK *c; - size_t s; - long pos; int formsize, z; - int ok, seek; - char buf[12]; + int ok; + const unsigned char *buf; ok = 0; - s = fread(buf, 1, 12, f); - if (s != 12) + buf = fptr; + if (!mm_check(buf + 12)) return ok; if (memcmp(buf, "FORM", 4) != 0 || memcmp(buf + 8, "ILBM", 4) != 0) @@ -93,15 +83,13 @@ loadchunks(FILE * f, ILBM * ilbm, int full) D("%s: %.4s %.4s formsize=%d\n", __func__, buf, buf + 8, formsize); + buf += 12; + while (1) { - pos = ftell(f); - if (pos < 0 || pos >= formsize + 8) - break; /* Error or FORM data is finished. */ - seek = 1; - - s = fread(buf, 1, 8, f); - if (s != 8) + if (buf >= fptr + formsize + 8) + break; + if (!mm_check(buf + 8)) break; /* Error or short file. */ z = L2RLONG(buf + 4); @@ -127,18 +115,15 @@ loadchunks(FILE * f, ILBM * ilbm, int full) c = &(ilbm->body); } + buf += 8; + if (c && !c->data) { c->size = z; - c->data = malloc(c->size); - if (!c->data) - break; /* Out of memory. */ - - s = fread(c->data, 1, c->size, f); - if (s != (size_t)c->size) - break; /* Error or short file. */ + if (!mm_check(buf + c->size)) + break; + c->data = buf; - seek = 0; if (!full) { /* Only BMHD required. */ ok = 1; @@ -146,11 +131,7 @@ loadchunks(FILE * f, ILBM * ilbm, int full) } } - if (pos + 8 + z >= formsize + 8) - break; /* This was last chunk. */ - - if (seek && fseek(f, z, SEEK_CUR) != 0) - break; + buf += z; } /* File may end strangely, especially if body size is uneven, but it's @@ -286,8 +267,12 @@ scalecmap(ILBM * ilbm) if (ilbm->cmap.data[i] & 0x0f) return; + ilbm->cmap_alloc = malloc((unsigned int)ilbm->cmap.size); + for (i = 0; i < ilbm->cmap.size; i++) - ilbm->cmap.data[i] |= ilbm->cmap.data[i] >> 4; + ilbm->cmap_alloc[i] = ilbm->cmap.data[i] | ilbm->cmap.data[i] >> 4; + + ilbm->cmap.data = ilbm->cmap_alloc; } /*------------------------------------------------------------------------------ @@ -457,6 +442,7 @@ int load2(ImlibImage * im, int load_data) { int rc; + void *fdata; char *env; int i, n, y, z; unsigned char *plane[40]; @@ -466,11 +452,15 @@ load2(ImlibImage * im, int load_data) plane[0] = NULL; memset(&ilbm, 0, sizeof(ilbm)); + fdata = mmap(NULL, im->fsize, PROT_READ, MAP_SHARED, fileno(im->fp), 0); + if (fdata == MAP_FAILED) + return rc; + /*---------- * Load the chunk(s) we're interested in. If load_data is not true, then we only * want the image size and format. *----------*/ - if (!loadchunks(im->fp, &ilbm, load_data)) + if (!loadchunks(fdata, im->fsize, &ilbm, load_data)) goto quit; /*---------- @@ -587,6 +577,9 @@ load2(ImlibImage * im, int load_data) freeilbm(&ilbm); + if (fdata != MAP_FAILED) + munmap(fdata, im->fsize); + return rc; } --
