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;
 }
 

-- 


Reply via email to