This section of the archives stores flipcode's complete Developer Toolbox collection, featuring a variety of mini-articles and source code contributions from our readers.

| Template Pixel Converter Submitted by

This piece code can convert between pre-described pixel formats (=color component size & order) It uses templates, macros and enums for optimalisations I use a simple technique using enums to prevent having to use switch statements

    enum
    {
       value = case1? result1:
        case2? result2:
        default
    };

This forces the compiler to calculate the value at compile time. Obviously, this requires all the variables to be known to the compiler at compile time as well. The code generated by the msvc compiler actually isn't that bad. i'm sure there are a lot of optimalisations that could be done here (by not using templates), especially when using assembly. But this code actually makes it possible to have a generalized piece of code that handles any situation (except indexed colors or colors that have non-integer values) ...and it's a lot more fun to make ;) I'm not sure how portable this code is, i've only tried it on msvc. Also i've only tested this code with the debugger, looking at the resulting values. So the code might have some small bugs, But they shouldn't be hard to solve. Besides, that's beside the point.. This method Is not really practical in real-life applications due to the long compile-times. The whole reason for me to write this was to experiment with various features of the C++ language. I hope some of the ideas used in this piece of code can inspire or teach something to someone. Sander van Rossen (aka Not)

Currently browsing [pixelconverter.zip] (9,543 bytes) - [colordescription.h] - (9,367 bytes)

    //
    // Written by Sander van Rossen
    //	You are free to use this piece of code any way you like
    //
    #pragma once

    /*!
    	@brief		Used to describe the order of the color components in a color
    */
    enum EColorType
    {
    	COLOR_NONE				,	///< Color has no components

    	COLOR_RGBA				,	///< Color is ordered as RGBA
    	COLOR_BGRA				,	///< Color is ordered as BGRA
    	COLOR_ARGB				,	///< Color is ordered as ARGB
    	COLOR_ABGR				,	///< Color is ordered as ABGR
    	COLOR_RGB				,	///< Color is ordered as RGB (no ALPHA channel)
    	COLOR_BGR				,	///< Color is ordered as BGR (no ALPHA channel)
    	COLOR_RED				,	///< Color only has a RED color channel

    	COLOR_GREEN				,	///< Color only has a GREEN color channel
    	COLOR_BLUE				,	///< Color only has a BLUE color channel
    	COLOR_ALPHA					///< Color only has an ALPHA channel

    };//EColorType

    /*!
    	@brief		ColorDescription describes a color and it's components
    */
    template
    <
    	EColorType	tColorOrder	,	///< the order of all the color components

    	cUInt		tRedSize	,	///< number of RED color component bits
    	cUInt		tGreenSize	,	///< number of GREEN color component bits
    	cUInt		tBlueSize	,	///< number of BLUE color component bits
    	cUInt		tAlphaSize	,	///< number of ALPHA component bits
    	cUInt		tSpacing		///< number of bits that are left unused
    >
    class ColorDescription
    {
    public:
    	enum EColorConstants
    	{
    		//
    		// Sizes of individual color components
    		//
    		RED_SIZE			= tRedSize		,	///< Size of the RED color component
    		GREEN_SIZE			= tGreenSize	,	///< Size of the GREEN color component
    		BLUE_SIZE			= tBlueSize		,	///< Size of the BLUE color component
    		ALPHA_SIZE			= tAlphaSize	,	///< Size of the ALPHA component
    		SPACING_SIZE		= tSpacing		,	///< Size of the unused space

    		///
    		/// Actuall size of color
    		///
    		COLOR_BIT_SIZE		= RED_SIZE		+
    							  GREEN_SIZE	+
    							  BLUE_SIZE		+
    							  ALPHA_SIZE	,

    		///
    		/// Storage size of color
    		///
    		COLOR_STORAGE_BITS	= RED_SIZE		+
    							  GREEN_SIZE	+
    							  BLUE_SIZE		+
    							  ALPHA_SIZE	+
    							  SPACING_SIZE	,

    		///
    		/// REMOVE_COMPONENT is used to shift a color component to outside an int
    		/// this way the color component is simply removed instead of used in the
    		/// calculation
    		///
    		REMOVE_COMPONENT	= BYTES_PER_INT ,

    		//
    		// Helpers to shorten the notation when calculating the position of each
    		// component
    		//
    		POS_0				= 0,												///< at the start of the color
    		POS_R				= RED_SIZE										,	///< after the RED component
    		POS_G				=			 GREEN_SIZE							,	///< after the GREEN component
    		POS_RG				= RED_SIZE + GREEN_SIZE							,	///< after the RED and GREEN components
    		POS_B				=						  BLUE_SIZE				,	///< after the BLUE component
    		POS_RB				= RED_SIZE +			  BLUE_SIZE				,	///< after the RED and BLUE components
    		POS_GB				=			 GREEN_SIZE + BLUE_SIZE				,	///< after the GREEN and BLUE components
    		POS_RGB				= RED_SIZE + GREEN_SIZE + BLUE_SIZE				,	///< after the RED, GREEN and BLUE components
    		POS_A				=									  ALPHA_SIZE,	///< after the ALPHA component
    		POS_RA				= RED_SIZE +						  ALPHA_SIZE,	///< after the RED and ALPHA components
    		POS_GA				=			 GREEN_SIZE +			  ALPHA_SIZE,	///< after the GREEN and ALPHA components
    		POS_RGA				= RED_SIZE + GREEN_SIZE +			  ALPHA_SIZE,	///< after the RED, GREEN and ALPHA components
    		POS_BA				=						  BLUE_SIZE + ALPHA_SIZE,	///< after the RED, BLUE and ALPHA components
    		POS_RBA				= RED_SIZE + 			  BLUE_SIZE + ALPHA_SIZE,	///< after the BLUE and ALPHA components
    		POS_GBA				=			 GREEN_SIZE + BLUE_SIZE + ALPHA_SIZE,	///< after the GREEN, BLUE and ALPHA components
    		POS_RGBA			= RED_SIZE + GREEN_SIZE + BLUE_SIZE + ALPHA_SIZE,	///< after the RED, GREEN, BLUE and ALPHA components

    		//
    		// Calculate the position of each color component in the color
    		//

    		/// Calculates the offset of the RED color component in the color
    		///		This 'switch' statement is calculated at compile time
    		RED_OFFSET			= (tColorOrder == COLOR_NONE )? REMOVE_COMPONENT:	///< this type of color has no components
    							  (tColorOrder == COLOR_RGBA )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_BGRA )? POS_GB			:	///< component starts after the GREEN and BLUE components
    							  (tColorOrder == COLOR_ARGB )? POS_A			:	///< component starts after the ALPHA component
    							  (tColorOrder == COLOR_ABGR )? POS_GBA			:	///< component starts after the GREEN, BLUE and ALPHA components
    							  (tColorOrder == COLOR_RGB  )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_BGR  )? POS_GB			:	///< component starts after the GREEN and BLUE components
    							  (tColorOrder == COLOR_RED	 )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_GREEN)? REMOVE_COMPONENT:	///< this type of color has no RED
    							  (tColorOrder == COLOR_BLUE )? REMOVE_COMPONENT:	///< this type of color has no RED
    							  (tColorOrder == COLOR_ALPHA)? REMOVE_COMPONENT:	///< this type of color has no RED
    							  REMOVE_COMPONENT,

    		/// Calculates the offset of the GREEN color component in the color
    		///		This 'switch' statement is calculated at compile time
    		GREEN_OFFSET		= (tColorOrder == COLOR_NONE )? REMOVE_COMPONENT:	///< this type of color has no components
    							  (tColorOrder == COLOR_RGBA )? POS_R			:	///< component starts after the RED component
    							  (tColorOrder == COLOR_BGRA )? POS_B			:	///< component starts after the BLUE component
    							  (tColorOrder == COLOR_ARGB )? POS_RA			:	///< component starts after the GREEN and ALPHA components
    							  (tColorOrder == COLOR_ABGR )? POS_BA			:	///< component starts after the BLUE and ALPHA components
    							  (tColorOrder == COLOR_RGB  )? POS_R			:	///< component starts after the RED component
    							  (tColorOrder == COLOR_BGR  )? POS_B			:	///< component starts after the BLUE component
    							  (tColorOrder == COLOR_RED	 )? REMOVE_COMPONENT:	///< this type of color has no GREEN
    							  (tColorOrder == COLOR_GREEN)? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_BLUE )? REMOVE_COMPONENT:	///< this type of color has no GREEN
    							  (tColorOrder == COLOR_ALPHA)? REMOVE_COMPONENT:	///< this type of color has no GREEN
    							  REMOVE_COMPONENT,

    		/// Calculates the offset of the BLUE color component in the color
    		///		This 'switch' statement is calculated at compile time
    		BLUE_OFFSET			= (tColorOrder == COLOR_NONE )? REMOVE_COMPONENT:	///< this type of color has no components
    							  (tColorOrder == COLOR_RGBA )? POS_RG			:	///< component starts after the RED and GREEN components
    							  (tColorOrder == COLOR_BGRA )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_ARGB )? POS_RGA			:	///< component starts after the RED, GREEN and ALPHA components
    							  (tColorOrder == COLOR_ABGR )? POS_A			:	///< component starts after the ALPHA component
    							  (tColorOrder == COLOR_RGB  )? POS_RG			:	///< component starts after the RED and GREEN components
    							  (tColorOrder == COLOR_BGR  )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_RED	 )? REMOVE_COMPONENT:	///< this type of color has no BLUE
    							  (tColorOrder == COLOR_GREEN)? REMOVE_COMPONENT:	///< this type of color has no BLUE
    							  (tColorOrder == COLOR_BLUE )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_ALPHA)? REMOVE_COMPONENT:	///< this type of color has no BLUE
    							  REMOVE_COMPONENT,

    		/// Calculates the offset of the ALPHA component in the color
    		///		This 'switch' statement is calculated at compile time
    		ALPHA_OFFSET		= (tColorOrder == COLOR_NONE )? REMOVE_COMPONENT:	///< this type of color has no components
    							  (tColorOrder == COLOR_RGBA )? POS_RGB			:	///< component starts after the RED, GREEN and BLUE components
    							  (tColorOrder == COLOR_BGRA )? POS_RGB			:	///< component starts after the RED, GREEN and BLUE components
    							  (tColorOrder == COLOR_ARGB )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_ABGR )? POS_0			:	///< component starts at the beginning of the color
    							  (tColorOrder == COLOR_RGB  )? REMOVE_COMPONENT:	///< this type of color has no ALPHA
    							  (tColorOrder == COLOR_BGR  )? REMOVE_COMPONENT:	///< this type of color has no ALPHA
    							  (tColorOrder == COLOR_RED	 )? REMOVE_COMPONENT:	///< this type of color has no ALPHA
    							  (tColorOrder == COLOR_GREEN)? REMOVE_COMPONENT:	///< this type of color has no ALPHA
    							  (tColorOrder == COLOR_BLUE )? REMOVE_COMPONENT:	///< this type of color has no ALPHA
    							  (tColorOrder == COLOR_ALPHA)? POS_0			:	///< component starts at the beginning of the color
    							  REMOVE_COMPONENT,

    		///
    		/// Set if the current color has an ALPHA channel
    		///
    		HAS_ALPHA			= ALPHA_SIZE	!= 0,

    		///
    		/// Set if the current color IS an ALPHA channel
    		///
    		IS_ALPHA			= RED_SIZE		== 0 &&
    							  GREEN_SIZE	== 0 &&
    							  BLUE_SIZE		== 0 &&
    							  ALPHA_SIZE	!= 0
    	};//EColorConstants

    };//ColorDescription

Currently browsing [pixelconverter.zip] (9,543 bytes) - [constants.h] - (571 bytes)

    //
    // Written by Sander van Rossen
    //	You are free to use this piece of code any way you like
    //
    #pragma once

    //
    // Some constants used to make calculations more readable..
    //	instead of just using some numbers in the calculations which
    //	only make sense to the person who wrote the code in the first place
    //
    enum EConstants
    {
    	BITS_PER_BYTE	= 8,														///< Number of bits per byte
    	BYTES_PER_INT	= sizeof(int),												///< Size of an int in bytes
    	BITS_PER_INT	= (BYTES_PER_INT * BITS_PER_BYTE)							///< Bits per int

    };//EConstants

Currently browsing [pixelconverter.zip] (9,543 bytes) - [convertbits.h] - (3,152 bytes)

    //
    // Written by Sander van Rossen
    //	You are free to use this piece of code any way you like
    //
    #pragma once

    /*!
    	@brief		Convert a number from a specified bit storage type to another
    				specified type with given source and destination offsets
    */
    #define	ConvertBits(inSrcOffset, inSrcSize, inDstOffset, inDstSize, inType)		\
    (																				\
    	(																			\
    		/* Shift it right by the source size (division)						*/	\
    		(																		\
    			(																	\
    				(																\
    					/* Get the source bits, remove all unused bits,			*/	\
    					/* and shift the bits to the start of the integer		*/	\
    					((inType) >> (inSrcOffset)) & ((1 << (inSrcSize))-1)		\
    				/* Shift it left by the destination size (multiplication)	*/	\
    				) << (inDstSize)												\
    			) >> (inSrcSize)													\
    		) +																		\
    		/*																	*/	\
    		/* This is to give the whole calculation more precision				*/	\
    		/* without this a 15 (4-bit) would become 240 (8-bit)				*/	\
    		/* instead of 255 (8-bit)											*/	\
    		/*																	*/	\
    		(																		\
    			(																	\
    				(																\
    					/* Get the source bits, remove all unused bits,			*/	\
    					/* and shift the bits to the start of the integer		*/	\
    					((inType) >> (inSrcOffset)) & ((1 << (inSrcSize))-1)		\
    				/* Shift it left by the destination size (multiplication)	*/	\
    				) << (inDstSize)												\
    			) >> (inSrcSize + inSrcSize)										\
    		) +																		\
    		/*																	*/	\
    		/* This is to give the whole calculation even more precision		*/	\
    		/* without this a 2 (1-bit) would become 252 (8-bit)				*/	\
    		/* instead of 255 (8-bit)											*/	\
    		/*																	*/	\
    		(																		\
    			(																	\
    				(																\
    					/* Get the source bits, remove all unused bits,			*/	\
    					/* and shift the bits to the start of the integer		*/	\
    					((inType) >> (inSrcOffset)) & ((1 << (inSrcSize))-1)		\
    				/* Shift it left by the destination size (multiplication)	*/	\
    				) << (inDstSize)												\
    			) >> (inSrcSize + inSrcSize + inSrcSize)							\
    		) +																		\
    		/*																	*/	\
    		/* This is to give the whole calculation even more precision		*/	\
    		/* without this a 1 (1-bit) would become 224 (8-bit)				*/	\
    		/* instead of 255 (8-bit)											*/	\
    		/*																	*/	\
    		(																		\
    			(																	\
    				(																\
    					/* Get the source bits, remove all unused bits,			*/	\
    					/* and shift the bits to the start of the integer		*/	\
    					((inType) >> (inSrcOffset)) & ((1 << (inSrcSize))-1)		\
    				/* Shift it left by the destination size (multiplication)	*/	\
    				) << (inDstSize)												\
    			) >> (inSrcSize + inSrcSize + inSrcSize + inSrcSize)				\
    		)																		\
    	/* Cap the value to the destination bits								*/	\
    	)  & ((1 << (inDstSize))-1)													\
    /* Shift it left to the destination position								*/	\
    ) << (inDstOffset)																\
    //endof	ConvertBits(inSrcOffset, inSrcSize, inDstOffset, inDstSize, inType

Currently browsing [pixelconverter.zip] (9,543 bytes) - [converter.h] - (6,290 bytes)

    //
    // Written by Sander van Rossen
    //	You are free to use this piece of code any way you like
    //
    #pragma once

    /*!
    	@brief		Main template, this creates the function to convert an array
    				containing colors of type <tSrcColor> to colors of type
    				<tDstColor> and store those in another array..

    	@warning	only use ColorDescription types with this structure!!
    */
    template<typename tSrcColor, typename tDstColor>
    struct ConvertColors
    {
    	enum EConversionConstants
    	{
    		//
    		// The storage sizes of src & dst
    		//
    		SRC_STORAGE			= tSrcColor::COLOR_STORAGE_BITS,
    		DST_STORAGE			= tDstColor::COLOR_STORAGE_BITS,

    		//
    		// The offset of each color component for src & dst
    		//
    		SRC_RED_OFFSET		= tSrcColor::RED_OFFSET		,
    		SRC_GREEN_OFFSET	= tSrcColor::GREEN_OFFSET	,
    		SRC_BLUE_OFFSET		= tSrcColor::BLUE_OFFSET	,
    		SRC_ALPHA_OFFSET	= tSrcColor::ALPHA_OFFSET	,
    		DST_RED_OFFSET		= tDstColor::RED_OFFSET		,
    		DST_GREEN_OFFSET	= tDstColor::GREEN_OFFSET	,
    		DST_BLUE_OFFSET		= tDstColor::BLUE_OFFSET	,
    		DST_ALPHA_OFFSET	= tDstColor::ALPHA_OFFSET	,

    		//
    		// The sizes of each color component for src & dst
    		//
    		SRC_RED_SIZE		= tSrcColor::RED_SIZE		,
    		SRC_GREEN_SIZE		= tSrcColor::GREEN_SIZE		,
    		SRC_BLUE_SIZE		= tSrcColor::BLUE_SIZE		,
    		SRC_ALPHA_SIZE		= tSrcColor::ALPHA_SIZE		,
    		DST_RED_SIZE		= tDstColor::RED_SIZE		,
    		DST_GREEN_SIZE		= tDstColor::GREEN_SIZE		,
    		DST_BLUE_SIZE		= tDstColor::BLUE_SIZE		,
    		DST_ALPHA_SIZE		= tDstColor::ALPHA_SIZE		,

    		///
    		/// The largest storage of the two (src/dst)
    		///
    		LARGEST_STORAGE		= (SRC_STORAGE > DST_STORAGE)
    								? DST_STORAGE : SRC_STORAGE,

    		///
    		/// Size of the most optimal number of color components to process at
    		/// the same time.
    		/// For example, converting 1bit colors to 2bit colors would require
    		/// us to process 4 colors at the same time (4 x 2bit == 8bit == 1byte)
    		/// If we didn't do this, our calculations wouldn't necesarrily end on
    		/// byte-boundaries, and make the calculations *a lot* more complex
    		///
    		CHUNK_SIZE			= (SRC_STORAGE > DST_STORAGE)				?
    								(SRC_STORAGE < BITS_PER_BYTE)			?
    									(SRC_STORAGE / DST_STORAGE)
    										* (BITS_PER_BYTE / SRC_STORAGE)	:
    									(SRC_STORAGE / DST_STORAGE)			:
    								(DST_STORAGE < BITS_PER_BYTE)			?
    									(DST_STORAGE / SRC_STORAGE)
    										* (BITS_PER_BYTE / DST_STORAGE)	:
    									(DST_STORAGE / SRC_STORAGE)			,
    		/// Lets make sure we process at least one color component per chunk
    		CHUNK_LOOPS			= CHUNK_SIZE ? CHUNK_SIZE : 1,

    		/// The size of each step to take in our outer-loop,
    		/// in bytes for the source data
    		SRC_STEP			= (CHUNK_LOOPS * SRC_STORAGE) / BITS_PER_BYTE,

    		/// The size of each step to take in our outer-loop,
    		/// in bytes for the destination data
    		DST_STEP			= (CHUNK_LOOPS * DST_STORAGE) / BITS_PER_BYTE,

    		/// The largest step of the two, to determine the required iterations
    		/// of the loop
    		LARGEST_STEP		= SRC_STEP > DST_STEP ? SRC_STEP : DST_STEP

    	};//enum EConversionConstants

    protected:
    	/*!
    		@brief	This template unrolls the loop used to convert a color-'chunk'
    				This 'chunk' is the most optimal number of colors to process
    				at once this is necesarry to keep calculations simple.
    				If you don't do this you'll have a hard time converting 4 bit
    				pixels to 2 bit pixels simply because multiple source pixels
    				will fit into one 'destination' byte
    	*/
    	struct Chunk
    	{
    		template<cUInt tLoopNum, typename _unused_dummy_ = int>
    		struct Loop
    		{
    			/*!
    				@brief	Some constants which are required for our calculations
    			*/
    			enum ELoopConstants
    			{
    				ELEMENT			= (tLoopNum - 1),
    				DST_BIT_OFFSET	= (ELEMENT * DST_STORAGE) & (BITS_PER_INT-1),
    				SRC_BYTE_OFFSET	= (ELEMENT * SRC_STORAGE) /  BITS_PER_BYTE,
    				SRC_BIT_OFFSET	= (ELEMENT * SRC_STORAGE) & (BITS_PER_BYTE-1),
    			};//enum ELoopConstants

    			INLINE static cUInt CalcElement(rcpcUChar	inType,
    											rcUInt		inSrcPos)
    			{
    				//
    				// Convert a single color from our source to our destination
    				//
    				return
    					  ConvertBits((SRC_RED_OFFSET	+       SRC_BIT_OFFSET ),
    								   SRC_RED_SIZE		,
    								  (DST_RED_OFFSET	+       DST_BIT_OFFSET ),
    								   DST_RED_SIZE		,
    								  (rUInt)(inType[inSrcPos + SRC_BYTE_OFFSET]))
    					| ConvertBits((SRC_GREEN_OFFSET	+       SRC_BIT_OFFSET ),
    								   SRC_GREEN_SIZE	,
    								  (DST_GREEN_OFFSET	+       DST_BIT_OFFSET ),
    			 					   DST_GREEN_SIZE	,
    								  (rUInt)(inType[inSrcPos + SRC_BYTE_OFFSET]))
    					| ConvertBits((SRC_BLUE_OFFSET	+       SRC_BIT_OFFSET ),
    								   SRC_BLUE_SIZE	,
    								  (DST_BLUE_OFFSET	+       DST_BIT_OFFSET ),
    								   DST_BLUE_SIZE	,
    								  (rUInt)(inType[inSrcPos + SRC_BYTE_OFFSET]))
    					| ConvertBits((SRC_ALPHA_OFFSET	+       SRC_BIT_OFFSET ),
    								   SRC_ALPHA_SIZE	,
    								  (DST_ALPHA_OFFSET	+       DST_BIT_OFFSET ),
    								   DST_ALPHA_SIZE	,
    								  (rUInt)(inType[inSrcPos + SRC_BYTE_OFFSET]))

    				//
    				// Add the next color to the destination...
    				//
    					| Loop<tLoopNum - 1,int>::CalcElement(inType, inSrcPos);
    			}
    		};//struct Loop

    		/*!
    			@brief	Used to stop the template loop
    		*/
    		template<>
    		struct Loop<0, int>
    		{
    			INLINE static cUInt CalcElement(rcpcUChar,rcUInt) { return 0; }
    		};//struct Loop

    	};//struct Chunk

    public:
    	/*!
    		@brief	Do the actual color conversion of the colors
    	*/
    	static void Convert(rcpUChar		outType,
    						rcpcUChar		inType,
    						rcUInt			inByteSize)
    	{
    		//
    		// Divide the size of the source by the size of the
    		// conversion color chunks
    		// (block of colors which are converted in one go)
    		//
    		cUInt	loop_size		= inByteSize / LARGEST_STEP;
    		for (UInt counter = 0; counter < loop_size; counter++)
    		{
    			//
    			// Calculate the source and destination positions of the input
    			// and output arrays
    			//
    			cUInt		src_pos		= counter * SRC_STEP;
    			cUInt		dst_pos		= counter * DST_STEP;

    			//
    			// Convert our chunk of colors
    			//
    			(rUInt)(outType[dst_pos]) =
    						Chunk::Loop<CHUNK_LOOPS>::
    									CalcElement(inType, src_pos);
    		}
    	}

    };//struct ConvertColors

Currently browsing [pixelconverter.zip] (9,543 bytes) - [main.cpp] - (2,959 bytes)

    //
    // Written by Sander van Rossen
    //	You are free to use this piece of code any way you like
    //
    #include "settings.h"
    #include "types.h"
    #include "constants.h"
    #include "convertbits.h"
    #include "colordescription.h"
    #include "converter.h"

    //
    // All color bit sizes must be byte aligned, meaning that you can either
    // divide the size of the color by 8, or 8 can be divided by the
    // size of the color..
    //
    // In it's current form the total size of the color is limited to 32bit
    //
    // ----------------------------------------------------------------------
    //						  color-type    R G B A  x
    typedef ColorDescription< COLOR_ABGR ,  8,8,8,8, 0 	> TYPE_ABGR_32_8888;
    typedef ColorDescription< COLOR_ARGB ,  8,8,8,8, 0	> TYPE_ARGB_32_8888;
    typedef ColorDescription< COLOR_BGRA ,  8,8,8,8, 0	> TYPE_BGRA_32_8888;
    typedef ColorDescription< COLOR_RGBA ,  8,8,8,8, 0	> TYPE_RGBA_32_8888;
    typedef ColorDescription< COLOR_RGB  ,  8,8,8,0, 8	> TYPE_RGB_32_888;
    typedef ColorDescription< COLOR_RGB  ,  8,8,8,0, 0	> TYPE_RGB_24_888;
    typedef ColorDescription< COLOR_RGBA ,  4,4,4,4, 0	> TYPE_RGBA_16_4444;
    typedef ColorDescription< COLOR_RGBA ,  5,5,5,1, 0	> TYPE_RGBA_16_5551;
    typedef ColorDescription< COLOR_RGBA ,  5,5,5,0, 1	> TYPE_RGB_16_555;
    typedef ColorDescription< COLOR_RGB  ,  5,6,5,0, 0	> TYPE_RGB_16_565;
    typedef ColorDescription< COLOR_ALPHA,  0,0,0,8, 0	> TYPE_ALPHA_8;
    typedef ColorDescription< COLOR_ALPHA,  0,0,0,4, 0	> TYPE_ALPHA_4;
    typedef ColorDescription< COLOR_ALPHA,  0,0,0,2, 0	> TYPE_ALPHA_2;
    typedef ColorDescription< COLOR_ALPHA,  0,0,0,1, 0	> TYPE_ALPHA_1;

    #define src_test	TYPE_ARGB_32_8888
    #define dst_test	TYPE_ALPHA_8

    #define	BYTE_ALIGN(x) (((UInt)x + (BITS_PER_BYTE-1)) / BITS_PER_BYTE)

    enum
    {
    	width		= 256,
    	height		= 256,
    	num_pixels	= width * height,
    	src_size	= BYTE_ALIGN(num_pixels * src_test::COLOR_STORAGE_BITS),
    	dst_size	= BYTE_ALIGN(num_pixels * dst_test::COLOR_STORAGE_BITS)

    };

    void main(void)
    {
    	UChar	input_buffer	[src_size];
    	UChar	output_buffer	[dst_size];
    	int		i;

    	// clear output buffer
    	for (i = 0;i < dst_size;i++) output_buffer[i]	= 0;

    	int j = (src_size - (src_size%15));
    	// fill input buffer with predictable junk
    	for (i = 0;i < j;i+=16)
    	{
    		input_buffer[i +  0] = 0x01;
    		input_buffer[i +  1] = 0x12;
    		input_buffer[i +  2] = 0x23;
    		input_buffer[i +  3] = 0x34;
    		input_buffer[i +  4] = 0x45;
    		input_buffer[i +  5] = 0x56;
    		input_buffer[i +  6] = 0x67;
    		input_buffer[i +  7] = 0x78;
    		input_buffer[i +  8] = 0x89;
    		input_buffer[i +  9] = 0x9A;
    		input_buffer[i + 10] = 0xAB;
    		input_buffer[i + 11] = 0xBC;
    		input_buffer[i + 12] = 0xCD;
    		input_buffer[i + 13] = 0xDE;
    		input_buffer[i + 14] = 0xEF;
    		input_buffer[i + 15] = 0xF0;
    	}
    	for (i=j;i < src_size;i++) input_buffer[i] = 0xFF;

    	// convert the colors
    	ConvertColors<src_test, dst_test>::
    		Convert(output_buffer, input_buffer, src_size);
    }

Currently browsing [pixelconverter.zip] (9,543 bytes) - [settings.h] - (1,364 bytes)

    //
    // Written by Sander van Rossen
    //	You are free to use this piece of code any way you like
    //
    #pragma once

    //
    // Some microsoft visual c++ specific compiler settings
    //
    #ifdef _MSC_VER

    //
    // Disable the following warnings:
    //
    #	pragma warning( disable : 4786 ) // 'identifier' : identifier was truncated to 'number' characters in the debug information
    #	pragma warning( disable : 4284 ) // return type for 'identifier::operator ->' is not a UDT or reference to a UDT. Will produce errors if applied using infix notation
    #	pragma warning( disable : 4250 ) // 'class1' : inherits 'class2::member' via dominance
    #	pragma warning( disable : 4002 ) // too many actual parameters for macro 'identifier'
    #	pragma warning( disable : 4311 ) // 'variable' : pointer truncation from 'type' to 'type'

    //
    // warning 4786 "disabled but still shows warning" bug in msvc6 workaround
    // ..god knows why this works
    //
    class  msVC6_4786WorkAround { public: msVC6_4786WorkAround(){} };
    static msVC6_4786WorkAround WowIWonderWhatCrapCodeMustBeInTheCompilerToMakeThisWorkaroundWork;

    //
    // Set the following optimalisations on
    //
    #	pragma inline_depth( 255 )
    #	pragma inline_recursion( on )
    #	define INLINE __forceinline

    #else//!_MSC_VER_

    //
    // Set the following optimalisations on
    //
    #	define	INLINE	inline

    #endif

