Bug Summary

File:image/xcb_image.c
Location:line 591, column 16
Description:The left operand of '&' is a garbage value

Annotated Source Code

1/* Copyright © 2007 Bart Massey
2 *
3 * Permission is hereby granted, free of charge, to any person obtaining a
4 * copy of this software and associated documentation files (the "Software"),
5 * to deal in the Software without restriction, including without limitation
6 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 * and/or sell copies of the Software, and to permit persons to whom the
8 * Software is furnished to do so, subject to the following conditions:
9 *
10 * The above copyright notice and this permission notice shall be included in
11 * all copies or substantial portions of the Software.
12 *
13 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
17 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
18 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
19 *
20 * Except as contained in this notice, the names of the authors or their
21 * institutions shall not be used in advertising or otherwise to promote the
22 * sale, use or other dealings in this Software without prior written
23 * authorization from the authors.
24 */
25
26#ifdef HAVE_CONFIG_H1
27#include "config.h"
28#endif
29
30#include <stdlib.h>
31#include <stdio.h>
32#include <string.h>
33
34#include <xcb/xcb.h>
35#include <xcb/shm.h>
36#include <xcb/xcb_aux.h>
37#include "xcb_bitops.h"
38#include "xcb_image.h"
39#define BUILD
40#include "xcb_pixel.h"
41
42
43static xcb_format_t *
44find_format_by_depth (const xcb_setup_t *setup, uint8_t depth)
45{
46 xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
47 xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
48 for(; fmt != fmtend; ++fmt)
49 if(fmt->depth == depth)
50 return fmt;
51 return 0;
52}
53
54
55static xcb_image_format_t
56effective_format(xcb_image_format_t format, uint8_t bpp)
57{
58 if (format == XCB_IMAGE_FORMAT_Z_PIXMAP && bpp != 1)
59 return format;
60 return XCB_IMAGE_FORMAT_XY_PIXMAP;
61}
62
63
64static int
65format_valid (uint8_t depth, uint8_t bpp, uint8_t unit,
66 xcb_image_format_t format, uint8_t xpad)
67{
68 xcb_image_format_t ef = effective_format(format, bpp);
69 if (depth > bpp)
70 return 0;
71 switch(ef) {
72 case XCB_IMAGE_FORMAT_XY_PIXMAP:
73 switch(unit) {
74 case 8:
75 case 16:
76 case 32:
77 break;
78 default:
79 return 0;
80 }
81 if (xpad < bpp)
82 return 0;
83 switch (xpad) {
84 case 8:
85 case 16:
86 case 32:
87 break;
88 default:
89 return 0;
90 }
91 break;
92 case XCB_IMAGE_FORMAT_Z_PIXMAP:
93 switch (bpp) {
94 case 4:
95 if (unit != 8)
96 return 0;
97 break;
98 case 8:
99 case 16:
100 case 24:
101 case 32:
102 if (unit != bpp)
103 return 0;
104 break;
105 default:
106 return 0;
107 }
108 break;
109 default:
110 return 0;
111 }
112 return 1;
113}
114
115
116static int
117image_format_valid (xcb_image_t *image) {
118 return format_valid(image->depth,
119 image->bpp,
120 image->unit,
121 image->format,
122 image->scanline_pad);
123}
124
125
126void
127xcb_image_annotate (xcb_image_t *image)
128{
129 xcb_image_format_t ef = effective_format(image->format, image->bpp);
130 switch (ef) {
131 case XCB_IMAGE_FORMAT_XY_PIXMAP:
132 image->stride = xcb_roundup(image->width, image->scanline_pad) >> 3;
133 image->size = image->height * image->stride * image->depth;
134 break;
135 case XCB_IMAGE_FORMAT_Z_PIXMAP:
136 image->stride = xcb_roundup((uint32_t)image->width *
137 (uint32_t)image->bpp,
138 image->scanline_pad) >> 3;
139 image->size = image->height * image->stride;
140 break;
141 default:
142 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 142, "0") : (void)0)
;
143 }
144}
145
146
147xcb_image_t *
148xcb_image_create_native (xcb_connection_t * c,
149 uint16_t width,
150 uint16_t height,
151 xcb_image_format_t format,
152 uint8_t depth,
153 void * base,
154 uint32_t bytes,
155 uint8_t * data)
156{
157 const xcb_setup_t * setup = xcb_get_setup(c);
158 xcb_format_t * fmt;
159 xcb_image_format_t ef = format;
160
161 if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP && depth == 1)
162 ef = XCB_IMAGE_FORMAT_XY_PIXMAP;
163 switch (ef) {
164 case XCB_IMAGE_FORMAT_XY_BITMAP:
165 if (depth != 1)
166 return 0;
167 /* fall through */
168 case XCB_IMAGE_FORMAT_XY_PIXMAP:
169 if (depth > 1) {
170 fmt = find_format_by_depth(setup, depth);
171 if (!fmt)
172 return 0;
173 }
174 return xcb_image_create(width, height, format,
175 setup->bitmap_format_scanline_pad,
176 depth, depth, setup->bitmap_format_scanline_unit,
177 setup->image_byte_order,
178 setup->bitmap_format_bit_order,
179 base, bytes, data);
180 case XCB_IMAGE_FORMAT_Z_PIXMAP:
181 fmt = find_format_by_depth(setup, depth);
182 if (!fmt)
183 return 0;
184 return xcb_image_create(width, height, format,
185 fmt->scanline_pad,
186 fmt->depth, fmt->bits_per_pixel, 0,
187 setup->image_byte_order,
188 XCB_IMAGE_ORDER_MSB_FIRST,
189 base, bytes, data);
190 default:
191 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 191, "0") : (void)0)
;
192 }
193 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 193, "0") : (void)0)
;
194 return NULL((void *)0);
195}
196
197
198xcb_image_t *
199xcb_image_create (uint16_t width,
200 uint16_t height,
201 xcb_image_format_t format,
202 uint8_t xpad,
203 uint8_t depth,
204 uint8_t bpp,
205 uint8_t unit,
206 xcb_image_order_t byte_order,
207 xcb_image_order_t bit_order,
208 void * base,
209 uint32_t bytes,
210 uint8_t * data)
211{
212 xcb_image_t * image;
213
214 if (unit == 0) {
215 switch (format) {
216 case XCB_IMAGE_FORMAT_XY_BITMAP:
217 case XCB_IMAGE_FORMAT_XY_PIXMAP:
218 unit = 32;
219 break;
220 case XCB_IMAGE_FORMAT_Z_PIXMAP:
221 if (bpp == 1) {
222 unit = 32;
223 break;
224 }
225 if (bpp < 8) {
226 unit = 8;
227 break;
228 }
229 unit = bpp;
230 break;
231 }
232 }
233 if (!format_valid(depth, bpp, unit, format, xpad))
234 return 0;
235 image = malloc(sizeof(*image));
236 if (image == 0)
237 return 0;
238 image->width = width;
239 image->height = height;
240 image->format = format;
241 image->scanline_pad = xpad;
242 image->depth = depth;
243 image->bpp = bpp;
244 image->unit = unit;
245 image->plane_mask = xcb_mask(depth);
246 image->byte_order = byte_order;
247 image->bit_order = bit_order;
248 xcb_image_annotate(image);
249
250 /*
251 * Ways this function can be called:
252 * * with data: we fail if bytes isn't
253 * large enough, else leave well enough alone.
254 * * with base and !data: if bytes is zero, we
255 * default; otherwise we fail if bytes isn't
256 * large enough, else fill in data
257 * * with !base and !data: we malloc storage
258 * for the data, save that address as the base,
259 * and fail if malloc does.
260 *
261 * When successful, we establish the invariant that data
262 * points at sufficient storage that may have been
263 * supplied, and base is set iff it should be
264 * auto-freed when the image is destroyed.
265 *
266 * Except as a special case when base = 0 && data == 0 &&
267 * bytes == ~0 we just return the image structure and let
268 * the caller deal with getting the allocation right.
269 */
270 if (!base && !data && bytes == ~0) {
271 image->base = 0;
272 image->data = 0;
273 return image;
274 }
275 if (!base && data && bytes == 0)
276 bytes = image->size;
277 image->base = base;
278 image->data = data;
279 if (!image->data) {
280 if (image->base) {
281 image->data = image->base;
282 } else {
283 bytes = image->size;
284 image->base = malloc(bytes);
285 image->data = image->base;
286 }
287 }
288 if (!image->data || bytes < image->size) {
289 free(image);
290 return 0;
291 }
292 return image;
293}
294
295
296void
297xcb_image_destroy (xcb_image_t *image)
298{
299 if (image->base)
300 free (image->base);
301 free (image);
302}
303
304
305xcb_image_t *
306xcb_image_get (xcb_connection_t * conn,
307 xcb_drawable_t draw,
308 int16_t x,
309 int16_t y,
310 uint16_t width,
311 uint16_t height,
312 uint32_t plane_mask,
313 xcb_image_format_t format)
314{
315 xcb_get_image_cookie_t image_cookie;
316 xcb_get_image_reply_t * imrep;
317 xcb_image_t * image = 0;
318 uint32_t bytes;
319 uint8_t * data;
320
321 image_cookie = xcb_get_image(conn, format, draw, x, y,
322 width, height, plane_mask);
323 imrep = xcb_get_image_reply(conn, image_cookie, 0);
324 if (!imrep)
325 return 0;
326 bytes = xcb_get_image_data_length(imrep);
327 data = xcb_get_image_data(imrep);
328 switch (format) {
329 case XCB_IMAGE_FORMAT_XY_PIXMAP:
330 plane_mask &= xcb_mask(imrep->depth);
331 if (plane_mask != xcb_mask(imrep->depth)) {
332 int i;
333 uint32_t rpm = plane_mask;
334 uint32_t size;
335 uint8_t *src_plane = data;
336 uint8_t *dst_plane;
337
338 image = xcb_image_create_native(conn, width, height, format,
339 imrep->depth, 0, 0, 0);
340 if (!image) {
341 free(imrep);
342 return 0;
343 }
344 image->plane_mask = plane_mask;
345 size = image->height * image->stride;
346 dst_plane = image->data;
347 for (i = imrep->depth - 1; i >= 0; --i) {
348 if (rpm & (1 << i)) {
349 memcpy(dst_plane, src_plane, size)__builtin___memcpy_chk (dst_plane, src_plane, size, __builtin_object_size
(dst_plane, 0))
;
350 src_plane += size;
351 } else {
352 memset(dst_plane, 0, size)__builtin___memset_chk (dst_plane, 0, size, __builtin_object_size
(dst_plane, 0))
;
353 }
354 dst_plane += size;
355 }
356 free(imrep);
357 break;
358 }
359 /* fall through */
360 case XCB_IMAGE_FORMAT_Z_PIXMAP:
361 image = xcb_image_create_native(conn, width, height, format,
362 imrep->depth, imrep, bytes, data);
363 if (!image) {
364 free(imrep);
365 return 0;
366 }
367 assert(bytes == image->size)(__builtin_expect(!(bytes == image->size), 0) ? __assert_rtn
(__func__, "xcb_image.c", 367, "bytes == image->size") : (
void)0)
;
368 break;
369 default:
370 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 370, "0") : (void)0)
;
371 }
372 return image;
373}
374
375
376xcb_image_t *
377xcb_image_native (xcb_connection_t * c,
378 xcb_image_t * image,
379 int convert)
380{
381 xcb_image_t * tmp_image = 0;
382 const xcb_setup_t * setup = xcb_get_setup(c);
383 xcb_format_t * fmt = 0;
384 xcb_image_format_t ef = effective_format(image->format, image->bpp);
385 uint8_t bpp = 1;
386
387 if (image->depth > 1 || ef == XCB_IMAGE_FORMAT_Z_PIXMAP) {
388 fmt = find_format_by_depth(setup, image->depth);
389 /* XXX For now, we don't do depth conversions, even
390 for xy-pixmaps */
391 if (!fmt)
392 return 0;
393 bpp = fmt->bits_per_pixel;
394 }
395 switch (ef) {
396 case XCB_IMAGE_FORMAT_XY_PIXMAP:
397 if (setup->bitmap_format_scanline_unit != image->unit ||
398 setup->bitmap_format_scanline_pad != image->scanline_pad ||
399 setup->image_byte_order != image->byte_order ||
400 setup->bitmap_format_bit_order != image->bit_order ||
401 bpp != image->bpp) {
402 if (!convert)
403 return 0;
404 tmp_image =
405 xcb_image_create(image->width, image->height, image->format,
406 setup->bitmap_format_scanline_pad,
407 image->depth, bpp,
408 setup->bitmap_format_scanline_unit,
409 setup->image_byte_order,
410 setup->bitmap_format_bit_order,
411 0, 0, 0);
412 if (!tmp_image)
413 return 0;
414 }
415 break;
416 case XCB_IMAGE_FORMAT_Z_PIXMAP:
417 if (fmt->scanline_pad != image->scanline_pad ||
418 setup->image_byte_order != image->byte_order ||
419 bpp != image->bpp) {
420 if (!convert)
421 return 0;
422 tmp_image =
423 xcb_image_create(image->width, image->height, image->format,
424 fmt->scanline_pad,
425 image->depth, bpp, 0,
426 setup->image_byte_order,
427 XCB_IMAGE_ORDER_MSB_FIRST,
428 0, 0, 0);
429 if (!tmp_image)
430 return 0;
431 }
432 break;
433 default:
434 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 434, "0") : (void)0)
;
435 }
436 if (tmp_image) {
437 if (!xcb_image_convert(image, tmp_image)) {
438 xcb_image_destroy(tmp_image);
439 return 0;
440 }
441 image = tmp_image;
442 }
443 return image;
444}
445
446
447xcb_void_cookie_t
448xcb_image_put (xcb_connection_t * conn,
449 xcb_drawable_t draw,
450 xcb_gcontext_t gc,
451 xcb_image_t * image,
452 int16_t x,
453 int16_t y,
454 uint8_t left_pad)
455{
456 return xcb_put_image(conn, image->format, draw, gc,
457 image->width, image->height,
458 x, y, left_pad,
459 image->depth,
460 image->size,
461 image->data);
462}
463
464
465
466/*
467 * Shm stuff
468 */
469
470xcb_image_t *
471xcb_image_shm_put (xcb_connection_t * conn,
472 xcb_drawable_t draw,
473 xcb_gcontext_t gc,
474 xcb_image_t * image,
475 xcb_shm_segment_info_t shminfo,
476 int16_t src_x,
477 int16_t src_y,
478 int16_t dest_x,
479 int16_t dest_y,
480 uint16_t src_width,
481 uint16_t src_height,
482 uint8_t send_event)
483{
484 if (!xcb_image_native(conn, image, 0))
485 return 0;
486 if (!shminfo.shmaddr)
487 return 0;
488 xcb_shm_put_image(conn, draw, gc,
489 image->width, image->height,
490 src_x, src_y, src_width, src_height,
491 dest_x, dest_y,
492 image->depth, image->format,
493 send_event,
494 shminfo.shmseg,
495 image->data - shminfo.shmaddr);
496 return image;
497}
498
499
500int
501xcb_image_shm_get (xcb_connection_t * conn,
502 xcb_drawable_t draw,
503 xcb_image_t * image,
504 xcb_shm_segment_info_t shminfo,
505 int16_t x,
506 int16_t y,
507 uint32_t plane_mask)
508{
509 xcb_shm_get_image_reply_t * setup;
510 xcb_shm_get_image_cookie_t cookie;
511 xcb_generic_error_t * err = 0;
512
513 if (!shminfo.shmaddr)
514 return 0;
515 cookie = xcb_shm_get_image(conn, draw,
516 x, y,
517 image->width, image->height,
518 plane_mask,
519 image->format,
520 shminfo.shmseg,
521 image->data - shminfo.shmaddr);
522 setup = xcb_shm_get_image_reply(conn, cookie, &err);
523 if (err) {
524 fprintf(stderr__stderrp, "ShmGetImageReply error %d\n", (int)err->error_code);
525 free(err);
526 return 0;
527 } else {
528 free (setup);
529 return 1;
530 }
531}
532
533
534static uint32_t
535xy_image_byte (xcb_image_t *image, uint32_t x)
536{
537 x >>= 3;
538 if (image->byte_order == image->bit_order)
539 return x;
540 switch (image->unit) {
541 default:
542 case 8:
543 return x;
544 case 16:
545 return x ^ 1;
546 case 32:
547 return x ^ 3;
548 }
549}
550
551static uint32_t
552xy_image_bit (xcb_image_t *image, uint32_t x)
553{
554 x &= 7;
555 if (image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST)
556 x = 7 - x;
557 return x;
558}
559
560/* GetPixel/PutPixel */
561
562/* XXX this is the most hideously done cut-and-paste
563 to below. Any bugs fixed there should be fixed here
564 and vice versa. */
565void
566xcb_image_put_pixel (xcb_image_t *image,
567 uint32_t x,
568 uint32_t y,
569 uint32_t pixel)
570{
571 uint8_t *row;
572
573 if (x > image->width || y > image->height)
9
Taking false branch
574 return;
575 row = image->data + (y * image->stride);
576 switch (effective_format(image->format, image->bpp)) {
10
Control jumps to 'case XCB_IMAGE_FORMAT_XY_PIXMAP:' at line 578
577 case XCB_IMAGE_FORMAT_XY_BITMAP:
578 case XCB_IMAGE_FORMAT_XY_PIXMAP:
579 /* block */ {
580 int p;
581 uint32_t plane_mask = image->plane_mask;
582 uint8_t * plane = row;
583 uint32_t byte = xy_image_byte(image, x);
584 uint32_t bit = xy_image_bit(image,x);
585 uint8_t mask = 1 << bit;
586
587 for (p = image->bpp - 1; p >= 0; p--) {
11
Assuming 'p' is >= 0
12
Loop condition is true. Entering loop body
588 if ((plane_mask >> p) & 1) {
13
Taking true branch
589 uint8_t * bp = plane + byte;
590 uint8_t this_bit = ((pixel >> p) & 1) << bit;
591 *bp = (*bp & ~mask) | this_bit;
14
The left operand of '&' is a garbage value
592 }
593 plane += image->stride * image->height;
594 }
595 }
596 break;
597 case XCB_IMAGE_FORMAT_Z_PIXMAP:
598 switch (image->bpp) {
599 uint32_t mask;
600 case 4:
601 mask = 0xf;
602 pixel &= 0xf;
603 if ((x & 1) ==
604 (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST)) {
605 pixel <<= 4;
606 mask <<= 4;
607 }
608 row[x >> 1] = (row[x >> 1] & ~mask) | pixel;
609 break;
610 case 8:
611 row[x] = pixel;
612 break;
613 case 16:
614 switch (image->byte_order) {
615 case XCB_IMAGE_ORDER_LSB_FIRST:
616 row[x << 1] = pixel;
617 row[(x << 1) + 1] = pixel >> 8;
618 break;
619 case XCB_IMAGE_ORDER_MSB_FIRST:
620 row[x << 1] = pixel >> 8;
621 row[(x << 1) + 1] = pixel;
622 break;
623 }
624 break;
625 case 24:
626 switch (image->byte_order) {
627 case XCB_IMAGE_ORDER_LSB_FIRST:
628 row[x * 3] = pixel;
629 row[x * 3 + 1] = pixel >> 8;
630 row[x * 3 + 2] = pixel >> 16;
631 break;
632 case XCB_IMAGE_ORDER_MSB_FIRST:
633 row[x * 3] = pixel >> 16;
634 row[x * 3 + 1] = pixel >> 8;
635 row[x * 3 + 2] = pixel;
636 break;
637 }
638 break;
639 case 32:
640 switch (image->byte_order) {
641 case XCB_IMAGE_ORDER_LSB_FIRST:
642 row[x << 2] = pixel;
643 row[(x << 2) + 1] = pixel >> 8;
644 row[(x << 2) + 2] = pixel >> 16;
645 row[(x << 2) + 3] = pixel >> 24;
646 break;
647 case XCB_IMAGE_ORDER_MSB_FIRST:
648 row[x << 2] = pixel >> 24;
649 row[(x << 2) + 1] = pixel >> 16;
650 row[(x << 2) + 2] = pixel >> 8;
651 row[(x << 2) + 3] = pixel;
652 break;
653 }
654 break;
655 default:
656 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 656, "0") : (void)0)
;
657 }
658 break;
659 default:
660 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 660, "0") : (void)0)
;
661 }
662}
663
664
665/* XXX this is the most hideously done cut-and-paste
666 from above. Any bugs fixed there should be fixed here
667 and vice versa. */
668uint32_t
669xcb_image_get_pixel (xcb_image_t *image,
670 uint32_t x,
671 uint32_t y)
672{
673 uint32_t pixel = 0;
674 uint8_t *row;
675
676 assert(x < image->width && y < image->height)(__builtin_expect(!(x < image->width && y < image
->height), 0) ? __assert_rtn(__func__, "xcb_image.c", 676,
"x < image->width && y < image->height")
: (void)0)
;
677 row = image->data + (y * image->stride);
678 switch (effective_format(image->format, image->bpp)) {
679 case XCB_IMAGE_FORMAT_XY_BITMAP:
680 case XCB_IMAGE_FORMAT_XY_PIXMAP:
681 /* block */ {
682 int p;
683 uint32_t plane_mask = image->plane_mask;
684 uint8_t * plane = row;
685 uint32_t byte = xy_image_byte(image, x);
686 uint32_t bit = xy_image_bit(image,x);
687
688 for (p = image->bpp - 1; p >= 0; p--) {
689 pixel <<= 1;
690 if ((plane_mask >> p) & 1) {
691 uint8_t * bp = plane + byte;
692 pixel |= (*bp >> bit) & 1;
693 }
694 plane += image->stride * image->height;
695 }
696 }
697 return pixel;
698 case XCB_IMAGE_FORMAT_Z_PIXMAP:
699 switch (image->bpp) {
700 case 4:
701 if ((x & 1) == (image->byte_order == XCB_IMAGE_ORDER_MSB_FIRST))
702 return row[x >> 1] >> 4;
703 return row[x >> 1] & 0xf;
704 case 8:
705 return row[x];
706 case 16:
707 switch (image->byte_order) {
708 case XCB_IMAGE_ORDER_LSB_FIRST:
709 pixel = row[x << 1];
710 pixel |= row[(x << 1) + 1] << 8;
711 break;
712 case XCB_IMAGE_ORDER_MSB_FIRST:
713 pixel = row[x << 1] << 8;
714 pixel |= row[(x << 1) + 1];
715 break;
716 }
717 break;
718 case 24:
719 switch (image->byte_order) {
720 case XCB_IMAGE_ORDER_LSB_FIRST:
721 pixel = row[x * 3];
722 pixel |= row[x * 3 + 1] << 8;
723 pixel |= row[x * 3 + 2] << 16;
724 break;
725 case XCB_IMAGE_ORDER_MSB_FIRST:
726 pixel = row[x * 3] << 16;
727 pixel |= row[x * 3 + 1] << 8;
728 pixel |= row[x * 3 + 2];
729 break;
730 }
731 break;
732 case 32:
733 switch (image->byte_order) {
734 case XCB_IMAGE_ORDER_LSB_FIRST:
735 pixel = row[x << 2];
736 pixel |= row[(x << 2) + 1] << 8;
737 pixel |= row[(x << 2) + 2] << 16;
738 pixel |= row[(x << 2) + 3] << 24;
739 break;
740 case XCB_IMAGE_ORDER_MSB_FIRST:
741 pixel = row[x << 2] << 24;
742 pixel |= row[(x << 2) + 1] << 16;
743 pixel |= row[(x << 2) + 2] << 8;
744 pixel |= row[(x << 2) + 3];
745 break;
746 }
747 break;
748 default:
749 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 749, "0") : (void)0)
;
750 }
751 return pixel;
752 default:
753 assert(0)(__builtin_expect(!(0), 0) ? __assert_rtn(__func__, "xcb_image.c"
, 753, "0") : (void)0)
;
754 }
755 return 0;
756}
757
758
759xcb_image_t *
760xcb_image_create_from_bitmap_data (uint8_t * data,
761 uint32_t width,
762 uint32_t height)
763{
764 return xcb_image_create(width, height, XCB_IMAGE_FORMAT_XY_PIXMAP,
765 8, 1, 1, 8,
766 XCB_IMAGE_ORDER_LSB_FIRST,
767 XCB_IMAGE_ORDER_LSB_FIRST,
768 0, 0, data);
769}
770
771
772/*
773 * (Adapted from libX11.)
774 *
775 * xcb_create_pixmap_from_bitmap_data: Routine to make a pixmap of
776 * given depth from user supplied bitmap data.
777 * D is any drawable on the same screen that the pixmap will be used in.
778 * Data is a pointer to the bit data, and
779 * width & height give the size in bits of the pixmap.
780 *
781 * The following format is assumed for data:
782 *
783 * format=XY (will use XYPixmap for depth 1 and XYBitmap for larger)
784 * bit_order=LSBFirst
785 * padding=8
786 * bitmap_unit=8
787 */
788xcb_pixmap_t
789xcb_create_pixmap_from_bitmap_data (xcb_connection_t * display,
790 xcb_drawable_t d,
791 uint8_t * data,
792 uint32_t width,
793 uint32_t height,
794 uint32_t depth,
795 uint32_t fg,
796 uint32_t bg,
797 xcb_gcontext_t * gcp)
798{
799 xcb_pixmap_t pix;
800 xcb_image_t * image;
801 xcb_image_t * final_image;
802 xcb_gcontext_t gc;
803 uint32_t mask = 0;
804 xcb_params_gc_t gcv;
805
806 image = xcb_image_create_from_bitmap_data(data, width, height);
807 if (!image)
808 return 0;
809 if (depth > 1)
810 image->format = XCB_IMAGE_FORMAT_XY_BITMAP;
811 final_image = xcb_image_native(display, image, 1);
812 if (!final_image) {
813 xcb_image_destroy(image);
814 return 0;
815 }
816 pix = xcb_generate_id(display);
817 xcb_create_pixmap(display, depth, pix, d, width, height);
818 gc = xcb_generate_id(display);
819 XCB_AUX_ADD_PARAM(&mask, &gcv, foreground, fg)((*(&mask)|=1<<((uint32_t const*)(&(((&gcv)
)->foreground))-(uint32_t const*)((&gcv)))), ((&gcv
)->foreground=(fg)))
;
820 XCB_AUX_ADD_PARAM(&mask, &gcv, background, bg)((*(&mask)|=1<<((uint32_t const*)(&(((&gcv)
)->background))-(uint32_t const*)((&gcv)))), ((&gcv
)->background=(bg)))
;
821 xcb_aux_create_gc(display, gc, pix, mask, &gcv);
822 xcb_image_put(display, pix, gc, final_image, 0, 0, 0);
823 if (final_image != image)
824 xcb_image_destroy(final_image);
825 xcb_image_destroy(image);
826 if (gcp)
827 *gcp = gc;
828 else
829 xcb_free_gc(display, gc);
830 return pix;
831}
832
833
834/* Thanks to Keith Packard <keithp@keithp.com> for this code */
835static void
836swap_image(uint8_t * src,
837 uint32_t src_stride,
838 uint8_t * dst,
839 uint32_t dst_stride,
840 uint32_t height,
841 uint32_t byteswap,
842 int bitswap,
843 int nibbleswap)
844{
845 while (height--) {
846 uint32_t s;
847
848 for (s = 0; s < src_stride; s++) {
849 uint8_t b;
850 uint32_t d = s ^ byteswap;
851
852 if (d > dst_stride)
853 continue;
854
855 b = src[s];
856 if (bitswap)
857 b = xcb_bit_reverse(b, 8);
858 if (nibbleswap)
859 b = (b << 4) | (b >> 4);
860 dst[d] = b;
861 }
862 src += src_stride;
863 dst += dst_stride;
864 }
865}
866
867/* Which order are bytes in (low two bits), given
868 * code which accesses an image one byte at a time
869 */
870static uint32_t
871byte_order(xcb_image_t *i)
872{
873 uint32_t flip = i->byte_order == XCB_IMAGE_ORDER_MSB_FIRST;
874
875 switch (i->bpp) {
876 default:
877 case 8:
878 return 0;
879 case 16:
880 return flip;
881 case 32:
882 return flip | (flip << 1);
883 }
884}
885
886static uint32_t
887bit_order(xcb_image_t *i)
888{
889 uint32_t flip = i->byte_order != i->bit_order;
890
891 switch (i->unit) {
892 default:
893 case 8:
894 return 0;
895 case 16:
896 return flip;
897 case 32:
898 return flip | (flip << 1);
899 }
900}
901
902/* Convert from one byte order to another by flipping the
903 * low two bits of the byte index along a scanline
904 */
905static uint32_t
906conversion_byte_swap(xcb_image_t *src, xcb_image_t *dst)
907{
908 xcb_image_format_t ef = effective_format(src->format, src->bpp);
909
910 /* src_ef == dst_ef in all callers of this function */
911 if (ef == XCB_IMAGE_FORMAT_XY_PIXMAP) {
912 return bit_order(src) ^ bit_order(dst);
913 } else {
914 /* src_bpp == dst_bpp in all callers of this function */
915 return byte_order(src) ^ byte_order(dst);
916 }
917}
918
919xcb_image_t *
920xcb_image_convert (xcb_image_t * src,
921 xcb_image_t * dst)
922{
923 xcb_image_format_t ef = effective_format(src->format, src->bpp);
924
925 /* Things will go horribly wrong here if a bad
926 image is passed in, so we check some things
927 up front just to be nice. */
928 assert(image_format_valid(src))(__builtin_expect(!(image_format_valid(src)), 0) ? __assert_rtn
(__func__, "xcb_image.c", 928, "image_format_valid(src)") : (
void)0)
;
929 assert(image_format_valid(dst))(__builtin_expect(!(image_format_valid(dst)), 0) ? __assert_rtn
(__func__, "xcb_image.c", 929, "image_format_valid(dst)") : (
void)0)
;
930
931 /* images must be the same size
932 * (yes, we could copy a sub-set)
933 */
934 if (src->width != dst->width ||
935 src->height != dst->height)
936 return 0;
937
938 if (ef == effective_format(dst->format, dst->bpp) &&
939 src->bpp == dst->bpp)
940 {
941 if (src->unit == dst->unit &&
942 src->scanline_pad == dst->scanline_pad &&
943 src->byte_order == dst->byte_order &&
944 (ef == XCB_IMAGE_FORMAT_Z_PIXMAP ||
945 src->bit_order == dst->bit_order)) {
946 memcpy(dst->data, src->data, src->size)__builtin___memcpy_chk (dst->data, src->data, src->size
, __builtin_object_size (dst->data, 0))
;
947 } else {
948 int bitswap = 0;
949 int nibbleswap = 0;
950 uint32_t byteswap = conversion_byte_swap(src, dst);
951 uint32_t height = src->height;;
952
953 if (ef == XCB_IMAGE_FORMAT_Z_PIXMAP) {
954 if (src->bpp == 4 && src->byte_order != dst->byte_order)
955 nibbleswap = 1;
956 } else {
957 if (src->bit_order != dst->bit_order)
958 bitswap = 1;
959 height *= src->depth;
960 }
961 swap_image (src->data, src->stride, dst->data, dst->stride,
962 height, byteswap, bitswap, nibbleswap);
963 }
964 }
965 else
966 {
967 uint32_t x;
968 uint32_t y;
969 /* General case: Slow pixel copy. Should we optimize
970 Z24<->Z32 copies of either endianness? */
971 for (y = 0; y < src->height; y++) {
972 for (x = 0; x < src->width; x++) {
973 uint32_t pixel = xcb_image_get_pixel(src, x, y);
974 xcb_image_put_pixel(dst, x, y, pixel);
975 }
976 }
977 }
978 return dst;
979}
980
981xcb_image_t *
982xcb_image_subimage(xcb_image_t * image,
983 uint32_t x,
984 uint32_t y,
985 uint32_t width,
986 uint32_t height,
987 void * base,
988 uint32_t bytes,
989 uint8_t * data)
990{
991 int i, j;
992 xcb_image_t * result;
993
994 if (x + width > image->width)
1
Taking false branch
995 return 0;
996 if (y + height > image->height)
2
Taking false branch
997 return 0;
998 result = xcb_image_create(width, height, image->format,
999 image->scanline_pad, image->depth,
1000 image->bpp, image->unit, image->byte_order,
1001 image->bit_order,
1002 base, bytes, data);
1003 if (!result)
3
Taking false branch
1004 return 0;
1005 /* XXX FIXME For now, lose on performance. Sorry. */
1006 for (j = 0; j < height; j++) {
4
Assuming 'j' is < 'height'
5
Loop condition is true. Entering loop body
1007 for (i = 0; i < width; i++) {
6
Assuming 'i' is < 'width'
7
Loop condition is true. Entering loop body
1008 uint32_t pixel = xcb_image_get_pixel(image, x + i, y + j);
1009 xcb_image_put_pixel(result, i, j, pixel);
8
Calling 'xcb_image_put_pixel'
1010 }
1011 }
1012 return result;
1013}