After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 339359 - GIMP should support 64-bit image editting
GIMP should support 64-bit image editting
Status: RESOLVED DUPLICATE of bug 74224
Product: GIMP
Classification: Other
Component: libgimp
2.2.x
Other All
: Normal enhancement
: ---
Assigned To: GIMP Bugs
GIMP Bugs
Depends on:
Blocks:
 
 
Reported: 2006-04-21 23:21 UTC by Nick Smith
Modified: 2008-01-15 13:07 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description Nick Smith 2006-04-21 23:21:27 UTC
GIMP should be able to support editting and working with 48 and 64-bit images
where red, green, blue, and alpha channels have values from 0 to 65535 instead.
 To get it to work on a 32-bit display, just divide the ARGB values by 256 and
drop the trash after the decimal then display that color.  48-bit color lacks
alpha channel and 64-bit color contains the alpha channel.  When saving into
other formats, like GIF or BMP (PNG supports 64-bit color), the image must be
exported to the 8-bit-per-channel format, of which GIMP current uses.  To choose
between 8-bit and 16-bit-per-channel modes, new options would be needed.  This
allows for higher precision image creation, but uses twice the memory.
Comment 1 Sven Neumann 2006-04-22 01:59:14 UTC

*** This bug has been marked as a duplicate of 74224 ***
Comment 2 Albert Cahalan 2006-04-23 20:09:52 UTC
That isn't a great way to round things. There are two problems I see:

1. not rounding to nearest

2. not rounding in a linear light (gamma==1) color space

Comment 3 Nick Smith 2006-04-24 03:43:09 UTC
The reason for this rounding system comes down to the range.  If red was 480, doing the division would yield 1.875.  Normally this would round to 2.  It would seem to work this way, but the trouble comes from using 65535, the highest value possible.  Doing the division, it comes out to 255.99609375 which rounds to 256.  256 is an invalid value for 8-bit.  Another option is to use 257 as the value to divide by.  However, half of 257 is 128.5 which makes things a bit screwy.  If I had red at 385, it would be 1 in the 8-bit system and if 386, it would be 2, if rounded.  This is where the difficulty comes in.

The system where you divide by 256 and drop the trash after the decimal is easier to work with, but less precise.  The system where you divide by 257 and round is trickier to work with, but more precise.  I prefer the more precise system as I tend to do things that require high precision (which is why I posted this 32-bit doesn't seem to be enough, but 64-bit is more than sufficient).  I searched for things like "64-bit color" or "64 color", but didn't see anything in my search results so I didn't think this bug has been submitted yet.
Comment 4 Albert Cahalan 2006-04-24 05:00:37 UTC
While trying to throw together an example of proper rounding, I came to the conclusion that a binary search or lookup table is probably required. There might be a decent polynomial that happens to round in all the right ways.

To do things properly, first you must convert to linear. You do that somewhat like this:

double linear = pow(src/65535.0,2.2); // real gamma curves are not pow()

Next, you need to round. You can't convert to 8-bit until you have rounded. Problem is, the values you must round to are not evenly spaced. Ouch...

So it is better to have precomputed tables that map from 16-bit to floating-point, and from 8-bit to floating-point. Look up your value in one table, then binary search for it in the other table.

Even better would be to have tables that go all the way, so a single table lookup does the job.
Comment 5 Nick Smith 2006-04-24 10:24:19 UTC
The methods I've explained for rounding each have their own pros and cons.  The first method of dropping the trash after the decimal is the fastest and easiest to program.

some_8bit_var = int(color/256);

This would normally drop the trash after the decimal.  This is the fastest conversion, but least precise.  The other method involves dividing by 257 and adding 0.5 then dropping the trash after the decimal.

some_8bit_var = int(color/257+0.5);

This method is much more accurate, but somewhat slower (though not much slower).  I don't know C programming, but this is based of that of Gamestudio's programming system.  int() takes the integer part of the result dropping the trash after the decimal.  The stuff inside is computed first though until a single value remains.

To convert back to 16-bit, the process is otherwise undone.  The first method would just multiply the 8-bit color by 256.  The second method would multiply by 257 then subtract 128 (not 128.5 or 129 (due to rounding the result from 128.5 up)).