diff --git a/tiny_gltf.h b/tiny_gltf.h index ad32ee4..42c64a7 100644 --- a/tiny_gltf.h +++ b/tiny_gltf.h @@ -801,7 +801,7 @@ enum SectionCheck { /// /// LoadImageDataFunction type. Signature for custom image loading callbacks. /// -typedef bool (*LoadImageDataFunction)(Image *, std::string *, std::string *, +typedef bool (*LoadImageDataFunction)(Image *, const int, std::string *, std::string *, int, int, const unsigned char *, int, void *); @@ -813,7 +813,7 @@ typedef bool (*WriteImageDataFunction)(const std::string *, const std::string *, #ifndef TINYGLTF_NO_STB_IMAGE // Declaration of default image loader callback -bool LoadImageData(Image *image, std::string *err, std::string *warn, +bool LoadImageData(Image *image, const int image_idx, std::string *err, std::string *warn, int req_width, int req_height, const unsigned char *bytes, int size, void *); #endif @@ -1588,9 +1588,9 @@ void TinyGLTF::SetImageLoader(LoadImageDataFunction func, void *user_data) { } #ifndef TINYGLTF_NO_STB_IMAGE -bool LoadImageData(Image *image, std::string *err, std::string *warn, +bool LoadImageData(Image *image, const int image_idx, std::string *err, std::string *warn, int req_width, int req_height, const unsigned char *bytes, - int size, void *) { + int size, void *user_data) { (void)warn; int w, h, comp, req_comp; @@ -1610,7 +1610,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (!data) { // NOTE: you can use `warn` instead of `err` if (err) { - (*err) += "Unknown image format.\n"; + (*err) += "Unknown image format. STB cannot decode image data for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\". Proably 16bit PNG?\n"; } return false; } @@ -1618,7 +1618,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (w < 1 || h < 1) { free(data); if (err) { - (*err) += "Invalid image data.\n"; + (*err) += "Invalid image data for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -1627,7 +1627,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (req_width != w) { free(data); if (err) { - (*err) += "Image width mismatch.\n"; + (*err) += "Image width mismatch for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -1637,7 +1637,7 @@ bool LoadImageData(Image *image, std::string *err, std::string *warn, if (req_height != h) { free(data); if (err) { - (*err) += "Image height mismatch.\n"; + (*err) += "Image height mismatch. for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -2427,7 +2427,7 @@ static bool ParseAsset(Asset *asset, std::string *err, const json &o) { return true; } -static bool ParseImage(Image *image, std::string *err, std::string *warn, +static bool ParseImage(Image *image, const int image_idx, std::string *err, std::string *warn, const json &o, const std::string &basedir, FsCallbacks *fs, LoadImageDataFunction *LoadImageData = nullptr, @@ -2439,24 +2439,25 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, bool hasBufferView = (o.find("bufferView") != o.end()); bool hasURI = (o.find("uri") != o.end()); + ParseStringProperty(&image->name, err, o, "name", false); + if (hasBufferView && hasURI) { // Should not both defined. if (err) { (*err) += "Only one of `bufferView` or `uri` should be defined, but both are " - "defined for Image.\n"; + "defined for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } if (!hasBufferView && !hasURI) { if (err) { - (*err) += "Neither required `bufferView` nor `uri` defined for Image.\n"; + (*err) += "Neither required `bufferView` nor `uri` defined for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } - ParseStringProperty(&image->name, err, o, "name", false); ParseExtensionsProperty(&image->extensions, err, o); ParseExtrasProperty(&image->extras, o); @@ -2464,7 +2465,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, double bufferView = -1; if (!ParseNumberProperty(&bufferView, err, o, "bufferView", true)) { if (err) { - (*err) += "Failed to parse `bufferView` for Image.\n"; + (*err) += "Failed to parse `bufferView` for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\"\n"; } return false; } @@ -2494,7 +2495,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, std::string tmp_err; if (!ParseStringProperty(&uri, &tmp_err, o, "uri", true)) { if (err) { - (*err) += "Failed to parse `uri` for Image.\n"; + (*err) += "Failed to parse `uri` for image[" + std::to_string(image_idx) + "] name = \"" + image->name + "\".\n"; } return false; } @@ -2504,7 +2505,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, if (IsDataURI(uri)) { if (!DecodeDataURI(&img, image->mimeType, uri, 0, false)) { if (err) { - (*err) += "Failed to decode 'uri' for image parameter.\n"; + (*err) += "Failed to decode 'uri' for image[" + std::to_string(image_idx) + "] name = [" + image->name + "]\n"; } return false; } @@ -2517,7 +2518,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, #endif if (!LoadExternalFile(&img, err, warn, uri, basedir, false, 0, false, fs)) { if (warn) { - (*warn) += "Failed to load external 'uri' for image parameter\n"; + (*warn) += "Failed to load external 'uri' for image[" + std::to_string(image_idx) + "] name = [" + image->name + "]\n"; } // If the image cannot be loaded, keep uri as image->uri. return true; @@ -2525,7 +2526,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, if (img.empty()) { if (warn) { - (*warn) += "Image is empty.\n"; + (*warn) += "Image data is empty for image[" + std::to_string(image_idx) + "] name = [" + image->name + "] \n"; } return false; } @@ -2537,7 +2538,7 @@ static bool ParseImage(Image *image, std::string *err, std::string *warn, } return false; } - return (*LoadImageData)(image, err, warn, 0, 0, &img.at(0), + return (*LoadImageData)(image, image_idx, err, warn, 0, 0, &img.at(0), static_cast(img.size()), load_image_user_data); } @@ -3665,15 +3666,16 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, json::const_iterator it(root.begin()); json::const_iterator itEnd(root.end()); - for (; it != itEnd; it++) { + int idx = 0; + for (; it != itEnd; it++, idx++) { if (!it.value().is_object()) { if (err) { - (*err) += "`images' does not contain an JSON object."; + (*err) += "image[" + std::to_string(idx) + "] is not a JSON object."; } return false; } Image image; - if (!ParseImage(&image, err, warn, it.value(), base_dir, &fs, + if (!ParseImage(&image, idx, err, warn, it.value(), base_dir, &fs, &this->LoadImageData, load_image_user_data_)) { return false; } @@ -3683,7 +3685,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, if (size_t(image.bufferView) >= model->bufferViews.size()) { if (err) { std::stringstream ss; - ss << "bufferView \"" << image.bufferView + ss << "image[" << idx << "] bufferView \"" << image.bufferView << "\" not found in the scene." << std::endl; (*err) += ss.str(); } @@ -3700,7 +3702,7 @@ bool TinyGLTF::LoadFromString(Model *model, std::string *err, std::string *warn, } return false; } - bool ret = LoadImageData(&image, err, warn, image.width, image.height, + bool ret = LoadImageData(&image, idx, err, warn, image.width, image.height, &buffer.data[bufferView.byteOffset], static_cast(bufferView.byteLength), load_image_user_data_);