-/* send.c
- *
- * send an Image to an X pixmap
- */
+/* send.c */
#include "xli.h"
if (BITMAPP(cimage))
return(NULL);
+ /*
printf(" Converting to monochrome...");
fflush(stdout);
+ */
image= newBitImage(cimage->width, cimage->height);
if (cimage->title)
dp += dll; /* next row */
}
+ /*
printf("done\n");
+ */
return(image);
}
}
image->title = dupString(oimage->title);
- lfree((byte *)xindex);
- lfree((byte *)yindex);
+ free((byte *)xindex);
+ free((byte *)yindex);
printf("done\n");
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 */
image->rgb.used = next_index;
/* clean up */
- lfree(map);
- lfree(used);
+ free(map);
+ free(used);
+ /*
if (badcount)
printf("%d out-of-range pixels, ", badcount);
printf("%d unique color%s\n",
next_index, (next_index == 1 ? "" : "s"));
}
+ */
image->rgb.compressed= TRUE; /* don't do it again */
}
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; a<NOFLASH_COLORS; a++) /* count entries we got */
- if (!XAllocColorCells(disp, our_default_cmap, FALSE, NULL, 0,
- our_default_index + a, 1))
- break;
-
- free_cmap_entries = max_cmap_entries = a;
-
- printf("We've got %d colormap entries.\n", free_cmap_entries);
+ static XColor xcolor_private[NOFLASH_COLORS];
+ static int colorcell_used[NOFLASH_COLORS];
+ static Colormap global_cmap = 0;
+ static Pixel *global_cmap_index;
+ static int num_cmap_entries, free_cmap_entries;
+ static private_cmap = FALSE;
+ Pixel *redvalue, *greenvalue, *bluevalue;
+ unsigned int a, c=0, x, y, linelen, dpixlen, dbits;
+ XColor xcolor;
+ XGCValues gcv;
+ XImageInfo *ximageinfo;
- for(a=0; a<max_cmap_entries; a++) /* copy default colors */
+ if (!global_cmap)
+ {
+ if (visual == DefaultVisual(disp, scrn))
+ global_cmap = DefaultColormap(disp, scrn);
+ else
{
- xcolor.pixel = *(our_default_index + a);
- XQueryColor(disp, DefaultColormap(disp, scrn), &xcolor);
- XStoreColor(disp, our_default_cmap, &xcolor);
+ global_cmap = XCreateColormap(disp, RootWindow(disp, scrn),
+ visual, AllocNone);
+ private_cmap = TRUE;
}
}
- xcolor.flags= DoRed | DoGreen | DoBlue;
- redvalue= greenvalue= bluevalue= NULL;
- orig_image= image;
- ximageinfo= (XImageInfo *)lmalloc(sizeof(XImageInfo));
- ximageinfo->disp= 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)
{
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 */
/* 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;
bluestep = 256 / bluecolors;
redbottom = greenbottom = bluebottom = 0;
redtop = greentop = bluetop = 0;
- for (a= 0; a < visual->map_entries; a++)
+ for (a=0; a<visual->map_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.
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;
}
*/
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);
}
*/
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; a<image->rgb.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; i<NOFLASH_COLORS; i++)
+ if (!XAllocColorCells(disp, global_cmap, FALSE, NULL, 0,
+ global_cmap_index + i, 1))
+ break;
+ num_cmap_entries = free_cmap_entries = i;
+
+ /*
+ printf("We've got %d free colormap entries.\n", free_cmap_entries);
+ */
+
+ /* to minimize colormap flashing, copy default colors and try
+ to keep them as near as possible to the old values */
+
+ for(i=0; i<num_cmap_entries; i++)
+ {
+ xcolor2.pixel = *(global_cmap_index + i);
+ XQueryColor(disp, DefaultColormap(disp, scrn), &xcolor2);
+ XStoreColor(disp, global_cmap, &xcolor2);
+ xcolor_private[xcolor2.pixel] = xcolor2;
+ colorcell_used[xcolor2.pixel] = FALSE;
+ }
+ /* now we have the default colormap private: all colors we
+ successfully allocated so far are read-only, which is okay,
+ because we don't want to change them anymore -- if we need
+ an existing color again, we get it by XAllocColor; all other
+ colors are read/write and we can set them by XStoreColor,
+ but we will try to overwrite those color cells with our new
+ color which are as close as possible to our new color */
+ }
- /* get the colormap to use.
- */
+ /* look for an existing default color close the one we want */
- ximageinfo->cmap = 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)
{
}
}
+ /*
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);
}
{
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 ??? */
}