test-buffer-changes.c 5.56 KB
Newer Older
Daniel Sabo's avatar
Daniel Sabo committed
1 2 3 4 5 6 7 8 9 10 11 12 13
/* This file is a test-case 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
14
 * License along with GEGL; if not, see <https://www.gnu.org/licenses/>.
Daniel Sabo's avatar
Daniel Sabo committed
15
 */
16
#define GEGL_ITERATOR2_API
17 18 19 20 21 22 23 24 25 26 27
#include <gegl.h>

typedef struct {
    GeglBuffer *buffer;
    GeglRectangle buffer_extent;
    const Babl *buffer_format;
    
    guint buffer_changed_called;
    GeglRectangle buffer_changed_rect;
} TestCase;

28
GeglRectangle null_rect = {0, 0, 0, 0};
29

30 31 32 33 34 35 36 37 38
gboolean    test_gegl_rectangle_equal(const GeglRectangle *expected, const GeglRectangle *actual);
TestCase *  test_case_new(void);
void        handle_buffer_changed(GeglBuffer *buffer, const GeglRectangle *rect, gpointer user_data);
void        test_buffer_change_signal_on_set(void);
void        test_buffer_change_signal_with_iter(guint access_method, guint expected_signal_calls);
void        test_buffer_change_signal_with_iter_write(void);
void        test_buffer_change_signal_with_iter_readwrite(void);
void        test_buffer_no_change_signal_with_iter_read(void);

39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55
gboolean
test_gegl_rectangle_equal(const GeglRectangle *expected, const GeglRectangle *actual)
{
    gboolean equal = gegl_rectangle_equal(expected, actual);
    if (!equal) {
        g_warning("GeglRectangle(%d, %d %dx%d) != GeglRectangle(%d, %d %dx%d)",
                  expected->x, expected->y, expected->width, expected->height,
                  actual->x, actual->y, actual->width, actual->height);
    }
    return equal;
}

TestCase *
test_case_new(void)
{
    TestCase *test_case = g_new(TestCase, 1);

56 57 58 59
    test_case->buffer_extent.x = 0;
    test_case->buffer_extent.y = 0;
    test_case->buffer_extent.width = 500;
    test_case->buffer_extent.height = 500;
60 61 62 63 64 65 66 67
    test_case->buffer_format = babl_format("RGBA u8");
    test_case->buffer = gegl_buffer_new(&test_case->buffer_extent, test_case->buffer_format);
    
    test_case->buffer_changed_called = 0;
    test_case->buffer_changed_rect = null_rect;
    return test_case;
}

68

69 70 71 72 73 74 75 76 77 78 79 80 81
void
handle_buffer_changed(GeglBuffer *buffer, const GeglRectangle *rect, gpointer user_data)
{
    TestCase *t = (TestCase *)user_data;
    t->buffer_changed_called++;
    t->buffer_changed_rect = *rect;
}

/* Test that 'changed' signal is emitted on gegl_buffer_set */
void
test_buffer_change_signal_on_set(void)
{
    TestCase *test_case = test_case_new();
82
    GeglRectangle rect = {0, 0, 100, 100};
83 84
    char *tmp = g_malloc(rect.height*rect.width*1*4);
    
85
    gegl_buffer_signal_connect(test_case->buffer, "changed", (GCallback)handle_buffer_changed, test_case);
86
    
87
    gegl_buffer_set(test_case->buffer, &rect, 0, test_case->buffer_format, tmp, GEGL_AUTO_ROWSTRIDE);
88 89 90 91 92 93 94 95 96 97
    
    g_assert_cmpint(test_case->buffer_changed_called, ==, 1);
    g_assert(test_gegl_rectangle_equal(&(test_case->buffer_changed_rect), &rect));
    
    g_free(tmp);
    g_free(test_case);
}

/* Utility function to test emission of 'changed' signal on GeglBuffer
 * when accessing with GeglBufferIterator. 
98
 * @access_method: GEGL_ACCESS_READ, GEGL_ACCESS_WRITE, GEGL_ACCESS_READWRITE
99 100 101 102 103 104
 * @expected_signal_calls: Whether the 'changed' signal is expected to be emitted or not
 */
void
test_buffer_change_signal_with_iter(guint access_method, guint expected_signal_calls)
{
    TestCase *test_case = test_case_new();
105
    GeglRectangle rect = {0, 0, 100, 100};
106 107
    char *tmp = g_malloc(rect.height*rect.width*1*4);
    GeglBufferIterator *gi = gegl_buffer_iterator_new(test_case->buffer, &rect, 0,
108
                                test_case->buffer_format, access_method, GEGL_ABYSS_NONE, 1);
109
    
110
    gegl_buffer_signal_connect(test_case->buffer, "changed", (GCallback)handle_buffer_changed, test_case);
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128

    while (gegl_buffer_iterator_next(gi)) {
    }

    if (expected_signal_calls == 0)
        rect = null_rect;

    g_assert(test_case->buffer_changed_called == expected_signal_calls);
    g_assert(test_gegl_rectangle_equal(&(test_case->buffer_changed_rect), &rect));
    
    g_free(tmp);
    g_free(test_case);
}

/* Test that 'changed' signal is emitted once for gegl_buffer_iterator in WRITE mode */
void
test_buffer_change_signal_with_iter_write(void)
{
129
    test_buffer_change_signal_with_iter(GEGL_ACCESS_WRITE, 1);
130 131 132 133 134 135
}

/* Test that 'changed' signal is emitted once for gegl_buffer_iterator in READWRITE mode */
void
test_buffer_change_signal_with_iter_readwrite(void)
{
136
    test_buffer_change_signal_with_iter(GEGL_ACCESS_READWRITE, 1);
137 138 139 140 141 142
}

/* Test that 'changed' signal is _not_ emitted on gegl_buffer_iterator in READ mode */
void
test_buffer_no_change_signal_with_iter_read(void)
{
143
    test_buffer_change_signal_with_iter(GEGL_ACCESS_READ, 0);
144 145 146 147 148 149 150 151 152 153 154 155 156 157 158
}

gint
main(gint argc, gchar **argv)
{
    babl_init();
    gegl_init(&argc, &argv);
    g_test_init (&argc, &argv, NULL);

    g_test_add_func ("/buffer/change/signal-on-set", test_buffer_change_signal_on_set);
    g_test_add_func ("/buffer/change/no-signal-with-iter-read", test_buffer_no_change_signal_with_iter_read);
    g_test_add_func ("/buffer/change/signal-with-iter-readwrite", test_buffer_change_signal_with_iter_readwrite);
    g_test_add_func ("/buffer/change/signal-with-iter-write", test_buffer_change_signal_with_iter_write);
    return g_test_run();
}