/* 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 * version 3 of the License, or (at your option) any later version. * * 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 * License along with GEGL; if not, see . * * Copyright 2007 Øyvind Kolås */ #include "config.h" #include #ifdef GEGL_CHANT_PROPERTIES /* No properties */ #else #define GEGL_CHANT_TYPE_COMPOSER #define GEGL_CHANT_C_FILE "hstack.c" #include "gegl-chant.h" #include static void prepare (GeglOperation *operation) { gegl_operation_set_format (operation, "output", babl_format ("RGBA float")); } static GeglRectangle get_bounding_box (GeglOperation *operation) { GeglRectangle result = {0,0,0,0}; GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (operation, "input"); GeglRectangle *aux_rect = gegl_operation_source_get_bounding_box (operation, "aux"); if (!in_rect || !aux_rect) return result; result = *in_rect; if (result.width != 0 && result.height != 0) { result.width += aux_rect->width; if (aux_rect->height > result.height) result.height = aux_rect->height; } return result; } static GeglRectangle get_required_for_output (GeglOperation *self, const gchar *input_pad, const GeglRectangle *roi) { GeglRectangle request = *roi; if (!strcmp (input_pad, "aux")) { GeglRectangle *in_rect = gegl_operation_source_get_bounding_box (self, "input"); GeglRectangle *aux_rect = gegl_operation_source_get_bounding_box (self, "aux"); if (request.width != 0 && request.height != 0) { request.x -= in_rect->width + aux_rect->x; } } return request; } static GeglRectangle get_invalidated_by_change (GeglOperation *self, const gchar *input_pad, const GeglRectangle *region) { if (!strcmp ("input_pad", "input")) { return *region; } else { /*region.x -= radius * 2;*/ } return *region; } static gboolean process (GeglOperation *operation, GeglBuffer *input, GeglBuffer *aux, GeglBuffer *output, const GeglRectangle *result, gint level) { GeglBuffer *temp_in; GeglBuffer *temp_aux; /* FIXME: just pass the originals buffers if the result rectangle does not * include both input buffers */ temp_in = gegl_buffer_create_sub_buffer (input, result); temp_aux = gegl_buffer_create_sub_buffer (aux, result); { gfloat *buf = g_new0 (gfloat, result->width * result->height * 4); gfloat *bufB = g_new0 (gfloat, result->width * result->height * 4); gegl_buffer_get (temp_in, NULL, 1.0, babl_format ("RGBA float"), buf, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); gegl_buffer_get (temp_aux, NULL, 1.0, babl_format ("RGBA float"), bufB, GEGL_AUTO_ROWSTRIDE, GEGL_ABYSS_NONE); { gint offset=0; gint x,y; for (y=0;yx >= gegl_buffer_get_width (input)) { buf[offset+0]=bufB[offset+0]; buf[offset+1]=bufB[offset+1]; buf[offset+2]=bufB[offset+2]; buf[offset+3]=bufB[offset+3]; } offset+=4; } } gegl_buffer_set (output, NULL, 0, babl_format ("RGBA float"), buf, GEGL_AUTO_ROWSTRIDE); g_free (buf); g_free (bufB); } g_object_unref (temp_in); g_object_unref (temp_aux); return TRUE; } static void gegl_chant_class_init (GeglChantClass *klass) { GeglOperationClass *operation_class; GeglOperationComposerClass *composer_class; operation_class = GEGL_OPERATION_CLASS (klass); composer_class = GEGL_OPERATION_COMPOSER_CLASS (klass); composer_class->process = process; operation_class->prepare = prepare; operation_class->get_bounding_box = get_bounding_box; operation_class->get_invalidated_by_change = get_invalidated_by_change; operation_class->get_required_for_output = get_required_for_output; gegl_operation_class_set_keys (operation_class, "name" , "gegl:hstack", "categories" , "misc", "description" , _("Horizontally stack inputs, (in \"output\" \"aux\" is placed to the right of \"input\")"), NULL); } #endif