X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fimage.c;h=cfd42ace044d963f89bacc1f2d5efbad8134125e;hb=2f9311c5cfa019e40c127df71e25659b641986d3;hp=f82a981b301b6688060981a5deb342e08bc62b22;hpb=ab0879a8bcb3e816912bc89b8e21c22cc2a4c0c2;p=rocksndiamonds.git diff --git a/src/image.c b/src/image.c index f82a981b..cfd42ace 100644 --- a/src/image.c +++ b/src/image.c @@ -14,6 +14,18 @@ #include "image.h" #include "misc.h" + +#ifdef DEBUG + +#define DEBUG_TIMING + +#endif + +#ifdef DEBUG_TIMING + long count1, count2; +#endif + + /* extra colors to try allocating in private color maps to minimise flashing */ #define NOFLASH_COLORS 256 @@ -28,9 +40,14 @@ static void Image_to_Mask(Image *image) src_ptr = image->data; dst_ptr = image->data_mask; + /* 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; yheight; y++) { - bitmask = 0x80; /* start with leftmost bit in the byte */ + bitmask = 0x01; /* start with leftmost bit in the byte */ dst_ptr2 = dst_ptr; /* start with leftmost byte in the row */ for (x=0; xwidth; x++) @@ -38,9 +55,9 @@ static void Image_to_Mask(Image *image) 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? */ + if ((bitmask <<= 1) == 0) /* bit at rightmost byte position reached? */ { - bitmask = 0x80; /* start again with leftmost bit position */ + bitmask = 0x01; /* start again with leftmost bit position */ dst_ptr2++; /* continue with next byte in image mask */ } } @@ -50,48 +67,33 @@ static void Image_to_Mask(Image *image) } static boolean XImage_to_Pixmap(Display *display, Window parent, - XImageInfo *ximageinfo) + XImageInfo *ximageinfo, Image *image) { - XGCValues gcv; - - ximageinfo->pixmap = - XCreatePixmap(display, parent, - ximageinfo->ximage->width, - ximageinfo->ximage->height, - ximageinfo->depth); - - ximageinfo->pixmap_mask = - XCreatePixmap(display, parent, - ximageinfo->ximage->width, - ximageinfo->ximage->height, - 1); + ximageinfo->pixmap = XCreatePixmap(display, parent, + ximageinfo->ximage->width, + ximageinfo->ximage->height, + ximageinfo->depth); /* build and cache the GC */ if (!ximageinfo->gc) { - gcv.function = GXcopy; - ximageinfo->gc = - XCreateGC(ximageinfo->display, ximageinfo->pixmap, - GCFunction, &gcv); - } + XGCValues gcv; - if (!ximageinfo->gc_mask) - { gcv.function = GXcopy; - gcv.foreground = ximageinfo->foreground; - gcv.background = ximageinfo->background; - ximageinfo->gc_mask = - XCreateGC(ximageinfo->display, ximageinfo->pixmap_mask, - GCFunction | GCForeground | GCBackground, &gcv); + ximageinfo->gc = XCreateGC(ximageinfo->display, ximageinfo->pixmap, + GCFunction, &gcv); } XPutImage(ximageinfo->display, ximageinfo->pixmap, ximageinfo->gc, ximageinfo->ximage, 0, 0, 0, 0, ximageinfo->ximage->width, ximageinfo->ximage->height); - XPutImage(ximageinfo->display, ximageinfo->pixmap_mask, ximageinfo->gc_mask, - ximageinfo->ximage_mask, 0, 0, 0, 0, - ximageinfo->ximage->width, ximageinfo->ximage->height); + + ximageinfo->pixmap_mask = XCreateBitmapFromData(ximageinfo->display, + parent, + image->data_mask, + image->width, + image->height); return (ximageinfo->pixmap != None && ximageinfo->pixmap_mask != None); } @@ -133,18 +135,14 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, static Colormap global_cmap = 0; static Pixel *global_cmap_index; static int num_cmap_entries, free_cmap_entries; - static private_cmap = FALSE; + static boolean private_cmap = FALSE; Pixel *redvalue, *greenvalue, *bluevalue; - unsigned int a, c=0, x, y, linelen, dpixlen, dbits; + unsigned int a, c = 0, x, y, dpixlen, dbits; XColor xcolor; - XGCValues gcv; XImageInfo *ximageinfo; /* for building image */ - byte *data, *destptr, *srcptr; - - /* for building image mask */ - byte *data_mask; + byte *data, *src_ptr, *dst_ptr; if (!global_cmap) { @@ -167,11 +165,8 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, ximageinfo->drawable = None; ximageinfo->index = NULL; ximageinfo->rootimage = FALSE; - ximageinfo->foreground = ximageinfo->background= 0; ximageinfo->gc = NULL; - ximageinfo->gc_mask = NULL; ximageinfo->ximage = NULL; - ximageinfo->ximage_mask = NULL; switch (visual->class) { @@ -193,8 +188,7 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, retry_direct: /* tag we hit if a DirectColor allocation fails on * default colormap */ - /* calculate number of distinct colors in each band - */ + /* calculate number of distinct colors in each band */ redcolors = greencolors = bluecolors = 1; for (pixval=1; pixval; pixval <<= 1) @@ -207,15 +201,12 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, bluecolors <<= 1; } - /* sanity check - */ + /* sanity check */ - if ((redcolors > visual->map_entries) || - (greencolors > visual->map_entries) || - (bluecolors > visual->map_entries)) - { - fprintf(stderr, "Warning: inconsistency in color information (this may be ugly)\n"); - } + if (redcolors > visual->map_entries || + greencolors > visual->map_entries || + bluecolors > visual->map_entries) + Error(ERR_WARN, "inconsistency in color information"); redstep = 256 / redcolors; greenstep = 256 / greencolors; @@ -405,11 +396,18 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, break; default: - printf("Sorry, only DirectColor, TrueColor and PseudoColor supported\n"); - exit(0); + Error(ERR_RETURN, "display type not supported"); + Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed"); break; } +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" CONVERTING IMAGE TO XIMAGE (IMAGE COLORMAP) IN %.2f SECONDS\n", + (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + /* CREATE IMAGE ITSELF */ /* modify image data to match visual and colormap */ @@ -420,12 +418,12 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, NULL, image->width, image->height, 8, image->width * dpixlen); - data = (byte *)checked_malloc(image->width * image->height * dpixlen); + data = checked_malloc(image->width * image->height * dpixlen); ximageinfo->depth = ddepth; ximageinfo->ximage->data = (char *)data; ximageinfo->ximage->byte_order = MSBFirst; - srcptr = image->data; - destptr = data; + src_ptr = image->data; + dst_ptr = data; switch (visual->class) { @@ -438,32 +436,25 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, { for (x=0; xwidth; x++) { - pixval = memToVal(srcptr, 1); + pixval = *src_ptr++; pixval = redvalue[image->rgb.red[pixval] >> 8] | greenvalue[image->rgb.green[pixval] >> 8] | bluevalue[image->rgb.blue[pixval] >> 8]; - valToMem(pixval, destptr, dpixlen); - srcptr += 1; - destptr += dpixlen; + valToMem(pixval, dst_ptr, dpixlen); + dst_ptr += dpixlen; } } break; } - default: + case PseudoColor: { - if (dpixlen == 1) /* most common */ + if (dpixlen == 1) /* most common */ { for (y=0; yheight; y++) - { for (x=0; xwidth; x++) - { - *destptr = ximageinfo->index[c + *srcptr]; - srcptr++; - destptr++; - } - } + *dst_ptr++ = ximageinfo->index[c + *src_ptr++]; } else /* less common */ { @@ -471,81 +462,20 @@ XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, { for (x=0; xwidth; x++) { - register unsigned long temp; - temp = memToVal(srcptr, 1); - valToMem(ximageinfo->index[c + temp], destptr, dpixlen); - srcptr += 1; - destptr += dpixlen; + valToMem(ximageinfo->index[c + *src_ptr++], dst_ptr, dpixlen); + dst_ptr += dpixlen; } } } + break; } - } - - /* NOW CREATE IMAGE MASK */ - /* we copy the data to be more consistent */ - - linelen = ((image->width + 7) / 8); - data_mask = checked_malloc(linelen * image->height); - memcpy((char *)data_mask, (char *)image->data_mask, - linelen * image->height); - - gcv.function = GXcopy; - ximageinfo->ximage_mask = - XCreateImage(display, visual, 1, XYBitmap, 0, (char *)data_mask, - image->width, image->height, 8, linelen); - - - /* use this if you want to use the bitmap as a mask */ - /* - ximageinfo->depth = image->depth; - */ - - if (visual->class == DirectColor || visual->class == TrueColor) - { - Pixel pixval; - dbits = bitsPerPixelAtDepth(display, screen, ddepth); - dpixlen = (dbits + 7) / 8; - pixval = - redvalue[65535 >> 8] | - greenvalue[65535 >> 8] | - bluevalue[65535 >> 8]; - /* - redvalue[image->rgb.red[0] >> 8] | - greenvalue[image->rgb.green[0] >> 8] | - bluevalue[image->rgb.blue[0] >> 8]; - */ - ximageinfo->background = pixval; - pixval = - redvalue[0 >> 8] | - greenvalue[0 >> 8] | - bluevalue[0 >> 8]; - /* - redvalue[image->rgb.red[1] >> 8] | - greenvalue[image->rgb.green[1] >> 8] | - bluevalue[image->rgb.blue[1] >> 8]; - */ - ximageinfo->foreground = pixval; - } - else /* Not Direct or True Color */ - { - ximageinfo->foreground = BlackPixel(display, screen); - ximageinfo->background = WhitePixel(display, screen); + default: + Error(ERR_RETURN, "display type not supported"); + Error(ERR_EXIT, "DirectColor, TrueColor or PseudoColor display needed"); + break; } - /* - ximageinfo->foreground = BlackPixel(display, screen); - ximageinfo->background = WhitePixel(display, screen); - */ - - ximageinfo->foreground = WhitePixel(display, screen); - ximageinfo->background = BlackPixel(display, screen); - - - ximageinfo->ximage_mask->bitmap_bit_order = MSBFirst; - ximageinfo->ximage_mask->byte_order = MSBFirst; - if (redvalue) { free((byte *)redvalue); @@ -613,12 +543,6 @@ void freeImage(Image *image) /* ------------------------------------------------------------------------- */ -#ifdef DEBUG - -#define DEBUG_TIMING - -#endif - int Read_PCX_to_Pixmaps(Display *display, Window window, char *filename, Pixmap *pixmap, Pixmap *pixmap_mask) @@ -636,7 +560,6 @@ int Read_PCX_to_Pixmaps(Display *display, Window window, char *filename, unsigned int depth; #ifdef DEBUG_TIMING - long count1, count2; count1 = Counter(); #endif @@ -682,7 +605,7 @@ int Read_PCX_to_Pixmaps(Display *display, Window window, char *filename, XSetWindowColormap(display, window, ximageinfo->cmap); /* convert XImage to Pixmap */ - if (!(XImage_to_Pixmap(display, window, ximageinfo))) + if (!(XImage_to_Pixmap(display, window, ximageinfo, image))) { fprintf(stderr, "Cannot convert XImage to Pixmap.\n"); exit(1);