1
0
mirror of https://github.com/gryf/wmaker.git synced 2026-01-05 21:34:17 +01:00

Updating to version 0.20.2

Many bug fixes.
This commit is contained in:
dan
1998-10-21 14:43:47 +00:00
parent 9d2e6ef9f1
commit 9af1c6c415
222 changed files with 9132 additions and 4322 deletions

View File

@@ -48,7 +48,10 @@ char *alloca ();
#include "wraster.h"
#define MIN(a,b) ((a)<(b) ? (a) : (b))
#ifdef XSHM
Pixmap R_CreateXImageMappedPixmap(RContext *context, RXImage *ximage);
#endif
typedef struct RConversionTable {
@@ -58,51 +61,6 @@ typedef struct RConversionTable {
} RConversionTable;
/*
* Lookup table for index*3/8
*/
static char errorTable1[]={
0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5,
6, 6, 6, 7, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11,
12, 12, 12, 13, 13, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17,
18, 18, 18, 19, 19, 19, 20, 20, 21, 21, 21, 22, 22, 22, 23, 23,
24, 24, 24, 25, 25, 25, 26, 26, 27, 27, 27, 28, 28, 28, 29, 29,
30, 30, 30, 31, 31, 31, 32, 32, 33, 33, 33, 34, 34, 34, 35, 35,
36, 36, 36, 37, 37, 37, 38, 38, 39, 39, 39, 40, 40, 40, 41, 41,
42, 42, 42, 43, 43, 43, 44, 44, 45, 45, 45, 46, 46, 46, 47, 47,
48, 48, 48, 49, 49, 49, 50, 50, 51, 51, 51, 52, 52, 52, 53, 53,
54, 54, 54, 55, 55, 55, 56, 56, 57, 57, 57, 58, 58, 58, 59, 59,
60, 60, 60, 61, 61, 61, 62, 62, 63, 63, 63, 64, 64, 64, 65, 65,
66, 66, 66, 67, 67, 67, 68, 68, 69, 69, 69, 70, 70, 70, 71, 71,
72, 72, 72, 73, 73, 73, 74, 74, 75, 75, 75, 76, 76, 76, 77, 77,
78, 78, 78, 79, 79, 79, 80, 80, 81, 81, 81, 82, 82, 82, 83, 83,
84, 84, 84, 85, 85, 85, 86, 86, 87, 87, 87, 88, 88, 88, 89, 89,
90, 90, 90, 91, 91, 91, 92, 92, 93, 93, 93, 94, 94, 94, 95
};
/*
* Lookup table for index*2/8
*/
static char errorTable2[]={
0, 1, 2, 1, 2, 3, 2, 3, 2, 3, 4, 3, 4, 5, 4, 5,
4, 5, 6, 5, 6, 7, 6, 7, 6, 7, 8, 7, 8, 9, 8, 9,
8, 9, 10, 9, 10, 11, 10, 11, 10, 11, 12, 11, 12, 13, 12, 13,
12, 13, 14, 13, 14, 15, 14, 15, 14, 15, 16, 15, 16, 17, 16, 17,
16, 17, 18, 17, 18, 19, 18, 19, 18, 19, 20, 19, 20, 21, 20, 21,
20, 21, 22, 21, 22, 23, 22, 23, 22, 23, 24, 23, 24, 25, 24, 25,
24, 25, 26, 25, 26, 27, 26, 27, 26, 27, 28, 27, 28, 29, 28, 29,
28, 29, 30, 29, 30, 31, 30, 31, 30, 31, 32, 31, 32, 33, 32, 33,
32, 33, 34, 33, 34, 35, 34, 35, 34, 35, 36, 35, 36, 37, 36, 37,
36, 37, 38, 37, 38, 39, 38, 39, 38, 39, 40, 39, 40, 41, 40, 41,
40, 41, 42, 41, 42, 43, 42, 43, 42, 43, 44, 43, 44, 45, 44, 45,
44, 45, 46, 45, 46, 47, 46, 47, 46, 47, 48, 47, 48, 49, 48, 49,
48, 49, 50, 49, 50, 51, 50, 51, 50, 51, 52, 51, 52, 53, 52, 53,
52, 53, 54, 53, 54, 55, 54, 55, 54, 55, 56, 55, 56, 57, 56, 57,
56, 57, 58, 57, 58, 59, 58, 59, 58, 59, 60, 59, 60, 61, 60, 61,
60, 61, 62, 61, 62, 63, 62, 63, 62, 63, 64, 63, 64, 65, 64
};
static RConversionTable *conversionTable = NULL;
@@ -145,6 +103,7 @@ image2TrueColor(RContext *ctx, RImage *image)
unsigned short rmask, gmask, bmask;
unsigned short roffs, goffs, boffs;
unsigned short *rtable, *gtable, *btable;
int ofs;
ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height);
if (!ximg) {
@@ -187,7 +146,7 @@ image2TrueColor(RContext *ctx, RImage *image)
btable = computeTable(bmask);
if (rtable==NULL || gtable==NULL || btable==NULL) {
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
@@ -197,133 +156,114 @@ image2TrueColor(RContext *ctx, RImage *image)
#ifdef DEBUG
puts("true color match");
#endif
for (y=0; y < image->height; y++) {
for (x=0; x < image->width; x++) {
for (y=0, ofs=0; y < image->height; y++) {
for (x=0; x < image->width; x++, ofs++) {
/* reduce pixel */
r = rtable[*red++];
g = gtable[*grn++];
b = btable[*blu++];
r = rtable[red[ofs]];
g = gtable[grn[ofs]];
b = btable[blu[ofs]];
pixel = (r<<roffs) | (g<<goffs) | (b<<boffs);
XPutPixel(ximg->image, x, y, pixel);
}
}
} else {
/* dither */
unsigned char *rerr, *gerr, *berr;
unsigned char *nrerr, *ngerr, *nberr;
unsigned char *rerr_, *gerr_, *berr_;
unsigned char *nrerr_, *ngerr_, *nberr_;
unsigned char *terr;
register int ac, err;
int width = image->width;
int dr=0xff-rmask;
int dg=0xff-gmask;
int db=0xff-bmask;
while ((dr & 1)==0) dr = dr >> 1;
while ((dg & 1)==0) dg = dg >> 1;
while ((db & 1)==0) db = db >> 1;
short *rerr, *gerr, *berr;
short *nrerr, *ngerr, *nberr;
short *terr;
int rer, ger, ber;
const int dr=0xff/rmask;
const int dg=0xff/gmask;
const int db=0xff/bmask;
#ifdef DEBUG
puts("true color dither");
#endif
rerr_ = rerr = (unsigned char*)alloca((width+2)*sizeof(char));
gerr_ = gerr = (unsigned char*)alloca((width+2)*sizeof(char));
berr_ = berr = (unsigned char*)alloca((width+2)*sizeof(char));
nrerr_ = nrerr = (unsigned char*)alloca((width+2)*sizeof(char));
ngerr_ = ngerr = (unsigned char*)alloca((width+2)*sizeof(char));
nberr_ = nberr = (unsigned char*)alloca((width+2)*sizeof(char));
rerr = (short*)alloca((image->width+2)*sizeof(short));
gerr = (short*)alloca((image->width+2)*sizeof(short));
berr = (short*)alloca((image->width+2)*sizeof(short));
nrerr = (short*)alloca((image->width+2)*sizeof(short));
ngerr = (short*)alloca((image->width+2)*sizeof(short));
nberr = (short*)alloca((image->width+2)*sizeof(short));
if (!rerr || !gerr || !berr || !nrerr || !ngerr || !nberr) {
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
for (x=0; x<width; x++) {
rerr[x] = *red++;
gerr[x] = *grn++;
berr[x] = *blu++;
for (x=0; x<image->width; x++) {
rerr[x] = red[x];
gerr[x] = grn[x];
berr[x] = blu[x];
}
rerr[x] = gerr[x] = berr[x] = 0;
/* convert and dither the image to XImage */
for (y=0; y<image->height; y++) {
for (y=0, ofs=0; y<image->height; y++) {
if (y<image->height-1) {
memcpy(nrerr, red, width);
memcpy(ngerr, grn, width);
memcpy(nberr, blu, width);
red+=width;
grn+=width;
blu+=width;
int x1;
for (x=0, x1=ofs+image->width; x<image->width; x++, x1++) {
nrerr[x] = red[x1];
ngerr[x] = grn[x1];
nberr[x] = blu[x1];
}
/* last column */
nrerr[x] = *(red-1);
ngerr[x] = *(grn-1);
nberr[x] = *(blu-1);
x1--;
nrerr[x] = red[x1];
ngerr[x] = grn[x1];
nberr[x] = blu[x1];
}
for (x=0; x<width; x++) {
for (x=0; x<image->width; x++) {
/* reduce pixel */
pixel = (rtable[*rerr]<<roffs) | (gtable[*gerr]<<goffs)
| (btable[*berr]<<boffs);
if (rerr[x]>0xff) rerr[x]=0xff; else if (rerr[x]<0) rerr[x]=0;
if (gerr[x]>0xff) gerr[x]=0xff; else if (gerr[x]<0) gerr[x]=0;
if (berr[x]>0xff) berr[x]=0xff; else if (berr[x]<0) berr[x]=0;
r = rtable[rerr[x]];
g = gtable[gerr[x]];
b = btable[berr[x]];
pixel = (r<<roffs) | (g<<goffs) | (b<<boffs);
XPutPixel(ximg->image, x, y, pixel);
/* calc error */
err = *rerr&dr;
rerr++;
/* distribute error */
ac = errorTable1[err] + *rerr;
*rerr=MIN(ac, 0xff);
ac = errorTable1[err] + *nrerr;
*nrerr=MIN(ac, 0xff);
nrerr++;
ac = *nrerr + errorTable2[err];
*nrerr=MIN(ac,0xff);
rer = rerr[x] - r*dr;
ger = gerr[x] - g*dg;
ber = berr[x] - b*db;
/* calc error */
err = *gerr&dg;
gerr++;
/* distribute error */
ac = errorTable1[err] + *gerr;
*gerr=MIN(ac, 0xff);
ac = errorTable1[err] + *ngerr;
*ngerr=MIN(ac, 0xff);
ngerr++;
ac = *ngerr + errorTable2[err];
*ngerr=MIN(ac,0xff);
/* calc error */
err = *berr&db;
berr++;
/* distribute error */
ac = errorTable1[err] + *berr;
*berr=MIN(ac, 0xff);
ac = errorTable1[err] + *nberr;
*nberr=MIN(ac, 0xff);
nberr++;
ac = *nberr + errorTable2[err];
*nberr=MIN(ac,0xff);
r = (rer*3)/8;
g = (ger*3)/8;
b = (ber*3)/8;
/* x+1, y */
rerr[x+1]+=r;
gerr[x+1]+=g;
berr[x+1]+=b;
/* x, y+1 */
nrerr[x]+=r;
ngerr[x]+=g;
nberr[x]+=b;
/* x+1, y+1 */
nrerr[x+1]+=rer-2*r;
ngerr[x+1]+=ger-2*g;
nberr[x+1]+=ber-2*b;
}
ofs+=image->width;
/* skip to next line */
rerr = nrerr_;
nrerr = rerr_;
terr = nrerr_;
nrerr_ = rerr_;
rerr_ = terr;
gerr = ngerr_;
ngerr = gerr_;
terr = ngerr_;
ngerr_ = gerr_;
gerr_ = terr;
terr = rerr;
rerr = nrerr;
nrerr = terr;
berr = nberr_;
nberr = berr_;
terr = nberr_;
nberr_ = berr_;
berr_ = terr;
terr = gerr;
gerr = ngerr;
ngerr = terr;
terr = berr;
berr = nberr;
nberr = terr;
}
}
return ximg;
}
static RXImage*
image2PseudoColor(RContext *ctx, RImage *image)
{
@@ -358,7 +298,7 @@ image2PseudoColor(RContext *ctx, RImage *image)
btable = computeTable(bmask);
if (rtable==NULL || gtable==NULL || btable==NULL) {
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
@@ -399,7 +339,7 @@ image2PseudoColor(RContext *ctx, RImage *image)
ngerr = (short*)alloca((image->width+2)*sizeof(short));
nberr = (short*)alloca((image->width+2)*sizeof(short));
if (!rerr || !gerr || !berr || !nrerr || !ngerr || !nberr) {
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
@@ -437,11 +377,31 @@ image2PseudoColor(RContext *ctx, RImage *image)
pixel = r*cpccpc + g*cpc + b;
/*data[ofs] = ctx->colors[pixel].pixel;*/
XPutPixel(ximg->image, x, y, ctx->colors[pixel].pixel);
/* calc error */
rer = rerr[x] - r*dr;
ger = gerr[x] - g*dg;
ber = berr[x] - b*db;
/* distribute error */
rerr[x+1]+=(rer*7)/16;
gerr[x+1]+=(ger*7)/16;
berr[x+1]+=(ber*7)/16;
nrerr[x]+=(rer*5)/16;
ngerr[x]+=(ger*5)/16;
nberr[x]+=(ber*5)/16;
if (x>0) {
nrerr[x-1]+=(rer*3)/16;
ngerr[x-1]+=(ger*3)/16;
nberr[x-1]+=(ber*3)/16;
}
nrerr[x+1]+=rer/16;
ngerr[x+1]+=ger/16;
nberr[x+1]+=ber/16;
#if 0
/* distribute error */
r = (rer*3)/8;
g = (ger*3)/8;
@@ -458,6 +418,7 @@ image2PseudoColor(RContext *ctx, RImage *image)
nrerr[x+1]+=rer-2*r;
ngerr[x+1]+=ger-2*g;
nberr[x+1]+=ber-2*b;
#endif
}
/* skip to next line */
terr = rerr;
@@ -473,6 +434,7 @@ image2PseudoColor(RContext *ctx, RImage *image)
nberr = terr;
}
}
ximg->image->data = (char*)data;
return ximg;
}
@@ -510,7 +472,7 @@ image2GrayScale(RContext *ctx, RImage *image)
table = computeTable(gmask);
if (table==NULL) {
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
@@ -543,7 +505,7 @@ image2GrayScale(RContext *ctx, RImage *image)
gerr = (short*)alloca((image->width+2)*sizeof(short));
ngerr = (short*)alloca((image->width+2)*sizeof(short));
if (!gerr || !ngerr) {
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
RDestroyXImage(ctx, ximg);
return NULL;
}
@@ -623,32 +585,57 @@ int
RConvertImage(RContext *context, RImage *image, Pixmap *pixmap)
{
RXImage *ximg=NULL;
#ifdef XSHM
Pixmap tmp;
#endif
assert(context!=NULL);
assert(image!=NULL);
assert(pixmap!=NULL);
/* clear error message */
RErrorString[0] = 0;
/* clear error message */
if (context->vclass == TrueColor)
ximg = image2TrueColor(context, image);
else if (context->vclass == PseudoColor || context->vclass == StaticColor)
ximg = image2PseudoColor(context, image);
else if (context->vclass == GrayScale || context->vclass == StaticGray)
ximg = image2GrayScale(context, image);
if (!ximg) {
strcat(RErrorString, ":could not convert RImage to XImage");
#ifdef C_ALLOCA
alloca(0);
#endif
return False;
}
*pixmap = XCreatePixmap(context->dpy, context->drawable, image->width,
image->height, context->depth);
#ifdef XSHM
tmp = R_CreateXImageMappedPixmap(context, ximg);
if (tmp) {
/*
* We have to copy the shm Pixmap into a normal Pixmap because
* otherwise, we would have to control when Pixmaps are freed so
* that we can detach their shm segments. This is a problem if the
* program crash, leaving stale shared memory segments in the
* system (lots of them). But with some work, we can optimize
* things and remove this XCopyArea. This will require
* explicitly freeing all pixmaps when exiting or restarting
* wmaker.
*/
XCopyArea(context->dpy, tmp, *pixmap, context->copy_gc, 0, 0,
image->width, image->height, 0, 0);
XFreePixmap(context->dpy, tmp);
} else {
RPutXImage(context, *pixmap, context->copy_gc, ximg, 0, 0, 0, 0,
image->width, image->height);
}
#else /* !XSHM */
RPutXImage(context, *pixmap, context->copy_gc, ximg, 0, 0, 0, 0,
image->width, image->height);
image->width, image->height);
#endif /* !XSHM */
RDestroyXImage(context, ximg);
@@ -683,7 +670,6 @@ RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap,
ximg = image2Bitmap(context, image, threshold);
if (!ximg) {
strcat(RErrorString, ":could not convert RImage mask to XImage");
#ifdef C_ALLOCA
alloca(0);
#endif
@@ -710,8 +696,6 @@ RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap,
Bool
RGetClosestXColor(RContext *context, RColor *color, XColor *retColor)
{
RErrorString[0] = 0;
if (context->vclass == TrueColor) {
unsigned short rmask, gmask, bmask;
unsigned short roffs, goffs, boffs;
@@ -751,7 +735,7 @@ RGetClosestXColor(RContext *context, RColor *color, XColor *retColor)
btable = computeTable(bmask);
if (rtable==NULL || gtable==NULL || btable==NULL) {
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
return False;
}
index = rtable[color->red]*cpccpc + gtable[color->green]*cpc
@@ -777,8 +761,7 @@ RGetClosestXColor(RContext *context, RColor *color, XColor *retColor)
*retColor = context->colors[index];
} else {
sprintf(RErrorString, "internal bug:unsupported visual:%i",
context->vclass);
RErrorCode = RERR_INTERNAL;
return False;
}