/* we replicate the process function from GeglOperationComposer3 to be * able to bail out earlier for some common processing time pitfalls */ static gboolean gegl_operation_composer3_process2 (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglOperationComposer3Class *klass = GEGL_OPERATION_COMPOSER3_GET_CLASS (operation); GeglBuffer *input; GeglBuffer *aux; GeglBuffer *aux2; GeglBuffer *output; gboolean success = FALSE; if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a composer", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); aux = gegl_operation_context_get_source (context, "aux"); aux2 = gegl_operation_context_get_source (context, "aux2"); /* we could be even faster by not alway writing to this buffer, that * would potentially break other assumptions we want to make from the * GEGL core so we avoid doing that */ output = gegl_operation_context_get_target (context, "output"); if (input != NULL || aux != NULL || aux2 != NULL) { if (result->width == 0 || result->height == 0) success = TRUE; else success = klass->process (operation, input, aux, aux2, output, result, level); if (input) g_object_unref (input); if (aux) g_object_unref (aux); if (aux2) g_object_unref (aux2); } else { g_warning ("%s received NULL input, aux, and aux2", gegl_node_get_operation (operation->node)); } return success; }
/* we replicate the process function from GeglOperationComposer to be * able to bail out earlier for some common processing time pitfalls */ static gboolean gegl_operation_composer_process2 (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result) { GeglOperationComposerClass *klass = GEGL_OPERATION_COMPOSER_GET_CLASS (operation); GeglBuffer *input; GeglBuffer *aux; GeglBuffer *output; gboolean success = FALSE; if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a composer", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); aux = gegl_operation_context_get_source (context, "aux"); if (gegl_can_do_inplace_processing (operation, input, result)) { output = g_object_ref (input); gegl_operation_context_take_object (context, "output", G_OBJECT (output)); } else output = gegl_operation_context_get_target (context, "output"); { gboolean done = FALSE; if (result->width == 0 || result->height == 0) done = TRUE; success = done; if (!done) { success = klass->process (operation, input, aux, output, result); if (output == GEGL_BUFFER (operation->node->cache)) gegl_cache_computed (operation->node->cache, result); } if (input) g_object_unref (input); if (aux) g_object_unref (aux); } return success; }
static gboolean gegl_operation_point_filter_op_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_pad, const GeglRectangle *roi) { GeglBuffer *input; GeglBuffer *output; gboolean success = FALSE; input = gegl_operation_context_get_source (context, "input"); if (gegl_can_do_inplace_processing (operation, input, roi)) { output = g_object_ref (input); gegl_operation_context_take_object (context, "output", G_OBJECT (output)); } else { output = gegl_operation_context_get_target (context, "output"); } success = gegl_operation_point_filter_process (operation, input, output, roi); if (output == GEGL_BUFFER (operation->node->cache)) gegl_cache_computed (operation->node->cache, roi); if (input != NULL) g_object_unref (input); return success; }
static gboolean process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglBuffer *input; if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a clone", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); if (!input) { g_warning ("clone received NULL input"); return FALSE; } gegl_operation_context_take_object (context, "output", G_OBJECT (input)); return TRUE; }
static gboolean gegl_operation_filter_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglOperationFilterClass *klass; GeglBuffer *input; GeglBuffer *output; gboolean success = FALSE; klass = GEGL_OPERATION_FILTER_GET_CLASS (operation); g_assert (klass->process); if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a filter", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); output = gegl_operation_context_get_target (context, "output"); success = klass->process (operation, input, output, result, level); if (output == GEGL_BUFFER (operation->node->cache)) gegl_cache_computed (operation->node->cache, result); if (input != NULL) g_object_unref (input); return success; }
static gboolean gegl_operation_composer_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglOperationComposerClass *klass = GEGL_OPERATION_COMPOSER_GET_CLASS (operation); GeglBuffer *input; GeglBuffer *aux; GeglBuffer *output; gboolean success = FALSE; if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a composer", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); aux = gegl_operation_context_get_source (context, "aux"); output = gegl_operation_context_get_target (context, "output"); /* A composer with a NULL aux, can still be valid, the * subclass has to handle it. */ if (input != NULL || aux != NULL) { success = klass->process (operation, input, aux, output, result, level); if (output == GEGL_BUFFER (operation->node->cache)) gegl_cache_computed (operation->node->cache, result); if (input) g_object_unref (input); if (aux) g_object_unref (aux); } else { g_warning ("%s received NULL input and aux", gegl_node_get_debug_name (operation->node)); } return success; }
static gboolean gimp_operation_histogram_sink_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglBuffer *input; GeglBuffer *aux; if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a sink", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); aux = gegl_operation_context_get_source (context, "aux"); if (! input) { g_warning ("received NULL input"); return FALSE; } if (aux) { /* do hist with mask */ g_printerr ("aux format: %s\n", babl_get_name (gegl_buffer_get_format (aux))); g_object_unref (aux); } else { /* without */ } g_printerr ("input format: %s\n", babl_get_name (gegl_buffer_get_format (input))); g_object_unref (input); return TRUE; }
static gboolean process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *roi, gint level) { GeglProperties *o = GEGL_PROPERTIES (operation); GeglBuffer *input; GeglBuffer *output; if (! o->input_format || ! o->output_format) { g_warning ("cast-format: input-format or output-format are not set"); return FALSE; } if (babl_format_get_bytes_per_pixel (o->input_format) != babl_format_get_bytes_per_pixel (o->output_format)) { g_warning ("cast-format: input-format and output-format have different bpp"); return FALSE; } if (strcmp (output_prop, "output")) { g_warning ("cast-format: requested processing of %s pad", output_prop); return FALSE; } input = gegl_operation_context_get_source (context, "input"); if (! input) { g_warning ("cast: received NULL input"); return FALSE; } output = gegl_buffer_new (roi, o->input_format); gegl_buffer_copy (input, roi, GEGL_ABYSS_NONE, output, roi); gegl_buffer_set_format (output, o->output_format); g_object_unref (input); gegl_operation_context_take_object (context, "output", G_OBJECT (output)); return TRUE; }
static gboolean gegl_crop_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglProperties *o = GEGL_PROPERTIES (operation); GeglBuffer *input; gboolean success = FALSE; GeglRectangle extent; extent.x = o->x; extent.y = o->y; extent.width = o->width; extent.height = o->height; input = gegl_operation_context_get_source (context, "input"); if (input) { GeglBuffer *output = gegl_buffer_create_sub_buffer (input, &extent); if (gegl_object_get_has_forked (G_OBJECT (input))) gegl_object_set_has_forked (G_OBJECT (output)); gegl_operation_context_take_object (context, "output", G_OBJECT (output)); g_object_unref (input); success = TRUE; } else { g_warning ("%s got NULL input pad", gegl_node_get_operation (operation->node)); } return success; }
static gboolean gegl_operation_sink_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result) { GeglOperationSinkClass *klass; GeglBuffer *input; gboolean success = FALSE; klass = GEGL_OPERATION_SINK_GET_CLASS (operation); g_assert (klass->process); input = gegl_operation_context_get_source (context, "input"); if (input) { success = klass->process (operation, input, result); g_object_unref (input); } return success; }
static gboolean gegl_affine_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result) { GeglBuffer *input; GeglBuffer *output; GeglMatrix3 matrix; OpAffine *affine = (OpAffine *) operation; gegl_affine_create_composite_matrix (affine, &matrix); if (gegl_affine_is_intermediate_node (affine) || gegl_matrix3_is_identity (&matrix)) { /* passing straight through (like gegl:nop) */ input = gegl_operation_context_get_source (context, "input"); if (!input) { g_warning ("transform received NULL input"); return FALSE; } gegl_operation_context_take_object (context, "output", G_OBJECT (input)); } else if (gegl_affine_matrix3_allow_fast_translate (&matrix) || (gegl_matrix3_is_translate (&matrix) && ! strcmp (affine->filter, "nearest"))) { /* doing a buffer shifting trick, (enhanced nop) */ input = gegl_operation_context_get_source (context, "input"); output = g_object_new (GEGL_TYPE_BUFFER, "source", input, "shift-x", (int)-matrix.coeff[0][2], "shift-y", (int)-matrix.coeff[1][2], "abyss-width", -1, /* turn of abyss (relying on abyss of source) */ NULL); if (gegl_object_get_has_forked (input)) gegl_object_set_has_forked (output); gegl_operation_context_take_object (context, "output", G_OBJECT (output)); if (input != NULL) g_object_unref (input); } else if (gegl_affine_matrix3_allow_fast_reflect_x (&matrix)) { GeglRectangle src_rect; GeglSampler *sampler; GeglRectangle context_rect; input = gegl_operation_context_get_source (context, "input"); if (!input) { g_warning ("transform received NULL input"); return FALSE; } output = gegl_operation_context_get_target (context, "output"); src_rect = gegl_operation_get_required_for_output (operation, "output", result); src_rect.y += 1; sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"), gegl_sampler_type_from_string (affine->filter)); context_rect = *gegl_sampler_get_context_rect (sampler); src_rect.width -= context_rect.width; src_rect.height -= context_rect.height; gegl_affine_fast_reflect_x (output, input, result, &src_rect); g_object_unref (sampler); if (input != NULL) g_object_unref (input); } else if (gegl_affine_matrix3_allow_fast_reflect_y (&matrix)) { GeglRectangle src_rect; GeglSampler *sampler; GeglRectangle context_rect; input = gegl_operation_context_get_source (context, "input"); if (!input) { g_warning ("transform received NULL input"); return FALSE; } output = gegl_operation_context_get_target (context, "output"); src_rect = gegl_operation_get_required_for_output (operation, "output", result); src_rect.x += 1; sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"), gegl_sampler_type_from_string (affine->filter)); context_rect = *gegl_sampler_get_context_rect (sampler); src_rect.width -= context_rect.width; src_rect.height -= context_rect.height; gegl_affine_fast_reflect_y (output, input, result, &src_rect); g_object_unref (sampler); if (input != NULL) g_object_unref (input); } else { /* for all other cases, do a proper resampling */ GeglSampler *sampler; input = gegl_operation_context_get_source (context, "input"); output = gegl_operation_context_get_target (context, "output"); sampler = gegl_buffer_sampler_new (input, babl_format("RaGaBaA float"), gegl_sampler_type_from_string (affine->filter)); affine_generic (output, input, &matrix, sampler); g_object_unref (sampler); if (input != NULL) g_object_unref (input); } return TRUE; }
static gboolean gegl_operation_composer3_process (GeglOperation *operation, GeglOperationContext *context, const gchar *output_prop, const GeglRectangle *result, gint level) { GeglOperationComposer3Class *klass = GEGL_OPERATION_COMPOSER3_GET_CLASS (operation); GeglBuffer *input; GeglBuffer *aux; GeglBuffer *aux2; GeglBuffer *output; gboolean success = FALSE; if (strcmp (output_prop, "output")) { g_warning ("requested processing of %s pad on a composer", output_prop); return FALSE; } if (result->width == 0 || result->height == 0) { output = gegl_operation_context_get_target (context, "output"); return TRUE; } input = gegl_operation_context_get_source (context, "input"); output = gegl_operation_context_get_output_maybe_in_place (operation, context, input, result); aux = gegl_operation_context_get_source (context, "aux"); aux2 = gegl_operation_context_get_source (context, "aux2"); /* A composer with a NULL aux, can still be valid, the * subclass has to handle it. */ if (input != NULL || aux != NULL || aux2 != NULL) { if (gegl_operation_use_threading (operation, result)) { gint threads = gegl_config_threads (); GThreadPool *pool = thread_pool (); ThreadData thread_data[GEGL_MAX_THREADS]; gint pending = threads; if (result->width > result->height) { gint bit = result->width / threads; for (gint j = 0; j < threads; j++) { thread_data[j].roi.y = result->y; thread_data[j].roi.height = result->height; thread_data[j].roi.x = result->x + bit * j; thread_data[j].roi.width = bit; } thread_data[threads-1].roi.width = result->width - (bit * (threads-1)); } else { gint bit = result->height / threads; for (gint j = 0; j < threads; j++) { thread_data[j].roi.x = result->x; thread_data[j].roi.width = result->width; thread_data[j].roi.y = result->y + bit * j; thread_data[j].roi.height = bit; } thread_data[threads-1].roi.height = result->height - (bit * (threads-1)); } for (gint i = 0; i < threads; i++) { thread_data[i].klass = klass; thread_data[i].operation = operation; thread_data[i].input = input; thread_data[i].aux = aux; thread_data[i].aux2 = aux2; thread_data[i].output = output; thread_data[i].pending = &pending; thread_data[i].level = level; thread_data[i].success = TRUE; } for (gint i = 1; i < threads; i++) g_thread_pool_push (pool, &thread_data[i], NULL); thread_process (&thread_data[0], NULL); while (g_atomic_int_get (&pending)) {}; success = thread_data[0].success; } else { success = klass->process (operation, input, aux, aux2, output, result, level); } g_clear_object (&input); g_clear_object (&aux); g_clear_object (&aux2); } else { g_warning ("%s received NULL input, aux, and aux2", gegl_node_get_operation (operation->node)); } return success; }