Re: [Gimp-developer] Displaying linear gamma images
On 9/12/13, Jon Nordby wrote: > On 12 September 2013 16:08, Elle Stone wrote: >> The problem at this point is that the image won't display properly >> until something like doing a very small levels correction forces a >> screen redraw. After forcing a screen redraw, the image is displayed >> without any posterization, but with magenta lines (outlining the >> tiles?). The screen redraw lasts until the level dialog is closed. >> >> I think the problem is that I'm not properly merging and updating >> "buffer" after the hard-coded transform. The corresponding code from >> the lcms.c file uses layer buffers, which seems not applicable to a >> projection: >> gimp_drawable_merge_shadow (layer_id, TRUE); >> gimp_drawable_update (layer_id, 0, 0, layer_width, layer_height); > > I do not know the GimpDisplayShell code well, but try to just read out > data from the projection GeglBuffer instead of modifying it. I created a copy of "buffer" and converted it to the monitor profile, with the same results. I'm pretty sure the problem is what happens to the buffer after it's been used. It doesn't quietly disappear. In a small test image the code that does the transform gets executed 11 times per anything that changes the screen. It takes up "pipes" and a larger image eventually crashes Gimp ("unable to open pipe: Too many open files"). > And > instead of the the "gegl_buffer_get (buffer, ... "cairo-ARGB32", ... > data ...)" that you have marked, do the lcms transform such that the > 8bit ready-for-display ends up in the "data" buffer. That code is the pre-existing code that sends the buffer to cairo, so I haven't tried to modify it. There's probably a way to get "buffer" to be converted from the image color space at 32f to the monitor profile at 8i in one fell swoop - I'm pretty sure lcms can do the conversion in one fell swoop but I don't have the gegl buffers set up correctly. But "gegl_buffer_get (buffer, ... "cairo-ARGB32", ..." does convert "buffer" to 8-bits. > Also, can you please post your changes as a (git formatted) diff? > It is much easier to read and apply for another contributor trying to > help you out. I posted the git patch, the two ICC profiles in the hard-coded transform, and a test image to http://ninedegreesbelow.com/temp/convert-buffer-before-cairo.html. I hope I did the git patch correctly! The git patch (but not the profiles or test image) is also attached to this email. > Jon Nordby - www.jonnor.com Thanks! Jon, for taking an interest in this project. Elle -- http://ninedegreesbelow.com commit 23c4619a16d2b3ef5c05fd086a93a8ae3f28bd85 Author: Elle Stone Date: Thu Sep 12 17:30:29 2013 -0400 elle - convert before cairo - modified: app/display/gimpdisplayshell-render.c elle - write statements added - modified: libgimpwidgets/gimpcolordisplay.c elle - write statements added - modified: libgimpwidgets/gimpcolordisplaystack.c elle - comment out actual conversion, write statements added - modified: modules/display-filter-lcms.c diff --git a/app/display/gimpdisplayshell-render.c b/app/display/gimpdisplayshell-render.c index 9c3f6c1..101bba7 100644 --- a/app/display/gimpdisplayshell-render.c +++ b/app/display/gimpdisplayshell-render.c @@ -16,6 +16,17 @@ */ #include "config.h" +#include /* elle lcms.h uses the "inline" keyword */ + +#include /* elle */ +/* this might be needed for Windows +#ifdef G_OS_WIN32 +#define STRICT +#include +#define LCMS_WIN_TYPES_ALREADY_DEFINED +#endif +*/ +#include /* elle */ #include #include @@ -43,7 +54,6 @@ #include "gimpdisplayshell-scroll.h" #include "gimpdisplayxfer.h" - void gimp_display_shell_render (GimpDisplayShell *shell, cairo_t *cr, @@ -68,6 +78,19 @@ gimp_display_shell_render (GimpDisplayShell *shell, gint stride; guchar *data; + cmsHTRANSFORM image_to_monitor_transform = NULL; + cmsHPROFILE image_space; + cmsHPROFILE monitor_profile; + gintloops; + /* gintprojection_alpha; this variable will eventually be needed. */ + gintprojection_bpp; + GeglBufferIterator *iter; + const Babl *iter_format; + GeglBuffer *buffer_clone; + gintprojection_width; + gintprojection_height; + /* gintprojection_alpha; this variable will eventually be needed. */ + g_return_if_fail (GIMP_IS_DISPLAY_SHELL (shell)); g_return_if_fail (cr != NULL); g_return_if_fail (w > 0 && h > 0); @@ -76,8 +99,46 @@ gimp_display_shell_render (GimpDisplayShell *shell, projection = gimp_image_get_projection (image); buffer = gimp_pickable_get_buffer (GIMP_PICKABLE (projection)); + projection_width = gegl_buffer_get_width (buffer); + projection_height = gegl_buffer_get_height (buffer); + printf("gimpdisplayshell-render.c projection_width, projection_height= %i %i \n", +pro
Re: [Gimp-developer] Displaying linear gamma images
You should bug mitch or me IRC for faster responses :). Issues with this code: Don't modify the buffer you got from gimp_pickable_get_buffer (GIMP_PICKABLE (projection)), it's a live part of the projection. Adding the buffer to the iterator twice probably doesn't do what you want it to do. Depending on the format pointers may be to the same buffer, so writing may immediately modify your read buffer, or it may not. Use READWRITE if interacting with the same buffer twice. For best results you should be writing to the cairo image in xfer. The call of gegl_buffer_get wirting to xfer *is* the gamma conversion, you want to replace it completely. Alternativly you could create a temp gegl buffer here and then use buffer_get from that to write to xfer. Finally, you need to detect weather the projection's format is linear or gamma and read in that, rather than always using "R'G'B'A float". Using gimp_drawable_get_linear is probably sufficient for now. On Thu, Sep 12, 2013 at 9:12 AM, Jon Nordby wrote: > On 12 September 2013 16:08, Elle Stone wrote: > > I've made progress getting a linear gamma image to display without > > posterization in the shadows. I put up a temporary web page with the > > modified code and a picture: > > http://ninedegreesbelow.com/temp/convert-buffer-before-cairo.html > > > > The problem at this point is that the image won't display properly > > until something like doing a very small levels correction forces a > > screen redraw. After forcing a screen redraw, the image is displayed > > without any posterization, but with magenta lines (outlining the > > tiles?). The screen redraw lasts until the level dialog is closed. > > > > I think the problem is that I'm not properly merging and updating > > "buffer" after the hard-coded transform. The corresponding code from > > the lcms.c file uses layer buffers, which seems not applicable to a > > projection: > > gimp_drawable_merge_shadow (layer_id, TRUE); > > gimp_drawable_update (layer_id, 0, 0, layer_width, layer_height); > > I do not know the GimpDisplayShell code well, but try to just read out > data from the projection GeglBuffer instead of modifying it. And > instead of the the "gegl_buffer_get (buffer, ... "cairo-ARGB32", ... > data ...)" that you have marked, do the lcms transform such that the > 8bit ready-for-display ends up in the "data" buffer. > > Also, can you please post your changes as a (git formatted) diff? > It is much easier to read and apply for another contributor trying to > help you out. > > -- > Jon Nordby - www.jonnor.com > ___ gimp-developer-list mailing list List address:gimp-developer-list@gnome.org List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
Re: [Gimp-developer] Displaying linear gamma images
On 12 September 2013 16:08, Elle Stone wrote: > I've made progress getting a linear gamma image to display without > posterization in the shadows. I put up a temporary web page with the > modified code and a picture: > http://ninedegreesbelow.com/temp/convert-buffer-before-cairo.html > > The problem at this point is that the image won't display properly > until something like doing a very small levels correction forces a > screen redraw. After forcing a screen redraw, the image is displayed > without any posterization, but with magenta lines (outlining the > tiles?). The screen redraw lasts until the level dialog is closed. > > I think the problem is that I'm not properly merging and updating > "buffer" after the hard-coded transform. The corresponding code from > the lcms.c file uses layer buffers, which seems not applicable to a > projection: > gimp_drawable_merge_shadow (layer_id, TRUE); > gimp_drawable_update (layer_id, 0, 0, layer_width, layer_height); I do not know the GimpDisplayShell code well, but try to just read out data from the projection GeglBuffer instead of modifying it. And instead of the the "gegl_buffer_get (buffer, ... "cairo-ARGB32", ... data ...)" that you have marked, do the lcms transform such that the 8bit ready-for-display ends up in the "data" buffer. Also, can you please post your changes as a (git formatted) diff? It is much easier to read and apply for another contributor trying to help you out. -- Jon Nordby - www.jonnor.com ___ gimp-developer-list mailing list List address:gimp-developer-list@gnome.org List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list
Re: [Gimp-developer] Displaying linear gamma images
I've made progress getting a linear gamma image to display without posterization in the shadows. I put up a temporary web page with the modified code and a picture: http://ninedegreesbelow.com/temp/convert-buffer-before-cairo.html The problem at this point is that the image won't display properly until something like doing a very small levels correction forces a screen redraw. After forcing a screen redraw, the image is displayed without any posterization, but with magenta lines (outlining the tiles?). The screen redraw lasts until the level dialog is closed. I think the problem is that I'm not properly merging and updating "buffer" after the hard-coded transform. The corresponding code from the lcms.c file uses layer buffers, which seems not applicable to a projection: gimp_drawable_merge_shadow (layer_id, TRUE); gimp_drawable_update (layer_id, 0, 0, layer_width, layer_height); If I can get the screen to consistently display properly, then the next step would be to merge the code in "modules/display-filter-lcms.c" with the code in "app/display/gimpdisplayshell-render.c". But I'm somewhat at a stand-still until serendipity or someone with more knowledge about gegl buffers can solve the problem of getting the screen to display all the way all the time correctly rather than only after using levels to force a redraw. I've been searching the Gimp code base looking for that "serendipitous" example code to follow, and came up with "gimp_projection_flush_now (projection);" which seemed to help, but only a little. Elle -- http://ninedegreesbelow.com ___ gimp-developer-list mailing list List address:gimp-developer-list@gnome.org List membership: https://mail.gnome.org/mailman/listinfo/gimp-developer-list