1 /**************************************************************************/ 2 /* Copyright 2009 Tim Day */ 3 /* */ 4 /* This file is part of Fracplanet */ 5 /* */ 6 /* Fracplanet is free software: you can redistribute it and/or modify */ 7 /* it under the terms of the GNU General Public License as published by */ 8 /* the Free Software Foundation, either version 3 of the License, or */ 9 /* (at your option) any later version. */ 10 /* */ 11 /* Fracplanet is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 14 /* GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public License */ 17 /* along with Fracplanet. If not, see <http://www.gnu.org/licenses/>. */ 18 /**************************************************************************/ 19 20 /* Copyright (C) 1998,1999 T Day */ 21 22 /*! \file 23 \brief Interface for class ByteRGBA and class FloatRGBA. 24 */ 25 26 #ifndef _image_rgb_h_ 27 #define _image_rgb_h_ 28 29 #include "common.h" 30 31 /*! Direct access to class members is permitted. 32 The uchar version is intended as a minimal class for efficient storage of colours. 33 (However, padding means there is a wasted byte if we just want RGB so we 34 might as well have an alpha channel). 35 */ 36 template <typename T> class RGBA 37 { 38 public: 39 //@{ 40 //! Colour component. 41 T r; 42 T g; 43 T b; 44 T a; 45 //@} 46 47 //! Null constructor. 48 /* NB There are no default values. 49 */ RGBA()50 RGBA() 51 {} 52 53 //! Copy constructor. RGBA(const RGBA & c)54 RGBA(const RGBA& c) 55 :r(c.r) 56 ,g(c.g) 57 ,b(c.b) 58 ,a(c.a) 59 {} 60 61 //! Initialise from separate components. RGBA(T vr,T vg,T vb,T va)62 RGBA(T vr,T vg,T vb,T va) 63 :r(vr) 64 ,g(vg) 65 ,b(vb) 66 ,a(va) 67 {} 68 69 //! Colour addition. 70 void operator+=(const RGBA& v) 71 { 72 r+=v.r; 73 g+=v.g; 74 b+=v.b; 75 a+=v.a; 76 } 77 78 //! Colour subtraction. 79 void operator-=(const RGBA& v) 80 { 81 r-=v.r; 82 g-=v.g; 83 b-=v.b; 84 a-=v.a; 85 } 86 }; 87 88 //! Colour equality operator. 89 template <typename T> inline bool operator==(const RGBA<T>& a,const RGBA<T>& b) 90 { 91 return (a.r==b.r && a.g==b.g && a.b==b.b && a.a==b.a); 92 } 93 94 //! Colour inequality operator. 95 template <typename T> inline bool operator!=(const RGBA<T>& a,const RGBA<T>& b) 96 { 97 return (a.r!=b.r || a.g!=b.g || a.b!=b.b || a.a!=b.a); 98 } 99 100 //! Colour addition operator. 101 template <typename T> inline RGBA<T> operator+(const RGBA<T>& a,const RGBA<T>& b) 102 { 103 return RGBA<T> 104 ( 105 a.r+b.r, 106 a.g+b.g, 107 a.b+b.b, 108 a.a+b.a 109 ); 110 } 111 112 //! Colour negation operator. 113 template <typename T> inline RGBA<T> operator-(const RGBA<T>& c) 114 { 115 return RGBA<T> 116 ( 117 -c.r, 118 -c.g, 119 -c.b, 120 -c.a 121 ); 122 } 123 124 //! Colour subtraction operator. 125 template <typename T> inline RGBA<T> operator-(const RGBA<T>& a,const RGBA<T>& b) 126 { 127 return RGBA<T> 128 ( 129 a.r-b.r, 130 a.g-b.g, 131 a.b-b.b, 132 a.a-b.a 133 ); 134 } 135 136 137 //! Class to represent red-green-blue-alpha colours stored with 8-bit resolution. 138 class ByteRGBA : public RGBA<uchar> 139 { 140 public: 141 142 //! Null constructor. NB There are no default values. ByteRGBA()143 ByteRGBA() 144 :RGBA<uchar>() 145 {} 146 147 //! Copy constructor. ByteRGBA(const RGBA<uchar> & c)148 ByteRGBA(const RGBA<uchar>& c) 149 :RGBA<uchar>(c) 150 {} 151 152 //! Componentwise initialization. ByteRGBA(uchar vr,uchar vg,uchar vb,uchar va)153 ByteRGBA(uchar vr,uchar vg,uchar vb,uchar va) 154 :RGBA<uchar>(vr,vg,vb,va) 155 {} 156 157 //! Construct ByteRGBA from float RGBAs. 158 /*! Components in the range [0.0,1.0] are scaled to [0,255]. 159 */ ByteRGBA(const RGBA<float> & c)160 explicit ByteRGBA(const RGBA<float>& c) 161 :RGBA<uchar> 162 ( 163 static_cast<uchar>(255.0*clamped(c.r,0.0f,1.0f)), 164 static_cast<uchar>(255.0*clamped(c.g,0.0f,1.0f)), 165 static_cast<uchar>(255.0*clamped(c.b,0.0f,1.0f)), 166 static_cast<uchar>(255.0*clamped(c.a,0.0f,1.0f)) 167 ) 168 {} 169 170 std::ostream& write(std::ostream&) const; 171 const std::string format_comma() const; 172 }; 173 174 //! Class to represent red-green-blue-alpha colours stored to floating point accuracy. 175 class FloatRGBA : public RGBA<float> 176 { 177 public: 178 179 //! Null constructor. 180 /* NB There are no default values. 181 */ FloatRGBA()182 FloatRGBA() 183 {} 184 185 //! Copy constructor. FloatRGBA(const RGBA<float> & c)186 FloatRGBA(const RGBA<float>& c) 187 :RGBA<float>(c) 188 {} 189 190 //! Initialise from separate components. FloatRGBA(float vr,float vg,float vb,float va)191 FloatRGBA(float vr,float vg,float vb,float va) 192 :RGBA<float>(vr,vg,vb,va) 193 {} 194 195 //! Initialise from ByteRGBA. 196 /*! Byte values [0,255] are normalised to [0.0,1.0] 197 */ FloatRGBA(const RGBA<uchar> & c)198 explicit FloatRGBA(const RGBA<uchar>& c) 199 :RGBA<float>(c.r/255.0f,c.g/255.0f,c.b/255.0,c.a/255.0) 200 {} 201 202 //! Output method. 203 std::ostream& write(std::ostream&) const; 204 205 const std::string format_pov_rgb() const; 206 207 const std::string format_pov_rgbf() const; 208 }; 209 210 //! Colour multiplication-by-scalar operator. 211 inline FloatRGBA operator*(float k,const FloatRGBA& c) 212 { 213 return FloatRGBA 214 ( 215 k*c.r, 216 k*c.g, 217 k*c.b, 218 k*c.a 219 ); 220 } 221 222 //! Colour multiplication-by-scalar operator. 223 inline FloatRGBA operator*(const FloatRGBA& c,float k) 224 { 225 return FloatRGBA 226 ( 227 k*c.r, 228 k*c.g, 229 k*c.b, 230 k*c.a 231 ); 232 } 233 234 //! Colour division-by-scalar operator. 235 inline FloatRGBA operator/(const FloatRGBA& c,float k) 236 { 237 return FloatRGBA 238 ( 239 c.r/k, 240 c.g/k, 241 c.b/k, 242 c.a/k 243 ); 244 } 245 246 247 //! Colour multiplication operator. 248 /*! Componentwise multiplication. 249 */ 250 inline FloatRGBA operator*(const FloatRGBA& a,const FloatRGBA& b) 251 { 252 return FloatRGBA 253 ( 254 a.r*b.r, 255 a.g*b.g, 256 a.b*b.b, 257 a.a*b.a 258 ); 259 } 260 261 inline std::ostream& operator<<(std::ostream& out,const FloatRGBA& c) 262 { 263 return c.write(out); 264 } 265 266 #endif 267