Show more expressive messages when parsing image.

This commit is contained in:
Syoyo Fujita 2019-01-06 18:55:57 +09:00
parent 105694b468
commit af3ebb2e76

View File

@ -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<int>(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<int>(bufferView.byteLength),
load_image_user_data_);