Refactor ParseImage function.

Returns error when both `bufferView` and `uri` are defined in Image.
This commit is contained in:
Syoyo Fujita 2018-03-21 19:54:38 +09:00
parent ba809ff52f
commit 8e2c24fb92

View File

@ -1662,73 +1662,71 @@ static bool ParseImage(Image *image, std::string *err, const json &o,
LoadImageDataFunction *LoadImageData = nullptr,
void *user_data = nullptr) {
// A glTF image must either reference a bufferView or an image uri
double bufferView = -1;
bool isEmbedded =
ParseNumberProperty(&bufferView, err, o, "bufferView", false);
std::string uri;
std::string tmp_err;
if (!ParseStringProperty(&uri, &tmp_err, o, "uri", false) && !isEmbedded) {
// schema says oneOf [`bufferView`, `uri`]
// TODO(syoyo): Check the type of each parameters.
bool hasBufferView = (o.find("bufferView") != o.end());
bool hasURI = (o.find("uri") != o.end());
if (hasBufferView && hasURI) {
// Should not both defined.
if (err) {
(*err) += "`bufferView` or `uri` required for Image.\n";
(*err) += "One of `bufferView` or `uri` should be defined, but both are defined for Image.\n";
}
return false;
}
if (!hasBufferView && !hasURI) {
if (err) {
(*err) += "Neither required `bufferView` nor `uri` defined for Image.\n";
}
return false;
}
ParseStringProperty(&image->name, err, o, "name", false);
double bufferView = -1;
if (hasBufferView) {
if (!ParseNumberProperty(&bufferView, err, o, "bufferView", true)) {
if (err) {
(*err) += "Invalid `bufferView` definition for Image.\n";
}
return false;
}
std::string mime_type;
ParseStringProperty(&mime_type, err, o, "mimeType", false);
double width = 0.0;
ParseNumberProperty(&width, err, o, "width", false);
double height = 0.0;
ParseNumberProperty(&height, err, o, "height", false);
// Just only save some information here. Loading actual image data from
// bufferView is done after this `ParseImage` function.
image->bufferView = static_cast<int>(bufferView);
image->mimeType = mime_type;
image->width = static_cast<int>(width);
image->height = static_cast<int>(height);
return true;
}
std::string uri;
std::string tmp_err;
if (hasURI) {
if (!ParseStringProperty(&uri, &tmp_err, o, "uri", true)) {
if (err) {
(*err) += "`bufferView` or `uri` required for Image.\n";
}
return false;
}
}
std::vector<unsigned char> img;
if (is_binary) {
// Still binary glTF accepts external dataURI. First try external resources.
bool loaded = false;
if (IsDataURI(uri)) {
loaded = DecodeDataURI(&img, uri, 0, false);
} else {
// Assume external file
// Keep texture path (for textures that cannot be decoded)
image->uri = uri;
#ifdef TINYGLTF_NO_EXTERNAL_IMAGE
return true;
#endif
loaded = LoadExternalFile(&img, err, uri, basedir, 0, false);
}
if (!loaded) {
// load data from (embedded) binary data
if ((bin_size == 0) || (bin_data == nullptr)) {
if (err) {
(*err) += "Invalid binary data.\n";
}
return false;
}
double buffer_view = -1.0;
if (!ParseNumberProperty(&buffer_view, err, o, "bufferView", true,
"Image")) {
return false;
}
std::string mime_type;
ParseStringProperty(&mime_type, err, o, "mimeType", false);
double width = 0.0;
ParseNumberProperty(&width, err, o, "width", false);
double height = 0.0;
ParseNumberProperty(&height, err, o, "height", false);
// Just only save some information here. Loading actual image data from
// bufferView is done in other place.
image->bufferView = static_cast<int>(buffer_view);
image->mimeType = mime_type;
image->width = static_cast<int>(width);
image->height = static_cast<int>(height);
return true;
}
} else {
if (hasURI) {
if (IsDataURI(uri)) {
if (!DecodeDataURI(&img, uri, 0, false)) {
if (err) {
@ -1750,6 +1748,7 @@ static bool ParseImage(Image *image, std::string *err, const json &o,
// If the image cannot be loaded, keep uri as image->uri.
return true;
}
if (img.empty()) {
if (err) {
(*err) += "Image is empty.\n";