GNOME Bugzilla – Bug 339359
GIMP should support 64-bit image editting
Last modified: 2008-01-15 13:07:06 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.
*** This bug has been marked as a duplicate of 74224 ***
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
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.
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.
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)).