summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorManolo Gouy <Manolo>2017-10-04 16:26:51 +0000
committerManolo Gouy <Manolo>2017-10-04 16:26:51 +0000
commit0b797d704c718aba64720734377f7b23aa0098f5 (patch)
treed47f4b010fe23df1c6423f149c283aff4256c874 /src
parent7a9d5be6cb2ae831b3c2409788d3a31aa61d62b9 (diff)
Fl_SVG_Image class: add support for compressed .svgz image files.
git-svn-id: file:///fltk/svn/fltk/branches/branch-1.4@12477 ea41ed52-d2ee-0310-a9c1-e6b18d33e121
Diffstat (limited to 'src')
-rw-r--r--src/Fl_SVG_Image.cxx69
-rw-r--r--src/fl_images_core.cxx13
2 files changed, 76 insertions, 6 deletions
diff --git a/src/Fl_SVG_Image.cxx b/src/Fl_SVG_Image.cxx
index c30227daa..c5ad1e69f 100644
--- a/src/Fl_SVG_Image.cxx
+++ b/src/Fl_SVG_Image.cxx
@@ -26,6 +26,9 @@
#include <FL/Fl_Screen_Driver.H>
#include <stdio.h>
#include <stdlib.h>
+#if defined(HAVE_LIBZ)
+#include <zlib.h>
+#endif
#if !defined(HAVE_LONG_LONG)
static double strtoll(const char *str, char **endptr, int base) {
@@ -41,8 +44,8 @@ static double strtoll(const char *str, char **endptr, int base) {
#include "../nanosvg/altsvgrast.h"
-/** The constructor loads the SVG image from the given .svg filename or in-memory data.
- \param filename A full path and name pointing to an SVG file, or NULL.
+/** The constructor loads the SVG image from the given .svg/.svgz filename or in-memory data.
+ \param filename A full path and name pointing to a .svg or .svgz file, or NULL.
\param filedata A pointer to the memory location of the SVG image data.
This parameter allows to load an SVG image from in-memory data, and is used when \p filename is NULL.
\note In-memory SVG data is modified by the object constructor and is no longer used after construction.
@@ -73,6 +76,55 @@ float Fl_SVG_Image::svg_scaling_(int W, int H) {
return (f1 < f2) ? f1 : f2;
}
+/** Opens for reading a potentially gzip'ed file identified by a UTF-8 encoded filename. */
+void* Fl_SVG_Image::gzopen(const char *fname) {
+#if defined(HAVE_LIBZ)
+# ifdef _WIN32
+ unsigned wl = fl_utf8towc(fname, strlen(fname), NULL, 0) + 1;
+ wchar_t *wc = new wchar_t[wl];
+ fl_utf8towc(fname, strlen(fname), wc, wl);
+ gzFile gzf = gzopen_w(wc, "r");
+ delete[] wc;
+ return gzf;
+# else
+ int fd = fl_open(fname, 0);
+ if (fd < 0) return NULL;
+ return gzdopen(fd, "r");
+# endif
+#else
+ return NULL;
+#endif // HAVE_LIBZ
+}
+
+#if defined(HAVE_LIBZ)
+
+static char *svg_inflate(const char *fname) {
+ struct stat b;
+ fl_stat(fname, &b);
+ long size = b.st_size;
+ gzFile gzf = (gzFile)Fl_SVG_Image::gzopen(fname);
+ int l;
+ bool direct = gzdirect(gzf);
+ long out_size = direct ? size + 1 : 3*size + 1;
+ char *out = (char*)malloc(out_size);
+ char *p = out;
+ do {
+ if ((!direct) && p + size > out + out_size) {
+ out_size += size;
+ char *tmp = (char*)realloc(out, out_size + 1);
+ p = tmp + (p - out);
+ out = tmp;
+ }
+ l = gzread(gzf, p, size);
+ if (l > 0) {
+ p += l; *p = 0;
+ }
+ } while ((!direct) && l >0);
+ gzclose(gzf);
+ if (!direct) out = (char*)realloc(out, (p-out)+1);
+ return out;
+}
+#endif
void Fl_SVG_Image::init_(const char *filename, char *filedata, Fl_SVG_Image *copy_source) {
if (copy_source) {
@@ -88,22 +140,29 @@ void Fl_SVG_Image::init_(const char *filename, char *filedata, Fl_SVG_Image *cop
average_weight_ = 1;
proportional = true;
if (filename) {
+#if defined(HAVE_LIBZ)
+ filedata = svg_inflate(filename);
+#else
filedata = NULL;
FILE *fp = fl_fopen(filename, "rb");
if (fp) {
fseek(fp, 0, SEEK_END);
- size_t size = ftell(fp);
+ long size = ftell(fp);
fseek(fp, 0, SEEK_SET);
filedata = (char*)malloc(size+1);
if (filedata) {
- if (fread(filedata, 1, size, fp) == size) filedata[size] = '\0';
+ if (fread(filedata, 1, size, fp) == size) {
+ filedata[size] = '\0';
+ }
else {
free(filedata);
filedata = NULL;
}
}
fclose(fp);
- } else ld(ERR_FILE_ACCESS);
+ }
+#endif // HAVE_LIBZ
+ if (!filedata) ld(ERR_FILE_ACCESS);
}
if (filedata) {
counted_svg_image_->svg_image = nsvgParse(filedata, "px", 96);
diff --git a/src/fl_images_core.cxx b/src/fl_images_core.cxx
index 5af696764..3ed225c8c 100644
--- a/src/fl_images_core.cxx
+++ b/src/fl_images_core.cxx
@@ -35,7 +35,9 @@
#include <stdio.h>
#include <stdlib.h>
#include "flstring.h"
-
+#if defined(HAVE_LIBZ)
+#include <zlib.h>
+#endif
//
// Define a simple global image registration function that registers
@@ -90,6 +92,15 @@ fl_check_images(const char *name, // I - Filename
#endif // HAVE_LIBJPEG
#ifdef FLTK_USE_NANOSVG
+# if defined(HAVE_LIBZ)
+ if (header[0] == 0x1f && header[1] == 0x8b) { // denotes gzip'ed data
+ gzFile gzf = (gzFile)Fl_SVG_Image::gzopen(name);
+ if (gzf) {
+ gzread(gzf, header, headerlen);
+ gzclose(gzf);
+ }
+ }
+# endif // HAVE_LIBZ
if ( (headerlen > 5 && memcmp(header, "<?xml", 5) == 0) ||
memcmp(header, "<svg", 4) == 0)
return new Fl_SVG_Image(name);