This is an automated email from the git hooks/post-receive script.

git pushed a commit to branch master
in repository legacy-imlib2.

View the commit online.

commit af587674a446b48a9aece81b998b9e565632d653
Author: Kim Woelders <[email protected]>
AuthorDate: Mon Mar 7 22:19:33 2022 +0100

    Introduce imlib_load_image_mem()
    
    For loading images from memory.
---
 src/lib/Imlib2.h.in | 23 +++++++++++++++++++++++
 src/lib/api.c       | 17 +++++++++++++++++
 src/lib/image.c     | 39 +++++++++++++++++++++++++--------------
 src/lib/image.h     |  2 ++
 test/test_load.cpp  | 25 +++++++++++++++++++++++++
 5 files changed, 92 insertions(+), 14 deletions(-)

diff --git a/src/lib/Imlib2.h.in b/src/lib/Imlib2.h.in
index c678147..3e9128a 100644
--- a/src/lib/Imlib2.h.in
+++ b/src/lib/Imlib2.h.in
@@ -836,6 +836,29 @@ EAPI Imlib_Image    imlib_load_image_fd(int fd, const char *file);
 EAPI Imlib_Image    imlib_load_image_fde(const char *file, int *error_return,
                                          int fd);
 
+/**
+ * Read an image from memory
+ *
+ * The file name @p file is only used to guess the file format.
+ * The image is loaded without deferred image data decoding and without
+ * looking in the cache.
+ *
+ * On error @p error_return is set to the detail of the error.
+ * error values:
+ *          0: Success,
+ *   positive: Regular errnos,
+ *   negative: IMLIB_ERR_... values, see above
+ *
+ * @param file          File name
+ * @param error_return  The returned error
+ * @param data          Image data
+ * @param size          Image data size
+ *
+ * @return Image handle (NULL on failure)
+ */
+EAPI Imlib_Image    imlib_load_image_mem(const char *file, int *error_return,
+                                         const void *data, size_t size);
+
 /**
  * Free the current image
  */
diff --git a/src/lib/api.c b/src/lib/api.c
index 6ec32c9..de19010 100644
--- a/src/lib/api.c
+++ b/src/lib/api.c
@@ -889,6 +889,23 @@ imlib_load_image_fd(int fd, const char *file)
    return imlib_load_image_fde(file, NULL, fd);
 }
 
+EAPI                Imlib_Image
+imlib_load_image_mem(const char *file, int *err, const void *data, size_t size)
+{
+   Imlib_Image         im;
+   ImlibLoadArgs       ila = { ILA0(ctx, 1, 1) };
+
+   CHECK_PARAM_POINTER_RETURN("file", file, NULL);
+   CHECK_PARAM_POINTER_RETURN("data", data, NULL);
+
+   ila.fdata = data;
+   ila.fsize = size;
+
+   im = __imlib_LoadImage(file, &ila);
+
+   return (Imlib_Image) im;
+}
+
 EAPI                Imlib_Image
 imlib_load_image_frame(const char *file, int frame)
 {
diff --git a/src/lib/image.c b/src/lib/image.c
index 225566f..15ba4ef 100644
--- a/src/lib/image.c
+++ b/src/lib/image.c
@@ -76,17 +76,17 @@ __imlib_ReplaceData(ImlibImage * im, unsigned int *new_data)
 }
 
 static int
-__imlib_FileContextOpen(ImlibImageFileInfo * fi, FILE * fp, off_t fsize)
+__imlib_FileContextOpen(ImlibImageFileInfo * fi, FILE * fp,
+                        const void *fdata, off_t fsize)
 {
    struct stat         st;
-   void               *fdata;
 
    if (fp)
      {
         fi->keep_fp = true;
         fi->fp = fp;
      }
-   else
+   else if (!fdata)
      {
         fi->fp = fopen(fi->name, "rb");
         if (!fi->fp)
@@ -103,9 +103,12 @@ __imlib_FileContextOpen(ImlibImageFileInfo * fi, FILE * fp, off_t fsize)
         fi->fsize = fsize;
      }
 
-   fdata = mmap(NULL, fi->fsize, PROT_READ, MAP_SHARED, fileno(fi->fp), 0);
-   if (fdata == MAP_FAILED)
-      return -1;
+   if (!fdata)
+     {
+        fdata = mmap(NULL, fi->fsize, PROT_READ, MAP_SHARED, fileno(fi->fp), 0);
+        if (fdata == MAP_FAILED)
+           return -1;
+     }
 
    fi->fdata = fdata;
 
@@ -487,7 +490,12 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
      }
 
    im_file = im_key = NULL;
