diff options
author | Kim Woelders <kim@woelders.dk> | 2021-12-23 16:22:21 +0100 |
---|---|---|
committer | Kim Woelders <kim@woelders.dk> | 2021-12-28 16:08:06 +0100 |
commit | c880edac55248a7314e9dd14fc68f4166b6ad531 (patch) | |
tree | 0ab61cf57dfe8d398d5737ddb04d86bf6d1a656c | |
parent | bf93574b8bd2eb315bf1a76dce6e5730eebd2018 (diff) | |
download | imlib2-c880edac55248a7314e9dd14fc68f4166b6ad531.tar.gz |
BZ2, ZLIB loaders: Move duplicated code to separate file
Also change decompressors to use mmap'ed data.
-rw-r--r-- | src/modules/loaders/Makefile.am | 4 | ||||
-rw-r--r-- | src/modules/loaders/decompress_load.c | 71 | ||||
-rw-r--r-- | src/modules/loaders/loader_bz2.c | 100 | ||||
-rw-r--r-- | src/modules/loaders/loader_common.h | 7 | ||||
-rw-r--r-- | src/modules/loaders/loader_zlib.c | 94 |
5 files changed, 146 insertions, 130 deletions
diff --git a/src/modules/loaders/Makefile.am b/src/modules/loaders/Makefile.am index 3917796..5d027f4 100644 --- a/src/modules/loaders/Makefile.am +++ b/src/modules/loaders/Makefile.am @@ -117,13 +117,13 @@ xpm_la_LDFLAGS = -module -avoid-version xpm_la_LIBADD = $(top_builddir)/src/lib/libImlib2.la xpm_la_LIBTOOLFLAGS = --tag=disable-static -bz2_la_SOURCES = loader_bz2.c +bz2_la_SOURCES = loader_bz2.c decompress_load.c bz2_la_CPPFLAGS = $(BZ2_CFLAGS) $(AM_CPPFLAGS) bz2_la_LDFLAGS = -module -avoid-version bz2_la_LIBADD = $(BZ2_LIBS) $(top_builddir)/src/lib/libImlib2.la bz2_la_LIBTOOLFLAGS = --tag=disable-static -zlib_la_SOURCES = loader_zlib.c +zlib_la_SOURCES = loader_zlib.c decompress_load.c zlib_la_CPPFLAGS = $(ZLIB_CFLAGS) $(AM_CPPFLAGS) zlib_la_LDFLAGS = -module -avoid-version zlib_la_LIBADD = $(ZLIB_LIBS) $(top_builddir)/src/lib/libImlib2.la diff --git a/src/modules/loaders/decompress_load.c b/src/modules/loaders/decompress_load.c new file mode 100644 index 0000000..e2f796f --- /dev/null +++ b/src/modules/loaders/decompress_load.c @@ -0,0 +1,71 @@ +#include "loader_common.h" + +#include <sys/mman.h> + +int +decompress_load(ImlibImage * im, int load_data, const char *const *pext, + int next, imlib_decompress_load_f * fdec) +{ + int rc, i; + ImlibLoader *loader; + int dest, res; + const char *s, *p, *q; + char tmp[] = "/tmp/imlib2_loader_dec-XXXXXX"; + char *real_ext; + void *fdata; + + rc = LOAD_FAIL; + + /* make sure this file ends in a known name and that there's another ext + * (e.g. "foo.png.bz2") */ + for (p = s = im->real_file, q = NULL; *s; s++) + { + if (*s != '.' && *s != '/') + continue; + q = p; + p = s + 1; + } + + if (!q) + return rc; + + res = 0; + for (i = 0; i < next; i++) + { + if (strcasecmp(p, pext[i])) + continue; + res = 1; + break; + } + if (!res) + return rc; + + if (!(real_ext = strndup(q, p - q - 1))) + return LOAD_OOM; + + loader = __imlib_FindBestLoaderForFormat(real_ext, 0); + free(real_ext); + if (!loader) + return rc; + + fdata = mmap(NULL, im->fsize, PROT_READ, MAP_SHARED, fileno(im->fp), 0); + if (fdata == MAP_FAILED) + return LOAD_BADFILE; + + if ((dest = mkstemp(tmp)) < 0) + QUIT_WITH_RC(LOAD_OOM); + + res = fdec(fdata, im->fsize, dest); + + close(dest); + + if (res) + rc = __imlib_LoadEmbedded(loader, im, tmp, load_data); + + unlink(tmp); + + quit: + munmap(fdata, im->fsize); + + return rc; +} diff --git a/src/modules/loaders/loader_bz2.c b/src/modules/loaders/loader_bz2.c index 66575bc..6d9b0f2 100644 --- a/src/modules/loaders/loader_bz2.c +++ b/src/modules/loaders/loader_bz2.c @@ -6,94 +6,60 @@ #define INBUF_SIZE 1024 static int -uncompress_file(FILE * fp, int dest) +uncompress_file(const void *fdata, unsigned int fsize, int dest) { - BZFILE *bf; - DATA8 outbuf[OUTBUF_SIZE]; - int bytes, error, ret = 1; + int ok; + bz_stream strm = { 0 }; + int ret, bytes; + char outbuf[OUTBUF_SIZE]; - bf = BZ2_bzReadOpen(&error, fp, 0, 0, NULL, 0); + ok = 0; - if (error != BZ_OK) - { - BZ2_bzReadClose(NULL, bf); - return 0; - } + ret = BZ2_bzDecompressInit(&strm, 0, 0); + if (ret != BZ_OK) + return ok; + + strm.next_in = (void *)fdata; + strm.avail_in = fsize; - while (1) + for (;;) { - bytes = BZ2_bzRead(&error, bf, &outbuf, OUTBUF_SIZE); + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); + + ret = BZ2_bzDecompress(&strm); + + if (ret != BZ_OK && ret != BZ_STREAM_END) + goto quit; - if (error == BZ_OK || error == BZ_STREAM_END) - if (write(dest, outbuf, bytes) != bytes) - break; + bytes = sizeof(outbuf) - strm.avail_out; + if (write(dest, outbuf, bytes) != bytes) + goto quit; - if (error == BZ_STREAM_END) + if (ret == BZ_STREAM_END) break; - else if (error != BZ_OK) - { - ret = 0; - break; - } } - BZ2_bzReadClose(&error, bf); + ok = 1; - return ret; + quit: + BZ2_bzDecompressEnd(&strm); + + return ok; } +static const char *const list_formats[] = { "bz2" }; + int load2(ImlibImage * im, int load_data) { - int rc; - ImlibLoader *loader; - int dest, res; - const char *s, *p, *q; - char tmp[] = "/tmp/imlib2_loader_bz2-XXXXXX"; - char *real_ext; - - rc = LOAD_FAIL; - - /* make sure this file ends in ".bz2" and that there's another ext - * (e.g. "foo.png.bz2") */ - for (p = s = im->real_file, q = NULL; *s; s++) - { - if (*s != '.' && *s != '/') - continue; - q = p; - p = s + 1; - } - if (!q || strcasecmp(p, "bz2")) - return rc; - - if (!(real_ext = strndup(q, p - q - 1))) - return rc; - - loader = __imlib_FindBestLoaderForFormat(real_ext, 0); - free(real_ext); - if (!loader) - return rc; - - if ((dest = mkstemp(tmp)) < 0) - return rc; - - res = uncompress_file(im->fp, dest); - close(dest); - - if (!res) - goto quit; - - res = __imlib_LoadEmbedded(loader, im, tmp, load_data); - - quit: - unlink(tmp); - return res; + return decompress_load(im, load_data, list_formats, ARRAY_SIZE(list_formats), + uncompress_file); } void formats(ImlibLoader * l) { - static const char *const list_formats[] = { "bz2" }; __imlib_LoaderSetFormats(l, list_formats, ARRAY_SIZE(list_formats)); } diff --git a/src/modules/loaders/loader_common.h b/src/modules/loaders/loader_common.h index 9d0dc71..f81725b 100644 --- a/src/modules/loaders/loader_common.h +++ b/src/modules/loaders/loader_common.h @@ -13,6 +13,13 @@ __EXPORT__ char save(ImlibImage * im, ImlibProgressFunction progress, char progress_granularity); __EXPORT__ void formats(ImlibLoader * l); +typedef int (imlib_decompress_load_f) (const void *fdata, + unsigned int fsize, int dest); + +int decompress_load(ImlibImage * im, int load_data, + const char *const *pext, int next, + imlib_decompress_load_f * fdec); + #define QUIT_WITH_RC(_err) { rc = _err; goto quit; } #define QUITx_WITH_RC(_err, _lbl) { rc = _err; goto _lbl; } diff --git a/src/modules/loaders/loader_zlib.c b/src/modules/loaders/loader_zlib.c index 0b98250..85d822a 100644 --- a/src/modules/loaders/loader_zlib.c +++ b/src/modules/loaders/loader_zlib.c @@ -5,88 +5,60 @@ #define OUTBUF_SIZE 16484 static int -uncompress_file(FILE * fp, int dest) +uncompress_file(const void *fdata, unsigned int fsize, int dest) { - gzFile gf; - DATA8 outbuf[OUTBUF_SIZE]; + int ok; + z_stream strm = { 0 };; + unsigned char outbuf[OUTBUF_SIZE]; int ret = 1, bytes; - gf = gzdopen(dup(fileno(fp)), "rb"); - if (!gf) - return 0; + ok = 0; - while (1) + ret = inflateInit2(&strm, 15 + 32); + if (ret != Z_OK) + return ok; + + strm.next_in = (void *)fdata; + strm.avail_in = fsize; + + for (;;) { - bytes = gzread(gf, outbuf, OUTBUF_SIZE); + strm.next_out = outbuf; + strm.avail_out = sizeof(outbuf); - if (!bytes) - break; - else if (bytes == -1) - { - ret = 0; - break; - } - else if (write(dest, outbuf, bytes) != bytes) + ret = inflate(&strm, 0); + + if (ret != Z_OK && ret != Z_STREAM_END) + goto quit; + + bytes = sizeof(outbuf) - strm.avail_out; + if (write(dest, outbuf, bytes) != bytes) + goto quit; + + if (ret == Z_STREAM_END) break; } - gzclose(gf); + ok = 1; + + quit: + inflateEnd(&strm); return ret; } +static const char *const list_formats[] = { "gz" }; + int load2(ImlibImage * im, int load_data) { - int rc; - ImlibLoader *loader; - int dest, res; - const char *s, *p, *q; - char tmp[] = "/tmp/imlib2_loader_zlib-XXXXXX"; - char *real_ext; - - rc = LOAD_FAIL; - - /* make sure this file ends in ".gz" and that there's another ext - * (e.g. "foo.png.gz") */ - for (p = s = im->real_file, q = NULL; *s; s++) - { - if (*s != '.' && *s != '/') - continue; - q = p; - p = s + 1; - } - if (!q || strcasecmp(p, "gz")) - return rc; - - if (!(real_ext = strndup(q, p - q - 1))) - return rc; - - loader = __imlib_FindBestLoaderForFormat(real_ext, 0); - free(real_ext); - if (!loader) - return rc; - - if ((dest = mkstemp(tmp)) < 0) - return rc; - - res = uncompress_file(im->fp, dest); - close(dest); - - if (!res) - goto quit; - - res = __imlib_LoadEmbedded(loader, im, tmp, load_data); - - quit: - unlink(tmp); - return res; + return decompress_load(im, load_data, list_formats, ARRAY_SIZE(list_formats), + uncompress_file); } void formats(ImlibLoader * l) { - static const char *const list_formats[] = { "gz" }; __imlib_LoaderSetFormats(l, list_formats, ARRAY_SIZE(list_formats)); } |