hack to import GIMP palette

Hello.

I wanted to import my favorite colors palettes (Tango, Ubuntu and others) into Synfig. They are often available as GIMP palette files (*.gpl). Hence a small hack proposal to extend the “load palette from file” capabilities.

I never used C++, so expect smthg awful. Tried to document it though.
Any help/comment to correct/improve is welcome. I couldn’t test is as I can’t get to build Synfig… sorry.

If you don’t want “untested” patches just tell me, I’ll restrain from posting until I can find the time to set up a proper dev setup.

Have a nice day,
Berteh
palette.cpp.txt (8.75 KB)
load-gimp-palette_synfig-git.diff.txt (3.58 KB)

Hi berteh!
Initially the patch looks fine to me!
I’ll try to test it as soon as possible and if it works well, it will be incorporated to the next release.
Thanks!
Cheers
-G

Cool!
How does this deal with Synfigs hard set gamma value of 2.2? Does it adjust the Gimp colour values so the colours looks the same in Synfig (same colour, different values)?

not yet. didn’t notice this issue. for now its a plain RGB syntactical transformation, but I’ll look into it and try to provide a correction. You got any pointer/doc/hint has to how Gamma relates to RGB?

Here’s the function I’m using in the SVG importer to take care of gamma:

color = [pow(red/255.0, sif.gamma), pow(green/255.0, sif.gamma), pow(blue/255.0, sif.gamma), 1.0]

Where gamma=2.2. As far as I can tell it’s the right formula.

Maybe, when the gimp palette is loaded, you can apply a gamma correction to 2.2 assuming that it is a 1.0 gamma color value and use one of the followings functions:
from synfig-core/src/synfig/gamma.h

float r_F32_to_F32(float x)const { return static_cast<float>(pow(x,gamma_r)*(1.0f-black_level)+black_level); } float g_F32_to_F32(float x)const { return static_cast<float>(pow(x,gamma_g)*(1.0f-black_level)+black_level); } float b_F32_to_F32(float x)const { return static_cast<float>(pow(x,gamma_b)*(1.0f-black_level)+black_level); }

with a gamma instance constructed with initial value of 2.2
It is used for example on sag_parser.cpp to convert colors from svg to synfig gamma = 2.2

EDIT: nikitakit’s functions are valid too assuming blacklevel = 1.0
-G

Hi berteh!
Very nice patch! The ability to load gimp color palettes has been a long time in the synfig wish list!
Maybe after this can come the Gimp palette saving feature :slight_smile:
I want to make a few C++ corrections to your patch though.
Can you post it in the patch tracker so we can work on it there preserving your authority?

Nice job!

Thanks all for the answers and pointers. It was interesting discovering what gamma correction is.

After a few quick tests though, it looks like the RGB values in GIMP Palettes have a gamma of 2.2 too… would that be possible?
I tested out a few colors by simply entering the gimp RGB/255*100 value into synfig’s color editor and the visual match seemed alright, as illustrated in the attached picture for the color “Plum 1” where the Synfig “Colours” dialog is on top of GIMP’s “Palette Editor”.

Plum 1 of the the Tango palett is GIMP RGB: 173 127 168 - Synfig computed RGB: 67,8 50,0 65,9.

So maybe I got lucky and don’t need to correct these colors?.. or does the palette load function not use the same gamma as the Synfig Colour editor?

Genete: I believe there’s a bug in my patch above since “filename_extension()” seems to keep the “.” as first character in its result. If that is indeed the case, you’d need to correct 2 constants, to add the dot in front, sorry:

#define PALETTE_SYNFIG_EXT ".spal" #define PALETTE_GIMP_EXT ".gpl"

eldruin: Patch added at sourceforge.net/tracker/?func=d … tid=757418
gamma-gimp.png

I think that you can use the ETL utilities to extract extensions form a file name:

From ETL/ETL/string_.h

inline std::string filename_extension(const std::string &str) { std::string base = basename(str); std::string::size_type pos = base.find_last_of('.'); if (pos == std::string::npos) return std::string(); return base.substr(pos); }

It would ride the dot string.

-G

Genete,
That’s exactly the method I use, and, from looking at the code it seems to keep the dot, as in

