1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * gimpoperationhistogramsink.c
5 * Copyright (C) 2012 Øyvind Kolås
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <gegl.h>
24
25 #include "operations-types.h"
26
27 #include "core/gimphistogram.h"
28
29 #include "gimpoperationhistogramsink.h"
30
31
32 enum
33 {
34 PROP_0,
35 PROP_AUX,
36 PROP_HISTOGRAM
37 };
38
39
40 static void gimp_operation_histogram_sink_finalize (GObject *object);
41 static void gimp_operation_histogram_sink_get_property (GObject *object,
42 guint prop_id,
43 GValue *value,
44 GParamSpec *pspec);
45 static void gimp_operation_histogram_sink_set_property (GObject *object,
46 guint prop_id,
47 const GValue *value,
48 GParamSpec *pspec);
49
50 static void gimp_operation_histogram_sink_attach (GeglOperation *operation);
51 static void gimp_operation_histogram_sink_prepare (GeglOperation *operation);
52 static GeglRectangle
53 gimp_operation_histogram_sink_get_required_for_output (GeglOperation *self,
54 const gchar *input_pad,
55 const GeglRectangle *roi);
56 static gboolean gimp_operation_histogram_sink_process (GeglOperation *operation,
57 GeglOperationContext *context,
58 const gchar *output_prop,
59 const GeglRectangle *result,
60 gint level);
61
62
G_DEFINE_TYPE(GimpOperationHistogramSink,gimp_operation_histogram_sink,GEGL_TYPE_OPERATION_SINK)63 G_DEFINE_TYPE (GimpOperationHistogramSink, gimp_operation_histogram_sink,
64 GEGL_TYPE_OPERATION_SINK)
65
66 #define parent_class gimp_operation_histogram_sink_parent_class
67
68
69 static void
70 gimp_operation_histogram_sink_class_init (GimpOperationHistogramSinkClass *klass)
71 {
72 GObjectClass *object_class = G_OBJECT_CLASS (klass);
73 GeglOperationClass *operation_class = GEGL_OPERATION_CLASS (klass);
74
75 object_class->finalize = gimp_operation_histogram_sink_finalize;
76 object_class->set_property = gimp_operation_histogram_sink_set_property;
77 object_class->get_property = gimp_operation_histogram_sink_get_property;
78
79 gegl_operation_class_set_keys (operation_class,
80 "name" , "gimp:histogram-sink",
81 "categories" , "color",
82 "description", "GIMP Histogram sink operation",
83 NULL);
84
85 operation_class->attach = gimp_operation_histogram_sink_attach;
86 operation_class->prepare = gimp_operation_histogram_sink_prepare;
87 operation_class->get_required_for_output = gimp_operation_histogram_sink_get_required_for_output;
88 operation_class->process = gimp_operation_histogram_sink_process;
89
90 g_object_class_install_property (object_class, PROP_AUX,
91 g_param_spec_object ("aux",
92 "Aux",
93 "Auxiliary image buffer input pad.",
94 GEGL_TYPE_BUFFER,
95 G_PARAM_READWRITE |
96 GEGL_PARAM_PAD_INPUT));
97
98 g_object_class_install_property (object_class, PROP_HISTOGRAM,
99 g_param_spec_object ("histogram",
100 "Histogram",
101 "The result histogram",
102 GIMP_TYPE_HISTOGRAM,
103 G_PARAM_READWRITE));
104 }
105
106 static void
gimp_operation_histogram_sink_init(GimpOperationHistogramSink * self)107 gimp_operation_histogram_sink_init (GimpOperationHistogramSink *self)
108 {
109 }
110
111 static void
gimp_operation_histogram_sink_finalize(GObject * object)112 gimp_operation_histogram_sink_finalize (GObject *object)
113 {
114 GimpOperationHistogramSink *sink = GIMP_OPERATION_HISTOGRAM_SINK (object);
115
116 g_clear_object (&sink->histogram);
117
118 G_OBJECT_CLASS (parent_class)->finalize (object);
119 }
120
121 static void
gimp_operation_histogram_sink_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)122 gimp_operation_histogram_sink_get_property (GObject *object,
123 guint prop_id,
124 GValue *value,
125 GParamSpec *pspec)
126 {
127 GimpOperationHistogramSink *sink = GIMP_OPERATION_HISTOGRAM_SINK (object);
128
129 switch (prop_id)
130 {
131 case PROP_AUX:
132 break;
133
134 case PROP_HISTOGRAM:
135 g_value_set_pointer (value, sink->histogram);
136 break;
137
138 default:
139 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
140 break;
141 }
142 }
143
144 static void
gimp_operation_histogram_sink_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)145 gimp_operation_histogram_sink_set_property (GObject *object,
146 guint prop_id,
147 const GValue *value,
148 GParamSpec *pspec)
149 {
150 GimpOperationHistogramSink *sink = GIMP_OPERATION_HISTOGRAM_SINK (object);
151
152 switch (prop_id)
153 {
154 case PROP_AUX:
155 break;
156
157 case PROP_HISTOGRAM:
158 if (sink->histogram)
159 g_object_unref (sink->histogram);
160 sink->histogram = g_value_dup_object (value);
161 break;
162
163 default:
164 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
165 break;
166 }
167 }
168
169 static void
gimp_operation_histogram_sink_attach(GeglOperation * self)170 gimp_operation_histogram_sink_attach (GeglOperation *self)
171 {
172 GeglOperation *operation = GEGL_OPERATION (self);
173 GObjectClass *object_class = G_OBJECT_GET_CLASS (self);
174
175 GEGL_OPERATION_CLASS (parent_class)->attach (self);
176
177 gegl_operation_create_pad (operation,
178 g_object_class_find_property (object_class,
179 "aux"));
180 }
181
182 static void
gimp_operation_histogram_sink_prepare(GeglOperation * operation)183 gimp_operation_histogram_sink_prepare (GeglOperation *operation)
184 {
185 /* XXX gegl_operation_set_format (operation, "input", babl_format ("Y u8")); */
186 gegl_operation_set_format (operation, "aux", babl_format ("Y float"));
187 }
188
189 static GeglRectangle
gimp_operation_histogram_sink_get_required_for_output(GeglOperation * self,const gchar * input_pad,const GeglRectangle * roi)190 gimp_operation_histogram_sink_get_required_for_output (GeglOperation *self,
191 const gchar *input_pad,
192 const GeglRectangle *roi)
193 {
194 /* dunno what to do here, make a wild guess */
195 return *roi;
196 }
197
198 static gboolean
gimp_operation_histogram_sink_process(GeglOperation * operation,GeglOperationContext * context,const gchar * output_prop,const GeglRectangle * result,gint level)199 gimp_operation_histogram_sink_process (GeglOperation *operation,
200 GeglOperationContext *context,
201 const gchar *output_prop,
202 const GeglRectangle *result,
203 gint level)
204 {
205 GeglBuffer *input;
206 GeglBuffer *aux;
207
208 if (strcmp (output_prop, "output"))
209 {
210 g_warning ("requested processing of %s pad on a sink", output_prop);
211 return FALSE;
212 }
213
214 input = (GeglBuffer*) gegl_operation_context_dup_object (context, "input");
215 aux = (GeglBuffer*) gegl_operation_context_dup_object (context, "aux");
216
217 if (! input)
218 {
219 g_warning ("received NULL input");
220
221 return FALSE;
222 }
223
224 if (aux)
225 {
226 /* do hist with mask */
227
228 g_printerr ("aux format: %s\n",
229 babl_get_name (gegl_buffer_get_format (aux)));
230
231 g_object_unref (aux);
232 }
233 else
234 {
235 /* without */
236 }
237
238 g_printerr ("input format: %s\n",
239 babl_get_name (gegl_buffer_get_format (input)));
240
241 g_object_unref (input);
242
243 return TRUE;
244 }
245