Пример #1
0
static void
_gegl_graph_do_build (GeglGraphTraversal *path, GeglNode *node)
{
  GeglPad *pad = NULL;
  GeglListVisitor *list_visitor = g_object_new (GEGL_TYPE_LIST_VISITOR, NULL);

  /* We need to check the real node of the output/input pad in case this is a proxy node */
  pad = gegl_node_get_pad (node, "output");
  if (pad)
    {
      node = gegl_pad_get_node (pad);
    }
  else
    {
      pad = gegl_node_get_pad (node, "input");
      if (pad)
        node = gegl_pad_get_node (pad);
    }

  path->dfs_path = gegl_list_visitor_get_dfs_path (list_visitor, GEGL_VISITABLE (node));
  path->bfs_path = gegl_list_visitor_get_bfs_path (list_visitor, GEGL_VISITABLE (node));
  path->contexts = g_hash_table_new_full (NULL,
                                          NULL,
                                          NULL,
                                          (GDestroyNotify)gegl_operation_context_destroy);
  path->rects_dirty = FALSE;
  g_object_unref (list_visitor);
}
static gboolean
gegl_operation_point_render_process (GeglOperation       *operation,
                                     GeglBuffer          *output,
                                     const GeglRectangle *result,
                                     gint                 level)
{
  GeglPad    *pad;
  const Babl *out_format;
  GeglOperationPointRenderClass *point_render_class;

  point_render_class = GEGL_OPERATION_POINT_RENDER_GET_CLASS (operation);

  pad        = gegl_node_get_pad (operation->node, "output");
  out_format = gegl_pad_get_format (pad);
  if (!out_format)
    {
      g_warning ("%s", gegl_node_get_debug_name (operation->node));
    }
  g_assert (out_format);

  if ((result->width > 0) && (result->height > 0))
    {
      GeglBufferIterator *i = gegl_buffer_iterator_new (output, result, level, out_format, GEGL_BUFFER_WRITE, GEGL_ABYSS_NONE);

      while (gegl_buffer_iterator_next (i))
          point_render_class->process (operation, i->data[0], i->length, &i->roi[0], level);
    }
  return TRUE;
}
Пример #3
0
static gboolean
gegl_affine_is_intermediate_node (OpAffine *affine)
{
  GSList        *connections;
  GeglOperation *op = GEGL_OPERATION (affine);

  connections = gegl_pad_get_connections (gegl_node_get_pad (op->node,
                                                             "output"));
  if (! connections)
    return FALSE;

  do
    {
      GeglOperation *sink;

      sink = gegl_connection_get_sink_node (connections->data)->operation;

      if (! IS_OP_AFFINE (sink) ||
          strcmp (affine->filter, OP_AFFINE (sink)->filter))
        return FALSE;
    }
  while ((connections = g_slist_next (connections)));

  return TRUE;
}
Пример #4
0
void
layer_add_gegl_node(GeglEditorLayer* layer, GeglNode* node)
{
  //get input pads
  //gegl_pad_is_output
  GSList	*pads	    = gegl_node_get_input_pads(node);
  guint		 num_inputs = g_slist_length(pads);
  gchar**	 inputs	    = malloc(sizeof(gchar*)*num_inputs);
  int		 i;
  for(i = 0; pads != NULL; pads = pads->next, i++)
    {
      inputs[i] = (gchar*)gegl_pad_get_name(pads->data);
    }

  gint	id;
  if(gegl_node_get_pad(node, "output") == NULL)
    {
      id = gegl_editor_add_node(layer->editor, gegl_node_get_operation(node), num_inputs, inputs, 0, NULL);
    }
  else
    {
      gchar*	output = "output";
      gchar* outputs[] = {output};
      id	       = gegl_editor_add_node(layer->editor, gegl_node_get_operation(node), num_inputs, inputs, 1, outputs);
    }

  node_id_pair* new_pair = malloc(sizeof(node_id_pair));
  new_pair->node	 = node;
  new_pair->id		 = id;
  layer->pairs		 = g_slist_append(layer->pairs, new_pair);
}
Пример #5
0
static void print_info(GeglNode* gegl)
{
  GSList *list = gegl_node_get_children(gegl);
  for(;list != NULL; list = list->next)
    {
      GeglNode* node = GEGL_NODE(list->data);
      g_print("Node %s\n", gegl_node_get_operation(node));

      if(gegl_node_get_pad(node, "output") == NULL) {
	g_print("Output pad is NULL\n");
      }

      /*      GeglNode** nodes;
      const gchar** pads;
      gint num = gegl_node_get_consumers(node, "output", &nodes, &pads);
      g_print("%s: %d consumer(s)\n", gegl_node_get_operation(node), num);

      int i;
      for(i = 0; i < num; i++)
	{
	  g_print("Connection: (%s to %s)\n", gegl_node_get_operation(node), gegl_node_get_operation(nodes[0]), pads[0]);
	}
	g_print("\n");*/
    }
}
Пример #6
0
/**
 * gegl_dot_add_node_and_dependencies:
 * @string:
 * @node:
 *
 * Adds @node to the graph, and all nodes that @node depends on both
 * directly and indirectly. There is no grouping of subgraphs.
 **/
