From 0d0e97e8cd0e3e0d294b622ad4de9f13f86b5d3f Mon Sep 17 00:00:00 2001 From: Selmar Kok Date: Wed, 22 Aug 2018 14:01:57 +0200 Subject: [PATCH 1/4] forward declare DataURI helper functions to allow usage outside of implementation file (in case of custom image handling) --- tiny_gltf.h | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index e253fce..fb8070d 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -189,6 +189,11 @@ static inline int32_t GetTypeSizeInBytes(uint32_t ty) { } } +bool IsDataURI(const std::string &in); +bool DecodeDataURI(std::vector *out, + std::string &mime_type, const std::string &in, + size_t reqBytes, bool checkSize); + #ifdef __clang__ #pragma clang diagnostic push // Suppress warning for : static Value null_value @@ -1608,7 +1613,7 @@ static void UpdateImageObject(Image &image, std::string &baseDir, int index, } } -static bool IsDataURI(const std::string &in) { +bool IsDataURI(const std::string &in) { std::string header = "data:application/octet-stream;base64,"; if (in.find(header) == 0) { return true; @@ -1647,7 +1652,7 @@ static bool IsDataURI(const std::string &in) { return false; } -static bool DecodeDataURI(std::vector *out, +bool DecodeDataURI(std::vector *out, std::string &mime_type, const std::string &in, size_t reqBytes, bool checkSize) { std::string header = "data:application/octet-stream;base64,"; From cda38e03ed8a6dc407319e1363ad710f581de662 Mon Sep 17 00:00:00 2001 From: Selmar Kok Date: Wed, 22 Aug 2018 18:26:10 +0200 Subject: [PATCH 2/4] change from warning to error for missing bin files --- tiny_gltf.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index fb8070d..d00be44 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -1257,8 +1257,8 @@ static bool LoadExternalFile(std::vector *out, std::string *err, std::string filepath = FindFile(paths, filename, fs); if (filepath.empty() || filename.empty()) { - if (warn) { - (*warn) += "File not found : " + filename + "\n"; + if (err) { + (*err) += "File not found : " + filename + "\n"; } return false; } From e3b3fa9eb663468e96f200754eed9b003501ef4f Mon Sep 17 00:00:00 2001 From: Selmar Kok Date: Wed, 22 Aug 2018 19:04:21 +0200 Subject: [PATCH 3/4] add required parameter to LoadExternalFile --- tiny_gltf.h | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index d00be44..3d18c48 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -1238,7 +1238,7 @@ std::string base64_decode(std::string const &encoded_string) { static bool LoadExternalFile(std::vector *out, std::string *err, std::string *warn, const std::string &filename, - const std::string &basedir, size_t reqBytes, + const std::string &basedir, bool required, size_t reqBytes, bool checkSize, FsCallbacks *fs) { if (fs == nullptr || fs->FileExists == nullptr || fs->ExpandFilePath == nullptr || fs->ReadWholeFile == nullptr) { @@ -1249,6 +1249,8 @@ static bool LoadExternalFile(std::vector *out, std::string *err, return false; } + std::string* failMsgOut = required ? err : warn; + out->clear(); std::vector paths; @@ -1257,8 +1259,8 @@ static bool LoadExternalFile(std::vector *out, std::string *err, std::string filepath = FindFile(paths, filename, fs); if (filepath.empty() || filename.empty()) { - if (err) { - (*err) += "File not found : " + filename + "\n"; + if (failMsgOut) { + (*failMsgOut) += "File not found : " + filename + "\n"; } return false; } @@ -1268,15 +1270,17 @@ static bool LoadExternalFile(std::vector *out, std::string *err, bool fileRead = fs->ReadWholeFile(&buf, &fileReadErr, filepath, fs->user_data); if (!fileRead) { - if (err) { - (*err) += "File read error : " + filepath + " : " + fileReadErr + "\n"; + if (failMsgOut) { + (*failMsgOut) += "File read error : " + filepath + " : " + fileReadErr + "\n"; } return false; } size_t sz = buf.size(); if (sz == 0) { - (*err) += "File is empty : " + filepath + "\n"; + if(failMsgOut) { + (*failMsgOut) += "File is empty : " + filepath + "\n"; + } return false; } @@ -1288,8 +1292,8 @@ static bool LoadExternalFile(std::vector *out, std::string *err, std::stringstream ss; ss << "File size mismatch : " << filepath << ", requestedBytes " << reqBytes << ", but got " << sz << std::endl; - if (err) { - (*err) += ss.str(); + if (failMsgOut) { + (*failMsgOut) += ss.str(); } return false; } @@ -2171,7 +2175,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, #ifdef TINYGLTF_NO_EXTERNAL_IMAGE return true; #endif - if (!LoadExternalFile(&img, err, warn, uri, basedir, 0, false, fs)) { + if (!LoadExternalFile(&img, err, warn, uri, basedir, false, 0, false, fs)) { if (warn) { (*warn) += "Failed to load external 'uri' for image parameter\n"; } @@ -2266,7 +2270,7 @@ static bool ParseBuffer(Buffer *buffer, std::string *err, const json &o, } else { // External .bin file. if (!LoadExternalFile(&buffer->data, err, /* warn */ nullptr, buffer->uri, - basedir, bytes, true, fs)) { + basedir, true, bytes, true, fs)) { return false; } } @@ -2308,7 +2312,7 @@ static bool ParseBuffer(Buffer *buffer, std::string *err, const json &o, } else { // Assume external .bin file. if (!LoadExternalFile(&buffer->data, err, /* warn */ nullptr, buffer->uri, - basedir, bytes, true, fs)) { + basedir, true, bytes, true, fs)) { return false; } } From 18ef338ff5a1875e0bdbc2550a8c9460d3c2e4bc Mon Sep 17 00:00:00 2001 From: Victor Bushong Date: Wed, 22 Aug 2018 22:03:30 -0500 Subject: [PATCH 4/4] Force default image loader to use 32-bit images for Vulkan compatibility. --- tiny_gltf.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/tiny_gltf.h b/tiny_gltf.h index 3d18c48..b12827b 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -1314,14 +1314,19 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, int size, void *) { (void)warn; - int w, h, comp; + int w, h, comp, req_comp; + + // force 32-bit textures for common Vulkan compatibility. It appears that + // some GPU drivers do not support 24-bit images for Vulkan + req_comp = 4; + // if image cannot be decoded, ignore parsing and keep it by its path // don't break in this case // FIXME we should only enter this function if the image is embedded. If // image->uri references // an image file, it should be left as it is. Image loading should not be // mandatory (to support other formats) - unsigned char *data = stbi_load_from_memory(bytes, size, &w, &h, &comp, 0); + unsigned char *data = stbi_load_from_memory(bytes, size, &w, &h, &comp, req_comp); if (!data) { // NOTE: you can use `warn` instead of `err` if (err) { @@ -1360,9 +1365,9 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, image->width = w; image->height = h; - image->component = comp; - image->image.resize(static_cast(w * h * comp)); - std::copy(data, data + w * h * comp, image->image.begin()); + image->component = req_comp; + image->image.resize(static_cast(w * h * req_comp)); + std::copy(data, data + w * h * req_comp, image->image.begin()); free(data);