[cairo-commit] packaging/debian/cairo/debian/patches 01-endianess-cairo-xlib-surface.patch, NONE, 1.1

Dave Beckett commit at pdx.freedesktop.org
Tue Sep 6 10:14:58 PDT 2005


Committed by: dajobe

Update of /cvs/cairo/packaging/debian/cairo/debian/patches
In directory gabe:/tmp/cvs-serv27551

Added Files:
	01-endianess-cairo-xlib-surface.patch 
Log Message:
Patch from CVS to fix endianess problem when running over remote X

--- NEW FILE: 01-endianess-cairo-xlib-surface.patch ---
Index: src/cairo-xlib-surface.c
===================================================================
diff -c -r1.119 -r1.120
*** src/cairo-xlib-surface.c	31 Aug 2005 22:08:02 -0000	1.119
--- src/cairo-xlib-surface.c	31 Aug 2005 22:09:35 -0000	1.120
***************
*** 60,65 ****
--- 60,68 ----
  static cairo_bool_t
  _cairo_surface_is_xlib (cairo_surface_t *surface);
  
+ static cairo_bool_t
+ _native_byte_order_lsb (void);
+ 
  /*
   * Instead of taking two round trips for each blending request,
   * assume that if a particular drawable fails GetImage that it will
***************
*** 314,319 ****
--- 317,432 ----
      return False;
  }
  
+ static void
+ _swap_ximage_2bytes (XImage *ximage)
+ {
+     int i, j;
+     char *line = ximage->data;
+ 
+     for (j = ximage->height; j; j--) {
+ 	uint16_t *p = (uint16_t *)line;
+ 	for (i = ximage->width; i; i--) {
+ 	    *p = (((*p & 0x00ff) << 8) |
+ 		  ((*p)          >> 8));
+ 	    p++;
+ 	}
+ 
+ 	line += ximage->bytes_per_line;
+     }
+ }
+ 
+ static void
+ _swap_ximage_4bytes (XImage *ximage)
+ {
+     int i, j;
+     char *line = ximage->data;
+ 
+     for (j = ximage->height; j; j--) {
+ 	uint32_t *p = (uint32_t *)line;
+ 	for (i = ximage->width; i; i--) {
+ 	    *p = (((*p & 0x000000ff) << 24) |
+ 		  ((*p & 0x0000ff00) << 8) |
+ 		  ((*p & 0x00ff0000) >> 8) |
+ 		  ((*p)              >> 24));
+ 	    p++;
+ 	}
+ 
+ 	line += ximage->bytes_per_line;
+     }
+ }
+ 
+ static void
+ _swap_ximage_bits (XImage *ximage)
+ {
+     int i, j;
+     char *line = ximage->data;
+     int unit = ximage->bitmap_unit;
+     int line_bytes = ((ximage->width + unit - 1) & ~(unit - 1)) / 8;
+ 
+     for (j = ximage->height; j; j--) {
+ 	char *p = line;
+ 	
+ 	for (i = line_bytes; i; i--) {
+ 	    char b = *p;
+ 	    b = ((b << 1) & 0xaa) | ((b >> 1) & 0x55);
+ 	    b = ((b << 2) & 0xcc) | ((b >> 2) & 0x33);
+ 	    b = ((b << 4) & 0xf0) | ((b >> 4) & 0x0f);
+ 	    *p = b;
+ 	    
+ 	    p++;
+ 	}
+ 
+ 	line += ximage->bytes_per_line;
+     }
+ }
+ 
+ static void
+ _swap_ximage_to_native (XImage *ximage)
+ {
+     int unit_bytes = 0;
+     int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
+ 
+     if (ximage->bits_per_pixel == 1 &&
+ 	ximage->bitmap_bit_order != native_byte_order) {
+ 	_swap_ximage_bits (ximage);
+ 	if (ximage->bitmap_bit_order == ximage->byte_order)
+ 	    return;
+     }
+     
+     if (ximage->byte_order == native_byte_order)
+ 	return;
+ 
+     switch (ximage->bits_per_pixel) {
+     case 1:
+ 	unit_bytes = ximage->bitmap_unit / 8;
+ 	break;
+     case 8:
+     case 16:
+     case 32:
+ 	unit_bytes = ximage->bits_per_pixel / 8;
+ 	break;
+     default:
+         /* This could be hit on some uncommon but possible cases,
+ 	 * such as bpp=4. These are cases that libpixman can't deal
+ 	 * with in any case.
+ 	 */
+ 	ASSERT_NOT_REACHED;
+     }
+ 
+     switch (unit_bytes) {
+     case 1:
+ 	return;
+     case 2:
+ 	_swap_ximage_2bytes (ximage);
+ 	break;
+     case 4:
+ 	_swap_ximage_4bytes (ximage);
+ 	break;
+     default:
+ 	ASSERT_NOT_REACHED;
+     }
+ }
+ 
  static cairo_status_t
  _get_image_surface (cairo_xlib_surface_t   *surface,
  		    cairo_rectangle_t      *interest_rect,
***************
*** 417,422 ****
--- 530,537 ----
      }
      if (!ximage)
  	return CAIRO_STATUS_NO_MEMORY;
