aboutsummaryrefslogtreecommitdiff
path: root/experimental
diff options
context:
space:
mode:
authorSyoyo Fujita <syoyo@lighttransport.com>2016-09-04 19:34:05 +0900
committerSyoyo Fujita <syoyo@lighttransport.com>2016-09-04 19:34:05 +0900
commit1b88a1e3c72a43aae0c42146555ac0ee3f5c9117 (patch)
treeb946298c3b30573587a89235c6744021a44a8466 /experimental
parentb3feefafdfddc670bcaebf2662a6c8f2c779dec9 (diff)
downloadtinyobjloader-1b88a1e3c72a43aae0c42146555ac0ee3f5c9117.tar.gz
Support reading .obj from ZStd compressed format.
Diffstat (limited to 'experimental')
-rw-r--r--experimental/premake4.lua10
-rw-r--r--experimental/viewer.cc82
2 files changed, 92 insertions, 0 deletions
diff --git a/experimental/premake4.lua b/experimental/premake4.lua
index 321ab19..211e1ea 100644
--- a/experimental/premake4.lua
+++ b/experimental/premake4.lua
@@ -3,6 +3,11 @@ newoption {
description = "Build with zlib."
}
+newoption {
+ trigger = "with-zstd",
+ description = "Build with ZStandard compression."
+}
+
solution "objview"
-- location ( "build" )
configurations { "Release", "Debug" }
@@ -23,6 +28,11 @@ solution "objview"
links { 'z' }
end
+ if _OPTIONS['with-zstd'] then
+ defines { 'ENABLE_ZSTD' }
+ links { 'zstd' }
+ end
+
-- Uncomment if you want address sanitizer(gcc/clang only)
--buildoptions { "-fsanitize=address" }
--linkoptions { "-fsanitize=address" }
diff --git a/experimental/viewer.cc b/experimental/viewer.cc
index be17c7a..b79fe46 100644
--- a/experimental/viewer.cc
+++ b/experimental/viewer.cc
@@ -16,6 +16,10 @@
#include <zlib.h>
#endif
+#if defined(ENABLE_ZSTD)
+#include <zstd.h>
+#endif
+
#include <GL/glew.h>
#ifdef __APPLE__
@@ -182,6 +186,71 @@ bool gz_load(std::vector<char>* buf, const char* filename)
#endif
}
+#ifdef ENABLE_ZSTD
+static off_t fsize_X(const char *filename)
+{
+ struct stat st;
+ if (stat(filename, &st) == 0) return st.st_size;
+ /* error */
+ printf("stat: %s : %s \n", filename, strerror(errno));
+ exit(1);
+}
+
+static FILE* fopen_X(const char *filename, const char *instruction)
+{
+ FILE* const inFile = fopen(filename, instruction);
+ if (inFile) return inFile;
+ /* error */
+ printf("fopen: %s : %s \n", filename, strerror(errno));
+ exit(2);
+}
+
+static void* malloc_X(size_t size)
+{
+ void* const buff = malloc(size);
+ if (buff) return buff;
+ /* error */
+ printf("malloc: %s \n", strerror(errno));
+ exit(3);
+}
+#endif
+
+bool zstd_load(std::vector<char>* buf, const char* filename)
+{
+#ifdef ENABLE_ZSTD
+ off_t const buffSize = fsize_X(filename);
+ FILE* const inFile = fopen_X(filename, "rb");
+ void* const buffer = malloc_X(buffSize);
+ size_t const readSize = fread(buffer, 1, buffSize, inFile);
+ if (readSize != (size_t)buffSize) {
+ printf("fread: %s : %s \n", filename, strerror(errno));
+ exit(4);
+ }
+ fclose(inFile);
+
+ unsigned long long const rSize = ZSTD_getDecompressedSize(buffer, buffSize);
+ if (rSize==0) {
+ printf("%s : original size unknown \n", filename);
+ exit(5);
+ }
+
+ buf->resize(rSize);
+
+ size_t const dSize = ZSTD_decompress(buf->data(), rSize, buffer, buffSize);
+
+ if (dSize != rSize) {
+ printf("error decoding %s : %s \n", filename, ZSTD_getErrorName(dSize));
+ exit(7);
+ }
+
+ free(buffer);
+
+ return true;
+#else
+ return false;
+#endif
+}
+
const char* get_file_data(size_t *len, const char* filename)
{
@@ -204,6 +273,19 @@ const char* get_file_data(size_t *len, const char* filename)
data_len = buf.size();
}
+ } else if (strcmp(ext, ".zst") == 0) {
+ // gzipped data.
+
+ std::vector<char> buf;
+ bool ret = zstd_load(&buf, filename);
+
+ if (ret) {
+ char *p = static_cast<char*>(malloc(buf.size() + 1)); // @fixme { implement deleter }
+ memcpy(p, &buf.at(0), buf.size());
+ p[buf.size()] = '\0';
+ data = p;
+ data_len = buf.size();
+ }
} else {
data = mmap_file(&data_len, filename);