1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License as published by
4  * the Free Software Foundation; either version 3 of the License, or
5  * (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, see <https://www.gnu.org/licenses/>.
14  *
15  * Copyright (C) 2013 Daniel Sabo
16  */
17 #include "gegl.h"
18 
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <string.h>
22 
23 static gboolean
test_scale(const gdouble scale,const gint x,const gint y,const Babl * format)24 test_scale (const gdouble scale, const gint x, const gint y, const Babl *format)
25 {
26   GeglNode *checkerboard;
27   GeglBuffer *tmp_buffer;
28   gboolean result = FALSE;
29 
30   const gint bpp = babl_format_get_bytes_per_pixel (format);
31   const gint scaled_width  = 32;
32   const gint scaled_height = 32;
33   gint pad = 32;
34 
35   guchar *output_buffer_scaled = gegl_malloc (scaled_width * scaled_height * bpp);
36   guchar *output_node_scaled   = gegl_malloc (scaled_width * scaled_height * bpp);
37 
38   if (2 / scale > pad)
39     pad = 2 / scale + 2;
40 
41   tmp_buffer = gegl_buffer_new (GEGL_RECTANGLE ((x / scale) - pad,
42                                                 (y / scale) - pad,
43                                                 (scaled_width / scale) + (2 * pad),
44                                                 (scaled_height / scale) + (2 * pad)),
45                                 babl_format ("RGBA float"));
46 
47   checkerboard = gegl_node_new_child(NULL,
48                                      "operation", "gegl:checkerboard",
49                                      "x", 16,
50                                      "y", 16,
51                                      NULL);
52 
53   gegl_node_blit_buffer (checkerboard,
54                          tmp_buffer,
55                          NULL,
56                          0,
57                          GEGL_ABYSS_NONE);
58 
59   gegl_buffer_get (tmp_buffer,
60                    GEGL_RECTANGLE (x, y, scaled_width, scaled_height),
61                    scale,
62                    format,
63                    output_buffer_scaled,
64                    GEGL_AUTO_ROWSTRIDE,
65                    GEGL_ABYSS_NONE);
66 
67   g_object_unref (checkerboard);
68   g_object_unref (tmp_buffer);
69 
70   /* Re-create the node so we don't hit its cache */
71   checkerboard = gegl_node_new_child(NULL,
72                                      "operation", "gegl:checkerboard",
73                                      "x", 16,
74                                      "y", 16,
75                                      NULL);
76 
77   gegl_node_blit (checkerboard,
78                   scale,
79                   GEGL_RECTANGLE (x, y, scaled_width, scaled_height),
80                   format,
81                   output_node_scaled,
82                   GEGL_AUTO_ROWSTRIDE,
83                   0);
84 
85   g_object_unref (checkerboard);
86 
87   if (0 == memcmp (output_buffer_scaled, output_node_scaled, scaled_width * scaled_height * bpp))
88     {
89       printf (".");
90       fflush(stdout);
91       result = TRUE;
92     }
93   else
94     {
95       printf ("\n scale=%.4f at %d, %d in \"%s\" ... FAIL\n", scale, x, y, babl_get_name (format));
96       result = FALSE;
97     }
98 
99   gegl_free (output_buffer_scaled);
100   gegl_free (output_node_scaled);
101 
102   return result;
103 }
104 
main(int argc,char ** argv)105 int main(int argc, char **argv)
106 {
107   gint tests_run    = 0;
108   gint tests_passed = 0;
109   gint tests_failed = 0;
110 
111   gdouble scale_list[] = {5.0, 2.5, 2.0, 1.5, 1.0, 0.9, 0.5, 0.3, 0.1, 0.09, 0.05, 0.03};
112   gint x_list[] = {-16, 0, 15};
113   gint i, j, k;
114 
115   gegl_init(0, NULL);
116   g_object_set(G_OBJECT(gegl_config()),
117                "swap", "RAM",
118                "use-opencl", FALSE,
119                NULL);
120 
121   printf ("testing scaled blit\n");
122 
123   for (i = 0; i < sizeof(x_list) / sizeof(x_list[0]); ++i)
124     {
125       for (j = 0; j < sizeof(scale_list) / sizeof(scale_list[0]); ++j)
126         {
127           const Babl *format_list[] = {babl_format ("RGBA u8"), babl_format ("RGBA u16")};
128 
129           for (k = 0; k < sizeof(format_list) / sizeof(format_list[0]); ++k)
130             {
131               if (test_scale (scale_list[j], x_list[i], 0, format_list[k]))
132                 tests_passed++;
133               else
134                 tests_failed++;
135               tests_run++;
136             }
137         }
138     }
139 
140   gegl_exit();
141 
142   printf ("\n");
143 
144   if (tests_passed == tests_run)
145     return 0;
146   return -1;
147 
148   return 0;
149 }
150