Tizen 2.0 Release
[framework/graphics/cairo.git] / test / png.c
1 /*
2  * Copyright © 2008 Chris Wilson
3  *
4  * Permission to use, copy, modify, distribute, and sell this software
5  * and its documentation for any purpose is hereby granted without
6  * fee, provided that the above copyright notice appear in all copies
7  * and that both that copyright notice and this permission notice
8  * appear in supporting documentation, and that the name of
9  * Chris Wilson not be used in advertising or publicity pertaining to
10  * distribution of the software without specific, written prior
11  * permission. Chris Wilson makes no representations about the
12  * suitability of this software for any purpose.  It is provided "as
13  * is" without express or implied warranty.
14  *
15  * CHRIS WILSON DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
16  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17  * FITNESS, IN NO EVENT SHALL CHRIS WILSON BE LIABLE FOR ANY SPECIAL,
18  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
19  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
20  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR
21  * IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
22  *
23  * Author: Chris Wilson <chris@chris-wilson.co.uk>
24  */
25
26 #include "cairo-test.h"
27
28 #include <assert.h>
29
30 /* Test the idempotency of write_png->read_png */
31
32 #define RGB_MASK 0x00ffffff
33
34 static cairo_bool_t
35 image_surface_equals (cairo_surface_t *A, cairo_surface_t *B)
36 {
37     if (cairo_image_surface_get_format (A) !=
38         cairo_image_surface_get_format (B))
39         return 0;
40
41     if (cairo_image_surface_get_width (A) !=
42         cairo_image_surface_get_width (B))
43         return 0;
44
45     if (cairo_image_surface_get_height (A) !=
46         cairo_image_surface_get_height (B))
47         return 0;
48
49     return 1;
50 }
51
52 static const char *
53 format_to_string (cairo_format_t format)
54 {
55     switch (format) {
56     case CAIRO_FORMAT_A1:     return "a1";
57     case CAIRO_FORMAT_A8:     return "a8";
58     case CAIRO_FORMAT_RGB16_565:  return "rgb16";
59     case CAIRO_FORMAT_RGB24:  return "rgb24";
60     case CAIRO_FORMAT_RGB30:  return "rgb30";
61     case CAIRO_FORMAT_ARGB32: return "argb32";
62     case CAIRO_FORMAT_INVALID:
63     default: return "???";
64     }
65 }
66
67 static void
68 print_surface (const cairo_test_context_t *ctx, cairo_surface_t *surface)
69 {
70     cairo_test_log (ctx,
71                     "%s (%dx%d)\n",
72                     format_to_string (cairo_image_surface_get_format (surface)),
73                     cairo_image_surface_get_width (surface),
74                     cairo_image_surface_get_height (surface));
75 }
76
77 static cairo_test_status_t
78 preamble (cairo_test_context_t *ctx)
79 {
80     const char *filename = "png.out.png";
81     cairo_surface_t *surface0, *surface1;
82     cairo_status_t status;
83     uint32_t argb32 = 0xdeadbede;
84
85     surface0 = cairo_image_surface_create_for_data ((unsigned char *) &argb32,
86                                                     CAIRO_FORMAT_ARGB32,
87                                                     1, 1, 4);
88     status = cairo_surface_write_to_png (surface0, filename);
89     if (status) {
90         cairo_test_log (ctx, "Error writing '%s': %s\n",
91                         filename, cairo_status_to_string (status));
92
93         cairo_surface_destroy (surface0);
94         return cairo_test_status_from_status (ctx, status);
95     }
96     surface1 = cairo_image_surface_create_from_png (filename);
97     status = cairo_surface_status (surface1);
98     if (status) {
99         cairo_test_log (ctx, "Error reading '%s': %s\n",
100                         filename, cairo_status_to_string (status));
101
102         cairo_surface_destroy (surface1);
103         cairo_surface_destroy (surface0);
104         return cairo_test_status_from_status (ctx, status);
105     }
106
107     if (! image_surface_equals (surface0, surface1)) {
108         cairo_test_log (ctx, "Error surface mismatch.\n");
109         cairo_test_log (ctx, "to png: "); print_surface (ctx, surface0);
110         cairo_test_log (ctx, "from png: "); print_surface (ctx, surface1);
111
112         cairo_surface_destroy (surface0);
113         cairo_surface_destroy (surface1);
114         return CAIRO_TEST_FAILURE;
115     }
116     assert (*(uint32_t *) cairo_image_surface_get_data (surface1) == argb32);
117
118     cairo_surface_destroy (surface0);
119     cairo_surface_destroy (surface1);
120
121     surface0 = cairo_image_surface_create_for_data ((unsigned char *) &argb32,
122                                                     CAIRO_FORMAT_RGB24,
123                                                     1, 1, 4);
124     status = cairo_surface_write_to_png (surface0, filename);
125     if (status) {
126         cairo_test_log (ctx, "Error writing '%s': %s\n",
127                         filename, cairo_status_to_string (status));
128         cairo_surface_destroy (surface0);
129         return cairo_test_status_from_status (ctx, status);
130     }
131     surface1 = cairo_image_surface_create_from_png (filename);
132     status = cairo_surface_status (surface1);
133     if (status) {
134         cairo_test_log (ctx, "Error reading '%s': %s\n",
135                         filename, cairo_status_to_string (status));
136
137         cairo_surface_destroy (surface1);
138         cairo_surface_destroy (surface0);
139         return cairo_test_status_from_status (ctx, status);
140     }
141
142     if (! image_surface_equals (surface0, surface1)) {
143         cairo_test_log (ctx, "Error surface mismatch.\n");
144         cairo_test_log (ctx, "to png: "); print_surface (ctx, surface0);
145         cairo_test_log (ctx, "from png: "); print_surface (ctx, surface1);
146
147         cairo_surface_destroy (surface0);
148         cairo_surface_destroy (surface1);
149         return CAIRO_TEST_FAILURE;
150     }
151     assert ((*(uint32_t *) cairo_image_surface_get_data (surface1) & RGB_MASK)
152             == (argb32 & RGB_MASK));
153
154     cairo_surface_destroy (surface0);
155     cairo_surface_destroy (surface1);
156
157     return CAIRO_TEST_SUCCESS;
158 }
159
160 CAIRO_TEST (png,
161             "Check that the png export/import is idempotent.",
162             "png, api", /* keywords */
163             NULL, /* requirements */
164             0, 0,
165             preamble, NULL)