Blame bin/gegl.c

Packit bc1512
/* This file is part of GEGL editor -- a gtk frontend for GEGL
Packit bc1512
 *
Packit bc1512
 * This program is free software; you can redistribute it and/or modify
Packit bc1512
 * it under the terms of the GNU General Public License as published by
Packit bc1512
 * the Free Software Foundation; either version 3 of the License, or
Packit bc1512
 * (at your option) any later version.
Packit bc1512
 *
Packit bc1512
 * This program is distributed in the hope that it will be useful,
Packit bc1512
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit bc1512
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit bc1512
 * GNU General Public License for more details.
Packit bc1512
 *
Packit bc1512
 * You should have received a copy of the GNU General Public License
Packit bc1512
 * along with this program; if not, see <http://www.gnu.org/licenses/>.
Packit bc1512
 *
Packit bc1512
 * Copyright (C) 2003, 2004, 2006, 2007, 2008 Øyvind Kolås
Packit bc1512
 */
Packit bc1512
Packit bc1512
#include "config.h"
Packit bc1512
Packit bc1512
#include <glib.h>
Packit bc1512
#include <glib/gprintf.h>
Packit bc1512
#include <gegl.h>
Packit bc1512
#include <stdio.h>
Packit bc1512
#include <stdlib.h>
Packit bc1512
#include <string.h>
Packit bc1512
#ifdef HAVE_UNISTD_H
Packit bc1512
#include <unistd.h>
Packit bc1512
#endif
Packit bc1512
Packit bc1512
#include "gegl-options.h"
Packit bc1512
#ifdef HAVE_SPIRO
Packit bc1512
#include "gegl-path-spiro.h"
Packit bc1512
#endif
Packit bc1512
#include "gegl-path-smooth.h"
Packit bc1512
#include "operation/gegl-extension-handler.h"
Packit bc1512
Packit bc1512
#ifdef G_OS_WIN32
Packit bc1512
#include <direct.h>
Packit bc1512
#define getcwd(b,n) _getcwd(b,n)
Packit bc1512
#define realpath(a,b) _fullpath(b,a,_MAX_PATH)
Packit bc1512
#endif
Packit bc1512
Packit bc1512
#define DEFAULT_COMPOSITION \
Packit bc1512
" <gegl> <node operation='gegl:crop'> <params> <param name='x'>0</param> <param name='y'>0</param> <param name='width'>395</param> <param name='height'>200</param> </params> </node> <node operation='gegl:over'> <node operation='gegl:translate'> <params> <param name='x'>80</param> <param name='y'>162</param> </params> </node> <node operation='gegl:opacity'> <params> <param name='value'>0.5</param> </params> </node> <node name='text' operation='gegl:text'> <params> <param name='string'>2000-2011 © Various contributors</param> <param name='font'>Sans</param> <param name='size'>12</param> <param name='color'>rgb(0.0000, 0.0000, 0.0000)</param> <param name='wrap'>628</param> <param name='alignment'>0</param> <param name='width'>622</param> <param name='height'>40</param> </params> </node> </node> <node operation='gegl:over'> <node operation='gegl:translate'> <params> <param name='x'>20</param> <param name='y'>50</param> </params> </node> <node operation='gegl:over'> <node operation='gegl:translate'> <params> <param name='x'>0</param> <param name='y'>0</param> </params> </node> <node operation='gegl:dropshadow'> <params> <param name='opacity'>1.2</param> <param name='x'>0</param> <param name='y'>0</param> <param name='radius'>8</param> </params> </node> <gegl:fill-path d='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' color='white'/> </node> <node operation='gegl:over'> <node operation='gegl:translate'> <params> <param name='x'>88</param> <param name='y'>0</param> </params> </node> <node operation='gegl:dropshadow'> <params> <param name='opacity'>1.2</param> <param name='x'>0</param> <param name='y'>0</param> <param name='radius'>8</param> </params> </node> <node operation='gegl:fill-path'> <params> <param name='d'>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</param> <param name='color'>rgb(1.0000, 1.0000, 1.0000)</param> </params> </node> </node> <node operation='gegl:over'> <node operation='gegl:translate'> <params> <param name='x'>176</param> <param name='y'>0</param> </params> </node> <node operation='gegl:dropshadow'> <params> <param name='opacity'>1.2</param> <param name='x'>0</param> <param name='y'>0</param> <param name='radius'>8</param> </params> </node> <node operation='gegl:fill-path'> <params> <param name='d'>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</param> <param name='color'>rgb(1.0000, 1.0000, 1.0000)</param> </params> </node> </node> <node operation='gegl:translate'> <params> <param name='x'>264</param> <param name='y'>0</param> </params> </node> <node operation='gegl:dropshadow'> <params> <param name='opacity'>1.2</param> <param name='x'>0</param> <param name='y'>0</param> <param name='radius'>8</param> </params> </node> <node operation='gegl:fill-path'> <params> <param name='d'>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</param> <param name='color'>rgb(1.0000, 1.0000, 1.0000)</param> </params> </node> </node> <node operation='gegl:rotate'> <params> <param name='origin-x'>0</param> <param name='origin-y'>0</param> <param name='filter'>linear</param> <param name='hard-edges'>false</param> <param name='lanczos-width'>3</param> <param name='degrees'>42</param> </params> </node> <node operation='gegl:checkerboard'> <params> <param name='x'>43</param> <param name='y'>44</param> <param name='x-offset'>0</param> <param name='y-offset'>0</param> <param name='color1'>rgb(0.7097, 0.7097, 0.7097)</param> <param name='color2'>rgb(0.7661, 0.7661, 0.7661)</param> </params> </node> </gegl>"
Packit bc1512
Packit bc1512
#define STDIN_BUF_SIZE 128
Packit bc1512
Packit bc1512
static void
Packit bc1512
gegl_enable_fatal_warnings (void)
Packit bc1512
{
Packit bc1512
  GLogLevelFlags fatal_mask;
Packit bc1512
Packit bc1512
  fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
Packit bc1512
  fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
Packit bc1512
Packit bc1512
  g_log_set_always_fatal (fatal_mask);
Packit bc1512
}
Packit bc1512
Packit bc1512
static gboolean file_is_gegl_xml (const gchar *path)
Packit bc1512
{
Packit bc1512
  gchar *extension;
Packit bc1512
Packit bc1512
  extension = strrchr (path, '.');
Packit bc1512
  if (!extension)
Packit bc1512
    return FALSE;
Packit bc1512
  extension++;
Packit bc1512
  if (extension[0]=='\0')
Packit bc1512
    return FALSE;
Packit bc1512
  if (!strcmp (extension, "xml")||
Packit bc1512
      !strcmp (extension, "XML")||
Packit bc1512
      !strcmp (extension, "svg")
Packit bc1512
      )
Packit bc1512
    return TRUE;
Packit bc1512
  return FALSE;
Packit bc1512
}
Packit bc1512
Packit bc1512
gint
Packit bc1512
main (gint    argc,
Packit bc1512
      gchar **argv)
