mirror of https://github.com/GNOME/gimp.git
Issue #5888: GIMP 2.99.2 crash when using brush in multiply mode.
The GimpOperationLayerMode variable member in DoLayerBlend was not properly constructed. C++ class constructor can be called by creating object variables, but with GObject, we have to do it with pointers. Otherwise here we were only allocating the memory for the struct, but not actually calling any initialization functions. Also it would seem that the struct was not initialized at zero, as the space_fish variable was not NULL when it should (i.e. even with same composite and blend space), hence composite_to_blend_fish was not NULL and since the operation was not a valid GeglOperation when entering gimp_operation_layer_mode_real_process(), we crashed. Not sure how it went unseen for so long! So instead let's make the layer_mode class member into a pointer. As such, I have to properly allocate and free it. This is also why I am adding a copy constructor which will ref the pointer (otherwise we unref more than we ref as the default copy constructor would just copy the pointer).
This commit is contained in:
parent
93756733ee
commit
b3fc24268a
|
@ -204,7 +204,7 @@ gimp_gegl_mode_node_set_mode (GeglNode *node,
|
|||
* all its properties
|
||||
*/
|
||||
gegl_node_set (node,
|
||||
"operation", gimp_layer_mode_get_operation (mode),
|
||||
"operation", gimp_layer_mode_get_operation_name (mode),
|
||||
"layer-mode", mode,
|
||||
"opacity", opacity,
|
||||
"blend-space", blend_space,
|
||||
|
|
|
@ -1255,7 +1255,7 @@ gimp_layer_mode_get_paint_composite_mode (GimpLayerMode mode)
|
|||
}
|
||||
|
||||
const gchar *
|
||||
gimp_layer_mode_get_operation (GimpLayerMode mode)
|
||||
gimp_layer_mode_get_operation_name (GimpLayerMode mode)
|
||||
{
|
||||
const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
|
||||
|
||||
|
@ -1265,6 +1265,27 @@ gimp_layer_mode_get_operation (GimpLayerMode mode)
|
|||
return info->op_name;
|
||||
}
|
||||
|
||||
GeglOperation *
|
||||
gimp_layer_mode_get_operation (GimpLayerMode mode)
|
||||
{
|
||||
const GimpLayerModeInfo *info = gimp_layer_mode_info (mode);
|
||||
GeglNode *node;
|
||||
GeglOperation *operation;
|
||||
|
||||
if (! info)
|
||||
info = layer_mode_infos;
|
||||
|
||||
node = gegl_node_new_child (NULL,
|
||||
"operation", info->op_name,
|
||||
NULL);
|
||||
|
||||
operation = gegl_node_get_gegl_operation (node);
|
||||
g_object_ref (operation);
|
||||
g_object_unref (node);
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
GimpLayerModeFunc
|
||||
gimp_layer_mode_get_function (GimpLayerMode mode)
|
||||
{
|
||||
|
|
|
@ -40,7 +40,8 @@ GimpLayerColorSpace gimp_layer_mode_get_composite_space (GimpLayer
|
|||
GimpLayerCompositeMode gimp_layer_mode_get_composite_mode (GimpLayerMode mode);
|
||||
GimpLayerCompositeMode gimp_layer_mode_get_paint_composite_mode (GimpLayerMode mode);
|
||||
|
||||
const gchar * gimp_layer_mode_get_operation (GimpLayerMode mode);
|
||||
const gchar * gimp_layer_mode_get_operation_name (GimpLayerMode mode);
|
||||
GeglOperation * gimp_layer_mode_get_operation (GimpLayerMode mode);
|
||||
|
||||
GimpLayerModeFunc gimp_layer_mode_get_function (GimpLayerMode mode);
|
||||
GimpLayerModeBlendFunc gimp_layer_mode_get_blend_function (GimpLayerMode mode);
|
||||
|
|
|
@ -1876,30 +1876,44 @@ struct DoLayerBlend : Base
|
|||
|
||||
static constexpr gint max_n_iterators = Base::max_n_iterators + 2;
|
||||
|
||||
const Babl *iterator_format;
|
||||
GimpOperationLayerMode layer_mode;
|
||||
const Babl *iterator_format;
|
||||
GimpOperationLayerMode *layer_mode = NULL;
|
||||
const GimpPaintCoreLoopsParams *params;
|
||||
|
||||
explicit
|
||||
DoLayerBlend (const GimpPaintCoreLoopsParams *params) :
|
||||
Base (params)
|
||||
Base (params), params(params)
|
||||
{
|
||||
layer_mode.layer_mode = params->paint_mode;
|
||||
layer_mode.opacity = params->image_opacity;
|
||||
layer_mode.function = gimp_layer_mode_get_function (params->paint_mode);
|
||||
layer_mode.blend_function = gimp_layer_mode_get_blend_function (params->paint_mode);
|
||||
layer_mode.blend_space = gimp_layer_mode_get_blend_space (params->paint_mode);
|
||||
layer_mode.composite_space = gimp_layer_mode_get_composite_space (params->paint_mode);
|
||||
layer_mode.composite_mode = gimp_layer_mode_get_paint_composite_mode (params->paint_mode);
|
||||
layer_mode = GIMP_OPERATION_LAYER_MODE (gimp_layer_mode_get_operation (params->paint_mode));
|
||||
layer_mode->layer_mode = params->paint_mode;
|
||||
layer_mode->opacity = params->image_opacity;
|
||||
layer_mode->function = gimp_layer_mode_get_function (params->paint_mode);
|
||||
layer_mode->blend_function = gimp_layer_mode_get_blend_function (params->paint_mode);
|
||||
layer_mode->blend_space = gimp_layer_mode_get_blend_space (params->paint_mode);
|
||||
layer_mode->composite_space = gimp_layer_mode_get_composite_space (params->paint_mode);
|
||||
layer_mode->composite_mode = gimp_layer_mode_get_paint_composite_mode (params->paint_mode);
|
||||
|
||||
iterator_format = gimp_layer_mode_get_format (params->paint_mode,
|
||||
layer_mode.blend_space,
|
||||
layer_mode.composite_space,
|
||||
layer_mode.composite_mode,
|
||||
layer_mode->blend_space,
|
||||
layer_mode->composite_space,
|
||||
layer_mode->composite_mode,
|
||||
gimp_temp_buf_get_format (params->paint_buf));
|
||||
|
||||
g_return_if_fail (gimp_temp_buf_get_format (params->paint_buf) == iterator_format);
|
||||
}
|
||||
|
||||
DoLayerBlend (const DoLayerBlend &algorithm) :
|
||||
Base (algorithm.params), params(algorithm.params)
|
||||
{
|
||||
layer_mode = GIMP_OPERATION_LAYER_MODE (g_object_ref (algorithm.layer_mode));
|
||||
iterator_format = algorithm.iterator_format;
|
||||
}
|
||||
|
||||
~DoLayerBlend ()
|
||||
{
|
||||
g_clear_object (&layer_mode);
|
||||
}
|
||||
|
||||
template <class Derived>
|
||||
struct State : Base::template State<Derived>
|
||||
{
|
||||
|
@ -2006,14 +2020,14 @@ struct DoLayerBlend : Base
|
|||
|
||||
state->process_roi.y = y;
|
||||
|
||||
layer_mode.function ((GeglOperation*) &layer_mode,
|
||||
state->in_pixel,
|
||||
state->paint_pixel,
|
||||
mask_pixel,
|
||||
out_pixel,
|
||||
rect->width,
|
||||
&state->process_roi,
|
||||
0);
|
||||
layer_mode->function ((GeglOperation*) layer_mode,
|
||||
state->in_pixel,
|
||||
state->paint_pixel,
|
||||
mask_pixel,
|
||||
out_pixel,
|
||||
rect->width,
|
||||
&state->process_roi,
|
||||
0);
|
||||
|
||||
state->in_pixel += rect->width * 4;
|
||||
state->paint_pixel += this->paint_stride;
|
||||
|
|
Loading…
Reference in New Issue