GNOME Bugzilla – Bug 168022
Resampling is not performed in a gamma correct manner
Last modified: 2017-07-06 11:48:26 UTC
Implement this: http://home.no.net/dmaurer/~dersch/gamma/gamma.html So images don't look badly. Anyway, is that a good idea?
Gamma correction should be done at the display level. Your report is a duplicate of bug #38649. It will however probably be solved by the addition of color management as dealed with in bug #78265. *** This bug has been marked as a duplicate of 38649 ***
The document says that is the program the one that should do the gamma correction when transforming the image so I thought I needed to open other bug.
Well, that needs to be done only if the image data is not in a linear color-space. If the gamma correction is implemented in the display routine and the image data is linear, then antialiasing can be performed directly.
It saddens me that everyone ignores this: Nearly all 8-bit-per-channel image data is non-linear, and generally not a simple exponent. The sRGB space is overwhelmingly the most common for 8-bit-per-channel. So, yeah, the image data is not in a linear color space. That's exactly the problem. Aside from cropping and the pencil tool, there aren't too many legitimate operations that can be performed.
I just saw this article: http://www.4p8.com/eric.brasseur/gamma.html He says that http://gegl.org/ does not have the problem. So maybe there is not point in fixing this bug in current GIMP code but wait to a GEGL enabled GIMP.
Yes, the simplest solution is to transform to a linear color space before applying the operation. and transform the result back. GEGL has support for both sRGB and linear RGB, through BABL,
Actually, I've been testing with this, and these errors seem so ubiquitous, that it would probably be well worth making linear RGB the preferred working space where possible. (clipboard data would be wanted in sRGB, of course, and any exported image (ie. not XCF) would probably also. I think we could manage to make linear RGB default for XCF > 8bpp, during the change of file formats. At the least we could lead the user towards it.) It addresses problems of: * chunky antialiasing * strange dithering (I used to get strange colors in some places, and you can see it in the examples he gives; using correct gamma also fixes the strangely matte effect I would get on some areas.) * transformations having weird effect on brightness (remember, this is not only scale! but rotate, perspective, anything that interpolates or averages at all -- which includes quite a lot of plug-in filters too.). I believe this has the potential to reduce 'cumulative transformation error' substantially. Yes, this seems to be a very serious issue for image quality.
http://www.aim-dtp.net/aim/photoshop/v6/blending/rgb_blending.htm Has some further details about how linear blending of nonlinear data effects colors in a layered paint program, and a 'linear RGB' profile that you can use as your working space if you want nominally correct interpolation -- remember, for your sRGB images to look right, if they don't have a profile attached, then you will have to apply a gamma of .4545 after loading. The main obstacle to that is, ironically, sRGB-aware but non-color-management aware filters (mainly gimp's indexization, which assumes that the input pixels are sRGB) Of course, the layer stack / any compositing operation may be categorized as interpolation, I hadn't comprehended until now just how many things this wrong treatment FUBARs. As an image processing software, GIMP really needs to use linear RGB internally if any RGB is used at all, and only use sRGB for display. Color selection would also be a lot more consistent if we could use linear RGB instead of sRGB there. But I suspect we need to have full colormanagement there, and display colors using whatever is the current working profile (for the current image).
*** Bug 610792 has been marked as a duplicate of this bug. ***
Adding to the 2.10 milestone, with GEGL these kind of operations will be performed in linear light 32 bits-per-channel RGBA.
I have been working on a pygimp-based gamma-correct image scaling plugin for GIMP yesterday, see <https://blog.hartwork.org/?p=1173>. Would you be interested in a patch against core GIMP if I wrote one for the time before GEGL takes over? Are there chances to get such a patch included for 2.6.12 or 2.6.13?
Thanks for the offer but, speaking for myself, I am not interested in spending time on improving our 8-bit only image processing core.
(In reply to comment #12) > Thanks for the offer but, speaking for myself, I am not interested in spending > time on improving our 8-bit only image processing core. I believe there isn't much more to do than wrapping the interpolation functions with exp-to-linear-and-back code to fix the main problem. GIMP 2.10 sounds quite far away - I cannot wait months for gamma-correct image scaling, every image mis-scaled hurts. Actually, image scaling is my personal most common use case of the GIMP.
Gimp 2.7 does use gegl to scale when "use gegl" is checked. You might want to look into that instead.
(In reply to comment #14) > Gimp 2.7 does use gegl to scale when "use gegl" is checked. You might want > to look into that instead. Are you saying that it's acceptable to keep it broken in non-GEGL mode? Why is non-GEGL scaling still possible if it is broken? When will GEGL be default?
We are working on getting 2.8 out which is overdue for a long time. After that we will start removing old gimp code in favor of existing gegl replacements. Since scaling works fine in gegl and there is even code in gimp to use it, you can be sure that will be among the first stuff to change.
Created attachment 187671 [details] [review] Gamma-correct scaling patch against the GIMP 2.6.11 (v1) See attachement for a first candidate of a patch against the GIMP 2.6.11. I have tested my patch against the image <http://www.4p8.com/eric.brasseur/gamma_colors.jpg>: - Well tested: 3 and 4 byte per pixel images with interpolation linear/cubic/lanczos3 - Basic testing: 1 and 2 byte per pixel images with interpolation linear/cubic/lanczos3 I'm unsure what the code in interpolate_bilinear_pr/scale_region_buffer is really used for. Maybe someone can shed light here. Also, I am unsure which code is responsible for generating preview/thumbnail images in GIMP: unless these images are read from some cache, their scaling may need fixing, too. As feedback so far hasn't been too excited I don't expect in depth review from you. I'd still be happy about anything I can get.
My review of the patch: one problem with your patch is that in function linear_to_exp you're rounding toward zero, this means that for example 29.9 is rounded to 29 instead of 30. You should use the C99 function lrint that rounds to the nearest integer and does not change the rounding mode of the FPU. An other improvement is to work in the range [0. 1.] instead of [0. 255.], that is, save the multiplication by 255 in exp_to_linear and the division by 255 in linear_to_exp. Regarding fixing thumbnails and previews: there would be nothing to fix if the conversions input->linear was done when loading/color choosing and linear->desired when displaying/saving, but you would need at least 16 bits for the internal representation. Otherwise every operation performing whatever average/blending needs fixing, it is a known issue. Unfortunately scaling in Gegl does not work fine. It inherited GIMP's bugs (Lanczos kernel sampled wrong, half pixel shift back and forth in affine.c), introduced new ones (the cubic sampler is unreadable and wrong for example) and the test suite is useless (uncomment the gegl:nop operation in tests/compositions/composite-transform.xml to regenerate the reference image and compare it with that in tests/compositions/reference).
Thanks for the review! (In reply to comment #18) > one problem with your patch is that in function linear_to_exp > you're rounding toward zero, this means that for example 29.9 > is rounded to 29 instead of 30. > You should use the C99 function lrint that rounds to the > nearest integer and does not change the rounding mode > of the FPU. I see. > An other improvement is to work in the range [0. 1.] instead > of [0. 255.], that is, save the multiplication by 255 in > exp_to_linear and the division by 255 in linear_to_exp. I had that in mind, too. I decided against it because I was afraid that change could have effects that I was just not noticing. My single test case does not seem to break with it. > Unfortunately scaling in Gegl does not work fine. It inherited GIMP's bugs > (Lanczos kernel sampled wrong, half pixel shift back and forth in affine.c), > introduced new ones (the cubic sampler is unreadable and wrong > for example) and the test suite is useless (uncomment the gegl:nop > operation in tests/compositions/composite-transform.xml to regenerate > the reference image and compare it with that in tests/compositions/reference). Are there existing bug reports for these? If not: can you open dedicated bugs for these, please?
Don't know about specific bug reports, but comments in the code show the matter is known to developers. Read for example: http://git.gnome.org/browse/gegl/tree/gegl/buffer/gegl-sampler-downsize.c#n208 http://git.gnome.org/browse/gegl/tree/gegl/buffer/gegl-sampler-downsizefast.c#n167 or http://git.gnome.org/browse/gegl/tree/gegl/buffer/gegl-sampler-lanczos.c#n18
All GEGL samplers now use pre-multiplied linear RGB (RaGaBaA) light. This is almost certainly the best choice when downsampling, and is an acceptable choice when upsampling. (When upsampling, perceptual color spaces like R'aG'aB'aA often give better results with filters with negative lobes, like Lanczos. I may implement one negative lobe filter that uses a different color space for upsampling and downsampling soon. But using the same one across the board is computationally expedient, and does not hurt anything when the filter does not create haloing.)
I request that this bug be reopened. Closing a bug with "RESOLVED FIXED" and then not actually including the fix in a stable release for FOUR YEARS is just plain ridiculous. There exists no reasonable practical sense in which this bug is "RESOLVED FIXED".