Packit bc1512
{
Packit bc1512
  GeglOptions *o         = NULL;
Packit bc1512
  GeglNode    *gegl      = NULL;
Packit bc1512
  gchar       *script    = NULL;
Packit bc1512
  GError      *err       = NULL;
Packit bc1512
  gchar       *path_root = NULL;
Packit bc1512
Packit bc1512
  o = gegl_options_parse (argc, argv);
Packit bc1512
Packit bc1512
  if (o->fatal_warnings)
Packit bc1512
    {
Packit bc1512
      gegl_enable_fatal_warnings ();
Packit bc1512
    }
Packit bc1512
Packit bc1512
  g_thread_init (NULL);
Packit bc1512
  gegl_init (&argc, &argv);
Packit bc1512
#ifdef HAVE_SPIRO
Packit bc1512
  gegl_path_spiro_init ();
Packit bc1512
#endif
Packit bc1512
  gegl_path_smooth_init ();
Packit bc1512
Packit bc1512
  if (o->xml)
Packit bc1512
    {
Packit bc1512
      path_root = g_get_current_dir ();
Packit bc1512
    }
Packit bc1512
  else if (o->file)
Packit bc1512
    {
Packit bc1512
      if (!strcmp (o->file, "-"))  /* read XML from stdin */
Packit bc1512
        {
Packit bc1512
          path_root = g_get_current_dir ();
Packit bc1512
        }
Packit bc1512
      else
Packit bc1512
        {
Packit bc1512
          gchar *tmp;
Packit bc1512
          gchar *temp1 = g_strdup (o->file);
Packit bc1512
          gchar *temp2 = g_path_get_dirname (temp1);
Packit bc1512
          path_root = g_strdup (tmp = realpath (temp2, NULL));
Packit bc1512
          g_free (tmp);
Packit bc1512
          g_free (temp1);
Packit bc1512
          g_free (temp2);
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
Packit bc1512
  if (o->xml)
Packit bc1512
    {
Packit bc1512
      script = g_strdup (o->xml);
Packit bc1512
    }
Packit bc1512
  else if (o->file)
Packit bc1512
    {
Packit bc1512
      if (!strcmp (o->file, "-"))  /* read XML from stdin */
Packit bc1512
        {
Packit bc1512
          gchar buf[STDIN_BUF_SIZE];
Packit bc1512
          GString *acc = g_string_new ("");
Packit bc1512
Packit bc1512
          while (fgets (buf, STDIN_BUF_SIZE, stdin))
Packit bc1512
            {
Packit bc1512
              g_string_append (acc, buf);
Packit bc1512
            }
Packit bc1512
          script = g_string_free (acc, FALSE);
Packit bc1512
        }
Packit bc1512
      else if (file_is_gegl_xml (o->file))
Packit bc1512
        {
Packit bc1512
          g_file_get_contents (o->file, &script, NULL, &err;;
Packit bc1512
          if (err != NULL)
Packit bc1512
            {
Packit bc1512
              g_warning ("Unable to read file: %s", err->message);
Packit bc1512
            }
Packit bc1512
        }
Packit bc1512
      else
Packit bc1512
        {
Packit bc1512
          gchar *leaked_string = g_malloc (strlen (o->file) + 5);
Packit bc1512
          GString *acc = g_string_new ("");
Packit bc1512
Packit bc1512
          {
Packit bc1512
            gchar *file_basename;
Packit bc1512
            gchar *tmp;
Packit bc1512
            tmp = g_strdup (o->file);
Packit bc1512
            file_basename = g_path_get_basename (tmp);
Packit bc1512
Packit bc1512
            g_string_append (acc, "<gegl>
Packit bc1512
            g_string_append (acc, file_basename);
Packit bc1512
            g_string_append (acc, "'/></gegl>");
Packit bc1512
Packit bc1512
            g_free (tmp);
Packit bc1512
          }
Packit bc1512
Packit bc1512
          script = g_string_free (acc, FALSE);
Packit bc1512
Packit bc1512
          leaked_string[0]='\0';
Packit bc1512
          strcat (leaked_string, o->file);
Packit bc1512
          strcat (leaked_string, ".xml");
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
  else
Packit bc1512
    {
Packit bc1512
      if (o->rest)
Packit bc1512
        {
Packit bc1512
          script = g_strdup ("<gegl></gegl>");
Packit bc1512
        }
Packit bc1512
      else
Packit bc1512
        {
Packit bc1512
          script = g_strdup (DEFAULT_COMPOSITION);
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
Packit bc1512
  gegl = gegl_node_new_from_xml (script, path_root);
Packit bc1512
Packit bc1512
  if (!gegl)
Packit bc1512
    {
Packit bc1512
      g_print ("Invalid graph, abort.\n");
Packit bc1512
      return 1;
Packit bc1512
    }
Packit bc1512
Packit bc1512
  if (o->rest)
Packit bc1512
    {
Packit bc1512
      GeglNode *proxy;
Packit bc1512
      GeglNode *iter;
Packit bc1512
Packit bc1512
      gchar **operation = o->rest;
Packit bc1512
      proxy = gegl_node_get_output_proxy (gegl, "output");
Packit bc1512
      iter = gegl_node_get_producer (proxy, "input", NULL);
Packit bc1512
Packit bc1512
      while (*operation)
Packit bc1512
        {
Packit bc1512
          GeglNode *new;
Packit bc1512
Packit bc1512
          new = gegl_node_new_child (gegl, "operation", *operation, NULL);
Packit bc1512
          if (iter)
Packit bc1512
            {
Packit bc1512
              gegl_node_link_many (iter, new, proxy, NULL);
Packit bc1512
            }
Packit bc1512
          else
Packit bc1512
            {
Packit bc1512
              gegl_node_link_many (new, proxy, NULL);
Packit bc1512
            }
Packit bc1512
          iter = new;
Packit bc1512
          operation++;
Packit bc1512
        }
Packit bc1512
    }
Packit bc1512
Packit bc1512
  switch (o->mode)
Packit bc1512
    {
Packit bc1512
      case GEGL_RUN_MODE_DISPLAY:
Packit bc1512
        {
Packit bc1512
          GeglNode *output = gegl_node_new_child (gegl,
Packit bc1512
                                                  "operation", "gegl:display",
Packit bc1512
                                                  o->file ? "window-title" : NULL, o->file,
Packit bc1512
                                                  NULL);
Packit bc1512
          gegl_node_connect_from (output, "input", gegl_node_get_output_proxy (gegl, "output"), "output");
Packit bc1512
          gegl_node_process (output);
Packit bc1512
          g_main_loop_run (g_main_loop_new (NULL, TRUE));
Packit bc1512
          g_object_unref (output);
Packit bc1512
        }
Packit bc1512
        break;
Packit bc1512
      case GEGL_RUN_MODE_XML:
Packit bc1512
        g_printf ("%s\n", gegl_node_to_xml (gegl, path_root));
Packit bc1512
        return 0;
Packit bc1512
        break;
Packit bc1512
Packit bc1512
      case GEGL_RUN_MODE_OUTPUT:
Packit bc1512
        {
Packit bc1512
          GeglNode *output = gegl_node_new_child (gegl,
Packit bc1512
                                                  "operation", "gegl:save",
Packit bc1512
                                                  "path", o->output,
Packit bc1512
                                                  NULL);
Packit bc1512
          gegl_node_connect_from (output, "input", gegl_node_get_output_proxy (gegl, "output"), "output");
Packit bc1512
          gegl_node_process (output);
Packit bc1512
          g_object_unref (output);
Packit bc1512
        }
Packit bc1512
        break;  
Packit bc1512
Packit bc1512
      case GEGL_RUN_MODE_HELP:
Packit bc1512
        break;
Packit bc1512
Packit bc1512
      default:
Packit bc1512
        g_warning ("Unknown GeglOption mode: %d", o->mode);
Packit bc1512
        break;
Packit bc1512
    }
Packit bc1512
Packit bc1512
  g_list_free_full (o->files, g_free);
Packit bc1512
  g_free (o);
Packit bc1512
  g_object_unref (gegl);
Packit bc1512
  g_free (script);
Packit bc1512
  g_clear_error (&err;;
Packit bc1512
  g_free (path_root);
Packit bc1512
  gegl_exit ();
Packit bc1512
  return 0;
Packit bc1512
}