+ 
+     _swap_ximage_to_native (ximage);
  					
      /*
       * Compute the pixel format masks from either a visual or a 
***************
*** 557,596 ****
  		     int                    dst_x,
  		     int                    dst_y)
  {
!     XImage *ximage;
!     unsigned bitmap_pad;
! 
!     /* XXX this is wrong */
!     if (image->depth > 16)
! 	bitmap_pad = 32;
!     else if (image->depth > 8)
! 	bitmap_pad = 16;
!     else
! 	bitmap_pad = 8;
! 
!     ximage = XCreateImage (surface->dpy,
! 			   DefaultVisual(surface->dpy, DefaultScreen(surface->dpy)),
! 			   image->depth,
! 			   ZPixmap,
! 			   0,
! 			   (char *) image->data,
! 			   image->width,
! 			   image->height,
! 			   bitmap_pad,
! 			   image->stride);
!     if (ximage == NULL)
! 	return CAIRO_STATUS_NO_MEMORY;
  
      _cairo_xlib_surface_ensure_gc (surface);
      XPutImage(surface->dpy, surface->drawable, surface->gc,
! 	      ximage, 0, 0, dst_x, dst_y,
  	      image->width, image->height);
  
-     /* Foolish XDestroyImage thinks it can free my data, but I won't
-        stand for it. */
-     ximage->data = NULL;
-     XDestroyImage (ximage);
- 
      return CAIRO_STATUS_SUCCESS;
  
  }
--- 672,706 ----
  		     int                    dst_x,
  		     int                    dst_y)
  {
!     XImage ximage;
!     int bpp, alpha, red, green, blue;
!     int native_byte_order = _native_byte_order_lsb () ? LSBFirst : MSBFirst;
!     
!     pixman_format_get_masks (pixman_image_get_format (image->pixman_image),
! 			     &bpp, &alpha, &red, &green, &blue);
!     
!     ximage.width = image->width;
!     ximage.height = image->height;
!     ximage.format = ZPixmap;
!     ximage.data = (char *)image->data;
!     ximage.byte_order = native_byte_order;
!     ximage.bitmap_unit = 32;	/* always for libpixman */
!     ximage.bitmap_bit_order = native_byte_order;
!     ximage.bitmap_pad = 32;	/* always for libpixman */
!     ximage.depth = image->depth;
!     ximage.bytes_per_line = image->stride;
!     ximage.bits_per_pixel = bpp;
!     ximage.red_mask = red;
!     ximage.green_mask = green;
!     ximage.blue_mask = blue;
  
+     XInitImage (&ximage);
+     
      _cairo_xlib_surface_ensure_gc (surface);
      XPutImage(surface->dpy, surface->drawable, surface->gc,
! 	      &ximage, 0, 0, dst_x, dst_y,
  	      image->width, image->height);
  
      return CAIRO_STATUS_SUCCESS;
  
  }



More information about the cairo-commit mailing list