1ecce36beSmrg/*
2ecce36beSmrg * Copyright © 2008 Keith Packard <keithp@keithp.com>
3ecce36beSmrg *
4ecce36beSmrg * Permission is hereby granted, free of charge, to any person
5ecce36beSmrg * obtaining a copy of this software and associated documentation
6ecce36beSmrg * files (the "Software"), to deal in the Software without
7ecce36beSmrg * restriction, including without limitation the rights to use, copy,
8ecce36beSmrg * modify, merge, publish, distribute, sublicense, and/or sell copies
9ecce36beSmrg * of the Software, and to permit persons to whom the Software is
10ecce36beSmrg * furnished to do so, subject to the following conditions:
11ecce36beSmrg *
12ecce36beSmrg * The above copyright notice and this permission notice shall be
13ecce36beSmrg * included in all copies or substantial portions of the Software.
14ecce36beSmrg *
15ecce36beSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16ecce36beSmrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17ecce36beSmrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18ecce36beSmrg * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
19ecce36beSmrg * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
20ecce36beSmrg * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21ecce36beSmrg * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22ecce36beSmrg *
23ecce36beSmrg * Except as contained in this notice, the names of the authors or
24ecce36beSmrg * their institutions shall not be used in advertising or otherwise to
25ecce36beSmrg * promote the sale, use or other dealings in this Software without
26ecce36beSmrg * prior written authorization from the authors.
27ecce36beSmrg */
28ecce36beSmrg
29ecce36beSmrg#include <stdlib.h>
30ecce36beSmrg#include <stdio.h>
31ecce36beSmrg#include <string.h>
32ecce36beSmrg#include <assert.h>
33ecce36beSmrg#include <xcb/xcb.h>
34ecce36beSmrg#include "../aux/xcb_aux.h"
35ecce36beSmrg#include "xcb_image.h"
36ecce36beSmrg
37ecce36beSmrgxcb_image_format_t  formats[] = {
38ecce36beSmrg    XCB_IMAGE_FORMAT_Z_PIXMAP,
39ecce36beSmrg    XCB_IMAGE_FORMAT_XY_PIXMAP,
40ecce36beSmrg    XCB_IMAGE_FORMAT_XY_BITMAP,
41ecce36beSmrg};
42ecce36beSmrg#define SIZE(a) (sizeof (a) / sizeof (a[0]))
43ecce36beSmrg#define NFORMAT SIZE(formats)
44ecce36beSmrg
45ecce36beSmrgint bpps[] = {
46ecce36beSmrg    1, 4, 8, 16, 32
47ecce36beSmrg};
48ecce36beSmrg#define NBPP SIZE(bpps)
49ecce36beSmrg
50ecce36beSmrgint units[] = {
51ecce36beSmrg    8, 16, 32
52ecce36beSmrg};
53ecce36beSmrg#define NUNIT SIZE(units)
54ecce36beSmrg
55ecce36beSmrgxcb_image_order_t   byte_orders[] = {
56ecce36beSmrg    XCB_IMAGE_ORDER_LSB_FIRST,
57ecce36beSmrg    XCB_IMAGE_ORDER_MSB_FIRST
58ecce36beSmrg};
59ecce36beSmrg#define NBYTE_ORDER SIZE(byte_orders)
60ecce36beSmrg
61ecce36beSmrgstatic
62ecce36beSmrguint32_t pixel_mask (int bpp)
63ecce36beSmrg{
64ecce36beSmrg    if (bpp == 32)
65ecce36beSmrg	return 0xffffffff;
66ecce36beSmrg    return (1 << bpp) - 1;
67ecce36beSmrg}
68ecce36beSmrg
69ecce36beSmrgint
70ecce36beSmrgcompare_image(xcb_image_t *a, xcb_image_t *b)
71ecce36beSmrg{
72ecce36beSmrg    int x, y;
73ecce36beSmrg    uint32_t	a_pixel, b_pixel;
74ecce36beSmrg    uint32_t	mask = pixel_mask (a->bpp) & pixel_mask (b->bpp);
75ecce36beSmrg
76ecce36beSmrg    for (y = 0; y < a->height; y++)
77ecce36beSmrg	for (x = 0; x < a->width; x++) {
78ecce36beSmrg	    a_pixel = xcb_image_get_pixel (a, x, y) & mask;
79ecce36beSmrg	    b_pixel = xcb_image_get_pixel (b, x, y) & mask;
80ecce36beSmrg	    if (a_pixel != b_pixel) {
81ecce36beSmrg		fprintf (stderr, "fail at %d,%d: 0x%x != 0x%x\n",
82ecce36beSmrg			 x, y, a_pixel, b_pixel);
83ecce36beSmrg		return 0;
84ecce36beSmrg	    }
85ecce36beSmrg	}
86ecce36beSmrg    return 1;
87ecce36beSmrg}
88ecce36beSmrg
89ecce36beSmrg#define test_width  63
90ecce36beSmrg#define test_height 2
91ecce36beSmrg
92ecce36beSmrgstatic xcb_image_t *
93ecce36beSmrgcreate_test_image (void)
94ecce36beSmrg{
95ecce36beSmrg    xcb_image_t	*test_image;
96ecce36beSmrg    int		x, y;
97ecce36beSmrg    uint32_t	pixel;
98ecce36beSmrg    test_image = xcb_image_create(test_width, test_height,
99ecce36beSmrg				  XCB_IMAGE_FORMAT_Z_PIXMAP,
100ecce36beSmrg				  32,
101ecce36beSmrg				  32,
102ecce36beSmrg				  32,
103ecce36beSmrg				  32,
104ecce36beSmrg				  XCB_IMAGE_ORDER_LSB_FIRST,
105ecce36beSmrg				  XCB_IMAGE_ORDER_LSB_FIRST,
106ecce36beSmrg				  NULL, 0, NULL);
107ecce36beSmrg
108ecce36beSmrg    pixel = 0;
109ecce36beSmrg    for (y = 0; y < test_height; y++)
110ecce36beSmrg	for (x = 0; x < test_width; x++) {
111ecce36beSmrg	    xcb_image_put_pixel (test_image, x, y, pixel);
112ecce36beSmrg	    pixel++;
113ecce36beSmrg	}
114ecce36beSmrg    return test_image;
115ecce36beSmrg}
116ecce36beSmrg
117ecce36beSmrgstatic void
118ecce36beSmrgconvert_test (xcb_image_t *test, xcb_image_t *a)
119ecce36beSmrg{
120ecce36beSmrg    int		x, y;
121ecce36beSmrg
122ecce36beSmrg    for (y = 0; y < test->height; y++)
123ecce36beSmrg	for (x = 0; x < test->width; x++)
124ecce36beSmrg	    xcb_image_put_pixel (a, x, y, xcb_image_get_pixel (test, x, y));
125ecce36beSmrg}
126ecce36beSmrg
127ecce36beSmrgstatic char *
128ecce36beSmrgorder_name (xcb_image_order_t order) {
129ecce36beSmrg  if (order == XCB_IMAGE_ORDER_MSB_FIRST)
130ecce36beSmrg    return "MSB";
131ecce36beSmrg  else
132ecce36beSmrg    return "LSB";
133ecce36beSmrg}
134ecce36beSmrg
135ecce36beSmrgstatic void
136ecce36beSmrgprint_format (xcb_image_t *image)
137ecce36beSmrg{
138ecce36beSmrg  switch (image->format) {
139ecce36beSmrg  case XCB_IMAGE_FORMAT_Z_PIXMAP: fprintf (stderr, "Z pixmap"); break;
140ecce36beSmrg  case XCB_IMAGE_FORMAT_XY_PIXMAP: fprintf (stderr, "XY pixmap"); break;
141ecce36beSmrg  case XCB_IMAGE_FORMAT_XY_BITMAP: fprintf (stderr, "XY bitmap"); break;
142ecce36beSmrg  }
143ecce36beSmrg  fprintf (stderr, " pad: %d bpp: %d depth: %d unit: %d planemask: 0x%08x",
144ecce36beSmrg	   image->scanline_pad, image->bpp, image->depth, image->unit,
145ecce36beSmrg	   image->plane_mask);
146ecce36beSmrg  fprintf (stderr, " byte order: %s bit order: %s stride: %d\n",
147ecce36beSmrg	   order_name (image->byte_order), order_name (image->bit_order),
148ecce36beSmrg	   image->stride);
149ecce36beSmrg}
150ecce36beSmrg
151ecce36beSmrgint main (int argc, char **argv) {
152ecce36beSmrg  xcb_image_t	*test_image;
153ecce36beSmrg  xcb_image_t	*src_image;
154ecce36beSmrg  xcb_image_t	*dst_image;
155ecce36beSmrg  int		dst_format_i, dst_bpp_i, dst_unit_i, dst_byte_order_i, dst_bit_order_i;
156ecce36beSmrg  int		src_format_i, src_bpp_i, src_unit_i, src_byte_order_i, src_bit_order_i;
157ecce36beSmrg  xcb_image_format_t	dst_format, src_format;
158ecce36beSmrg  int		dst_bpp, src_bpp;
159ecce36beSmrg  int		dst_unit, src_unit;
160ecce36beSmrg  int		dst_byte_order, src_byte_order;
161ecce36beSmrg  int		dst_bit_order, src_bit_order;
162ecce36beSmrg
163ecce36beSmrg  test_image = create_test_image ();
164ecce36beSmrg
165ecce36beSmrg  for (dst_format_i = 0; dst_format_i < NFORMAT; dst_format_i++) {
166ecce36beSmrg    dst_format = formats[dst_format_i];
167ecce36beSmrg    for (src_format_i = 0; src_format_i < NFORMAT; src_format_i++) {
168ecce36beSmrg      src_format = formats[src_format_i];
169ecce36beSmrg      for (dst_bpp_i = 0; dst_bpp_i < NBPP; dst_bpp_i++) {
170ecce36beSmrg	dst_bpp = bpps[dst_bpp_i];
171ecce36beSmrg	for (src_bpp_i = 0; src_bpp_i < NBPP; src_bpp_i++) {
172ecce36beSmrg	  src_bpp = bpps[src_bpp_i];
173ecce36beSmrg	  for (dst_unit_i = 0; dst_unit_i < NUNIT; dst_unit_i++) {
174ecce36beSmrg	    dst_unit = units[dst_unit_i];
175ecce36beSmrg	    if (dst_format == XCB_IMAGE_FORMAT_Z_PIXMAP) {
176ecce36beSmrg	      if (dst_bpp == 4 && dst_unit != 8)
177ecce36beSmrg		continue;
178ecce36beSmrg	      if (dst_bpp > 4 && dst_unit != dst_bpp)
179ecce36beSmrg		continue;
180ecce36beSmrg	    }
181ecce36beSmrg	    if (dst_format == XCB_IMAGE_FORMAT_XY_BITMAP && dst_bpp != 1)
182ecce36beSmrg	      continue;
183ecce36beSmrg	    for (src_unit_i = 0; src_unit_i < NUNIT; src_unit_i++) {
184ecce36beSmrg	      src_unit = units[src_unit_i];
185ecce36beSmrg	      if (src_format == XCB_IMAGE_FORMAT_Z_PIXMAP) {
186ecce36beSmrg		if (src_bpp == 4 && src_unit != 8)
187ecce36beSmrg		  continue;
188ecce36beSmrg		if (src_bpp > 4 && src_unit != src_bpp)
189ecce36beSmrg		  continue;
190ecce36beSmrg	      }
191ecce36beSmrg	      if (src_format == XCB_IMAGE_FORMAT_XY_BITMAP && src_bpp != 1)
192ecce36beSmrg		continue;
193ecce36beSmrg	      for (dst_byte_order_i = 0; dst_byte_order_i < NBYTE_ORDER; dst_byte_order_i++) {
194ecce36beSmrg		dst_byte_order = byte_orders[dst_byte_order_i];
195ecce36beSmrg		for (src_byte_order_i = 0; src_byte_order_i < NBYTE_ORDER; src_byte_order_i++) {
196ecce36beSmrg		  src_byte_order = byte_orders[src_byte_order_i];
197ecce36beSmrg		  for (dst_bit_order_i = 0; dst_bit_order_i < NBYTE_ORDER; dst_bit_order_i++) {
198ecce36beSmrg		    dst_bit_order = byte_orders[dst_bit_order_i];
199ecce36beSmrg		    if (dst_format == XCB_IMAGE_FORMAT_Z_PIXMAP && dst_bit_order != dst_byte_order)
200ecce36beSmrg		      continue;
201ecce36beSmrg		    for (src_bit_order_i = 0; src_bit_order_i < NBYTE_ORDER; src_bit_order_i++) {
202ecce36beSmrg		      src_bit_order = byte_orders[src_bit_order_i];
203ecce36beSmrg		      if (src_format == XCB_IMAGE_FORMAT_Z_PIXMAP && src_bit_order != src_byte_order)
204ecce36beSmrg			continue;
205ecce36beSmrg		      src_image = xcb_image_create (test_width, test_height, src_format, 32, src_bpp, src_bpp, src_unit,
206ecce36beSmrg						    src_byte_order, src_bit_order, NULL, 0, NULL);
207ecce36beSmrg		      dst_image = xcb_image_create (test_width, test_height, dst_format, 32, dst_bpp, dst_bpp, dst_unit,
208ecce36beSmrg						    dst_byte_order, dst_bit_order, NULL, 0, NULL);
209ecce36beSmrg		      convert_test (test_image, src_image);
210ecce36beSmrg		      if (!compare_image (test_image, src_image)) {
211ecce36beSmrg			fprintf (stderr, "Initialization failure:\n");
212ecce36beSmrg			fprintf (stderr, "src format: "); print_format(src_image);
213ecce36beSmrg			exit (1);
214ecce36beSmrg		      }
215ecce36beSmrg		      xcb_image_convert (src_image, dst_image);
216ecce36beSmrg		      if (!compare_image (src_image, dst_image)) {
217ecce36beSmrg			/*
218ecce36beSmrg			 * Call the conversion function again so that debugging
219ecce36beSmrg			 * is easier
220ecce36beSmrg			 */
221ecce36beSmrg			fprintf (stderr, "Conversion failure:\n");
222ecce36beSmrg			fprintf (stderr, "src format: "); print_format(src_image);
223ecce36beSmrg			fprintf (stderr, "dst format: "); print_format(dst_image);
224ecce36beSmrg			exit (1);
225ecce36beSmrg		      }
226ecce36beSmrg		      xcb_image_destroy (src_image);
227ecce36beSmrg		      xcb_image_destroy (dst_image);
228ecce36beSmrg		    }
229ecce36beSmrg		  }
230ecce36beSmrg		}
231ecce36beSmrg	      }
232ecce36beSmrg	    }
233ecce36beSmrg	  }
234ecce36beSmrg	}
235ecce36beSmrg      }
236ecce36beSmrg    }
237ecce36beSmrg  }
238ecce36beSmrg  return 0;
239ecce36beSmrg}
240