CrystalSpace

Public API Reference

csgfx/rgbpixel.h

Go to the documentation of this file.
00001 /*
00002     Copyright (C) 1998 by Jorrit Tyberghein
00003     Contributions made by Ivan Avramovic <[email protected]>
00004 
00005     This library is free software; you can redistribute it and/or
00006     modify it under the terms of the GNU Library General Public
00007     License as published by the Free Software Foundation; either
00008     version 2 of the License, or (at your option) any later version.
00009 
00010     This library is distributed in the hope that it will be useful,
00011     but WITHOUT ANY WARRANTY; without even the implied warranty of
00012     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013     Library General Public License for more details.
00014 
00015     You should have received a copy of the GNU Library General Public
00016     License along with this library; if not, write to the Free
00017     Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00018 */
00019 
00026 //-----------------------------------------------------------------------------
00027 // Implementation Note: Eric Sunshine <[email protected]>      1999/02/09
00028 //
00029 // Certain portions of the Crystal Space code have strict requirements about
00030 // the sizes of the structures csRGBcolor and csRGBpixel.  In particular, some
00031 // pieces of code make these assumptions:
00032 //
00033 //    sizeof(csRGBcolor) == 3  (byte:rgb)
00034 //    sizeof(csRGBpixel) == 4  (byte:rgb + byte:alpha)
00035 //
00036 // Originally, csRGBpixel was implemented as a subclasse of csRGBcolor and
00037 // added a byte-sized "alpha" variable.  Thus, the original implementation made
00038 // the assumption that the compiler would not pad out the csRGBcolor structure.
00039 //
00040 // Unfortunately in some environments (such as the NextStep compiler on M68K
00041 // hardware) the compiler does pad csRGBcolor thus breaking the original
00042 // assumptions about structure sizes.  In such cases, csRGBcolor is padded out
00043 // to 4 bytes instead of 3 and csRGBpixel is padded out to 6 bytes instead of
00044 // 4.  This padding results in problems in code which makes assumptions about
00045 // the sizes of each structure.  In practice, problems were observed in code
00046 // which expected csRGBpixel to be 4 bytes.
00047 //
00048 // To work around this problem, csRGBpixel has been re-implemented so that it
00049 // is no longer derived from csRGBcolor.  An unfortunate side-effect of this
00050 // re-implementation is that code is no longer inherited, and is thus
00051 // duplicated in each class.  However, except for this minor point, the size of
00052 // each structure should now be more stable between various compilers.
00053 //-----------------------------------------------------------------------------
00054 
00055 #ifndef __CS_RGBPIXEL_H__
00056 #define __CS_RGBPIXEL_H__
00057 
00058 #include "csextern.h"
00059 #include "csutil/comparator.h"
00060 
00061 
00066 CS_STRUCT_ALIGN_4BYTE_BEGIN
00067 struct csRGBcolor
00068 {
00070   unsigned char red, green, blue;
00072   csRGBcolor () : red(0), green(0), blue(0) {}
00074   csRGBcolor (unsigned char r, unsigned char g, unsigned char b) :
00075     red(r), green(g), blue(b) {}
00077   void Set (unsigned char r, unsigned char g, unsigned char b)
00078   { red = r; green = g; blue = b; }
00080   bool operator == (const csRGBcolor& c) const
00081   { return (c.red == red) && (c.green == green) && (c.blue == blue); }
00083   bool operator != (const csRGBcolor& c) const
00084   { return !operator == (c); }
00086   csRGBcolor operator + (const csRGBcolor& c) const
00087   { return csRGBcolor (
00088     (unsigned char)(c.red + red),
00089     (unsigned char)(c.green + green),
00090     (unsigned char)(c.blue + blue)); }
00094   void UnsafeAdd (const csRGBcolor& c)
00095   {
00096     red   = (unsigned char)(red   + c.red  );
00097     green = (unsigned char)(green + c.green);
00098     blue  = (unsigned char)(blue  + c.blue );
00099   }
00103   void SafeAdd (const csRGBcolor& c)
00104   {
00105     int color = red + c.red;
00106     red   = (unsigned char)(color > 255 ? 255 : color);
00107     color = green + c.green;
00108     green = (unsigned char)(color > 255 ? 255 : color);
00109     color = blue + c.blue;
00110     blue  = (unsigned char)(color > 255 ? 255 : color);
00111   }
00112 } CS_STRUCT_ALIGN_4BYTE_END;
00113 
00114 
00118 template<>
00119 class csComparator<csRGBcolor, csRGBcolor>
00120 {
00121 public:
00122   static int Compare (csRGBcolor const& r1, csRGBcolor const& r2)
00123   {
00124     if (r1.red != r2.red)
00125       return (int)r1.red - (int)r2.red;
00126     if (r1.green != r2.green)
00127       return (int)r1.green - (int)r2.green;
00128     if (r1.blue != r2.blue)
00129       return (int)r1.blue - (int)r2.blue;
00130     return 0;
00131   }
00132 };
00133 
00138 template<>
00139 class csComparator<csRGBcolor*, csRGBcolor*> 
00140 {
00141 public:
00142   static int Compare (csRGBcolor* const& r1, csRGBcolor* const& r2)
00143   { return csComparator<csRGBcolor, csRGBcolor>::Compare (*r1, *r2); }
00144 };
00145 
00151 CS_STRUCT_ALIGN_4BYTE_BEGIN
00152 struct csRGBpixel
00153 {
00155   unsigned char red, green, blue, alpha;
00157   csRGBpixel () : red(0), green(0), blue(0), alpha(255) {}
00159   csRGBpixel (const csRGBpixel& p) :
00160     red (p.red), green (p.green), blue (p.blue), alpha (p.alpha) {}
00162   csRGBpixel (const csRGBcolor& c) :
00163     red (c.red), green (c.green), blue (c.blue), alpha (255) {}
00165   csRGBpixel (int r, int g, int b, int a = 255) :
00166     red ((unsigned char)r),
00167     green ((unsigned char)g),
00168     blue ((unsigned char)b),
00169     alpha ((unsigned char)a) {}
00171   bool operator == (const csRGBcolor& c) const
00172   { return (c.red == red) && (c.green == green) && (c.blue == blue); }
00174   bool operator == (const csRGBpixel& p) const
00175   { return (p.red == red) && (p.green == green) && (p.blue == blue); }
00177   bool operator != (const csRGBcolor& c) const
00178   { return !operator == (c); }
00183   bool operator != (const csRGBpixel& p) const
00184   { return !operator == (p); }
00186   operator csRGBcolor () const
00187   { return csRGBcolor (red, green, blue); }
00189   bool eq (const csRGBpixel& p) const
00190   { return operator==(p); }
00192   int Intensity () const
00193   { return (red + green + blue) / 3; }
00195   unsigned char Luminance () const
00196   {
00197     return (unsigned char)(((int)red*30 + (int)green*59 + (int)blue*11) / 100);
00198   }
00200   void Set (const int r, const int g, const int b, const int a = 255)
00201   {
00202     red = (unsigned char)r;
00203     green = (unsigned char)g;
00204     blue = (unsigned char)b;
00205     alpha = (unsigned char)a;
00206   }
00208   void Set (const csRGBpixel& p)
00209   { red = p.red; green = p.green; blue = p.blue; alpha = p.alpha; }
00211   void operator += (const csRGBcolor& c)
00212   {
00213       red   = (unsigned char)(red   + c.red  );
00214       green = (unsigned char)(green + c.green);
00215       blue  = (unsigned char)(blue  + c.blue );
00216   }
00221   void UnsafeAdd (const csRGBpixel& c)
00222   {
00223     red   = (unsigned char)(red   + c.red  );
00224     green = (unsigned char)(green + c.green);
00225     blue  = (unsigned char)(blue  + c.blue );
00226   }
00231   void SafeAdd (const csRGBpixel& c)
00232   {
00233     int color = red + c.red;
00234     red   = (unsigned char)(color > 255 ? 255 : color);
00235     color = green + c.green;
00236     green = (unsigned char)(color > 255 ? 255 : color);
00237     color = blue + c.blue;
00238     blue  = (unsigned char)(color > 255 ? 255 : color);
00239   }
00240 } CS_STRUCT_ALIGN_4BYTE_END;
00241 
00242 
00249 
00250 #define R_COEF          173
00252 #define G_COEF          242
00254 #define B_COEF          107
00255 
00258 
00259 #define R_COEF_SQ       299
00261 #define G_COEF_SQ       587
00263 #define B_COEF_SQ       114
00264 
00268 #endif // __CS_RGBPIXEL_H__

Generated for Crystal Space by doxygen 1.4.7