Gimp/app/operations/gimpoperationpointfilter.c
Jehan f8b7429a6c app: do not let trc uninitialized.
The trc variable could be initialized by the "trc" property, but even
though this is processed inside GimpOperationPointFilter code, the
property is only set in some of the child classes (such as Curves or
Levels). As a consequence, this was left unitialized and even actually
used in other child operations (unless they overrode prepare()). This
was the case of GimpOperationEqualize which was always working in
linear mode since GIMP 3.0 (see #14486).

Since uninitialized variables may end up as 0, which would have been
GIMP_TRC_LINEAR enum case anyway, this probably doesn't really change
the behavior. This is not guaranteed by C, but IIRC GObject zero-ed
object structs. Yet it is always better to be explicit.
2026-02-20 15:00:39 +00:00

149 lines
4.7 KiB
C

/* GIMP - The GNU Image Manipulation Program
* Copyright (C) 1995 Spencer Kimball and Peter Mattis
*
* gimpoperationpointfilter.c
* Copyright (C) 2007 Michael Natterer <mitch@gimp.org>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gegl.h>
#include "operations-types.h"
#include "gimpoperationpointfilter.h"
static void gimp_operation_point_filter_finalize (GObject *object);
static void gimp_operation_point_filter_prepare (GeglOperation *operation);
G_DEFINE_ABSTRACT_TYPE (GimpOperationPointFilter, gimp_operation_point_filter,
GEGL_TYPE_OPERATION_POINT_FILTER)
#define parent_class gimp_operation_point_filter_parent_class
static void
gimp_operation_point_filter_class_init (GimpOperationPointFilterClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
object_class->finalize = gimp_operation_point_filter_finalize;
operation_class->prepare = gimp_operation_point_filter_prepare;
}
static void
gimp_operation_point_filter_init (GimpOperationPointFilter *self)
{
self->trc_binding = NULL;
self->trc = GIMP_TRC_LINEAR;
}
static void
gimp_operation_point_filter_finalize (GObject *object)
{
GimpOperationPointFilter *self = GIMP_OPERATION_POINT_FILTER (object);
g_clear_object (&self->config);
G_OBJECT_CLASS (parent_class)->finalize (object);
}
void
gimp_operation_point_filter_get_property (GObject *object,
guint property_id,
GValue *value,
GParamSpec *pspec)
{
GimpOperationPointFilter *self = GIMP_OPERATION_POINT_FILTER (object);
switch (property_id)
{
case GIMP_OPERATION_POINT_FILTER_PROP_TRC:
g_value_set_enum (value, self->trc);
break;
case GIMP_OPERATION_POINT_FILTER_PROP_CONFIG:
g_value_set_object (value, self->config);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
void
gimp_operation_point_filter_set_property (GObject *object,
guint property_id,
const GValue *value,
GParamSpec *pspec)
{
GimpOperationPointFilter *self = GIMP_OPERATION_POINT_FILTER (object);
switch (property_id)
{
case GIMP_OPERATION_POINT_FILTER_PROP_TRC:
self->trc = g_value_get_enum (value);
break;
case GIMP_OPERATION_POINT_FILTER_PROP_CONFIG:
g_clear_object (&self->trc_binding);
g_set_object (&self->config, g_value_dup_object (value));
if (self->config &&
g_object_class_find_property (G_OBJECT_GET_CLASS (self), "trc") &&
g_object_class_find_property (G_OBJECT_GET_CLASS (self->config), "trc"))
self->trc_binding = g_object_bind_property (self->config, "trc",
self, "trc",
G_BINDING_SYNC_CREATE);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
}
}
static void
gimp_operation_point_filter_prepare (GeglOperation *operation)
{
GimpOperationPointFilter *self = GIMP_OPERATION_POINT_FILTER (operation);
const Babl *space = gegl_operation_get_source_space (operation,
"input");
const Babl *format;
switch (self->trc)
{
default:
case GIMP_TRC_LINEAR:
format = babl_format_with_space ("RGBA float", space);
break;
case GIMP_TRC_NON_LINEAR:
format = babl_format_with_space ("R'G'B'A float", space);
break;
case GIMP_TRC_PERCEPTUAL:
format = babl_format_with_space ("R~G~B~A float", space);
break;
}
gegl_operation_set_format (operation, "input", format);
gegl_operation_set_format (operation, "output", format);
}