//  // // # # ### # # -= Nuclex Library =-  // // ## # # # ## ## PixelFormat.h - Pixel format description  // // ### # # ###  // // # ### # ### A template-based pixel format description with  // // # ## # # ## ## color conversion functions  // // # # ### # # R1 (C)2002-2004 Markus Ewald -> License.txt  // //  // #ifndef NUCLEX_VIDEO_PIXELFORMAT_H #define NUCLEX_VIDEO_PIXELFORMAT_H #include "Nuclex/Nuclex.h" #include "Nuclex/Support/Color.h" #include "Nuclex/Support/ColorConversion.h" namespace Nuclex { namespace Video { //  // //  Nuclex::Video::PixelFormatDescription  // //  // /// Pixel format descriptor /** Describes a pixel format by storing a set of color channels and their bit layouts. @param PixelType The data type to use for a pixel @param Red, Green, Blue, Alpha Color channel layouts. Set to a valid ColorChannel<> or to NullChannel @param BitsPerPixel The number of bits per pixel. Will be deduced from the channels if not supplied */ template< typename PixelType, typename Red = NullChannel, typename Green = NullChannel, typename Blue = NullChannel, typename Alpha = NullChannel, size_t BitsPerPixel = StaticMax< StaticMax::Result, StaticMax::Result >::Result > struct PixelFormatDescription { typedef PixelType PixelType; typedef Red Red; typedef Green Green; typedef Blue Blue; typedef Alpha Alpha; private: template struct ChannelProvided { enum { Result = true }; }; template<> struct ChannelProvided { enum { Result = false }; }; public: enum { /// True when an alpha channel is present HasAlphaChannel = ChannelProvided::Result, /// The number of color channels ChannelCount = ChannelProvided::Result + ChannelProvided::Result + ChannelProvided::Result + ChannelProvided::Result, /// The number of bits per pixel BitsPerPixel = BitsPerPixel, /// The number of bytes per pixel BytesPerPixel = BitsPerPixel / BitsPerByte }; /// Convert a pixel from another format into this format template static inline PixelType convertFrom(typename OtherPixelFormatDescription::PixelType Pixel) { return convertFrom( Pixel, Bool2Type<(sizeof(OtherPixelFormatDescription::PixelType) > sizeof(PixelType))>() ); } /// Build a pixel color from a visix color specification /** @param Color Color to convert to a pixel color @return The pixel color of the specified visix color specification */ static inline PixelType pixelFromColor(const Color &Color) { return Red::fromFloat(Color.R) | Green::fromFloat(Color.G) | Blue::fromFloat(Color.B) | Alpha::fromFloat(Color.A); } /// Get the visix color specification of a pixel color /** @param Pixel Pixel color to convert to a color @return The visix color specification of the specified pixel color */ static inline Color colorFromPixel(PixelType Pixel) { return Color( Red::toFloat(Pixel), Green::toFloat(Pixel), Blue::toFloat(Pixel), Alpha::toFloat(Pixel) ); } private: // Required to let the ColorChannelConverter use the larger of two pixel types template static inline PixelType convertFrom(typename OtherPixelFormatDescription::PixelType Pixel, Bool2Type) { return static_cast( ColorChannelConverter< OtherPixelFormatDescription::PixelType, Red, OtherPixelFormatDescription::Red >()(Pixel) | ColorChannelConverter< OtherPixelFormatDescription::PixelType, Green, OtherPixelFormatDescription::Green >()(Pixel) | ColorChannelConverter< OtherPixelFormatDescription::PixelType, Blue, OtherPixelFormatDescription::Blue >()(Pixel) | ColorChannelConverter< OtherPixelFormatDescription::PixelType, Alpha, OtherPixelFormatDescription::Alpha >()(Pixel) ); } template static inline PixelType convertFrom(typename OtherPixelFormatDescription::PixelType Pixel, Bool2Type) { return ColorChannelConverter()(Pixel) | ColorChannelConverter()(Pixel) | ColorChannelConverter()(Pixel) | ColorChannelConverter()(Pixel); } }; /// Read a pixel in the specified pixel format /** You can specialize this function if the default implementation is not adequate for a pixel format (as is the case with rgb-8-8-8) */ template struct ReadPixel { typedef PixelFormatDescription PixelFormatDescription; inline typename PixelFormatDescription::PixelType operator ()(const void *pMemory) { return *reinterpret_cast(pMemory); } }; /// Write a pixel in the specified pixel format /** You can specialize this function if the default implementation is not adequate for a pixel format (as is the case with rgb-8-8-8) */ template struct WritePixel { typedef PixelFormatDescription PixelFormatDescription; inline void operator ()(void *pMemory, typename PixelFormatDescription::PixelType Pixel) { *reinterpret_cast(pMemory) = Pixel; } }; typedef PixelFormatDescription< unsigned_8, // 8 bits NullChannel, NullChannel, NullChannel, ColorChannel<0, 8> // aaaaaaaa > A_8; typedef PixelFormatDescription< unsigned_8, // 8 bits ColorChannel<5, 3>, // rrr..... ColorChannel<2, 3>, // ...ggg.. ColorChannel<0, 2> // ......bb > RGB_3_3_2; typedef PixelFormatDescription< unsigned_8, // 8 bits ColorChannel<5, 3>, // rrr..... ColorChannel<2, 3>, // ...ggg.. ColorChannel<0, 2> // ......bb > RGB_3_3_2; typedef PixelFormatDescription< unsigned_16, // 16 bits ColorChannel<11, 5>, // rrrrr... ........ ColorChannel< 5, 6>, // .....ggg ggg..... ColorChannel< 0, 5> // ........ ...bbbbb > RGB_5_6_5; typedef PixelFormatDescription< unsigned_32, // 24 bits ColorChannel<16, 8>, // rrrrrrrr ........ ........ ColorChannel< 8, 8>, // ........ gggggggg ........ ColorChannel< 0, 8>, // ........ ........ bbbbbbbb NullChannel, 24 > RGB_8_8_8; typedef PixelFormatDescription< unsigned_16, // 16 bits ColorChannel<10, 5>, // .rrrrr.. ........ ColorChannel< 5, 5>, // ......gg ggg..... ColorChannel< 0, 5>, // ........ ...bbbbb NullChannel, 16 > XRGB_1_5_5_5; typedef PixelFormatDescription< unsigned_32, // 32 bits ColorChannel<16, 8>, // ........ rrrrrrrr ........ ........ ColorChannel< 8, 8>, // ........ ........ gggggggg ........ ColorChannel< 0, 8>, // ........ ........ ........ bbbbbbbb NullChannel, 32 > XRGB_8_8_8_8; typedef PixelFormatDescription< unsigned_16, // 16 bits ColorChannel<10, 5>, // .rrrrr.. ........ ColorChannel< 5, 5>, // ......gg ggg..... ColorChannel< 0, 5>, // ........ ...bbbbb ColorChannel<15, 1> // a....... ........ > ARGB_1_5_5_5; typedef PixelFormatDescription< unsigned_16, // 16 bits ColorChannel< 8, 4>, // ....rrrr ........ ColorChannel< 4, 4>, // ........ gggg.... ColorChannel< 0, 4>, // ........ ....bbbb ColorChannel<12, 4> // aaaa.... ........ > ARGB_4_4_4_4; typedef PixelFormatDescription< unsigned_32, // 32 bits ColorChannel<16, 8>, // ........ rrrrrrrr ........ ........ ColorChannel< 8, 8>, // ........ ........ gggggggg ........ ColorChannel< 0, 8>, // ........ ........ ........ bbbbbbbb ColorChannel<24, 8> // aaaaaaaa ........ ........ ........ > ARGB_8_8_8_8; // Specialization because default implementation would touch neighboring pixel template<> struct ReadPixel { typedef RGB_8_8_8 PixelFormatDescription; inline PixelFormatDescription::PixelType operator ()(const void *pMemory) { return *reinterpret_cast(pMemory); } }; template<> struct WritePixel { typedef RGB_8_8_8 PixelFormatDescription; inline void operator ()(void *pMemory, PixelFormatDescription::PixelType Pixel) { *reinterpret_cast(pMemory) = Pixel; } }; }} // namespace Nuclex::Video #endif // NUCLEX_VIDEO_PIXELFORMAT_H