ICO loader: Use mmap() for loading
This commit is contained in:
parent
7c0ec91fe2
commit
ff79901a07
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue