core/vgui/vgui_pixel.cxx
Go to the documentation of this file.
00001 // This is core/vgui/vgui_pixel.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 // \author fsm
00008 // \brief  See vgui_pixel.h for a description of this file
00009 
00010 
00011 #include "vgui_pixel.h"
00012 #include <vgui/vgui_gl.h>
00013 
00014 //------------------------------------------------------------------------------
00015 
00016 template <int M, int N> struct vgui_pixel_assert;
00017 VCL_DEFINE_SPECIALIZATION struct vgui_pixel_assert<2, 2> { };
00018 VCL_DEFINE_SPECIALIZATION struct vgui_pixel_assert<3, 3> { };
00019 VCL_DEFINE_SPECIALIZATION struct vgui_pixel_assert<4, 4> { };
00020 struct vgui_pixel_generates_no_code
00021 {
00022 #define as(T, sz) vgui_pixel_assert<sizeof(T), sz> T##_is_##sz
00023   as(vgui_pixel_rgb888, 3);
00024   as(vgui_pixel_bgr888, 3);
00025   as(vgui_pixel_rgb565, 2);
00026   as(vgui_pixel_bgra5551, 2);
00027   as(vgui_pixel_rgba8888, 4);
00028   as(vgui_pixel_abgr8888, 4);
00029   as(vgui_pixel_bgra8888, 4);
00030 #undef as
00031 };
00032 
00033 //------------------------------------------------------------------------------
00034 
00035 // 200201 AWF changed from template magic to an explicit writing out of
00036 //            the 40 conversions.  It's not a template, because the
00037 //            bodies are different in each one.
00038 
00039 
00040 //: Set an int of unknown size to all-bits-one
00041 #define SET_FF(x) x = 0; x = ~x
00042 
00043 //: Clamp float to 0..255
00044 static inline
00045 unsigned int clamp(double f)
00046 {
00047   if (f > 255) return 255u;
00048   else if (f < 0) return 0u;
00049   else return (unsigned int)f;
00050 }
00051 
00052 //: This macro is used to generate a "vgui_pixel_convert_span(S*, D*)" function with body "Code"
00053 // Within Code, s is a reference to the source pixel, d to the destination.
00054 // Remember, vgui_pixel_convert_span is not a function template -- each overload has
00055 // rather different code.
00056 #define VGUI_PIXEL_CONVERT_SPAN_DO(S, D, Code) \
00057   void vgui_pixel_convert_span(S const *src, D *dst, unsigned size) { \
00058     for (unsigned i=0; i<size; ++i) { \
00059       S const& s = src[i]; \
00060       D      & d = dst[i]; \
00061       Code; \
00062     }\
00063   }
00064 
00065 // SrcType, DstType, Code
00066 VGUI_PIXEL_CONVERT_SPAN_DO(GLubyte, vgui_pixel_rgb888,   { d.R = d.G = d.B = s; } );
00067 VGUI_PIXEL_CONVERT_SPAN_DO(GLubyte, vgui_pixel_bgr888,   { d.R = d.G = d.B = s; } );
00068 VGUI_PIXEL_CONVERT_SPAN_DO(GLubyte, vgui_pixel_rgb565,   { d.R = d.B = (s >> 3); d.G = (s >> 2); } );
00069 VGUI_PIXEL_CONVERT_SPAN_DO(GLubyte, vgui_pixel_bgra5551, { d.R = d.G = d.B = (s>>3); SET_FF(d.A); } );
00070 VGUI_PIXEL_CONVERT_SPAN_DO(GLubyte, vgui_pixel_rgba8888, { d.R = d.G = d.B = s; SET_FF(d.A); } );
00071 VGUI_PIXEL_CONVERT_SPAN_DO(GLubyte, vgui_pixel_abgr8888, { d.R = d.G = d.B = s; SET_FF(d.A); } );
00072 VGUI_PIXEL_CONVERT_SPAN_DO(GLubyte, vgui_pixel_bgra8888, { d.R = d.G = d.B = s; SET_FF(d.A); } );
00073 
00074 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgb888, vgui_pixel_rgb888,   { d = s; });
00075 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgb888, vgui_pixel_bgr888,   { d.R = s.R; d.G = s.G; d.B = s.B; })
00076 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgb888, vgui_pixel_rgb565,   { d.R = s.R>>3; d.G = s.G>>2; d.B = s.B>>3; })
00077 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgb888, vgui_pixel_bgra5551, { d.R = s.R>>3; d.G = s.G>>3; d.B = s.B>>3; SET_FF(d.A); })
00078 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgb888, vgui_pixel_rgba8888, { d.R = s.R; d.G = s.G; d.B = s.B; SET_FF(d.A); })
00079 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgb888, vgui_pixel_abgr8888, { d.R = s.R; d.G = s.G; d.B = s.B; SET_FF(d.A); })
00080 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgb888, vgui_pixel_bgra8888, { d.R = s.R; d.G = s.G; d.B = s.B; SET_FF(d.A); })
00081 
00082 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgba8888, vgui_pixel_rgb888,   { d.R = s.R;    d.G = s.G;    d.B = s.B; })
00083 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgba8888, vgui_pixel_bgr888,   { d.R = s.R;    d.G = s.G;    d.B = s.B; })
00084 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgba8888, vgui_pixel_rgb565,   { d.R = s.R>>3; d.G = s.G>>2; d.B = s.B>>3; })
00085 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgba8888, vgui_pixel_bgra5551, { d.R = s.R>>3; d.G = s.G>>3; d.B = s.B>>3; })
00086 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgba8888, vgui_pixel_rgba8888, { d = s; })
00087 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgba8888, vgui_pixel_abgr8888, { d.R = s.R;    d.G = s.G;    d.B = s.B; d.A = s.A; })
00088 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgba8888, vgui_pixel_bgra8888, { d.R = s.R;    d.G = s.G;    d.B = s.B; d.A = s.A; })
00089 
00090 VGUI_PIXEL_CONVERT_SPAN_DO(float, vgui_pixel_rgb888,   { d.R = d.G = d.B = clamp(s); })
00091 VGUI_PIXEL_CONVERT_SPAN_DO(float, vgui_pixel_bgr888,   { d.R = d.G = d.B = clamp(s); })
00092 VGUI_PIXEL_CONVERT_SPAN_DO(float, vgui_pixel_rgb565,   { int v = clamp(s); d.R = d.B = v>>3; d.G = v>>2; })
00093 VGUI_PIXEL_CONVERT_SPAN_DO(float, vgui_pixel_bgra5551, { d.R = d.G = d.B = clamp(s)>>3; SET_FF(d.A); })
00094 VGUI_PIXEL_CONVERT_SPAN_DO(float, vgui_pixel_rgba8888, { d.R = d.G = d.B = clamp(s); SET_FF(d.A); })
00095 VGUI_PIXEL_CONVERT_SPAN_DO(float, vgui_pixel_abgr8888, { d.R = d.G = d.B = clamp(s); SET_FF(d.A); })
00096 VGUI_PIXEL_CONVERT_SPAN_DO(float, vgui_pixel_bgra8888, { d.R = d.G = d.B = clamp(s); SET_FF(d.A); })
00097 
00098 VGUI_PIXEL_CONVERT_SPAN_DO(double, vgui_pixel_rgb888,   { d.R = d.G = d.B = clamp(s); })
00099 VGUI_PIXEL_CONVERT_SPAN_DO(double, vgui_pixel_bgr888,   { d.R = d.G = d.B = clamp(s); })
00100 VGUI_PIXEL_CONVERT_SPAN_DO(double, vgui_pixel_rgb565,   { int v = clamp(s); d.R = d.B = v>>3; d.G = v>>2; })
00101 VGUI_PIXEL_CONVERT_SPAN_DO(double, vgui_pixel_bgra5551, { d.R = d.G = d.B = clamp(s)>>3; SET_FF(d.A); })
00102 VGUI_PIXEL_CONVERT_SPAN_DO(double, vgui_pixel_rgba8888, { d.R = d.G = d.B = clamp(s); SET_FF(d.A); })
00103 VGUI_PIXEL_CONVERT_SPAN_DO(double, vgui_pixel_abgr8888, { d.R = d.G = d.B = clamp(s); SET_FF(d.A); })
00104 VGUI_PIXEL_CONVERT_SPAN_DO(double, vgui_pixel_bgra8888, { d.R = d.G = d.B = clamp(s); SET_FF(d.A); })
00105 
00106 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgbfloat, vgui_pixel_rgb888,  {d.R=clamp(s.R); d.G = clamp(s.G); d.B = clamp(s.B); })
00107 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgbfloat, vgui_pixel_bgr888,  {d.R=clamp(s.R); d.G = clamp(s.G); d.B = clamp(s.B); })
00108 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgbfloat, vgui_pixel_rgb565,  {d.R=clamp(s.R)>>3;d.G =clamp(s.G)>>2; d.B = clamp(s.B)>>3; })
00109 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgbfloat, vgui_pixel_bgra5551,{d.R=clamp(s.R)>>3;d.G =clamp(s.G)>>3; d.B = clamp(s.B)>>3; })
00110 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgbfloat, vgui_pixel_rgba8888,{d.R=clamp(s.R);d.G=clamp(s.G);d.B=clamp(s.B); SET_FF(d.A); })
00111 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgbfloat, vgui_pixel_abgr8888,{d.R=clamp(s.R);d.G=clamp(s.G);d.B=clamp(s.B); SET_FF(d.A); })
00112 VGUI_PIXEL_CONVERT_SPAN_DO(vgui_pixel_rgbfloat, vgui_pixel_bgra8888,{d.R=clamp(s.R);d.G=clamp(s.G);d.B=clamp(s.B); SET_FF(d.A); })