Currently browsing [pixelconverter.zip] (9,543 bytes) - [types.h] - (1,243 bytes)

    //
    // Written by Sander van Rossen
    //	You are free to use this piece of code any way you like
    //
    #pragma once

    /*!
    	@brief		Declare an alias named <tAliasName> for the type <tTypeName>
    */
    #define DECLARE_ALIAS(tTypeName, tAliasName)					\
    	typedef		  tTypeName				tAliasName;				\
    //endof DECLARE_ALIAS(inType, outType)

    /*!
    	@brief		Declare the base hungarian names for <tTypeName>
    */
    #define DECLARE_HUNGARIAN(tTypeName)							\
    	typedef		  tTypeName	  &			r##tTypeName;			\
    	typedef		  tTypeName*			p##tTypeName;			\
    	typedef		  tTypeName*const		cp##tTypeName;			\
    	typedef		  tTypeName*const&		rcp##tTypeName;			\
    	typedef	const tTypeName				c##tTypeName;			\
    	typedef	const tTypeName	  &			rc##tTypeName;			\
    	typedef	const tTypeName*			pc##tTypeName;			\
    	typedef	const tTypeName*const		cpc##tTypeName;			\
    	typedef	const tTypeName*const&		rcpc##tTypeName;		\
    //endof DECLARE_HUNGARIAN(inType)

    DECLARE_ALIAS(unsigned char, UChar);	// Create UChar alias for unsigned chars
    DECLARE_ALIAS(unsigned int,  UInt);		// Create UInt alias for unsigned ints
    DECLARE_HUNGARIAN(UChar);				// Declare all hungarian names for UChar
    DECLARE_HUNGARIAN(UInt);				// Declare all hungarian names for UInt

The zip file viewer built into the Developer Toolbox made use of the zlib library, as well as the zlibdll source additions.

Copyright 1999-2008 (C) FLIPCODE.COM and/or the original content author(s). All rights reserved.
Please read our Terms, Conditions, and Privacy information.