#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 a pixel between two different floating point-based 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 ) { (void)sourcePixel; // MSVC fantasizes a constellation where no channels exist (void)targetPixel; // then warns that these two parameters aren't used... // Convert the red color channel, if one is present if constexpr(NeedConvertChannel1) { static_assert( ((PixelFormatDescription::Channel1::LowestBitIndex % 8) == 0) && u8"Source floating point channel bits start at a byte boundary" ); static_assert( ((PixelFormatDescription::Channel1::LowestBitIndex % 8) == 0) && u8"Target floating point channel bits start at a byte boundary" ); typedef ChannelFloatType< PixelFormatDescription::Channel1::BitCount > SourceFloatType; const SourceFloatType *source = reinterpret_cast( reinterpret_cast(sourcePixel) + (PixelFormatDescription::Channel1::LowestBitIndex / 8) ); typedef ChannelFloatType< PixelFormatDescription::Channel1::BitCount > TargetFloatType; TargetFloatType *target = reinterpret_cast( reinterpret_cast(targetPixel) + (PixelFormatDescription::Channel1::LowestBitIndex / 8) ); *target = static_cast(*source); } // Convert the green color channel, if one is present if constexpr(NeedConvertChannel2) { static_assert( ((PixelFormatDescription::Channel2::LowestBitIndex % 8) == 0) && u8"Source floating point channel bits start at a byte boundary" ); static_assert( ((PixelFormatDescription::Channel2::LowestBitIndex % 8) == 0) && u8"Target floating point channel bits start at a byte boundary" ); typedef ChannelFloatType< PixelFormatDescription::Channel2::BitCount > SourceFloatType; const SourceFloatType *source = reinterpret_cast( reinterpret_cast(sourcePixel) + (PixelFormatDescription::Channel2::LowestBitIndex / 8) ); typedef ChannelFloatType< PixelFormatDescription::Channel2::BitCount > TargetFloatType; TargetFloatType *target = reinterpret_cast( reinterpret_cast(targetPixel) + (PixelFormatDescription::Channel2::LowestBitIndex / 8) ); *target = static_cast(*source); } // Convert the blue color channel, if one is present if constexpr(NeedConvertChannel3) { static_assert( ((PixelFormatDescription::Channel3::LowestBitIndex % 8) == 0) && u8"Source floating point channel bits start at a byte boundary" ); static_assert( ((PixelFormatDescription::Channel3::LowestBitIndex % 8) == 0) && u8"Target floating point channel bits start at a byte boundary" ); typedef ChannelFloatType< PixelFormatDescription::Channel3::BitCount > SourceFloatType; const SourceFloatType *source = reinterpret_cast( reinterpret_cast(sourcePixel) + (PixelFormatDescription::Channel3::LowestBitIndex / 8) ); typedef ChannelFloatType< PixelFormatDescription::Channel3::BitCount > TargetFloatType; TargetFloatType *target = reinterpret_cast( reinterpret_cast(targetPixel) + (PixelFormatDescription::Channel3::LowestBitIndex / 8) ); *target = static_cast(*source); } // Convert the alpha channel, if one is present if constexpr(NeedConvertChannel4) { static_assert( ((PixelFormatDescription::Channel4::LowestBitIndex % 8) == 0) && u8"Source floating point channel bits start at a byte boundary" ); static_assert( ((PixelFormatDescription::Channel4::LowestBitIndex % 8) == 0) && u8"Target floating point channel bits start at a byte boundary" ); typedef ChannelFloatType< PixelFormatDescription::Channel4::BitCount > SourceFloatType; const SourceFloatType *source = reinterpret_cast( reinterpret_cast(sourcePixel) + (PixelFormatDescription::Channel4::LowestBitIndex / 8) ); typedef ChannelFloatType< PixelFormatDescription::Channel4::BitCount > TargetFloatType; TargetFloatType *target = reinterpret_cast( reinterpret_cast(targetPixel) + (PixelFormatDescription::Channel4::LowestBitIndex / 8) ); *target = static_cast(*source); } else if constexpr(HasAlphaChannel) { typedef ChannelFloatType< PixelFormatDescription::Channel4::BitCount > TargetFloatType; TargetFloatType *target = reinterpret_cast( reinterpret_cast(targetPixel) + (PixelFormatDescription::Channel4::LowestBitIndex / 8) ); *target = static_cast(1); } } // ------------------------------------------------------------------------------------------- // }}} // namespace Nuclex::Pixels::PixelFormats