magick-load.c 4.19 KB
Newer Older
1 2 3 4 5
/* This file is an image processing operation for GEGL
 *
 * GEGL is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
6
 * version 3 of the License, or (at your option) any later version.
7 8 9 10 11 12 13
 *
 * GEGL 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
 * Lesser General Public License for more details.
 *
 * 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/>.
15 16 17
 *
 * Copyright 2006 Øyvind Kolås <pippin@gimp.org>
 */
18 19

#include "config.h"
20
#include <stdlib.h>
21 22 23
#include <glib/gi18n-lib.h>


24
#ifdef GEGL_PROPERTIES
25

26 27
property_file_path (path, _("File"), "/tmp/gegl-logo.svg")
    description (_("Path of file to load."))
28

29 30
#else

31
#define GEGL_OP_SOURCE
32
#define GEGL_OP_NAME     magick_load
33
#define GEGL_OP_C_SOURCE magick-load.c
34

35
#include "gegl-op.h"
36 37 38
#include <stdio.h>

static void
39
load_cache (GeglProperties *op_magick_load)
40
{
41
  if (!op_magick_load->user_data)
42
    {
43 44
      gchar    *filename;
      gchar    *cmd;
45
      GeglNode *graph, *sink, *loader;
46
      GeglBuffer *newbuf = NULL;
47 48

      /* ImageMagick backed fallback FIXME: make this robust.
49 50
       * maybe use pipes in a manner similar to the raw loader,
       * or at least use a properly unique filename  */
51 52 53 54

      filename = g_build_filename (g_get_tmp_dir (), "gegl-magick.png", NULL);
      cmd = g_strdup_printf ("convert \"%s\"'[0]' \"%s\"",
                             op_magick_load->path, filename);
55 56
      if (system (cmd) == -1)
        g_warning ("Error executing ImageMagick convert program");
57

58 59 60 61 62 63 64 65 66

      graph = gegl_node_new ();
      sink = gegl_node_new_child (graph,
                                 "operation", "gegl:buffer-sink",
                                 "buffer", &newbuf, NULL);
      loader = gegl_node_new_child (graph,
                                    "operation", "gegl:png-load",
                                    "path", filename, NULL);
      gegl_node_link_many (loader, sink, NULL);
67
      gegl_node_process (sink);
68
      op_magick_load->user_data = (gpointer) newbuf;
69 70
      g_object_unref (graph);
      g_free (cmd);
71
      g_free (filename);
72
    }
73 74
}

75 76 77 78
static GeglRectangle
get_bounding_box (GeglOperation *operation)
{
  GeglRectangle result = {0,0,0,0};
79
  GeglProperties   *o = GEGL_PROPERTIES (operation);
80 81 82 83
  gint width, height;

  load_cache (o);

84
  g_object_get (o->user_data, "width", &width,
85 86 87 88 89 90
                               "height", &height, NULL);
  result.width  = width;
  result.height = height;
  return result;
}

91
static GeglRectangle
92 93 94 95 96 97
get_cached_region (GeglOperation *operation,
                   const GeglRectangle *roi)
{
  return get_bounding_box (operation);
}

98
static gboolean
99 100 101 102 103
process (GeglOperation         *operation,
         GeglOperationContext  *context,
         const gchar           *output_pad,
         const GeglRectangle   *result,
         gint                   level)
104
{
105
  GeglProperties *o = GEGL_PROPERTIES (operation);
106

107
  if (!o->user_data)
Øyvind Kolås's avatar
Øyvind Kolås committed
108
    return FALSE;
109
  /* overriding the predefined behavior */
110 111
  g_object_ref (o->user_data);
  gegl_operation_context_take_object (context, "output", G_OBJECT (o->user_data));
112 113 114
  return  TRUE;
}

115 116 117
static void finalize (GObject *object)
{
  GeglOperation *op = (void*) object;
118
  GeglProperties *o = GEGL_PROPERTIES (op);
Debarshi Ray's avatar
Debarshi Ray committed
119 120 121

  g_clear_object (&o->user_data);

122
  G_OBJECT_CLASS (gegl_op_parent_class)->finalize (object);
123
}
124

125
static void
126
gegl_op_class_init (GeglOpClass *klass)
127
{
128
  GeglOperationClass       *operation_class;
129
  GObjectClass             *object_class;
130

131
  operation_class = GEGL_OPERATION_CLASS (klass);
132 133 134
  object_class    = G_OBJECT_CLASS (klass);

  object_class->finalize = finalize;
135

136
  operation_class->process = process;
137
  operation_class->get_bounding_box = get_bounding_box;
138
  operation_class->get_cached_region = get_cached_region;;
139

140 141 142 143 144 145
  gegl_operation_class_set_keys (operation_class,
        "name"       , "gegl:magick-load",
        "categories" , "hidden",
        "description",
        _("Image Magick wrapper using the png op."),
        NULL);
146 147 148
}

#endif