ARGB loader: Use mmap() for loading

This commit is contained in:
Kim Woelders 2021-09-16 21:15:23 +02:00
parent 670a4a41f8
commit ffd356a43a
1 changed files with 52 additions and 8 deletions

View File

@ -1,13 +1,47 @@
#include "loader_common.h"
#include <sys/mman.h>
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;
}
int
load2(ImlibImage * im, int load_data)
{
int rc;
void *fdata;
int alpha;
DATA32 *ptr;
int y;
char buf[256], buf2[256];
const char *fptr, *row;
unsigned int size;
#ifdef WORDS_BIGENDIAN
int l;
@ -15,17 +49,23 @@ load2(ImlibImage * im, int load_data)
rc = LOAD_FAIL;
fdata = mmap(NULL, im->fsize, PROT_READ, MAP_SHARED, fileno(im->fp), 0);
if (fdata == MAP_FAILED)
return rc;
mm_init(fdata, im->fsize);
/* header */
buf[0] = '\0';
if (!fgets(buf, 255, im->fp))
fptr = fdata;
size = im->fsize > 31 ? 31 : im->fsize; /* Look for \n in at most 31 byte */
row = memchr(fptr, '\n', size);
if (!row)
goto quit;
row += 1; /* After LF */
buf2[0] = '\0';
im->w = im->h = alpha = 0;
sscanf(buf, "%s %i %i %i", buf2, &im->w, &im->h, &alpha);
if (strcmp(buf2, "ARGB"))
goto quit;
sscanf(fptr, "ARGB %i %i %i", &im->w, &im->h, &alpha);
if (!IMAGE_DIMENSIONS_OK(im->w, im->h))
goto quit;
@ -47,9 +87,11 @@ load2(ImlibImage * im, int load_data)
if (!ptr)
goto quit;
mm_seek(row - fptr);
for (y = 0; y < im->h; y++)
{
if (fread(ptr, im->w, 4, im->fp) != 4)
if (mm_read(ptr, 4 * im->w))
goto quit;
#ifdef WORDS_BIGENDIAN
@ -70,6 +112,8 @@ load2(ImlibImage * im, int load_data)
quit:
if (rc <= 0)
__imlib_FreeData(im);
if (fdata != MAP_FAILED)
munmap(fdata, im->fsize);
return rc;
}