static void
gegl_dot_add_node_and_dependencies (GString  *string,
                                    GeglNode *node)
{
  GeglDotVisitor *dot_visitor;
  GeglPad        *pad;
  gpointer        context_id = string;

  dot_visitor = g_object_new (GEGL_TYPE_DOT_VISITOR,
                              "id", context_id,
                              NULL);

  gegl_dot_visitor_set_string_to_append (dot_visitor,
                                         string);

  /* Add the nodes */
  gegl_visitor_bfs_traverse (GEGL_VISITOR (dot_visitor),
                             GEGL_VISITABLE (node));

  /* Add the edges */
  pad = gegl_node_get_pad (node, "output");
  if (! pad)
    {
      pad = gegl_node_get_pad (node, "input");

      if (pad)
        {
          /* This is a sink node, we need to add these edges manually
           * since no pad depends on this input pad */
          GSList *iter;
          for (iter = pad->connections; iter; iter = g_slist_next (iter))
            {
              GeglConnection *connection = iter->data;
              gegl_dot_util_add_connection (string, connection);
            }
        }
    }


  gegl_visitor_bfs_traverse (GEGL_VISITOR (dot_visitor),
                             GEGL_VISITABLE (pad));

  g_object_unref (dot_visitor);
}
Пример #7
0
void
gegl_operation_set_format (GeglOperation *self,
                           const gchar   *pad_name,
                           const Babl    *format)
{
  GeglPad *pad;

  g_return_if_fail (GEGL_IS_OPERATION (self));
  g_return_if_fail (pad_name != NULL);

  pad = gegl_node_get_pad (self->node, pad_name);

  g_return_if_fail (pad != NULL);

  pad->format = format;
}
Пример #8
0
static gboolean
gegl_affine_is_composite_node (OpAffine *affine)
{
  GSList        *connections;
  GeglOperation *op = GEGL_OPERATION (affine);
  GeglOperation *source;

  connections = gegl_pad_get_connections (gegl_node_get_pad (op->node,
                                                             "input"));
  if (! connections)
    return FALSE;

  source = gegl_connection_get_source_node (connections->data)->operation;

  return (IS_OP_AFFINE (source) &&
          ! strcmp (affine->filter, OP_AFFINE (source)->filter));
}
Пример #9
0
static void
gegl_affine_get_source_matrix (OpAffine    *affine,
                               GeglMatrix3 *output)
{
  GSList        *connections;
  GeglOperation *op = GEGL_OPERATION (affine);
  GeglOperation *source;

  connections = gegl_pad_get_connections (gegl_node_get_pad (op->node,
                                                             "input"));
  g_assert (connections);

  source = gegl_connection_get_source_node (connections->data)->operation;
  g_assert (IS_OP_AFFINE (source));

  gegl_affine_create_composite_matrix (OP_AFFINE (source), output);
  /*gegl_matrix3_copy (output, OP_AFFINE (source)->matrix);*/
}
Пример #10
0
const Babl *
gegl_operation_get_format (GeglOperation *self,
                           const gchar   *pad_name)
{
  GeglPad *pad;

  g_return_val_if_fail (GEGL_IS_OPERATION (self), NULL);
  g_return_val_if_fail (pad_name != NULL, NULL);

  pad = gegl_node_get_pad (self->node, pad_name);

  if (pad == NULL || pad->format == NULL)
    {
      g_warning ("%s: returns NULL", G_STRFUNC);
    }
  g_return_val_if_fail (pad != NULL, NULL);

  return pad->format;
}
Пример #11
0
GeglNode *
gegl_operation_get_source_node (GeglOperation *operation,
                                const gchar   *input_pad_name)
{
  GeglPad *pad;

  g_assert (operation &&
            operation->node &&
            input_pad_name);
  pad = gegl_node_get_pad (operation->node, input_pad_name);

  if (!pad)
    return NULL;

  pad = gegl_pad_get_connected_to (pad);

  if (!pad)
    return NULL;

  g_assert (gegl_pad_get_node (pad));

  return gegl_pad_get_node (pad);
}
Пример #12
0
/**
 * gegl_graph_process:
 * @path: The traversal path
 *
 * Process the prepared request. This will return the
 * resulting buffer from the final node, or NULL if
 * that node is a sink.
 *
 * If gegl_graph_prepare_request has not been called
 * the behavior of this function is undefined.
 *
 * Return value: (transfer full): The result of the graph, or NULL if
 * there is no output pad.
 */
