1 /* === S Y N F I G ========================================================= */
3 ** \brief Template File
5 ** $Id: palette.cpp,v 1.1.1.1 2005/01/04 01:23:14 darco Exp $
8 ** Copyright (c) 2002 Robert B. Quattlebaum Jr.
10 ** This software and associated documentation
11 ** are CONFIDENTIAL and PROPRIETARY property of
12 ** the above-mentioned copyright holder.
14 ** You may not copy, print, publish, or in any
15 ** other way distribute this software without
16 ** a prior written agreement with
17 ** the copyright holder.
20 /* ========================================================================= */
22 /* === H E A D E R S ======================================================= */
39 /* === U S I N G =========================================================== */
43 using namespace synfig;
45 /* === M A C R O S ========================================================= */
47 #define PALETTE_FILE_COOKIE "SYNFIGPAL1.0"
49 /* === G L O B A L S ======================================================= */
51 bool weight_less_than(const PaletteItem& lhs,const PaletteItem& rhs)
53 return lhs.weight<rhs.weight;
56 bool luma_less_than(const PaletteItem& lhs,const PaletteItem& rhs)
58 return lhs.color.get_y()<rhs.color.get_y();
61 bool luma_less_than(const PaletteItem& lhs,const float& rhs)
63 return lhs.color.get_y()<rhs;
66 /* === P R O C E D U R E S ================================================= */
68 /* === M E T H O D S ======================================================= */
75 Palette::Palette(const String& name_):
81 PaletteItem::add(const Color& x,int xweight)
83 color=(color*weight+x*xweight)/(weight+xweight);
87 Palette::Palette(const Surface& surface, int max_colors):
88 name_(_("Surface Palette"))
91 for(int y=0;y<surface.get_h();y++)
92 for(int x=0;x<surface.get_w();x++)
95 Color color(surface[y][x]);
105 if(front().color.get_a()!=0)
106 insert(begin(),Color(1,0,1,0));
111 iterator iter(find_closest(color,&dist));
118 /*if(size()>=max_colors)
120 iterator iterlight(find_light());
121 PaletteItem light(*iterlight);
123 find_closest(light.color)->add(light.color,light.weight);
130 sort(rbegin(),rend());
134 iterator best_match(begin());
135 while((signed)size()>max_colors)
137 PaletteItem item(back());
139 find_closest(item.color)->add(item.color,item.weight);
141 push_back(Color::black());
142 push_back(Color::white());
144 // sort(begin(),end(),&luma_less_than);
147 Palette::const_iterator
148 Palette::find_closest(const Color& color, float* dist)const
150 // For the sake of avoiding cut-and-paste
151 // bugs, we'll just use the non-const
152 // find_closest()... It doesn't change anything
154 return const_cast<Palette*>(this)->find_closest(color,dist);
158 Palette::find_closest(const Color& color, float* dist)
162 iterator best_match(begin());
163 float best_dist(1000000);
165 const float prep_y(powf(color.get_y(),2.2f)*color.get_a());
166 const float prep_u(color.get_u());
167 const float prep_v(color.get_v());
169 for(iter=begin();iter!=end();++iter)
171 const float diff_y(prep_y-powf(iter->color.get_y(),2.2f)*iter->color.get_a());
172 const float diff_u(prep_u-iter->color.get_u());
173 const float diff_v(prep_v-iter->color.get_v());
174 const float diff_a(color.get_a()-iter->color.get_a());
186 prep_u*iter->color.get_u()-
187 prep_v*iter->color.get_v()
204 Palette::find_heavy()
208 iterator best_match(begin());
210 for(iter=begin();iter!=end();++iter)
212 if(iter->weight>best_match->weight)
220 Palette::find_light()
224 iterator best_match(begin());
226 for(iter=begin();iter!=end();++iter)
228 if(iter->weight<best_match->weight)
236 Palette::grayscale(int steps)
239 for(int i=0;i<steps;i++)
241 float amount(i/(steps-1));
242 float y(powf(amount,2.2f));
246 strprintf(_("%0.2f%% Gray"),amount)
254 Palette::save_to_file(const synfig::String& filename)const
258 std::ofstream file(filename.c_str());
261 throw strprintf(_("Unable to open %s for write"),filename.c_str());
263 file<<PALETTE_FILE_COOKIE<<endl;
265 for(iter=begin();iter!=end();++iter)
267 file<<iter->name<<endl;
269 <<iter->color.get_r()<<endl
270 <<iter->color.get_g()<<endl
271 <<iter->color.get_b()<<endl
272 <<iter->color.get_a()<<endl;
278 Palette::load_from_file(const synfig::String& filename)
280 std::ifstream file(filename.c_str());
283 throw strprintf(_("Unable to open %s for read"),filename.c_str());
290 if(line!=PALETTE_FILE_COOKIE)
291 throw strprintf(_("%s does not appear to be a palette file"),filename.c_str());
293 getline(file,ret.name_);
298 getline(file,item.name);
299 if(!file.eof())break;
302 if(!file.eof())break;
303 item.color.set_r(atof(line.c_str()));
306 if(!file.eof())break;
307 item.color.set_g(atof(line.c_str()));
310 if(!file.eof())break;
311 item.color.set_b(atof(line.c_str()));
314 if(!file.eof())break;
315 item.color.set_a(atof(line.c_str()));