Update Chinese (China) translation
[gegl.git] / operations / common / alpha-clip.c
blob6f786130d8f30b809c963b5ba2a3a4c0338edb75
1 /* This file is an image processing operation for GEGL
3 * GEGL is free software; you can redistribute it and/or
4 * modify it under the terms of the GNU Lesser General Public
5 * License as published by the Free Software Foundation; either
6 * version 3 of the License, or (at your option) any later version.
8 * GEGL is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 * Lesser General Public License for more details.
13 * You should have received a copy of the GNU Lesser General Public
14 * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
16 * Copyright 2015 Thomas Manni <thomas.manni@free.fr>
17 * 2023 Øyvind Kolås <pippin@gimp.org>
21 #include "config.h"
22 #include <glib/gi18n-lib.h>
24 #ifdef GEGL_PROPERTIES
26 property_boolean (clip_low, _("Clip low pixel values"), TRUE)
27 description (_("Clip low pixel values"))
29 property_double (low_limit, _("Low limit"), 0.0)
30 value_range (-G_MAXDOUBLE, G_MAXDOUBLE)
31 ui_range (-1.0, 1.0)
32 description (_("Pixels values lower than this limit will be set to it"))
33 ui_meta ("sensitive", "clip-low")
35 property_boolean (clip_high, _("Clip high pixel values"), TRUE)
36 description (_("Clip high pixel values"))
38 property_double (high_limit, _("High limit"), 1.0)
39 value_range (-G_MAXDOUBLE, G_MAXDOUBLE)
40 ui_range (0.0, 2.0)
41 description (_("Pixels values higher than this limit will be set to it"))
42 ui_meta ("sensitive", "clip-high")
44 #else
46 #define GEGL_OP_POINT_FILTER
47 #define GEGL_OP_NAME alpha_clip
48 #define GEGL_OP_C_SOURCE alpha-clip.c
50 #include "gegl-op.h"
52 static void
53 prepare (GeglOperation *operation)
55 const Babl *space = gegl_operation_get_source_space (operation, "input");
56 const Babl *src_format = gegl_operation_get_source_format (operation, "input");
57 const char *format = "RGBA float";
59 if (src_format)
61 const Babl *model = babl_format_get_model (src_format);
63 if (babl_model_is (model, "RGB"))
64 format = "RGBA float";
65 else if (babl_model_is (model, "RGBA"))
66 format = "RGBA float";
67 else if (babl_model_is (model, "R'G'B'"))
68 format = "R'G'B'A float";
69 else if (babl_model_is (model, "R'G'B'A"))
70 format = "R'G'B'A float";
73 gegl_operation_set_format (operation, "input", babl_format_with_space (format, space));
74 gegl_operation_set_format (operation, "output", babl_format_with_space (format, space));
77 static gboolean
78 process (GeglOperation *operation,
79 void *in_buf,
80 void *out_buf,
81 glong n_pixels,
82 const GeglRectangle *roi,
83 gint level)
85 GeglProperties *o = GEGL_PROPERTIES (operation);
86 gint n_components = 4;
87 gfloat *input = in_buf;
88 gfloat *output = out_buf;
90 float low_limit = o->low_limit;
91 float high_limit = o->high_limit;
93 if (o->clip_low && o->clip_high)
95 while (n_pixels--)
97 for (int i = 0; i < 3; i++) output[i] = input[i];
98 output[3] = CLAMP (input[3], low_limit, high_limit);
100 input += n_components;
101 output += n_components;
105 else if (o->clip_high)
107 while (n_pixels--)
109 for (int i = 0; i < 3; i++) output[i] = input[i];
110 output[3] = input[3] > high_limit ? high_limit : input[3];
112 input += n_components;
113 output += n_components;
117 else if (o->clip_low)
119 while (n_pixels--)
121 for (int i = 0; i < 3; i++) output[i] = input[i];
122 output[3] = input[3] < low_limit ? low_limit : input[3];
124 input += n_components;
125 output += n_components;
129 return TRUE;
132 static gboolean
133 operation_process (GeglOperation *operation,
134 GeglOperationContext *context,
135 const gchar *output_prop,
136 const GeglRectangle *result,
137 gint level)
139 GeglOperationClass *operation_class;
140 GeglProperties *o = GEGL_PROPERTIES (operation);
142 operation_class = GEGL_OPERATION_CLASS (gegl_op_parent_class);
144 if (!o->clip_high && !o->clip_low)
146 gpointer in = gegl_operation_context_get_object (context, "input");
147 gegl_operation_context_take_object (context, "output",
148 g_object_ref (G_OBJECT (in)));
149 return TRUE;
152 /* chain up, which will create the needed buffers for our actual
153 * process function
155 return operation_class->process (operation, context, output_prop, result,
156 gegl_operation_context_get_level (context));
159 static void
160 gegl_op_class_init (GeglOpClass *klass)
162 GeglOperationClass *operation_class;
163 GeglOperationPointFilterClass *filter_class;
164 gchar *composition =
165 "<?xml version='1.0' encoding='UTF-8'?>"
166 "<gegl>"
167 " <node operation='gegl:crop' width='200' height='200'/>"
168 " <node operation='gegl:over'>"
169 " <node operation='gegl:alpha-clip'>"
170 " <params>"
171 " <param name='low_limit'>0.2</param>"
172 " <param name='high_limit'>0.8</param>"
173 " </params>"
174 " </node>"
175 " <node operation='gegl:load' path='standard-input.png'/>"
176 " </node>"
177 " <node operation='gegl:checkerboard'>"
178 " <params>"
179 " <param name='color1'>rgb(0.25,0.25,0.25)</param>"
180 " <param name='color2'>rgb(0.75,0.75,0.75)</param>"
181 " </params>"
182 " </node>"
183 "</gegl>";
185 operation_class = GEGL_OPERATION_CLASS (klass);
186 filter_class = GEGL_OPERATION_POINT_FILTER_CLASS (klass);
188 operation_class->prepare = prepare;
189 operation_class->process = operation_process;
190 operation_class->opencl_support = FALSE;
192 filter_class->process = process;
194 gegl_operation_class_set_keys (operation_class,
195 "name", "gegl:alpha-clip",
196 "title", _("Clip Alpha"),
197 "categories", "color",
198 "reference-composition", composition,
199 "description", _("Keep alpha values inside a specific range"),
200 NULL);
203 #endif