rgba.h

Go to the documentation of this file.
00001 
00005 /* Copyright, 2000 Nevrax Ltd.
00006  *
00007  * This file is part of NEVRAX NEL.
00008  * NEVRAX NEL is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2, or (at your option)
00011  * any later version.
00012 
00013  * NEVRAX NEL is distributed in the hope that it will be useful, but
00014  * WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00016  * General Public License for more details.
00017 
00018  * You should have received a copy of the GNU General Public License
00019  * along with NEVRAX NEL; see the file COPYING. If not, write to the
00020  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00021  * MA 02111-1307, USA.
00022  */
00023 
00024 #ifndef NL_RGBA_H
00025 #define NL_RGBA_H
00026 
00027 #include <algorithm>
00028 
00029 #include "types_nl.h"
00030 #include "common.h"
00031 
00032 
00033 namespace NLMISC
00034 {
00035 
00036 class   IStream;
00037 
00044 class CRGBA
00045 {
00046 public:
00047 
00049     CRGBA() {}
00050 
00058     CRGBA(uint8 r, uint8 g, uint8 b, uint8 a=255) :
00059         R(r), G(g), B(b), A(a) {}
00060 
00064     void    setPacked(uint packed)
00065     {
00066         R= (packed>>24)&255;
00067         G= (packed>>16)&255;
00068         B= (packed>>8)&255;
00069         A= packed & 255;
00070     }
00071 
00075     uint    getPacked() const {return ((uint)R<<24) + ((uint)G<<16) + ((uint)B<<8) + A;}
00076 
00080     bool    operator<(CRGBA c) const {return getPacked()<c.getPacked();}
00084     bool    operator!=(CRGBA c) const {return !(*this==c);}
00085 
00089     bool    operator==(CRGBA c) const
00090         {return R==c.R && G==c.G && B==c.B && A==c.A;}
00091 
00096     void    serial (class NLMISC::IStream &f);
00097 
00104     void blendFromui(CRGBA c0, CRGBA c1, uint coef) // coef must be in [0,256]
00105     {
00106         uint    a1 = coef;
00107         uint    a2 = 256-a1;
00108         R = uint8((c0.R*a2 + c1.R*a1) >>8);
00109         G = uint8((c0.G*a2 + c1.G*a1) >>8);
00110         B = uint8((c0.B*a2 + c1.B*a1) >>8);
00111         A = uint8((c0.A*a2 + c1.A*a1) >>8);
00112     }
00113 
00119     void    modulateFromui (CRGBA c0, uint a)
00120     {
00121         R = uint8((c0.R*a) >>8);
00122         G = uint8((c0.G*a) >>8);
00123         B = uint8((c0.B*a) >>8);
00124         A = uint8((c0.A*a) >>8);
00125     }
00126 
00127 
00133     void    modulateFromColor (CRGBA c0, CRGBA c1)
00134     {
00135         R = (c0.R*c1.R) >>8;
00136         G = (c0.G*c1.G) >>8;
00137         B = (c0.B*c1.B) >>8;
00138         A = (c0.A*c1.A) >>8;
00139     }
00140 
00141 
00149     void    set (uint8 r, uint8 g, uint8 b, uint8 a=255);
00150 
00154     uint16 get565 () const
00155     {
00156         return ((uint16)(R&0xf8)<<8) | ((uint16)(G&0xfc)<<3) | (uint16)(B>>3);
00157     }
00158 
00162     void    set565(uint16 col)
00163     {
00164         // unpack.
00165         R= col>>11;
00166         G= (col>>5)&0x3F;
00167         B= (col)&0x1F;
00168         // to 8 bits.
00169         R= (R<<3) + (R>>2);
00170         G= (G<<2) + (G>>4);
00171         B= (B<<3) + (B>>2);
00172     }
00173 
00174 
00178     void    avg2(CRGBA a, CRGBA b)
00179     {
00180         R= ((uint)a.R+(uint)b.R)>>1;
00181         G= ((uint)a.G+(uint)b.G)>>1;
00182         B= ((uint)a.B+(uint)b.B)>>1;
00183         A= ((uint)a.A+(uint)b.A)>>1;
00184     }
00185 
00190     void    avg4(CRGBA a, CRGBA b, CRGBA c, CRGBA d)
00191     {
00192         R= ((uint)a.R+(uint)b.R+(uint)c.R+(uint)d.R+ 1)>>2;
00193         G= ((uint)a.G+(uint)b.G+(uint)c.G+(uint)d.G+ 1)>>2;
00194         B= ((uint)a.B+(uint)b.B+(uint)c.B+(uint)d.B+ 1)>>2;
00195         A= ((uint)a.A+(uint)b.A+(uint)c.A+(uint)d.A+ 1)>>2;
00196     }
00197 
00201     void    add(CRGBA c0, CRGBA c1)
00202     {
00203         uint    r,g,b,a;
00204         r= c0.R + c1.R; r= std::min(r, 255U);   R= (uint8)r;
00205         g= c0.G + c1.G; g= std::min(g, 255U);   G= (uint8)g;
00206         b= c0.B + c1.B; b= std::min(b, 255U);   B= (uint8)b;
00207         a= c0.A + c1.A; a= std::min(a, 255U);   A= (uint8)a;
00208     }
00209 
00213     void    sub(CRGBA c0, CRGBA c1)
00214     {
00215         sint    r,g,b,a;
00216         r= c0.R - c1.R; r= std::max(r, 0);  R= (uint8)r;
00217         g= c0.G - c1.G; g= std::max(g, 0);  G= (uint8)g;
00218         b= c0.B - c1.B; b= std::max(b, 0);  B= (uint8)b;
00219         a= c0.A - c1.A; a= std::max(a, 0);  A= (uint8)a;
00220     }
00221 
00222 
00224     // @{
00225 
00227     void    blendFromuiRGBOnly(CRGBA c0, CRGBA c1, uint coef) // coef must be in [0,256]
00228     {
00229         uint    a1 = coef;
00230         uint    a2 = 256-a1;
00231         R = uint8((c0.R*a2 + c1.R*a1) >>8);
00232         G = uint8((c0.G*a2 + c1.G*a1) >>8);
00233         B = uint8((c0.B*a2 + c1.B*a1) >>8);
00234     }
00236     void    modulateFromuiRGBOnly(CRGBA c0, uint a)
00237     {
00238         R = uint8((c0.R*a) >>8);
00239         G = uint8((c0.G*a) >>8);
00240         B = uint8((c0.B*a) >>8);
00241     }
00243     void    modulateFromColorRGBOnly(CRGBA c0, CRGBA c1)
00244     {
00245         R = (c0.R*c1.R) >>8;
00246         G = (c0.G*c1.G) >>8;
00247         B = (c0.B*c1.B) >>8;
00248     }
00250     void    avg2RGBOnly(CRGBA a, CRGBA b)
00251     {
00252         R= ((uint)a.R+(uint)b.R)>>1;
00253         G= ((uint)a.G+(uint)b.G)>>1;
00254         B= ((uint)a.B+(uint)b.B)>>1;
00255     }
00257     void    avg4RGBOnly(CRGBA a, CRGBA b, CRGBA c, CRGBA d)
00258     {
00259         R= ((uint)a.R+(uint)b.R+(uint)c.R+(uint)d.R+ 1)>>2;
00260         G= ((uint)a.G+(uint)b.G+(uint)c.G+(uint)d.G+ 1)>>2;
00261         B= ((uint)a.B+(uint)b.B+(uint)c.B+(uint)d.B+ 1)>>2;
00262     }
00264     void    addRGBOnly(CRGBA c0, CRGBA c1)
00265     {
00266         uint    r,g,b;
00267         r= c0.R + c1.R; r= std::min(r, 255U);   R= (uint8)r;
00268         g= c0.G + c1.G; g= std::min(g, 255U);   G= (uint8)g;
00269         b= c0.B + c1.B; b= std::min(b, 255U);   B= (uint8)b;
00270     }
00272     void    subRGBOnly(CRGBA c0, CRGBA c1)
00273     {
00274         sint    r,g,b;
00275         r= c0.R - c1.R; r= std::max(r, 0);  R= (uint8)r;
00276         g= c0.G - c1.G; g= std::max(g, 0);  G= (uint8)g;
00277         b= c0.B - c1.B; b= std::max(b, 0);  B= (uint8)b;
00278     }
00279 
00280 
00281 
00282     // @}
00283 
00285 
00286 
00295         static void addColors(CRGBA *dest, const CRGBA *src1, const CRGBA *src2, uint numColors, uint srcStride = sizeof(CRGBA), uint destStride = sizeof(CRGBA), uint dup = 1);
00296 
00304         static void modulateColors(CRGBA *dest, const CRGBA *src1, const CRGBA *src2, uint numColors, uint srcStride = sizeof(CRGBA), uint destStride = sizeof(CRGBA), uint dup = 1);
00305 
00313         static void subtractColors(CRGBA *dest, const CRGBA *src1, const CRGBA *src2, uint numColors, uint srcStride = sizeof(CRGBA), uint destStride = sizeof(CRGBA), uint dup = 1);
00315 
00317 
00318 
00323             bool convertToHLS(float &h, float &l, float &S) const;
00324 
00328             void buildFromHLS(float h, float l, float s);
00330 
00331 
00333     void    swapBR()
00334     {
00335         std::swap(R,B);
00336     }
00337 
00338 
00340     uint8   R;
00342     uint8   G;
00344     uint8   B;
00346     uint8   A;
00347 
00348 
00350     static const CRGBA Black ;
00351     static const CRGBA Red ;
00352     static const CRGBA Green ;
00353     static const CRGBA Yellow ;
00354     static const CRGBA Blue ;
00355     static const CRGBA Magenta ;
00356     static const CRGBA Cyan ;
00357     static const CRGBA White ;
00358 };
00359 
00360 
00367 class CBGRA
00368 {
00369 public:
00370 
00372     CBGRA() {}
00373 
00378     CBGRA(CRGBA c)
00379     {
00380         R=c.R;
00381         G=c.G;
00382         B=c.B;
00383         A=c.A;
00384     };
00385 
00393     CBGRA(uint8 r, uint8 g, uint8 b, uint8 a=255) :
00394         B(b), G(g), R(r), A(a) {}
00395 
00399     operator CRGBA()
00400     {
00401         return CRGBA (R, G, B, A);
00402     }
00403 
00407     uint    getPacked() const
00408     {
00409         return ((uint)B<<24) + ((uint)G<<16) + ((uint)R<<8) + A;
00410     }
00411 
00415     bool    operator<(const CBGRA &c) const
00416     {
00417         return getPacked()<c.getPacked();
00418     }
00419 
00423     bool    operator==(const CBGRA &c) const
00424     {
00425         return R==c.R && G==c.G && B==c.B && A==c.A;
00426     }
00427 
00432     void    serial(class NLMISC::IStream &f);
00433 
00440     void blendFromui(CBGRA &c0, CBGRA &c1, uint factor);
00441 
00449     void set(uint8 r, uint8 g, uint8 b, uint8 a);
00450 
00452     uint8   B;
00454     uint8   G;
00456     uint8   R;
00458     uint8   A;
00459 };
00460 
00461 // specialisation of the 'blend' function found in algo.h
00462 template <class U>
00463 inline CRGBA blend(CRGBA c0, CRGBA c1, U blendFactor)
00464 {
00465     CRGBA result;
00466     result.blendFromui(c0, c1, (uint) ((float) blendFactor * 256.f));
00467     return result;
00468 }
00469 
00476 class CRGBAF
00477 {
00478 public:
00480     CRGBAF ()
00481     {}
00482 
00490     CRGBAF (float _r, float _g, float _b, float _a=1.f)
00491     {
00492         R=_r;
00493         G=_g;
00494         B=_b;
00495         A=_a;
00496     }
00497 
00502     CRGBAF (CRGBA c)
00503     {
00504         R=(float)c.R/255.f;
00505         G=(float)c.G/255.f;
00506         B=(float)c.B/255.f;
00507         A=(float)c.A/255.f;
00508     }
00509 
00513     operator CRGBA() const
00514     {
00515         uint8 _r=(uint8)(R*255.f);
00516         uint8 _g=(uint8)(G*255.f);
00517         uint8 _b=(uint8)(B*255.f);
00518         uint8 _a=(uint8)(A*255.f);
00519         return CRGBA (_r, _g, _b, _a);
00520     }
00521 
00525     void normalize ()
00526     {
00527         R= (R>1.f) ? 1.f : (R<0.f) ? 0.f : R;
00528         G= (G>1.f) ? 1.f : (G<0.f) ? 0.f : G;
00529         B= (B>1.f) ? 1.f : (B<0.f) ? 0.f : B;
00530         A= (A>1.f) ? 1.f : (A<0.f) ? 0.f : A;
00531     }
00532 
00538     CRGBAF operator+ (const CRGBAF& c) const
00539     {
00540         return CRGBAF (R+c.R, G+c.G, B+c.B, A+c.A);
00541     }
00542 
00548     CRGBAF operator- (const CRGBAF& c) const
00549     {
00550         return CRGBAF (R-c.R, G-c.G, B-c.B, A-c.A);
00551     }
00552 
00558     CRGBAF operator* (const CRGBAF& c) const
00559     {
00560         return CRGBAF (R*c.R, G*c.G, B*c.B, A*c.A);
00561     }
00562 
00568     CRGBAF operator* (float f) const
00569     {
00570         return CRGBAF (R*f, G*f, B*f, A*f);
00571     }
00572 
00578     CRGBAF operator/ (float f) const
00579     {
00580         return CRGBAF (R/f, G/f, B/f, A/f);
00581     }
00582 
00588     CRGBAF& operator+= (const CRGBAF& c)
00589     {
00590         R+=c.R;
00591         G+=c.G;
00592         B+=c.B;
00593         A+=c.A;
00594         return *this;
00595     }
00596 
00602     CRGBAF& operator-= (const CRGBAF& c)
00603     {
00604         R-=c.R;
00605         G-=c.G;
00606         B-=c.B;
00607         A-=c.A;
00608         return *this;
00609     }
00610 
00616     CRGBAF& operator*= (const CRGBAF& c)
00617     {
00618         R*=c.R;
00619         G*=c.G;
00620         B*=c.B;
00621         A*=c.A;
00622         return *this;
00623     }
00624 
00630     CRGBAF& operator*= (float f)
00631     {
00632         R*=f;
00633         G*=f;
00634         B*=f;
00635         A*=f;
00636         return *this;
00637     }
00638 
00644     CRGBAF& operator/= (float f)
00645     {
00646         R/=f;
00647         G/=f;
00648         B/=f;
00649         A/=f;
00650         return *this;
00651     }
00652 
00657     void    serial(class NLMISC::IStream &f);
00658 
00666     void set(float r, float g, float b, float a);
00667 
00669     float   R;
00671     float   G;
00673     float   B;
00675     float   A;
00676 };
00677 
00683 inline CRGBAF operator* (float f, const CRGBAF& c)
00684 {
00685     return CRGBAF (c.R*f, c.G*f, c.B*f, c.A*f);
00686 }
00687 
00688 #ifdef NL_LITTLE_ENDIAN
00689 #define NL_RGBA_R_DWORD_MASK (0x000000ff)
00690 #define NL_RGBA_G_DWORD_MASK (0x0000ff00)
00691 #define NL_RGBA_B_DWORD_MASK (0x00ff0000)
00692 #define NL_RGBA_A_DWORD_MASK (0xff000000)
00693 #else // NL_LITTLE_ENDIAN
00694 #define NL_RGBA_R_DWORD_MASK (0xff0000)
00695 #define NL_RGBA_G_DWORD_MASK (0x00ff0000)
00696 #define NL_RGBA_B_DWORD_MASK (0x0000ff00)
00697 #define NL_RGBA_A_DWORD_MASK (0x000000ff)
00698 #endif // NL_LITTLE_ENDIAN
00699 
00700 } // NLMISC
00701 
00702 
00703 #endif // NL_RGBA_H
00704 
00705 /* End of rgba.h */

Generated on Thu Jan 7 08:26:23 2010 for NeL by  doxygen 1.6.1