#pragma region CPL License /* Nuclex Native Framework Copyright (C) 2002-2021 Nuclex Development Labs This library is free software; you can redistribute it and/or modify it under the terms of the IBM Common Public License as published by the IBM Corporation; either version 1.0 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the IBM Common Public License for more details. You should have received a copy of the IBM Common Public License along with this library */ #pragma endregion // CPL License // If the library is compiled as a DLL, this ensures symbols are exported #define NUCLEX_PIXELS_SOURCE 1 #include "Nuclex/Pixels/PixelFormats/PixelFormatQuery.h" #include "ChannelHelpers.h" #include "PixelFormatDescription.h" #include "OnPixelFormat.h" #include namespace { // ------------------------------------------------------------------------------------------- // /// Checks whether the specified pixel format has a red color channel /// Pixel format that will be checked template class CheckIfRedChannelPresent { /// Returns whether the pixel format has a red color channel /// True if the pixel format has a red color channel public: bool operator()() const { return !std::is_same< typename Nuclex::Pixels::PixelFormats::PixelFormatDescription::Channel1, std::nullptr_t >::value; } }; // ------------------------------------------------------------------------------------------- // /// Checks whether the specified pixel format has a green color channel /// Pixel format that will be checked template class CheckIfGreenChannelPresent { /// Returns whether the pixel format has a green color channel /// True if the pixel format has a green color channel public: bool operator()() const { return !std::is_same< typename Nuclex::Pixels::PixelFormats::PixelFormatDescription::Channel2, std::nullptr_t >::value; } }; // ------------------------------------------------------------------------------------------- // /// Checks whether the specified pixel format has a blue color channel /// Pixel format that will be checked template class CheckIfBlueChannelPresent { /// Returns whether the pixel format has a blue color channel /// True if the pixel format has a blue color channel public: bool operator()() const { return !std::is_same< typename Nuclex::Pixels::PixelFormats::PixelFormatDescription::Channel3, std::nullptr_t >::value; } }; // ------------------------------------------------------------------------------------------- // /// Checks whether the specified pixel format has a alpha channel /// Pixel format that will be checked template class CheckIfAlphaChannelPresent { /// Returns whether the pixel format has an alpha channel /// True if the pixel format has a alpha channel public: bool operator()() const { return !std::is_same< typename Nuclex::Pixels::PixelFormats::PixelFormatDescription::Channel4, std::nullptr_t >::value; } }; // ------------------------------------------------------------------------------------------- // /// Checks whether the specified pixel format uses signed channels /// Pixel format that will be checked template class CheckIfSignedFormat { /// Returns whether the pixel format uses signed channels /// True if the pixel format uses signed integers or floats public: bool operator()() const { return Nuclex::Pixels::PixelFormats::IsSignedFormat; } }; // ------------------------------------------------------------------------------------------- // /// Checks whether the specified pixel format uses floating point channels /// Pixel format that will be checked template class CheckIfFloatFormat { /// Returns whether the pixel format uses floating point channels /// True if the pixel format uses floating point channels public: bool operator()() const { return Nuclex::Pixels::PixelFormats::IsFloatFormat; } }; // ------------------------------------------------------------------------------------------- // /// /// Checks whether all channels in the specified pixel format are byte-aligned /// /// Pixel format that will be checked template class CheckIfChannelsByteAligned { /// Returns whether the pixel format uses byte-aligned channels /// True if the pixel format uses byte-aligned channels public: bool operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; bool allByteAligned = true; if constexpr(!std::is_same::value) { allByteAligned &= ((Description::Channel1::LowestBitIndex % 8) == 0); allByteAligned &= ((Description::Channel1::BitCount % 8) == 0); } if constexpr(!std::is_same::value) { allByteAligned &= ((Description::Channel2::LowestBitIndex % 8) == 0); allByteAligned &= ((Description::Channel2::BitCount % 8) == 0); } if constexpr(!std::is_same::value) { allByteAligned &= ((Description::Channel3::LowestBitIndex % 8) == 0); allByteAligned &= ((Description::Channel3::BitCount % 8) == 0); } if constexpr(!std::is_same::value) { allByteAligned &= ((Description::Channel4::LowestBitIndex % 8) == 0); allByteAligned &= ((Description::Channel4::BitCount % 8) == 0); } return allByteAligned; } }; // ------------------------------------------------------------------------------------------- // /// Checks whether the specified pixel format requires endian-flipping /// Pixel format that will be checked template class CheckIfEndianFlippingRequired { /// Returns whether the pixel format requires endian-flipping /// True if the pixel format required endian-flipping public: bool operator()() const { //typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; //return (Description::EndianFlip != nuclex::Pixels::PixelFormats::EndianFlipMode::None); return false; // TODO: Actually determine whether endian flipping is needed. } }; // ------------------------------------------------------------------------------------------- // /// Retrieves the index of the lowest red bit in the pixel format /// Pixel format that will be checked template class FetchLowestRedBitIndex { /// Returns the index of the lowest red bit in the pixel format /// The index of the lowest red bit in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel1::LowestBitIndex; } } }; // ------------------------------------------------------------------------------------------- // /// Retrieves the index of the lowest green bit in the pixel format /// Pixel format that will be checked template class FetchLowestGreenBitIndex { /// Returns the index of the lowest green bit in the pixel format /// The index of the lowest green bit in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel2::LowestBitIndex; } } }; // ------------------------------------------------------------------------------------------- // /// Retrieves the index of the lowest blue bit in the pixel format /// Pixel format that will be checked template class FetchLowestBlueBitIndex { /// Returns the index of the lowest blue bit in the pixel format /// The index of the lowest blue bit in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel3::LowestBitIndex; } } }; // ------------------------------------------------------------------------------------------- // /// Retrieves the index of the lowest alpha bit in the pixel format /// Pixel format that will be checked template class FetchLowestAlphaBitIndex { /// Returns the index of the lowest alpha bit in the pixel format /// The index of the lowest alpha bit in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel4::LowestBitIndex; } } }; // ------------------------------------------------------------------------------------------- // /// Counts the number of red bits used by the pixel format /// Pixel format that will be checked template class FetchRedBitCount { /// Returns the number of red bits used by the pixel format /// The number of bits used for the red channel in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel1::BitCount; } } }; // ------------------------------------------------------------------------------------------- // /// Counts the number of green bits used by the pixel format /// Pixel format that will be checked template class FetchGreenBitCount { /// Returns the number of green bits used by the pixel format /// The number of bits used for the green channel in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel2::BitCount; } } }; // ------------------------------------------------------------------------------------------- // /// Counts the number of blue bits used by the pixel format /// Pixel format that will be checked template class FetchBlueBitCount { /// Returns the number of blue bits used by the pixel format /// The number of bits used for the blue channel in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel3::BitCount; } } }; // ------------------------------------------------------------------------------------------- // /// Counts the number of alpha bits used by the pixel format /// Pixel format that will be checked template class FetchAlphaBitCount { /// Returns the number of alpha bits used by the pixel format /// The number of bits used for the alpha channel in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; if constexpr(std::is_same::value) { return std::size_t(-1); } else { return Description::Channel4::BitCount; } } }; // ------------------------------------------------------------------------------------------- // /// Counts the number of bits used by the pixel format's widest channel /// Pixel format that will be checked template class FetchWidestChannelBitCount { /// Returns the number of bits used by the pixel format's widest channel /// The number of bits used for the widest channel in the pixel format public: std::size_t operator()() const { typedef Nuclex::Pixels::PixelFormats::PixelFormatDescription Description; std::size_t widestColorChannelBitCount = 0; if constexpr(!std::is_same::value) { widestColorChannelBitCount = Description::Channel1::BitCount; } if constexpr(!std::is_same::value) { if(Description::Channel2::BitCount > widestColorChannelBitCount) { widestColorChannelBitCount = Description::Channel2::BitCount; } } if constexpr(!std::is_same::value) { if(Description::Channel3::BitCount > widestColorChannelBitCount) { widestColorChannelBitCount = Description::Channel3::BitCount; } } if constexpr(!std::is_same::value) { if(Description::Channel4::BitCount > widestColorChannelBitCount) { widestColorChannelBitCount = Description::Channel4::BitCount; } } return widestColorChannelBitCount; } }; // ------------------------------------------------------------------------------------------- // } // anonymous namespace namespace Nuclex { namespace Pixels { namespace PixelFormats { // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::HasRedChannel(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::HasGreenChannel(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::HasBlueChannel(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::HasAlphaChannel(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::IsSignedFormat(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::IsFloatFormat(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::HasDifferentlySizedChannels(PixelFormat pixelFormat) { return ( (pixelFormat == PixelFormat::A2_B10_G10_R10_Unsigned_Native32) || (pixelFormat == PixelFormat::A2_R10_G10_B10_Unsigned_Native32) || (pixelFormat == PixelFormat::B5_G6_R5_Unsigned_Native16) || (pixelFormat == PixelFormat::R5_G6_B5_Unsigned_Native16) ); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::AreAllChannelsByteAligned(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // bool PixelFormatQuery::RequiresEndianFlip(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::GetLowestRedBitIndex(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::GetLowestGreenBitIndex(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::GetLowestBlueBitIndex(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::GetLowestAlphaBitIndex(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::CountRedBits(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::CountGreenBits(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::CountBlueBits(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::optional PixelFormatQuery::CountAlphaBits(PixelFormat pixelFormat) { std::size_t index = OnPixelFormat(pixelFormat); if(index == std::size_t(-1)) { return std::optional(); } else { return index; } } // ------------------------------------------------------------------------------------------- // std::size_t PixelFormatQuery::CountWidestChannelBits(PixelFormat pixelFormat) { return OnPixelFormat(pixelFormat); } // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Pixels::PixelFormats