summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKim Woelders <kim@woelders.dk>2021-12-23 16:22:21 +0100
committerKim Woelders <kim@woelders.dk>2021-12-28 16:08:06 +0100
commitc880edac55248a7314e9dd14fc68f4166b6ad531 (patch)
tree0ab61cf57dfe8d398d5737ddb04d86bf6d1a656c
parentbf93574b8bd2eb315bf1a76dce6e5730eebd2018 (diff)
downloadimlib2-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.am4
-rw-r--r--src/modules/loaders/decompress_load.c71
-rw-r--r--src/modules/loaders/loader_bz2.c100
-rw-r--r--src/modules/loaders/loader_common.h7
-rw-r--r--src/modules/loaders/loader_zlib.c94
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));
}