From 6537cf8ba3ea022dd96d7e97cdd9b428d2767913 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Wed, 18 Oct 2023 01:45:39 +0000 Subject: [PATCH 1/2] support loading glb with compressed jpeg textures Signed-off-by: Ian Chen --- graphics/include/gz/common/Image.hh | 6 ++++- graphics/src/AssimpLoader.cc | 25 ++++++++++++++++---- graphics/src/AssimpLoader_TEST.cc | 34 ++++++++++++++++++++++++++++ graphics/src/Image.cc | 16 +++++++++++-- test/data/box_texture_jpg.glb | Bin 0 -> 7612 bytes 5 files changed, 74 insertions(+), 7 deletions(-) create mode 100644 test/data/box_texture_jpg.glb diff --git a/graphics/include/gz/common/Image.hh b/graphics/include/gz/common/Image.hh index 4a30eb4c..42196def 100644 --- a/graphics/include/gz/common/Image.hh +++ b/graphics/include/gz/common/Image.hh @@ -85,7 +85,11 @@ namespace gz BAYER_GBRG8, BAYER_GRBG8, COMPRESSED_PNG, - PIXEL_FORMAT_COUNT + PIXEL_FORMAT_COUNT, + // \todo(iche033) COMPRESSED_JPEG is added at the end to + // preserve ABI compatibility. Move this enum up when merging + // forward to main + COMPRESSED_JPEG }; diff --git a/graphics/src/AssimpLoader.cc b/graphics/src/AssimpLoader.cc index ba2c5765..4bbd39f0 100644 --- a/graphics/src/AssimpLoader.cc +++ b/graphics/src/AssimpLoader.cc @@ -542,16 +542,33 @@ std::pair ImagePtr AssimpLoader::Implementation::LoadEmbeddedTexture( const aiTexture* _texture) const { - auto img = std::make_shared(); if (_texture->mHeight == 0) { + Image::PixelFormatType format = Image::PixelFormatType::UNKNOWN_PIXEL_FORMAT; if (_texture->CheckFormat("png")) { - img->SetFromCompressedData((unsigned char*)_texture->pcData, - _texture->mWidth, Image::PixelFormatType::COMPRESSED_PNG); + format = Image::PixelFormatType::COMPRESSED_PNG; + } + else if (_texture->CheckFormat("jpg")) + { + format = Image::PixelFormatType::COMPRESSED_JPEG; + } + if (format != Image::PixelFormatType::UNKNOWN_PIXEL_FORMAT) + { + auto img = std::make_shared(); + img->SetFromCompressedData( + reinterpret_cast(_texture->pcData), + _texture->mWidth, format); + return img; + } + else + { + gzerr << "Unable to load embedded texture. " + << "Unsupported compressed image format" + << std::endl; } } - return img; + return ImagePtr(); } ////////////////////////////////////////////////// diff --git a/graphics/src/AssimpLoader_TEST.cc b/graphics/src/AssimpLoader_TEST.cc index f171d427..b331e8dd 100644 --- a/graphics/src/AssimpLoader_TEST.cc +++ b/graphics/src/AssimpLoader_TEST.cc @@ -644,6 +644,40 @@ TEST_F(AssimpLoader, LoadGlTF2BoxExternalTexture) EXPECT_EQ(testTextureFile, mat->TextureImage()); } +///////////////////////////////////////////////// +// This test loads a box glb mesh with embedded compressed jpeg texture +TEST_F(AssimpLoader, LoadGlTF2BoxWithJPEGTexture) +{ + common::AssimpLoader loader; + common::Mesh *mesh = loader.Load( + common::testing::TestFile("data", "box_texture_jpg.glb")); + + EXPECT_STREQ("unknown", mesh->Name().c_str()); + EXPECT_EQ(math::Vector3d(1, 1, 1), mesh->Max()); + EXPECT_EQ(math::Vector3d(-1, -1, -1), mesh->Min()); + + EXPECT_EQ(24u, mesh->VertexCount()); + EXPECT_EQ(24u, mesh->NormalCount()); + EXPECT_EQ(36u, mesh->IndexCount()); + EXPECT_EQ(24u, mesh->TexCoordCount()); + EXPECT_EQ(1u, mesh->SubMeshCount()); + EXPECT_EQ(1u, mesh->MaterialCount()); + + // Make sure we can read the submesh name + EXPECT_STREQ("Cube", mesh->SubMeshByIndex(0).lock()->Name().c_str()); + + const common::MaterialPtr mat = mesh->MaterialByIndex(0u); + ASSERT_TRUE(mat.get()); + + // Make sure we read the material color values + EXPECT_EQ(math::Color(0.4f, 0.4f, 0.4f, 1.0f), mat->Ambient()); + EXPECT_EQ(math::Color(1.0f, 1.0f, 1.0f, 1.0f), mat->Diffuse()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), mat->Specular()); + EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), mat->Specular()); + EXPECT_EQ("Cube_Material_Diffuse", mat->TextureImage()); + EXPECT_NE(nullptr, mat->TextureData()); +} + ///////////////////////////////////////////////// // Use a fully featured glb test asset, including PBR textures, emissive maps // embedded textures, lightmaps, animations to test advanced glb features diff --git a/graphics/src/Image.cc b/graphics/src/Image.cc index 2eb76154..1bbdf74f 100644 --- a/graphics/src/Image.cc +++ b/graphics/src/Image.cc @@ -274,10 +274,22 @@ void Image::SetFromCompressedData(unsigned char *_data, FreeImage_Unload(this->dataPtr->bitmap); this->dataPtr->bitmap = nullptr; - if (_format == COMPRESSED_PNG) + FREE_IMAGE_FORMAT format = FIF_UNKNOWN; + switch (_format) + { + case COMPRESSED_PNG: + format = FIF_PNG; + break; + case COMPRESSED_JPEG: + format = FIF_JPEG; + break; + default: + break; + } + if (format != FIF_UNKNOWN) { FIMEMORY *fiMem = FreeImage_OpenMemory(_data, _size); - this->dataPtr->bitmap = FreeImage_LoadFromMemory(FIF_PNG, fiMem); + this->dataPtr->bitmap = FreeImage_LoadFromMemory(format, fiMem); FreeImage_CloseMemory(fiMem); } else diff --git a/test/data/box_texture_jpg.glb b/test/data/box_texture_jpg.glb new file mode 100644 index 0000000000000000000000000000000000000000..6260273cd26e689e734b21350cb75e9a04447f27 GIT binary patch literal 7612 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 literal 0 HcmV?d00001 From 76be6e6d5f9c2f14193c69c328ade52e12177e87 Mon Sep 17 00:00:00 2001 From: Ian Chen Date: Mon, 23 Oct 2023 22:54:04 +0000 Subject: [PATCH 2/2] remove dup call Signed-off-by: Ian Chen --- graphics/src/AssimpLoader_TEST.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/graphics/src/AssimpLoader_TEST.cc b/graphics/src/AssimpLoader_TEST.cc index b331e8dd..53a58849 100644 --- a/graphics/src/AssimpLoader_TEST.cc +++ b/graphics/src/AssimpLoader_TEST.cc @@ -673,7 +673,6 @@ TEST_F(AssimpLoader, LoadGlTF2BoxWithJPEGTexture) EXPECT_EQ(math::Color(0.4f, 0.4f, 0.4f, 1.0f), mat->Ambient()); EXPECT_EQ(math::Color(1.0f, 1.0f, 1.0f, 1.0f), mat->Diffuse()); EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), mat->Specular()); - EXPECT_EQ(math::Color(0.0f, 0.0f, 0.0f, 1.0f), mat->Specular()); EXPECT_EQ("Cube_Material_Diffuse", mat->TextureImage()); EXPECT_NE(nullptr, mat->TextureData()); }