palette.cpp
00001 #include "palette.h"
00002 #include <fstream>
00003 #include <cmath>
00004
00005 #define COLOR_EPSILON (1./512.)
00006
00007 namespace util
00008 {
00009
00010 Palette::Palette(std::string filename)
00011 : FileObject(filename)
00012 {
00013 reread();
00014 }
00015
00016 Palette::Palette()
00017 : FileObject()
00018 {
00019 for(int i = 0 ; i < 255 ; ++i)
00020 {
00021 colors[i] = 0.0f;
00022 }
00023 }
00024
00025 void Palette::reread()
00026 {
00027 std::ifstream in(filename.c_str(), std::ios::binary);
00028
00029 unsigned int index = 0;
00030 while (!in.eof() || !in.good() || !in)
00031 {
00032 if (index > 255) break;
00033 colors[index].r(GLfloat(in.get())/255.f);
00034 colors[index].g(GLfloat(in.get())/255.f);
00035 colors[index].b(GLfloat(in.get())/255.f);
00036 index++;
00037 }
00038 }
00039
00040 Palette::Color Palette::getColor(unsigned int index, double alpha) const
00041 {
00042 if (index > 255)
00043 index = 255;
00044 Color color = colors[index];
00045 color.a(GLfloat(alpha));
00046 return color;
00047 }
00048
00049 void Palette::useColor(unsigned int index, double alpha) const
00050 {
00051 glColor4fv(getColor(index, alpha).c_data());
00052 }
00053
00054 Palette::Color Palette::getColor(unsigned int ind1, unsigned int ind2, double w, double alpha ) const
00055 {
00056 if (ind1 > 255)
00057 ind1 = 255;
00058 if (ind2 > 255)
00059 ind2 = 255;
00060 if (w > 1.0)
00061 w = 1.0;
00062 else if (w < 0.0)
00063 w = 0.0;
00064
00065 if(ind1 == ind2)
00066 return getColor(ind1, alpha);
00067 else if(w < COLOR_EPSILON)
00068 return getColor(ind1, alpha);
00069 else if(w > 1-COLOR_EPSILON)
00070 return getColor(ind2, alpha);
00071 else
00072 {
00073 Color a = colors[ind1], b = colors[ind2];
00074 Color result( GLfloat(a.r() * (1.0 - w) + b.r() * w),
00075 GLfloat(a.g() * (1.0 - w) + b.g() * w),
00076 GLfloat(a.b() * (1.0 - w) + b.b() * w),
00077 GLfloat(alpha));
00078 return result;
00079 }
00080 }
00081
00082 void Palette::blend(unsigned int ind1, unsigned int ind2, double w, double alpha ) const
00083 {
00084 glColor4fv( getColor(ind1, ind2, w, alpha).c_data() );
00085 }
00086
00087 Palette::Color Palette::blend(const Color& a, const Color& b, double w)
00088 {
00089 Color result( GLfloat(a.r() * (1.0 - w) + b.r() * w),
00090 GLfloat(a.g() * (1.0 - w) + b.g() * w),
00091 GLfloat(a.b() * (1.0 - w) + b.b() * w),
00092 GLfloat(a.a() * (1.0 - w) + b.a() * w));
00093 return result;
00094 }
00095
00096 Palette::Color Palette::selectColor(unsigned int start, unsigned int end, double w, double alpha) const
00097 {
00098 if (start > 255)
00099 start = 255;
00100 if (end > 255)
00101 end = 255;
00102 if (w > 1.0)
00103 w = 1.0;
00104 else if (w < 0.0)
00105 w = 0.0;
00106
00107 int delta_color = (int)end-(int)start;
00108 double pos_w = delta_color*w + start;
00109 int before = (int)std::floor(pos_w);
00110 int after = before+1;
00111 double ratio = pos_w - (double)before;
00112 if(ratio < COLOR_EPSILON)
00113 return getColor(before, alpha);
00114 if(ratio > 1-COLOR_EPSILON)
00115 return getColor(after, alpha);
00116 return getColor(before, after, ratio, alpha);
00117 }
00118
00119 void Palette::select(unsigned int start, unsigned int end, double w, double alpha) const
00120 {
00121 glColor4fv(selectColor(start, end, w, alpha).c_data());
00122 }
00123 }