Skip to content

Commit

Permalink
fixes syoyo#497
Browse files Browse the repository at this point in the history
Do not discard image data uri if uri still needed
  • Loading branch information
ptc-tgamper committed Jul 31, 2024
1 parent 10b23b6 commit 01858ab
Show file tree
Hide file tree
Showing 2 changed files with 66 additions and 10 deletions.
45 changes: 45 additions & 0 deletions tests/tester.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1247,3 +1247,48 @@ TEST_CASE("empty-images-not-written", "[issue-495]") {
// WriteImageData should be invoked for both images
CHECK(counter == 2);
}

TEST_CASE("images-data-uri-lost", "[issue-497]") {
std::string err;
std::string warn;
tinygltf::Model model;
tinygltf::TinyGLTF ctx;

// First, load a model that has images
tinygltf::Model modelWithExternalURIs;
bool ok = ctx.LoadASCIIFromFile(&modelWithExternalURIs, &err, &warn, "../models/Cube/Cube.gltf");
REQUIRE(ok);
REQUIRE(err.empty());
REQUIRE(warn.empty());

// Write as GLB and embed the images as data URIs
ok = ctx.WriteGltfSceneToFile(&modelWithExternalURIs, "issue-497.glb", true, true, false, true);
REQUIRE(ok);

// Now load the GLB with the data URI images.
// Use a custom image loader that does not load any image data.
ctx.SetImageLoader(LoadImageData, nullptr);
ok = ctx.LoadBinaryFromFile(&model, &err, &warn, "issue-497.glb");
REQUIRE(ok);
REQUIRE(err.empty());
REQUIRE(warn.empty());

// Now check the images of the model
CHECK(model.images.size() == 2);
for (const auto& image : model.images) {
// No data loaded or decoded
CHECK(image.image.empty());
// The URI is kept
CHECK_FALSE(image.uri.empty());
// The URI should be a data URI
CHECK(image.uri.find("data:") == 0);
}

// Now write the model with the data URIs
int counter = 0;
ctx.SetImageWriter(WriteImageData, &counter);
ok = ctx.WriteGltfSceneToFile(&model, "issue-497-data-uris.gltf");
CHECK(ok);
// WriteImageData should not have been invoked for the data URIs
CHECK(counter == 0);
}
31 changes: 21 additions & 10 deletions tiny_gltf.h
Original file line number Diff line number Diff line change
Expand Up @@ -3293,15 +3293,17 @@ static bool UpdateImageObject(const Image &image, std::string &baseDir,
void *user_data, std::string *out_uri) {
std::string filename;
std::string ext;
// If image has uri, use it as a filename
if (image.uri.size()) {
std::string decoded_uri;
if (!uri_cb->decode(image.uri, &decoded_uri, uri_cb->user_data)) {
// A decode failure results in a failure to write the gltf.
return false;
// If image has a uri, and it is not a data uri, use it as filename
if (!image.uri.empty()) {
if (!IsDataURI(image.uri)) {
std::string decoded_uri;
if (!uri_cb->decode(image.uri, &decoded_uri, uri_cb->user_data)) {
// A decode failure results in a failure to write the gltf.
return false;
}
filename = GetBaseFilename(decoded_uri);
ext = GetFilePathExtension(filename);
}
filename = GetBaseFilename(decoded_uri);
ext = GetFilePathExtension(filename);
} else if (image.bufferView != -1) {
// If there's no URI and the data exists in a buffer,
// don't change properties or write images
Expand Down Expand Up @@ -4442,8 +4444,17 @@ static bool ParseImage(Image *image, const int image_idx, std::string *err,
return false;
}

return LoadImageData(image, image_idx, err, warn, 0, 0, &img.at(0),
static_cast<int>(img.size()), load_image_user_data);
bool ok = LoadImageData(image, image_idx, err, warn, 0, 0, &img.at(0),
static_cast<int>(img.size()), load_image_user_data);

// If the image is encoded as data URI, and the actual image data was
// not extracted, then we keep the original data URI that holds all
// the data.
if (IsDataURI(uri) && ok && image->image.empty()) {
image->uri = uri;
}

return ok;
}

static bool ParseTexture(Texture *texture, std::string *err,
Expand Down

0 comments on commit 01858ab

Please sign in to comment.