X-Git-Url: https://git.artsoft.org/?p=rocksndiamonds.git;a=blobdiff_plain;f=src%2Fimage.c;h=d73c9a5a4afdd112d5f7d8fee937c80e306dbdf8;hp=85861dcc56ed6072c0ef3e6884b8eedcfa904530;hb=cfd77b3698baacb01dff3853c96d0be117db1d30;hpb=333896e44bae70515b2d82877dd14e7e28338977 diff --git a/src/image.c b/src/image.c index 85861dcc..d73c9a5a 100644 --- a/src/image.c +++ b/src/image.c @@ -1,5 +1,15 @@ - -/* image.c */ +/*********************************************************** +* Rocks'n'Diamonds -- McDuffin Strikes Back! * +*----------------------------------------------------------* +* (c) 1995-98 Artsoft Entertainment * +* Holger Schemel * +* Oststrasse 11a * +* 33604 Bielefeld * +* phone: ++49 +521 290471 * +* email: aeglos@valinor.owl.de * +*----------------------------------------------------------* +* image.c * +***********************************************************/ #include "image.h" #include "misc.h" @@ -32,12 +42,12 @@ Image *monochrome(Image *cimage) sp = cimage->data; dp = image->data; - for (y= 0; y < cimage->height; y++) + for (y=0; yheight; y++) { - for (x= 0; x < cimage->width; x++) + for (x=0; xwidth; x++) { dp2 = dp + (x / 8); /* dp + x/8 */ - color= memToVal(sp, spl); + color = memToVal(sp, spl); if (cimage->rgb.red[color] > 0x0000 || cimage->rgb.green[color] > 0x0000 || @@ -46,7 +56,7 @@ Image *monochrome(Image *cimage) else bitmap_pixel = 0x80; - *dp2 |= bitmap_pixel >> ( x % 8); + *dp2 |= bitmap_pixel >> (x % 8); sp += spl; } @@ -66,21 +76,21 @@ static unsigned int *buildIndex(unsigned int width, if (!zoom) { - fzoom= 100.0; - *rwidth= width; + fzoom = 100.0; + *rwidth = width; } else { - fzoom= (float)zoom / 100.0; - *rwidth= (unsigned int)(fzoom * width + 0.5); + fzoom = (float)zoom / 100.0; + *rwidth = (unsigned int)(fzoom * width + 0.5); } - index= (unsigned int *)checked_malloc(sizeof(unsigned int) * *rwidth); - for (a= 0; a < *rwidth; a++) + index = (unsigned int *)checked_malloc(sizeof(unsigned int) * *rwidth); + for (a=0; a<*rwidth; a++) { if (zoom) - *(index + a)= (unsigned int)((float)a / fzoom + 0.5); + *(index + a) = (unsigned int)((float)a / fzoom + 0.5); else - *(index + a)= a; + *(index + a) = a; } return(index); } @@ -99,7 +109,7 @@ Image *zoom(Image *oimage, unsigned int xzoom, unsigned int yzoom) byte srcmask, destmask, bit; Pixel value; - if ((!xzoom || xzoom==100) && (!yzoom || yzoom==100)) + if ((!xzoom || xzoom == 100) && (!yzoom || yzoom == 100)) return(oimage); if (!xzoom) @@ -113,37 +123,37 @@ Image *zoom(Image *oimage, unsigned int xzoom, unsigned int yzoom) xzoom, yzoom); fflush(stdout); - xindex= buildIndex(oimage->width, xzoom, &xwidth); - yindex= buildIndex(oimage->height, yzoom, &ywidth); + xindex = buildIndex(oimage->width, xzoom, &xwidth); + yindex = buildIndex(oimage->height, yzoom, &ywidth); switch (oimage->type) { case IBITMAP: - image= newBitImage(xwidth, ywidth); - for (x= 0; x < oimage->rgb.used; x++) + image = newBitImage(xwidth, ywidth); + for (x=0; xrgb.used; x++) { - *(image->rgb.red + x)= *(oimage->rgb.red + x); - *(image->rgb.green + x)= *(oimage->rgb.green + x); - *(image->rgb.blue + x)= *(oimage->rgb.blue + x); + *(image->rgb.red + x) = *(oimage->rgb.red + x); + *(image->rgb.green + x) = *(oimage->rgb.green + x); + *(image->rgb.blue + x) = *(oimage->rgb.blue + x); } - image->rgb.used= oimage->rgb.used; - destline= image->data; - destlinelen= (xwidth / 8) + (xwidth % 8 ? 1 : 0); - srcline= oimage->data; - srclinelen= (oimage->width / 8) + (oimage->width % 8 ? 1 : 0); - for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) + image->rgb.used = oimage->rgb.used; + destline = image->data; + destlinelen = (xwidth / 8) + (xwidth % 8 ? 1 : 0); + srcline = oimage->data; + srclinelen = (oimage->width / 8) + (oimage->width % 8 ? 1 : 0); + for (y=0, ysrc=*(yindex + y); y>= 1)) { - srcmask= 0x80; + srcmask = 0x80; srcptr++; } } while (xsrc != *(xindex + x)); - bit= srcmask & *srcptr; + bit = srcmask & *srcptr; } if (bit) *destptr |= destmask; if (!(destmask >>= 1)) { - destmask= 0x80; + destmask = 0x80; destptr++; } } @@ -173,20 +183,20 @@ Image *zoom(Image *oimage, unsigned int xzoom, unsigned int yzoom) break; case IRGB: - image= newRGBImage(xwidth, ywidth, oimage->depth); - for (x= 0; x < oimage->rgb.used; x++) + image = newRGBImage(xwidth, ywidth, oimage->depth); + for (x=0; xrgb.used; x++) { - *(image->rgb.red + x)= *(oimage->rgb.red + x); - *(image->rgb.green + x)= *(oimage->rgb.green + x); - *(image->rgb.blue + x)= *(oimage->rgb.blue + x); + *(image->rgb.red + x) = *(oimage->rgb.red + x); + *(image->rgb.green + x) = *(oimage->rgb.green + x); + *(image->rgb.blue + x) = *(oimage->rgb.blue + x); } - image->rgb.used= oimage->rgb.used; + image->rgb.used = oimage->rgb.used; - pixlen= oimage->pixlen; - destptr= image->data; - srcline= oimage->data; - srclinelen= oimage->width * pixlen; - for (y= 0, ysrc= *(yindex + y); y < ywidth; y++) + pixlen = oimage->pixlen; + destptr = image->data; + srcline = oimage->data; + srclinelen = oimage->width * pixlen; + for (y=0, ysrc=*(yindex + y); ypixlen); - for (x=0, xsrc= *(xindex + x); xrgb.compressed= TRUE; /* don't do it again */ + image->rgb.compressed = TRUE; /* don't do it again */ } -Pixmap XImage_to_Pixmap(Display *disp, Window parent, XImageInfo *ximageinfo) +Pixmap XImage_to_Pixmap(Display *display, Window parent, + XImageInfo *ximageinfo) { Pixmap pixmap; - pixmap = XCreatePixmap(disp, parent, + pixmap = XCreatePixmap(display, parent, ximageinfo->ximage->width, ximageinfo->ximage->height, ximageinfo->depth); @@ -372,13 +383,13 @@ Pixmap XImage_to_Pixmap(Display *disp, Window parent, XImageInfo *ximageinfo) * by looking at the structure ourselves. */ -static unsigned int bitsPerPixelAtDepth(Display *disp, int scrn, +static unsigned int bitsPerPixelAtDepth(Display *display, int screen, unsigned int depth) { XPixmapFormatValues *xf; int nxf, a; - xf = XListPixmapFormats(disp, &nxf); + xf = XListPixmapFormats(display, &nxf); for (a = 0; a < nxf; a++) { if (xf[a].depth == depth) @@ -398,7 +409,7 @@ static unsigned int bitsPerPixelAtDepth(Display *disp, int scrn, exit(1); } -XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, +XImageInfo *Image_to_XImage(Display *display, int screen, Visual *visual, unsigned int ddepth, Image *image) { static XColor xcolor_private[NOFLASH_COLORS]; @@ -415,11 +426,11 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, if (!global_cmap) { - if (visual == DefaultVisual(disp, scrn)) - global_cmap = DefaultColormap(disp, scrn); + if (visual == DefaultVisual(display, screen)) + global_cmap = DefaultColormap(display, screen); else { - global_cmap = XCreateColormap(disp, RootWindow(disp, scrn), + global_cmap = XCreateColormap(display, RootWindow(display, screen), visual, AllocNone); private_cmap = TRUE; } @@ -428,8 +439,8 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, xcolor.flags = DoRed | DoGreen | DoBlue; redvalue = greenvalue = bluevalue = NULL; ximageinfo = (XImageInfo *)checked_malloc(sizeof(XImageInfo)); - ximageinfo->disp = disp; - ximageinfo->scrn = scrn; + ximageinfo->display = display; + ximageinfo->screen = screen; ximageinfo->depth = 0; ximageinfo->drawable = None; ximageinfo->index = NULL; @@ -499,16 +510,16 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, xcolor.red = (redtop - 1) << 8; xcolor.green = (greentop - 1) << 8; xcolor.blue = (bluetop - 1) << 8; - if (!XAllocColor(disp, ximageinfo->cmap, &xcolor)) + if (!XAllocColor(display, ximageinfo->cmap, &xcolor)) { /* if an allocation fails for a DirectColor default visual then * we should create a private colormap and try again. */ if ((visual->class == DirectColor) && - (visual == DefaultVisual(disp, scrn))) + (visual == DefaultVisual(display, screen))) { - global_cmap = XCopyColormapAndFree(disp, global_cmap); + global_cmap = XCopyColormapAndFree(display, global_cmap); ximageinfo->cmap = global_cmap; private_cmap = TRUE; @@ -557,7 +568,7 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, xcolor.blue = *(image->rgb.blue + a); /* look if this color already exists in our colormap */ - if (!XAllocColor(disp, ximageinfo->cmap, &xcolor)) + if (!XAllocColor(display, ximageinfo->cmap, &xcolor)) { if (!private_cmap) { @@ -568,7 +579,7 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, /* we just filled up the default colormap -- get a private one which contains all already allocated colors */ - global_cmap = XCopyColormapAndFree(disp, global_cmap); + global_cmap = XCopyColormapAndFree(display, global_cmap); ximageinfo->cmap = global_cmap; private_cmap = TRUE; @@ -576,7 +587,7 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, global_cmap_index = (Pixel *)checked_malloc(sizeof(Pixel) * NOFLASH_COLORS); for (i=0; icmap, &xcolor); + XStoreColor(display, ximageinfo->cmap, &xcolor); free_cmap_entries--; } @@ -693,8 +704,9 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, memcpy((char *)data, (char *)image->data, linelen * image->height); gcv.function= GXcopy; - ximageinfo->ximage= XCreateImage(disp, visual, 1, XYBitmap, - 0, (char *)data, image->width, image->height, + ximageinfo->ximage= XCreateImage(display, visual, 1, XYBitmap, + 0, (char *)data, image->width, + image->height, 8, linelen); /* use this if you want to use the bitmap as a mask */ @@ -703,7 +715,7 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, if(visual->class == DirectColor || visual->class == TrueColor) { Pixel pixval; - dbits= bitsPerPixelAtDepth(disp, scrn, ddepth); + dbits= bitsPerPixelAtDepth(display, screen, ddepth); dpixlen= (dbits + 7) / 8; pixval= redvalue[image->rgb.red[0] >> 8] | greenvalue[image->rgb.green[0] >> 8] | @@ -716,8 +728,8 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, } else /* Not Direct or True Color */ { - ximageinfo->foreground = BlackPixel(disp,scrn); - ximageinfo->background = WhitePixel(disp,scrn); + ximageinfo->foreground = BlackPixel(display, screen); + ximageinfo->background = WhitePixel(display, screen); } ximageinfo->ximage->bitmap_bit_order= MSBFirst; ximageinfo->ximage->byte_order= MSBFirst; @@ -732,10 +744,10 @@ XImageInfo *Image_to_XImage(Display *disp, int scrn, Visual *visual, byte *data, *destptr, *srcptr; - dbits = bitsPerPixelAtDepth(disp, scrn, ddepth); /* bits per pixel */ + dbits = bitsPerPixelAtDepth(display, screen, ddepth);/* bits per pixel */ dpixlen = (dbits + 7) / 8; /* bytes per pixel */ - ximageinfo->ximage = XCreateImage(disp, visual, ddepth, ZPixmap, 0, + ximageinfo->ximage = XCreateImage(display, visual, ddepth, ZPixmap, 0, NULL, image->width, image->height, 8, image->width * dpixlen); @@ -837,16 +849,16 @@ void XImage_to_Drawable(XImageInfo *ximageinfo, { gcv.foreground = ximageinfo->foreground; gcv.background = ximageinfo->background; - ximageinfo->gc = XCreateGC(ximageinfo->disp, ximageinfo->drawable, + ximageinfo->gc = XCreateGC(ximageinfo->display, ximageinfo->drawable, GCFunction | GCForeground | GCBackground, &gcv); } else - ximageinfo->gc = XCreateGC(ximageinfo->disp, ximageinfo->drawable, + ximageinfo->gc = XCreateGC(ximageinfo->display, ximageinfo->drawable, GCFunction, &gcv); } - XPutImage(ximageinfo->disp, ximageinfo->drawable, ximageinfo->gc, + XPutImage(ximageinfo->display, ximageinfo->drawable, ximageinfo->gc, ximageinfo->ximage, src_x, src_y, dst_x, dst_y, w, h); } @@ -858,12 +870,12 @@ void freeXImage(Image *image, XImageInfo *ximageinfo) if (ximageinfo->index != NULL) /* if we allocated colors */ { if (ximageinfo->no > 0 && !ximageinfo->rootimage) /* don't free root colors */ - XFreeColors(ximageinfo->disp, ximageinfo->cmap, ximageinfo->index, + XFreeColors(ximageinfo->display, ximageinfo->cmap, ximageinfo->index, ximageinfo->no, 0); free(ximageinfo->index); } if (ximageinfo->gc) - XFreeGC(ximageinfo->disp, ximageinfo->gc); + XFreeGC(ximageinfo->display, ximageinfo->gc); free((byte *)ximageinfo->ximage->data); ximageinfo->ximage->data= NULL; XDestroyImage(ximageinfo->ximage); @@ -972,3 +984,134 @@ void freeImage(Image *image) freeImageData(image); free((byte *)image); } + +/* ------------------------------------------------------------------------- */ + + +#ifdef DEBUG +/* +#define DEBUG_TIMING +*/ +#endif + + +int Read_PCX_to_Pixmaps(Display *display, Window window, char *filename, + Pixmap *pixmap, Pixmap *pixmap_mask) +{ + Image *image, *image_mask; + XImageInfo *ximageinfo, *ximageinfo_mask; + int screen; + Visual *visual; + unsigned int depth; + +#ifdef DEBUG_TIMING + long count1, count2; + count1 = Counter(); +#endif + + /* load GIF file */ + if (!(image = Read_PCX_to_Image(filename))) + { + printf("Loading GIF image failed -- maybe no GIF...\n"); + exit(1); + } + +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" LOADING '%s' IN %.2f SECONDS\n", + filename, (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + + if (image->depth > 8) + { + printf("Sorry, GIFs with more than 256 colors are not supported.\n"); + exit(1); + } + + /* minimize colormap */ + compress(image); + +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" COMPRESSING IMAGE COLORMAP IN %.2f SECONDS\n", + (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + + screen = DefaultScreen(display); + visual = DefaultVisual(display, screen); + depth = DefaultDepth(display, screen); + + /* convert internal image structure to X11 XImage */ + if (!(ximageinfo = Image_to_XImage(display, screen, visual, depth, image))) + { + fprintf(stderr, "Cannot convert Image to XImage.\n"); + exit(1); + } + +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" CONVERTING IMAGE TO XIMAGE IN %.2f SECONDS\n", + (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + + if (ximageinfo->cmap != DefaultColormap(display, screen)) + XSetWindowColormap(display, window, ximageinfo->cmap); + + /* convert XImage to Pixmap */ + if ((*pixmap = XImage_to_Pixmap(display, window, ximageinfo)) == None) + { + fprintf(stderr, "Cannot convert XImage to Pixmap.\n"); + exit(1); + } + +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" CONVERTING IMAGE TO PIXMAP IN %.2f SECONDS\n", + (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + + /* create mono image for masking */ + image_mask = monochrome(image); + +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" CONVERTING IMAGE TO MASK IN %.2f SECONDS\n", + (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + + /* convert internal image structure to X11 XImage */ + if (!(ximageinfo_mask = Image_to_XImage(display, screen, visual, depth, + image_mask))) + { + fprintf(stderr, "Cannot convert Image to XImage.\n"); + exit(1); + } + +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" CONVERTING MASK TO XIMAGE IN %.2f SECONDS\n", + (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + + /* convert XImage to Pixmap */ + if ((*pixmap_mask = XImage_to_Pixmap(display, window, ximageinfo_mask)) == None) + { + fprintf(stderr, "Cannot convert XImage to Pixmap.\n"); + exit(1); + } + +#ifdef DEBUG_TIMING + count2 = Counter(); + printf(" CONVERTING MASK TO PIXMAP IN %.2f SECONDS\n", + (float)(count2-count1)/1000.0); + count1 = Counter(); +#endif + + return(GIF_Success); +}