kwo pushed a commit to branch master. http://git.enlightenment.org/legacy/imlib2.git/commit/?id=ff79901a071a76ec73cc98c7ff15102c514afb7b
commit ff79901a071a76ec73cc98c7ff15102c514afb7b Author: Kim Woelders <[email protected]> Date: Mon Sep 27 19:54:54 2021 +0200 ICO loader: Use mmap() for loading --- src/modules/loaders/loader_ico.c | 74 +++++++++++++++++++++++++++++----------- 1 file changed, 55 insertions(+), 19 deletions(-) diff --git a/src/modules/loaders/loader_ico.c b/src/modules/loaders/loader_ico.c index 4209a99..dd48acb 100644 --- a/src/modules/loaders/loader_ico.c +++ b/src/modules/loaders/loader_ico.c @@ -6,10 +6,42 @@ * https://en.wikipedia.org/wiki/BMP_file_format */ #include "loader_common.h" + #include <limits.h> +#include <sys/mman.h> #define DBG_PFX "LDR-ico" +static struct { + const unsigned char *data, *dptr; + unsigned int size; +} mdata; + +static void +mm_init(void *src, unsigned int size) +{ + mdata.data = mdata.dptr = src; + mdata.size = size; +} + +static void +mm_seek(unsigned int offs) +{ + mdata.dptr = mdata.data + offs; +} + +static int +mm_read(void *dst, unsigned int len) +{ + if (mdata.dptr + len > mdata.data + mdata.size) + return 1; /* Out of data */ + + memcpy(dst, mdata.dptr, len); + mdata.dptr += len; + + return 0; +} + /* The ICONDIR */ typedef struct { DATA16 rsvd; @@ -85,13 +117,11 @@ static void ico_read_idir(ico_t * ico, int ino) { ie_t *ie; - unsigned int nr; ie = &ico->ie[ino]; - fseek(ico->fp, sizeof(idir_t) + ino * sizeof(ide_t), SEEK_SET); - nr = fread(&ie->ide, 1, sizeof(ie->ide), ico->fp); - if (nr != sizeof(ie->ide)) + mm_seek(sizeof(idir_t) + ino * sizeof(ide_t)); + if (mm_read(&ie->ide, sizeof(ie->ide))) return; ie->w = (ie->ide.width > 0) ? ie->ide.width : 256; @@ -111,13 +141,12 @@ static void ico_read_icon(ico_t * ico, int ino) { ie_t *ie; - unsigned int nr, size; + unsigned int size; ie = &ico->ie[ino]; - fseek(ico->fp, ie->ide.offs, SEEK_SET); - nr = fread(&ie->bih, 1, sizeof(ie->bih), ico->fp); - if (nr != sizeof(ie->bih)) + mm_seek(ie->ide.offs); + if (mm_read(&ie->bih, sizeof(ie->bih))) goto bail; SWAP_LE_32_INPLACE(ie->bih.header_size); @@ -165,8 +194,7 @@ ico_read_icon(ico_t * ico, int ino) ie->cmap = malloc(size); if (ie->cmap == NULL) goto bail; - nr = fread(ie->cmap, 1, size, ico->fp); - if (nr != size) + if (mm_read(ie->cmap, size)) goto bail; #ifdef WORDS_BIGENDIAN for (nr = 0; nr < ie->bih.colors; nr++) @@ -185,8 +213,7 @@ ico_read_icon(ico_t * ico, int ino) ie->pxls = malloc(size); if (ie->pxls == NULL) goto bail; - nr = fread(ie->pxls, 1, size, ico->fp); - if (nr != size) + if (mm_read(ie->pxls, size)) goto bail; D("Pixel data size: %u\n", size); @@ -194,8 +221,7 @@ ico_read_icon(ico_t * ico, int ino) ie->mask = malloc(size); if (ie->mask == NULL) goto bail; - nr = fread(ie->mask, 1, size, ico->fp); - if (nr != size) + if (mm_read(ie->mask, size)) goto bail; D("Mask data size: %u\n", size); @@ -206,10 +232,10 @@ ico_read_icon(ico_t * ico, int ino) } static ico_t * -ico_read(ImlibImage * im) +ico_read(ImlibImage * im, void *data, unsigned int size) { ico_t *ico; - unsigned int nr, i; + unsigned int i; ico = calloc(1, sizeof(ico_t)); if (!ico) @@ -217,8 +243,7 @@ ico_read(ImlibImage * im) ico->fp = im->fp; - nr = fread(&ico->idir, 1, sizeof(ico->idir), ico->fp); - if (nr != sizeof(ico->idir)) + if (mm_read(&ico->idir, sizeof(ico->idir))) goto bail; SWAP_LE_16_INPLACE(ico->idir.rsvd); @@ -409,11 +434,18 @@ int load2(ImlibImage * im, int load_data) { int rc; + void *fdata; ico_t *ico; rc = LOAD_FAIL; - ico = ico_read(im); + fdata = mmap(NULL, im->fsize, PROT_READ, MAP_SHARED, fileno(im->fp), 0); + if (fdata == MAP_FAILED) + return rc; + + mm_init(fdata, im->fsize); + + ico = ico_read(im, fdata, im->fsize); if (!ico) goto quit; @@ -427,6 +459,10 @@ load2(ImlibImage * im, int load_data) ico_delete(ico); quit: + if (rc <= 0) + __imlib_FreeData(im); + if (fdata != MAP_FAILED) + munmap(fdata, im->fsize); return rc; } --
