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 79f513b4..25d2e9ed 100644 --- a/graphics/src/AssimpLoader.cc +++ b/graphics/src/AssimpLoader.cc @@ -551,16 +551,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 fffd50f4..5df30d0f 100644 --- a/graphics/src/AssimpLoader_TEST.cc +++ b/graphics/src/AssimpLoader_TEST.cc @@ -644,6 +644,39 @@ 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("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 00000000..6260273c Binary files /dev/null and b/test/data/box_texture_jpg.glb differ