/* This file is part of GEGL editor -- a gtk frontend for GEGL * * 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 . * * Copyright (C) 2003, 2004, 2006, 2007, 2008 Øyvind Kolås */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_UNISTD_H #include #endif #include "gegl-options.h" #ifdef HAVE_SPIRO #include "gegl-path-spiro.h" #endif #include "gegl-path-smooth.h" #include "operation/gegl-extension-handler.h" #ifdef G_OS_WIN32 #include #define getcwd(b,n) _getcwd(b,n) #define realpath(a,b) _fullpath(b,a,_MAX_PATH) #endif #define DEFAULT_COMPOSITION \ " 0 0 395 200 80 162 0.5 2000-2011 © Various contributors Sans 12 rgb(0.0000, 0.0000, 0.0000) 628 0 622 40 20 50 0 0 1.2 0 0 8 88 0 1.2 0 0 8 M50,0 C23,0 0,22 0,50 C0,77 22,100 50,100 C68,100 85,90 93,75 L40,75 C35,75 35,65 40,65 L98,65 C100,55 100,45 98,35 L40,35 C35,35 35,25 40,25 L93,25 C84,10 68,0 50,0 z rgb(1.0000, 1.0000, 1.0000) 176 0 1.2 0 0 8 M0,50 C0,78 24,100 50,100 C77,100 100,78 100,50 C100,45 99,40 98,35 C82,35 66,35 50,35 C42,35 35,42 35,50 C35,58 42,65 50,65 C56,65 61,61 64,56 C67,51 75,55 73,60 C69,69 60,75 50,75 C36,75 25,64 25,50 C25,36 36,25 50,25 L93,25 C83,9 67,0 49,0 C25,0 0,20 0,50 z rgb(1.0000, 1.0000, 1.0000) 264 0 1.2 0 0 8 M30,4 C12,13 0,30 0,50 C0,78 23,100 50,100 C71,100 88,88 96,71 L56,71 C42,71 30,59 30,45 L30,4 z rgb(1.0000, 1.0000, 1.0000) 0 0 linear false 3 42 43 44 0 0 rgb(0.7097, 0.7097, 0.7097) rgb(0.7661, 0.7661, 0.7661) " #define STDIN_BUF_SIZE 128 static void gegl_enable_fatal_warnings (void) { GLogLevelFlags fatal_mask; fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK); fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL; g_log_set_always_fatal (fatal_mask); } static gboolean file_is_gegl_xml (const gchar *path) { gchar *extension; extension = strrchr (path, '.'); if (!extension) return FALSE; extension++; if (extension[0]=='\0') return FALSE; if (!strcmp (extension, "xml")|| !strcmp (extension, "XML")|| !strcmp (extension, "svg") ) return TRUE; return FALSE; } gint main (gint argc, gchar **argv) { GeglOptions *o = NULL; GeglNode *gegl = NULL; gchar *script = NULL; GError *err = NULL; gchar *path_root = NULL; o = gegl_options_parse (argc, argv); if (o->fatal_warnings) { gegl_enable_fatal_warnings (); } g_thread_init (NULL); gegl_init (&argc, &argv); #ifdef HAVE_SPIRO gegl_path_spiro_init (); #endif gegl_path_smooth_init (); if (o->xml) { path_root = g_get_current_dir (); } else if (o->file) { if (!strcmp (o->file, "-")) /* read XML from stdin */ { path_root = g_get_current_dir (); } else { gchar *tmp; gchar *temp1 = g_strdup (o->file); gchar *temp2 = g_path_get_dirname (temp1); path_root = g_strdup (tmp = realpath (temp2, NULL)); g_free (tmp); g_free (temp1); g_free (temp2); } } if (o->xml) { script = g_strdup (o->xml); } else if (o->file) { if (!strcmp (o->file, "-")) /* read XML from stdin */ { gchar buf[STDIN_BUF_SIZE]; GString *acc = g_string_new (""); while (fgets (buf, STDIN_BUF_SIZE, stdin)) { g_string_append (acc, buf); } script = g_string_free (acc, FALSE); } else if (file_is_gegl_xml (o->file)) { g_file_get_contents (o->file, &script, NULL, &err); if (err != NULL) { g_warning ("Unable to read file: %s", err->message); } } else { gchar *leaked_string = g_malloc (strlen (o->file) + 5); GString *acc = g_string_new (""); { gchar *file_basename; gchar *tmp; tmp = g_strdup (o->file); file_basename = g_path_get_basename (tmp); g_string_append (acc, ""); g_free (tmp); } script = g_string_free (acc, FALSE); leaked_string[0]='\0'; strcat (leaked_string, o->file); strcat (leaked_string, ".xml"); } } else { if (o->rest) { script = g_strdup (""); } else { script = g_strdup (DEFAULT_COMPOSITION); } } gegl = gegl_node_new_from_xml (script, path_root); if (!gegl) { g_print ("Invalid graph, abort.\n"); return 1; } if (o->rest) { GeglNode *proxy; GeglNode *iter; gchar **operation = o->rest; proxy = gegl_node_get_output_proxy (gegl, "output"); iter = gegl_node_get_producer (proxy, "input", NULL); while (*operation) { GeglNode *new; new = gegl_node_new_child (gegl, "operation", *operation, NULL); if (iter) { gegl_node_link_many (iter, new, proxy, NULL); } else { gegl_node_link_many (new, proxy, NULL); } iter = new; operation++; } } switch (o->mode) { case GEGL_RUN_MODE_DISPLAY: { GeglNode *output = gegl_node_new_child (gegl, "operation", "gegl:display", o->file ? "window-title" : NULL, o->file, NULL); gegl_node_connect_from (output, "input", gegl_node_get_output_proxy (gegl, "output"), "output"); gegl_node_process (output); g_main_loop_run (g_main_loop_new (NULL, TRUE)); g_object_unref (output); } break; case GEGL_RUN_MODE_XML: g_printf ("%s\n", gegl_node_to_xml (gegl, path_root)); return 0; break; case GEGL_RUN_MODE_OUTPUT: { GeglNode *output = gegl_node_new_child (gegl, "operation", "gegl:save", "path", o->output, NULL); gegl_node_connect_from (output, "input", gegl_node_get_output_proxy (gegl, "output"), "output"); gegl_node_process (output); g_object_unref (output); } break; case GEGL_RUN_MODE_HELP: break; default: g_warning ("Unknown GeglOption mode: %d", o->mode); break; } g_list_free_full (o->files, g_free); g_free (o); g_object_unref (gegl); g_free (script); g_clear_error (&err); g_free (path_root); gegl_exit (); return 0; }