X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Flibgame%2Fimage.c;h=4088af3b0bf5665b171efee4e64ffa4decd5cb7d;hb=b7c0e8ca1c06e1d54714b382d6b92f4ff2d47af7;hp=e4ec9ebfd58437dda03fa25974c6e111241674eb;hpb=df11f4a529251a285f3a33946da81623044fef3f;p=rocksndiamonds.git diff --git a/src/libgame/image.c b/src/libgame/image.c index e4ec9ebf..4088af3b 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; @@ -560,7 +625,7 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, XPutImage(ximageinfo->display, ximageinfo->pixmap, gc, ximage, 0, 0, 0, 0, ximage->width, ximage->height); - XDestroyImage(ximage); + X11DestroyImage(ximage); return ximageinfo; } @@ -569,8 +634,8 @@ XImageInfo *Image_to_Pixmap(Display *display, int screen, Visual *visual, ----------------------------------------------------------------------------- ZoomPixmap - Important note: The scaling code currently only supports scaling down the - image by a power of 2 -- scaling up is currently not supported at all! + 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! ----------------------------------------------------------------------------- */ @@ -582,24 +647,43 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap, byte *src_ptr, *dst_ptr; int bits_per_pixel; int bytes_per_pixel; - int x, y, i; + 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; - /* adjust source image size to integer multiple of destination image size */ - src_width = dst_width * zoom_factor; - src_height = dst_height * zoom_factor; + if (scale_down) + { + zoom_factor = src_width / dst_width; + + /* adjust source image size to integer multiple of destination size */ + src_width = dst_width * zoom_factor; + src_height = dst_height * zoom_factor; + } + else + { + zoom_factor = dst_width / src_width; + + /* no adjustment needed when scaling up (some pixels may be left blank) */ + } /* 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; @@ -607,22 +691,83 @@ void ZoomPixmap(Display *display, GC gc, Pixmap src_pixmap, Pixmap dst_pixmap, src_ptr = (byte *)src_ximage->data; dst_ptr = (byte *)dst_ximage->data; - col_skip = (zoom_factor - 1) * bytes_per_pixel; - row_skip = col_skip * src_width; + if (scale_down) + { + col_skip = (zoom_factor - 1) * bytes_per_pixel; + row_skip = col_skip * src_width; + + /* scale image down by scaling factor 'zoom_factor' */ + for (y = 0; y < src_height; y += zoom_factor, src_ptr += row_skip) + for (x = 0; x < src_width; x += zoom_factor, src_ptr += col_skip) + for (i = 0; i < bytes_per_pixel; i++) + *dst_ptr++ = *src_ptr++; + } + else + { + row_skip = src_width * bytes_per_pixel; - /* scale image down by scaling factor 'zoom_factor' */ - for (y = 0; y < src_height; y += zoom_factor, src_ptr += row_skip) - for (x = 0; x < src_width; x += zoom_factor, src_ptr += col_skip) - for (i = 0; i < bytes_per_pixel; i++) - *dst_ptr++ = *src_ptr++; +#if 0 + printf("::: %d, %d -> %d, %d [%d / %d]\n[%ld -> %ld (%ld)] [%ld -> %ld (%ld)]\n", + src_width, src_height, + dst_width, dst_height, + zoom_factor, bytes_per_pixel, + src_ptr, + src_ptr + src_width * src_height * bytes_per_pixel, + src_width * src_height * bytes_per_pixel, + dst_ptr, + dst_ptr + dst_width * dst_height * bytes_per_pixel, + dst_width * dst_height * bytes_per_pixel); + + printf("A\n"); + + for (i = 0; i < src_width * src_height * bytes_per_pixel; + i++) + { + byte x = *(byte *)(src_ptr + i); + + printf("::: %d ...\n", i); + + x = x * 1; + } + + printf("B\n"); +#endif + + /* scale image up by scaling factor 'zoom_factor' */ + for (y = 0; y < src_height; y++) + { + for (yy = 0; yy < zoom_factor; yy++) + { + if (yy > 0) + src_ptr -= row_skip; + +#if 0 + printf("::: [%d -> %ld / %ld]\n", y, src_ptr, dst_ptr); +#endif + + for (x = 0; x < src_width; x++) + { + for (xx = 0; xx < zoom_factor; xx++) + for (i = 0; i < bytes_per_pixel; i++) +#if 1 + *dst_ptr++ = *(src_ptr + i); +#else + *dst_ptr++ = 0; +#endif + + src_ptr += i; + } + } + } + } /* copy scaled image to destination pixmap */ XPutImage(display, dst_pixmap, gc, dst_ximage, 0, 0, 0, 0, dst_width, dst_height); /* free temporary images */ - XDestroyImage(src_ximage); - XDestroyImage(dst_ximage); + X11DestroyImage(src_ximage); + X11DestroyImage(dst_ximage); } void freeXImage(Image *image, XImageInfo *ximageinfo) @@ -845,7 +990,7 @@ struct PropertyMapping *getImageListPropertyMapping() } void InitImageList(struct ConfigInfo *config_list, int num_file_list_entries, - struct ConfigInfo *config_suffix_list, + struct ConfigTypeInfo *config_suffix_list, char **base_prefixes, char **ext1_suffixes, char **ext2_suffixes, char **ext3_suffixes, char **ignore_tokens)