synfig/savecanvas.cpp - line 771 if (filename_extension(filename) == ".sifz")

B.

Excuse me, I was blind yesterday! :blush: :blush:
-G

don’t code too much and have a rest frequently :mrgreen:

Thanks for berteh’s awesome job. I expected this feature for a long time.

While waiting for the “palette import” patch to be included in Synfig, here’s a tiny Perl Script that does translate a GIMP palette into a Synfig palette.
It applies a gamma correction of 3 (best visual match after quick test&trial), but easy to change to 2.2 or other.

run it from the command line:

./gpl2spal.pl </usr/share/gimp/2.0/palettes/Named_Colors.gpl >Named_Colors.spal

And attached are some sample results too (Tango, Pastel, and Named Colors palettes in spal).

Patch updated at sourceforge.net/tracker/?func=d … tid=757418 to add gamma correction accordingly.

Thanks for Synfig!
gpl2spal.zip (4.1 KB)

Cool, thanks for this script (waiting to have the feature inside synfig…)

I’ve made some tests, and I’ve replaced the value with the correct 2.2 gamma;
at first result didn’t match exactly beacause I had “Linear color correction” desactivated in my settings.

after re-activating it, and then re-import the spal file, colors did match those from gimp perfectly.

:.)

Nice! I’m working on the patch, I’ll have it shortly.

Hey!
I have reworked and applied your patch (including the gamma correction) on the branch eldruin_gimp_palette.
Here is the commit.

However, I don’t know about the correctness of the hard-coded gamma factor. Maybe we should use the functions from gamma.h or the formula from nikitakit.

Please give it a try and comment.

Thank you berteh!

Hi eldruin!
next time you start a new branch, please create it starting from the current master branch. When possible, rebase master is easier and cleaner than merge one branch into master.

In other term os things, to check if the imported color from a Gimp palette that uses the correct gamma or not, the best way is use a external color picker (or maybe the provided with Gimp) and compare the color picked value from the Gimp palette and the Synfig imported palette. It should give the same value because it is as it is shown on the screen. Visual subjective comparing shouldn’t be the right approaching.

Regarding to gamma corrections I think that you should use the proposed functions that take account the possibly different gamma corrections from the user on the different gamma channels and the difference on the black level.
See my post above about that. All they are defined in gamma.h

-G

Uups, sorry about the branch start. I’ve just merged the actual master into it (and eldruin_clang_fixes too).

Agreed. Right now I need to study but I’ll work on it soon :slight_smile:

thanks to you eldruin, for taking the time to rework it as well!

Just one bit I didn’t understood in your modifications… for my personal education :slight_smile: how do your next 2 lines effectively get the values from a single line in the gpl file? would “>>” by chance progressively read words and stop at any space? does this operator work on strings too, or only streams?

file >> r >> g >> b; getline(file, item.name);

Thanks again.
Berteh.

Hi,
I was very happy to adapt your patch and finally see this feature in Synfig. (Please continue sending patches!! :slight_smile:)

About those lines, as you said, the extraction operator ( >> ) applied to a stream, reads data, stops at any blank (’ ‘,’\t’,’\n’), and give you a formatted output according to what you want to read. In this case, it would read a number, convert it to float, which is the target, and assign it to the variable.

If you want to use this operator for a string, you can’t do it directly, but you can use the magic stringstream, which is what you should use when you want to convert a string containing, say, a double, to an actual double. i.e:

double pi, e; string numbers("3.1415 2.71828"); stringstream ss; ss << numbers; // put the string in ss >> pi; ss >> e; // also the same as ss >> pi >> e; you would extract first pi and from the rest you would extract e
Continuing with the patch code, once we have extracted the numbers from the stream, we have to get the name, which can contain spaces, so we can’t use the extraction operator because this one won’t stop at the end of the line. So, we extract the rest of the line from the file, as it is, and assign it to the name. In this case: getline(file_input_stream, name);
We should apply trimming to the extracted name to remove any posible preceeding or trailing spaces but I have to add write this function in the ETL String class (which almost all it contains is just files-path-related, but that’s another battle) and then apply it.