#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 #ifndef NUCLEX_PIXELS_PIXELFORMATS_CONVERTPIXEL_H #error This file is intended to be included through ConvertPixel.h #endif namespace Nuclex { namespace Pixels { namespace PixelFormats { // ------------------------------------------------------------------------------------------- // /// Converts between two different integer-based pixel formats /// Pixel format used by the input pixel /// Pixel format used by the output pixel /// Pixel that will be converted to the output pixel format /// A pixel in the output pixel format that's equivalent to the input pixel template< PixelFormat TSourcePixelFormat, PixelFormat TTargetPixelFormat, typename std::enable_if_t< (TSourcePixelFormat != TTargetPixelFormat) && (!IsFloatFormat) && (!IsFloatFormat) > * = nullptr > NUCLEX_PIXELS_ALWAYS_INLINE void ConvertPixel( const PixelTypeFromFormat *sourcePixel, PixelTypeFromFormat *targetPixel ) { typedef LargerPixelType IntermediatePixelType; static_assert( (!IsSignedFormat) && (!IsSignedFormat) && u8"Signed pixel formats not implemented yet, results will be wrong" ); (void)sourcePixel; // MSVC fantasizes a constellation where no channels exist (void)targetPixel; // then warns that these two parameters aren't used... // Convert the red channel and assign it to the target pixel if constexpr(NeedConvertChannel1) { *targetPixel = static_cast>( PixelFormats::UnsignedBitAdjuster< PixelFormats::PixelFormatDescription::Channel1::BitCount, PixelFormats::PixelFormatDescription::Channel1::BitCount >::template Adjust< PixelFormats::PixelFormatDescription::Channel1::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel1::LowestBitIndex >( static_cast(*sourcePixel) ) & BitMask< IntermediatePixelType, PixelFormats::PixelFormatDescription::Channel1::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel1::BitCount > ); } // Convert the green channel and assign it to the target pixel if constexpr(NeedConvertChannel2) { if constexpr(NeedConvertChannel1) { *targetPixel |= static_cast>( PixelFormats::UnsignedBitAdjuster< PixelFormats::PixelFormatDescription::Channel2::BitCount, PixelFormats::PixelFormatDescription::Channel2::BitCount >::template Adjust< PixelFormats::PixelFormatDescription::Channel2::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel2::LowestBitIndex >( static_cast(*sourcePixel) ) & BitMask< IntermediatePixelType, PixelFormats::PixelFormatDescription::Channel2::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel2::BitCount > ); } else { *targetPixel = static_cast>( PixelFormats::UnsignedBitAdjuster< PixelFormats::PixelFormatDescription::Channel2::BitCount, PixelFormats::PixelFormatDescription::Channel2::BitCount >::template Adjust< PixelFormats::PixelFormatDescription::Channel2::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel2::LowestBitIndex >( static_cast(*sourcePixel) ) & BitMask< IntermediatePixelType, PixelFormats::PixelFormatDescription::Channel2::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel2::BitCount > ); } } // Convert the blue channel and assign it to the target pixel if constexpr(NeedConvertChannel3) { if constexpr( NeedConvertChannel1 || NeedConvertChannel2 ) { *targetPixel |= static_cast>( PixelFormats::UnsignedBitAdjuster< PixelFormats::PixelFormatDescription::Channel3::BitCount, PixelFormats::PixelFormatDescription::Channel3::BitCount >::template Adjust< PixelFormats::PixelFormatDescription::Channel3::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel3::LowestBitIndex >( static_cast(*sourcePixel) ) & BitMask< IntermediatePixelType, PixelFormats::PixelFormatDescription::Channel3::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel3::BitCount > ); } else { *targetPixel = static_cast>( PixelFormats::UnsignedBitAdjuster< PixelFormats::PixelFormatDescription::Channel3::BitCount, PixelFormats::PixelFormatDescription::Channel3::BitCount >::template Adjust< PixelFormats::PixelFormatDescription::Channel3::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel3::LowestBitIndex >( static_cast(*sourcePixel) ) & BitMask< IntermediatePixelType, PixelFormats::PixelFormatDescription::Channel3::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel3::BitCount > ); } } // Convert the alpha channel and assign it to the target pixel if constexpr(NeedConvertChannel4) { if constexpr( NeedConvertChannel1 || NeedConvertChannel2 || NeedConvertChannel3 ) { *targetPixel |= static_cast>( PixelFormats::UnsignedBitAdjuster< PixelFormats::PixelFormatDescription::Channel4::BitCount, PixelFormats::PixelFormatDescription::Channel4::BitCount >::template Adjust< PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex >( static_cast(*sourcePixel) ) & BitMask< IntermediatePixelType, PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel4::BitCount > ); } else { *targetPixel = static_cast>( PixelFormats::UnsignedBitAdjuster< PixelFormats::PixelFormatDescription::Channel4::BitCount, PixelFormats::PixelFormatDescription::Channel4::BitCount >::template Adjust< PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex >( static_cast(*sourcePixel) ) & BitMask< IntermediatePixelType, PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel4::BitCount > ); } } else if constexpr(HasAlphaChannel) { if constexpr( NeedConvertChannel1 || NeedConvertChannel2 || NeedConvertChannel3 ) { *targetPixel |= BitMask< PixelTypeFromFormat, PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel4::BitCount >; } else { *targetPixel = BitMask< PixelTypeFromFormat, PixelFormats::PixelFormatDescription::Channel4::LowestBitIndex, PixelFormats::PixelFormatDescription::Channel4::BitCount >; } } } // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Pixels::PixelFormats