diff --git a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py index f84e367d1d..0b75760e05 100644 --- a/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py +++ b/AutomatedTesting/Gem/PythonTests/atom_renderer/test_Atom_MainSuite.py @@ -18,7 +18,7 @@ import pytest import editor_python_test_tools.hydra_test_utils as hydra logger = logging.getLogger(__name__) -EDITOR_TIMEOUT = 120 +EDITOR_TIMEOUT = 300 TEST_DIRECTORY = os.path.join(os.path.dirname(__file__), "atom_hydra_scripts") diff --git a/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp b/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp index c94978c63d..540178f4d9 100644 --- a/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp +++ b/Gems/Atom/Asset/ImageProcessingAtom/Code/Tests/ImageProcessing_Test.cpp @@ -95,32 +95,32 @@ namespace UnitTest class ImageProcessingTest : public ::testing::Test , public AllocatorsBase - , public ComponentApplicationBus::Handler + , public AZ::ComponentApplicationBus::Handler { public: ////////////////////////////////////////////////////////////////////////// // ComponentApplicationMessages. - ComponentApplication* GetApplication() override { return nullptr; } - void RegisterComponentDescriptor(const ComponentDescriptor*) override { } - void UnregisterComponentDescriptor(const ComponentDescriptor*) override { } - void RegisterEntityAddedEventHandler(EntityAddedEvent::Handler&) override { } - void RegisterEntityRemovedEventHandler(EntityRemovedEvent::Handler&) override { } - void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler&) override { } - void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler&) override { } - void SignalEntityActivated(Entity*) override { } - void SignalEntityDeactivated(Entity*) override { } - bool AddEntity(Entity*) override { return false; } - bool RemoveEntity(Entity*) override { return false; } - bool DeleteEntity(const EntityId&) override { return false; } - Entity* FindEntity(const EntityId&) override { return nullptr; } - SerializeContext* GetSerializeContext() override { return m_context.get(); } - BehaviorContext* GetBehaviorContext() override { return nullptr; } + AZ::ComponentApplication* GetApplication() override { return nullptr; } + void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } + void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } + void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override { } + void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override { } + void RegisterEntityActivatedEventHandler(AZ::EntityActivatedEvent::Handler&) override { } + void RegisterEntityDeactivatedEventHandler(AZ::EntityDeactivatedEvent::Handler&) override { } + void SignalEntityActivated(AZ::Entity*) override { } + void SignalEntityDeactivated(AZ::Entity*) override { } + bool AddEntity(AZ::Entity*) override { return false; } + bool RemoveEntity(AZ::Entity*) override { return false; } + bool DeleteEntity(const AZ::EntityId&) override { return false; } + Entity* FindEntity(const AZ::EntityId&) override { return nullptr; } + AZ::SerializeContext* GetSerializeContext() override { return m_context.get(); } + AZ::BehaviorContext* GetBehaviorContext() override { return nullptr; } AZ::JsonRegistrationContext* GetJsonRegistrationContext() override { return m_jsonRegistrationContext.get(); } const char* GetAppRoot() const override { return nullptr; } const char* GetEngineRoot() const override { return nullptr; } const char* GetExecutableFolder() const override { return nullptr; } - Debug::DrillerManager* GetDrillerManager() override { return nullptr; } - void EnumerateEntities(const EntityCallback& /*callback*/) override {} + AZ::Debug::DrillerManager* GetDrillerManager() override { return nullptr; } + void EnumerateEntities(const AZ::ComponentApplicationRequests::EntityCallback& /*callback*/) override {} void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {} ////////////////////////////////////////////////////////////////////////// diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp index e0b79e23aa..3497855c07 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.cpp @@ -120,13 +120,13 @@ namespace AZ { // stencil Srg // Note: the stencil pass uses a slightly reduced inner AABB to avoid seams - Vector3 innerExtentsReduced = m_innerExtents * m_transform.GetScale() - Vector3(0.1f, 0.1f, 0.1f); + Vector3 innerExtentsReduced = m_innerExtents - Vector3(0.1f, 0.1f, 0.1f); Matrix3x4 modelToWorldStencil = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(innerExtentsReduced); m_stencilSrg->SetConstant(m_reflectionRenderData->m_modelToWorldStencilConstantIndex, modelToWorldStencil); m_stencilSrg->Compile(); // blend weight Srg - Matrix3x4 modelToWorldOuter = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_outerExtents * m_transform.GetScale()); + Matrix3x4 modelToWorldOuter = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_outerExtents); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_modelToWorldRenderConstantIndex, modelToWorldOuter); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_aabbPosRenderConstantIndex, m_outerAabbWs.GetCenter()); m_blendWeightSrg->SetConstant(m_reflectionRenderData->m_outerAabbMinRenderConstantIndex, m_outerAabbWs.GetMin()); @@ -149,7 +149,7 @@ namespace AZ m_renderOuterSrg->Compile(); // render inner Srg - Matrix3x4 modelToWorldInner = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_innerExtents * m_transform.GetScale()); + Matrix3x4 modelToWorldInner = Matrix3x4::CreateFromMatrix3x3AndTranslation(Matrix3x3::CreateIdentity(), m_transform.GetTranslation()) * Matrix3x4::CreateScale(m_innerExtents); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_modelToWorldRenderConstantIndex, modelToWorldInner); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_aabbPosRenderConstantIndex, m_outerAabbWs.GetCenter()); m_renderInnerSrg->SetConstant(m_reflectionRenderData->m_outerAabbMinRenderConstantIndex, m_outerAabbWs.GetMin()); @@ -208,6 +208,12 @@ namespace AZ void ReflectionProbe::SetTransform(const AZ::Transform& transform) { + // retrieve previous scale and revert the scale on the inner/outer extents + AZ::Vector3 previousScale = m_transform.GetScale(); + m_outerExtents /= previousScale; + m_innerExtents /= previousScale; + + // store new transform m_transform = transform; // avoid scaling the visualization sphere @@ -215,22 +221,26 @@ namespace AZ visualizationTransform.ExtractScale(); m_meshFeatureProcessor->SetTransform(m_visualizationMeshHandle, visualizationTransform); - m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents * m_transform.GetScale() / 2.0f); - m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents * m_transform.GetScale() / 2.0f); + // update the inner/outer extents with the new scale + m_outerExtents *= m_transform.GetScale(); + m_innerExtents *= m_transform.GetScale(); + + m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f); + m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f); m_updateSrg = true; } void ReflectionProbe::SetOuterExtents(const AZ::Vector3& outerExtents) { - m_outerExtents = outerExtents; - m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents * m_transform.GetScale() / 2.0f); + m_outerExtents = outerExtents * m_transform.GetScale(); + m_outerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_outerExtents / 2.0f); m_updateSrg = true; } void ReflectionProbe::SetInnerExtents(const AZ::Vector3& innerExtents) { - m_innerExtents = innerExtents; - m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents * m_transform.GetScale() / 2.0f); + m_innerExtents = innerExtents * m_transform.GetScale(); + m_innerAabbWs = Aabb::CreateCenterHalfExtents(m_transform.GetTranslation(), m_innerExtents / 2.0f); m_updateSrg = true; } diff --git a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h index ab0e7a81d3..f062e0a42f 100644 --- a/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h +++ b/Gems/Atom/Feature/Common/Code/Source/ReflectionProbe/ReflectionProbe.h @@ -78,10 +78,10 @@ namespace AZ const Vector3& GetPosition() const { return m_transform.GetTranslation(); } void SetTransform(const AZ::Transform& transform); - AZ::Vector3 GetOuterExtents() const { return m_outerExtents * m_transform.GetScale(); } + const AZ::Vector3& GetOuterExtents() const { return m_outerExtents; } void SetOuterExtents(const AZ::Vector3& outerExtents); - AZ::Vector3 GetInnerExtents() const { return m_innerExtents * m_transform.GetScale(); } + const AZ::Vector3& GetInnerExtents() const { return m_innerExtents; } void SetInnerExtents(const AZ::Vector3& innerExtents); const Aabb& GetOuterAabbWs() const { return m_outerAabbWs; } diff --git a/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp b/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp index 2555d1a6af..c2db0da54a 100644 --- a/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp +++ b/Gems/ImGui/External/ImGui/v1.82/imgui/imgui.cpp @@ -7118,7 +7118,9 @@ static void ImGui::ErrorCheckEndFrameSanityChecks() // We silently accommodate for this case by ignoring/ the case where all io.KeyXXX modifiers were released (aka key_mod_flags == 0), // while still correctly asserting on mid-frame key press events. const ImGuiKeyModFlags key_mod_flags = GetMergedKeyModFlags(); - IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); + + // [GFX TODO] Commented this line until Atom ImGuiPass is refactored (ATOM-15495). + // IM_ASSERT((key_mod_flags == 0 || g.IO.KeyMods == key_mod_flags) && "Mismatching io.KeyCtrl/io.KeyShift/io.KeyAlt/io.KeySuper vs io.KeyMods"); IM_UNUSED(key_mod_flags); // Recover from errors diff --git a/Gems/ImageProcessing/AssetProcessorGemConfig.setreg b/Gems/ImageProcessing/AssetProcessorGemConfig.setreg deleted file mode 100644 index 17d9887fe8..0000000000 --- a/Gems/ImageProcessing/AssetProcessorGemConfig.setreg +++ /dev/null @@ -1,7 +0,0 @@ -{ - "Amazon": { - "AssetProcessor": { - "Settings": {} - } - } -} diff --git a/Gems/ImageProcessing/Assets/Editor/Backward.png b/Gems/ImageProcessing/Assets/Editor/Backward.png deleted file mode 100644 index 82b3eafbd9..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/Backward.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1a1623477f4e2e5ef0440ecfc0c08e775d9b5f12d8ebc6b434e8212bf3445bcd -size 224 diff --git a/Gems/ImageProcessing/Assets/Editor/Forward.png b/Gems/ImageProcessing/Assets/Editor/Forward.png deleted file mode 100644 index a7a29a4c25..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/Forward.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:31b247223c1116d4fc014189a9d8d86d4458b792c1120442673631136fd89520 -size 222 diff --git a/Gems/ImageProcessing/Assets/Editor/Resources.qrc b/Gems/ImageProcessing/Assets/Editor/Resources.qrc deleted file mode 100644 index c309d19053..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/Resources.qrc +++ /dev/null @@ -1,11 +0,0 @@ - - - refresh-active.png - warning.png - refresh.png - info.png - Backward.png - Forward.png - reset.png - - diff --git a/Gems/ImageProcessing/Assets/Editor/info.png b/Gems/ImageProcessing/Assets/Editor/info.png deleted file mode 100644 index 002cf9c775..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/info.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3fec3caae92b9c9290c4157b3aeca29dcb366edd12719355e1d93dfb9d80cfed -size 825 diff --git a/Gems/ImageProcessing/Assets/Editor/refresh-active.png b/Gems/ImageProcessing/Assets/Editor/refresh-active.png deleted file mode 100644 index 33bc1c592a..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/refresh-active.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d29af2b69b74815c88352f85a7131384482e4f2d26ecf36581b46dede542fccb -size 2973 diff --git a/Gems/ImageProcessing/Assets/Editor/refresh.png b/Gems/ImageProcessing/Assets/Editor/refresh.png deleted file mode 100644 index fc9ef09987..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/refresh.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:36591b457ee3519b16405d281674fcdd18645e3570bfc960a22b8f142ee99a14 -size 436 diff --git a/Gems/ImageProcessing/Assets/Editor/reset.png b/Gems/ImageProcessing/Assets/Editor/reset.png deleted file mode 100644 index ed9c2f016d..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/reset.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0362da38d3804e2911130d138be4fd73040d66c8ac7d1b5f9f60c70037e8ca93 -size 1292 diff --git a/Gems/ImageProcessing/Assets/Editor/warning.png b/Gems/ImageProcessing/Assets/Editor/warning.png deleted file mode 100644 index 6020245f86..0000000000 --- a/Gems/ImageProcessing/Assets/Editor/warning.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cf5e987ea92164dcaa6deb88989aaac962bc092f5745274017f71224f48dbf7a -size 651 diff --git a/Gems/ImageProcessing/CMakeLists.txt b/Gems/ImageProcessing/CMakeLists.txt deleted file mode 100644 index 20a680bce9..0000000000 --- a/Gems/ImageProcessing/CMakeLists.txt +++ /dev/null @@ -1,12 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -add_subdirectory(Code) diff --git a/Gems/ImageProcessing/Code/CMakeLists.txt b/Gems/ImageProcessing/Code/CMakeLists.txt deleted file mode 100644 index a5cb6f6cb9..0000000000 --- a/Gems/ImageProcessing/Code/CMakeLists.txt +++ /dev/null @@ -1,147 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -ly_add_target( - NAME ImageProcessing.Headers HEADERONLY - NAMESPACE Gem - FILES_CMAKE - imageprocessing_headers_files.cmake - INCLUDE_DIRECTORIES - INTERFACE - Include -) - -if (NOT PAL_TRAIT_BUILD_HOST_TOOLS) - return() -endif() - -ly_get_list_relative_pal_filename(pal_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${PAL_PLATFORM_NAME}) - -set(platform_tools_files) -set(pal_tools_include_files) -set(pal_tools_dirs) -foreach(enabled_platform ${LY_PAL_TOOLS_ENABLED}) - string(TOLOWER ${enabled_platform} enabled_platform_lowercase) - ly_get_list_relative_pal_filename(pal_tools_dir ${CMAKE_CURRENT_LIST_DIR}/Source/Platform/${enabled_platform}) - list(APPEND platform_tools_files ${pal_tools_dir}/pal_tools_${enabled_platform_lowercase}.cmake) - list(APPEND pal_tools_include_files ${pal_tools_dir}/pal_tools_${enabled_platform_lowercase}_files.cmake) - list(APPEND pal_tools_dirs ${pal_tools_dir}) -endforeach() - -ly_add_target( - NAME ImageProcessing.Static STATIC - NAMESPACE Gem - AUTOMOC - AUTOUIC - FILES_CMAKE - imageprocessing_static_files.cmake - ${pal_tools_include_files} - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}_files.cmake - PLATFORM_INCLUDE_FILES - ${pal_dir}/platform_${PAL_PLATFORM_NAME_LOWERCASE}.cmake - ${platform_tools_files} - INCLUDE_DIRECTORIES - PRIVATE - . - Source - ../External - ${pal_dir} - ${pal_tools_dirs} - PUBLIC - Include - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Core - 3rdParty::Qt::Widgets - 3rdParty::etc2comp - 3rdParty::PVRTexTool - 3rdParty::squish-ccr - 3rdParty::zlib - 3rdParty::tiff - Legacy::CryCommon - AZ::AzCore - AZ::AssetBuilderSDK - Gem::TextureAtlas -) -ly_add_source_properties( - SOURCES - Source/BuilderSettings/BuilderSettingManager.cpp - Source/Processing/ImageConvert.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES ${LY_PAL_TOOLS_DEFINES} -) - -ly_add_target( - NAME ImageProcessing.Editor GEM_MODULE - - NAMESPACE Gem - AUTOMOC - AUTORCC - FILES_CMAKE - imageprocessing_files.cmake - PLATFORM_INCLUDE_FILES - ${platform_tools_files} - INCLUDE_DIRECTORIES - PRIVATE - . - Source - ${pal_dir} - PUBLIC - Include - BUILD_DEPENDENCIES - PRIVATE - 3rdParty::Qt::Widgets - 3rdParty::PVRTexTool - 3rdParty::squish-ccr - Legacy::CryCommon - AZ::AzCore - AZ::AzToolsFramework - AZ::AssetBuilderSDK - Gem::ImageProcessing.Static - Gem::TextureAtlas - RUNTIME_DEPENDENCIES - 3rdParty::ASTCEncoder - Gem::TextureAtlas -) - -if(PAL_TRAIT_BUILD_TESTS_SUPPORTED) - ly_add_target( - NAME ImageProcessing.Tests ${PAL_TRAIT_TEST_TARGET_TYPE} - NAMESPACE Gem - FILES_CMAKE - imageprocessing_tests_files.cmake - INCLUDE_DIRECTORIES - PRIVATE - Tests - . - Source - ${pal_dir} - BUILD_DEPENDENCIES - PRIVATE - AZ::AzTest - 3rdParty::Qt::Widgets - Legacy::CryCommon - AZ::AssetBuilderSDK - Gem::ImageProcessing.Static - Gem::ImageProcessing.Editor - Gem::TextureAtlas - ) - ly_add_googletest( - NAME Gem::ImageProcessing.Tests - ) - - ly_add_source_properties( - SOURCES Tests/ImageProcessing_Test.cpp - PROPERTY COMPILE_DEFINITIONS - VALUES ${LY_PAL_TOOLS_DEFINES} - ) - -endif() diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageObject.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageObject.h deleted file mode 100644 index baa6613daf..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageObject.h +++ /dev/null @@ -1,147 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include - -namespace AZ -{ - namespace IO - { - class SystemFileStream; - } -} - -namespace ImageProcessing -{ - class IImageObject; - class TextureSettings; - typedef AZStd::shared_ptr IImageObjectPtr; - - enum class EAlphaContent - { - eAlphaContent_Indeterminate, // the format may have alpha, but can't be calculated - eAlphaContent_Absent, // the format has no alpha - eAlphaContent_OnlyWhite, // alpha contains just white - eAlphaContent_OnlyBlack, // alpha contains just black - eAlphaContent_OnlyBlackAndWhite, // alpha contains just black and white - eAlphaContent_Greyscale // alpha contains grey tones - }; - - //interface for image object. The image object may have mipmaps. - class IImageObject - { - public: - //static functions - static IImageObject* CreateImage(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat); - - virtual ~IImageObject() {}; - public: - //creating new image object outof this image object - virtual IImageObject* Clone() const = 0; - // allocate an empty image object with requested format and same properties with current image - virtual IImageObject* AllocateImage(EPixelFormat pixelFormat) const = 0; - virtual IImageObject* AllocateImage() const = 0; - - //get pixel format - virtual EPixelFormat GetPixelFormat() const = 0; - - virtual AZ::u32 GetPixelCount(AZ::u32 mip) const = 0; - virtual AZ::u32 GetWidth(AZ::u32 mip) const = 0; - virtual AZ::u32 GetHeight(AZ::u32 mip) const = 0; - virtual bool IsCubemap() const = 0; - virtual AZ::u32 GetMipCount() const = 0; - - //get pixel data buffer - virtual void GetImagePointer(AZ::u32 mip, AZ::u8*& pMem, AZ::u32& pitch) const = 0; - virtual AZ::u32 GetMipBufSize(AZ::u32 mip) const = 0; - virtual void SetMipData(AZ::u32 mip, AZ::u8* mipBuf, AZ::u32 bufSize, AZ::u32 pitch) = 0; - - //get/set image flags - virtual AZ::u32 GetImageFlags() const = 0; - virtual void SetImageFlags(AZ::u32 imageFlags) = 0; - virtual void AddImageFlags(AZ::u32 imageFlags) = 0; - virtual void RemoveImageFlags(AZ::u32 imageFlags) = 0; - virtual bool HasImageFlags(AZ::u32 imageFlags) const = 0; - - // image data operations and calculation - // Calculates "(pixel.rgba * scale) + bias" - virtual void ScaleAndBiasChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& scale, const AZ::Vector4& bias) = 0; - // Calculates "clamp(pixel.rgba, min, max)" - virtual void ClampChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& min, const AZ::Vector4& max) = 0; - - //transfer alpha coverage from source image - virtual void TransferAlphaCoverage(const TextureSettings* textureSetting, const IImageObjectPtr srcImg) = 0; - // Routines to measure and manipulate alpha coverage - virtual float ComputeAlphaCoverageScaleFactor(AZ::u32 mip, float fDesiredCoverage, float fAlphaRef) const = 0; - virtual float ComputeAlphaCoverage(AZ::u32 mip, float fAlphaRef) const = 0; - - //helper functions - //compare whether two images are same. return true if they are same. - virtual bool CompareImage(const IImageObjectPtr otherImage) const = 0; - - // Writes this image to file used for runtime, overwrites any existing file. - // It may write alpha image as attached image into the same file - // outFilePaths will save filenames finally saved to since the image might be split and saved to multiple files - virtual bool SaveImage(const char* filename, IImageObjectPtr alphaImage, AZStd::vector& outFilePaths) const = 0; - virtual bool SaveImage(AZ::IO::SystemFileStream& out) const = 0; - virtual bool SaveMipToFile(AZ::u32 mip, const AZStd::string& filename) const = 0; - - //get total image data size in memory of all mipmaps. Not includs header and flags. - virtual AZ::u32 GetTextureMemory() const = 0; - - //identify content of the alpha channel - virtual EAlphaContent GetAlphaContent() const = 0; - - //normalize rgb channel for specified mips - virtual void NormalizeVectors(AZ::u32 firstMip, AZ::u32 maxMipCount) = 0; - - // use when you convert an image to another one - virtual void CopyPropertiesFrom(const IImageObjectPtr src) = 0; - - //swizzle data for source channels to dest channels - virtual void Swizzle(const char channels[4]) = 0; - - //get/set properties of the image object - virtual void GetColorRange(AZ::Color& minColor, AZ::Color& maxColor) const = 0; - virtual void SetColorRange(const AZ::Color& minColor, const AZ::Color& maxColor) = 0; - virtual AZ::u32 GetNumPersistentMips() const = 0; - virtual void SetNumPersistentMips(AZ::u32 nMips) = 0; - virtual float GetAverageBrightness() const = 0; - virtual void SetAverageBrightness(float avgBrightness) = 0; - - // Derive new roughness from normal variance to preserve the bumpiness of normal map mips and to reduce specular aliasing. - // The derived roughness is combined with the artist authored roughness stored in the alpha channel of the normal map. - // The algorithm is based on the Frequency Domain Normal Mapping implementation presented by Neubelt and Pettineo at Siggraph 2013. - virtual void GlossFromNormals(bool hasAuthoredGloss) = 0; - - //convert gloss map from legacy distribution to new one. New World is still using legacy gloss map. - virtual void ConvertLegacyGloss() = 0; - - //clear image with color - virtual void ClearColor(float r, float g, float b, float a) = 0; - - virtual bool HasPowerOfTwoSizes() const = 0; - }; - - //loading function to load output dds file to a IImageObject - IImageObject* LoadImageFromDdsFile(const AZStd::string& filename); - IImageObject* LoadImageFromDdsFile(AZ::IO::SystemFileStream& fileLoadStream); - IImageObject* LoadAttachedImageFromDdsFile(const AZStd::string& filename, IImageObjectPtr originImage); - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingBus.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingBus.h deleted file mode 100644 index 8b127b3f6e..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingBus.h +++ /dev/null @@ -1,37 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - class ImageProcessingRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ////////////////////////////////////////////////////////////////////////// - - // Loads an image from a source file path - virtual IImageObjectPtr LoadImage(const AZStd::string& filePath) = 0; - - // Loads an image from a source file path and converts it to a format suitable for previewing in tools - virtual IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) = 0; - }; - using ImageProcessingRequestBus = AZ::EBus; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingEditorBus.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingEditorBus.h deleted file mode 100644 index eae1fdeb6d..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/ImageProcessingEditorBus.h +++ /dev/null @@ -1,36 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include - -class QString; - -namespace ImageProcessingEditor -{ - class ImageProcessingEditorRequests - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Single; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ///////////////////////////////////////////////////////////////////////// - - //! Open single texture file - virtual void OpenSourceTextureFile(const AZ::Uuid& textureSourceID) = 0; - }; - - using ImageProcessingEditorRequestBus = AZ::EBus; -}//namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Include/ImageProcessing/PixelFormats.h b/Gems/ImageProcessing/Code/Include/ImageProcessing/PixelFormats.h deleted file mode 100644 index 2ceb889ac9..0000000000 --- a/Gems/ImageProcessing/Code/Include/ImageProcessing/PixelFormats.h +++ /dev/null @@ -1,107 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -namespace ImageProcessing -{ - enum EPixelFormat : int - { - //unsigned formats - ePixelFormat_R8G8B8A8 = 0, - ePixelFormat_R8G8B8X8, - ePixelFormat_R8G8, - ePixelFormat_R8, - ePixelFormat_A8, - ePixelFormat_R16G16B16A16, - ePixelFormat_R16G16, - ePixelFormat_R16, - - //Custom FourCC Formats - // Data in these FourCC formats is custom compressed data and only decodable by certain hardware. - //ASTC formats supported by ios devices with A8 processor. Also supported by Android Extension Pack. - ePixelFormat_ASTC_4x4, - ePixelFormat_ASTC_5x4, - ePixelFormat_ASTC_5x5, - ePixelFormat_ASTC_6x5, - ePixelFormat_ASTC_6x6, - ePixelFormat_ASTC_8x5, - ePixelFormat_ASTC_8x6, - ePixelFormat_ASTC_8x8, - ePixelFormat_ASTC_10x5, - ePixelFormat_ASTC_10x6, - ePixelFormat_ASTC_10x8, - ePixelFormat_ASTC_10x10, - ePixelFormat_ASTC_12x10, - ePixelFormat_ASTC_12x12, - //Formats supported by PowerVR GPU. Mainly for ios devices. - ePixelFormat_PVRTC2, //2bpp - ePixelFormat_PVRTC4, //4bpp - //formats for opengl and opengles 3.0 (android devices) - ePixelFormat_EAC_R11, //one channel unsigned data - ePixelFormat_EAC_RG11, //two channel unsigned data - ePixelFormat_ETC2, //Compresses RGB888 data, it taks 4x4 groups of pixel data and compresses each into a 64-bit - ePixelFormat_ETC2a, //Compresses RGBA8888 data with full alpha support - - // Standardized Compressed DXGI Formats (DX10+) - // Data in these compressed formats is hardware decodable on all DX10 chips, and manageable with the DX10-API. - ePixelFormat_BC1, // RGB without alpha, 0.5 byte/px - ePixelFormat_BC1a, // RGB with 1 bit of alpha, 0.5 byte/px. - ePixelFormat_BC3, // RGBA 1 byte/px, color maps with full alpha. - ePixelFormat_BC3t, // BC3 with alpha weighted color - ePixelFormat_BC4, // One color channel, 0.5 byte/px, unsigned - ePixelFormat_BC4s, // BC4, signed - ePixelFormat_BC5, // Two color channels, 1 byte/px, unsigned. Usually use for tangent-space normal maps - ePixelFormat_BC5s, // BC5, signed - ePixelFormat_BC6UH, // RGB, floating-point. Used for HDR images. Decompress to RGB in half floating point - ePixelFormat_BC7, // RGB or RGBA. 1 byte/px. Three color channels (4 to 7 bits per channel) with 0 to 8 bits of alpha - ePixelFormat_BC7t, // BC& with alpha weighted color - - // Float formats - // Data in a Float format is floating point data. - ePixelFormat_R9G9B9E5, - ePixelFormat_R32G32B32A32F, - ePixelFormat_R32G32F, - ePixelFormat_R32F, - ePixelFormat_R16G16B16A16F, - ePixelFormat_R16G16F, - ePixelFormat_R16F, - - //legacy format. Only used to load old converted dds files. - ePixelFormat_B8G8R8A8, //32bits rgba format - - ePixelFormat_R32, - - ePixelFormat_Count, - ePixelFormat_Unknown = ePixelFormat_Count - }; - - inline bool IsASTCFormat(EPixelFormat fmt) - { - return fmt == ePixelFormat_ASTC_4x4 || fmt == ePixelFormat_ASTC_5x4 || fmt == ePixelFormat_ASTC_5x5 || - fmt == ePixelFormat_ASTC_6x5 || fmt == ePixelFormat_ASTC_6x6 || fmt == ePixelFormat_ASTC_8x5 || - fmt == ePixelFormat_ASTC_8x6 || fmt == ePixelFormat_ASTC_8x8 || fmt == ePixelFormat_ASTC_10x5 || - fmt == ePixelFormat_ASTC_10x6 || fmt == ePixelFormat_ASTC_10x8 || fmt == ePixelFormat_ASTC_10x10 || - fmt == ePixelFormat_ASTC_12x10 || fmt == ePixelFormat_ASTC_12x12; - } - - inline bool IsETCFormat(EPixelFormat fmt) - { - return fmt == ePixelFormat_ETC2 || fmt == ePixelFormat_ETC2a || fmt == ePixelFormat_EAC_R11 || - fmt == ePixelFormat_EAC_RG11; - } - - inline bool IsPVRTCFormat(EPixelFormat fmt) - { - return fmt == ePixelFormat_PVRTC2 || fmt == ePixelFormat_PVRTC4; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.cpp b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.cpp deleted file mode 100644 index e8d4948cc9..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.cpp +++ /dev/null @@ -1,99 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include "AtlasBuilderComponent.h" - -#include - -namespace TextureAtlasBuilder -{ - // AZ Components should only initialize their members to null and empty in constructor - // Allocation of data should occur in Init(), once we can guarantee reflection and registration of types - AtlasBuilderComponent::AtlasBuilderComponent() - { - } - - // Handle deallocation of your memory allocated in Init() - AtlasBuilderComponent::~AtlasBuilderComponent() - { - } - - // Init is where you'll actually allocate memory or create objects - // This ensures that any dependency components will have been been created and serialized - void AtlasBuilderComponent::Init() - { - } - - // Activate is where you'd perform registration with other objects and systems. - // All builder classes owned by this component should be registered here - // Any EBuses for the builder classes should also be connected at this point - void AtlasBuilderComponent::Activate() - { - AssetBuilderSDK::AssetBuilderDesc builderDescriptor; - builderDescriptor.m_name = "Atlas Worker Builder"; - builderDescriptor.m_version = 1; - builderDescriptor.m_patterns.emplace_back(AssetBuilderSDK::AssetBuilderPattern("*.texatlas", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_busId = azrtti_typeid(); - builderDescriptor.m_createJobFunction = AZStd::bind(&AtlasBuilderWorker::CreateJobs, &m_atlasBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - builderDescriptor.m_processJobFunction = AZStd::bind(&AtlasBuilderWorker::ProcessJob, &m_atlasBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - - m_atlasBuilder.BusConnect(builderDescriptor.m_busId); - - AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor); - } - - // Disconnects from any EBuses we connected to in Activate() - // Unregisters from objects and systems we register with in Activate() - void AtlasBuilderComponent::Deactivate() - { - m_atlasBuilder.BusDisconnect(); - - // We don't need to unregister the builder - the AP will handle this for us, because it is managing the lifecycle of this component - } - - // Reflect the input and output formats for the serializer - void AtlasBuilderComponent::Reflect(AZ::ReflectContext* context) - { - // components also get Reflect called automatically - // this is your opportunity to perform static reflection or type registration of any types you want the serializer to know about - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0) - ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })) - ; - } - - AtlasBuilderInput::Reflect(context); - } - - void AtlasBuilderComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("Atlas Builder Plugin Service", 0x35974d0d)); - } - - void AtlasBuilderComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("Atlas Builder Plugin Service", 0x35974d0d)); - } - - void AtlasBuilderComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - AZ_UNUSED(required); - } - - void AtlasBuilderComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) - { - AZ_UNUSED(dependent); - } -} diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.h b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.h deleted file mode 100644 index eb8b85dfcf..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderComponent.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or - * its licensors. - * - * For complete copyright and license terms please see the LICENSE at the root of this - * distribution (the "License"). All use of this software is governed by the License, - * or, if provided, by the license below or the license accompanying this file. Do not - * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * - */ - -#pragma once - -#include -#include -#include "AtlasBuilderWorker.h" - -namespace TextureAtlasBuilder -{ - class AtlasBuilderComponent : public AZ::Component - { - public: - AZ_COMPONENT(AtlasBuilderComponent, "{F49987FB-3375-4417-AB83-97B44C78B335}"); - - AtlasBuilderComponent(); - ~AtlasBuilderComponent() override; - - void Init() override; - void Activate() override; - void Deactivate() override; - - //! Reflect formats for input and output - static void Reflect(AZ::ReflectContext* context); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - - private: - AtlasBuilderWorker m_atlasBuilder; - }; -} // namespace TextureAtlasBuilder diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.cpp b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.cpp deleted file mode 100644 index 95cc9b851f..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.cpp +++ /dev/null @@ -1,1494 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include "AtlasBuilderWorker.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include -#include -#include -#include - -namespace TextureAtlasBuilder -{ - //! Counts leading zeros - uint32 CountLeadingZeros32(uint32 x) - { - return x == 0 ? 32 : az_clz_u32(x); - } - - //! Integer log2 - uint32 IntegerLog2(uint32 x) - { - return 31 - CountLeadingZeros32(x); - } - - bool IsFolderPath(const AZStd::string& path) - { - bool hasExtension = AzFramework::StringFunc::Path::HasExtension(path.c_str()); - return !hasExtension; - } - - bool HasTrailingSlash(const AZStd::string& path) - { - size_t pathLength = path.size(); - return (pathLength > 0 && (path.at(pathLength - 1) == '/' || path.at(pathLength - 1) == '\\')); - } - - bool ResolveRelativePath(const AZStd::string& relativePath, const AZStd::string& watchDirectory, AZStd::string& resolvedFullPathOut) - { - // Get full path by appending the relative path to the watch directory - AZ::IO::FixedMaxPath resolvedPath; - AZ::IO::FileIOBase::GetInstance()->ReplaceAlias(resolvedPath, AZ::IO::PathView{relativePath}); - - resolvedPath = (AZ::IO::FixedMaxPath{watchDirectory} / resolvedPath).LexicallyNormal(); - resolvedFullPathOut = resolvedPath.String(); - - return true; - } - - bool GetAbsoluteSourcePathFromRelativePath(const AZStd::string& relativeSourcePath, AZStd::string& absoluteSourcePathOut) - { - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, relativeSourcePath.c_str(), info, watchFolder); - if (result) - { - absoluteSourcePathOut = AZStd::string::format("%s/%s", watchFolder.c_str(), info.m_relativePath.c_str()); - - // Normalize path - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, absoluteSourcePathOut); - } - return result; - } - - const ImageProcessing::PresetSettings* GetImageProcessPresetSettings(const AZStd::string& presetName, const AZStd::string& platformIdentifier) - { - // Get the specified presetId - AZ::Uuid presetId = ImageProcessing::BuilderSettingManager::Instance()->GetPresetIdFromName(presetName); - if (presetId.IsNull()) - { - AZ_Error("Texture Editor", false, "Texture Preset %s has no associated UUID.", presetName.c_str()); - return nullptr; - } - - // Get the preset settings for the platform this job is building for - const ImageProcessing::PresetSettings* presetSettings = ImageProcessing::BuilderSettingManager::Instance()->GetPreset( - presetId, platformIdentifier); - - return presetSettings; - } - - // Reflect the input parameters - void AtlasBuilderInput::Reflect(AZ::ReflectContext* context) - { - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(1) - ->Field("Force Square", &AtlasBuilderInput::m_forceSquare) - ->Field("Force Power of Two", &AtlasBuilderInput::m_forcePowerOf2) - ->Field("Include White Texture", &AtlasBuilderInput::m_includeWhiteTexture) - ->Field("Maximum Dimension", &AtlasBuilderInput::m_maxDimension) - ->Field("Padding", &AtlasBuilderInput::m_padding) - ->Field("UnusedColor", &AtlasBuilderInput::m_unusedColor) - ->Field("PresetName", &AtlasBuilderInput::m_presetName) - ->Field("Textures to Add", &AtlasBuilderInput::m_filePaths); - } - } - - // Supports a custom parser format - AtlasBuilderInput AtlasBuilderInput::ReadFromFile(const AZStd::string& path, const AZStd::string& directory, bool& valid) - { - // Open the file - AZ::IO::FileIOBase* input = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::HandleType handle; - input->Open(path.c_str(), AZ::IO::OpenMode::ModeRead, handle); - - // Read the file - AZ::u64 size; - input->Size(handle, size); - char* buffer = new char[size + 1]; - input->Read(handle, buffer, size); - buffer[size] = 0; - - // Close the file - input->Close(handle); - - // Prepare the output - AtlasBuilderInput data; - - // Parse the input into lines - AZStd::vector lines; - AzFramework::StringFunc::Tokenize(buffer, lines, "\n\t"); - delete[] buffer; - - // Parse the individual lines - for (auto line : lines) - { - line = AzFramework::StringFunc::TrimWhiteSpace(line, true, true); - // Check for comments and empty lines - if ((line.length() >= 2 && line[0] == '/' && line[1] == '/') || line.length() < 1) - { - continue; - } - else if (line.find('=') != -1) - { - AZStd::vector args; - AzFramework::StringFunc::Tokenize(line.c_str(), args, '=', true, true); - - if (args.size() > 2) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to parse line: Excessive '=' symbols were found: \"%s\"", line.c_str()).c_str()); - valid = false; - } - - // Trim whitespace - args[0] = AzFramework::StringFunc::TrimWhiteSpace(args[0], true, true); - args[1] = AzFramework::StringFunc::TrimWhiteSpace(args[1], true, true); - - // No case sensitivity for property names - AZStd::to_lower(args[0].begin(), args[0].end()); - - // Keep track of if the value is rejected - bool accepted = false; - - if (args[0] == "square") - { - accepted = AzFramework::StringFunc::LooksLikeBool(args[1].c_str()); - if (accepted) - { - data.m_forceSquare = AzFramework::StringFunc::ToBool(args[1].c_str()); - } - } - else if (args[0] == "poweroftwo") - { - accepted = AzFramework::StringFunc::LooksLikeBool(args[1].c_str()); - if (accepted) - { - data.m_forcePowerOf2 = AzFramework::StringFunc::ToBool(args[1].c_str()); - } - } - else if (args[0] == "whitetexture") - { - accepted = AzFramework::StringFunc::LooksLikeBool(args[1].c_str()); - if (accepted) - { - data.m_includeWhiteTexture = AzFramework::StringFunc::ToBool(args[1].c_str()); - } - } - else if (args[0] == "maxdimension") - { - accepted = AzFramework::StringFunc::LooksLikeInt(args[1].c_str()); - if (accepted) - { - data.m_maxDimension = AzFramework::StringFunc::ToInt(args[1].c_str()); - } - } - else if (args[0] == "padding") - { - accepted = AzFramework::StringFunc::LooksLikeInt(args[1].c_str()); - if (accepted) - { - data.m_padding = AzFramework::StringFunc::ToInt(args[1].c_str()); - } - } - else if (args[0] == "unusedcolor") - { - accepted = args[1].at(0) == '#' && args[1].length() == 9; - if (accepted) - { - AZStd::string color = AZStd::string::format("%s%s%s%s", args[1].substr(7).c_str(), args[1].substr(5, 2).c_str(), - args[1].substr(3, 2).c_str(), args[1].substr(1, 2).c_str()); - data.m_unusedColor.FromU32(AZStd::stoul(color, nullptr, 16)); - } - } - else if (args[0] == "presetname") - { - accepted = true; - data.m_presetName = args[1]; - } - else - { - // Supress accepted error because this error superceeds it - accepted = true; - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to parse line: Unrecognized property: \"%s\"", args[0].c_str()).c_str()); - } - - // If the property is recognized but the value is rejected, fail the job - if (!accepted) - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to parse line: Invalid value assigned to property: Property: \"%s\" Value: \"%s\"", args[0].c_str(), args[1].c_str()).c_str()); - } - } - else if ((line[0] == '-')) - { - // Remove image files - AZStd::string remove = line.substr(1); - remove = AzFramework::StringFunc::TrimWhiteSpace(remove, true, true); - if (remove.find('*') != -1) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(remove, directory, resolvedAbsolutePath); - if (resolved) - { - RemoveFilesUsingWildCard(data.m_filePaths, resolvedAbsolutePath); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", remove.c_str()).c_str()); - } - } - else if (IsFolderPath(remove)) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(remove, directory, resolvedAbsolutePath); - if (resolved) - { - RemoveFolderContents(data.m_filePaths, resolvedAbsolutePath); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", remove.c_str()).c_str()); - } - } - else - { - // Get the full path to the source image from the relative source path - AZStd::string fullSourceAssetPathName; - bool fullPathFound = GetAbsoluteSourcePathFromRelativePath(remove, fullSourceAssetPathName); - - if (!fullPathFound) - { - // Try to resolve relative path as it might be using "./" or "../" - fullPathFound = ResolveRelativePath(remove, directory, fullSourceAssetPathName); - } - - if (fullPathFound) - { - for (size_t i = 0; i < data.m_filePaths.size(); ++i) - { - if (data.m_filePaths[i] == fullSourceAssetPathName) - { - data.m_filePaths.erase(data.m_filePaths.begin() + i); - } - } - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to get source asset path for image: %s", remove.c_str()).c_str()); - } - } - } - else - { - // Add image files - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, line); - bool duplicate = false; - if (line.find('*') != -1) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(line, directory, resolvedAbsolutePath); - if (resolved) - { - AddFilesUsingWildCard(data.m_filePaths, resolvedAbsolutePath); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", line.c_str()).c_str()); - } - } - else if (IsFolderPath(line)) - { - AZStd::string resolvedAbsolutePath; - bool resolved = ResolveRelativePath(line, directory, resolvedAbsolutePath); - if (resolved) - { - AddFolderContents(data.m_filePaths, resolvedAbsolutePath, valid); - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to resolve relative path: %s", line.c_str()).c_str()); - } - } - else - { - // Get the full path to the source image from the relative source path - AZStd::string fullSourceAssetPathName; - bool fullPathFound = GetAbsoluteSourcePathFromRelativePath(line, fullSourceAssetPathName); - - if (!fullPathFound) - { - // Try to resolve relative path as it might be using "./" or "../" - fullPathFound = ResolveRelativePath(line, directory, fullSourceAssetPathName); - } - - if (fullPathFound) - { - // Prevent duplicates - for (size_t i = 0; i < data.m_filePaths.size() && !duplicate; ++i) - { - duplicate = data.m_filePaths[i] == fullSourceAssetPathName; - } - if (!duplicate) - { - data.m_filePaths.push_back(fullSourceAssetPathName); - } - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to get source asset path for image: %s", line.c_str()).c_str()); - } - } - } - } - - return data; - } - - void AtlasBuilderInput::AddFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& insert) - { - AZ::IO::PathView fullPathView(insert); - - // Find first path element with a wild card in it - AZ::IO::Path staticPath; - auto wildCardPathElementIter = fullPathView.begin(); - for (; wildCardPathElementIter != fullPathView.end(); ++wildCardPathElementIter) - { - if (wildCardPathElementIter->Native().contains('*')) - { - break; - } - staticPath /= *wildCardPathElementIter; - } - - // The remaining path segments are part of the wild card path - - AZStd::vector candidates{ AZStd::move(staticPath) }; - for(; wildCardPathElementIter != fullPathView.end() && !candidates.empty(); ++wildCardPathElementIter) - { - AZStd::vector nextCandidates; - for (const AZ::IO::Path& candidate : candidates) - { - if (QDir inputFolder(QString::fromUtf8(candidate.c_str(), aznumeric_cast(candidate.Native().size()))); - inputFolder.exists()) - { - QFileInfoList entries = inputFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files); - for (const QFileInfo& entry : entries) - { - AZ::IO::Path filenameEntry(entry.fileName().toUtf8().data()); - if (filenameEntry.Match(wildCardPathElementIter->Native())) - { - nextCandidates.push_back(entry.filePath().toUtf8().data()); - } - } - } - } - candidates = nextCandidates; - } - - for (const AZ::IO::Path& candidate : candidates) - { - QFileInfo fileInfo(QString::fromUtf8(candidate.c_str(), aznumeric_cast(candidate.Native().size()))); - if (fileInfo.isFile()) - { - AZStd::string ext = fileInfo.suffix().toUtf8().data(); - if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds") - { - auto FindExistingPath = [&candidate](const AZStd::string& path) - { - return candidate == AZ::IO::PathView(path); - }; - if (auto foundIt = AZStd::find_if(paths.begin(), paths.end(), FindExistingPath); - foundIt == paths.end()) - { - AZStd::string normalizedPath = AZ::IO::Path(candidate.Native(), AZ::IO::PosixPathSeparator).LexicallyNormal().Native(); - paths.push_back(AZStd::move(normalizedPath)); - } - } - } - else if (fileInfo.isDir()) - { - bool waste = true; - AddFolderContents(paths, candidate.Native(), waste); - } - } - } - - void AtlasBuilderInput::RemoveFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& remove) - { - auto RemoveWildCardPath = [&remove](const AZStd::string& subPath) - { - return AZ::IO::PathView(subPath).Match(remove); - }; - AZStd::erase_if(paths, RemoveWildCardPath); - } - - // Replaces all folder paths with the files they contain - void AtlasBuilderInput::AddFolderContents(AZStd::vector& paths, const AZStd::string& insert, bool& valid) - { - if (QDir inputFolder(insert.c_str()); inputFolder.exists()) - { - QFileInfoList entries = inputFolder.entryInfoList(QDir::Dirs | QDir::NoDotAndDotDot | QDir::Files); - for (const QFileInfo& entry : entries) - { - AZ::IO::Path child = entry.filePath().toUtf8().data(); - AZStd::string ext = entry.suffix().toUtf8().data(); - const bool isDir = entry.isDir(); - if (isDir) - { - AddFolderContents(paths, child.Native(), valid); - } - else if (ImageProcessing::IsExtensionSupported(ext.c_str()) && ext != "dds") - { - auto FindExistingPath = [&child](const AZStd::string& path) - { - return child == AZ::IO::PathView(path); - }; - if (auto foundIter = AZStd::find_if(paths.begin(), paths.end(), FindExistingPath); - foundIter == paths.end()) - { - // Normalize the path to have posix slashes - AZStd::string normalizedPath = AZ::IO::Path(child.Native(), AZ::IO::PosixPathSeparator).LexicallyNormal().Native(); - paths.push_back(AZStd::move(normalizedPath)); - } - } - } - } - else - { - valid = false; - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to find requested directory: %s", insert.c_str()).c_str()); - } - } - - // Removes all of the contents of a folder - void AtlasBuilderInput::RemoveFolderContents(AZStd::vector& paths, const AZStd::string& remove) - { - auto RemoveSubPath = [folder = AZ::IO::PathView(remove)](const AZStd::string& subPath) - { - return AZ::IO::PathView(subPath).IsRelativeTo(folder); - }; - AZStd::erase_if(paths, RemoveSubPath); - } - - // Note - Shutdown will be called on a different thread than your process job thread - void AtlasBuilderWorker::ShutDown() { m_isShuttingDown = true; } - - void AtlasBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, - AssetBuilderSDK::CreateJobsResponse& response) - { - // Read in settings/filepaths to set dependencies - AZStd::string fullPath; - AzFramework::StringFunc::Path::Join( - request.m_watchFolder.c_str(), request.m_sourceFile.c_str(), fullPath, true, true); - // Check if input is valid - bool valid = true; - AtlasBuilderInput input = AtlasBuilderInput::ReadFromFile(fullPath, request.m_watchFolder, valid); - - // Set dependencies - for (int i = 0; i < input.m_filePaths.size(); ++i) - { - AssetBuilderSDK::SourceFileDependency dependency; - dependency.m_sourceFileDependencyPath = input.m_filePaths[i].c_str(); - response.m_sourceFileDependencyList.push_back(dependency); - } - - // We process the same file for all platforms - for (const AssetBuilderSDK::PlatformInfo& info : request.m_enabledPlatforms) - { - if (ImageProcessing::BuilderSettingManager::Instance()->DoesSupportPlatform(info.m_identifier)) - { - AssetBuilderSDK::JobDescriptor descriptor = GetJobDescriptor(request.m_sourceFile, input); - descriptor.SetPlatformIdentifier(info.m_identifier.c_str()); - response.m_createJobOutputs.push_back(descriptor); - } - } - - if (valid) - { - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; - } - - return; - } - - AssetBuilderSDK::JobDescriptor AtlasBuilderWorker::GetJobDescriptor(const AZStd::string& sourceFile, const AtlasBuilderInput& input) - { - // Get the extension of the file - AZStd::string ext; - AzFramework::StringFunc::Path::GetExtension(sourceFile.c_str(), ext, false); - AZStd::to_upper(ext.begin(), ext.end()); - - AssetBuilderSDK::JobDescriptor descriptor; - descriptor.m_jobKey = ext + " Atlas"; - descriptor.m_critical = false; - descriptor.m_jobParameters[AZ_CRC("forceSquare")] = input.m_forceSquare ? "true" : "false"; - descriptor.m_jobParameters[AZ_CRC("forcePowerOf2")] = input.m_forcePowerOf2 ? "true" : "false"; - descriptor.m_jobParameters[AZ_CRC("includeWhiteTexture")] = input.m_includeWhiteTexture ? "true" : "false"; - descriptor.m_jobParameters[AZ_CRC("padding")] = AZStd::to_string(input.m_padding); - descriptor.m_jobParameters[AZ_CRC("maxDimension")] = AZStd::to_string(input.m_maxDimension); - descriptor.m_jobParameters[AZ_CRC("filePaths")] = AZStd::to_string(input.m_filePaths.size()); - - AZ::u32 col = input.m_unusedColor.ToU32(); - descriptor.m_jobParameters[AZ_CRC("unusedColor")] = AZStd::to_string(*reinterpret_cast(&col)); - descriptor.m_jobParameters[AZ_CRC("presetName")] = input.m_presetName; - - // The starting point for the list - const int start = static_cast(descriptor.m_jobParameters.size()) + 1; - descriptor.m_jobParameters[AZ_CRC("startPoint")] = AZStd::to_string(start); - - for (int i = 0; i < input.m_filePaths.size(); ++i) - { - descriptor.m_jobParameters[start + i] = input.m_filePaths[i]; - } - - return descriptor; - } - - void AtlasBuilderWorker::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, - AssetBuilderSDK::ProcessJobResponse& response) - { - // Before we begin, let's make sure we are not meant to abort. - AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId); - - AZStd::vector productFilepaths; - - const AZStd::string path = request.m_fullPath; - - bool imageProcessingSuccessful = false; - - // read in settings/filepaths - AtlasBuilderInput input; - input.m_forceSquare = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("forceSquare"))->second.c_str()); - input.m_forcePowerOf2 = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("forcePowerOf2"))->second.c_str()); - input.m_includeWhiteTexture = AzFramework::StringFunc::ToBool(request.m_jobDescription.m_jobParameters.find(AZ_CRC("includeWhiteTexture"))->second.c_str()); - input.m_padding = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("padding"))->second.c_str()); - input.m_maxDimension = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("maxDimension"))->second.c_str()); - int startAsInt = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("startPoint"))->second.c_str()); - int sizeAsInt = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("filePaths"))->second.c_str()); - AZ::u32 start = static_cast(AZStd::max(0, startAsInt)); - AZ::u32 size = static_cast(AZStd::max(0, sizeAsInt)); - - int col = AzFramework::StringFunc::ToInt(request.m_jobDescription.m_jobParameters.find(AZ_CRC("unusedColor"))->second.c_str()); - input.m_unusedColor.FromU32(*reinterpret_cast(&col)); - - input.m_presetName = request.m_jobDescription.m_jobParameters.find(AZ_CRC("presetName"))->second; - - for (AZ::u32 i = 0; i < size; ++i) - { - input.m_filePaths.push_back(request.m_jobDescription.m_jobParameters.find(start + i)->second); - } - - if (input.m_filePaths.empty()) - { - AZ_Error("AtlasBuilder", false, "No image files specified. Cannot create an empty atlas."); - return; - } - - // Don't allow padding to be less than zero - if (input.m_padding < 0) - { - input.m_padding = 0; - } - - if (input.m_presetName.empty()) - { - // Default to the TextureAtlas preset which is currently set to use compression for all platforms except for iOS. - // Currently the only fully supported compression for iOS is PVRTC which requires the texture to be square and a power of 2. - // Due to this limitation, we default to using no compression for iOS until ASTC is fully supported - const AZStd::string defaultPresetName = "TextureAtlas"; - input.m_presetName = defaultPresetName; - } - - // Get a preset to use for the output image - const ImageProcessing::PresetSettings* preset = GetImageProcessPresetSettings(input.m_presetName, request.m_platformInfo.m_identifier); - if (preset) - { - // Check the preset's pixel format requirements - const ImageProcessing::PixelFormatInfo* pixelFormatInfo = ImageProcessing::CPixelFormats::GetInstance().GetPixelFormatInfo(preset->m_pixelFormat); - if (pixelFormatInfo && pixelFormatInfo->bSquarePow2) - { - // Override the user config settings to force square and power of 2. - // Otherwise the image conversion process will stretch the image to satisfy these requirements - input.m_forceSquare = true; - input.m_forcePowerOf2 = true; - } - } - else - { - AZ_Error("AtlasBuilder", false, "Could not find a preset setting for the output image."); - return; - } - - // Read in images - AZStd::vector images; - AZ::u64 totalArea = 0; - int maxArea = input.m_maxDimension * input.m_maxDimension; - bool sizeFailure = false; - for (int i = 0; i < input.m_filePaths.size() && !jobCancelListener.IsCancelled(); ++i) - { - ImageProcessing::IImageObject* inputImage = ImageProcessing::LoadImageFromFile(input.m_filePaths[i]); - // Check if we were able to load the image - if (inputImage) - { - ImageProcessing::IImageObjectPtr image = ImageProcessing::IImageObjectPtr(inputImage); - images.push_back(image); - totalArea += inputImage->GetWidth(0) * inputImage->GetHeight(0); - } - else - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to load file: %s", input.m_filePaths[i].c_str()).c_str()); - return; - } - if (maxArea < totalArea) - { - sizeFailure = true; - } - } - // If we get cancelled, return - if (jobCancelListener.IsCancelled()) - { - return; - } - - if (sizeFailure) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Total image area exceeds maximum alotted area. %llu > %d", totalArea, maxArea).c_str()); - return; - } - - // Convert all image paths to their output format referenced at runtime - for (auto& filePath : input.m_filePaths) - { - // Get path relative to the watch folder - bool result = false; - AZ::Data::AssetInfo info; - AZStd::string watchFolder; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(result, &AzToolsFramework::AssetSystemRequestBus::Events::GetSourceInfoBySourcePath, filePath.c_str(), info, watchFolder); - if (!result) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Atlas Builder unable to get relative source path for image: %s", filePath.c_str()).c_str()); - return; - } - - // Remove extension - filePath = info.m_relativePath.substr(0, info.m_relativePath.find_last_of('.')); - - // Normalize path - AzFramework::ApplicationRequests::Bus::Broadcast(&AzFramework::ApplicationRequests::NormalizePathKeepCase, filePath); - } - - // Add white texture if we need to - if (input.m_includeWhiteTexture) - { - ImageProcessing::IImageObjectPtr texture(ImageProcessing::IImageObject::CreateImage( - cellSize, cellSize, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8)); - - // Make the texture white - texture->ClearColor(1, 1, 1, 1); - images.push_back(texture); - input.m_filePaths.push_back("WhiteTexture"); - } - - // Generate algorithm inputs - ImageDimensionData data; - for (int i = 0; i < images.size(); ++i) - { - data.push_back(IndexImageDimension(i, - ImageDimension(images[i]->GetWidth(0), - images[i]->GetHeight(0)))); - } - AZStd::sort(data.begin(), data.end()); - - // Run algorithm - - // Variables that keep track of the optimal solution - int resultWidth = -1; - int resultHeight = -1; - - // Check that the max dimension is not large enough for the area to loop past the maximum integer - // This is important because we do not want the area to be calculated negative - if (input.m_maxDimension > 65535) - { - input.m_maxDimension = 65535; - } - - // Get the optimal mappings based on the input settings - AZStd::vector paddedMap; - size_t amountFit = 0; - if (!TryTightening( - input, data, GetWidest(data), GetTallest(data), aznumeric_cast(totalArea), input.m_padding, resultWidth, resultHeight, amountFit, paddedMap)) - { - AZ_Error("AtlasBuilder", false, AZStd::string::format("Cannot fit images into given maximum atlas size (%dx%d). Only %zu out of %zu images fit.", input.m_maxDimension, input.m_maxDimension, amountFit, input.m_filePaths.size()).c_str()); - // For some reason, failing the assert isn't enough to stop the Asset builder. It will still fail further - // down when it tries to assemble the atlas, but returning here is cleaner. - return; - } - - // Move coordinates from algorithm space to padded result space - TextureAtlasNamespace::AtlasCoordinateSets output; - resultWidth = 0; - resultHeight = 0; - AZStd::vector map; - for (int i = 0; i < paddedMap.size(); ++i) - { - map.push_back(AtlasCoordinates(paddedMap[i].GetLeft(), paddedMap[i].GetLeft() + images[data[i].first]->GetWidth(0), paddedMap[i].GetTop(), paddedMap[i].GetTop() + images[data[i].first]->GetHeight(0))); - resultHeight = resultHeight > map[i].GetBottom() ? resultHeight : map[i].GetBottom(); - resultWidth = resultWidth > map[i].GetRight() ? resultWidth : map[i].GetRight(); - - const AZStd::string& outputFilePath = input.m_filePaths[data[i].first]; - output.push_back(AZStd::pair(outputFilePath, map[i])); - } - if (input.m_forcePowerOf2) - { - resultWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultWidth - 1)))); - resultHeight = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(resultHeight - 1)))); - } - else - { - resultWidth = (resultWidth + (cellSize - 1)) / cellSize * cellSize; - resultHeight = (resultHeight + (cellSize - 1)) / cellSize * cellSize; - } - if (input.m_forceSquare) - { - if (resultWidth > resultHeight) - { - resultHeight = resultWidth; - } - else - { - resultWidth = resultHeight; - } - } - - // Process texture sheet - ImageProcessing::IImageObjectPtr outImage(ImageProcessing::IImageObject::CreateImage( - resultWidth, resultHeight, 1, ImageProcessing::EPixelFormat::ePixelFormat_R8G8B8A8)); - - // Clear the sheet - outImage->ClearColor(input.m_unusedColor.GetR(), input.m_unusedColor.GetG(), input.m_unusedColor.GetB(), input.m_unusedColor.GetA()); - - AZ::u8* outBuffer = nullptr; - AZ::u32 outPitch; - outImage->GetImagePointer(0, outBuffer, outPitch); - - // Copy images over - for (int i = 0; i < map.size() && !jobCancelListener.IsCancelled(); ++i) - { - AZ::u8* inBuffer = nullptr; - AZ::u32 inPitch; - images[data[i].first]->GetImagePointer(0, inBuffer, inPitch); - int j = 0; - - // The padding calculated here is the amount of excess horizontal space measured in bytes that are in each - // row of the destination space AFTER the placement of the source row. - int rightPadding = (paddedMap[i].GetRight() - map[i].GetRight() - input.m_padding); - if (map[i].GetRight() + rightPadding > resultWidth) - { - rightPadding = resultWidth - map[i].GetRight(); - } - rightPadding *= bytesPerPixel; - int bottomPadding = (paddedMap[i].GetBottom() - map[i].GetBottom() - input.m_padding); - if (map[i].GetBottom() + bottomPadding > resultHeight) - { - bottomPadding = resultHeight - map[i].GetBottom(); - } - - int leftPadding = 0; - if (map[i].GetLeft() - input.m_padding >= 0) - { - leftPadding = input.m_padding * bytesPerPixel; - } - - int topPadding = 0; - if (map[i].GetTop() - input.m_padding >= 0) - { - topPadding = input.m_padding; - } - - for (j = 0; j < map[i].GetHeight(); ++j) - { - // When we multiply `map[i].GetLeft()` by 4, we are changing the measure from atlas space, to byte array - // space. The number is 4 because in this format, each pixel is 4 bytes long. - memcpy(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel), - inBuffer + inPitch * j, - inPitch); - // Fill in the last bit of the row in the destination space with the same colors - SetPixels(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) + inPitch, - outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) + inPitch - bytesPerPixel, - rightPadding); - // Fill in the first bit of the row in the destination space with the same colors - SetPixels(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel), - leftPadding); - } - // Fill in the last few rows of the buffer with the same colors - for (; j < map[i].GetHeight() + bottomPadding; ++j) - { - memcpy(outBuffer + (map[i].GetTop() + j) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - outBuffer + (map[i].GetBottom() - 1) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - inPitch + leftPadding + rightPadding); - } - for (j = 1; j <= topPadding; ++j) - { - memcpy(outBuffer + (map[i].GetTop() - j) * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - outBuffer + map[i].GetTop() * outPitch + (map[i].GetLeft() * bytesPerPixel) - leftPadding, - inPitch + rightPadding + leftPadding); - } - } - - // If we get cancelled, return - if (jobCancelListener.IsCancelled()) - { - return; - } - - // Output Atlas Coordinates - AZStd::string fileName; - AZStd::string outputPath; - AzFramework::StringFunc::Path::GetFullFileName(request.m_sourceFile.c_str(), fileName); - fileName = fileName.append("idx"); - AzFramework::StringFunc::Path::Join( - request.m_tempDirPath.c_str(), fileName.c_str(), outputPath, true, true); - - // Output texture sheet - AZStd::string imageFileName, imageOutputPath; - AzFramework::StringFunc::Path::GetFileName(request.m_sourceFile.c_str(), imageFileName); - imageFileName += ".dds"; - AzFramework::StringFunc::Path::Join( - request.m_tempDirPath.c_str(), imageFileName.c_str(), imageOutputPath, true, true); - - // Let the ImageProcessor do the rest of the work. - ImageProcessing::TextureSettings textureSettings; - textureSettings.m_preset = preset->m_uuid; - - // Mipmaps for the texture atlas would require more work than the Image Processor does. This is because if we - // let the Image Processor make mipmaps, it might bleed the textures in the atlas together. - textureSettings.m_enableMipmap = false; - - // Check if the ImageBuilder wants to enable streaming - bool isStreaming = ImageProcessing::BuilderSettingManager::Instance() - ->GetBuilderSetting(request.m_platformInfo.m_identifier) - ->m_enableStreaming; - - bool canOverridePreset = false; - ImageProcessing::ImageConvertProcess* process = - new ImageProcessing::ImageConvertProcess(outImage, - textureSettings, - *preset, - false, - isStreaming, - canOverridePreset, - imageOutputPath, - request.m_platformInfo.m_identifier); - - if (process != nullptr) - { - // the process can be stopped if the job is cancelled or the worker is shutting down - while (!process->IsFinished() && !m_isShuttingDown && !jobCancelListener.IsCancelled()) - { - process->UpdateProcess(); - } - - // get process result - imageProcessingSuccessful = process->IsSucceed(); - process->GetAppendOutputFilePaths(productFilepaths); - - delete process; - } - else - { - imageProcessingSuccessful = false; - } - - if (imageProcessingSuccessful) - { - TextureAtlasNamespace::TextureAtlasRequestBus::Broadcast( - &TextureAtlasNamespace::TextureAtlasRequests::SaveAtlasToFile, outputPath, output, resultWidth, resultHeight); - response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(outputPath)); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_productAssetType = azrtti_typeid(); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_productSubID = 0; - - // The Image Processing Gem can produce multiple output files under certain - // circumstances, but the texture atlas is not expected to produce such output - if (productFilepaths.size() > 1) - { - AZ_Error("AtlasBuilder", false, "Image processing resulted in multiple output files. Texture atlas is expected to produce one output."); - response.m_outputProducts.clear(); - return; - } - - if (productFilepaths.size() > 0) - { - response.m_outputProducts.push_back(AssetBuilderSDK::JobProduct(productFilepaths[0])); - response.m_outputProducts.back().m_productAssetType = azrtti_typeid(); - response.m_outputProducts.back().m_productSubID = 1; - - // The texatlasidx file is a data file that indicates where the original parts are inside the atlas, - // and this would usually imply that it refers to its dds file in some way or needs it to function. - // The texatlasidx file should be the one that depends on the DDS because its possible to use the DDS - // without the texatlasid, but not the other way around - AZ::Data::AssetId productAssetId(request.m_sourceFileUUID, response.m_outputProducts.back().m_productSubID); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependencies.push_back(AssetBuilderSDK::ProductDependency(productAssetId, 0)); - response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependenciesHandled = true; // We've populated the dependencies immediately above so it's OK to tell the AP we've handled dependencies - } - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; - } - } - - bool AtlasBuilderWorker::TryPack(const ImageDimensionData& images, - int targetWidth, - int targetHeight, - int padding, - size_t& amountFit, - AZStd::vector& out) - { - // Start with one open slot and initialize a vector to store the closed products - AZStd::vector open; - AZStd::vector closed; - open.push_back(AtlasCoordinates(0, targetWidth, 0, targetHeight)); - bool slotNotFound = false; - for (size_t i = 0; i < images.size() && !slotNotFound; ++i) - { - slotNotFound = true; - // Try to place the image in every open slot - for (size_t j = 0; j < open.size(); ++j) - { - if (CanInsert(open[j], images[i].second, padding, targetWidth, targetHeight)) - { - // if it fits, subdivide the excess space in the slot, add it back to the open list and place the - // filled space into the closed vector - slotNotFound = false; - AtlasCoordinates spent(open[j].GetLeft(), - open[j].GetLeft() + images[i].second.m_width, - open[j].GetTop(), - open[j].GetTop() + images[i].second.m_height); - - // We are going to try pushing the object up / left to try to avoid creating tight open spaces. - bool needTrim = false; - AtlasCoordinates coords = spent; - // Modifying left will preserve width - coords.SetLeft(coords.GetLeft() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - while (spent.GetLeft() > 0 && !Collides(coords, closed)) - { - spent.SetLeft(coords.GetLeft()); - coords = spent; - coords.SetLeft(coords.GetLeft() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - needTrim = true; - } - // Refocus the search to see if we can push up - coords = spent; - coords.SetTop(coords.GetTop() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - while (spent.GetTop() > 0 && !Collides(coords, closed)) - { - spent.SetTop(coords.GetTop()); - coords = spent; - coords.SetTop(coords.GetTop() - 1); - AddPadding(coords, padding, targetWidth, targetHeight); - needTrim = true; - } - AddPadding(spent, padding, targetWidth, targetHeight); - if (needTrim) - { - TrimOverlap(open, spent); - closed.push_back(spent); - break; - } - AtlasCoordinates bigCoords; - AtlasCoordinates smallCoords; - - // Create the largest possible subdivision and another subdivision that uses the left over space - if (open[j].GetBottom() - spent.GetBottom() < open[j].GetRight() - spent.GetRight()) - { - smallCoords = AtlasCoordinates( - open[j].GetLeft(), spent.GetRight(), spent.GetBottom(), open[j].GetBottom()); - bigCoords = AtlasCoordinates(spent.GetRight(), open[j].GetRight(), open[j].GetTop(), smallCoords.GetBottom()); - } - else - { - bigCoords = AtlasCoordinates( - open[j].GetLeft(), open[j].GetRight(), spent.GetBottom(), open[j].GetBottom()); - smallCoords = AtlasCoordinates(spent.GetRight(), open[j].GetRight(), open[j].GetTop(), bigCoords.GetTop()); - } - - open.erase(open.begin() + j, open.begin() + j + 1); - if (bigCoords.GetHeight() > 0 && bigCoords.GetHeight() > 0) - { - InsertInOrder(open, bigCoords); - } - if (smallCoords.GetHeight() > 0 && smallCoords.GetHeight() > 0) - { - InsertInOrder(open, smallCoords); - } - - closed.push_back(spent); - break; - } - } - if (slotNotFound) - { - // If no single open slot can fit the object, do one last check to see if we can fit it in at any open - // corner. The reason we perform this check is in case the object can be fit across multiple different - // open spaces. If there is a space that an object can be fit in, it will probably involve the top left - // corner of that object in the top left corner of an open slot. This may miss some odd fits, but due to - // the nature of the packing algorithm, such solutions are highly unlikely to exist. If we wanted to - // expand the algorithm, we could theoretically base it on edges instead of corners to find all results, - // but it would not be time efficient. - for (size_t j = 0; j < open.size(); ++j) - { - AtlasCoordinates insert = AtlasCoordinates(open[j].GetLeft(), - open[j].GetLeft() + images[i].second.m_width, - open[j].GetTop(), - open[j].GetTop() + images[i].second.m_height); - AddPadding(insert, padding, targetWidth, targetHeight); - if (insert.GetRight() <= targetWidth && insert.GetBottom() <= targetHeight) - { - bool collision = Collides(insert, closed); - if (!collision) - { - closed.push_back(insert); - // Trim overlapping open slots - TrimOverlap(open, insert); - slotNotFound = false; - break; - } - } - } - } - } - // If we succeeded, update the output - if (!slotNotFound) - { - out = closed; - } - amountFit = amountFit > closed.size() ? amountFit : closed.size(); - return !slotNotFound; - } - - // Modifies slotList so that no items in slotList overlap with item - void AtlasBuilderWorker::TrimOverlap(AZStd::vector& slotList, AtlasCoordinates item) - { - for (size_t i = 0; i < slotList.size(); ++i) - { - if (Collides(slotList[i], item)) - { - // Subdivide the overlapping slot to seperate overlapping and non overlapping portions - AtlasCoordinates overlap = GetOverlap(item, slotList[i]); - AZStd::vector excess; - excess.push_back(AtlasCoordinates( - slotList[i].GetLeft(), overlap.GetRight(), slotList[i].GetTop(), overlap.GetTop())); - excess.push_back(AtlasCoordinates( - slotList[i].GetLeft(), overlap.GetLeft(), overlap.GetTop(), slotList[i].GetBottom())); - excess.push_back(AtlasCoordinates( - overlap.GetRight(), slotList[i].GetRight(), slotList[i].GetTop(), overlap.GetBottom())); - excess.push_back(AtlasCoordinates( - overlap.GetLeft(), slotList[i].GetRight(), overlap.GetBottom(), slotList[i].GetBottom())); - slotList.erase(slotList.begin() + i); - for (size_t j = 0; j < excess.size(); ++j) - { - if (excess[j].GetWidth() > 0 && excess[j].GetHeight() > 0) - { - InsertInOrder(slotList, excess[j]); - } - } - --i; - } - } - } - - // This function interprets input and performs the proper tightening option - bool AtlasBuilderWorker::TryTightening(AtlasBuilderInput input, - const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int targetArea, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out) - { - if (input.m_forceSquare) - { - return TryTighteningSquare(images, - smallestWidth > smallestHeight ? smallestWidth : smallestHeight, - input.m_maxDimension, - targetArea, - input.m_forcePowerOf2, - padding, - resultWidth, - resultHeight, - amountFit, - out); - } - else - { - return TryTighteningOptimal(images, - smallestWidth, - smallestHeight, - input.m_maxDimension, - targetArea, - input.m_forcePowerOf2, - padding, - resultWidth, - resultHeight, - amountFit, - out); - } - } - - // Finds the optimal square solution by starting with the ideal solution and expanding the size of the space until everything fits - bool AtlasBuilderWorker::TryTighteningSquare(const ImageDimensionData& images, - int lowerBound, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out) - { - // Square solution cannot be smaller than the target area - int dimension = aznumeric_cast(sqrt(static_cast(targetArea))); - // Solution cannot be smaller than the smallest side - dimension = dimension > lowerBound ? dimension : lowerBound; - if (powerOfTwo) - { - // Starting dimension needs to be rounded up to the nearest power of two - dimension = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(dimension - 1)))); - } - - AZStd::vector track; - // Expand the square until the contents fit - while (!TryPack(images, dimension, dimension, padding, amountFit, track) && dimension <= maxDimension) - { - // Step to the next valid value - dimension = powerOfTwo ? dimension * 2 : dimension + cellSize; - } - // Make sure we found a solution - if (dimension > maxDimension) - { - return false; - } - - resultHeight = dimension; - resultWidth = dimension; - out = track; - return true; - } - - // Finds the optimal solution by starting with a somewhat optimal solution and searching for better solutions - bool AtlasBuilderWorker::TryTighteningOptimal(const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out) - { - AZStd::vector track; - - // round max dimension down to a multiple of cellSize - AZ::u32 maxDimensionRounded = maxDimension - (maxDimension % cellSize); - - // The starting width is the larger of the widest individual texture and the width required - // to fit the total texture area given the max dimension - AZ::u32 smallestWidthDueToArea = targetArea / maxDimensionRounded; - AZ::u32 minWidth = AZStd::max(static_cast(smallestWidth), smallestWidthDueToArea); - - if (powerOfTwo) - { - // Starting dimension needs to be rounded up to the nearest power of two - minWidth = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(minWidth - 1)))); - } - - // Round min width up to the nearest compression unit - minWidth = (minWidth + (cellSize - 1)) / cellSize * cellSize; - - AZ::u32 height = 0; - // Finds the optimal thin solution - // This uses a standard binary search to find the smallest width that can pack everything - AZ::u32 lower = minWidth; - AZ::u32 upper = maxDimensionRounded; - AZ::u32 width = 0; - while (lower <= upper) - { - AZ::u32 testWidth = (lower + upper) / 2; // must be divisible by cellSize because lower and upper are - bool canPack = TryPack(images, testWidth, maxDimension, padding, amountFit, track); - if (canPack) - { - // it packed, continue looking for smaller widths that pack - width = testWidth; // best fit so far - upper = testWidth - cellSize; - } - else - { - // it failed to pack, don't try any widths smaller than this - lower = testWidth + cellSize; - } - } - // Make sure we found a solution - if (width == 0) - { - return false; - } - - // Find the height of the solution - for (int i = 0; i < track.size(); ++i) - { - uint32 bottom = static_cast(AZStd::max(0, track[i].GetBottom())); - if (height < bottom) - { - height = bottom; - } - } - - // Fix height for power of two when applicable - if (powerOfTwo) - { - // Starting dimensions need to be rounded up to the nearest power of two - height = aznumeric_cast(pow(2, 1 + IntegerLog2(static_cast(height - 1)))); - } - - AZ::u32 resultArea = height * width; - // This for loop starts with the optimal thin width and makes it wider at each step. For each width, it - // calculates what height would be neccesary to have a more optimal solution than the stored solution. If the - // more optimal solution is valid, it tries shrinking the height until the solution fails. The loop ends when it - // is determined that a valid solution cannot exist at further steps - for (AZ::u32 testWidth = width; testWidth <= maxDimensionRounded && resultArea / testWidth >= static_cast(smallestHeight); - testWidth = powerOfTwo ? testWidth * 2 : testWidth + cellSize) - { - // The area of test height and width should be equal or less than resultArea - // Note: We don't need to force powers of two here because the Area and the width are already powers of two - int testHeight = resultArea / testWidth * cellSize / cellSize; - // Try the tighter pack - while (TryPack(images, static_cast(testWidth), testHeight, padding, amountFit, track)) - { - // Loop and continue to shrink the height until you cannot do so any further - width = testWidth; - height = testHeight; - resultArea = height * width; - // Try to step down a level - testHeight = powerOfTwo ? testHeight / 2 : testHeight - cellSize; - } - } - // Output the results of the function - out = track; - resultHeight = height; - resultWidth = width; - return true; - } - - // Allows us to keep the list of open spaces in order from lowest to highest area - void AtlasBuilderWorker::InsertInOrder(AZStd::vector& slotList, AtlasCoordinates item) - { - int area = item.GetWidth() * item.GetHeight(); - for (size_t i = 0; i < slotList.size(); ++i) - { - if (area < slotList[i].GetWidth() * slotList[i].GetHeight()) - { - slotList.insert(slotList.begin() + i, item); - return; - } - } - slotList.push_back(item); - } - - // Defines priority so that sorting can be meaningful. It may seem odd that larger items are "less than" smaller - // ones, but as this is a deduction of priority, not value, it is correct. - static bool operator<(ImageDimension a, ImageDimension b) - { - // Prioritize first by longest size - if ((a.m_width > a.m_height ? a.m_width : a.m_height) != (b.m_width > b.m_height ? b.m_width : b.m_height)) - { - return (a.m_width > a.m_height ? a.m_width : a.m_height) > (b.m_width > b.m_height ? b.m_width : b.m_height); - } - // Prioritize second by the length of the smaller side - if (a.m_width * a.m_height != b.m_width * b.m_height) - { - return a.m_width * a.m_height > b.m_width * b.m_height; - } - // Prioritize wider objects over taller objects for objects of the same size - else - { - return a.m_width > b.m_width; - } - } - - // Exposes priority logic to the sorting algorithm - static bool operator<(IndexImageDimension a, IndexImageDimension b) { return a.second < b.second; } - - // Tests if two coordinate sets intersect - bool Collides(AtlasCoordinates a, AtlasCoordinates b) - { - return !((a.GetRight() <= b.GetLeft()) || (a.GetBottom() <= b.GetTop()) || (b.GetRight() <= a.GetLeft()) - || (b.GetBottom() <= a.GetTop())); - } - - // Tests if an item collides with any items in a list - bool Collides(AtlasCoordinates item, AZStd::vector list) - { - for (size_t i = 0; i < list.size(); ++i) - { - if (Collides(list[i], item)) - { - return true; - } - } - return false; - } - - // Returns the overlap of two intersecting coordinate sets - AtlasCoordinates GetOverlap(AtlasCoordinates a, AtlasCoordinates b) - { - return AtlasCoordinates(b.GetLeft() > a.GetLeft() ? b.GetLeft() : a.GetLeft(), - b.GetRight() < a.GetRight() ? b.GetRight() : a.GetRight(), - b.GetTop() > a.GetTop() ? b.GetTop() : a.GetTop(), - b.GetBottom() < a.GetBottom() ? b.GetBottom() : a.GetBottom()); - } - - // Returns the width of the widest element in imageList - int AtlasBuilderWorker::GetWidest(const ImageDimensionData& imageList) - { - int max = 0; - for (size_t i = 0; i < imageList.size(); ++i) - { - if (max < imageList[i].second.m_width) - { - max = imageList[i].second.m_width; - } - } - return max; - } - - // Returns the height of the tallest element in imageList - int AtlasBuilderWorker::GetTallest(const ImageDimensionData& imageList) - { - int max = 0; - for (size_t i = 0; i < imageList.size(); ++i) - { - if (max < imageList[i].second.m_height) - { - max = imageList[i].second.m_height; - } - } - return max; - } - - // Performs an operation that copies a pixel to the output - void SetPixels(AZ::u8* dest, const AZ::u8* source, int destBytes) - { - if (destBytes >= bytesPerPixel) - { - memcpy(dest, source, bytesPerPixel); - int bytesCopied = bytesPerPixel; - while (bytesCopied * 2 < destBytes) - { - memcpy(dest + bytesCopied, dest, bytesCopied); - bytesCopied *= 2; - } - memcpy(dest + bytesCopied, dest, destBytes - bytesCopied); - } - } - - // Checks if we can insert an image into a slot - bool CanInsert(AtlasCoordinates slot, ImageDimension image, int padding, int farRight, int farBot) - { - int right = slot.GetLeft() + image.m_width; - if (slot.GetRight() < farRight) - { - // Add padding for my right border - right += padding; - // Round up to the nearest compression unit - right = (right + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - right += padding; - } - - int bot = slot.GetTop() + image.m_height; - if (slot.GetBottom() < farBot) - { - // Add padding for my right border - bot += padding; - // Round up to the nearest compression unit - bot = (bot + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - bot += padding; - } - - return slot.GetRight() >= right && slot.GetBottom() >= bot; - } - - // Adds the necessary padding to an Atlas Coordinate - void AddPadding(AtlasCoordinates& slot, int padding, [[maybe_unused]] int farRight, [[maybe_unused]] int farBot) - { - // Add padding for my right border - int right = slot.GetRight() + padding; - // Round up to the nearest compression unit - right = (right + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - right += padding; - - // Add padding for my right border - int bot = slot.GetBottom() + padding; - // Round up to the nearest compression unit - bot = (bot + (cellSize - 1)) / cellSize * cellSize; - // Add padding for an adjacent unit's left border - bot += padding; - - slot.SetRight(right); - slot.SetBottom(bot); - } - -} diff --git a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.h b/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.h deleted file mode 100644 index f28535998e..0000000000 --- a/Gems/ImageProcessing/Code/Source/AtlasBuilder/AtlasBuilderWorker.h +++ /dev/null @@ -1,221 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace TextureAtlasBuilder -{ - //! Struct that is used to communicate input commands - struct AtlasBuilderInput - { - AZ_CLASS_ALLOCATOR(AtlasBuilderInput, AZ::SystemAllocator, 0); - AZ_TYPE_INFO(AtlasBuilderInput, "{F54477F9-1BDE-4274-8CC0-8320A3EF4A42}"); - - bool m_forceSquare; - bool m_forcePowerOf2; - // Includes a white default texture for the UI to use under certain circumstances - bool m_includeWhiteTexture; - int m_maxDimension; - // At least this much padding will surround each texture except on the edges of the atlas - int m_padding; - // Color used in wasted space - AZ::Color m_unusedColor; - // A preset to use for the texture atlas image processing - AZStd::string m_presetName; - - AZStd::vector m_filePaths; - AtlasBuilderInput(): - m_forceSquare(false), - m_forcePowerOf2(false), - m_includeWhiteTexture(true), - m_maxDimension(4096), - m_padding(1), - // Default color should be a non-transparent color that isn't used often in uis - m_unusedColor(.235f, .702f, .443f, 1) - { - } - - static void Reflect(AZ::ReflectContext* context); - - //! Attempts to read the input from a .texatlas file. "valid" is for reporting exceptions and telling the asset - //! proccesor to fail the job. Supports parsing through a human readable custom parser. - static AtlasBuilderInput ReadFromFile(const AZStd::string& path, const AZStd::string& directory, bool& valid); - - //! Resolves any wild cards in paths - static void AddFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& insert); - - //! Removes anything that matches the wildcard - static void RemoveFilesUsingWildCard(AZStd::vector& paths, const AZStd::string& remove); - - //! Resolves any folder paths into image file paths - static void AddFolderContents(AZStd::vector& paths, const AZStd::string& insert, bool& valid); - - //! Resolves remove commands for folders - static void RemoveFolderContents(AZStd::vector& paths, const AZStd::string& remove); - }; - - //! Struct that is used to represent an object with a width and height in pixels - struct ImageDimension - { - int m_width; - int m_height; - - ImageDimension(int width, int height) - { - m_width = width; - m_height = height; - } - }; - - //! Typedef for an ImageDimension paired with an integer - using IndexImageDimension = AZStd::pair; - - //! Typedef for a list of ImageDimensions paired with integers - using ImageDimensionData = AZStd::vector; - - //! Typedef to simplify references to TextureAtlas::AtlasCoordinates - using AtlasCoordinates = TextureAtlasNamespace::AtlasCoordinates; - - //! Number of bytes in a pixel - const int bytesPerPixel = 4; - - //! The size of the padded sorting units (important for compression) - const int cellSize = 4; - - //! Indexes of the products - enum class Product - { - TexatlasidxProduct = 0, - DdsProduct = 1 - }; - - //! An asset builder for texture atlases - class AtlasBuilderWorker : public AssetBuilderSDK::AssetBuilderCommandBus::Handler - { - public: - AZ_RTTI(AtlasBuilderWorker, "{79036188-E017-4575-9EC0-8D39CB560EA6}"); - - AtlasBuilderWorker() = default; - ~AtlasBuilderWorker() = default; - - //! Asset Builder Callback Functions - - //! Called by asset processor to gather information on a job for a ".texatlas" file - void CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, - AssetBuilderSDK::CreateJobsResponse& response); - //! Called by asset proccessor when it wants us to execute a job - void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, - AssetBuilderSDK::ProcessJobResponse& response); - - //! Returns the job related information used by the builder - static AssetBuilderSDK::JobDescriptor GetJobDescriptor(const AZStd::string& sourceFile, const AtlasBuilderInput& input); - - ////////////////////////////////////////////////////////////////////////// - //! AssetBuilderSDK::AssetBuilderCommandBus interface - void ShutDown() override; // if you get this you must fail all existing jobs and return. - ////////////////////////////////////////////////////////////////////////// - - private: - bool m_isShuttingDown = false; - - //! This is the main function that takes a set of inputs and attempts to pack them into an atlas of a given - //! size. Returns true if succesful, does not update out on failure. - static bool TryPack(const ImageDimensionData& images, - int targetWidth, - int targetHeight, - int padding, - size_t& amountFit, - AZStd::vector& out); - - //! Removes any overlap between slotList and the given item - static void TrimOverlap(AZStd::vector& slotList, AtlasCoordinates item); - - //! Uses the proper tightening method based on the input and returns the maximum number of items that were able to be fit - bool TryTightening(AtlasBuilderInput input, - const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int targetArea, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out); - - //! Finds the tightest square fit achievable by expanding a square area until a valid fit is found - bool TryTighteningSquare(const ImageDimensionData& images, - int lowerBound, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out); - - //! Finds the tightest fit achievable by starting with the optimal thin solution and attempting to resize to be - //! a better shape - bool TryTighteningOptimal(const ImageDimensionData& images, - int smallestWidth, - int smallestHeight, - int maxDimension, - int targetArea, - bool powerOfTwo, - int padding, - int& resultWidth, - int& resultHeight, - size_t& amountFit, - AZStd::vector& out); - - //! Sorting logic for adding a slot to a sorted list in order to maintain increasing order - static void InsertInOrder(AZStd::vector& slotList, AtlasCoordinates item); - - //! Misc Logic For Estimating Target Shape - - //! Returns the width of the widest element - static int GetWidest(const ImageDimensionData& imageList); - - //! Returns the height of the tallest area - static int GetTallest(const ImageDimensionData& imageList); - }; - - //! Used for sorting ImageDimensions - static bool operator<(ImageDimension a, ImageDimension b); - - //! Used to expose the ImageDimension in a pair to AZStd::Sort - static bool operator<(IndexImageDimension a, IndexImageDimension b); - - //! Returns true if two coordinate sets overlap - static bool Collides(AtlasCoordinates a, AtlasCoordinates b); - - //! Returns true if item collides with any object in list - static bool Collides(AtlasCoordinates item, AZStd::vector list); - - //! Returns the portion of the second item that overlaps with the first - static AtlasCoordinates GetOverlap(AtlasCoordinates a, AtlasCoordinates b); - - //! Performs an operation that copies a pixel to the output - static void SetPixels(AZ::u8* dest, const AZ::u8* source, int destBytes); - - //! Checks if we can insert an image into a slot - static bool CanInsert(AtlasCoordinates slot, ImageDimension image, int padding, int farRight, int farBot); - - //! Adds the necessary padding to an Atlas Coordinate - static void AddPadding(AtlasCoordinates& slot, int padding, int farRight, int farBot); -} diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.cpp deleted file mode 100644 index f8b0a1651b..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.cpp +++ /dev/null @@ -1,1114 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include "BuilderSettingManager.h" -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - namespace ImageProcess##PrivateName\ - {\ - bool DoesSupport(AZStd::string);\ - } -AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - const char* BuilderSettingManager::s_environmentVariableName = "ImageBuilderSettingManager"; - AZ::EnvironmentVariable BuilderSettingManager::s_globalInstance = nullptr; - AZStd::mutex BuilderSettingManager::s_instanceMutex; - const PlatformName BuilderSettingManager::s_defaultPlatform = AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM; - - AZ::Outcome, AZStd::string> GetPlatformNamesFromRC(AZStd::string& filePath) - { - QFile inputFile(filePath.c_str()); - - if (inputFile.exists() == false) - { - return AZ::Failure(AZStd::string::format("'%s' does not exist", filePath.c_str())); - } - - AZStd::vector all_platforms; - if (inputFile.open(QIODevice::ReadOnly)) - { - QTextStream in(&inputFile); - while (!in.atEnd()) - { - if (in.readLine() == "[_platform]") - { - QString name_line = in.readLine(); - if (name_line.contains("name=")) - { - QString name_value = name_line.split("=")[1]; - // Remove name alias after ',' - AZStd::string az_name_value = name_value.split(",")[0].toUtf8().constData(); - all_platforms.push_back(az_name_value); - } - } - } - inputFile.close(); - } - return AZ::Success(all_platforms); - } - - StringOutcome ParseKeyToData(QString settingKey, const QSettings& rcINI, PresetSettings& presetSettings) - { - // We may be parsing platform-specific settings denoted by a colon and a platform (ex. mintexturesize:ios=35). - // We always extract the actual setting name to determine the setting we are parsing. We must reference the key - // as a whole to properly index into the rcINI file content. - QString key = settingKey.split(":")[0]; - - // There is no standard way to map an enum to string-- - // Also, can't seem to make this static because it allocates something that the destructor doesn't catch. - const AZStd::map colorSpaceMap{ - { "linear" , ColorSpace::linear }, - { "sRGB" , ColorSpace::sRGB }, - { "auto" , ColorSpace::autoSelect } - }; - - const AZStd::map rgbWeightMap{ - { "uniform" , RGBWeight::uniform }, - { "luminance" , RGBWeight::luminance }, - { "ciexyz" , RGBWeight::ciexyz } - }; - - //cm_ftype: gaussian, cone, disc, cosine, cosine_power, ggx - const AZStd::map cubemapFilterTypeMap{ - { "cone" , CubemapFilterType::cone }, - { "gaussian" , CubemapFilterType::gaussian }, - { "ggx" , CubemapFilterType::ggx }, - { "cosine" , CubemapFilterType::cosine }, - { "cosine_power" , CubemapFilterType::cosine_power } - }; - - // To avoid abusing '#define', we use lambda instead. - auto INI_VALUE = [&rcINI, &settingKey]() { return rcINI.value(settingKey); }; - auto INI_VALUE_QSTRING = [&rcINI, &settingKey]() { return rcINI.value(settingKey).toString(); }; - - /************************************************************************/ - /* GENERAL PRESET SETTINGS */ - /************************************************************************/ - if (key == "rgbweights") - { - auto rgbWeightStr = INI_VALUE_QSTRING().toUtf8(); - auto rgbWeightIter = rgbWeightMap.find(rgbWeightStr); - if (rgbWeightIter != rgbWeightMap.end()) - { - presetSettings.m_rgbWeight = rgbWeightIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped rgbweights enum detected.")); - } - } - else if (key == "powof2") - { - presetSettings.m_isPowerOf2 = INI_VALUE().toBool(); - } - else if (key == "discardalpha") - { - presetSettings.m_discardAlpha = INI_VALUE().toBool(); - } - else if (key == "reduce") - { - int reduce = INI_VALUE().toInt(); - if (reduce > 0) - { - presetSettings.m_sizeReduceLevel = reduce; - } - } - else if (key == "ser") - { - presetSettings.m_suppressEngineReduce = INI_VALUE().toBool(); - } - else if (key == "colorchart") - { - presetSettings.m_isColorChart = INI_VALUE().toBool(); - } - else if (key == "highpass") - { - presetSettings.m_highPassMip = INI_VALUE().toInt(); - } - else if (key == "glossfromnormals") - { - presetSettings.m_glossFromNormals = INI_VALUE().toBool(); - } - else if (key == "glosslegacydist") - { - presetSettings.m_isLegacyGloss = INI_VALUE().toBool(); - } - else if (key == "swizzle") - { - presetSettings.m_swizzle = INI_VALUE_QSTRING().toUtf8().constData(); - } - else if (key == "mipnormalize") - { - presetSettings.m_isMipRenormalize = INI_VALUE().toBool(); - } - else if (key == "numstreamablemips") - { - presetSettings.m_numStreamableMips = INI_VALUE().toInt(); - } - else if (key == "colorspace") - { - // By default, RC.ini contains data written in non-standard INI format inherited from CryEngine. - // We need to parse in the value as string list. - // Example: - // - // [MyValues] - // colorspace=src,dst - // - QVariant paramValue = rcINI.value(key, QString()); - if (paramValue.type() != QVariant::StringList) - { - return AZ::Failure(AZStd::string("Expect ColorSpace parameter to be a string list!")); - } - QStringList stringValueList = paramValue.toStringList(); // The order of values for this key is... (SRC, DST) - - if (stringValueList.size() != 2) - { - return AZ::Failure(AZStd::string("Expect ColorSpace parameter list size to be 2!")); - } - - auto srcColorSpaceIter = colorSpaceMap.find(stringValueList[0]); - if (srcColorSpaceIter != colorSpaceMap.end()) - { - presetSettings.m_srcColorSpace = srcColorSpaceIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped ColorSpace enum detected.")); - } - - auto dstColorSpaceIter = colorSpaceMap.find(stringValueList[1]); - if (dstColorSpaceIter != colorSpaceMap.end()) - { - presetSettings.m_destColorSpace = dstColorSpaceIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped ColorSpace enum detected.")); - } - } - else if (key == "filemasks") - { - QVariant iniVariant = rcINI.value(settingKey); - QStringList stringValueList = iniVariant.toStringList(); - for (QString value : stringValueList) - { - //remove stars. For example: "*_ddna*" => "_ddna" - QString suffix = value.mid(1, value.length()-2); - QByteArray suffixByteArray = suffix.toUtf8(); - presetSettings.m_fileMasks.emplace_back(suffixByteArray.constData()); - } - } - else if (key == "pixelformat") - { - auto pixelFormatQBytes = INI_VALUE_QSTRING().toUtf8(); - const char* pixelFormatString = pixelFormatQBytes.constData(); - - EPixelFormat pixelFormatEnum = CPixelFormats::GetInstance().FindPixelFormatByLegacyName(pixelFormatString); - if (pixelFormatEnum == EPixelFormat::ePixelFormat_Unknown) - { - return AZ::Failure(AZStd::string::format("Unsupported ePixelFormat detected: %s", pixelFormatString)); - } - - presetSettings.m_pixelFormat = pixelFormatEnum; - presetSettings.m_pixelFormatName = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormatEnum)->szName; - } - else if (key == "pixelformatalpha") - { - auto pixelFormatQBytes = INI_VALUE_QSTRING().toUtf8(); - const char* pixelFormatString = pixelFormatQBytes.constData(); - - EPixelFormat pixelFormatEnum = CPixelFormats::GetInstance().FindPixelFormatByLegacyName(pixelFormatString); - if (pixelFormatEnum == EPixelFormat::ePixelFormat_Unknown) - { - return AZ::Failure(AZStd::string::format("Unsupported ePixelFormat detected: %s", pixelFormatString)); - } - - presetSettings.m_pixelFormatAlpha = pixelFormatEnum; - presetSettings.m_pixelFormatAlphaName = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormatEnum)->szName; - } - else if (key == "maxtexturesize") - { - bool isOk = false; - auto maxTextureSize = INI_VALUE().toUInt(&isOk); - if (isOk) - { - presetSettings.m_maxTextureSize = maxTextureSize; - } - else - { - return AZ::Failure(AZStd::string::format("Invalid number for key 'maxtexturesize' for [%s]", presetSettings.m_name.c_str())); - } - } - else if (key == "mintexturesize") - { - bool isOk = false; - auto minTextureSize = INI_VALUE().toUInt(&isOk); - if (isOk) - { - presetSettings.m_minTextureSize = minTextureSize; - } - else - { - return AZ::Failure(AZStd::string::format("Invalid number for key 'mintexturesize' for [%s]", presetSettings.m_name.c_str())); - } - } - /************************************************************************/ - /* CUBEMAP PRESET SETTINGS */ - /************************************************************************/ - else if (key == "cm") - { - if (presetSettings.m_cubemapSetting == nullptr && INI_VALUE().toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - } - else - { - return AZ::Failure(AZStd::string("Multiple CubeMap settings detected. Reduce to a single settings entry.")); - } - } - else if (key == "cm_ftype") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - } - } - - if (presetSettings.m_cubemapSetting) - { - auto filterTypeStr = INI_VALUE_QSTRING().toUtf8(); - auto filterTypeIter = cubemapFilterTypeMap.find(filterTypeStr); - if (filterTypeIter != cubemapFilterTypeMap.end()) - { - presetSettings.m_cubemapSetting->m_filter = filterTypeIter->second; - } - else - { - return AZ::Failure(AZStd::string("Unmapped cubemap filter type enum detected.")); - } - } - } - else if (key == "cm_fangle") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_angle = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_angle = INI_VALUE().toFloat(); - } - } - else if (key == "cm_fmipangle") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_mipAngle = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_mipAngle = INI_VALUE().toFloat(); - } - } - else if (key == "cm_fmipslope") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_mipSlope = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_mipSlope = INI_VALUE().toFloat(); - } - } - else if (key == "cm_edgefixup") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_edgeFixup = INI_VALUE().toFloat(); - } - } - else - { - presetSettings.m_cubemapSetting->m_edgeFixup = INI_VALUE().toFloat(); - } - } - else if (key == "cm_diff") - { - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_generateDiff = INI_VALUE().toBool(); - } - } - else - { - presetSettings.m_cubemapSetting->m_generateDiff = INI_VALUE().toBool(); - } - } - else if (key == "cm_diffpreset") - { - QByteArray presetNameByteArray = INI_VALUE().toString().toUtf8(); - AZ::Uuid presetID = BuilderSettingManager::Instance()->GetPresetIdFromName(presetNameByteArray.constData()); - if (presetID.IsNull()) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("Parsing error [cm_diffpreset]. Unable to find UUID for preset: %s", presetNameByteArray.constData())); - } - - if (presetSettings.m_cubemapSetting == nullptr) - { - if (rcINI.value("cm").toBool()) - { - presetSettings.m_cubemapSetting = AZStd::make_unique(); - presetSettings.m_cubemapSetting->m_diffuseGenPreset = presetID; - } - } - else - { - presetSettings.m_cubemapSetting->m_diffuseGenPreset = presetID; - } - } - /************************************************************************/ - /* MIPMAP PRESET SETTINGS */ - /************************************************************************/ - else if (key == "mipmaps") - { - // We convey whether 'mipmaps' is enabled/available by whether the pointer is valid or empty. - if (presetSettings.m_mipmapSetting == nullptr && INI_VALUE().toBool()) - { - presetSettings.m_mipmapSetting = AZStd::make_unique(); - } - } - else if (key == "mipgentype") - { - // We must handle parsing settings of missing/disabled parent settings ("mipmaps") - if (rcINI.value("mipmaps") == QVariant()) - { - return AZ::Failure(AZStd::string("'mipgentype' specified, but dependent 'mipmaps' setting is missing in rc.ini.")); - } - - // If we are missing the mipmap settings (possibly yet to be parsed)... - if (presetSettings.m_mipmapSetting == nullptr) - { - if (rcINI.value("mipmaps").toBool()) - { - presetSettings.m_mipmapSetting = AZStd::make_unique(); - } - else - { - return AZ::Failure(AZStd::string::format( - "Cannot assign 'mipgentype' because current Preset [%s] has 'mipmaps' disabled.", presetSettings.m_name.c_str())); - } - } - - presetSettings.m_mipmapSetting->m_type = MipGenType::blackmanHarris; - if ("average" == INI_VALUE_QSTRING().toUtf8()) - { - presetSettings.m_mipmapSetting->m_type = MipGenType::box; - } - } - else - { - QByteArray keyByteArray = key.toUtf8(); - return STRING_OUTCOME_WARNING(AZStd::string::format("Unsupported key parsed from RC.ini: %s", keyByteArray.constData())); - } - - return STRING_OUTCOME_SUCCESS; - } - - void LoadPresetAliasFromRC(QSettings& rcINI, AZStd::map & presetAliases) - { - rcINI.beginGroup("_presetAliases"); - - for (QString legacyPresetString : rcINI.childKeys()) - { - QString modernPresetString = rcINI.value(legacyPresetString).toString(); - - // We must store this intermediary data in order to convert to a c-string. - QByteArray legacyPresetUtf8 = legacyPresetString.toUtf8(); - QByteArray modernPresetUtf8 = modernPresetString.toUtf8(); - - PresetName legacyPresetName(legacyPresetUtf8.constData()); - PresetName modernPresetName(modernPresetUtf8.constData()); - - presetAliases.insert(AZStd::pair(legacyPresetName, modernPresetName)); - } - - rcINI.endGroup(); - } - - void BuilderSettingManager::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("BuildSettings", &BuilderSettingManager::m_builderSettings) - ->Field("PresetAliases", &BuilderSettingManager::m_presetAliases) - ->Field("DefaultPresetsByFileMask", &BuilderSettingManager::m_defaultPresetByFileMask) - ->Field("DefaultPreset", &BuilderSettingManager::m_defaultPreset) - ->Field("DefaultPresetAlpha", &BuilderSettingManager::m_defaultPresetAlpha) - ->Field("DefaultPresetNonePOT", &BuilderSettingManager::m_defaultPresetNonePOT); - } - } - - BuilderSettingManager* BuilderSettingManager::Instance() - { - AZStd::lock_guard lock(s_instanceMutex); - - if (!s_globalInstance) - { - s_globalInstance = AZ::Environment::FindVariable(s_environmentVariableName); - } - AZ_Assert(s_globalInstance, "BuilderSettingManager not created!"); - - return s_globalInstance.Get(); - } - - void BuilderSettingManager::CreateInstance() - { - AZStd::lock_guard lock(s_instanceMutex); - - if (s_globalInstance) - { - AZ_Assert(false, "BuilderSettingManager already created!"); - return; - } - - if (!s_globalInstance) - { - s_globalInstance = AZ::Environment::CreateVariable(s_environmentVariableName); - } - if (!s_globalInstance.Get()) - { - s_globalInstance.Set(aznew BuilderSettingManager()); - } - } - - void BuilderSettingManager::DestroyInstance() - { - AZStd::lock_guard lock(s_instanceMutex); - AZ_Assert(s_globalInstance, "Invalid call to DestroyInstance - no instance exists."); - AZ_Assert(s_globalInstance.Get(), "You can only call DestroyInstance if you have called CreateInstance."); - - delete s_globalInstance.Get(); - s_globalInstance.Reset(); - } - - const PresetSettings* BuilderSettingManager::GetPreset(const AZ::Uuid presetId, const PlatformName& platform) - { - AZStd::lock_guard lock(m_presetMapLock); - PlatformName platformName = platform; - if (platformName.empty()) - { - platformName = BuilderSettingManager::s_defaultPlatform; - } - - if (m_builderSettings.find(platformName) != m_builderSettings.end()) - { - const BuilderSettings& platformBuilderSetting = m_builderSettings[platformName]; - auto settingsIter = platformBuilderSetting.m_presets.find(presetId); - if (settingsIter != platformBuilderSetting.m_presets.end()) - { - return &settingsIter->second; - } - else - { - AZ_Error("Image Processing", false, "Cannot find preset settings on platform [%s] for preset id: %s", platformName.c_str(), presetId.ToString().c_str()); - } - } - else - { - AZ_Error("Image Processing", false, "Cannot find platform [%s]", platformName.c_str()); - } - - return nullptr; - } - - - const BuilderSettings* BuilderSettingManager::GetBuilderSetting(const PlatformName& platform) - { - if (m_builderSettings.find(platform) != m_builderSettings.end()) - { - return &m_builderSettings[platform]; - } - return nullptr; - } - - const PlatformNameList BuilderSettingManager::GetPlatformList() - { - PlatformNameList platforms; - - for(auto& builderSetting : m_builderSettings) - { - if (builderSetting.second.m_enablePlatform) - { - platforms.push_back(builderSetting.first); - } - } - - return platforms; - } - - const AZStd::map >& BuilderSettingManager::GetPresetFilterMap() - { - AZStd::lock_guard lock(m_presetMapLock); - return m_presetFilterMap; - } - - const AZ::Uuid BuilderSettingManager::GetPresetIdFromName(const PresetName& presetName) - { - AZStd::lock_guard lock(m_presetMapLock); - - // Each preset shares the same UUID across platforms, therefore, it's safe to pick a random - // platform to search for the preset UUID. We'll use PC, in this case. - const PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (m_builderSettings.find(defaultPlatform) != m_builderSettings.end()) - { - auto presets = m_builderSettings[defaultPlatform].m_presets; - - for (auto curIter : presets) - { - if (curIter.second.m_name == presetName) - { - return curIter.first; - } - } - } - - return AZ::Uuid::CreateNull(); - } - - const PresetName BuilderSettingManager::GetPresetNameFromId(const AZ::Uuid& presetId) - { - AZStd::lock_guard lock(m_presetMapLock); - const PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (m_builderSettings.find(defaultPlatform) != m_builderSettings.end()) - { - auto& presetMap = m_builderSettings[defaultPlatform].m_presets; - auto presetIter = presetMap.find(presetId); - if (presetIter != presetMap.end()) - { - return presetIter->second.m_name; - } - } - - return "Unknown"; - } - - void BuilderSettingManager::ClearSettings() - { - AZStd::lock_guard lock(m_presetMapLock); - m_presetFilterMap.clear(); - m_presetAliases.clear(); - m_builderSettings.clear(); - } - - StringOutcome BuilderSettingManager::LoadBuilderSettings() - { - StringOutcome outcome = STRING_OUTCOME_ERROR(""); - // Construct the project setting path that is used by the tool for loading setting file - const char* gameFolderPath = nullptr; - AzToolsFramework::AssetSystemRequestBus::BroadcastResult(gameFolderPath, &AzToolsFramework::AssetSystemRequestBus::Events::GetAbsoluteDevGameFolderPath); - AZStd::string projectSettingPath = ""; - - if (gameFolderPath) - { - AzFramework::StringFunc::Path::Join(gameFolderPath, "Config/ImageBuilder/ImageBuilderPresets.settings", projectSettingPath); - outcome = LoadBuilderSettings(projectSettingPath); - } - - if (!outcome.IsSuccess()) - { - AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Failed to read project specific preset setting at [%s], will use default setting file.\n", projectSettingPath.c_str()); - // Construct the default setting path - const char* engineRoot = nullptr; - AzFramework::ApplicationRequests::Bus::BroadcastResult(engineRoot, &AzFramework::ApplicationRequests::GetEngineRoot); - - if (engineRoot) - { - AZStd::string defaultSettingPath = ""; - AzFramework::StringFunc::Path::Join(engineRoot, "Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings", defaultSettingPath); - outcome = LoadBuilderSettings(defaultSettingPath); - } - } - - return outcome; - } - - StringOutcome BuilderSettingManager::LoadBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context) - { - // Ensure filepath exists. - AZ::IO::FileIOBase* fileReader = AZ::IO::FileIOBase::GetInstance(); - if(false == fileReader->Exists(filepath.c_str())) - { - return AZ::Failure(AZStd::string::format("Build settings file not found: %s", filepath.c_str())); - } - - AZ::IO::HandleType settingsFileHandle; - m_builderSettingsFileVersion = 0; - if (fileReader->Open(filepath.c_str(), AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, settingsFileHandle) == AZ::IO::ResultCode::Success) - { - // Read the contents of the file and hash it. The first u32 of the result of this will be used as a version - // number. Any changes to the builder settings file will then cause all textures to be reconverted to pick - // up that change. - AZStd::string settingsFileBuffer; - AZ::u64 settingsFileSize = 0; - fileReader->Size(settingsFileHandle, settingsFileSize); - settingsFileBuffer.resize_no_construct(settingsFileSize); - fileReader->Read(settingsFileHandle, settingsFileBuffer.data(), settingsFileSize); - fileReader->Close(settingsFileHandle); - - AZ::Sha1 block; - AZ::u32 hashDigest[5]; - block.ProcessBytes(settingsFileBuffer.data(), settingsFileSize); - block.GetDigest(hashDigest); - m_builderSettingsFileVersion = hashDigest[0]; - } - - auto loadedSettingsPtr = AZStd::unique_ptr(AZ::Utils::LoadObjectFromFile(filepath, context)); - - // Ensure file is loaded. - if (!loadedSettingsPtr) - { - return AZ::Failure(AZStd::string::format("Failed to read from file: %s", filepath.c_str())); - } - - m_presetMapLock.lock(); - // Normally, we would perform a deep-copy from the loaded settings onto 'this' via assignment operator overload. However, we have deleted our - // assignment operator overloads, because we intend for this class to be a singleton. Instead, we will manually perform a deep-copy - // in this function since it's the only time we require something akin to assignment operation. - m_builderSettings = loadedSettingsPtr->m_builderSettings; - m_presetAliases = loadedSettingsPtr->m_presetAliases; - m_defaultPresetByFileMask = loadedSettingsPtr->m_defaultPresetByFileMask; - m_defaultPreset = loadedSettingsPtr->m_defaultPreset; - m_defaultPresetAlpha = loadedSettingsPtr->m_defaultPresetAlpha; - m_defaultPresetNonePOT = loadedSettingsPtr->m_defaultPresetNonePOT; - - m_presetFilterMap.clear(); - - //enable builder settings for enabled restricted platforms. These settings should be disabled by default in the setting file -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - for (auto& buildSetting : m_builderSettings)\ - {\ - if (ImageProcess##PrivateName::DoesSupport(buildSetting.first))\ - {\ - buildSetting.second.m_enablePlatform = true;\ - break;\ - }\ - } - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - //convert pixel format string to enum for each preset - for (auto& buildSetting : m_builderSettings) - { - for (auto& preset : buildSetting.second.m_presets) - { - preset.second.m_pixelFormat = CPixelFormats::GetInstance().FindPixelFormatByName(preset.second.m_pixelFormatName.c_str()); - preset.second.m_pixelFormatAlpha = CPixelFormats::GetInstance().FindPixelFormatByName(preset.second.m_pixelFormatAlphaName.c_str()); - } - } - m_presetMapLock.unlock(); - - RegenerateMappings(); - - return AZ::Success(AZStd::string()); - } - - StringOutcome BuilderSettingManager::WriteBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context) - { - if( false == AZ::Utils::SaveObjectToFile(filepath, AZ::DataStream::StreamType::ST_XML, this, context)) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("Failed to write file: %s", filepath.c_str())); - } - return STRING_OUTCOME_SUCCESS; - } - - const PresetName BuilderSettingManager::TranslateLegacyPresetName(const PresetName& legacyName) - { - auto iterResult = m_presetAliases.find(legacyName); - - if (iterResult == m_presetAliases.end()) - { - return legacyName; - } - - return iterResult->second; - } - - StringOutcome BuilderSettingManager::LoadBuilderSettingsFromRC(AZStd::string& filePath) - { - //Clear previous settings first - ClearSettings(); - - // Find all the platforms - auto outcome = GetPlatformNamesFromRC(filePath); - AZ_ENSURE_STRING_OUTCOME(outcome); - PlatformNameVector all_platforms = outcome.TakeValue(); - - m_presetMapLock.lock(); - // Register all the platforms with empty settings. - for (const AZStd::string& platformName : all_platforms) - { - auto newEntry = AZStd::pair(platformName, BuilderSettings()); - m_builderSettings.insert(newEntry); - } - - // Open settings for parsing - QSettings set(filePath.c_str(), QSettings::IniFormat); - - // Load the preset alias mapping - LoadPresetAliasFromRC(set, m_presetAliases); - - QStringList childGroups = set.childGroups(); - QStringList exemptGroups; - exemptGroups.append("_platform"); - exemptGroups.append("_presetAliases"); - - // We must generate new preset settings and UUID's prior to parsing the rest of the data, because - // some preset settings make references to other presets within RC.ini. We must make sure all presets - // are identified, before making references to them via their UUID. - for (QString groupName : childGroups) - { - auto newPresetUuid = AZ::Uuid::CreateRandom(); - PresetSettings newPresetSetting; - newPresetSetting.m_name = groupName.toUtf8().constData(); - newPresetSetting.m_uuid = newPresetUuid; - for (const PlatformName& platform : all_platforms) - { - m_builderSettings[platform].m_presets.insert(AZStd::make_pair(newPresetUuid, newPresetSetting)); - } - } - m_presetMapLock.unlock(); - - // Apply preset settings from file to the existing presets (process each platform). - for(QString groupName : childGroups) - { - // Only process Presets from here on out. - if (exemptGroups.contains(groupName)) - { - continue; - } - - auto outcome2 = ProcessPreset(groupName, set, all_platforms); - AZ_ENSURE_STRING_OUTCOME(outcome2); - } - - RegenerateMappings(); - - // The original rc.ini doesn't have the information below. Included here for GetSuggestedPreset() to work properly. - m_defaultPresetByFileMask["_diff"] = GetPresetIdFromName("Albedo"); - m_defaultPresetByFileMask["_spec"] = GetPresetIdFromName("Reflectance"); - m_defaultPresetByFileMask["_refl"] = GetPresetIdFromName("Reflectance"); - m_defaultPresetByFileMask["_ddn"] = GetPresetIdFromName("Normals"); - m_defaultPresetByFileMask["_ddna"] = GetPresetIdFromName("NormalsWithSmoothness"); - m_defaultPresetByFileMask["_cch"] = GetPresetIdFromName("ColorChart"); - m_defaultPresetByFileMask["_cm"] = GetPresetIdFromName("EnvironmentProbeHDR"); - - m_defaultPreset = GetPresetIdFromName("Albedo"); - m_defaultPresetAlpha = GetPresetIdFromName("AlbedoWithGenericAlpha"); - m_defaultPresetNonePOT = GetPresetIdFromName("ReferenceImage"); - - return STRING_OUTCOME_SUCCESS; - } - - AZ::u32 BuilderSettingManager::BuilderSettingsVersion() const - { - return m_builderSettingsFileVersion; - } - - void BuilderSettingManager::RegenerateMappings() - { - AZStd::lock_guard lock(m_presetMapLock); - - AZStd::string noFilter = AZStd::string(); - - m_presetFilterMap.clear(); - - for (auto& builderSettingIter : m_builderSettings) - { - const BuilderSettings& builderSetting = builderSettingIter.second; - for (auto& presetIter : builderSetting.m_presets) - { - //Put into no filter preset list - m_presetFilterMap[noFilter].insert(presetIter.second.m_name); - - //Put into file mask preset list if any - for (const PlatformName& filemask : presetIter.second.m_fileMasks) - { - m_presetFilterMap[filemask].insert(presetIter.second.m_name); - } - } - } - } - - StringOutcome BuilderSettingManager::ProcessPreset(QString& preset, QSettings& rcINI, PlatformNameVector& all_platforms) - { - // Early-out check. We should have the preset available before processing. - QByteArray presetByteArray = preset.toUtf8(); - AZ::Uuid parsingPresetUuid = GetPresetIdFromName(presetByteArray.constData()); - if (parsingPresetUuid.IsNull()) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("Unable to find UUID for preset: %s", presetByteArray.constData())); - } - - rcINI.beginGroup(preset); - QStringList groupKeys = rcINI.allKeys(); - - // Build a list for common & platform-specific settings - QStringList commonPresetSettingKeys; - QStringList platformSpecificPresetSettingKeys; - for (QString key : groupKeys) - { - if (key.contains(":")) - { - platformSpecificPresetSettingKeys.append(key); - } - else - { - commonPresetSettingKeys.append(key); - } - } - - // Parse the common settings (retain preset name & uuid) - PresetSettings commonPresetSettings; - commonPresetSettings.m_name = presetByteArray.constData(); - commonPresetSettings.m_uuid = parsingPresetUuid; - for (QString settingKey : commonPresetSettingKeys) - { - AZ_ENSURE_STRING_OUTCOME(ParseKeyToData(settingKey, rcINI, commonPresetSettings)); - } - - // When loading a preset, the UUID is the same per-preset, regardless of the target-platform. - for (AZStd::string& platformId : all_platforms) - { - // Begin platform-specific settings loading with a copy of common Preset settings. - PresetSettings currentPlatformPresetSetting = commonPresetSettings; - - // Obtain platform-specific settings - QString platformFilter = QString(":%1").arg(platformId.c_str()); // Example results-> ":ios", ":osx", ":es3" - QStringList currentPlatformSettings = platformSpecificPresetSettingKeys.filter(platformFilter); - - // Overwrite values for platform-specific settings... - for (QString platformSetting : currentPlatformSettings) - { - AZ_ENSURE_STRING_OUTCOME(ParseKeyToData(platformSetting, rcINI, currentPlatformPresetSetting)); - } - - // Assign the overridden platform preset settings to the BuilderSettingManager. - m_builderSettings[platformId].m_presets[parsingPresetUuid] = currentPlatformPresetSetting; - } - - rcINI.endGroup(); - return STRING_OUTCOME_SUCCESS; - } - - void BuilderSettingManager::MetafilePathFromImagePath(const AZStd::string& imagePath, AZStd::string& metafilePath) - { - // Determine if we have a meta file (legacy or modern). - AZ::IO::LocalFileIO fileIO; - - AZStd::string modernMetaFilepath = imagePath + TextureSettings::modernExtensionName; - if (fileIO.Exists(modernMetaFilepath.c_str())) - { - metafilePath = modernMetaFilepath; - return; - } - - AZStd::string legacyMetaFilepath = imagePath + TextureSettings::legacyExtensionName; - if (fileIO.Exists(legacyMetaFilepath.c_str())) - { - metafilePath = legacyMetaFilepath; - return; - } - - // We found neither. - metafilePath = AZStd::string(); - } - - AZStd::string GetFileMask(const AZStd::string& imageFilePath) - { - //get file name - AZStd::string fileName; - QString lowerFileName = imageFilePath.c_str(); - lowerFileName = lowerFileName.toLower(); - AzFramework::StringFunc::Path::GetFileName(lowerFileName.toUtf8().constData(), fileName); - - //get the substring from last '_' - size_t lastUnderScore = fileName.find_last_of('_'); - if (lastUnderScore != AZStd::string::npos) - { - return fileName.substr(lastUnderScore); - } - - return AZStd::string(); - } - - AZ::Uuid BuilderSettingManager::GetSuggestedPreset(const AZStd::string& imageFilePath, IImageObjectPtr imageFromFile) - { - //load the image to get its size for later use - IImageObjectPtr image = imageFromFile; - //if the input image is empty we will try to load it from the path - if (imageFromFile == nullptr) - { - image = IImageObjectPtr(LoadImageFromFile(imageFilePath)); - } - - if (image == nullptr) - { - AZ_Error("Image Processing", image, "Cannot load image file [%s]. Invalid image format or corrupt data. Note that \"Indexed Color\" is not currently supported for .tga files.", imageFilePath.c_str()); - return AZ::Uuid::CreateNull(); - } - - //get file mask of this image file - AZStd::string fileMask = GetFileMask(imageFilePath); - - AZ::Uuid outPreset = AZ::Uuid::CreateNull(); - - if ("_diff" == fileMask && image->GetAlphaContent() != EAlphaContent::eAlphaContent_Absent) - { - outPreset = m_defaultPresetAlpha; - } - else - { - //check default presets for some file masks - if (m_defaultPresetByFileMask.find(fileMask) != m_defaultPresetByFileMask.end()) - { - outPreset = m_defaultPresetByFileMask[fileMask]; - } - } - - //use the preset filter map to find - if (outPreset.IsNull() && !fileMask.empty()) - { - auto& presetFilterMap = GetPresetFilterMap(); - if (presetFilterMap.find(fileMask) != presetFilterMap.end()) - { - AZStd::string presetName = *(presetFilterMap.find(fileMask)->second.begin()); - outPreset = GetPresetIdFromName(presetName); - } - } - - const PresetSettings* presetInfo = nullptr; - - if (!outPreset.IsNull()) - { - presetInfo = GetPreset(outPreset); - - //special case for cubemap - if (presetInfo && presetInfo->m_cubemapSetting) - { - if (CubemapLayout::GetCubemapLayoutInfo(image) == nullptr) - { - outPreset = AZ::Uuid::CreateNull(); - } - } - } - - if (outPreset.IsNull()) - { - if (!image->HasPowerOfTwoSizes()) - { - // The resource compiler used the non power of 2 preset if the width or the height is not power of 2 - // even if it would have been possible to compress the image, so this behavior is matched here. - return m_defaultPresetNonePOT; - } - else if (image->GetAlphaContent() == EAlphaContent::eAlphaContent_Absent) - { - outPreset = m_defaultPreset; - } - else - { - outPreset = m_defaultPresetAlpha; - } - } - - //get the pixel format for selected preset - presetInfo = GetPreset(outPreset); - - if (presetInfo) - { - //valid whether image size work with pixel format - if (CPixelFormats::GetInstance().IsImageSizeValid(presetInfo->m_pixelFormat, - image->GetWidth(0), image->GetHeight(0), false)) - { - return outPreset; - } - } - - //uncompressed one which could be used for almost everything - return m_defaultPresetNonePOT; - } - - bool BuilderSettingManager::DoesSupportPlatform(const AZStd::string& platformId) - { - bool rv = m_builderSettings.find(platformId) != m_builderSettings.end(); - return rv; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.h deleted file mode 100644 index c6d03eae54..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettingManager.h +++ /dev/null @@ -1,192 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -class QSettings; -class QString; - -namespace AZ -{ - template class EnvironmentVariable; - class SerializeContext; -} - -namespace ImageProcessing -{ - class BuilderSettingManager - { - public: - AZ_TYPE_INFO(CBuilderSettingManager, "{DAA55241-64FA-4A9B-A37F-C0A36B36D536}"); - AZ_CLASS_ALLOCATOR(BuilderSettingManager, AZ::SystemAllocator, 0); - //load builder settings for all platform - //contain builder setting for all platforms - //this manager should be able to get texture setting for a platform - - - static BuilderSettingManager* Instance(); - // life cycle management: - static void CreateInstance(); - static void DestroyInstance(); - static void Reflect(AZ::ReflectContext* context); - - const PresetSettings* GetPreset(const AZ::Uuid presetId, const PlatformName& platform = ""); - - const BuilderSettings* GetBuilderSetting(const PlatformName& platform); - - /** - * Attempts to translate a legacy preset name into Open 3D Engine preset name. - * @param legacy preset name string - * @return A translated preset name. If no translation is available, returns the same value as input argument. - */ - const PresetName TranslateLegacyPresetName(const PresetName& legacyName); - - /** - * @return A list of platform supported - */ - const PlatformNameList GetPlatformList(); - - /** - * @return A map of preset settings based on their filemasks. - * @key filemask string, empty string means no filemask - * @value set of preset setting names supporting the specified filemask - */ - const AZStd::map>& GetPresetFilterMap(); - - /** - * Find preset id list based on the preset name. - * @param preset name string - * @return a map of preset ids whose name are specified by the input on different platforms - * @key platform name string - * @value uuid of the preset setting - */ - const AZ::Uuid GetPresetIdFromName(const PresetName& presetName); - - /** - * Find preset name based on the preset id. - * @param uuid of the preset setting - * @return preset name string - */ - const PresetName GetPresetNameFromId(const AZ::Uuid& presetId); - - /** - * Writes preset data to file using AZ::Serialization format. - * @param filepath string to the build settings xml - */ - StringOutcome WriteBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context = nullptr); - - /** - * Loads preset data from file using AZ::Serialization format. - * @param filepath string to the build settings xml - */ - StringOutcome LoadBuilderSettings(AZStd::string filepath, AZ::SerializeContext* context = nullptr); - - /** - * Overload function. Loads preset data from project setting file if any - * Otherwise, the function will load default setting file inside the gem - */ - StringOutcome LoadBuilderSettings(); - - /** - * Loads preset data from legacy format found in RC.ini. - * @param filepath string to RC.ini - */ - StringOutcome LoadBuilderSettingsFromRC(AZStd::string& filePath); - - /** - * Returns the first u32 generated from a hash of the builder settings - * file that can be used as a version to detect changes to the file. - */ - AZ::u32 BuilderSettingsVersion() const; - - /** - * Provides a full path to the adjacent metafile of a given texture/image file. - * @param Filepath string to the texture/image file. - * @param Output filepath string to the adjacent texture/image metafile. - * Will output whichever metafile is present, whether it is legacy or modern format. - * If both are present, modern format is returned. - * If none are present, an empty string is returned. - */ - void MetafilePathFromImagePath(const AZStd::string& imagePath, AZStd::string& metafilePath); - - /** - * Find a suitable preset a given image file. - * @param imageFilePath: Filepath string of the image file. The function may load the image from the path for better detection - * @param image: an optional image object which can be used for preset selection if there is no match based file mask. - * @return suggested preset uuid. - */ - AZ::Uuid GetSuggestedPreset(const AZStd::string& imageFilePath, IImageObjectPtr image = nullptr); - - bool DoesSupportPlatform(const AZStd::string& platformId); - - static const char* s_environmentVariableName; - static AZ::EnvironmentVariable s_globalInstance; - static AZStd::mutex s_instanceMutex; - static const PlatformName s_defaultPlatform; - - BuilderSettingManager(){} - - private: // functions - AZ_DISABLE_COPY_MOVE(BuilderSettingManager); - - StringOutcome ProcessPreset(QString& preset, QSettings& rcINI, PlatformNameVector& all_platforms); - - /** - * Clear Builder Settings and any cached maps/lists - */ - void ClearSettings(); - - /** - * Regenerate Builder Settings and any cached maps/lists - */ - void RegenerateMappings(); - - private: // variables - - //builder settings for each platform - AZStd::map m_builderSettings; - AZStd::map m_presetAliases; - - /** - * Cached list of presets mapped by their file masks. - * @Key file mask, use empty string to indicate all presets without filtering - * @Value set of preset names that matches the file mask - */ - AZStd::map > m_presetFilterMap; - - /** - * A mutex to protect when modifying any map in this manager - */ - AZStd::mutex m_presetMapLock; - - //default presets for certian file masks - AZStd::map m_defaultPresetByFileMask; - - //default preset for none power of two image - AZ::Uuid m_defaultPresetNonePOT; - - //default preset for power of two - AZ::Uuid m_defaultPreset; - - //default preset for power of two with alpha - AZ::Uuid m_defaultPresetAlpha; - - //generated from hashing the builder settings file - AZ::u32 m_builderSettingsFileVersion; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.cpp deleted file mode 100644 index 6f68ea7581..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.cpp +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "ImageProcessing_precompiled.h" -#include -#include - -namespace ImageProcessing -{ - void BuilderSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("GlossScale", &BuilderSettings::m_brdfGlossScale) - ->Field("GlossBias", &BuilderSettings::m_brdfGlossBias) - ->Field("Streaming", &BuilderSettings::m_enableStreaming) - ->Field("Enable", &BuilderSettings::m_enablePlatform) - ->Field("Presets", &BuilderSettings::m_presets); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.h deleted file mode 100644 index 500b69f472..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/BuilderSettings.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - //builder setting for a platform - struct BuilderSettings - { - AZ_TYPE_INFO(BuilderSettings, "{4085AB56-934C-43A6-AF25-4443E1EEB71D}"); - AZ_CLASS_ALLOCATOR(BuilderSettings, AZ::SystemAllocator, 0); - static void Reflect(AZ::ReflectContext* context); - - //global settings - float m_brdfGlossScale = 16.0f; - float m_brdfGlossBias = 0.0f; - bool m_enableStreaming = true; - bool m_enablePlatform = true; - AZStd::map m_presets; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.cpp deleted file mode 100644 index 43f2a50535..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include - -namespace ImageProcessing -{ - - bool CubemapSettings::operator!=(const CubemapSettings& other) - { - return !(*this == other); - } - - bool CubemapSettings::operator==(const CubemapSettings& other) - { - return - m_angle == other.m_angle && - m_mipAngle == other.m_mipAngle && - m_mipSlope == other.m_mipSlope && - m_edgeFixup == other.m_edgeFixup && - m_generateDiff == other.m_generateDiff && - m_diffuseGenPreset == other.m_diffuseGenPreset; - } - - void CubemapSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("Filter", &CubemapSettings::m_filter) - ->Field("Angle", &CubemapSettings::m_angle) - ->Field("MipAngle", &CubemapSettings::m_mipAngle) - ->Field("MipSlope", &CubemapSettings::m_mipSlope) - ->Field("EdgeFixup", &CubemapSettings::m_edgeFixup) - ->Field("GenerateDiff", &CubemapSettings::m_generateDiff) - ->Field("DiffuseProbePreset", &CubemapSettings::m_diffuseGenPreset); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.h deleted file mode 100644 index edfdde8cbe..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/CubemapSettings.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace ImageProcessing -{ - //! settings related to cubemap. Part of texture preset setting. only useful when cubemap enabled - struct CubemapSettings - { - AZ_TYPE_INFO(CubemapSettings, "{C6BDEB7B-8E05-4B2D-8F39-8F6275BC84E8}"); - AZ_CLASS_ALLOCATOR(CubemapSettings, AZ::SystemAllocator, 0); - bool operator!=(const CubemapSettings& other); - bool operator==(const CubemapSettings& other); - static void Reflect(AZ::ReflectContext* context); - - // "cm_ftype", cubemap angular filter type: gaussian, cone, disc, cosine, cosine_power, ggx - CubemapFilterType m_filter; - - // "cm_fangle", base filter angle for cubemap filtering(degrees), 0 - disabled - float m_angle; - - // "cm_fmipangle", initial mip filter angle for cubemap filtering(degrees), 0 - disabled - float m_mipAngle; - - // "cm_fmipslope", mip filter angle multiplier for cubemap filtering, 1 - default" - float m_mipSlope; - - // "cm_edgefixup", cubemap edge fix-up width, 0 - disabled - float m_edgeFixup; - - // "cm_diff", generate a diffuse illumination light-probe in addition - bool m_generateDiff; - - // "cm_diffpreset", the name of the preset to be used for the diffuse probe - AZ::Uuid m_diffuseGenPreset; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/ImageProcessingDefines.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/ImageProcessingDefines.h deleted file mode 100644 index c9fa860240..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/ImageProcessingDefines.h +++ /dev/null @@ -1,108 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include - -/** -* Shorthand for checking a condition, and failing if false. -* Works with any function that returns AZ::Outcome<..., AZStd::string>. -* Unlike assert, it is not removed in release builds. -* Ensure all strings are passed with c_str(), as they are passed to AZStd::string::format(). -*/ -#define AZ_ENSURE_STRING_OUTCOME_CONDITION(cond, ...) if (!(cond)) { return AZ::Failure(AZStd::string::format(__VA_ARGS__)); } - -// Similar to above macro, but ensures on an AZ::Outcome. Not removed in release builds. -#define AZ_ENSURE_STRING_OUTCOME(outcome) if (!(outcome.IsSuccess())) { return AZ::Failure(outcome.GetError()); } - -namespace ImageProcessing -{ - //! Common return type for operations that can fail. - // Empty success string == Success. - // Populated success string == Warning. - // Populated error string == Failure. - using StringOutcome = AZ::Outcome; -#define STRING_OUTCOME_SUCCESS AZ::Success(AZStd::string()) -#define STRING_OUTCOME_WARNING(warning) AZ::Success(AZStd::string(warning)) -#define STRING_OUTCOME_ERROR(error) AZ::Failure(AZStd::string(error)) - - // Common typedefs (with dependent forward-declarations) - typedef AZStd::string PlatformName, PresetName, FileMask; - typedef AZStd::vector PlatformNameVector; - typedef AZStd::list PlatformNameList; - - //! min and max reduce level - static const unsigned int s_MinReduceLevel = 0; - static const unsigned int s_MaxReduceLevel = 5; - - static const int s_TotalSupportedImageExtensions = 8; - static const char* s_SupportedImageExtensions[s_TotalSupportedImageExtensions] = { - "*.tif", - "*.tiff", - "*.png", - "*.bmp", - "*.jpg", - "*.jpeg", - "*.tga", - "*.gif" - }; - - enum class RGBWeight : AZ::u32 - { - uniform, // uniform weights (1.0, 1.0, 1.0) (default) - luminance, // luminance-based weights (0.3086, 0.6094, 0.0820) - ciexyz // ciexyz-based weights (0.2126, 0.7152, 0.0722) - }; - - enum class ColorSpace : AZ::u32 - { - linear, - sRGB, - autoSelect, - }; - - enum class MipGenType : AZ::u32 - { - point, //Also called nearest neighbor - box, //Also called 'average'. When shrinking images it will average, and merge the pixels together. - triangle, //Also called linear or Bartlett window - quadratic, //Also called bilinear or Welch window - gaussian, //It remove high frequency noise in a highly controllable way. - blackmanHarris, - kaiserSinc //Good for foliage and tree assets exported from Speedtree. - }; - - enum class MipGenEvalType : AZ::u32 - { - sum, - max, - min - }; - - //cubemap angular filter type. Only two filter types were used in rc.ini - enum class CubemapFilterType : AZ::u32 - { - disc = 0, // same as CP_FILTER_TYPE_DISC in CubemapGen - cone = 1, // same as CP_FILTER_TYPE_CONE - cosine = 2, // same as CP_FILTER_TYPE_COSINE. only used for [EnvironmentProbeHDR_Irradiance] - gaussian = 3, // same as CP_FILTER_TYPE_ANGULAR_GAUSSIAN - cosine_power = 4, // same as CP_FILTER_TYPE_COSINE_POWER - ggx = 5 // same as CP_FILTER_TYPE_GGX. only used for [EnvironmentProbeHDR] - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.cpp deleted file mode 100644 index 0285404f50..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.cpp +++ /dev/null @@ -1,66 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include -#include - -namespace ImageProcessing -{ - bool MipmapSettings::operator!=(const MipmapSettings& other) const - { - return !(*this == other); - } - - bool MipmapSettings::operator==(const MipmapSettings& other) const - { - return - m_type == other.m_type && - m_borderColor == other.m_borderColor && - m_normalize == other.m_normalize && - m_streamableMips == other.m_streamableMips; - } - - void MipmapSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("MipGenType", &MipmapSettings::m_type) - ->Field("BorderColor", &MipmapSettings::m_borderColor) - ->Field("Normalize", &MipmapSettings::m_normalize) - ->Field("StreamableMips", &MipmapSettings::m_streamableMips); - - AZ::EditContext* editContext = serialize->GetEditContext(); - if (editContext) - { - editContext->Class("Mipmap Setting", "") - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &MipmapSettings::m_type, "Type", "") - ->EnumAttribute(MipGenType::point, "Point") - ->EnumAttribute(MipGenType::box, "Average") - ->EnumAttribute(MipGenType::triangle, "Linear") - ->EnumAttribute(MipGenType::quadratic, "Bilinear") - ->EnumAttribute(MipGenType::gaussian, "Gaussian") - ->EnumAttribute(MipGenType::blackmanHarris, "BlackmanHarris") - ->EnumAttribute(MipGenType::kaiserSinc, "KaiserSinc") - ->DataElement(AZ::Edit::UIHandlers::Color, &MipmapSettings::m_borderColor, "Color", "") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &MipmapSettings::m_normalize, "Normalized", "") - ->DataElement(AZ::Edit::UIHandlers::SpinBox, &MipmapSettings::m_streamableMips, "Streamable Mips", "") - ->Attribute(AZ::Edit::Attributes::Min, 0) - ; - } - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.h deleted file mode 100644 index 4a2864d2b7..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/MipmapSettings.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - struct MipmapSettings - { - AZ_TYPE_INFO(MipmapSettings, "{9239618E-23A6-43C8-9B87-50528CBFA6FF}"); - AZ_CLASS_ALLOCATOR(MipmapSettings, AZ::SystemAllocator, 0); - bool operator!=(const MipmapSettings& other) const; - bool operator==(const MipmapSettings& other) const; - - static void Reflect(AZ::ReflectContext* context); - - MipGenType m_type = MipGenType::blackmanHarris; - - //Unused or duplicated properties. We may want to move same properties from perset setting to here. - AZ::Color m_borderColor; - bool m_normalize; - AZ::u32 m_streamableMips; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/PlatformSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/PlatformSettings.h deleted file mode 100644 index 5cfc7757b2..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/PlatformSettings.h +++ /dev/null @@ -1,34 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace ImageProcessing -{ - //! default settings for platform - struct PlatformSetting - { - AZ_TYPE_INFO(PlatformSetting, "{19EF828B-DDFF-4591-AD5A-946801FCC98E}"); - AZ_CLASS_ALLOCATOR(PlatformSetting, AZ::SystemAllocator, 0); - - //! Platform's name - PlatformName m_name; - - //! pixel formats supported for the platform - AZStd::list m_availableFormat; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.cpp deleted file mode 100644 index 8f904058d3..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.cpp +++ /dev/null @@ -1,213 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include - -namespace ImageProcessing -{ - PresetSettings::PresetSettings() - : m_uuid(0) - , m_rgbWeight(RGBWeight::uniform) - , m_srcColorSpace(ColorSpace::sRGB) - , m_destColorSpace(ColorSpace::autoSelect) - , m_suppressEngineReduce(false) - , m_pixelFormat(ePixelFormat_R8G8B8A8) - , m_pixelFormatName("R8G8B8A8") - , m_pixelFormatAlpha(ePixelFormat_Unknown) - , m_pixelFormatAlphaName("") - , m_discardAlpha(false) - , m_maxTextureSize(0) - , m_minTextureSize(0) - , m_isPowerOf2(false) - , m_sizeReduceLevel(0) - , m_isColorChart(0) - , m_highPassMip(0) - , m_glossFromNormals(false) - , m_isMipRenormalize(false) - , m_numStreamableMips(100) - , m_isLegacyGloss(false) - { - - } - - PresetSettings::PresetSettings(const PresetSettings& other) - { - DeepCopyMembers(other); - } - - void PresetSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("UUID", &PresetSettings::m_uuid) - ->Field("Name", &PresetSettings::m_name) - ->Field("Description", &PresetSettings::m_description) - ->Field("RGB_Weight", &PresetSettings::m_rgbWeight) - ->Field("SourceColor", &PresetSettings::m_srcColorSpace) - ->Field("DestColor", &PresetSettings::m_destColorSpace) - ->Field("FileMasks", &PresetSettings::m_fileMasks) - ->Field("SuppressEngineReduce", &PresetSettings::m_suppressEngineReduce) - ->Field("PixelFormat", &PresetSettings::m_pixelFormatName) - ->Field("PixelFormatAlpha", &PresetSettings::m_pixelFormatAlphaName) - ->Field("DiscardAlpha", &PresetSettings::m_discardAlpha) - ->Field("MaxTextureSize", &PresetSettings::m_maxTextureSize) - ->Field("MinTextureSize", &PresetSettings::m_minTextureSize) - ->Field("IsPowerOf2", &PresetSettings::m_isPowerOf2) - ->Field("SizeReduceLevel", &PresetSettings::m_sizeReduceLevel) - ->Field("IsColorChart", &PresetSettings::m_isColorChart) - ->Field("HighPassMip", &PresetSettings::m_highPassMip) - ->Field("GlossFromNormal", &PresetSettings::m_glossFromNormals) - ->Field("UseLegacyGloss", &PresetSettings::m_isLegacyGloss) - ->Field("MipRenormalize", &PresetSettings::m_isMipRenormalize) - ->Field("NumberStreamableMips", &PresetSettings::m_numStreamableMips) - ->Field("Swizzle", &PresetSettings::m_swizzle) - ->Field("CubemapSettings", &PresetSettings::m_cubemapSetting) - ->Field("MipMapSetting", &PresetSettings::m_mipmapSetting); - } - } - - PresetSettings& PresetSettings::operator= (const PresetSettings& other) - { - DeepCopyMembers(other); - return *this; - } - - bool PresetSettings::operator==(const PresetSettings& other) const - { - bool arePointersEqual = true; - - /////// - // MipMap Settings - ////// - // If both pointers are allocated... - if (m_mipmapSetting && other.m_mipmapSetting) - { - // If the allocated values are different... - if (*m_mipmapSetting != *other.m_mipmapSetting) - { - arePointersEqual = false; - } - } - // Otherwise, one or both pointers are un-allocated. - // If only one pointer is allocated (via unequivalency)... - else if (m_mipmapSetting != other.m_mipmapSetting) - { - arePointersEqual = false; - } - /////// - // CubeMap Settings - ////// - // If both pointers are allocated... - if (m_cubemapSetting && other.m_cubemapSetting) - { - // If the allocated values are different... - if (*m_cubemapSetting != *other.m_cubemapSetting) - { - arePointersEqual = false; - } - } - // Otherwise, one or both pointers are un-allocated. - // If only one pointer is allocated (via unequivalency)... - else if (m_cubemapSetting != other.m_cubemapSetting) - { - arePointersEqual = false; - } - return - arePointersEqual && - m_uuid == other.m_uuid && - m_name == other.m_name && - m_description == other.m_description && - m_rgbWeight == other.m_rgbWeight && - m_srcColorSpace == other.m_srcColorSpace && - m_destColorSpace == other.m_destColorSpace && - m_fileMasks == other.m_fileMasks && - m_suppressEngineReduce == other.m_suppressEngineReduce && - m_pixelFormat == other.m_pixelFormat && - m_pixelFormatName == other.m_pixelFormatName && - m_pixelFormatAlpha == other.m_pixelFormatAlpha && - m_pixelFormatAlphaName == other.m_pixelFormatAlphaName && - m_discardAlpha == other.m_discardAlpha && - m_minTextureSize == other.m_minTextureSize && - m_maxTextureSize == other.m_maxTextureSize && - m_isPowerOf2 == other.m_isPowerOf2 && - m_sizeReduceLevel == other.m_sizeReduceLevel && - m_isColorChart == other.m_isColorChart && - m_highPassMip == other.m_highPassMip && - m_glossFromNormals == other.m_glossFromNormals && - m_isLegacyGloss == other.m_isLegacyGloss && - m_swizzle == other.m_swizzle && - m_isMipRenormalize == other.m_isMipRenormalize && - m_numStreamableMips == other.m_numStreamableMips; - } - - void PresetSettings::DeepCopyMembers(const PresetSettings & other) - { - if (this != &other) - { - if(other.m_mipmapSetting) - { - m_mipmapSetting = AZStd::make_unique(*other.m_mipmapSetting); - } - - if(other.m_cubemapSetting) - { - m_cubemapSetting = AZStd::make_unique(*other.m_cubemapSetting); - } - - m_uuid = other.m_uuid; - m_name = other.m_name; - m_description = other.m_description; - m_rgbWeight = other.m_rgbWeight; - m_srcColorSpace = other.m_srcColorSpace; - m_destColorSpace = other.m_destColorSpace; - m_fileMasks = other.m_fileMasks; - m_suppressEngineReduce = other.m_suppressEngineReduce; - m_pixelFormat = other.m_pixelFormat; - m_pixelFormatAlpha = other.m_pixelFormatAlpha; - m_pixelFormatName = other.m_pixelFormatName; - m_pixelFormatAlphaName = other.m_pixelFormatAlphaName; - m_discardAlpha = other.m_discardAlpha; - m_minTextureSize = other.m_minTextureSize; - m_maxTextureSize = other.m_maxTextureSize; - m_isPowerOf2 = other.m_isPowerOf2; - m_sizeReduceLevel = other.m_sizeReduceLevel; - m_isColorChart = other.m_isColorChart; - m_highPassMip = other.m_highPassMip; - m_glossFromNormals = other.m_glossFromNormals; - m_isLegacyGloss = other.m_isLegacyGloss; - m_swizzle = other.m_swizzle; - m_isMipRenormalize = other.m_isMipRenormalize; - m_numStreamableMips = other.m_numStreamableMips; - } - } - - AZ::Vector3 PresetSettings::GetColorWeight() - { - switch (m_rgbWeight) - { - case RGBWeight::uniform: - return AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - case RGBWeight::ciexyz: - return AZ::Vector3(0.2126f, 0.7152f, 0.0722f); - case RGBWeight::luminance: - return AZ::Vector3(0.3086f, 0.6094f, 0.0820f); - default: - AZ_Assert(false, "color weight value need to be added to new rgbWeight enum"); - return AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.h deleted file mode 100644 index fa881e853b..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/PresetSettings.h +++ /dev/null @@ -1,120 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - //settings for texture process preset - class PresetSettings - { - public: - AZ_TYPE_INFO(PresetSettings, "{935BCE3F-9E76-494E-9408-47C5937D7288}"); - AZ_CLASS_ALLOCATOR(PresetSettings, AZ::SystemAllocator, 0); - - PresetSettings(); - PresetSettings(const PresetSettings& other); - PresetSettings& operator= (const PresetSettings& other); - bool operator== (const PresetSettings& other) const; - static void Reflect(AZ::ReflectContext* context); - - //unique id for the preset - AZ::Uuid m_uuid; - - PresetName m_name; - - //a brief description for the usage of this Preset - AZStd::string m_description; - - //misc options - // "rgbweights". specify preset for weighting of R,G,B channels (used by compressor) - RGBWeight m_rgbWeight; - ColorSpace m_srcColorSpace; - ColorSpace m_destColorSpace; - - // file masks used for helping select default preset and option preset list in texture property dialog - AZStd::vector m_fileMasks; - - // "ser". Whether to enable supress reduce resolution (m_sizeReduceLevel) during loading, 0(default) - bool m_suppressEngineReduce; - - //pixel format - EPixelFormat m_pixelFormat; - AZStd::string m_pixelFormatName; - //pixel format for image which only contains alpha channel. this is for if we need to save alpha channel into a seperate image - EPixelFormat m_pixelFormatAlpha; - AZStd::string m_pixelFormatAlphaName; - bool m_discardAlpha; - - // Resolution related settings - - // "maxtexturesize", upper limit of the resolution of generated textures. It should be a power-of-2 number larger than 1 - // resulting texture will be downscaled if its width or height larger than this value - // 0 - no upper resolution limit (default) - unsigned int m_maxTextureSize; - - // "mintexturesize", lower limit of the resolution of generated textures.It should be a power-of-2 number larger than 1 - // resulting texture will be upscaled if its width or height smaller than this value - // 0 - no lower resolution limit (default) - unsigned int m_minTextureSize; - - bool m_isPowerOf2; - - //"reduce", 0=no size reduce /1=half resolution /2=quarter resolution, etc" - unsigned int m_sizeReduceLevel; - - //settings for cubemap generation. it's null if this preset is not for cubemap. - //"cm" equals 1 to enable cubemap in rc.ini - AZStd::unique_ptr m_cubemapSetting; - - //settings for mipmap generation. it's null if this preset disable mipmap. - AZStd::unique_ptr m_mipmapSetting; - - //some specific settings - // "colorchart". This is to indicate if need to extract color chart from the image and output the color chart data. - // This is very specific usage for cryEngine. Check ColorChart.cpp for better explaination. - bool m_isColorChart; - - //"highpass". Defines which mip level is subtracted when applying the high pass filter - //this is only used for terrain asset. we might remove it later since it can be done with source image directly - AZ::u32 m_highPassMip; - - //"glossfromnormals". Bake normal variance into smoothness stored in alpha channel - AZ::u32 m_glossFromNormals; - - //"mipnormalize". need normalize the rgb - bool m_isMipRenormalize; - - //function to get color's rgb weight in vec3 based on m_rgbWeight enum - //this is useful for squisher compression - AZ::Vector3 GetColorWeight(); - - //numstreamablemips - AZ::u32 m_numStreamableMips; - - //legacy options might be removed later - //"glosslegacydist". If the gloss map use legacy distribution. NW is still using legacy dist - bool m_isLegacyGloss; - - //"swizzle". need to be 4 character and each character need to be one of "rgba01" - AZStd::string m_swizzle; - - private: - void DeepCopyMembers(const PresetSettings& other); - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.cpp b/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.cpp deleted file mode 100644 index b465ec81f3..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.cpp +++ /dev/null @@ -1,589 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include -#include -#include -#include -#include -#include - -#include -#include - - -namespace ImageProcessing -{ - const char* TextureSettings::legacyExtensionName = ".exportsettings"; - const char* TextureSettings::modernExtensionName = ".imagesettings"; - - StringOutcome ParseLegacyTextureSettingString(AZStd::string& key, AZStd::string& value, TextureSettings& textureSettingOut) - { - // Parse only the settings we support for TextureSetting - if ("reduce" == key) // Example: reduce=0 - { - int reduce = AzFramework::StringFunc::ToInt(value.c_str()); - if (reduce >= 0) - { - textureSettingOut.m_sizeReduceLevel = reduce; - } - } - else if ("M" == key) // Example: M=50,50,0,50,50,50 - { - textureSettingOut.m_enableMipmap = true; - - AZStd::vector mipStringValues; - AzFramework::StringFunc::Tokenize(value.c_str(), mipStringValues, ','); - - for (size_t mipIndex = 0; mipIndex < mipStringValues.size(); ++mipIndex) - { - AZ::u32 mipValue = AzFramework::StringFunc::ToInt(mipStringValues[mipIndex].c_str()); - textureSettingOut.m_mipAlphaAdjust[mipIndex] = mipValue; - } - } - else if ("ser" == key) // Example: ser=1 - { - textureSettingOut.m_suppressEngineReduce = (value == "1"); - } - else if ("preset" == key) // Example: preset=NormalsWithSmoothness - { - AZ::Uuid presetUuid = BuilderSettingManager::Instance()->GetPresetIdFromName(value); - - // There's a chance the preset name still adheres to legacy preset naming convention (from CryEngine). - const PresetName translation = BuilderSettingManager::Instance()->TranslateLegacyPresetName(value); - AZ::Uuid translatedPresetUuid = BuilderSettingManager::Instance()->GetPresetIdFromName(translation); - - if (!presetUuid.IsNull()) - { - textureSettingOut.m_preset = presetUuid; - } - else if (!translatedPresetUuid.IsNull()) - { - textureSettingOut.m_preset = translatedPresetUuid; - } - else - { - AZ_Error("Image processing", false, "Can't find preset %s", value.c_str()); - } - } - else if ("mipgentype" == key) // Example: mipgentype=box - { - if ("box" == value || "average" == value) - { - textureSettingOut.m_mipGenType = MipGenType::box; - } - else if ("gauss" == value) - { - textureSettingOut.m_mipGenType = MipGenType::gaussian; - } - else if ("blackman-harris" == value) - { - textureSettingOut.m_mipGenType = MipGenType::blackmanHarris; - } - else if ("kaiser" == value) - { - textureSettingOut.m_mipGenType = MipGenType::kaiserSinc; - } - else if ("point" == value) - { - textureSettingOut.m_mipGenType = MipGenType::point; - } - else if ("quadric" == value) - { - textureSettingOut.m_mipGenType = MipGenType::quadratic; - } - else if ("triangle" == value) - { - textureSettingOut.m_mipGenType = MipGenType::triangle; - } - } - return STRING_OUTCOME_SUCCESS; - } - - TextureSettings::TextureSettings() - : m_preset(0) - , m_sizeReduceLevel(0) - , m_suppressEngineReduce(false) - , m_enableMipmap(true) - , m_maintainAlphaCoverage(false) - , m_mipGenEval(MipGenEvalType::sum) - , m_mipGenType(MipGenType::blackmanHarris) - { - const int defaultMipMapValue = 50; - - for (int i = 0; i < s_MaxMipMaps; ++i) - { - m_mipAlphaAdjust.push_back(defaultMipMapValue); - } - } - - void TextureSettings::Reflect(AZ::ReflectContext* context) - { - AZ::SerializeContext* serialize = azrtti_cast(context); - if (serialize) - { - serialize->Class() - ->Version(1) - ->Field("PresetID", &TextureSettings::m_preset) - ->Field("SizeReduceLevel", &TextureSettings::m_sizeReduceLevel) - ->Field("EngineReduce", &TextureSettings::m_suppressEngineReduce) - ->Field("EnableMipmap", &TextureSettings::m_enableMipmap) - ->Field("MaintainAlphaCoverage", &TextureSettings::m_maintainAlphaCoverage) - ->Field("MipMapAlphaAdjustments", &TextureSettings::m_mipAlphaAdjust) - ->Field("MipMapGenEval", &TextureSettings::m_mipGenEval) - ->Field("MipMapGenType", &TextureSettings::m_mipGenType) - ->Field("PlatformSpecificOverrides", &TextureSettings::m_platfromOverrides) - ->Field("OverridingPlatform", &TextureSettings::m_overridingPlatform); - - AZ::EditContext* edit = serialize->GetEditContext(); - if (edit) - { - edit->Class("Texture Setting", "") - ->ClassElement(AZ::Edit::ClassElements::EditorData, "") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::Visibility, AZ::Edit::PropertyVisibility::ShowChildrenOnly) - ->DataElement(AZ::Edit::UIHandlers::Default, &TextureSettings::m_mipAlphaAdjust, "Alpha Test Bias", "Multiplies the mipmap's alpha with a scale value that is based on alpha coverage. \ - Set the mip 0 to mip 5 values to offset the alpha test values and ensure the mipmap's alpha coverage matches the original image. Specify a value from 0 to 100.") - ->Attribute(AZ::Edit::Attributes::AutoExpand, true) - ->Attribute(AZ::Edit::Attributes::ContainerCanBeModified, false) - ->ElementAttribute(AZ::Edit::UIHandlers::Handler, AZ::Edit::UIHandlers::Slider) - ->ElementAttribute(AZ::Edit::Attributes::Min, 0) - ->ElementAttribute(AZ::Edit::Attributes::Max, 100) - ->ElementAttribute(AZ::Edit::Attributes::Step, 1) - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &TextureSettings::m_mipGenType, "Filter Method", "") - ->EnumAttribute(MipGenType::point, "Point") - ->EnumAttribute(MipGenType::box, "Average") - ->EnumAttribute(MipGenType::triangle, "Linear") - ->EnumAttribute(MipGenType::quadratic, "Bilinear") - ->EnumAttribute(MipGenType::gaussian, "Gaussian") - ->EnumAttribute(MipGenType::blackmanHarris, "BlackmanHarris") - ->EnumAttribute(MipGenType::kaiserSinc, "KaiserSinc") - ->DataElement(AZ::Edit::UIHandlers::ComboBox, &TextureSettings::m_mipGenEval, "Pixel Sampling Type", "") - ->EnumAttribute(MipGenEvalType::max, "Max") - ->EnumAttribute(MipGenEvalType::min, "Min") - ->EnumAttribute(MipGenEvalType::sum, "Sum") - ->DataElement(AZ::Edit::UIHandlers::CheckBox, &TextureSettings::m_maintainAlphaCoverage, "Maintain Alpha Coverage", "Select this option to manually adjust Alpha channel mipmaps.") - ; - } - } - - } - - bool TextureSettings::operator!=(const TextureSettings& other) const - { - return !(*this == other); - } - - bool TextureSettings::operator==(const TextureSettings& other) const - { - ///////////////////////////// - // Compare Alpha Adjust - ///////////////////////////// - bool matchingAlphaTestAdjust = true; - for (AZ::u8 curIndex = 0; curIndex < s_MaxMipMaps; ++curIndex) - { - if (m_mipAlphaAdjust[curIndex] != other.m_mipAlphaAdjust[curIndex]) - { - matchingAlphaTestAdjust = false; - break; - } - } - return - matchingAlphaTestAdjust && - m_preset == other.m_preset && - m_sizeReduceLevel == other.m_sizeReduceLevel && - m_suppressEngineReduce == other.m_suppressEngineReduce && - m_maintainAlphaCoverage == other.m_maintainAlphaCoverage && - m_mipGenEval == other.m_mipGenEval && - m_mipGenType == other.m_mipGenType; - } - - bool TextureSettings::Equals(const TextureSettings& other, AZ::SerializeContext* serializeContext) - { - ///////////////////////////// - // Compare Common Settings - ///////////////////////////// - if (*this != other) - { - return false; - } - - ///////////////////////////// - // Compare Overrides - ///////////////////////////// - const MultiplatformTextureSettings selfOverrides = GetMultiplatformTextureSetting(*this, serializeContext); - const MultiplatformTextureSettings otherOverrides = GetMultiplatformTextureSetting(other, serializeContext); - auto selfOverridesIter = selfOverrides.begin(); - auto otherOverridesIter = otherOverrides.begin(); - - while (selfOverridesIter != selfOverrides.end() && otherOverridesIter != otherOverrides.end()) - { - if (selfOverridesIter->second != otherOverridesIter->second) - { - return false; - } - otherOverridesIter++; - selfOverridesIter++; - } - - AZ_Assert(selfOverridesIter == selfOverrides.end() && otherOverridesIter == otherOverrides.end(), "Both iterators must be at the end by now.") - return true; - } - - float TextureSettings::ComputeMIPAlphaOffset(AZ::u32 mip) const - { - if (mip / 2 + 1 >= s_MaxMipMaps) - { - return 0; - } - - float fVal = static_cast(m_mipAlphaAdjust[s_MaxMipMaps - 1]); - if (mip / 2 + 1 < s_MaxMipMaps) - { - float fInterpolationSlider1 = static_cast(m_mipAlphaAdjust[mip / 2]); - float fInterpolationSlider2 = static_cast(m_mipAlphaAdjust[mip / 2 + 1]); - fVal = fInterpolationSlider1 + (fInterpolationSlider2 - fInterpolationSlider1) * (mip & 1) * 0.5f; - } - - return 0.5f - fVal / 100.0f; - } - - void TextureSettings::ApplyPreset(AZ::Uuid presetId) - { - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(presetId); - if (presetSetting != nullptr) - { - m_sizeReduceLevel = presetSetting->m_sizeReduceLevel; - m_suppressEngineReduce = presetSetting->m_suppressEngineReduce; - if (presetSetting->m_mipmapSetting) - { - m_mipGenType = presetSetting->m_mipmapSetting->m_type; - } - - m_preset = presetId; - } - else - { - AZ_Error("Image Processing", false, "Cannot set an invalid preset %s!", presetId.ToString().c_str()); - } - } - - StringOutcome TextureSettings::LoadTextureSetting(const AZStd::string& filepath, TextureSettings& textureSettingPtrOut, AZ::SerializeContext* serializeContext /*= nullptr*/) - { - auto loadedTextureSettingPtr = AZStd::unique_ptr(AZ::Utils::LoadObjectFromFile(filepath, serializeContext)); - - if (!loadedTextureSettingPtr) - { - return AZ::Failure(AZStd::string()); - } - - textureSettingPtrOut = *loadedTextureSettingPtr; - return AZ::Success(AZStd::string()); - } - - StringOutcome TextureSettings::WriteTextureSetting(const AZStd::string& filepath, TextureSettings& textureSetting, AZ::SerializeContext* serializeContext) - { - if(false == AZ::Utils::SaveObjectToFile(filepath, AZ::DataStream::StreamType::ST_XML, &textureSetting, serializeContext)) - { - return STRING_OUTCOME_ERROR("Failed to write to file: " + filepath); - } - - return STRING_OUTCOME_SUCCESS; - } - - StringOutcome TextureSettings::LoadLegacyTextureSetting(const AZStd::string& imagePath, const AZStd::string& contentString, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext) - { - AZStd::string trimmedContent = contentString; - AzFramework::StringFunc::TrimWhiteSpace(trimmedContent, true /* leading */, true /* trailing */); - if (trimmedContent.empty()) - { - return STRING_OUTCOME_ERROR("Empty legacy texture setting!"); - } - - AZStd::vector settings; - AZStd::vector overrideSettings; - - // Each setting begins with a forward-slash. - AzFramework::StringFunc::Tokenize(trimmedContent.c_str(), settings, " /"); // requires space character. - - // For each setting pair (field & value)... - for (AZStd::string& settingPair : settings) - { - // Split setting pair into key & value. - AZStd::string key, value; - { - AZStd::vector key_value; - AzFramework::StringFunc::Tokenize(settingPair.c_str(), key_value, '='); - if (key_value.size() == 2) - { - key = key_value[0]; - value = key_value[1]; - } - else - { - return STRING_OUTCOME_ERROR("Invalid format found in legacy texture setting: " + settingPair); - } - } - - bool containsPlatformOverrides = !value.empty() && (value[0] == '"' && value[value.length() - 1] == '"'); - if (containsPlatformOverrides) - { - // Process platform-specific overrides on the next loop. - overrideSettings.push_back(&settingPair); - continue; - } - - // Parse the common settings. - ParseLegacyTextureSettingString(key, value, textureSettingOut); - } - - // Some setting file won't assign a proper preset for the image, need to assign a suggested one here - if (textureSettingOut.m_preset.IsNull()) - { - textureSettingOut.m_preset = BuilderSettingManager::Instance()->GetSuggestedPreset(imagePath); - } - - // Store a temporary settings of all platforms intended to have overrides within this preset. - // We will collate all overrides per-platform to generate PatchData at the end. - MultiplatformTextureSettings overrideCache; - - // For each platform-specific override setting pair - for (AZStd::string* overrideSettingPair : overrideSettings) - { - // Split setting pair into key & value. - AZStd::string key, value; - { - AZStd::vector key_value; - AzFramework::StringFunc::Tokenize(overrideSettingPair->c_str(), key_value, '='); - - if (key_value.size() == 2) - { - key = key_value[0]; - value = key_value[1]; - } - else - { - return STRING_OUTCOME_ERROR("Invalid format found in legacy texture setting: " + *overrideSettingPair); - } - } - - // Chop the surrounding quotation marks. - AzFramework::StringFunc::LChop(value, 1); - AzFramework::StringFunc::RChop(value, 1); - - // Split the collection of platforms overrides into entries in a vector. - // Layout: { [platform0],[value0],[platform1],[value1],[platform2],[value2] } - AZStd::vector override_platform_value; - AzFramework::StringFunc::Tokenize(value.c_str(), override_platform_value, ",:"); - - if (override_platform_value.size() % 2 != 0) - { - return STRING_OUTCOME_ERROR("Invalid format found in legacy texture setting: " + value); - } - - for (int platformIdx = 0, valueIdx = 1; - valueIdx < override_platform_value.size(); - platformIdx += 2, valueIdx = platformIdx + 1) - { - PlatformName& overridePlatform = override_platform_value[platformIdx]; - AZStd::string& overrideValue = override_platform_value[valueIdx]; - - // Insert a copy of the base settings we've parsed from the legacy metafile. - overrideCache.insert(AZStd::pair(overridePlatform, textureSettingOut)); - - ParseLegacyTextureSettingString(key, overrideValue, overrideCache[overridePlatform]); - overrideCache[overridePlatform].m_overridingPlatform = overridePlatform; - overrideCache[overridePlatform].m_platfromOverrides.clear(); - } - } - - // Store the final result in a temp variable to do a whole-sale copy at the end. - TextureSettings finalResult = textureSettingOut; - - // Use the override cache to generate a DataPatch per-platform. - for (auto& overridePair : overrideCache) - { - // Every DataPatch is only a diff between a vanilla common-settings (with no platform-specific overrides) and the specified platform's override. - AZ::DataPatch platformOverridePatch; - platformOverridePatch.Create(&textureSettingOut, &overridePair.second,AZ::DataPatch::FlagsMap(), AZ::DataPatch::FlagsMap(), serializeContext); - finalResult.m_platfromOverrides.insert(AZStd::pair(overridePair.first, platformOverridePatch)); - } - - // Fully overwrite output variable. The only difference should be properly filled-out overrides. - textureSettingOut = finalResult; - - return STRING_OUTCOME_SUCCESS; - } - - StringOutcome TextureSettings::LoadLegacyTextureSettingFromFile(const AZStd::string& imagePath, const AZStd::string& filepath, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext) - { - AZStd::string fileContents; - - // Perform file I/O to read the contents of the metafile into the string above. - auto fileIoPtr = AZ::IO::FileIOBase::GetInstance(); - AZ::IO::HandleType fileHandle; - fileIoPtr->Open(filepath.c_str(), AZ::IO::OpenMode::ModeRead, fileHandle); - AZ::u64 fileSize = 0; - AZ::u64 bytesRead = 0; - fileIoPtr->Size(fileHandle, fileSize); - char* fileString = new char[fileSize + 1]; - fileIoPtr->Read(fileHandle, fileString, fileSize, false, &bytesRead); - fileIoPtr->Close(fileHandle); - fileString[bytesRead] = 0; - fileContents = fileString; - delete[] fileString; - - - return LoadLegacyTextureSetting(imagePath, fileContents, textureSettingOut, serializeContext); - } - - MultiplatformTextureSettings TextureSettings::GenerateDefaultMultiplatformTextureSettings(const AZStd::string& imageFilepath) - { - MultiplatformTextureSettings settings; - PlatformNameList platformsList = BuilderSettingManager::Instance()->GetPlatformList(); - AZ::Uuid suggestedPreset = BuilderSettingManager::Instance()->GetSuggestedPreset(imageFilepath); - if (!suggestedPreset.IsNull()) - { - for (PlatformName& platform : platformsList) - { - TextureSettings textureSettings; - textureSettings.ApplyPreset(suggestedPreset); - settings.insert(AZStd::pair(platform, textureSettings)); - } - } - return settings; - } - - StringOutcome TextureSettings::GetPlatformSpecificTextureSetting(const PlatformName& platformName, const TextureSettings& baseTextureSettings, - TextureSettings& textureSettingsOut, AZ::SerializeContext* serializeContext) - { - // Obtain the DataPatch (if platform exists) - auto overrideIter = baseTextureSettings.m_platfromOverrides.find(platformName); - if (overrideIter == baseTextureSettings.m_platfromOverrides.end()) - { - return STRING_OUTCOME_ERROR(AZStd::string::format("TextureSettings preset [%s] does not have override for platform [%s]", - baseTextureSettings.m_preset.ToString().c_str(), platformName.c_str())); - } - AZ::DataPatch& platformOverride = const_cast(overrideIter->second); - - // Update settings instance with override values. - if (platformOverride.IsData()) - { - // Apply the AZ::DataPatch to obtain a platform-overridden version of the TextureSettings. - AZStd::unique_ptr platformSpecificTextureSettings(platformOverride.Apply(&baseTextureSettings, serializeContext)); - AZ_Assert(platformSpecificTextureSettings->m_mipAlphaAdjust.size() == s_MaxMipMaps, "Unexpected m_mipAlphaAdjust size."); - - // Adjust overrides data to imply 'platformSpecificTextureSettings' *IS* the override. - platformSpecificTextureSettings->m_platfromOverrides.clear(); - platformSpecificTextureSettings->m_overridingPlatform = platformName; - textureSettingsOut = *platformSpecificTextureSettings; - } - else - { - textureSettingsOut = baseTextureSettings; - } - - return STRING_OUTCOME_SUCCESS; - } - - const MultiplatformTextureSettings TextureSettings::GetMultiplatformTextureSetting(const TextureSettings& textureSettings, AZ::SerializeContext* serializeContext) - { - MultiplatformTextureSettings loadedSettingsReturn; - PlatformNameList platformsList = BuilderSettingManager::Instance()->GetPlatformList(); - // Generate MultiplatformTextureSettings based on existing available overrides. - for (const PlatformName& curPlatformName : platformsList) - { - // Start with a copy of the base settings - TextureSettings curPlatformOverride = textureSettings; - if (!GetPlatformSpecificTextureSetting(curPlatformName, textureSettings, curPlatformOverride, serializeContext).IsSuccess()) - { - // We have failed to obtain an override. Maintain base settings to indicate zero overrides. - // We still want to designate these TextureSettings as an (empty) override. - curPlatformOverride.m_platfromOverrides.clear(); - curPlatformOverride.m_overridingPlatform = curPlatformName; - } - - // Add as an entry to the multiplatform texture settings - loadedSettingsReturn.insert(AZStd::pair(curPlatformName, curPlatformOverride)); - } - - // return a copy of the results - return loadedSettingsReturn; - } - - const MultiplatformTextureSettings TextureSettings::GetMultiplatformTextureSetting(const AZStd::string& imageFilepath, bool& canOverridePreset, AZ::SerializeContext* serializeContext) - { - TextureSettings loadedTextureSetting; - - // Attempt to get metadata filepath from image path. - AZStd::string legacyMetadataFilepath = imageFilepath + legacyExtensionName; - AZStd::string modernMetadataFilepath = imageFilepath + modernExtensionName; - bool hasLegacyMetafile = AZ::IO::SystemFile::Exists(legacyMetadataFilepath.c_str()); - bool hasModernMetafile = AZ::IO::SystemFile::Exists(modernMetadataFilepath.c_str()); - - // If the image has an accompanying metadata... - if(hasModernMetafile) - { - // Parse the metadata file. - if (!LoadTextureSetting(modernMetadataFilepath, loadedTextureSetting, serializeContext).IsSuccess()) - { - canOverridePreset = true; - return GenerateDefaultMultiplatformTextureSettings(imageFilepath); - } - } - else if (hasLegacyMetafile) - { - if (!LoadLegacyTextureSettingFromFile(imageFilepath, legacyMetadataFilepath, loadedTextureSetting, serializeContext).IsSuccess()) - { - canOverridePreset = true; - return GenerateDefaultMultiplatformTextureSettings(imageFilepath); - } - } - else - { - canOverridePreset = true; // RC could override settings if it was loaded from the image so this is set to - // true regardless of whether settings existed in the texture for compatibility. - // Try to load from image file if it has embedded setting file - AZStd::string embeddedString = LoadEmbeddedSettingFromFile(imageFilepath); - if (!LoadLegacyTextureSetting(imageFilepath, embeddedString, loadedTextureSetting, serializeContext).IsSuccess()) - { - // If the texture has neither of legacy/modern meta file nor embedded setting, generate data for a new metadata file. - return GenerateDefaultMultiplatformTextureSettings(imageFilepath); - } - } - - // Generate MultiplatformTextureSettings based on the loaded texture setting. - return GetMultiplatformTextureSetting(loadedTextureSetting, serializeContext); - } - - StringOutcome TextureSettings::ApplySettings(const TextureSettings& settings, const PlatformName& overridePlatform, AZ::SerializeContext* serializeContext) - { - if (overridePlatform.empty()) - { - *this = settings; - } - else - { - AZ::DataPatch newOverride; - if (false == newOverride.Create(this, &settings, AZ::DataPatch::FlagsMap(), AZ::DataPatch::FlagsMap(), serializeContext)) - { - return STRING_OUTCOME_ERROR("Failed to create TextureSettings platform override data. See AZ_Error log for details."); - } - - m_platfromOverrides[overridePlatform] = newOverride; - } - - return STRING_OUTCOME_SUCCESS; - } -} diff --git a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.h b/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.h deleted file mode 100644 index 2ecc2c0a96..0000000000 --- a/Gems/ImageProcessing/Code/Source/BuilderSettings/TextureSettings.h +++ /dev/null @@ -1,171 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include - -namespace ImageProcessing -{ - class TextureSettings; - typedef AZStd::map MultiplatformTextureSettings; - - class TextureSettings - { - public: - AZ_TYPE_INFO(TextureSettings, "{CC3ED018-7FF7-4233-AAD8-6D3115FD844A}"); - AZ_CLASS_ALLOCATOR(TextureSettings, AZ::SystemAllocator, 0); - - TextureSettings(); - float ComputeMIPAlphaOffset(AZ::u32 mip) const; - void ApplyPreset(AZ::Uuid presetId); - - /** - * Performs a comprehensive comparison between two TextureSettings instances. - * @param Reference to the settings which will be compared. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return True, is both instances are equivalent. - */ - bool Equals(const TextureSettings& other, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Applies texture settings to the instance (including overrides). Common settings are applied, unless specific platform is specified. - * @param Reference to the settings which will be applied. - * @param Optional. Applies settings as a platform override if a platform is specified. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - StringOutcome ApplySettings(const TextureSettings& settings, const PlatformName& overridePlatform = PlatformName(), AZ::SerializeContext* serializeContext = nullptr); - - /** - * Gets platform-specific texture settings obtained from the base settings version of a pre-loaded TextureSettings instance. - * @param Name of platform to get the settings from. - * @param Base TextureSettings which we will get overrides from. - * @param Output TextureSettings which will contain the result of the function. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome GetPlatformSpecificTextureSetting(const PlatformName& platformName, const TextureSettings& baseTextureSettings, TextureSettings& textureSettingsOut, AZ::SerializeContext* serializeContext = nullptr); - - static void Reflect(AZ::ReflectContext* context); - - - /** - * Loads base texture settings obtained from ".exportsettings" file (legacy setting) - * @param ImagePath absolute/relative path of the image file. - * @param FilePath absolute/relative path of the ".exportsettings" file. - * @param Output TextureSettings which contain the result of the function, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome LoadLegacyTextureSettingFromFile(const AZStd::string& imagePath, const AZStd::string& filepath, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Loads base texture settings obtained from a legacy setting string - * @param ImagePath absolute/relative path of the image file. - * @param Content string of the legacy setting to be read. - * @param Output TextureSettings which contain the result of the function, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome LoadLegacyTextureSetting(const AZStd::string& imagePath, const AZStd::string& contentString, TextureSettings& textureSettingOut, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Loads base texture settings obtained from ".imagesettings" file (modern setting) - * @param FilePath absolute/relative path of the ".imagesettings" file. - * @param Output TextureSettings which contain the result of the function, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome LoadTextureSetting(const AZStd::string& filepath, TextureSettings& textureSettingPtrOut, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Writes base texture settings to a ".imagesettings" file (modern setting) - * @param FilePath absolute/relative path of the ".imagesettings" file. - * @param TextureSetting to be written on the disk, it may contains platform-specific overrides. - * @param Optional. Serialize context. Will use global context if none is provided. - * @return Status outcome result. - */ - static StringOutcome WriteTextureSetting(const AZStd::string& filepath, TextureSettings& textureSetting, AZ::SerializeContext* serializeContext = nullptr); - - // Generates a MultiplatformTextureSettings collection with default texture settings for all - static MultiplatformTextureSettings GenerateDefaultMultiplatformTextureSettings(const AZStd::string& imageFilepath); - - /** - * Generates a TextureSetting instance of a particular image file for each supported platform. - * @param filepath - A path to the texture file. - * @param canOverridePreset - Returns whether the preset can be overriden. Will return false if the preset was selecting from a settings file created by the user. - * @param serializeContext - Optional. Serialize context used for reflection/serialization - * @return - The collection of TextureSetting instances. If error occurs, a default MultiplatformTextureSettings is returned (see GenerateDefaultMultiplatformTextureSettings()). - */ - static const MultiplatformTextureSettings GetMultiplatformTextureSetting(const AZStd::string& filepath, bool& canOverridePreset, AZ::SerializeContext* serializeContext = nullptr); - - /** - * Generates a TextureSetting instance of a particular image file for each supported platform. - * @param textureSettings - A reference to an already-loaded texture settings. - * @param serializeContext - Optional. Serialize context used for reflection/serialization - * @return - The collection of TextureSetting instances. If error occurs, a default MultiplatformTextureSettings is returned (see GenerateDefaultMultiplatformTextureSettings()). - */ - static const MultiplatformTextureSettings GetMultiplatformTextureSetting(const TextureSettings& textureSettings, AZ::SerializeContext* serializeContext = nullptr); - - static const char* legacyExtensionName; - static const char* modernExtensionName; - static const size_t s_MaxMipMaps = 6; - - // uuid of selected preset for this texture - AZ::Uuid m_preset; - - // texture size reduce level. the value of this variable will override the same variable in PresetSettings - unsigned int m_sizeReduceLevel; - - // "ser". Whether to enable supress reduce resolution (m_sizeReduceLevel) during loading, 0(default) - // the value of this variable will override the same variable in PresetSettings - bool m_suppressEngineReduce; - - //enable generate mipmap or not - bool m_enableMipmap; - - //"mc". not used in rc.ini. experiemental - //maybe relate to http://the-witness.net/news/2010/09/computing-alpha-mipmaps/ - bool m_maintainAlphaCoverage; - - // "M", adjust mipalpha, 0..50=normal..100. associate with ComputeMIPAlphaOffset function - // only useful if m_maintainAlphaCoverage set to true. - // This data type MUST be an AZStd::vector, even though we treat is as a fixed array. This is due to a limitation - // during AZ::DataPatch serialization, where an element is allocated one by one while extending the container.. - AZStd::vector m_mipAlphaAdjust; - - MipGenEvalType m_mipGenEval; - - MipGenType m_mipGenType; - - private: - // Platform overrides in form of DataPatch. Each entry is a patch for a specified platform. - // This map is used to generate TextureSettings with overridden values. The map is empty if - // the instance is for platform-specific settings. - AZStd::map m_platfromOverrides; - - // The platform which these settings override. - // Blank if the instance is for common settings. - PlatformName m_overridingPlatform; - - // Comparison operators only compare the base settings, they do not compare overrides. - // For a comprehensive equality comparison, use Equals() function. - bool operator==(const TextureSettings& other) const; - bool operator!=(const TextureSettings& other) const; - - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.cpp deleted file mode 100644 index efb9d85cab..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.cpp +++ /dev/null @@ -1,387 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -#include - -namespace ImageProcessing -{ - struct CrySquisherCallbackUserData - { - IImageObjectPtr m_pImageObject; - AZ::u8* m_dstMem; - AZ::u32 m_dstOffset; - }; - - // callbacks for the CryTextureSquisher - void CrySquisherOutputCallback(const CryTextureSquisher::CompressorParameters& compress, const void* data, AZ::u32 size, AZ::u32 oy, AZ::u32 ox) - { - CrySquisherCallbackUserData* const pUserData = (CrySquisherCallbackUserData*)compress.userPtr; - - AZ::u32 stride = (compress.width + 3) >> 2; - AZ::u32 blocks = (compress.height + 3) >> 2; - memcpy(pUserData->m_dstMem + size * (stride * oy + ox), data, size); - pUserData->m_dstOffset = size * (stride * blocks); - } - - void CrySquisherInputCallback(const CryTextureSquisher::DecompressorParameters& decompress, void* data, AZ::u32 size, AZ::u32 oy, AZ::u32 ox) - { - CrySquisherCallbackUserData* const pUserData = (CrySquisherCallbackUserData*)decompress.userPtr; - AZ::u32 stride = (decompress.width + 3) >> 2; - AZ::u32 blocks = (decompress.height + 3) >> 2; - - //assert(CPixelFormats::GetPixelFormatInfo(pUserData->m_pImageObject->GetPixelFormat())->bCompressed); - - memcpy(data, pUserData->m_dstMem + size * (stride * oy + ox), size); - - pUserData->m_dstOffset = size * (stride * blocks); - } - - - CryTextureSquisher::ECodingPreset CTSquisher::GetCompressPreset(EPixelFormat compressFmt, EPixelFormat uncompressFmt) - { - CryTextureSquisher::ECodingPreset preset = CryTextureSquisher::eCompressorPreset_Num; - switch (compressFmt) - { - case ePixelFormat_BC1: - preset = CryTextureSquisher::eCompressorPreset_BC1U; - break; - case ePixelFormat_BC1a: - preset = CryTextureSquisher::eCompressorPreset_BC1Ua; - break; - case ePixelFormat_BC3: - preset = CryTextureSquisher::eCompressorPreset_BC3U; - break; - case ePixelFormat_BC3t: - preset = CryTextureSquisher::eCompressorPreset_BC3Ut; - break; - case ePixelFormat_BC4: - preset = (CPixelFormats::GetInstance().IsFormatSingleChannel(uncompressFmt) - ? CryTextureSquisher::eCompressorPreset_BC4Ua // a-channel - : CryTextureSquisher::eCompressorPreset_BC4U); // r-channel - break; - case ePixelFormat_BC4s: - preset = (CPixelFormats::GetInstance().IsFormatSingleChannel(uncompressFmt) - ? CryTextureSquisher::eCompressorPreset_BC4Sa // a-channel - : CryTextureSquisher::eCompressorPreset_BC4S); // r-channel - break; - case ePixelFormat_BC5: - preset = CryTextureSquisher::eCompressorPreset_BC5Un; - break; - case ePixelFormat_BC5s: - preset = CryTextureSquisher::eCompressorPreset_BC5Sn; - break; - case ePixelFormat_BC6UH: - preset = CryTextureSquisher::eCompressorPreset_BC6UH; - break; - case ePixelFormat_BC7: - preset = CryTextureSquisher::eCompressorPreset_BC7U; - break; - case ePixelFormat_BC7t: - preset = CryTextureSquisher::eCompressorPreset_BC7Ut; - break; - default: - AZ_Assert(false, "%s: Unexpected pixel format (in compressing an image). Inform an RC programmer.", __FUNCTION__); - } - - return preset; - } - - bool CTSquisher::IsCompressedPixelFormatSupported(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_BC1: - case ePixelFormat_BC1a: - case ePixelFormat_BC3: - case ePixelFormat_BC3t: - case ePixelFormat_BC4: - case ePixelFormat_BC4s: - case ePixelFormat_BC5: - case ePixelFormat_BC5s: - case ePixelFormat_BC6UH: - case ePixelFormat_BC7: - case ePixelFormat_BC7t: - return true; - default: - return false; - } - } - - bool CTSquisher::IsUncompressedPixelFormatSupported(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_R8: - case ePixelFormat_A8: - case ePixelFormat_R8G8B8A8: - case ePixelFormat_R8G8B8X8: - case ePixelFormat_R32F: - case ePixelFormat_R32G32B32A32F: - return true; - default: - return false; - } - } - - bool CTSquisher::DoesSupportDecompress([[maybe_unused]] EPixelFormat fmtDst) - { - return true; - } - - EPixelFormat CTSquisher::GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) - { - //special cases - if (compressedfmt == ePixelFormat_BC6UH || compressedfmt == ePixelFormat_BC5 || compressedfmt == ePixelFormat_BC5s) - { - return ePixelFormat_R32G32B32A32F; - } - - if (IsUncompressedPixelFormatSupported(uncompressedfmt)) - { - return uncompressedfmt; - } - - //for fmt dont support, convert to supported uncompressed formats: ePixelFormat_A8, ePixelFormat_R8, ePixelFormat_A8R8G8B8, - // ePixelFormat_X8R8G8B8, ePixelFormat_R32F, ePixelFormat_A32B32G32R32F - - switch (uncompressedfmt) - { - case ePixelFormat_R8G8: - case ePixelFormat_R16G16: - return ePixelFormat_R8G8B8X8; - case ePixelFormat_R16: - return ePixelFormat_R8; - case ePixelFormat_R16G16B16A16: - case ePixelFormat_B8G8R8A8: - return ePixelFormat_R8G8B8A8; - case ePixelFormat_R9G9B9E5: - case ePixelFormat_R32G32F: - case ePixelFormat_R16G16B16A16F: - case ePixelFormat_R16G16F: - return ePixelFormat_R32G32B32A32F; - case ePixelFormat_R16F: - return ePixelFormat_R32F; - default: - //this shouldn't happen. but we could handle it with uncompressed data anyway - if (CPixelFormats::GetInstance().IsPixelFormatWithoutAlpha(uncompressedfmt)) - { - return ePixelFormat_R8G8B8X8; - } - else - { - return ePixelFormat_R8G8B8A8; - } - } - } - - IImageObjectPtr CTSquisher::DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) - { - // Decompressing - // the output pixel format could only have one channel or four channels. need to find out more - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be compressed and dst format need to uncompressed. - if (!IsCompressedPixelFormatSupported(fmtSrc) || !IsUncompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //clear the dstImage to (0, 0, 0, 1) since some compression format only write to certain channels - dstImage->ClearColor(0, 0, 0, 1); - - //for each mipmap - const AZ::u32 mipCount = srcImage->GetMipCount(); - for (AZ::u32 dwMip = 0; dwMip < mipCount; ++dwMip) - { - const AZ::u32 dwLocalWidth = srcImage->GetWidth(dwMip); - const AZ::u32 dwLocalHeight = srcImage->GetHeight(dwMip); - - AZ::u8* pSrcMem; - AZ::u32 dwSrcPitch; - srcImage->GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - AZ::u8* pDstMem; - AZ::u32 dwDstPitch; - dstImage->GetImagePointer(dwMip, pDstMem, dwDstPitch); - - CrySquisherCallbackUserData userData; - userData.m_pImageObject = srcImage; - userData.m_dstOffset = 0; - userData.m_dstMem = pSrcMem; - - CryTextureSquisher::DecompressorParameters decompress; - - decompress.dstBuffer = pDstMem; - decompress.width = dwLocalWidth; - decompress.height = dwLocalHeight; - decompress.pitch = dwDstPitch; - - decompress.dstType = (CPixelFormats::GetInstance().IsFormatFloatingPoint(fmtDst, true) ? - CryTextureSquisher::eBufferType_ufloat : CryTextureSquisher::eBufferType_uint8); - - if (CPixelFormats::GetInstance().IsFormatSigned(fmtSrc)) - { - decompress.dstType = (decompress.dstType == CryTextureSquisher::eBufferType_ufloat ? - CryTextureSquisher::eBufferType_sfloat : CryTextureSquisher::eBufferType_sint8); - } - - decompress.userPtr = &userData; - decompress.userInputFunction = CrySquisherInputCallback; - decompress.preset = GetCompressPreset(fmtSrc, fmtDst); - - CryTextureSquisher::Decompress(decompress); - } - - // CTsquish operates on native normal vectors when floating-point - // buffers are used. Apply bias and scale when returning a normal-map. - if (fmtSrc == ePixelFormat_BC5 || fmtSrc == ePixelFormat_BC5s) - { - if (fmtDst == ePixelFormat_R32G32B32A32F) - { - //conver from [-1, 1] to [0, 1]. And set alpha to 1. - dstImage->ScaleAndBiasChannels(0, 100, - AZ::Vector4(0.5f, 0.5f, 0.5f, 0.0f), - AZ::Vector4(0.5f, 0.5f, 0.5f, 1.0f)); - } - } - - return dstImage; - } - - /////////////////////////////////////////////////////////////////////////////////// - IImageObjectPtr CTSquisher::CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, - const CompressOption *compressOption) - { - // Compressing - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be uncompressed and dst format need to compressed. - if (!IsUncompressedPixelFormatSupported(fmtSrc) || !IsCompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //passing compress option - ICompressor::EQuality quality = ICompressor::eQuality_Normal; - AZ::Vector3 weights = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - if (compressOption) - { - quality = compressOption->compressQuality; - weights = compressOption->rgbWeight; - } - - //do some clamp for float - if (fmtSrc == ePixelFormat_R32G32B32A32F) - { - const uint32 nMips = srcImage->GetMipCount(); - - // NOTES: - // - all incoming images are unsigned, even normal maps - // - all mipmaps of incoming images can contain out-of-range values from mipmap filtering - // - 3Dc/BC5 is synonymous with "is a normal map" because they are not tagged explicitly as such - if (fmtDst == ePixelFormat_BC5 || fmtDst == ePixelFormat_BC5s) - { - srcImage->ScaleAndBiasChannels(0, nMips, - AZ::Vector4(2.0f, 2.0f, 2.0f, 1.0f), - AZ::Vector4(-1.0f, -1.0f, -1.0f, 0.0f)); - srcImage->ClampChannels(0, nMips, - AZ::Vector4(-1.0f, -1.0f, -1.0f, -1.0f), - AZ::Vector4(1.0f, 1.0f, 1.0f, 1.0f)); - } - else if (fmtDst == ePixelFormat_BC6UH) - { - srcImage->ClampChannels(0, nMips, - AZ::Vector4(0.0f, 0.0f, 0.0f, 0.0f), - AZ::Vector4(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX)); - } - else - { - srcImage->ClampChannels(0, nMips, - AZ::Vector4(0.0f, 0.0f, 0.0f, 0.0f), - AZ::Vector4(1.0f, 1.0f, 1.0f, 1.0f)); - } - } - - const uint32 mipCount = dstImage->GetMipCount(); - for (uint32 dwMip = 0; dwMip < mipCount; ++dwMip) - { - uint32 dwLocalWidth = srcImage->GetWidth(dwMip); - uint32 dwLocalHeight = srcImage->GetHeight(dwMip); - - uint8* pSrcMem; - uint32 dwSrcPitch; - srcImage->GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - uint8* pDstMem; - uint32 dwDstPitch; - dstImage->GetImagePointer(dwMip, pDstMem, dwDstPitch); - - { - CrySquisherCallbackUserData userData; - userData.m_pImageObject = dstImage; - userData.m_dstOffset = 0; - userData.m_dstMem = pDstMem; - - CryTextureSquisher::CompressorParameters compress; - - compress.srcBuffer = pSrcMem; - compress.width = dwLocalWidth; - compress.height = dwLocalHeight; - compress.pitch = dwSrcPitch; - - compress.srcType = (CPixelFormats::GetInstance().IsFormatFloatingPoint(fmtSrc, true) ? - CryTextureSquisher::eBufferType_ufloat : CryTextureSquisher::eBufferType_uint8); - if (CPixelFormats::GetInstance().IsFormatSigned(fmtDst)) - { - compress.srcType = (compress.srcType == CryTextureSquisher::eBufferType_ufloat ? - CryTextureSquisher::eBufferType_sfloat : CryTextureSquisher::eBufferType_sint8); - } - - const AZ::Vector3 uniform = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - - compress.weights[0] = weights.GetX(); - compress.weights[1] = weights.GetY(); - compress.weights[2] = weights.GetZ(); - - compress.perceptual = - (compress.weights[0] != uniform.GetX()) || - (compress.weights[1] != uniform.GetY()) || - (compress.weights[2] != uniform.GetZ()); - - compress.quality = - (quality == eQuality_Preview ? CryTextureSquisher::eQualityProfile_Low : - (quality == eQuality_Fast ? CryTextureSquisher::eQualityProfile_Low : - (quality == eQuality_Slow ? CryTextureSquisher::eQualityProfile_High : - CryTextureSquisher::eQualityProfile_Medium))); - - compress.userPtr = &userData; - compress.userOutputFunction = CrySquisherOutputCallback; - compress.preset = GetCompressPreset(fmtDst, fmtSrc); - - CryTextureSquisher::Compress(compress); - } - } // for: all mips - - return dstImage; - } - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.h b/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.h deleted file mode 100644 index 6cb08ac295..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CTSquisher.h +++ /dev/null @@ -1,38 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - //Cry Texture Squisher for all the BC compressions - class CTSquisher : public ICompressor - { - public: - static bool IsCompressedPixelFormatSupported(EPixelFormat fmt); - static bool IsUncompressedPixelFormatSupported(EPixelFormat fmt); - static bool DoesSupportDecompress(EPixelFormat fmtDst); - - IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) override; - IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) override; - - EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) override; - - - private: - static CryTextureSquisher::ECodingPreset GetCompressPreset(EPixelFormat compressFmt, EPixelFormat uncompressFmt); - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.cpp b/Gems/ImageProcessing/Code/Source/Compressors/Compressor.cpp deleted file mode 100644 index fe151d8954..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -namespace ImageProcessing -{ - ICompressorPtr ICompressor::FindCompressor(EPixelFormat fmt, bool isCompressing) - { - if (CTSquisher::IsCompressedPixelFormatSupported(fmt)) - { - if (isCompressing || (!isCompressing && CTSquisher::DoesSupportDecompress(fmt))) - { - return ICompressorPtr(new CTSquisher()); - } - } - - // Both ETC2Compressor and PVRTCCompressor can process ETC formats - // According to Mobile team, Etc2Com is faster than PVRTexLib, so we check with ETC2Compressor before PVRTCCompressor - // Note: with the test I have done, I found out it cost similar time for both Etc2Com and PVRTexLib to compress - // a 2048x2048 test texture to EAC_R11 and EAC_RG11. It was around 7 minutes for EAC_R11 and 14 minutes for EAC_RG11 - if (ETC2Compressor::IsCompressedPixelFormatSupported(fmt)) - { - if (isCompressing || (!isCompressing && ETC2Compressor::DoesSupportDecompress(fmt))) - { - return ICompressorPtr(new ETC2Compressor()); - } - } - - if (PVRTCCompressor::IsCompressedPixelFormatSupported(fmt)) - { - if (isCompressing || (!isCompressing && PVRTCCompressor::DoesSupportDecompress(fmt))) - { - return ICompressorPtr(new PVRTCCompressor()); - } - } - - return nullptr; - } - - ICompressor::~ICompressor() - { - - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.h b/Gems/ImageProcessing/Code/Source/Compressors/Compressor.h deleted file mode 100644 index 14fb6d2b9a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/Compressor.h +++ /dev/null @@ -1,56 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - class ICompressor; - typedef AZStd::shared_ptr ICompressorPtr; - - //the interface base class for any compressors which can decompress/compress image with compressed pixel format - class ICompressor - { - public: - enum EQuality - { - eQuality_Preview, // for the 256x256 preview only - eQuality_Fast, - eQuality_Normal, - eQuality_Slow, - }; - - //some extra information required for different compressors. - //keep is a simple structure for now. - struct CompressOption - { - EQuality compressQuality = eQuality_Normal; - //required for CTSquisher - AZ::Vector3 rgbWeight = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - }; - - public: - //compress the source image to desired compressed pixel format - virtual IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) = 0; - virtual IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) = 0; - virtual EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) = 0; - - //find compressor for specified compressed pixel format. isCompressing to indicate if it's for compressing or decompressing - static ICompressorPtr FindCompressor(EPixelFormat fmt, bool isCompressing); - - virtual ~ICompressor() = 0; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp deleted file mode 100644 index b436e7bbc2..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include - -#include "ColorBlockRGBA4x4c.h" - -namespace ImageProcessing -{ - static_assert(sizeof(int) == 4, "Expected size of int to be 4 bytes!"); - - void ColorBlockRGBA4x4c::setRGBA8(const void* imgBGRA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgBGRA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint8* const pSrc = ((const uint8*)imgBGRA8) + (pitch * (y + row)) + (x * sizeof(ColorRGBA8)); - - ColorRGBA8* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(&pSrc[0 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - pDst[1].setRGBA(&pSrc[1 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - pDst[2].setRGBA(&pSrc[2 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - pDst[3].setRGBA(&pSrc[3 * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint8* const pSrc = ((const uint8*)imgBGRA8) + pitch * (y + by); - - ColorRGBA8* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(&pSrc[(x + bx) * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4c::getRGBA8(void* imgRGBA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgRGBA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint8* const pDst = ((uint8*)imgRGBA8) + (pitch * (y + row)) + (x * sizeof(ColorRGBA8)); - - const ColorRGBA8* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(&pDst[0 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - pSrc[1].getRGBA(&pDst[1 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - pSrc[2].getRGBA(&pDst[2 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - pSrc[3].getRGBA(&pDst[3 * sizeof(ColorRGBA8) / sizeof(*pDst)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint8* const pDst = ((uint8*)imgRGBA8) + pitch * (y + by); - - const ColorRGBA8* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(&pDst[(x + bx) * sizeof(ColorRGBA8) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4c::setA8(const void* imgA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint8* const pSrc = ((const uint8*)imgA8) + (pitch * (y + row)) + (x * sizeof(uint8)); - - ColorRGBA8* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(0, 0, 0, pSrc[0]); - pDst[1].setRGBA(0, 0, 0, pSrc[1]); - pDst[2].setRGBA(0, 0, 0, pSrc[2]); - pDst[3].setRGBA(0, 0, 0, pSrc[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint8* const pSrc = ((const uint8*)imgA8) + pitch * (y + by); - - ColorRGBA8* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(0, 0, 0, pSrc[x + bx]); - } - } - } - } - - void ColorBlockRGBA4x4c::getA8(void* imgA8, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA8, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA8* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint8* const pDst = ((uint8*)imgA8) + (pitch * (y + row)) + (x * sizeof(uint8)); - uint8 r, g, b; - - const ColorRGBA8* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(r, g, b, pDst[0]); - pSrc[1].getRGBA(r, g, b, pDst[1]); - pSrc[2].getRGBA(r, g, b, pDst[2]); - pSrc[3].getRGBA(r, g, b, pDst[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint8* const pDst = ((uint8*)imgA8) + pitch * (y + by); - uint8 r, g, b; - - const ColorRGBA8* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(r, g, b, pDst[x + bx]); - } - } - } - } - - bool ColorBlockRGBA4x4c::isSingleColorIgnoringAlpha() const - { - for (unsigned int i = 1; i < COLOR_COUNT; ++i) - { - if ((m_color[0].b != m_color[i].b) || - (m_color[0].g != m_color[i].g) || - (m_color[0].r != m_color[i].r)) - { - return false; - } - } - - return true; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h deleted file mode 100644 index 06f0ac00ed..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - - -#include "ColorTypes.h" - -namespace ImageProcessing -{ - // Uncompressed 4x4 color block of 8bit integers. - struct ColorBlockRGBA4x4c - { - ColorBlockRGBA4x4c() - { - } - - void setRGBA8(const void* imgBGRA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getRGBA8(void* imgBGRA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - void setA8(const void* imgA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getA8(void* imgA8, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - bool isSingleColorIgnoringAlpha() const; - - const ColorRGBA8* colors() const - { - return m_color; - } - - ColorRGBA8* colors() - { - return m_color; - } - - ColorRGBA8 color(unsigned int i) const - { - return m_color[i]; - } - - ColorRGBA8& color(unsigned int i) - { - return m_color[i]; - } - - private: - static const unsigned int COLOR_COUNT = 4 * 4; - - ColorRGBA8 m_color[COLOR_COUNT]; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp deleted file mode 100644 index 20db26100a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp +++ /dev/null @@ -1,282 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include - -#include "ColorBlockRGBA4x4f.h" - -namespace ImageProcessing -{ - static_assert(sizeof(int) == 4, "Expected size of int to be 4 bytes!"); - - void ColorBlockRGBA4x4f::setRGBAf(const void* imgRGBAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgRGBAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBAf), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const float* const pSrc = (const float*)(((const uint8*)imgRGBAf) + (pitch * (y + row)) + (x * sizeof(ColorRGBAf))); - - ColorRGBAf* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(&pSrc[0 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - pDst[1].setRGBA(&pSrc[1 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - pDst[2].setRGBA(&pSrc[2 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - pDst[3].setRGBA(&pSrc[3 * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const float* const pSrc = (const float*)(((const uint8*)imgRGBAf) + pitch * (y + by)); - - ColorRGBAf* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(&pSrc[(x + bx) * sizeof(ColorRGBAf) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4f::getRGBAf(void* imgRGBAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgRGBAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBAf), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - float* const pDst = (float*)(((uint8*)imgRGBAf) + (pitch * (y + row)) + (x * sizeof(ColorRGBAf))); - - const ColorRGBAf* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(&pDst[0 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - pSrc[1].getRGBA(&pDst[1 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - pSrc[2].getRGBA(&pDst[2 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - pSrc[3].getRGBA(&pDst[3 * sizeof(ColorRGBAf) / sizeof(*pDst)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - float* const pDst = (float*)(((uint8*)imgRGBAf) + pitch * (y + by)); - - const ColorRGBAf* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(&pDst[(x + bx) * sizeof(ColorRGBAf) / sizeof(*pDst)]); - } - } - } - } - - void ColorBlockRGBA4x4f::setAf(const void* imgAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(float), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const float* const pSrc = (const float*)(((const uint8*)imgAf) + (pitch * (y + row)) + (x * sizeof(float))); - - ColorRGBAf* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(0, 0, 0, pSrc[0]); - pDst[1].setRGBA(0, 0, 0, pSrc[1]); - pDst[2].setRGBA(0, 0, 0, pSrc[2]); - pDst[3].setRGBA(0, 0, 0, pSrc[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const float* const pSrc = (const float*)(((const uint8*)imgAf) + (pitch * (y + by))); - - ColorRGBAf* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(0, 0, 0, pSrc[x + bx]); - } - } - } - } - - void ColorBlockRGBA4x4f::getAf(void* imgAf, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgAf, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(float), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorRGBAf* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - float* const pDst = (float*)(((uint8*)imgAf) + (pitch * (y + row)) + (x * sizeof(float))); - float r, g, b; - - const ColorRGBAf* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(r, g, b, pDst[0]); - pSrc[1].getRGBA(r, g, b, pDst[1]); - pSrc[2].getRGBA(r, g, b, pDst[2]); - pSrc[3].getRGBA(r, g, b, pDst[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - float* const pDst = (float*)(((uint8*)imgAf) + pitch * (y + by)); - float r, g, b; - - const ColorRGBAf* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(r, g, b, pDst[x + bx]); - } - } - } - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h deleted file mode 100644 index 0235dd18db..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "ColorTypes.h" - -namespace ImageProcessing -{ - // Uncompressed 4x4 color block of single precision floating points. - struct ColorBlockRGBA4x4f - { - ColorBlockRGBA4x4f() - { - } - - void setRGBAf(const void* imgARGBf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getRGBAf(void* imgARGBf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - void setAf(const void* imgAf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getAf(void* imgAf, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - const ColorRGBAf* colors() const - { - return m_color; - } - - ColorRGBAf* colors() - { - return m_color; - } - - ColorRGBAf color(unsigned int i) const - { - return m_color[i]; - } - - ColorRGBAf& color(unsigned int i) - { - return m_color[i]; - } - - private: - static const unsigned int COLOR_COUNT = 4 * 4; - - ColorRGBAf m_color[COLOR_COUNT]; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp deleted file mode 100644 index 9e95a23f17..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp +++ /dev/null @@ -1,297 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include - -#include "ColorBlockRGBA4x4s.h" - -namespace ImageProcessing -{ - static_assert(sizeof(int) == 4, "Expected size of int to be 4 bytes!"); - - void ColorBlockRGBA4x4s::setRGBA16(const void* imgBGRA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgBGRA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA16), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint16* const pSrc = (const uint16*)(((const uint8*)imgBGRA16) + (pitch * (y + row)) + (x * sizeof(ColorRGBA16))); - - ColorRGBA16* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(&pSrc[0 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - pDst[1].setRGBA(&pSrc[1 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - pDst[2].setRGBA(&pSrc[2 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - pDst[3].setRGBA(&pSrc[3 * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint16* const pSrc = (const uint16*)(((const uint8*)imgBGRA16) + pitch * (y + by)); - - ColorRGBA16* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(&pSrc[(x + bx) * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4s::getRGBA16(void* imgBGRA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgBGRA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(ColorRGBA16), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint16* const pDst = (uint16*)(((uint8*)imgBGRA16) + (pitch * (y + row)) + (x * sizeof(ColorRGBA16))); - - const ColorRGBA16* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(&pDst[0 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - pSrc[1].getRGBA(&pDst[1 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - pSrc[2].getRGBA(&pDst[2 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - pSrc[3].getRGBA(&pDst[3 * sizeof(ColorRGBA16) / sizeof(*pDst)]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint16* const pDst = (uint16*)(((uint8*)imgBGRA16) + pitch * (y + by)); - - const ColorRGBA16* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(&pDst[(x + bx) * sizeof(ColorRGBA16) / sizeof(*pSrc)]); - } - } - } - } - - void ColorBlockRGBA4x4s::setA16(const void* imgA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - const uint16* const pSrc = (const uint16*)(((const uint8*)imgA16) + (pitch * (y + row)) + (x * sizeof(uint16))); - - ColorRGBA16* const pDst = &m_color[row << 2]; - - pDst[0].setRGBA(0, 0, 0, pSrc[0]); - pDst[1].setRGBA(0, 0, 0, pSrc[1]); - pDst[2].setRGBA(0, 0, 0, pSrc[2]); - pDst[3].setRGBA(0, 0, 0, pSrc[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - const uint16* const pSrc = (const uint16*)(((const uint8*)imgA16) + pitch * (y + by)); - - ColorRGBA16* pDst = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pDst[col].setRGBA(0, 0, 0, pSrc[x + bx]); - } - } - } - } - - void ColorBlockRGBA4x4s::getA16(void* imgA16, unsigned int const width, unsigned int const height, unsigned int const pitch, unsigned int x, unsigned int y) - { - AZ_Assert(imgA16, "%s: Unexpected image pointer", __FUNCTION__); - AZ_Assert((width & 3) == 0, "%s: Unexpected image width", __FUNCTION__); - AZ_Assert((height & 3) == 0, "%s: Unexpected image height", __FUNCTION__); - AZ_Assert(pitch >= width * sizeof(uint8), "%s: Unexpected image pitch", __FUNCTION__); - AZ_Assert(x < width, "%s: Unexpected pixel position x", __FUNCTION__); - AZ_Assert(y < height, "%s: Unexpected pixel position y", __FUNCTION__); - - const unsigned int bw = AZ::GetMin(width - x, 4U); - const unsigned int bh = AZ::GetMin(height - y, 4U); - - // note: it's allowed for source data to be not aligned to 4 byte boundary - // (so, we cannot cast source data pointer to ColorBGRA16* in code below) - - if ((bw == 4) && (bh == 4)) - { - for (unsigned int row = 0; row < 4; ++row) - { - uint16* const pDst = (uint16*)(((uint8*)imgA16) + (pitch * (y + row)) + (x * sizeof(uint16))); - uint16 r, g, b; - - const ColorRGBA16* const pSrc = &m_color[row << 2]; - - pSrc[0].getRGBA(r, g, b, pDst[0]); - pSrc[1].getRGBA(r, g, b, pDst[1]); - pSrc[2].getRGBA(r, g, b, pDst[2]); - pSrc[3].getRGBA(r, g, b, pDst[3]); - } - } - else - { - // Rare case: block is smaller than 4x4. - // Let's repeat pixels in this case. - // It will keep frequency of colors, except the case - // when width and/or height equals 3. But, this case - // is very rare because images usually are "power of 2" sized, and even - // if they are not, nobody will notice that the resulting encoding - // for such block is not ideal. - - static unsigned int remainder[] = - { - 0, 0, 0, 0, - 0, 1, 0, 1, - 0, 1, 2, 0, - 0, 1, 2, 3, - }; - - for (unsigned int row = 0; row < 4; ++row) - { - const unsigned int by = remainder[(bh - 1) * 4 + row]; - uint16* const pDst = (uint16*)(((uint8*)imgA16) + pitch * (y + by)); - uint16 r, g, b; - - const ColorRGBA16* const pSrc = &m_color[row * 4]; - - for (unsigned int col = 0; col < 4; ++col) - { - const unsigned int bx = remainder[(bw - 1) * 4 + col]; - - pSrc[col].getRGBA(r, g, b, pDst[x + bx]); - } - } - } - } - - bool ColorBlockRGBA4x4s::isSingleColorIgnoringAlpha() const - { - for (unsigned int i = 1; i < COLOR_COUNT; ++i) - { - if ((m_color[0].b != m_color[i].b) || - (m_color[0].g != m_color[i].g) || - (m_color[0].r != m_color[i].r)) - { - return false; - } - } - - return true; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h deleted file mode 100644 index 3c4b47cae7..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - - -#include "ColorTypes.h" - -namespace ImageProcessing -{ - // Uncompressed 4x4 color block of 16bit integers. - struct ColorBlockRGBA4x4s - { - ColorBlockRGBA4x4s() - { - } - - void setRGBA16(const void* imgRGBA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getRGBA16(void* imgRGBA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - void setA16(const void* imgA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - void getA16(void* imgA16, unsigned int width, unsigned int height, unsigned int pitch, unsigned int x, unsigned int y); - - bool isSingleColorIgnoringAlpha() const; - - const ColorRGBA16* colors() const - { - return m_color; - } - - ColorRGBA16* colors() - { - return m_color; - } - - ColorRGBA16 color(unsigned int i) const - { - return m_color[i]; - } - - ColorRGBA16& color(unsigned int i) - { - return m_color[i]; - } - - private: - static const unsigned int COLOR_COUNT = 4 * 4; - - ColorRGBA16 m_color[COLOR_COUNT]; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h deleted file mode 100644 index 2d5c8eb1e3..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/ColorTypes.h +++ /dev/null @@ -1,228 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace ImageProcessing -{ - // 32 bit 8888 RGBA color - struct ColorRGBA8 - { - ColorRGBA8() - { - } - - ColorRGBA8(const ColorRGBA8& a_c) - : u(a_c.u) - { - } - - ColorRGBA8(uint8 a_r, uint8 a_g, uint8 a_b, uint8 a_a) - : r(a_r) - , g(a_g) - , b(a_b) - , a(a_a) - { - } - - explicit ColorRGBA8(uint32 a_u) - : u(a_u) - { - } - - void setRGBA(uint8 a_r, uint8 a_g, uint8 a_b, uint8 a_a) - { - r = a_r; - g = a_g; - b = a_b; - a = a_a; - } - - void setRGBA(const uint8* a_pRGBA8) - { - r = a_pRGBA8[0]; - g = a_pRGBA8[1]; - b = a_pRGBA8[2]; - a = a_pRGBA8[3]; - } - - void getRGBA(uint8& a_r, uint8& a_g, uint8& a_b, uint8& a_a) const - { - a_r = r; - a_g = g; - a_b = b; - a_a = a; - } - - void getRGBA(uint8* a_pRGBA8) const - { - a_pRGBA8[0] = r; - a_pRGBA8[1] = g; - a_pRGBA8[2] = b; - a_pRGBA8[3] = a; - } - - union - { - struct - { - uint8 r; - uint8 g; - uint8 b; - uint8 a; - }; - uint32 u; - }; - }; - - // 64 bit 16161616 RGBA color - struct ColorRGBA16 - { - ColorRGBA16() - { - } - - ColorRGBA16(const ColorRGBA16& a_c) - : u(a_c.u) - { - } - - ColorRGBA16(uint16 a_r, uint16 a_g, uint16 a_b, uint16 a_a) - : r(a_r) - , g(a_g) - , b(a_b) - , a(a_a) - { - } - - explicit ColorRGBA16(AZ::u64 a_u) - : u(a_u) - { - } - - void setRGBA(uint16 a_r, uint16 a_g, uint16 a_b, uint16 a_a) - { - r = a_r; - g = a_g; - b = a_b; - a = a_a; - } - - void setRGBA(const uint16* a_pRGBA16) - { - r = a_pRGBA16[0]; - g = a_pRGBA16[1]; - b = a_pRGBA16[2]; - a = a_pRGBA16[3]; - } - - - void getRGBA(uint16& a_r, uint16& a_g, uint16& a_b, uint16& a_a) const - { - a_r = r; - a_g = g; - a_b = b; - a_a = a; - } - - void getRGBA(uint16* a_pRGBA16) const - { - a_pRGBA16[0] = r; - a_pRGBA16[1] = g; - a_pRGBA16[2] = b; - a_pRGBA16[3] = a; - } - - union - { - struct - { - uint16 r; - uint16 g; - uint16 b; - uint16 a; - }; - AZ::u64 u; - }; - }; - - // 128 bit (4 floats) RGBA color - struct ColorRGBAf - { - ColorRGBAf() - { - } - - ColorRGBAf(const ColorRGBAf& a_c) - : r(a_c.r) - , g(a_c.g) - , b(a_c.b) - , a(a_c.a) - { - } - - ColorRGBAf(float a_r, float a_g, float a_b, float a_a) - : r(a_r) - , g(a_g) - , b(a_b) - , a(a_a) - { - } - - void setRGBA(float a_r, float a_g, float a_b, float a_a) - { - r = a_r; - g = a_g; - b = a_b; - a = a_a; - } - - void setRGBA(const float* a_pRGBAf) - { - r = a_pRGBAf[0]; - g = a_pRGBAf[1]; - b = a_pRGBAf[2]; - a = a_pRGBAf[3]; - } - - void getRGBA(float& a_r, float& a_g, float& a_b, float& a_a) const - { - a_r = r; - a_g = g; - a_b = b; - a_a = a; - } - - void getRGBA(float* a_pRGBAf) const - { - a_pRGBAf[0] = r; - a_pRGBAf[1] = g; - a_pRGBAf[2] = b; - a_pRGBAf[3] = a; - } - - union - { - struct - { - float r; - float g; - float b; - float a; - }; - }; - }; - static_assert(sizeof(ColorRGBA8) == 4, "Expected size of ColorRGBA8 to be 4 bytes!"); - static_assert(sizeof(ColorRGBA16) == 8, "Expected size of ColorRGBA16 to be 4 bytes!"); - static_assert(sizeof(ColorRGBAf) == 16, "Expected size of ColorRGBAf to be 4 bytes!"); -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp deleted file mode 100644 index 27bb11a35b..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp +++ /dev/null @@ -1,657 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include -#include -#include "ColorBlockRGBA4x4c.h" -#include "ColorBlockRGBA4x4s.h" -#include "ColorBlockRGBA4x4f.h" -#include "CryTextureSquisher.h" - -#include - -#if defined(__clang__) -# pragma clang diagnostic push -# pragma clang diagnostic ignored "-Wnull-dereference" -# pragma clang diagnostic ignored "-Wsometimes-uninitialized" -# pragma clang diagnostic ignored "-Wshift-negative-value" -#endif - -#if AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL -#define __fastcall -#define _fastcall -#define __assume(x) -#endif - -#include - -#if defined(__clang__) -# pragma clang diagnostic pop -#endif - -// number of bytes per block per type -#define BLOCKSIZE_BC1 8 -#define BLOCKSIZE_BC2 16 -#define BLOCKSIZE_BC3 16 -#define BLOCKSIZE_BC4 8 -#define BLOCKSIZE_BC5 16 -#define BLOCKSIZE_BC6 16 -#define BLOCKSIZE_BC7 16 -#define BLOCKSIZE_CTX1 8 -#define BLOCKSIZE_LIMIT 16 - -#define PTROFFSET_R 0 -#define PTROFFSET_G 1 -#define PTROFFSET_B 2 -#define PTROFFSET_A 3 - -namespace ImageProcessing -{ - AZStd::mutex s_squishLock; - - -/* ------------------------------------------------------------------------------------------------------------- - * internal presets - */ - static struct ParameterMatrix - { - int flagsBaseline; - int flagsUniform; - int flagsPerceptual; - int flagsQuality[CryTextureSquisher::EQualityProfile::eQualityProfile_Num]; - - size_t offset; - bool alphaOnly; - } P2P[] = - { - // eCompressorPreset_BC1U, - { - squish::kBtc1 + squish::kExcludeAlphaFromPalette, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC2U, - { - squish::kBtc2, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC3U, - { - squish::kBtc3, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit }, - - 0, false - }, - // eCompressorPreset_BC4U, - { - squish::kBtc4, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC5U, - { - squish::kBtc5, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC6UH, - { - squish::kBtc6, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourRangeFit }, - - 0, false - }, - // eCompressorPreset_BC7U, - { - squish::kBtc7, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - - // eCompressorPreset_BC4S, - { - squish::kBtc4 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC5S, - { - squish::kBtc5 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_R, false - }, - - // eCompressorPreset_BC1Un, - { - squish::kBtc1 + squish::kExcludeAlphaFromPalette, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - // eCompressorPreset_BC2Un, - { - squish::kBtc2, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - // eCompressorPreset_BC3Un, - { - squish::kBtc3, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit + squish::kAlphaIterativeFit, squish::kNormalRangeFit + squish::kAlphaIterativeFit, squish::kNormalRangeFit + squish::kAlphaIterativeFit }, - - 0, false - }, - // eCompressorPreset_BC4Un, - { - squish::kBtc4, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_B, false - }, - // eCompressorPreset_BC5Un, - { - squish::kBtc5, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { 0, 0, squish::kNormalIterativeFit, squish::kNormalIterativeFit }, - - PTROFFSET_R, false - }, - // eCompressorPreset_BC6UHn, - { - squish::kBtc6, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - // eCompressorPreset_BC7Un, - { - squish::kBtc7, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - - // eCompressorPreset_BC4Sn, - { - squish::kBtc4 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_B, false - }, - // eCompressorPreset_BC5Sn, - { - squish::kBtc5 + squish::kSignedInternal, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { 0, 0, squish::kNormalIterativeFit, squish::kNormalIterativeFit }, - - PTROFFSET_R, false - }, - - // eCompressorPreset_BC1Ua, - { - squish::kBtc1 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC2Ut, - { - squish::kBtc2 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_BC3Ut, - { - squish::kBtc3 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit, squish::kColourIterativeClusterFit + squish::kAlphaIterativeFit }, - - 0, false - }, - // eCompressorPreset_BC4Ua, - { - squish::kBtc4, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_A, true - }, - // eCompressorPreset_BC7Ut - { - squish::kBtc7 + squish::kWeightColourByAlpha, - squish::kColourMetricUniform, - squish::kColourMetricPerceptual, - { squish::kColourRangeFit, squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - - // eCompressorPreset_BC4Sa, - { - squish::kBtc4 + squish::kSignedInternal, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { 0, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit, squish::kAlphaIterativeFit }, - - PTROFFSET_A, true - }, - - // eCompressorPreset_BC7Ug - { - squish::kBtc7, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourClusterFit * 15, squish::kColourClusterFit * 15 }, - - 0, false - }, - - // eCompressorPreset_CTX1U - { - squish::kCtx1, - squish::kColourMetricUniform, - squish::kColourMetricUniform, - { squish::kColourRangeFit, squish::kColourClusterFit, squish::kColourIterativeClusterFit, squish::kColourIterativeClusterFit }, - - 0, false - }, - // eCompressorPreset_CTX1Un - { - squish::kCtx1, - squish::kColourMetricUnit, - squish::kColourMetricUnit, - { squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit, squish::kNormalRangeFit }, - - 0, false - }, - }; - - /* ------------------------------------------------------------------------------------------------------------- - * compression functions - */ - void CryTextureSquisher::Compress(const CryTextureSquisher::CompressorParameters& compress) - { - const unsigned int w = compress.width; - const unsigned int h = compress.height; - const size_t offset = P2P[compress.preset].offset; - int flags = P2P[compress.preset].flagsBaseline + P2P[compress.preset].flagsQuality[compress.quality] + - (!compress.perceptual ? P2P[compress.preset].flagsUniform : P2P[compress.preset].flagsPerceptual); - const bool bAlphaOnly = P2P[compress.preset].alphaOnly; - - squish::sqio::dtp datatype; - switch (compress.srcType) - { - case eBufferType_sint8: - flags += squish::kSignedExternal; - case eBufferType_uint8: - datatype = squish::sqio::dtp::DT_U8; - break; - case eBufferType_sint16: - flags += squish::kSignedExternal; - case eBufferType_uint16: - datatype = squish::sqio::dtp::DT_U16; - break; - case eBufferType_sfloat: - flags += squish::kSignedExternal; - case eBufferType_ufloat: - datatype = squish::sqio::dtp::DT_F23; - break; - default: - __assume(0); - break; - } - - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - flags |= squish::kColourMetricCustom; - } - - const struct squish::sqio sqio = squish::GetSquishIO(w, h, datatype, flags); - - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - s_squishLock.lock(); - } - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - squish::SetWeights(sqio.flags, &compress.weights[0]); - } - - AZ_Assert(!(h & 3), "%s: Unexpected compress parameter of height", __FUNCTION__); - - switch (compress.srcType) - { - // compress an unsigned 8bit texture -------------------------------------------------- - // compress a signed 8bit texture ----------------------------------------------------- - case eBufferType_uint8: - case eBufferType_sint8: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - ColorBlockRGBA4x4c srcBlock; - uint8 dstBlock[BLOCKSIZE_LIMIT]; - - uint8* const targetBlock = dstBlock; - const uint8* const sourceRgba = (const uint8*)srcBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (!bAlphaOnly) - { - srcBlock.setRGBA8(compress.srcBuffer, w, h, compress.pitch, x, y); - } - else - { - srcBlock.setA8(compress.srcBuffer, w, h, compress.pitch, x, y); - } - - sqio.encoder(sourceRgba, 0xFFFF, targetBlock, sqio.flags); - - if (compress.userOutputFunction) - { - compress.userOutputFunction(compress, targetBlock, sqio.blocksize, y >> 2, x >> 2); - } - } - } - } - break; - // compress an unsigned 16bit texture ------------------------------------------------- - // compress a signed 16bit texture ---------------------------------------------------- - case eBufferType_uint16: - case eBufferType_sint16: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - ColorBlockRGBA4x4s srcBlock; - uint8 dstBlock[BLOCKSIZE_LIMIT]; - - uint8* const targetBlock = dstBlock; - const float* const sourceRgba = (const float*)srcBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (!bAlphaOnly) - { - srcBlock.setRGBA16(compress.srcBuffer, w, h, compress.pitch, x, y); - } - else - { - srcBlock.setA16(compress.srcBuffer, w, h, compress.pitch, x, y); - } - - sqio.encoder(sourceRgba, 0xFFFF, targetBlock, sqio.flags); - - if (compress.userOutputFunction) - { - compress.userOutputFunction(compress, targetBlock, sqio.blocksize, y >> 2, x >> 2); - } - } - } - } - break; - // compress an unsigned floating point texture ---------------------------------------- - // compress a signed floating point texture ------------------------------------------- - case eBufferType_ufloat: - case eBufferType_sfloat: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - ColorBlockRGBA4x4f srcBlock; - uint8 dstBlock[BLOCKSIZE_LIMIT]; - - uint8* const targetBlock = dstBlock; - const float* const sourceRgba = (const float*)srcBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (!bAlphaOnly) - { - srcBlock.setRGBAf(compress.srcBuffer, w, h, compress.pitch, x, y); - } - else - { - srcBlock.setAf(compress.srcBuffer, w, h, compress.pitch, x, y); - } - - sqio.encoder(sourceRgba, 0xFFFF, targetBlock, sqio.flags); - - if (compress.userOutputFunction) - { - compress.userOutputFunction(compress, targetBlock, sqio.blocksize, y >> 2, x >> 2); - } - } - } - } - break; - default: - AZ_Assert(false, "%s: Unexpected compress source type", __FUNCTION__); - break; - } - - if (compress.perceptual && (flags & squish::kColourMetricPerceptual)) - { - s_squishLock.unlock(); - } - } - - void CryTextureSquisher::Decompress(const DecompressorParameters& decompress) - { - const unsigned int w = decompress.width; - const unsigned int h = decompress.height; - const size_t offset = P2P[decompress.preset].offset; - int flags = P2P[decompress.preset].flagsBaseline + - P2P[decompress.preset].flagsUniform; - const bool bAlphaOnly = P2P[decompress.preset].alphaOnly; - - squish::sqio::dtp datatype; - switch (decompress.dstType) - { - case eBufferType_sint8: - flags += squish::kSignedExternal; - case eBufferType_uint8: - datatype = squish::sqio::dtp::DT_U8; - break; - case eBufferType_sint16: - flags += squish::kSignedExternal; - case eBufferType_uint16: - datatype = squish::sqio::dtp::DT_U16; - break; - case eBufferType_sfloat: - flags += squish::kSignedExternal; - case eBufferType_ufloat: - datatype = squish::sqio::dtp::DT_F23; - break; - default: - __assume(0); - break; - } - - const struct squish::sqio sqio = squish::GetSquishIO(w, h, datatype, flags); - - AZ_Assert(!(h & 3), "%s: Unexpected compress parameter of height", __FUNCTION__); - - switch (decompress.dstType) - { - // decompress an unsigned 8bit texture -------------------------------------------------- - // decompress a signed 8bit texture ----------------------------------------------------- - case eBufferType_uint8: - case eBufferType_sint8: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - uint8 srcBlock[BLOCKSIZE_LIMIT]; - ColorBlockRGBA4x4c dstBlock; - - uint8* const sourceBlock = srcBlock; - uint8* const targetRgba = (uint8*)dstBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (decompress.userInputFunction) - { - decompress.userInputFunction(decompress, sourceBlock, sqio.blocksize, y >> 2, x >> 2); - } - - if (!bAlphaOnly) - { - dstBlock.setRGBA8(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - - sqio.decoder(targetRgba, sourceBlock, sqio.flags); - - if (!bAlphaOnly) - { - dstBlock.getRGBA8(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - else - { - dstBlock.getA8(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - } - } - } - break; - // decompress an unsigned 16bit texture ------------------------------------------------- - // decompress a signed 16bit texture ---------------------------------------------------- - case eBufferType_uint16: - case eBufferType_sint16: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - uint8 srcBlock[BLOCKSIZE_LIMIT]; - ColorBlockRGBA4x4s dstBlock; - - uint8* const sourceBlock = srcBlock; - uint16* const targetRgba = (uint16*)dstBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (decompress.userInputFunction) - { - decompress.userInputFunction(decompress, sourceBlock, sqio.blocksize, y >> 2, x >> 2); - } - - if (!bAlphaOnly) - { - dstBlock.setRGBA16(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - - sqio.decoder(targetRgba, sourceBlock, sqio.flags); - - if (!bAlphaOnly) - { - dstBlock.setRGBA16(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - else - { - dstBlock.getA16(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - } - } - } - break; - // decompress an unsigned floating point texture ---------------------------------------- - // decompress a signed floating point texture ------------------------------------------- - case eBufferType_ufloat: - case eBufferType_sfloat: - { - for (unsigned int y = 0U; y < h; y += 4U) - { - uint8 srcBlock[BLOCKSIZE_LIMIT]; - ColorBlockRGBA4x4f dstBlock; - - uint8* const sourceBlock = srcBlock; - float* const targetRgba = (float*)dstBlock.colors() + offset; - - for (unsigned int x = 0U; x < w; x += 4U) - { - if (decompress.userInputFunction) - { - decompress.userInputFunction(decompress, sourceBlock, sqio.blocksize, y >> 2, x >> 2); - } - - if (!bAlphaOnly) - { - dstBlock.setRGBAf(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - sqio.decoder(targetRgba, sourceBlock, sqio.flags); - - if (!bAlphaOnly) - { - dstBlock.getRGBAf(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - else - { - dstBlock.getAf(decompress.dstBuffer, w, h, decompress.pitch, x, y); - } - } - } - } - break; - default: - AZ_Assert(false, "%s: Unexpected compress destination type", __FUNCTION__); - break; - } - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.h b/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.h deleted file mode 100644 index 2aa7117d46..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/CryTextureSquisher/CryTextureSquisher.h +++ /dev/null @@ -1,132 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace ImageProcessing -{ - class CryTextureSquisher - { - public: - enum EBufferType - { - eBufferType_uint8, // native support: BC1-5/7,CTX1 - eBufferType_sint8, // native support: BC4-5 - eBufferType_uint16, // native support: BC1-7,CTX1 - eBufferType_sint16, // native support: BC4-6 - eBufferType_ufloat, // native support: BC1-7,CTX1 - eBufferType_sfloat, // native support: BC4-6 - }; - - enum EQualityProfile - { - eQualityProfile_Low = 0,// as-fast-as-possible - eQualityProfile_Medium, // not so bad (nightly builds) - eQualityProfile_High, // relative good (weekly builds) - eQualityProfile_Best, // as-best-as-possible (final build for release) - - eQualityProfile_Num - }; - - enum ECodingPreset - { - eCompressorPreset_BC1U = 0, - eCompressorPreset_BC2U, - eCompressorPreset_BC3U, - eCompressorPreset_BC4U, // r-channel from RGBA - eCompressorPreset_BC5U, // rg-channels from RGBA - eCompressorPreset_BC6UH, - eCompressorPreset_BC7U, - - eCompressorPreset_BC4S, // r-channel from RGBA - eCompressorPreset_BC5S, // rg-channels from RGBA - - // normal vectors -> unit metric - eCompressorPreset_BC1Un, - eCompressorPreset_BC2Un, - eCompressorPreset_BC3Un, - eCompressorPreset_BC4Un, // z-channel from XYZD - eCompressorPreset_BC5Un, // xy-channels from XYZD, xyz must be a valid unit-vector - eCompressorPreset_BC6UHn, - eCompressorPreset_BC7Un, - - eCompressorPreset_BC4Sn, // z-channel from XYZD - eCompressorPreset_BC5Sn, // xy-channels from XYZD, xyz must be a valid unit-vector - - // transparency -> weighted alpha - eCompressorPreset_BC1Ua, - eCompressorPreset_BC2Ut, - eCompressorPreset_BC3Ut, - eCompressorPreset_BC4Ua, // a-channel from RGBA - eCompressorPreset_BC7Ut, - - eCompressorPreset_BC4Sa, // a-channel from RGBA - - // grey-scale -> 12+ bits of precision - eCompressorPreset_BC7Ug, - - // special ones - eCompressorPreset_CTX1U, // rg-channels from RGBA - eCompressorPreset_CTX1Un, // xy-channels from XYZD, xyz must be a valid unit-vector - - eCompressorPreset_Num - }; - - struct CompressorParameters - { - // source's parameters - EBufferType srcType; - const void* srcBuffer; - unsigned int width; - unsigned int height; - unsigned int pitch; - - // coding preset - ECodingPreset preset; - EQualityProfile quality; - - // either if "srgb==1" or if "rgbweights!=uniform" - bool perceptual; - float weights[4]; - - void* userPtr; - int userInt; - - void(*userOutputFunction)(const CompressorParameters& compress, const void* compressedData, unsigned int compressedSize, unsigned int oy, unsigned int ox); - }; - - struct DecompressorParameters - { - // destination's parameters - EBufferType dstType; - void* dstBuffer; - unsigned int width; - unsigned int height; - unsigned int pitch; - - // coding preset - ECodingPreset preset; - - void* userPtr; - int userInt; - - void(*userInputFunction)(const DecompressorParameters& decompress, void* compressedData, unsigned int compressedSize, unsigned int oy, unsigned int ox); - }; - - public: - static void Compress(const CompressorParameters& compress); - static void Decompress(const DecompressorParameters& decompress); - }; - -} //namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.cpp b/Gems/ImageProcessing/Code/Source/Compressors/ETC2.cpp deleted file mode 100644 index 3d43fe7dda..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.cpp +++ /dev/null @@ -1,229 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -namespace ImageProcessing -{ - //limited to 1 thread because AP requires so. We may change to n when AP allocate n thread to a job in the furture - static const int MAX_COMP_JOBS = 1; - static const int MIN_COMP_JOBS = 1; - static const float ETC_LOW_EFFORT_LEVEL = 25.0f; - static const float ETC_MED_EFFORT_LEVEL = 40.0f; - static const float ETC_HIGH_EFFORT_LEVEL = 80.0f; - - //Grab the Etc2Comp specific pixel format enum - static Etc::Image::Format FindEtc2PixelFormat(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_EAC_RG11: - return Etc::Image::Format::RG11; - case ePixelFormat_EAC_R11: - return Etc::Image::Format::R11; - case ePixelFormat_ETC2: - return Etc::Image::Format::RGB8; - case ePixelFormat_ETC2a: - return Etc::Image::Format::RGBA8; - default: - return Etc::Image::Format::FORMATS; - } - } - - //Get the errmetric required for the compression - static Etc::ErrorMetric FindErrMetric(Etc::Image::Format fmt) - { - switch (fmt) - { - case Etc::Image::Format::RG11: - return Etc::ErrorMetric::NORMALXYZ; - case Etc::Image::Format::R11: - return Etc::ErrorMetric::NUMERIC; - case Etc::Image::Format::RGB8: - return Etc::ErrorMetric::RGBX; - case Etc::Image::Format::RGBA8: - return Etc::ErrorMetric::RGBA; - default: - return Etc::ErrorMetric::ERROR_METRICS; - } - - } - - //Convert to sRGB format - static Etc::Image::Format FindGammaEtc2PixelFormat(Etc::Image::Format fmt) - { - switch (fmt) - { - case Etc::Image::Format::RGB8: - return Etc::Image::Format::SRGB8; - case Etc::Image::Format::RGBA8: - return Etc::Image::Format::SRGBA8; - case Etc::Image::Format::RGB8A1: - return Etc::Image::Format::SRGB8A1; - default: - return Etc::Image::Format::FORMATS; - } - } - - bool ETC2Compressor::IsCompressedPixelFormatSupported(EPixelFormat fmt) - { - return (FindEtc2PixelFormat(fmt) != Etc::Image::Format::FORMATS); - } - - bool ETC2Compressor::IsUncompressedPixelFormatSupported(EPixelFormat fmt) - { - //for uncompress format - if (fmt == ePixelFormat_R8G8B8A8) - { - return true; - } - return false; - } - - EPixelFormat ETC2Compressor::GetSuggestedUncompressedFormat([[maybe_unused]] EPixelFormat compressedfmt, [[maybe_unused]] EPixelFormat uncompressedfmt) - { - return ePixelFormat_R8G8B8A8; - } - - bool ETC2Compressor::DoesSupportDecompress([[maybe_unused]] EPixelFormat fmtDst) - { - return false; - } - - IImageObjectPtr ETC2Compressor::CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, - const CompressOption *compressOption) - { - const size_t srcPixelSize = 4; - - //validate input - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be uncompressed and dst format need to compressed. - if (!IsUncompressedPixelFormatSupported(fmtSrc) || !IsCompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //determinate compression quality - ICompressor::EQuality quality = ICompressor::eQuality_Normal; - //get setting from compression option - if (compressOption) - { - quality = compressOption->compressQuality; - } - - float qualityEffort = 0.0f; - switch (quality) - { - case eQuality_Preview: - case eQuality_Fast: - { - qualityEffort = ETC_LOW_EFFORT_LEVEL; - break; - } - case eQuality_Normal: - { - qualityEffort = ETC_MED_EFFORT_LEVEL; - break; - } - default: - { - qualityEffort = ETC_HIGH_EFFORT_LEVEL; - } - } - - Etc::Image::Format dstEtc2Format = FindEtc2PixelFormat(fmtDst); - if (srcImage->GetImageFlags() & EIF_SRGBRead) - { - dstEtc2Format = FindGammaEtc2PixelFormat(dstEtc2Format); - } - - //use to read pixel data from src image - IPixelOperationPtr pixelOp = CreatePixelOperation(fmtSrc); - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtSrc)->bitsPerBlock / 8; - - const AZ::u32 mipCount = dstImage->GetMipCount(); - for (AZ::u32 mip = 0; mip < mipCount; ++mip) - { - const AZ::u32 width = srcImage->GetWidth(mip); - const AZ::u32 height = srcImage->GetHeight(mip); - - // Prepare source data - AZ::u8* srcMem; - AZ::u32 srcPitch; - srcImage->GetImagePointer(mip, srcMem, srcPitch); - const AZ::u32 pixelCount = srcImage->GetPixelCount(mip); - - Etc::ColorFloatRGBA* rgbaPixels = new Etc::ColorFloatRGBA[pixelCount]; - Etc::ColorFloatRGBA* rgbaPixelPtr = rgbaPixels; - float r, g, b, a; - for (AZ::u32 pixelIdx = 0; pixelIdx < pixelCount; pixelIdx++, srcMem += pixelBytes, rgbaPixelPtr++) - { - pixelOp->GetRGBA(srcMem, r, g, b, a); - rgbaPixelPtr->fA = a; - rgbaPixelPtr->fR = r; - rgbaPixelPtr->fG = g; - rgbaPixelPtr->fB = b; - } - - //Call into etc2Comp lib to compress. https://medium.com/@duhroach/building-a-blazing-fast-etc2-compressor-307f3e9aad99 - Etc::ErrorMetric errMetric = FindErrMetric(dstEtc2Format); - unsigned char* paucEncodingBits; - unsigned int uiEncodingBitsBytes; - unsigned int uiExtendedWidth; - unsigned int uiExtendedHeight; - int iEncodingTime_ms; - - Etc::Encode(reinterpret_cast(rgbaPixels), - width, height, - dstEtc2Format, - errMetric, - qualityEffort, - MIN_COMP_JOBS, - MAX_COMP_JOBS, - &paucEncodingBits, &uiEncodingBitsBytes, - &uiExtendedWidth, &uiExtendedHeight, - &iEncodingTime_ms); - - AZ::u8* dstMem; - AZ::u32 dstPitch; - dstImage->GetImagePointer(mip, dstMem, dstPitch); - - memcpy(dstMem, paucEncodingBits, uiEncodingBitsBytes); - delete[] rgbaPixels; - } - - return dstImage; - } - - IImageObjectPtr ETC2Compressor::DecompressImage(IImageObjectPtr srcImage, [[maybe_unused]] EPixelFormat fmtDst) - { - //etc2Comp doesn't support decompression - //Since PVRTexLib support ETC formats too. It may take over the decompression. - return nullptr; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.h b/Gems/ImageProcessing/Code/Source/Compressors/ETC2.h deleted file mode 100644 index d862bead68..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/ETC2.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class ETC2Compressor : public ICompressor - { - public: - static bool IsCompressedPixelFormatSupported(EPixelFormat fmt); - static bool IsUncompressedPixelFormatSupported(EPixelFormat fmt); - static bool DoesSupportDecompress(EPixelFormat fmtDst); - - IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) override; - IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) override; - - EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) override; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp b/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp deleted file mode 100644 index 64fee3b747..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.cpp +++ /dev/null @@ -1,389 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include - -#if AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT -//_WINDLL_IMPORT need to be defined before including PVRTexLib header files to avoid linking error on windows. -#define _WINDLL_IMPORT -// NOMINMAX needs to be defined before including PVRTexLib header files (which include Windows.h) -// so that Windows.h doesn't define min/max. Otherwise, a compile error may arise in Uber builds -#ifndef NOMINMAX -#define NOMINMAX -#endif -#endif -#include -#include - - -namespace ImageProcessing -{ - // Note: PVRTexLib supports ASTC formats, ETC formats, PVRTC formats and BC formats - // We haven't tested the performace to compress BC formats compare to CTSquisher - // For PVRTC formats, we only added PVRTC 1 support for now - // The compression for ePVRTPF_EAC_R11 and ePVRTPF_EAC_RG11 are very slow. It takes 7 and 14 minutes for a 2048x2048 texture. - EPVRTPixelFormat FindPvrPixelFormat(EPixelFormat fmt) - { - switch (fmt) - { - case ePixelFormat_ASTC_4x4: - return ePVRTPF_ASTC_4x4; - case ePixelFormat_ASTC_5x4: - return ePVRTPF_ASTC_5x4; - case ePixelFormat_ASTC_5x5: - return ePVRTPF_ASTC_5x5; - case ePixelFormat_ASTC_6x5: - return ePVRTPF_ASTC_6x5; - case ePixelFormat_ASTC_6x6: - return ePVRTPF_ASTC_6x6; - case ePixelFormat_ASTC_8x5: - return ePVRTPF_ASTC_8x5; - case ePixelFormat_ASTC_8x6: - return ePVRTPF_ASTC_8x6; - case ePixelFormat_ASTC_8x8: - return ePVRTPF_ASTC_8x8; - case ePixelFormat_ASTC_10x5: - return ePVRTPF_ASTC_10x5; - case ePixelFormat_ASTC_10x6: - return ePVRTPF_ASTC_10x6; - case ePixelFormat_ASTC_10x8: - return ePVRTPF_ASTC_10x8; - case ePixelFormat_ASTC_10x10: - return ePVRTPF_ASTC_10x10; - case ePixelFormat_ASTC_12x10: - return ePVRTPF_ASTC_12x10; - case ePixelFormat_ASTC_12x12: - return ePVRTPF_ASTC_12x12; - case ePixelFormat_PVRTC2: - return ePVRTPF_PVRTCI_2bpp_RGBA; - case ePixelFormat_PVRTC4: - return ePVRTPF_PVRTCI_4bpp_RGBA; - case ePixelFormat_EAC_R11: - return ePVRTPF_EAC_R11; - case ePixelFormat_EAC_RG11: - return ePVRTPF_EAC_RG11; - case ePixelFormat_ETC2: - return ePVRTPF_ETC2_RGB; - case ePixelFormat_ETC2a: - return ePVRTPF_ETC2_RGBA; - default: - return ePVRTPF_NumCompressedPFs; - } - } - - bool PVRTCCompressor::IsCompressedPixelFormatSupported(EPixelFormat fmt) - { - return (FindPvrPixelFormat(fmt) != ePVRTPF_NumCompressedPFs); - } - - bool PVRTCCompressor::IsUncompressedPixelFormatSupported(EPixelFormat fmt) - { - //for uncompress format - if (fmt == ePixelFormat_R8G8B8A8) - { - return true; - } - return false; - } - - - EPixelFormat PVRTCCompressor::GetSuggestedUncompressedFormat([[maybe_unused]] EPixelFormat compressedfmt, [[maybe_unused]] EPixelFormat uncompressedfmt) - { - return ePixelFormat_R8G8B8A8; - } - - - bool PVRTCCompressor::DoesSupportDecompress([[maybe_unused]] EPixelFormat fmtDst) - { - return true; - } - - IImageObjectPtr PVRTCCompressor::CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, - const CompressOption *compressOption) - { - //validate input - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); - - //src format need to be uncompressed and dst format need to compressed. - if (!IsUncompressedPixelFormatSupported(fmtSrc) || !IsCompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - //determinate compression quality - pvrtexture::ECompressorQuality internalQuality = pvrtexture::eETCFast; - ICompressor::EQuality quality = ICompressor::eQuality_Normal; - AZ::Vector3 uniformWeights = AZ::Vector3(0.3333f, 0.3334f, 0.3333f); - AZ::Vector3 weights = uniformWeights; - bool isUniform = true; - //get setting from compression option - if (compressOption) - { - quality = compressOption->compressQuality; - weights = compressOption->rgbWeight; - isUniform = (weights == uniformWeights); - } - - if (IsETCFormat(fmtDst)) - { - if ((quality <= eQuality_Normal) && isUniform) - { - internalQuality = pvrtexture::eETCFast; - } - else if (quality <= eQuality_Normal) - { - internalQuality = pvrtexture::eETCNormal; - } - else if (isUniform) - { - internalQuality = pvrtexture::eETCSlow; - } - else - { - internalQuality = pvrtexture::eETCSlow; - } - } - else if (IsASTCFormat(fmtDst)) - { - if (quality == eQuality_Preview) - { - internalQuality = pvrtexture::eASTCVeryFast; - } - else if (quality == eQuality_Fast) - { - internalQuality = pvrtexture::eASTCFast; - } - else if (quality == eQuality_Normal) - { - internalQuality = pvrtexture::eASTCMedium; - } - else - { - internalQuality = pvrtexture::eASTCThorough; - } - } - else - { - if (quality == eQuality_Preview) - { - internalQuality = pvrtexture::ePVRTCFastest; - } - else if (quality == eQuality_Fast) - { - internalQuality = pvrtexture::ePVRTCFast; - } - else if (quality == eQuality_Normal) - { - internalQuality = pvrtexture::ePVRTCNormal; - } - else - { - internalQuality = pvrtexture::ePVRTCHigh; - } - } - - // setup color space - EPVRTColourSpace cspace = ePVRTCSpacelRGB; - if (srcImage->GetImageFlags() & EIF_SRGBRead) - { - cspace = ePVRTCSpacesRGB; - } - - //setup src texture for compression - const pvrtexture::PixelType srcPixelType('r', 'g', 'b', 'a', 8, 8, 8, 8); - const AZ::u32 dstMips = dstImage->GetMipCount(); - for (AZ::u32 mip = 0; mip < dstMips; ++mip) - { - const AZ::u32 width = srcImage->GetWidth(mip); - const AZ::u32 height = srcImage->GetHeight(mip); - - // Prepare source data - AZ::u8* srcMem; - uint32 srcPitch; - srcImage->GetImagePointer(mip, srcMem, srcPitch); - - const pvrtexture::CPVRTextureHeader srcHeader( - srcPixelType.PixelTypeID, // AZ::u64 u64PixelFormat, - width, // uint32 u32Height=1, - height, // uint32 u32Width=1, - 1, // uint32 u32Depth=1, - 1, // uint32 u32NumMipMaps=1, - 1, // uint32 u32NumArrayMembers=1, - 1, // uint32 u32NumFaces=1, - cspace, // EPVRTColourSpace eColourSpace=ePVRTCSpacelRGB, - ePVRTVarTypeUnsignedByteNorm, // EPVRTVariableType eChannelType=ePVRTVarTypeUnsignedByteNorm, - false); // bool bPreMultiplied=false); - - pvrtexture::CPVRTexture compressTexture(srcHeader, srcMem); - - //compressing - bool isSuccess = false; -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - try -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - { - isSuccess = pvrtexture::Transcode( - compressTexture, - pvrtexture::PixelType(FindPvrPixelFormat(fmtDst)), - ePVRTVarTypeUnsignedByteNorm, - cspace, - internalQuality); - } -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - catch (...) - { - AZ_Error("Image Processing", false, "Unknown exception in PVRTexLib"); - return nullptr; - } -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - - if (!isSuccess) - { - AZ_Error("Image Processing", false, "Failed to compress image with PVRTexLib. You may not have astcenc.exe for compressing ASTC formates"); - return nullptr; - } - - // Getting compressed data - const void* const compressedData = compressTexture.getDataPtr(); - if (!compressedData) - { - AZ_Error("Image Processing", false, "Failed to obtain compressed image data by using PVRTexLib"); - return nullptr; - } - - const AZ::u32 compressedDataSize = compressTexture.getDataSize(); - if (dstImage->GetMipBufSize(mip) != compressedDataSize) - { - AZ_Error("Image Processing", false, "Compressed image data size mismatch while using PVRTexLib"); - return nullptr; - } - - //save compressed data to dst image - AZ::u8* dstMem; - AZ::u32 dstPitch; - dstImage->GetImagePointer(mip, dstMem, dstPitch); - memcpy(dstMem, compressedData, compressedDataSize); - } - - return dstImage; - } - - IImageObjectPtr PVRTCCompressor::DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) - { - //validate input - EPixelFormat fmtSrc = srcImage->GetPixelFormat(); //compressed - - if (!IsCompressedPixelFormatSupported(fmtSrc) || !IsUncompressedPixelFormatSupported(fmtDst)) - { - return nullptr; - } - - EPVRTColourSpace colorSpace = ePVRTCSpacelRGB; - if (srcImage->GetImageFlags() & EIF_SRGBRead) - { - colorSpace = ePVRTCSpacesRGB; - } - - IImageObjectPtr dstImage(srcImage->AllocateImage(fmtDst)); - - const AZ::u32 mipCount = dstImage->GetMipCount(); - for (AZ::u32 mip = 0; mip < mipCount; ++mip) - { - const AZ::u32 width = srcImage->GetWidth(mip); - const AZ::u32 height = srcImage->GetHeight(mip); - - // Preparing source compressed data - const pvrtexture::CPVRTextureHeader compressedHeader( - FindPvrPixelFormat(fmtSrc), // AZ::u64 u64PixelFormat, - width, // uint32 u32Height=1, - height, // uint32 u32Width=1, - 1, // uint32 u32Depth=1, - 1, // uint32 u32NumMipMaps=1, - 1, // uint32 u32NumArrayMembers=1, - 1, // uint32 u32NumFaces=1, - colorSpace, // EPVRTColourSpace eColourSpace=ePVRTCSpacelRGB, - ePVRTVarTypeUnsignedByteNorm, // EPVRTVariableType eChannelType=ePVRTVarTypeUnsignedByteNorm, - false); // bool bPreMultiplied=false); - - const AZ::u32 compressedDataSize = compressedHeader.getDataSize(); - if (srcImage->GetMipBufSize(mip) != compressedDataSize) - { - AZ_Error("Image Processing", false, "Decompressed image data size mismatch while using PVRTexLib"); - return nullptr; - } - - AZ::u8* srcMem; - AZ::u32 srcPitch; - srcImage->GetImagePointer(mip, srcMem, srcPitch); - pvrtexture::CPVRTexture cTexture(compressedHeader, srcMem); - - // Decompress - bool bOk = false; -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - try - { -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - bOk = pvrtexture::Transcode( - cTexture, - pvrtexture::PVRStandard8PixelType, - ePVRTVarTypeUnsignedByteNorm, - colorSpace, - pvrtexture::ePVRTCHigh); - -#if AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - } - catch (...) - { - AZ_Error("Image Processing", false, "Unknown exception in PVRTexLib when decompressing"); - return nullptr; - } -#endif // AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH - - if (!bOk) - { - AZ_Error("Image Processing", false, "Failed to decompress an image by using PVRTexLib"); - return nullptr; - } - - // Getting decompressed data - const void* const pDecompressedData = cTexture.getDataPtr(); - if (!pDecompressedData) - { - AZ_Error("Image Processing", false, "Failed to obtain decompressed image data by using PVRTexLib"); - return nullptr; - } - - const AZ::u32 decompressedDataSize = cTexture.getDataSize(); - if (dstImage->GetMipBufSize(mip) != decompressedDataSize) - { - AZ_Error("Image Processing", false, "Decompressed image data size mismatch while using PVRTexLib"); - return nullptr; - } - - //save decompressed image to dst image - AZ::u8* dstMem; - AZ::u32 dstPitch; - dstImage->GetImagePointer(mip, dstMem, dstPitch); - memcpy(dstMem, pDecompressedData, decompressedDataSize); - } - - return dstImage; - } - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.h b/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.h deleted file mode 100644 index 648990a819..0000000000 --- a/Gems/ImageProcessing/Code/Source/Compressors/PVRTC.h +++ /dev/null @@ -1,32 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class PVRTCCompressor : public ICompressor - { - public: - static bool IsCompressedPixelFormatSupported(EPixelFormat fmt); - static bool IsUncompressedPixelFormatSupported(EPixelFormat fmt); - static bool DoesSupportDecompress(EPixelFormat fmtDst); - - IImageObjectPtr CompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst, const CompressOption *compressOption) override; - IImageObjectPtr DecompressImage(IImageObjectPtr srcImage, EPixelFormat fmtDst) override; - - EPixelFormat GetSuggestedUncompressedFormat(EPixelFormat compressedfmt, EPixelFormat uncompressedfmt) override; - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/AlphaCoverage.cpp b/Gems/ImageProcessing/Code/Source/Converters/AlphaCoverage.cpp deleted file mode 100644 index 46444d8d87..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/AlphaCoverage.cpp +++ /dev/null @@ -1,121 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// -//functions for maintaining alpha coverage. - -namespace ImageProcessing -{ - void CImageObject::TransferAlphaCoverage(const TextureSettings* textureSetting, const IImageObjectPtr srcImg) - { - EPixelFormat srcFmt = srcImg->GetPixelFormat(); - //both this image and src image need to be uncompressed - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat) - || !CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcFmt)) - { - AZ_Assert(false, "Both source image and dest image need to be uncompressed"); - return; - } - - const float fAlphaRef = 0.5f; // Seems to give good overall results - const float fDesiredAlphaCoverage = srcImg->ComputeAlphaCoverage(0, fAlphaRef); - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - for (uint32 mip = 0; mip < GetMipCount(); mip++) - { - const float fAlphaOffset = textureSetting->ComputeMIPAlphaOffset(mip); - const float fAlphaScale = ComputeAlphaCoverageScaleFactor(mip, fDesiredAlphaCoverage, fAlphaRef); - - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - float r, g, b, a; - pixelOp->GetRGBA(pixelBuf, r, g, b, a); - a = AZ::GetMin(a * fAlphaScale + fAlphaOffset, 1.0f); - pixelOp->SetRGBA(pixelBuf, r, g, b, a); - } - } - } - - float CImageObject::ComputeAlphaCoverageScaleFactor(AZ::u32 mip, float fDesiredCoverage, float fAlphaRef) const - { - float minAlphaRef = 0.0f; - float maxAlphaRef = 1.0f; - float midAlphaRef = 0.5f; - - // Find best alpha test reference value using a binary search - for (int i = 0; i < 10; i++) - { - const float currentCoverage = ComputeAlphaCoverage(mip, midAlphaRef); - - if (currentCoverage > fDesiredCoverage) - { - minAlphaRef = midAlphaRef; - } - else if (currentCoverage < fDesiredCoverage) - { - maxAlphaRef = midAlphaRef; - } - else - { - break; - } - - midAlphaRef = (minAlphaRef + maxAlphaRef) * 0.5f; - } - - return fAlphaRef / midAlphaRef; - } - - float CImageObject::ComputeAlphaCoverage(AZ::u32 mip, float fAlphaRef) const - { - //This function only works with uncompressed image - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - AZ_Assert(false, "This image need to be uncompressed"); - return 0; - } - - uint32 coverage = 0; - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - float r, g, b, a; - pixelOp->GetRGBA(pixelBuf, r, g, b, a); - coverage += a > fAlphaRef; - } - - return (float)coverage / (float)(pixelCount); - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/ColorChart.cpp b/Gems/ImageProcessing/Code/Source/Converters/ColorChart.cpp deleted file mode 100644 index 63067a57b5..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/ColorChart.cpp +++ /dev/null @@ -1,314 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include - -namespace ImageProcessing -{ - const int COLORCHART_IMAGE_WIDTH = 78; - const int COLORCHART_IMAGE_HEIGHT = 66; - - // color chart in cry engine is a special image data, with size 78x66, you may see in game screenshot which is defined by a rectangle - // area with a yellow-black dash line boarder - // Create color chart function is to read that block of image data and convert it to a color table then save it to another image - // with size 256x16. - - class C3dLutColorChart - { - public: - C3dLutColorChart() {} - ~C3dLutColorChart() {}; - - //generate default color chart data - void GenerateDefault(); - - //generate color chart data from input image - bool GenerateFromInput(IImageObjectPtr image); - - //ouput the color chart data to an image object - IImageObjectPtr GenerateChartImage(); - - protected: - //extract color chart data from specified location in an image - void ExtractFromImageAt(IImageObjectPtr pImg, AZ::u32 x, AZ::u32 y); - - //find color chart location in an image - static bool FindColorChart(const IImageObjectPtr pImg, AZ::u32& outLocX, AZ::u32& outLocY); - - //if there is a color chart at specified location - static bool IsColorChartAt(AZ::u32 x, AZ::u32 y, void* pData, AZ::u32 pitch); - - private: - enum EPrimaryShades - { - ePS_Red = 16, - ePS_Green = 16, - ePS_Blue = 16, - - ePS_NumColors = ePS_Red * ePS_Green * ePS_Blue - }; - - struct SColor - { - unsigned char r, g, b, _padding; - }; - - typedef AZStd::vector ColorMapping; - - ColorMapping m_mapping; - }; - - void C3dLutColorChart::GenerateDefault() - { - m_mapping.reserve(ePS_NumColors); - - for (int b = 0; b < ePS_Blue; ++b) - { - for (int g = 0; g < ePS_Green; ++g) - { - for (int r = 0; r < ePS_Red; ++r) - { - SColor col; - col.r = 255 * r / (ePS_Red); - col.g = 255 * g / (ePS_Green); - col.b = 255 * b / (ePS_Blue); - int l = 255 - (col.r * 3 + col.g * 6 + col.b) / 10; - col.r = col.g = col.b = (unsigned char)l; - m_mapping.push_back(col); - } - } - } - } - - //find color chart location in a image - bool C3dLutColorChart::FindColorChart(const IImageObjectPtr pImg, AZ::u32& outLocX, AZ::u32& outLocY) - { - const AZ::u32 width = pImg->GetWidth(0); - const AZ::u32 height = pImg->GetHeight(0); - - //the origin image is too small to have a color chart - if (width < COLORCHART_IMAGE_WIDTH || height < COLORCHART_IMAGE_HEIGHT) - { - return false; - } - - AZ::u8* pData; - AZ::u32 pitch; - pImg->GetImagePointer(0, pData, pitch); - - //check all the posible start location on whether there might be a color chart - for (AZ::u32 y = 0; y <= height - COLORCHART_IMAGE_HEIGHT; ++y) - { - for (AZ::u32 x = 0; x <= width - COLORCHART_IMAGE_WIDTH; ++x) - { - if (IsColorChartAt(x, y, pData, pitch)) - { - outLocX = x; - outLocY = y; - return true; - } - } - } - - return false; - } - - bool C3dLutColorChart::GenerateFromInput(IImageObjectPtr image) - { - AZ::u32 outLocX, outLocY; - if (FindColorChart(image, outLocX, outLocY)) - { - ExtractFromImageAt(image, outLocX, outLocY); - return true; - } - return false; - } - - IImageObjectPtr C3dLutColorChart::GenerateChartImage() - { - const AZ::u32 mipCount = 1; - IImageObjectPtr image( IImageObject::CreateImage(ePS_Red * ePS_Blue, ePS_Green, 1, ePixelFormat_R8G8B8A8)); - - { - AZ::u8* pData; - AZ::u32 pitch; - image->GetImagePointer(0, pData, pitch); - - size_t nSlicePitch = (pitch / ePS_Blue); - AZ::u32 src = 0; - for (int b = 0; b < ePS_Blue; ++b) - { - for (int g = 0; g < ePS_Green; ++g) - { - - AZ::u8* p = pData + g * pitch + b * nSlicePitch; - for (int r = 0; r < ePS_Red; ++r) - { - const SColor& c = m_mapping[src]; - p[0] = c.r; - p[1] = c.g; - p[2] = c.b; - p[3] = 255; - ++src; - p += 4; - } - } - } - } - - return image; - } - - void C3dLutColorChart::ExtractFromImageAt(IImageObjectPtr image, AZ::u32 x, AZ::u32 y) - { - int ox = x + 1; - int oy = y + 1; - - AZ::u8* pData; - AZ::u32 pitch; - image->GetImagePointer(0, pData, pitch); - - m_mapping.reserve(ePS_NumColors); - - for (int b = 0; b < ePS_Blue; ++b) - { - int px = ox + ePS_Red * (b % 4); - int py = oy + ePS_Green * (b / 4); - - for (int g = 0; g < ePS_Green; ++g) - { - for (int r = 0; r < ePS_Red; ++r) - { - AZ::u8* p = pData + pitch * (py + g) + (px + r) * 4; - - SColor col; - col.r = p[0]; - col.g = p[1]; - col.b = p[2]; - m_mapping.push_back(col); - } - } - } - } - - //check if image data at location x and y could be a color chart - //based on if the boarder is dash lines with two pixel each segement - //the idea and implementation are both coming from CryEngine. - bool C3dLutColorChart::IsColorChartAt(AZ::u32 x, AZ::u32 y, void* pData, AZ::u32 pitch) - { - struct Color - { - private: - int c[3]; - - public: - Color(AZ::u32 x, AZ::u32 y, void* pPixels, AZ::u32 pitch) - { - const uint8* p = (const uint8*)pPixels + pitch * y + x * 4; - c[0] = p[0]; - c[1] = p[1]; - c[2] = p[2]; - } - - bool isSimilar(const Color& a, int maxDiff) const - { - return - abs(a.c[0] - c[0]) <= maxDiff && - abs(a.c[1] - c[1]) <= maxDiff && - abs(a.c[2] - c[2]) <= maxDiff; - } - }; - - const Color colorRef[2] = - { - Color(x, y, pData, pitch), - Color(x + 2, y, pData, pitch) - }; - - // We require two colors of the border to be at least a bit different - if (colorRef[0].isSimilar(colorRef[1], 15)) - { - return false; - } - - static const int kMaxDiff = 3; - - int refIdx = 0; - //rectangle's top - for (int i = 0; i < COLORCHART_IMAGE_WIDTH; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x + i, y, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x + i + 1, y, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - refIdx = 0; - //left - for (int i = 0; i < COLORCHART_IMAGE_HEIGHT; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x, y + i, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x, y + i + 1, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - refIdx = 0; - //right - for (int i = 0; i < COLORCHART_IMAGE_HEIGHT; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x + COLORCHART_IMAGE_WIDTH - 1, y + i, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x + COLORCHART_IMAGE_WIDTH - 1, y + i + 1, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - refIdx = 0; - //bottom - for (int i = 0; i < COLORCHART_IMAGE_WIDTH; i += 2) - { - if (!colorRef[refIdx].isSimilar(Color(x + i, y + COLORCHART_IMAGE_HEIGHT - 1, pData, pitch), kMaxDiff) || - !colorRef[refIdx].isSimilar(Color(x + i + 1, y + COLORCHART_IMAGE_HEIGHT - 1, pData, pitch), kMaxDiff)) - { - return false; - } - refIdx ^= 1; - } - - return true; - } - - - void ImageToProcess::CreateColorChart() - { - C3dLutColorChart colorChart; - - //get color chart data from source image. - if (!colorChart.GenerateFromInput(m_img)) - { - //if load from image failed then generate default color data - colorChart.GenerateDefault(); - } - - //save color chart data to an image and save as current - m_img = colorChart.GenerateChartImage(); - } -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/ConvertPixelFormat.cpp b/Gems/ImageProcessing/Code/Source/Converters/ConvertPixelFormat.cpp deleted file mode 100644 index 9a49bf9b63..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/ConvertPixelFormat.cpp +++ /dev/null @@ -1,170 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// -//functions for maintaining alpha coverage. - -namespace ImageProcessing -{ - void ImageToProcess::ConvertFormat(EPixelFormat fmtDst) - { - //pixel format before convertion - EPixelFormat fmtSrc = Get()->GetPixelFormat(); - - //return directly if the image already has the desired pixel format - if (fmtDst == fmtSrc) - { - return; - } - - uint32 dwWidth, dwHeight, dwMips; - dwWidth = Get()->GetWidth(0); - dwHeight = Get()->GetHeight(0); - dwMips = Get()->GetMipCount(); - - //if the output image size doesn't work the desired pixel format. set to fallback format - const PixelFormatInfo* dstFmtInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(fmtDst); - if (!CPixelFormats::GetInstance().IsImageSizeValid(fmtDst, dwWidth, dwHeight, true)) - { - AZ_Warning("Image Processing", false, "Output pixel format %d doesn't work with output image size %d x %d", - fmtDst, dwWidth, dwHeight); - - //fall back to safe texture format - if (dstFmtInfo->nChannels == 1) - { - fmtDst = dstFmtInfo->bHasAlpha ? ePixelFormat_A8 : ePixelFormat_R8; - } - else if (dstFmtInfo->nChannels == 2) - { - fmtDst = ePixelFormat_R8G8; - } - else - { - fmtDst = dstFmtInfo->bHasAlpha ? ePixelFormat_R8G8B8A8 : ePixelFormat_R8G8B8X8; - } - } - - //convert src image to uncompressed formats if it's compressed format - bool isSrcUncompressed = CPixelFormats::GetInstance().IsPixelFormatUncompressed(fmtSrc); - bool isDstUncompressed = CPixelFormats::GetInstance().IsPixelFormatUncompressed(fmtDst); - - if (isSrcUncompressed && isDstUncompressed) - {//both are uncompressed - ConvertFormatUncompressed(fmtDst); - } - else if (!isSrcUncompressed && !isDstUncompressed) - { //both are compressed - AZ_Assert(false, "unusual user case. but we can still handle it"); - } - else - { //one fmt is compressed format - //use the compressed format to find right compressor - EPixelFormat compressedFmt = isSrcUncompressed ? fmtDst : fmtSrc; - EPixelFormat uncompressedFmt = isSrcUncompressed ? fmtSrc : fmtDst; - ICompressorPtr compressor = ICompressor::FindCompressor(compressedFmt, isSrcUncompressed); - - if (compressor == nullptr) - { - //no avaible compressor for compressed format - AZ_Warning("Image Processing", false, "No avaliable compressor for pixel format %d", compressedFmt); - return; - } - - //check if the uncompressed fmt also supported by the compressor - EPixelFormat desiredUncompressedFmt = compressor->GetSuggestedUncompressedFormat(compressedFmt, uncompressedFmt); - if (desiredUncompressedFmt != uncompressedFmt) - { - //we need to do intermedia convertion to convert to the temperory format - ConvertFormat(desiredUncompressedFmt); - ConvertFormat(fmtDst); - } - else - { - IImageObjectPtr dstImage = nullptr; - if (isSrcUncompressed) - { - dstImage = compressor->CompressImage(Get(), fmtDst, &m_compressOption); - } - else - { - dstImage = compressor->DecompressImage(Get(), fmtDst); - } - - Set(dstImage); - } - - if (Get() == nullptr) - { - AZ_Error("Image Processing", false, "The selected compressor failed to compress this image"); - } - } - } - - void ImageToProcess::ConvertFormatUncompressed(EPixelFormat fmtTo) - { - IImageObjectPtr srcImage = m_img; - EPixelFormat srcFmt = srcImage->GetPixelFormat(); - EPixelFormat dstFmt = fmtTo; - - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcFmt) - && CPixelFormats::GetInstance().IsPixelFormatUncompressed(dstFmt))) - { - AZ_Assert(false, "both source and dest images' pixel format need to be uncompressed"); - return; - } - - IImageObjectPtr dstImage(m_img->AllocateImage(fmtTo)); - - AZ_Assert(srcImage->GetPixelCount(0) == dstImage->GetPixelCount(0), "dest image has different size than source image"); - - //create pixel operation function for src and dst images - IPixelOperationPtr srcOp = CreatePixelOperation(srcFmt); - IPixelOperationPtr dstOp = CreatePixelOperation(dstFmt); - - //get count of bytes per pixel for both src and dst images - uint32 srcPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(srcFmt)->bitsPerBlock / 8; - uint32 dstPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->bitsPerBlock / 8; - - const uint32 dwMips = dstImage->GetMipCount(); - float r, g, b, a; - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* srcPixelBuf; - uint32 srcPitch; - srcImage->GetImagePointer(dwMip, srcPixelBuf, srcPitch); - uint8* dstPixelBuf; - uint32 dstPitch; - dstImage->GetImagePointer(dwMip, dstPixelBuf, dstPitch); - - const uint32 pixelCount = srcImage->GetPixelCount(dwMip); - - for (uint32 i = 0; i < pixelCount; ++i, srcPixelBuf += srcPixelBytes, dstPixelBuf += dstPixelBytes) - { - srcOp->GetRGBA(srcPixelBuf, r, g, b, a); - dstOp->SetRGBA(dstPixelBuf, r, g, b, a); - } - } - - m_img = dstImage; - } - - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.cpp b/Gems/ImageProcessing/Code/Source/Converters/Cubemap.cpp deleted file mode 100644 index 71e629b553..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.cpp +++ /dev/null @@ -1,620 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -namespace ImageProcessing -{ - CubemapLayoutInfo CubemapLayout::s_layoutList[CubemapLayoutTypeCount]; - - template - inline bool IsPowerOfTwo(TInteger x) - { - return (x & (x - 1)) == 0; - } - - CubemapLayoutInfo::CubemapLayoutInfo() - : m_type(CubemapLayoutNone) - , m_rows(0) - , m_columns(0) - { - - } - - void CubemapLayoutInfo::SetFaceInfo(CubemapFace face, AZ::u8 row, AZ::u8 col, CubemapFaceDirection dir) - { - m_faceInfos[face].row = row; - m_faceInfos[face].column = col; - m_faceInfos[face].direction = dir; - } - - void CubemapLayout::InitCubemapLayoutInfos() - { - //CubemapLayoutHorizontal - //left , right, front, back, top, bottom; - //NOTE: this layout is widely used in game projects by Jan 2018 since other layouts weren't supported correctly - //but the faces in one has unusual directions compare to other format. - //The direction matters when using it as input for Cubemap generation filter. - //Left: rotated left 90 degree. Right: rotated right 90 degree - //Front: rotated 180 degree. Back: no rotation - //Top: rotate 180 degree. Bottom: no rotation - CubemapLayoutInfo *info = &s_layoutList[CubemapLayoutHorizontal]; - info->m_rows = 1; - info->m_columns = 6; - info->m_type = CubemapLayoutHorizontal; - info->SetFaceInfo(FaceLeft, 0, 0, CubemapFaceDirection::DirRotateLeft90); - info->SetFaceInfo(FaceRight, 0, 1, CubemapFaceDirection::DirRotateRight90); - info->SetFaceInfo(FaceFront, 0, 2, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBack, 0, 3, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceTop, 0, 4, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBottom, 0, 5, CubemapFaceDirection::DirNoRotation); - - //CubemapLayoutHorizontalCross - // top - // left front right back - // bottom - info = &s_layoutList[CubemapLayoutHorizontalCross]; - info->m_rows = 3; - info->m_columns = 4; - info->m_type = CubemapLayoutHorizontalCross; - info->SetFaceInfo(FaceLeft, 1, 0, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceRight, 1, 2, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceFront, 1, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBack, 1, 3, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceTop, 0, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBottom, 2, 1, CubemapFaceDirection::DirNoRotation); - - //CubemapLayoutVerticalCross - // top - // left front right - // bottom - // back - info = &s_layoutList[CubemapLayoutVerticalCross]; - info->m_rows = 4; - info->m_columns = 3; - info->m_type = CubemapLayoutVerticalCross; - info->SetFaceInfo(FaceLeft, 1, 0, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceRight, 1, 2, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceFront, 1, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBack, 3, 1, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceTop, 0, 1, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceBottom, 2, 1, CubemapFaceDirection::DirNoRotation); - - //CubemapLayoutVertical - // left - // right - // front - // back - // top - // bottom - info = &s_layoutList[CubemapLayoutVertical]; - info->m_rows = 6; - info->m_columns = 1; - info->m_type = CubemapLayoutVertical; - info->SetFaceInfo(FaceLeft, 0, 0, CubemapFaceDirection::DirRotateLeft90); - info->SetFaceInfo(FaceRight, 1, 0, CubemapFaceDirection::DirRotateRight90); - info->SetFaceInfo(FaceFront, 2, 0, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBack, 3, 0, CubemapFaceDirection::DirNoRotation); - info->SetFaceInfo(FaceTop, 4, 0, CubemapFaceDirection::DirRotate180); - info->SetFaceInfo(FaceBottom, 5, 0, CubemapFaceDirection::DirNoRotation); - - //make sure all types were initialized - for (int i = 0; i < CubemapLayoutTypeCount; i++) - { - AZ_Assert(s_layoutList[i].m_type == i, "layout %d is not initialized", i); - } - } - - const float* GetTransformMatrix(CubemapFaceDirection dir, bool isInvert) - { - switch (dir) - { - case CubemapFaceDirection::DirNoRotation: - { - static const float mat[] = { 1, 0, 0, 1 }; - return mat; - } - case CubemapFaceDirection::DirRotateLeft90: - { - //thelta = 90 degree - //{cos, -sin, sin, cos} - if (isInvert) - { - return GetTransformMatrix(CubemapFaceDirection::DirRotateRight90, false); - } - static const float mat[] = { 0, -1, 1, 0 }; - return mat; - } - case CubemapFaceDirection::DirRotateRight90: - { - //thelta = -90 degree - if (isInvert) - { - return GetTransformMatrix(CubemapFaceDirection::DirRotateLeft90, false); - } - static const float mat[] = { 0, 1, -1, 0 }; - return mat; - } - case CubemapFaceDirection::DirRotate180: - { - //thelta = 180 degree - static const float mat[] = { -1, 0, 0, -1 }; - return mat; - } - case CubemapFaceDirection::DirMirrorHorizontal: - { - static const float mat[] = { 1, 0, 0, -1 }; - return mat; - } - default: - { - AZ_Assert(false, "unimplemented direction matrix"); - static const float mat[] = { 1, 0, 0, 1 }; - return mat; - } - } - } - - void TransformImage(CubemapFaceDirection srcDir, CubemapFaceDirection dstDir, const AZ::u8* srcImageBuf, - AZ::u8* dstImageBuf, AZ::u8 bytePerPixel, AZ::u32 rectSize) - { - //get final matrix to transform dst back to src - const float* m1 = GetTransformMatrix(dstDir, true); - const float* m2 = GetTransformMatrix(srcDir, false); - float mtx[4]; - mtx[0] = m1[0] * m2[0] + m1[1] * m2[2]; - mtx[1] = m1[0] * m2[1] + m1[1] * m2[3]; - mtx[2] = m1[2] * m2[0] + m1[3] * m2[2]; - mtx[3] = m1[2] * m2[1] + m1[3] * m2[3]; - - const float* noRotate = GetTransformMatrix(CubemapFaceDirection::DirNoRotation, false); - - if (memcmp(noRotate, mtx, 4 * sizeof(float)) == 0) - { - memcpy(dstImageBuf, srcImageBuf, rectSize*rectSize*bytePerPixel); - return; - } - - //for each pixel in dst image, find it's location in src and copy the data from there - float halfSize = rectSize / 2; - for (AZ::u32 row = 0; row < rectSize; row++) - { - for (AZ::u32 col = 0; col < rectSize; col++) - { - //coordinate in image center as origin and right as positive X, up as positive Y - float dstX = col + 0.5f - halfSize; - float dstY = halfSize - row - 0.5f; - float srcX = dstX * mtx[0] + dstY * mtx[1]; - float srcY = dstX * mtx[2] + dstY * mtx[3]; - AZ::u32 srcCol = srcX + halfSize; - AZ::u32 srcRow = halfSize - srcY; - - memcpy(&dstImageBuf[(row*rectSize + col)*bytePerPixel], - &srcImageBuf[(srcRow*rectSize + srcCol)*bytePerPixel], bytePerPixel); - } - } - } - - CubemapLayout::CubemapLayout() - : m_info(nullptr) - , m_image(nullptr) - , m_faceSize(256) - { - } - - CubemapLayout* CubemapLayout::CreateCubemapLayout(IImageObjectPtr image) - { - //only support uncompressed format. - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(image->GetPixelFormat())) - { - AZ_Assert(false, "CubemapLayout only support uncompressed image"); - return nullptr; - } - - CubemapLayout* layout = nullptr; - CubemapLayoutInfo* info = GetCubemapLayoutInfo(image); - if (info) - { - layout = new CubemapLayout(); - layout->m_info = GetCubemapLayoutInfo(image); - layout->m_image = image; - layout->m_faceSize = image->GetWidth(0)/layout->m_info->m_columns; - } - return layout; - } - - - CubemapLayoutInfo* CubemapLayout::GetCubemapLayoutInfo(CubemapLayoutType type) - { - if (type == CubemapLayoutNone) - { - return nullptr; - } - - //if it's never initialized - if (s_layoutList[0].m_type == CubemapLayoutNone) - { - InitCubemapLayoutInfos(); - } - - return &s_layoutList[type]; - } - - CubemapLayoutInfo* CubemapLayout::GetCubemapLayoutInfo(IImageObjectPtr image) - { - //if it's never initialized - if (s_layoutList[0].m_type == CubemapLayoutNone) - { - InitCubemapLayoutInfos(); - } - - if (image == nullptr) - { - return nullptr; - } - - uint32 width, height; - width = image->GetWidth(0); - height = image->GetHeight(0); - CubemapLayoutInfo* info = nullptr; - - for (int i = 0; i < CubemapLayoutTypeCount; i++) - { - if (width * s_layoutList[i].m_rows == height*s_layoutList[i].m_columns) - { - info = &s_layoutList[i]; - - //we require the face size need to be power of two - if (IsPowerOfTwo(width / info->m_columns)) - { - return info; - } - else - { - return nullptr; - } - } - } - return nullptr; - } - - //public functions to get faces information for associated image - AZ::u32 CubemapLayout::GetFaceSize() - { - return m_faceSize; - } - - CubemapLayoutInfo* CubemapLayout::GetLayoutInfo() - { - return m_info; - } - - CubemapFaceDirection CubemapLayout::GetFaceDirection(CubemapFace face) - { - return m_info->m_faceInfos[face].direction; - } - - void CubemapLayout::GetFaceData(CubemapFace face, void* outBuffer, AZ::u32& outSize) - { - //only valid for uncompressed - AZ::u32 sizePerPixel = CPixelFormats::GetInstance().GetPixelFormatInfo(m_image->GetPixelFormat())->bitsPerBlock / 8; - - AZ::u8* imageBuf; - AZ::u32 dwPitch; - m_image->GetImagePointer(0, imageBuf, dwPitch); - AZ::u8* dstBuf = (AZ::u8*)outBuffer; - - AZ::u32 startX = m_info->m_faceInfos[face].column * m_faceSize; - AZ::u32 startY = m_info->m_faceInfos[face].row * m_faceSize; - - //face size is same as rows for uncompressed format - for (AZ::u32 y = 0; y < m_faceSize; y++) - { - AZ::u32 scanlineSize = m_faceSize*sizePerPixel; - AZ::u8* srcBuf = &imageBuf[(startY + y) * dwPitch + startX*sizePerPixel]; - memcpy(dstBuf, srcBuf, scanlineSize); - dstBuf += scanlineSize; - } - - outSize = m_faceSize*m_faceSize*sizePerPixel; - - } - - void CubemapLayout::SetFaceData(CubemapFace face, void* dataBuffer, [[maybe_unused]] AZ::u32 dataSize) - { - //only valid for uncompressed - AZ::u32 sizePerPixel = CPixelFormats::GetInstance().GetPixelFormatInfo(m_image->GetPixelFormat())->bitsPerBlock / 8; - - AZ::u8* imageBuf; - AZ::u32 dwPitch; - m_image->GetImagePointer(0, imageBuf, dwPitch); - AZ::u8* srcBuf = (AZ::u8*)dataBuffer; - - AZ::u32 startX = m_info->m_faceInfos[face].column * m_faceSize; - AZ::u32 startY = m_info->m_faceInfos[face].row * m_faceSize; - - //face size is same as rows for uncompressed format - for (AZ::u32 y = 0; y < m_faceSize; y++) - { - AZ::u32 scanlineSize = m_faceSize*sizePerPixel; - AZ::u8* dstBuf = &imageBuf[(startY + y) * dwPitch + startX*sizePerPixel]; - memcpy(dstBuf, srcBuf, scanlineSize); - srcBuf += scanlineSize; - } - } - - void* CubemapLayout::GetFaceMemBuffer(AZ::u32 mip, CubemapFace face, AZ::u32& outPitch) - { - if (CubemapLayoutVertical != m_info->m_type) - { - AZ_Assert(false, "this should only be used for CubemapLayoutVertical which has continous memory for each face"); - return nullptr; - } - - AZ::u32 faceSize = m_faceSize >> mip; - AZ::u8* imageBuf; - m_image->GetImagePointer(mip, imageBuf, outPitch); - AZ::u32 startY = m_info->m_faceInfos[face].row * faceSize; - - //use startY is same as rows from m_image since the pixel format is uncompressed - return &imageBuf[startY * outPitch]; - } - - void CubemapLayout::SetToFaceMemBuffer(AZ::u32 mip, CubemapFace face, void* dataBuffer) - { - if (CubemapLayoutVertical != m_info->m_type) - { - AZ_Assert(false, "this should only be used for CubemapLayoutVertical which has continuous memory for each face"); - return; - } - - AZ::u32 faceSize = m_faceSize >> mip; - AZ::u32 pitch; - AZ::u8* imageBuf; - m_image->GetImagePointer(mip, imageBuf, pitch); - AZ::u32 startY = m_info->m_faceInfos[face].row * faceSize; - - //use startY is same as rows from m_image since the pixel format is uncompressed - memcpy(&imageBuf[startY * pitch], dataBuffer, faceSize*pitch); - } - - void CubemapLayout::GetRectForFace(AZ::u32 mip, CubemapFace face, QRect& outRect) - { - AZ::u32 faceSize = m_faceSize >> mip; - AZ::u32 startY = m_info->m_faceInfos[face].row * faceSize; - AZ::u32 startX = m_info->m_faceInfos[face].column * faceSize; - - outRect.setRect(startX, startY, faceSize, faceSize); - } - - bool ImageToProcess::ConvertCubemapLayout(CubemapLayoutType dstLayoutType) - { - const EPixelFormat srcPixelFormat = m_img->GetPixelFormat(); - - //it need to be uncompressed format - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcPixelFormat)) - { - AZ_Assert(false, "Please convert the image to uncompressed pixel format before calling ConvertCubemapLayout"); - return false; - } - - //check if it's valid cubemap size - CubemapLayoutInfo* layoutInfo = CubemapLayout::GetCubemapLayoutInfo(m_img); - if (layoutInfo == nullptr) - { - AZ_Error("Image Processing", false, "The original image doesn't have a valid size (layout) as cubemap"); - return false; - } - - //if the source is same as output layout, return directly - if (layoutInfo->m_type == dstLayoutType) - { - return true; - } - - CubemapLayoutInfo* dstLayoutInfo = CubemapLayout::GetCubemapLayoutInfo(dstLayoutType); - - //create cubemap layout for source image for later operation. - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_img); - AZ::u32 faceSize = srcCubemap->GetFaceSize(); - - //create new image with same pixel format and copy prperties from source image - IImageObjectPtr newImage(IImageObject::CreateImage(faceSize * dstLayoutInfo->m_columns, - faceSize*dstLayoutInfo->m_rows, 1, srcPixelFormat)); - CubemapLayout *dstCubemap = CubemapLayout::CreateCubemapLayout(newImage); - newImage->CopyPropertiesFrom(newImage); - - //copy data from src cube to dst cube for each face - //temp buf for copy over data - AZ::u32 sizePerPixel = CPixelFormats::GetInstance().GetPixelFormatInfo(srcPixelFormat)->bitsPerBlock/8; //only valid for uncompressed - AZ::u8 *buf = new AZ::u8[faceSize*faceSize*sizePerPixel]; - AZ::u8 *tempBuf = new AZ::u8[faceSize*faceSize*sizePerPixel]; - - for (AZ::u32 faceIdx = 0; faceIdx < FaceCount; faceIdx++) - { - AZ::u32 outSize = 0; - CubemapFace face = (CubemapFace)faceIdx; - srcCubemap->GetFaceData(face, buf, outSize); - CubemapFaceDirection srcDir = srcCubemap->GetFaceDirection(face); - CubemapFaceDirection dstDir = dstCubemap->GetFaceDirection(face); - if (srcDir == dstDir) - { - dstCubemap->SetFaceData(face, buf, outSize); - } - else - { - //transform the image - TransformImage(srcDir, dstDir, buf, tempBuf, sizePerPixel, faceSize); - dstCubemap->SetFaceData(face, tempBuf, outSize); - } - } - - //clean up - delete[] buf; - delete[] tempBuf; - delete srcCubemap; - delete dstCubemap; - - newImage->AddImageFlags(EIF_Cubemap); - m_img = newImage; - return true; - } - - bool ImageConvertProcess::FillCubemapMipmaps() - { - //this function only works with pixel format rgba32f - const EPixelFormat srcPixelFormat = m_image->Get()->GetPixelFormat(); - if (srcPixelFormat != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s only works with pixel format rgba32f", __FUNCTION__); - return false; - } - - //only if the src image has one mip - if (m_image->Get()->GetMipCount() != 1) - { - AZ_Assert(false, "%s called for a mipmapped image. ", __FUNCTION__); - return false; - } - - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_image->Get()); - - uint32 outWidth; - uint32 outHeight; - uint32 outReduce = 0; - AZ::u32 srcFaceSize = srcCubemap->GetFaceSize(); - //get output face size - GetOutputExtent(srcFaceSize, srcFaceSize, outWidth, outHeight, outReduce, &m_textureSetting, &m_presetSetting); - AZ_Assert(outWidth == outHeight, "something wrong with GetOutputExtent function"); - - //get final cubemap image size - outWidth *= srcCubemap->GetLayoutInfo()->m_columns; - outHeight *= srcCubemap->GetLayoutInfo()->m_rows; - - //max mipmap count - uint32 maxMipCount; - if (m_presetSetting.m_mipmapSetting == nullptr || !m_textureSetting.m_enableMipmap) - { - maxMipCount = 1; - } - else - { - //calculate based on face size, and use final export format which may save some low level mip calculation - maxMipCount = CPixelFormats::GetInstance().ComputeMaxMipCount(m_presetSetting.m_pixelFormat, srcFaceSize, srcFaceSize); - - //the FilterImage function won't do well with rect size 1. avoiding cubemap with face size 1 - if (srcFaceSize >> maxMipCount == 1 && maxMipCount > 1) - { - maxMipCount -= 1; - } - } - - //create new new output image with proper face - IImageObjectPtr outImage(IImageObject::CreateImage(outWidth, outHeight, maxMipCount, srcPixelFormat)); - outImage->CopyPropertiesFrom(m_image->Get()); - CubemapLayout *dstCubemap = CubemapLayout::CreateCubemapLayout(outImage); - AZ::u32 outFaceSize = dstCubemap->GetFaceSize(); - AZ::u32 dstMipCount = outImage->GetMipCount(); - - //filter the image for top mip first - for (int iSide = 0; iSide < 6; ++iSide) - { - QRect srcRect; - QRect dstRect; - - srcRect.setLeft(0); - srcRect.setRight(srcFaceSize); - srcRect.setTop(iSide * srcFaceSize); - srcRect.setBottom((iSide + 1) * srcFaceSize); - - dstRect.setLeft(0); - dstRect.setRight(outFaceSize); - dstRect.setTop(iSide * outFaceSize); - dstRect.setBottom((iSide + 1) * outFaceSize); - - FilterImage(m_textureSetting.m_mipGenType, m_textureSetting.m_mipGenEval, 0, 0, m_image->Get(), 0, - outImage, 0, &srcRect, &dstRect); - } - - - CCubeMapProcessor atiCubemanGen; - //ATI's cubemap generator to filter the image edges to avoid seam problem - // https://gpuopen.com/archive/gamescgi/cubemapgen/ - - //the thread support was done with windows thread function so it's removed for multi-dev platform support - atiCubemanGen.m_NumFilterThreads = 0; - - // input and output cubemap set to have save dimensions, - atiCubemanGen.Init(outFaceSize, outFaceSize, dstMipCount, 4); - - // Load the 6 faces of the input cubemap and copy them into the cubemap processor - void* pMem; - uint32 nPitch; - - for (int iFace = 0; iFace < 6; ++iFace) - { - pMem = dstCubemap->GetFaceMemBuffer(0, (CubemapFace)iFace, nPitch); - atiCubemanGen.SetInputFaceData( - iFace, // FaceIdx, - CP_VAL_FLOAT32, // SrcType, - 4, // SrcNumChannels, - nPitch, // SrcPitch, - pMem, // SrcDataPtr, - 1000000.0f, // MaxClamp, - 1.0f, // Degamma, - 1.0f); // Scale - } - - //Filter cubemap - atiCubemanGen.InitiateFiltering( - m_presetSetting.m_cubemapSetting->m_angle, //BaseFilterAngle, - m_presetSetting.m_cubemapSetting->m_mipAngle, //InitialMipAngle, - m_presetSetting.m_cubemapSetting->m_mipSlope, //MipAnglePerLevelScale, - (int)m_presetSetting.m_cubemapSetting->m_filter, //FilterType, CP_FILTER_TYPE_COSINE for diffuse cube - m_presetSetting.m_cubemapSetting->m_edgeFixup > 0? CP_FIXUP_PULL_LINEAR : CP_FIXUP_NONE, //FixupType, CP_FIXUP_PULL_LINEAR if FixupWidth> 0 - m_presetSetting.m_cubemapSetting->m_edgeFixup, //FixupWidth, - true, //bUseSolidAngle, - 16, //GlossScale, - 0, //GlossBias - 128); //SampleCountGGX - - // Download data into it - for (int iFace = 0; iFace < 6; ++iFace) - { - for (unsigned int dstMip = 0; dstMip < dstMipCount; ++dstMip) - { - pMem = dstCubemap->GetFaceMemBuffer(dstMip, (CubemapFace)iFace, nPitch); - atiCubemanGen.GetOutputFaceData(iFace, dstMip, CP_VAL_FLOAT32, 4, nPitch, pMem, 1.0f, 1.0f); - } - } - - delete srcCubemap; - delete dstCubemap; - - //set back to image - m_image->Set(outImage); - return true; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.h b/Gems/ImageProcessing/Code/Source/Converters/Cubemap.h deleted file mode 100644 index 76dd8d2c30..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Cubemap.h +++ /dev/null @@ -1,118 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - // note: O3DE is right hand Z up coordinate - // please don't change the order of the enum since we are using it to match the face id defined in AMD's CubemapGen - // and they are using left hand Y up coordinate - enum CubemapFace - { - FaceLeft = 0, - FaceRight, - FaceFront, - FaceBack, - FaceTop, - FaceBottom, - FaceCount - }; - - //we are treating the orientation of faces in 4x3 layout as the original direction. - enum class CubemapFaceDirection - { - DirNoRotation = 0, - DirRotateLeft90, - DirRotateRight90, - DirRotate180, - DirMirrorHorizontal - }; - - //this class contains information to describe a cubemap layout - class CubemapLayoutInfo - { - public: - struct FaceInfo - { - AZ::u8 row; - AZ::u8 column; - CubemapFaceDirection direction; - }; - - //rows and columns of how cubemap's faces laid - AZ::u8 m_rows; - AZ::u8 m_columns; - - //the type of this layout info for - CubemapLayoutType m_type; - - //the index of row and column where all the faces located - FaceInfo m_faceInfos[FaceCount]; - - CubemapLayoutInfo(); - void SetFaceInfo(CubemapFace face, AZ::u8 row, AZ::u8 col, CubemapFaceDirection dir); - }; - - //class to help doing operations with faces for an image as cubemap - class CubemapLayout - { - public: - //create a cubemapLayout object for the image. It can be used later to get image information as a cubemap - static CubemapLayout* CreateCubemapLayout(IImageObjectPtr image); - - //get layout info for input layout type - static CubemapLayoutInfo* GetCubemapLayoutInfo(CubemapLayoutType type); - - //get layout info for input image based on its size - static CubemapLayoutInfo* GetCubemapLayoutInfo(IImageObjectPtr image); - - //public functions to get faces information for associated image - AZ::u32 GetFaceSize(); - - //get the rect where the face in the image - void GetRectForFace(AZ::u32 mip, CubemapFace face, QRect& outRect); - - CubemapLayoutInfo* GetLayoutInfo(); - - //set/get pixels' data from/to specific face. only works for mip 0 - void GetFaceData(CubemapFace face, void* outBuffer, AZ::u32& outSize); - void SetFaceData(CubemapFace face, void* dataBuffer, AZ::u32 dataSize); - - //get the face's direction - CubemapFaceDirection GetFaceDirection(CubemapFace face); - - //get memory for a face from Image data. only works for CubemapLayoutVertical since its memory for each face is continuous - void* GetFaceMemBuffer(AZ::u32 mip, CubemapFace face, AZ::u32& outPitch); - void SetToFaceMemBuffer(AZ::u32 mip, CubemapFace face, void* dataBuffer); - - private: - //information for all supported cubemap layouts - static CubemapLayoutInfo s_layoutList[CubemapLayoutTypeCount]; - - //the image associated for this CubemapLayout - IImageObjectPtr m_image; - //the layout information of m_image - CubemapLayoutInfo *m_info; - //the size of the cubemap's face (which is square and power of 2). - uint32 m_faceSize; - - //private constructor. User should always use CreateCubemapLayout create a layout for an image object - CubemapLayout(); - - //initialize information of all available cubemap layouts - static void InitCubemapLayoutInfos(); - }; - -}//end namspace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Filter.cpp b/Gems/ImageProcessing/Code/Source/Converters/FIR-Filter.cpp deleted file mode 100644 index 8d1b8f2877..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Filter.cpp +++ /dev/null @@ -1,1285 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include - -/* #################################################################################################################### - */ -#define mallocAligned(sze) _aligned_malloc(sze, 16) -#define freeAligned(ptr) _aligned_free(ptr) - -/* #################################################################################################################### - */ - -namespace ImageProcessing -{ - class Rect2D - { - public: - /* ================================================================================================================== - * Rect2D = ??? - */ - Rect2D() { } - Rect2D(const int x, const int y) { visual[0] = x; visual[1] = y; } - - private: - int visual[2]; - - public: - /* ================================================================================================================== - * Access operators - * M(i, j) == [row i][col j] - */ - inline int& operator () (int i) { return visual[i]; } - inline int operator () (int i) const { return visual[i]; } - - inline int& operator [] (int i) { return visual[i]; } - inline int operator [] (int i) const { return visual[i]; } - - /* ================================================================================================================== - * Logical operators - */ - inline bool operator == (const Rect2D& tht) - { - return (visual[0] == tht.visual[0]) && - (visual[1] == tht.visual[1]); - } - }; - - /* #################################################################################################################### - */ - template - class Plane2D - { - public: - /* ================================================================================================================== - * Plane2D = ??? - */ - Plane2D(const int x, const int y, const int p) { planes = p; allocatedC[0] = x; allocatedC[1] = y; used = allocatedC; aligned[0] = (allocatedC[0] + 15) & (~15); aligned[1] = allocatedC[1]; allocate(); } - Plane2D(const Rect2D& i, const int p) { planes = p; allocatedC = i; used = allocatedC; aligned[0] = (allocatedC[0] + 15) & (~15); aligned[1] = allocatedC[1]; allocate(); } - - ~Plane2D() { deallocate(); } - - /* ================================================================================================================== - * ??? = Plane2D - */ - inline operator Rect2D() const { return used; } - inline operator int () const { return planes; } - - inline operator DataType* () const { return buffers; } - inline operator DataType*** () const { return rows; } - inline operator const DataType* () const { return (const DataType*)buffers; } - inline operator const DataType*** () const { return (const DataType***)rows; } - - public: - inline void locate(Rect2D take) - { - taken = take; - - if ((taken[0] > aligned[0]) || - (taken[1] > abs(aligned[1]))) - { - abort(); - } - - /* align column#length */ - used[0] = (taken[0] + 15) & (~15); - used[1] = taken[1]; - - for (int p = 0; p < planes; p++) - { - /* we may need to replicate the row-unsigned __int64 over all rows only (y < 0) */ - const unsigned long int rowsize = (aligned[1] <= 0 ? 0 : aligned[0] * sizeof(DataType)); - int r; - char* buffer; - AZ_Assert((rowsize % 16) == 0, "%s: Unexpected row size!", __FUNCTION__); - - /* first block contains the row*-pointers */ - rows[p] = (DataType**)((char*)(rows + planes) + rowblocksize * p) + excess; - - /* "excess" empty pointers on negative offsets ----------------------------- */ - buffer = (char*)NULL; - AZ_Assert((reinterpret_cast(buffer) % 16) == 0, "%s: Unexpected buffer size!", __FUNCTION__); - - - for (r = -excess; r < 0; r++) - { - rows[p][r] = (DataType*)buffer; - } - - /* regular row-pointers ---------------------------------------------------- */ - buffer = (char*)buffers + (planesize * p); - AZ_Assert((reinterpret_cast(buffer) % 16) == 0, "%s: Unexpected buffer size!", __FUNCTION__); - - for (r = 0; r < abs(aligned[1]); r++, buffer += rowsize) - { - rows[p][r] = (DataType*)buffer; - } - - /* overhanging row-pointers show on the first valid row (loop) ------------- */ - buffer = (char*)buffers + (planesize * p); - AZ_Assert((reinterpret_cast(buffer) % 16) == 0, "%s: Unexpected buffer size!", __FUNCTION__); - - - for (r = abs(aligned[1]); r < abs(aligned[1]) + excess; r++, buffer += rowsize) - { - rows[p][r] = (DataType*)buffer; - } - } - } - - inline void clear() - { - memset(buffers, 0, planesize * planes); - } - - inline void delocate() - { - memset(buffers, 0, planesize * planes); - memset(rows, 0, sizeof(DataType * *) * planes + rowblocksize * planes); - } - - inline void relocate(Rect2D take) - { - delocate(); - locate(take); - } - - protected: - inline void allocate () - { - /* adjust rows */ - allocatedC[0] = allocatedC[0]; - allocatedC[1] = maximum(1, allocatedC[1]); - - /* if "(y < 0)", we allocate exactly 1 row and replicate it over "abs(y)" */ - planesize = sizeof(DataType) * aligned[0] * maximum(1, aligned[1]); - rowblocksize = sizeof(DataType*) * (abs(aligned[1]) + (2 * excess) + 16); - - /* all planes after each other: - * - * start -> plane0 -> plane1 -> ... - */ - buffers = (DataType* )AZ_OS_MALLOC(planesize * planes, 16); - /* all pointers after each other: - * - * start -> unsigned __int64 to planes -> unsigned __int64 to rows of planes - */ - rows = (DataType***)AZ_OS_MALLOC(sizeof(DataType * *) * planes + rowblocksize * planes, 16); - - /* ensure the blocks are aligned */ - AZ_Assert(((AZ::s64)buffers % 16) == 0, "%s: Expect blocks are aligned!", __FUNCTION__); - /* ensure the planes concat aligned */ - AZ_Assert((planesize % 16) == 0, "%s: Expect planes concat is aligned!", __FUNCTION__); - - locate(allocatedC); - } - - inline void deallocate() - { - AZ_OS_FREE(buffers); - AZ_OS_FREE(rows); - } - - Rect2D allocatedC, aligned; // real buffer sizes and its aligned counterpart - Rect2D taken, used; // actually taken sizes and its aligned counterpart - - int planes; - long int planesize, rowblocksize; - DataType* buffers; - DataType*** rows; - }; - - /* #################################################################################################################### \ - */ - #define filterTVariables(filterVxNNum, dtyp, wtyp, reps) \ - /* addition of c-pointers already takes care of datatype-sizes */ \ - const signed long int dy = /*parm->mirror ? -1 :*/ 1; \ - const unsigned int stridei = parm->incols * 1 * 1; \ - const unsigned int stridet = parm->subcols * 1 * 1; \ - const unsigned int strideo = parm->outcols * 1 * 1; \ - /* offset and shift calculations still require the unmodified values */ \ - const unsigned int strideiraw = parm->incols; \ - const unsigned int stridetraw = parm->subcols; \ - const unsigned int strideoraw = parm->outcols; \ - \ - class Plane2D tmp(tmpcols, tmprows, 4); \ - dtyp*** t = (dtyp***)tmp; \ - int srcPos, dstPos; \ - bool plusminush = false; const bool of = true; \ - bool plusminusv = false; const bool nc = false; \ - FilterWeights* fwh = calculateFilterWeights(parm->resample.colrem, parm->caged ? 0 : 0 - parm->region.subtop, parm->caged ? srccols : parm->subrows - parm->region.subtop, \ - parm->resample.colquo, 0, dstcols, reps, parm->resample.colblur, parm->resample.wf, parm->resample.operation != eWindowEvaluation_Sum, plusminush); \ - FilterWeights* fwv = calculateFilterWeights(parm->resample.rowrem, parm->caged ? 0 : 0 - parm->region.intop, parm->caged ? srcrows : parm->inrows - parm->region.intop, \ - parm->resample.rowquo, 0, dstrows, reps, parm->resample.rowblur, parm->resample.wf, parm->resample.operation != eWindowEvaluation_Sum, plusminusv); \ - - #define filterFTVariables(filterVxNNum) \ - filterTVariables(filterVxNNum, float, signed short, 1) - - /* #################################################################################################################### \ - */ - #define filterTCleanUp(filterVxNNum) \ - delete[] fwh; \ - delete[] fwv; - - /* #################################################################################################################### \ - */ - #define filterTInitLoop() - - /* ******************************************************************************************************************** \ - */ - #define filterTExitLoop() - - /* #################################################################################################################### \ - */ - #define filter4xNf(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, pm, hv, dtyp, atyp) \ - init(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - \ - dstPos = 0; do { \ - FilterWeights& fw = *(hv + dstPos); \ - const signed short* w = fw.weights; \ - \ - next(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - \ - atyp res0 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - atyp res1 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - atyp res2 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - atyp res3 = (op != eWindowEvaluation_Min ? 0 : 32768); \ - \ - srcPos = fw.first; do { \ - /* get value */ \ - fetch(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - \ - /* build result using sign inverted weights [32767,-32768] */ \ - if constexpr (op == eWindowEvaluation_Sum) { \ - res0 -= ((atyp)_0 * *w); \ - res1 -= ((atyp)_1 * *w); \ - res2 -= ((atyp)_2 * *w); \ - res3 -= ((atyp)_3 * *w++); \ - } \ - else if constexpr (op == eWindowEvaluation_Max) { \ - res0 = maximum(res0, -(atyp)_0 * *w); \ - res1 = maximum(res1, -(atyp)_1 * *w); \ - res2 = maximum(res2, -(atyp)_2 * *w); \ - res3 = maximum(res3, -(atyp)_3 * *w++); \ - } \ - else if constexpr (op == eWindowEvaluation_Min) { \ - res0 = (atyp)32768.0 - maximum((atyp)32768.0 - res0, -(atyp)(1.0f - _0) * *w); \ - res1 = (atyp)32768.0 - maximum((atyp)32768.0 - res1, -(atyp)(1.0f - _1) * *w); \ - res2 = (atyp)32768.0 - maximum((atyp)32768.0 - res2, -(atyp)(1.0f - _2) * *w); \ - res3 = (atyp)32768.0 - maximum((atyp)32768.0 - res3, -(atyp)(1.0f - _3) * *w++); \ - } \ - } while (++srcPos < fw.last); \ - \ - /* dtyp _0 = ldexp((dtyp)res0, -15); */ \ - /* dtyp _1 = ldexp((dtyp)res1, -15); */ \ - /* dtyp _2 = ldexp((dtyp)res2, -15); */ \ - /* dtyp _3 = ldexp((dtyp)res3, -15); */ \ - \ - dtyp _0 = (dtyp)res0 * (dtyp)(1.0 / 32768.0); \ - dtyp _1 = (dtyp)res1 * (dtyp)(1.0 / 32768.0); \ - dtyp _2 = (dtyp)res2 * (dtyp)(1.0 / 32768.0); \ - dtyp _3 = (dtyp)res3 * (dtyp)(1.0 / 32768.0); \ - \ - /* put value */ \ - store(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); \ - } while (++dstPos < (signed)dstSize); \ - \ - exit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip); - - #define filterF4xNHor(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, pm) \ - filter4xNf(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, 0, fwh, float, float /*double*/) - - #define filterF4xNVer(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, pm) \ - filter4xNf(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip, init, next, fetch, store, exit, op, 0, fwv, float, float /*double*/) - - /* #################################################################################################################### \ - */ - #define resampleF4xNFromPlane(stride) \ - float _0, _1, _2, _3; \ - \ - _0 = (*i0)[ix], i0 += (stride) * dy; \ - _1 = (*i1)[ix], i1 += (stride) * dy; \ - _2 = (*i2)[ix], i2 += (stride) * dy; \ - _3 = (*i3)[ix], i3 += (stride) * dy; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNFromStream(stride, instream) \ - float _0, _1, _2, _3; \ - \ - _0 = instream[0]; \ - _1 = instream[1]; \ - _2 = instream[2]; \ - _3 = instream[3], instream += (stride) * 4; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNFromStreamSwapped(stride, instream) \ - float _0, _1, _2, _3; \ - \ - _3 = instream[0]; \ - _2 = instream[1]; \ - _1 = instream[2]; \ - _0 = instream[3], instream += (stride) * 4; - - /* #################################################################################################################### \ - */ - #define resampleF4xNToPlane(stride) \ - (*o0)[ox] = _0; \ - (*o1)[ox] = _1; \ - (*o2)[ox] = _2; \ - (*o3)[ox] = _3, ox += (1) * 1; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNToStream(stride, outstream) \ - outstream[0] = _0; \ - outstream[1] = _1; \ - outstream[2] = _2; \ - outstream[3] = _3, outstream += (1) * 4; - - /* ******************************************************************************************************************** \ - */ - #define resampleF4xNToStreamSwapped(stride, outstream) \ - outstream[0] = _3; \ - outstream[1] = _2; \ - outstream[2] = _1; \ - outstream[3] = _0, outstream += (1) * 4; - - /* #################################################################################################################### \ - */ - #undef filterF4xNFromPlane - #define filterF4xNFromPlane(stride) \ - resampleF4xNFromPlane(stride) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNFromStream - #define filterF4xNFromStream(stride, instream) \ - resampleF4xNFromStream(stride, instream) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNFromStreamSwapped - #define filterF4xNFromStreamSwapped(stride, instream) \ - resampleF4xNFromStreamSwapped(stride, instream) - - /* #################################################################################################################### \ - */ - #undef filterF4xNToPlane - #define filterF4xNToPlane(stride) \ - resampleF4xNToPlane(stride) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNToStream - #define filterF4xNToStream(stride, outstream) \ - resampleF4xNToStream(stride, outstream) - - /* ******************************************************************************************************************** \ - */ - #undef filterF4xNToStreamSwapped - #define filterF4xNToStreamSwapped(stride, outstream) \ - resampleF4xNToStreamSwapped(stride, outstream) - - /* #################################################################################################################### \ - */ - #define loopEnter(id, untill, advance) \ - unsigned int id; for (id = 0; id < untill; id += advance) { - #define loopLeave(id, untill, advance) \ - } - - /* #################################################################################################################### \ - */ - #define all4InitSwappablePlanePointers(left, top, row, rows, pp, swap, dtyp) \ - dtyp * pp##0, *pp##1, *pp##2, *pp##3; \ - \ - pp##0 = pp[0][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* r */ \ - pp##1 = pp[1][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* g */ \ - pp##2 = pp[2][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* b */ \ - pp##3 = pp[3][/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)] + left; /* a */ - - #define allF4InitSwappablePlanePointers(left, top, row, rows, pp, swap) \ - all4InitSwappablePlanePointers(left, top, row, rows, pp, swap, float) - - /* #################################################################################################################### \ - */ - #define all4InitFixedPlanePointers(left, top, row, rows, pp, swap, dtyp) \ - dtyp * pp##0, *pp##1, *pp##2, *pp##3; \ - \ - pp##0 = pp[0][(row + top)] + left; /* r */ \ - pp##1 = pp[1][(row + top)] + left; /* g */ \ - pp##2 = pp[2][(row + top)] + left; /* b */ \ - pp##3 = pp[3][(row + top)] + left; /* a */ - - #define allF4InitFixedPlanePointers(left, top, row, rows, pp, swap) \ - all4InitFixedPlanePointers(left, top, row, rows, pp, swap, float) - - /* #################################################################################################################### \ - */ - #define all4InitSwappablePlaneReferences(left, offs, top, row, rows, pp, swap, dtyp) \ - unsigned long int pp##x = left + offs; \ - dtyp** pp##0; \ - dtyp** pp##1; \ - dtyp** pp##2; \ - dtyp** pp##3; \ - \ - pp##0 = pp[0] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* r */ \ - pp##1 = pp[1] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* g */ \ - pp##2 = pp[2] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* b */ \ - pp##3 = pp[3] + (/*parm->mirror ? (rows - 1) - (row + top) :*/ (row + top)); /* a */ - - #define allF4InitSwappablePlaneReferences(left, offs, top, row, rows, pp, swap) \ - all4InitSwappablePlaneReferences(left, offs, top, row, rows, pp, swap, float) - - /* #################################################################################################################### \ - */ - #define all4InitFixedPlaneReferences(left, row, rows, pp, ps, dtyp) \ - unsigned long int pp##x = left; \ - dtyp** pp##0; \ - dtyp** pp##1; \ - dtyp** pp##2; \ - dtyp** pp##3; \ - \ - pp##0 = ps[0] + (row); /* r */ \ - pp##1 = ps[1] + (row); /* g */ \ - pp##2 = ps[2] + (row); /* b */ \ - pp##3 = ps[3] + (row); /* a */ - - #define allF4InitFixedPlaneReferences(left, row, rows, pp, ps) \ - all4InitFixedPlaneReferences(left, row, rows, pp, ps, float) - - /* #################################################################################################################### \ - */ - #define allF4AdvanceSwappablePlaneReferences(row, rows, pp) \ - pp##0 += (rows - row) * dy; /* r */ \ - pp##1 += (rows - row) * dy; /* g */ \ - pp##2 += (rows - row) * dy; /* b */ \ - pp##3 += (rows - row) * dy; /* a */ - - /* #################################################################################################################### \ - */ - #define allF4AdvanceFixedPlaneReferences(row, rows, pp) \ - allF4AdvanceSwappablePlaneReferences(row, rows, pp) - - /* #################################################################################################################### \ - */ - #define allF4AdvanceStreamPointer(left, col, cols, sp) \ - sp += ((cols) - (left + col)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvNMULStreamPointer(top, stride, sp) \ - sp -= ((stride) * (top)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvPMULStreamPointer(top, stride, sp) \ - sp += ((stride) * (top)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvSUBMStreamPointer(left, top, stride, sp) \ - sp -= (((stride) * (top)) - (left)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvADDMStreamPointer(left, top, stride, sp) \ - sp += ((left) + ((stride) * (top))) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvPADDStreamPointer(offs, sp) \ - sp += (offs) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvSSUBStreamPointer(top, shift, offs, sp) \ - sp += (((top) << (shift)) - (offs)) * 4; - - /* ******************************************************************************************************************** \ - */ - #define allF4AdvNAMAStreamPointer(left, top, offs, stride, sp) \ - sp -= ((left) + (((top) + (offs)) * (stride))) * 4; - - /* ################################################################################################################### \ - */ - #undef comcpyFNum - #define comcpyFNum 1 - #undef orderedFNum - #define orderedFNum 1 - #undef orderedFShift - #define orderedFShift 0 - #undef interleavedFNum - #define interleavedFNum 1 - - /* #################################################################################################################### \ - */ - # define allTInitFixedOutPlaneReferences allF4InitFixedPlaneReferences - # define allTInitFixedInPlaneReferences allF4InitFixedPlaneReferences - # define allCInitSwappableInPlaneReferences /*allF4InitSwappablePlaneReferences*/ - # define allCInitSwappableOutPlaneReferences /*allF4InitSwappablePlaneReferences*/ - - # define allCAdvADDMInStreamPointer allF4AdvADDMStreamPointer - # define allCAdvPADDInStreamPointer allF4AdvPADDStreamPointer - # define allCAdvPMULInStreamPointer allF4AdvPMULStreamPointer - # define allCAdvNMULInStreamPointer allF4AdvNMULStreamPointer - # define allCAdvADDMOutStreamPointer allF4AdvADDMStreamPointer - # define allCAdvSSUBOutStreamPointer allF4AdvSSUBStreamPointer - - # define getCxNFromStreamSwapped /*filterF4xNFromStreamSwapped*/ - # define getCxNFromStream filterF4xNFromStream - # define getCxNFromPlane /*filterF4xNFromPlane*/ - # define getTxNFromPlane filterF4xNFromPlane - - # define filterHor filterF4xNHor - # define filterVer filterF4xNVer - - # define comcpyCCheckHiLo() /*orderedF4CheckHiLo*/ - # define comcpyCCoVar() /*orderedF4CoVar*/ - # define comcpyCHistogram() /*orderedF4Histogram*/ - - # define putCxNToStreamSwapped /*filterF4xNToStreamSwapped*/ - # define putCxNToStream filterF4xNToStream - # define putCxNToPlane /*filterF4xNToPlane*/ - # define putTxNToPlane filterF4xNToPlane - - # define orderedNum orderedFNum - # define orderedShift orderedFShift - - # define comcpyCMergeHiLo(orderedNum) /*comcpyFTMergeHiLo*/ - # define comcpyCCompleteCoVar(orderedNum) /*comcpyFTCompleteCoVar*/ - # define comcpyCCompleteHistogram(orderedNum) /*comcpyFTCompleteHistogram*/ - - # define hiloCVariables /*hiloFTVariables*/ - # define covarCVariables /*covarFTVariables*/ - # define histoCVariables /*histoFTVariables*/ - - # define filterCVariables filterFTVariables - - # define orderedTInitLoop() /*orderedTInitLoop*/ - # define hiloTInitLoop() /*hiloTInitLoop*/ - # define covarTInitLoop() /*covarTInitLoop*/ - # define histoTInitLoop() /*histoTInitLoop*/ - - # define orderedTExitLoop() /*orderedTExitLoop*/ - # define hiloTExitLoop() /*hiloTExitLoop*/ - # define covarTExitLoop() /*covarTExitLoop*/ - # define histoTExitLoop() /*histoTExitLoop*/ - - # define filterCCleanUp filterTCleanUp - - /* #################################################################################################################### \ - */ - - struct prcparm - { - /* configuration -------------------------------------------------------------------------------- */ - - /* dimensions of the source/destination image */ - int inrows, outrows, subrows; - int incols, outcols, subcols; - - /* region to process the stuff in */ - bool regional; - /* don't fetch data from outside the region */ - bool caged; - struct - { - /* offsets to the source/destination image-region */ - int intop, outtop, subtop; - int inleft, outleft, subleft; - - /* dimensions of the source/destination image-region */ - int inrows, outrows, subrows; - int incols, outcols, subcols; - } region; - - /* parameters ----------------------------------------------------------------------------------- */ - - /* parameters for resampling */ - struct - { - /* we don't give floating-point x/y-factor, it's not exact enough */ - unsigned int rowquo, rowrem; - unsigned int colquo, colrem; - - /* over/under-blurring (window minification/magnification) */ - float rowblur, colblur; - - /* the windowing-function for the filtering */ - IWindowFunction* wf; - - /* operation to perform the filter with */ - int operation; - } resample; - - /* private stuff -------------------------------------------------------------------------------- */ - - /* what really has do be done after choosing/recalculation */ - int dorows, docols; - }; - - static void CheckBoundaries(const void* i, void* o, struct prcparm* parm) - { - /* the parameter evaluation ----------------------------------------------- */ - const bool scaler = true; - - /* this is fairly straightforward */ - if (!parm->regional) - { - int rgrows = parm->inrows; - int rgcols = parm->incols; - - /* compare out-region against available out-size */ - if (o) - { - int dorows = parm->outrows; - int docols = parm->outcols; - - /* scale up */ - if (scaler) - { - dorows = dorows * parm->resample.rowrem / parm->resample.rowquo; - docols = docols * parm->resample.colrem / parm->resample.colquo; - } - - /* compare in scaled space */ - rgrows = maximum(rgrows, dorows); - rgcols = maximum(rgcols, docols); - - /* scale down */ - if (scaler) - { - rgrows = rgrows * parm->resample.rowquo / parm->resample.rowrem; - rgcols = rgcols * parm->resample.colquo / parm->resample.colrem; - } - } - - parm->dorows = rgrows; - parm->docols = rgcols; - } - /* this may need some adjustment */ - else - { - int rgrows = parm->region.inrows; - int rgcols = parm->region.incols; - - /* compare in/out-region against available out-size */ - if (o) - { - int dorows = parm->region.outrows; - int docols = parm->region.outcols; - - /* compare out-region against available in-size */ - if (dorows > parm->outrows - parm->region.outtop) - { - dorows = parm->outrows - parm->region.outtop; - } - if (docols > parm->outcols - parm->region.outleft) - { - docols = parm->outcols - parm->region.outleft; - } - - /* scale to in */ - if (scaler) - { - dorows = dorows * parm->resample.rowrem / parm->resample.rowquo; - docols = docols * parm->resample.colrem / parm->resample.colquo; - } - - /* compare in scaled space */ - rgrows = maximum(rgrows, dorows); - rgcols = maximum(rgcols, docols); - - /* compare in-region against available in-size */ - if (i) - { - if (rgrows > parm->inrows - parm->region.intop) - { - rgrows = parm->inrows - parm->region.intop; - } - if (rgcols > parm->incols - parm->region.inleft) - { - rgcols = parm->incols - parm->region.inleft; - } - } - - /* scale to out */ - if (scaler) - { - rgrows = rgrows * parm->resample.rowquo / parm->resample.rowrem; - rgcols = rgcols * parm->resample.colquo / parm->resample.colrem; - } - } - else - { - /* compare in-region against available in-size */ - if (i) - { - if (rgrows > parm->inrows - parm->region.intop) - { - rgrows = parm->inrows - parm->region.intop; - } - if (rgcols > parm->incols - parm->region.inleft) - { - rgcols = parm->incols - parm->region.inleft; - } - } - } - - parm->dorows = rgrows; - parm->docols = rgcols; - } - - AZ_Assert(parm->dorows > 0, "%s: Expect row count to be above zero!", __FUNCTION__); - AZ_Assert(parm->docols > 0, "%s: Expect column count to be above zero!", __FUNCTION__); - } - - /* #################################################################################################################### \ - * multi-threadable if needed - */ - static void RunAlgorithm(const float* i, float* o, struct prcparm* parm) - { - /* make these local, so no indirect access is needed */ - const unsigned int srcrows = parm->dorows * parm->resample.rowrem / parm->resample.rowquo; - const unsigned int srccols = parm->docols * parm->resample.colrem / parm->resample.colquo; - const unsigned int dstrows = parm->dorows; - const unsigned int dstcols = parm->docols; - const unsigned int cstZero = 0; - - /* temporary buffer region */ - parm->subrows = srccols; - parm->subcols = dstrows; - parm->region.subleft = 0; - parm->region.subtop = 0; - parm->region.subcols = parm->subcols; - parm->region.subrows = parm->subrows; - - if (!parm->caged) - { - int oleft; - int oright; - - /* check for out-of-region access rectangle */ - calculateFilterRange(srccols, oleft, oright, dstcols, 0, dstcols, parm->resample.colblur, parm->resample.wf); - - /* round down left, round up right */ - oleft = oleft & (~(orderedNum - 1)); - oright = (oright + (orderedNum - 1)) & (~(orderedNum - 1)); - - /* clamp to available image-rectangle */ - if ((oleft < (signed)parm->region.subtop) || - (oright > (signed)parm->subrows)) - { - oleft = maximum(oleft, -(signed)parm->region.inleft); - oright = minimum(oright, (signed)parm->incols); - } - - /* readjust temporary buffer region to include out-of-region accesses */ - parm->region.inleft += oleft; //rm->docols -= oleft; //rm->docols += (oright - srccols); - parm->region.subtop -= oleft; - parm->subrows -= oleft; - parm->subrows += (oright - srccols); - } - - const unsigned int tmprows = parm->subrows; - const unsigned int tmpcols = parm->subcols; - - /* -------------------------------------------------------------------------------------------- - * common resampling - */ - - /* init t */ - filterCVariables(orderedNum); - - filterTInitLoop(); - - /* -------------------------------------------------------------------------------------------- - * reading rows, writing cols (xy-flip) - * - * make srccol x inrow -> dstrow x srccol - * - * we are reading vertical, and writing horizontal - * in effect we can use fast parallel-reads, but need - * slow interleaved-writes - * as reads are slower (ask+receive) than writes (send) - * this should even be gracefully fast - */ - allCAdvADDMInStreamPointer(parm->region.inleft, parm->region.intop, parm->incols, i); - - #define filterRowInit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allTInitFixedOutPlaneReferences(cstZero, srcOffs, -, o, t); - - #define filterRowNext(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* every in/out-put may swap */ \ - allCInitSwappableInPlaneReferences(parm->region.inleft, srcOffs, parm->region.intop, fw.first, parm->inrows, i, false); \ - /* because the filter moves back and forth, we always have to reposition from 0 */ \ - allCAdvPMULInStreamPointer(srcSkip##raw, fw.first, i); - - #define filterRowFetch(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* vertical stride, horizontal fetch */ \ - getCxNFromStreamSwapped(srcSkip, i); \ - getCxNFromStream(srcSkip, i); \ - getCxNFromPlane(1); \ - \ - /*srcPos++;*/ - - #define filterRowStore(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* because the filter moves back and forth, we always have to reposition to 0 */ \ - allCAdvNMULInStreamPointer(srcSkip##raw, fw.last, i); \ - \ - /* horizontal stride, vertical store */ \ - putTxNToPlane(1); \ - \ - /*dstPos++;*/ - - #define filterRowExit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allCAdvPADDInStreamPointer(orderedNum, i); - - if (parm->resample.operation == eWindowEvaluation_Sum) - { - loopEnter(tmprow, tmprows, orderedNum); - - { - filterVer(tmprow, srcrows, stridei, - tmprow, dstrows, stridet, filterRowInit, filterRowNext, filterRowFetch, filterRowStore, filterRowExit, eWindowEvaluation_Sum, of); - } - - loopLeave(tmprow, tmprows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Max) - { - loopEnter(tmprow, tmprows, orderedNum); - - { - filterVer(tmprow, srcrows, stridei, - tmprow, dstrows, stridet, filterRowInit, filterRowNext, filterRowFetch, filterRowStore, filterRowExit, eWindowEvaluation_Max, of); - } - - loopLeave(tmprow, tmprows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Min) - { - loopEnter(tmprow, tmprows, orderedNum); - - { - filterVer(tmprow, srcrows, stridei, - tmprow, dstrows, stridet, filterRowInit, filterRowNext, filterRowFetch, filterRowStore, filterRowExit, eWindowEvaluation_Min, of); - } - - loopLeave(tmprow, tmprows, orderedNum); - } - - /* 1st resampling end - * -------------------------------------------------------------------------------------------- - */ - filterTExitLoop(); - - /* return collected min/max */ - hiloCVariables(orderedNum); - covarCVariables(orderedNum); - histoCVariables(orderedNum); - - /* --------------------------------------------------------------- */ - orderedTInitLoop(); - filterTInitLoop(); - - hiloTInitLoop(); - covarTInitLoop(); - histoTInitLoop(); - - /* -------------------------------------------------------------------------------------------- - * reading rows, writing cols (xy-flip) - * - * make dstrow x srccol -> outcol x dstrow - * - * we are reading vertical, and writing horizontal - * in effect we can use fast parallel-reads, but need - * slow interleaved-writes - * as reads are slower (ask+receive) than writes (send) - * this should even be gracefully fast - */ - allCAdvADDMOutStreamPointer(parm->region.outleft, parm->region.outtop, parm->outcols, o); - - #define filterColInit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allCInitSwappableOutPlaneReferences(parm->region.outleft, cstZero, parm->region.outtop, srcOffs, parm->outrows, o, false); - - #define filterColNext(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* every in/out-put may swap */ \ - allTInitFixedInPlaneReferences(srcOffs, parm->region.subtop + fw.first, -, i, t); - - #define filterColFetch(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - /* vertical stride, horizontal fetch */ \ - getTxNFromPlane(1); \ - \ - /*srcPos++;*/ - - #define filterColStore(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - comcpyCCheckHiLo(); \ - comcpyCCoVar(); \ - comcpyCHistogram(); \ - \ - /* horizontal stride, vertical store */ \ - putCxNToStreamSwapped(dstSkip, o); \ - putCxNToStream(dstSkip, o); \ - putCxNToPlane(1); \ - \ - /*dstPos++;*/ - - #define filterColExit(srcOffs, srcSize, srcSkip, dstOffs, dstSize, dstSkip) \ - allCAdvSSUBOutStreamPointer(dstSkip##raw, orderedShift, dstPos, o); - - if (parm->resample.operation == eWindowEvaluation_Sum) - { - loopEnter(dstrow, dstrows, orderedNum); - - { - filterHor(dstrow, srccols, stridet, - dstrow, dstcols, strideo, filterColInit, filterColNext, filterColFetch, filterColStore, filterColExit, eWindowEvaluation_Sum, of); - } - - loopLeave(dstrow, dstrows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Max) - { - loopEnter(dstrow, dstrows, orderedNum); - - { - filterHor(dstrow, srccols, stridet, - dstrow, dstcols, strideo, filterColInit, filterColNext, filterColFetch, filterColStore, filterColExit, eWindowEvaluation_Max, of); - } - - loopLeave(dstrow, dstrows, orderedNum); - } - else if (parm->resample.operation == eWindowEvaluation_Min) - { - loopEnter(dstrow, dstrows, orderedNum); - - { - filterHor(dstrow, srccols, stridet, - dstrow, dstcols, strideo, filterColInit, filterColNext, filterColFetch, filterColStore, filterColExit, eWindowEvaluation_Min, of); - } - - loopLeave(dstrow, dstrows, orderedNum); - } - - /* 2nd resampling end - * -------------------------------------------------------------------------------------------- - */ - histoTExitLoop(); - covarTExitLoop(); - hiloTExitLoop(); - - filterTExitLoop(); - orderedTExitLoop(); - /* --------------------------------------------------------------- */ - - /* return collected min/max */ - comcpyCMergeHiLo(orderedNum); - comcpyCCompleteCoVar(orderedNum); - comcpyCCompleteHistogram(orderedNum); - - /* exit t */ - filterCCleanUp(orderedNum); - } - - // TODO: not working yet, debug and enable - //static void SplitAlgorithm(const void* i, void* o, struct prcparm* templ, int threads = 8) - //{ - // struct prcparm fraction[32]; - // int t, istart = 0, sstart = 0, ostart = 0; - // const bool scaler = true; - - // int theight = 0; - - // /* prepare data to be emitted to the threads */ - // for (t = 0; t < threads; t++) - // { - // fraction[t] = *templ; - - // /* adjust the processing-region according to the available threads */ - // { - //#undef split /* only prefix-threads need aligned transpose (for not trashing suffix-thread data) */ - //#define split(rows) !scaler \ - // ? ((rows * (t + 1)) / threads) & (~(t != threads - 1 ? 15 : 0)) \ - // : ((rows * (t + 1)) / threads) & (~0) - - // /* area covered */ - // const int inrows = (fraction[t].regional ? fraction[t].region.inrows : fraction[t].inrows); - // const int incols = (fraction[t].regional ? fraction[t].region.incols : fraction[t].incols); - // const int subrows = (fraction[t].regional ? fraction[t].region.subrows : fraction[t].subrows); - // const int subcols = (fraction[t].regional ? fraction[t].region.subcols : fraction[t].subcols); - // const int outrows = (fraction[t].regional ? fraction[t].region.outrows : fraction[t].outrows); - // const int outcols = (fraction[t].regional ? fraction[t].region.outcols : fraction[t].outcols); - - // /* splitting blocks */ - // const int istop = split(inrows), sstop = split(subrows), ostop = split(outrows); - // const int irows = istop - istart, srows = sstop - sstart, orows = ostop - ostart; - // const int icols = incols, scols = subcols, ocols = outcols; - - // AZ_Assert(irows > 0, "%s: Expect row count to be above zero!", __FUNCTION__); - // AZ_Assert(orows > 0, "%s: Expect row count to be above zero!", __FUNCTION__); - // AZ_Assert(icols > 0, "%s: Expect column count to be above zero!", __FUNCTION__); - // AZ_Assert(ocols > 0, "%s: Expect column count to be above zero!", __FUNCTION__); - - // /* now we are regional */ - // fraction[t].regional = true; - - // /* take previous regionality into account */ - // fraction[t].region.intop += istart; - // fraction[t].region.subtop += sstart; - // fraction[t].region.outtop += ostart; - // fraction[t].region.inrows = irows; - // fraction[t].region.subrows = srows; - // fraction[t].region.outrows = orows; - - // /* take previous regionality into account */ - // fraction[t].region.inleft += 0; - // fraction[t].region.subleft += 0; - // fraction[t].region.outleft += 0; - // fraction[t].region.incols = icols; - // fraction[t].region.subcols = scols; - // fraction[t].region.outcols = ocols; - - // /* advance block */ - // istart = istop; - // sstart = sstop; - // ostart = ostop; - - // /* check */ - // theight += irows; - // } - - // // the algorithm supports "i" and "o" pointing to the same memory - // CheckBoundaries((float*)i, (float*)o, &fraction[t]); - // RunAlgorithm((float*)i, (float*)o, &fraction[t]); - // } - - // AZ_Assert(theight >= (templ->regional ? templ->region.inrows : templ->inrows), "%s: Invalid height!", __FUNCTION__); - //} - - /* #################################################################################################################### \ - */ - void FilterImage(int filterIndex, int filterOp, float blurH, float blurV, const IImageObjectPtr srcImg, int srcMip, - IImageObjectPtr dstImg, int dstMip, QRect* srcRect, QRect* dstRect) - { - //only support ePixelFormat_R32G32B32A32F - if (srcImg->GetPixelFormat() != ePixelFormat_R32G32B32A32F || dstImg->GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "FilterImage only support both source and dest image objects have pixel format R32G32B32A32F"); - return; - } - - uint32 srcWidth, srcHeight; - uint8* pSrcMem; - uint32 dwSrcPitch; - - srcImg->GetImagePointer(srcMip, pSrcMem, dwSrcPitch); - - srcWidth = srcImg->GetWidth(srcMip); - srcHeight = srcImg->GetHeight(srcMip); - - uint32 dstWidth, dstHeight; - uint8* pDestMem; - uint32 dwDestPitch; - - dstImg->GetImagePointer(dstMip, pDestMem, dwDestPitch); - - dstWidth = dstImg->GetWidth(dstMip); - dstHeight = dstImg->GetHeight(dstMip); - - { - struct prcparm parm; - memset(&parm, 0, sizeof(parm)); - - parm.incols = srcWidth; - parm.inrows = srcHeight; - parm.outcols = dstWidth; - parm.outrows = dstHeight; - parm.regional = false; - parm.caged = false; - - if (srcRect || dstRect) - { - parm.regional = true; - parm.caged = true; - - parm.region.inleft = (!srcRect ? 0 : srcRect->left()); - parm.region.intop = (!srcRect ? 0 : srcRect->top()); - parm.region.incols = (!srcRect ? parm.incols : srcRect->right() - srcRect->left()); - parm.region.inrows = (!srcRect ? parm.inrows : srcRect->bottom() - srcRect->top()); - - parm.region.outleft = (!dstRect ? 0 : dstRect->left()); - parm.region.outtop = (!dstRect ? 0 : dstRect->top()); - parm.region.outcols = (!dstRect ? parm.outcols : dstRect->right() - dstRect->left()); - parm.region.outrows = (!dstRect ? parm.outrows : dstRect->bottom() - dstRect->top()); - - if (!srcRect) - { - parm.region.inleft = parm.region.outleft * srcHeight / dstHeight; - parm.region.intop = parm.region.outtop * srcWidth / dstWidth; - } - - if (!dstRect) - { - parm.region.outleft = parm.region.inleft * dstHeight / srcHeight; - parm.region.outtop = parm.region.intop * dstWidth / srcWidth; - } - } - - parm.resample.colquo = dstWidth; - parm.resample.colrem = srcWidth; - parm.resample.rowquo = dstHeight; - parm.resample.rowrem = srcHeight; - parm.resample.rowblur = blurH; - parm.resample.colblur = blurV; - parm.resample.operation = filterOp; - - switch (filterIndex) - { - // case eWindowFunction_COMBINER : parm.resample.wf = new CombinerWindowFunction(..., ...); break; - case eWindowFunction_Point: - parm.resample.wf = new PointWindowFunction(); - break; - case eWindowFunction_Box: - parm.resample.wf = new BoxWindowFunction(); - break; - case eWindowFunction_Triangle: - parm.resample.wf = new TriangleWindowFunction(); - break; - case eWindowFunction_Quadric: - parm.resample.wf = new QuadricWindowFunction(); - break; - case eWindowFunction_Cubic: - parm.resample.wf = new CubicWindowFunction(); - break; - case eWindowFunction_Hermite: - parm.resample.wf = new HermiteWindowFunction(); - break; - case eWindowFunction_Catrom: - parm.resample.wf = new CatromWindowFunction(); - break; - case eWindowFunction_Sine: - parm.resample.wf = new SineWindowFunction(); - break; - case eWindowFunction_Sinc: - parm.resample.wf = new SincWindowFunction(); - break; - case eWindowFunction_Bessel: - parm.resample.wf = new BesselWindowFunction(); - break; - case eWindowFunction_Lanczos: - parm.resample.wf = new LanczosWindowFunction(); - break; - case eWindowFunction_Gaussian: - parm.resample.wf = new GaussianWindowFunction(); - break; - case eWindowFunction_Normal: - parm.resample.wf = new NormalWindowFunction(); - break; - case eWindowFunction_Mitchell: - parm.resample.wf = new MitchellWindowFunction(); - break; - case eWindowFunction_Hann: - parm.resample.wf = new HannWindowFunction(); - break; - case eWindowFunction_BartlettHann: - parm.resample.wf = new BartlettHannWindowFunction(); - break; - case eWindowFunction_Hamming: - parm.resample.wf = new HammingWindowFunction(); - break; - case eWindowFunction_Blackman: - parm.resample.wf = new BlackmanWindowFunction(); - break; - case eWindowFunction_BlackmanHarris: - parm.resample.wf = new BlackmanHarrisWindowFunction(); - break; - case eWindowFunction_BlackmanNuttall: - parm.resample.wf = new BlackmanNuttallWindowFunction(); - break; - case eWindowFunction_Flattop: - parm.resample.wf = new FlatTopWindowFunction(); - break; - case eWindowFunction_Kaiser: - parm.resample.wf = new KaiserWindowFunction(); - break; - - case eWindowFunction_SigmaSix: - parm.resample.wf = new SigmaSixWindowFunction(); - break; - case eWindowFunction_KaiserSinc: - parm.resample.wf = new CombinerWindowFunction(new SincWindowFunction(), new KaiserWindowFunction()); - break; - - default: - abort(); - break; - } - - // TODO: not working yet, debug and enable - // SplitAlgorithm(pSrcMem, pDestMem, &parm); - - // the algorithm supports "pSrcMem" and "pDestMem" pointing to the same memory - CheckBoundaries((float*)pSrcMem, (float*)pDestMem, &parm); - RunAlgorithm((float*)pSrcMem, (float*)pDestMem, &parm); - - delete parm.resample.wf; - } - } - - int MipGenTypeToFilterIndex(MipGenType filterType) - { - switch (filterType) - { - case MipGenType::point: - return eWindowFunction_Point; - case MipGenType::box: - return eWindowFunction_Box; - case MipGenType::triangle: - return eWindowFunction_Triangle; - case MipGenType::quadratic: - return eWindowFunction_Bilinear; - case MipGenType::gaussian: - return eWindowFunction_Gaussian; - case MipGenType::blackmanHarris: - return eWindowFunction_BlackmanHarris; - case MipGenType::kaiserSinc: - return eWindowFunction_KaiserSinc; - default: - AZ_Assert(false, "unable find filter type for mipmap gen type %d", filterType); - return eWindowFunction_BlackmanHarris; - } - } - - /* #################################################################################################################### \ - */ - void FilterImage(MipGenType filterType, MipGenEvalType evalType, float blurH, float blurV, const IImageObjectPtr srcImg, int srcMip, - IImageObjectPtr dstImg, int dstMip, QRect* srcRect, QRect* dstRect) - { - int filterIndex = MipGenTypeToFilterIndex(filterType); - int filterOp = static_cast(evalType); - FilterImage(filterIndex, filterOp, blurH, blurV, srcImg, srcMip, dstImg, dstMip, srcRect, dstRect); - } - -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.cpp b/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.cpp deleted file mode 100644 index d5d9d617c4..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.cpp +++ /dev/null @@ -1,329 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include -#include "FIR-Weights.h" - -/* #################################################################################################################### - */ - -namespace ImageProcessing -{ - void calculateFilterRange(unsigned int srcFactor, int& srcFirst, int& srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, - double blurFactor, class IWindowFunction* windowFunction) - { - double s, t, u, scaleFactor; /* scale factors */ - double srcRadius, srcCenter; /* window position and size */ - -#define s0 0 -#define s1 srcFactor -#define d0 0 -#define d1 dstFactor - - /* the mapping from discrete destination coordinates to continuous source coordinates: */ -#define MAP(b, scaleFactor, offset) ((b) + (offset)) / (scaleFactor) - - /* relation of dstFactor to srcFactor */ - s = (double)dstFactor / srcFactor; - t = d0 - s * (s0 - 0.5) - 0.5; - - /* compute offsets for MAP */ - u = d0 - s * (s0 - 0.5) - t; - - /* find scale of filter - * when minifying, scaleFactor = 1/s, but when magnifying, scaleFactor = 1 - */ - scaleFactor = (blurFactor == 0.0 ? 1.0 : (blurFactor > 0.0 ? (1.0 + blurFactor) : 1.0 / (1.0 - blurFactor))) * maximum(1., 1. / s); - - /* find support radius of scaled filter - * if the window's length is <= 0.5 then we've got point sampling. - */ - srcRadius = maximum(0.5, scaleFactor * windowFunction->getLength()); - - /* sample the continuous filter, scaled by scaleFactor and - * positioned at continuous source coordinate srcCenter - */ - { - srcCenter = MAP(dstFirst + 0, s, u); - - /* find the source coordinate range of this positioned filter window */ - srcFirst = int(floor(srcCenter - srcRadius + 0.5)); - } - - { - srcCenter = MAP(dstLast - 1, s, u); - - /* find the source coordinate range of this positioned filter window */ - srcLast = int(floor(srcCenter + srcRadius + 0.5)); - } - } - - template<> - FilterWeights* calculateFilterWeights(unsigned int srcFactor, int srcFirst, int srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, signed short int numRepetitions, - double blurFactor, class IWindowFunction* windowFunction, - bool peaknorm, bool& plusminus) - - { -#define WEIGHTBITS 15 -#define WEIGHTONE (1 << WEIGHTBITS) /* filter weight of one */ - - double s, t, u, scaleFactor; /* scale factors */ - double srcRadius, srcCenter; /* window position and size */ - double sumfWeights, neg, pos, nrmWeights, fWeight; /* window position and size */ - int i, i0, i1; /* window position and size */ - int dstPosition; - signed short int n; - bool trimZeros = true, stillzero; - int lastnonzero, hWeight, highest; - signed int sumiWeights, iWeight; - signed short int* weightsPtr, *weightsMem; - FilterWeights* weightsObjs; - bool pm, pma = false; - - /* pre-calculate filter window solutions for all rows - */ - weightsObjs = new FilterWeights[dstLast - dstFirst]; - -#define s0 0 -#define s1 srcFactor -#define d0 0 -#define d1 dstFactor - - /* relation of dstFactor to srcFactor */ - s = (double)dstFactor / srcFactor; - t = d0 - s * (s0 - 0.5) - 0.5; - - /* compute offsets for MAP */ - u = d0 - s * (s0 - 0.5) - t; - - /* find scale of filter - * when minifying, scaleFactor = 1/s, but when magnifying, scaleFactor = 1 - */ - scaleFactor = (blurFactor == 0.0 ? 1.0 : (blurFactor > 0.0 ? (1.0 + blurFactor) : 1.0 / (1.0 - blurFactor))) * maximum(1., 1. / s); - - /* find support radius of scaled filter - * if the window's length is <= 0.5 then we've got point sampling. - */ - srcRadius = maximum(0.5, scaleFactor * windowFunction->getLength()); - - /* sample the continuous filter, scaled by ap->scaleFactor and - * positioned at continuous source coordinate srcCenter, for source coordinates in - * the range [0..len-1], writing the weights into wtab. - * Scale the weights so they sum up to WEIGHTONE, and trim leading and trailing - * zeros if trimZeros is true. - */ -#undef NORMALIZE_SUMMED_PEAK -#define NORMALIZE_MAXXED_PEAK - for (dstPosition = dstFirst, pm = false; dstPosition < dstLast; dstPosition++) - { - srcCenter = MAP(dstPosition, s, u); - - /* find the source coordinate range of this positioned filter window */ - i0 = int(floor(srcCenter - srcRadius + 0.5)); - i1 = int(floor(srcCenter + srcRadius + 0.5)); - - /* clip against the source-range */ - if (i0 < srcFirst) - { - i0 = srcFirst; - } - if (i1 > srcLast) - { - i1 = srcLast; - } - - /* this is possible if we hit the final line */ - if (i1 <= i0) - { - if (i1 >= srcLast) - { - i0 = i1 - 1; - } - else - { - i1 = i0 + 1; - } - } - - AZ_Assert(i0 >= srcFirst, "%s: Invalid source coordinate range!", __FUNCTION__); - AZ_Assert(i1 <= srcLast, "%s: Invalid source coordinate range!", __FUNCTION__); - AZ_Assert(i0 < i1, "%s: Invalid source coordinate range!", __FUNCTION__); - - /* find maximum peak to normalize the filter */ - for (sumfWeights = 0, pos = 0, neg = 0, i = i0; i < i1; i++) - { - /* evaluate the filter function: */ - fWeight = (*windowFunction)((i + 0.5 - srcCenter) / scaleFactor); - -#if defined(NORMALIZE_SUMMED_PEAK) - /* get positive and negative summed peaks */ - if (fWeight >= 0) - { - pos += fWeight; - } - else - { - neg += fWeight; - } -#elif defined(NORMALIZE_MAXXED_PEAK) - /* get positive and negative maximum peaks */ - minmax(fWeight, neg, pos); -#endif - - sumfWeights += fWeight; - } - - /* the range of source samples to buffer: */ - weightsMem = new signed short int[(i1 - i0) * abs(numRepetitions)]; - - /* set nrmWeights so that sumWeights of windowFunction() is approximately WEIGHTONE - * this needs to be adjusted because the maximum weight-coefficient - * is NOT allowed to leave [-32768,32767] - * a case like {+1.25,-0.25} does produce a sumWeights of 1.0 BUT - * produced a weight much too high (-40000) - */ -#if defined(NORMALIZE_SUMMED_PEAK) - sumfWeights = maximum(-neg, pos); -#elif defined(NORMALIZE_MAXXED_PEAK) - sumfWeights = maximum(sumfWeights, maximum(-neg, pos)); -#endif - - if (!peaknorm) - { - nrmWeights = (sumfWeights == 0. ? WEIGHTONE : (-neg > pos ? WEIGHTONE - 1 : WEIGHTONE) / sumfWeights); - } - else - { - nrmWeights = (sumfWeights == 0. ? WEIGHTONE : (-neg > pos ? WEIGHTONE - 1 : WEIGHTONE) / maximum(-neg, pos)); - } - - /* compute the discrete, sampled filter coefficients */ - stillzero = trimZeros; - for (sumiWeights = 0, hWeight = -WEIGHTONE, weightsPtr = weightsMem, i = i0; i < i1; i++) - { - /* evaluate the filter function: */ - fWeight = (*windowFunction)((i + 0.5 - srcCenter) / scaleFactor); - - /* normalize against the peak sumWeights, because the sums are not allowed to leave -32768/32767 */ - fWeight = fWeight * nrmWeights; - iWeight = int(round(fWeight)); - - /* find first nonzero */ - if (stillzero && (iWeight == 0)) - { - i0++; - } - else - { - AZ_Assert((-fWeight >= -32768.5) && (-fWeight <= 32767.5), "%s:The weight exceeded the maximum weight-coefficient.", __FUNCTION__); - - if (!peaknorm) - { - sumiWeights += iWeight; - } - else - { - sumiWeights = maximum(sumiWeights, iWeight); - } - -#define sgnextend(n, iWeight) (n & 1 ? (iWeight < 0 ? -1 : 0) : iWeight) - if (numRepetitions < 0) - { - /* add weight to table, interleaved sign */ - for (n = 0; n < -numRepetitions; n++) - { - *weightsPtr++ = sgnextend(n, -iWeight); - } - } - else - { - /* add weight to table */ - for (n = 0; n < numRepetitions; n++) - { - *weightsPtr++ = -iWeight; - } - } - - stillzero = false; - - /* find last nonzero */ - if (iWeight != 0) - { - lastnonzero = i; - } - - /* check for negative values */ - if (iWeight < 0) - { - pm = pma = true; - } - - /* find most influential value */ - if (iWeight >= hWeight) - { - highest = i; - hWeight = iWeight; - } - } - } - - if (sumiWeights == 0) - { - i0 = (i0 + i1) >> 1; - i1 = (i0 + 1); - - for (n = 0, weightsPtr = weightsMem; n < numRepetitions; n++) - { - *weightsPtr++ = -WEIGHTONE; - } - } - else - { - /* skip leading and trailing zeros */ - if (trimZeros) - { - /* set i0 and i1 to the nonzero support of the filter */ - i0 = i0; - i1 = i1 = lastnonzero + 1; - } - - if (sumiWeights != WEIGHTONE) - { - /* Fudge with the highest value */ - i = highest; - - /* fudge srcCenter sample */ - iWeight = WEIGHTONE - sumiWeights; - - for (n = 0, weightsPtr = weightsMem + (i - i0) * numRepetitions; n < numRepetitions; n++) - { - *weightsPtr++ -= iWeight; - } - } - } - - /* the new adjusted range of source samples to buffer: */ - weightsObjs[dstPosition].first = i0; - weightsObjs[dstPosition].last = i1; - weightsObjs[dstPosition].hasNegativeWeights = pm; - weightsObjs[dstPosition].weights = weightsMem; - } - - plusminus = pma; - return weightsObjs; - } -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.h b/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.h deleted file mode 100644 index 0dee77aa1a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Weights.h +++ /dev/null @@ -1,83 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -#include "FIR-Windows.h" - -namespace ImageProcessing -{ - /* #################################################################################################################### - */ - template - inline DataType abs (const DataType& ths) { return (ths < 0 ? -ths : ths); } - template - inline void minmax (const DataType& ths, DataType& mn, DataType& mx) { mn = (mn > ths ? ths : mn); mx = (mx < ths ? ths : mx); } - template - inline DataType minimum(const DataType& ths, const DataType& tht) { return (ths < tht ? ths : tht); } - template - inline DataType maximum(const DataType& ths, const DataType& tht) { return (ths > tht ? ths : tht); } - - /* #################################################################################################################### - */ - - template - class FilterWeights - { - public: - FilterWeights() - : weights(nullptr) - { - } - - ~FilterWeights() - { - delete[] weights; - } - - public: - // window-position - int first, last; - - // do we encounter positive as well as negative weights - bool hasNegativeWeights; - - /* weights, summing up to -(1 << 15), - * means weights are given negative - * that enables us to use signed short - * multiplication while occupying 0x8000 - */ - T* weights; - }; - - /* #################################################################################################################### - */ - - void calculateFilterRange (unsigned int srcFactor, int& srcFirst, int& srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, - double blurFactor, class IWindowFunction* windowFunction); - - template - FilterWeights* calculateFilterWeights(unsigned int srcFactor, int srcFirst, int srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, signed short int numRepetitions, - double blurFactor, class IWindowFunction* windowFunction, - bool peaknorm, bool& plusminus); - - template<> - FilterWeights* calculateFilterWeights(unsigned int srcFactor, int srcFirst, int srcLast, - unsigned int dstFactor, int dstFirst, int dstLast, signed short int numRepetitions, - double blurFactor, class IWindowFunction* windowFunction, - bool peaknorm, bool& plusminus); - - -} //end namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/FIR-Windows.h b/Gems/ImageProcessing/Code/Source/Converters/FIR-Windows.h deleted file mode 100644 index b814d911d0..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/FIR-Windows.h +++ /dev/null @@ -1,1283 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -// Description : A collection of window functions with Finite Impulse Response FIR -// and some helper window functions with Infinite Impulse Response IIR - -#pragma once -#include -#include - -/* #################################################################################################################### - */ -#ifndef M_PI -#define M_PI 3.14159265358979323846 /* pi */ -#endif - -//the original file was from cry's RC.exe with all the filters. We decided we would only use few of them for users -namespace ImageProcessing -{ - template - F cube(const F& op) { return op * op * op; } - - template - F square(F fOp) { return(fOp * fOp); } - - enum EWindowFunction - { - eWindowFunction_Combiner = 0, - - /*--------------- unit-area filters for unit-spaced samples ----------------*/ - eWindowFunction_Point = 1, - - eWindowFunction_Box = 2, // box, pulse, Fourier window, 1st order (constant) b-spline - eWindowFunction_Triangle = 3, // triangle, Bartlett window, 2nd order (linear) b-spline - eWindowFunction_Linear = eWindowFunction_Triangle, - eWindowFunction_Bartlett = eWindowFunction_Triangle, - - eWindowFunction_Quadric = 4, // 3rd order (quadratic) b-spline - eWindowFunction_Bilinear = eWindowFunction_Quadric, - eWindowFunction_Welch = eWindowFunction_Quadric, - eWindowFunction_Cubic = 5, // 4th order (cubic) b-spline - eWindowFunction_Hermite = 6, // 4th order (cubic hermite) b-spline - eWindowFunction_Catrom = 7, // Catmull-Rom spline, Overhauser spline - - eWindowFunction_Sine = 8, // IIR - eWindowFunction_Sinc = 9, // Sinc, perfect lowpass filter (infinite) - eWindowFunction_Bessel = 10, // Bessel (for circularly symm. 2-d filt, inf) - eWindowFunction_Lanczos = 11, // Lanczos filtering, windowed Sinc - - /*------------------ filters for non-unit spaced samples -------------------*/ - eWindowFunction_Gaussian = 12, // Gaussian (infinite) - eWindowFunction_Normal = 13, // Normal distribution (infinite) - - /*------------------------- parameterized filters --------------------------*/ - eWindowFunction_Mitchell = 14, // Mitchell & Netravali's two-param cubic - - /*--------------------------- window functions -----------------------------*/ - eWindowFunction_Hann = 15, // Hanning window - eWindowFunction_BartlettHann = 16, - eWindowFunction_Hamming = 17, // Hamming window - eWindowFunction_Blackman = 18, // Blackman window - eWindowFunction_BlackmanHarris = 19, - eWindowFunction_BlackmanNuttall = 20, - eWindowFunction_Flattop = 21, - - /*------------------------- parameterized windows --------------------------*/ - eWindowFunction_Kaiser = 22, // parameterized Kaiser window - - /*---------------------------- custom windows ------------------------------*/ - eWindowFunction_SigmaSix = 23, // two Normal distributions - eWindowFunction_KaiserSinc = 24, // Kaiser and Sinc - - eWindowFunction_Num = eWindowFunction_KaiserSinc + 1, - }; - - enum EWindowEvaluation - { - eWindowEvaluation_Sum, - eWindowEvaluation_Max, - eWindowEvaluation_Min, - }; - - /* #################################################################################################################### - */ - template - class IWindowFunction - { - public: - virtual ~IWindowFunction() {} - - virtual const char* getName() const = 0; - virtual T getLength() const = 0; - - virtual bool isCardinal() const = 0; - virtual bool isInfinite() const = 0; - virtual bool isUnitSpaced() const = 0; - virtual bool isCentered() const = 0; - - public: - virtual T operator () (T pos) const = 0; - }; - - /* #################################################################################################################### - * box, pulse, Fourier window, - * box function also know as rectangle function - * 1st order (constant) b-spline - */ - template - class BoxWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Box-window"; - } - virtual T getLength() const - { - return 0.5; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos <= 0.5) - { - return 1.0; - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * triangle, Bartlett window, - * triangle function also known as lambda function - * 2nd order (linear) b-spline - */ - template - class TriangleWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Triangle-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 1.0 - pos; - } - return 0.0; - } - }; - - /* #################################################################################################################### - * 3rd order (quadratic) b-spline - */ - template - class QuadricWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Quadric-window"; - } - virtual T getLength() const - { - return 1.5; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 0.5) - { - return 0.75 - square(pos); - } - if (pos < 1.5) - { - return 0.50 * square(pos - 1.5); - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * 4th order (cubic) b-spline - */ - template - class CubicWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Cubic-window"; - } - virtual T getLength() const - { - return 2.0; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 0.5 * cube(pos) - square(pos) + 2.0 / 3.0; - } - if (pos < 2.0) - { - return cube(2.0 - pos) / 6.0; - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Hermite filter - * f(x) = 2|x|^3 - 3|x|^2 + 1, -1 <= x <= 1 - */ - template - class HermiteWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Hermite-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 2.0 * cube(pos) - 3.0 * square(pos) + 1.0; - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Catmull-Rom spline, Overhauser spline - */ - template - class CatromWindowFunction - : public IWindowFunction - { - public: - CatromWindowFunction() { } - - public: - virtual const char* getName() const - { - return "Catrom-window"; - } - virtual T getLength() const - { - return 2.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return 1.5 * cube(pos) - 2.5 * square(pos) + 1.0; - } - if (pos < 2.0) - { - return -0.5 * cube(pos) + 2.5 * square(pos) - 4.0 * pos + 2.0; - } - return 0.0; - } - }; - - /* #################################################################################################################### - */ - template - class SineWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Sine-window"; - } - virtual T getLength() const - { - return 0.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return sin(pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * sinc, perfect lowpass filter (infinite) - * - * Note: Some people say sinc(x) is sin(x)/x. Others say it's - * sin(PI*x)/(PI*x), a horizontal compression of the former which is - * zero at integer values. We use the latter, whose Fourier transform - * is a canonical rectangle function (edges at -1/2, +1/2, height 1). - */ - template - class SincWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Sinc-window"; - } - virtual T getLength() const - { - return 4.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos == 0.0) - { - return 1.0; - } - - return sin(M_PI * pos) / (M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Bessel (for circularly symm. 2-d filt, infinite) - * See Pratt "Digital Image Processing" p. 97 for Bessel functions - */ - template - class BesselWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Bessel-window"; - } - virtual T getLength() const - { - return 3.2383; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos == 0.0) - { - return M_PI / 4.0; - } - return AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER(M_PI * pos) / (2.0 * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Lanczos filter - */ - template - class LanczosWindowFunction - : public SincWindowFunction - { - public: - LanczosWindowFunction(T tap = 3.0) - { - this->tap = AZ::GetMax(3.0, tap); - } - - protected: - T tap; - - public: - virtual const char* getName() const - { - return "Lanczos-window"; - } - virtual T getLength() const - { - return tap; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < tap) - { - return ((SincWindowFunction) * this)(pos) * ((SincWindowFunction) * this)(pos / tap); - } - return 0.0; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Gaussian filter (infinite) - */ - template - class GaussianWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Gaussian-window"; - } - virtual T getLength() const - { - return 1.25; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return exp(-2.0 * square(pos)) * sqrt(2.0 / M_PI); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * normal distribution (infinite) - * Normal(x) = Gaussian(x/2)/2 - */ - template - class NormalWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Normal-window"; - } - virtual T getLength() const - { - return 2.5; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return exp(-square(pos) / 2.0) / sqrt(2.0 * M_PI); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - */ - template - class SigmaSixWindowFunction - : public IWindowFunction - { - public: - SigmaSixWindowFunction(T diameter = 1.0, T negative = 0.0) - { - // we aim for 6 * sigma = 99,99996% of all values - const T sigma = 1.0 / 3.0; - - s2 = sigma * sigma * 2.0; - d2 = s2 / (diameter * diameter); - d = diameter; - n = negative; - } - - protected: - T s2, d2, d, n; - - public: - virtual const char* getName() const - { - return "SigmaSix-window"; - } - virtual T getLength() const - { - return 1.44; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - T o = exp(-square(pos) / s2) - (1.0 - 0.9999996); - T i = exp(-square(pos) / d2) - (1.0 - 0.9999996); - return (pos >= d ? 0.0 : i) - o * n; - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Mitchell & Netravali's two-param cubic - * see Mitchell & Netravali, - * "Reconstruction Filters in Computer Graphics", SIGGRAPH 88 - */ - template - class MitchellWindowFunction - : public IWindowFunction - { - public: - MitchellWindowFunction(T b = 1.0 / 3.0, T c = 1.0 / 3.0) - { - p0 = (6. - 2. * b) / 6.; - p2 = (-18. + 12. * b + 6. * c) / 6.; - p3 = (12. - 9. * b - 6. * c) / 6.; - q0 = (8. * b + 24. * c) / 6.; - q1 = (-12. * b - 48. * c) / 6.; - q2 = (6. * b + 30. * c) / 6.; - q3 = (-b - 6. * c) / 6.; - } - - protected: - T p0, p2, p3, q0, q1, q2, q3; - - public: - virtual const char* getName() const - { - return "Mitchell-window"; - } - virtual T getLength() const - { - return 2.0; - } - - virtual bool isCardinal() const - { - return false; - } - virtual bool isInfinite() const - { - return false; - } - virtual bool isUnitSpaced() const - { - return false; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - if (pos < 0.0) - { - pos = -pos; - } - if (pos < 1.0) - { - return p3 * cube(pos) + p2 * square(pos) + p0; - } - if (pos < 2.0) - { - return q3 * cube(pos) + q2 * square(pos) + q1 * pos + q0; - } - return 0.0; - } - }; - - /* #################################################################################################################### - * Hanning window (infinite) - */ - template - class HannWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Hann-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.5 + 0.5 * cos(M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * BartlettHanning window (infinite) - */ - template - class BartlettHannWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Bartlett-Hann-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.62 + 0.48 * (1.0 - pos) + 0.38 * cos(M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Hamming window (infinite) - */ - template - class HammingWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Hamming-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.53836 + 0.46164 * cos(M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * Blackman window (infinite) - */ - template - class BlackmanWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Blackman-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.42659 - + 0.49656 * cos(M_PI * pos) - + 0.07685 * cos(2.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * BlackmanHarris window (infinite) - */ - template - class BlackmanHarrisWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Blackman-Harris-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.35875 - + 0.48829 * cos(M_PI * pos) - + 0.14128 * cos(2.0 * M_PI * pos) - + 0.01168 * cos(3.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * BlackmanNuttall window (infinite) - */ - template - class BlackmanNuttallWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Blackman-Nuttall-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.3635819 - + 0.4891775 * cos(M_PI * pos) - + 0.1365995 * cos(2.0 * M_PI * pos) - + 0.0106411 * cos(3.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * FlatTop window (infinite) - */ - template - class FlatTopWindowFunction - : public IWindowFunction - { - public: - virtual const char* getName() const - { - return "Flat-Top-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return 0.215578948 - + 0.416631580 * cos(M_PI * pos) - + 0.277263158 * cos(2.0 * M_PI * pos) - + 0.083578947 * cos(3.0 * M_PI * pos) - + 0.006947368 * cos(4.0 * M_PI * pos); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - * parameterized Kaiser window (infinite) - * from Oppenheim & Schafer, Hamming - */ - template - class KaiserWindowFunction - : public IWindowFunction - { - public: - KaiserWindowFunction(T a = 6.5) - { - /* typically 4a = a; - this->i0a = 1. / bessel_i0(a); - } - - protected: - T a, i0a; - - /* modified zeroth order Bessel function of the first kind. */ - static T bessel_i0(T x) - { - #define EPSILON 1e-7 - const T y = square(x) / 4.0; - - T sum = 1.0; - T t = y; - - for (int i = 2; t > EPSILON; i++) - { - sum += t; - t *= y / square(i); - } - - return sum; - - #undef EPSILON - } - - public: - virtual const char* getName() const - { - return "Kaiser-window"; - } - virtual T getLength() const - { - return 1.0; - } - - virtual bool isCardinal() const - { - return true; - } - virtual bool isInfinite() const - { - return true; - } - virtual bool isUnitSpaced() const - { - return true; - } - virtual bool isCentered() const - { - return true; - } - - public: - virtual T operator () (T pos) const - { - return i0a * bessel_i0(a * sqrt(1.0 - square(pos))); - } - }; - - /* #################################################################################################################### - */ - template - class CombinerWindowFunction - : public IWindowFunction - { - public: - CombinerWindowFunction(IWindowFunction* fu, IWindowFunction* wi) - { - shaper = fu; - restrictor = wi; - } - - protected: - IWindowFunction* shaper; - IWindowFunction* restrictor; - - public: - virtual const char* getName() const - { - return "Combiner of two window-generators"; - } - virtual T getLength() const - { - return shaper->getLength(); - } - - virtual bool isCardinal() const - { - return shaper->isCardinal() && restrictor->isCardinal(); - } - virtual bool isInfinite() const - { - return shaper->isInfinite() && restrictor->isInfinite(); - } - virtual bool isUnitSpaced() const - { - return shaper->isUnitSpaced() && restrictor->isUnitSpaced(); - } - virtual bool isCentered() const - { - return shaper->isCentered() && restrictor->isCentered(); - } - - public: - virtual T operator () (T pos) const - { - return (*shaper)(pos) * (*restrictor)(pos / shaper->getLength()); - } - }; - - /* -------------------------------------------------------------------------------------------------------------------- - */ - template - class PointWindowFunction - : public BoxWindowFunction - { - public: - PointWindowFunction() - : BoxWindowFunction() { } - - public: - virtual const char* getName() const - { - return "Point-window"; - } - virtual T getLength() const - { - return 0.0; - } - }; -} //end namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/Converters/Gamma.cpp b/Gems/ImageProcessing/Code/Source/Converters/Gamma.cpp deleted file mode 100644 index c30385c608..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Gamma.cpp +++ /dev/null @@ -1,260 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include - -#include -#include -#include -#include - -#include -#include - -#include - -namespace ImageProcessing -{ - /////////////////////////////////////////////////////////////////////////////////// - // Lookup table for a function 'float fn(float x)'. - // Computed function values are stored in the table for x in [0.0; 1.0]. - // - // If passed x is less than xMin (xMin must be >= 0) or greater than 1.0, - // then the original function is called. - // Otherwise, a value from the table (linearly interpolated) - // is returned. - template - class FunctionLookupTable - { - public: - FunctionLookupTable(float(*fn)(float x), float xMin, float maxAllowedDifference) - : m_fn(fn) - , m_xMin(xMin) - , m_fMaxDiff(maxAllowedDifference) - { - } - - void Initialize() const - { - m_initialized = true; - AZ_Assert(m_xMin >= 0.0f, "wrong initial data for m_xMin"); - for (int i = 0; i <= TABLE_SIZE; ++i) - { - const float x = i / (float)TABLE_SIZE; - const float y = (*m_fn)(x); - m_table[i] = y; - } - } - - inline float compute(float x) const - { - if (x < m_xMin || x > 1) - { - return m_fn(x); - } - - const float f = x * TABLE_SIZE; - - const int i = int(f); - - if (!m_initialized) - { - Initialize(); - } - - if (i >= TABLE_SIZE) - { - return m_table[TABLE_SIZE]; - } - - const float alpha = f - i; - return (1 - alpha) * m_table[i] + alpha * m_table[i + 1]; - } - - public: - bool Test(const float maxDifferenceAllowed) const - { - if (int(-0.99f) != 0 || - int(+0.00f) != 0 || - int(+0.01f) != 0 || - int(+0.99f) != 0 || - int(+1.00f) != 1 || - int(+1.01f) != 1 || - int(+1.99f) != 1 || - int(+2.00f) != 2 || - int(+2.01f) != 2) - { - return false; - } - - if (m_xMin < 0) - { - return false; - } - - const int n = 1000000; - for (int i = 0; i <= n; ++i) - { - const float x = 1.1f * (i / (float)n); - const float resOriginal = m_fn(x); - const float resTable = compute(x); - const float difference = resOriginal - resTable; - - if (fabs(difference) > maxDifferenceAllowed) - { - return false; - } - } - return true; - } - - private: - float(*m_fn)(float x); - float m_xMin; - mutable float m_table[TABLE_SIZE + 1]; - mutable bool m_initialized = false; - float m_fMaxDiff = 0.0f; - }; - - - static float GammaToLinear(float x) - { - return (x <= 0.04045f) ? x / 12.92f : powf((x + 0.055f) / 1.055f, 2.4f); - } - - static float LinearToGamma(float x) - { - return (x <= 0.0031308f) ? x * 12.92f : 1.055f * powf(x, 1.0f / 2.4f) - 0.055f; - } - - static FunctionLookupTable<1024> s_lutGammaToLinear(GammaToLinear, 0.04045f, 0.00001f); - static FunctionLookupTable<1024> s_lutLinearToGamma(LinearToGamma, 0.05f, 0.00001f); - - /////////////////////////////////////////////////////////////////////////////////// - - /////////////////////////////////////////////////////////////////////////////////// - bool ImageToProcess::GammaToLinearRGBA32F(bool bDeGamma) - { - // return immediately if there is no need to de-gamma image and the source is in the desired format - EPixelFormat srcFmt = m_img->GetPixelFormat(); - if (!bDeGamma && (srcFmt == ePixelFormat_R32G32B32A32F)) - { - return true; - } - - //convert to 32F first - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcFmt)) - { - AZ_Warning("Image Processing", false, "This is not common user case with compressed format input. But it may continue"); - ConvertFormat(ePixelFormat_R32G32B32A32F); - } - - IImageObjectPtr srcImage = m_img; - EPixelFormat dstFmt = ePixelFormat_R32G32B32A32F; - IImageObjectPtr dstImage(m_img->AllocateImage(dstFmt)); - - //create pixel operation function for src and dst images - IPixelOperationPtr srcOp = CreatePixelOperation(srcFmt); - IPixelOperationPtr dstOp = CreatePixelOperation(dstFmt); - - //get count of bytes per pixel for both src and dst images - uint32 srcPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(srcFmt)->bitsPerBlock / 8; - uint32 dstPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->bitsPerBlock / 8; - - const uint32 dwMips = dstImage->GetMipCount(); - float r, g, b, a; - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* srcPixelBuf; - uint32 srcPitch; - srcImage->GetImagePointer(dwMip, srcPixelBuf, srcPitch); - uint8* dstPixelBuf; - uint32 dstPitch; - dstImage->GetImagePointer(dwMip, dstPixelBuf, dstPitch); - - const uint32 pixelCount = srcImage->GetPixelCount(dwMip); - - for (uint32 i = 0; i < pixelCount; ++i, srcPixelBuf += srcPixelBytes, dstPixelBuf += dstPixelBytes) - { - srcOp->GetRGBA(srcPixelBuf, r, g, b, a); - if (bDeGamma) - { - r = s_lutGammaToLinear.compute(r); - g = s_lutGammaToLinear.compute(g); - b = s_lutGammaToLinear.compute(b); - } - - dstOp->SetRGBA(dstPixelBuf, r, g, b, a); - } - } - - m_img = dstImage; - - if (bDeGamma) - { - m_img->RemoveImageFlags(EIF_SRGBRead); - } - return true; - } - - void ImageToProcess::LinearToGamma() - { - if (Get()->HasImageFlags(EIF_SRGBRead)) - { - AZ_Assert(false, "%s: input image is already SRGB", __FUNCTION__); - return; - } - - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_img->GetPixelFormat())) - { - AZ_Assert(false, "This is not common user case with compressed format input. But it may continue"); - ConvertFormat(ePixelFormat_R32G32B32A32F); - } - - EPixelFormat srcFmt = m_img->GetPixelFormat(); - IImageObjectPtr srcImage = m_img; - - IImageObjectPtr dstImage(m_img->AllocateImage(srcFmt)); - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(srcFmt); - - //get count of bytes per pixel for both src and dst images - uint32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(srcFmt)->bitsPerBlock / 8; - - const uint32 dwMips = srcImage->GetMipCount(); - float r, g, b, a; - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* srcPixelBuf; - uint32 srcPitch; - srcImage->GetImagePointer(dwMip, srcPixelBuf, srcPitch); - uint8* dstPixelBuf; - uint32 dstPitch; - dstImage->GetImagePointer(dwMip, dstPixelBuf, dstPitch); - - const uint32 pixelCount = srcImage->GetPixelCount(dwMip); - - for (uint32 i = 0; i < pixelCount; ++i, srcPixelBuf += pixelBytes, dstPixelBuf += pixelBytes) - { - pixelOp->GetRGBA(srcPixelBuf, r, g, b, a); - r = s_lutLinearToGamma.compute(r); - g = s_lutLinearToGamma.compute(g); - b = s_lutLinearToGamma.compute(b); - pixelOp->SetRGBA(dstPixelBuf, r, g, b, a); - } - } - - m_img = dstImage; - Get()->AddImageFlags(EIF_SRGBRead); - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/HighPass.cpp b/Gems/ImageProcessing/Code/Source/Converters/HighPass.cpp deleted file mode 100644 index 7660d02016..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/HighPass.cpp +++ /dev/null @@ -1,110 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - - // higher mip level is subtracted by lower mip level when applying the [cheap] high pass filter - void ImageToProcess::CreateHighPass(AZ::u32 dwMipDown) - { - //no need to convert if mip go down 0 - if (dwMipDown == 0) - { - return; - } - - const EPixelFormat ePixelFormat = m_img->GetPixelFormat(); - - if (ePixelFormat != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "You need convert the orginal image to ePixelFormat_R32G32B32A32F before call this function"); - return; - } - - - AZ::u32 dwWidth, dwHeight, dwMips; - dwWidth = m_img->GetWidth(0); - dwHeight = m_img->GetHeight(0); - dwMips = m_img->GetMipCount(); - - if (dwMipDown >= dwMips) - { - AZ_Warning("Image Processing", false, "CreateHighPass can't go down %i MIP levels for high pass as there are not\ - enough MIP levels available, going down by %i instead", dwMipDown, dwMips - 1); - dwMipDown = dwMips - 1; - } - - IImageObjectPtr newImage(IImageObject::CreateImage(dwWidth, dwHeight, dwMips, ePixelFormat)); - newImage->CopyPropertiesFrom(m_img); - - IPixelOperationPtr pixelOp = CreatePixelOperation(ePixelFormat); - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat)->bitsPerBlock / 8; - - AZ::u32 dstMips = newImage->GetMipCount(); - for (AZ::u32 dstMip = 0; dstMip < dwMipDown; ++dstMip) - { - // linear interpolation - FilterImage(MipGenType::triangle, MipGenEvalType::sum, 0.0f, 0.0f, m_img, dwMipDown, newImage, dstMip, NULL, NULL); - - const AZ::u32 pixelCountIn = m_img->GetWidth(dstMip) *m_img->GetHeight(dstMip); - const AZ::u32 pixelCountOut = newImage->GetWidth(dstMip) * newImage->GetHeight(dstMip); - - //substraction - AZ::u8* srcPixelBuf; - AZ::u32 srcPitch; - m_img->GetImagePointer(dstMip, srcPixelBuf, srcPitch); - AZ::u8* dstPixelBuf; - AZ::u32 dstPitch; - newImage->GetImagePointer(dstMip, dstPixelBuf, dstPitch); - const AZ::u32 pixelCount = newImage->GetPixelCount(dstMip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, srcPixelBuf += pixelBytes, dstPixelBuf += pixelBytes) - { - float r1, g1, b1, a1, r2, g2, b2, a2; - pixelOp->GetRGBA(srcPixelBuf, r1, g1, b1, a1); - pixelOp->GetRGBA(dstPixelBuf, r2, g2, b2, a2); - - r2 = AZ::GetClamp(r1 - r2 + 0.5f, 0.0f, 1.0f); - g2 = AZ::GetClamp(g1 - g2 + 0.5f, 0.0f, 1.0f); - b2 = AZ::GetClamp(b1 - b2 + 0.5f, 0.0f, 1.0f); - a2 = AZ::GetClamp(a1 - a2 + 0.5f, 0.0f, 1.0f); - pixelOp->SetRGBA(dstPixelBuf, r2, g2, b2, a2); - } - } - - // mips below the chosen highpass mip are grey - for (AZ::u32 dstMip = dwMipDown; dstMip < dstMips; ++dstMip) - { - AZ::u8* dstPixelBuf; - AZ::u32 dstPitch; - newImage->GetImagePointer(dstMip, dstPixelBuf, dstPitch); - const AZ::u32 pixelCount = newImage->GetPixelCount(dstMip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, dstPixelBuf += pixelBytes) - { - pixelOp->SetRGBA(dstPixelBuf, 0.5f, 0.5f, 0.5f, 1.0f); - } - } - - m_img = newImage; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Histogram.cpp b/Gems/ImageProcessing/Code/Source/Converters/Histogram.cpp deleted file mode 100644 index 23cd836891..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Histogram.cpp +++ /dev/null @@ -1,81 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include - -#include - -/////////////////////////////////////////////////////////////////////////////////// - -namespace ImageProcessing -{ - float GetLuminance(const float& r, const float& g, const float& b) - { - return (r * 0.30f + g * 0.59f + b * 0.11f); - } - - bool ComputeLuminanceHistogram(IImageObjectPtr imageObject, Histogram<256>& histogram) - { - EPixelFormat pixelFormat = imageObject->GetPixelFormat(); - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return false; - } - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(pixelFormat); - - //setup histogram bin - static const size_t binCount = 256; - Histogram::Bins bins; - Histogram::clearBins(bins); - - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(pixelFormat)->bitsPerBlock / 8; - - const AZ::u32 mipCount = imageObject->GetMipCount(); - float color[4]; - for (uint32 mip = 0; mip < mipCount; ++mip) - { - AZ::u8* pixelBuf; - AZ::u32 pitch; - imageObject->GetImagePointer(mip, pixelBuf, pitch); - const uint32 pixelCount = imageObject->GetPixelCount(mip); - - for (uint32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - - const float luminance = AZ::GetClamp(GetLuminance(color[0], color[1], color[2]), 0.0f, 1.0f); - const float f = luminance * binCount; - if (f <= 0) - { - ++bins[0]; - } - else - { - const int bin = int(f); - ++bins[(bin < binCount) ? bin : binCount - 1]; - } - } - } - - histogram.set(bins); - return true; - } -} // end namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/Histogram.h b/Gems/ImageProcessing/Code/Source/Converters/Histogram.h deleted file mode 100644 index 4f73f23a74..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Histogram.h +++ /dev/null @@ -1,84 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#pragma once - -namespace ImageProcessing -{ - template - class Histogram - { - public: - typedef AZ::u64 Bins[BIN_COUNT]; - - public: - Histogram() - { - } - - static void clearBins(Bins& bins) - { - memset(&bins, 0, sizeof(bins)); - } - - void set(const Bins& bins) - { - m_bins[0] = bins[0]; - m_binsCumulative[0] = bins[0]; - double sum = 0.0f; - for (size_t i = 1; i < BIN_COUNT; ++i) - { - m_bins[i] = bins[i]; - m_binsCumulative[i] = m_binsCumulative[i - 1] + bins[i]; - sum += i * double(bins[i]); - } - - const AZ::u64 totalCount = getTotalSampleCount(); - m_meanBin = (totalCount <= 0) ? 0.0f : float(sum / totalCount); - } - - AZ::u64 getTotalSampleCount() const - { - return m_binsCumulative[BIN_COUNT - 1]; - } - - float getPercentage(size_t minBin, size_t maxBin) const - { - const AZ::u64 totalCount = getTotalSampleCount(); - - if ((totalCount <= 0) || (minBin > maxBin) || (maxBin < 0) || (minBin >= BIN_COUNT)) - { - return 0.0f; - } - - minBin = AZ::GetMax(minBin, size_t(0)); - maxBin = AZ::GetMin(maxBin, BIN_COUNT-1); - - const AZ::u64 count = m_binsCumulative[maxBin] - ((minBin <= 0) ? 0 : m_binsCumulative[minBin-1]); - - return float((double(count) * 100.0) / double(totalCount)); - } - - float getMeanBin() const - { - return m_meanBin; - } - - private: - Bins m_bins; - Bins m_binsCumulative; - float m_meanBin; - }; - - bool ComputeLuminanceHistogram(IImageObjectPtr imageObject, Histogram<256>& histogram); -} diff --git a/Gems/ImageProcessing/Code/Source/Converters/Normalize.cpp b/Gems/ImageProcessing/Code/Source/Converters/Normalize.cpp deleted file mode 100644 index bb41991385..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/Normalize.cpp +++ /dev/null @@ -1,420 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -// Original file Copyright Crytek GMBH or its affiliates, used under license. - -#include - -#include -#include - -namespace ImageProcessing -{ - template - static void AdjustScaleForQuantization(float fBaseValue, float fBaseLine, float& cScale, float& cMinColor, float& cMaxColor) - { - const int qOne = (1 << qBits) - 1; - const int qUpperBits = (8 - qBits); - const int qLowerBits = qBits - qUpperBits; - - const int v = int(floor(fBaseValue * qOne)); - - int v0 = v - (v != 0); - int v1 = v + 0; - int v2 = v + (v != qOne); - - v0 = (v0 << qUpperBits) | (v0 >> qLowerBits); - v1 = (v1 << qUpperBits) | (v1 >> qLowerBits); - v2 = (v2 << qUpperBits) | (v2 >> qLowerBits); - - const float f0 = v0 / 255.0f; - const float f1 = v1 / 255.0f; - const float f2 = v2 / 255.0f; - - float fBaseLock = -1; - - if (fabsf(f0 - fBaseValue) < fabsf(fBaseLock - fBaseValue)) - { - fBaseLock = f0; - } - if (fabsf(f1 - fBaseValue) < fabsf(fBaseLock - fBaseValue)) - { - fBaseLock = f1; - } - if (fabsf(f2 - fBaseValue) < fabsf(fBaseLock - fBaseValue)) - { - fBaseLock = f2; - } - - float lScale = (1.0f - fBaseLock) / (1.0f - fBaseLine); - float vScale = (1.0f - fBaseValue) / (1.0f - fBaseLine); - float sScale = lScale / vScale; - - float csScale = (cScale / sScale); - float csBias = cMinColor - (1.0f - sScale) * (cScale / sScale); - - if ((csBias > 0.0f) && ((csScale + csBias) < 1.0f)) - { - cMinColor = csBias; - cScale = csScale; - cMaxColor = csScale + csBias; - } - } - - /////////////////////////////////////////////////////////////////////////////////// - - void CImageObject::NormalizeImageRange(EColorNormalization eColorNorm, EAlphaNormalization eAlphaNorm, bool bMaintainBlack, int nExponentBits) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: unsupported source format", __FUNCTION__); - return; - } - - uint32 dwWidth, dwHeight, dwMips; - GetExtent(dwWidth, dwHeight, dwMips); - - // find image's range, can be negative - float cMinColor[4] = { FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX }; - float cMaxColor[4] = { -FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX }; - - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* pSrcMem; - uint32 dwSrcPitch; - GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - dwHeight = GetHeight(dwMip); - dwWidth = GetWidth(dwMip); - for (uint32 dwY = 0; dwY < dwHeight; ++dwY) - { - const float* pSrcPix = (float*)&pSrcMem[dwY * dwSrcPitch]; - for (uint32 dwX = 0; dwX < dwWidth; ++dwX) - { - cMinColor[0] = AZ::GetMin(cMinColor[0], pSrcPix[0]); - cMinColor[1] = AZ::GetMin(cMinColor[1], pSrcPix[1]); - cMinColor[2] = AZ::GetMin(cMinColor[2], pSrcPix[2]); - cMinColor[3] = AZ::GetMin(cMinColor[3], pSrcPix[3]); - - cMaxColor[0] = AZ::GetMax(cMaxColor[0], pSrcPix[0]); - cMaxColor[1] = AZ::GetMax(cMaxColor[1], pSrcPix[1]); - cMaxColor[2] = AZ::GetMax(cMaxColor[2], pSrcPix[2]); - cMaxColor[3] = AZ::GetMax(cMaxColor[3], pSrcPix[3]); - - pSrcPix += 4; - } - } - } - - if (bMaintainBlack) - { - cMinColor[0] = AZ::GetMin(0.f, cMinColor[0]); - cMinColor[1] = AZ::GetMin(0.f, cMinColor[1]); - cMinColor[2] = AZ::GetMin(0.f, cMinColor[2]); - cMinColor[3] = AZ::GetMin(0.f, cMinColor[3]); - } - - AZ_Assert(cMaxColor[0] >= cMinColor[0] && cMaxColor[1] >= cMinColor[1] && - cMaxColor[2] >= cMinColor[2] && cMaxColor[3] >= cMinColor[3], "bad color range"); - - // some graceful threshold to avoid extreme cases - if (cMaxColor[0] - cMinColor[0] < (3.f / 255)) - { - cMinColor[0] = AZ::GetMax(0.f, cMinColor[0] - (2.f / 255)); - cMaxColor[0] = AZ::GetMin(1.f, cMaxColor[0] + (2.f / 255)); - } - if (cMaxColor[1] - cMinColor[1] < (3.f / 255)) - { - cMinColor[1] = AZ::GetMax(0.f, cMinColor[1] - (2.f / 255)); - cMaxColor[1] = AZ::GetMin(1.f, cMaxColor[1] + (2.f / 255)); - } - if (cMaxColor[2] - cMinColor[2] < (3.f / 255)) - { - cMinColor[2] = AZ::GetMax(0.f, cMinColor[2] - (2.f / 255)); - cMaxColor[2] = AZ::GetMin(1.f, cMaxColor[2] + (2.f / 255)); - } - if (cMaxColor[3] - cMinColor[3] < (3.f / 255)) - { - cMinColor[3] = AZ::GetMax(0.f, cMinColor[3] - (2.f / 255)); - cMaxColor[3] = AZ::GetMin(1.f, cMaxColor[3] + (2.f / 255)); - } - - // calculate range to normalize to - const float fMaxExponent = powf(2.0f, (float)nExponentBits) - 1.0f; - const float cUprValue = powf(2.0f, fMaxExponent); - - if (eColorNorm == eColorNormalization_PassThrough) - { - cMinColor[0] = cMinColor[1] = cMinColor[2] = 0.f; - cMaxColor[0] = cMaxColor[1] = cMaxColor[2] = 1.f; - } - - // don't touch alpha channel if not used - if (eAlphaNorm == eAlphaNormalization_SetToZero) - { - // Store the range explicitly into the structure for read-back. - // The formats which request range expansion don't support alpha. - cMinColor[3] = 0.f; - cMaxColor[3] = cUprValue; - } - else if (eAlphaNorm == eAlphaNormalization_PassThrough) - { - cMinColor[3] = 0.f; - cMaxColor[3] = 1.f; - } - - // get the origins of the color model's lattice for the range of values - // these values need to be encoded as precise as possible under quantization - AZ::Vector4 cBaseLines = AZ::Vector4(0.0f, 0.0f, 0.0f, 0.0f); - AZ::Vector4 cScale = AZ::Vector4(cMaxColor[0] - cMinColor[0], cMaxColor[1] - cMinColor[1], - cMaxColor[2] - cMinColor[2], cMaxColor[3] - cMinColor[3]); - -#if 0 - // NOTE: disabled for now, in the future we can turn this on to force availability - // of value to guarantee for example perfect grey-scales (using YFF) - switch (GetImageFlags() & EIF_Colormodel) - { - case EIF_Colormodel_RGB: - cBaseLines = Vec4(0.0f, 0.0f, 0.0f, 0.0f); - break; - case EIF_Colormodel_CIE: - cBaseLines = Vec4(0.0f, 1.f / 3, 1.f / 3, 0.0f); - break; - case EIF_Colormodel_IRB: - cBaseLines = Vec4(0.0f, 1.f / 2, 1.f / 2, 0.0f); - break; - case EIF_Colormodel_YCC: - case EIF_Colormodel_YFF: - cBaseLines = Vec4(1.f / 2, 0.0f, 1.f / 2, 0.0f); - break; - } - - Vec4 cBaseScale = cBaseLines; - cBaseLines = cBaseLines - cMinColor; - cBaseLines = cBaseLines / cScale; - - if ((cBaseLines.x > 0.0f) && (cBaseLines.x < 1.0f)) - { - AdjustScaleForQuantization<5>(cBaseLines.x, cBaseScale.x, cScale.x, cMinColor.x, cMaxColor.x); - } - if ((cBaseLines.y > 0.0f) && (cBaseLines.y < 1.0f)) - { - AdjustScaleForQuantization<6>(cBaseLines.y, cBaseScale.y, cScale.y, cMinColor.y, cMaxColor.y); - } - if ((cBaseLines.z > 0.0f) && (cBaseLines.z < 1.0f)) - { - AdjustScaleForQuantization<5>(cBaseLines.z, cBaseScale.z, cScale.z, cMinColor.z, cMaxColor.z); - } -#endif - - // normalize the image - AZ::Vector4 vMin = AZ::Vector4(cMinColor[0], cMinColor[1], cMinColor[2], cMinColor[3]); - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* pSrcMem; - uint32 dwSrcPitch; - GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - dwHeight = GetHeight(dwMip); - dwWidth = GetWidth(dwMip); - for (uint32 dwY = 0; dwY < dwHeight; ++dwY) - { - AZ::Vector4* pSrcPix = (AZ::Vector4*)&pSrcMem[dwY * dwSrcPitch]; - for (uint32 dwX = 0; dwX < dwWidth; ++dwX) - { - *pSrcPix = *pSrcPix - vMin; - *pSrcPix = *pSrcPix / cScale; - *pSrcPix = *pSrcPix * cUprValue; - - pSrcPix++; - } - } - } - - // set up a range - SetColorRange(AZ::Color(cMinColor[0], cMinColor[1], cMinColor[2], cMinColor[3]), - AZ::Color(cMaxColor[0], cMaxColor[1], cMaxColor[2], cMaxColor[3])); - - // set up a flag - AddImageFlags(EIF_RenormalizedTexture); - } - - void CImageObject::ExpandImageRange([[maybe_unused]] EColorNormalization eColorMode, EAlphaNormalization eAlphaMode, int nExponentBits) - { - AZ_Assert(!((eAlphaMode != eAlphaNormalization_SetToZero) && (nExponentBits != 0)), "%s: Unexpected alpha mode", __FUNCTION__); - - if (!HasImageFlags(EIF_RenormalizedTexture)) - { - return; - } - - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - uint32 dwWidth, dwHeight, dwMips; - GetExtent(dwWidth, dwHeight, dwMips); - - // calculate range to normalize to - const float fMaxExponent = powf(2.0f, (float)nExponentBits) - 1.0f; - float cUprValue = powf(2.0f, fMaxExponent); - - // find image's range, can be negative - AZ::Color cMinColor = AZ::Color(FLT_MAX, FLT_MAX, FLT_MAX, FLT_MAX); - AZ::Color cMaxColor = AZ::Color(-FLT_MAX, -FLT_MAX, -FLT_MAX, -FLT_MAX); - - GetColorRange(cMinColor, cMaxColor); - - // don't touch alpha channel if not used - if (eAlphaMode == eAlphaNormalization_SetToZero) - { - // Overwrite the range explicitly into the structure. - // The formats which request range expansion don't support alpha. - cUprValue = cMaxColor.GetA(); - - cMinColor.SetA(1.f); - cMaxColor.SetA(1.f); - } - - // expand the image - const AZ::Vector4 cScale = cMaxColor.GetAsVector4() - cMinColor.GetAsVector4(); - for (uint32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - uint8* pSrcMem; - uint32 dwSrcPitch; - GetImagePointer(dwMip, pSrcMem, dwSrcPitch); - - dwHeight = GetHeight(dwMip); - dwWidth = GetWidth(dwMip); - for (uint32 dwY = 0; dwY < dwHeight; ++dwY) - { - AZ::Vector4* pSrcPix = (AZ::Vector4*)&pSrcMem[dwY * dwSrcPitch]; - for (uint32 dwX = 0; dwX < dwWidth; ++dwX) - { - *pSrcPix = *pSrcPix / cUprValue; - *pSrcPix = *pSrcPix * cScale; - *pSrcPix = *pSrcPix + cMinColor.GetAsVector4(); - - pSrcPix++; - } - } - } - - // set up a range - SetColorRange(AZ::Color(0.0f, 0.0f, 0.0f, 0.0f), AZ::Color(1.0f, 1.0f, 1.0f, 1.0f)); - - // set up a flag - RemoveImageFlags(EIF_RenormalizedTexture); - } - - /////////////////////////////////////////////////////////////////////////////////// - - void CImageObject::NormalizeVectors(AZ::u32 firstMip, AZ::u32 maxMipCount) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - uint32 lastMip = AZ::GetMin(firstMip + maxMipCount, GetMipCount()); - for (uint32 mip = firstMip; mip < lastMip; ++mip) - { - const uint32 pixelCount = GetPixelCount(mip); - uint8* imageMem; - uint32 pitch; - GetImagePointer(mip, imageMem, pitch); - float* pPixels = (float*)imageMem; - - for (uint32 i = 0; i < pixelCount; ++i, pPixels += 4) - { - AZ::Vector3 vNormal = AZ::Vector3(pPixels[0] * 2.0f - 1.0f, pPixels[1] * 2.0f - 1.0f, pPixels[2] * 2.0f - 1.0f); - - // TODO: every opposing vector addition produces the zero-vector for - // normals on the entire sphere, in that case the forward vector [0,0,1] - // isn't necessarily right and we should look at the adjacent normals - // for a direction - if (vNormal.IsZero()) - { - vNormal = AZ::Vector3(1.0f, 0.0f, 0.0f); - } - else - { - vNormal.NormalizeSafe(); - } - - pPixels[0] = vNormal.GetX() * 0.5f + 0.5f; - pPixels[1] = vNormal.GetY() * 0.5f + 0.5f; - pPixels[2] = vNormal.GetZ() * 0.5f + 0.5f; - } - } - } - - /////////////////////////////////////////////////////////////////////////////////// - void CImageObject::ScaleAndBiasChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& scale, const AZ::Vector4& bias) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - const uint32 lastMip = AZ::GetMin(firstMip + maxMipCount, GetMipCount()); - for (uint32 mip = firstMip; mip < lastMip; ++mip) - { - const uint32 pixelCount = GetPixelCount(mip); - uint8* imageMem; - uint32 pitch; - GetImagePointer(mip, imageMem, pitch); - float* pPixels = (float*)imageMem; - - for (uint32 i = 0; i < pixelCount; ++i, pPixels += 4) - { - pPixels[0] = pPixels[0] * scale.GetX() + bias.GetX(); - pPixels[1] = pPixels[1] * scale.GetY() + bias.GetY(); - pPixels[2] = pPixels[2] * scale.GetZ() + bias.GetZ(); - pPixels[3] = pPixels[3] * scale.GetW() + bias.GetW(); - } - } - } - - /////////////////////////////////////////////////////////////////////////////////// - void CImageObject::ClampChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& min, const AZ::Vector4& max) - { - if (GetPixelFormat() != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s: only supports source format A32B32G32R32F", __FUNCTION__); - return; - } - - const uint32 lastMip = AZ::GetMin(firstMip + maxMipCount, GetMipCount()); - for (uint32 mip = firstMip; mip < lastMip; ++mip) - { - - const uint32 pixelCount = GetPixelCount(mip); - uint8* imageMem; - uint32 pitch; - GetImagePointer(mip, imageMem, pitch); - float* pPixels = (float*)imageMem; - - for (uint32 i = 0; i < pixelCount; ++i, pPixels += 4) - { - pPixels[0] = AZ::GetClamp(pPixels[0], float(min.GetX()), float(max.GetX())); - pPixels[1] = AZ::GetClamp(pPixels[1], float(min.GetY()), float(max.GetY())); - pPixels[2] = AZ::GetClamp(pPixels[2], float(min.GetZ()), float(max.GetZ())); - pPixels[3] = AZ::GetClamp(pPixels[3], float(min.GetW()), float(max.GetW())); - } - } - } - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.cpp b/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.cpp deleted file mode 100644 index 034dcdfda1..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.cpp +++ /dev/null @@ -1,487 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include - -#include -#include -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// -//functions for maintaining alpha coverage. - -namespace ImageProcessing -{ - //convertion: all data type supported by pixel channel <=> float - float U8ToF32(uint8 in) - { - return in / 255.f; - } - - uint8 F32ToU8(float in) - { - return aznumeric_cast(round(AZ::GetClamp(in, 0.f, 1.f) * 255)); - } - - float U16ToF32(uint16 in) - { - return in / 65535.f; - } - - uint16 F32ToU16(float in) - { - return aznumeric_cast(round(AZ::GetClamp(in, 0.f, 1.f) * 65535.f)); - } - - float HalfToF32(SHalf in) - { - return in; - } - - SHalf F32ToHalf(float in) - { - return SHalf(in); - } - - //stucture for RGBE pixel format - struct RgbE - { - static const int RGB9E5_EXPONENT_BITS = 5; - static const int RGB9E5_MANTISSA_BITS = 9; - static const int RGB9E5_EXP_BIAS = 15; - static const int RGB9E5_MAX_VALID_BIASED_EXP = 31; - static const int MAX_RGB9E5_EXP = (RGB9E5_MAX_VALID_BIASED_EXP - RGB9E5_EXP_BIAS); - static const int RGB9E5_MANTISSA_VALUES = (1 << RGB9E5_MANTISSA_BITS); - static const int MAX_RGB9E5_MANTISSA = (RGB9E5_MANTISSA_VALUES - 1); - - static float MAX_RGB9E5; - - unsigned int r : 9; - unsigned int g : 9; - unsigned int b : 9; - unsigned int e : 5; - - static int log2(float x) - { - int bitfield = *((int*)(&x)); - bitfield &= ~0x80000000; - - return ((bitfield >> 23) - 127); - } - - void GetRGBF(float& outR, float& outG, float& outB) const - { - int exponent = e - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; - float scale = powf(2.0f, aznumeric_cast(exponent)); - outR = r * scale; - outG = g * scale; - outB = b * scale; - } - - void SetRGBF(const float& inR, const float& inG, const float& inB) - { - float rf = AZStd::GetMax(0.0f, AZStd::GetMin(inR, MAX_RGB9E5)); - float gf = AZStd::GetMax(0.0f, AZStd::GetMin(inG, MAX_RGB9E5)); - float bf = AZStd::GetMax(0.0f, AZStd::GetMin(inB, MAX_RGB9E5)); - float mf = AZStd::GetMax(rf, AZStd::GetMax(gf, bf)); - - e = AZStd::GetMax(0, log2(mf) + (RGB9E5_EXP_BIAS + 1)); - - int exponent = e - RGB9E5_EXP_BIAS - RGB9E5_MANTISSA_BITS; - float scale = powf(2.0f, aznumeric_cast(exponent)); - - r = AZStd::GetMin(511, (int)floorf(rf / scale + 0.5f)); - g = AZStd::GetMin(511, (int)floorf(gf / scale + 0.5f)); - b = AZStd::GetMin(511, (int)floorf(bf / scale + 0.5f)); - } - }; - - float RgbE::MAX_RGB9E5 = (((float)MAX_RGB9E5_MANTISSA) / RGB9E5_MANTISSA_VALUES * (1 << MAX_RGB9E5_EXP)); - - //ePixelFormat_R8G8B8A8 - class PixelOperationR8G8B8A8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = U8ToF32(data[1]); - b = U8ToF32(data[2]); - a = U8ToF32(data[3]); - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - data[1] = F32ToU8(g); - data[2] = F32ToU8(b); - data[3] = F32ToU8(a); - } - }; - - //ePixelFormat_R8G8B8X8 - class PixelOperationR8G8B8X8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = U8ToF32(data[1]); - b = U8ToF32(data[2]); - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, [[maybe_unused]] const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - data[1] = F32ToU8(g); - data[2] = F32ToU8(b); - data[3] = 0xff; - } - }; - - //ePixelFormat_B8G8R8A8 - class PixelOperationB8G8R8A8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[2]); - g = U8ToF32(data[1]); - b = U8ToF32(data[0]); - a = U8ToF32(data[3]); - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(b); - data[1] = F32ToU8(g); - data[2] = F32ToU8(r); - data[3] = F32ToU8(a); - } - }; - - //ePixelFormat_R8G8 - class PixelOperationR8G8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = U8ToF32(data[1]); - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - data[1] = F32ToU8(g); - } - }; - - //ePixelFormat_R8 - class PixelOperationR8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - r = U8ToF32(data[0]); - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(r); - } - }; - - //ePixelFormat_A8 - class PixelOperationA8 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint8* data = buf; - a = U8ToF32(data[0]); - //save alpha information to rgb too. useful for preview. - r = a; - g = a; - b = a; - } - - void SetRGBA(uint8* buf, [[maybe_unused]] const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, const float& a) override - { - uint8* data = buf; - data[0] = F32ToU8(a); - } - }; - - //ePixelFormat_R16G16B16A16 - class PixelOperationR16G16B16A16 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint16* data = (uint16*)(buf); - r = U16ToF32(data[0]); - g = U16ToF32(data[1]); - b = U16ToF32(data[2]); - a = U16ToF32(data[3]); - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - uint16* data = (uint16*)(buf); - data[0] = F32ToU16(r); - data[1] = F32ToU16(g); - data[2] = F32ToU16(b); - data[3] = F32ToU16(a); - } - }; - - //ePixelFormat_R16G16 - class PixelOperationR16G16 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint16* data = (uint16*)(buf); - r = U16ToF32(data[0]); - g = U16ToF32(data[1]); - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint16* data = (uint16*)(buf); - data[0] = F32ToU16(r); - data[1] = F32ToU16(g); - } - }; - - //ePixelFormat_R16 - class PixelOperationR16 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const uint16* data = (uint16*)(buf); - r = U16ToF32(data[0]); - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - uint16* data = (uint16*)(buf); - data[0] = F32ToU16(r); - } - }; - - //ePixelFormat_R9G9B9E5 - class PixelOperationR9G9B9E5 : public IPixelOperation - { - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const RgbE* data = (RgbE*)(buf); - data->GetRGBF(r, g, b); - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, [[maybe_unused]] const float& a) override - { - RgbE* data = (RgbE*)(buf); - data->SetRGBF(r, g, b); - } - }; - - //ePixelFormat_R32G32B32A32F - class PixelOperationR32G32B32A32F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const float* data = (float*)(buf); - r = data[0]; - g = data[1]; - b = data[2]; - a = data[3]; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - float* data = (float*)(buf); - data[0] = r; - data[1] = g; - data[2] = b; - data[3] = a; - } - }; - - //ePixelFormat_R32G32F - class PixelOperationR32G32F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const float* data = (float*)(buf); - r = data[0]; - g = data[1]; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - float* data = (float*)(buf); - data[0] = r; - data[1] = g; - } - }; - - //ePixelFormat_R32F - class PixelOperationR32F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const float* data = (float*)(buf); - r = data[0]; - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - float* data = (float*)(buf); - data[0] = r; - } - }; - - //ePixelFormat_R16G16B16A16F - class PixelOperationR16G16B16A16F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const SHalf* data = (SHalf*)(buf); - r = data[0]; - g = data[1]; - b = data[2]; - a = data[3]; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) override - { - SHalf* data = (SHalf*)(buf); - data[0] = SHalf(r); - data[1] = SHalf(g); - data[2] = SHalf(b); - data[3] = SHalf(a); - } - }; - - //ePixelFormat_R16G16F - class PixelOperationR16G16F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const SHalf* data = (SHalf*)(buf); - r = data[0]; - g = data[1]; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - SHalf* data = (SHalf*)(buf); - data[0] = SHalf(r); - data[1] = SHalf(g); - } - }; - - //ePixelFormat_R16F - class PixelOperationR16F : public IPixelOperation - { - public: - void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) override - { - const SHalf* data = (SHalf*)(buf); - r = data[0]; - g = 0.f; - b = 0.f; - a = 1.f; - } - - void SetRGBA(uint8* buf, const float& r, [[maybe_unused]] const float& g, [[maybe_unused]] const float& b, [[maybe_unused]] const float& a) override - { - SHalf* data = (SHalf*)(buf); - data[0] = SHalf(r); - } - }; - - IPixelOperationPtr CreatePixelOperation(EPixelFormat pixelFmt) - { - switch (pixelFmt) - { - case ePixelFormat_R8G8B8A8: - return AZStd::make_shared(); - case ePixelFormat_R8G8B8X8: - return AZStd::make_shared(); - case ePixelFormat_B8G8R8A8: - return AZStd::make_shared(); - case ePixelFormat_R8G8: - return AZStd::make_shared(); - case ePixelFormat_R8: - return AZStd::make_shared(); - case ePixelFormat_A8: - return AZStd::make_shared(); - case ePixelFormat_R16G16B16A16: - return AZStd::make_shared(); - case ePixelFormat_R16G16: - return AZStd::make_shared(); - case ePixelFormat_R16: - return AZStd::make_shared(); - case ePixelFormat_R9G9B9E5: - return AZStd::make_shared(); - case ePixelFormat_R32G32B32A32F: - return AZStd::make_shared(); - case ePixelFormat_R32G32F: - return AZStd::make_shared(); - case ePixelFormat_R32F: - return AZStd::make_shared(); - case ePixelFormat_R16G16B16A16F: - return AZStd::make_shared(); - case ePixelFormat_R16G16F: - return AZStd::make_shared(); - case ePixelFormat_R16F: - return AZStd::make_shared(); - default: - AZ_Assert(false, "This function should be only called for uncompressed pixel format"); - break; - } - return nullptr; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.h b/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.h deleted file mode 100644 index 4ce8a20643..0000000000 --- a/Gems/ImageProcessing/Code/Source/Converters/PixelOperation.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class IPixelOperation - { - public: - virtual ~IPixelOperation() {} - - virtual void GetRGBA(const uint8* buf, float& r, float& g, float& b, float& a) = 0; - virtual void SetRGBA(uint8* buf, const float& r, const float& g, const float& b, const float& a) = 0; - }; - - typedef AZStd::shared_ptr IPixelOperationPtr; - IPixelOperationPtr CreatePixelOperation(EPixelFormat pixelFmt); - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.cpp b/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.cpp deleted file mode 100644 index fb62bd258f..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.cpp +++ /dev/null @@ -1,386 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - - bool EditorHelper::s_IsPixelFormatStringInited = false; - const char* EditorHelper::s_PixelFormatString[ImageProcessing::EPixelFormat::ePixelFormat_Count]; - - void EditorHelper::InitPixelFormatString() - { - if (!s_IsPixelFormatStringInited) - { - s_IsPixelFormatStringInited = true; - } - - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - for (int format = 0; format < EPixelFormat::ePixelFormat_Count; format ++) - { - const PixelFormatInfo* info = pixelFormats.GetPixelFormatInfo((EPixelFormat)format); - s_PixelFormatString[(EPixelFormat)format] = ""; - if (info) - { - s_PixelFormatString[(EPixelFormat)format] = info->szName; - } - else - { - AZ_Error("Texture Editor", false, "Cannot find name of EPixelFormat %i", format); - } - } - } - - const AZStd::string EditorHelper::GetFileSizeString(AZ::u32 fileSizeInBytes) - { - AZStd::string fileSizeStr; - - static double kb = 1024.0f; - static double mb = kb * 1024.0; - static double gb = mb * 1024.0; - - static AZStd::string byteStr = "B"; - static AZStd::string kbStr = "KB"; - static AZStd::string mbStr = "MB"; - static AZStd::string gbStr = "GB"; - -#if AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX - kb = 1000.0; - mb = kb * 1000.0; - gb = mb * 1000.0; - - kbStr = "kB"; - mbStr = "mB"; - gbStr = "gB"; -#endif // AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX - - if (fileSizeInBytes < kb) - { - fileSizeStr = AZStd::string::format("%u%s", fileSizeInBytes, byteStr.c_str()); - } - else if (fileSizeInBytes < mb) - { - double size = fileSizeInBytes / kb; - fileSizeStr = AZStd::string::format("%.2f%s", size, kbStr.c_str()); - } - else if (fileSizeInBytes < gb) - { - double size = fileSizeInBytes / mb; - fileSizeStr = AZStd::string::format("%.2f%s", size, mbStr.c_str()); - } - else - { - double size = fileSizeInBytes / gb; - fileSizeStr = AZStd::string::format("%.2f%s", size, gbStr.c_str()); - } - return fileSizeStr; - } - - const AZStd::string EditorHelper::ToReadablePlatformString(const AZStd::string& platformRawStr) - { - AZStd::string readableString; - AZStd::string platformStrLowerCase = platformRawStr; - AZStd::to_lower(platformStrLowerCase.begin(), platformStrLowerCase.end()); - if (platformStrLowerCase == "pc") - { - readableString = "PC"; - } - else if (platformStrLowerCase == "es3") - { - readableString = "Android"; - } - else if (platformStrLowerCase == "osx_gl") - { - readableString = "macOS"; - } - else if (platformStrLowerCase == "provo") - { - readableString = "Provo"; - } - else if (platformStrLowerCase == "ios") - { - readableString = "iOS"; - } - else - { - return platformRawStr; - } - - return readableString; - } - - - EditorTextureSetting::EditorTextureSetting(const AZ::Uuid& sourceTextureId) - { - const AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry* fullDetails = AzToolsFramework::AssetBrowser::SourceAssetBrowserEntry::GetSourceByUuid(sourceTextureId); - InitFromPath(fullDetails->GetFullPath()); - } - - EditorTextureSetting::EditorTextureSetting(const AZStd::string& texturePath) - { - InitFromPath(texturePath); - } - - void EditorTextureSetting::InitFromPath(const AZStd::string& texturePath) - { - m_fullPath = texturePath; - AzFramework::StringFunc::Path::GetFullFileName(texturePath.c_str(), m_textureName); - - m_img = IImageObjectPtr(LoadImageFromFile(m_fullPath)); - - if (m_img == nullptr) - { - AZ_Warning("Texture Editor", false, "%s is not a valid texture image.", texturePath.c_str()); - return; - } - - bool generatedDefaults = false; - m_settingsMap = TextureSettings::GetMultiplatformTextureSetting(m_fullPath, generatedDefaults); - - // Get the preset id from one platform. The preset id for each platform should always be same - AZ_Assert(m_settingsMap.size() > 0, "There is no platform information"); - AZ::Uuid presetId = m_settingsMap.begin()->second.m_preset; - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetId); - - if (!preset) - { - AZ_Warning("Texture Editor", false, "Cannot find preset %s! Will assign a suggested one for the texture.", presetId.ToString().c_str()); - presetId = BuilderSettingManager::Instance()->GetSuggestedPreset(m_fullPath, m_img); - - for (auto& settingIter : m_settingsMap) - { - settingIter.second.ApplyPreset(presetId); - } - } - } - - void EditorTextureSetting::SetIsOverrided() - { - for (auto& it : m_settingsMap) - { - m_overrideFromPreset = false; - TextureSettings& textureSetting = it.second; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(textureSetting.m_preset); - if (presetSetting != nullptr) - { - if ((textureSetting.m_sizeReduceLevel != presetSetting->m_sizeReduceLevel) || - (textureSetting.m_suppressEngineReduce != presetSetting->m_suppressEngineReduce) || - (presetSetting->m_mipmapSetting != nullptr && textureSetting.m_mipGenType != presetSetting->m_mipmapSetting->m_type)) - { - m_overrideFromPreset = true; - } - } - else - { - AZ_Error("Texture Editor", false, "Texture Preset %s is not found!", textureSetting.m_preset.ToString().c_str()); - } - } - } - - void EditorTextureSetting::SetToPreset(const AZStd::string& presetName) - { - m_overrideFromPreset = false; - - AZ::Uuid presetId = BuilderSettingManager::Instance()->GetPresetIdFromName(presetName); - if (presetId.IsNull()) - { - AZ_Error("Texture Editor", false, "Texture Preset %s has no associated UUID.", presetName.c_str()); - return; - } - - for (auto& settingIter : m_settingsMap) - { - settingIter.second.ApplyPreset(presetId); - } - } - - //Get the texture setting on certain platform - TextureSettings& EditorTextureSetting::GetMultiplatformTextureSetting(const AZStd::string& platform) - { - AZ_Assert(m_settingsMap.size() > 0, "Texture Editor", "There is no texture settings for texture %s", m_fullPath.c_str()); - PlatformName platformName = platform; - if (platform.empty()) - { - platformName = BuilderSettingManager::s_defaultPlatform; - } - if (m_settingsMap.find(platformName) != m_settingsMap.end()) - { - return m_settingsMap[platformName]; - } - else - { - AZ_Error("Texture Editor", false, "Cannot find texture setting on platform %s", platformName.c_str()); - } - return m_settingsMap.begin()->second; - } - - bool EditorTextureSetting::GetFinalInfoForTextureOnPlatform(const AZStd::string& platform, AZ::u32 wantedReduce, ResolutionInfo& outResolutionInfo) - { - if (m_settingsMap.find(platform) == m_settingsMap.end()) - { - return false; - } - - // Copy current texture setting and set to desired reduce - TextureSettings textureSetting = m_settingsMap[platform]; - wantedReduce = AZStd::min(AZStd::max(s_MinReduceLevel, wantedReduce), s_MaxReduceLevel); - textureSetting.m_sizeReduceLevel = wantedReduce; - - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(textureSetting.m_preset, platform); - if (presetSetting) - { - EPixelFormat pixelFormat = presetSetting->m_pixelFormat; - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - - AZ::u32 inputWidth = m_img->GetWidth(0); - AZ::u32 inputHeight = m_img->GetHeight(0); - - // Update input width and height if it's a cubemap - if (presetSetting->m_cubemapSetting != nullptr) - { - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(m_img); - if (srcCubemap == nullptr) - { - return false; - } - inputWidth = srcCubemap->GetFaceSize(); - inputHeight = inputWidth; - outResolutionInfo.arrayCount = 6; - delete srcCubemap; - } - - GetOutputExtent(inputWidth, inputHeight, outResolutionInfo.width, outResolutionInfo.height, outResolutionInfo.reduce, &textureSetting, presetSetting); - - AZ::u32 mipMapCount = pixelFormats.ComputeMaxMipCount(pixelFormat, outResolutionInfo.width, outResolutionInfo.height); - outResolutionInfo.mipCount = presetSetting->m_mipmapSetting != nullptr && textureSetting.m_enableMipmap ? mipMapCount : 1; - - return true; - } - else - { - return false; - } - } - - bool EditorTextureSetting::RefreshMipSetting(bool enableMip) - { - bool enabled = true; - for (auto& it : m_settingsMap) - { - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(it.second.m_preset); - if (enableMip) - { - if (preset && preset->m_mipmapSetting) - { - it.second.m_enableMipmap = true; - it.second.m_mipGenType = preset->m_mipmapSetting->m_type; - } - else - { - it.second.m_enableMipmap = false; - enabled = false; - AZ_Error("Texture Editor", false, "Preset %s does not support mipmap!", preset->m_name.c_str()); - } - } - else - { - it.second.m_enableMipmap = false; - enabled = false; - } - } - return enabled; - } - - void EditorTextureSetting::PropagateCommonSettings() - { - if (m_settingsMap.size() <= 1) - { - //Only one setting available, no need to propagate - return; - } - - TextureSettings& texSetting = GetMultiplatformTextureSetting(); - for (auto& it = ++ m_settingsMap.begin(); it != m_settingsMap.end(); ++it) - { - const PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (it->first != defaultPlatform) - { - it->second.m_enableMipmap = texSetting.m_enableMipmap; - it->second.m_maintainAlphaCoverage = texSetting.m_maintainAlphaCoverage; - it->second.m_mipGenEval = texSetting.m_mipGenEval; - it->second.m_mipGenType = texSetting.m_mipGenType; - for (size_t i = 0; i < TextureSettings::s_MaxMipMaps; i++) - { - it->second.m_mipAlphaAdjust[i] = texSetting.m_mipAlphaAdjust[i]; - } - } - } - } - - AZStd::list EditorTextureSetting::GetResolutionInfo(AZStd::string platform, AZ::u32& minReduce, AZ::u32& maxReduce) - { - AZStd::list resolutionInfos; - // Set the min/max reduce to the global value range first - minReduce = s_MaxReduceLevel; - maxReduce = s_MinReduceLevel; - for (AZ::u32 i = s_MinReduceLevel; i <= s_MaxReduceLevel; i++) - { - ResolutionInfo resolutionInfo; - GetFinalInfoForTextureOnPlatform(platform, i, resolutionInfo); - // If actual reduce is lower than desired reduce, it reaches the limit and we can stop try lower resolution - if (i > resolutionInfo.reduce) - { - break; - } - // Finds out the final min/max reduce based on range in different platforms - minReduce = AZStd::min(resolutionInfo.reduce, minReduce); - maxReduce = AZStd::max(resolutionInfo.reduce, maxReduce); - resolutionInfos.push_back(resolutionInfo); - } - return resolutionInfos; - } - - AZStd::list EditorTextureSetting::GetResolutionInfoForMipmap(AZStd::string platform) - { - AZStd::list resolutionInfos; - unsigned int baseReduce = m_settingsMap[platform].m_sizeReduceLevel; - ResolutionInfo baseInfo; - GetFinalInfoForTextureOnPlatform(platform, baseReduce, baseInfo); - resolutionInfos.push_back(baseInfo); - for (AZ::u32 i = 1; i < baseInfo.mipCount; i++) - { - ResolutionInfo resolutionInfo = baseInfo; - resolutionInfo.width = AZStd::max(baseInfo.width >> i, 1); - resolutionInfo.height = AZStd::max(baseInfo.height >> i, 1); - resolutionInfo.reduce = baseInfo.reduce + i; - resolutionInfo.mipCount = 1; - resolutionInfos.push_back(resolutionInfo); - } - return resolutionInfos; - } - -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.h b/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.h deleted file mode 100644 index cbba723f06..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/EditorCommon.h +++ /dev/null @@ -1,105 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include -#include - -#include -namespace ImageProcessingEditor -{ - class EditorHelper - { - public: - static const char* s_PixelFormatString[ImageProcessing::EPixelFormat::ePixelFormat_Count]; - static void InitPixelFormatString(); - static const AZStd::string GetFileSizeString(AZ::u32 fileSizeInBytes); - static const AZStd::string ToReadablePlatformString(const AZStd::string& platformRawStr); - - private: - static bool s_IsPixelFormatStringInited; - }; - - struct ResolutionInfo - { - AZ::u32 width = 0; - AZ::u32 height = 0; - AZ::u32 arrayCount = 1; - AZ::u32 reduce = 0; - AZ::u32 mipCount = 0; - }; - - struct EditorTextureSetting - { - AZStd::string m_textureName = ""; - AZStd::string m_fullPath = ""; - ImageProcessing::MultiplatformTextureSettings m_settingsMap; - bool m_overrideFromPreset = false; - bool m_modified = false; - ImageProcessing::IImageObjectPtr m_img; - - EditorTextureSetting(const AZ::Uuid& sourceTextureId); - EditorTextureSetting(const AZStd::string& texturePath); - ~EditorTextureSetting() = default; - - void InitFromPath(const AZStd::string& texturePath); - - void SetIsOverrided(); - - void SetToPreset(const AZStd::string& presetName); - - //Get the texture setting on certain platform - ImageProcessing::TextureSettings& GetMultiplatformTextureSetting(const AZStd::string& platform = ""); - - //Gets the final resolution/reduce/mip count for a texture on a certain platform - //@param wantedReduce indicates the reduce level that's preferred - //@return successfully get the value or not - bool GetFinalInfoForTextureOnPlatform(const AZStd::string& platform, AZ::u32 wantedReduce, ResolutionInfo& outResolutionInfo); - - //Refresh the mip setting when the mip map setting is enabled/disabled. - //@return whether the mipmap is enabled or not. - bool RefreshMipSetting(bool enableMip); - - //Propagate non platform specific settings from the first setting to all the settings stored in m_settingsMap - void PropagateCommonSettings(); - - //Returns a list of calculated final resolution info based on different base reduce levels - AZStd::list GetResolutionInfo(AZStd::string platform, AZ::u32& minReduce, AZ::u32& maxReduce); - - //Returns a list of calculated final resolution info based on different mipmap levels - AZStd::list GetResolutionInfoForMipmap(AZStd::string platform); - }; - - - class ImageProcessingEditorInteralNotifications - : public AZ::EBusTraits - { - public: - ////////////////////////////////////////////////////////////////////////// - // EBusTraits overrides - static const AZ::EBusHandlerPolicy HandlerPolicy = AZ::EBusHandlerPolicy::Multiple; - static const AZ::EBusAddressPolicy AddressPolicy = AZ::EBusAddressPolicy::Single; - ///////////////////////////////////////////////////////////////////////// - - //! Used to inform the settings changed across widgets - virtual void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform) = 0; - }; - - using EditorInternalNotificationBus = AZ::EBus; - -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.cpp b/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.cpp deleted file mode 100644 index c646d7adad..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.cpp +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "ImagePopup.h" -#include -#include -#include - -namespace ImageProcessingEditor -{ - ImagePopup::ImagePopup(QImage previewImage, QWidget* parent /*= nullptr*/) - : QDialog(parent, Qt::Dialog | Qt::FramelessWindowHint | Qt::Popup) - , m_ui(new Ui::ImagePopup) - { - m_ui->setupUi(this); - m_previewImage = previewImage; - - if (!m_previewImage.isNull()) - { - int height = previewImage.height(); - int width = previewImage.width(); - - this->resize(width, height); - m_ui->imageLabel->resize(width, height); - QPixmap pixmap = QPixmap::fromImage(previewImage); - m_ui->imageLabel->setPixmap(pixmap); - - this->setFocusPolicy(Qt::FocusPolicy::NoFocus); - this->setModal(false); - } - } - - ImagePopup::~ImagePopup() - { - - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.h b/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.h deleted file mode 100644 index adc91d9dfe..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace Ui -{ - class ImagePopup; -} - -namespace ImageProcessingEditor -{ - class ImagePopup - : public QDialog - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(ImagePopup, AZ::SystemAllocator, 0); - explicit ImagePopup(QImage previewImage, QWidget* parent = nullptr); - ~ImagePopup(); - - private: - QScopedPointer m_ui; - QImage m_previewImage; - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.ui b/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.ui deleted file mode 100644 index 419812b686..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ImagePopup.ui +++ /dev/null @@ -1,43 +0,0 @@ - - - ImagePopup - - - Qt::WindowModal - - - - 0 - 0 - 400 - 300 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.cpp deleted file mode 100644 index e0e70e30be..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.cpp +++ /dev/null @@ -1,122 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "MipmapSettingWidget.h" -#include - -#include -#include -#include - -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - MipmapSettingWidget::MipmapSettingWidget(EditorTextureSetting& textureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::MipmapSettingWidget) - , m_textureSetting(&textureSetting) - { - m_ui->setupUi(this); - - - AZ::SerializeContext* serializeContext = nullptr; - EBUS_EVENT_RESULT(serializeContext, AZ::ComponentApplicationBus, GetSerializeContext); - AZ_Assert(serializeContext, "Serialization context not available"); - - m_ui->propertyEditor->SetAutoResizeLabels(true); - m_ui->propertyEditor->Setup(serializeContext, this, true, 250); - - m_ui->propertyEditor->ClearInstances(); - TextureSettings* instance = &m_textureSetting->GetMultiplatformTextureSetting(); - const AZ::Uuid& classId = AZ::SerializeTypeInfo::GetUuid(instance); - m_ui->propertyEditor->AddInstance(instance, classId); - m_ui->propertyEditor->InvalidateAll(); - m_ui->propertyEditor->ExpandAll(); - - RefreshUI(); - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - MipmapSettingWidget::~MipmapSettingWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void MipmapSettingWidget::RefreshUI() - { - TextureSettings& texSetting = m_textureSetting->GetMultiplatformTextureSetting(); - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(texSetting.m_preset); - if (preset == nullptr || preset->m_mipmapSetting == nullptr) - { - m_ui->enableCheckBox->setCheckState(Qt::CheckState::Unchecked); - m_ui->enableCheckBox->setEnabled(false); - m_ui->propertyEditor->hide(); - } - else - { - bool showMipMap = texSetting.m_enableMipmap; - m_ui->enableCheckBox->setEnabled(true); - m_ui->enableCheckBox->setCheckState(showMipMap ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - QObject::connect(m_ui->enableCheckBox, &QCheckBox::clicked, this, &MipmapSettingWidget::OnCheckBoxStateChanged); - if (showMipMap) - { - m_ui->propertyEditor->show(); - this->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); - } - else - { - m_ui->propertyEditor->hide(); - this->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum); - } - } - m_ui->propertyEditor->InvalidateValues(); - } - - void MipmapSettingWidget::OnCheckBoxStateChanged(bool checked) - { - bool finalChecked = m_textureSetting->RefreshMipSetting(checked); - - if (finalChecked) - { - m_ui->propertyEditor->show(); - } - else - { - m_ui->propertyEditor->hide(); - } - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, BuilderSettingManager::s_defaultPlatform); - } - - - void MipmapSettingWidget::AfterPropertyModified(AzToolsFramework::InstanceDataNode* /*pNode*/) - { - //Only the first texture setting reflected is changed, we need to propagate the change to every texture settings. - m_textureSetting->PropagateCommonSettings(); - m_ui->propertyEditor->InvalidateValues(); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, BuilderSettingManager::s_defaultPlatform); - } - - void MipmapSettingWidget::OnEditorSettingsChanged(bool needRefresh, const AZStd::string& /*platform*/) - { - if (needRefresh) - { - RefreshUI(); - } - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.h b/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.h deleted file mode 100644 index 813c09eb77..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#endif - -namespace Ui -{ - class MipmapSettingWidget; -} - -namespace ImageProcessingEditor -{ - class MipmapSettingWidget - : public QWidget - , public AzToolsFramework::IPropertyEditorNotify - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(MipmapSettingWidget, AZ::SystemAllocator, 0); - explicit MipmapSettingWidget(EditorTextureSetting& textureSetting, QWidget* parent = nullptr); - ~MipmapSettingWidget(); - - //IPropertyEditorNotify Interface - void BeforePropertyModified([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {} - void AfterPropertyModified(AzToolsFramework::InstanceDataNode* pNode) override; - void SetPropertyEditingActive([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {} - void SetPropertyEditingComplete([[maybe_unused]] AzToolsFramework::InstanceDataNode* pNode) override {} - void SealUndoStack() override {} - - public slots: - void OnCheckBoxStateChanged(bool checked); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - private: - void RefreshUI(); - QScopedPointer m_ui; - EditorTextureSetting* m_textureSetting; - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.ui deleted file mode 100644 index bdab04033c..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/MipmapSettingWidget.ui +++ /dev/null @@ -1,89 +0,0 @@ - - - MipmapSettingWidget - - - - 0 - 0 - 583 - 489 - - - - - 0 - 0 - - - - Form - - - - - - - - Mipmap Settings - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - Enable - - - - - - - - - - 0 - 0 - - - - - - - - Qt::Vertical - - - - 20 - 1 - - - - - - - - - AzToolsFramework::ReflectedPropertyEditor - QFrame -
AzToolsFramework/UI/PropertyEditor/ReflectedPropertyEditor.hxx
- 1 -
-
- - -
diff --git a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.cpp b/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.cpp deleted file mode 100644 index e3fc2500c2..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.cpp +++ /dev/null @@ -1,120 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "PresetInfoPopup.h" -#include -#include -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - // Help functions to convert enum to strings - static const char* RGBWeightToString(RGBWeight weight) - { - static const char* RGBWeightNames[] = { "uniform", "luminance", "ciexyz" }; - AZ_Assert(weight <= RGBWeight::ciexyz, "Invalid RGBWeight!"); - return RGBWeightNames[(int)weight]; - } - - static const char* ColorSpaceToString(ColorSpace colorSpace) - { - static const char* colorSpaceNames[] = { "linear", "sRGB", "auto" }; - AZ_Assert(colorSpace <= ColorSpace::autoSelect, "Invalid ColorSpace!"); - return colorSpaceNames[(int)colorSpace]; - } - - static const char* MipGenTypeToString(MipGenType mipGenType) - { - static const char* mipGenTypeNames[] = { "point", "average", "linear" , "bilinear" , "gaussian" , "blackmanHarris", "kaiserSinc" }; - AZ_Assert(mipGenType <= MipGenType::kaiserSinc, "Invalid MipGenType!"); - return mipGenTypeNames[(int)mipGenType]; - } - - static const char* CubemapFilterTypeToString(CubemapFilterType cubemapFilterType) - { - static const char* cubemapFilterTypeNames[] = { "disc", "cone", "cosine" , "gaussian" , "cosine power" , "ggx" }; - AZ_Assert(cubemapFilterType <= CubemapFilterType::ggx, "Invalid CubemapFilterType!"); - return cubemapFilterTypeNames[(int)cubemapFilterType]; - } - - PresetInfoPopup::PresetInfoPopup(const PresetSettings* presetSettings, QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent, Qt::Dialog | Qt::Popup) - , m_ui(new Ui::PresetInfoPopup) - { - m_ui->setupUi(this); - RefreshPresetInfoLabel(presetSettings); - } - - PresetInfoPopup::~PresetInfoPopup() - { - - } - void PresetInfoPopup::RefreshPresetInfoLabel(const PresetSettings* presetSettings) - { - - QString presetInfoText = ""; - if (!presetSettings) - { - presetInfoText = "Invalid Preset!"; - m_ui->infoLabel->setText(presetInfoText); - return; - } - - presetInfoText += QString("UUID: %1\n").arg(presetSettings->m_uuid.ToString().c_str()); - presetInfoText += QString("Name: %1\n").arg(presetSettings->m_name.c_str()); - presetInfoText += QString("RGB Weight: %1\n").arg(RGBWeightToString(presetSettings->m_rgbWeight)); - presetInfoText += QString("Source ColorSpace: %1\n").arg(ColorSpaceToString(presetSettings->m_srcColorSpace)); - presetInfoText += QString("Destination ColorSpace: %1\n").arg(ColorSpaceToString(presetSettings->m_destColorSpace)); - presetInfoText += QString("FileMasks: "); - int i = 0; - for (auto& mask : presetSettings->m_fileMasks) - { - presetInfoText += i > 0 ? ", " : ""; - presetInfoText += mask.c_str(); - i++; - } - presetInfoText += "\n"; - presetInfoText += QString("Suppress Engine Reduce: %1\n").arg(presetSettings->m_suppressEngineReduce ? "True" : "False"); - presetInfoText += QString("Discard Alpha: %1\n").arg(presetSettings->m_discardAlpha ? "True" : "False"); - presetInfoText += QString("Is Power Of 2: %1\n").arg(presetSettings->m_isPowerOf2 ? "True" : "False"); - presetInfoText += QString("Is Color Chart: %1\n").arg(presetSettings->m_isColorChart ? "True" : "False"); - presetInfoText += QString("High Pass Mip: %1\n").arg(presetSettings->m_highPassMip); - presetInfoText += QString("Gloss From Normal: %1\n").arg(presetSettings->m_glossFromNormals); - presetInfoText += QString("Use Legacy Gloss: %1\n").arg(presetSettings->m_isLegacyGloss ? "True" : "False"); - presetInfoText += QString("Mip Re-normalize: %1\n").arg(presetSettings->m_isMipRenormalize ? "True" : "False"); - presetInfoText += QString("Streamable Mips Number: %1\n").arg(presetSettings->m_numStreamableMips); - presetInfoText += QString("Swizzle: %1\n").arg(presetSettings->m_swizzle.c_str()); - if (presetSettings->m_cubemapSetting) - { - presetInfoText += QString("[Cubemap Settings]\n"); - presetInfoText += QString("Filter: %1\n").arg(CubemapFilterTypeToString(presetSettings->m_cubemapSetting->m_filter)); - presetInfoText += QString("Angle: %1\n").arg(presetSettings->m_cubemapSetting->m_angle); - presetInfoText += QString("Mip Angle: %1\n").arg(presetSettings->m_cubemapSetting->m_mipAngle); - presetInfoText += QString("Mip Slope: %1\n").arg(presetSettings->m_cubemapSetting->m_mipSlope); - presetInfoText += QString("Edge Fixup: %1\n").arg(presetSettings->m_cubemapSetting->m_edgeFixup); - presetInfoText += QString("Generate Diff: %1\n").arg(presetSettings->m_cubemapSetting->m_generateDiff ? "True" : "False"); - presetInfoText += QString("Diffuse Probe Preset: %1\n").arg(presetSettings->m_cubemapSetting->m_diffuseGenPreset.ToString().c_str()); - } - - if (presetSettings->m_mipmapSetting) - { - presetInfoText += QString("[MipMapSetting]\n"); - presetInfoText += QString("Type: %1\n").arg(MipGenTypeToString(presetSettings->m_mipmapSetting->m_type)); - } - - m_ui->infoLabel->setText(presetInfoText); - } -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.h b/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.h deleted file mode 100644 index 64fa666d25..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace ImageProcessing -{ - class PresetSettings; -} -namespace Ui -{ - class PresetInfoPopup; -} - -namespace ImageProcessingEditor -{ - class PresetInfoPopup - : public AzQtComponents::StyledDialog - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(PresetInfoPopup, AZ::SystemAllocator, 0); - explicit PresetInfoPopup(const ImageProcessing::PresetSettings* preset, QWidget* parent = nullptr); - ~PresetInfoPopup(); - void RefreshPresetInfoLabel(const ImageProcessing::PresetSettings* presetSettings); - private: - QScopedPointer m_ui; - - - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.ui b/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.ui deleted file mode 100644 index fd52b34c8e..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/PresetInfoPopup.ui +++ /dev/null @@ -1,83 +0,0 @@ - - - PresetInfoPopup - - - Qt::NonModal - - - - 0 - 0 - 300 - 400 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Preset Info - - - false - - - false - - - - - - 10 - - - 10 - - - 10 - - - 10 - - - 10 - - - - - - 0 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - - - - Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.cpp deleted file mode 100644 index 73340a45a7..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.cpp +++ /dev/null @@ -1,145 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "ResolutionSettingItemWidget.h" -#include -#include - -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - - ResolutionSettingItemWidget::ResolutionSettingItemWidget(ResoultionWidgetType type, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::ResolutionSettingItemWidget) - { - m_ui->setupUi(this); - m_type = type; - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - ResolutionSettingItemWidget::~ResolutionSettingItemWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void ResolutionSettingItemWidget::Init(AZStd::string platform, EditorTextureSetting* editorTextureSetting) - { - m_platform = platform; - m_editorTextureSetting = editorTextureSetting; - m_textureSetting = &m_editorTextureSetting->m_settingsMap[m_platform]; - m_preset = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->m_preset, platform); - SetupResolutionInfo(); - RefreshUI(); - if (m_type == ResoultionWidgetType::TexturePropety) - { - m_ui->formatLabel->show(); - m_ui->formatComboBox->hide(); - } - else - { - m_ui->formatLabel->hide(); - m_ui->formatComboBox->show(); - QObject::connect(m_ui->formatComboBox, static_cast(&QComboBox::currentIndexChanged), this, &ResolutionSettingItemWidget::OnChangeFormat); - } - QObject::connect(m_ui->downResSpinBox, static_cast(&QSpinBox::valueChanged), this, &ResolutionSettingItemWidget::OnChangeDownRes); - - } - - void ResolutionSettingItemWidget::RefreshUI() - { - m_ui->platformLabel->setText(EditorHelper::ToReadablePlatformString(m_platform).c_str()); - - m_ui->downResSpinBox->setRange(m_minReduce, m_maxReduce); - int clampedReduce = AZStd::min(AZStd::max(m_textureSetting->m_sizeReduceLevel, s_MinReduceLevel), s_MaxReduceLevel); - auto it = m_resolutionInfos.begin(); - it = AZStd::next(it, clampedReduce); - m_ui->downResSpinBox->setValue(it->reduce); - - QString finalResolution; - - if (it->arrayCount > 1) - { - finalResolution = QString("%1 x %2 x %3").arg(QString::number(it->width), QString::number(it->height), QString::number(it->arrayCount)); - } - else - { - finalResolution = QString("%1 x %2").arg(QString::number(it->width), QString::number(it->height)); - } - - m_ui->sizeLabel->setText(finalResolution); - - QString finalFormat = GetFinalFormat(m_textureSetting->m_preset); - if (m_type == ResoultionWidgetType::TexturePropety) - { - m_ui->formatLabel->setText(finalFormat); - } - else - { - SetupFormatComboBox(); - m_ui->formatComboBox->setCurrentText(finalFormat); - } - } - - void ResolutionSettingItemWidget::SetupResolutionInfo() - { - m_resolutionInfos = m_editorTextureSetting->GetResolutionInfo(m_platform, m_minReduce, m_maxReduce); - } - - void ResolutionSettingItemWidget::OnChangeDownRes(int downRes) - { - if ((unsigned int)downRes >= m_minReduce && (unsigned int)downRes <= m_maxReduce) - { - m_textureSetting->m_sizeReduceLevel = downRes; - RefreshUI(); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, m_platform); - } - } - - QString ResolutionSettingItemWidget::GetFinalFormat([[maybe_unused]] const AZ::Uuid& presetId) - { - if (m_preset && m_preset->m_pixelFormat >=0 && m_preset->m_pixelFormat < ePixelFormat_Count) - { - return EditorHelper::s_PixelFormatString[m_preset->m_pixelFormat]; - } - return QString(); - } - - - void ResolutionSettingItemWidget::SetupFormatComboBox() - { - m_ui->formatComboBox->clear(); - } - - void ResolutionSettingItemWidget::OnChangeFormat([[maybe_unused]] int index) - { - bool oldState = m_ui->formatComboBox->blockSignals(true); - m_ui->formatComboBox->blockSignals(oldState); - } - - void ResolutionSettingItemWidget::OnEditorSettingsChanged(bool needRefresh, const AZStd::string& /*platform*/) - { - if (needRefresh) - { - m_preset = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->m_preset, m_platform); - SetupResolutionInfo(); - RefreshUI(); - } - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.h b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.h deleted file mode 100644 index ef86ad716e..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.h +++ /dev/null @@ -1,81 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace ImageProcessing -{ - class PresetSettings; -} -namespace Ui -{ - class ResolutionSettingItemWidget; -} - -namespace ImageProcessingEditor -{ - enum class ResoultionWidgetType - { - TexturePipeline, //Fully editable - TexturePropety, //Only DownRes is editable - }; - - class ResolutionSettingItemWidget - : public QWidget - , EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - - AZ_CLASS_ALLOCATOR(ResolutionSettingItemWidget, AZ::SystemAllocator, 0); - explicit ResolutionSettingItemWidget(ResoultionWidgetType type, QWidget* parent = nullptr); - ~ResolutionSettingItemWidget(); - void Init(AZStd::string platform, EditorTextureSetting* editorTextureSetting); - - public slots: - - void OnChangeDownRes(int downRes); - void OnChangeFormat(int index); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - private: - - void SetupFormatComboBox(); - void SetupResolutionInfo(); - void RefreshUI(); - QString GetFinalFormat(const AZ::Uuid& presetId); - - QScopedPointer m_ui; - ResoultionWidgetType m_type; - AZStd::string m_platform; - ImageProcessing::TextureSettings* m_textureSetting; - EditorTextureSetting* m_editorTextureSetting; - const ImageProcessing::PresetSettings* m_preset; - //Cached list of calculated final resolution info based on different reduce levels - AZStd::list m_resolutionInfos; - //Final reduce level range - unsigned int m_maxReduce; - unsigned int m_minReduce; - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.ui deleted file mode 100644 index 5e5055e382..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingItemWidget.ui +++ /dev/null @@ -1,205 +0,0 @@ - - - ResolutionSettingItemWidget - - - - 0 - 0 - 400 - 20 - - - - - 0 - 0 - - - - - 400 - 0 - - - - - 400 - 20 - - - - Form - - - Qt::LeftToRight - - - - 0 - - - QLayout::SetDefaultConstraint - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - 0 - 0 - - - - - 60 - 0 - - - - - 60 - 16777215 - - - - - 60 - 0 - - - - Provo - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - - 50 - 0 - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - - 100 - 0 - - - - TextLabel - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - - 80 - 0 - - - - TextLabel - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.cpp deleted file mode 100644 index 4fe8bdbb0b..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.cpp +++ /dev/null @@ -1,58 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "ResolutionSettingWidget.h" -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - ResolutionSettingWidget::ResolutionSettingWidget(ResoultionWidgetType type, EditorTextureSetting& textureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::ResolutionSettingWidget) - , m_textureSetting(&textureSetting) - { - m_ui->setupUi(this); - m_type = type; - - //Put default platform in the first row - ResolutionSettingItemWidget* item = new ResolutionSettingItemWidget(ResoultionWidgetType::TexturePropety, this); - item->Init(BuilderSettingManager::s_defaultPlatform, m_textureSetting); - m_ui->listLayout->addWidget(item); - - //Add the other platforms in the list - for (auto& it : m_textureSetting->m_settingsMap) - { - AZStd::string platform = it.first; - if (platform != BuilderSettingManager::s_defaultPlatform) - { - ResolutionSettingItemWidget* item2 = new ResolutionSettingItemWidget(ResoultionWidgetType::TexturePropety, this); - item2->Init(platform, m_textureSetting); - m_ui->listLayout->addWidget(item2); - } - } - - // Tooltips - m_ui->downResLabel->setToolTip(QString("Adjust the resolution based on the target platform. \ - Use this setting to preserve the resolution of a source file even though it appears smaller in the game. \ - Select 0 to preserve the original size or 5 for the maximum reduction.")); - } - - ResolutionSettingWidget::~ResolutionSettingWidget() - { - - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.h b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.h deleted file mode 100644 index 1960130521..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.h +++ /dev/null @@ -1,44 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#endif - -namespace Ui -{ - class ResolutionSettingWidget; -} - -namespace ImageProcessingEditor -{ - class ResolutionSettingWidget - : public QWidget - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(ResolutionSettingWidget, AZ::SystemAllocator, 0); - explicit ResolutionSettingWidget(ResoultionWidgetType type, EditorTextureSetting& texureSetting, QWidget* parent = nullptr); - ~ResolutionSettingWidget(); - - private: - QScopedPointer m_ui; - ResoultionWidgetType m_type; - EditorTextureSetting* m_textureSetting; - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.ui deleted file mode 100644 index d8987a37eb..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/ResolutionSettingWidget.ui +++ /dev/null @@ -1,177 +0,0 @@ - - - ResolutionSettingWidget - - - - 0 - 0 - 550 - 300 - - - - - 0 - 0 - - - - - 0 - 0 - - - - Form - - - - - - 0 - - - - - 0 - - - QLayout::SetDefaultConstraint - - - - - - 0 - 0 - - - - - 60 - 0 - - - - - 60 - 16777215 - - - - - 60 - 0 - - - - Platform - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 50 - 0 - - - - DownRes - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 100 - 0 - - - - Size - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - 0 - 0 - - - - - 80 - 0 - - - - Format - - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.cpp deleted file mode 100644 index da78295c80..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.cpp +++ /dev/null @@ -1,199 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "TexturePresetSelectionWidget.h" -#include - -#include -#include -#include -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - TexturePresetSelectionWidget::TexturePresetSelectionWidget(EditorTextureSetting& textureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::TexturePresetSelectionWidget) - , m_textureSetting(&textureSetting) - { - m_ui->setupUi(this); - - // Add presets into combo box - m_presetList.clear(); - auto& presetFilterMap = BuilderSettingManager::Instance()->GetPresetFilterMap(); - - AZStd::set noFilterPresetList; - - // Check if there is any filtered preset list first - for(auto& presetFilter : presetFilterMap) - { - if (presetFilter.first.empty()) - { - noFilterPresetList = presetFilter.second; - } - else if (IsMatchingWithFileMask(m_textureSetting->m_textureName, presetFilter.first)) - { - for(const AZStd::string& presetName : presetFilter.second) - { - m_presetList.insert(presetName); - } - } - } - // If no filtered preset list available or should list all presets, use non-filter list - if (m_presetList.size() == 0 || m_listAllPresets) - { - m_presetList = noFilterPresetList; - } - - foreach (const AZStd::string& presetName, m_presetList) - { - m_ui->presetComboBox->addItem(QString(presetName.c_str())); - } - - // Set current preset - const AZ::Uuid& currPreset = m_textureSetting->GetMultiplatformTextureSetting().m_preset; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(currPreset); - - if (presetSetting) - { - m_ui->presetComboBox->setCurrentText(presetSetting->m_name.c_str()); - QObject::connect(m_ui->presetComboBox, static_cast(&QComboBox::currentIndexChanged), this, &TexturePresetSelectionWidget::OnChangePreset); - - // Suppress engine reduction checkbox - m_ui->serCheckBox->setCheckState(m_textureSetting->GetMultiplatformTextureSetting().m_suppressEngineReduce ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - - SetCheckBoxReadOnly(m_ui->serCheckBox, presetSetting->m_suppressEngineReduce); - QObject::connect(m_ui->serCheckBox, &QCheckBox::clicked, this, &TexturePresetSelectionWidget::OnCheckBoxStateChanged); - - // Set convention label - SetPresetConvention(presetSetting); - } - - // Reset btn - QObject::connect(m_ui->resetBtn, &QPushButton::clicked, this, &TexturePresetSelectionWidget::OnRestButton); - - // PresetInfo btn - QObject::connect(m_ui->infoBtn, &QPushButton::clicked, this, &TexturePresetSelectionWidget::OnPresetInfoButton); - - // Tooltips - m_ui->activeFileConventionLabel->setToolTip(QString("Displays the supported naming convention for the selected preset.")); - m_ui->presetComboBox->setToolTip(QString("Choose a preset to update the preview and other properties.")); - m_ui->resetBtn->setToolTip(QString("Reset values to current preset defaults.")); - m_ui->serCheckBox->setToolTip(QString("Preserves the original size. Use this setting for textures that include text.")); - m_ui->infoBtn->setToolTip(QString("Show detail properties of the current preset")); - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - TexturePresetSelectionWidget::~TexturePresetSelectionWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void TexturePresetSelectionWidget::OnCheckBoxStateChanged(bool checked) - { - for (auto& it : m_textureSetting->m_settingsMap) - { - it.second.m_suppressEngineReduce = checked; - } - m_textureSetting->SetIsOverrided(); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, false, BuilderSettingManager::s_defaultPlatform); - } - - void TexturePresetSelectionWidget::OnRestButton() - { - m_textureSetting->SetToPreset(AZStd::string(m_ui->presetComboBox->currentText().toUtf8().data())); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, true, BuilderSettingManager::s_defaultPlatform); - } - - void TexturePresetSelectionWidget::OnChangePreset(int index) - { - QString text = m_ui->presetComboBox->itemText(index); - m_textureSetting->SetToPreset(AZStd::string(text.toUtf8().data())); - EditorInternalNotificationBus::Broadcast(&EditorInternalNotificationBus::Events::OnEditorSettingsChanged, true, BuilderSettingManager::s_defaultPlatform); - } - - void ImageProcessingEditor::TexturePresetSelectionWidget::OnPresetInfoButton() - { - const AZ::Uuid& currPreset = m_textureSetting->GetMultiplatformTextureSetting().m_preset; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(currPreset); - m_presetPopup.reset(new PresetInfoPopup(presetSetting, this)); - m_presetPopup->installEventFilter(this); - m_presetPopup->show(); - } - - void TexturePresetSelectionWidget::OnEditorSettingsChanged(bool needRefresh, const AZStd::string& /*platform*/) - { - if (needRefresh) - { - bool oldState = m_ui->serCheckBox->blockSignals(true); - m_ui->serCheckBox->setChecked(m_textureSetting->GetMultiplatformTextureSetting().m_suppressEngineReduce); - // If the preset's SER is true, texture setting should not override - const AZ::Uuid& currPreset = m_textureSetting->GetMultiplatformTextureSetting().m_preset; - const PresetSettings* presetSetting = BuilderSettingManager::Instance()->GetPreset(currPreset); - if (presetSetting) - { - SetCheckBoxReadOnly(m_ui->serCheckBox, presetSetting->m_suppressEngineReduce); - SetPresetConvention(presetSetting); - // If there is preset info dialog open, update the text - if (m_presetPopup && m_presetPopup->isVisible()) - { - m_presetPopup->RefreshPresetInfoLabel(presetSetting); - } - } - m_ui->serCheckBox->blockSignals(oldState); - } - } - - bool TexturePresetSelectionWidget::IsMatchingWithFileMask(const AZStd::string& filename, const AZStd::string& fileMask) - { - if (fileMask.empty()) - { - // Will not match with empty string - return false; - } - else - { - // Extract the file name and compare if it ends with file mask or not - AZStd::string filenameNoExt; - AzFramework::StringFunc::Path::GetFileName(filename.c_str(), filenameNoExt); - return filenameNoExt.length() >= fileMask.length() && filenameNoExt.compare(filenameNoExt.length() - fileMask.length(), fileMask.length(), fileMask) == 0; - } - } - - void ImageProcessingEditor::TexturePresetSelectionWidget::SetPresetConvention(const PresetSettings* presetSettings) - { - AZStd::string conventionText = ""; - if (presetSettings) - { - int i = 0; - for (const PlatformName& filemask : presetSettings->m_fileMasks) - { - conventionText += i > 0 ? " " + filemask : filemask; - i++; - } - } - m_ui->conventionLabel->setText(QString(conventionText.c_str())); - } - - void ImageProcessingEditor::TexturePresetSelectionWidget::SetCheckBoxReadOnly(QCheckBox* checkBox, bool readOnly) - { - checkBox->setAttribute(Qt::WA_TransparentForMouseEvents, readOnly); - checkBox->setFocusPolicy(readOnly ? Qt::NoFocus : Qt::StrongFocus); - checkBox->setEnabled(!readOnly); - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.h b/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.h deleted file mode 100644 index c490fdbf1f..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.h +++ /dev/null @@ -1,65 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#include -#endif - -class QCheckBox; -namespace Ui -{ - class TexturePresetSelectionWidget; -} - -namespace ImageProcessingEditor -{ - class TexturePresetSelectionWidget - : public QWidget - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(TexturePresetSelectionWidget, AZ::SystemAllocator, 0); - explicit TexturePresetSelectionWidget(EditorTextureSetting& texureSetting, QWidget* parent = nullptr); - ~TexturePresetSelectionWidget(); - - public slots: - void OnCheckBoxStateChanged(bool checked); - void OnRestButton(); - void OnChangePreset(int index); - void OnPresetInfoButton(); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - private: - QScopedPointer m_ui; - AZStd::set m_presetList; - EditorTextureSetting* m_textureSetting; - QScopedPointer m_presetPopup; - bool IsMatchingWithFileMask(const AZStd::string& filename, const AZStd::string& fileMask); - void SetPresetConvention(const ImageProcessing::PresetSettings* presetSettings); - void SetCheckBoxReadOnly(QCheckBox* checkBox, bool readOnly); - - bool m_listAllPresets = true; - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.ui deleted file mode 100644 index 73a7741dde..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePresetSelectionWidget.ui +++ /dev/null @@ -1,91 +0,0 @@ - - - TexturePresetSelectionWidget - - - - 0 - 0 - 624 - 118 - - - - Form - - - - - - - - - - - - - Active file conventions - - - - - - - Texture presets - - - - - - - - - - Active preset - - - - - - - - - - - :/Reset.png - - - - - - - - Suppress spec reduction - - - - - - - - - - - :/info.png - - - - - 16 - 16 - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.cpp b/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.cpp deleted file mode 100644 index 8a1cd3b650..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.cpp +++ /dev/null @@ -1,639 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "TexturePreviewWidget.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace ImageProcessingEditor -{ - using namespace ImageProcessing; - - TexturePreviewWidget::TexturePreviewWidget(EditorTextureSetting& texureSetting, QWidget* parent /*= nullptr*/) - : QWidget(parent) - , m_ui(new Ui::TexturePreviewWidget) - , m_textureSetting(&texureSetting) - { - m_ui->setupUi(this); - - m_platform = BuilderSettingManager::s_defaultPlatform; - // For now, only provide preview for default platform - m_previewConverter = AZStd::make_unique(m_textureSetting->m_fullPath, &m_textureSetting->GetMultiplatformTextureSetting()); - - m_updateTimer = new QTimer(this); - connect(m_updateTimer, &QTimer::timeout, this, &TexturePreviewWidget::UpdatePreview); - m_updateTimer->setSingleShot(false); - - m_ui->infoLayer->setAttribute(Qt::WA_NoSystemBackground); - m_ui->mipLevelLabel->setAttribute(Qt::WA_NoSystemBackground); - m_ui->imageSizeLabel->setAttribute(Qt::WA_NoSystemBackground); - m_ui->fileSizeLabel->setAttribute(Qt::WA_NoSystemBackground); - - // Setup preview mode combo box - static const QString previewModeString[] = { "RGB", - "R", - "G", - "B", - "Alpha", - "RGBA" }; - - for (int i = 0; i < (int)PreviewMode::Count; i ++) - { - m_ui->previewComboBox->addItem(previewModeString[i]); - } - - QSize size = m_ui->imageLabel->size(); - m_imageLabelSize = aznumeric_cast(size.width()); - - SetUpResolutionInfo(); - RefreshUI(true); - - QObject::connect(m_ui->previewCheckBox, &QCheckBox::clicked, this, &TexturePreviewWidget::OnTiledChanged); - QObject::connect(m_ui->nextMipBtn, &QPushButton::clicked, this, &TexturePreviewWidget::OnNextMip); - QObject::connect(m_ui->prevMipBtn, &QPushButton::clicked, this, &TexturePreviewWidget::OnPrevMip); - QObject::connect(m_ui->previewComboBox, static_cast(&QComboBox::currentIndexChanged), this, &TexturePreviewWidget::OnChangePreviewMode); - - // Set up Refresh button - m_alwaysRefreshAction = new QAction("Always refresh preview", this); - m_alwaysRefreshAction->setCheckable(true); - m_alwaysRefreshAction->setChecked(m_alwaysRefreshPreview); - QObject::connect(m_alwaysRefreshAction, &QAction::triggered, this, &TexturePreviewWidget::OnAlwaysRefresh); - - m_refreshPerClickAction = new QAction("Press to refresh preview", this); - m_refreshPerClickAction->setCheckable(true); - m_refreshPerClickAction->setChecked(!m_alwaysRefreshPreview); - QObject::connect(m_refreshPerClickAction, &QAction::triggered, this, &TexturePreviewWidget::OnRefreshPerClick); - - QMenu* menu = new QMenu(this); - menu->addAction(m_alwaysRefreshAction); - menu->addAction(m_refreshPerClickAction); - - m_ui->refreshBtn->setMenu(menu); - AzQtComponents::PushButton::applySmallIconStyle(m_ui->refreshBtn); - - QObject::connect(m_ui->refreshBtn, &QPushButton::clicked, this, &TexturePreviewWidget::OnRefreshClicked); - m_alwaysRefreshIcon.addFile(QStringLiteral(":/refresh.png"), QSize(), QIcon::Normal, QIcon::On); - m_refreshPerClickIcon.addFile(QStringLiteral(":/refresh-active.png"), QSize(), QIcon::Normal, QIcon::On); - m_ui->refreshBtn->setIcon(m_alwaysRefreshIcon); - - m_ui->busyLabel->SetBusyIconSize(16); - SetImageLabelText(QString(), false); - - // Tooltips - m_ui->previewComboBox->setToolTip(QString("Preview the texture in different channels.")); - m_ui->previewCheckBox->setToolTip(QString("Show or hide a 2x2 tiling of the texture.")); - m_ui->hotkeyLabel->setToolTip(QString("Preview different texture states with keyboard shortcuts.")); - m_ui->refreshBtn->setToolTip(QString("Provide different ways to refresh the preview. Click on the button to refresh manually.")); - - EditorInternalNotificationBus::Handler::BusConnect(); - } - - TexturePreviewWidget::~TexturePreviewWidget() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - void TexturePreviewWidget::resizeEvent(QResizeEvent *event) - { - QWidget::resizeEvent(event); - - QSize size = m_ui->mainWidget->size(); - m_ui->infoLayer->resize(size); - - QSize imageSize = m_ui->imageLabel->size(); - QPoint center = m_ui->mainWidget->rect().center(); - m_ui->imageLabel->move(center - QPoint(imageSize.width() / 2, imageSize.height() / 2)); - QSize busyLabelSize = m_ui->busyLabel->size(); - m_ui->busyLabel->move(center - QPoint(busyLabelSize.width() + m_ui->imageLabel->sizeHint().width() / 2, busyLabelSize.width() / 2)); - } - - void TexturePreviewWidget::SetUpResolutionInfo() - { - m_resolutionInfos = m_textureSetting->GetResolutionInfoForMipmap(m_platform); - m_mipCount = (unsigned int)m_resolutionInfos.size(); - if (m_currentMipIndex > (int)m_mipCount) - { - m_currentMipIndex = 0; - } - } - - void TexturePreviewWidget::OnEditorSettingsChanged([[maybe_unused]] bool needRefresh, const AZStd::string& platform) - { - // Only update the preview if there is any change in current platform - if (platform == m_platform) - { - SetUpResolutionInfo(); - RefreshUI(true); - } - } - - void TexturePreviewWidget::RefreshUI(bool fullRefresh) - { - m_ui->mipLevelLabel->setText(QString("Mip %1").arg(QString::number(m_currentMipIndex))); - m_ui->previewCheckBox->setCheckState(m_previewTiled ? Qt::CheckState::Checked : Qt::CheckState::Unchecked); - - bool hasNextMip = m_currentMipIndex < (int)m_mipCount - 1; - m_ui->nextMipBtn->setVisible(hasNextMip); - - bool hasPrevMip = m_currentMipIndex > 0; - m_ui->prevMipBtn->setVisible(hasPrevMip); - - RefreshWarning(); - - if (m_currentMipIndex < m_resolutionInfos.size()) - { - auto it = AZStd::next(m_resolutionInfos.begin(), m_currentMipIndex); - QString finalResolution; - if (it->arrayCount > 1) - { - finalResolution = QString("Image Size: %1 x %2 x %3").arg(QString::number(it->width), QString::number(it->height), QString::number(it->arrayCount)); - } - else - { - finalResolution = QString("Image Size: %1 x %2").arg(QString::number(it->width), QString::number(it->height)); - } - m_ui->imageSizeLabel->setText(finalResolution); - - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->GetMultiplatformTextureSetting().m_preset); - if (preset) - { - uint32 size = pixelFormats.EvaluateImageDataSize(preset->m_pixelFormat, it->width, it->height) * it->arrayCount; - AZStd::string fileSizeString = EditorHelper::GetFileSizeString(size); - QString finalFileSize = QString("File Size: %1").arg(fileSizeString.c_str()); - m_ui->fileSizeLabel->setText(finalFileSize); - } - - if (m_alwaysRefreshPreview) - { - RefreshPreviewImage(fullRefresh ? RefreshMode::Convert : RefreshMode::Mip); - } - - } - else - { - AZ_Error("Texture Setting", false, "Cannot find mip reduce level for mip %d", m_currentMipIndex); - } - } - - void TexturePreviewWidget::OnNextMip() - { - if (m_currentMipIndex >= (int)m_mipCount - 1) - { - return; - } - m_currentMipIndex ++; - RefreshUI(false); - } - - - void TexturePreviewWidget::OnPrevMip() - { - if (m_currentMipIndex <= 0) - { - return; - } - - m_currentMipIndex--; - RefreshUI(false); - } - - void TexturePreviewWidget::UpdatePreview() - { - if (!m_previewConverter->IsDone()) - { - float progress = m_previewConverter->GetProgress(); - SetImageLabelText(QString("Converting for preview...Progress %1%").arg(QString::number(progress * 100, 'f', 2))); - return; - } - - m_updateTimer->stop(); - m_previewImageRaw = m_previewConverter->GetOutputImage(); - - GenerateMipmap(m_currentMipIndex); - GenerateChannelImage(m_previewMode); - PaintPreviewImage(); - } - - void TexturePreviewWidget::OnAlwaysRefresh() - { - m_alwaysRefreshPreview = true; - m_alwaysRefreshAction->setChecked(true); - m_refreshPerClickAction->setChecked(false); - - m_ui->refreshBtn->setIcon(m_alwaysRefreshIcon); - } - - void TexturePreviewWidget::OnRefreshPerClick() - { - m_alwaysRefreshPreview = false; - m_alwaysRefreshAction->setChecked(false); - m_refreshPerClickAction->setChecked(true); - - m_ui->refreshBtn->setIcon(m_refreshPerClickIcon); - } - - void TexturePreviewWidget::OnRefreshClicked() - { - RefreshPreviewImage(RefreshMode::Convert); - } - - void TexturePreviewWidget::GenerateMipmap(int mip) - { - // Clear all cached preview images - for (int i = 0; i < (int)PreviewMode::Count; i++) - { - m_previewImages[i] = QImage(); - } - - if (m_previewImageRaw && (AZ::u32)mip < m_previewImageRaw->GetMipCount() ) - { - uint8* imageBuf; - uint32 pitch; - m_previewImageRaw->GetImagePointer(mip, imageBuf, pitch); - const uint32 width = m_previewImageRaw->GetWidth(mip); - const uint32 height = m_previewImageRaw->GetHeight(mip); - m_previewImages[PreviewMode::RGBA] = QImage(imageBuf, width, height, pitch, QImage::Format_RGBA8888); - } - else - { - AZ_Error("Texture Editor", false, "Cannot generate mip preview from an invalid image."); - } - - } - - void TexturePreviewWidget::GenerateChannelImage(PreviewMode channel) - { - // If there is no preview image generated, ignore this function - if (m_previewImages[PreviewMode::RGBA].isNull()) - { - AZ_Error("Texture Editor", false, "Cannot generate channel image from an invalid image."); - return; - } - - if (m_previewImages[channel].isNull()) - { - // Copy the RGBA image before changing the color - QImage previewImg = m_previewImages[PreviewMode::RGBA].copy(); - for (int x = 0; x < previewImg.width(); x++) - { - for (int y = 0; y < previewImg.height(); y++) - { - QRgb pixel = previewImg.pixel(x, y); - int r = qRed(pixel); - int g = qGreen(pixel); - int b = qBlue(pixel); - int a = qAlpha(pixel); - - switch (channel) - { - case ImageProcessingEditor::RGB: - pixel = qRgba(r, g, b, 255); - break; - case ImageProcessingEditor::RRR: - pixel = qRgba(r, r, r, 255); - break; - case ImageProcessingEditor::GGG: - pixel = qRgba(g, g, g, 255); - break; - case ImageProcessingEditor::BBB: - pixel = qRgba(b, b, b, 255); - break; - case ImageProcessingEditor::Alpha: - pixel = qRgba(a, a, a, 255); - break; - default: - break; - } - - previewImg.setPixel(x, y, pixel); - } - } - // Cache the image in current preview mode - m_previewImages[channel] = previewImg; - } - } - - void TexturePreviewWidget::RefreshPreviewImage(RefreshMode mode) - { - // Ignore any none-conversion refresh request when the image is being converted - if (m_updateTimer->isActive() && mode != RefreshMode::Convert) - { - return; - } - - switch (mode) - { - case RefreshMode::Convert: - { - // Start conversion in a AZ::Job - m_previewConverter->StartConvert(); - // Start the timer to trigger the update function - m_updateTimer->start(s_updateInterval); - SetImageLabelText(QString("Converting for preview...Progress 0.01%")); - } - break; - case RefreshMode::Mip: - { - GenerateMipmap(m_currentMipIndex); - GenerateChannelImage(m_previewMode); - PaintPreviewImage(); - } - break; - case RefreshMode::Channel: - { - GenerateChannelImage(m_previewMode); - PaintPreviewImage(); - } - break; - default: - PaintPreviewImage(); - break; - } - } - - void TexturePreviewWidget::PaintPreviewImage() - { - if (m_previewImages[m_previewMode].isNull()) - { - SetImageLabelText(QString("Conversion failed, please check console for more information."), false); - return; - } - SetImageLabelText(QString(), false); - - // Paint the image on to the image label - QPixmap pixMap = QPixmap::fromImage(m_previewImages[m_previewMode]); - QSize size = m_ui->imageLabel->size(); - QPixmap finalPix = pixMap.copy(); - finalPix.fill(Qt::transparent); - finalPix = finalPix.scaled(size, Qt::KeepAspectRatio, Qt::SmoothTransformation); - QPainter painter(&finalPix); - painter.setCompositionMode(QPainter::CompositionMode_DestinationOver); - QRect rect = finalPix.rect(); - if (m_previewTiled) - { - pixMap = pixMap.scaled(size / 2, Qt::KeepAspectRatio, Qt::SmoothTransformation); - painter.drawTiledPixmap(rect, pixMap); - } - else - { - painter.drawPixmap(rect, pixMap); - } - // Recenter the image label - float aspectRatio = static_cast(finalPix.width()) / static_cast(finalPix.height()); - QSize preferredSize; - if (aspectRatio >= 1.0f) - { - preferredSize = QSize(aznumeric_cast(m_imageLabelSize), aznumeric_cast(m_imageLabelSize / aspectRatio)); - } - else - { - preferredSize = QSize(aznumeric_cast(m_imageLabelSize * aspectRatio), aznumeric_cast(m_imageLabelSize)); - } - - m_ui->imageLabel->resize(preferredSize); - m_ui->imageLabel->setPixmap(finalPix); - - QPoint center = m_ui->mainWidget->rect().center(); - m_ui->imageLabel->move(center - QPoint(preferredSize.width() / 2, preferredSize.height() / 2)); - - } - - void TexturePreviewWidget::SetImageLabelText(const QString& text, bool busyStatus /*= true*/) - { - // Since setting pixmap will change the label size - // Need to set back to initial size and recenter before displaying text - m_ui->imageLabel->resize(QSize(aznumeric_cast(m_imageLabelSize), aznumeric_cast(m_imageLabelSize))); - QPoint center = m_ui->mainWidget->rect().center(); - m_ui->imageLabel->move(center - QPoint(aznumeric_cast(m_imageLabelSize / 2), aznumeric_cast(m_imageLabelSize / 2))); - m_ui->imageLabel->setText(text); - - // Set busy label status and position to align with the text - m_ui->busyLabel->SetIsBusy(busyStatus); - QSize size = m_ui->busyLabel->size(); - m_ui->busyLabel->move(center - QPoint(size.width() + m_ui->imageLabel->sizeHint().width() / 2, size.width() / 2)); - m_ui->busyLabel->setVisible(busyStatus); - } - - void TexturePreviewWidget::RefreshWarning() - { - int imageWidth = m_textureSetting->m_img->GetWidth(0); - int imageHeight = m_textureSetting->m_img->GetHeight(0); - AZStd::list stretchedPlatform; - - for (auto& iter: m_textureSetting->m_settingsMap) - { - PlatformName platform = iter.first; - const PresetSettings* presetSettings = BuilderSettingManager::Instance()->GetPreset(iter.second.m_preset, platform); - if (presetSettings) - { - EPixelFormat dstFmt = presetSettings->m_pixelFormat; - if (!CPixelFormats::GetInstance().IsImageSizeValid(dstFmt, imageWidth, imageHeight, false)) - { - stretchedPlatform.push_back(EditorHelper::ToReadablePlatformString(platform).c_str()); - } - } - } - - if (stretchedPlatform.size() > 0) - { - QString warningText = QString("The output image will be stretched on Platform:"); - int i = 0; - for (AZStd::string platform: stretchedPlatform) - { - warningText += i > 0 ? ", " : " "; - warningText += platform.c_str(); - i ++; - } - m_ui->warningLabel->setText(warningText); - m_ui->warningLabel->setVisible(true); - m_ui->warningIcon->setVisible(true); - } - else - { - m_ui->warningLabel->setVisible(false); - m_ui->warningIcon->setVisible(false); - } - } - - void TexturePreviewWidget::OnChangePreviewMode(int index) - { - if (index < (int)PreviewMode::Count) - { - m_previewMode = (PreviewMode)index; - - RefreshPreviewImage(RefreshMode::Channel); - } - } - - void TexturePreviewWidget::OnTiledChanged(bool checked) - { - m_previewTiled = checked; - RefreshPreviewImage(RefreshMode::Repaint); - } - - bool TexturePreviewWidget::OnQtEvent(QEvent * event) - { - if (event->type() == QEvent::KeyPress) - { - const QKeyEvent* ke = static_cast(event); - if (ke->isAutoRepeat()) - { - return false; //ignore repeat key event - } - - if (ke->key() == Qt::Key_Space) - { - if (!m_updateTimer->isActive()) // Only popup when image is not converting - { - m_previewPopup.reset(new ImagePopup(m_previewImages[m_previewMode], this)); - m_previewPopup->installEventFilter(this); - m_previewPopup->show(); - event->accept(); - return true; - } - } - else if (ke->key() == Qt::Key_Alt) - { - m_previewMode = PreviewMode::Alpha; - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - else if (ke->key() == Qt::Key_Shift) - { - m_previewMode = PreviewMode::RGBA; - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - } - else if (event->type() == QEvent::KeyRelease) - { - const QKeyEvent* ke = static_cast(event); - if (ke->isAutoRepeat()) - { - return false; //ignore repeat key event - } - if (ke->key() == Qt::Key_Space) - { - if (m_previewPopup) - { - m_previewPopup->hide(); - } - event->accept(); - return true; - } - else if (ke->key() == Qt::Key_Alt) - { - m_previewMode = (PreviewMode)m_ui->previewComboBox->currentIndex(); - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - else if (ke->key() == Qt::Key_Shift) - { - m_previewMode = (PreviewMode)m_ui->previewComboBox->currentIndex(); - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - } - else if (event->type() == QEvent::ApplicationStateChange) - { - const QApplicationStateChangeEvent* appEvent = static_cast(event); - AZ_Warning("Texture Editor", false, "app status change %d", appEvent->applicationState()); - if (appEvent->applicationState() != Qt::ApplicationState::ApplicationActive) - { - PreviewMode currPreviewMode = (PreviewMode)m_ui->previewComboBox->currentIndex(); - if (m_previewMode != currPreviewMode) - { - m_previewMode = currPreviewMode; - RefreshPreviewImage(RefreshMode::Channel); - event->accept(); - return true; - } - } - } - else if (event->type() == QEvent::ShortcutOverride) - { - // since we respond to the following things, let Qt know so that shortcuts don't override us - - QKeyEvent* kev = static_cast(event); - int key = kev->key() | kev->modifiers(); - switch (key) - { - case Qt::Key_Space: - case Qt::Key_Alt: - case Qt::Key_Shift: - event->accept(); - return true; - break; - - default: - break; - } - } - return false; - } - - bool TexturePreviewWidget::eventFilter(QObject* obj, QEvent* event) - { - if (event->type() == QEvent::KeyRelease) - { - const QKeyEvent* ke = static_cast(event); - if (ke->key() == Qt::Key_Space && !ke->isAutoRepeat()) - { - if (m_previewPopup) - { - m_previewPopup->hide(); - } - return true; - } - } - else if (event->type() == QEvent::ApplicationStateChange) - { - const QApplicationStateChangeEvent* appEvent = static_cast(event); - if (appEvent->applicationState() != Qt::ApplicationState::ApplicationActive) - { - if (m_previewPopup) - { - m_previewPopup->hide(); - } - } - return true; - } - - return QWidget::eventFilter(obj, event); - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.h b/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.h deleted file mode 100644 index 84ef09d366..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.h +++ /dev/null @@ -1,121 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include -#include -#include - -#include -#endif - -namespace Ui -{ - class TexturePreviewWidget; -} - -namespace ImageProcessingEditor -{ - enum PreviewMode - { - RGB = 0, - RRR, - GGG, - BBB, - Alpha, - RGBA, - Count - }; - - enum class RefreshMode - { - Convert, // Convert the whole image from beginning, takes longest time - Mip, // Generate a new mip from from converted image - Channel, // Generate a new channel image from converted image - Repaint, - }; - - class TexturePreviewWidget - : public QWidget - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - AZ_CLASS_ALLOCATOR(TexturePreviewWidget, AZ::SystemAllocator, 0); - explicit TexturePreviewWidget(EditorTextureSetting& texureSetting, QWidget* parent = 0); - ~TexturePreviewWidget(); - bool OnQtEvent(QEvent* event); - - public slots: - void OnTiledChanged(bool checked); - void OnPrevMip(); - void OnNextMip(); - void OnChangePreviewMode(int index); - void UpdatePreview(); - void OnAlwaysRefresh(); - void OnRefreshPerClick(); - void OnRefreshClicked(); - - protected: - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - void resizeEvent(QResizeEvent *event) override; - bool eventFilter(QObject* obj, QEvent* event) override; - - private: - void SetUpResolutionInfo(); - void RefreshUI(bool fullRefresh = false); - void RefreshPreviewImage(RefreshMode mode); - void GenerateMipmap(int mip); - void GenerateChannelImage(PreviewMode channel); - void PaintPreviewImage(); - void SetImageLabelText(const QString& text, bool busyStatus = true); - void RefreshWarning(); - - AZStd::list m_resolutionInfos; - QScopedPointer m_ui; - EditorTextureSetting* m_textureSetting; - int m_currentMipIndex = 0; - bool m_previewTiled = false; - float m_imageLabelSize = 0; - AZStd::string m_platform; - unsigned int m_mipCount = 1; - - /////////////////////////////////////////// - // Preview window - PreviewMode m_previewMode = PreviewMode::RGB; - QScopedPointer m_previewPopup; - AZStd::unique_ptr m_previewConverter; - ImageProcessing::IImageObjectPtr m_previewImageRaw; - QImage m_previewImages[PreviewMode::Count]; - QTimer* m_updateTimer; - static const int s_updateInterval = 200; - //////////////////////////////////////////// - - //////////////////////////////////////////// - // Refresh button - bool m_alwaysRefreshPreview = true; - QAction* m_alwaysRefreshAction = nullptr; - QAction* m_refreshPerClickAction = nullptr; - QIcon m_refreshPerClickIcon; - QIcon m_alwaysRefreshIcon; - //////////////////////////////////////////// - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.ui b/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.ui deleted file mode 100644 index 5f42fc8fd9..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePreviewWidget.ui +++ /dev/null @@ -1,371 +0,0 @@ - - - TexturePreviewWidget - - - - 0 - 0 - 672 - 579 - - - - Form - - - - - - - - - - - Preview tiled - - - - - - - - 0 - 0 - - - - Shift: RGBA | Alt:Alpha | Space: Full-size - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 0 - 500 - - - - - - 0 - 0 - 171 - 185 - - - - - 0 - 0 - - - - Qt::RightToLeft - - - - - - - - - - - - - - - - 0 - 0 - - - - - 16 - 16 - - - - - 26 - 25 - - - - - - - :/warning.png - - - - - - - - - Qt::Vertical - - - - 115 - 32 - - - - - - - - - - - - - - :/Forward.png - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - ... - - - - :/Backward.png - - - - - - - - - - Qt::Vertical - - - - 115 - 32 - - - - - - - - - - - - Mip 1 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - Image size: 2048 x 2048 - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - File Size: 4,096 KB - - - Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter - - - - - - - - - - 0 - 0 - - - - - 16777215 - 16777215 - - - - - 0 - 0 - - - - Qt::LeftToRight - - - true - - - - - - - - - - 24 - 24 - - - - false - - - false - - - QToolButton::MenuButtonPopup - - - Qt::ToolButtonIconOnly - - - false - - - - - - - - - - - 0 - 0 - 400 - 400 - - - - - 0 - 0 - - - - - 0 - 0 - - - - - 2048 - 2048 - - - - image - - - true - - - Qt::AlignCenter - - - - - - 510 - 80 - 30 - 30 - - - - - 0 - 0 - - - - - 10 - 10 - - - - - 0 - 0 - - - - - 24 - 24 - - - - imageLabel - infoLayer - busyLabel - - - - - - - AzQtComponents::StyledBusyLabel - QWidget -
AzQtComponents/Components/StyledBusyLabel.h
- 1 -
-
- - - - -
diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.cpp b/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.cpp deleted file mode 100644 index 90044a18c0..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include -#include "TexturePropertyEditor.h" -#include - -#include -#include -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -namespace ImageProcessingEditor -{ - TexturePropertyEditor::TexturePropertyEditor(const AZ::Uuid& sourceTextureId, QWidget* parent /*= nullptr*/) - : AzQtComponents::StyledDialog(parent, Qt::Dialog | Qt::CustomizeWindowHint | Qt::WindowCloseButtonHint | Qt::WindowTitleHint) - , m_ui(new Ui::TexturePropertyEditor) - , m_textureSetting(sourceTextureId) - , m_validImage(true) - { - if (m_textureSetting.m_img == nullptr) - { - m_validImage = false; - return; - } - - m_ui->setupUi(this); - - //Initialize all the format string here - EditorHelper::InitPixelFormatString(); - - //TexturePreviewWidget will be the widget to preview mipmaps - m_previewWidget.reset(aznew TexturePreviewWidget(m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_previewWidget.data()); - - //TexturePresetSelectionWidget will be the widget to select the preset for the texture - m_presetSelectionWidget.reset(aznew TexturePresetSelectionWidget(m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_presetSelectionWidget.data()); - - //ResolutionSettingWidget will be the table section to display mipmap resolution for each platform - m_resolutionSettingWidget.reset(aznew ResolutionSettingWidget(ResoultionWidgetType::TexturePropety, m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_resolutionSettingWidget.data()); - - //MipmapSettingWidget will be simple ReflectedProperty editor to reflect mipmap settings section - m_mipmapSettingWidget.reset(aznew MipmapSettingWidget(m_textureSetting, this)); - m_ui->mainLayout->layout()->addWidget(m_mipmapSettingWidget.data()); - - // Disable horizontal scroll - m_ui->scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - - QObject::connect(m_ui->saveBtn, &QPushButton::clicked, this, &TexturePropertyEditor::OnSave); - QObject::connect(m_ui->helpBtn, &QPushButton::clicked, this, &TexturePropertyEditor::OnHelp); - QObject::connect(m_ui->cancelBtn, &QPushButton::clicked, this, &QDialog::reject); - - EditorInternalNotificationBus::Handler::BusConnect(); - - // When checkbox and combobox is focused, they will intercept the space shortcut, need to disable focus on them first - // to get space shortcut pass through - QList checkBoxWidgets = QObject::findChildren(); - for (QCheckBox* widget: checkBoxWidgets) - { - widget->setFocusPolicy(Qt::NoFocus); - } - QList comboBoxWidgets = QObject::findChildren(); - for (QComboBox* widget : comboBoxWidgets) - { - widget->setFocusPolicy(Qt::NoFocus); - } - this->setFocusPolicy(Qt::StrongFocus); - - } - - TexturePropertyEditor::~TexturePropertyEditor() - { - EditorInternalNotificationBus::Handler::BusDisconnect(); - } - - bool TexturePropertyEditor::HasValidImage() - { - return m_validImage; - } - - void TexturePropertyEditor::OnEditorSettingsChanged([[maybe_unused]] bool needRefresh, const AZStd::string& /*platform*/) - { - m_textureSetting.m_modified = true; - } - - void TexturePropertyEditor::OnSave() - { - if (!m_validImage) - { - return; - } - - bool sourceControlActive = false; - AzToolsFramework::SourceControlConnectionRequestBus::BroadcastResult(sourceControlActive, &AzToolsFramework::SourceControlConnectionRequests::IsActive); - AZStd::string outputPath = m_textureSetting.m_fullPath + ImageProcessing::TextureSettings::modernExtensionName; - - if (sourceControlActive) - { - using ApplicationBus = AzToolsFramework::ToolsApplicationRequestBus; - bool checkoutResult = false; - ApplicationBus::BroadcastResult(checkoutResult, &ApplicationBus::Events::RequestEditForFileBlocking, outputPath.c_str(), "Checking out .imagesetting file", []([[maybe_unused]] int& current, [[maybe_unused]] int& max) {}); - - if (checkoutResult) - { - SaveTextureSetting(outputPath); - } - else - { - AZ_Error("Texture Editor", false, "Cannot checkout file '%s' from source control.", outputPath.c_str()); - } - } - else - { - const bool fileExisted = AZ::IO::FileIOBase::GetInstance()->Exists(outputPath.c_str()); - const bool fileReadOnly = AZ::IO::FileIOBase::GetInstance()->IsReadOnly(outputPath.c_str()); - - if (!fileExisted || !fileReadOnly) - { - SaveTextureSetting(outputPath); - } - } - } - - void TexturePropertyEditor::SaveTextureSetting(AZStd::string outputPath) - { - if (!m_validImage) - { - return; - } - - ImageProcessing::TextureSettings& baseSetting = m_textureSetting.GetMultiplatformTextureSetting(); - for (auto& it : m_textureSetting.m_settingsMap) - { - baseSetting.ApplySettings(it.second, it.first); - } - - ImageProcessing::StringOutcome outcome = ImageProcessing::TextureSettings::WriteTextureSetting(outputPath, baseSetting); - - if (outcome.IsSuccess()) - { - // Since setting is successfully saved, we can safely delete the legacy setting now - DeleteLegacySetting(); - } - else - { - AZ_Error("Texture Editor", false, "Cannot save texture settings!"); - } - } - - void TexturePropertyEditor::DeleteLegacySetting() - { - AZStd::string legacyFile = m_textureSetting.m_fullPath + ImageProcessing::TextureSettings::legacyExtensionName; - const bool fileExisted = AZ::IO::FileIOBase::GetInstance()->Exists(legacyFile.c_str()); - if (fileExisted) - { - bool sourceControlActive = false; - AzToolsFramework::SourceControlConnectionRequestBus::BroadcastResult(sourceControlActive, &AzToolsFramework::SourceControlConnectionRequests::IsActive); - - if (sourceControlActive) - { - AzToolsFramework::SourceControlCommandBus::Broadcast(&AzToolsFramework::SourceControlCommandBus::Events::RequestDelete, legacyFile.c_str(), - [](bool success, const AzToolsFramework::SourceControlFileInfo& info) - { - //Deletes the file locally if it's not tracked by source control - if (!success && !info.IsManaged()) - { - AZ::IO::FileIOBase::GetInstance()->Remove(info.m_filePath.c_str()); - } - }); - } - else - { - AZ::IO::FileIOBase::GetInstance()->Remove(legacyFile.c_str()); - } - } - } - - - void TexturePropertyEditor::OnHelp() - { - QString webLink = tr("https://docs.aws.amazon.com/console/lumberyard/texturepipeline"); - QDesktopServices::openUrl(QUrl(webLink)); - } - - - bool TexturePropertyEditor::event(QEvent* event) - { - bool needsBlocking = false; - if (m_previewWidget) - { - needsBlocking = m_previewWidget->OnQtEvent(event); - } - return needsBlocking ? true : QWidget::event(event); - } - -}//namespace ImageProcessingEditor -#include diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.h b/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.h deleted file mode 100644 index 77261d820a..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#if !defined(Q_MOC_RUN) -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#endif - -namespace Ui -{ - class TexturePropertyEditor; -} - -namespace ImageProcessingEditor -{ - class TexturePropertyEditor - : public AzQtComponents::StyledDialog - , protected EditorInternalNotificationBus::Handler - { - Q_OBJECT - public: - - AZ_CLASS_ALLOCATOR(TexturePropertyEditor, AZ::SystemAllocator, 0); - explicit TexturePropertyEditor(const AZ::Uuid& sourceTextureId, QWidget* parent = nullptr); - ~TexturePropertyEditor(); - - bool HasValidImage(); - - protected: - void OnSave(); - void OnHelp(); - - //////////////////////////////////////////////////////////////////////// - //EditorInternalNotificationBus - void OnEditorSettingsChanged(bool needRefresh, const AZStd::string& platform); - //////////////////////////////////////////////////////////////////////// - - bool event(QEvent* event) override; - - private: - QScopedPointer m_ui; - QScopedPointer m_previewWidget; - QScopedPointer m_presetSelectionWidget; - QScopedPointer m_resolutionSettingWidget; - QScopedPointer m_mipmapSettingWidget; - - EditorTextureSetting m_textureSetting; - bool m_validImage = true; - - void SaveTextureSetting(AZStd::string outputPath); - void DeleteLegacySetting(); - - }; -} //namespace ImageProcessingEditor - diff --git a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.ui b/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.ui deleted file mode 100644 index 33a7fd3376..0000000000 --- a/Gems/ImageProcessing/Code/Source/Editor/TexturePropertyEditor.ui +++ /dev/null @@ -1,120 +0,0 @@ - - - TexturePropertyEditor - - - - 0 - 0 - 580 - 1100 - - - - - 580 - 800 - - - - - 580 - 1200 - - - - Texture Settings Editor - - - - - - - 0 - 0 - - - - true - - - - - 0 - 0 - 560 - 1049 - - - - - 0 - 0 - - - - - 0 - - - 0 - - - 0 - - - 0 - - - - - - - - - - - - - - ? - - - - - - - Qt::Horizontal - - - QSizePolicy::Expanding - - - - 40 - 20 - - - - - - - - Apply - - - - - - - Close - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h b/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h deleted file mode 100644 index 962cd81668..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderBaseType.h +++ /dev/null @@ -1,29 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License").All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file.Do not -* remove or modify any license notices.This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once -#include - -typedef AZ::s8 int8; -typedef AZ::s8 sint8; -typedef AZ::u8 uint8; - -typedef AZ::s16 int16; -typedef AZ::s16 sint16; -typedef AZ::u16 uint16; - -typedef AZ::s32 int32; -typedef AZ::s32 sint32; -typedef AZ::u32 uint32; - -typedef float f32; -typedef double f64; diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.cpp b/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.cpp deleted file mode 100644 index 8c0dc0ff56..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.cpp +++ /dev/null @@ -1,346 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include -#include -#include - -namespace ImageProcessing -{ - BuilderPluginComponent::BuilderPluginComponent() - { - // AZ Components should only initialize their members to null and empty in constructor - // after construction, they may be deserialized from file. - } - - BuilderPluginComponent::~BuilderPluginComponent() - { - } - - void BuilderPluginComponent::Init() - { - } - - void BuilderPluginComponent::Activate() - { - // create and initialize BuilderSettingManager once since it's will be used for image conversion - BuilderSettingManager::CreateInstance(); - - auto outcome = ImageProcessing::BuilderSettingManager::Instance()->LoadBuilderSettings(); - AZ_Error("Image Processing", outcome.IsSuccess(), "Failed to load default preset settings!"); - - // Activate is where you'd perform registration with other objects and systems. - // Since we want to register our builder, we do that here: - AssetBuilderSDK::AssetBuilderDesc builderDescriptor; - builderDescriptor.m_name = "Image Worker Builder"; - builderDescriptor.m_version = 2; - builderDescriptor.m_analysisFingerprint = AZStd::string::format("%d", ImageProcessing::BuilderSettingManager::Instance()->BuilderSettingsVersion()); - - for (int i = 0; i < s_TotalSupportedImageExtensions; i++) - { - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern(s_SupportedImageExtensions[i], AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - } - - //add ".dds" here separately since we only apply copy operation for this type of file. and there won't be export option for dds files. - builderDescriptor.m_patterns.push_back(AssetBuilderSDK::AssetBuilderPattern("*.dds", AssetBuilderSDK::AssetBuilderPattern::PatternType::Wildcard)); - builderDescriptor.m_busId = azrtti_typeid(); - builderDescriptor.m_createJobFunction = AZStd::bind(&ImageBuilderWorker::CreateJobs, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - builderDescriptor.m_processJobFunction = AZStd::bind(&ImageBuilderWorker::ProcessJob, &m_imageBuilder, AZStd::placeholders::_1, AZStd::placeholders::_2); - m_imageBuilder.BusConnect(builderDescriptor.m_busId); - ImageProcessingRequestBus::Handler::BusConnect(); - AssetBuilderSDK::AssetBuilderBus::Broadcast(&AssetBuilderSDK::AssetBuilderBusTraits::RegisterBuilderInformation, builderDescriptor); - } - - void BuilderPluginComponent::Deactivate() - { - ImageProcessingRequestBus::Handler::BusDisconnect(); - m_imageBuilder.BusDisconnect(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - } - - void BuilderPluginComponent::Reflect(AZ::ReflectContext* context) - { - // components also get Reflect called automatically - // this is your opportunity to perform static reflection or type registration of any types you want the serializer to know about - if (AZ::SerializeContext* serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0) - ->Attribute(AZ::Edit::Attributes::SystemComponentTags, AZStd::vector({ AssetBuilderSDK::ComponentTags::AssetBuilder })) - ; - } - - BuilderSettingManager::Reflect(context); - BuilderSettings::Reflect(context); - PresetSettings::Reflect(context); - CubemapSettings::Reflect(context); - MipmapSettings::Reflect(context); - TextureSettings::Reflect(context); - } - - void BuilderPluginComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("ImagerBuilderPluginService", 0x6dc0db6e)); - } - - void BuilderPluginComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("ImagerBuilderPluginService", 0x6dc0db6e)); - } - - IImageObjectPtr BuilderPluginComponent::LoadImage(const AZStd::string& filePath) - { - return IImageObjectPtr(LoadImageFromFile(filePath)); - } - - IImageObjectPtr BuilderPluginComponent::LoadImagePreview(const AZStd::string& filePath) - { - IImageObjectPtr image(LoadImageFromFile(filePath)); - if (image) - { - ImageToProcess imageToProcess(image); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - return imageToProcess.Get(); - } - return image; - } - - void ImageBuilderWorker::ShutDown() - { - // it is important to note that this will be called on a different thread than your process job thread - m_isShuttingDown = true; - } - - // this happens early on in the file scanning pass - // this function should consistently always create the same jobs, and should do no checking whether the job is up to date or not - just be consistent. - void ImageBuilderWorker::CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response) - { - if (m_isShuttingDown) - { - response.m_result = AssetBuilderSDK::CreateJobsResultCode::ShuttingDown; - return; - } - - // Get the extension of the file - AZStd::string ext; - AzFramework::StringFunc::Path::GetExtension(request.m_sourceFile.c_str(), ext, false); - AZStd::to_upper(ext.begin(), ext.end()); - - // We process the same file for all platforms - for (const AssetBuilderSDK::PlatformInfo& platformInfo : request.m_enabledPlatforms) - { - if (ImageProcessing::BuilderSettingManager::Instance()->DoesSupportPlatform(platformInfo.m_identifier)) - { - AssetBuilderSDK::JobDescriptor descriptor; - descriptor.m_jobKey = ext + " Compile"; - descriptor.SetPlatformIdentifier(platformInfo.m_identifier.c_str()); - descriptor.m_critical = false; - descriptor.m_additionalFingerprintInfo = AZStd::string::format("%d", ImageProcessing::BuilderSettingManager::Instance()->BuilderSettingsVersion()); - response.m_createJobOutputs.push_back(descriptor); - } - } - - response.m_result = AssetBuilderSDK::CreateJobsResultCode::Success; - return; - } - - // later on, this function will be called for jobs that actually need doing. - // the request will contain the CreateJobResponse you constructed earlier, including any keys and values you placed into the hash table - void ImageBuilderWorker::ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response) - { - // Before we begin, let's make sure we are not meant to abort. - AssetBuilderSDK::JobCancelListener jobCancelListener(request.m_jobId); - - AZStd::vector productFilepaths; - bool imageProcessingSuccessful = false; - bool needConversion = true; - - //if the original file is a dds file then skip conversion - if (AzFramework::StringFunc::Path::IsExtension(request.m_fullPath.c_str(), "dds", false)) - { - productFilepaths.push_back(request.m_fullPath); - imageProcessingSuccessful = true; - needConversion = false; - } - - // Do conversion and get exported file's path - if (needConversion) - { - AZ_TracePrintf(AssetBuilderSDK::InfoWindow, "Performing image conversion: %s\n", request.m_fullPath.c_str()); - ImageConvertProcess* process = CreateImageConvertProcess(request.m_fullPath, request.m_tempDirPath, - request.m_jobDescription.GetPlatformIdentifier()); - - if (process != nullptr) - { - //the process can be stopped if the job is cancelled or the worker is shutting down - while (!process->IsFinished() && !m_isShuttingDown && !jobCancelListener.IsCancelled()) - { - process->UpdateProcess(); - } - - //get process result - imageProcessingSuccessful = process->IsSucceed(); - process->GetAppendOutputFilePaths(productFilepaths); - - delete process; - } - else - { - imageProcessingSuccessful = false; - } - } - - if (imageProcessingSuccessful) - { - AZ::Outcome result = PopulateProducts(request, productFilepaths, response.m_outputProducts); - if (result.IsSuccess()) - { - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Success; - } - else - { - AZ_Error(AssetBuilderSDK::ErrorWindow, false, result.GetError().c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; - } - } - else - { - if (m_isShuttingDown) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Cancelled job %s because shutdown was requested.\n", request.m_fullPath.c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; - } - else if (jobCancelListener.IsCancelled()) - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Cancelled was requested for job %s.\n", request.m_fullPath.c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Cancelled; - } - else - { - AZ_TracePrintf(AssetBuilderSDK::ErrorWindow, "Unexpected error during processing job %s.\n", request.m_fullPath.c_str()); - response.m_resultCode = AssetBuilderSDK::ProcessJobResult_Failed; - } - } - } - - AZ::Outcome ImageBuilderWorker::PopulateProducts(const AssetBuilderSDK::ProcessJobRequest& request, const AZStd::vector& productFilepaths, AZStd::vector& jobProducts) - { - AssetBuilderSDK::JobProduct* rgbBaseJobProduct = nullptr; - AssetBuilderSDK::JobProduct* diffBaseJobProduct = nullptr; - AssetBuilderSDK::JobProduct* baseJobProduct = nullptr; - AssetBuilderSDK::JobProduct* alphaBaseJobProduct = nullptr; - // Report the image-import result (filepath to one or many '.dds') - - // This reserve is critically important to prevent resizing the vector and invalidating the pointers we need to save off - jobProducts.reserve(productFilepaths.size()); - - for (const auto& product : productFilepaths) - { - AssetBuilderSDK::JobProduct jobProduct(product); - jobProduct.m_dependenciesHandled = true; // Dependencies are handled down below. The base products will have dependencies, lod products won't - jobProducts.push_back(jobProduct); - - AZ::u32 lodLevel = AssetBuilderSDK::GetSubID_LOD(jobProduct.m_productSubID); - - if(jobProduct.m_productSubID == 0) - { - rgbBaseJobProduct = &jobProducts.back(); - } - else if((jobProduct.m_productSubID & AssetBuilderSDK::SUBID_FLAG_DIFF) && lodLevel == 0) - { - diffBaseJobProduct = &jobProducts.back(); - } - else if((jobProduct.m_productSubID & AssetBuilderSDK::SUBID_FLAG_ALPHA) && lodLevel == 0) - { - alphaBaseJobProduct = &jobProducts.back(); - } - } - - //We can have a diff and/or a rgb base. The rgb base always takes precedence when present - baseJobProduct = rgbBaseJobProduct; - - if(!baseJobProduct) - { - baseJobProduct = diffBaseJobProduct; - } - - for (AssetBuilderSDK::JobProduct& jobProduct : jobProducts) - { - AssetBuilderSDK::ProductDependency productDependency(AZ::Data::AssetId(request.m_sourceFileUUID, jobProduct.m_productSubID), 0); - - AZ::u32 lodLevel = AssetBuilderSDK::GetSubID_LOD(jobProduct.m_productSubID); - bool isAlpha = jobProduct.m_productSubID & AssetBuilderSDK::SUBID_FLAG_ALPHA; - - if (lodLevel > 0) - { - if (isAlpha) - { - if (alphaBaseJobProduct) - { - // add all alpha mips to the base alpha texture as product dependency - alphaBaseJobProduct->m_dependencies.push_back(productDependency); - } - else - { - return AZ::Failure(AZStd::string::format("Unable to add (%s) file as a product dependency of the base alpha texture file. Base alpha texture file is missing from the products list.\n", jobProduct.m_productFileName.c_str())); - } - } - else - { - if (baseJobProduct) - { - // add all rgb mips to the base rgb texture as product dependency - baseJobProduct->m_dependencies.push_back(productDependency); - } - else - { - return AZ::Failure(AZStd::string::format("Unable to add (%s) file as a product dependency of the base rgb texture file. Base rgb texture file is missing from the products list.\n", jobProduct.m_productFileName.c_str())); - } - } - } - } - - // Diffuse (_diff) is required by the base (typically for cubemaps) - if (rgbBaseJobProduct && diffBaseJobProduct) - { - AssetBuilderSDK::ProductDependency productDependency(AZ::Data::AssetId(request.m_sourceFileUUID, diffBaseJobProduct->m_productSubID), 0); - rgbBaseJobProduct->m_dependencies.push_back(productDependency); - } - - if (alphaBaseJobProduct && baseJobProduct) - { - // Add the alphaBaseTexture as a product dependency for baseTexture - AssetBuilderSDK::ProductDependency productDependency(AZ::Data::AssetId(request.m_sourceFileUUID, alphaBaseJobProduct->m_productSubID), 0); - baseJobProduct->m_dependencies.push_back(productDependency); - } - - return AZ::Success(); - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.h b/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.h deleted file mode 100644 index 212081ec92..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderComponent.h +++ /dev/null @@ -1,80 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - //! Builder to process images - class ImageBuilderWorker - : public AssetBuilderSDK::AssetBuilderCommandBus::Handler - { - public: - AZ_RTTI(ImageBuilderWorker, "{525422DE-05B3-4095-966F-90CD7657A7E1}"); - - ImageBuilderWorker() = default; - ~ImageBuilderWorker() = default; - - //! Asset Builder Callback Functions - void CreateJobs(const AssetBuilderSDK::CreateJobsRequest& request, AssetBuilderSDK::CreateJobsResponse& response); - void ProcessJob(const AssetBuilderSDK::ProcessJobRequest& request, AssetBuilderSDK::ProcessJobResponse& response); - - ////////////////////////////////////////////////////////////////////////// - //!AssetBuilderSDK::AssetBuilderCommandBus interface - void ShutDown() override; // if you get this you must fail all existing jobs and return. - ////////////////////////////////////////////////////////////////////////// - - //! Populates the jobProduct vector with all the entries including their product dependencies - AZ::Outcome PopulateProducts(const AssetBuilderSDK::ProcessJobRequest& request, const AZStd::vector& productFilepaths, AZStd::vector& jobProducts); - - private: - bool m_isShuttingDown = false; - }; - - //! BuilderPluginComponent is to handle the lifecycle of ImageBuilder module. - class BuilderPluginComponent - : public AZ::Component - , protected ImageProcessingRequestBus::Handler - { - public: - AZ_COMPONENT(BuilderPluginComponent, "{2F12E1BE-D8F6-47A4-AC3E-6C5527C55840}") - static void Reflect(AZ::ReflectContext* context); - - BuilderPluginComponent(); // avoid initialization here. - ~BuilderPluginComponent() override; // free memory an uninitialize yourself. - - ////////////////////////////////////////////////////////////////////////// - // AZ::Component - void Init() override; // create objects, allocate memory and initialize yourself without reaching out to the outside world - void Activate() override; // reach out to the outside world and connect up to what you need to, register things, etc. - void Deactivate() override; // unregister things, disconnect from the outside world - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - ////////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // ImageProcessingRequestBus interface implementation - IImageObjectPtr LoadImage(const AZStd::string& filePath) override; - IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override; - //////////////////////////////////////////////////////////////////////// - - private: - ImageBuilderWorker m_imageBuilder; - }; -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings b/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings deleted file mode 100644 index 7e16a3c98f..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings +++ /dev/null @@ -1,8051 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/BTImageLoader.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/BTImageLoader.cpp deleted file mode 100644 index b06ceccddc..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/BTImageLoader.cpp +++ /dev/null @@ -1,227 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include "ImageLoaders.h" - -#include -#include - -#include - -namespace -{ - //--------------------------------------------------------------------------- - // Load and save the VTP Binary Terrain (BT) format, documented here: - // http://vterrain.org/Implementation/Formats/BT.html - - // This structure represents a binary layout in the file. To direct load & save it, we need to remove all structure memory padding -#pragma pack(push,1) - struct BtHeader - { - char headerTag[7]; // Should be "binterr" - char headerTagVersion[3]; // Should be "1.3" - AZ::s32 columns; // # of columns in the heightfield - AZ::s32 rows; // # of rows in the heightfield - AZ::s16 bytesPerPoint; // bytes per height value, either 2 for signed ints or 4 for floats - AZ::s16 isFloatingPointData; // 1 if height values are floats, 0 for 16-bit signed ints - AZ::s16 horizUnits; // 0 if degrees, 1 if meters, 2 if international feet, 3 if US survey feet - AZ::s16 utmZone; // UTM projection zone 1 to 60 or -1 to -60 (see https://en.wikipedia.org/wiki/Universal_Transverse_Mercator_coordinate_system ) - AZ::s16 datum; // Datum value (6001 to 6094), see http://www.epsg.org/ - double leftExtent; // left coordinate projection of the file - double rightExtent; // right coordinate projection of the file - double bottomExtent; // bottom coordinate projection of the file - double topExtent; // top coordinate projection of the file - AZ::s16 externalProjection; // 1 if projection is in an external .prj file, 0 if it's contained in the header - float scale; // vertical units in meters. 0.0 should be treated as 1.0 - char unused[190]; - }; -#pragma pack(pop) - - AZStd::vector LoadFile(const AZStd::string& fileName) - { - AZ::IO::FileIOBase* fileReader = AZ::IO::FileIOBase::GetInstance(); - - if (!fileReader) - { - return {}; - } - - // an engine compatible file reader has been attached, so use that. - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - AZ::u64 fileSize = 0; - - if (!fileReader->Open(fileName.c_str(), AZ::IO::OpenMode::ModeRead | AZ::IO::OpenMode::ModeBinary, fileHandle)) - { - return {}; - } - - if ((!fileReader->Size(fileHandle, fileSize)) || (fileSize == 0)) - { - fileReader->Close(fileHandle); - return {}; - } - - AZStd::vector fileBuf(fileSize); - - if (!fileReader->Read(fileHandle, fileBuf.data(), fileSize, true)) - { - fileReader->Close(fileHandle); - return {}; - } - - fileReader->Close(fileHandle); - - return fileBuf; - } - - bool IsHeaderValid(const BtHeader* header, std::size_t fileSize) - { - bool validData = true; - - // Do some quick error-checking on the header to make sure it meets our expectations - - // Does the header have the right header tag? (binterr1.0 - binterr1.3) - validData = validData && (memcmp(header->headerTag, "binterr", sizeof(header->headerTag)) == 0); - validData = validData && (header->headerTagVersion[0] == '1') && (header->headerTagVersion[1] == '.') && (header->headerTagVersion[2] >= '0') && (header->headerTagVersion[2] <= '3'); - - // Will the grid fit into a reasonable image size? - validData = validData && (header->columns >= 0) && (header->columns < 65536); - validData = validData && (header->rows >= 0) && (header->rows < 65536); - - // Do we either have 32-bit floats or 16-bit ints? - validData = validData && (((header->isFloatingPointData == 1) && (header->bytesPerPoint == 4)) || ((header->isFloatingPointData == 0) && (header->bytesPerPoint == 2))); - - // Is the remaining data exactly the size needed to fill our image? - AZ::s32 total = header->columns * header->rows * header->bytesPerPoint; - validData = validData && ((fileSize - sizeof(BtHeader)) == total); - - return validData; - } -} - -namespace ImageProcessing -{ - bool BTLoader::IsExtensionSupported(const char* extension) - { - return strcmp(extension, "bt") == 0; - } - - /* - Most of the logic here was taken from ImageBT.cpp. Please make sure - any changes are kept in sync :) - */ - IImageObject* BTLoader::LoadImageFromBT(const AZStd::string& fileName) - { - auto fileData = LoadFile(fileName); - - if (fileData.size() < sizeof(BtHeader)) - { - return nullptr; - } - - auto header = reinterpret_cast(fileData.data()); - - if (!header || !IsHeaderValid(header, fileData.size())) - { - return nullptr; - } - - if (header->scale == 0.0f) - { - header->scale = 1.0f; - } - - // The BT format defines the data as stored in column-first order, from bottom to top. - // However, some BT files store the data in row-first order, from top to bottom. - // There isn't anything that clearly specifies which type of file it is. If you load it the wrong way, - // the data will look like a bunch of wavy stripes. - // The only difference I've found in test files is datum values above 8000, which appears to be an invalid value for datum - // (it should be 6001-6904 according to the BT definition) - constexpr AZ::s32 invalidDatumValueDenotingColumnFirstData = 8000; - bool isColumnFirstData = (header->datum >= invalidDatumValueDenotingColumnFirstData) ? true : false; - AZ::s32 imageWidth = 0; - AZ::s32 imageHeight = 0; - - if (isColumnFirstData) - { - imageWidth = header->rows; - imageHeight = header->columns; - } - else - { - imageWidth = header->columns; - imageHeight = header->rows; - } - - IImageObject* image = IImageObject::CreateImage(imageWidth, imageHeight, 1, EPixelFormat::ePixelFormat_R32F); - - AZ::u8* p = nullptr; - AZ::u32 dwPitch = 0; - image->GetImagePointer(0, p, dwPitch); - - auto dst = reinterpret_cast(p); - auto maxPixel = std::numeric_limits::lowest(); - auto minPixel = std::numeric_limits::max(); - auto terrainData = reinterpret_cast(header + 1); - - // Read in the pixel data - if (header->isFloatingPointData) - { - for (AZ::s32 y = 0; y < imageHeight; ++y) - { - for (AZ::s32 x = 0; x < imageWidth; ++x) - { - float height = *reinterpret_cast(terrainData); - terrainData += sizeof(float); - - // Scale based on what our header defines - float setVal = dst[(y * imageWidth) + x] = height * header->scale; - maxPixel = AZStd::max(maxPixel, setVal); - minPixel = AZStd::min(minPixel, setVal); - } - } - } - else - { - for (AZ::s32 y = 0; y < imageHeight; ++y) - { - for (AZ::s32 x = 0; x < imageWidth; ++x) - { - float height = static_cast(*reinterpret_cast(terrainData)); - terrainData += sizeof(AZ::s16); - - // Scale based on what our header defines - float setVal = dst[(y * imageWidth) + x] = height * header->scale; - maxPixel = AZStd::max(maxPixel, setVal); - minPixel = AZStd::min(minPixel, setVal); - } - } - } - - // Scale our range down to 0 - 1 - auto diff = maxPixel - minPixel; - if (AZ::GetAbs(diff) < std::numeric_limits::epsilon()) - { - diff = 1.0f; - } - - auto imagePixels = imageWidth * imageHeight; - for (AZ::s32 i = 0; i < imagePixels; ++i) - { - dst[i] = (dst[i] - minPixel) / diff; - } - - return image; - } -} diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.cpp deleted file mode 100644 index ac6b1d34d5..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include - -namespace ImageProcessing -{ - IImageObject* LoadImageFromFile(const AZStd::string& filename) - { - QFileInfo fileInfo(filename.c_str()); - QString ext = fileInfo.suffix(); - - if (TIFFLoader::IsExtensionSupported(ext.toUtf8())) - { - return TIFFLoader::LoadImageFromTIFF(filename); - } - else if (BTLoader::IsExtensionSupported(ext.toUtf8())) - { - return BTLoader::LoadImageFromBT(filename); - } - else if (QtImageLoader::IsExtensionSupported(ext.toUtf8())) - { - return QtImageLoader::LoadImageFromFile(filename); - } - - AZ_Warning("ImageProcessing", false, "No proper image loader to load file: %s", filename.c_str()); - return nullptr; - } - - bool IsExtensionSupported(const char* extension) - { - if (TIFFLoader::IsExtensionSupported(extension)) - { - return true; - } - else if (BTLoader::IsExtensionSupported(extension)) - { - return true; - } - else if (QtImageLoader::IsExtensionSupported(extension)) - { - return true; - } - return false; - } - - const AZStd::string LoadEmbeddedSettingFromFile(const AZStd::string& filename) - { - QFileInfo fileInfo(filename.c_str()); - QString ext = fileInfo.suffix(); - - if (TIFFLoader::IsExtensionSupported(ext.toUtf8())) - { - return TIFFLoader::LoadSettingFromTIFF(filename); - } - return ""; - } - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.h b/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.h deleted file mode 100644 index ae460b3552..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/ImageLoaders.h +++ /dev/null @@ -1,51 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -namespace ImageProcessing -{ - class IImageObject; - - IImageObject* LoadImageFromFile(const AZStd::string& filename); - bool IsExtensionSupported(const char* extension); - const AZStd::string LoadEmbeddedSettingFromFile(const AZStd::string& filename); - - // Tiff loader. The loader support uncompressed tiff with with 1~4 channels and 8bit and 16bit uint or 16bits and 32bits float per channel - // QImage also support tiff (tiff plugin), but it only supports 8bits uint - namespace TIFFLoader - { - bool IsExtensionSupported(const char* extension); - // Load a tiff file to an image object. - IImageObject* LoadImageFromTIFF(const AZStd::string& filename); - // Load embedded .exportsettings string from tiff which was exported by deprecated feature of CryTif plugin. - const AZStd::string LoadSettingFromTIFF(const AZStd::string& filename); - };// namespace ImageTIFF - - namespace BTLoader - { - bool IsExtensionSupported(const char* extension); - // Load a BT file to an image object. - IImageObject* LoadImageFromBT(const AZStd::string& fileName); - }// namespace BTLoader - - // Image loader through Qt's QImage with image formats supported native and through plugins - namespace QtImageLoader - { - bool IsExtensionSupported(const char* extension); - // Load image file which supported by QtImage to an image object - IImageObject* LoadImageFromFile(const AZStd::string& filename); - };// namespace QtImageLoader - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/QtImageLoader.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/QtImageLoader.cpp deleted file mode 100644 index dd5dd62b73..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/QtImageLoader.cpp +++ /dev/null @@ -1,76 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "ImageProcessing_precompiled.h" - -#include -#include - -#include -#include - -/////////////////////////////////////////////////////////////////////////////////// - -namespace ImageProcessing -{ - namespace QtImageLoader - { - IImageObject* LoadImageFromFile(const AZStd::string& filename) - { - //try to open the image - QImage qimage(filename.c_str()); - if (qimage.isNull()) - { - return NULL; - } - - //convert to format which compatiable our pixel format - if (qimage.format() != QImage::Format_RGBA8888) - { - qimage = qimage.convertToFormat(QImage::Format_RGBA8888); - } - - //create a new image object - IImageObject *pImage = IImageObject::CreateImage(qimage.width(), qimage.height(), 1, - ePixelFormat_R8G8B8A8); - - //get a pointer to the image objects pixel data - uint8* pDst; - uint32 dwPitch; - pImage->GetImagePointer(0, pDst, dwPitch); - - //copy the qImage into the image object - for (uint32 dwY = 0; dwY < (uint32)qimage.height(); ++dwY) - { - uint8* dstLine = &pDst[dwPitch * dwY]; - uchar* srcLine = qimage.scanLine(dwY); - memcpy(dstLine, srcLine, dwPitch); - } - return pImage; - } - - bool IsExtensionSupported(const char* extension) - { - QList imgFormats = QImageReader::supportedImageFormats(); - - for (int i = 0; i < imgFormats.size(); ++i) - { - if (QString::fromUtf8(imgFormats[i]).toLower() == QString(extension).toLower()) - { - return true; - } - } - - return false; - } - }//namespace QtImageLoader -} //namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp b/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp deleted file mode 100644 index 6c2881423d..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageLoader/TIFFLoader.cpp +++ /dev/null @@ -1,660 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include -#include -#include -#include - -#include -#include - -#include - -#include // TIFF library - -namespace ImageProcessing -{ - namespace TIFFLoader - { - class TiffFileRead - { - public: - TiffFileRead(const AZStd::string& filename) - : m_tif(nullptr) - { - m_tif = TIFFOpen(filename.c_str(), "r");; - } - - ~TiffFileRead() - { - if (m_tif != nullptr) - { - TIFFClose(m_tif); - } - } - - TIFF *GetTiff() - { - return m_tif; - } - - private: - TIFF *m_tif; - }; - - bool IsExtensionSupported(const char* extension) - { - QString ext = QString(extension).toLower(); - // This is the list of file extensions supported by this loader - return ext == "tif" || ext == "tiff"; - } - - struct TiffData - { - AZ::u32 m_channels = 0; - AZ::u32 m_photometric = 0; - AZ::u32 m_bitsPerPixel = 0; - AZ::u16 m_format = 0; - - AZ::u32 m_width = 0; - AZ::u32 m_height = 0; - - AZ::u32 m_tileWidth = 0; - AZ::u32 m_tileHeight = 0; - bool m_isTiled = false; - AZ::u32 m_bufSize = 0; - - bool m_isGeoTiff = false; - float m_pixelValueScale = 1.0f; - - EPixelFormat m_pixelFormat = EPixelFormat::ePixelFormat_Unknown; - }; - - static void Process8BitTiff(AZ::u8* dst, const AZ::u8* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 3] = 0xFF; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - // convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = aznumeric_cast(0xFF - src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(0xFF - src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = 0x00; - dst[destIdx + 3] = 0xFF; - - dstMult = 4; - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - - dstMult = 2; - } - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx + 2] * data.m_pixelValueScale); - dst[destIdx + 3] = (data.m_channels == 3) ? 0xFF : aznumeric_cast(src[srcIdx + 3] * data.m_pixelValueScale); - - dstMult = 4; - } - } - - static void Process16BitHDRTiff(AZ::s16* dst, const AZ::s16* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 3] = 1; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - //but convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = uint16(1.0f - src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = uint16(1.0f - src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = 0; - dst[destIdx + 3] = 1; - - dstMult = 4; - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - - dstMult = 2; - } - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx + 2] * data.m_pixelValueScale); - dst[destIdx + 3] = (data.m_channels == 3) ? 1 : aznumeric_cast(src[srcIdx + 3] * data.m_pixelValueScale); - - dstMult = 4; - } - } - - static void Process16BitTiff(AZ::u16* dst, const AZ::u16* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 3] = 0xFFFF; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - //convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = 0xFFFF - aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = 0xFFFF - aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = 0x0000; - dst[destIdx + 3] = 0xFFFF; - - dstMult = 4; - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - - dstMult = 2; - } - } - else - { - dst[destIdx] = aznumeric_cast(src[srcIdx] * data.m_pixelValueScale); - dst[destIdx + 1] = aznumeric_cast(src[srcIdx + 1] * data.m_pixelValueScale); - dst[destIdx + 2] = aznumeric_cast(src[srcIdx + 2] * data.m_pixelValueScale); - dst[destIdx + 3] = (data.m_channels == 3) ? 0xFFFF : aznumeric_cast(src[srcIdx + 3] * data.m_pixelValueScale); - - dstMult = 4; - } - } - - static void Process32BitHDRTiff(float* dst, const float* src, AZ::u32 destIdx, AZ::u32 srcIdx, const TiffData& data, AZ::u8& dstMult) - { - auto getScaledOrClamped = [&data](auto val) - { - // GeoTiff doesn't clamp because negative values are legitimate when the data represents height values below sea level. - return data.m_isGeoTiff ? (val * data.m_pixelValueScale) : AZ::GetMax(val, 0.0f); - }; - - if (data.m_channels == 1) - { - if (data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - // clamp negative values - const float v = getScaledOrClamped(src[srcIdx]); - dst[destIdx] = v; - } - else - { - // clamp negative values - const float v = getScaledOrClamped(src[srcIdx]); - dst[destIdx] = v; - dst[destIdx + 1] = v; - dst[destIdx + 2] = v; - dst[destIdx + 3] = 1.0f; - - dstMult = 4; - } - } - else if (data.m_channels == 2) - { - if (data.m_photometric == PHOTOMETRIC_SEPARATED) - { - //convert CMY to RGB (PHOTOMETRIC_SEPARATED refers to inks in TIFF, the value is inverted) - dst[destIdx] = 1.0f - getScaledOrClamped(src[srcIdx]); - dst[destIdx + 1] = 1.0f - getScaledOrClamped(src[srcIdx + 1]); - dst[destIdx + 2] = 0.0f; - dst[destIdx + 3] = 1.0f; - - dstMult = 4; - } - else - { - dst[destIdx] = src[srcIdx] * data.m_pixelValueScale; - dst[destIdx + 1] = src[srcIdx + 1] * data.m_pixelValueScale; - - dstMult = 2; - } - } - else - { - // clamp negative values; don't swap red and blue -> RGB(A) - dst[destIdx] = getScaledOrClamped(src[srcIdx]); - dst[destIdx + 1] = getScaledOrClamped(src[srcIdx + 1]); - dst[destIdx + 2] = getScaledOrClamped(src[srcIdx + 2]); - dst[destIdx + 3] = (data.m_channels == 3) ? 1.0f : getScaledOrClamped(src[srcIdx + 3]) * data.m_pixelValueScale; - - dstMult = 4; - } - } - - static TiffData GetTiffData(TIFF* tif) - { - TiffData data; - - TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &data.m_channels); - TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &data.m_photometric); - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &data.m_bitsPerPixel); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &data.m_format); - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &data.m_width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &data.m_height); - TIFFGetField(tif, TIFFTAG_TILEWIDTH, &data.m_tileWidth); - TIFFGetField(tif, TIFFTAG_TILELENGTH, &data.m_tileHeight); - - // Check to see if this is a tiled TIFF (vs a scanline-based TIFF) - if ((data.m_tileWidth > 0) && (data.m_tileHeight > 0)) - { - // Tiled TIFF, so our buffer needs to be tile-sized - data.m_isTiled = true; - data.m_bufSize = TIFFTileSize(tif); - } - else - { - // Scanline TIFF, so our buffer needs to be scanline-sized. - data.m_bufSize = TIFFScanlineSize(tif); - - // Treat scanlines like a tile of 1 x width size. - data.m_tileHeight = 1; - data.m_tileWidth = data.m_width; - } - - // Defined in GeoTIFF format - http://web.archive.org/web/20160403164508/http://www.remotesensing.org/geotiff/spec/geotiffhome.html - // Used to get the X, Y, Z scales from a GeoTIFF file - constexpr auto GEOTIFF_MODELPIXELSCALE_TAG = 33550; - - // Check to see if it's a GeoTIFF, and if so, whether or not it has the ZScale parameter. - AZ::u32 tagCount = 0; - double* pixelScales = nullptr; - if (TIFFGetField(tif, GEOTIFF_MODELPIXELSCALE_TAG, &tagCount, &pixelScales) == 1) - { - data.m_isGeoTiff = true; - - // if there's an xyz scale, and the Z scale isn't 0, let's use it. - if ((tagCount == 3) && (pixelScales != nullptr) && (pixelScales[2] != 0.0f)) - { - data.m_pixelValueScale = static_cast(pixelScales[2]); - } - } - - // Retrieve the pixel format of the image - switch (data.m_bitsPerPixel) - { - case 8: - { - data.m_pixelFormat = ePixelFormat_R8G8B8X8; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R8; - } - else if (data.m_channels == 4) - { - data.m_pixelFormat = ePixelFormat_R8G8B8A8; - } - - break; - } - - case 16: - { - if (data.m_format == SAMPLEFORMAT_IEEEFP) - { - data.m_pixelFormat = ePixelFormat_R16G16B16A16F; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R16F; - } - } - else - { - data.m_pixelFormat = ePixelFormat_R16G16B16A16; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R16; - } - } - - break; - } - - case 32: - { - if (data.m_format == SAMPLEFORMAT_IEEEFP) - { - data.m_pixelFormat = ePixelFormat_R32G32B32A32F; - - if (data.m_channels == 1 && data.m_photometric != PHOTOMETRIC_MINISBLACK) - { - data.m_pixelFormat = ePixelFormat_R32F; - } - } - - break; - } - - default: - break; - } - - return data; - } - - static IImageObject* LoadTIFF(TIFF* tif) - { - TiffData data = GetTiffData(tif); - AZStd::unique_ptr destImageObject; - destImageObject.reset(IImageObject::CreateImage(data.m_width, data.m_height, - 1, data.m_pixelFormat)); - - uint8* dst; - uint32 pitch; - destImageObject->GetImagePointer(0, dst, pitch); - - AZStd::vector buf(data.m_bufSize); - - AZ::u8 dstMult = 1; - - // Loop across the image height, one tile at a time - for (AZ::u32 imageY = 0; imageY < data.m_height; imageY += data.m_tileHeight) - { - // If we aren't actually tiled, we'll need to read a scanline here - if (!data.m_isTiled) - { - if (TIFFReadScanline(tif, buf.data(), imageY) == -1) - { - AZ_Error("LoadTIFF", false, "Error reading scanline."); - return nullptr; - } - } - - // Loop across the image width, one tile at a time - for (AZ::u32 imageX = 0; imageX < data.m_width; imageX += data.m_tileWidth) - { - // If we *are* tiled, read in a new tile here - if (data.m_isTiled) - { - if (TIFFReadTile(tif, buf.data(), imageX, imageY, 0, 0) == -1) - { - AZ_Error("LoadTIFF", false, "Error reading tile."); - return nullptr; - } - } - - // For each pixel in the tile buffer, read it in and convert. - for (AZ::u32 tileY = 0; tileY < data.m_tileHeight; ++tileY) - { - for (AZ::u32 tileX = 0; tileX < data.m_tileWidth; ++tileX) - { - AZ::u32 srcIdx = ((tileY * data.m_tileWidth) + tileX) * data.m_channels; - AZ::u32 destIdx = (((imageY + tileY) * data.m_width) + (imageX + tileX)) * dstMult; - - switch (data.m_bitsPerPixel) - { - case 8: - Process8BitTiff(dst, buf.data(), destIdx, srcIdx, data, dstMult); - break; - - case 16: - { - switch (data.m_format) - { - case SAMPLEFORMAT_INT: - case SAMPLEFORMAT_IEEEFP: - Process16BitHDRTiff(reinterpret_cast(dst), reinterpret_cast(buf.data()), - destIdx, srcIdx, data, dstMult); - - break; - - default: - Process16BitTiff(reinterpret_cast(dst), reinterpret_cast(buf.data()), - destIdx, srcIdx, data, dstMult); - - break; - } - - break; - } - - case 32: - if (data.m_format == SAMPLEFORMAT_IEEEFP) - { - Process32BitHDRTiff(reinterpret_cast(dst), reinterpret_cast(buf.data()), - destIdx, srcIdx, data, dstMult); - } - else - { - AZ_Error("LoadTIFF", false, "Unknown / unsupported format."); - return nullptr; - } - - break; - - default: - AZ_Error("LoadTIFF", false, "Unknown / unsupported format."); - return nullptr; - } - - } - } - } - } - - return destImageObject.release(); - } - - IImageObject* LoadImageFromTIFF(const AZStd::string& filename) - { - TiffFileRead tiffRead(filename); - TIFF* tif = tiffRead.GetTiff(); - - IImageObject* destImageObject = nullptr; - - if (!tif) - { - AZ_Warning("Image Processing", false, "%s: Open tiff failed (%s)", __FUNCTION__, filename.c_str()); - return destImageObject; - } - - uint32 bitsPerChannel = 0; - uint32 channels = 0; - uint32 format = 0; - TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &channels); - TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerChannel); - TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &format); - - if (channels != 1 && channels != 2 && channels != 3 && channels != 4) - { - AZ_Warning("Image Processing", false, "Unsupported TIFF pixel format (channel count: %d)", channels); - return destImageObject; - } - - uint32 width = 0; - uint32 height = 0; - TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width); - TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height); - if (width <= 0 || height <= 0) - { - AZ_Error("Image Processing", false, "%s failed (empty image)", __FUNCTION__); - return destImageObject; - } - - destImageObject = LoadTIFF(tif); - - if (destImageObject == nullptr) - { - AZ_Error("Image Processing", false, "Failed to read TIFF pixels"); - } - - return destImageObject; - } - - const AZStd::string LoadSettingFromTIFF(const AZStd::string& filename) - { - AZStd::string setting = ""; - - TiffFileRead tiffRead(filename); - TIFF* tif = tiffRead.GetTiff(); - - if (tif == nullptr) - { - return setting; - } - - // get image metadata - const unsigned char* buffer = nullptr; - unsigned int bufferLength = 0; - - if (!TIFFGetField(tif, TIFFTAG_PHOTOSHOP, &bufferLength, &buffer)) // 34377 IPTC TAG - { - return setting; - } - - const unsigned char* const bufferEnd = buffer + bufferLength; - - // detailed structure here: - // https://www.adobe.com/devnet-apps/photoshop/fileformatashtml/#50577409_pgfId-1037504 - while (buffer < bufferEnd) - { - const unsigned char* const bufferStart = buffer; - - // sanity check - if (buffer[0] != '8' || buffer[1] != 'B' || buffer[2] != 'I' || buffer[3] != 'M') - { - AZ_Warning("Image Processing", false, "Invalid Photoshop TIFF file [%s]!", filename.c_str()); - return setting; - } - buffer += 4; - - // get image resource id - const unsigned short resourceId = (((unsigned short)buffer[0]) << 8) | (unsigned short)buffer[1]; - buffer += 2; - - // get size of pascal string - const unsigned int nameSize = (unsigned int)buffer[0]; - ++buffer; - - // get pascal string - AZStd::string szName(buffer, buffer + nameSize); - buffer += nameSize; - - // align 2 bytes - if ((buffer - bufferStart) & 1) - { - ++buffer; - } - - // get size of resource data - const unsigned int resDataSize = - (((unsigned int)buffer[0]) << 24) | - (((unsigned int)buffer[1]) << 16) | - (((unsigned int)buffer[2]) << 8) | - (unsigned int)buffer[3]; - buffer += 4; - - // IPTC-NAA record. Contains the [File Info...] information. Old RC use this section to store the setting string. - if (resourceId == 0x0404) - { - const unsigned char* const iptcBufferStart = buffer; - - // Old RC uses IPTC ApplicationRecord tags SpecialInstructions to store the setting string - // IPTC Details: https://iptc.org/std/photometadata/specification/mapping/iptc-pmd-newsmlg2.html - unsigned int iptcPos = 0; - while (iptcPos + 5 < resDataSize) - { - int marker = iptcBufferStart[iptcPos++]; - int recordNumber = iptcBufferStart[iptcPos++]; - int dataSetNumber = iptcBufferStart[iptcPos++]; - int fieldLength = (iptcBufferStart[iptcPos++] << 8); - fieldLength += iptcBufferStart[iptcPos++]; - - // Ignore fields other than SpecialInstructions - if (marker != 0x1C || recordNumber != 0x02 || dataSetNumber != 0x28 ) - { - iptcPos += fieldLength; - continue; - } - - //save the setting string before close file - setting = AZStd::string(iptcBufferStart + iptcPos, iptcBufferStart + iptcPos + fieldLength); - return setting; - } - } - - buffer += resDataSize; - - // align 2 bytes - if ((buffer - bufferStart) & 1) - { - ++buffer; - } - } - - return setting; - } - - }// namespace ImageTIFF - -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessingModule.cpp b/Gems/ImageProcessing/Code/Source/ImageProcessingModule.cpp deleted file mode 100644 index 9cd28b39fe..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessingModule.cpp +++ /dev/null @@ -1,53 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" -#include -#include "ImageProcessingSystemComponent.h" -#include "ImageBuilderComponent.h" -#include "AtlasBuilder/AtlasBuilderComponent.h" - -namespace ImageProcessing -{ - class ImageProcessingModule - : public AZ::Module - { - public: - AZ_RTTI(ImageProcessingModule, "{A5392495-DD0E-4719-948A-B98DBAE88197}", AZ::Module); - - ImageProcessingModule() - : AZ::Module() - { - // Push results of the components' ::CreateDescriptor() into m_descriptors here. - m_descriptors.insert(m_descriptors.end(), { - ImageProcessingSystemComponent::CreateDescriptor(), //system component for editor - BuilderPluginComponent::CreateDescriptor(), //builder component for AP - TextureAtlasBuilder::AtlasBuilderComponent::CreateDescriptor(), //builder component for texture atlas - }); - } - - /** - * Add required SystemComponents to the SystemEntity. - */ - AZ::ComponentTypeList GetRequiredSystemComponents() const override - { - return AZ::ComponentTypeList{ - azrtti_typeid(), - }; - } - }; -} - -// DO NOT MODIFY THIS LINE UNLESS YOU RENAME THE GEM -// The first parameter should be GemName_GemIdLower -// The second should be the fully qualified name of the class above -AZ_DECLARE_MODULE_CLASS(Gem_ImageProcessing, ImageProcessing::ImageProcessingModule) diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.cpp b/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.cpp deleted file mode 100644 index 6629dc592a..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.cpp +++ /dev/null @@ -1,196 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" - -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include - -#include "ImageProcessingSystemComponent.h" -#include -#include - -namespace ImageProcessing -{ - void ImageProcessingSystemComponent::Reflect(AZ::ReflectContext* context) - { - if (auto serialize = azrtti_cast(context)) - { - serialize->Class() - ->Version(0) - ; - } - } - - void ImageProcessingSystemComponent::GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided) - { - provided.push_back(AZ_CRC("ImageBuilderService", 0x43c4be37)); - } - - void ImageProcessingSystemComponent::GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible) - { - incompatible.push_back(AZ_CRC("ImageBuilderService", 0x43c4be37)); - } - - void ImageProcessingSystemComponent::GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required) - { - (void)required; - } - - void ImageProcessingSystemComponent::GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent) - { - (void)dependent; - } - - void ImageProcessingSystemComponent::Init() - { - - } - - void ImageProcessingSystemComponent::Activate() - { - // Call to allocate BuilderSettingManager - BuilderSettingManager::CreateInstance(); - - ImageProcessingEditor::ImageProcessingEditorRequestBus::Handler::BusConnect(); - AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusConnect(); - AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler::BusConnect(); - ImageProcessingRequestBus::Handler::BusConnect(); - } - - void ImageProcessingSystemComponent::Deactivate() - { - ImageProcessingRequestBus::Handler::BusDisconnect(); - ImageProcessingEditor::ImageProcessingEditorRequestBus::Handler::BusDisconnect(); - AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler::BusDisconnect(); - AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler::BusDisconnect(); - - // Deallocate BuilderSettingManager - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - } - - void ImageProcessingSystemComponent::OpenSourceTextureFile(const AZ::Uuid& textureSourceID) - { - if (textureSourceID.IsNull()) - { - QMessageBox::warning(QApplication::activeWindow(), "Warning", - "Texture source does not have a unique ID. This can occur if the source asset has not yet been processed by the Asset Processor.", - QMessageBox::Ok); - } - else - { - ImageProcessingEditor::TexturePropertyEditor editor(textureSourceID, QApplication::activeWindow()); - if (!editor.HasValidImage()) - { - QMessageBox::warning(QApplication::activeWindow(), "Warning", "Invalid texture file", QMessageBox::Ok); - return; - } - editor.exec(); - } - } - - IImageObjectPtr ImageProcessingSystemComponent::LoadImage(const AZStd::string& filePath) - { - return IImageObjectPtr(LoadImageFromFile(filePath)); - } - - IImageObjectPtr ImageProcessingSystemComponent::LoadImagePreview(const AZStd::string& filePath) - { - IImageObjectPtr image(LoadImageFromFile(filePath)); - if (image) - { - ImageToProcess imageToProcess(image); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - return imageToProcess.Get(); - } - return image; - } - - void ImageProcessingSystemComponent::AddSourceFileOpeners(const char* fullSourceFileName, [[maybe_unused]] const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) - { - if (HandlesSource(fullSourceFileName)) - { - openers.push_back( - { - "Image_Processing_Editor", - "Edit Image Settings...", - QIcon(), - [&](const char* fullSourceFileNameInCallback, const AZ::Uuid& sourceUUID) - { - AZ_UNUSED(fullSourceFileNameInCallback); - - if (!LoadTextureSettings()) - { - return; - } - - ImageProcessingEditor::ImageProcessingEditorRequestBus::Broadcast(&ImageProcessingEditor::ImageProcessingEditorRequests::OpenSourceTextureFile, sourceUUID); - } - }); - } - } - - bool ImageProcessingSystemComponent::HandlesSource(AZStd::string_view fileName) const - { - for (int i = 0; i < s_TotalSupportedImageExtensions; i ++ ) - { - if (AZStd::wildcard_match(s_SupportedImageExtensions[i], fileName.data())) - { - return true; - } - } - - return false; - } - - bool ImageProcessingSystemComponent::GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo) - { - return ImagePreview::GetProductTexturePreview(fullProductFileName, previewImage, productInfo, productAlphaInfo); - } - - bool ImageProcessingSystemComponent::LoadTextureSettings() - { - if (m_textureSettingsLoaded) - { - return true; - } - - // Load the preset settings before opening the editor - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(); - if (outcome.IsSuccess()) - { - m_textureSettingsLoaded = true; - return true; - } - - AZ_Error("Image Processing", false, "Failed to load default preset settings!"); - return false; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.h b/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.h deleted file mode 100644 index 3d6f03b295..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessingSystemComponent.h +++ /dev/null @@ -1,77 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -#include -#include -#include -#include - -namespace ImageProcessing -{ - class ImageProcessingSystemComponent - : public AZ::Component - , protected ImageProcessingRequestBus::Handler - , protected ImageProcessingEditor::ImageProcessingEditorRequestBus::Handler - , protected AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationBus::Handler - , protected AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler - { - public: - AZ_COMPONENT(ImageProcessingSystemComponent, "{13B1EB88-316F-4D44-B59C-886F023A5A58}"); - - static void Reflect(AZ::ReflectContext* context); - - static void GetProvidedServices(AZ::ComponentDescriptor::DependencyArrayType& provided); - static void GetIncompatibleServices(AZ::ComponentDescriptor::DependencyArrayType& incompatible); - static void GetRequiredServices(AZ::ComponentDescriptor::DependencyArrayType& required); - static void GetDependentServices(AZ::ComponentDescriptor::DependencyArrayType& dependent); - - protected: - //////////////////////////////////////////////////////////////////////// - // ImageProcessingEditorRequestBus interface implementation - void OpenSourceTextureFile(const AZ::Uuid& textureSourceID) override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // ImageProcessingRequestBus interface implementation - IImageObjectPtr LoadImage(const AZStd::string& filePath) override; - IImageObjectPtr LoadImagePreview(const AZStd::string& filePath) override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AZ::Component interface implementation - void Init() override; - void Activate() override; - void Deactivate() override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AzToolsFramework::AssetBrowser::AssetBrowserInteractionNotificationsBus::Handler - void AddSourceFileOpeners(const char* fullSourceFileName, const AZ::Uuid& sourceUUID, AzToolsFramework::AssetBrowser::SourceFileOpenerList& openers) override; - //////////////////////////////////////////////////////////////////////// - - //////////////////////////////////////////////////////////////////////// - // AzToolsFramework::AssetBrowser::AssetBrowserTexturePreviewRequestsBus::Handler - bool GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo) override; - //////////////////////////////////////////////////////////////////////// - - private: - bool HandlesSource(AZStd::string_view fileName) const; - - bool LoadTextureSettings(); - - bool m_textureSettingsLoaded = false; - }; -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.cpp b/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.cpp deleted file mode 100644 index cb97685105..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.cpp +++ /dev/null @@ -1,13 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include "ImageProcessing_precompiled.h" diff --git a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.h b/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.h deleted file mode 100644 index 2972414a1f..0000000000 --- a/Gems/ImageProcessing/Code/Source/ImageProcessing_precompiled.h +++ /dev/null @@ -1,33 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -///////////////////////////////////////////////////////////////////////////// -// Qt -///////////////////////////////////////////////////////////////////////////// -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////// -// AZCore -///////////////////////////////////////////////////////////////////////////// -#include -#include -#include -#include - -///////////////////////////////////////////////////////////////////////////// -//Type definitions -///////////////////////////////////////////////////////////////////////////// -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Android.h b/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Android.h deleted file mode 100644 index ab7622478b..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Android.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "pc" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 0 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 0 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 1 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 0 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Platform.h deleted file mode 100644 index db38b9f980..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android.cmake b/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android_files.cmake deleted file mode 100644 index fd81e56d8d..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Android/platform_android_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Android.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Linux.h b/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Linux.h deleted file mode 100644 index f1186391ad..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Linux.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "pc" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 0 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 1 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 0 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 0 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Platform.h deleted file mode 100644 index 4131e01743..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux.cmake b/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux_files.cmake deleted file mode 100644 index 5f1d5dfd84..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Linux/platform_linux_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Linux.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Mac.h b/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Mac.h deleted file mode 100644 index b2e35a528d..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Mac.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "osx_gl" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 1 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 1 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 0 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 1 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Platform.h deleted file mode 100644 index bc9d313e91..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac.cmake b/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac.cmake deleted file mode 100644 index 4d5680a30d..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac.cmake +++ /dev/null @@ -1,10 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# diff --git a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac_files.cmake deleted file mode 100644 index a25ce357a8..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Mac/platform_mac_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Mac.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Platform.h deleted file mode 100644 index d2a32135c3..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Windows.h b/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Windows.h deleted file mode 100644 index 0410a31986..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/ImageProcessing_Traits_Windows.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER _j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "pc" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 0 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 1 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 0 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 0 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 0 diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows.cmake b/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows_files.cmake deleted file mode 100644 index eabc30e929..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/Windows/platform_windows_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_Windows.h -) diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_Platform.h b/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_Platform.h deleted file mode 100644 index 4ecfd207ca..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_Platform.h +++ /dev/null @@ -1,14 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#include diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_iOS.h b/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_iOS.h deleted file mode 100644 index 55b1be4d77..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/ImageProcessing_Traits_iOS.h +++ /dev/null @@ -1,20 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#pragma once - -#define AZ_TRAIT_IMAGEPROCESSING_BESSEL_FUNCTION_FIRST_ORDER j1 -#define AZ_TRAIT_IMAGEPROCESSING_DEFAULT_PLATFORM "osx_gl" -#define AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS 1 -#define AZ_TRAIT_IMAGEPROCESSING_PVRTEXLIB_USE_WINDLL_IMPORT 0 -#define AZ_TRAIT_IMAGEPROCESSING_SQUISH_DO_NOT_USE_FASTCALL 1 -#define AZ_TRAIT_IMAGEPROCESSING_SUPPORT_TRY_CATCH 1 -#define AZ_TRAIT_IMAGEPROCESSING_USE_BASE10_BYTE_PREFIX 1 diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios.cmake b/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios.cmake deleted file mode 100644 index bafe20e506..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios.cmake +++ /dev/null @@ -1,16 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -# Platform specific cmake file for configuring target compiler/link properties -# based on the active platform -# NOTE: functions in cmake are global, therefore adding functions to this file -# is being avoided to prevent overriding functions declared in other targets platfrom -# specific cmake files diff --git a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios_files.cmake b/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios_files.cmake deleted file mode 100644 index 12d59f3933..0000000000 --- a/Gems/ImageProcessing/Code/Source/Platform/iOS/platform_ios_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ImageProcessing_Traits_Platform.h - ImageProcessing_Traits_iOS.h -) diff --git a/Gems/ImageProcessing/Code/Source/Processing/DDSHeader.h b/Gems/ImageProcessing/Code/Source/Processing/DDSHeader.h deleted file mode 100644 index 9fd0827e21..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/DDSHeader.h +++ /dev/null @@ -1,230 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -*or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once -#include -#include -#include - -//! The following defines and constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with ImageExtensionHelper.h - -#define IMAGE_BUIDER_MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((AZ::u32)(AZ::u8)(ch0) | ((AZ::u32)(AZ::u8)(ch1) << 8) | \ - ((AZ::u32)(AZ::u8)(ch2) << 16) | ((AZ::u32)(AZ::u8)(ch3) << 24)) - -// This header defines constants and structures that are useful when parsing -// DDS files. DDS files were originally designed to use several structures -// and constants that are native to DirectDraw and are defined in ddraw.h, -// such as DDSURFACEDESC2 and DDSCAPS2. This file defines similar -// (compatible) constants and structures so that one can use DDS files -// without needing to include ddraw.h. - - -//Needed to write out DDS files on Mac -#if AZ_TRAIT_IMAGEPROCESSING_DEFINE_DIRECT3D_CONSTANTS -#define DDPF_ALPHAPIXELS 0x00000001 // Texture contains alpha data -#define DDPF_ALPHA 0x00000002 // For alpha channel only uncompressed data -#define DDPF_FOURCC 0x00000004 // Texture contains compressed RGB data -#define DDPF_RGB 0x00000040 // Texture contains uncompressed RGB data -#define DDPF_YUV 0x00000200 // For YUV uncompressed data -#define DDPF_LUMINANCE 0x00020000 // For single channel color uncompressed data - -#define DDSCAPS_COMPLEX 0x00000008 // Must be used on any file that contains more than one surface -#define DDSCAPS_MIPMAP 0x00400000 // Should be used for a mipmap -#define DDSCAPS_TEXTURE 0x00001000 // Required -#endif - -#define DDS_FOURCC 0x00000004 // DDPF_FOURCC -#define DDS_RGB 0x00000040 // DDPF_RGB -#define DDS_LUMINANCE 0x00020000 // DDPF_LUMINANCE -#define DDS_SIGNED 0x00080000 // DDPF_SIGNED -#define DDS_RGBA 0x00000041 // DDPF_RGB | DDPF_ALPHAPIXELS -#define DDS_LUMINANCEA 0x00020001 // DDS_LUMINANCE | DDPF_ALPHAPIXELS -#define DDS_A 0x00000001 // DDPF_ALPHAPIXELS -#define DDS_A_ONLY 0x00000002 // DDPF_ALPHA - -#define DDS_FOURCC_A16B16G16R16 0x00000024 // FOURCC A16B16G16R16 -#define DDS_FOURCC_V16U16 0x00000040 // FOURCC V16U16 -#define DDS_FOURCC_Q16W16V16U16 0x0000006E // FOURCC Q16W16V16U16 -#define DDS_FOURCC_R16F 0x0000006F // FOURCC R16F -#define DDS_FOURCC_G16R16F 0x00000070 // FOURCC G16R16F -#define DDS_FOURCC_A16B16G16R16F 0x00000071 // FOURCC A16B16G16R16F -#define DDS_FOURCC_R32F 0x00000072 // FOURCC R32F -#define DDS_FOURCC_G32R32F 0x00000073 // FOURCC G32R32F -#define DDS_FOURCC_A32B32G32R32F 0x00000074 // FOURCC A32B32G32R32F - -#define DDSD_CAPS 0x00000001l // default -#define DDSD_PIXELFORMAT 0x00001000l -#define DDSD_WIDTH 0x00000004l -#define DDSD_HEIGHT 0x00000002l -#define DDSD_LINEARSIZE 0x00080000l - -#define DDS_HEADER_FLAGS_TEXTURE 0x00001007 // DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_PIXELFORMAT -#define DDS_HEADER_FLAGS_MIPMAP 0x00020000 // DDSD_MIPMAPCOUNT -#define DDS_HEADER_FLAGS_VOLUME 0x00800000 // DDSD_DEPTH -#define DDS_HEADER_FLAGS_PITCH 0x00000008 // DDSD_PITCH -#define DDS_HEADER_FLAGS_LINEARSIZE 0x00080000 // DDSD_LINEARSIZE - -#define DDS_SURFACE_FLAGS_TEXTURE 0x00001000 // DDSCAPS_TEXTURE -#define DDS_SURFACE_FLAGS_MIPMAP 0x00400008 // DDSCAPS_COMPLEX | DDSCAPS_MIPMAP -#define DDS_SURFACE_FLAGS_CUBEMAP 0x00000008 // DDSCAPS_COMPLEX - -#define DDS_CUBEMAP_POSITIVEX 0x00000600 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEX -#define DDS_CUBEMAP_NEGATIVEX 0x00000a00 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEX -#define DDS_CUBEMAP_POSITIVEY 0x00001200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEY -#define DDS_CUBEMAP_NEGATIVEY 0x00002200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEY -#define DDS_CUBEMAP_POSITIVEZ 0x00004200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_POSITIVEZ -#define DDS_CUBEMAP_NEGATIVEZ 0x00008200 // DDSCAPS2_CUBEMAP | DDSCAPS2_CUBEMAP_NEGATIVEZ - -#define DDS_CUBEMAP_ALLFACES (DDS_CUBEMAP_POSITIVEX | DDS_CUBEMAP_NEGATIVEX | \ - DDS_CUBEMAP_POSITIVEY | DDS_CUBEMAP_NEGATIVEY | \ - DDS_CUBEMAP_POSITIVEZ | DDS_CUBEMAP_NEGATIVEZ) - -#define DDS_FLAGS_VOLUME 0x00200000 // DDSCAPS2_VOLUME - -#define DDS_RESF1_NORMALMAP 0x01000000 -#define DDS_RESF1_DSDT 0x02000000 - - -namespace ImageProcessing -{ - const static AZ::u32 FOURCC_DX10 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', '1', '0'); - const static AZ::u32 FOURCC_DDS = IMAGE_BUIDER_MAKEFOURCC('D', 'D', 'S', ' '); - const static AZ::u32 FOURCC_FYRC = IMAGE_BUIDER_MAKEFOURCC('F', 'Y', 'R', 'C'); - - //The values of each elements in this enum should be same as ITexture ETEX_TileMode enum. - enum DDS_TileMode : AZ::u8 - { - eTM_None = 0, - eTM_LinearPadded, - eTM_Optimal, - }; - - struct DDS_PIXELFORMAT - { - AZ::u32 dwSize; - AZ::u32 dwFlags; - AZ::u32 dwFourCC; - AZ::u32 dwRGBBitCount; - AZ::u32 dwRBitMask; - AZ::u32 dwGBitMask; - AZ::u32 dwBBitMask; - AZ::u32 dwABitMask; - - const bool operator == (const DDS_PIXELFORMAT& fmt) const - { - return dwFourCC == fmt.dwFourCC && - dwFlags == fmt.dwFlags && - dwRGBBitCount == fmt.dwRGBBitCount && - dwRBitMask == fmt.dwRBitMask && - dwGBitMask == fmt.dwGBitMask && - dwBBitMask == fmt.dwBBitMask && - dwABitMask == fmt.dwABitMask && - dwSize == fmt.dwSize; - } - - }; - - struct DDS_HEADER_DXT10 - { - // we're unable to use native enums, so we use AZ::u32 instead. - AZ::u32 /*DXGI_FORMAT*/ dxgiFormat; - AZ::u32 /*D3D10_RESOURCE_DIMENSION*/ resourceDimension; - AZ::u32 miscFlag; - AZ::u32 arraySize; - AZ::u32 reserved; - }; - - struct DDS_HEADER - { - AZ::u32 dwSize; - AZ::u32 dwHeaderFlags; - AZ::u32 dwHeight; - AZ::u32 dwWidth; - AZ::u32 dwPitchOrLinearSize; - AZ::u32 dwDepth; // only if DDS_HEADER_FLAGS_VOLUME is set in dwHeaderFlags - AZ::u32 dwMipMapCount; - AZ::u32 dwAlphaBitDepth; - AZ::u32 dwReserved1; // Crytek image flags - float fAvgBrightness; // Average top mip brightness. Could be f16/half - float cMinColor[4]; - float cMaxColor[4]; - DDS_PIXELFORMAT ddspf; - AZ::u32 dwSurfaceFlags; - AZ::u32 dwCubemapFlags; - AZ::u8 bNumPersistentMips; - AZ::u8 tileMode; //DDS_TileMode - AZ::u8 bReserved2[6]; - AZ::u32 dwTextureStage; - - - inline const bool IsValid() const { return sizeof(*this) == dwSize; } - inline const bool IsDX10Ext() const { return ddspf.dwFourCC == FOURCC_DX10; } - inline const AZ::u32 GetMipCount() const { return AZStd::GetMax(1u, (AZ::u32)dwMipMapCount); } - - inline const size_t GetFullHeaderSize() const - { - if (IsDX10Ext()) - { - return sizeof(DDS_HEADER) + sizeof(DDS_HEADER_DXT10); - } - - return sizeof(DDS_HEADER); - } - }; - - // standard description of file header - struct DDS_FILE_DESC - { - AZ::u32 dwMagic; - DDS_HEADER header; - - inline const bool IsValid() const { return dwMagic == FOURCC_DDS && header.IsValid(); } - inline const size_t GetFullHeaderSize() const { return sizeof(dwMagic) + header.GetFullHeaderSize(); } - }; - - // chunk identifier - const static AZ::u32 FOURCC_CExt = IMAGE_BUIDER_MAKEFOURCC('C', 'E', 'x', 't'); // Crytek extension start - const static AZ::u32 FOURCC_CEnd = IMAGE_BUIDER_MAKEFOURCC('C', 'E', 'n', 'd'); // Crytek extension end - const static AZ::u32 FOURCC_AttC = IMAGE_BUIDER_MAKEFOURCC('A', 't', 't', 'C'); // Chunk Attached Channel - - //Fourcc for pixel formats which aren't supported by dx10, such as astc formats, etc formats, pvrtc formats - //They are used for dwFourCC of dds header's DDS_PIXELFORMAT to identify non-dx10 pixel formats - const static AZ::u32 FOURCC_EAC_R11 = IMAGE_BUIDER_MAKEFOURCC('E', 'A', 'R', ' '); - const static AZ::u32 FOURCC_EAC_RG11 = IMAGE_BUIDER_MAKEFOURCC('E', 'A', 'R', 'G'); - const static AZ::u32 FOURCC_ETC2 = IMAGE_BUIDER_MAKEFOURCC('E', 'T', '2', ' '); - const static AZ::u32 FOURCC_ETC2A = IMAGE_BUIDER_MAKEFOURCC('E', 'T', '2', 'A'); - const static AZ::u32 FOURCC_PVRTC2 = IMAGE_BUIDER_MAKEFOURCC('P', 'V', 'R', '2'); - const static AZ::u32 FOURCC_PVRTC4 = IMAGE_BUIDER_MAKEFOURCC('P', 'V', 'R', '4'); - const static AZ::u32 FOURCC_ASTC_4x4 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '4', '4'); - const static AZ::u32 FOURCC_ASTC_5x4 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '5', '4'); - const static AZ::u32 FOURCC_ASTC_5x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '5', '5'); - const static AZ::u32 FOURCC_ASTC_6x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '6', '5'); - const static AZ::u32 FOURCC_ASTC_6x6 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '6', '6'); - const static AZ::u32 FOURCC_ASTC_8x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '8', '5'); - const static AZ::u32 FOURCC_ASTC_8x6 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '8', '6'); - const static AZ::u32 FOURCC_ASTC_10x5 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', '5'); - const static AZ::u32 FOURCC_ASTC_10x6 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', '6'); - const static AZ::u32 FOURCC_ASTC_8x8 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', '8', '8'); - const static AZ::u32 FOURCC_ASTC_10x8 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', '8'); - const static AZ::u32 FOURCC_ASTC_10x10 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'A', 'A'); - const static AZ::u32 FOURCC_ASTC_12x10 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'C', 'A'); - const static AZ::u32 FOURCC_ASTC_12x12 = IMAGE_BUIDER_MAKEFOURCC('A', 'S', 'C', 'C'); - - //legacy formats names. they are only used for load rc.exe's dds formats - const static AZ::u32 FOURCC_DXT1 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', 'T', '1'); - const static AZ::u32 FOURCC_DXT3 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', 'T', '3'); - const static AZ::u32 FOURCC_DXT5 = IMAGE_BUIDER_MAKEFOURCC('D', 'X', 'T', '5'); - const static AZ::u32 FOURCC_3DCP = IMAGE_BUIDER_MAKEFOURCC('A', 'T', 'I', '1'); - const static AZ::u32 FOURCC_3DC = IMAGE_BUIDER_MAKEFOURCC('A', 'T', 'I', '2'); -} diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp deleted file mode 100644 index b5fc329a03..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.cpp +++ /dev/null @@ -1,1014 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -//qt has convenience functions to handle file -#include -#include - -//for texture splitting -//mininum number of low level mips will be saved in the base file. -#define MinPersistantMips 3 -//mininum texture size to be splitted. A texture will only be split when the size is larger than this number -#define MinSizeToSplit 1<<5 - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) - #if defined(TOOLS_SUPPORT_JASPER) - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageProcess, Jasper) - #endif - #if defined(TOOLS_SUPPORT_PROVO) - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageProcess, Provo) - #endif - #if defined(TOOLS_SUPPORT_SALEM) - #include AZ_RESTRICTED_FILE_EXPLICIT(ImageProcess, Salem) - #endif -#endif - -namespace ImageProcessing -{ - - IImageObjectPtr ImageConvertProcess::GetOutputImage() - { - if (m_image) - { - return m_image->Get(); - } - return nullptr; - } - - IImageObjectPtr ImageConvertProcess::GetOutputAlphaImage() - { - return m_alphaImage; - } - - IImageObjectPtr ImageConvertProcess::GetOutputDiffCubemap() - { - return m_diffCubemapImage; - } - - void ImageConvertProcess::GetAppendOutputFilePaths(AZStd::vector& outPaths) - { - for (const auto& path : m_productFilepaths) - { - outPaths.push_back(path); - } - } - - ImageConvertProcess::ImageConvertProcess(const IImageObjectPtr inputImage, const TextureSettings& textureSetting, - const PresetSettings& presetSetting, bool isPreview, bool isStreaming, bool canOverridePreset, - const AZStd::string& outputPath, const AZStd::string& platformId) : - m_inputImage(inputImage), - m_textureSetting(textureSetting), - m_presetSetting(presetSetting), - m_canOverridePreset(canOverridePreset), - m_image(nullptr), - m_isPreview(isPreview), - m_outputPath(outputPath), - m_progressStep(0), - m_isFinished(false), - m_isSucceed(false), - m_processTime(0), - m_isStreaming(isStreaming), - m_platformId(platformId) - { - } - - ImageConvertProcess::~ImageConvertProcess() - { - delete m_image; - } - - bool ImageConvertProcess::IsConvertToCubemap() - { - return m_presetSetting.m_cubemapSetting != nullptr; - } - - void ImageConvertProcess::UpdateProcess() - { - if (m_isFinished) - { - return; - } - - switch (m_progressStep) - { - case StepValidateInput: - //validate - if (!ValidateInput()) - { - m_isSucceed = false; - break; - } - - //set start time - m_startTime = AZStd::GetTimeUTCMilliSecond(); - - //identify the alpha content of input image if gloss from normal wasn't set - m_alphaContent = m_inputImage->GetAlphaContent(); - - //create image for process - m_image = new ImageToProcess(IImageObjectPtr(m_inputImage->Clone())); - - break; - case StepGenerateColorChart: - //GenerateColorChart. - if (m_presetSetting.m_isColorChart) - { - m_image->CreateColorChart(); - } - break; - case StepConvertToLinear: - //convert to linear space and the output image pixel format should be rgba32f - ConvertToLinear(); - break; - case StepSwizzle: - //convert texture format. - if (m_presetSetting.m_swizzle.size() >= 4) - { - m_image->Get()->Swizzle(m_presetSetting.m_swizzle.substr(0, 4).c_str()); - m_alphaContent = m_image->Get()->GetAlphaContent(); - } - - //convert gloss map (alhpa channel) from legacy distribution to new one - if (m_presetSetting.m_isLegacyGloss) - { - m_image->Get()->ConvertLegacyGloss(); - } - break; - case StepOverridePreset: - if (m_canOverridePreset) - { - // Set the pixel format to BC3 if the source contains greyscale alpha and BC1 if it does not. - if (m_presetSetting.m_pixelFormat == ePixelFormat_BC1 - || m_presetSetting.m_pixelFormat == ePixelFormat_BC1a - || m_presetSetting.m_pixelFormat == ePixelFormat_BC3) - { - if (m_alphaContent == EAlphaContent::eAlphaContent_Greyscale) - { - m_presetSetting.m_pixelFormat = ePixelFormat_BC3; - } - else if (m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlackAndWhite - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlack - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyWhite) - { - m_presetSetting.m_pixelFormat = ePixelFormat_BC1a; - } - else - { - m_presetSetting.m_pixelFormat = ePixelFormat_BC1; - } - } - } - break; - case StepCubemapLayout: - //convert cubemap image's layout to vertical strip used in game. - if (IsConvertToCubemap()) - { - if (!m_image->ConvertCubemapLayout(CubemapLayoutVertical)) - { - m_image->Set(nullptr); - } - } - break; - case StepPreNormalize: - //normalize base image before mipmap generation if glossfromnormals is enabled and require normalize - if (m_presetSetting.m_isMipRenormalize && m_presetSetting.m_glossFromNormals) - { - // Normalize the base mip map. This has to be done explicitly because we need to disable mip renormalization to - // preserve the normal length when deriving the normal variance - m_image->Get()->NormalizeVectors(0, 1); - } - break; - case StepDiffCubemap: - //create diffuse cubemap. We need to have better way to handle one input multiple export settings later. - CreateDiffuseCubemap(); - break; - case StepMipmap: - //generate mipmaps - if (IsConvertToCubemap()) - { - FillCubemapMipmaps(); - } - else - { - FillMipmaps(); - } - //add image flag - if (m_presetSetting.m_suppressEngineReduce || m_textureSetting.m_suppressEngineReduce) - { - m_image->Get()->AddImageFlags(EIF_SupressEngineReduce); - } - break; - case StepGlossFromNormal: - //get gloss from normal for all mipmaps and save to alpha channel - if (m_presetSetting.m_glossFromNormals) - { - bool hasAlpha = (m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlack - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyBlackAndWhite - || m_alphaContent == EAlphaContent::eAlphaContent_Greyscale); - - m_image->Get()->GlossFromNormals(hasAlpha); - //set alpha content so it won't be ignored later. - m_alphaContent = EAlphaContent::eAlphaContent_Greyscale; - } - break; - case StepPostNormalize: - //normalize all the other mipmaps - if (!IsConvertToCubemap() && m_presetSetting.m_isMipRenormalize) - { - if (m_presetSetting.m_glossFromNormals) - { - //normalize other mips except first mip - m_image->Get()->NormalizeVectors(1, 100); - } - else - { - //normalize all mips - m_image->Get()->NormalizeVectors(0, 100); - } - - m_image->Get()->AddImageFlags(EIF_RenormalizedTexture); - } - break; - case StepCreateHighPass: - if (m_presetSetting.m_highPassMip > 0) - { - m_image->CreateHighPass(m_presetSetting.m_highPassMip); - } - break; - case StepConvertOutputColorSpace: - //comvert image from linear space to desired output color space - ConvertToOuputColorSpace(); - break; - case StepAlphaImage: - //save alpha channel to separate image if it's needed - CreateAlphaImage(); - break; - case StepConvertPixelFormat: - //convert pixel format - ConvertPixelformat(); - break; - case StepSaveToFile: - //save to file - if (!m_isPreview) - { - m_isSucceed = SaveOutput(); - } - else - { - m_isSucceed = true; - } - break; - } - - m_progressStep++; - - if (m_image == nullptr || m_image->Get() == nullptr || m_progressStep >= StepAll) - { - m_isFinished = true; - AZStd::sys_time_t endTime = AZStd::GetTimeUTCMilliSecond(); - m_processTime = aznumeric_cast((endTime - m_startTime) / 1000); - } - - //output conversion log - if (m_isSucceed && m_isFinished) - { - const uint32 sizeTotal = m_image->Get()->GetTextureMemory(); - if (m_isPreview) - { - AZ_TracePrintf("Image Processing", "Image ( %d bytes) converted in %f seconds\n", sizeTotal, m_processTime); - } - else - { - AZ_TracePrintf("Image Processing", "Image converted and saved to %s ( %d bytes) with %f seconds\n", m_outputPath.c_str(), - sizeTotal, m_processTime); - } - } - } - - void ImageConvertProcess::ProcessAll() - { - while (!m_isFinished) - { - UpdateProcess(); - } - } - - float ImageConvertProcess::GetProgress() - { - return m_progressStep / (float)StepAll; - } - - bool ImageConvertProcess::IsFinished() - { - return m_isFinished; - } - - bool ImageConvertProcess::IsSucceed() - { - return m_isSucceed; - } - - //function to get desired output image extent - void GetOutputExtent(AZ::u32 inputWidth, AZ::u32 inputHeight, AZ::u32& outWidth, AZ::u32& outHeight, AZ::u32& outReduce, - const TextureSettings* textureSettings, const PresetSettings* presetSettings) - { - outWidth = inputWidth; - outHeight = inputHeight; - outReduce = 0; - - if (textureSettings == nullptr || presetSettings == nullptr) - { - return; - } - - //don't do any reduce for color chart - if (presetSettings->m_isColorChart) - { - return; - } - - //get suitable size for dest pixel format - CPixelFormats::GetInstance().GetSuitableImageSize(presetSettings->m_pixelFormat, inputWidth, inputHeight, - outWidth, outHeight); - - //desired reduce level. 1 means reduce one level - uint sizeReduceLevel = textureSettings->m_sizeReduceLevel; - - outReduce = 0; - - //reduce to not exceed max texture size - if (presetSettings->m_maxTextureSize > 0) - { - while (outWidth > presetSettings->m_maxTextureSize || outHeight > presetSettings->m_maxTextureSize) - { - outWidth >>= 1; - outHeight >>= 1; - outReduce++; - } - } - - //if it requires to reduce more and the result size will still larger than min texture size, then reduce - while (outReduce < sizeReduceLevel && - (outWidth >= presetSettings->m_minTextureSize * 2 && outHeight >= presetSettings->m_minTextureSize * 2)) - { - outWidth >>= 1; - outHeight >>= 1; - outReduce++; - } - } - - bool ImageConvertProcess::ConvertToLinear() - { - //de-gamma only if the input is sRGB. this will convert other uncompressed format to RGBA32F - return m_image->GammaToLinearRGBA32F(m_presetSetting.m_srcColorSpace == ColorSpace::sRGB); - } - - //mipmap generation - bool ImageConvertProcess::FillMipmaps() - { - //this function only works with pixel format rgba32f - const EPixelFormat srcPixelFormat = m_image->Get()->GetPixelFormat(); - if (srcPixelFormat != ePixelFormat_R32G32B32A32F) - { - AZ_Assert(false, "%s only works with pixel format rgba32f", __FUNCTION__); - return false; - } - - //only if the src image has one mip - if (m_image->Get()->GetMipCount() != 1) - { - AZ_Assert(false, "%s called for a mipmapped image. ", __FUNCTION__); - return false; - } - - //get output image size - uint32 outWidth; - uint32 outHeight; - uint32 outReduce = 0; - GetOutputExtent(m_image->Get()->GetWidth(0), m_image->Get()->GetHeight(0), outWidth, outHeight, outReduce, &m_textureSetting, - &m_presetSetting); - - //max mipmap count - uint32 mipCount = UINT32_MAX; - if (m_presetSetting.m_mipmapSetting == nullptr || !m_textureSetting.m_enableMipmap) - { - mipCount = 1; - } - - //create new new output image with proper side - IImageObjectPtr outImage(IImageObject::CreateImage(outWidth, outHeight, mipCount, ePixelFormat_R32G32B32A32F)); - - //filter setting for mip map generation - float blurH = 0; - float blurV = 0; - - //fill mipmap data for uncompressed output image - for (uint32 mip = 0; mip < outImage->GetMipCount(); mip++) - { - FilterImage(m_textureSetting.m_mipGenType, m_textureSetting.m_mipGenEval, blurH, blurV, m_image->Get(), 0, outImage, mip, nullptr, nullptr); - } - - //transfer alpha coverage - if (m_textureSetting.m_maintainAlphaCoverage) - { - outImage->TransferAlphaCoverage(&m_textureSetting, m_image->Get()); - } - - //set back to image - m_image->Set(outImage); - return true; - } - - void ImageConvertProcess::CreateAlphaImage() - { - //if alpha content doesn't have alpha or we need to discard alpha, skip - //we won't create alpha image for cubemap too - if (m_alphaContent == EAlphaContent::eAlphaContent_Absent - || m_alphaContent == EAlphaContent::eAlphaContent_OnlyWhite - || m_presetSetting.m_discardAlpha || IsConvertToCubemap()) - { - return; - } - - //Ensure that the PixelFormatAlpha is set otherwise no need to create m_alphaImage - if (m_presetSetting.m_pixelFormatAlpha == ePixelFormat_Unknown) - { - return; - } - - //now create alpha image - ImageToProcess alphaImage(m_image->Get()); - alphaImage.ConvertFormat(ePixelFormat_A8); - - - if(CPixelFormats::GetInstance().IsFormatSingleChannel(m_presetSetting.m_pixelFormatAlpha)) - { - alphaImage.ConvertFormat(m_presetSetting.m_pixelFormatAlpha); - } - else - { - //For PVRTC compression we need to clear out the alpha to get accurate rgb compression. - if (IsPVRTCFormat(m_presetSetting.m_pixelFormat) || IsASTCFormat(m_presetSetting.m_pixelFormat)) - { - alphaImage.ConvertFormat(ePixelFormat_R8G8B8A8); - alphaImage.Get()->Swizzle("rgb1"); - alphaImage.ConvertFormat(m_presetSetting.m_pixelFormatAlpha); - } - else - { - AZ_Assert(false, "Did you apply the correct pixel format for PixelFormatAlpha?"); - } - } - - //get final result and save it to member variable for later use - m_alphaImage = alphaImage.Get(); - - m_image->Get()->AddImageFlags(EIF_AttachedAlpha); - } - - //pixel format convertions - bool ImageConvertProcess::ConvertPixelformat() - { - - //For PVRTC compression we need to clear out the alpha to get accurate rgb compression. - if(m_alphaImage && (IsPVRTCFormat(m_presetSetting.m_pixelFormat) || IsASTCFormat(m_presetSetting.m_pixelFormat))) - { - m_image->Get()->Swizzle("rgb1"); - } - - - //set up compress option - ICompressor::EQuality quality; - if (m_isPreview) - { - quality = ICompressor::eQuality_Preview; - } - else - { - quality = ICompressor::eQuality_Normal; - } - m_image->GetCompressOption().compressQuality = quality; - m_image->GetCompressOption().rgbWeight = m_presetSetting.GetColorWeight(); - m_image->ConvertFormat(m_presetSetting.m_pixelFormat); - return true; - } - - //convert color space from linear to sRGB space if it's neccessary - bool ImageConvertProcess::ConvertToOuputColorSpace() - { - if (m_presetSetting.m_destColorSpace == ColorSpace::sRGB) - { - m_image->LinearToGamma(); - } - else if (m_presetSetting.m_destColorSpace == ColorSpace::autoSelect) - { - //convert to sRGB color space if it's dark image (converting bright images decreases image quality) - bool bThresholded = false; - { - Histogram<256> histogram; - if (ComputeLuminanceHistogram(m_image->Get(), histogram)) - { - const size_t medianBinIndex = 116; - float percentage = histogram.getPercentage(medianBinIndex, 255); - - // The image has significant amount of dark pixels, it's good to use sRGB - bThresholded = (percentage < 50.0f); - } - } - - if (bThresholded) - { - bool convertToSRGB = true; - - // if the image is BC1 compressable, additionally estimate the conversion error - // to only convert if it doesn't introduce error - if (CPixelFormats::GetInstance().IsImageSizeValid(ePixelFormat_BC1, m_image->Get()->GetWidth(0), - m_image->Get()->GetHeight(0), false)) - { - //get image in RGB space - ImageToProcess imageProcess(m_image->Get()); - imageProcess.LinearToGamma(); - - ICompressor::CompressOption option; - option.compressQuality = ICompressor::eQuality_Preview; - option.rgbWeight = m_presetSetting.GetColorWeight(); - - float errorLinearBC1; - float errorSrgbBC1; - GetBC1CompressionErrors(m_image->Get(), errorLinearBC1, errorSrgbBC1, option); - - // Don't convert if it would lower the image quality when saved as sRGB according to GetDXT1GammaCompressionError() - if (errorSrgbBC1 >= errorLinearBC1) - { - convertToSRGB = false; - } - } - - // our final conclusion: if the texture had a significant percentage of dark pixels and, - // if applicable, it was BC1 compressable and gamma compression wouldn't introduce error, - // then we convert it to sRGB - if (convertToSRGB) - { - m_image->LinearToGamma(); - } - } - } - return true; - } - - bool ImageConvertProcess::ValidateInput() - { - //valid the input image and output settings here. - uint32 dwWidth, dwHeight; - dwWidth = m_inputImage->GetWidth(0); - dwHeight = m_inputImage->GetHeight(0); - - EPixelFormat dstFmt = m_presetSetting.m_pixelFormat; - - //check if whether input image can be a cubemap - if (m_presetSetting.m_cubemapSetting) - { - if (CubemapLayout::GetCubemapLayoutInfo(m_inputImage) == nullptr) - { - AZ_Error("Image Processing", false, "Invalid image size %dx%d using as cubemap. Requires power of two with 6x1, 1x6, 4x3 or 3x4 layouts", dwWidth, dwHeight); - return false; - } - } - else if (!CPixelFormats::GetInstance().IsImageSizeValid(dstFmt, dwWidth, dwHeight, false)) - { - AZ_Warning("Image Processing", false, "Image size will be scaled for pixel format %s", CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->szName); - } - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - if (ImageProcess##PrivateName::DoesSupport(m_platformId))\ - {\ - if(!ImageProcess##PrivateName::IsPixelFormatSupported(m_presetSetting.m_pixelFormat))\ - {\ - AZ_Error("Image Processing", false, "Unsupported pixel format %s for %s",\ - CPixelFormats::GetInstance().GetPixelFormatInfo(dstFmt)->szName, m_platformId.c_str());\ - return false;\ - }\ - } - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - return true; - } - - bool ImageConvertProcess::SaveOutput() - { - //if the path wasn't specified, skip - if (m_outputPath.empty()) - { - AZ_Error("Image Processing", false, "No output path provided for saving"); - return false; - } - - //set all mips as presistent mips by default. it will be modified if the image is splitted later - m_image->Get()->SetNumPersistentMips(m_image->Get()->GetMipCount()); - - //split - if (m_isStreaming && m_presetSetting.m_numStreamableMips > 0) - { - IImageObjectPtr curImage = m_image->Get(); - - if (curImage->GetMipCount() > MinPersistantMips && (curImage->GetWidth(0) > MinSizeToSplit || - curImage->GetWidth(0) > MinSizeToSplit)) - { - //calculate final persistance mip count - AZ::u32 persistantMips = MinPersistantMips; - if (m_presetSetting.m_numStreamableMips < curImage->GetMipCount() - MinPersistantMips) - { - persistantMips = curImage->GetMipCount() - m_presetSetting.m_numStreamableMips; - } - curImage->SetNumPersistentMips(persistantMips); - curImage->AddImageFlags(EIF_Splitted); - - //add flags for alpha image too, assuming alpha image has same size as origin - if (m_alphaImage) - { - m_alphaImage->SetNumPersistentMips(persistantMips); - m_alphaImage->AddImageFlags(EIF_Splitted); - } - } - } - -#if defined(AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS) -#define AZ_RESTRICTED_PLATFORM_EXPANSION(CodeName, CODENAME, codename, PrivateName, PRIVATENAME, privatename, PublicName, PUBLICNAME, publicname, PublicAuxName1, PublicAuxName2, PublicAuxName3)\ - if (ImageProcess##PrivateName::DoesSupport(m_platformId))\ - {\ - ImageProcess##PrivateName::PrepareImageForExport(m_image->Get());\ - ImageProcess##PrivateName::PrepareImageForExport(m_alphaImage);\ - } - AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -#undef AZ_RESTRICTED_PLATFORM_EXPANSION -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - - AZStd::vector outputFilePaths; - if (!m_image->Get()->SaveImage(m_outputPath.c_str(), m_alphaImage, outputFilePaths)) - { - AZ_Error("Image Processing", false, "Save image to %s failed", m_outputPath.c_str()); - return false; - } - - for (auto& path : outputFilePaths) - { - m_productFilepaths.push_back(path); - } - return true; - } - - ImageConvertProcess* CreateImageConvertProcess(const AZStd::string& imageFilePath, const AZStd::string& exportDir - , const PlatformName& platformName, AZ::SerializeContext* context) - { - AZStd::string metafilePath; - BuilderSettingManager::Instance()->MetafilePathFromImagePath(imageFilePath, metafilePath); - TextureSettings textureSettings; - - MultiplatformTextureSettings multiTextureSetting; - bool canOverridePreset = false; - - multiTextureSetting = TextureSettings::GetMultiplatformTextureSetting(imageFilePath, canOverridePreset, context); - if (multiTextureSetting.empty()) - { - AZ_Error("Image Processing", false, "Could not determine export settings for image file [%s] due to previous error(s). Skipping export...", imageFilePath.c_str()); - return nullptr; - } - - if (multiTextureSetting.find(platformName) != multiTextureSetting.end()) - { - textureSettings = multiTextureSetting[platformName]; - } - else - { - PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - if (multiTextureSetting.find(defaultPlatform) != multiTextureSetting.end()) - { - textureSettings = multiTextureSetting[defaultPlatform]; - } - else - { - textureSettings = (*multiTextureSetting.begin()).second; - } - } - - //load image. Do it earlier so GetSuggestedPreset function could use the information of file to choose better preset - IImageObjectPtr srcImage(LoadImageFromFile(imageFilePath)); - if (srcImage == nullptr) - { - AZ_Error("Image Processing", false, "Load image file %s failed", imageFilePath.c_str()); - return nullptr; - } - - //if get textureSetting failed, use the default texture setting, and find suitable preset for this file - //in very rare user case, an old texture setting file may not have a preset. We fix it over here too. - if (textureSettings.m_preset.IsNull()) - { - textureSettings.m_preset = BuilderSettingManager::Instance()->GetSuggestedPreset(imageFilePath, srcImage); - } - - //get preset - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(textureSettings.m_preset, platformName); - - if (preset == nullptr) - { - AZStd::string uuidStr; - textureSettings.m_preset.ToString(uuidStr); - AZ_Assert(false, "%s cannot find image preset with ID %s.", imageFilePath.c_str(), uuidStr.c_str()); - return nullptr; - } - - //generate export file name - QDir dir(exportDir.c_str()); - if (!dir.exists()) - { - dir.mkpath("."); - } - AZStd::string fileName, outputPath; - AzFramework::StringFunc::Path::GetFileName(imageFilePath.c_str(), fileName); - fileName += ".dds"; - AzFramework::StringFunc::Path::Join(exportDir.c_str(), fileName.c_str(), outputPath, true, true); - - //if it need streaming - bool isStreaming = BuilderSettingManager::Instance()->GetBuilderSetting(platformName)->m_enableStreaming; - - //create convert process - ImageConvertProcess* process = new ImageConvertProcess(srcImage, textureSettings, *preset, false, isStreaming, - canOverridePreset, outputPath, platformName); - - return process; - } - - void ImageConvertProcess::CreateDiffuseCubemap() - { - //only need to convert if the diffuseGenPreset in cubemap setting is set - if (m_presetSetting.m_cubemapSetting == nullptr || m_presetSetting.m_cubemapSetting->m_diffuseGenPreset.IsNull()) - { - return; - } - - //need to create another ImageConvertProcess - //prepare preset setting and texture setting - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset( - m_presetSetting.m_cubemapSetting->m_diffuseGenPreset, m_platformId); - - TextureSettings textureSettings = m_textureSetting; - m_textureSetting.m_preset = m_presetSetting.m_cubemapSetting->m_diffuseGenPreset; - - if (preset == nullptr) - { - AZ_Error("Image Processing", false,"Couldn't find preset for diffuse cubemap generation"); - return; - } - - //generate export file name. add "_diff" in the end of file name - AZStd::string fileName, folderName, outProductPath; - AzFramework::StringFunc::Path::GetFileName(m_outputPath.c_str(), fileName); - AzFramework::StringFunc::Path::GetFullPath(m_outputPath.c_str(), folderName); - fileName += "_diff.dds"; - AzFramework::StringFunc::Path::Join(folderName.c_str(), fileName.c_str(), outProductPath, true, true); - - //create convert process - //we might be able to use current image result for the input to save some performance. But it's more safe to use input image - bool canOverridePreset = false; - ImageConvertProcess* process = new ImageConvertProcess(m_inputImage, textureSettings, *preset, - false, m_isStreaming, canOverridePreset, outProductPath, m_platformId); - if (process) - { - process->ProcessAll(); - if (process->IsSucceed()) - { - process->GetAppendOutputFilePaths(m_productFilepaths); - m_diffCubemapImage = process->m_image->Get(); - } - else - { - AZ_Error("Image Processing", false, "Convert diffuse cubemap failed"); - } - delete process; - } - else - { - AZ_Error("Image Processing", false, "Create convert process for diffuse cubemap failed"); - } - } - - bool ConvertImageFile(const AZStd::string& imageFilePath, const AZStd::string& exportDir, - AZStd::vector& outPaths, const PlatformName& platformName, AZ::SerializeContext* context) - { - bool result = false; - ImageConvertProcess* process = CreateImageConvertProcess(imageFilePath, exportDir, platformName, context); - if (process) - { - process->ProcessAll(); - result = process->IsSucceed(); - if (result) - { - process->GetAppendOutputFilePaths(outPaths); - } - delete process; - } - return result; - } - - IImageObjectPtr MergeOutputImageForPreview(IImageObjectPtr image, IImageObjectPtr alphaImage) - { - if (!image) - { - return IImageObjectPtr(); - } - - ImageToProcess imageToProcess(image); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - IImageObjectPtr previewImage = imageToProcess.Get(); - - // If there is separate Alpha image, combine it with output - if (alphaImage) - { - // Create pixel operation function for rgb and alpha images - IPixelOperationPtr imageOp = CreatePixelOperation(ePixelFormat_R8G8B8A8); - IPixelOperationPtr alphaOp = CreatePixelOperation(ePixelFormat_A8); - - // Convert the alpha image to A8 first - ImageToProcess imageToProcess2(alphaImage); - imageToProcess2.ConvertFormat(ePixelFormat_A8); - IImageObjectPtr previewImageAlpha = imageToProcess2.Get(); - - const uint32 imageMips = previewImage->GetMipCount(); - const uint32 alphaMips = previewImageAlpha->GetMipCount(); - - // Get count of bytes per pixel for both rgb and alpha images - uint32 imagePixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat_R8G8B8A8)->bitsPerBlock / 8; - uint32 alphaPixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(ePixelFormat_A8)->bitsPerBlock / 8; - - AZ_Assert(imageMips <= alphaMips, "Mip level of alpha image is less than origin image!"); - - // For each mip level, set the alpha value to the image - for (uint32 mipLevel = 0; mipLevel < imageMips; ++mipLevel) - { - const uint32 pixelCount = previewImage->GetPixelCount(mipLevel); - const uint32 alphaPixelCount = previewImageAlpha->GetPixelCount(mipLevel); - - AZ_Assert(pixelCount == alphaPixelCount, "Pixel count for image and alpha image at mip level %d is not equal!", mipLevel); - - uint8* imageBuf; - uint32 pitch; - previewImage->GetImagePointer(mipLevel, imageBuf, pitch); - - uint8* alphaBuf; - uint32 alphaPitch; - previewImageAlpha->GetImagePointer(mipLevel, alphaBuf, alphaPitch); - - float rAlpha, gAlpha, bAlpha, aAlpha, rImage, gImage, bImage, aImage; - - for (uint32 i = 0; i < pixelCount; ++i, imageBuf += imagePixelBytes, alphaBuf += alphaPixelBytes) - { - alphaOp->GetRGBA(alphaBuf, rAlpha, gAlpha, bAlpha, aAlpha); - imageOp->GetRGBA(imageBuf, rImage, gImage, bImage, aImage); - imageOp->SetRGBA(imageBuf, rImage, gImage, bImage, aAlpha); - } - } - } - - return previewImage; - } - - // This function will convert compressed image to RGBA32. - // Also if the image is in sRGB space will convert it to Linear space. - IImageObjectPtr GetUncompressedLinearImage(IImageObjectPtr ddsImage) - { - if (ddsImage) - { - ImageToProcess processImage(ddsImage); - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(ddsImage->GetPixelFormat())) - { - processImage.ConvertFormat(ePixelFormat_R32G32B32A32F); - } - if (ddsImage->HasImageFlags(EIF_SRGBRead)) - { - processImage.GammaToLinearRGBA32F(true); - } - return processImage.Get(); - } - return nullptr; - } - - float GetErrorBetweenImages(IImageObjectPtr inputImage1, IImageObjectPtr inputImage2) - { - // First make sure images are in uncompressed format and linear space - // Convert them if necessary - IImageObjectPtr image1 = GetUncompressedLinearImage(inputImage1); - IImageObjectPtr image2 = GetUncompressedLinearImage(inputImage2); - - const float errorValue = FLT_MAX; - - if (!image1 || !image2) - { - AZ_Warning("Image Processing", false, "Invalid images passed into %s function", __FUNCTION__); - return errorValue; - } - - // Two images should share same size - if (image1->GetWidth(0) != image2->GetWidth(0) || image1->GetHeight(0) != image2->GetHeight(0)) - { - AZ_Warning("Image Processing", false, "%s function only can get error between two images with same size", __FUNCTION__); - return errorValue; - } - - //create pixel operation function - IPixelOperationPtr pixelOp1 = CreatePixelOperation(image1->GetPixelFormat()); - IPixelOperationPtr pixelOp2 = CreatePixelOperation(image2->GetPixelFormat()); - - //get count of bytes per pixel - AZ::u32 pixelBytes1 = CPixelFormats::GetInstance().GetPixelFormatInfo(image1->GetPixelFormat())->bitsPerBlock / 8; - AZ::u32 pixelBytes2 = CPixelFormats::GetInstance().GetPixelFormatInfo(image2->GetPixelFormat())->bitsPerBlock / 8; - - float color1[4]; - float color2[4]; - AZ::u8* mem1; - AZ::u8* mem2; - uint32 pitch1, pitch2; - - float sumDeltaSqLinear = 0; - - //only process the highest mip - image1->GetImagePointer(0, mem1, pitch1); - image2->GetImagePointer(0, mem2, pitch2); - - const uint32 pixelCount = image1->GetPixelCount(0); - - for (uint32 i = 0; i < pixelCount; ++i) - { - pixelOp1->GetRGBA(mem1, color1[0], color1[1], color1[2], color1[3]); - pixelOp2->GetRGBA(mem2, color2[0], color2[1], color2[2], color2[3]); - - sumDeltaSqLinear += (color1[0] - color2[0]) * (color1[0] - color2[0]) - + (color1[1] - color2[1]) * (color1[1] - color2[1]) - + (color1[2] - color2[2]) * (color1[2] - color2[2]); - - mem1 += pixelBytes1; - mem2 += pixelBytes2; - } - - return sumDeltaSqLinear / pixelCount; - } - - void GetBC1CompressionErrors(IImageObjectPtr originImage, float& errorLinear, float& errorSrgb, - ICompressor::CompressOption option) - { - errorLinear = 0; - errorSrgb = 0; - - if (originImage->HasImageFlags(EIF_SRGBRead)) - { - AZ_Assert(false, "The input origin image of %s function need be in linear color space", __FUNCTION__); - return; - } - - //compress and decompress in linear space - ImageToProcess processLinear(originImage); - processLinear.SetCompressOption(option); - processLinear.ConvertFormat(ePixelFormat_BC1); - processLinear.ConvertFormat(ePixelFormat_R32G32B32A32F); - - errorLinear = GetErrorBetweenImages(originImage, processLinear.Get()); - - //compress and descompress in srgb space, then convert back to linear space to compare to original image - ImageToProcess processSrgb(originImage); - processSrgb.SetCompressOption(option); - processSrgb.LinearToGamma(); - processSrgb.ConvertFormat(ePixelFormat_BC1); - processSrgb.ConvertFormat(ePixelFormat_R32G32B32A32F); - processSrgb.GammaToLinearRGBA32F(true); - - errorSrgb = GetErrorBetweenImages(originImage, processSrgb.Get()); - } - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.h b/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.h deleted file mode 100644 index 01cd422672..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvert.h +++ /dev/null @@ -1,182 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include - -#include -#include -#include -#include -#include - -#include -#include - -namespace ImageProcessing -{ - class IImageObject; - class ImageToProcess; - - //Convert image file with its image export setting and save to specified folder. - //this function can be useful for a cancelable job - class ImageConvertProcess* CreateImageConvertProcess(const AZStd::string& imageFilePath, - const AZStd::string& exportDir, const PlatformName& platformName, AZ::SerializeContext* context = nullptr); - - //Convert image file with its image export setting and save to specified folder. it will return when the whole conversion is done. - //Could be used for command mode or test - bool ConvertImageFile(const AZStd::string& imageFilePath, const AZStd::string& exportDir, AZStd::vector& outPaths, - const PlatformName& platformName = "", AZ::SerializeContext* context = nullptr); - - //image filter function - void FilterImage(MipGenType genType, MipGenEvalType evalType, float blurH, float blurV, const IImageObjectPtr srcImg, int srcMip, - IImageObjectPtr dstImg, int dstMip, QRect* srcRect, QRect* dstRect); - - //get compression error for an image converting to certain format - void GetBC1CompressionErrors(IImageObjectPtr originImage, float& errorLinear, float& errorSrgb, - ICompressor::CompressOption option); - - float GetErrorBetweenImages(IImageObjectPtr inputImage1, IImageObjectPtr inputImage2); - - //Combine image with alpha image if any and output as RGBA8 - IImageObjectPtr MergeOutputImageForPreview(IImageObjectPtr image, IImageObjectPtr alphaImage); - - //get output image size and mip count based on the texture setting and preset setting - - //other helper functions - //Get desired output image size based on the texture settings - void GetOutputExtent(AZ::u32 inputWidth, AZ::u32 inputHeight, AZ::u32& outWidth, AZ::u32& outHeight, AZ::u32& outReduce, - const TextureSettings* textureSettings, const PresetSettings* presetSettings); - - class ImageConvertProcess - { - public: - //constructor - ImageConvertProcess(const IImageObjectPtr inputImage, const TextureSettings& textureSetting, - const PresetSettings& presetSetting, bool isPreview, bool isStreaming, bool canOverridePreset, - const AZStd::string& outputPath, const AZStd::string& platformId); - ~ImageConvertProcess(); - - //doing image conversion, this function need to be called repeatly until the process is done - //it could used for a working thread which may need to cancel a process - void UpdateProcess(); - - //doing all conversion in one step. This function will call UpdateProcess in a while loop until it's done. - void ProcessAll(); - - //for multi-thread - //get percentage of image convertion progress - float GetProgress(); - bool IsFinished(); - bool IsSucceed(); - - //get output images - IImageObjectPtr GetOutputImage(); - IImageObjectPtr GetOutputAlphaImage(); - IImageObjectPtr GetOutputDiffCubemap(); - - //get output file paths and append the paths to the outPaths vector. - void GetAppendOutputFilePaths(AZStd::vector& outPaths); - - private: - enum ConvertStep - { - StepValidateInput = 0, - StepGenerateColorChart, - StepConvertToLinear, - StepSwizzle, - StepOverridePreset, - StepCubemapLayout, - StepPreNormalize, - StepDiffCubemap, - StepMipmap, - StepGlossFromNormal, - StepPostNormalize, - StepCreateHighPass, - StepConvertOutputColorSpace, - StepAlphaImage, - StepConvertPixelFormat, - StepSaveToFile, - StepAll - }; - - //input image and settings - const IImageObjectPtr m_inputImage; - TextureSettings m_textureSetting; - PresetSettings m_presetSetting; - bool m_canOverridePreset; - bool m_isPreview; - AZStd::string m_outputPath; - AZStd::string m_platformId; - - //some global settings from builder setting - bool m_isStreaming; - - //for alpha - //to indicate the current alpha chanenl content - EAlphaContent m_alphaContent; - //An image object to hold alpha channel in a seperate image - IImageObjectPtr m_alphaImage; - - //for cubemap - //An image object to save output result of diffuse cubemap conversion - IImageObjectPtr m_diffCubemapImage; - - //image for processing - ImageToProcess *m_image; - - //progress - uint32 m_progressStep; - bool m_isFinished; - bool m_isSucceed; - - //all the output products' paths - AZStd::vector m_productFilepaths; - - //for get processing time - AZStd::sys_time_t m_startTime; - double m_processTime; //in seconds - - private: - //validate the input image and settings - bool ValidateInput(); - - //mipmap generation - bool FillMipmaps(); - - //mipmap generation for cubemap - bool FillCubemapMipmaps(); - - //special case: create diffuse cubemap - void CreateDiffuseCubemap(); - - //convert color space to linear with pixel format rgba32f - bool ConvertToLinear(); - - //convert to output color space before compression - bool ConvertToOuputColorSpace(); - - //create alpha image if it's needed - void CreateAlphaImage(); - - //pixel format convertion/compression - bool ConvertPixelformat(); - - //save output image to a file - bool SaveOutput(); - - //if it's converting for cubemap - bool IsConvertToCubemap(); - }; - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.cpp deleted file mode 100644 index cab3918a05..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.cpp +++ /dev/null @@ -1,148 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - IImageObjectPtr ImageConvertOutput::GetOutputImage(OutputImageType type) const - { - if (type < OutputImageType::Count) - { - return m_outputImage[static_cast(type)]; - } - else - { - return IImageObjectPtr(); - } - } - - void ImageConvertOutput::SetOutputImage(IImageObjectPtr image, OutputImageType type) - { - if (type < OutputImageType::Count) - { - m_outputImage[static_cast(type)] = image; - } - else - { - AZ_Error("ImageProcess", false, "Cannot set output image to %d", type); - } - } - - void ImageConvertOutput::SetReady(bool ready) - { - m_outputReady = ready; - } - - bool ImageConvertOutput::IsReady() const - { - return m_outputReady; - } - - float ImageConvertOutput::GetProgress() const - { - return m_progress; - } - - void ImageConvertOutput::SetProgress(float progress) - { - m_progress = progress; - } - - void ImageConvertOutput::Reset() - { - for (int i = 0; i < static_cast(OutputImageType::Count); i ++ ) - { - m_outputImage[i] = nullptr; - } - m_outputReady = false; - m_progress = 0.0f; - } - - ImageConvertJob::ImageConvertJob(IImageObjectPtr image, const TextureSettings* textureSetting, - const PresetSettings* preset, bool isPreview, const AZStd::string& platformId, - ImageConvertOutput* output, bool autoDelete /*= true*/, AZ::JobContext* jobContext /*= nullptr*/) - : AZ::Job(autoDelete, jobContext) - , m_isPreview(isPreview) - , m_isCancelled(false) - , m_output(output) - { - AZ_Assert(m_output, "Needs to have an output destination for image conversion!"); - if (image && textureSetting && preset) - { - bool isStreaming = BuilderSettingManager::Instance()->GetBuilderSetting(platformId)->m_enableStreaming; - bool canOverridePreset = false; - m_process = AZStd::make_unique(image, *textureSetting, *preset, isPreview, isStreaming, canOverridePreset, "", platformId); - } - } - - void ImageConvertJob::Process() - { - if (!m_process) - { - AZ_Error("Image Processing", false, "Cannot start processing, invalid setting or image!"); - m_output->SetReady(true); - m_output->SetProgress(1.0f); - return; - } - m_output->SetReady(false); - while (!m_process->IsFinished() && !IsJobCancelled()) - { - m_process->UpdateProcess(); - if (m_isPreview) - { - m_output->SetProgress(m_process->GetProgress() / static_cast(m_previewProcessStep)); - } - else - { - m_output->SetProgress(m_process->GetProgress()); - } - } - - IImageObjectPtr outputImage = m_process->GetOutputImage(); - IImageObjectPtr outputImageAlpha = m_process->GetOutputAlphaImage(); - - m_output->SetOutputImage(outputImage, ImageConvertOutput::Base); - m_output->SetOutputImage(outputImageAlpha, ImageConvertOutput::Alpha); - - if (m_isPreview && !IsJobCancelled()) - { - // For preview, combine image output with alpha if any - m_output->SetProgress(1.0f / static_cast(m_previewProcessStep)); - IImageObjectPtr combinedImage = MergeOutputImageForPreview(outputImage, outputImageAlpha); - m_output->SetOutputImage(combinedImage, ImageConvertOutput::Preview); - } - - m_output->SetReady(true); - m_output->SetProgress(1.0f); - } - - void ImageConvertJob::Cancel() - { - m_isCancelled = true; - } - - bool ImageConvertJob::IsJobCancelled() - { - return m_isCancelled || IsCancelled(); - } - - - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.h b/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.h deleted file mode 100644 index fb3f26af50..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageConvertJob.h +++ /dev/null @@ -1,74 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include -#include -#include - -namespace ImageProcessing -{ - class ImageConvertProcess; - - class ImageConvertOutput - { - public: - enum OutputImageType - { - Base = 0, // Might contains alpha or not - Alpha, // Separate alpha image - Preview, // Combine base image with alpha if any, format RGBA8 - Count - }; - - IImageObjectPtr GetOutputImage(OutputImageType type) const; - void SetOutputImage(IImageObjectPtr image, OutputImageType type); - void SetReady(bool ready); - bool IsReady() const; - float GetProgress() const; - void SetProgress(float progress); - void Reset(); - - private: - IImageObjectPtr m_outputImage[OutputImageType::Count]; - bool m_outputReady = false; - float m_progress = 0.0f; - }; - - class ImageConvertJob - : public AZ::Job - { - public: - AZ_CLASS_ALLOCATOR(ImageConvertJob, AZ::ThreadPoolAllocator, 0) - - ImageConvertJob(IImageObjectPtr image, const TextureSettings* textureSetting, const PresetSettings* preset - , bool isPreview, const AZStd::string& platformId, ImageConvertOutput* output, bool autoDelete = true - , AZ::JobContext* jobContext = nullptr); - - void Process() override; - // Cancel the job itself - void Cancel(); - // Whether the job is being cancelled or the whole job group is being cancelled - bool IsJobCancelled(); - - private: - static const int m_previewProcessStep = 2; - - AZStd::unique_ptr m_process; - bool m_isPreview; - AZStd::atomic_bool m_isCancelled; - ImageConvertOutput* m_output; - }; -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageFlags.h b/Gems/ImageProcessing/Code/Source/Processing/ImageFlags.h deleted file mode 100644 index 2f09fbb588..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageFlags.h +++ /dev/null @@ -1,43 +0,0 @@ -/* -* All or portions of this file Copyright(c) Amazon.com, Inc.or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -*WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -//! The following constants are extracted from ImageExtensionHelper.h -//! Please make sure they are always synced with the same constants defined in ImageExtensionHelper.h - -namespace ImageProcessing -{ - // flags to propagate from the RC to the engine through GetImageFlags() - // 32bit bitmask, numbers should not change as engine relies on them - const static AZ::u32 EIF_Cubemap = 0x1; - const static AZ::u32 EIF_Volumetexture = 0x2; - const static AZ::u32 EIF_Decal = 0x4; // this is usually set through the preset - const static AZ::u32 EIF_Greyscale = 0x8; // hint for the engine (e.g. greyscale light beams can be applied to shadow mask), can be for DXT1 because compression artfacts don't count as color - const static AZ::u32 EIF_SupressEngineReduce = 0x10; // info for the engine: don't reduce texture resolution on this texture - const static AZ::u32 EIF_UNUSED_BIT = 0x40; // Free to use - const static AZ::u32 EIF_AttachedAlpha = 0x400; // info for the engine: it's a texture with attached alpha channel - const static AZ::u32 EIF_SRGBRead = 0x800; // info for the engine: if gamma corrected rendering is on, this texture requires SRGBRead (it's not stored in linear) - const static AZ::u32 EIF_DontResize = 0x8000; // info for the engine: for dds textures that shouldn't be resized with r_TexResolution - const static AZ::u32 EIF_RenormalizedTexture = 0x10000; // info for the engine: for dds textures that have renormalized color range - const static AZ::u32 EIF_CafeNative = 0x20000; // info for the engine: native Cafe texture format - const static AZ::u32 EIF_RestrictedPlatformONative = 0x40000; // native tiled texture for restrict platform O - const static AZ::u32 EIF_Tiled = 0x80000; // info for the engine: texture has been tiled for the platform - const static AZ::u32 EIF_RestrictedPlatformDNative = 0x100000; // native tiled texture for restrict platform D - const static AZ::u32 EIF_Splitted = 0x200000; // info for the engine: this texture is splitted - const static AZ::u32 EIF_Colormodel = 0x7000000; // info for the engine: bitmask: colormodel used in the texture - const static AZ::u32 EIF_Colormodel_RGB = 0x0000000; // info for the engine: colormodel is RGB (default) - const static AZ::u32 EIF_Colormodel_CIE = 0x1000000; // info for the engine: colormodel is CIE (used for terrain) - const static AZ::u32 EIF_Colormodel_YCC = 0x2000000; // info for the engine: colormodel is Y'CbCr (used for reflectance) - const static AZ::u32 EIF_Colormodel_YFF = 0x3000000; // info for the engine: colormodel is Y'FbFr (used for reflectance) - const static AZ::u32 EIF_Colormodel_IRB = 0x4000000; // info for the engine: colormodel is IRB (used for reflectance) -} diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.cpp deleted file mode 100644 index 7a6b1e3002..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.cpp +++ /dev/null @@ -1,1417 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include - -// Indicates a 2D texture is a cube-map texture. -#define DDS_RESOURCE_MISC_TEXTURECUBE 0x4 - -namespace ImageProcessing -{ - - IImageObject* IImageObject::CreateImage(AZ::u32 width, AZ::u32 height, - AZ::u32 maxMipCount, EPixelFormat pixelFormat) - { - return aznew CImageObject(width, height, maxMipCount, pixelFormat); - } - - CImageObject::CImageObject(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat) - : m_pixelFormat(pixelFormat) - , m_colMinARGB(0.0f, 0.0f, 0.0f, 0.0f) - , m_colMaxARGB(1.0f, 1.0f, 1.0f, 1.0f) - , m_averageBrightness(0.63f) - , m_imageFlags(0) - , m_numPersistentMips(0) - { - ResetImage(width, height, maxMipCount, pixelFormat); - } - - EPixelFormat CImageObject::GetPixelFormat() const - { - return m_pixelFormat; - } - - AZ::u32 CImageObject::GetPixelCount(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "Mip doesn't exist: %d", mip); - - return m_mips[mip]->m_width * m_mips[mip]->m_height; - } - - AZ::u32 CImageObject::GetWidth(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "Mip doesn't exist: %d", mip); - - return m_mips[mip]->m_width; - } - - AZ::u32 CImageObject::GetHeight(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "Mip doesn't exist: %d", mip); - - return m_mips[mip]->m_height; - } - - AZ::u32 CImageObject::GetMipCount() const - { - return (AZ::u32)m_mips.size(); - } - - void CImageObject::ResetImage(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat) - { - //check input - AZ_Assert(width > 0 && height > 0, "image width and height need to larger than 0. width: %d, height: %d", width, height); - AZ_Assert(maxMipCount > 0, "image mipmap count need to larger than 0. maxMipCount: %d", maxMipCount); - - //clean up mipmaps - for (AZ::u32 mip = 0; mip < AZ::u32(m_mips.size()); ++mip) - { - delete m_mips[mip]; - } - - m_pixelFormat = pixelFormat; - m_colMinARGB = AZ::Color(0.0f, 0.0f, 0.0f, 0.0f); - m_colMaxARGB = AZ::Color(1.0f, 1.0f, 1.0f, 1.0f); - m_averageBrightness = 0.0f; - m_imageFlags = 0; - m_numPersistentMips = 0; - m_mips.clear(); - - const PixelFormatInfo* const pFmt = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat); - AZ_Assert(pFmt, "can't find pixe format info for %d", m_pixelFormat); - - const AZ::u32 mipCount = AZStd::min(maxMipCount, - CPixelFormats::GetInstance().ComputeMaxMipCount(m_pixelFormat, width, height)); - - m_mips.reserve(mipCount); - - for (AZ::u32 mip = 0; mip < mipCount; ++mip) - { - MipLevel* const pEntry = aznew MipLevel; - - AZ::u32 localWidth = width >> mip; - AZ::u32 localHeight = height >> mip; - if (localWidth < 1) - { - localWidth = 1; - } - if (localHeight < 1) - { - localHeight = 1; - } - - pEntry->m_width = localWidth; - pEntry->m_height = localHeight; - - if (pFmt->bCompressed) - { - const AZ::u32 blocksInRow = (pEntry->m_width + (pFmt->blockWidth - 1)) / pFmt->blockWidth; - pEntry->m_pitch = (blocksInRow * pFmt->bitsPerBlock) / 8; - pEntry->m_rowCount = (localHeight + (pFmt->blockHeight - 1)) / pFmt->blockHeight; - } - else - { - pEntry->m_pitch = (pEntry->m_width * pFmt->bitsPerBlock) / 8; - pEntry->m_rowCount = localHeight; - } - - pEntry->Alloc(); - - m_mips.push_back(pEntry); - } - } - - bool CImageObject::CompareImage(const IImageObjectPtr otherImage) const - { - CImageObject* other = static_cast(otherImage.get()); - if (other == nullptr) - { - return false; - } - - if (m_pixelFormat == other->m_pixelFormat - && m_colMinARGB == other->m_colMinARGB - && m_colMaxARGB == other->m_colMaxARGB - && m_averageBrightness == other->m_averageBrightness - && m_imageFlags == other->m_imageFlags - && m_numPersistentMips == other->m_numPersistentMips - && m_mips.size() == other->m_mips.size()) - { - for (int mip = 0; mip < m_mips.size(); mip++) - { - if (!(*m_mips[mip] == *other->m_mips[mip])) - { - return false; - } - } - return true; - } - return false; - } - - uint CImageObject::GetTextureMemory() const - { - int totalSize = 0; - for (int mip = 0; mip < m_mips.size(); mip++) - { - totalSize += CPixelFormats::GetInstance().EvaluateImageDataSize(m_pixelFormat, - m_mips[mip]->m_width, m_mips[mip]->m_height); - } - - return totalSize; - } - - EAlphaContent CImageObject::GetAlphaContent() const - { - if (CPixelFormats::GetInstance().IsPixelFormatWithoutAlpha(m_pixelFormat)) - { - return EAlphaContent::eAlphaContent_Absent; - } - - //if it's compressed format, return indeterminate. if user really want to know the content, they may convert the format to ARGB8 first - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - AZ_Assert(false, "the function only works right with uncompressed formats. convert to uncompressed format if you get accurate result"); - return EAlphaContent::eAlphaContent_Indeterminate; - } - - //go though alpha channel of first mip - //create pixel operation function to access pixel data - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - // counts of blacks and white - uint nBlacks = 0; - uint nWhites = 0; - - float r, g, b, a; - AZ::u8* pixelBuf; - AZ::u32 pitch; - GetImagePointer(0, pixelBuf, pitch); - - const AZ::u32 pixelCount = GetPixelCount(0); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, r, g, b, a); - if (a == 0.0f) - { - ++nBlacks; - } - else if (a == 1.0f) - { - ++nWhites; - } - else - { - return EAlphaContent::eAlphaContent_Greyscale; - } - } - - if (nBlacks == 0) - { - return EAlphaContent::eAlphaContent_OnlyWhite; - } - - if (nWhites == 0) - { - return EAlphaContent::eAlphaContent_OnlyBlack; - } - - return EAlphaContent::eAlphaContent_OnlyBlackAndWhite; - } - - // clone this image-object's contents - IImageObject* CImageObject::Clone() const - { - const EPixelFormat srcPixelformat = GetPixelFormat(); - - IImageObject* pRet = AllocateImage(); - - AZ::u32 dwMips = pRet->GetMipCount(); - for (AZ::u32 dwMip = 0; dwMip < dwMips; ++dwMip) - { - //AZ::u32 dwLocalWidth = GetWidth(dwMip); // we get error on NVidia with this (assumes input is 4x4 as well) - AZ::u32 dwLocalHeight = GetHeight(dwMip); - - AZ::u32 dwLines = dwLocalHeight; - - if (CPixelFormats::GetInstance().IsPixelFormatUncompressed(srcPixelformat)) - { - dwLines = m_mips[dwMip]->m_rowCount; - } - - AZ::u8* pMem; - AZ::u32 dwPitch; - GetImagePointer(dwMip, pMem, dwPitch); - - AZ::u8* pDstMem; - AZ::u32 dwDstPitch; - pRet->GetImagePointer(dwMip, pDstMem, dwDstPitch); - - for (AZ::u32 dwY = 0; dwY < dwLines; ++dwY) - { - memcpy(&pDstMem[dwDstPitch * dwY], &pMem[dwPitch * dwY], AZStd::min(dwPitch, dwDstPitch)); - } - } - return pRet; - } - - void CImageObject::ClearColor(float r, float g, float b, float a) - { - //if it's compressed format, return directly - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - AZ_Assert(false, "The %s function only works with uncompressed formats", __FUNCTION__); - return; - } - //create pixel operation function to access pixel data - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - AZ::u8* pixelBuf; - AZ::u32 pitch; - - AZ::u32 mips = GetMipCount(); - for (AZ::u32 mip = 0; mip < mips; ++mip) - { - GetImagePointer(mip, pixelBuf, pitch); - const AZ::u32 pixelCount = GetPixelCount(mip); - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->SetRGBA(pixelBuf, r, g, b, a); - } - } - } - - // allocate an empty image with the same properties as the given image and the requested format - IImageObject* CImageObject::AllocateImage(EPixelFormat pixelFormat) const - { - AZ::u32 width = GetWidth(0); - AZ::u32 height = GetHeight(0); - - if (!CPixelFormats::GetInstance().IsImageSizeValid(pixelFormat, width, height, false)) - { - AZ_Assert(false, "Cann't allocate image with format: %d", pixelFormat); - return nullptr; - } - - CImageObject* pRet = aznew CImageObject(width, height, GetMipCount(), pixelFormat); - pRet->CopyPropertiesFrom(this); - return pRet; - } - - IImageObject* CImageObject::AllocateImage() const - { - return AllocateImage(m_pixelFormat); - } - - CImageObject::~CImageObject() - { - for (size_t i = 0; i < m_mips.size(); ++i) - { - delete m_mips[i]; - } - m_mips.clear(); - } - - //note: there are some unreasonable parts of the save files formats for cry textures. We might need to rethink about - // it for new renderer - bool CImageObject::SaveImage(const char* filename, IImageObjectPtr alphaImage, AZStd::vector& outFilePaths) const - { - AZ::IO::SystemFile file; - file.Open(filename, AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY); - - AZ::IO::SystemFileStream fileSaveStream(&file, true); - if (!fileSaveStream.IsOpen()) - { - - AZ_Warning("Image Processing", false, "%s: failed to create file %s", __FUNCTION__, filename); - return false; - } - - if (alphaImage) - { - AZ_Assert(HasImageFlags(EIF_AttachedAlpha), "attached alpha image flag wasn't set"); - AZ_Assert(!alphaImage->HasImageFlags(EIF_AttachedAlpha), "alpha image shouldn't have attached alpha image flag"); - - // inherit cubemap and decal image flags to attached alpha image - alphaImage->AddImageFlags(GetImageFlags() & (EIF_Cubemap - | EIF_Decal | EIF_Splitted)); - alphaImage->SetNumPersistentMips(m_numPersistentMips); - } - - bool bOk = SaveImage(fileSaveStream); - bool hasSplitFlag = HasImageFlags(EIF_Splitted); - - //append alpha image data in the end if there is no split - if (bOk && alphaImage && !hasSplitFlag) - { - //4 bytes extension tag, 4 bytes attached alpha tag, then 4 bytes of chunk size - fileSaveStream.Write(sizeof(FOURCC_CExt), &FOURCC_CExt); // marker for the start of Crytek Extended data - fileSaveStream.Write(sizeof(FOURCC_AttC), &FOURCC_AttC); // Attached Channel chunk - - AZ::u32 size = 0; - AZ::u32 sizeBytes = sizeof(size); - fileSaveStream.Write(sizeBytes, &size); //size of attached chunk - - //save alpha image and get the size - AZ::IO::SizeType startPos = fileSaveStream.GetCurPos(); - bOk = alphaImage->SaveImage(fileSaveStream); - AZ::IO::SizeType endPos = fileSaveStream.GetCurPos(); - size = aznumeric_cast(endPos - startPos); - - //move back to beginning of chunk and write chunk size then move back to end - fileSaveStream.Seek(startPos - sizeBytes, AZ::IO::GenericStream::ST_SEEK_BEGIN); - fileSaveStream.Write(sizeBytes, &size); - fileSaveStream.Seek(endPos, AZ::IO::GenericStream::ST_SEEK_BEGIN); - - // marker for the end of Crytek Extended data - fileSaveStream.Write(sizeof(FOURCC_CEnd), &FOURCC_CEnd); - } - - if (!bOk) - { - AZ::IO::SystemFile::Delete(filename); - return false; - } - - // It's important to maintain the product output sequence. Asset Database/Browser will use the first product to determine the source type! - outFilePaths.push_back(filename); - - // save stand alone products - if (hasSplitFlag) - { - // alpha - if (alphaImage) - { - AZStd::string alphaFile = AZStd::string::format("%s.a", filename); - - AZ::IO::SystemFile outAlphaFile; - outAlphaFile.Open(alphaFile.c_str(), AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY); - - AZ::IO::SystemFileStream alphaFileSaveStream(&outAlphaFile, true); - - if (alphaFileSaveStream.IsOpen()) - { - alphaImage->SaveImage(alphaFileSaveStream); - outFilePaths.push_back(alphaFile); - } - else - { - AZ_Warning("Image Processing", false, "%s: failed to create file %s", __FUNCTION__, alphaFile.c_str()); - } - } - - // mips - AZ::u32 numStreamable = GetMipCount() - m_numPersistentMips; - for (AZ::u32 mip = 0; mip < numStreamable; mip++) - { - AZ::u32 nameIdx = numStreamable - mip; - AZStd::string mipFileName = AZStd::string::format("%s.%d", filename, nameIdx); - SaveMipToFile(mip, mipFileName); - outFilePaths.push_back(mipFileName); - if (alphaImage) - { - AZStd::string mipAlphaFileName = mipFileName + "a"; - alphaImage->SaveMipToFile(mip, mipAlphaFileName); - outFilePaths.push_back(mipAlphaFileName); - } - } - } - - return bOk; - } - - bool CImageObject::SaveMipToFile(AZ::u32 mip, const AZStd::string& filename) const - { - AZ::IO::SystemFile saveFile; - saveFile.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_CREATE | AZ::IO::SystemFile::SF_OPEN_CREATE_PATH | AZ::IO::SystemFile::SF_OPEN_WRITE_ONLY); - - AZ::IO::SystemFileStream saveFileStream(&saveFile, true); - - if (!saveFileStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to create file %s", __FUNCTION__, filename.c_str()); - return false; - } - - saveFileStream.Write(GetMipBufSize(mip), m_mips[mip]->m_pData); - return true; - } - - IImageObject* CreateImageFromHeader(DDS_HEADER& header, DDS_HEADER_DXT10& exthead) - { - EPixelFormat eFormat = ePixelFormat_Unknown; - AZ::u32 dwWidth, dwMips, dwHeight; - AZ::u32 imageFlags = header.dwReserved1; - AZ::Color colMinARGB, colMaxARGB; - - dwWidth = header.dwWidth; - dwHeight = header.dwHeight; - dwMips = 1; - if (header.dwHeaderFlags & DDS_HEADER_FLAGS_MIPMAP) - { - dwMips = header.dwMipMapCount; - } - if ((header.dwSurfaceFlags & DDS_SURFACE_FLAGS_CUBEMAP) && (header.dwCubemapFlags & DDS_CUBEMAP_ALLFACES)) - { - AZ_Assert(header.dwReserved1&EIF_Cubemap, "Image flag should have cubemap flag"); - dwHeight *= 6; - } - - colMinARGB = AZ::Color(header.cMinColor[0], header.cMinColor[1], header.cMinColor[2], header.cMinColor[3]); - colMaxARGB = AZ::Color(header.cMaxColor[0], header.cMaxColor[1], header.cMaxColor[2], header.cMaxColor[3]); - - //get pixel format - { - // DX10 formats - if (header.ddspf.dwFourCC == FOURCC_DX10) - { - AZ::u32 dxgiFormat = exthead.dxgiFormat; - - //remove the SRGB from dxgi format and add sRGB to image flag - if (dxgiFormat == DXGI_FORMAT_R8G8B8A8_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_R8G8B8A8_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC1_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC1_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC2_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC2_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC3_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC3_UNORM; - } - else if (dxgiFormat == DXGI_FORMAT_BC7_UNORM_SRGB) - { - dxgiFormat = DXGI_FORMAT_BC7_UNORM; - } - - //add rgb flag if the dxgiformat was changed (which means it was sRGB format) above - if (dxgiFormat != exthead.dxgiFormat) - { - AZ_Assert(imageFlags&EIF_SRGBRead, "Image flags should have SRGBRead flag"); - imageFlags |= EIF_SRGBRead; - } - - //check all the pixel formats and find matching one - if (dxgiFormat != DXGI_FORMAT_UNKNOWN) - { - int i = 0; - for (i; id3d10Format == dxgiFormat) - { - eFormat = (EPixelFormat)i; - break; - } - } - if (i == ePixelFormat_Count) - { - AZ_Error("Image Processing", false, "Unhandled d3d10 format: %d", dxgiFormat); - return nullptr; - } - } - } - else - { - //for non-dx10 formats, use fourCC to find out its pixel formats - //go through all pixel formats and find a match with the fourcc - for (AZ::u32 formatIdx = 0; formatIdx < ePixelFormat_Count; formatIdx++) - { - const PixelFormatInfo *info = CPixelFormats::GetInstance().GetPixelFormatInfo((EPixelFormat)formatIdx); - if (header.ddspf.dwFourCC == info->fourCC) - { - eFormat = (EPixelFormat)formatIdx; - break; - } - } - - //legacy formats. This section is only used for load dds files converted by RC.exe - //our save to dds file function won't use any of these fourcc - if (eFormat == ePixelFormat_Unknown) - { - if (header.ddspf.dwFourCC == FOURCC_DXT1) - { - eFormat = ePixelFormat_BC1; - } - else if (header.ddspf.dwFourCC == FOURCC_DXT5) - { - eFormat = ePixelFormat_BC3; - } - else if (header.ddspf.dwFourCC == FOURCC_3DCP) - { - eFormat = ePixelFormat_BC4; - } - else if (header.ddspf.dwFourCC == FOURCC_3DC) - { - eFormat = ePixelFormat_BC5; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_R32F) - { - eFormat = ePixelFormat_R32F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_G32R32F) - { - eFormat = ePixelFormat_R32G32F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_A32B32G32R32F) - { - eFormat = ePixelFormat_R32G32B32A32F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_R16F) - { - eFormat = ePixelFormat_R16F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_G16R16F) - { - eFormat = ePixelFormat_R16G16F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_A16B16G16R16F) - { - eFormat = ePixelFormat_R16G16B16A16F; - } - else if (header.ddspf.dwFourCC == DDS_FOURCC_A16B16G16R16) - { - eFormat = ePixelFormat_R16G16B16A16; - } - else if ((header.ddspf.dwFlags == DDS_RGBA || header.ddspf.dwFlags == DDS_RGB) - && header.ddspf.dwRGBBitCount == 32) - { - if (header.ddspf.dwRBitMask == 0x00ff0000) - { - eFormat = ePixelFormat_B8G8R8A8; - } - else - { - eFormat = ePixelFormat_R8G8B8A8; - } - } - else if (header.ddspf.dwFlags == DDS_LUMINANCEA && header.ddspf.dwRGBBitCount == 8) - { - eFormat = ePixelFormat_R8G8; - } - else if (header.ddspf.dwFlags == DDS_LUMINANCE && header.ddspf.dwRGBBitCount == 8) - { - eFormat = ePixelFormat_A8; - } - else if ((header.ddspf.dwFlags == DDS_A || header.ddspf.dwFlags == DDS_A_ONLY || header.ddspf.dwFlags == (DDS_A | DDS_A_ONLY)) && header.ddspf.dwRGBBitCount == 8) - { - eFormat = ePixelFormat_A8; - } - } - } - } - - if (eFormat == ePixelFormat_Unknown) - { - AZ_Error("Image Processing", false, "Unhandled dds pixel format fourCC: %d, flags: %d", - header.ddspf.dwFourCC, header.ddspf.dwFlags); - return nullptr; - } - - IImageObject* newImage = IImageObject::CreateImage(dwWidth, dwHeight, dwMips, eFormat); - - if (dwMips != newImage->GetMipCount()) - { - AZ_Error("Image Processing", false, "Mipcount from image data doesn't match image size and pixelformat"); - delete newImage; - return nullptr; - } - - //set properties - newImage->SetImageFlags(imageFlags); - newImage->SetAverageBrightness(header.fAvgBrightness); - newImage->SetColorRange(colMinARGB, colMaxARGB); - newImage->SetNumPersistentMips(header.bNumPersistentMips); - - return newImage; - } - - float CImageObject::CalculateAverageBrightness() const - { - //if it's compressed format, return a default value - if (!CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat)) - { - return 0.5f; - } - - // Accumulate pixel colors of the top mip - double avgOverall[3] = { 0.0, 0.0, 0.0 }; - - //create pixel operation function to access pixel data - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel for images - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - //only calculate mip 0 - AZ::u32 mip = 0; - float color[4]; - AZ::u8* pixelBuf; - AZ::u32 pitch; - GetImagePointer(mip, pixelBuf, pitch); - const AZ::u32 pixelCount = GetPixelCount(mip); - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - avgOverall[0] += color[0]; - avgOverall[1] += color[1]; - avgOverall[2] += color[2]; - } - - const double avg = (avgOverall[0] + avgOverall[1] + avgOverall[2]) / (3 * pixelCount); - - return (float)avg; - } - - bool CImageObject::BuildSurfaceHeader(DDS_HEADER& header) const - { - AZ::u32 dwWidth, dwMips, dwHeight; - GetExtent(dwWidth, dwHeight, dwMips); - - if (dwMips <= 0) - { - AZ_Error("Image Processing", false, "%s: dwMips is %u", __FUNCTION__, (unsigned)dwMips); - return false; - } - - const EPixelFormat format = GetPixelFormat(); - if ((format < 0) || (format >= ePixelFormat_Count)) - { - AZ_Error("Image Processing", false, "%s: Bad format %d", __FUNCTION__, (int)format); - return false; - } - - const PixelFormatInfo* const pPixelFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(format); - - memset(&header, 0, sizeof(DDS_HEADER)); - - header.dwSize = sizeof(DDS_HEADER); - header.dwHeaderFlags = DDSD_CAPS | DDSD_PIXELFORMAT | DDSD_WIDTH | DDSD_HEIGHT; - header.dwWidth = dwWidth; - header.dwHeight = dwHeight; - - if (HasImageFlags(EIF_Cubemap)) - { - header.dwSurfaceFlags |= DDS_SURFACE_FLAGS_CUBEMAP; - header.dwCubemapFlags |= DDS_CUBEMAP_ALLFACES; - //save face size instead of image size. - header.dwHeight /= 6; - } - - header.ddspf.dwSize = sizeof(DDS_PIXELFORMAT); - header.ddspf.dwFlags = DDS_FOURCC; - - header.ddspf.dwFourCC = pPixelFormatInfo->fourCC; - - header.dwSurfaceFlags |= DDS_SURFACE_FLAGS_TEXTURE; - - if (dwMips > 1) - { - header.dwHeaderFlags |= DDS_HEADER_FLAGS_MIPMAP; - header.dwMipMapCount = dwMips; - header.dwSurfaceFlags |= DDS_SURFACE_FLAGS_MIPMAP; - } - - // non standardized way to expose some features in the header (same information is in attached chunk but then - // streaming would need to find this spot in the file) - // if this is causing problems we need to change it - header.dwTextureStage = FOURCC_FYRC; - header.dwReserved1 = GetImageFlags(); - header.bNumPersistentMips = (AZ::u8)GetNumPersistentMips(); - - //tile mode for some platform native texture - if (HasImageFlags(EIF_RestrictedPlatformDNative)) - { - header.tileMode = eTM_LinearPadded; - } - else if (HasImageFlags(EIF_RestrictedPlatformONative)) - { - header.tileMode = eTM_Optimal; - } - - // setting up min and max colors - for (int i = 0; i < 4; i ++) - { - header.cMinColor[i] = m_colMinARGB.GetElement(i); - header.cMaxColor[i] = m_colMaxARGB.GetElement(i); - } - - // set avg brightness - header.fAvgBrightness = GetAverageBrightness(); - - return true; - } - - bool CImageObject::BuildSurfaceExtendedHeader(DDS_HEADER_DXT10& exthead) const - { - const EPixelFormat format = GetPixelFormat(); - - const PixelFormatInfo* const pPixelFormatInfo = CPixelFormats::GetInstance().GetPixelFormatInfo(format); - - DXGI_FORMAT dxgiformat = pPixelFormatInfo->d3d10Format; - - // check if we hit a format which can't be stored into a DX10 DDS-file (fe. L8) - if (dxgiformat == DXGI_FORMAT_UNKNOWN) - { - AZ_Error("Image Processing", false, "%s: Format can not be stored in a DDS-file %d", __FUNCTION__, dxgiformat); - return false; - } - - //the dxgi format are different for linear space or gamma space - if (HasImageFlags(EIF_SRGBRead)) - { - switch (dxgiformat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM: - dxgiformat = DXGI_FORMAT_R8G8B8A8_UNORM_SRGB; - break; - case DXGI_FORMAT_BC1_UNORM: - dxgiformat = DXGI_FORMAT_BC1_UNORM_SRGB; - break; - case DXGI_FORMAT_BC2_UNORM: - dxgiformat = DXGI_FORMAT_BC2_UNORM_SRGB; - break; - case DXGI_FORMAT_BC3_UNORM: - dxgiformat = DXGI_FORMAT_BC3_UNORM_SRGB; - break; - case DXGI_FORMAT_BC7_UNORM: - dxgiformat = DXGI_FORMAT_BC7_UNORM_SRGB; - break; - default: - break; - } - } - else - { - switch (dxgiformat) - { - case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_R8G8B8A8_UNORM; - break; - case DXGI_FORMAT_BC1_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC1_UNORM; - break; - case DXGI_FORMAT_BC2_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC2_UNORM; - break; - case DXGI_FORMAT_BC3_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC3_UNORM; - break; - case DXGI_FORMAT_BC7_UNORM_SRGB: - dxgiformat = DXGI_FORMAT_BC7_UNORM; - break; - default: - break; - } - } - - memset(&exthead, 0, sizeof(exthead)); - - exthead.dxgiFormat = dxgiformat; - exthead.resourceDimension = 3; //texture2d. not used - - if (HasImageFlags(EIF_Volumetexture)) - { - AZ_Assert(false, "There isn't any support for volume texture"); - } - else if (HasImageFlags(EIF_Cubemap)) - { - exthead.miscFlag = DDS_RESOURCE_MISC_TEXTURECUBE; - exthead.arraySize = 6; - } - else - { - exthead.miscFlag = 0; - exthead.arraySize = 1; - } - - return true; - } - - bool CImageObject::SaveImage(AZ::IO::SystemFileStream &saveFileStream) const - { - DDS_FILE_DESC desc; - DDS_HEADER_DXT10 exthead; - - desc.dwMagic = FOURCC_DDS; - - if (!BuildSurfaceHeader(desc.header)) - { - return false; - } - - if (desc.header.IsDX10Ext() && !BuildSurfaceExtendedHeader(exthead)) - { - return false; - } - - saveFileStream.Write(sizeof(desc), &desc); - - if (desc.header.IsDX10Ext()) - { - saveFileStream.Write(sizeof(exthead), &exthead); - } - - AZ::u32 faces = 1; - - //for cubemap. export each face and its mipmap - if (HasImageFlags(EIF_Cubemap)) - { - faces = 6; - } - - AZ::u32 mipStart = 0; - if (HasImageFlags(EIF_Splitted)) - { - if (m_numPersistentMips < m_mips.size()) - { - mipStart = (AZ::u32)m_mips.size() - m_numPersistentMips; - } - else - { - AZ_Assert(false, "numPersistentMips wasn't setup correctly"); - } - } - - for (AZ::u32 face = 0; face < faces; face++) - { - for (AZ::u32 mip = mipStart; mip < m_mips.size(); ++mip) - { - const MipLevel& level = *m_mips[mip]; - AZ::u32 faceBufSize = level.m_pitch*level.m_rowCount / faces; - saveFileStream.Write(faceBufSize, level.m_pData + faceBufSize*face); - } - } - return true; - } - - void CImageObject::GetExtent(AZ::u32& width, AZ::u32& height, AZ::u32& mipCount) const - { - mipCount = (AZ::u32)m_mips.size(); - - width = m_mips[0]->m_width; - height = m_mips[0]->m_height; - } - - AZ::u32 CImageObject::GetMipDataSize(const AZ::u32 mip) const - { - AZ_Assert(mip < m_mips.size(), "mip %d doesn't exist", mip); - - return m_mips[mip]->GetSize(); - } - - void CImageObject::GetImagePointer(const AZ::u32 mip, AZ::u8*& pMem, AZ::u32& pitch) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "requested mip doesn't exist"); - - pMem = m_mips[mip]->m_pData; - pitch = m_mips[mip]->m_pitch; - } - - AZ::u32 CImageObject::GetMipBufSize(AZ::u32 mip) const - { - AZ_Assert(mip < (AZ::u32)m_mips.size() && m_mips[mip], "requested mip doesn't exist"); - - return m_mips[mip]->m_rowCount * m_mips[mip]->m_pitch; - } - - - void CImageObject::SetMipData(AZ::u32 mip, AZ::u8* mipBuf, AZ::u32 bufSize, AZ::u32 pitch) - { - if (mip >= m_mips.size()) - { - return; - } - m_mips[mip]->m_pData = mipBuf; - m_mips[mip]->m_pitch = pitch; - m_mips[mip]->m_rowCount = bufSize/pitch; - AZ_Assert(bufSize == m_mips[mip]->m_rowCount * pitch, "Bad pitch size"); - } - - // ARGB - void CImageObject::GetColorRange(AZ::Color& minColor, AZ::Color& maxColor) const - { - minColor = m_colMinARGB; - maxColor = m_colMaxARGB; - } - - // ARGB - void CImageObject::SetColorRange(const AZ::Color& minColor, const AZ::Color& maxColor) - { - m_colMinARGB = minColor; - m_colMaxARGB = maxColor; - } - - float CImageObject::GetAverageBrightness() const - { - return m_averageBrightness; - } - - void CImageObject::SetAverageBrightness(const float avgBrightness) - { - m_averageBrightness = avgBrightness; - } - - AZ::u32 CImageObject::GetImageFlags() const - { - return m_imageFlags; - } - - void CImageObject::SetImageFlags(const AZ::u32 imageFlags) - { - m_imageFlags = imageFlags; - } - - void CImageObject::AddImageFlags(const AZ::u32 imageFlags) - { - m_imageFlags |= imageFlags; - } - - void CImageObject::RemoveImageFlags(const AZ::u32 imageFlags) - { - m_imageFlags &= ~imageFlags; - } - - bool CImageObject::HasImageFlags(const AZ::u32 imageFlags) const - { - return (m_imageFlags & imageFlags) != 0; - } - - AZ::u32 CImageObject::GetNumPersistentMips() const - { - return m_numPersistentMips; - } - - void CImageObject::SetNumPersistentMips(AZ::u32 nMips) - { - m_numPersistentMips = nMips; - } - - bool CImageObject::HasPowerOfTwoSizes() const - { - AZ::u32 w, h, mips; - GetExtent(w, h, mips); - return ((w&(w - 1)) == 0) && ((h&(h - 1)) == 0); - } - - // use when you convert an image to another one - void CImageObject::CopyPropertiesFrom(const IImageObjectPtr src) - { - const CImageObject *imageObj = static_cast(src.get()); - CopyPropertiesFrom(imageObj); - } - - void CImageObject::CopyPropertiesFrom(const CImageObject* src) - { - m_colMinARGB = src->m_colMinARGB; - m_colMaxARGB = src->m_colMaxARGB; - m_averageBrightness = src->m_averageBrightness; - m_imageFlags = src->GetImageFlags(); - } - - void CImageObject::Swizzle(const char channels[4]) - { - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return; - } - - const AZ::u8 channelCnt = 4; - - enum Channel_Id - { - ChannelR = 0, - ChannelG, - ChannelB, - ChannelA, - ChannelVal0, - ChannelVal1, - ChannelTypeCount - }; - - float values[ChannelTypeCount]; - values[ChannelVal0] = 0.f; - values[ChannelVal1] = 1.f; - - AZ::u8 channelIndics[channelCnt]; - for (AZ::u8 idx = 0; idx < channelCnt; idx++) - { - switch (channels[idx]) - { - case 'a': - channelIndics[idx] = ChannelA; - break; - case 'r': - channelIndics[idx] = ChannelR; - break; - case 'g': - channelIndics[idx] = ChannelG; - break; - case 'b': - channelIndics[idx] = ChannelB; - break; - case '0': - channelIndics[idx] = ChannelVal0; - break; - case '1': - channelIndics[idx] = ChannelVal1; - break; - default: - AZ_Assert(false, "%s function only works with channel name \"rgba01\"", __FUNCTION__); - return; - } - } - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel - uint32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - const uint32 mips = (uint32)m_mips.size(); - for (uint32 mip = 0; mip < mips; ++mip) - { - uint8* pixelBuf = m_mips[mip]->m_pData; - const uint32 pixelCount = GetPixelCount(mip); - - for (uint32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, values[ChannelR], values[ChannelG], values[ChannelB], values[ChannelA]); - pixelOp->SetRGBA(pixelBuf, values[channelIndics[0]], values[channelIndics[1]], - values[channelIndics[2]], values[channelIndics[3]]); - } - } - } - - void CImageObject::GlossFromNormals(bool hasAuthoredGloss) - { - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return; - } - - // Derive new roughness from normal variance to preserve the bumpiness of normal map mips and to reduce specular aliasing. - // The derived roughness is combined with the artist authored roughness stored in the alpha channel of the normal map. - // The algorithm is based on the Frequency Domain Normal Mapping implementation presented by Neubelt and Pettineo at Siggraph 2013. - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - const AZ::u32 mips = (AZ::u32)m_mips.size(); - float color[4]; - for (AZ::u32 mip = 0; mip < mips; ++mip) - { - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - - // Get length of the averaged normal - AZ::Vector3 normal(color[0] * 2.0f - 1.0f, color[1] * 2.0f - 1.0f, color[2] * 2.0f - 1.0f); - - float len = AZ::GetMax(normal.GetLength(), 1.0f / (1 << 15)); - - float authoredSmoothness = hasAuthoredGloss ? color[3] : 1.0f; - float finalSmoothness = authoredSmoothness; - - if (len < 1.0f) - { - // Convert from smoothness to roughness (needs to match shader code) - float authoredRoughness = (1.0f - authoredSmoothness) * (1.0f - authoredSmoothness); - - // Derive new roughness based on normal variance - float kappa = (3.0f * len - len * len * len) / (1.0f - len * len); - float variance = 1.0f / (2.0f * kappa); - float finalRoughness = AZ::GetMin(sqrtf(authoredRoughness * authoredRoughness + variance), 1.0f); - - // Convert roughness back to smoothness - finalSmoothness = 1.0f - sqrtf(finalRoughness); - } - - pixelOp->SetRGBA(pixelBuf, color[0], color[1], color[2], finalSmoothness); - - } - } - } - - void CImageObject::ConvertLegacyGloss() - { - if (!(CPixelFormats::GetInstance().IsPixelFormatUncompressed(m_pixelFormat))) - { - AZ_Assert(false, "%s function only works with uncompressed pixel format", __FUNCTION__); - return; - } - - //create pixel operation function - IPixelOperationPtr pixelOp = CreatePixelOperation(m_pixelFormat); - - //get count of bytes per pixel - AZ::u32 pixelBytes = CPixelFormats::GetInstance().GetPixelFormatInfo(m_pixelFormat)->bitsPerBlock / 8; - - const AZ::u32 mips = (AZ::u32)m_mips.size(); - float color[4]; - for (AZ::u32 mip = 0; mip < mips; ++mip) - { - AZ::u8* pixelBuf = m_mips[mip]->m_pData; - const AZ::u32 pixelCount = GetPixelCount(mip); - - for (AZ::u32 i = 0; i < pixelCount; ++i, pixelBuf += pixelBytes) - { - pixelOp->GetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - // Convert from (1 - s * 0.7)^6 to (1 - s)^2 - color[3] = 1 - pow(1.0f - color[3] * 0.7f, 3.0f); - pixelOp->SetRGBA(pixelBuf, color[0], color[1], color[2], color[3]); - } - } - } - - IImageObject* LoadImageFromDdsFile(const AZStd::string& filename) - { - AZ::IO::SystemFile file; - file.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY); - - AZ::IO::SystemFileStream fileLoadStream(&file, true); - if (!fileLoadStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to open file %s", __FUNCTION__, filename.c_str()); - return nullptr; - } - - AZStd::string ext = ""; - AzFramework::StringFunc::Path::GetExtension(filename.c_str(), ext, false); - bool isAlphaImage = (ext == "a"); - - IImageObject* imageObj = LoadImageFromDdsFile(fileLoadStream); - - //load mips from seperated files if it's splitted - if (imageObj && imageObj->HasImageFlags(EIF_Splitted)) - { - AZStd::string baseName; - if (isAlphaImage) - { - baseName = filename.substr(0, filename.size() - 2); - } - else - { - baseName = filename; - } - - AZ::u32 externalMipCount = 0; - if (imageObj->GetNumPersistentMips() < imageObj->GetMipCount()) - { - externalMipCount = imageObj->GetMipCount() - imageObj->GetNumPersistentMips(); - } - //load other mips from files with number extensions - for (AZ::u32 mipIdx = 1; mipIdx <= externalMipCount; mipIdx++) - { - AZ::u32 mip = externalMipCount - mipIdx; - AZStd::string mipFileName = AZStd::string::format("%s.%d%s", baseName.c_str(), mipIdx, isAlphaImage?"a":""); - - AZ::IO::SystemFile mipFile; - mipFile.Open(mipFileName.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY); - - AZ::IO::SystemFileStream mipFileLoadStream(&mipFile, true); - - if (!mipFileLoadStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to open mip file %s", __FUNCTION__, mipFileName.c_str()); - break; - } - - AZ::u32 pitch; - AZ::u8* mem; - imageObj->GetImagePointer(mip, mem, pitch); - AZ::u32 bufSize = imageObj->GetMipBufSize(mip); - mipFileLoadStream.Read(bufSize, mem); - } - } - - return imageObj; - } - - IImageObject* LoadImageFromDdsFile(AZ::IO::SystemFileStream& fileLoadStream) - { - if (fileLoadStream.GetLength() - fileLoadStream.GetCurPos() < sizeof(DDS_FILE_DESC)) - { - AZ_Error("Image Processing", false, "%s: Trying to load a none-DDS file", __FUNCTION__); - return nullptr; - } - - DDS_FILE_DESC desc; - DDS_HEADER_DXT10 exthead; - - AZ::IO::SizeType startPos = fileLoadStream.GetCurPos(); - fileLoadStream.Read(sizeof(desc.dwMagic), &desc.dwMagic); - - if (desc.dwMagic != FOURCC_DDS) - { - desc.dwMagic = FOURCC_DDS; - //the old cry .a file doesn't have "DDS " in the beginning of the file. - //so reset to previous position - fileLoadStream.Seek(startPos, AZ::IO::GenericStream::ST_SEEK_BEGIN); - } - - fileLoadStream.Read(sizeof(desc.header), &desc.header); - - if (!desc.IsValid()) - { - AZ_Error("Image Processing", false, "%s: Trying to load a none-DDS file", __FUNCTION__); - return nullptr; - } - - if (desc.header.IsDX10Ext()) - { - fileLoadStream.Read(sizeof(exthead), &exthead); - } - - IImageObject* outImage = CreateImageFromHeader(desc.header, exthead); - - if (outImage == nullptr) - { - return nullptr; - } - - //load mip data - AZ::u32 mipStart = 0; - //There are at least three lowest mips are in the file if it was splitted. This is to load splitted dds file exported by legacy rc.exe - int numPersistentMips = outImage->GetNumPersistentMips(); - if (numPersistentMips == 0 && outImage->HasImageFlags(EIF_Splitted)) - { - outImage->SetNumPersistentMips(3); - } - - if (outImage->HasImageFlags(EIF_Splitted) - && outImage->GetMipCount() > outImage->GetNumPersistentMips()) - { - mipStart = outImage->GetMipCount() - outImage->GetNumPersistentMips(); - } - - AZ::u32 faces = 1; - if (outImage->HasImageFlags(EIF_Cubemap)) - { - faces = 6; - } - - for (AZ::u32 face = 0; face < faces; face++) - { - for (AZ::u32 mip = mipStart; mip < outImage->GetMipCount(); ++mip) - { - AZ::u32 pitch; - AZ::u8* mem; - outImage->GetImagePointer(mip, mem, pitch); - AZ::u32 faceBufSize = outImage->GetMipBufSize(mip) / faces; - fileLoadStream.Read(faceBufSize, mem + faceBufSize*face); - } - } - - return outImage; - } - - IImageObject* LoadAttachedImageFromDdsFile(const AZStd::string& filename, IImageObjectPtr originImage) - { - if (originImage == nullptr) - { - return nullptr; - } - - AZ_Assert(originImage->HasImageFlags(EIF_AttachedAlpha), - "this function should only be called for origin image loaded from same file with attached alpha flag"); - - AZ::IO::SystemFile file; - file.Open(filename.c_str(), AZ::IO::SystemFile::SF_OPEN_READ_ONLY); - - AZ::IO::SystemFileStream fileLoadStream(&file, true); - if (!fileLoadStream.IsOpen()) - { - AZ_Warning("Image Processing", false, "%s: failed to open file %s", __FUNCTION__, filename.c_str()); - return nullptr; - } - - DDS_FILE_DESC desc; - DDS_HEADER_DXT10 exthead; - - fileLoadStream.Read(sizeof(desc), &desc); - if (desc.dwMagic != FOURCC_DDS) - { - AZ_Error("Image Processing", false, "%s:Trying to load a none-DDS file", __FUNCTION__); - return nullptr; - } - - if (desc.header.IsDX10Ext()) - { - fileLoadStream.Read(sizeof(exthead), &exthead); - } - - //skip size for originImage's mip data - for (AZ::u32 mip = 0; mip < originImage->GetMipCount(); ++mip) - { - AZ::u32 bufSize = originImage->GetMipBufSize(mip); - fileLoadStream.Seek(bufSize, AZ::IO::GenericStream::ST_SEEK_CUR); - } - - IImageObject* alphaImage = nullptr; - - AZ::u32 marker = 0; - fileLoadStream.Read(4, &marker); - if (marker == FOURCC_CExt) // marker for the start of Crytek Extended data - { - fileLoadStream.Read(4, &marker); - if (FOURCC_AttC == marker) // Attached Channel chunk - { - AZ::u32 size = 0; - fileLoadStream.Read(4, &size); - - alphaImage = LoadImageFromDdsFile(fileLoadStream); - fileLoadStream.Read(4, &marker); - } - - if (FOURCC_CEnd == marker ) // marker for the end of Crytek Extended data - { - fileLoadStream.Read(4, &marker); - } - } - - return alphaImage; - } - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.h b/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.h deleted file mode 100644 index e6f40dac2e..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageObjectImpl.h +++ /dev/null @@ -1,199 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -namespace ImageProcessing -{ - // ImageObject allows the abstraction of different kinds of - // images generated during conversion - class CImageObject: public IImageObject - { - public: - AZ_CLASS_ALLOCATOR(CImageObject, AZ::SystemAllocator, 0); - - public: - // Constructors - CImageObject(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat); - ~CImageObject(); - - //virtual functions from IImageObject - IImageObject* AllocateImage(EPixelFormat pixelFormat) const override; - IImageObject* AllocateImage() const override; - IImageObject* Clone() const override; - EPixelFormat GetPixelFormat() const override; - AZ::u32 GetPixelCount(AZ::u32 mip) const override; - AZ::u32 GetWidth(AZ::u32 mip) const override; - AZ::u32 GetHeight(AZ::u32 mip) const override; - AZ::u32 GetMipCount() const override; - bool IsCubemap() const override - { - return false; - }; - - void GetImagePointer(AZ::u32 mip, AZ::u8*& pMem, AZ::u32& pitch) const override; - AZ::u32 GetMipBufSize(AZ::u32 mip) const override; - void SetMipData(AZ::u32 mip, AZ::u8* mipBuf, AZ::u32 bufSize, AZ::u32 pitch) override; - - AZ::u32 GetImageFlags() const override; - void SetImageFlags(AZ::u32 imageFlags) override; - void AddImageFlags(AZ::u32 imageFlags) override; - void RemoveImageFlags(AZ::u32 imageFlags) override; - bool HasImageFlags(AZ::u32 imageFlags) const override; - - //image data operations and calculations - void ScaleAndBiasChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& scale, const AZ::Vector4& bias) override; - void ClampChannels(AZ::u32 firstMip, AZ::u32 maxMipCount, const AZ::Vector4& min, const AZ::Vector4& max) override; - - void TransferAlphaCoverage(const TextureSettings* textureSetting, const IImageObjectPtr srcImg) override; - float ComputeAlphaCoverageScaleFactor(AZ::u32 mip, float fDesiredCoverage, float fAlphaRef) const override; - float ComputeAlphaCoverage(AZ::u32 firstMip, float fAlphaRef) const override; - - bool CompareImage(const IImageObjectPtr otherImage) const override; - - bool SaveImage(const char* filename, IImageObjectPtr alphaImage, AZStd::vector& outFilePaths) const override; - bool SaveImage(AZ::IO::SystemFileStream& out) const override; - bool SaveMipToFile(AZ::u32 mip, const AZStd::string& filename) const override; - - uint GetTextureMemory() const override; - - EAlphaContent GetAlphaContent() const override; - - void NormalizeVectors(AZ::u32 firstMip, AZ::u32 maxMipCount) override; - - void CopyPropertiesFrom(const IImageObjectPtr src) override; - - void Swizzle(const char channels[4]) override; - - void GetColorRange(AZ::Color& minColor, AZ::Color& maxColor) const override; - void SetColorRange(const AZ::Color& minColor, const AZ::Color& maxColor) override; - float GetAverageBrightness() const override; - void SetAverageBrightness(float avgBrightness) override; - AZ::u32 GetNumPersistentMips() const override; - void SetNumPersistentMips(AZ::u32 nMips) override; - - void GlossFromNormals(bool hasAuthoredGloss) override; - void ConvertLegacyGloss() override; - void ClearColor(float r, float g, float b, float a) override; - //end virtual functions from IImageObject - - private: - - enum EColorNormalization - { - eColorNormalization_Normalize, - eColorNormalization_PassThrough, - }; - - enum EAlphaNormalization - { - eAlphaNormalization_SetToZero, - eAlphaNormalization_Normalize, - eAlphaNormalization_PassThrough, - }; - - private: - class MipLevel - { - public: - AZ_CLASS_ALLOCATOR(MipLevel, AZ::SystemAllocator, 0); - - AZ::u32 m_width; - AZ::u32 m_height; - AZ::u32 m_rowCount; // for compressed textures m_rowCount is usually less than m_height - AZ::u32 m_pitch; // row size in bytes - AZ::u8* m_pData; - - public: - MipLevel() - : m_width(0) - , m_height(0) - , m_rowCount(0) - , m_pitch(0) - , m_pData(0) - { - } - - ~MipLevel() - { - delete[] m_pData; - m_pData = 0; - } - - void Alloc() - { - AZ_Assert(m_pData == 0, "Mip data must be empty before Allocation!"); - m_pData = new AZ::u8[m_pitch * m_rowCount]; - } - - AZ::u32 GetSize() const - { - AZ_Assert(m_pitch, "Pitch must be greater than zero!"); - return m_pitch * m_rowCount; - } - - bool operator==(const MipLevel& other) - { - if (m_width == other.m_width && m_height == other.m_height - && m_rowCount == other.m_rowCount && m_pitch == other.m_pitch) - { - return (memcmp(m_pData, other.m_pData, m_pitch * m_rowCount) == 0); - } - return false; - } - }; - - private: - EPixelFormat m_pixelFormat; - std::vector m_mips; // stores *pointers* to avoid reallocations when elements are erase()'d - - AZ::Color m_colMinARGB; // ARGB will be added the properties of the DDS file - AZ::Color m_colMaxARGB; // ARGB will be added the properties of the DDS file - float m_averageBrightness; // will be added to the properties of the DDS file - AZ::u32 m_imageFlags; // combined from CImageExtensionHelper::EIF_Cubemap,... - AZ::u32 m_numPersistentMips; // number of mipmaps won't be splitted - - public: - //reset this image object to specified format and size - void ResetImage(AZ::u32 width, AZ::u32 height, AZ::u32 maxMipCount, EPixelFormat pixelFormat); - - //get mip count and the origin (top mip) size - void GetExtent(AZ::u32& width, AZ::u32& height, AZ::u32& mipCount) const; - - AZ::u32 GetMipDataSize(AZ::u32 mip) const; - - //! calculates the average brightness for a texture - float CalculateAverageBrightness() const; - - bool HasPowerOfTwoSizes() const override; - - void CopyPropertiesFrom(const CImageObject* src); - - // Computes the dynamically used range for the texture and expands it to use the - // full range [0,2^(2^ExponentBits-1)] for better quality. - void NormalizeImageRange(EColorNormalization eColorNorm, EAlphaNormalization eAlphaNorm, bool bMaintainBlack = false, int nExponentBits = 0); - // Brings normalized ranges back to it's original range. - void ExpandImageRange(EColorNormalization eColorNorm, EAlphaNormalization eAlphaNorm, int nExponentBits = 0); - - private: - //build image file header from this image object - bool BuildSurfaceHeader(DDS_HEADER& header) const; - bool BuildSurfaceExtendedHeader(DDS_HEADER_DXT10& exthead) const; - }; - -} // namespace ImageProcessing - - diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.cpp b/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.cpp deleted file mode 100644 index 09085540a9..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include -#include -#include - -#include - - -namespace ImageProcessing -{ - - ImagePreview::ImagePreview(const AZStd::string& inputImageFile, TextureSettings* textureSetting) - : m_imageFileName(inputImageFile) - , m_textureSetting(textureSetting) - , m_presetSetting(nullptr) - , m_inputImage(nullptr) - { - InitializeJobSettings(); - } - - void ImagePreview::StartConvert() - { - // If there is ongoing job, cancel it - Cancel(); - m_output.Reset(); - if (m_inputImage == nullptr) - { - // Load input image - m_inputImage = IImageObjectPtr(LoadImageFromFile(m_imageFileName)); - } - // Get preset if the setting in texture is changed - if (m_presetSetting == nullptr || m_presetSetting->m_uuid != m_textureSetting->m_preset) - { - m_presetSetting = BuilderSettingManager::Instance()->GetPreset(m_textureSetting->m_preset); - } - const bool isPreview = true; - const bool autoDelete = false; - PlatformName defaultPlatform = BuilderSettingManager::s_defaultPlatform; - - m_convertJob = AZStd::make_unique(m_inputImage, m_textureSetting, m_presetSetting, - isPreview, defaultPlatform, &m_output, autoDelete, m_jobContext.get()); - m_convertJob->SetDependent(&m_doneJob); - m_convertJob->Start(); - } - - bool ImagePreview::IsDone() - { - return m_output.IsReady(); - } - - float ImagePreview::GetProgress() - { - if (!m_output.IsReady()) - { - return m_output.GetProgress(); - } - return 1.0f; - } - - void ImagePreview::Cancel() - { - if (m_convertJob) - { - m_convertJob->Cancel(); - // Block until job completes - m_doneJob.StartAndWaitForCompletion(); - - AZ_Assert(m_output.IsReady(), "Conversion job is not done yet!"); - } - m_convertJob.release(); - m_doneJob.Reset(true); - } - - IImageObjectPtr ImagePreview::GetOutputImage() - { - return m_output.GetOutputImage(ImageConvertOutput::Preview); - } - - ImagePreview::~ImagePreview() - { - Cancel(); - // Maintain the releasing order - m_jobManager.release(); - m_jobContext.release(); - m_jobCancelGroup.release(); - } - - void ImagePreview::InitializeJobSettings() - { - AZ::JobManagerDesc desc; - AZ::JobManagerThreadDesc threadDesc; - desc.m_workerThreads.push_back(threadDesc); - // Check to ensure these have not already been initialized. - AZ_Error("Image Processing", !m_jobManager && !m_jobCancelGroup && !m_jobContext, "ImagePreview::InitializeJobSettings is being called again after it has already been initialized"); - m_jobManager = AZStd::make_unique(desc); - m_jobCancelGroup = AZStd::make_unique(); - m_jobContext = AZStd::make_unique(*m_jobManager, *m_jobCancelGroup); - - new (&m_doneJob) AZ::JobCompletion(m_jobContext.get()); //re-initialize with the job context - } - - - void GetImageInfoString(IImageObjectPtr image, bool isAlpha, AZStd::string& output) - { - if (!image) - { - return; - } - - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - EPixelFormat format = image->GetPixelFormat(); - const PixelFormatInfo* info = pixelFormats.GetPixelFormatInfo(format); - if (info) - { - output += AZStd::string::format("Format: %s\r\n", info->szName); - } - - AZ::u32 mipCount = image->GetMipCount(); - output += AZStd::string::format("Mip Count: %d\r\n", mipCount); - - AZ::u32 memSize = image->GetTextureMemory(); - AZStd::string memSizeString = ImageProcessingEditor::EditorHelper::GetFileSizeString(memSize); - output += AZStd::string::format("Memory Size: %s\r\n", memSizeString.c_str()); - - if (!isAlpha) - { - if (image->HasImageFlags(EIF_SRGBRead)) - { - output += "Color Space: sRGB\r\n"; - } - else - { - output += "Color Space: Linear\r\n"; - } - - if (image->HasImageFlags(EIF_Cubemap)) - { - output += "Cubemap\r\n"; - } - } - - AZ::u32 imageFlag = image->GetImageFlags(); - output += AZStd::string::format("Image Flag: 0x%08x\r\n", imageFlag); - } - - bool ImagePreview::GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo) - { - if (!AzFramework::StringFunc::Path::IsExtension(fullProductFileName, "dds", false)) - { - return false; - } - - IImageObjectPtr originImage = IImageObjectPtr(LoadImageFromDdsFile(fullProductFileName)); - IImageObjectPtr alphaImage; - - if (originImage && originImage->HasImageFlags(EIF_AttachedAlpha)) - { - if (originImage->HasImageFlags(EIF_Splitted)) - { - AZStd::string alphaFileName = AZStd::string::format("%s.a", fullProductFileName); - alphaImage = IImageObjectPtr(LoadImageFromDdsFile(alphaFileName)); - - } - else - { - alphaImage = IImageObjectPtr(LoadAttachedImageFromDdsFile(fullProductFileName, originImage)); - } - } - - GetImageInfoString(originImage, false, productInfo); - GetImageInfoString(alphaImage, true, productAlphaInfo); - - IImageObjectPtr combinedImage = MergeOutputImageForPreview(originImage, alphaImage); - if (combinedImage) - { - AZ::u8* imageBuf; - AZ::u32 pitch; - combinedImage->GetImagePointer(0, imageBuf, pitch); - const AZ::u32 width = originImage->GetWidth(0); - const AZ::u32 height = originImage->GetHeight(0); - QImage result = QImage(imageBuf, width, height, pitch, QImage::Format_RGBA8888); - previewImage = result.copy(); // Return a deep copy here - return true; - } - - return false; - } - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.h b/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.h deleted file mode 100644 index 25be5ed37c..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImagePreview.h +++ /dev/null @@ -1,59 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include - -namespace ImageProcessing -{ - // The reason to have image preview class, we should keep the source image loaded once, - // we could restart conversion and cancel the old conversion at anytime when setting changed - class ImagePreview - { - public: - ImagePreview(const AZStd::string& inputImageFile, TextureSettings* textureSetting); - ~ImagePreview(); - - void InitializeJobSettings(); - void StartConvert(); - bool IsDone(); - float GetProgress(); - void Cancel(); - IImageObjectPtr GetOutputImage(); - - // Output preview image for Asset Browser - static bool GetProductTexturePreview(const char* fullProductFileName, QImage& previewImage, AZStd::string& productInfo, AZStd::string& productAlphaInfo); - - private: - AZStd::string m_imageFileName; - IImageObjectPtr m_inputImage; - const TextureSettings* m_textureSetting; - const PresetSettings* m_presetSetting; - - IImageObjectPtr m_outputImage; - IImageObjectPtr m_outputAlphaImage; - - ImageConvertOutput m_output; - - AZStd::unique_ptr m_jobManager; - AZStd::unique_ptr m_jobCancelGroup; - AZStd::unique_ptr m_jobContext; - AZStd::unique_ptr m_convertJob; - AZ::JobCompletion m_doneJob; - }; - - // Get basic image info as string - void GetImageInfoString(IImageObjectPtr image, bool isAlpha, AZStd::string& output); - -}// namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/ImageToProcess.h b/Gems/ImageProcessing/Code/Source/Processing/ImageToProcess.h deleted file mode 100644 index 080fd602e8..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/ImageToProcess.h +++ /dev/null @@ -1,114 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include -#include -#include - -namespace ImageProcessing -{ - - //cubemap layouts - enum CubemapLayoutType - { - CubemapLayoutHorizontal = 0, //6x1 strip. with rotations. - CubemapLayoutHorizontalCross, //4x3. - CubemapLayoutVerticalCross, //3x4 - CubemapLayoutVertical, //1x6 strip. new output format. it's better because the memory is continuous for each face - CubemapLayoutTypeCount, - CubemapLayoutNone = CubemapLayoutTypeCount - }; - - class ImageToProcess - { - private: - IImageObjectPtr m_img; - ICompressor::CompressOption m_compressOption; - - private: - ImageToProcess(const ImageToProcess&); - - public: - ImageToProcess(IImageObjectPtr img) - { - m_img = img; - } - - ~ImageToProcess() - { - } - - void Set(IImageObjectPtr img) - { - m_img = img; - } - - IImageObjectPtr Get() const - { - return m_img; - } - - ICompressor::CompressOption& GetCompressOption() - { - return m_compressOption; - } - - void SetCompressOption(const ICompressor::CompressOption& compressOption) - { - m_compressOption = compressOption; - } - - public: - // --------------------------------------------------------------------------------- - //! can be used to compress, requires a preset - void ConvertFormat(EPixelFormat fmtTo); - void ConvertFormatUncompressed(EPixelFormat fmtTo); - - // --------------------------------------------------------------------------------- - // Arguments: - // bDeGamma - apply de-gamma correction - bool GammaToLinearRGBA32F(bool bDeGamma); - void LinearToGamma(); - - // --------------------------------------------------------------------------------- - // Resizers for A32B32G32R32F - - // Prerequisites: image width is even, ARGB32F only, no mips. - void DownscaleTwiceHorizontally(); - - // Prerequisites: height is even, ARGB32F only, no mips. - void DownscaleTwiceVertically(); - - // Prerequisites: width is pow of 2, ARGB32F only, no mips. - void UpscalePow2TwiceHorizontally(); - - // Prerequisites: height is pow of 2, ARGB32F only, no mips. - void UpscalePow2TwiceVertically(); - - // --------------------------------------------------------------------------------- - // Tools for A32B32G32R32F - - // input needs to be in range 0..1 - void AddNormalMap(const IImageObject* pAddBump); - - void CreateHighPass(uint32 dwMipDown); - - void CreateColorChart(); - - //convert various original cubemap layouts to new layout - bool ConvertCubemapLayout(CubemapLayoutType newLayout); - - }; -}// namespace ImageProcessing - diff --git a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.cpp b/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.cpp deleted file mode 100644 index 3bfa371dc0..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.cpp +++ /dev/null @@ -1,430 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include - -namespace ImageProcessing -{ - CPixelFormats* CPixelFormats::s_instance = nullptr; - - CPixelFormats& CPixelFormats::GetInstance() - { - if (s_instance == nullptr) - { - s_instance = new CPixelFormats(); - } - - return *s_instance; - } - - void CPixelFormats::DestroyInstance() - { - delete s_instance; - s_instance = nullptr; - } - - PixelFormatInfo::PixelFormatInfo( - int a_bitsPerPixel, - int a_Channels, - bool a_Alpha, - const char* a_szAlpha, - uint32 a_minWidth, - uint32 a_minHeight, - int a_blockWidth, - int a_blockHeight, - int a_bitsPerBlock, - bool a_bSquarePow2, - DXGI_FORMAT a_d3d10Format, - AZ::u32 a_fourCC, - ESampleType a_eSampleType, - const char* a_szName, - const char* a_szDescription, - bool a_bCompressed, - bool a_bSelectable) - : nChannels(a_Channels) - , bHasAlpha(a_Alpha) - , minWidth(a_minWidth) - , minHeight(a_minHeight) - , blockWidth(a_blockWidth) - , blockHeight(a_blockHeight) - , bitsPerBlock(a_bitsPerBlock) - , bSquarePow2(a_bSquarePow2) - , szAlpha(a_szAlpha) - , d3d10Format(a_d3d10Format) - , fourCC(a_fourCC) - , eSampleType(a_eSampleType) - , szName(a_szName) - , szLegacyName(a_szName) - , szDescription(a_szDescription) - , bCompressed(a_bCompressed) - , bSelectable(a_bSelectable) - { - //validate pixel format - //a_bitsPerPixel could be 0 if it's ACTC format since the actual bits per-pixel could be 6.4, 5.12 etc. - if (a_bitsPerPixel) - { - AZ_Assert(a_bitsPerPixel * blockWidth * blockHeight == bitsPerBlock, "PixelFormatInfo: Wrong block setting"); - } - - AZ_Assert(szName, "szName can't be nullptr"); - AZ_Assert(nChannels > 0 && nChannels <= 4, "unreasonable channel count %d", nChannels); - AZ_Assert(a_szDescription, "szDescription can't be nullptr"); - AZ_Assert(blockWidth > 0 && blockHeight > 0, "blcok size need to be larger than 0: %d x %d", blockWidth, blockHeight); - AZ_Assert(minWidth > 0 && minHeight > 0, "piexel required mininum image size need to be larger than 0: %d x %d", minWidth, minHeight); - if (!bCompressed) - { - AZ_Assert(blockWidth == 1 && blockHeight == 1, "Uncompressed format shouldn't have block which size > 1"); - } - } - - CPixelFormats::CPixelFormats() - { - InitPixelFormats(); - - m_removedLegacyFormats["DXT1"] = ePixelFormat_BC1; - m_removedLegacyFormats["DXT1a"] = ePixelFormat_BC1a; - m_removedLegacyFormats["DXT3"] = ePixelFormat_BC3; - m_removedLegacyFormats["DXT3t"] = ePixelFormat_BC3t; - m_removedLegacyFormats["DXT5"] = ePixelFormat_BC3; - m_removedLegacyFormats["DXT5t"] = ePixelFormat_BC3t; - m_removedLegacyFormats["3DCp"] = ePixelFormat_BC4; - m_removedLegacyFormats["3DC"] = ePixelFormat_BC5; - } - - void CPixelFormats::InitPixelFormat(EPixelFormat format, const PixelFormatInfo& formatInfo) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - - if (m_pixelFormatInfo[format].szName && m_pixelFormatNameMap.find(formatInfo.szName) != m_pixelFormatNameMap.end()) - { - // double initialization - AZ_Assert(false, "Pixel format already exist: %s", m_pixelFormatInfo[format].szName); - } - m_pixelFormatNameMap[formatInfo.szName] = format; - m_pixelFormatInfo[format] = formatInfo; - } - - void CPixelFormats::InitPixelFormats() - { - // Unsigned Formats - // Data in an unsigned format must be positive. Unsigned formats use combinations of - // (R)ed, (G)reen, (B)lue, (A)lpha, (L)uminance - InitPixelFormat(ePixelFormat_R8G8B8A8, PixelFormatInfo(32, 4, true, "8", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R8G8B8A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8G8B8A8", "32-bit RGBA pixel format with alpha, using 8 bits per channel", false, true)); - InitPixelFormat(ePixelFormat_R8G8B8X8, PixelFormatInfo(32, 4, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R8G8B8A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8G8B8X8", "32-bit RGB pixel format, where 8 bits are reserved for each color", false, true)); - InitPixelFormat(ePixelFormat_R8G8, PixelFormatInfo(16, 2, false, "0", 1, 1, 1, 1, 16, false, DXGI_FORMAT_R8G8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8G8", "16-bit red/green, using 8 bits per channel", false, false)); - InitPixelFormat(ePixelFormat_R8, PixelFormatInfo( 8, 1, false, "0", 1, 1, 1, 1, 8, false, DXGI_FORMAT_R8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "R8", "8-bit red only", false, false)); - InitPixelFormat(ePixelFormat_A8, PixelFormatInfo( 8, 1, true, "8", 1, 1, 1, 1, 8, false, DXGI_FORMAT_A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "A8", "8-bit alpha only", false, true)); - InitPixelFormat(ePixelFormat_R16G16B16A16, PixelFormatInfo(64, 4, true, "16", 1, 1, 1, 1, 64, false, DXGI_FORMAT_R16G16B16A16_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint16, "R16G16B16A16", "64-bit ARGB pixel format with alpha, using 16 bits per channel", false, false)); - InitPixelFormat(ePixelFormat_R16G16, PixelFormatInfo(32, 2, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R16G16_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint16, "R16G16", "32-bit red/green, using 16 bits per channel", false, false)); - InitPixelFormat(ePixelFormat_R16, PixelFormatInfo(16, 1, false, "0", 1, 1, 1, 1, 16, false, DXGI_FORMAT_R16_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint16, "R16", "16-bit red only", false, false)); - - // Custom FourCC Formats - // Data in these FourCC formats is custom compressed data and only decodable by certain hardware. - InitPixelFormat(ePixelFormat_ASTC_4x4, PixelFormatInfo(0, 4, true, "?", 16, 16, 4, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_4x4, ESampleType::eSampleType_Compressed, "ASTC_4x4", "ASTC 4x4 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_5x4, PixelFormatInfo(0, 4, true, "?", 16, 16, 5, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_5x4, ESampleType::eSampleType_Compressed, "ASTC_5x4", "ASTC 5x4 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_5x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 5, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_5x5, ESampleType::eSampleType_Compressed, "ASTC_5x5", "ASTC 5x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_6x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 6, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_6x5, ESampleType::eSampleType_Compressed, "ASTC_6x5", "ASTC 6x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_6x6, PixelFormatInfo(0, 4, true, "?", 16, 16, 6, 6, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_6x6, ESampleType::eSampleType_Compressed, "ASTC_6x6", "ASTC 6x6 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_8x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 8, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_8x5, ESampleType::eSampleType_Compressed, "ASTC_8x5", "ASTC 8x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_8x6, PixelFormatInfo(0, 4, true, "?", 16, 16, 8, 6, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_8x6, ESampleType::eSampleType_Compressed, "ASTC_8x6", "ASTC 8x6 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_8x8, PixelFormatInfo(0, 4, true, "?", 16, 16, 8, 8, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_8x8, ESampleType::eSampleType_Compressed, "ASTC_8x8", "ASTC 8x8 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x5, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 5, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x5, ESampleType::eSampleType_Compressed, "ASTC_10x5", "ASTC 10x5 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x6, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 6, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x6, ESampleType::eSampleType_Compressed, "ASTC_10x6", "ASTC 10x6 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x8, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 8, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x8, ESampleType::eSampleType_Compressed, "ASTC_10x8", "ASTC 10x8 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_10x10, PixelFormatInfo(0, 4, true, "?", 16, 16, 10, 10, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_10x10, ESampleType::eSampleType_Compressed, "ASTC_10x10", "ASTC 10x10 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_12x10, PixelFormatInfo(0, 4, true, "?", 16, 16, 12, 10, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_12x10, ESampleType::eSampleType_Compressed, "ASTC_12x10", "ASTC 12x10 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ASTC_12x12, PixelFormatInfo(0, 4, true, "?", 16, 16, 12, 12, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ASTC_12x12, ESampleType::eSampleType_Compressed, "ASTC_12x12", "ASTC 12x12 compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_PVRTC2, PixelFormatInfo(2, 4, true, "2", 16, 16, 8, 4, 64, true, DXGI_FORMAT_UNKNOWN, FOURCC_PVRTC2, ESampleType::eSampleType_Compressed, "PVRTC2", "POWERVR 2 bpp compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_PVRTC4, PixelFormatInfo(4, 4, true, "2", 8, 8, 4, 4, 64, true, DXGI_FORMAT_UNKNOWN, FOURCC_PVRTC4, ESampleType::eSampleType_Compressed, "PVRTC4", "POWERVR 4 bpp compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_EAC_R11, PixelFormatInfo(4, 1, true, "4", 4, 4, 4, 4, 64, false, DXGI_FORMAT_UNKNOWN, FOURCC_EAC_R11, ESampleType::eSampleType_Compressed, "EAC_R11", "EAC 4 bpp single channel texture format", true, false)); - InitPixelFormat(ePixelFormat_EAC_RG11, PixelFormatInfo(8, 2, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_EAC_RG11, ESampleType::eSampleType_Compressed, "EAC_RG11", "EAC 8 bpp dual channel texture format", true, false)); - InitPixelFormat(ePixelFormat_ETC2, PixelFormatInfo(4, 3, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_UNKNOWN, FOURCC_ETC2, ESampleType::eSampleType_Compressed, "ETC2", "ETC2 RGB 4 bpp compressed texture format", true, false)); - InitPixelFormat(ePixelFormat_ETC2a, PixelFormatInfo(8, 4, true, "4", 4, 4, 4, 4, 128, false, DXGI_FORMAT_UNKNOWN, FOURCC_ETC2A, ESampleType::eSampleType_Compressed, "ETC2a", "ETC2 RGBA 8 bpp compressed texture format", true, false)); - - // Standardized Compressed DXGI Formats (DX10+) - // Data in these compressed formats is hardware decodable on all DX10 chips, and manageable with the DX10-API. - InitPixelFormat(ePixelFormat_BC1, PixelFormatInfo(4, 3, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC1_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC1", "BC1 compressed texture format", true, true)); - InitPixelFormat(ePixelFormat_BC1a, PixelFormatInfo(4, 4, true, "1", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC1_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC1a", "BC1a compressed texture format with transparency", true, true)); - InitPixelFormat(ePixelFormat_BC3, PixelFormatInfo(8, 4, true, "3of8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC3_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC3", "BC3 compressed texture format", true, true)); - InitPixelFormat(ePixelFormat_BC3t, PixelFormatInfo(8, 4, true, "3of8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC3_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC3t", "BC3t compressed texture format with transparency", true, true)); - InitPixelFormat(ePixelFormat_BC4, PixelFormatInfo(4, 1, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC4_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC4", "BC4 compressed texture format for single channel maps. 3DCp", true, true)); - InitPixelFormat(ePixelFormat_BC4s, PixelFormatInfo(4, 1, false, "0", 4, 4, 4, 4, 64, false, DXGI_FORMAT_BC4_SNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC4s", "BC4 compressed texture format for signed single channel maps", true, true)); - InitPixelFormat(ePixelFormat_BC5, PixelFormatInfo(8, 2, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC5_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC5", "BC5 compressed texture format for two channel maps or normalmaps. 3DC", true, true)); - InitPixelFormat(ePixelFormat_BC5s, PixelFormatInfo(8, 2, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC5_SNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC5s", "BC5 compressed texture format for signed two channel maps or normalmaps", true, true)); - InitPixelFormat(ePixelFormat_BC6UH, PixelFormatInfo(8, 3, false, "0", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC6H_UF16, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC6UH", "BC6 compressed texture format, unsigned half", true, true)); - InitPixelFormat(ePixelFormat_BC7, PixelFormatInfo(8, 4, true, "8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC7_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC7", "BC7 compressed texture format", true, true)); - InitPixelFormat(ePixelFormat_BC7t, PixelFormatInfo(8, 4, true, "8", 4, 4, 4, 4, 128, false, DXGI_FORMAT_BC7_UNORM, FOURCC_DX10, ESampleType::eSampleType_Compressed, "BC7t", "BC7t compressed texture format with transparency", true, true)); - - // Float formats - // Data in a Float format is floating point data. - InitPixelFormat(ePixelFormat_R9G9B9E5, PixelFormatInfo(32, 3, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R9G9B9E5_SHAREDEXP, FOURCC_DX10, ESampleType::eSampleType_Compressed, "R9G9B9E5", "32-bit RGB pixel format with shared exponent", false, true)); - InitPixelFormat(ePixelFormat_R32G32B32A32F, PixelFormatInfo(128, 4, true, "23", 1, 1, 1, 1, 128, false, DXGI_FORMAT_R32G32B32A32_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Float, "R32G32B32A32F", "four float channels", false, false)); - InitPixelFormat(ePixelFormat_R32G32F, PixelFormatInfo(64, 2, false, "0", 1, 1, 1, 1, 64, false, DXGI_FORMAT_R32G32_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Float, "R32G32F", "two float channels", false, false)); // FIXME: This should be eTF_R32G32F, but CryTek did not add that enum to ITexture.h yet - InitPixelFormat(ePixelFormat_R32F, PixelFormatInfo(32, 1, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R32_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Float, "R32F", "one float channel", false, false)); - InitPixelFormat(ePixelFormat_R16G16B16A16F, PixelFormatInfo(64, 4, true, "10", 1, 1, 1, 1, 64, false, DXGI_FORMAT_R16G16B16A16_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Half, "R16G16B16A16F", "four half channels", false, false)); - InitPixelFormat(ePixelFormat_R16G16F, PixelFormatInfo(32, 2, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_R16G16_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Half, "R16G16F", "two half channel", false, false)); - InitPixelFormat(ePixelFormat_R16F, PixelFormatInfo(16, 1, false, "0", 1, 1, 1, 1, 16, false, DXGI_FORMAT_R16_FLOAT, FOURCC_DX10, ESampleType::eSampleType_Half, "R16F", "one half channel", false, false)); - - //legacy BGRA8 - InitPixelFormat(ePixelFormat_B8G8R8A8, PixelFormatInfo(32, 4, true, "8", 1, 1, 1, 1, 32, false, DXGI_FORMAT_B8G8R8A8_UNORM, FOURCC_DX10, ESampleType::eSampleType_Uint8, "B8G8R8A8", "32-bit BGRA pixel format with alpha, using 8 bits per channel", false, true)); - - InitPixelFormat(ePixelFormat_R32, PixelFormatInfo(32, 1, false, "0", 1, 1, 1, 1, 32, false, DXGI_FORMAT_FORCE_UINT, FOURCC_DX10, ESampleType::eSampleType_Uint32, "R32", "32-bit red only", false, false)); - - //Set legacy name it can be used for convertion - m_pixelFormatInfo[ePixelFormat_R8G8B8A8].szLegacyName = "A8R8G8B8"; - m_pixelFormatInfo[ePixelFormat_R8G8B8X8].szLegacyName = "X8R8G8B8"; - m_pixelFormatInfo[ePixelFormat_R8G8].szLegacyName = "G8R8"; - m_pixelFormatInfo[ePixelFormat_R16G16B16A16].szLegacyName = "A16B16G16R16"; - m_pixelFormatInfo[ePixelFormat_R16G16].szLegacyName = "G16R16"; - m_pixelFormatInfo[ePixelFormat_R32G32B32A32F].szLegacyName = "A32B32G32R32F"; - m_pixelFormatInfo[ePixelFormat_R32G32F].szLegacyName = "G32R32F"; - m_pixelFormatInfo[ePixelFormat_R16G16B16A16F].szLegacyName = "A16B16G16R16F"; - m_pixelFormatInfo[ePixelFormat_R16G16F].szLegacyName = "G16R16F"; - - //validate all pixel formats are proper initialized - for (int i = 0; i < ePixelFormat_Count; ++i) - { - if (m_pixelFormatInfo[i].szName == 0) - { - // Uninitialized entry. Should never happen. But, if it happened: make sure that entries from - // the EPixelFormat enum and InitPixelFormat() calls match. - AZ_Assert(false, "InitPixelFormats error: not all pixel formats have an implementation."); - } - } - } - - - EPixelFormat CPixelFormats::FindPixelFormatByName(const char* name) - { - if (m_pixelFormatNameMap.find(name) != m_pixelFormatNameMap.end()) - { - return m_pixelFormatNameMap[name]; - } - return ePixelFormat_Unknown; - } - - EPixelFormat CPixelFormats::FindPixelFormatByLegacyName(const char* name) - { - if (m_removedLegacyFormats.find(name) != m_removedLegacyFormats.end()) - { - return m_removedLegacyFormats[name]; - } - - for (int i = 0; i < ePixelFormat_Count; ++i) - { - if (azstricmp(m_pixelFormatInfo[i].szLegacyName, name) == 0) - { - return (EPixelFormat)i; - } - } - return ePixelFormat_Unknown; - } - - const PixelFormatInfo* CPixelFormats::GetPixelFormatInfo(EPixelFormat format) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - return &m_pixelFormatInfo[format]; - } - - bool CPixelFormats::IsPixelFormatUncompressed(EPixelFormat format) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - return !m_pixelFormatInfo[format].bCompressed; - } - - bool CPixelFormats::IsPixelFormatWithoutAlpha(EPixelFormat format) - { - AZ_Assert((format >= 0) && (format < ePixelFormat_Count), "Unsupport pixel format: %d", format); - return !m_pixelFormatInfo[format].bHasAlpha; - } - - uint32 CPixelFormats::ComputeMaxMipCount(EPixelFormat format, uint32 width, uint32 height) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - - AZ_Assert(pFormatInfo != nullptr, "ComputeMaxMipCount: unsupport pixel format %d", format); - - uint32 tmpWidth = width; - uint32 tmpHeight = height; - - bool bIgnoreBlockSize = CanImageSizeIgnoreBlockSize(format); - - uint32 mipCountW = 0; - while ((tmpWidth >= pFormatInfo->minWidth) && (bIgnoreBlockSize || (tmpWidth % pFormatInfo->blockWidth == 0))) - { - ++mipCountW; - tmpWidth >>= 1; - } - - uint32 mipCountH = 0; - while ((tmpHeight >= pFormatInfo->minHeight) && (bIgnoreBlockSize || (tmpHeight % pFormatInfo->blockHeight == 0))) - { - ++mipCountH; - tmpHeight >>= 1; - } - - //for compressed image, use minmum mip out of W and H because any size below won't be compressed properly - //for non-compressed image. use maximum mip count. for example the lowest two mips of 128x64 would be 2x1 and 1x1 - const uint32 mipCount = (pFormatInfo->bCompressed) - ? AZStd::min(mipCountW, mipCountH) - : AZStd::max(mipCountW, mipCountH); - - // In some cases, user may call this function for image size which is qualified for this pixel format, - // the mipCount could be 0 for those cases. Round it to 1 if it happend. - return AZStd::max((uint32)1, mipCount); - } - - bool CPixelFormats::CanImageSizeIgnoreBlockSize(EPixelFormat format) - { - // ASTC is a kind of block compression but it doesn't need the image size to be interger mutiples of block size. - // reference: https://www.khronos.org/registry/OpenGL/extensions/KHR/KHR_texture_compression_astc_hdr.txt - //"For images which are not an integer multiple of the block size, additional texels are added to the edges - // with maximum X and Y.These texels may be any color, as they will not be accessed." - bool bIgnoreBlockSize = IsASTCFormat(format); - - return bIgnoreBlockSize; - } - - bool CPixelFormats::IsImageSizeValid(EPixelFormat format, uint32 imageWidth, uint32 imageHeight, [[maybe_unused]] bool logWarning) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - AZ_Assert(pFormatInfo != nullptr, "IsImageSizeValid: unsupport pixel format %d", format); - - //if the format requires image to be sqaure and power of 2 - if (pFormatInfo->bSquarePow2 && ((imageWidth != imageHeight) || (imageWidth & (imageWidth - 1)) != 0)) - { - AZ_Warning("ImageBuilder", !logWarning, "Image size need to be square and power of 2 for pixel format %s", - pFormatInfo->szName); - return false; - } - - // minimum size required by the pixel format - if (imageWidth < pFormatInfo->minWidth || imageHeight < pFormatInfo->minHeight) - { - AZ_Warning("ImageBuilder", !logWarning, "The image size (%dx%d) is smaller than minimum size (%dx%d) for pixel format %s", - imageWidth, imageHeight, pFormatInfo->minWidth, pFormatInfo->minHeight, pFormatInfo->szName); - return false; - } - - //check image size againest block size - if (!CanImageSizeIgnoreBlockSize(format)) - { - if (imageWidth % pFormatInfo->blockWidth != 0 || imageHeight % pFormatInfo->blockHeight != 0) - { - AZ_Warning("ImageBuilder", !logWarning, "Image size (%dx%d) need to be integer multiplier of compression block size (%dx%d) for pixel format %s", - imageWidth, imageHeight, pFormatInfo->minWidth, pFormatInfo->minHeight, pFormatInfo->szName); - return false; - } - } - - return true; - } - - AZ::u32 NextPowOf2(AZ::u32 value) - { - value--; - value |= value >> 1; - value |= value >> 2; - value |= value >> 4; - value |= value >> 8; - value |= value >> 16; - value++; - return value; - } - - void CPixelFormats::GetSuitableImageSize(EPixelFormat format, AZ::u32 imageWidth, AZ::u32 imageHeight, - AZ::u32& outWidth, AZ::u32& outHeight) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - AZ_Assert(pFormatInfo != nullptr, "IsImageSizeValid: unsupport pixel format %d", format); - - outWidth = imageWidth; - outHeight = imageHeight; - - // minimum size required by the pixel format - if (outWidth < pFormatInfo->minWidth) - { - outWidth = pFormatInfo->minWidth; - } - if (outHeight < pFormatInfo->minHeight) - { - outHeight = pFormatInfo->minHeight; - } - - if (pFormatInfo->bSquarePow2 && ((outWidth != outHeight) || (outWidth & (outWidth - 1)) != 0)) - { - AZ::u32 sideSide = AZ::GetMax(outWidth, outHeight); - outWidth = NextPowOf2(sideSide); - outHeight = outWidth; - } - - //check image size againest block size - //if the format requires square and power of 2. we can skip this step - if (!CanImageSizeIgnoreBlockSize(format) && !pFormatInfo->bSquarePow2) - { - if (outWidth % pFormatInfo->blockWidth != 0) - { - outWidth = ((outWidth + pFormatInfo->blockWidth -1) / pFormatInfo->blockWidth) * pFormatInfo->blockWidth; - } - if (outHeight % pFormatInfo->blockHeight != 0) - { - outHeight = ((outHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->blockHeight; - } - } - - } - - uint32 CPixelFormats::EvaluateImageDataSize(EPixelFormat format, uint32 imageWidth, uint32 imageHeight) - { - const PixelFormatInfo* const pFormatInfo = GetPixelFormatInfo(format); - AZ_Assert(pFormatInfo != nullptr, "IsImageSizeValid: unsupport pixel format %d", format); - - //the image should pass IsImageSizeValid test to be eavluated correctly - if (!IsImageSizeValid(format, imageWidth, imageHeight, false)) - { - return 0; - } - - // get number of blocks (ceiling round up for block count) and multiply with bits per block. Divided by 8 to get - // final byte size - return (((imageWidth + pFormatInfo->blockWidth -1) / pFormatInfo->blockWidth) * - ((imageHeight + pFormatInfo->blockHeight - 1) / pFormatInfo->blockHeight) * pFormatInfo->bitsPerBlock) / 8; - } - - bool CPixelFormats::IsFormatSingleChannel(EPixelFormat fmt) - { - return (m_pixelFormatInfo[fmt].nChannels == 1); - } - - bool CPixelFormats::IsFormatSigned(EPixelFormat fmt) - { - // all these formats contain signed data, the FP-formats contain scale & biased unsigned data - return (fmt == ePixelFormat_BC4s || fmt == ePixelFormat_BC5s /*|| fmt == ePixelFormat_BC6SH*/); - } - - bool CPixelFormats::IsFormatFloatingPoint(EPixelFormat fmt, bool bFullPrecision) - { - // all these formats contain floating point data - if (!bFullPrecision) - { - return ((fmt == ePixelFormat_R16F || fmt == ePixelFormat_R16G16F || - fmt == ePixelFormat_R16G16B16A16F) || (fmt == ePixelFormat_BC6UH || fmt == ePixelFormat_R9G9B9E5)); - } - else - { - return ((fmt == ePixelFormat_R32F || fmt == ePixelFormat_R32G32F || fmt == ePixelFormat_R32G32B32A32F)); - } - } -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.h b/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.h deleted file mode 100644 index aee61d1a9f..0000000000 --- a/Gems/ImageProcessing/Code/Source/Processing/PixelFormatInfo.h +++ /dev/null @@ -1,222 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -#include // DX10+ formats. DXGI_FORMAT - -#include - -#include -#include - -namespace ImageProcessing -{ - //The original implementation was from cryhalf's CryConvertFloatToHalf and CryConvertHalfToFloat function - struct SHalf - { - explicit SHalf(float floatValue) - { - AZ::u32 Result; - - AZ::u32 intValue = ((AZ::u32*)(&floatValue))[0]; - AZ::u32 Sign = (intValue & 0x80000000U) >> 16U; - intValue = intValue & 0x7FFFFFFFU; - - if (intValue > 0x47FFEFFFU) - { - // The number is too large to be represented as a half. Saturate to infinity. - Result = 0x7FFFU; - } - else - { - if (intValue < 0x38800000U) - { - // The number is too small to be represented as a normalized half. - // Convert it to a denormalized value. - AZ::u32 Shift = 113U - (intValue >> 23U); - intValue = (0x800000U | (intValue & 0x7FFFFFU)) >> Shift; - } - else - { - // Rebias the exponent to represent the value as a normalized half. - intValue += 0xC8000000U; - } - - Result = ((intValue + 0x0FFFU + ((intValue >> 13U) & 1U)) >> 13U) & 0x7FFFU; - } - h = (Result | Sign); - } - - operator float() const - { - AZ::u32 Mantissa; - AZ::u32 Exponent; - AZ::u32 Result; - - Mantissa = h & 0x03FF; - - if ((h & 0x7C00) != 0) // The value is normalized - { - Exponent = ((h >> 10) & 0x1F); - } - else if (Mantissa != 0) // The value is denormalized - { - // Normalize the value in the resulting float - Exponent = 1; - - do - { - Exponent--; - Mantissa <<= 1; - } while ((Mantissa & 0x0400) == 0); - - Mantissa &= 0x03FF; - } - else // The value is zero - { - Exponent = -112; - } - - Result = ((h & 0x8000) << 16) | // Sign - ((Exponent + 112) << 23) | // Exponent - (Mantissa << 13); // Mantissa - - return *(float*)&Result; - } - - private: - AZ::u16 h; - }; - - enum class ESampleType - { - eSampleType_Uint8, - eSampleType_Uint16, - eSampleType_Uint32, - eSampleType_Half, - eSampleType_Float, - eSampleType_Compressed, - }; - - struct PixelFormatInfo - { - - int nChannels; // channel count per pixel - bool bHasAlpha; // has alpha channel or not - const char* szAlpha; // a string of bits of alpha channel used to show brief of the pixel format - uint32 minWidth; // minimum width required for image using this pixel format - uint32 minHeight; // minimum height required for image using this pixel format - int blockWidth; // width of the block for block based compressing - int blockHeight; // Height of the block for block based compressing - int bitsPerBlock; // bits per pixel before uncompressed - bool bSquarePow2; // whether the pixel format requires image size be square and power of 2. - DXGI_FORMAT d3d10Format; // the mapping d3d10 pixel format - ESampleType eSampleType; // the data type used to present pixel - const char* szLegacyName; // name used for cryEngine - const char* szName; // name for showing in editors - const char* szDescription; // description for showing in editors - bool bCompressed; // if it's a compressed format - bool bSelectable; // shows up in the list of usable destination pixel formats in the dialog window - AZ::u32 fourCC; // fourCC to identify a none d3d10 format - - PixelFormatInfo() - : szAlpha(0) - , bitsPerBlock(-1) - , d3d10Format(DXGI_FORMAT_UNKNOWN) - , szName(0) - , szDescription(0) - , fourCC(0) - { - } - - PixelFormatInfo( - int a_bitsPerPixel, - int a_Channels, - bool a_Alpha, - const char* a_szAlpha, - uint32 a_minWidth, - uint32 a_minHeight, - int a_blockWidth, - int a_blockHeight, - int a_bitsPerBlock, - bool a_bSquarePow2, - DXGI_FORMAT a_d3d10Format, - AZ::u32 a_fourCC, - ESampleType a_eSampleType, - const char* a_szName, - const char* a_szDescription, - bool a_bCompressed, - bool a_bSelectable); - }; - - class CPixelFormats - { - public: - //singleton - static CPixelFormats& GetInstance(); - static void DestroyInstance(); - - const PixelFormatInfo* GetPixelFormatInfo(EPixelFormat format); - - bool IsPixelFormatWithoutAlpha(EPixelFormat format); - bool IsPixelFormatUncompressed(EPixelFormat format); - - //functions seems only used for BC compressions. need re-evaluate later - bool IsFormatSingleChannel(EPixelFormat fmt); - bool IsFormatSigned(EPixelFormat fmt); - bool IsFormatFloatingPoint(EPixelFormat fmt, bool bFullPrecision); - - //find the pixel format for name used by Cry's RC.ini - //returns ePixelFormat_Unknown if the name was not found in registed format list - EPixelFormat FindPixelFormatByLegacyName(const char* name); - - //find pixel format by its name - EPixelFormat FindPixelFormatByName(const char* name); - - //returns maximum lod levels for image which has certain pixel format, width and height. - uint32 ComputeMaxMipCount(EPixelFormat format, uint32 imageWidth, uint32 imageHeight); - - //check if the input image size work with the pixel format. Some compression formats have requirements with the input image size. - bool IsImageSizeValid(EPixelFormat format, uint32 imageWidth, uint32 imageHeight, bool logWarning); - - //get suitable new size for an image with certain width, height and pixel format - void GetSuitableImageSize(EPixelFormat format, AZ::u32 imageWidth, AZ::u32 imageHeight, - AZ::u32& outWidth, AZ::u32& outHeight); - - //check if the image size of the specified pixel format need to be integer mutiple of block size - bool CanImageSizeIgnoreBlockSize(EPixelFormat format); - - //eavluate image data size. it doesn't include mips - uint32 EvaluateImageDataSize(EPixelFormat format, uint32 imageWidth, uint32 imageHeight); - - private: - CPixelFormats(); - void InitPixelFormats(); - void InitPixelFormat(EPixelFormat format, const PixelFormatInfo& formatInfo); - - private: - static CPixelFormats *s_instance; - - PixelFormatInfo m_pixelFormatInfo[ePixelFormat_Count]; - - //pixel format name to pixel format enum - AZStd::map m_pixelFormatNameMap; - - // some formats from cryEngine were removed. using this name-pixelFormat mapping to look for new format - AZStd::map m_removedLegacyFormats; - }; - - template - bool IsPowerOfTwo(TInteger x); - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp b/Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp deleted file mode 100644 index 61462475a7..0000000000 --- a/Gems/ImageProcessing/Code/Tests/AtlasBuilderTest.cpp +++ /dev/null @@ -1,186 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ -#include "ImageProcessing_precompiled.h" -#include "Source/AtlasBuilder/AtlasBuilderWorker.h" -#include "Source/ImageBuilderComponent.h" - -#include -#include - -#include -#include -#include -#include -#include - -#include - -using namespace TextureAtlasBuilder; -using namespace ImageProcessing; - -#if defined(AZ_PLATFORM_APPLE_OSX) -# define AZ_ROOT_TEST_FOLDER "./" -#else -# define AZ_ROOT_TEST_FOLDER "" -#endif - -namespace UnitTest -{ - class AtlasBuilderTest - : public ::testing::Test - , public AzToolsFramework::AssetSystemRequestBus::Handler - { - protected: - void SetUp() override - { - AZ::AllocatorInstance::Create(); - - m_app.reset(aznew AZ::ComponentApplication()); - AZ::ComponentApplication::Descriptor desc; - desc.m_useExistingAllocator = true; - m_app->Create(desc); - - BuilderSettingManager::CreateInstance(); - - m_context = AZStd::make_unique(); - BuilderPluginComponent::Reflect(m_context.get()); - - //load qt plugins for some image file formats support - int argc = 0; - char** argv = nullptr; - m_coreApplication.reset(new QCoreApplication(argc, argv)); - - m_engineRoot.reset(new AZStd::string(AZ::Test::GetEngineRootPath())); - - // Startup default local FileIO (hits OSAllocator) if not already setup. - if (AZ::IO::FileIOBase::GetInstance() == nullptr) - { - AZ::IO::FileIOBase::SetInstance(aznew AZ::IO::LocalFileIO()); - } - - AzToolsFramework::AssetSystemRequestBus::Handler::BusConnect(); - } - - void TearDown() override - { - AzToolsFramework::AssetSystemRequestBus::Handler::BusDisconnect(); - - delete AZ::IO::FileIOBase::GetInstance(); - AZ::IO::FileIOBase::SetInstance(nullptr); - - m_app->Destroy(); - m_app = nullptr; - - m_context.release(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - - m_engineRoot.reset(); - m_coreApplication.reset(); - - AZ::AllocatorInstance::Destroy(); - } - - AZStd::string GetFullPath(AZStd::string_view fileName) - { - const AZStd::string testsFolder = *m_engineRoot + "/Gems/ImageProcessing/Code/Tests/"; - return AZStd::string::format("%s%.*s", testsFolder.c_str(), aznumeric_cast(fileName.size()), fileName.data()); - } - - AZStd::unique_ptr m_context; - AZStd::unique_ptr m_app; - AZStd::unique_ptr m_coreApplication; // required by engine root and IsExtensionSupported - AZStd::unique_ptr m_engineRoot; - - public: - AssetBuilderSDK::ProcessJobRequest CreateTestJobRequest( - const AZStd::string& testFileName, - const AZStd::string& watchFolder, - const AZStd::string& tempDirPath, - [[maybe_unused]] bool critical, - QString platform, - AZ::s64 jobId = 0) - { - AZStd::string fullPath; - AzFramework::StringFunc::Path::Join( - watchFolder.c_str(), testFileName.c_str(), fullPath, true, true); - - bool valid = true; - AtlasBuilderInput testInput = AtlasBuilderInput::ReadFromFile(fullPath, watchFolder, valid); - - AssetBuilderSDK::ProcessJobRequest request; - request.m_sourceFile = testFileName; - request.m_fullPath = fullPath; - request.m_tempDirPath = tempDirPath; - request.m_jobId = jobId; - request.m_platformInfo.m_identifier = platform.toUtf8().constData(); - request.m_jobDescription = AtlasBuilderWorker::GetJobDescriptor(testFileName, testInput); - - return request; - } - - AZStd::string GetTestFolderPath() - { - return AZ_ROOT_TEST_FOLDER; - } - - ////////////////////////////////////////////////////////////////////////// - // AssetSystemRequestBus - bool GetAbsoluteAssetDatabaseLocation([[maybe_unused]] AZStd::string& result) override { return false; }; - const char* GetAbsoluteDevGameFolderPath() override { return ""; }; - const char* GetAbsoluteDevRootFolderPath() override { return ""; }; - bool GetRelativeProductPathFromFullSourceOrProductPath([[maybe_unused]] const AZStd::string& fullPath, [[maybe_unused]] AZStd::string& outputPath) override { return false; }; - bool GetFullSourcePathFromRelativeProductPath([[maybe_unused]] const AZStd::string& relPath, [[maybe_unused]] AZStd::string& fullPath) override { return false; }; - bool GetAssetInfoById([[maybe_unused]] const AZ::Data::AssetId& assetId, [[maybe_unused]] const AZ::Data::AssetType& assetType, [[maybe_unused]] const AZStd::string& platformName, [[maybe_unused]] AZ::Data::AssetInfo& assetInfo, [[maybe_unused]] AZStd::string& rootFilePath) override { return false; }; - bool GetSourceInfoBySourcePath(const char* sourcePath, AZ::Data::AssetInfo& assetInfo, AZStd::string& watchFolder) override - { - assetInfo.m_relativePath = sourcePath; - watchFolder = GetFullPath("TestAssets"); - return true; - }; - bool GetSourceInfoBySourceUUID([[maybe_unused]] const AZ::Uuid& sourceUuid, [[maybe_unused]] AZ::Data::AssetInfo& assetInfo, [[maybe_unused]] AZStd::string& watchFolder) override { return false; }; - bool GetScanFolders([[maybe_unused]] AZStd::vector& scanFolders) override { return false; }; - bool GetAssetSafeFolders([[maybe_unused]] AZStd::vector& assetSafeFolders) override { return false; }; - bool IsAssetPlatformEnabled([[maybe_unused]] const char* platform) override { return false; }; - int GetPendingAssetsForPlatform([[maybe_unused]] const char* platform) override { return -1; }; - bool GetAssetsProducedBySourceUUID([[maybe_unused]] const AZ::Uuid& sourceUuid, [[maybe_unused]] AZStd::vector& productsAssetInfo) override { return false; }; - }; - - TEST_F(AtlasBuilderTest, ProcessJob_ProcessValidTextureAtlas_OutputProductDependencies) - { - AZStd::string builderSetting(*m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(builderSetting, m_context.get()); - - // create the test job - AssetBuilderSDK::ProcessJobRequest request = CreateTestJobRequest( - "TextureAtlasTest.texatlas", GetFullPath("TestAssets"), GetTestFolderPath(), false, BuilderSettingManager::s_defaultPlatform.c_str(), 1); - - AssetBuilderSDK::ProcessJobResponse response; - - AtlasBuilderWorker testBuilder; - testBuilder.ProcessJob(request, response); - - ASSERT_EQ(response.m_resultCode, AssetBuilderSDK::ProcessJobResultCode::ProcessJobResult_Success); - - // texture atlas builder only has two output products - ASSERT_EQ(response.m_outputProducts.size(), 2); - - // textureatlasidx depends on dds its paired with, but not the other way around - AZ::Data::AssetId ddsProductAssetId(request.m_sourceFileUUID, response.m_outputProducts[static_cast(Product::DdsProduct)].m_productSubID); - AZStd::vector textureatlasidxProductDependencies = response.m_outputProducts[static_cast(Product::TexatlasidxProduct)].m_dependencies; - ASSERT_EQ(textureatlasidxProductDependencies.size(), 1); - ASSERT_EQ(textureatlasidxProductDependencies[0].m_dependencyId, ddsProductAssetId); - - AZStd::vector ddsProductDependencies = response.m_outputProducts[static_cast(Product::DdsProduct)].m_dependencies; - ASSERT_EQ(ddsProductDependencies.size(), 0); - } -} diff --git a/Gems/ImageProcessing/Code/Tests/ImageProcessing_Test.cpp b/Gems/ImageProcessing/Code/Tests/ImageProcessing_Test.cpp deleted file mode 100644 index 78094bf90f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/ImageProcessing_Test.cpp +++ /dev/null @@ -1,1544 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#include - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include - -#include -#include - -//Enable generate image files for result of some tests. -//This is slow and only useful for debugging. This should be disabled for unit test -//#define DEBUG_OUTPUT_IMAGES - -//There are some test functions in this test which are DISABLED. They were mainly for programming tests. -//It's only recommended to enable them for programming test purpose. - -#include -#include -#include "../Source/ImageBuilderComponent.h" - -using namespace ImageProcessing; - -namespace UnitTest -{ - -class ImageProcessingTest - : public ScopedAllocatorSetupFixture - // Only used to provide the serialize context - , public AZ::ComponentApplicationBus::Handler -{ -protected: - AZStd::unique_ptr m_coreApplication; // required by engine root and IsExtensionSupported - AZStd::unique_ptr m_context; - AZStd::string m_engineRoot; - - void SetUp() override - { - BuilderSettingManager::CreateInstance(); - - //prepare reflection - m_context = AZStd::make_unique(); - BuilderPluginComponent::Reflect(m_context.get()); - AZ::DataPatch::Reflect(m_context.get()); - - // Startup default local FileIO (hits OSAllocator) if not already setup. - if (AZ::IO::FileIOBase::GetInstance() == nullptr) - { - AZ::IO::FileIOBase::SetInstance(aznew AZ::IO::LocalFileIO()); - } - - // Adding this handler to allow utility functions access the serialize context - AZ::ComponentApplicationBus::Handler::BusConnect(); - AZ::Interface::Register(this); - - //load qt plugins for some image file formats support - int argc = 0; - char** argv = nullptr; - m_coreApplication.reset(new QCoreApplication(argc, argv)); - m_engineRoot = AZ::Test::GetEngineRootPath(); - - InitialImageFilenames(); - - ImageProcessingEditor::EditorHelper::InitPixelFormatString(); - } - - - void TearDown() override - { - delete AZ::IO::FileIOBase::GetInstance(); - AZ::IO::FileIOBase::SetInstance(nullptr); - - m_context.reset(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - - AZ::Interface::Unregister(this); - AZ::ComponentApplicationBus::Handler::BusDisconnect(); - - m_coreApplication.reset(); - } - - // ComponentApplicationMessages overrides... - AZ::ComponentApplication* GetApplication() override { return nullptr; } - void RegisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } - void UnregisterComponentDescriptor(const AZ::ComponentDescriptor*) override { } - void RegisterEntityAddedEventHandler(AZ::EntityAddedEvent::Handler&) override { } - void RegisterEntityRemovedEventHandler(AZ::EntityRemovedEvent::Handler&) override { } - void RegisterEntityActivatedEventHandler(EntityActivatedEvent::Handler&) override { } - void RegisterEntityDeactivatedEventHandler(EntityDeactivatedEvent::Handler&) override { } - void SignalEntityActivated(AZ::Entity* entity) override { } - void SignalEntityDeactivated(AZ::Entity* entity) override { } - bool AddEntity(AZ::Entity*) override { return false; } - bool RemoveEntity(AZ::Entity*) override { return false; } - bool DeleteEntity(const AZ::EntityId&) override { return false; } - AZ::Entity* FindEntity(const AZ::EntityId&) override { return nullptr; } - AZ::BehaviorContext* GetBehaviorContext() override { return nullptr; } - AZ::JsonRegistrationContext* GetJsonRegistrationContext() override { return nullptr; } - const char* GetAppRoot() const override { return nullptr; } - const char* GetEngineRoot() const override { return nullptr; } - const char* GetExecutableFolder() const override { return nullptr; } - AZ::Debug::DrillerManager* GetDrillerManager() override { return nullptr; } - void EnumerateEntities(const EntityCallback& /*callback*/) override {} - void QueryApplicationType(AZ::ApplicationTypeQuery& /*appType*/) const override {} - // The only one function we need to implement. - AZ::SerializeContext* GetSerializeContext() override - { - return m_context.get(); - } - - //enum names for Images with specific identification - enum ImageFeature - { - Image_20X16_RGBA8_Png = 0, - Image_32X32_16bit_F_Tif, - Image_32X32_32bit_F_Tif, - Image_200X200_RGB8_Jpg, - Image_512X288_RGB8_Tga, - Image_1024X1024_RGB8_Tif, - Image_UpperCase_Tga, - Image_512x512_Normal_Tga, - Image_128x128_Transparent_Tga, - Image_237x177_RGB_Jpg, - Image_GreyScale_Png, - Image_BlackWhite_Png, - Image_TerrainHeightmap_Bt - }; - - //image file names for testing - AZStd::map m_imagFileNameMap; - - //intialial image file names for testing - void InitialImageFilenames() - { - const AZStd::string fileFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/"; - - m_imagFileNameMap[Image_20X16_RGBA8_Png] = fileFolder + AZStd::string("20x16_32bit.png"); - m_imagFileNameMap[Image_32X32_16bit_F_Tif] = fileFolder + AZStd::string("32x32_16bit_f.tif"); - m_imagFileNameMap[Image_32X32_32bit_F_Tif] = fileFolder + AZStd::string("32x32_32bit_f.tif"); - m_imagFileNameMap[Image_200X200_RGB8_Jpg] = fileFolder + AZStd::string("200x200_24bit.jpg"); - m_imagFileNameMap[Image_512X288_RGB8_Tga] = fileFolder + AZStd::string("512x288_24bit.tga"); - m_imagFileNameMap[Image_1024X1024_RGB8_Tif] = fileFolder + AZStd::string("1024x1024_24bit.tif"); - m_imagFileNameMap[Image_UpperCase_Tga] = fileFolder + AZStd::string("uppercase.TGA"); - m_imagFileNameMap[Image_512x512_Normal_Tga] = fileFolder + AZStd::string("512x512_RGB_N.tga"); - m_imagFileNameMap[Image_128x128_Transparent_Tga] = fileFolder + AZStd::string("128x128_RGBA8.tga"); - m_imagFileNameMap[Image_237x177_RGB_Jpg] = fileFolder + AZStd::string("237x177_RGB.jpg"); - m_imagFileNameMap[Image_GreyScale_Png] = fileFolder + AZStd::string("greyscale.png"); - m_imagFileNameMap[Image_BlackWhite_Png] = fileFolder + AZStd::string("BlackWhite.png"); - m_imagFileNameMap[Image_TerrainHeightmap_Bt] = fileFolder + AZStd::string("TerrainHeightmap.bt"); - } - -public: - //helper function to save an image object to a file through QtImage - static void SaveImageToFile(const IImageObjectPtr imageObject, const AZStd::string imageName, AZ::u32 maxMipCnt = 100) - { -#ifndef DEBUG_OUTPUT_IMAGES - return; -#endif - if (imageObject == nullptr) - { - return; - } - - //create the directory if it's not exist - const AZStd::string outputDir = AZ::Test::GetEngineRootPath() + "/Gems/ImageProcessing/Code/Tests/TestAssets/Output/"; - QDir dir(outputDir.c_str()); - if (!dir.exists()) - { - dir.mkpath("."); - } - - //save origin file pixel format so we could use it to generate name later - EPixelFormat originPixelFormat = imageObject->GetPixelFormat(); - - //convert to RGBA8 before can be exported. - ImageToProcess imageToProcess(imageObject); - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - - IImageObjectPtr finalImage = imageToProcess.Get(); - - //for each mipmap - for (uint32 mip = 0; mip < finalImage->GetMipCount() && mip < maxMipCnt; mip++) - { - uint8* imageBuf; - uint32 pitch; - finalImage->GetImagePointer(mip, imageBuf, pitch); - uint32 width = finalImage->GetWidth(mip); - uint32 height = finalImage->GetHeight(mip); - - //generate file name - char filePath[2048]; - azsprintf(filePath, "%s%s_%s_mip%d_%dx%d.png", outputDir.c_str(), imageName.c_str() - , CPixelFormats::GetInstance().GetPixelFormatInfo(originPixelFormat)->szName - , mip, width, height); - - QImage qimage(imageBuf, width, height, pitch, QImage::Format_RGBA8888); - qimage.save(filePath); - } - } - - static bool GetComparisonResult(IImageObjectPtr image1, IImageObjectPtr image2, QString& output) - { - bool isImageLoaded = true; - bool isDifferent = false; - - if (image1 == nullptr) - { - isImageLoaded = false; - output += ",Image 1 does not exist. "; - } - - if (image2 == nullptr) - { - isImageLoaded = false; - output += ",Image 2 does not exist. "; - } - - if (!isImageLoaded) - { - return (!image1 && !image2) ? false: true; - } - - // Mip - int mip1 = image1->GetMipCount(); - int mip2 = image2->GetMipCount(); - int mipDiff = abs(mip1 - mip2); - - isDifferent |= mipDiff != 0; - - // Format - EPixelFormat format1 = image1->GetPixelFormat(); - EPixelFormat format2 = image2->GetPixelFormat(); - - isDifferent |= (format1 != format2); - - // Flag - AZ::u32 flag1 = image1->GetImageFlags(); - AZ::u32 flag2 = image2->GetImageFlags(); - - isDifferent |= (flag1 != flag2); - - // Size - int memSize1 = image1->GetTextureMemory(); - int memSize2 = image2->GetTextureMemory(); - int memDiff = abs(memSize1 - memSize2); - - isDifferent |= memDiff != 0; - - // Error - float error = GetErrorBetweenImages(image1, image2); - - static float EPSILON = 0.000001f; - isDifferent |= abs(error) >= EPSILON; - - output += QString(",%1/%2,%3,%4/%5,%6/%7,").arg(QString::number(mip1,'f',1), QString::number(mip2,'f',1), QString::number(mipDiff), - QString(ImageProcessingEditor::EditorHelper::s_PixelFormatString[format1]), - QString(ImageProcessingEditor::EditorHelper::s_PixelFormatString[format2]), - QString::number(flag1, 16), QString::number(flag2, 16)); - - output += QString("%1/%2,%3,%4").arg(QString(ImageProcessingEditor::EditorHelper::GetFileSizeString(memSize1).c_str()), - QString(ImageProcessingEditor::EditorHelper::GetFileSizeString(memSize2).c_str()), - QString(ImageProcessingEditor::EditorHelper::GetFileSizeString(memDiff).c_str()), - QString::number(error, 'f', 8)); - - - return isDifferent; - } - - - static bool CompareDDSImage(const QString& imagePath1, const QString& imagePath2, QString& output) - { - IImageObjectPtr image1, alphaImage1, image2, alphaImage2; - - - image1 = IImageObjectPtr(LoadImageFromDdsFile(imagePath1.toUtf8().constData())); - if (image1 && image1->HasImageFlags(EIF_AttachedAlpha)) - { - if (image1->HasImageFlags(EIF_Splitted)) - { - alphaImage1 = IImageObjectPtr(LoadImageFromDdsFile(QString(imagePath1 + ".a").toUtf8().constData())); - } - else - { - alphaImage1 = IImageObjectPtr(LoadAttachedImageFromDdsFile(imagePath1.toUtf8().constData(), image1)); - } - } - - image2 = IImageObjectPtr(LoadImageFromDdsFile(imagePath2.toUtf8().constData())); - if (image2 && image2->HasImageFlags(EIF_AttachedAlpha)) - { - if (image2->HasImageFlags(EIF_Splitted)) - { - alphaImage2 = IImageObjectPtr(LoadImageFromDdsFile(QString(imagePath2 + ".a").toUtf8().constData())); - } - else - { - alphaImage2 = IImageObjectPtr(LoadAttachedImageFromDdsFile(imagePath2.toUtf8().constData(), image2)); - } - } - - if (!image1 && !image2) - { - output += "Cannot load both image file! "; - return false; - } - bool isDifferent = false; - - isDifferent = GetComparisonResult(image1, image2, output); - - - QFileInfo fi(imagePath1); - AZStd::string imageName = fi.baseName().toUtf8().constData(); - SaveImageToFile(image1, imageName + "_new"); - SaveImageToFile(image2, imageName + "_old"); - - if (alphaImage1 || alphaImage2) - { - isDifferent |= GetComparisonResult(alphaImage1, alphaImage2, output); - } - - return isDifferent; - } -}; - -// test CPixelFormats related functions -TEST_F(ImageProcessingTest, TestPixelFormats) -{ - CPixelFormats& pixelFormats = CPixelFormats::GetInstance(); - - //verify names which was used for legacy rc.ini - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC7t") == ePixelFormat_BC7t); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("ETC2A") == ePixelFormat_ETC2a); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("PVRTC4") == ePixelFormat_PVRTC4); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC1") == ePixelFormat_BC1); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("ETC2") == ePixelFormat_ETC2); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC1a") == ePixelFormat_BC1a); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC3") == ePixelFormat_BC3); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC7") == ePixelFormat_BC7); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC5s") == ePixelFormat_BC5s); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("EAC_RG11") == ePixelFormat_EAC_RG11); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC4") == ePixelFormat_BC4); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("EAC_R11") == ePixelFormat_EAC_R11); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("A8R8G8B8") == ePixelFormat_R8G8B8A8); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("BC6UH") == ePixelFormat_BC6UH); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("R9G9B9E5") == ePixelFormat_R9G9B9E5); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("X8R8G8B8") == ePixelFormat_R8G8B8X8); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("A16B16G16R16F") == ePixelFormat_R16G16B16A16F); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("G8R8") == ePixelFormat_R8G8); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("G16R16") == ePixelFormat_R16G16); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("G16R16F") == ePixelFormat_R16G16F); - - //some legacy format need to be mapping to new format. - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("DXT1") == ePixelFormat_BC1); - ASSERT_TRUE(pixelFormats.FindPixelFormatByLegacyName("DXT5") == ePixelFormat_BC3); - - //calculate mipmap count. no cubemap support at this moment - - //for all the non-compressed textures, if there minimum required texture size is 1x1 - for (uint32 i = 0; i < ePixelFormat_Count; i++) - { - EPixelFormat pixelFormat = (EPixelFormat)i; - if (pixelFormats.IsPixelFormatUncompressed(pixelFormat)) - { - //square, power of 2 sizes for uncompressed format which minimum required size is 1x1 - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 128) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 64, 64) == 7); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 4, 4) == 3); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 2, 2) == 2); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 1, 1) == 1); - - //non-square, power of 2 sizes for uncompressed format which minimum required size is 1x1 - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 64) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 32) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 32, 2) == 6); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 2, 1) == 2); - - //Non power of 2 sizes for uncompressed format which minimum required size is 1x1 - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 64) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 128, 32) == 8); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 32, 2) == 6); - ASSERT_TRUE(pixelFormats.ComputeMaxMipCount(pixelFormat, 2, 1) == 2); - } - } - - //check function IsImageSizeValid && EvaluateImageDataSize function - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 2, 1, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 4, 4, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 16, 32, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 34, 34, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_PVRTC4, 256, 256, false) == true); - - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 2, 1, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 16, 32, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 34, 34, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_BC1, 256, 256, false) == true); - - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 2, 1, false) == false); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 16, 32, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 34, 34, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_ASTC_4x4, 256, 256, false) == true); - - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 2, 1, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 16, 16, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 16, 32, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 34, 34, false) == true); - ASSERT_TRUE(pixelFormats.IsImageSizeValid(ePixelFormat_A8, 256, 256, false) == true); -} - -// test image file loading -TEST_F(ImageProcessingTest, TestImageLoaders) -{ - //file extention support for different loader - ASSERT_TRUE(IsExtensionSupported("jpg") == true); - ASSERT_TRUE(IsExtensionSupported("JPG") == true); - ASSERT_TRUE(IsExtensionSupported(".JPG") == false); - ASSERT_TRUE(IsExtensionSupported("tga") == true); - ASSERT_TRUE(IsExtensionSupported("TGA") == true); - ASSERT_TRUE(IsExtensionSupported("tif") == true); - ASSERT_TRUE(IsExtensionSupported("tiff") == true); - ASSERT_TRUE(IsExtensionSupported("bt") == true); - - IImageObjectPtr img; - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_1024X1024_RGB8_Tif])); - - ASSERT_TRUE(img != nullptr); - ASSERT_TRUE(img->GetWidth(0) == 1024); - ASSERT_TRUE(img->GetHeight(0) == 1024); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8X8); - - //load png - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_20X16_RGBA8_Png])); - ASSERT_TRUE(img != nullptr); - ASSERT_TRUE(img->GetWidth(0) == 20); - ASSERT_TRUE(img->GetHeight(0) == 16); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //load jpg - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_200X200_RGB8_Jpg])); - ASSERT_TRUE(img->GetWidth(0) == 200); - ASSERT_TRUE(img->GetHeight(0) == 200); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //tga - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_512X288_RGB8_Tga])); - ASSERT_TRUE(img->GetWidth(0) == 512); - ASSERT_TRUE(img->GetHeight(0) == 288); - ASSERT_TRUE(img->GetMipCount() == 1); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //image with upper case extension - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_UpperCase_Tga])); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - //16bits float tif - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_32X32_16bit_F_Tif])); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R16G16B16A16F); - - //32bits float tif - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_32X32_32bit_F_Tif])); - ASSERT_TRUE(img->GetPixelFormat() == ePixelFormat_R32G32B32A32F); - - //BT - img = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[Image_TerrainHeightmap_Bt])); - ASSERT_TRUE(img != nullptr); - EXPECT_EQ(img->GetWidth(0), 128); - EXPECT_EQ(img->GetHeight(0), 128); - EXPECT_EQ(img->GetMipCount(), 1); - EXPECT_EQ(img->GetPixelFormat(), ePixelFormat_R32F); -} - -TEST_F(ImageProcessingTest, PresetSettingCopyAssignmentOperatorOverload_WithDynamicallyAllocatedSettings_ReturnsTwoSeparateAllocations) -{ - PresetSettings presetSetting; - presetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - presetSetting.m_cubemapSetting = AZStd::unique_ptr(new CubemapSettings()); - - // Explicit invoke assignment operator by splitting the operation into two lines. - PresetSettings otherPresetSetting; - otherPresetSetting = presetSetting; - - EXPECT_NE(otherPresetSetting.m_cubemapSetting, presetSetting.m_cubemapSetting); - EXPECT_NE(otherPresetSetting.m_mipmapSetting, presetSetting.m_mipmapSetting); -} - -TEST_F(ImageProcessingTest, PresetSettingCopyConstructor_WithDynamicallyAllocatedSettings_ReturnsTwoSeparateAllocations) -{ - PresetSettings presetSetting; - presetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - presetSetting.m_cubemapSetting = AZStd::unique_ptr(new CubemapSettings()); - - PresetSettings otherPresetSetting(presetSetting); - - EXPECT_NE(otherPresetSetting.m_cubemapSetting, presetSetting.m_cubemapSetting); - EXPECT_NE(otherPresetSetting.m_mipmapSetting, presetSetting.m_mipmapSetting); -} - -TEST_F(ImageProcessingTest, PresetSettingEqualityOperatorOverload_WithIdenticalSettings_ReturnsEquivalent) -{ - PresetSettings presetSetting; - PresetSettings otherPresetSetting(presetSetting); - - EXPECT_TRUE(otherPresetSetting == presetSetting); -} - -TEST_F(ImageProcessingTest, PresetSettingEqualityOperatorOverload_WithDifferingDynamicallyAllocatedSettings_ReturnsUnequivalent) -{ - PresetSettings presetSetting; - presetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - presetSetting.m_mipmapSetting->m_type = MipGenType::gaussian; - - PresetSettings otherPresetSetting(presetSetting); - otherPresetSetting.m_mipmapSetting = AZStd::unique_ptr(new MipmapSettings()); - otherPresetSetting.m_mipmapSetting->m_type = MipGenType::blackmanHarris; - - EXPECT_FALSE(otherPresetSetting == presetSetting); - -} - -//this test is to test image data won't be lost between uncompressed formats (for low to high precision or same precision) -TEST_F(ImageProcessingTest, TestConvertFormatUncompressed) -{ - //source image - IImageObjectPtr srcImage(LoadImageFromFile(m_imagFileNameMap[Image_200X200_RGB8_Jpg])); - ImageToProcess imageToProcess(srcImage); - - //image pointers to hold precessed images for comparison - IImageObjectPtr dstImage1, dstImage2, dstImage3, dstImage4, dstImage5; - - //compare four channels pixel formats - //we will convert to target format then convert back to RGBX8 so they can compare to easy other - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16B16A16); - ASSERT_FALSE(srcImage->CompareImage(imageToProcess.Get())); //this is different than source image - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage2 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16B16A16F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage3 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R32G32B32A32F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8A8); - dstImage4 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage3->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage4->CompareImage(dstImage1)); - - // three channels formats - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R9G9B9E5); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage2 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - - //convert image to all one channel formats then convert them back to RGBX8 for comparison - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage2 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage3 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R32F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage4 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage3->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage4->CompareImage(dstImage1)); - - //convert image to all two channels formats then convert them back to RGBX8 for comparison - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage1 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage2 = imageToProcess.Get(); - - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R16G16F); - imageToProcess.ConvertFormatUncompressed(ePixelFormat_R8G8B8X8); - dstImage3 = imageToProcess.Get(); - - ASSERT_TRUE(dstImage2->CompareImage(dstImage1)); - ASSERT_TRUE(dstImage3->CompareImage(dstImage1)); -} - -TEST_F(ImageProcessingTest, DISABLED_TestConvertPVRTC) -{ - //load builder presets - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - AZStd::vector outPaths; - AZStd::string inputFile = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif"; - const AZStd::string outputFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/temp/"; - ImageConvertProcess* process = CreateImageConvertProcess(inputFile, outputFolder, "ios", m_context.get()); - if (process != nullptr) - { - //the process can be stopped if the job is cancelled or the worker is shutting down - int step = 0; - while (!process->IsFinished()) - { - process->UpdateProcess(); - step++; - } - - //get process result - ASSERT_TRUE(process->IsSucceed()); - - SaveImageToFile(process->GetOutputImage(), "rgb", 10); - SaveImageToFile(process->GetOutputAlphaImage(), "alpha", 10); - - process->GetAppendOutputFilePaths(outPaths); - delete process; - } - - //ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, "ios", m_context.get())); - -} - -TEST_F(ImageProcessingTest, DISABLED_TestConvertFormat) -{ - EPixelFormat pixelFormat; - IImageObjectPtr srcImage; - - //images to be tested - static const int imageCount = 5; - ImageFeature images[imageCount] = { - Image_20X16_RGBA8_Png, - Image_32X32_16bit_F_Tif, - Image_32X32_32bit_F_Tif , - Image_512x512_Normal_Tga , - Image_128x128_Transparent_Tga }; - - for (int imageIdx = 0; imageIdx < imageCount; imageIdx++) - { - //get image's name and it will be used for output file name - QFileInfo fi(m_imagFileNameMap[images[imageIdx]].c_str()); - AZStd::string imageName = fi.baseName().toUtf8().constData(); - - srcImage = IImageObjectPtr(LoadImageFromFile(m_imagFileNameMap[images[imageIdx]])); - ImageToProcess imageToProcess(srcImage); - - //test ConvertFormat functions againest all the pixel formats - for (pixelFormat = ePixelFormat_R8G8B8A8; pixelFormat < ePixelFormat_Unknown;) - { - imageToProcess.Set(srcImage); - imageToProcess.ConvertFormat(pixelFormat); - - ASSERT_TRUE(imageToProcess.Get()); - - //if the format is compressed and there is no compressor for it, it won't be converted to the expected format - if (ICompressor::FindCompressor(pixelFormat, true) == nullptr - && !CPixelFormats::GetInstance().IsPixelFormatUncompressed(pixelFormat)) - { - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() != pixelFormat); - } - else - { - //validate the size and it may not working for some uncompressed format - if (!CPixelFormats::GetInstance().IsImageSizeValid( - pixelFormat, srcImage->GetWidth(0), srcImage->GetHeight(0), false)) - { - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() != pixelFormat); - } - else - { - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() == pixelFormat); - - //save the image to a file so we can check the visual result - SaveImageToFile(imageToProcess.Get(), imageName, 1); - - //convert back to an uncompressed format and expect it will be successful - imageToProcess.ConvertFormat(ePixelFormat_R8G8B8A8); - ASSERT_TRUE(imageToProcess.Get()->GetPixelFormat() == ePixelFormat_R8G8B8A8); - - } - } - - //next pixel format - pixelFormat = EPixelFormat(pixelFormat + 1); - } - } -} - -TEST_F(ImageProcessingTest, DISABLED_TestImageFilter) -{ - AZStd::string testImageFile = m_imagFileNameMap[Image_1024X1024_RGB8_Tif]; - IImageObjectPtr srcImage, dstImage; - - QFileInfo fi(testImageFile.c_str()); - AZStd::string imageName = fi.baseName().toUtf8().constData(); - - //load src image and convert it to RGBA32F - srcImage = IImageObjectPtr(LoadImageFromFile(testImageFile)); - ImageToProcess imageToProcess(srcImage); - imageToProcess.ConvertFormat(ePixelFormat_R32G32B32A32F); - srcImage = imageToProcess.Get(); - - //create dst image with same size and mipmaps - dstImage = IImageObjectPtr( - IImageObject::CreateImage(srcImage->GetWidth(0), srcImage->GetHeight(0), 3, - ePixelFormat_R32G32B32A32F)); - - //for each filters - const std::array, 7> allFilters = - { - { - {MipGenType::point, "point"}, - {MipGenType::box, "box" }, - { MipGenType::triangle, "triangle" }, - { MipGenType::quadratic, "Quadratic" }, - { MipGenType::blackmanHarris, "blackmanHarris" }, - { MipGenType::kaiserSinc, "kaiserSinc" } - } - }; - - for (std::pair filter : allFilters) - { - for (uint mip = 0; mip < dstImage->GetMipCount(); mip++) - { - FilterImage(filter.first, MipGenEvalType::sum, - 0, 0, imageToProcess.Get(), 0, dstImage, mip, nullptr, nullptr); - } - SaveImageToFile(dstImage, imageName + "_" + filter.second); - } -} - -TEST_F(ImageProcessingTest, TestColorSpaceConversion) -{ - IImageObjectPtr srcImage(LoadImageFromFile(m_imagFileNameMap[Image_GreyScale_Png])); - - ImageToProcess imageToProcess(srcImage); - imageToProcess.GammaToLinearRGBA32F(true); - SaveImageToFile(imageToProcess.Get(), "GammaTolinear_DeGamma", 1); - imageToProcess.LinearToGamma(); - SaveImageToFile(imageToProcess.Get(), "LinearToGamma_DeGamma", 1); -} - -//This function can be used to modify some value in the builder setting and keep all presets uuid then save back to setting file -//It will only change the file if the file was checked out -TEST_F(ImageProcessingTest, DISABLED_ModifyBuilderSetting) -{ - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - QFileInfo fileInfo(buiderSetting.c_str()); - if (fileInfo.isWritable()) - { - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - BuilderSettingManager::Instance()->WriteBuilderSettings(buiderSetting, m_context.get()); - } -} - -TEST_F(ImageProcessingTest, VerifyRestrictedPlatform) -{ - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - PlatformNameList platforms = BuilderSettingManager::Instance()->GetPlatformList(); - -#ifndef AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS - ASSERT_TRUE(platforms.size() == 4); -#endif //AZ_TOOLS_EXPAND_FOR_RESTRICTED_PLATFORMS -} - -TEST_F(ImageProcessingTest, DISABLED_TestCubemap) -{ - //load builder presets - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - const AZStd::string outputFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/temp/"; - AZStd::string inputFile; - AZStd::vector outPaths; - - inputFile = m_engineRoot + "/Assets/Engine/EngineAssets/Shading/defaultProbe_cm.tif"; - - IImageObjectPtr srcImage(LoadImageFromFile(inputFile)); - ImageToProcess imageToProcess(srcImage); - imageToProcess.ConvertCubemapLayout(CubemapLayoutVertical); - SaveImageToFile(imageToProcess.Get(), "Vertical", 100); - imageToProcess.ConvertCubemapLayout(CubemapLayoutHorizontalCross); - SaveImageToFile(imageToProcess.Get(), "HorizontalCross", 100); - imageToProcess.ConvertCubemapLayout(CubemapLayoutVerticalCross); - SaveImageToFile(imageToProcess.Get(), "VerticalCross", 100); - imageToProcess.ConvertCubemapLayout(CubemapLayoutHorizontal); - SaveImageToFile(imageToProcess.Get(), "VerticalHorizontal", 100); - - ImageConvertProcess* process = CreateImageConvertProcess(inputFile, outputFolder, "pc"); - - if (process != nullptr) - { - int step = 0; - while (!process->IsFinished()) - { - process->UpdateProcess(); - step++; - char name[100]; - azsprintf(name, "cubemap_%d", step); - //SaveImageToFile(process->GetOutputImage(), name, 1); - } - - //get process result - ASSERT_TRUE(process->IsSucceed()); - - SaveImageToFile(process->GetOutputImage(), "cubemap", 100); - SaveImageToFile(process->GetOutputDiffCubemap(), "diffCubemap", 100); - SaveImageToFile(process->GetOutputAlphaImage(), "alpha", 1); - process->GetAppendOutputFilePaths(outPaths); - - delete process; - } -} - -//test image conversion for builder -TEST_F(ImageProcessingTest, DISABLED_TestBuilderImageConvertor) -{ - AZStd::string oldCacheFolder = "E:/Javelin_old_tex_cache/textures"; - AZStd::string srcFolder = "E:/Javelin_NWLYDev/dev/Assets/Textures"; - - //load builder presets - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - const AZStd::string outputFolder = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/temp/"; - AZStd::string inputFile; - AZStd::vector outPaths; - - inputFile = srcFolder + "/terrain/cry/detail/grass_with_stones_displ.tif"; - inputFile = m_imagFileNameMap[Image_128x128_Transparent_Tga]; - AZStd::string oldFile = oldCacheFolder + "/terrain/cry/detail/grass_with_stones_displ.dds"; - ImageConvertProcess* process = CreateImageConvertProcess(inputFile, outputFolder, "pc", m_context.get()); - - if (process != nullptr) - { - //the process can be stopped if the job is cancelled or the worker is shutting down - int step = 0; - while (!process->IsFinished() ) - { - process->UpdateProcess(); - step++; - } - - //get process result - ASSERT_TRUE(process->IsSucceed()); - - SaveImageToFile(process->GetOutputImage(), "rgb", 10); - SaveImageToFile(process->GetOutputAlphaImage(), "alpha", 10); - - process->GetAppendOutputFilePaths(outPaths); - - QString output; - //CompareDDSImage(outPaths[0].c_str(), oldFile.c_str(), output); - delete process; - } - - - -/* //test cases for different presets - //ddna - inputFile = "../AutomatedTesting/Objects/ParticleAssets/ShowRoom/showroom_pipe_blue_001_m_ddna.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //cubemap - inputFile = "../AutomatedTesting/Levels/Samples/Camera_Sample/Cubemaps/noon_cm.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //albedo - inputFile = "../AutomatedTesting/Objects/ParticleAssets/ShowRoom/showroom_steel_brushed_001_diff.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - inputFile = "../AutomatedTesting/materials/pbs_reference/light_leather_diff.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - inputFile = "../Gems/PBSreferenceMaterials/Assets/materials/pbs_reference/brushed_steel.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //ui ReferenceImage auto preset - inputFile = "../Bems/UiBasics/Assets/UI/Textures/Prefab/textinput_normal.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //albedo with generic alpha auto preset - inputFile = "../AutomatedTesting/textures/GettingStartedTextures/LY_Logo_Beaver.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); - //color chart - inputFile = "../Gems/PBSreferenceMaterials/Assets/materials/pbs_reference/colorcharts/debug_contrast_low_cch.tif"; - ASSERT_TRUE(ConvertImageFile(inputFile, outputFolder, outPaths, m_context.get())); -*/ -} - - -//test image loading function for output dds files -TEST_F(ImageProcessingTest, DISABLED_TestLoadDdsImage) -{ - IImageObjectPtr originImage, alphaImage; - AZStd::string inputFolder = m_engineRoot + "/Cache/AutomatedTesting/pc/automatedtesting/engineassets/texturemsg/"; - AZStd::string inputFile; - - inputFile = "E:/Javelin_NWLYDev/dev/Cache/Assets/pc/assets/textures/blend_maps/moss/jav_moss_ddn.dds"; - - IImageObjectPtr newImage = IImageObjectPtr(LoadImageFromDdsFile(inputFile)); - if (newImage->HasImageFlags(EIF_AttachedAlpha)) - { - if (newImage->HasImageFlags(EIF_Splitted)) - { - alphaImage = IImageObjectPtr(LoadImageFromDdsFile(inputFile+".a")); - - } - else - { - alphaImage = IImageObjectPtr(LoadAttachedImageFromDdsFile(inputFile, newImage)); - } - } - - SaveImageToFile(newImage, "jav_moss_ddn", 10); -} - -TEST_F(ImageProcessingTest, DISABLED_CompareOutputImage) -{ - AZStd::string curretTextureFolder = m_engineRoot + "/TestAssets/TextureAssets/assets_new/textures"; - AZStd::string oldTextureFolder = m_engineRoot + "/TestAssets/TextureAssets/assets_old/textures"; - bool outputOnlyDifferent = false; - QDirIterator it(curretTextureFolder.c_str(), QStringList() << "*.dds", QDir::Files, QDirIterator::Subdirectories); - QFile f("../texture_comparison_output.csv"); - f.open(QIODevice::ReadWrite | QIODevice::Truncate); - // Write a header for csv file - f.write("Texture Name, Path, Mip new/old, MipDiff, Format new/old, Flag new/old, MemSize new/old, MemDiff, Error, AlphaMip new/old, AlphaMipDiff, AlphaFormat new/old, AlphaFlag new/old, AlphaMemSize new/old, AlphaMemDiff, AlphaError\r\n"); - int i = 0; - while (it.hasNext()) - { - i++; - it.next(); - - QString fileName = it.fileName(); - QString newFilePath = it.filePath(); - QString sharedPath = QString(newFilePath).remove(curretTextureFolder.c_str()); - QString oldFilePath = QString(oldTextureFolder.c_str()) + sharedPath; - QString output; - if (QFile::exists(oldFilePath)) - { - bool isDifferent = CompareDDSImage(newFilePath, oldFilePath, output); - if (outputOnlyDifferent && !isDifferent) - { - continue; - } - else - { - f.write(fileName.toUtf8().constData()); - f.write(","); - f.write(sharedPath.toUtf8().constData()); - f.write(output.toUtf8().constData()); - } - } - else - { - f.write(fileName.toUtf8().constData()); - f.write(","); - f.write(sharedPath.toUtf8().constData()); - output += ",No old file for comparison!"; - f.write(output.toUtf8().constData()); - } - f.write("\r\n"); - } - f.close(); -} - - -TEST_F(ImageProcessingTest, EditorTextureSettingTest) -{ - AZStd::string buiderSetting = m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - auto TestFunc = [](const AZStd::string& textureFilepath, bool isCubemap) { - - ImageProcessingEditor::EditorTextureSetting setting(textureFilepath); - const TextureSettings& textSettings = setting.m_settingsMap["pc"]; - auto& presetId = textSettings.m_preset; - const PresetSettings* preset = BuilderSettingManager::Instance()->GetPreset(presetId); - AZ::u32 arrayCount = 1; - AZ::u32 originalWidth = setting.m_img->GetWidth(0); - AZ::u32 originalHeight = setting.m_img->GetHeight(0); - - if (isCubemap) - { - ASSERT_TRUE(preset->m_cubemapSetting != nullptr); - CubemapLayout *srcCubemap = CubemapLayout::CreateCubemapLayout(setting.m_img); - ASSERT_TRUE(srcCubemap != nullptr); - - originalWidth = srcCubemap->GetFaceSize(); - originalHeight = srcCubemap->GetFaceSize(); - arrayCount = 6; - - delete srcCubemap; - } - - // Test GetFinalInfoForTextureOnPlatform function - { - for (AZ::u32 reduce = 0; reduce < 15; reduce++) - { - ImageProcessingEditor::ResolutionInfo info; - if (setting.GetFinalInfoForTextureOnPlatform("pc", reduce, info)) - { - ASSERT_TRUE(info.reduce <= reduce); - ASSERT_TRUE(info.arrayCount == arrayCount); - ASSERT_TRUE(info.width == AZStd::max(originalWidth >> info.reduce, 1)); - ASSERT_TRUE(info.height == AZStd::max(originalHeight >> info.reduce, 1)); - if (preset->m_maxTextureSize > 0) - { - ASSERT_TRUE(info.width <= preset->m_maxTextureSize); - ASSERT_TRUE(info.height <= preset->m_maxTextureSize); - } - if (preset->m_minTextureSize > 0) - { - ASSERT_TRUE(info.width >= preset->m_minTextureSize); - ASSERT_TRUE(info.height >= preset->m_minTextureSize); - } - } - } - } - - // Test GetResolutionInfo function - { - AZ::u32 minReduce, maxReduce; - auto resolutions = setting.GetResolutionInfo("pc", minReduce, maxReduce); - ASSERT_TRUE(resolutions.size() > 0); - ASSERT_TRUE(resolutions.size() == maxReduce - minReduce + 1); - for (auto& info : resolutions) - { - ASSERT_TRUE(info.reduce >= minReduce); - ASSERT_TRUE(info.reduce <= maxReduce); - ASSERT_TRUE(info.arrayCount == arrayCount); - ASSERT_TRUE(info.width == AZStd::max(originalWidth >> info.reduce, 1)); - ASSERT_TRUE(info.height == AZStd::max(originalHeight >> info.reduce, 1)); - ASSERT_TRUE(info.width >= 1); - ASSERT_TRUE(info.height >= 1); - } - } - - // Test GetResolutionInfo function - { - auto resolutions = setting.GetResolutionInfoForMipmap("pc"); - for (auto& info : resolutions) - { - ASSERT_TRUE(info.arrayCount == arrayCount); - ASSERT_TRUE(info.width == AZStd::max(originalWidth >> info.reduce, 1)); - ASSERT_TRUE(info.height == AZStd::max(originalHeight >> info.reduce, 1)); - ASSERT_TRUE(info.width >= 1); - ASSERT_TRUE(info.height >= 1); - } - setting.m_settingsMap["pc"].m_sizeReduceLevel += 1; - auto reducedResolutions = setting.GetResolutionInfoForMipmap("pc"); - ASSERT_TRUE(resolutions.size() >= reducedResolutions.size()); - } - }; - - // For cubemap texture - AZStd::string textureFilePath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif"; - TestFunc(textureFilePath, true); - - // For albedo texture - textureFilePath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif"; - TestFunc(textureFilePath, false); -} - -class ImageProcessingSerializationTest - : public ScopedAllocatorSetupFixture -{ -protected: - AZStd::unique_ptr m_context; - AZStd::string m_engineRoot; - - void SetUp() override - { - BuilderSettingManager::CreateInstance(); - - m_context = AZStd::make_unique(); - BuilderPluginComponent::Reflect(m_context.get()); - AZ::DataPatch::Reflect(m_context.get()); - - // Startup default local FileIO (hits OSAllocator) if not already setup. - if (AZ::IO::FileIOBase::GetInstance() == nullptr) - { - AZ::IO::FileIOBase::SetInstance(aznew AZ::IO::LocalFileIO()); - } - { - int argc = 0; - char** argv = nullptr; - QCoreApplication app(argc, argv); - m_engineRoot = AZ::Test::GetEngineRootPath(); - } - } - - void TearDown() override - { - delete AZ::IO::FileIOBase::GetInstance(); - AZ::IO::FileIOBase::SetInstance(nullptr); - - m_context.reset(); - BuilderSettingManager::DestroyInstance(); - CPixelFormats::DestroyInstance(); - } -}; - -TEST_F(ImageProcessingSerializationTest, DISABLED_LoadBuilderSettingsFromRC_SerializingLegacyDataIn_InvalidFiles) -{ - AZStd::string filepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/rc.ini_Missing"; - ASSERT_FALSE(BuilderSettingManager::Instance()->LoadBuilderSettingsFromRC(filepath).IsSuccess()); - - filepath = m_engineRoot + "/Code/Tools/RC/Config/rc/rc.ini"; - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettingsFromRC(filepath); - ASSERT_TRUE(outcome.IsSuccess()); - - AZ::IO::HandleType fileHandle = AZ::IO::InvalidHandle; - - // Load legacy texture settings from file that not exists - TextureSettings legacyTextureSetting; - AZStd::string notExistingFile = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/NotExistingFile"; - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile("", notExistingFile, legacyTextureSetting, m_context.get()); - EXPECT_FALSE(legacyLoadOutcome.IsSuccess()); - - // Load legacy texture settings from file whose format is wrong - - // Wrong override data - AZStd::string wrongFormatFile = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/invalid.exportsettings"; - AZStd::string wrongFormatContent = "/autooptimizefile=0 /preset=Diffuse_highQ /reduce=\"es3:0,randomdata,ios:3,osx_gl:0,pc:4\" /ser=0"; - if (AZ::IO::FileIOBase::GetInstance()->Open(wrongFormatFile.c_str(), AZ::IO::OpenMode::ModeWrite, fileHandle)) - { - AZ::IO::FileIOBase::GetInstance()->Write(fileHandle, wrongFormatContent.c_str(), wrongFormatContent.size()); - AZ::IO::FileIOBase::GetInstance()->Close(fileHandle); - } - else - { - EXPECT_TRUE(false); - } - legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile("", wrongFormatFile, legacyTextureSetting, m_context.get()); - EXPECT_FALSE(legacyLoadOutcome.IsSuccess()); - - // Wrong format data - wrongFormatContent = "//// ,&*&#$@#/preset=Diffuse_highQ / //reduce=0 /ser=0"; - if (AZ::IO::FileIOBase::GetInstance()->Open(wrongFormatFile.c_str(), AZ::IO::OpenMode::ModeWrite, fileHandle)) - { - AZ::IO::FileIOBase::GetInstance()->Write(fileHandle, wrongFormatContent.c_str(), wrongFormatContent.size()); - AZ::IO::FileIOBase::GetInstance()->Close(fileHandle); - } - legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile("", wrongFormatFile, legacyTextureSetting, m_context.get()); - EXPECT_FALSE(legacyLoadOutcome.IsSuccess()); - - AZ::IO::FileIOBase::GetInstance()->Remove(wrongFormatFile.c_str()); -} - - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingLegacyDataIn_EmbeddedSetting) -{ - AZStd::string buiderSetting(m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - // Load legacy texture settings - TextureSettings legacyTextureSetting; - AZStd::string textureFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif"; - AZStd::string textureSetting = LoadEmbeddedSettingFromFile(textureFilepath); - EXPECT_FALSE(textureSetting.empty()); - - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSetting(textureFilepath, textureSetting, legacyTextureSetting, m_context.get()); - // Ensure we loaded and parsed the texture settings correctly. - EXPECT_TRUE(legacyLoadOutcome.IsSuccess()); - EXPECT_EQ(legacyTextureSetting.m_preset, BuilderSettingManager::Instance()->GetPresetIdFromName("LensOptics")); -} - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingLegacyDataIn_CommonAndPlatformSpecificSettingsAreSerializedCorrectly) -{ - AZStd::string buiderSetting(m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - // Load legacy texture settings - TextureSettings legacyTextureSetting; - AZStd::string textureFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif"; - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile(textureFilepath, - textureFilepath + TextureSettings::legacyExtensionName, legacyTextureSetting, m_context.get()); - - // Ensure we loaded and parsed the texture settings correctly. - EXPECT_TRUE(legacyLoadOutcome.IsSuccess()); - EXPECT_EQ(legacyTextureSetting.m_mipGenType, MipGenType::kaiserSinc); - EXPECT_EQ(legacyTextureSetting.m_preset, BuilderSettingManager::Instance()->GetPresetIdFromName("Albedo")); - EXPECT_EQ(legacyTextureSetting.m_mipAlphaAdjust[0], 62); - EXPECT_EQ(legacyTextureSetting.m_suppressEngineReduce, false); - - // Ensure overrides are properly parsed as well. - { - TextureSettings iosTextureSettings; - auto iosOutcome = TextureSettings::GetPlatformSpecificTextureSetting("ios", legacyTextureSetting, iosTextureSettings, m_context.get()); - EXPECT_TRUE(iosOutcome.IsSuccess()); - EXPECT_EQ(iosTextureSettings.m_sizeReduceLevel, 3); - } -} - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingModernDataOutThenIn_PreSerializedAndPostSerializedDataIsEquivalent) -{ - AZStd::string buiderSetting(m_engineRoot + "/Gems/ImageProcessing/Code/Source/ImageBuilderDefaultPresets.settings"); - auto outcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buiderSetting, m_context.get()); - - // Load legacy texture settings - TextureSettings legacyTextureSetting; - AZStd::string textureFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif"; - auto legacyLoadOutcome = TextureSettings::LoadLegacyTextureSettingFromFile(textureFilepath, - textureFilepath+TextureSettings::legacyExtensionName, legacyTextureSetting, m_context.get()); - - // Let's make modifications to the loaded texture setting - // Modification1: Set reduce level for common settings. - // Modification2: Set reduce level for iOS-override settings. - legacyTextureSetting.m_sizeReduceLevel = 1337; - TextureSettings iosOverride = legacyTextureSetting; - iosOverride.m_sizeReduceLevel = 0xDAD; - legacyTextureSetting.ApplySettings(iosOverride, "ios", m_context.get()); - - // Write the modified texture settings to file, using AZ::Serialization. - AZStd::string modernMetafilePath = textureFilepath + TextureSettings::modernExtensionName; - auto writeOutcome = TextureSettings::WriteTextureSetting(modernMetafilePath, legacyTextureSetting, m_context.get()); - EXPECT_TRUE(writeOutcome.IsSuccess()); - - // Load the modified settings back to memory, using AZ::Serialization - TextureSettings modernTextureSetting; - auto modernLoadOutcome = TextureSettings::LoadTextureSetting(modernMetafilePath, modernTextureSetting, m_context.get()); - - // Ensure what we just serialized-in is identical to what we serialized-out. - // The comparison operator also compares overrides. - EXPECT_TRUE(modernLoadOutcome.IsSuccess()); - EXPECT_TRUE(modernTextureSetting.Equals(legacyTextureSetting, m_context.get())); - - // Remove the temp file that was written out. - AZ::IO::FileIOBase::GetInstance()->Remove(modernMetafilePath.c_str()); -} - -TEST_F(ImageProcessingSerializationTest, TextureSettingReflect_SerializingModernDataInAndOut_WritesAndParsesFileAccurately) -{ - AZStd::string filepath = "test.xml"; - - // Fill-in structure with test data - TextureSettings fakeTextureSettings; - fakeTextureSettings.m_preset = AZ::Uuid::CreateRandom(); - fakeTextureSettings.m_sizeReduceLevel = 0; - fakeTextureSettings.m_suppressEngineReduce = true; - fakeTextureSettings.m_enableMipmap = false; - fakeTextureSettings.m_maintainAlphaCoverage = true; - fakeTextureSettings.m_mipAlphaAdjust = { 0xDEAD, 0xBADBEEF, 0xBADC0DE, 0xFEEFEE, 0xBADF00D, 0xC0FFEE }; - fakeTextureSettings.m_mipGenEval = MipGenEvalType::max; - fakeTextureSettings.m_mipGenType = MipGenType::quadratic; - - // Write test data to file - auto writeOutcome = TextureSettings::WriteTextureSetting(filepath, fakeTextureSettings, m_context.get()); - EXPECT_TRUE(writeOutcome.IsSuccess()); - - // Parse test data to file - TextureSettings parsedFakeTextureSettings; - auto readOutcome = TextureSettings::LoadTextureSetting(filepath, parsedFakeTextureSettings, m_context.get()); - EXPECT_TRUE(readOutcome.IsSuccess()); - EXPECT_TRUE(parsedFakeTextureSettings.Equals(fakeTextureSettings, m_context.get())); - - // Delete temp data - AZ::IO::FileIOBase::GetInstance()->Remove(filepath.c_str()); -} - -TEST_F(ImageProcessingSerializationTest, DISABLED_BuilderSettingsReflect_SerializingDataInAndOut_WritesAndParsesFileAccurately) -{ - AZStd::string buildSettingsFilepath = m_engineRoot + "/Gems/ImageProcessing/Code/Tests/TestAssets/tempPresets.settings"; - AZStd::string rcFilePath = m_engineRoot + "/Code/Tools/RC/Config/rc/rc.ini"; - - auto loadOutcome = BuilderSettingManager::Instance()->LoadBuilderSettingsFromRC(rcFilePath); - ASSERT_TRUE(loadOutcome.IsSuccess()); - - //Save the preset loaded from rc.ini for later comparison - AZ::Uuid oldPresetSettingsUuid = BuilderSettingManager::Instance()->GetPresetIdFromName("NormalsFromDisplacement"); - const PresetSettings oldPresetSetting = *BuilderSettingManager::Instance()->GetPreset(oldPresetSettingsUuid, "pc"); - - //Save builder settings to new file format - auto writeOutcome = BuilderSettingManager::Instance()->WriteBuilderSettings(buildSettingsFilepath, m_context.get()); - ASSERT_TRUE(writeOutcome.IsSuccess()); - - //Re-load Builder Settings - auto reloadOutcome = BuilderSettingManager::Instance()->LoadBuilderSettings(buildSettingsFilepath, m_context.get()); - ASSERT_TRUE(reloadOutcome.IsSuccess()); - - //Find the same preset - AZ::Uuid newPresetSettingsUuid = BuilderSettingManager::Instance()->GetPresetIdFromName("NormalsFromDisplacement"); - const PresetSettings newPresetSetting = *BuilderSettingManager::Instance()->GetPreset(newPresetSettingsUuid, "pc"); - - // Delete temp data - AZ::IO::FileIOBase::GetInstance()->Remove(buildSettingsFilepath.c_str()); - - //make sure the preset loaded from RC.ini is same as the preset loaded from builder setting - ASSERT_EQ(oldPresetSetting, newPresetSetting); -} - -class ProductDependencyTest - : public AllocatorsTestFixture -{ -public: - void SetUp() override - { - AllocatorsTestFixture::SetUp(); - m_data = AZStd::make_unique(); - m_data->m_request.m_sourceFileUUID = AZ::Uuid::CreateRandom(); - m_data->m_rgbBaseFilePath = AZStd::string("Foo/test.dds"); - m_data->m_alphaBaseFilePath = AZStd::string("Foo/test.dds.a"); - m_data->m_diffBaseFilePath = "Foo/test_diff.dds"; - - for (int idx = 1; idx < NumOfMips; idx++) - { - m_data->m_rgbMipsFilePath.push_back(AZStd::string::format("Foo/test.dds.%d", idx)); - m_data->m_alphaMipsFilePath.push_back(AZStd::string::format("Foo/test.dds.%da", idx)); - } - } - - void TearDown() override - { - m_data.reset(); - AllocatorsTestFixture::TearDown(); - } - - - bool ValidateResult(const AZStd::vector& productFilePaths, const AZStd::unordered_map& productDependencyMap) - { - AZStd::vector jobProducts; - m_data->m_imageBuilderWorker.PopulateProducts(m_data->m_request, productFilePaths, jobProducts); - - EXPECT_EQ(productFilePaths.size(), jobProducts.size()); - - for (const AssetBuilderSDK::JobProduct& jobProduct : jobProducts) - { - auto found = productDependencyMap.find(jobProduct.m_productFileName); - if (found != productDependencyMap.end()) - { - EXPECT_EQ(jobProduct.m_dependencies.size(), found->second); - - if (jobProduct.m_dependencies.size() != found->second) - { - return false; - } - } - } - - return true; - } -protected: - - struct StaticData - { - AssetBuilderSDK::ProcessJobRequest m_request; - AZStd::string m_rgbBaseFilePath; - AZStd::vector m_rgbMipsFilePath; - AZStd::string m_alphaBaseFilePath; - AZStd::vector m_alphaMipsFilePath; - AZStd::string m_diffBaseFilePath; - ImageProcessing::ImageBuilderWorker m_imageBuilderWorker; - }; - - AZStd::unique_ptr m_data; - static const int NumOfMips = 5; -}; - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFile_Emit_None) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = 0; - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFileAndMips_Emit_All) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size(); - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFileAndBaseAlpha_Emit_ALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = 1; // one for the alphaBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBFile_Emit_ALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 1; // adding one for the alphaBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = m_data->m_alphaMipsFilePath.size(); - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependency_Rgb_Diff_EmitALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_diffBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 1; // adding one for the diffBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = 0; - productDependencyMap[m_data->m_diffBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependency_Diff_Alpha_EmitALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_diffBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = 0; - productDependencyMap[m_data->m_alphaBaseFilePath] = m_data->m_alphaMipsFilePath.size(); - productDependencyMap[m_data->m_diffBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 1; // adding one for the alphaBaseFile - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependency_Rgb_Diff_Alpha_EmitALL) -{ - AZStd::vector productFilePaths; - productFilePaths.push_back(m_data->m_rgbBaseFilePath); - productFilePaths.push_back(m_data->m_diffBaseFilePath); - productFilePaths.push_back(m_data->m_alphaBaseFilePath); - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - - AZStd::unordered_map productDependencyMap; - - productDependencyMap[m_data->m_rgbBaseFilePath] = m_data->m_rgbMipsFilePath.size() + 2; // adding one for the alphaBaseFile and one for diffBaseFile - productDependencyMap[m_data->m_alphaBaseFilePath] = m_data->m_alphaMipsFilePath.size(); - productDependencyMap[m_data->m_diffBaseFilePath] = 0; - EXPECT_TRUE(ValidateResult(productFilePaths, productDependencyMap)); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseRGBMissing_Error_OK) -{ - AZStd::vector productFilePaths; - productFilePaths.insert(productFilePaths.end(), m_data->m_rgbMipsFilePath.begin(), m_data->m_rgbMipsFilePath.end()); - AZStd::vector jobProducts; - AZ::Outcome result = m_data->m_imageBuilderWorker.PopulateProducts(m_data->m_request, productFilePaths, jobProducts); - - EXPECT_FALSE(result.IsSuccess()); -} - -TEST_F(ProductDependencyTest, ProductDependencyBaseAlphaMissing_Error_OK) -{ - AZStd::vector productFilePaths; - productFilePaths.insert(productFilePaths.end(), m_data->m_alphaMipsFilePath.begin(), m_data->m_alphaMipsFilePath.end()); - AZStd::vector jobProducts; - AZ::Outcome result = m_data->m_imageBuilderWorker.PopulateProducts(m_data->m_request, productFilePaths, jobProducts); - - EXPECT_FALSE(result.IsSuccess()); -} - -} - -AZ_UNIT_TEST_HOOK(DEFAULT_UNIT_TEST_ENV); diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif deleted file mode 100644 index 0a03a3f231..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:db3450a2e68b0ac5d88e82ed01c897ed4ea60a502bf1f44760c6f63ce4970816 -size 3157396 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif.exportsettings b/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif.exportsettings deleted file mode 100644 index 0417122033..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/1024x1024_24bit.tif.exportsettings +++ /dev/null @@ -1 +0,0 @@ -/autooptimizefile=0 /bumptype=none /M=62,18,32,83,50,50 /preset=Diffuse_highQ /mipgentype=kaiser /reduce="es3:0,ios:3,osx_gl:0,pc:4,provo:1" /ser=0 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/128x128_RGBA8.tga b/Gems/ImageProcessing/Code/Tests/TestAssets/128x128_RGBA8.tga deleted file mode 100644 index b94d39d838..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/128x128_RGBA8.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:116cd9a554235a0a2bf1b2ebbc7fdc38f50aafad7910cad01a7373bbfda3f562 -size 65580 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/200x200_24bit.jpg b/Gems/ImageProcessing/Code/Tests/TestAssets/200x200_24bit.jpg deleted file mode 100644 index d682456d63..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/200x200_24bit.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:588e3bca4304823fdf795fd96a640d3b1e31cc8e82dc1cb1835071aa96f2eb22 -size 34658 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/20x16_32bit.png b/Gems/ImageProcessing/Code/Tests/TestAssets/20x16_32bit.png deleted file mode 100644 index a7f48148f1..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/20x16_32bit.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bd5106eebb6cf264fdac5f3568977fc8f944df4a4d4de6b0e9f35b3a001a3001 -size 206 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/237x177_RGB.jpg b/Gems/ImageProcessing/Code/Tests/TestAssets/237x177_RGB.jpg deleted file mode 100644 index 637ce7a86a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/237x177_RGB.jpg +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:af31ad61e58d030ef5406685fbccf67f83054fd81cf840aa308e513940f68645 -size 22767 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_16bit_f.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_16bit_f.tif deleted file mode 100644 index cfe2389ab5..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_16bit_f.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dfa0e2bbe4691b2fc98e8456298fc05d771cf2b30c61bba992b340abd2bacd91 -size 23944 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_32bit_f.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_32bit_f.tif deleted file mode 100644 index 7fb71acf75..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/32x32_32bit_f.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fee58c41e2306ad03870b517963f353f9be30378fbbe61e596007f4c3ac4b2cd -size 30088 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/512x288_24bit.tga b/Gems/ImageProcessing/Code/Tests/TestAssets/512x288_24bit.tga deleted file mode 100644 index 7f2daece10..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/512x288_24bit.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f0098e9308e50755484b9bc7205422a54106c593d5d36073bbdbd822c9d459d -size 366890 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/512x512_RGB_N.tga b/Gems/ImageProcessing/Code/Tests/TestAssets/512x512_RGB_N.tga deleted file mode 100644 index d47f00912a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/512x512_RGB_N.tga +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:646a9a9035cc3f4dfd57babc0055710d2f5bb8aee0a792f2b65d69b4fd6a94b3 -size 786450 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/BlackWhite.png b/Gems/ImageProcessing/Code/Tests/TestAssets/BlackWhite.png deleted file mode 100644 index dfe856790a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/BlackWhite.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:969c6597a6346c5ff8ae24b4ae143bacbeed2944dd139ddef9b440483dbe4c02 -size 8866921 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif deleted file mode 100644 index 090991ec7a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/Lenstexture_dirtyglass.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:265ae231486dc6d5d61aa2416b0010ea743722f7238660faeed9edacd46e8a6b -size 6303186 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TerrainHeightmap.bt b/Gems/ImageProcessing/Code/Tests/TestAssets/TerrainHeightmap.bt deleted file mode 100644 index d79577ea18..0000000000 Binary files a/Gems/ImageProcessing/Code/Tests/TestAssets/TerrainHeightmap.bt and /dev/null differ diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest.texatlas b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest.texatlas deleted file mode 100644 index 5cd9287208..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest.texatlas +++ /dev/null @@ -1,50 +0,0 @@ -TextureAtlasTest/button.tif -TextureAtlasTest/buttonPressed.tif -TextureAtlasTest/buttonSlider.tif -TextureAtlasTest/checkbox_spritesheet.tif -TextureAtlasTest/checkered3.tif -TextureAtlasTest/Circle_Shadow.tif -TextureAtlasTest/CircleFrame.tif -TextureAtlasTest/CircleGradient.png -TextureAtlasTest/CircleMask.tif -TextureAtlasTest/empty_icon.tif -TextureAtlasTest/fixed_image.tif -TextureAtlasTest/flipbook_walking.tif -TextureAtlasTest/mask.tif -TextureAtlasTest/outline.tif -TextureAtlasTest/outlineRounded.tif -TextureAtlasTest/panelBkgd.tif -TextureAtlasTest/ParticleGlow.tif -TextureAtlasTest/pattern02.tif -TextureAtlasTest/pattern02_big.tif -TextureAtlasTest/pattern02vertical.tif -TextureAtlasTest/pattern02vertical_big.tif -TextureAtlasTest/pattern03.tif -TextureAtlasTest/pattern03_big.tif -TextureAtlasTest/scroll_box_icon_1.tif -TextureAtlasTest/scroll_box_icon_2.tif -TextureAtlasTest/scroll_box_icon_3.tif -TextureAtlasTest/scroll_box_icon_4.tif -TextureAtlasTest/scroll_box_icon_5.tif -TextureAtlasTest/scroll_box_icon_6.tif -TextureAtlasTest/scroll_box_icon_7.tif -TextureAtlasTest/scroll_box_icon_8.tif -TextureAtlasTest/scroll_box_icon_9.tif -TextureAtlasTest/scroll_box_icon_10.tif -TextureAtlasTest/scroll_box_map.tif -TextureAtlasTest/selected.tif -TextureAtlasTest/shadowInside2.tif -TextureAtlasTest/shadowInsideSquare.tif -TextureAtlasTest/imagesequence/flipbook_walking_00.png -TextureAtlasTest/imagesequence/flipbook_walking_01.png -TextureAtlasTest/imagesequence/flipbook_walking_02.png -TextureAtlasTest/imagesequence/flipbook_walking_03.png -TextureAtlasTest/imagesequence/flipbook_walking_04.png -TextureAtlasTest/imagesequence/flipbook_walking_05.png -TextureAtlasTest/imagesequence/flipbook_walking_06.png -TextureAtlasTest/imagesequence/flipbook_walking_07.png -TextureAtlasTest/imagesequence/flipbook_walking_08.png -TextureAtlasTest/imagesequence/flipbook_walking_09.png -TextureAtlasTest/imagesequence/flipbook_walking_10.png -TextureAtlasTest/imagesequence/flipbook_walking_11.png - diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleFrame.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleFrame.tif deleted file mode 100644 index 392119bd62..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleFrame.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:839defde93893bced650c3aae365da2492ed5d3a36833f0d23b842a64459a73a -size 1069744 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleGradient.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleGradient.png deleted file mode 100644 index ab4a88134e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleGradient.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:9a1ada36ae4b3ef01744ab9041f6b822470c2c7595934a05d9eae8dbf4312e90 -size 38112 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleMask.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleMask.tif deleted file mode 100644 index fd29516609..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/CircleMask.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8474b897fe02f70ed8d0e5c47cae8c816c832a7a5739b8c32317737fd275774f -size 1069752 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/Circle_Shadow.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/Circle_Shadow.tif deleted file mode 100644 index a9e9885ee0..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/Circle_Shadow.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:65145dca27e8ddf865019947659956bae3cec4ff069bc0ff6dc4d87379fbd6fe -size 1070868 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/ParticleGlow.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/ParticleGlow.tif deleted file mode 100644 index 50fd39d881..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/ParticleGlow.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4633d813a6111cfe518853737897925b60616ad73f99fc47a4342c5fd2d5134b -size 267526 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/button.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/button.tif deleted file mode 100644 index d43f5383ec..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/button.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4c5e07103351b9c8a05056c00abc44370c39cfb9480f5e99d1612ae9ad45cfc5 -size 37780 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonPressed.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonPressed.tif deleted file mode 100644 index eec732a736..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonPressed.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c10511cc5898f3edd24c24099d3dc569ebe9f014af01a523b708d74523209189 -size 37804 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonSlider.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonSlider.tif deleted file mode 100644 index 59fdd32998..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/buttonSlider.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:75a0174a65eb945fdb579816968c42de002ec6210f75add6d4c2829bd1cb8c5a -size 37980 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkbox_spritesheet.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkbox_spritesheet.tif deleted file mode 100644 index 6e2b74b486..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkbox_spritesheet.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:40a03c12c1a0123a1fcfaa3f44d343d4318917a9b5851748c74accaa33efda56 -size 17765 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkered3.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkered3.tif deleted file mode 100644 index c1530d4b81..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/checkered3.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6546cc22a1030d2207cd98f8b9afa18abccd24e8b603770c8af6f2c08a769ff0 -size 22360 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/empty_icon.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/empty_icon.tif deleted file mode 100644 index 34a317e80e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/empty_icon.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:23a048ecd54699e9f243f33e9d73b8d8611100357da3f7bcb56a5e1fed08b463 -size 362 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/fixed_image.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/fixed_image.tif deleted file mode 100644 index e1c6d3ad0e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/fixed_image.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cced003316fae3dec3244be8967b7e28a9168d6184362bd0eb65828ac8a0b53b -size 25642 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/flipbook_walking.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/flipbook_walking.tif deleted file mode 100644 index 9a0f604003..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/flipbook_walking.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:91e7ffe470fddde4459e54eb889b2074dc26e8a1c705238c70672b5b3563098a -size 2303404 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_00.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_00.png deleted file mode 100644 index 770d3c724f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_00.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:356ad2eaf78f24ff44f9a136fa22a17f7114052fff3061b417a48ae6b2767ab0 -size 8742 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_01.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_01.png deleted file mode 100644 index f0624bcdf6..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_01.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f5eab5cb57ba50dc1d08abb610599ae6cd8e486dfb8bef1492e01a372ad5b31f -size 7979 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_02.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_02.png deleted file mode 100644 index 36e2450e1b..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_02.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:969a99c99f596f36a51893b14f2f70976809bc7a2ffb1794d0ebca0d5ad20604 -size 7575 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_03.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_03.png deleted file mode 100644 index e18a46d1d6..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_03.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:73a6871305f9ee31ae35d78634cd88bb13d4da5273fce11ae5f353460d43e3c9 -size 5923 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_04.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_04.png deleted file mode 100644 index e6235daabd..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_04.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b28de207784be22c7f501e6ada59e9f9174446f43dba9929633627429e8e0ce3 -size 7076 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_05.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_05.png deleted file mode 100644 index 65f5792ac9..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_05.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4b74237f5e285dd4eab6d1936b639aa1b87f285e5473b3514f9c1713eef39813 -size 8163 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_06.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_06.png deleted file mode 100644 index 61e547151f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_06.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ad6946b610769ba6d2ccc4269cfae24c5e4f30964fd499442108f8bf17c2e8cd -size 8846 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_07.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_07.png deleted file mode 100644 index d3e1aa0ef6..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_07.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:dddff30e20fc4e2f36bedaaca14606d44c9085e8c73841f339ed0a9bc08f26bd -size 7927 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_08.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_08.png deleted file mode 100644 index bdf29b4777..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_08.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d52afab812c6fc8e9c0916c71dc2ea8d957f4326ff9a0ce71658aae06f9d07e5 -size 7459 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_09.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_09.png deleted file mode 100644 index 26fd687534..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_09.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1dad7ebe7690cc9318838dd63bfcace0fad67e14f8f1916dca2fb6ebd267a26c -size 6123 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_10.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_10.png deleted file mode 100644 index dae9568f47..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_10.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a91f9d4be1e432e7b4fa998722ecea178e38ae63ca9f521bb04e5ce2e5159e0f -size 7619 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_11.png b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_11.png deleted file mode 100644 index 60f52297c5..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/imagesequence/flipbook_walking_11.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2979e15676720eb2b81d792880360f8ea26e17322253800b4432f84541d7da7b -size 8245 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/mask.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/mask.tif deleted file mode 100644 index 5e3cd778b4..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/mask.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:764d622d9c589f89f164f4a23d0b66270c25d34c2ecb687640c4ea3e2da55035 -size 36812 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outline.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outline.tif deleted file mode 100644 index 79bdc27a73..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outline.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:e502b7ad23409df89c713c9ce43e1df159d4a634f35fec220a7cf8b5e6c2807f -size 56428 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outlineRounded.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outlineRounded.tif deleted file mode 100644 index e48f6108e7..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/outlineRounded.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb9616528ac43a6c46c8f3b4802cbc7cea51ccc0f86dbc5d156fe0806f34edf0 -size 66024 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/panelBkgd.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/panelBkgd.tif deleted file mode 100644 index b9ad540ce0..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/panelBkgd.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5abfb3bfd5eb8044ec3fde65c65d515a43179c87734b1813dc71c07050841b9f -size 27704 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02.tif deleted file mode 100644 index c9895b73b3..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:739955d9e61a89f732316876e1d1ae0503a6296f946324d7d0305b71e12c9f9e -size 23776 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02_big.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02_big.tif deleted file mode 100644 index 50b056d4ef..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02_big.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ed7bdcd8572fda83219564e8a92cc6f3d4d15e40e8c5950bf1412f74a799edd9 -size 24824 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical.tif deleted file mode 100644 index f8f2fd578c..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:290a417825baaed85811bcc29d91fd0ba436463dadc1648f669c5042234f96c1 -size 23948 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical_big.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical_big.tif deleted file mode 100644 index afebca233e..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern02vertical_big.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:005b9d7623d9ea1e4a470f6fee67f1eb5f38d7a1ad4e357e0036ce81850c6d5f -size 26032 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03.tif deleted file mode 100644 index 7a13c37c36..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6730661ad80d0d9b94c2c05b9cb321e5e5646a99b267d1680cf8fa9b8d62fb42 -size 23792 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03_big.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03_big.tif deleted file mode 100644 index 0098f2ce53..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/pattern03_big.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2ba16a432f64432c6de9b52703faa1dc413c880e284c8719b3e56c737af6d4a0 -size 26720 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_1.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_1.tif deleted file mode 100644 index a21d2aaaa3..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_1.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0426d9b043f9033967a31a3392b80651871af1d4e60eada2d17e445c19105e32 -size 284432 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_10.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_10.tif deleted file mode 100644 index 54ea437920..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_10.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4eef390a93715bd46f196dc0c7ca311300ae7aca33b8163555b6429e91450497 -size 283492 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_2.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_2.tif deleted file mode 100644 index 9f7ba47daa..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_2.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a3d0845d8cc9c75a51ad2c812e6c72ca8147bae2ce12a7ea80e07f579bead937 -size 284884 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_3.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_3.tif deleted file mode 100644 index 4dc54a1950..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_3.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ee3d82984650486f6d2cf4488b60b1723f143134fdb763e390a7fc7c52ace18 -size 284872 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_4.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_4.tif deleted file mode 100644 index 54433305f8..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_4.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:becdab2a389207a942895017511cf453fe059c275dce25c1f5efd41ef13c9d38 -size 285396 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_5.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_5.tif deleted file mode 100644 index 5eae045870..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_5.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:da0222316fcabd92da0908d1750122296e11f7b3e2669e4cbfed3e8c15f08cb0 -size 285076 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_6.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_6.tif deleted file mode 100644 index 54611d8187..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_6.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3d0414c7d73a2ec33a50225af455819abb41f8d35077d3b3ec6bff8cabc3ff6b -size 283664 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_7.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_7.tif deleted file mode 100644 index 2da7dba224..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_7.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:05490310ee718b472efe4b8272077a88e2edf2992c253f46930c9ff1eb52a1e2 -size 283072 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_8.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_8.tif deleted file mode 100644 index 7115f20b1d..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_8.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ba9fb34b4769374304e50d54cd34d1b971a5ec975cdae60ac33aa672c738e245 -size 283216 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_9.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_9.tif deleted file mode 100644 index c4f9f70332..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_icon_9.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0d96c5874954efba8c1c164fe5395a3a73647c09c887fe41d74d3a0f7b109ea8 -size 283488 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_map.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_map.tif deleted file mode 100644 index 8235c16cfc..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/scroll_box_map.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:98b4c4ee5937d1211a4cf9deca85291bbe1419753cd80d97726839aaacd37699 -size 1597872 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/selected.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/selected.tif deleted file mode 100644 index 6d97b05566..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/selected.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fae0b4d2b33ec478d440fdfdb495a36a3980254087291ffdb5557abd66ffbb6e -size 37124 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInside2.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInside2.tif deleted file mode 100644 index ed0a235b5c..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInside2.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ea15986ef41dafe27f642ca91cccbc89e58247bee6b3f8e7e95bf7e5748c29d4 -size 36848 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInsideSquare.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInsideSquare.tif deleted file mode 100644 index 26c13cf93b..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/TextureAtlasTest/shadowInsideSquare.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:095c764409002b30048579c50c552e63b1578acc473a0bce4a646fdc0748df64 -size 37312 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/greyscale.png b/Gems/ImageProcessing/Code/Tests/TestAssets/greyscale.png deleted file mode 100644 index 6df643605a..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/greyscale.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0c0bcbed46bceef7e0686b9b42027d28d98f637c9f7d0d1370eb9911921ba531 -size 1518 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif deleted file mode 100644 index 5c3c4c7a6f..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/noon_cm.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:461580d9bdd4919b72d1703284f53667378d7345ea57f4c52272ef17603a91c1 -size 3148003 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif b/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif deleted file mode 100644 index 4fb9dce719..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/normalSmoothness_ddna.tif +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cd619f19b99ea234c44c79a39413faa18e85a4817a57674c27ebf050edad5515 -size 3776022 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/red.png b/Gems/ImageProcessing/Code/Tests/TestAssets/red.png deleted file mode 100644 index 800faddee4..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/red.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:37d146db3de179add861ee86d2316ef1dd413cdb0b02448b3b95bf0023f44bae -size 613 diff --git a/Gems/ImageProcessing/Code/Tests/TestAssets/uppercase.TGA b/Gems/ImageProcessing/Code/Tests/TestAssets/uppercase.TGA deleted file mode 100644 index d3808cdbce..0000000000 --- a/Gems/ImageProcessing/Code/Tests/TestAssets/uppercase.TGA +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a6b6c1bf24dd39159e38c880071abad7b7315c8667192ff2495501dd0b1dec9c -size 85419 diff --git a/Gems/ImageProcessing/Code/imageprocessing_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_files.cmake deleted file mode 100644 index 98aa870b46..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_files.cmake +++ /dev/null @@ -1,18 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - ../Assets/Editor/Resources.qrc - ../Assets/Editor/Backward.png - ../Assets/Editor/Forward.png - ../Assets/Editor/reset.png - Source/ImageProcessingModule.cpp -) diff --git a/Gems/ImageProcessing/Code/imageprocessing_headers_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_headers_files.cmake deleted file mode 100644 index 5714be5dfb..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_headers_files.cmake +++ /dev/null @@ -1,13 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES -) diff --git a/Gems/ImageProcessing/Code/imageprocessing_static_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_static_files.cmake deleted file mode 100644 index 07bf2ad375..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_static_files.cmake +++ /dev/null @@ -1,133 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Source/ImageProcessing_precompiled.cpp - Source/ImageProcessing_precompiled.h - Source/Compressors/CryTextureSquisher/CryTextureSquisher.cpp - Source/Compressors/CryTextureSquisher/CryTextureSquisher.h - Include/ImageProcessing/ImageProcessingBus.h - Include/ImageProcessing/ImageProcessingEditorBus.h - Include/ImageProcessing/PixelFormats.h - Include/ImageProcessing/ImageObject.h - Source/ImageProcessingSystemComponent.cpp - Source/ImageProcessingSystemComponent.h - Source/ImageBuilderComponent.cpp - Source/ImageBuilderComponent.h - Source/ImageBuilderBaseType.h - Source/BuilderSettings/MipmapSettings.h - Source/BuilderSettings/MipmapSettings.cpp - Source/BuilderSettings/CubemapSettings.h - Source/BuilderSettings/CubemapSettings.cpp - Source/BuilderSettings/PresetSettings.h - Source/BuilderSettings/PresetSettings.cpp - Source/BuilderSettings/TextureSettings.h - Source/BuilderSettings/TextureSettings.cpp - Source/BuilderSettings/BuilderSettings.cpp - Source/BuilderSettings/BuilderSettings.h - Source/BuilderSettings/BuilderSettingManager.cpp - Source/BuilderSettings/BuilderSettingManager.h - Source/BuilderSettings/ImageProcessingDefines.h - Source/BuilderSettings/PlatformSettings.h - Source/Processing/ImageObjectImpl.h - Source/Processing/ImageObjectImpl.cpp - Source/Processing/PixelFormatInfo.h - Source/Processing/PixelFormatInfo.cpp - Source/Processing/ImageConvert.h - Source/Processing/ImageConvert.cpp - Source/Processing/ImageConvertJob.h - Source/Processing/ImageConvertJob.cpp - Source/Processing/ImagePreview.h - Source/Processing/ImagePreview.cpp - Source/Processing/ImageToProcess.h - Source/Processing/ImageFlags.h - Source/Processing/DDSHeader.h - Source/ImageLoader/ImageLoaders.h - Source/ImageLoader/ImageLoaders.cpp - Source/ImageLoader/QtImageLoader.cpp - Source/ImageLoader/TIFFLoader.cpp - Source/ImageLoader/BTImageLoader.cpp - Source/Editor/EditorCommon.h - Source/Editor/EditorCommon.cpp - Source/Editor/TexturePropertyEditor.cpp - Source/Editor/TexturePropertyEditor.h - Source/Editor/TexturePropertyEditor.ui - Source/Editor/MipmapSettingWidget.cpp - Source/Editor/MipmapSettingWidget.h - Source/Editor/MipmapSettingWidget.ui - Source/Editor/ResolutionSettingWidget.cpp - Source/Editor/ResolutionSettingWidget.h - Source/Editor/ResolutionSettingWidget.ui - Source/Editor/ResolutionSettingItemWidget.cpp - Source/Editor/ResolutionSettingItemWidget.h - Source/Editor/ResolutionSettingItemWidget.ui - Source/Editor/TexturePresetSelectionWidget.cpp - Source/Editor/TexturePresetSelectionWidget.h - Source/Editor/TexturePresetSelectionWidget.ui - Source/Editor/TexturePreviewWidget.cpp - Source/Editor/TexturePreviewWidget.h - Source/Editor/TexturePreviewWidget.ui - Source/Editor/ImagePopup.cpp - Source/Editor/ImagePopup.h - Source/Editor/ImagePopup.ui - Source/Editor/PresetInfoPopup.cpp - Source/Editor/PresetInfoPopup.h - Source/Editor/PresetInfoPopup.ui - Source/Converters/Gamma.cpp - Source/Converters/FIR-Filter.cpp - Source/Converters/FIR-Windows.h - Source/Converters/FIR-Weights.h - Source/Converters/FIR-Weights.cpp - Source/Converters/AlphaCoverage.cpp - Source/Converters/PixelOperation.h - Source/Converters/PixelOperation.cpp - Source/Converters/Normalize.cpp - Source/Converters/ConvertPixelFormat.cpp - Source/Converters/Cubemap.h - Source/Converters/Cubemap.cpp - Source/Converters/ColorChart.cpp - Source/Converters/HighPass.cpp - Source/Converters/Histogram.cpp - Source/Converters/Histogram.h - ../External/CubeMapGen/CBBoxInt32.cpp - ../External/CubeMapGen/CBBoxInt32.h - ../External/CubeMapGen/CCubeMapProcessor.cpp - ../External/CubeMapGen/CCubeMapProcessor.h - ../External/CubeMapGen/CImageSurface.cpp - ../External/CubeMapGen/CImageSurface.h - ../External/CubeMapGen/VectorMacros.h - Source/Compressors/Compressor.h - Source/Compressors/Compressor.cpp - Source/Compressors/CTSquisher.h - Source/Compressors/CTSquisher.cpp - Source/Compressors/PVRTC.cpp - Source/Compressors/PVRTC.h - Source/Compressors/ETC2.cpp - Source/Compressors/ETC2.h - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.cpp - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.cpp - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.cpp - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4f.h - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4s.h - Source/Compressors/CryTextureSquisher/ColorBlockRGBA4x4c.h - Source/Compressors/CryTextureSquisher/ColorTypes.h - Source/AtlasBuilder/AtlasBuilderComponent.h - Source/AtlasBuilder/AtlasBuilderComponent.cpp - Source/AtlasBuilder/AtlasBuilderWorker.h - Source/AtlasBuilder/AtlasBuilderWorker.cpp -) - -set(SKIP_UNITY_BUILD_INCLUSION_FILES - Source/Compressors/PVRTC.cpp - Source/Compressors/PVRTC.h -) - - diff --git a/Gems/ImageProcessing/Code/imageprocessing_tests_files.cmake b/Gems/ImageProcessing/Code/imageprocessing_tests_files.cmake deleted file mode 100644 index 290f00104a..0000000000 --- a/Gems/ImageProcessing/Code/imageprocessing_tests_files.cmake +++ /dev/null @@ -1,15 +0,0 @@ -# -# All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -# its licensors. -# -# For complete copyright and license terms please see the LICENSE at the root of this -# distribution (the "License"). All use of this software is governed by the License, -# or, if provided, by the license below or the license accompanying this file. Do not -# remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# - -set(FILES - Tests/ImageProcessing_Test.cpp - Tests/AtlasBuilderTest.cpp -) diff --git a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.cpp b/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.cpp deleted file mode 100644 index 5e80267f56..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.cpp +++ /dev/null @@ -1,129 +0,0 @@ - -//============================================================================= -//CBBoxInt32 -// 3D bounding box with int32 coordinates -// -//============================================================================= -// (C) 2005 ATI Research, Inc., All rights reserved. -//============================================================================= -// modifications by Crytek GmbH -// modifications by Amazon - -#include - -#include "CBBoxInt32.h" - -#define CP_MIN_INT32 0x80000000 -#define CP_MAX_INT32 0x7fffffff -#define CP_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define CP_MAX(a, b) (((a) > (b)) ? (a) : (b)) - - -namespace ImageProcessing -{ - //-------------------------------------------------------------------------------------- - // CBBoxInt32 - //-------------------------------------------------------------------------------------- - CBBoxInt32::CBBoxInt32(void) - { - Clear(); - } - - - //-------------------------------------------------------------------------------------- - // Text to see if CBBoxInt32 is empty or not - //-------------------------------------------------------------------------------------- - bool CBBoxInt32::Empty(void) - { - if ((m_minCoord[0] > m_maxCoord[0]) || - (m_minCoord[1] > m_maxCoord[1]) || - (m_minCoord[2] > m_maxCoord[2])) - { - return true; - } - else - { - return false; - } - } - - - //-------------------------------------------------------------------------------------- - // Clear bounding box extents - //-------------------------------------------------------------------------------------- - void CBBoxInt32::Clear(void) - { - m_minCoord[0] = CP_MAX_INT32; - m_minCoord[1] = CP_MAX_INT32; - m_minCoord[2] = CP_MAX_INT32; - m_maxCoord[0] = CP_MIN_INT32; - m_maxCoord[1] = CP_MIN_INT32; - m_maxCoord[2] = CP_MIN_INT32; - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying point to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::Augment(int32 aX, int32 aY, int32 aZ) - { - m_minCoord[0] = CP_MIN(m_minCoord[0], aX); - m_minCoord[1] = CP_MIN(m_minCoord[1], aY); - m_minCoord[2] = CP_MIN(m_minCoord[2], aZ); - m_maxCoord[0] = CP_MAX(m_maxCoord[0], aX); - m_maxCoord[1] = CP_MAX(m_maxCoord[1], aY); - m_maxCoord[2] = CP_MAX(m_maxCoord[2], aZ); - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying x coordinate to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::AugmentX(int32 aX) - { - m_minCoord[0] = CP_MIN(m_minCoord[0], aX); - m_maxCoord[0] = CP_MAX(m_maxCoord[0], aX); - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying x coordinate to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::AugmentY(int32 aY) - { - m_minCoord[1] = CP_MIN(m_minCoord[1], aY); - m_maxCoord[1] = CP_MAX(m_maxCoord[1], aY); - } - - - //-------------------------------------------------------------------------------------- - // Augment bounding box extents by specifying x coordinate to include in bounding box - //-------------------------------------------------------------------------------------- - void CBBoxInt32::AugmentZ(int32 aZ) - { - m_minCoord[2] = CP_MIN(m_minCoord[2], aZ); - m_maxCoord[2] = CP_MAX(m_maxCoord[2], aZ); - } - - - //-------------------------------------------------------------------------------------- - // Clamp minimum values in bbox to be no larger than aX, aY, aZ - //-------------------------------------------------------------------------------------- - void CBBoxInt32::ClampMin(int32 aX, int32 aY, int32 aZ) - { - m_minCoord[0] = CP_MAX(m_minCoord[0], aX); - m_minCoord[1] = CP_MAX(m_minCoord[1], aY); - m_minCoord[2] = CP_MAX(m_minCoord[2], aZ); - } - - - //-------------------------------------------------------------------------------------- - // Clamp maximum values in bbox to be no larger than aX, aY, aZ - //-------------------------------------------------------------------------------------- - void CBBoxInt32::ClampMax(int32 aX, int32 aY, int32 aZ) - { - m_maxCoord[0] = CP_MIN(m_maxCoord[0], aX); - m_maxCoord[1] = CP_MIN(m_maxCoord[1], aY); - m_maxCoord[2] = CP_MIN(m_maxCoord[2], aZ); - } -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.h b/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.h deleted file mode 100644 index a6bbe0c327..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CBBoxInt32.h +++ /dev/null @@ -1,32 +0,0 @@ -//============================================================================= -//CBBoxInt32 -// 3D bounding box with int32 coordinates -// -//============================================================================= -// (C) 2005 ATI Research, Inc., All rights reserved. -//============================================================================= -// modifications by Crytek GmbH -// modifications by Amazon - -#pragma once - -namespace ImageProcessing -{ - //bounding box class with coords specified as int32 - class CBBoxInt32 - { - public: - int32 m_minCoord[3]; //upper left back corner - int32 m_maxCoord[3]; //lower right front corner - - CBBoxInt32(); - bool Empty(void); - void Clear(void); - void Augment(int32 a_X, int32 a_Y, int32 a_Z); - void AugmentX(int32 a_X); - void AugmentY(int32 a_Y); - void AugmentZ(int32 a_Z); - void ClampMin(int32 a_X, int32 a_Y, int32 a_Z); - void ClampMax(int32 a_X, int32 a_Y, int32 a_Z); - }; -} //namespace ImageProcessing diff --git a/Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.cpp b/Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.cpp deleted file mode 100644 index 794e860f28..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CCubeMapProcessor.cpp +++ /dev/null @@ -1,2237 +0,0 @@ -//============================================================================= -// (C) 2005 ATI Research, Inc., All rights reserved. -//============================================================================= -// modifications by Crytek GmbH -// modifications by Amazon - -#include -#include "CCubeMapProcessor.h" - -#include - -#define CP_PI 3.14159265358979323846 - - -namespace ImageProcessing -{ - - //------------------------------------------------------------------------------ - // D3D cube map face specification - // mapping from 3D x,y,z cube map lookup coordinates - // to 2D within face u,v coordinates - // - // --------------------> U direction - // | (within-face texture space) - // | _____ - // | | | - // | | +Y | - // | _____|_____|_____ _____ - // | | | | | | - // | | -X | +Z | +X | -Z | - // | |_____|_____|_____|_____| - // | | | - // | | -Y | - // | |_____| - // | - // v V direction - // (within-face texture space) - //------------------------------------------------------------------------------ - - //Information about neighbors and how texture coorrdinates change across faces - // in ORDER of left, right, top, bottom (e.g. edges corresponding to u=0, - // u=1, v=0, v=1 in the 2D coordinate system of the particular face. - //Note this currently assumes the D3D cube face ordering and orientation - CPCubeMapNeighbor sg_CubeNgh[6][4] = - { - //XPOS face - {{CP_FACE_Z_POS, CP_EDGE_RIGHT }, - {CP_FACE_Z_NEG, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_RIGHT }, - {CP_FACE_Y_NEG, CP_EDGE_RIGHT }}, - //XNEG face - {{CP_FACE_Z_NEG, CP_EDGE_RIGHT }, - {CP_FACE_Z_POS, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_LEFT }, - {CP_FACE_Y_NEG, CP_EDGE_LEFT }}, - //YPOS face - {{CP_FACE_X_NEG, CP_EDGE_TOP }, - {CP_FACE_X_POS, CP_EDGE_TOP }, - {CP_FACE_Z_NEG, CP_EDGE_TOP }, - {CP_FACE_Z_POS, CP_EDGE_TOP }}, - //YNEG face - {{CP_FACE_X_NEG, CP_EDGE_BOTTOM}, - {CP_FACE_X_POS, CP_EDGE_BOTTOM}, - {CP_FACE_Z_POS, CP_EDGE_BOTTOM}, - {CP_FACE_Z_NEG, CP_EDGE_BOTTOM}}, - //ZPOS face - {{CP_FACE_X_NEG, CP_EDGE_RIGHT }, - {CP_FACE_X_POS, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_BOTTOM }, - {CP_FACE_Y_NEG, CP_EDGE_TOP }}, - //ZNEG face - {{CP_FACE_X_POS, CP_EDGE_RIGHT }, - {CP_FACE_X_NEG, CP_EDGE_LEFT }, - {CP_FACE_Y_POS, CP_EDGE_TOP }, - {CP_FACE_Y_NEG, CP_EDGE_BOTTOM }} - }; - - - //3x2 matrices that map cube map indexing vectors in 3d - // (after face selection and divide through by the - // _ABSOLUTE VALUE_ of the max coord) - // into NVC space - //Note this currently assumes the D3D cube face ordering and orientation - #define CP_UDIR 0 - #define CP_VDIR 1 - #define CP_FACEAXIS 2 - - float sgFace2DMapping[6][3][3] = { - //XPOS face - {{ 0, 0, -1}, //u towards negative Z - { 0, -1, 0}, //v towards negative Y - {1, 0, 0}}, //pos X axis - //XNEG face - {{0, 0, 1}, //u towards positive Z - {0, -1, 0}, //v towards negative Y - {-1, 0, 0}}, //neg X axis - //YPOS face - {{1, 0, 0}, //u towards positive X - {0, 0, 1}, //v towards positive Z - {0, 1 , 0}}, //pos Y axis - //YNEG face - {{1, 0, 0}, //u towards positive X - {0, 0 , -1}, //v towards negative Z - {0, -1 , 0}}, //neg Y axis - //ZPOS face - {{1, 0, 0}, //u towards positive X - {0, -1, 0}, //v towards negative Y - {0, 0, 1}}, //pos Z axis - //ZNEG face - {{-1, 0, 0}, //u towards negative X - {0, -1, 0}, //v towards negative Y - {0, 0, -1}}, //neg Z axis - }; - - - //The 12 edges of the cubemap, (entries are used to index into the neighbor table) - // this table is used to average over the edges. - int32 sg_CubeEdgeList[12][2] = { - {CP_FACE_X_POS, CP_EDGE_LEFT}, - {CP_FACE_X_POS, CP_EDGE_RIGHT}, - {CP_FACE_X_POS, CP_EDGE_TOP}, - {CP_FACE_X_POS, CP_EDGE_BOTTOM}, - - {CP_FACE_X_NEG, CP_EDGE_LEFT}, - {CP_FACE_X_NEG, CP_EDGE_RIGHT}, - {CP_FACE_X_NEG, CP_EDGE_TOP}, - {CP_FACE_X_NEG, CP_EDGE_BOTTOM}, - - {CP_FACE_Z_POS, CP_EDGE_TOP}, - {CP_FACE_Z_POS, CP_EDGE_BOTTOM}, - {CP_FACE_Z_NEG, CP_EDGE_TOP}, - {CP_FACE_Z_NEG, CP_EDGE_BOTTOM} - }; - - - //Information about which of the 8 cube corners are correspond to the - // the 4 corners in each cube face - // the order is upper left, upper right, lower left, lower right - int32 sg_CubeCornerList[6][4] = { - { CP_CORNER_PPP, CP_CORNER_PPN, CP_CORNER_PNP, CP_CORNER_PNN }, // XPOS face - { CP_CORNER_NPN, CP_CORNER_NPP, CP_CORNER_NNN, CP_CORNER_NNP }, // XNEG face - { CP_CORNER_NPN, CP_CORNER_PPN, CP_CORNER_NPP, CP_CORNER_PPP }, // YPOS face - { CP_CORNER_NNP, CP_CORNER_PNP, CP_CORNER_NNN, CP_CORNER_PNN }, // YNEG face - { CP_CORNER_NPP, CP_CORNER_PPP, CP_CORNER_NNP, CP_CORNER_PNP }, // ZPOS face - { CP_CORNER_PPN, CP_CORNER_NPN, CP_CORNER_PNN, CP_CORNER_NNN } // ZNEG face - }; - - - //-------------------------------------------------------------------------------------- - // Convert cubemap face texel coordinates and face idx to 3D vector - // note the U and V coords are integer coords and range from 0 to size-1 - // this routine can be used to generate a normalizer cube map - //-------------------------------------------------------------------------------------- - void TexelCoordToVect(int32 a_FaceIdx, float a_U, float a_V, int32 a_Size, float *a_XYZ) - { - float nvcU, nvcV; - float tempVec[3]; - - //scale up to [-1, 1] range (inclusive) - nvcU = (2.0f * ((float)a_U + 0.5f) / a_Size ) - 1.0f; - nvcV = (2.0f * ((float)a_V + 0.5f) / a_Size ) - 1.0f; - - //generate x,y,z vector (xform 2d NVC coord to 3D vector) - //U contribution - VM_SCALE3(a_XYZ, sgFace2DMapping[a_FaceIdx][CP_UDIR], nvcU); - //V contribution - VM_SCALE3(tempVec, sgFace2DMapping[a_FaceIdx][CP_VDIR], nvcV); - VM_ADD3(a_XYZ, tempVec, a_XYZ); - //add face axis - VM_ADD3(a_XYZ, sgFace2DMapping[a_FaceIdx][CP_FACEAXIS], a_XYZ); - - //normalize vector - VM_NORM3(a_XYZ, a_XYZ); - } - - - //-------------------------------------------------------------------------------------- - // Convert 3D vector to cubemap face texel coordinates and face idx - // note the U and V coords are integer coords and range from 0 to size-1 - // this routine can be used to generate a normalizer cube map - // - // returns face IDX and texel coords - //-------------------------------------------------------------------------------------- - void VectToTexelCoord(float *a_XYZ, int32 a_Size, int32 *a_FaceIdx, int32 *a_U, int32 *a_V ) - { - float nvcU, nvcV; - float absXYZ[3]; - float maxCoord; - float onFaceXYZ[3]; - int32 faceIdx; - int32 u, v; - - //absolute value 3 - VM_ABS3(absXYZ, a_XYZ); - - if( (absXYZ[0] >= absXYZ[1]) && (absXYZ[0] >= absXYZ[2]) ) - { - maxCoord = absXYZ[0]; - - if(a_XYZ[0] >= 0) //face = XPOS - { - faceIdx = CP_FACE_X_POS; - } - else - { - faceIdx = CP_FACE_X_NEG; - } - } - else if ( (absXYZ[1] >= absXYZ[0]) && (absXYZ[1] >= absXYZ[2]) ) - { - maxCoord = absXYZ[1]; - - if(a_XYZ[1] >= 0) //face = XPOS - { - faceIdx = CP_FACE_Y_POS; - } - else - { - faceIdx = CP_FACE_Y_NEG; - } - } - else // if( (absXYZ[2] > absXYZ[0]) && (absXYZ[2] > absXYZ[1]) ) - { - maxCoord = absXYZ[2]; - - if(a_XYZ[2] >= 0) //face = XPOS - { - faceIdx = CP_FACE_Z_POS; - } - else - { - faceIdx = CP_FACE_Z_NEG; - } - } - - //divide through by max coord so face vector lies on cube face - VM_SCALE3(onFaceXYZ, a_XYZ, 1.0f/maxCoord); - nvcU = VM_DOTPROD3(sgFace2DMapping[ faceIdx ][CP_UDIR], onFaceXYZ ); - nvcV = VM_DOTPROD3(sgFace2DMapping[ faceIdx ][CP_VDIR], onFaceXYZ ); - - u = (int32)floor( a_Size * 0.5f * (nvcU + 1.0f) ); - v = (int32)floor( a_Size * 0.5f * (nvcV + 1.0f) ); - - *a_FaceIdx = faceIdx; - *a_U = u; - *a_V = v; - } - - - //-------------------------------------------------------------------------------------- - // gets texel ptr in a cube map given a direction vector, and an array of - // CImageSurfaces that represent the cube faces. - // - //-------------------------------------------------------------------------------------- - CP_ITYPE *GetCubeMapTexelPtr(float *a_XYZ, CImageSurface *a_Surface) - { - int32 u, v, faceIdx; - - //get face idx and u, v texel coordinate in face - VectToTexelCoord(a_XYZ, a_Surface[0].m_Width, &faceIdx, &u, &v ); - - u = VM_MIN(u, a_Surface[0].m_Width - 1); - v = VM_MIN(v, a_Surface[0].m_Width - 1); - - return( a_Surface[faceIdx].GetSurfaceTexelPtr(u, v) ); - } - - - //-------------------------------------------------------------------------------------- - // Compute solid angle of given texel in cubemap face for weighting taps in the - // kernel by the area they project to on the unit sphere. - // - // Note that this code uses an approximation to the solid angle, by treating the - // two triangles that make up the quad comprising the texel as planar. If more - // accuracy is required, the solid angle per triangle lying on the sphere can be - // computed using the sum of the interior angles - PI. - // - //-------------------------------------------------------------------------------------- - float TexelCoordSolidAngle(int32 a_FaceIdx, float a_U, float a_V, int32 a_Size) - { - float cornerVect[4][3]; - double cornerVect64[4][3]; - - float halfTexelStep = 0.5f; //note u, and v are in texel coords (where each texel is one unit) - double edgeVect0[3]; - double edgeVect1[3]; - double xProdVect[3]; - double texelArea; - - //compute 4 corner vectors of texel - TexelCoordToVect(a_FaceIdx, a_U - halfTexelStep, a_V - halfTexelStep, a_Size, cornerVect[0] ); - TexelCoordToVect(a_FaceIdx, a_U - halfTexelStep, a_V + halfTexelStep, a_Size, cornerVect[1] ); - TexelCoordToVect(a_FaceIdx, a_U + halfTexelStep, a_V - halfTexelStep, a_Size, cornerVect[2] ); - TexelCoordToVect(a_FaceIdx, a_U + halfTexelStep, a_V + halfTexelStep, a_Size, cornerVect[3] ); - - VM_NORM3_UNTYPED(cornerVect64[0], cornerVect[0] ); - VM_NORM3_UNTYPED(cornerVect64[1], cornerVect[1] ); - VM_NORM3_UNTYPED(cornerVect64[2], cornerVect[2] ); - VM_NORM3_UNTYPED(cornerVect64[3], cornerVect[3] ); - - //area of triangle defined by corners 0, 1, and 2 - VM_SUB3_UNTYPED(edgeVect0, cornerVect64[1], cornerVect64[0] ); - VM_SUB3_UNTYPED(edgeVect1, cornerVect64[2], cornerVect64[0] ); - VM_XPROD3_UNTYPED(xProdVect, edgeVect0, edgeVect1 ); - texelArea = 0.5f * sqrt( VM_DOTPROD3_UNTYPED(xProdVect, xProdVect ) ); - - //area of triangle defined by corners 1, 2, and 3 - VM_SUB3_UNTYPED(edgeVect0, cornerVect64[2], cornerVect64[1] ); - VM_SUB3_UNTYPED(edgeVect1, cornerVect64[3], cornerVect64[1] ); - VM_XPROD3_UNTYPED(xProdVect, edgeVect0, edgeVect1 ); - texelArea += 0.5f * sqrt( VM_DOTPROD3_UNTYPED(xProdVect, xProdVect ) ); - - return texelArea; - } - - - - //-------------------------------------------------------------------------------------- - //Builds a normalizer cubemap - // - // Takes in a cube face size, and an array of 6 surfaces to write the cube faces into - // - // Note that this normalizer cube map stores the vectors in unbiased -1 to 1 range. - // if _bx2 style scaled and biased vectors are needed, uncomment the SCALE and BIAS - // below - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface ) - { - int32 iCubeFace, u, v; - - //iterate over cube faces - for(iCubeFace=0; iCubeFace<6; iCubeFace++) - { - a_Surface[iCubeFace].Clear(); - a_Surface[iCubeFace].Init(a_Size, a_Size, 3); - - //fast texture walk, build normalizer cube map - CP_ITYPE *texelPtr = a_Surface[iCubeFace].m_ImgData; - - for(v=0; v < a_Surface[iCubeFace].m_Height; v++) - { - for(u=0; u < a_Surface[iCubeFace].m_Width; u++) - { - TexelCoordToVect(iCubeFace, (float)u, (float)v, a_Size, texelPtr); - - //VM_SCALE3(texelPtr, texelPtr, 0.5f); - //VM_BIAS3(texelPtr, texelPtr, 0.5f); - - texelPtr += a_Surface[iCubeFace].m_NumChannels; - } - } - } - } - - - //-------------------------------------------------------------------------------------- - //Builds a normalizer cubemap, with the texels solid angle stored in the fourth component - // - //Takes in a cube face size, and an array of 6 surfaces to write the cube faces into - // - //Note that this normalizer cube map stores the vectors in unbiased -1 to 1 range. - // if _bx2 style scaled and biased vectors are needed, uncomment the SCALE and BIAS - // below - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface ) - { - //iterate over cube faces - for(int32 iCubeFace=0; iCubeFace<6; iCubeFace++) - { - a_Surface[iCubeFace].Clear(); - a_Surface[iCubeFace].Init(a_Size, a_Size, 4); //First three channels for norm cube, and last channel for solid angle - } - - //iterate over cube faces - for(int32 iCubeFace=0; iCubeFace<6; iCubeFace++) - { - const int32 height = a_Surface[iCubeFace].m_Height; - const int32 width = a_Surface[iCubeFace].m_Width; - - for(int32 v=0; v 0) - { - neighborFace = sg_CubeNgh[faceIdx][i].m_Face; - neighborEdge = sg_CubeNgh[faceIdx][i].m_Edge; - - //For certain types of edge abutments, the bleedOverBBoxMin, and bleedOverBBoxMax need to - // be flipped: the cases are - // if a left edge mates with a left or bottom edge on the neighbor - // if a top edge mates with a top or right edge on the neighbor - // if a right edge mates with a right or top edge on the neighbor - // if a bottom edge mates with a bottom or left edge on the neighbor - //Seeing as the edges are enumerated as follows - // left =0 - // right =1 - // top =2 - // bottom =3 - // - // so if the edge enums are the same, or the sum of the enums == 3, - // the bbox needs to be flipped - if( (i == neighborEdge) || ((i+neighborEdge) == 3) ) - { - bleedOverBBoxMin[i] = (a_SrcSize-1) - bleedOverBBoxMin[i]; - bleedOverBBoxMax[i] = (a_SrcSize-1) - bleedOverBBoxMax[i]; - } - - - //The way the bounding box is extended onto the neighboring face - // depends on which edge of neighboring face abuts with this one - switch(sg_CubeNgh[faceIdx][i].m_Edge) - { - case CP_EDGE_LEFT: - a_FilterExtents[neighborFace].Augment(0, bleedOverBBoxMin[i], 0); - a_FilterExtents[neighborFace].Augment(bleedOverAmount[i], bleedOverBBoxMax[i], 0); - break; - case CP_EDGE_RIGHT: - a_FilterExtents[neighborFace].Augment( (a_SrcSize-1), bleedOverBBoxMin[i], 0); - a_FilterExtents[neighborFace].Augment( (a_SrcSize-1) - bleedOverAmount[i], bleedOverBBoxMax[i], 0); - break; - case CP_EDGE_TOP: - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMin[i], 0, 0); - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMax[i], bleedOverAmount[i], 0); - break; - case CP_EDGE_BOTTOM: - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMin[i], (a_SrcSize-1), 0); - a_FilterExtents[neighborFace].Augment(bleedOverBBoxMax[i], (a_SrcSize-1) - bleedOverAmount[i], 0); - break; - } - - //clamp filter extents in non-center tap faces to remain within surface - a_FilterExtents[neighborFace].ClampMin(0, 0, 0); - a_FilterExtents[neighborFace].ClampMax(a_SrcSize-1, a_SrcSize-1, 0); - } - - //If the bleed over amount bleeds past the adjacent face onto the opposite face - // from the center tap face, then process the opposite face entirely for now. - //Note that the cases in which this happens, what usually happens is that - // more than one edge bleeds onto the opposite face, and the bounding box - // encompasses the entire cube map face. - if(bleedOverAmount[i] > a_SrcSize) - { - uint32 oppositeFaceIdx; - - //determine opposite face - switch(faceIdx) - { - case CP_FACE_X_POS: - oppositeFaceIdx = CP_FACE_X_NEG; - break; - case CP_FACE_X_NEG: - oppositeFaceIdx = CP_FACE_X_POS; - break; - case CP_FACE_Y_POS: - oppositeFaceIdx = CP_FACE_Y_NEG; - break; - case CP_FACE_Y_NEG: - oppositeFaceIdx = CP_FACE_Y_POS; - break; - case CP_FACE_Z_POS: - oppositeFaceIdx = CP_FACE_Z_NEG; - break; - default: // CP_FACE_Z_NEG: - oppositeFaceIdx = CP_FACE_Z_POS; - break; - } - - //just encompass entire face for now - a_FilterExtents[oppositeFaceIdx].Augment(0, 0, 0); - a_FilterExtents[oppositeFaceIdx].Augment((a_SrcSize-1), (a_SrcSize-1), 0); - } - } - - minV=minV; - } - - - //-------------------------------------------------------------------------------------- - //ProcessFilterExtents - // Process bounding box in each cube face - // - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, - CBBoxInt32 *a_FilterExtents, CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, - CP_ITYPE *a_DstVal, uint32 a_FilterType, bool a_bUseSolidAngleWeighting, float a_SpecularPower) - { - //accumulators are 64-bit floats in order to have the precision needed - // over a summation of a large number of pixels - double dstAccumFace[6][4]; - double weightAccumFace[6]; - - const int32 nSrcChannels = a_SrcCubeMap[0].m_NumChannels; - - //norm cube map and srcCubeMap have same face width - const int32 faceWidth = a_NormCubeMap[0].m_Width; - - //amount to add to pointer to move to next scanline in images - const int32 normCubePitch = faceWidth * a_NormCubeMap[0].m_NumChannels; - const int32 srcCubePitch = faceWidth * a_SrcCubeMap[0].m_NumChannels; - - //iterate over cubefaces - for(int32 iFaceIdx=0; iFaceIdx<6; iFaceIdx++ ) - { - //dest accum - for(int32 k=0; k= a_DotProdThresh ) - { - CP_ITYPE weight; - - //for now just weight all taps equally, but ideally - // weight should be proportional to the solid angle of the tap - if(a_bUseSolidAngleWeighting == true) - { //solid angle stored in 4th channel of normalizer/solid angle cube map - weight = *(texelVect+3); - } - else - { //all taps equally weighted - weight = 1.0f; - } - - switch(a_FilterType) - { - case CP_FILTER_TYPE_COSINE_POWER: - { - if(tapDotProd > 0.0f) - { - weight *= pow(tapDotProd, a_SpecularPower) * tapDotProd; - } - else - { - weight = 0; - } - } - break; - case CP_FILTER_TYPE_CONE: - case CP_FILTER_TYPE_ANGULAR_GAUSSIAN: - { - //weights are in same lookup table for both of these filter types - weight *= m_FilterLUT[(int32)(tapDotProd * (m_NumFilterLUTEntries - 1))]; - } - break; - case CP_FILTER_TYPE_COSINE: - { - if(tapDotProd > 0.0f) - { - weight *= tapDotProd; - } - else - { - weight = 0.0f; - } - } - break; - case CP_FILTER_TYPE_DISC: - default: - break; - } - - //iterate over channels - for(int32 k=0; k>= 1; - - m_NumMipLevels++; - - //terminate if mip chain becomes too small - if(mipLevelSize == 0) - { - return; - } - } - } - - - //-------------------------------------------------------------------------------------- - //Copy and convert cube map face data from an external image/surface into this object - // - // a_FaceIdx = a value 0 to 5 speciying which face to copy into (one of the CP_FACE_? ) - // a_Level = mip level to copy into - // a_SrcType = data type of image being copyed from (one of the CP_TYPE_? types) - // a_SrcNumChannels = number of channels of the image being copied from (usually 1 to 4) - // a_SrcPitch = number of bytes per row of the source image being copied from - // a_SrcDataPtr = pointer to the image data to copy from - // a_Degamma = original gamma level of input image to undo by degamma - // a_Scale = scale to apply to pixel values after degamma (in linear space) - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, - int32 a_SrcPitch, void *a_SrcDataPtr, float a_MaxClamp, float a_Degamma, float a_Scale) - { - //since input is being modified, terminate any active filtering threads - TerminateActiveThreads(); - - m_InputSurface[a_FaceIdx].SetImageDataClampDegammaScale( a_SrcType, a_SrcNumChannels, a_SrcPitch, - a_SrcDataPtr, a_MaxClamp, a_Degamma, a_Scale ); - } - - - //-------------------------------------------------------------------------------------- - //Copy and convert cube map face data from this object into an external image/surface - // - // a_FaceIdx = a value 0 to 5 speciying which face to copy into (one of the CP_FACE_? ) - // a_Level = mip level to copy into - // a_DstType = data type of image to copy to (one of the CP_TYPE_? types) - // a_DstNumChannels = number of channels of the image to copy to (usually 1 to 4) - // a_DstPitch = number of bytes per row of the dest image to copy to - // a_DstDataPtr = pointer to the image data to copy to - // a_Scale = scale to apply to pixel values (in linear space) before gamma for output - // a_Gamma = gamma level to apply to pixels after scaling - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, - int32 a_DstPitch, void *a_DstDataPtr, float a_Scale, float a_Gamma) - { - m_InputSurface[a_FaceIdx].GetImageDataScaleGamma( a_DstType, a_DstNumChannels, a_DstPitch, - a_DstDataPtr, a_Scale, a_Gamma ); - } - - - //-------------------------------------------------------------------------------------- - //ChannelSwapInputFaceData - // swizzle data in first 4 channels for input faces - // - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::ChannelSwapInputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, - int32 a_Channel2Src, int32 a_Channel3Src ) - { - int32 iFace, u, v, k; - int32 size; - CP_ITYPE texelData[4]; - int32 channelSrcArray[4]; - - //since input is being modified, terminate any active filtering threads - TerminateActiveThreads(); - - size = m_InputSize; - - channelSrcArray[0] = a_Channel0Src; - channelSrcArray[1] = a_Channel1Src; - channelSrcArray[2] = a_Channel2Src; - channelSrcArray[3] = a_Channel3Src; - - //Iterate over faces for input images - for(iFace=0; iFace<6; iFace++) - { - for(v=0; v> 16u); - bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u); - bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u); - bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u); - bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u); - - return float(bits) * 2.3283064365386963e-10; // float(bits) * 2^-32 - } - - inline void HammersleySequence(uint32 sampleIndex, uint32 sampleCount, float* vXi) - { - vXi[0] = float(sampleIndex) / float(sampleCount); - vXi[1] = RadicalInverse2(sampleIndex); - } - - void ImportanceSampleGGX(float* vXi, float roughness, float* vNormal, float* vOut) - { - float phi = 2 * CP_PI * vXi[0]; - float cosTheta = sqrtf((1 - vXi[1]) / ( 1 + (roughness * roughness - 1) * vXi[1])); - float sinTheta = sqrtf(1 - cosTheta * cosTheta); - - float vH[3]; - vH[0] = sinTheta * cosf(phi); - vH[1] = sinTheta * sinf(phi); - vH[2] = cosTheta; - - float vUpVectorX[3] = {1, 0, 0}; - float vUpVectorZ[3] = {0, 0, 1}; - float vTangentX[3]; - float vTangentY[3]; - float vTempVec[3]; - - // Build local frame - VM_XPROD3(vTempVec, fabs(vNormal[2]) < 0.999f ? vUpVectorZ : vUpVectorX, vNormal); - VM_NORM3(vTangentX, vTempVec); - VM_XPROD3(vTangentY, vNormal, vTangentX); - - // Convert from tangent to world space - vOut[0] = vTangentX[0] * vH[0] + vTangentY[0] * vH[1] + vNormal[0] * vH[2]; - vOut[1] = vTangentX[1] * vH[0] + vTangentY[1] * vH[1] + vNormal[1] * vH[2]; - vOut[2] = vTangentX[2] * vH[0] + vTangentY[2] * vH[1] + vNormal[2] * vH[2]; - } - - - void CCubeMapProcessor::FilterCubeSurfacesGGX(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, int32 a_SampleCount, float a_Roughness, - int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 a_ThreadIdx) - { - const uint32 numChannels = VM_MIN(m_NumChannels, 4); - const int32 dstSize = a_DstCubeMap[0].m_Width; - - //thread progress - m_ThreadProgress[a_ThreadIdx].m_StartFace = a_FaceIdxStart; - m_ThreadProgress[a_ThreadIdx].m_EndFace = a_FaceIdxEnd; - - //process required faces - for(int32 iCubeFace = a_FaceIdxStart; iCubeFace <= a_FaceIdxEnd && !m_shutdownWorkerThreadSignal; iCubeFace++) - { - //iterate over dst cube map face texel - for(int32 v = 0; v < dstSize && !m_shutdownWorkerThreadSignal; v++) - { - CP_ITYPE *texelPtr = a_DstCubeMap[iCubeFace].m_ImgData + v * a_DstCubeMap[iCubeFace].m_NumChannels * dstSize; - - m_ThreadProgress[a_ThreadIdx].m_CurrentFace = iCubeFace; - m_ThreadProgress[a_ThreadIdx].m_CurrentRow = v; - - for (int32 u = 0; u < dstSize && !m_shutdownWorkerThreadSignal; u++) - { - float color[4] = { 0 }; - float totalWeight = 0; - float vH[3]; - float vL[3]; - - // Assume normal and view vector to be vCenterTapDir - float vCenterTapDir[3]; - TexelCoordToVect(iCubeFace, (float)u, (float)v, dstSize, vCenterTapDir); - - for (uint32 i = 0; i < (uint32)a_SampleCount && !m_shutdownWorkerThreadSignal; i++) - { - float vXi[2]; - HammersleySequence(i, a_SampleCount, vXi); - ImportanceSampleGGX(vXi, a_Roughness, vCenterTapDir, vH); - - float fVdotH = VM_DOTPROD3(vCenterTapDir, vH); - vL[0] = 2 * fVdotH * vH[0] - vCenterTapDir[0]; - vL[1] = 2 * fVdotH * vH[1] - vCenterTapDir[1]; - vL[2] = 2 * fVdotH * vH[2] - vCenterTapDir[2]; - - float fNdotL = VM_DOTPROD3(vCenterTapDir, vL); - if (fNdotL > 0) - { - CP_ITYPE *sourceTexel = GetCubeMapTexelPtr(vL, a_SrcCubeMap); - for (uint32 k = 0; k < numChannels; k++) - { - color[k] += sourceTexel[k] * fNdotL; - } - - totalWeight += fNdotL; - } - } - - for (uint32 k = 0; k < numChannels; k++) - { - texelPtr[k] = color[k] / totalWeight; - } - - texelPtr += a_DstCubeMap[iCubeFace].m_NumChannels; - } - } - } - } - - - void CCubeMapProcessor::FilterCubeMapMipChain(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle, float a_GlossScale, float a_GlossBias, - int32 a_SampleCountGGX) - { - int32 i; - float coneAngle; - - if(a_FilterType == CP_FILTER_TYPE_COSINE_POWER || a_FilterType == CP_FILTER_TYPE_GGX) - { - // Don't filter top mipmap - a_BaseFilterAngle = 0; - } - - //Build filter lookup tables based on the source miplevel size - PrecomputeFilterLookupTables(a_FilterType, m_InputSurface[0].m_Width, a_BaseFilterAngle); - - //initialize thread progress - m_ThreadProgress[0].m_CurrentMipLevel = 0; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - //Filter the top mip level (initial filtering used for diffuse or blurred specular lighting ) - FilterCubeSurfaces(m_InputSurface, m_OutputSurface[0], a_BaseFilterAngle, a_FilterType, a_bUseSolidAngle, - 0, //start at face 0 - 5, //end at face 5 - 0); //thread 0 is processing - - m_ThreadProgress[0].m_CurrentMipLevel = 1; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - - FixupCubeEdges(m_OutputSurface[0], a_FixupType, a_FixupWidth); - - //Cone angle start (for generating subsequent mip levels) - coneAngle = a_InitialMipAngle; - - //generate subsequent mip levels - for(i=0; i<(m_NumMipLevels-1) && !m_shutdownWorkerThreadSignal; i++) - { - m_ThreadProgress[0].m_CurrentMipLevel = i+1; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - CImageSurface* srcCubeImage = m_OutputSurface[i]; - - if (a_FilterType == CP_FILTER_TYPE_GGX) - { - uint32 numUsableMips = m_NumMipLevels - 2; // Lowest used mip is 4x4 - float smoothness = VM_MAX(1.0f - (float)(i + 1) / (float)(numUsableMips - 1), 0.0f); - - // Convert smoothness to roughness (needs to match shader code) - float roughness = (1.0f - smoothness) * (1.0f - smoothness); - - FilterCubeSurfacesGGX(srcCubeImage, m_OutputSurface[i+1], a_SampleCountGGX, roughness, - 0, //start at face 0 - 5, //end at face 5 - 0 //thread 0 is processing - ); - } - else - { - float specPow = 1.0f; - - if(a_FilterType == CP_FILTER_TYPE_COSINE_POWER) - { - uint32 numMipsForGloss = m_NumMipLevels - 2; // Lowest used mip is 4x4 - float gloss = VM_MAX(1.0f - (float)(i + 1) / (float)(numMipsForGloss - 1), 0.0f); - - // Compute specular power (this must match shader code) - specPow = pow(2.0f, a_GlossScale * gloss + a_GlossBias); - - // Blinn to Phong approximation: (R.E)^p == (N.H)^(4*p) - specPow /= 4.0f; - - coneAngle = ComputeBaseFilterAngle(specPow); - srcCubeImage = m_InputSurface; - } - - //Build filter lookup tables based on the source miplevel size - PrecomputeFilterLookupTables(a_FilterType, srcCubeImage->m_Width, coneAngle); - - //filter cube surfaces - FilterCubeSurfaces(srcCubeImage, m_OutputSurface[i+1], coneAngle, a_FilterType, a_bUseSolidAngle, - 0, //start at face 0 - 5, //end at face 5 - 0, //thread 0 is processing - specPow); - } - - m_ThreadProgress[0].m_CurrentMipLevel = i+2; - m_ThreadProgress[0].m_CurrentRow = 0; - m_ThreadProgress[0].m_CurrentFace = 0; - - FixupCubeEdges(m_OutputSurface[i+1], a_FixupType, a_FixupWidth); - - coneAngle = coneAngle * a_MipAnglePerLevelScale; - } - - m_Status = CP_STATUS_FILTER_COMPLETED; - } - - - //-------------------------------------------------------------------------------------- - //Builds the following lookup tables prior to filtering: - // -normalizer cube map - // -tap weight lookup table - // - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle) - { - float srcTexelAngle; - int32 iCubeFace; - - //angle about center tap that defines filter cone - float filterAngle; - - //min angle a src texel can cover (in degrees) - srcTexelAngle = (180.0f / (float)CP_PI) * atan2f(1.0f, (float)a_SrcCubeMapWidth); - - //filter angle is 1/2 the cone angle - filterAngle = a_FilterConeAngle / 2.0f; - - //ensure filter angle is larger than a texel - if(filterAngle < srcTexelAngle) - { - filterAngle = srcTexelAngle; - } - - //ensure filter cone is always smaller than the hemisphere - if(filterAngle > 90.0f) - { - filterAngle = 90.0f; - } - - //build lookup table for tap weights based on angle between current tap and center tap - BuildAngleWeightLUT(a_SrcCubeMapWidth * 2, a_FilterType, filterAngle); - - //clear pre-existing normalizer cube map - for(iCubeFace=0; iCubeFace<6; iCubeFace++) - { - m_NormCubeMap[iCubeFace].Clear(); - } - - //Normalized vectors per cubeface and per-texel solid angle - BuildNormalizerSolidAngleCubemap(a_SrcCubeMapWidth, m_NormCubeMap); - - } - - //-------------------------------------------------------------------------------------- - //The key to the speed of these filtering routines is to quickly define a per-face - // bounding box of pixels which enclose all the taps in the filter kernel efficiently. - // Later these pixels are selectively processed based on their dot products to see if - // they reside within the filtering cone. - // - //This is done by computing the smallest per-texel angle to get a conservative estimate - // of the number of texels needed to be covered in width and height order to filter the - // region. the bounding box for the center taps face is defined first, and if the - // filtereing region bleeds onto the other faces, bounding boxes for the other faces are - // defined next - //-------------------------------------------------------------------------------------- - void CCubeMapProcessor::FilterCubeSurfaces(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, - float a_FilterConeAngle, int32 a_FilterType, bool a_bUseSolidAngle, int32 a_FaceIdxStart, - int32 a_FaceIdxEnd, int32 a_ThreadIdx, float a_SpecularPower) - { - const int32 srcSize = a_SrcCubeMap[0].m_Width; - const int32 dstSize = a_DstCubeMap[0].m_Width; - - //min angle a src texel can cover (in degrees) - const float srcTexelAngle = (180.0f / (float)CP_PI) * atan2f(1.0f, (float)srcSize); - - //angle about center tap to define filter cone - float filterAngle; - - //filter angle is 1/2 the cone angle - filterAngle = a_FilterConeAngle / 2.0f; - - //ensure filter angle is larger than a texel - if(filterAngle < srcTexelAngle) - { - filterAngle = srcTexelAngle; - } - - //ensure filter cone is always smaller than the hemisphere - if(filterAngle > 90.0f) - { - filterAngle = 90.0f; - } - - //the maximum number of texels in 1D the filter cone angle will cover - // used to determine bounding box size for filter extents - //ensure conservative region always covers at least one texel - const int32 filterSize = AZ::GetMax((int32)ceil(filterAngle / srcTexelAngle), 1); - - //dotProdThresh threshold based on cone angle to determine whether or not taps - // reside within the cone angle - const float dotProdThresh = cosf( ((float)CP_PI / 180.0f) * filterAngle ); - - //thread progress - m_ThreadProgress[a_ThreadIdx].m_StartFace = a_FaceIdxStart; - m_ThreadProgress[a_ThreadIdx].m_EndFace = a_FaceIdxEnd; - - //process required faces - for(int32 iCubeFace = a_FaceIdxStart; iCubeFace <= a_FaceIdxEnd && !m_shutdownWorkerThreadSignal; iCubeFace++) - { - //iterate over dst cube map face texel - for(int32 v = 0; v < dstSize && !m_shutdownWorkerThreadSignal; v++) - { - CP_ITYPE *texelPtr = a_DstCubeMap[iCubeFace].m_ImgData + v * a_DstCubeMap[iCubeFace].m_NumChannels * dstSize; - - m_ThreadProgress[a_ThreadIdx].m_CurrentFace = iCubeFace; - m_ThreadProgress[a_ThreadIdx].m_CurrentRow = v; - - for(int32 u=0; u 0.0f) - { - totalMipComputation = pow(m_InputSize * m_BaseFilterAngle , 2.0f) * (m_OutputSize * m_OutputSize); - } - else - { - totalMipComputation = pow(m_InputSize * 0.01f , 2.0f) * (m_OutputSize * m_OutputSize); - } - - progressMipComputation = 0.0f; - if(a_FilterProgress->m_CurrentMipLevel > 0) - { - progressMipComputation = totalMipComputation; - } - - //filtering angle for this miplevel - filterAngle = m_InitialMipAngle; - dstSize = m_OutputSize; - - //computation for entire base mip level (if current level is base level) - if(a_FilterProgress->m_CurrentMipLevel == 0) - { - currentMipComputation = totalMipComputation; - currentMipSize = dstSize; - } - - //compuatation to generate subsequent mip levels - for(i=1; i 180) - { - filterAngle = 180; - } - - //note src size is dstSize*2 since miplevels are generated from the subsequent level - computation = pow(dstSize * 2 * filterAngle, 2.0f) * (dstSize * dstSize); - - totalMipComputation += computation; - - //accumulate computation for completed mip levels - if(a_FilterProgress->m_CurrentMipLevel > i) - { - progressMipComputation = totalMipComputation; - } - - //computation for entire current mip level - if(a_FilterProgress->m_CurrentMipLevel == i) - { - currentMipComputation = computation; - currentMipSize = dstSize; - } - } - - //fraction of compuation time processing the entire current mip level will take - currentMipComputation /= totalMipComputation; - progressMipComputation /= totalMipComputation; - - progressFaceComputation = currentMipComputation * - (float)(a_FilterProgress->m_CurrentFace - a_FilterProgress->m_StartFace) / - (float)(1 + a_FilterProgress->m_EndFace - a_FilterProgress->m_StartFace); - - currentFaceComputation = currentMipComputation * - 1.0f / - (1 + a_FilterProgress->m_EndFace - a_FilterProgress->m_StartFace); - - progressRowComputation = currentFaceComputation * - ((float)a_FilterProgress->m_CurrentRow / (float)currentMipSize); - - //progress completed - a_FilterProgress->m_FractionCompleted = - progressMipComputation + - progressFaceComputation + - progressRowComputation; - - - if( a_FilterProgress->m_CurrentFace < 0) - { - a_FilterProgress->m_CurrentFace = 0; - } - - if( a_FilterProgress->m_CurrentMipLevel < 0) - { - a_FilterProgress->m_CurrentMipLevel = 0; - } - - if( a_FilterProgress->m_CurrentRow < 0) - { - a_FilterProgress->m_CurrentRow = 0; - } - - } - - - //-------------------------------------------------------------------------------------- - // Return string describing the current status of the cubemap processing threads - // - //-------------------------------------------------------------------------------------- - WCHAR *CCubeMapProcessor::GetFilterProgressString(void) - { - WCHAR threadProgressString[CP_MAX_FILTER_THREADS][CP_MAX_PROGRESS_STRING]; - int32 i; - - for(i=0; i -#include -#include -#include - -#include "VectorMacros.h" -#include "CBBoxInt32.h" -#include "CImageSurface.h" - -//has routines for saving .rgbe files -#define CG_RGBE_SUPPORT - - -#ifndef WCHAR -#define WCHAR wchar_t -#endif //WCHAR - - -//used to index cube faces -#define CP_FACE_X_POS 0 -#define CP_FACE_X_NEG 1 -#define CP_FACE_Y_POS 2 -#define CP_FACE_Y_NEG 3 -#define CP_FACE_Z_POS 4 -#define CP_FACE_Z_NEG 5 - - -//used to index image edges -// NOTE.. the actual number corresponding to the edge is important -// do not change these, or the code will break -// -// CP_EDGE_LEFT is u = 0 -// CP_EDGE_RIGHT is u = width-1 -// CP_EDGE_TOP is v = 0 -// CP_EDGE_BOTTOM is v = height-1 -#define CP_EDGE_LEFT 0 -#define CP_EDGE_RIGHT 1 -#define CP_EDGE_TOP 2 -#define CP_EDGE_BOTTOM 3 - -//corners of CUBE map (P or N specifys if it corresponds to the -// positive or negative direction each of X, Y, and Z -#define CP_CORNER_NNN 0 -#define CP_CORNER_NNP 1 -#define CP_CORNER_NPN 2 -#define CP_CORNER_NPP 3 -#define CP_CORNER_PNN 4 -#define CP_CORNER_PNP 5 -#define CP_CORNER_PPN 6 -#define CP_CORNER_PPP 7 - -//data types processed by cube map processor -// note that UNORM data types use the full range -// of the unsigned integer to represent the range [0, 1] inclusive -// the float16 datatype is stored as D3Ds S10E5 representation -#define CP_VAL_UNORM8 0 -#define CP_VAL_UNORM8_BGRA 1 -#define CP_VAL_UNORM16 10 -#define CP_VAL_FLOAT16 20 -#define CP_VAL_FLOAT32 30 - - -//return codes for thread execution -// warning STILL_ACTIVE maps to 259, so the number 259 is reserved in this case -// and should only be used for STILL_ACTIVE -#define CP_THREAD_COMPLETED 0 -#define CP_THREAD_TERMINATED 15 -#define CP_THREAD_STILL_ACTIVE STILL_ACTIVE - -#define CP_MAX_PROGRESS_STRING 1024 - -// Type of data used internally by cube map processor -// just in case for any reason more preecision is needed, -// this type can be changed down the road -#define CP_ITYPE float - -// Filter type -#define CP_FILTER_TYPE_DISC 0 -#define CP_FILTER_TYPE_CONE 1 -#define CP_FILTER_TYPE_COSINE 2 -#define CP_FILTER_TYPE_ANGULAR_GAUSSIAN 3 -#define CP_FILTER_TYPE_COSINE_POWER 4 -#define CP_FILTER_TYPE_GGX 5 - - -// Edge fixup type (how to perform smoothing near edge region) -#define CP_FIXUP_NONE 0 -#define CP_FIXUP_PULL_LINEAR 1 -#define CP_FIXUP_PULL_HERMITE 2 -#define CP_FIXUP_AVERAGE_LINEAR 3 -#define CP_FIXUP_AVERAGE_HERMITE 4 - - -// Max potential cubemap size is limited to 65k (2^16 texels) on a side -#define CP_MAX_MIPLEVELS 16 - -//maximum number of threads running for cubemap processor is 2 -#define CP_MAX_FILTER_THREADS 2 - -//initial number of filtering threads for cubemap processor -#define CP_INITIAL_NUM_FILTER_THREADS 1 - - -//current status of cubemap processor -#define CP_STATUS_READY 0 -#define CP_STATUS_PROCESSING 1 -#define CP_STATUS_FILTER_TERMINATED 2 -#define CP_STATUS_FILTER_COMPLETED 3 - - -#define CP_SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } -#define CP_SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } - -namespace ImageProcessing -{ - - - //information about cube maps neighboring face after traversing - // across an edge - struct CPCubeMapNeighbor - { - uint8 m_Face; //index of neighboring face - uint8 m_Edge; //edge in neighboring face that abuts this face - }; - - - //-------------------------------------------------------------------------------------------------- - //structure used to store current progress of the filtering - //-------------------------------------------------------------------------------------------------- - struct SFilterProgress - { - //status of current cube map processing - int32 m_CurrentFace; - int32 m_CurrentRow; - int32 m_CurrentMipLevel; - - int32 m_StartFace; - int32 m_EndFace; - - float m_FractionCompleted; //Approximate fraction of work completed for this thread - }; - - - //-------------------------------------------------------------------------------------------------- - //structure used to pass filtering parameters for Thread 0 - //-------------------------------------------------------------------------------------------------- - struct SThreadOptionsThread0 - { - class CCubeMapProcessor *m_cmProc; - float m_BaseFilterAngle; - float m_InitialMipAngle; - float m_MipAnglePerLevelScale; - float m_GlossScale; - float m_GlossBias; - int32 m_FilterType; - int32 m_FixupType; - int32 m_FixupWidth; - int32 m_SampleCountGGX; - bool m_bUseSolidAngle; - }; - - - //-------------------------------------------------------------------------------------------------- - //structure used to pass filtering parameters to the process for Thread 1 (if used) - //-------------------------------------------------------------------------------------------------- - struct SThreadOptionsThread1 - { - class CCubeMapProcessor *m_cmProc; - CImageSurface *m_SrcCubeMap; - CImageSurface *m_DstCubeMap; - float m_FilterConeAngle; - int32 m_FilterType; - bool m_bUseSolidAngle; - int32 m_FaceIdxStart; - int32 m_FaceIdxEnd; - int32 m_ThreadIdx; - }; - - - //-------------------------------------------------------------------------------------------------- - //Class to filter, perform edge fixup, and build a mip chain for a cubemap - //-------------------------------------------------------------------------------------------------- - class CCubeMapProcessor - { - public: - - //cubemap processor status - int32 m_Status; - - //information about threads actively processing the cubemap - int32 m_NumFilterThreads; - bool m_bThreadInitialized[CP_MAX_FILTER_THREADS]; - - AZStd::thread m_ThreadHandle[CP_MAX_FILTER_THREADS]; - - AZ::u32 m_ThreadID[CP_MAX_FILTER_THREADS]; - SFilterProgress m_ThreadProgress[CP_MAX_FILTER_THREADS]; - WCHAR m_ProgressString[CP_MAX_PROGRESS_STRING]; - - //filtering parameters last used for filtering - float m_BaseFilterAngle; - float m_InitialMipAngle; - float m_MipAnglePerLevelScale; - - int32 m_InputSize; //input cubemap size (e.g. face width and height of topmost mip level) - int32 m_OutputSize; //output cubemap size (e.g. face width and height of topmost mip level) - int32 m_NumMipLevels; //number of output mip levels - int32 m_NumChannels; //number of channels in cube map processor - - CP_ITYPE *m_FilterLUT; //filter weight lookup table (scale dot product 0-1 range to index into it) - int32 m_NumFilterLUTEntries; //number of filter lookup table entries - - CImageSurface m_NormCubeMap[6]; //normalizer cube map and solid angle lookup table - - CImageSurface m_InputSurface[6]; //input faces for topmost mip level - - CImageSurface m_OutputSurface[CP_MAX_MIPLEVELS][6]; //output faces for all mip levels - - private: - //========================================================================================================== - //BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface ); - // Builds a normalizer cubemap of size a_Size. This routine deallocates the CImageSurfaces passed - // into the the function and reallocates them with the correct size and 3 channels to store the - // normalized vector for each texel. - // - // a_Size [in] size of normalizer cubemap - // a_Surface [out] Pointer to array of 6 CImageSurfaces where normalizer cube faces will be stored - // - //========================================================================================================== - void BuildNormalizerCubemap(int32 a_Size, CImageSurface *a_Surface); - - //========================================================================================================== - //void BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface ); - // Builds a normalizer|solid angle cubemap of size a_Size. This routine deallocates the CImageSurfaces - // passed into the the function and reallocates them with the correct size and 4 channels to store the - // normalized vector, and solid angle for each texel. - // - // a_Size [in] - // a_Surface [out] Pointer to array of 6 CImageSurfaces where normalizer cube faces will be stored - // - //========================================================================================================== - void BuildNormalizerSolidAngleCubemap(int32 a_Size, CImageSurface *a_Surface); - - //========================================================================================================== - //Clears filter extent bounding boxes for each face of the cubemap - // - // a_FilterExtents [in] Array of 6 bounding boxes (corresponding to the 6 cubemap faces) to clear - //========================================================================================================== - void ClearFilterExtents(CBBoxInt32 *a_FilterExtents); - - //========================================================================================================== - //void DetermineFilterExtents(float *a_CenterTapDir, int32 a_SrcSize, int32 a_BBoxSize, - // CBBoxInt32 *a_FilterExtents); - // - //Determines bounding boxes for each cube face for a single kernels angular extent - // a_CenterTapDir [in] Vector of 3 float32s specifying the center tap direction - // a_SrcSize [in] Source cubemap size (for the miplevel used as input to the filtering) - // a_BBoxSize [in] Maximum length in texels of the bbox extent derived from the filtering - // cone angle - // a_FilterExtents [out] Array of 6 bounding boxes (corresponding to the 6 cubemap faces) to clear - //========================================================================================================== - void DetermineFilterExtents(float *a_CenterTapDir, int32 a_SrcSize, int32 a_BBoxSize, CBBoxInt32 *a_FilterExtents); - - //========================================================================================================== - //void ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, CBBoxInt32 *a_FilterExtents, - // CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, CP_ITYPE *a_DstVal, uint32 a_FilterType, - // bool a_bUseSolidAngle ); - // - //Processes all the texels within the bounding boxes in order to accumulate all the weighted taps to - // compute a single fitered texel value. - // - //a_CenterTapDir [in] Center tap directions - //a_DotProdThresh [in] Threshhold on dot product between center tap and - //a_FilterExtents [in] array of 6 bounding boxes describing rough filter extents for each face - //a_NormCubeMap [in] normalizer|solid angle cubemap - //a_SrcCubeMap [in] array of 6 faces comprising the miplevel of the source cubemap the filter is - // generated from - //a_DstVal [out] resulting filtered texel color - //a_FilterType [in] filter type: Choose one of the following options: CP_FILTER_TYPE_DISC, - // CP_FILTER_TYPE_CONE, CP_FILTER_TYPE_COSINE, CP_FILTER_TYPE_ANGULAR_GAUSSIAN - //a_bUseSolidAngle [in] Set this to true in order to incorporate the solid angle subtended - // each texel in the filter kernel in the filtering. - // - //========================================================================================================== - void ProcessFilterExtents(float *a_CenterTapDir, float a_DotProdThresh, CBBoxInt32 *a_FilterExtents, - CImageSurface *a_NormCubeMap, CImageSurface *a_SrcCubeMap, CP_ITYPE *a_DstVal, uint32 a_FilterType, - bool a_bUseSolidAngle, float a_SpecularPower); - - //========================================================================================================== - //void FixupCubeEdges(CImageSurface *a_CubeMap, int32 a_FixupType, int32 a_FixupWidth); - // - //Apply edge fixup to a cubemap mip level. - // - //a_CubeMap [in/out] Array of 6 images comprising cubemap miplevel to apply edge fixup to. - //a_FixupType [in] Specifies the technique used for edge fixup. Choose one of the following, - // CP_FIXUP_NONE, CP_FIXUP_PULL_LINEAR, CP_FIXUP_PULL_HERMITE, CP_FIXUP_AVERAGE_LINEAR, - // CP_FIXUP_AVERAGE_HERMITE - //a_FixupWidth [in] Fixup width in texels - // - //========================================================================================================== - void FixupCubeEdges(CImageSurface *a_CubeMap, int32 a_FixupType, int32 a_FixupWidth); - - //========================================================================================================== - //void BuildAngleWeightLUT(int32 a_NumFilterLUTEntries, int32 a_FilterType, float a_FilterAngle); - // - // Builds filter weight lookup table in order to quickly evaluate the weight of a particular texel - // for the Cone and Angular Gaussian fiter types. This lookup table is quickly indexed using the - // same dot product between the center tap and current texel that is used to determine whether a - // texel is inside or outside the filtering kernel. - // - //a_NumFilterLUTEntries [in] Number of entries in filter weight lookup table - //a_FilterType [in] Filter type - //a_FilterAngle [in] Filtering half cone angle - //========================================================================================================== - void BuildAngleWeightLUT(int32 a_NumFilterLUTEntries, int32 a_FilterType, float a_FilterAngle); - - //========================================================================================================== - //void PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle); - // - // Builds the following lookup tables prior to filtering: - // -normalizer cube map - // -filter weight lookup table - // - //a_FilterType [in] Filter type - //a_SrcCubeMapWidth [in] source cubemap size - //a_FilterConeAngle [in] Filtering half cone angle - //========================================================================================================== - void PrecomputeFilterLookupTables(uint32 a_FilterType, int32 a_SrcCubeMapWidth, float a_FilterConeAngle); - - //========================================================================================================== - //void EstimateFilterThreadProgress(SFilterProgress *a_FilterProgress); - // - // Estimates percentage complete for a filtering thread for the current tap that is being filtered - // - //a_FilterProgress [in/out] Information about the filtereing thread's current position, and range of faces - // that it will process. - //========================================================================================================== - void EstimateFilterThreadProgress(SFilterProgress *a_FilterProgress); - - public: - //========================================================================================================== - //note that these functions are only public so that they can be called from within the global scope - // from the thread starting point functions. These should not be called by any other functions external - // to the class. - //========================================================================================================== - void FilterCubeMapMipChain(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle, float a_GlossScale, float a_GlossBias, - int32 a_SampleCountGGX); - void FilterCubeSurfaces(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, float a_FilterConeAngle, - int32 a_FilterType, bool a_bUseSolidAngle, int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 aThreadIdx, - float a_SpecularPower = 1.0f); - void FilterCubeSurfacesGGX(CImageSurface *a_SrcCubeMap, CImageSurface *a_DstCubeMap, int32 a_SampleCount, float a_Roughness, - int32 a_FaceIdxStart, int32 a_FaceIdxEnd, int32 aThreadIdx); - - public: - CCubeMapProcessor(void); - ~CCubeMapProcessor(); - - //========================================================================================================== - // void Init(int32 a_InputSize, int32 a_OutputSize, int32 a_NumMipLevels, int32 a_NumChannels); - // - // Initializes cube map processor class - // - // a_InputSize [in] Size of the input cubemap - // a_OutputSize [in] Size of the input cubemap - // a_NumMipLevels [in] Number of miplevels in the output cubemap - // a_NumChannels [in] Number of color channels (internally) in the input and output cubemap - //========================================================================================================== - void Init(int32 a_InputSize, int32 a_OutputSize, int32 a_NumMipLevels, int32 a_NumChannels); - - - //========================================================================================================== - // void GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - // void *a_DstDataPtr, float a_Scale, float a_Gamma); - // - // Copies image data from the input cube map into a destination image. These routine describe the output - // image layout using a pitch and a pointer so that the image can be copied from a subrect of a locked - // D3D surface easily. Note that when reading out the image data, the intensity scale is applied first, - // and then degamma. - // - // a_FaceIdx [in] Index (0-5) of the input cubemap cube face to read the image data from. - // a_DstType [in] Data type for the image data being copied out the input cube map. - // choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16 - // CP_VAL_FLOAT16, CP_VAL_FLOAT32. - // a_DstNumChannels [in] Number of channels in the destination image. - // a_DstPitch [in] Pitch in bytes of the destination image. - // a_DstDataPtr [in] Pointer to the top-left pixel in the destination image. - // a_Scale [in] Scale factor to apply to intensities. - // a_Gamma [in] Degamma to apply to intensities. - // - //========================================================================================================== - void GetInputFaceData(int32 a_FaceIdx, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - void *a_DstDataPtr, float a_Scale, float a_Gamma); - - - //========================================================================================================== - // void SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, - // void *a_SrcDataPtr, float a_MaxClamp, float a_Scale, float a_Gamma ); - // - // Copies image data from a source image into one of the faces in the input cubemap in the cubemap. - // processor. These routines describe the output image layout using a pitch and a pointer so that the image - // can be copied from a subrect of a locked D3D surface easily. Note that the clamping is applied first, - // followed by the scale and then gamma. - // - // a_FaceIdx [in] Index (0-5) of the input cubemap cube face to write the image data into - // a_SrcType [in] Data type for the image data being copied into the cube map processor. - // choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16 - // CP_VAL_FLOAT16, CP_VAL_FLOAT32. - // a_SrcNumChannels [in] Number of channels in the source image. - // a_SrcPitch [in] Pitch in bytes of the source image. - // a_SrcDataPtr [in] Pointer to the top-left pixel in the source image. - // a_MaxClamp [in] Max value to clamp the input intensity values to. - // a_Degamma [in] Degamma to apply to input intensities. - // a_Scale [in] Scale factor to apply to input intensities. - // - //========================================================================================================== - void SetInputFaceData(int32 a_FaceIdx, int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, - void *a_SrcDataPtr, float a_MaxClamp, float a_Degamma, float a_Scale); - - - //========================================================================================================== - // void GetOutputFaceData(int32 a_FaceIdx, int32 a_Level, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - // void *a_DstDataPtr, float a_Scale, float a_Gamma ); - // - // a_FaceIdx [in] Index (0-5) of the output cubemap cube face to read the image data from. - // a_Level [in] Miplevel of the output cubemap to read from - // a_DstType [in] Data type for the image data being copied out the input cube map. - // choose one of the following: CP_VAL_UNORM8, CP_VAL_UNORM8_BGRA, CP_VAL_UNORM16 - // CP_VAL_FLOAT16, CP_VAL_FLOAT32 - // a_DstNumChannels [in] Number of channels in the destination image. - // a_DstPitch [in] Pitch in bytes of the destination image. - // a_DstDataPtr [in] Pointer to the top-left pixel in the destination image. - // a_Scale [in] Scale factor to apply to intensities. - // a_Gamma [in] Degamma to apply to intensities. - // - //========================================================================================================== - void GetOutputFaceData(int32 a_FaceIdx, int32 a_Level, int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - void *a_DstDataPtr, float a_Scale, float a_Gamma); - - - //========================================================================================================== - //void InitiateFiltering(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - // int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle ); - // - // Starts filtering the cubemap. - // If the number of filter threads is zero, the function does not return until the filtering is complete - // If the number of filter threads is non-zero, a filtering thread (or multiple threads) are started and - // the function returns immediately, with the threads running in the background. - // - // The cube map filtereing is specified using a number of parameters: - // Filtering per miplevel is specified using 2D cone angle (in degrees) that - // indicates the region of the hemisphere to filter over for each tap. - // - // Note that the top mip level is also a filtered version of the original input images - // as well in order to create mip chains for diffuse environment illumination. - // The cone angle for the top level is specified by a_BaseAngle. This can be used to - // generate mipchains used to store the results of preintegration across the hemisphere. - // - // The angle for the subsequent levels of the mip chain are specified by their parents - // filtering angle and a per-level scale and bias - // newAngle = oldAngle * a_MipAnglePerLevelScale; - // - // a_BaseFilterAngle [in] Base filter angle - // a_InitialMipAngle [in] Mip angle used to generate the next level of the mip chain from the base level - // a_MipAnglePerLevelScale [in] Scale factor to iteratively apply to the filtering angle to filter subsequent - // mip-levels. - // a_FilterType [in] Specifies the filtering type for angular extent filtering. Choose one of the - // following options: CP_FILTER_TYPE_DISC, CP_FILTER_TYPE_CONE, - // CP_FILTER_TYPE_COSINE, CP_FILTER_TYPE_ANGULAR_GAUSSIAN - // a_FixupType [in] Specifies the technique used for edge fixup. Choose one of the following, - // CP_FIXUP_NONE, CP_FIXUP_PULL_LINEAR, CP_FIXUP_PULL_HERMITE, - // CP_FIXUP_AVERAGE_LINEAR, CP_FIXUP_AVERAGE_HERMITE - // a_FixupWidth [in] Width in texels of the fixup region. - // a_bUseSolidAngle [in] Set this to true in order to incorporate the solid angle subtended - // each texel in the filter kernel in the filtering. - //========================================================================================================== - void InitiateFiltering(float a_BaseFilterAngle, float a_InitialMipAngle, float a_MipAnglePerLevelScale, - int32 a_FilterType, int32 a_FixupType, int32 a_FixupWidth, bool a_bUseSolidAngle, - float a_GlossScale, float a_GlossBias, int32 a_SampleCountGGX); - - //========================================================================================================== - // void WriteMipLevelIntoAlpha(void) - // - // Encodes the miplevel in the alpha channel of the output cubemap. - // The miplevel is encoded as (miplevel * 16.0f / 255.0f) so that the miplevel has an exact encoding in an - // 8-bit or 16-bit UNORM representation. - // - //========================================================================================================== - void WriteMipLevelIntoAlpha(void); - - - //========================================================================================================== - // Horizontally flips all the faces in the input cubemap - // - //========================================================================================================== - void FlipInputCubemapFaces(void); - - //========================================================================================================== - // Horizontally flips all the faces in the output cubemap - // - //========================================================================================================== - void FlipOutputCubemapFaces(void); - - - //========================================================================================================== - // Allows for in-place color channel swapping of the input cubemap. This routine can be useful for - // converting RGBA format data to BGRA format data. - // - // a_Channel0Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel1Src [in] Index of the color channel used as the source for the new channel 1 - // a_Channel2Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel3Src [in] Index of the color channel used as the source for the new channel 1 - // - //========================================================================================================== - void ChannelSwapInputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, int32 a_Channel2Src, int32 a_Channel3Src); - - - //========================================================================================================== - // Allows for in-place color channel swapping of the output cubemap. This routine can be useful for - // converting RGBA format data to BGRA format data. - // - // a_Channel0Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel1Src [in] Index of the color channel used as the source for the new channel 1 - // a_Channel2Src [in] Index of the color channel used as the source for the new channel 0 - // a_Channel3Src [in] Index of the color channel used as the source for the new channel 1 - //========================================================================================================== - void ChannelSwapOutputFaceData(int32 a_Channel0Src, int32 a_Channel1Src, int32 a_Channel2Src, int32 a_Channel3Src); - - - //========================================================================================================== - // Resets the current cubemap processor, and deallocates the input and output cubemaps. - // - // This function is automatically called by destructor. - //========================================================================================================== - void Clear(void); - - - //========================================================================================================== - // Terminates any active filtering threads. This stops the filtering of the current cubemap. - // - //========================================================================================================== - void TerminateActiveThreads(void); - - - //========================================================================================================== - // Gets the current filtering progress string - // - //========================================================================================================== - WCHAR *GetFilterProgressString(void); - - - //========================================================================================================== - // Checks to see if either of the filtering threads is active - // - //========================================================================================================== - bool IsFilterThreadActive(uint32 a_ThreadIdx); - - //========================================================================================================== - // Gets the current status of the cubemap processing threads. The possible return values and their - // associated meanings are: - // - // CP_STATUS_READY: The cubemap processor is currently ready to change settings, and to load a - // new input cubemap. - // CP_STATUS_PROCESSING: The cubemap processor is currently filtering a cubemap - // CP_STATUS_FILTER_TERMINATED: The cubemap processor was terminated before the filtering was completed. - // CP_STATUS_FILTER_COMPLETED: The cubemap processor fully completed filtering the cubemap. - // - //========================================================================================================== - int32 GetStatus(void); - - - //========================================================================================================== - // This signifies to the cubemap processor that you have acknowledged a - // CP_STATUS_FILTER_TERMINATED or CP_STATUS_FILTER_COMPLETED status code, and would like to - // reset the cubemap processor to CP_STATUS_READY. - //========================================================================================================== - void RefreshStatus(void); - - AZStd::atomic_bool m_shutdownWorkerThreadSignal; ///< Signals the worker threads to stop. - }; - -} // namespace ImageProcessing diff --git a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.cpp b/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.cpp deleted file mode 100644 index 62daa2b4d7..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.cpp +++ /dev/null @@ -1,695 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -//-------------------------------------------------------------------------------------- -//CImageSurface -// Class for storing, manipulating, and copying image data to and from D3D Surfaces -// -//-------------------------------------------------------------------------------------- -// (C) 2005 ATI Research, Inc., All rights reserved. -//-------------------------------------------------------------------------------------- -// modifications by Crytek GmbH -// modifications by Amazon - -#include - -#include "CImageSurface.h" - - -namespace ImageProcessing -{ - //-------------------------------------------------------------------------------------- - // convert D3D 16 bit float to standard 32 bit float - // Format: - // - // 1 sign bit in MSB, (s) - // 5 bits of biased exponent, (e) - // 10 bits of fraction, (f), with an additional hidden bit - // A float16 value, v, made from the format above takes the following meaning: - // - // (a) if e == 31 and f != 0, then v is NaN regardless of s - // (b) if e == 31 and f == 0, then v = (-1)^s * infinity (signed infinity) - // (c) if 0 < e < 31, then v = (-1)^s * 2^(e-15) * (1.f) - // (d) if e == 0 and f != 0, then v = (-1)^s * 2^(e-14) * (0.f) (denormalized numbers) - // (e) if e == 0 and f == 0, then v = (-1)^s *0 (signed zero) - // - //-------------------------------------------------------------------------------------- - float CPf16Tof32(uint16 aVal) - { - uint32 signVal = (aVal >> 15); //sign bit in MSB - uint32 exponent = ((aVal >> 10) & 0x01f); //next 5 bits after signbit - uint32 mantissa = (aVal & 0x03ff); //lower 10 bits - uint32 rawFloat32Data; //raw binary float data - - //convert s10e5 5-bit exponent to IEEE754 s23e8 8-bit exponent - if (exponent == 31) - { // infinity or Nan depending on mantissa - exponent = 255; - } - else if (exponent == 0) - { // denormalized floats mantissa is treated as = 0.f - exponent = 0; - } - else - { //change 15base exponent to 127base exponent - //normalized floats mantissa is treated as = 1.f - exponent += (127 - 15); - } - - //convert 10-bit mantissa to 23-bit mantissa - mantissa <<= (23 - 10); - - //assemble s23e8 number using logical operations - rawFloat32Data = (signVal << 31) | (exponent << 23) | mantissa; - - //treat raw data as a 32 bit float - return *((float *)&rawFloat32Data); - } - - - //-------------------------------------------------------------------------------------- - // convert standard 32 bit float to D3D 16 bit float - // - // 16-bit float format: - // - // 1 sign bit in MSB, (s) - // 5 bits of biased exponent, (e) - // 10 bits of fraction, (f), with an additional hidden bit - // A float16 value, v, made from the format above takes the following meaning: - // - // (a) if e == 31 and f != 0, then v is NaN regardless of s - // (b) if e == 31 and f == 0, then v = (-1)s*infinity (signed infinity) - // (c) if 0 < e < 31, then v = (-1)s*2(e-15)*(1.f) - // (d) if e == 0 and f != 0, then v = (-1)s*2(e-14)*(0.f) (denormalized numbers) - // (e) if e == 0 and f == 0, then v = (-1)s*0 (signed zero) - //-------------------------------------------------------------------------------------- - uint16 CPf32Tof16(float aVal) - { - uint32 rawf32Data = *((uint32 *)&aVal); //raw binary float data - - uint32 signVal = (rawf32Data >> 31); //sign bit in MSB - uint32 exponent = ((rawf32Data >> 23) & 0xff); //next 8 bits after signbit - uint32 mantissa = (rawf32Data & 0x7fffff); //mantissa = lower 23 bits - - uint16 rawf16Data; - - //convert IEEE754 s23e8 8-bit exponent to s10e5 5-bit exponent - if (exponent == 255) - {//special case 32 bit float is inf or NaN, use mantissa as is - exponent = 31; - } - else if (exponent < ((127 - 15) - 10)) - {//special case, if 32-bit float exponent is out of 16-bit float range, then set 16-bit float to 0 - exponent = 0; - mantissa = 0; - } - else if (exponent >= (127 + (31 - 15))) - { // max 15based exponent for s10e5 is 31 - // force s10e5 number to represent infinity by setting mantissa to 0 - // and exponent to 31 - exponent = 31; - mantissa = 0; - } - else if (exponent <= (127 - 15)) - { //convert normalized s23e8 float to denormalized s10e5 float - - //add implicit 1.0 to mantissa to convert from 1.f to use as a 0.f mantissa - mantissa |= (1 << 23); - - //shift over mantissa number of bits equal to exponent underflow - mantissa = mantissa >> (1 + ((127 - 15) - exponent)); - - //zero exponent to treat value as a denormalized number - exponent = 0; - } - else - { //change 127base exponent to 15base exponent - // no underflow or overflow of exponent - //normalized floats mantissa is treated as= 1.f, so - // no denormalization or exponent derived shifts to the mantissa - exponent -= (127 - 15); - } - - //convert 23-bit mantissa to 10-bit mantissa - mantissa >>= (23 - 10); - - //assemble s10e5 number using logical operations - rawf16Data = (signVal << 15) | (exponent << 10) | mantissa; - - //return re-assembled raw data as a 32 bit float - return rawf16Data; - } - - - //-------------------------------------------------------------------------------------- - //size of data types in bytes - //-------------------------------------------------------------------------------------- - int32 CPTypeSizeOf(int32 a_Type) - { - switch (a_Type) - { - case CP_VAL_UNORM8: - case CP_VAL_UNORM8_BGRA: - return 1; - break; - case CP_VAL_UNORM16: - return 2; - break; - case CP_VAL_FLOAT16: - return 2; - break; - case CP_VAL_FLOAT32: - return 4; - break; - default: - return 1; - break; - } - } - - - //-------------------------------------------------------------------------------------- - //get value of data pointed to by a_Ptr given type information - //-------------------------------------------------------------------------------------- - CP_ITYPE CPTypeGetVal(int32 a_Type, void *a_Ptr) - { - switch (a_Type) - { - case CP_VAL_UNORM8: - case CP_VAL_UNORM8_BGRA: - return (1.0f / 255.0f) * *((uint8 *)a_Ptr); - break; - case CP_VAL_UNORM16: - return (1.0f / 65535.0f) * *((uint16 *)a_Ptr); - break; - case CP_VAL_FLOAT16: - return CPf16Tof32(*((uint16 *)a_Ptr)); - break; - case CP_VAL_FLOAT32: - return *((float *)a_Ptr); - break; - default: - return 0; - break; - } - } - - - //-------------------------------------------------------------------------------------- - //Given a CP_ITYPE value as input, convert it to the given type specified by a_Type - // and write the value to a_Ptr - //-------------------------------------------------------------------------------------- - void CPTypeSetVal(CP_ITYPE a_Val, int32 a_Type, void *a_Ptr) - { - CP_ITYPE clampVal; //clamp value to 0-1 range to output UNORM types - - switch (a_Type) - { - case CP_VAL_UNORM8: - case CP_VAL_UNORM8_BGRA: - clampVal = VM_MIN(VM_MAX(a_Val, 0.0f), 1.0f); - *((uint8 *)a_Ptr) = (uint8)(clampVal * 255.0f); - break; - case CP_VAL_UNORM16: - clampVal = VM_MIN(VM_MAX(a_Val, 0.0f), 1.0f); - *((uint16 *)a_Ptr) = (uint16)(clampVal * 65535.0f); - break; - case CP_VAL_FLOAT16: - *((uint16 *)a_Ptr) = CPf32Tof16(a_Val); - break; - case CP_VAL_FLOAT32: - *((float *)a_Ptr) = a_Val; - break; - default: - break; - } - } - - - //-------------------------------------------------------------------------------------- - //Error handling for imagesurface class - // Pop up dialog box, and terminate application - //-------------------------------------------------------------------------------------- - void CImageSurface::FatalError([[maybe_unused]] const WCHAR *a_Msg) - { - AZ_Error("Image Processing", false, "CImageSurface Error: %s", a_Msg); - } - - - //-------------------------------------------------------------------------------------- - // Image surface - //-------------------------------------------------------------------------------------- - CImageSurface::CImageSurface(void) - { - m_Width = 0; //cubemap face width - m_Height = 0; //cubemap face height - m_NumChannels = 0; //number of channels - m_ImgData = NULL; - - } - - - //-------------------------------------------------------------------------------------- - // Clear - //-------------------------------------------------------------------------------------- - void CImageSurface::Clear(void) - { - m_Width = 0; //cubemap face width - m_Height = 0; //cubemap face height - m_NumChannels = 0; //number of channels - SAFE_DELETE_ARRAY(m_ImgData); //safe delete old image data - } - - - //-------------------------------------------------------------------------------------- - // Initialize surface and associated memory - //-------------------------------------------------------------------------------------- - void CImageSurface::Init(int32 a_Width, int32 a_Height, int32 a_NumChannels) - { - m_Width = a_Width; //cubemap face width - m_Height = a_Height; //cubemap face height - m_NumChannels = a_NumChannels; //number of channels - - SAFE_DELETE_ARRAY(m_ImgData); //safe delete old image data - - m_ImgData = new(std::nothrow) CP_ITYPE[m_Width * m_Height * m_NumChannels]; //assume tight data packing - if (!m_ImgData) - { - FatalError(L"Unable to allocate data for image in CImageSurface::Init."); - } - } - - - //-------------------------------------------------------------------------------------- - //copy and convert data from external buffer into this surface - // - // note that srcPitch == the source pitch in bytes - //-------------------------------------------------------------------------------------- - void CImageSurface::SetImageData(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr) - { - int32 i, j, k; - - CP_ITYPE *dstDataWalk = m_ImgData; - uint8 *srcDataWalk = (uint8 *)a_SrcDataPtr; - - int32 srcValueSize = CPTypeSizeOf(a_SrcType); - int32 srcTexelStep = srcValueSize * a_SrcNumChannels; - int32 numChannelsSet = VM_MIN(a_SrcNumChannels, m_NumChannels); - int32 srcChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - srcDataWalk = ((uint8 *)a_SrcDataPtr + (j * a_SrcPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - srcChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - if (a_SrcType == CP_VAL_UNORM8_BGRA) //swap channels 0, and 2 if in BGRA format - { - switch (k) - { - case 0: - *(dstDataWalk + 2) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - break; - case 2: - *(dstDataWalk + 0) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - break; - default: - *(dstDataWalk + k) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - break; - } - } - else - { - *(dstDataWalk + k) = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - } - - srcChannelSelect += srcValueSize; - } - - dstDataWalk += m_NumChannels; - srcDataWalk += srcTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - // Copy and convert data from external buffer into this surface set image data degamma - // and scale - // - //-------------------------------------------------------------------------------------- - void CImageSurface::SetImageDataClampDegammaScale(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, - void *a_SrcDataPtr, float a_MaxClamp, float a_Gamma, float a_Scale) - { - int32 i, j, k; - - CP_ITYPE *dstDataWalk = m_ImgData; - uint8 *srcDataWalk = (uint8 *)a_SrcDataPtr; - - int32 srcValueSize = CPTypeSizeOf(a_SrcType); - int32 srcTexelStep = srcValueSize * a_SrcNumChannels; - int32 numChannelsSet = VM_MIN(a_SrcNumChannels, m_NumChannels); - int32 srcChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - srcDataWalk = ((uint8 *)a_SrcDataPtr + (j * a_SrcPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - srcChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - CP_ITYPE texelVal; - - //get texel value from external buffer - texelVal = CPTypeGetVal(a_SrcType, srcDataWalk + srcChannelSelect); - - //clamp texelVal using max value only - // (using texelVal as the min clamping arguement means no minimum clamping) - VM_CLAMP(texelVal, texelVal, texelVal, a_MaxClamp); - - if (k < 3) //only apply gamma and scale to RGB channels - { - //degamma texel val, by raising to the power gamma - texelVal = pow(texelVal, a_Gamma); - - //scale texel val in linear space (after degamma) - texelVal *= a_Scale; - } - - //write data - if ((a_SrcType == CP_VAL_UNORM8_BGRA) && (k == 0)) - { - *(dstDataWalk + 2) = texelVal; - } - else if ((a_SrcType == CP_VAL_UNORM8_BGRA) && (k == 2)) - { - *(dstDataWalk + 0) = texelVal; - } - else - { - *(dstDataWalk + k) = texelVal; - } - - srcChannelSelect += srcValueSize; - } - - dstDataWalk += m_NumChannels; - srcDataWalk += srcTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - //copy data from this image surface into an external buffer - // - //-------------------------------------------------------------------------------------- - void CImageSurface::GetImageData(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr) - { - int32 i, j, k; - - CP_ITYPE *srcDataWalk = m_ImgData; - uint8 *dstDataWalk = (uint8 *)a_DstDataPtr; - - int32 dstValueSize = CPTypeSizeOf(a_DstType); - int32 dstTexelStep = dstValueSize * a_DstNumChannels; - - int32 numChannelsSet = VM_MIN(a_DstNumChannels, m_NumChannels); - int32 dstChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - dstDataWalk = ((uint8 *)a_DstDataPtr + (j * a_DstPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - dstChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - //write data - if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 0)) - { - CPTypeSetVal(*(srcDataWalk + 2), a_DstType, dstDataWalk + dstChannelSelect); - } - else if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 2)) - { - CPTypeSetVal(*(srcDataWalk + 0), a_DstType, dstDataWalk + dstChannelSelect); - } - else - { - CPTypeSetVal(*(srcDataWalk + k), a_DstType, dstDataWalk + dstChannelSelect); - } - - dstChannelSelect += dstValueSize; - } - - srcDataWalk += m_NumChannels; - dstDataWalk += dstTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - // Scale and then apply gamma to image data, then copy image data into an external buffer - // note: only apply scale and gamma to RGB channels (e.g. first 3 channels) - // - //-------------------------------------------------------------------------------------- - void CImageSurface::GetImageDataScaleGamma(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, - void *a_DstDataPtr, float a_Scale, float a_Gamma) - { - int32 i, j, k; - - CP_ITYPE *srcDataWalk = m_ImgData; - uint8 *dstDataWalk = (uint8 *)a_DstDataPtr; - - int32 dstValueSize = CPTypeSizeOf(a_DstType); - int32 dstTexelStep = dstValueSize * a_DstNumChannels; - - int32 numChannelsSet = VM_MIN(a_DstNumChannels, m_NumChannels); - int32 dstChannelSelect; - - //loop over rows - for (j = 0; j < m_Height; j++) - { - //pointer arithmetic to offset pointer by pitch in bytes - dstDataWalk = ((uint8 *)a_DstDataPtr + (j * a_DstPitch)); - - //loop over texels within row - for (i = 0; i < m_Width; i++) - { - dstChannelSelect = 0; - - //loop over channels within texel - for (k = 0; k < numChannelsSet; k++) - { - CP_ITYPE texelVal; - - texelVal = *(srcDataWalk + k); - - if (k < 3) //only apply gamma and scale to RGB channels - { - //scale texel val - texelVal *= a_Scale; - - //apply gamma to texel val by raising the texelVal to the power of (1/gamma) - texelVal = pow(texelVal, 1.0f / a_Gamma); - } - - //write out texture value - if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 0)) - { - CPTypeSetVal(texelVal, a_DstType, dstDataWalk + (dstValueSize * 2)); - } - else if ((a_DstType == CP_VAL_UNORM8_BGRA) && (k == 2)) - { - CPTypeSetVal(texelVal, a_DstType, dstDataWalk + (dstValueSize * 0)); - } - else - { - CPTypeSetVal(texelVal, a_DstType, dstDataWalk + dstChannelSelect); - } - - - dstChannelSelect += dstValueSize; - } - - srcDataWalk += m_NumChannels; - dstDataWalk += dstTexelStep; - } - } - } - - - //-------------------------------------------------------------------------------------- - //Set image channel a_ChannelIdx to a_ClearColor for all pixels. - // - //-------------------------------------------------------------------------------------- - void CImageSurface::ClearChannelConst(int32 a_ChannelIdx, CP_ITYPE a_ClearColor) - { - int32 u, v; - CP_ITYPE *texelPtr; - - //if channel does not exist, do not attempt to clear the channel - if (a_ChannelIdx > (m_NumChannels - 1)) - { - return; - } - - for (v = 0; v < m_Height; v++) - { - for (u = 0; u < m_Width; u++) - { - texelPtr = GetSurfaceTexelPtr(u, v); - - *(texelPtr + a_ChannelIdx) = a_ClearColor; - } - } - } - - - //-------------------------------------------------------------------------------------- - //Gets texel ptr in a surface given u and v coordinates, - // - //-------------------------------------------------------------------------------------- - CP_ITYPE *CImageSurface::GetSurfaceTexelPtr(int32 u, int32 v) - { - return(m_ImgData + (((m_Width * v) + u) * m_NumChannels)); - } - - - //-------------------------------------------------------------------------------------- - //flips surface image in place horizontally - // - //-------------------------------------------------------------------------------------- - void CImageSurface::InPlaceHorizonalFlip(void) - { - int32 u, v, k; - CP_ITYPE *texelPtrTop, *texelPtrBottom; - - //iterate over V - for (v = 0; v < (m_Height / 2); v++) - { - for (u = 0; u < m_Height; u++) - { - texelPtrTop = GetSurfaceTexelPtr(u, v); - texelPtrBottom = GetSurfaceTexelPtr(u, (m_Height - 1) - v); - - //iterate over channels - for (k = 0; k < m_NumChannels; k++) - { - CP_ITYPE tmpTexelVal; - - tmpTexelVal = *(texelPtrTop + k); - *(texelPtrTop + k) = *(texelPtrBottom + k); - *(texelPtrBottom + k) = tmpTexelVal; - - } - } - } - } - - - //-------------------------------------------------------------------------------------- - //flips surface image in place vertically - // - //-------------------------------------------------------------------------------------- - void CImageSurface::InPlaceVerticalFlip(void) - { - int32 u, v, k; - CP_ITYPE *texelPtrLeft, *texelPtrRight; - - for (u = 0; u < (m_Width / 2); u++) - { - for (v = 0; v < m_Height; v++) - { - texelPtrLeft = GetSurfaceTexelPtr(u, v); - texelPtrRight = GetSurfaceTexelPtr((m_Width - 1) - u, v); - - //iterate over channels - for (k = 0; k < m_NumChannels; k++) - { - CP_ITYPE tmpTexelVal; - - tmpTexelVal = *(texelPtrLeft + k); - *(texelPtrLeft + k) = *(texelPtrRight + k); - *(texelPtrRight + k) = tmpTexelVal; - } - } - } - } - - - //-------------------------------------------------------------------------------------- - //flip image around line defined by u = v (effectively swaps the u and v axises) - //-------------------------------------------------------------------------------------- - void CImageSurface::InPlaceDiagonalUVFlip(void) - { - int32 u, v, k; - CP_ITYPE *texelPtrLeft, *texelPtrRight; - - if (m_Width != m_Height) - { //only flip image if square - return; - } - - for (v = 0; v < m_Height; v++) - { - for (u = 0; u < v; u++) //only iterate over lower left triangle - { - texelPtrLeft = GetSurfaceTexelPtr(u, v); - texelPtrRight = GetSurfaceTexelPtr(v, u); - - //iterate over channels - for (k = 0; k < m_NumChannels; k++) - { - CP_ITYPE tmpTexelVal; - - tmpTexelVal = *(texelPtrLeft + k); - *(texelPtrLeft + k) = *(texelPtrRight + k); - *(texelPtrRight + k) = tmpTexelVal; - } - } - } - } - - //-------------------------------------------------------------------------------------- - // destructor, free all memory used - //-------------------------------------------------------------------------------------- - CImageSurface::~CImageSurface() - { - SAFE_DELETE_ARRAY(m_ImgData); - } -} // namespace ImageProcessing - - - diff --git a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.h b/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.h deleted file mode 100644 index abd8cc5b50..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/CImageSurface.h +++ /dev/null @@ -1,94 +0,0 @@ -//-------------------------------------------------------------------------------------- -//CImageSurface -// Class for storing, manipulating, and copying image data to and from D3D Surfaces -// -//-------------------------------------------------------------------------------------- -// (C) 2005 ATI Research, Inc., All rights reserved. -//-------------------------------------------------------------------------------------- -// modifications by Crytek GmbH -// modifications by Amazon - -#pragma once - -#include -#include - -#include "VectorMacros.h" - - -#ifndef WCHAR -#define WCHAR wchar_t -#endif //WCHAR - -#ifndef SAFE_DELETE -#define SAFE_DELETE(p) { if(p) { delete (p); (p)=NULL; } } -#endif - -#ifndef SAFE_DELETE_ARRAY -#define SAFE_DELETE_ARRAY(p) { if(p) { delete[] (p); (p)=NULL; } } -#endif - - -//Data types processed by cube map processor -// note that UNORM data types use the full range -// of the unsigned integer to represent the range [0, 1] inclusive -// the float16 datatype is stored as D3Ds S10E5 representation -#define CP_VAL_UNORM8 0 -#define CP_VAL_UNORM8_BGRA 1 -#define CP_VAL_UNORM16 10 -#define CP_VAL_FLOAT16 20 -#define CP_VAL_FLOAT32 30 - - -// Type of data used internally by CSurfaceImage -#define CP_ITYPE float - -namespace ImageProcessing -{ - //2D images used to store cube faces for processing, note that this class is - // meant to facilitate the copying of data to and from D3D surfaces hence the name ImageSurface - class CImageSurface - { - public: - int32 m_Width; //image width - int32 m_Height; //image height - int32 m_NumChannels; //number of channels - CP_ITYPE *m_ImgData; //cubemap image data - - private: - //fatal error - void FatalError(const WCHAR *a_Msg); - - public: - CImageSurface(void); - void Clear(void); - void Init(int32 a_Width, int32 a_Height, int32 a_NumChannels); - - //copy data from external buffer into this CImageSurface - void SetImageData(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr); - - // copy image data from an external buffer and scale and degamma the data - void SetImageDataClampDegammaScale(int32 a_SrcType, int32 a_SrcNumChannels, int32 a_SrcPitch, void *a_SrcDataPtr, - float a_MaxClamp, float a_Degamma, float a_Scale); - - //copy data from this CImageSurface into an external buffer - void GetImageData(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr); - - //copy image data from an external buffer and scale and gamma the data - void GetImageDataScaleGamma(int32 a_DstType, int32 a_DstNumChannels, int32 a_DstPitch, void *a_DstDataPtr, - float a_Scale, float a_Gamma); - - //clear one of the channels in the CSurfaceImage to a particular color - void ClearChannelConst(int32 a_ChannelIdx, CP_ITYPE a_ClearColor); - - //various image operations that can be performed on the CImageSurface - void InPlaceVerticalFlip(void); - void InPlaceHorizonalFlip(void); - void InPlaceDiagonalUVFlip(void); - - CP_ITYPE *GetSurfaceTexelPtr(int32 a_U, int32 a_V); - ~CImageSurface(); - }; - -} // namespace ImageProcessing - diff --git a/Gems/ImageProcessing/External/CubeMapGen/ReadMe_CubeGen.doc b/Gems/ImageProcessing/External/CubeMapGen/ReadMe_CubeGen.doc deleted file mode 100644 index 56ad1c16b9..0000000000 Binary files a/Gems/ImageProcessing/External/CubeMapGen/ReadMe_CubeGen.doc and /dev/null differ diff --git a/Gems/ImageProcessing/External/CubeMapGen/VectorMacros.h b/Gems/ImageProcessing/External/CubeMapGen/VectorMacros.h deleted file mode 100644 index b752d0b3c1..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/VectorMacros.h +++ /dev/null @@ -1,176 +0,0 @@ -/* -* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or -* its licensors. -* -* For complete copyright and license terms please see the LICENSE at the root of this -* distribution (the "License"). All use of this software is governed by the License, -* or, if provided, by the license below or the license accompanying this file. Do not -* remove or modify any license notices. This file is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* -*/ - -#pragma once - -//-------------------------------------------------------------------------------------- -// VectorMacros.h -// -// Fast operations on vectors, stored as arrays of floats -// -//-------------------------------------------------------------------------------------- -// (C) 2001-2005 ATI Research, Inc. All rights reserved. -//-------------------------------------------------------------------------------------- -// modifications by Crytek GmbH - -//disable warning about doubles being converted down to float -#pragma warning (disable : 4244 ) - -#define VM_LARGE_FLOAT 3.7e37f - -#define VM_MIN(a, b) (((a) < (b)) ? (a) : (b)) -#define VM_MAX(a, b) (((a) > (b)) ? (a) : (b)) - -//clamping macros -#define VM_CLAMP(d, s, mn, mx){(d) = ((s)<(mx))?( ((s)>(mn))?(s):(mn) ):(mx); } - -#define VM_CLAMP2_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx);} -#define VM_CLAMP2(d, s, mn, mx) VM_CLAMP2_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx)) - -#define VM_CLAMP3_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx); VM_CLAMP(d[2], s[2], mn, mx);} -#define VM_CLAMP3(d, s, mn, mx) VM_CLAMP3_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx)) - -#define VM_CLAMP4_UNTYPED(d, s, mn, mx) {VM_CLAMP(d[0], s[0], mn, mx); VM_CLAMP(d[1], s[1], mn, mx); VM_CLAMP(d[2], s[2], mn, mx); VM_CLAMP(d[3], s[3], mn, mx);} -#define VM_CLAMP4(d, s, mn, mx) VM_CLAMP4_UNTYPED(((float *)(d)), ((float *)(s)), (float)(mn), (float)(mx)) - - -//set vectors -#define VM_SET2_UNTYPED(d, f) { d[0]=f; d[1]=f;} -#define VM_SET2(d, f) VM_SET2_UNTYPED(((float *)(d)), ((float)(f))) - -#define VM_SET3_UNTYPED(d, f) { d[0]=f; d[1]=f; d[2]=f; } -#define VM_SET3(d, f) VM_SET3_UNTYPED(((float *)(d)), ((float)(f))) - -#define VM_SET4_UNTYPED(d, f) { d[0]=f; d[1]=f; d[2]=f; d[3]=f; } -#define VM_SET4(d, f) VM_SET4_UNTYPED(((float *)(d)), ((float)(f))) - - -//copy vectors -#define VM_COPY2_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1];} -#define VM_COPY2(d, s) VM_COPY2_UNTYPED(((float *)(d)), ((float *)(s))) - -#define VM_COPY3_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; } -#define VM_COPY3(d, s) VM_COPY3_UNTYPED(((float *)(d)), ((float *)(s))) - -#define VM_COPY4_UNTYPED(d, s) { d[0]=s[0]; d[1]=s[1]; d[2]=s[2]; d[3]=s[3]; } -#define VM_COPY4(d, s) VM_COPY4_UNTYPED(((float *)(d)), ((float *)(s))) - - -//add two vectors -#define VM_ADD2_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; } -#define VM_ADD2(d, sa, sb) VM_ADD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_ADD3_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; d[2]=sa[2]+sb[2]; } -#define VM_ADD3(d, sa, sb) VM_ADD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_ADD4_UNTYPED(d, sa, sb) { d[0]=sa[0]+sb[0]; d[1]=sa[1]+sb[1]; d[2]=sa[2]+sb[2]; d[3]=sa[3]+sb[3]; } -#define VM_ADD4(d, sa, sb) VM_ADD4_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - - -//subtract two vectors -#define VM_SUB2_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; } -#define VM_SUB2(d, sa, sb) VM_SUB2_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_SUB3_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; d[2]=sa[2]-sb[2]; } -#define VM_SUB3(d, sa, sb) VM_SUB3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - -#define VM_SUB4_UNTYPED(d, sa, sb) { d[0]=sa[0]-sb[0]; d[1]=sa[1]-sb[1]; d[2]=sa[2]-sb[2]; d[3]=sa[3]-sb[3]; } -#define VM_SUB4(d, sa, sb) VM_SUB4_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - - -//multiply all elements of a vector by a scalar -#define VM_SCALE2_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; } -#define VM_SCALE2(d, s, f) VM_SCALE2_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) ) - -#define VM_SCALE3_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; d[2]=s[2]*f; } -#define VM_SCALE3(d, s, f) VM_SCALE3_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) ) - -#define VM_SCALE4_UNTYPED(d, s, f) {d[0]=s[0]*f; d[1]=s[1]*f; d[2]=s[2]*f; d[3]=s[3]*f; } -#define VM_SCALE4(d, s, f) VM_SCALE4_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f)) ) - - -//add a scalar to all elements of a vector -#define VM_BIAS2_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; } -#define VM_BIAS2(d, s, f) VM_BIAS2_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f))) - -#define VM_BIAS3_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; d[2]=s[2]+f; } -#define VM_BIAS3(d, s, f) VM_BIAS3_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f))) - -#define VM_BIAS4_UNTYPED(d, s, f) { d[0]=s[0]+f; d[1]=s[1]+f; d[2]=s[2]+f; d[3]=s[3]+f; } -#define VM_BIAS4(d, s, f) VM_BIAS4_UNTYPED(((float *)(d)), ((float *)(s)), ((float)(f))) - - -//3D cross product -#define VM_XPROD3_UNTYPED(d, sa, sb) { d[0]=sa[1]*sb[2]-sa[2]*sb[1]; d[1]=sa[2]*sb[0]-sa[0]*sb[2]; d[2]=sa[0]*sb[1]-sa[1]*sb[0]; } -#define VM_XPROD3(d, sa, sb) VM_XPROD3_UNTYPED(((float *)(d)), ((float *)(sa)), ((float *)(sb))) - - -//dot products -#define VM_DOTPROD2_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]) -#define VM_DOTPROD2(sa, sb) VM_DOTPROD2_UNTYPED(((float *)(sa)), ((float *)(sb))) - -#define VM_DOTPROD3_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]+ sa[2]*sb[2]) -#define VM_DOTPROD3(sa, sb) VM_DOTPROD3_UNTYPED(((float *)(sa)), ((float *)(sb))) - -#define VM_DOTPROD4_UNTYPED(sa, sb) (sa[0]*sb[0]+ sa[1]*sb[1]+ sa[2]*sb[2] + sa[3]*sb[3]) -#define VM_DOTPROD4(sa, sb) VM_DOTPROD4_UNTYPED(((float *)(sa)), ((float *)(sb))) - - -//dp3 then and add 4th component from second arguement -#define VM_DOTPROD3ADD_UNTYPED(pt, pl) (pt[0]*pl[0]+ pt[1]*pl[1]+ pt[2]*pl[2] + pl[3]) -#define VM_DOTPROD3ADD(pt, pl) VM_DOTPROD3ADD_UNTYPED(((float *)(pt)), ((float *)(pl))) - - -//normalize vectors -#define VM_NORM3_UNTYPED(d, s) {double __idsq; __idsq=1.0/sqrt(VM_DOTPROD3_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; } -#define VM_NORM3_UNTYPED_F32(d, s) {float __idsq; __idsq=1.0/sqrt(VM_DOTPROD3_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; } -#define VM_NORM3(d, s) VM_NORM3_UNTYPED_F32(((float *)(d)), ((float *)(s))) - -#define VM_NORM4_UNTYPED(d, s) {double __idsq; __idsq=1.0/sqrt(VM_DOTPROD4_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; d[3]=s[3]*__idsq; } -#define VM_NORM4_UNTYPED_F32(d, s) {float __idsq; __idsq=1.0/sqrt(VM_DOTPROD4_UNTYPED(s,s)); d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; d[3]=s[3]*__idsq; } -#define VM_NORM4(d, s) VM_NORM4_UNTYPED_F32(((float *)(d)), ((float *)(s))) - - -//safely normalize vectors, deal with 0 length case -#define VM_SAFENORM3_UNTYPED(d, s) {float __idsq, __dp; __dp = VM_DOTPROD3_UNTYPED(s,s); \ - __idsq=( (__dp > 0.0f)?(1.0/sqrt(__dp)):0.0f ) ; d[0]=s[0]*__idsq; d[1]=s[1]*__idsq; d[2]=s[2]*__idsq; } -#define VM_SAFENORM3(d, s) VM_NORM3_UNTYPED_F32(((float *)(d)), ((float *)(s))) - - - -//absolute value -#define VM_ABS2_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); } -#define VM_ABS2(d, s) VM_ABS2_UNTYPED(((float *)(d)), ((float *)(s)) ) - -#define VM_ABS3_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); d[2] = fabs(s[2]); } -#define VM_ABS3(d, s) VM_ABS3_UNTYPED(((float *)(d)), ((float *)(s)) ) - -#define VM_ABS4_UNTYPED(d, s) { d[0] = fabs(s[0]); d[1] = fabs(s[1]); d[2] = fabs(s[2]); d[3] = fabs(s[3]); } -#define VM_ABS4(d, s) VM_ABS4_UNTYPED(((float *)(d)), ((float *)(s)) ) - - -//projection of a vector onto another vector (assumes vector v is normalized) -// computes d, which is the parallel component of s onto vector v -#define VM_PROJ3_UNTYPED(d, s, v) { double __dp; __dp = VM_DOTPROD3_UNTYPED(s, v); VM_SCALE3_UNTYPED(d, s, __dp); } -#define VM_PROJ3(d, s, v) VM_PROJ3_UNTYPED(((float *)(d)), ((float *)(s)), ((float *)(v)) ) -#define VM_PROJ3_F64(d, s, v) VM_PROJ3_UNTYPED(((double *)(d)), ((double *)(s)), ((double *)(v)) ) - - -//compute component of a vector perpendicular to another vector -// d is perpendicular component of s onto vector v -// this macro first computes the parallel projection, then subtracts off from the original vector -// to obtain the perpendicular component -#define VM_PERP3_UNTYPED(d, s, v) {double __proj[3]; VM_PROJ3_UNTYPED(__proj, s, v); VM_SUB3_UNTYPED(d, s, __proj); } -#define VM_PERP3(d, s, v) VM_PERP3_UNTYPED(((float *)(d)), ((float *)(s)), ((float *)(v)) ) -#define VM_PERP3_F64(d, s, v) VM_PERP3_UNTYPED(((double *)(d)), ((double *)(s)), ((double *)(v)) ) - - diff --git a/Gems/ImageProcessing/External/CubeMapGen/license.txt b/Gems/ImageProcessing/External/CubeMapGen/license.txt deleted file mode 100644 index aa663d5ba7..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/license.txt +++ /dev/null @@ -1,19 +0,0 @@ -Modified BSD License (2009): - -Copyright (c) 2011, Advanced Micro Devices, Inc. -All rights reserved. - -Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: - -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. - -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. - -Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - -If you use the software (in whole or in part), you shall adhere to all applicable U.S., European, and other export laws, including but not limited to the U.S. Export Administration Regulations (“EAR”), (15 C.F.R. Sections 730 through 774), and E.U. Council Regulation (EC) No 1334/2000 of 22 June 2000. Further, pursuant to Section 740.6 of the EAR, you hereby certify that, except pursuant to a license granted by the United States Department of Commerce Bureau of Industry and Security or as otherwise permitted pursuant to a License Exception under the U.S. Export Administration Regulations ("EAR"), you will not (1) export, re-export or release to a national of a country in Country Groups D:1, E:1 or E:2 any restricted technology, software, or source code you receive hereunder, or (2) export to Country Groups D:1, E:1 or E:2 the direct product of such technology or software, if such foreign produced direct product is subject to national security controls as identified on the Commerce Control List (currently found in Supplement 1 to Part 774 of EAR). For the most current Country Group listings, or for additional information about the EAR or your obligations under those regulations, please refer to the U.S. Bureau of Industry and Security’s website at http://www.bis.doc.gov/. - - - diff --git a/Gems/ImageProcessing/External/CubeMapGen/readme.txt b/Gems/ImageProcessing/External/CubeMapGen/readme.txt deleted file mode 100644 index 8026674cc4..0000000000 --- a/Gems/ImageProcessing/External/CubeMapGen/readme.txt +++ /dev/null @@ -1,5 +0,0 @@ -Cropped version of CubeMapGen-1.4-Source.zip - -More detail and download access: -https://gpuopen.com/archive/gamescgi/cubemapgen/ - diff --git a/Gems/ImageProcessing/gem.json b/Gems/ImageProcessing/gem.json deleted file mode 100644 index f211bad1e3..0000000000 --- a/Gems/ImageProcessing/gem.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "gem_name": "ImageProcessing", - "GemFormatVersion": 4, - "Uuid": "eeffbd9211cf4ce0b5cc73696b427cbe", - "Name": "ImageProcessing", - "DisplayName": "Image Processing", - "Version": "0.1.0", - "Summary": "Contains ImageBuilder for Asset Processor processing image files and UI for texture property editing", - "Tags": ["Image Builder", "Texture Property Editor"], - "IconPath": "preview.png", - "IsRequired": false, - "Modules": [ - { - "Name": "Editor", - "Type": "EditorModule" - } - ], - "Dependencies": [ - { - "Uuid": "5a149b6b3c964064bd4970f0e92f72e2", - "VersionConstraints": [ - "~>0.1" - ], - "_comment": "Texture Atlas" - } - ] -} diff --git a/Gems/ImageProcessing/preview.png b/Gems/ImageProcessing/preview.png deleted file mode 100644 index 2f1ed47754..0000000000 --- a/Gems/ImageProcessing/preview.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d6204c6730e5675791765ca194e9b1cbec282208e280507de830afc2805e5fa -size 41127 diff --git a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py index dc2e92f518..87a396ea1c 100755 --- a/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py +++ b/Tools/LyTestTools/ly_test_tools/_internal/pytest_plugin/test_tools_fixtures.py @@ -29,7 +29,7 @@ import ly_test_tools.environment.file_system import ly_test_tools.launchers.launcher_helper import ly_test_tools.launchers.platforms.base import ly_test_tools.environment.watchdog -from ly_test_tools import ALL_PLATFORM_OPTIONS, HOST_OS_PLATFORM, HOST_OS_GENERIC_EXECUTABLE +from ly_test_tools import ALL_PLATFORM_OPTIONS, HOST_OS_PLATFORM, HOST_OS_DEDICATED_SERVER, HOST_OS_GENERIC_EXECUTABLE logger = logging.getLogger(__name__) @@ -260,7 +260,7 @@ def dedicated_launcher(request, workspace, crash_log_watchdog): return _dedicated_launcher( request=request, workspace=workspace, - launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_PLATFORM), + launcher_platform=get_fixture_argument(request, 'launcher_platform', HOST_OS_DEDICATED_SERVER), level=get_fixture_argument(request, 'level', '')) diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py index 6b53c1f8f3..36746b510f 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/base.py @@ -70,7 +70,7 @@ class Launcher(object): return config_dict - def setup(self, backupFiles = True, launch_ap = True): + def setup(self, backupFiles=True, launch_ap=True): """ Perform setup of this launcher, must be called before launching. Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files @@ -193,7 +193,7 @@ class Launcher(object): """ raise NotImplementedError("There is no binary file for this launcher") - def start(self, backupFiles = True, launch_ap = True): + def start(self, backupFiles=True, launch_ap=None): """ Automatically prepare and launch the application When called using "with launcher.start():" it will automatically call stop() when block exits @@ -203,14 +203,14 @@ class Launcher(object): """ return _Application(self, backupFiles, launch_ap=launch_ap) - def _start_impl(self, backupFiles = True, launch_ap=True): + def _start_impl(self, backupFiles = True, launch_ap=None): """ Implementation of start(), intended to be called via context manager in _Application :param backupFiles: Bool to backup settings files :return None: """ - self.setup(backupFiles, launch_ap=launch_ap) + self.setup(backupFiles=backupFiles, launch_ap=launch_ap) self.launch() def stop(self): @@ -326,7 +326,7 @@ class _Application(object): """ Context-manager for opening an application, enables using both "launcher.start()" and "with launcher.start()" """ - def __init__(self, launcher, backupFiles = True, launch_ap = True): + def __init__(self, launcher, backupFiles = True, launch_ap=None): """ Called during both "launcher.start()" and "with launcher.start()" @@ -334,7 +334,7 @@ class _Application(object): :return None: """ self.launcher = launcher - launcher._start_impl(backupFiles, launch_ap=launch_ap) + launcher._start_impl(backupFiles, launch_ap) def __enter__(self): """ diff --git a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py index ebb3566806..30c3e6eddd 100755 --- a/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py +++ b/Tools/LyTestTools/ly_test_tools/launchers/platforms/win/launcher.py @@ -42,21 +42,26 @@ class WinLauncher(Launcher): assert self.workspace.project is not None return os.path.join(self.workspace.paths.build_directory(), f"{self.workspace.project}.GameLauncher.exe") - def setup(self, backupFiles = True, launch_ap = True): + def setup(self, backupFiles=True, launch_ap=True): """ Perform setup of this launcher, must be called before launching. Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files :param backupFiles: Bool to backup setup files + :param lauch_ap: Bool to lauch the asset processor :return: None """ # Backup if backupFiles: self.backup_settings() + # Base setup defaults to None + if launch_ap is None: + launch_ap = True + # Modify and re-configure self.configure_settings() - super(WinLauncher, self).setup(launch_ap=launch_ap) + super(WinLauncher, self).setup(backupFiles, launch_ap) def launch(self): """ @@ -177,6 +182,21 @@ class WinLauncher(Launcher): class DedicatedWinLauncher(WinLauncher): + def setup(self, backupFiles=True, launch_ap=False): + """ + Perform setup of this launcher, must be called before launching. + Subclasses should call its parent's setup() before calling its own code, unless it changes configuration files + + :param backupFiles: Bool to backup setup files + :param lauch_ap: Bool to lauch the asset processor + :return: None + """ + # Base setup defaults to None + if launch_ap is None: + launch_ap = False + + super(DedicatedWinLauncher, self).setup(backupFiles, launch_ap) + def binary_path(self): """ Return full path to the dedicated server launcher for the build directory.