-   if (ila->fp)
+   if (ila->fdata)
+     {
+        err = 0;
+        st.st_size = ila->fsize;
+     }
+   else if (ila->fp)
      {
         err = fstat(fileno(ila->fp), &st);
      }
@@ -507,10 +515,10 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
 
    if (err)
       err = errno;
-   else if (__imlib_StatIsDir(&st))
-      err = EISDIR;
    else if (st.st_size == 0)
       err = IMLIB_ERR_BAD_IMAGE;
+   else if (!ila->fdata && __imlib_StatIsDir(&st))
+      err = EISDIR;
 
    if (err)
      {
@@ -528,7 +536,7 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
    im->frame_num = ila->frame;
 
    if (__imlib_ImageFileContextPush(im, true, im_file ? im_file : im->file) ||
-       __imlib_FileContextOpen(im->fi, ila->fp, st.st_size))
+       __imlib_FileContextOpen(im->fi, ila->fp, ila->fdata, st.st_size))
      {
         ila->err = errno;
         __imlib_ConsumeImage(im);
@@ -595,8 +603,11 @@ __imlib_LoadImage(const char *file, ImlibLoadArgs * ila)
 
           case LOAD_FAIL:
              /* Image was not recognized by loader - try next */
-             fflush(im->fi->fp);
-             rewind(im->fi->fp);
+             if (im->fi->fp)
+               {
+                  fflush(im->fi->fp);
+                  rewind(im->fi->fp);
+               }
              continue;
 
           default:             /* We should not go here */
@@ -652,7 +663,7 @@ __imlib_LoadImageData(ImlibImage * im)
    if (!im->loader)
       return IMLIB_ERR_INTERNAL;
 
-   err = __imlib_FileContextOpen(im->fi, NULL, 0);
+   err = __imlib_FileContextOpen(im->fi, NULL, NULL, 0);
    if (err)
       return err;
    err = __imlib_LoadImageWrapper(im->loader, im, 1);
@@ -672,7 +683,7 @@ __imlib_LoadEmbedded(ImlibLoader * l, ImlibImage * im, const char *file,
       return 0;
 
    __imlib_ImageFileContextPush(im, true, strdup(file));
-   rc = __imlib_FileContextOpen(im->fi, NULL, 0);
+   rc = __imlib_FileContextOpen(im->fi, NULL, NULL, 0);
    if (rc)
       return LOAD_FAIL;
 
diff --git a/src/lib/image.h b/src/lib/image.h
index 41983f6..01608d2 100644
--- a/src/lib/image.h
+++ b/src/lib/image.h
@@ -88,6 +88,8 @@ struct _ImlibImage {
 
 typedef struct {
    FILE               *fp;
+   const void         *fdata;
+   size_t              fsize;
    ImlibProgressFunction pfunc;
    int                 pgran;
    char                immed;
diff --git a/test/test_load.cpp b/test/test_load.cpp
index 641f470..b6417cd 100644
--- a/test/test_load.cpp
+++ b/test/test_load.cpp
@@ -6,6 +6,7 @@
 
 #include <errno.h>
 #include <fcntl.h>
+#include <sys/mman.h>
 
 #include "test.h"
 
@@ -185,6 +186,30 @@ test_load(void)
         EXPECT_EQ(err, 0);
         err = close(fd);
         EXPECT_NE(err, 0);
+
+        if (!strcmp(pfxs[i], "jpg.mp3"))        // id3 cannot do mem
+           continue;
+
+        // Load via mem
+        snprintf(fileo, sizeof(fileo), "%s/%s.%s", IMG_SRC, "icon-64", pfxs[i]);
+        fd = open(fileo, O_RDONLY);
+        void               *fdata;
+        struct stat         st;
+
+        err = stat(fileo, &st);
+        ASSERT_EQ(err, 0);
+        fdata = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
+        ASSERT_TRUE(fdata != NULL);
+        ASSERT_TRUE(fdata != MAP_FAILED);
+        D("Load mem %d '%s'\n", fd, fileo);
+        snprintf(fileo, sizeof(fileo), ".%s", pfxs[i]);
+        im = imlib_load_image_mem(pfxs[i], &err, fdata, st.st_size);
+        EXPECT_TRUE(im) << "Load mem: " << fileo;
+        if (im)
+           image_free(im);
+        munmap(fdata, st.st_size);
+        err = close(fd);
+        EXPECT_EQ(err, 0);
      }
 }
 

-- 
To stop receiving notification emails like this one, please contact
the administrator of this repository.

Reply via email to