GeglBuffer *
gegl_graph_process (GeglGraphTraversal *path,
                    gint                level)
{
  GList *list_iter = NULL;
  GeglBuffer *result = NULL;
  GeglOperationContext *context = NULL;
  GeglOperationContext *last_context = NULL;
  GeglBuffer *operation_result = NULL;

  for (list_iter = path->dfs_path; list_iter; list_iter = list_iter->next)
    {
      GeglNode *node = GEGL_NODE (list_iter->data);
      GeglOperation *operation = node->operation;
      g_return_val_if_fail (node, NULL);
      g_return_val_if_fail (operation, NULL);
      
      GEGL_INSTRUMENT_START();

      operation_result = NULL;

      if (last_context)
        gegl_operation_context_purge (last_context);
      
      context = g_hash_table_lookup (path->contexts, node);
      g_return_val_if_fail (context, NULL);

      GEGL_NOTE (GEGL_DEBUG_PROCESS,
                 "Will process %s result_rect = %d, %d %d×%d",
                 gegl_node_get_debug_name (node),
                 context->result_rect.x, context->result_rect.y, context->result_rect.width, context->result_rect.height);
      
      if (context->need_rect.width > 0 && context->need_rect.height > 0)
        {
          if (context->cached)
            {
              GEGL_NOTE (GEGL_DEBUG_PROCESS,
                         "Using cached result for %s",
                         gegl_node_get_debug_name (node));
              operation_result = GEGL_BUFFER (node->cache);
            }
          else
            {
              /* provide something on input pad, always - this makes having
                 behavior depending on it not being set.. not work, is
                 sacrifising that worth it?
               */
              if (gegl_node_has_pad (node, "input") &&
                  !gegl_operation_context_get_object (context, "input"))
                {
                  gegl_operation_context_set_object (context, "input", G_OBJECT (gegl_graph_get_shared_empty(path)));
                }

              context->level = level;

              /* note: this hard-coding of "output" makes some more custom
               * graph topologies harder than neccesary.
               */
              gegl_operation_process (operation, context, "output", &context->need_rect, context->level);
              operation_result = GEGL_BUFFER (gegl_operation_context_get_object (context, "output"));

              if (operation_result && operation_result == (GeglBuffer *)operation->node->cache)
                gegl_cache_computed (operation->node->cache, &context->need_rect, level);
            }
        }
      else
        {
          operation_result = NULL;
        }

      if (operation_result)
        {
          GeglPad *output_pad = gegl_node_get_pad (node, "output");
          GList   *targets = gegl_graph_get_connected_output_contexts (path, output_pad);
          GList   *targets_iter;

          GEGL_NOTE (GEGL_DEBUG_PROCESS,
                     "Will deliver the results of %s:%s to %d targets",
                     gegl_node_get_debug_name (node),
                     "output",
                     g_list_length (targets));

          if (g_list_length (targets) > 1)
            gegl_object_set_has_forked (G_OBJECT (operation_result));

          for (targets_iter = targets; targets_iter; targets_iter = g_list_next (targets_iter))
            {
              ContextConnection *target_con = targets_iter->data;
              gegl_operation_context_set_object (target_con->context, target_con->name, G_OBJECT (operation_result));
            }
          g_list_free_full (targets, free_context_connection);
        }
      last_context = context;

      GEGL_INSTRUMENT_END ("process", gegl_node_get_operation (node));
    }
  if (last_context)
    {
      if (operation_result)
        result = g_object_ref (operation_result);
      else if (gegl_node_has_pad (last_context->operation->node, "output"))
        result = g_object_ref (gegl_graph_get_shared_empty (path));
      gegl_operation_context_purge (last_context);
    }

  return result;
}