diff --git a/tiny_gltf.h b/tiny_gltf.h index 05624a9..9b6494d 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 @@ -1235,7 +1240,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) { @@ -1246,6 +1251,8 @@ static bool LoadExternalFile(std::vector *out, std::string *err, return false; } + std::string* failMsgOut = required ? err : warn; + out->clear(); std::vector paths; @@ -1254,8 +1261,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 (failMsgOut) { + (*failMsgOut) += "File not found : " + filename + "\n"; } return false; } @@ -1265,15 +1272,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; } @@ -1285,8 +1294,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; } @@ -1307,14 +1316,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) { @@ -1353,9 +1367,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); @@ -1610,7 +1624,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; @@ -1649,7 +1663,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,"; @@ -2168,7 +2182,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"; } @@ -2263,7 +2277,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; } } @@ -2305,7 +2319,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; } }