X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fimage.c;h=8ddcc6879fea3fff5a9a2688218579e5e93ee2b7;hb=2b65ec99f743dde3ee41083cf89623d4d9b8740e;hp=42c3384a0cd6c8f518b97138750a370de561134c;hpb=391f8c019bdd5591015f8f310d97cf077de93fa2;p=rocksndiamonds.git diff --git a/src/libgame/image.c b/src/libgame/image.c index 42c3384a..8ddcc687 100644 --- a/src/libgame/image.c +++ b/src/libgame/image.c @@ -136,8 +136,73 @@ static Pixmap Image_to_Mask(Image *image, Display *display, Window window) dst_ptr += bytes_per_row; /* continue with leftmost byte of next row */ } - mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data, - image->width, image->height); + if ((mask_pixmap = XCreateBitmapFromData(display, window, (char *)mask_data, + image->width, image->height)) + == None) + Error(ERR_EXIT, "Image_to_Mask(): XCreateBitmapFromData() failed"); + + free(mask_data); + + return mask_pixmap; +} + +Pixmap Pixmap_to_Mask(Pixmap src_pixmap, int src_width, int src_height) +{ + XImage *src_ximage; + byte *src_ptr, *dst_ptr, *dst_ptr2; + int bits_per_pixel; + int bytes_per_pixel; + unsigned int bytes_per_row; + unsigned int x, y, i; + byte bitmask; + byte *mask_data; + Pixmap mask_pixmap; + + /* copy source pixmap to temporary image */ + if ((src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height, + AllPlanes, ZPixmap)) == NULL) + Error(ERR_EXIT, "Pixmap_to_Mask(): XGetImage() failed"); + + bits_per_pixel = src_ximage->bits_per_pixel; + bytes_per_pixel = (bits_per_pixel + 7) / 8; + + bytes_per_row = (src_width + 7) / 8; + mask_data = checked_calloc(bytes_per_row * src_height); + + src_ptr = (byte *)src_ximage->data; + dst_ptr = mask_data; + + /* create bitmap data which can be used by 'XCreateBitmapFromData()' + * directly to create a pixmap of depth 1 for use as a clip mask for + * the corresponding image pixmap + */ + + for (y = 0; y < src_height; y++) + { + bitmask = 0x01; /* start with leftmost bit in the byte */ + dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */ + + for (x = 0; x < src_width; x++) + { + for (i = 0; i < bytes_per_pixel; i++) + if (*src_ptr++) /* source pixel solid? (pixel index != 0) */ + *dst_ptr2 |= bitmask; /* then write a bit into the image mask */ + + if ((bitmask <<= 1) == 0) /* bit at rightmost byte position reached? */ + { + bitmask = 0x01; /* start again with leftmost bit position */ + dst_ptr2++; /* continue with next byte in image mask */ + } + } + + dst_ptr += bytes_per_row; /* continue with leftmost byte of next row */ + } + + if ((mask_pixmap = XCreateBitmapFromData(display, window->drawable, + (char *)mask_data, + src_width, src_height)) == None) + Error(ERR_EXIT, "Pixmap_to_Mask(): XCreateBitmapFromData() failed"); + free(mask_data); return mask_pixmap; @@ -571,6 +636,8 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, Important note: The scaling code currently only supports scaling of the image up or down by a power of 2 -- other scaling factors currently not supported! + Also not supported is scaling of pixmap masks (with depth 1); to scale them, + better use Pixmap_to_Mask() for now. ----------------------------------------------------------------------------- */ @@ -583,13 +650,9 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap, int bits_per_pixel; int bytes_per_pixel; int x, y, xx, yy, i; -#if 1 - boolean scale_down = (src_width > dst_width); - int zoom_factor; -#else - int zoom_factor = src_width / dst_width; /* currently very limited! */ -#endif int row_skip, col_skip; + int zoom_factor; + boolean scale_down = (src_width > dst_width); if (scale_down) { @@ -607,15 +670,18 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap, } /* copy source pixmap to temporary image */ - src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height, - AllPlanes, ZPixmap); + if ((src_ximage = XGetImage(display, src_pixmap, 0, 0, src_width, src_height, + AllPlanes, ZPixmap)) == NULL) + Error(ERR_EXIT, "ZoomPixmap(): XGetImage() failed"); bits_per_pixel = src_ximage->bits_per_pixel; bytes_per_pixel = (bits_per_pixel + 7) / 8; - dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap, - 0, NULL, dst_width, dst_height, - 8, dst_width * bytes_per_pixel); + if ((dst_ximage = XCreateImage(display, visual, src_ximage->depth, ZPixmap, + 0, NULL, dst_width, dst_height, + 8, dst_width * bytes_per_pixel)) == NULL) + Error(ERR_EXIT, "ZoomPixmap(): XCreateImage() failed"); + dst_ximage->data = checked_malloc(dst_width * dst_height * bytes_per_pixel); dst_ximage->byte_order = src_ximage->byte_order;