X-Git-Url: https://git.artsoft.org/?a=blobdiff_plain;f=src%2Fsend.c;h=f0aeee1a6ea0eb6127ad5a2ee746aa38da849805;hb=ab0879a8bcb3e816912bc89b8e21c22cc2a4c0c2;hp=e8f0ffd99879a79deb3d372e513cf2662d72bb65;hpb=4b0f1eb4220d2dbe4cffb288f745661b32c96a5b;p=rocksndiamonds.git diff --git a/src/send.c b/src/send.c index e8f0ffd9..f0aeee1a 100644 --- a/src/send.c +++ b/src/send.c @@ -1,8 +1,5 @@ -/* send.c - * - * send an Image to an X pixmap - */ +/* send.c */ #include "xli.h" @@ -22,8 +19,10 @@ Image *monochrome(Image *cimage) if (BITMAPP(cimage)) return(NULL); + /* printf(" Converting to monochrome..."); fflush(stdout); + */ image= newBitImage(cimage->width, cimage->height); if (cimage->title) @@ -59,7 +58,9 @@ Image *monochrome(Image *cimage) dp += dll; /* next row */ } + /* printf("done\n"); + */ return(image); } @@ -230,8 +231,8 @@ Image *zoom(Image *oimage, unsigned int xzoom, unsigned int yzoom) } image->title = dupString(oimage->title); - lfree((byte *)xindex); - lfree((byte *)yindex); + free((byte *)xindex); + free((byte *)yindex); printf("done\n"); @@ -254,8 +255,10 @@ void compress(Image *image) if (!RGBP(image) || image->rgb.compressed) return; + /* printf(" Compressing colormap..."); fflush(stdout); + */ used = (unsigned char *)lcalloc(sizeof(unsigned char) * depthToColors(image->depth)); dmask = (1 << image->depth) -1; /* Mask any illegal bits for that depth */ @@ -332,9 +335,10 @@ void compress(Image *image) image->rgb.used = next_index; /* clean up */ - lfree(map); - lfree(used); + free(map); + free(used); + /* if (badcount) printf("%d out-of-range pixels, ", badcount); @@ -349,6 +353,7 @@ void compress(Image *image) printf("%d unique color%s\n", next_index, (next_index == 1 ? "" : "s")); } + */ image->rgb.compressed= TRUE; /* don't do it again */ } @@ -413,71 +418,45 @@ static unsigned int bitsPerPixelAtDepth(Display *disp, int scrn, exit(1); } -/* - visual: visual to use - ddepth: depth of the visual to use -*/ -XImageInfo *imageToXImage(Display *disp, - int scrn, - Visual *visual, - unsigned int ddepth, - Image *image) +XImageInfo *imageToXImage(Display *disp, int scrn, Visual *visual, + unsigned int ddepth, Image *image) { - Pixel *redvalue, *greenvalue, *bluevalue; - unsigned int a, c=0, x, y, linelen, dpixlen, dbits; - XColor xcolor; - XGCValues gcv; - XImageInfo *ximageinfo; - Image *orig_image; - - static Colormap our_default_cmap = 0; - static Pixel *our_default_index; - static int free_cmap_entries, max_cmap_entries; - int use_cmap_entry; - - if (!our_default_cmap) - { -#if 0 - our_default_cmap = DefaultColormap(disp, scrn); -#endif - - our_default_cmap = XCreateColormap(disp, RootWindow(disp, scrn), - visual, AllocNone); - our_default_index = (Pixel *)lmalloc(sizeof(Pixel) * NOFLASH_COLORS); - - for (a=0; adisp= disp; - ximageinfo->scrn= scrn; - ximageinfo->depth= 0; - ximageinfo->drawable= None; - ximageinfo->index= NULL; - ximageinfo->rootimage= FALSE; /* assume not */ - ximageinfo->foreground= ximageinfo->background= 0; - ximageinfo->gc= NULL; - ximageinfo->ximage= NULL; - - /* do color allocation - */ + xcolor.flags = DoRed | DoGreen | DoBlue; + redvalue = greenvalue = bluevalue = NULL; + ximageinfo = (XImageInfo *)lmalloc(sizeof(XImageInfo)); + ximageinfo->disp = disp; + ximageinfo->scrn = scrn; + ximageinfo->depth = 0; + ximageinfo->drawable = None; + ximageinfo->index = NULL; + ximageinfo->rootimage = FALSE; + ximageinfo->foreground = ximageinfo->background= 0; + ximageinfo->gc = NULL; + ximageinfo->ximage = NULL; switch (visual->class) { @@ -490,19 +469,11 @@ XImageInfo *imageToXImage(Display *disp, unsigned int redbottom, greenbottom, bluebottom; unsigned int redtop, greentop, bluetop; - redvalue= (Pixel *)lmalloc(sizeof(Pixel) * 256); - greenvalue= (Pixel *)lmalloc(sizeof(Pixel) * 256); - bluevalue= (Pixel *)lmalloc(sizeof(Pixel) * 256); + redvalue = (Pixel *)lmalloc(sizeof(Pixel) * 256); + greenvalue = (Pixel *)lmalloc(sizeof(Pixel) * 256); + bluevalue = (Pixel *)lmalloc(sizeof(Pixel) * 256); -#if 1 - if (visual == DefaultVisual(disp, scrn)) - ximageinfo->cmap= DefaultColormap(disp, scrn); - else - ximageinfo->cmap= XCreateColormap(disp, RootWindow(disp, scrn), - visual, AllocNone); -#else - ximageinfo->cmap = our_default_cmap; -#endif + ximageinfo->cmap = global_cmap; retry_direct: /* tag we hit if a DirectColor allocation fails on * default colormap */ @@ -510,8 +481,8 @@ XImageInfo *imageToXImage(Display *disp, /* calculate number of distinct colors in each band */ - redcolors= greencolors= bluecolors= 1; - for (pixval= 1; pixval; pixval <<= 1) + redcolors = greencolors = bluecolors = 1; + for (pixval=1; pixval; pixval <<= 1) { if (pixval & visual->red_mask) redcolors <<= 1; @@ -536,19 +507,19 @@ XImageInfo *imageToXImage(Display *disp, bluestep = 256 / bluecolors; redbottom = greenbottom = bluebottom = 0; redtop = greentop = bluetop = 0; - for (a= 0; a < visual->map_entries; a++) + for (a=0; amap_entries; a++) { if (redbottom < 256) - redtop= redbottom + redstep; + redtop = redbottom + redstep; if (greenbottom < 256) - greentop= greenbottom + greenstep; + greentop = greenbottom + greenstep; if (bluebottom < 256) - bluetop= bluebottom + bluestep; + bluetop = bluebottom + bluestep; - xcolor.red= (redtop - 1) << 8; - xcolor.green= (greentop - 1) << 8; - xcolor.blue= (bluetop - 1) << 8; - if (! XAllocColor(disp, ximageinfo->cmap, &xcolor)) + xcolor.red = (redtop - 1) << 8; + xcolor.green = (greentop - 1) << 8; + xcolor.blue = (bluetop - 1) << 8; + if (!XAllocColor(disp, ximageinfo->cmap, &xcolor)) { /* if an allocation fails for a DirectColor default visual then * we should create a private colormap and try again. @@ -557,13 +528,10 @@ XImageInfo *imageToXImage(Display *disp, if ((visual->class == DirectColor) && (visual == DefaultVisual(disp, scrn))) { -#if 1 - ximageinfo->cmap = XCreateColormap(disp, RootWindow(disp, scrn), - visual, AllocNone); -#else - our_default_cmap = XCopyColormapAndFree(disp, our_default_cmap); - ximageinfo->cmap = our_default_cmap; -#endif + global_cmap = XCopyColormapAndFree(disp, global_cmap); + ximageinfo->cmap = global_cmap; + private_cmap = TRUE; + goto retry_direct; } @@ -571,10 +539,10 @@ XImageInfo *imageToXImage(Display *disp, */ fprintf(stderr, "imageToXImage: XAllocColor failed on a TrueColor/Directcolor visual\n"); - lfree((byte *)redvalue); - lfree((byte *)greenvalue); - lfree((byte *)bluevalue); - lfree((byte *)ximageinfo); + free((byte *)redvalue); + free((byte *)greenvalue); + free((byte *)bluevalue); + free((byte *)ximageinfo); return(NULL); } @@ -582,77 +550,152 @@ XImageInfo *imageToXImage(Display *disp, */ while ((redbottom < 256) && (redbottom < redtop)) - redvalue[redbottom++]= xcolor.pixel & visual->red_mask; + redvalue[redbottom++] = xcolor.pixel & visual->red_mask; while ((greenbottom < 256) && (greenbottom < greentop)) - greenvalue[greenbottom++]= xcolor.pixel & visual->green_mask; + greenvalue[greenbottom++] = xcolor.pixel & visual->green_mask; while ((bluebottom < 256) && (bluebottom < bluetop)) - bluevalue[bluebottom++]= xcolor.pixel & visual->blue_mask; + bluevalue[bluebottom++] = xcolor.pixel & visual->blue_mask; } + break; } - break; - default: /* Not TrueColor or DirectColor */ + case PseudoColor: - ximageinfo->index= (Pixel *)lmalloc(sizeof(Pixel) * (image->rgb.used+NOFLASH_COLORS)); + ximageinfo->cmap = global_cmap; + ximageinfo->index = (Pixel *)lmalloc(sizeof(Pixel) * image->rgb.used); + + for (a=0; argb.used; a++) + { + XColor xcolor2; + unsigned short mask; + int color_found; + int i; + + xcolor.red = *(image->rgb.red + a); + xcolor.green = *(image->rgb.green + a); + xcolor.blue = *(image->rgb.blue + a); + + /* look if this color already exists in our colormap */ + if (!XAllocColor(disp, ximageinfo->cmap, &xcolor)) + { + if (!private_cmap) + { + /* + printf("switching to private colormap...\n"); + */ + + /* we just filled up the default colormap -- get a private one + which contains all already allocated colors */ + + global_cmap = XCopyColormapAndFree(disp, global_cmap); + ximageinfo->cmap = global_cmap; + private_cmap = TRUE; + + /* allocate the rest of the color cells read/write */ + global_cmap_index = + (Pixel *)lmalloc(sizeof(Pixel) * NOFLASH_COLORS); + for (i=0; icmap = our_default_cmap; + mask = 0xf000; + color_found = FALSE; - /* allocate colors shareable (if we can) - */ + while (!color_found) + { + for (i=num_cmap_entries-1; i>=0; i--) + { + xcolor2.pixel = *(global_cmap_index + i); + xcolor2 = xcolor_private[xcolor2.pixel]; - for (a= 0; a < image->rgb.used; a++) - { - int i; - XColor xcolor2; + if (colorcell_used[xcolor2.pixel]) + continue; - xcolor.red= *(image->rgb.red + a); - xcolor.green= *(image->rgb.green + a); - xcolor.blue= *(image->rgb.blue + a); + if ((xcolor.red & mask) == (xcolor2.red & mask) && + (xcolor.green & mask) == (xcolor2.green & mask) && + (xcolor.blue & mask) == (xcolor2.blue & mask)) + { + /* + printf("replacing color cell %ld with a close color\n", + xcolor2.pixel); + */ + color_found = TRUE; + break; + } + } - for (i=max_cmap_entries-1; i>=free_cmap_entries; i--) - { - xcolor2.pixel = *(our_default_index + i); - XQueryColor(disp, ximageinfo->cmap, &xcolor2); + if (mask == 0x0000) + break; - if ((xcolor.red >> 8) == (xcolor2.red >> 8) && - (xcolor.green >> 8) == (xcolor2.green >> 8) && - (xcolor.blue >> 8) == (xcolor2.blue >> 8)) - break; - } + mask = (mask << 1) & 0xffff; + } - use_cmap_entry = i; + if (!color_found) /* no more free color cells */ + { + printf("Sorry, cannot allocate enough colors!\n"); + exit(0); + } - if (use_cmap_entry < free_cmap_entries) - free_cmap_entries--; + xcolor.pixel = xcolor2.pixel; + xcolor_private[xcolor.pixel] = xcolor; + colorcell_used[xcolor.pixel] = TRUE; + XStoreColor(disp, ximageinfo->cmap, &xcolor); + free_cmap_entries--; + } - if (free_cmap_entries < 0) - { - printf("imageToXImage: too many global colors!\n"); - exit(0); + *(ximageinfo->index + a) = xcolor.pixel; } - xcolor.pixel = use_cmap_entry; - *(ximageinfo->index + a) = xcolor.pixel; - XStoreColor(disp, ximageinfo->cmap, &xcolor); - } - - ximageinfo->no = a; /* number of pixels allocated in default visual */ + /* + printf("still %d free colormap entries\n", free_cmap_entries); + */ - printf("still %d free colormap entries\n", free_cmap_entries); + ximageinfo->no = a; /* number of pixels allocated for this image */ + break; + + default: + printf("Sorry, only DirectColor, TrueColor and PseudoColor supported\n"); + exit(0); + break; } - - /* create an XImage and related colormap based on the image type * we have. */ + /* printf(" Building XImage..."); fflush(stdout); + */ switch (image->type) { @@ -779,17 +822,17 @@ XImageInfo *imageToXImage(Display *disp, } } + /* printf("done\n"); + */ if (redvalue) { - lfree((byte *)redvalue); - lfree((byte *)greenvalue); - lfree((byte *)bluevalue); + free((byte *)redvalue); + free((byte *)greenvalue); + free((byte *)bluevalue); } - if (image != orig_image) - freeImage(image); return(ximageinfo); } @@ -835,13 +878,13 @@ void freeXImage(Image *image, XImageInfo *ximageinfo) { if (ximageinfo->no > 0 && !ximageinfo->rootimage) /* don't free root colors */ XFreeColors(ximageinfo->disp, ximageinfo->cmap, ximageinfo->index, ximageinfo->no, 0); - lfree(ximageinfo->index); + free(ximageinfo->index); } if (ximageinfo->gc) XFreeGC(ximageinfo->disp, ximageinfo->gc); - lfree((byte *)ximageinfo->ximage->data); + free((byte *)ximageinfo->ximage->data); ximageinfo->ximage->data= NULL; XDestroyImage(ximageinfo->ximage); - lfree((byte *)ximageinfo); + free((byte *)ximageinfo); /* should we free private color map to ??? */ }