1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <https://www.gnu.org/licenses/>.
16 */
17
18 #include "config.h"
19
20 #include <cairo.h>
21 #include <fontconfig/fontconfig.h>
22 #include <pango/pango.h>
23 #include <pango/pangoft2.h>
24 #include <gdk-pixbuf/gdk-pixbuf.h>
25 #include <lcms2.h>
26 #include <gexiv2/gexiv2.h>
27 #include <gegl.h>
28
29 #include "libgimpbase/gimpbase.h"
30
31 #include "sanity.h"
32
33 #include "gimp-intl.h"
34
35
36 /* early-stage tests */
37 static gchar * sanity_check_gimp (void);
38 static gchar * sanity_check_glib (void);
39 static gchar * sanity_check_cairo (void);
40 static gchar * sanity_check_pango (void);
41 static gchar * sanity_check_fontconfig (void);
42 static gchar * sanity_check_freetype (void);
43 static gchar * sanity_check_gdk_pixbuf (void);
44 static gchar * sanity_check_lcms (void);
45 static gchar * sanity_check_gexiv2 (void);
46 static gchar * sanity_check_babl (void);
47 static gchar * sanity_check_gegl (void);
48 static gchar * sanity_check_filename_encoding (void);
49
50 /* late-stage tests */
51 static gchar * sanity_check_gegl_ops (void);
52
53
54 /* public functions */
55
56 /* early-stage sanity check, performed before the call to app_run(). */
57 const gchar *
sanity_check_early(void)58 sanity_check_early (void)
59 {
60 gchar *abort_message = NULL;
61
62 if (! abort_message)
63 abort_message = sanity_check_gimp ();
64
65 if (! abort_message)
66 abort_message = sanity_check_glib ();
67
68 if (! abort_message)
69 abort_message = sanity_check_cairo ();
70
71 if (! abort_message)
72 abort_message = sanity_check_pango ();
73
74 if (! abort_message)
75 abort_message = sanity_check_fontconfig ();
76
77 if (! abort_message)
78 abort_message = sanity_check_freetype ();
79
80 if (! abort_message)
81 abort_message = sanity_check_gdk_pixbuf ();
82
83 if (! abort_message)
84 abort_message = sanity_check_lcms ();
85
86 if (! abort_message)
87 abort_message = sanity_check_gexiv2 ();
88
89 if (! abort_message)
90 abort_message = sanity_check_babl ();
91
92 if (! abort_message)
93 abort_message = sanity_check_gegl ();
94
95 if (! abort_message)
96 abort_message = sanity_check_filename_encoding ();
97
98 return abort_message;
99 }
100
101 /* late-stage sanity check, performed during app_run(), after the user
102 * configuration has been loaded.
103 */
104 const gchar *
sanity_check_late(void)105 sanity_check_late (void)
106 {
107 gchar *abort_message = NULL;
108
109 /* the gegl ops test initializes all gegl ops; in particular, it initializes
110 * all the strings used by their properties, which appear in the ui. it
111 * must be run after we've called language_init(), potentially overriding
112 * LANGUAGE according to the user config, or else all affected strings would
113 * use the translation corresponding to the system locale, regardless.
114 */
115 if (! abort_message)
116 abort_message = sanity_check_gegl_ops ();
117
118 return abort_message;
119 }
120
121
122 /* private functions */
123
124
125 /* early-stage tests */
126
127 static gboolean
sanity_check_version(guint major_version,guint required_major,guint minor_version,guint required_minor,guint micro_version,guint required_micro)128 sanity_check_version (guint major_version, guint required_major,
129 guint minor_version, guint required_minor,
130 guint micro_version, guint required_micro)
131 {
132 if (major_version > required_major)
133 return TRUE;
134
135 if (major_version < required_major)
136 return FALSE;
137
138 if (minor_version > required_minor)
139 return TRUE;
140
141 if (minor_version < required_minor)
142 return FALSE;
143
144 if (micro_version >= required_micro)
145 return TRUE;
146
147 return FALSE;
148 }
149
150 static gchar *
sanity_check_gimp(void)151 sanity_check_gimp (void)
152 {
153 if (GIMP_MAJOR_VERSION != gimp_major_version ||
154 GIMP_MINOR_VERSION != gimp_minor_version ||
155 GIMP_MICRO_VERSION != gimp_micro_version)
156 {
157 return g_strdup_printf
158 ("Libgimp version mismatch!\n\n"
159 "The GIMP binary cannot run with a libgimp version\n"
160 "other than its own. This is GIMP %d.%d.%d, but the\n"
161 "libgimp version is %d.%d.%d.\n\n"
162 "Maybe you have GIMP versions in both /usr and /usr/local ?",
163 GIMP_MAJOR_VERSION, GIMP_MINOR_VERSION, GIMP_MICRO_VERSION,
164 gimp_major_version, gimp_minor_version, gimp_micro_version);
165 }
166
167 return NULL;
168 }
169
170 static gchar *
sanity_check_glib(void)171 sanity_check_glib (void)
172 {
173 #define GLIB_REQUIRED_MAJOR 2
174 #define GLIB_REQUIRED_MINOR 56
175 #define GLIB_REQUIRED_MICRO 2
176
177 const gchar *mismatch = glib_check_version (GLIB_REQUIRED_MAJOR,
178 GLIB_REQUIRED_MINOR,
179 GLIB_REQUIRED_MICRO);
180
181 if (mismatch)
182 {
183 return g_strdup_printf
184 ("%s\n\n"
185 "GIMP requires GLib version %d.%d.%d or later.\n"
186 "Installed GLib version is %d.%d.%d.\n\n"
187 "Somehow you or your software packager managed\n"
188 "to install GIMP with an older GLib version.\n\n"
189 "Please upgrade to GLib version %d.%d.%d or later.",
190 mismatch,
191 GLIB_REQUIRED_MAJOR, GLIB_REQUIRED_MINOR, GLIB_REQUIRED_MICRO,
192 glib_major_version, glib_minor_version, glib_micro_version,
193 GLIB_REQUIRED_MAJOR, GLIB_REQUIRED_MINOR, GLIB_REQUIRED_MICRO);
194 }
195
196 #undef GLIB_REQUIRED_MAJOR
197 #undef GLIB_REQUIRED_MINOR
198 #undef GLIB_REQUIRED_MICRO
199
200 return NULL;
201 }
202
203 static gchar *
sanity_check_cairo(void)204 sanity_check_cairo (void)
205 {
206 #define CAIRO_REQUIRED_MAJOR 1
207 #define CAIRO_REQUIRED_MINOR 12
208 #define CAIRO_REQUIRED_MICRO 2
209
210 if (cairo_version () < CAIRO_VERSION_ENCODE (CAIRO_REQUIRED_MAJOR,
211 CAIRO_REQUIRED_MINOR,
212 CAIRO_REQUIRED_MICRO))
213 {
214 return g_strdup_printf
215 ("The Cairo version being used is too old!\n\n"
216 "GIMP requires Cairo version %d.%d.%d or later.\n"
217 "Installed Cairo version is %s.\n\n"
218 "Somehow you or your software packager managed\n"
219 "to install GIMP with an older Cairo version.\n\n"
220 "Please upgrade to Cairo version %d.%d.%d or later.",
221 CAIRO_REQUIRED_MAJOR, CAIRO_REQUIRED_MINOR, CAIRO_REQUIRED_MICRO,
222 cairo_version_string (),
223 CAIRO_REQUIRED_MAJOR, CAIRO_REQUIRED_MINOR, CAIRO_REQUIRED_MICRO);
224 }
225
226 #undef CAIRO_REQUIRED_MAJOR
227 #undef CAIRO_REQUIRED_MINOR
228 #undef CAIRO_REQUIRED_MICRO
229
230 return NULL;
231 }
232
233 static gchar *
sanity_check_pango(void)234 sanity_check_pango (void)
235 {
236 #define PANGO_REQUIRED_MAJOR 1
237 #define PANGO_REQUIRED_MINOR 29
238 #define PANGO_REQUIRED_MICRO 4
239
240 const gchar *mismatch = pango_version_check (PANGO_REQUIRED_MAJOR,
241 PANGO_REQUIRED_MINOR,
242 PANGO_REQUIRED_MICRO);
243
244 if (mismatch)
245 {
246 const gint pango_major_version = pango_version () / 100 / 100;
247 const gint pango_minor_version = pango_version () / 100 % 100;
248 const gint pango_micro_version = pango_version () % 100;
249
250 return g_strdup_printf
251 ("%s\n\n"
252 "GIMP requires Pango version %d.%d.%d or later.\n"
253 "Installed Pango version is %d.%d.%d.\n\n"
254 "Somehow you or your software packager managed\n"
255 "to install GIMP with an older Pango version.\n\n"
256 "Please upgrade to Pango version %d.%d.%d or later.",
257 mismatch,
258 PANGO_REQUIRED_MAJOR, PANGO_REQUIRED_MINOR, PANGO_REQUIRED_MICRO,
259 pango_major_version, pango_minor_version, pango_micro_version,
260 PANGO_REQUIRED_MAJOR, PANGO_REQUIRED_MINOR, PANGO_REQUIRED_MICRO);
261 }
262
263 #undef PANGO_REQUIRED_MAJOR
264 #undef PANGO_REQUIRED_MINOR
265 #undef PANGO_REQUIRED_MICRO
266
267 return NULL;
268 }
269
270 static gchar *
sanity_check_fontconfig(void)271 sanity_check_fontconfig (void)
272 {
273 const gint fc_version = FcGetVersion ();
274
275 #define FC_REQUIRED_MAJOR 2
276 #define FC_REQUIRED_MINOR 2
277 #define FC_REQUIRED_MICRO 0
278
279 if (fc_version < ((FC_REQUIRED_MAJOR * 10000) +
280 (FC_REQUIRED_MINOR * 100) +
281 (FC_REQUIRED_MICRO * 1)))
282 {
283 const gint fc_major_version = fc_version / 100 / 100;
284 const gint fc_minor_version = fc_version / 100 % 100;
285 const gint fc_micro_version = fc_version % 100;
286
287 return g_strdup_printf
288 ("The Fontconfig version being used is too old!\n\n"
289 "GIMP requires Fontconfig version %d.%d.%d or later.\n"
290 "The Fontconfig version loaded by GIMP is %d.%d.%d.\n\n"
291 "This may be caused by another instance of libfontconfig.so.1\n"
292 "being installed in the system, probably in /usr/X11R6/lib.\n"
293 "Please correct the situation or report it to someone who can.",
294 FC_REQUIRED_MAJOR, FC_REQUIRED_MINOR, FC_REQUIRED_MICRO,
295 fc_major_version, fc_minor_version, fc_micro_version);
296 }
297
298 #undef FC_REQUIRED_MAJOR
299 #undef FC_REQUIRED_MINOR
300 #undef FC_REQUIRED_MICRO
301
302 return NULL;
303 }
304
305 static gchar *
sanity_check_freetype(void)306 sanity_check_freetype (void)
307 {
308 FT_Library ft_library;
309 FT_Int ft_major_version;
310 FT_Int ft_minor_version;
311 FT_Int ft_micro_version;
312 FT_Int ft_version;
313
314 #define FT_REQUIRED_MAJOR 2
315 #define FT_REQUIRED_MINOR 1
316 #define FT_REQUIRED_MICRO 7
317
318 if (FT_Init_FreeType (&ft_library) != 0)
319 g_error ("FT_Init_FreeType() failed");
320
321 FT_Library_Version (ft_library,
322 &ft_major_version,
323 &ft_minor_version,
324 &ft_micro_version);
325
326 if (FT_Done_FreeType (ft_library) != 0)
327 g_error ("FT_Done_FreeType() failed");
328
329 ft_version = (ft_major_version * 10000 +
330 ft_minor_version * 100 +
331 ft_micro_version * 1);
332
333 if (ft_version < ((FT_REQUIRED_MAJOR * 10000) +
334 (FT_REQUIRED_MINOR * 100) +
335 (FT_REQUIRED_MICRO * 1)))
336 {
337 return g_strdup_printf
338 ("FreeType version too old!\n\n"
339 "GIMP requires FreeType version %d.%d.%d or later.\n"
340 "Installed FreeType version is %d.%d.%d.\n\n"
341 "Somehow you or your software packager managed\n"
342 "to install GIMP with an older FreeType version.\n\n"
343 "Please upgrade to FreeType version %d.%d.%d or later.",
344 FT_REQUIRED_MAJOR, FT_REQUIRED_MINOR, FT_REQUIRED_MICRO,
345 ft_major_version, ft_minor_version, ft_micro_version,
346 FT_REQUIRED_MAJOR, FT_REQUIRED_MINOR, FT_REQUIRED_MICRO);
347 }
348
349 #undef FT_REQUIRED_MAJOR
350 #undef FT_REQUIRED_MINOR
351 #undef FT_REQUIRED_MICRO
352
353 return NULL;
354 }
355
356 static gchar *
sanity_check_gdk_pixbuf(void)357 sanity_check_gdk_pixbuf (void)
358 {
359 #define GDK_PIXBUF_REQUIRED_MAJOR 2
360 #define GDK_PIXBUF_REQUIRED_MINOR 30
361 #define GDK_PIXBUF_REQUIRED_MICRO 8
362
363 if (! sanity_check_version (gdk_pixbuf_major_version, GDK_PIXBUF_REQUIRED_MAJOR,
364 gdk_pixbuf_minor_version, GDK_PIXBUF_REQUIRED_MINOR,
365 gdk_pixbuf_micro_version, GDK_PIXBUF_REQUIRED_MICRO))
366 {
367 return g_strdup_printf
368 ("GdkPixbuf version too old!\n\n"
369 "GIMP requires GdkPixbuf version %d.%d.%d or later.\n"
370 "Installed GdkPixbuf version is %d.%d.%d.\n\n"
371 "Somehow you or your software packager managed\n"
372 "to install GIMP with an older GdkPixbuf version.\n\n"
373 "Please upgrade to GdkPixbuf version %d.%d.%d or later.",
374 GDK_PIXBUF_REQUIRED_MAJOR, GDK_PIXBUF_REQUIRED_MINOR, GDK_PIXBUF_REQUIRED_MICRO,
375 gdk_pixbuf_major_version, gdk_pixbuf_minor_version, gdk_pixbuf_micro_version,
376 GDK_PIXBUF_REQUIRED_MAJOR, GDK_PIXBUF_REQUIRED_MINOR, GDK_PIXBUF_REQUIRED_MICRO);
377 }
378
379 #undef GDK_PIXBUF_REQUIRED_MAJOR
380 #undef GDK_PIXBUF_REQUIRED_MINOR
381 #undef GDK_PIXBUF_REQUIRED_MICRO
382
383 return NULL;
384 }
385
386 static gchar *
sanity_check_lcms(void)387 sanity_check_lcms (void)
388 {
389 #define LCMS_REQUIRED_MAJOR 2
390 #define LCMS_REQUIRED_MINOR 8
391
392 gint lcms_version = cmsGetEncodedCMMversion ();
393
394 if (lcms_version < (LCMS_REQUIRED_MAJOR * 1000 +
395 LCMS_REQUIRED_MINOR * 10))
396 {
397 const gint lcms_major_version = lcms_version / 1000;
398 const gint lcms_minor_version = lcms_version % 1000 / 10;
399
400 return g_strdup_printf
401 ("Liblcms2 version too old!\n\n"
402 "GIMP requires LittleCMS version %d.%d or later.\n"
403 "Installed LittleCMS version is %d.%d.\n\n"
404 "Somehow you or your software packager managed\n"
405 "to install GIMP with an older LittleCMS version.\n\n"
406 "Please upgrade to LittleCMS version %d.%d or later.",
407 LCMS_REQUIRED_MAJOR, LCMS_REQUIRED_MINOR,
408 lcms_major_version, lcms_minor_version,
409 LCMS_REQUIRED_MAJOR, LCMS_REQUIRED_MINOR);
410 }
411
412 #undef LCMS_REQUIRED_MAJOR
413 #undef LCMS_REQUIRED_MINOR
414
415 return NULL;
416 }
417
418 static gchar *
sanity_check_gexiv2(void)419 sanity_check_gexiv2 (void)
420 {
421 #ifdef GEXIV2_MAJOR_VERSION
422
423 #define GEXIV2_REQUIRED_MAJOR 0
424 #define GEXIV2_REQUIRED_MINOR 10
425 #define GEXIV2_REQUIRED_MICRO 6
426
427 gint gexiv2_version = gexiv2_get_version ();
428
429 if (gexiv2_version < (GEXIV2_REQUIRED_MAJOR * 100 * 100 +
430 GEXIV2_REQUIRED_MINOR * 100 +
431 GEXIV2_REQUIRED_MICRO))
432 {
433 const gint gexiv2_major_version = gexiv2_version / 100 / 100;
434 const gint gexiv2_minor_version = gexiv2_version / 100 % 100;
435 const gint gexiv2_micro_version = gexiv2_version % 100;
436
437 return g_strdup_printf
438 ("gexiv2 version too old!\n\n"
439 "GIMP requires gexiv2 version %d.%d.%d or later.\n"
440 "Installed gexiv2 version is %d.%d.%d.\n\n"
441 "Somehow you or your software packager managed\n"
442 "to install GIMP with an older gexiv2 version.\n\n"
443 "Please upgrade to gexiv2 version %d.%d.%d or later.",
444 GEXIV2_REQUIRED_MAJOR, GEXIV2_REQUIRED_MINOR, GEXIV2_REQUIRED_MICRO,
445 gexiv2_major_version, gexiv2_minor_version, gexiv2_micro_version,
446 GEXIV2_REQUIRED_MAJOR, GEXIV2_REQUIRED_MINOR, GEXIV2_REQUIRED_MICRO);
447 }
448
449 #undef GEXIV2_REQUIRED_MAJOR
450 #undef GEXIV2_REQUIRED_MINOR
451 #undef GEXIV2_REQUIRED_MICRO
452
453 #endif
454
455 return NULL;
456 }
457
458 static gchar *
sanity_check_babl(void)459 sanity_check_babl (void)
460 {
461 gint babl_major_version;
462 gint babl_minor_version;
463 gint babl_micro_version;
464
465 #define BABL_REQUIRED_MAJOR 0
466 #define BABL_REQUIRED_MINOR 1
467 #define BABL_REQUIRED_MICRO 78
468
469 babl_get_version (&babl_major_version,
470 &babl_minor_version,
471 &babl_micro_version);
472
473 if (! sanity_check_version (babl_major_version, BABL_REQUIRED_MAJOR,
474 babl_minor_version, BABL_REQUIRED_MINOR,
475 babl_micro_version, BABL_REQUIRED_MICRO))
476 {
477 return g_strdup_printf
478 ("BABL version too old!\n\n"
479 "GIMP requires BABL version %d.%d.%d or later.\n"
480 "Installed BABL version is %d.%d.%d.\n\n"
481 "Somehow you or your software packager managed\n"
482 "to install GIMP with an older BABL version.\n\n"
483 "Please upgrade to BABL version %d.%d.%d or later.",
484 BABL_REQUIRED_MAJOR, BABL_REQUIRED_MINOR, BABL_REQUIRED_MICRO,
485 babl_major_version, babl_minor_version, babl_micro_version,
486 BABL_REQUIRED_MAJOR, BABL_REQUIRED_MINOR, BABL_REQUIRED_MICRO);
487 }
488
489 #undef BABL_REQUIRED_MAJOR
490 #undef BABL_REQUIRED_MINOR
491 #undef BABL_REQUIRED_MICRO
492
493 return NULL;
494 }
495
496 static gchar *
sanity_check_gegl(void)497 sanity_check_gegl (void)
498 {
499 gint gegl_major_version;
500 gint gegl_minor_version;
501 gint gegl_micro_version;
502
503 #define GEGL_REQUIRED_MAJOR 0
504 #define GEGL_REQUIRED_MINOR 4
505 #define GEGL_REQUIRED_MICRO 34
506
507 gegl_get_version (&gegl_major_version,
508 &gegl_minor_version,
509 &gegl_micro_version);
510
511 if (! sanity_check_version (gegl_major_version, GEGL_REQUIRED_MAJOR,
512 gegl_minor_version, GEGL_REQUIRED_MINOR,
513 gegl_micro_version, GEGL_REQUIRED_MICRO))
514 {
515 return g_strdup_printf
516 ("GEGL version too old!\n\n"
517 "GIMP requires GEGL version %d.%d.%d or later.\n"
518 "Installed GEGL version is %d.%d.%d.\n\n"
519 "Somehow you or your software packager managed\n"
520 "to install GIMP with an older GEGL version.\n\n"
521 "Please upgrade to GEGL version %d.%d.%d or later.",
522 GEGL_REQUIRED_MAJOR, GEGL_REQUIRED_MINOR, GEGL_REQUIRED_MICRO,
523 gegl_major_version, gegl_minor_version, gegl_micro_version,
524 GEGL_REQUIRED_MAJOR, GEGL_REQUIRED_MINOR, GEGL_REQUIRED_MICRO);
525 }
526
527 #undef GEGL_REQUIRED_MAJOR
528 #undef GEGL_REQUIRED_MINOR
529 #undef GEGL_REQUIRED_MICRO
530
531 return NULL;
532 }
533
534 static gchar *
sanity_check_filename_encoding(void)535 sanity_check_filename_encoding (void)
536 {
537 gchar *result;
538 GError *error = NULL;
539
540 result = g_filename_to_utf8 ("", -1, NULL, NULL, &error);
541
542 if (! result)
543 {
544 gchar *msg =
545 g_strdup_printf
546 (_("The configured filename encoding cannot be converted to UTF-8: "
547 "%s\n\n"
548 "Please check the value of the environment variable "
549 "G_FILENAME_ENCODING."),
550 error->message);
551
552 g_error_free (error);
553
554 return msg;
555 }
556
557 g_free (result);
558
559 result = g_filename_to_utf8 (gimp_directory (), -1, NULL, NULL, &error);
560
561 if (! result)
562 {
563 gchar *msg =
564 g_strdup_printf
565 (_("The name of the directory holding the GIMP user configuration "
566 "cannot be converted to UTF-8: "
567 "%s\n\n"
568 "Your filesystem probably stores files in an encoding "
569 "other than UTF-8 and you didn't tell GLib about this. "
570 "Please set the environment variable G_FILENAME_ENCODING."),
571 error->message);
572
573 g_error_free (error);
574
575 return msg;
576 }
577
578 g_free (result);
579
580 return NULL;
581 }
582
583
584 /* late-stage tests */
585
586 static gchar *
sanity_check_gegl_ops(void)587 sanity_check_gegl_ops (void)
588 {
589 static const gchar *required_ops[] =
590 {
591 "gegl:alien-map",
592 "gegl:bayer-matrix",
593 "gegl:bloom",
594 "gegl:buffer-sink",
595 "gegl:buffer-source",
596 "gegl:c2g",
597 "gegl:cache",
598 "gegl:cartoon",
599 "gegl:cell-noise",
600 "gegl:checkerboard",
601 "gegl:color",
602 "gegl:color-enhance",
603 "gegl:color-exchange",
604 "gegl:color-rotate",
605 "gegl:color-temperature",
606 "gegl:color-to-alpha",
607 "gegl:component-extract",
608 "gegl:convolution-matrix",
609 "gegl:copy-buffer",
610 "gegl:crop",
611 "gegl:cubism",
612 "gegl:deinterlace",
613 "gegl:difference-of-gaussians",
614 "gegl:diffraction-patterns",
615 "gegl:displace",
616 "gegl:distance-transform",
617 "gegl:dither",
618 "gegl:dropshadow",
619 "gegl:edge",
620 "gegl:edge-laplace",
621 "gegl:edge-neon",
622 "gegl:edge-sobel",
623 "gegl:emboss",
624 "gegl:engrave",
625 "gegl:exposure",
626 "gegl:fattal02",
627 "gegl:focus-blur",
628 "gegl:fractal-trace",
629 "gegl:gaussian-blur",
630 "gegl:gaussian-blur-selective",
631 "gegl:gegl",
632 "gegl:grid",
633 "gegl:high-pass",
634 "gegl:hue-chroma",
635 "gegl:illusion",
636 "gegl:image-gradient",
637 "gegl:invert-gamma",
638 "gegl:invert-linear",
639 "gegl:lens-blur",
640 "gegl:lens-distortion",
641 "gegl:lens-flare",
642 "gegl:linear-sinusoid",
643 "gegl:long-shadow",
644 "gegl:mantiuk06",
645 "gegl:map-absolute",
646 "gegl:map-relative",
647 "gegl:matting-global",
648 "gegl:maze",
649 "gegl:mean-curvature-blur",
650 "gegl:median-blur",
651 "gegl:mirrors",
652 "gegl:mono-mixer",
653 "gegl:mosaic",
654 "gegl:motion-blur-circular",
655 "gegl:motion-blur-linear",
656 "gegl:motion-blur-zoom",
657 "gegl:newsprint",
658 "gegl:noise-cie-lch",
659 "gegl:noise-hsv",
660 "gegl:noise-hurl",
661 "gegl:noise-pick",
662 "gegl:noise-rgb",
663 "gegl:noise-slur",
664 "gegl:noise-solid",
665 "gegl:noise-spread",
666 "gegl:normal-map",
667 "gegl:npd",
668 "gegl:oilify",
669 "gegl:opacity",
670 "gegl:over",
671 "gegl:panorama-projection",
672 "gegl:perlin-noise",
673 "gegl:photocopy",
674 "gegl:pixelize",
675 "gegl:polar-coordinates",
676 "gegl:recursive-transform",
677 "gegl:red-eye-removal",
678 "gegl:reinhard05",
679 "gegl:rgb-clip",
680 "gegl:ripple",
681 "gegl:saturation",
682 "gegl:scale-ratio",
683 "gegl:seamless-clone",
684 "gegl:sepia",
685 "gegl:shadows-highlights",
686 "gegl:shift",
687 "gegl:simplex-noise",
688 "gegl:shift",
689 "gegl:sinus",
690 "gegl:slic",
691 "gegl:snn-mean",
692 "gegl:softglow",
693 "gegl:spherize",
694 "gegl:spiral",
695 "gegl:stereographic-projection",
696 "gegl:stretch-contrast",
697 "gegl:stretch-contrast-hsv",
698 "gegl:stress",
699 "gegl:supernova",
700 "gegl:threshold",
701 "gegl:tile",
702 "gegl:tile-paper",
703 "gegl:tile-glass",
704 "gegl:tile-seamless",
705 "gegl:transform",
706 "gegl:translate",
707 "gegl:unsharp-mask",
708 "gegl:value-invert",
709 "gegl:value-propagate",
710 "gegl:variable-blur",
711 "gegl:video-degradation",
712 "gegl:vignette",
713 "gegl:warp",
714 "gegl:waterpixels",
715 "gegl:wavelet-blur",
716 "gegl:waves",
717 "gegl:whirl-pinch",
718 "gegl:write-buffer"
719 };
720
721 gint i;
722
723 for (i = 0; i < G_N_ELEMENTS (required_ops); i++)
724 {
725 if (! gegl_has_operation (required_ops[i]))
726 {
727 return g_strdup_printf
728 ("GEGL operation missing!\n\n"
729 "GIMP requires the GEGL operation \"%s\".\n"
730 "This operation cannot be found. Check your\n"
731 "GEGL install and ensure it has been compiled\n"
732 "with any dependencies required for GIMP.",
733 required_ops [i]);
734 }
735 }
736
737 return NULL;
738 }
739