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