kwo pushed a commit to branch master.

http://git.enlightenment.org/legacy/imlib2.git/commit/?id=b99b984bb8201104088de0fc6cb1450b5a236b00

commit b99b984bb8201104088de0fc6cb1450b5a236b00
Author: Kim Woelders <[email protected]>
Date:   Fri Sep 17 06:18:37 2021 +0200

    BMP loader: Use mmap() for loading
---
 src/modules/loaders/loader_bmp.c | 73 ++++++++++++++++++++++++++--------------
 1 file changed, 48 insertions(+), 25 deletions(-)

diff --git a/src/modules/loaders/loader_bmp.c b/src/modules/loaders/loader_bmp.c
index 51a7813..14a3a7d 100644
--- a/src/modules/loaders/loader_bmp.c
+++ b/src/modules/loaders/loader_bmp.c
@@ -8,11 +8,36 @@
  * - Fix 16 and 32 bit depth (old code was incorrect and it's commented)
  */
 #include "loader_common.h"
-#include <sys/stat.h>
+
+#include <sys/mman.h>
 
 #define DBG_PFX "LDR-bmp"
 #define Dx(fmt...)
 
+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 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 BITMAPFILEHEADER (size 14) */
 typedef struct {
    DATA8               header[2];
@@ -132,7 +157,8 @@ int
 load2(ImlibImage * im, int load_data)
 {
    int                 rc;
-   struct stat         st;
+   void               *fdata;
+   const unsigned char *fptr;
    bfh_t               bfh;
    unsigned int        bfh_offset;
    unsigned int        size, comp, imgsize;
@@ -142,7 +168,7 @@ load2(ImlibImage * im, int load_data)
    unsigned int        i, k;
    int                 w, h, x, y, j, l;
    DATA32             *ptr, pixel;
-   unsigned char      *buffer_ptr, *buffer, *buffer_end, *buffer_end_safe;
+   const unsigned char *buffer_ptr, *buffer_end, *buffer_end_safe;
    RGBQUAD             rgbQuads[256];
    DATA32              argbCmap[256];
    unsigned int        amask, rmask, gmask, bmask;
@@ -151,20 +177,23 @@ load2(ImlibImage * im, int load_data)
    bih_t               bih;
 
    rc = LOAD_FAIL;
-   buffer = NULL;
 
-   /* Load header */
+   fdata = mmap(NULL, im->fsize, PROT_READ, MAP_SHARED, fileno(im->fp), 0);
+   if (fdata == MAP_FAILED)
+      return rc;
 
-   if (fstat(fileno(im->fp), &st) < 0)
-      goto quit;
+   fptr = fdata;
+   mm_init(fdata, im->fsize);
+
+   /* Load header */
 
-   if (fread(&bfh, sizeof(bfh), 1, im->fp) != 1)
+   if (mm_read(&bfh, sizeof(bfh)))
       goto quit;
 
    if (bfh.header[0] != 'B' || bfh.header[1] != 'M')
       goto quit;
 
-   size = st.st_size;
+   size = im->fsize;
 #define WORD_LE_32(p8) (((p8)[3] << 24) | ((p8)[2] << 16) | ((p8)[1] << 8) | 
(p8)[0])
    bfh_offset = WORD_LE_32(bfh.offs);
 
@@ -172,7 +201,7 @@ load2(ImlibImage * im, int load_data)
       goto quit;
 
    memset(&bih, 0, sizeof(bih));
-   if (fread(&bih, 4, 1, im->fp) != 1)
+   if (mm_read(&bih.header_size, sizeof(bih.header_size)))
       goto quit;
 
    SWAP_LE_32_INPLACE(bih.header_size);
@@ -183,7 +212,7 @@ load2(ImlibImage * im, int load_data)
    if (bih.header_size < 12 || bih.header_size > sizeof(bih))
       goto quit;
 
-   if (fread(&bih.header_size + 1, bih.header_size - 4, 1, im->fp) != 1)
+   if (mm_read(&bih.header_size + 1, bih.header_size - 4))
       goto quit;
 
    comp = BI_RGB;
@@ -215,7 +244,7 @@ load2(ImlibImage * im, int load_data)
              if (bih.header_size == 40)
                {
                   ncols = (comp == BI_ALPHABITFIELDS) ? 4 : 3;
-                  if (fread(&bih.bih.mask_r, 4, ncols, im->fp) != ncols)
+                  if (mm_read(&bih.bih.mask_r, 4 * ncols))
                      goto quit;
                }
              rmask = SWAP_LE_32(bih.bih.mask_r);
@@ -256,7 +285,7 @@ load2(ImlibImage * im, int load_data)
              if (ncols > 256)
                 ncols = 256;
              for (i = 0; i < ncols; i++)
-                if (fread(&rgbQuads[i], 3, 1, im->fp) != 1)
+                if (mm_read(&rgbQuads[i], 3))
                    goto quit;
           }
         else
@@ -264,7 +293,7 @@ load2(ImlibImage * im, int load_data)
              ncols /= 4;
              if (ncols > 256)
                 ncols = 256;
-             if (fread(rgbQuads, 4, ncols, im->fp) != ncols)
+             if (mm_read(rgbQuads, 4 * ncols))
                 goto quit;
           }
         for (i = 0; i < ncols; i++)
@@ -377,20 +406,13 @@ load2(ImlibImage * im, int load_data)
 
    /* Load data */
 
-   fseek(im->fp, bfh_offset, SEEK_SET);
-
    if (!__imlib_AllocateData(im))
       goto quit;
 
-   buffer = malloc(imgsize);
-   if (!buffer)
-      goto quit;
-
-   if (fread(buffer, imgsize, 1, im->fp) != 1)
-      goto quit;
+   fptr += bfh_offset;
 
-   buffer_ptr = buffer;
-   buffer_end = buffer + imgsize;
+   buffer_ptr = fptr;
+   buffer_end = fptr + imgsize;
 
    ptr = im->data + ((h - 1) * w);
 
@@ -765,7 +787,8 @@ load2(ImlibImage * im, int load_data)
  quit:
    if (rc <= 0)
       __imlib_FreeData(im);
-   free(buffer);
+   if (fdata != MAP_FAILED)
+      munmap(fdata, im->fsize);
 
    return rc;
 }

-- 


Reply via email to