summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2021-09-27 19:54:54 +0200
committerKim Woelders <kim@woelders.dk>2021-10-22 19:27:47 +0200
commitff79901a071a76ec73cc98c7ff15102c514afb7b (patch)
treeefe7548e022a64ff856ca53cb2dec79f018daa8d
parent7c0ec91fe2bf6c3abd852f3e03b2042a9ef0cdcd (diff)
ICO loader: Use mmap() for loading
-rw-r--r--src/modules/loaders/loader_ico.c74
1 files changed, 55 insertions, 19 deletions
diff --git a/src/modules/loaders/loader_ico.c b/src/modules/loaders/loader_ico.c
index 4209a99..dd48acb 100644
--- a/src/modules/loaders/loader_ico.c
+++ b/src/modules/loaders/loader_ico.c
@@ -6,10 +6,42 @@
6 * https://en.wikipedia.org/wiki/BMP_file_format 6 * https://en.wikipedia.org/wiki/BMP_file_format
7 */ 7 */
8#include "loader_common.h" 8#include "loader_common.h"
9
9#include <limits.h> 10#include <limits.h>
11#include <sys/mman.h>
10 12
11#define DBG_PFX "LDR-ico" 13#define DBG_PFX "LDR-ico"
12 14
15static struct {
16 const unsigned char *data, *dptr;
17 unsigned int size;
18} mdata;
19
20static void
21mm_init(void *src, unsigned int size)
22{
23 mdata.data = mdata.dptr = src;
24 mdata.size = size;
25}
26
27static void
28mm_seek(unsigned int offs)
29{
30 mdata.dptr = mdata.data + offs;
31}
32
33static int
34mm_read(void *dst, unsigned int len)
35{
36 if (mdata.dptr + len > mdata.data + mdata.size)
37 return 1; /* Out of data */
38
39 memcpy(dst, mdata.dptr, len);
40 mdata.dptr += len;
41
42 return 0;
43}
44
13/* The ICONDIR */ 45/* The ICONDIR */
14typedef struct { 46typedef struct {
15 DATA16 rsvd; 47 DATA16 rsvd;
@@ -85,13 +117,11 @@ static void
85ico_read_idir(ico_t * ico, int ino) 117ico_read_idir(ico_t * ico, int ino)
86{ 118{
87 ie_t *ie; 119 ie_t *ie;
88 unsigned int nr;
89 120
90 ie = &ico->ie[ino]; 121 ie = &ico->ie[ino];
91 122
92 fseek(ico->fp, sizeof(idir_t) + ino * sizeof(ide_t), SEEK_SET); 123 mm_seek(sizeof(idir_t) + ino * sizeof(ide_t));
93 nr = fread(&ie->ide, 1, sizeof(ie->ide), ico->fp); 124 if (mm_read(&ie->ide, sizeof(ie->ide)))
94 if (nr != sizeof(ie->ide))
95 return; 125 return;
96 126
97 ie->w = (ie->ide.width > 0) ? ie->ide.width : 256; 127 ie->w = (ie->ide.width > 0) ? ie->ide.width : 256;
@@ -111,13 +141,12 @@ static void
111ico_read_icon(ico_t * ico, int ino) 141ico_read_icon(ico_t * ico, int ino)
112{ 142{
113 ie_t *ie; 143 ie_t *ie;
114 unsigned int nr, size; 144 unsigned int size;
115 145
116 ie = &ico->ie[ino]; 146 ie = &ico->ie[ino];
117 147
118 fseek(ico->fp, ie->ide.offs, SEEK_SET); 148 mm_seek(ie->ide.offs);
119 nr = fread(&ie->bih, 1, sizeof(ie->bih), ico->fp); 149 if (mm_read(&ie->bih, sizeof(ie->bih)))
120 if (nr != sizeof(ie->bih))
121 goto bail; 150 goto bail;
122 151
123 SWAP_LE_32_INPLACE(ie->bih.header_size); 152 SWAP_LE_32_INPLACE(ie->bih.header_size);
@@ -165,8 +194,7 @@ ico_read_icon(ico_t * ico, int ino)
165 ie->cmap = malloc(size); 194 ie->cmap = malloc(size);
166 if (ie->cmap == NULL) 195 if (ie->cmap == NULL)
167 goto bail; 196 goto bail;
168 nr = fread(ie->cmap, 1, size, ico->fp); 197 if (mm_read(ie->cmap, size))
169 if (nr != size)
170 goto bail; 198 goto bail;
171#ifdef WORDS_BIGENDIAN 199#ifdef WORDS_BIGENDIAN
172 for (nr = 0; nr < ie->bih.colors; nr++) 200 for (nr = 0; nr < ie->bih.colors; nr++)
@@ -185,8 +213,7 @@ ico_read_icon(ico_t * ico, int ino)
185 ie->pxls = malloc(size); 213 ie->pxls = malloc(size);
186 if (ie->pxls == NULL) 214 if (ie->pxls == NULL)
187 goto bail; 215 goto bail;
188 nr = fread(ie->pxls, 1, size, ico->fp); 216 if (mm_read(ie->pxls, size))
189 if (nr != size)
190 goto bail; 217 goto bail;
191 D("Pixel data size: %u\n", size); 218 D("Pixel data size: %u\n", size);
192 219
@@ -194,8 +221,7 @@ ico_read_icon(ico_t * ico, int ino)
194 ie->mask = malloc(size); 221 ie->mask = malloc(size);
195 if (ie->mask == NULL) 222 if (ie->mask == NULL)
196 goto bail; 223 goto bail;
197 nr = fread(ie->mask, 1, size, ico->fp); 224 if (mm_read(ie->mask, size))
198 if (nr != size)
199 goto bail; 225 goto bail;
200 D("Mask data size: %u\n", size); 226 D("Mask data size: %u\n", size);
201 227
@@ -206,10 +232,10 @@ ico_read_icon(ico_t * ico, int ino)
206} 232}
207 233
208static ico_t * 234static ico_t *
209ico_read(ImlibImage * im) 235ico_read(ImlibImage * im, void *data, unsigned int size)
210{ 236{
211 ico_t *ico; 237 ico_t *ico;
212 unsigned int nr, i; 238 unsigned int i;
213 239
214 ico = calloc(1, sizeof(ico_t)); 240 ico = calloc(1, sizeof(ico_t));
215 if (!ico) 241 if (!ico)
@@ -217,8 +243,7 @@ ico_read(ImlibImage * im)
217 243
218 ico->fp = im->fp; 244 ico->fp = im->fp;
219 245
220 nr = fread(&ico->idir, 1, sizeof(ico->idir), ico->fp); 246 if (mm_read(&ico->idir, sizeof(ico->idir)))
221 if (nr != sizeof(ico->idir))
222 goto bail; 247 goto bail;
223 248
224 SWAP_LE_16_INPLACE(ico->idir.rsvd); 249 SWAP_LE_16_INPLACE(ico->idir.rsvd);
@@ -409,11 +434,18 @@ int
409load2(ImlibImage * im, int load_data) 434load2(ImlibImage * im, int load_data)
410{ 435{
411 int rc; 436 int rc;
437 void *fdata;
412 ico_t *ico; 438 ico_t *ico;
413 439
414 rc = LOAD_FAIL; 440 rc = LOAD_FAIL;
415 441
416 ico = ico_read(im); 442 fdata = mmap(NULL, im->fsize, PROT_READ, MAP_SHARED, fileno(im->fp), 0);
443 if (fdata == MAP_FAILED)
444 return rc;
445
446 mm_init(fdata, im->fsize);
447
448 ico = ico_read(im, fdata, im->fsize);
417 if (!ico) 449 if (!ico)
418 goto quit; 450 goto quit;
419 451
@@ -427,6 +459,10 @@ load2(ImlibImage * im, int load_data)
427 ico_delete(ico); 459 ico_delete(ico);
428 460
429 quit: 461 quit:
462 if (rc <= 0)
463 __imlib_FreeData(im);
464 if (fdata != MAP_FAILED)
465 munmap(fdata, im->fsize);
430 return rc; 466 return rc;
431} 467}
432 468