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.