diff --git a/synfig-core/src/synfig/palette.cpp b/synfig-core/src/synfig/palette.cpp index 96c2ceb..cae9c3d 100644 --- a/synfig-core/src/synfig/palette.cpp +++ b/synfig-core/src/synfig/palette.cpp @@ -47,7 +47,11 @@ using namespace synfig; /* === M A C R O S ========================================================= */ -#define PALETTE_FILE_COOKIE "SYNFIGPAL1.0" +#define PALETTE_SYNFIG_FILE_COOKIE "SYNFIGPAL1.0" +#define PALETTE_SYNFIG_EXT "spal" +#define PALETTE_GIMP_FILE_COOKIE "GIMP Palette" +#define PALETTE_GIMP_EXT "gpl" + /* === G L O B A L S ======================================================= */ @@ -323,29 +327,72 @@ Palette::load_from_file(const synfig::String& filename) throw strprintf(_("Unable to open %s for read"),filename.c_str()); Palette ret; - String line; - - getline(file,line); - - if(line!=PALETTE_FILE_COOKIE) - throw strprintf(_("%s does not appear to be a palette file"),filename.c_str()); + String line(""); + String ext(filename_extension(filename)); //todo check function result for multiple '.' in file name and 4 chars ext. - getline(file,ret.name_); - while(!file.eof()) + if (ext==PALETTE_SYNFIG_EXT) + { + getline(file,line); + + if(line!=PALETTE_SYNFIG_FILE_COOKIE) + throw strprintf(_("%s does not appear to be a valid %s palette file"),filename.c_str(),"Synfig"); + + getline(file,ret.name_); + + while(!file.eof()) + { + PaletteItem item; + String n; + float r, g, b, a; + getline(file,item.name); + file>>r>>g>>b>>a; + item.color.set_r(r); + item.color.set_g(g); + item.color.set_b(b); + item.color.set_a(a); + if(file.eof()) break; + ret.push_back(item); + } + } + else if (ext==PALETTE_GIMP_EXT) { - PaletteItem item; - String n; - float r, g, b, a; - getline(file,item.name); - file>>r>>g>>b>>a; - item.color.set_r(r); - item.color.set_g(g); - item.color.set_b(b); - item.color.set_a(a); - if(file.eof()) break; - ret.push_back(item); + /* + file format: GPL (GIMP Palette) file should have the following layout: + GIMP Palette + Name: + ... + # + + + ... ... + */ + while(line=="" && !file.eof()) //drops empty first header lines in malformed files + getline(file,line); + + if(line!=PALETTE_GIMP_FILE_COOKIE) + throw strprintf(_("%s does not appear to be a valid %s palette file"),filename.c_str(),"GIMP"); + + getline(file,line); + ret.name_=String(line.substr(6)); //drops 6 first chars from line (ie 'Name: ') + + while(line!="#" && !file.eof()) //drops remaining header lines + getline(file,line); + + while(!file.eof()) + { + PaletteItem item; + getline(file,line); //todo how to efficiently split stream line between spaces+ in C++? Perlregexp would be smthg like (\d{1-3})\s+(\d{1-3})\s+(\d{1-3})\s+(.*) + float r(line.substr(0,3)), g(line.substr(4,3)), b(line.substr(8,3)); //todo does multiple declaration+init work; does float(String) trim the spaces? + item.name=String(line.substr(12)); + Color c(r/255,g/255,b/255); //alpha is 1 by default + item.color=c; + if(file.eof()) break; + ret.push_back(item); + } } + else + throw strprintf(_("%s does not appear to be a supported palette file"),filename.c_str()); return ret; }