mirror of
https://github.com/gryf/wmaker.git
synced 2026-02-02 22:25:48 +01:00
Updating to version 0.20.2
Many bug fixes.
This commit is contained in:
@@ -15,6 +15,7 @@ libwraster_a_SOURCES = \
|
||||
draw.c \
|
||||
color.c \
|
||||
load.c \
|
||||
save.c \
|
||||
gradient.c \
|
||||
xpixmap.c \
|
||||
convert.c \
|
||||
|
||||
@@ -68,8 +68,6 @@ I18N = @I18N@
|
||||
I18N_MB = @I18N_MB@
|
||||
ICONEXT = @ICONEXT@
|
||||
INTLIBS = @INTLIBS@
|
||||
LIBPL_INC_PATH = @LIBPL_INC_PATH@
|
||||
LIBPL_LIBS = @LIBPL_LIBS@
|
||||
LN_S = @LN_S@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MOFILES = @MOFILES@
|
||||
@@ -106,6 +104,7 @@ libwraster_a_SOURCES = \
|
||||
draw.c \
|
||||
color.c \
|
||||
load.c \
|
||||
save.c \
|
||||
gradient.c \
|
||||
xpixmap.c \
|
||||
convert.c \
|
||||
@@ -155,7 +154,7 @@ X_CFLAGS = @X_CFLAGS@
|
||||
X_LIBS = @X_LIBS@
|
||||
X_PRE_LIBS = @X_PRE_LIBS@
|
||||
libwraster_a_DEPENDENCIES = @ALLOCA@
|
||||
libwraster_a_OBJECTS = raster.o draw.o color.o load.o gradient.o \
|
||||
libwraster_a_OBJECTS = raster.o draw.o color.o load.o save.o gradient.o \
|
||||
xpixmap.o convert.o context.o misc.o scale.o convolve.o nxpm.o xpm.o \
|
||||
xutil.o ppm.o png.o jpeg.o tiff.o gif.o
|
||||
AR = ar
|
||||
|
||||
102
wrlib/context.c
102
wrlib/context.c
@@ -28,6 +28,7 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <math.h>
|
||||
|
||||
@@ -65,14 +66,11 @@ allocatePseudoColor(RContext *ctx)
|
||||
ncolors = cpc * cpc * cpc;
|
||||
}
|
||||
|
||||
if (cpc < 2 || ncolors > (1<<ctx->depth)) {
|
||||
sprintf(RErrorString, "invalid colormap size %i", cpc);
|
||||
return NULL;
|
||||
}
|
||||
assert(cpc >= 2 && ncolors <= (1<<ctx->depth));
|
||||
|
||||
colors = malloc(sizeof(XColor)*ncolors);
|
||||
if (!colors) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
i=0;
|
||||
@@ -89,7 +87,6 @@ allocatePseudoColor(RContext *ctx)
|
||||
for (r=0; r<cpc; r++) {
|
||||
for (g=0; g<cpc; g++) {
|
||||
for (b=0; b<cpc; b++) {
|
||||
|
||||
colors[i].red=(r*0xffff) / (cpc-1);
|
||||
colors[i].green=(g*0xffff) / (cpc-1);
|
||||
colors[i].blue=(b*0xffff) / (cpc-1);
|
||||
@@ -191,16 +188,13 @@ allocateGrayScale(RContext *ctx)
|
||||
/* we might as well use all grays */
|
||||
ncolors = 1<<ctx->depth;
|
||||
} else {
|
||||
if ( ncolors > (1<<ctx->depth) ) {
|
||||
/* reduce colormap size */
|
||||
cpc = ctx->attribs->colors_per_channel = 1<<((int)ctx->depth/3);
|
||||
ncolors = cpc * cpc * cpc;
|
||||
}
|
||||
if ( ncolors > (1<<ctx->depth) ) {
|
||||
/* reduce colormap size */
|
||||
cpc = ctx->attribs->colors_per_channel = 1<<((int)ctx->depth/3);
|
||||
ncolors = cpc * cpc * cpc;
|
||||
}
|
||||
|
||||
if (cpc < 2 || ncolors > (1<<ctx->depth)) {
|
||||
sprintf(RErrorString, "invalid colormap size %i", cpc);
|
||||
return NULL;
|
||||
}
|
||||
assert(cpc >= 2 && ncolors <= (1<<ctx->depth));
|
||||
}
|
||||
|
||||
if (ncolors>=256 && ctx->vclass==StaticGray) {
|
||||
@@ -210,7 +204,7 @@ allocateGrayScale(RContext *ctx)
|
||||
|
||||
colors = malloc(sizeof(XColor)*ncolors);
|
||||
if (!colors) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return False;
|
||||
}
|
||||
for (i=0; i<ncolors; i++) {
|
||||
@@ -290,11 +284,9 @@ mygetenv(char *var, int scr)
|
||||
char *p;
|
||||
char varname[64];
|
||||
|
||||
if (scr==0) {
|
||||
p = getenv(var);
|
||||
}
|
||||
if (scr!=0 || !p) {
|
||||
sprintf(varname, "%s%i", var, scr);
|
||||
sprintf(varname, "%s%i", var, scr);
|
||||
p = getenv(varname);
|
||||
if (!p) {
|
||||
p = getenv(var);
|
||||
}
|
||||
return p;
|
||||
@@ -320,6 +312,16 @@ gatherconfig(RContext *context, int screen_n)
|
||||
context->attribs->bgamma = g3;
|
||||
}
|
||||
}
|
||||
ptr = mygetenv("WRASTER_COLOR_RESOLUTION", screen_n);
|
||||
if (ptr) {
|
||||
int i;
|
||||
if (sscanf(ptr, "%d", &i)!=1 || i<2 || i>6) {
|
||||
printf("wrlib: invalid value for color resolution \"%s\"\n",ptr);
|
||||
} else {
|
||||
context->attribs->flags |= RC_ColorsPerChannel;
|
||||
context->attribs->colors_per_channel = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -355,6 +357,7 @@ getColormap(RContext *context, int screen_number)
|
||||
color.red = color.green = color.blue = 0xffff;
|
||||
XAllocColor(context->dpy, cmap, &color);
|
||||
context->white = color.pixel;
|
||||
|
||||
}
|
||||
context->cmap = cmap;
|
||||
}
|
||||
@@ -381,10 +384,9 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
||||
XGCValues gcv;
|
||||
|
||||
|
||||
RErrorString[0]=0;
|
||||
context = malloc(sizeof(RContext));
|
||||
if (!context) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
memset(context, 0, sizeof(RContext));
|
||||
@@ -396,7 +398,7 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
||||
context->attribs = malloc(sizeof(RContextAttributes));
|
||||
if (!context->attribs) {
|
||||
free(context);
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
if (!attribs)
|
||||
@@ -415,34 +417,34 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
|
||||
templ.visualid = context->attribs->visualid;
|
||||
vinfo = XGetVisualInfo(context->dpy, VisualIDMask|VisualScreenMask,
|
||||
&templ, &nret);
|
||||
|
||||
if (!vinfo || nret==0) {
|
||||
sprintf(RErrorString, "invalid visual id %x\n",
|
||||
(unsigned int)context->attribs->visualid);
|
||||
} else {
|
||||
if (vinfo[0].visual == DefaultVisual(dpy, screen_number)) {
|
||||
context->attribs->flags |= RC_DefaultVisual;
|
||||
} else {
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
|
||||
context->visual = vinfo[0].visual;
|
||||
context->depth = vinfo[0].depth;
|
||||
context->vclass = vinfo[0].class;
|
||||
getColormap(context, screen_number);
|
||||
attr.colormap = context->cmap;
|
||||
attr.override_redirect = True;
|
||||
attr.border_pixel = 0;
|
||||
attr.background_pixel = 0;
|
||||
mask = CWBorderPixel|CWColormap|CWOverrideRedirect|CWBackPixel;
|
||||
context->drawable =
|
||||
XCreateWindow(dpy, RootWindow(dpy, screen_number), 1, 1,
|
||||
1, 1, 0, context->depth, CopyFromParent,
|
||||
context->visual, mask, &attr);
|
||||
/* XSetWindowColormap(dpy, context->drawable, attr.colormap);*/
|
||||
}
|
||||
XFree(vinfo);
|
||||
free(context);
|
||||
RErrorCode = RERR_BADVISUALID;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (vinfo[0].visual == DefaultVisual(dpy, screen_number)) {
|
||||
context->attribs->flags |= RC_DefaultVisual;
|
||||
} else {
|
||||
XSetWindowAttributes attr;
|
||||
unsigned long mask;
|
||||
|
||||
context->visual = vinfo[0].visual;
|
||||
context->depth = vinfo[0].depth;
|
||||
context->vclass = vinfo[0].class;
|
||||
getColormap(context, screen_number);
|
||||
attr.colormap = context->cmap;
|
||||
attr.override_redirect = True;
|
||||
attr.border_pixel = 0;
|
||||
attr.background_pixel = 0;
|
||||
mask = CWBorderPixel|CWColormap|CWOverrideRedirect|CWBackPixel;
|
||||
context->drawable =
|
||||
XCreateWindow(dpy, RootWindow(dpy, screen_number), 1, 1,
|
||||
1, 1, 0, context->depth, CopyFromParent,
|
||||
context->visual, mask, &attr);
|
||||
/* XSetWindowColormap(dpy, context->drawable, attr.colormap);*/
|
||||
}
|
||||
XFree(vinfo);
|
||||
}
|
||||
|
||||
/* use default */
|
||||
|
||||
295
wrlib/convert.c
295
wrlib/convert.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ RBlurImage(RImage *image)
|
||||
return True;
|
||||
|
||||
outofmem:
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
|
||||
@@ -68,8 +68,8 @@ RPutPixel(RImage *image, int x, int y, RColor *color)
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(color!=NULL);
|
||||
assert(x >= 0 && x < image->width);
|
||||
assert(y >= 0 && y < image->height);
|
||||
if (x < 0 || x >= image->width || y < 0 || y >= image->height)
|
||||
return;
|
||||
|
||||
ofs = y*image->width + x;
|
||||
sr = image->data[0] + ofs;
|
||||
|
||||
48
wrlib/gif.c
48
wrlib/gif.c
@@ -58,12 +58,22 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
index = 0;
|
||||
|
||||
/* default error message */
|
||||
sprintf(RErrorString, "file does not contain image of index %i", index);
|
||||
RErrorCode = RERR_BADINDEX;
|
||||
|
||||
gif = DGifOpenFileName(file);
|
||||
|
||||
if (!gif) {
|
||||
sprintf(RErrorString, "could not load gif file");
|
||||
switch (GifLastError()) {
|
||||
case D_GIF_ERR_OPEN_FAILED:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case D_GIF_ERR_READ_FAILED:
|
||||
RErrorCode = RERR_READ;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -76,8 +86,7 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
GifByteType *extension;
|
||||
|
||||
if (DGifGetRecordType(gif, &recType) == GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
goto giferr;
|
||||
}
|
||||
switch (recType) {
|
||||
case IMAGE_DESC_RECORD_TYPE:
|
||||
@@ -85,8 +94,7 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
break;
|
||||
|
||||
if (DGifGetImageDesc(gif)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
goto giferr;
|
||||
}
|
||||
|
||||
width = gif->Image.Width;
|
||||
@@ -103,7 +111,6 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
* lets just render it with whatever garbage the stack
|
||||
* has :)
|
||||
*
|
||||
sprintf(RErrorString, "bad gif file");
|
||||
|
||||
goto bye;
|
||||
*/
|
||||
@@ -117,13 +124,12 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
|
||||
buffer = malloc(width * sizeof(GifColorType));
|
||||
if (!buffer) {
|
||||
sprintf(RErrorString, "out of memory while loading gif");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
|
||||
image = RCreateImage(width, height, False);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory while loading gif");
|
||||
goto bye;
|
||||
}
|
||||
|
||||
@@ -134,8 +140,7 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
for (k = InterlacedOffset[j]; k < height;
|
||||
k += InterlacedJumps[j]) {
|
||||
if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
goto giferr;
|
||||
}
|
||||
ofs = k*width;
|
||||
for (l = 0; l < width; l++, ofs++) {
|
||||
@@ -149,8 +154,7 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
} else {
|
||||
for (j = 0; j < height; j++) {
|
||||
if (DGifGetLine(gif, buffer, width)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
goto giferr;
|
||||
}
|
||||
for (k = 0; k < width; k++, ofs++) {
|
||||
int pixel = buffer[k];
|
||||
@@ -165,13 +169,11 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
case EXTENSION_RECORD_TYPE:
|
||||
/* skip all extension blocks */
|
||||
if (DGifGetExtension(gif, &extCode, &extension)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
goto giferr;
|
||||
}
|
||||
while (extension) {
|
||||
if (DGifGetExtensionNext(gif, &extension)==GIF_ERROR) {
|
||||
sprintf(RErrorString, "error while loading gif");
|
||||
goto bye;
|
||||
goto giferr;
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -183,6 +185,18 @@ RLoadGIF(RContext *context, char *file, int index)
|
||||
|
||||
/* yuck! */
|
||||
goto did_not_get_any_errors;
|
||||
giferr:
|
||||
switch (GifLastError()) {
|
||||
case D_GIF_ERR_OPEN_FAILED:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case D_GIF_ERR_READ_FAILED:
|
||||
RErrorCode = RERR_READ;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
bye:
|
||||
if (image)
|
||||
RDestroyImage(image);
|
||||
|
||||
@@ -220,8 +220,8 @@ renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0,
|
||||
*----------------------------------------------------------------------
|
||||
*/
|
||||
#if 0
|
||||
/* This version is slower then the second below. It uses more operations,
|
||||
* most of them multiplication of floats. -Dan
|
||||
/* This version is slower then the one below. It uses more operations,
|
||||
* most of them multiplication of floats. Dan.
|
||||
*/
|
||||
static RImage*
|
||||
renderDGradient(unsigned width, unsigned height, int r0, int g0, int b0,
|
||||
|
||||
@@ -109,12 +109,10 @@ RLoadJPEG(RContext *context, char *file_name, int index)
|
||||
|
||||
file = fopen(file_name, "r");
|
||||
if (!file) {
|
||||
sprintf(RErrorString, "could not open JPEG file \"%s\"", file_name);
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
cinfo.err = jpeg_std_error(&jerr.pub);
|
||||
jerr.pub.error_exit = my_error_exit;
|
||||
/* Establish the setjmp return context for my_error_exit to use. */
|
||||
@@ -135,13 +133,13 @@ RLoadJPEG(RContext *context, char *file_name, int index)
|
||||
|
||||
buffer[0] = (JSAMPROW)malloc(cinfo.image_width*cinfo.num_components);
|
||||
if (!buffer[0]) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
|
||||
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
goto bye;
|
||||
}
|
||||
|
||||
|
||||
22
wrlib/load.c
22
wrlib/load.c
@@ -29,6 +29,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef USE_PNG
|
||||
#include <png.h>
|
||||
@@ -213,13 +214,13 @@ RLoadImage(RContext *context, char *file, int index)
|
||||
RImage *image = NULL;
|
||||
int i;
|
||||
struct stat st;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
|
||||
assert(file!=NULL);
|
||||
|
||||
if (RImageCacheSize<0) {
|
||||
init_cache();
|
||||
}
|
||||
|
||||
|
||||
if (RImageCacheSize>0) {
|
||||
|
||||
for (i=0; i<RImageCacheSize; i++) {
|
||||
@@ -243,11 +244,10 @@ RLoadImage(RContext *context, char *file, int index)
|
||||
|
||||
switch (identFile(file)) {
|
||||
case IM_ERROR:
|
||||
sprintf(RErrorString, "error opening file");
|
||||
return NULL;
|
||||
|
||||
case IM_UNKNOWN:
|
||||
sprintf(RErrorString, "unknown image format");
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return NULL;
|
||||
|
||||
case IM_XPM:
|
||||
@@ -283,7 +283,7 @@ RLoadImage(RContext *context, char *file, int index)
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(RErrorString, "unsupported image format");
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -338,14 +338,16 @@ identFile(char *path)
|
||||
int fd;
|
||||
unsigned char buffer[32];
|
||||
|
||||
if (!path)
|
||||
return IM_ERROR;
|
||||
assert(path!=NULL);
|
||||
|
||||
fd = open(path, O_RDONLY);
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return IM_ERROR;
|
||||
}
|
||||
if (read(fd, buffer, 32)<1) {
|
||||
close(fd);
|
||||
RErrorCode = RERR_READ;
|
||||
return IM_ERROR;
|
||||
}
|
||||
close(fd);
|
||||
|
||||
68
wrlib/misc.c
68
wrlib/misc.c
@@ -28,7 +28,7 @@
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
int
|
||||
void
|
||||
RBevelImage(RImage *image, int bevel_type)
|
||||
{
|
||||
RColor color;
|
||||
@@ -36,7 +36,7 @@ RBevelImage(RImage *image, int bevel_type)
|
||||
int w, h;
|
||||
|
||||
if (image->width<3 || image->height<3)
|
||||
return False;
|
||||
return;
|
||||
|
||||
w = image->width;
|
||||
h = image->height;
|
||||
@@ -86,11 +86,10 @@ RBevelImage(RImage *image, int bevel_type)
|
||||
ROperateLine(image, RAddOperation, 0, h-1, w-1, h-1, &cdelta); /* bottom */
|
||||
ROperateLine(image, RAddOperation, w-1, 0, w-1, h-2, &cdelta); /* right */
|
||||
}
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
void
|
||||
RClearImage(RImage *image, RColor *color)
|
||||
{
|
||||
int bytes;
|
||||
@@ -111,21 +110,64 @@ RClearImage(RImage *image, RColor *color)
|
||||
dr = image->data[0];
|
||||
dg = image->data[1];
|
||||
db = image->data[2];
|
||||
|
||||
r = color->red;
|
||||
g = color->green;
|
||||
b = color->blue;
|
||||
|
||||
alpha = color->alpha;
|
||||
r = color->red * alpha;
|
||||
g = color->green * alpha;
|
||||
b = color->blue * alpha;
|
||||
nalpha = 255 - alpha;
|
||||
|
||||
for (i=0; i<bytes; i++) {
|
||||
*dr = (((int)*dr * nalpha) + (r * alpha))/256;
|
||||
*dg = (((int)*dg * nalpha) + (g * alpha))/256;
|
||||
*db = (((int)*db * nalpha) + (b * alpha))/256;
|
||||
*dr = (((int)*dr * nalpha) + r)/256;
|
||||
*dg = (((int)*dg * nalpha) + g)/256;
|
||||
*db = (((int)*db * nalpha) + b)/256;
|
||||
dr++; dg++; db++;
|
||||
}
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
const char*
|
||||
RMessageForError(int errorCode)
|
||||
{
|
||||
switch (errorCode) {
|
||||
case RERR_NONE:
|
||||
return "no error";
|
||||
break;
|
||||
case RERR_OPEN:
|
||||
return "could not open file";
|
||||
break;
|
||||
case RERR_READ:
|
||||
return "error reading from file";
|
||||
break;
|
||||
case RERR_WRITE:
|
||||
return "error writing to file";
|
||||
break;
|
||||
case RERR_NOMEMORY:
|
||||
return "out of memory";
|
||||
break;
|
||||
case RERR_NOCOLOR:
|
||||
return "out of color cells";
|
||||
break;
|
||||
case RERR_BADIMAGEFILE:
|
||||
return "invalid or corrupted image file";
|
||||
break;
|
||||
case RERR_BADFORMAT:
|
||||
return "unsupported image format";
|
||||
break;
|
||||
case RERR_BADINDEX:
|
||||
return "image file does not contain requested image index";
|
||||
break;
|
||||
case RERR_BADVISUALID:
|
||||
return "request for an invalid visual ID";
|
||||
break;
|
||||
case RERR_XERROR:
|
||||
return "internal X error";
|
||||
break;
|
||||
default:
|
||||
case RERR_INTERNAL:
|
||||
return "internal error";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
228
wrlib/nxpm.c
228
wrlib/nxpm.c
@@ -42,6 +42,7 @@ char *alloca ();
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
@@ -100,7 +101,7 @@ RGetImageFromXPMData(RContext *context, char **data)
|
||||
|
||||
if (!color_table[0] || !color_table[1] || !color_table[2] ||
|
||||
!color_table[3] || !symbol_table || !bsize) {
|
||||
sprintf(RErrorString, "out of memory while converting XPM data");
|
||||
RErrorCode = RERR_MEMORY;
|
||||
alloca(0);
|
||||
return NULL;
|
||||
}
|
||||
@@ -149,7 +150,6 @@ RGetImageFromXPMData(RContext *context, char **data)
|
||||
|
||||
image = RCreateImage(w, h, transp);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory while converting XPM data");
|
||||
alloca(0);
|
||||
return NULL;
|
||||
}
|
||||
@@ -205,7 +205,7 @@ RGetImageFromXPMData(RContext *context, char **data)
|
||||
return image;
|
||||
|
||||
bad_format:
|
||||
sprintf(RErrorString, "XPM data is not in the normalized format");
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
#endif
|
||||
@@ -234,7 +234,7 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
|
||||
f = fopen(file, "r");
|
||||
if (!f) {
|
||||
sprintf(RErrorString, "can't open XPM file \"%s\"", file);
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
/* sig */
|
||||
@@ -270,8 +270,7 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
|
||||
if (!color_table[0] || !color_table[1] || !color_table[2] ||
|
||||
!color_table[3] || !symbol_table || !bsize) {
|
||||
sprintf(RErrorString, "out of memory while loading XPM file \"%s\"",
|
||||
file);
|
||||
RErrorCode = RERR_MEMORY;
|
||||
fclose(f);
|
||||
alloca(0);
|
||||
return NULL;
|
||||
@@ -325,8 +324,6 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
|
||||
image = RCreateImage(w, h, transp);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory while loading XPM file \"%s\"",
|
||||
file);
|
||||
fclose(f);
|
||||
alloca(0);
|
||||
return NULL;
|
||||
@@ -390,7 +387,7 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
return image;
|
||||
|
||||
bad_format:
|
||||
sprintf(RErrorString, "XPM file \"%s\" is not in the normalized format", file);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
fclose(f);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
@@ -400,7 +397,7 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
return NULL;
|
||||
|
||||
bad_file:
|
||||
sprintf(RErrorString, "bad XPM file \"%s\"", file);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
fclose(f);
|
||||
#ifdef C_ALLOCA
|
||||
alloca(0);
|
||||
@@ -411,3 +408,214 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
typedef struct XPMColor {
|
||||
unsigned char red;
|
||||
unsigned char green;
|
||||
unsigned char blue;
|
||||
char text[12];
|
||||
struct XPMColor *next;
|
||||
} XPMColor;
|
||||
|
||||
|
||||
|
||||
#define I2CHAR(i) ((i)<12 ? (i)+'0' : ((i)<38 ? (i)+'A'-12 : (i)+'a'-38))
|
||||
#define CINDEX(xpmc) (((unsigned)(xpmc)->red)<<16|((unsigned)(xpmc)->green)<<8|((unsigned)(xpmc)->blue))
|
||||
|
||||
|
||||
|
||||
static XPMColor*
|
||||
lookfor(XPMColor *list, int index)
|
||||
{
|
||||
if (!list)
|
||||
return NULL;
|
||||
|
||||
for (; list!=NULL; list=list->next) {
|
||||
if (CINDEX(list) == index)
|
||||
return list;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Looks for the color in the colormap and inserts if it is not found.
|
||||
*
|
||||
* list is a binary search list. The unbalancing problem is just ignored.
|
||||
*
|
||||
* Returns False on error
|
||||
*/
|
||||
static Bool
|
||||
addcolor(XPMColor **list, unsigned r, unsigned g, unsigned b, int *colors)
|
||||
{
|
||||
XPMColor *tmpc;
|
||||
XPMColor *newc;
|
||||
int index;
|
||||
|
||||
index = r<<16|g<<8|b;
|
||||
tmpc = *list;
|
||||
|
||||
tmpc = lookfor(*list, index);
|
||||
|
||||
if (tmpc)
|
||||
return True;
|
||||
|
||||
newc = malloc(sizeof(XPMColor));
|
||||
|
||||
if (!newc) {
|
||||
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
|
||||
return False;
|
||||
}
|
||||
|
||||
newc->red = r;
|
||||
newc->green = g;
|
||||
newc->blue = b;
|
||||
newc->next = *list;
|
||||
*list = newc;
|
||||
|
||||
(*colors)++;
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
outputcolormap(FILE *file, XPMColor *colormap, int colorCount)
|
||||
{
|
||||
int j;
|
||||
int i,index;
|
||||
|
||||
if (!colormap)
|
||||
return;
|
||||
|
||||
for (index=0; colormap!=NULL; colormap=colormap->next,index++) {
|
||||
j = index;
|
||||
for (i=0; i<colorCount/64+1; i++) {
|
||||
colormap->text[i] = I2CHAR(j&63);
|
||||
j >>= 5;
|
||||
}
|
||||
colormap->text[i] = 0;
|
||||
fprintf(file, "\"%s c #%02x%02x%02x\",\n", colormap->text, colormap->red,
|
||||
colormap->green, colormap->blue);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
freecolormap(XPMColor *colormap)
|
||||
{
|
||||
XPMColor *tmp;
|
||||
|
||||
while (colormap) {
|
||||
tmp = colormap->next;
|
||||
free(colormap);
|
||||
colormap = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* save routine is common to internal support and library support */
|
||||
Bool
|
||||
RSaveXPM(RImage *image, char *filename)
|
||||
{
|
||||
FILE *file;
|
||||
int x, y;
|
||||
int colorCount=0;
|
||||
XPMColor *colormap = NULL;
|
||||
XPMColor *tmpc;
|
||||
int i;
|
||||
int ok = 0;
|
||||
unsigned char *r, *g, *b, *a;
|
||||
char transp[16];
|
||||
|
||||
file = fopen(filename, "w+");
|
||||
if (!file) {
|
||||
RErrorCode = RERR_OPEN;
|
||||
return False;
|
||||
}
|
||||
|
||||
fprintf(file, "/* XPM */\n");
|
||||
|
||||
fprintf(file, "static char *image[] = {\n");
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
/* first pass: make colormap for the image */
|
||||
if (a)
|
||||
colorCount = 1;
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
if (!a || *a++>127)
|
||||
if (!addcolor(&colormap, *r, *g, *b, &colorCount)) {
|
||||
goto uhoh;
|
||||
}
|
||||
r++; g++; b++;
|
||||
}
|
||||
}
|
||||
|
||||
/* write header info */
|
||||
fprintf(file, "\"%i %i %i %i\",\n", image->width, image->height,
|
||||
colorCount, colorCount/64+1);
|
||||
|
||||
|
||||
/* write colormap data */
|
||||
if (image->data[3]) {
|
||||
for (i=0; i<colorCount/64+1; i++)
|
||||
transp[i] = ' ';
|
||||
transp[i] = 0;
|
||||
|
||||
fprintf(file, "\"%s c None\",\n", transp);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
outputcolormap(file, colormap, colorCount);
|
||||
|
||||
r = image->data[0];
|
||||
g = image->data[1];
|
||||
b = image->data[2];
|
||||
a = image->data[3];
|
||||
|
||||
/* write data */
|
||||
for (y = 0; y < image->height; y++) {
|
||||
|
||||
fprintf(file, "\"");
|
||||
|
||||
for (x = 0; x < image->width; x++) {
|
||||
|
||||
if (!a || *a++>127) {
|
||||
tmpc = lookfor(colormap, (unsigned)*r<<16|(unsigned)*g<<8|(unsigned)*b);
|
||||
|
||||
fprintf(file, tmpc->text);
|
||||
} else {
|
||||
fprintf(file, transp);
|
||||
}
|
||||
|
||||
r++; g++; b++;
|
||||
}
|
||||
|
||||
if (y < image->height-1)
|
||||
fprintf(file, "\",\n");
|
||||
else
|
||||
fprintf(file, "\"};\n");
|
||||
}
|
||||
|
||||
ok = 1;
|
||||
uhoh:
|
||||
errno = 0;
|
||||
fclose(file);
|
||||
if (ok && errno==ENOSPC) {
|
||||
RErrorCode = RERR_WRITE;
|
||||
}
|
||||
|
||||
freecolormap(colormap);
|
||||
|
||||
return ok ? True : False;
|
||||
}
|
||||
|
||||
|
||||
|
||||
17
wrlib/png.c
17
wrlib/png.c
@@ -73,20 +73,20 @@ RLoadPNG(RContext *context, char *file, int index)
|
||||
|
||||
f = fopen(file, "r");
|
||||
if (!f) {
|
||||
sprintf(RErrorString, "could not open file \"%s\"", file);
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
png = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL,
|
||||
(png_error_ptr)NULL, (png_error_ptr)NULL);
|
||||
if (!png) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
pinfo = png_create_info_struct(png);
|
||||
if (!pinfo) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, NULL, NULL);
|
||||
return NULL;
|
||||
@@ -94,14 +94,14 @@ RLoadPNG(RContext *context, char *file, int index)
|
||||
|
||||
einfo = png_create_info_struct(png);
|
||||
if (!einfo) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
RErrorCode = RERR_INTERNAL;
|
||||
if (setjmp(png->jmpbuf)) {
|
||||
sprintf(RErrorString, "error loading PNG file \"%s\"", file);
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
if (image)
|
||||
@@ -126,7 +126,6 @@ RLoadPNG(RContext *context, char *file, int index)
|
||||
/* allocate RImage */
|
||||
image = RCreateImage(width, height, alpha);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "could not create RImage");
|
||||
fclose(f);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
return NULL;
|
||||
@@ -157,7 +156,7 @@ RLoadPNG(RContext *context, char *file, int index)
|
||||
} else if ((tmp = getenv("DISPLAY_GAMMA")) != NULL) {
|
||||
sgamma = atof(tmp);
|
||||
if (sgamma==0)
|
||||
sgamma = 1;
|
||||
sgamma = 1;
|
||||
} else {
|
||||
sgamma = 2.0;
|
||||
}
|
||||
@@ -179,7 +178,7 @@ RLoadPNG(RContext *context, char *file, int index)
|
||||
|
||||
png_rows = alloca(sizeof(char*)*height);
|
||||
if (!png_rows) {
|
||||
sprintf(RErrorString, "out of memory loading \"%s\"", file);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
RDestroyImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
@@ -191,7 +190,7 @@ RLoadPNG(RContext *context, char *file, int index)
|
||||
for (y=0; y<height; y++) {
|
||||
png_rows[y] = alloca(png_get_rowbytes(png, pinfo));
|
||||
if (!png_rows[y]) {
|
||||
sprintf(RErrorString, "out of memory loading \"%s\"", file);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
fclose(f);
|
||||
RDestroyImage(image);
|
||||
png_destroy_read_struct(&png, &pinfo, &einfo);
|
||||
|
||||
18
wrlib/ppm.c
18
wrlib/ppm.c
@@ -37,7 +37,6 @@ load_graymap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
if (!raw) {
|
||||
@@ -56,7 +55,7 @@ load_graymap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
return image;
|
||||
|
||||
short_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -71,7 +70,6 @@ load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
|
||||
image = RCreateImage(w, h, 0);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
return NULL;
|
||||
}
|
||||
r = image->data[0];
|
||||
@@ -98,7 +96,7 @@ load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
|
||||
return image;
|
||||
|
||||
short_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -114,11 +112,9 @@ RLoadPPM(RContext *context, char *file_name, int index)
|
||||
|
||||
#define GETL() if (!fgets(buffer, 255, file)) goto short_file
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
file = fopen(file_name, "r");
|
||||
if (!file) {
|
||||
sprintf(RErrorString, "could not open PPM file \"%s\"", file_name);
|
||||
RErrorCode = RERR_OPEN;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -127,7 +123,7 @@ RLoadPPM(RContext *context, char *file_name, int index)
|
||||
|
||||
/* only accept raw pixmaps or graymaps */
|
||||
if (buffer[0] != 'P' || (buffer[1] != '5' && buffer[1] != '6')) {
|
||||
sprintf(RErrorString, "unknown PPM format in \"%s\"", file_name);
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
@@ -160,12 +156,8 @@ RLoadPPM(RContext *context, char *file_name, int index)
|
||||
return image;
|
||||
|
||||
bad_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be corrupted", file_name);
|
||||
fclose(file);
|
||||
return NULL;
|
||||
|
||||
short_file:
|
||||
sprintf(RErrorString, "PPM file \"%s\" seems to be truncated", file_name);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
fclose(file);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -29,12 +29,10 @@
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#define MAXERRLEN 512
|
||||
|
||||
char *WRasterLibVersion="0.9";
|
||||
|
||||
char *WRasterLibVersion="0.2";
|
||||
|
||||
char RErrorString[MAXERRLEN];
|
||||
int RErrorCode=RERR_NONE;
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +46,7 @@ RCreateImage(unsigned width, unsigned height, int alpha)
|
||||
|
||||
image = malloc(sizeof(RImage));
|
||||
if (!image) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -69,7 +67,7 @@ RCreateImage(unsigned width, unsigned height, int alpha)
|
||||
}
|
||||
if (image)
|
||||
free(image);
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -207,11 +205,10 @@ RCombineImages(RImage *image, RImage *src)
|
||||
*dg = (((int)*dg * calpha) + ((int)*sg * alpha))/256;
|
||||
*db = (((int)*db * calpha) + ((int)*sb * alpha))/256;
|
||||
if (image->data[3])
|
||||
*da |= *sa;
|
||||
*da++ |= *sa;
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
sa++;
|
||||
da++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -223,7 +220,7 @@ void
|
||||
RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness)
|
||||
{
|
||||
register int i;
|
||||
unsigned char *dr, *dg, *db;
|
||||
unsigned char *dr, *dg, *db, *da;
|
||||
unsigned char *sr, *sg, *sb, *sa;
|
||||
int c_opaqueness;
|
||||
|
||||
@@ -234,6 +231,7 @@ RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness)
|
||||
dr = image->data[0];
|
||||
dg = image->data[1];
|
||||
db = image->data[2];
|
||||
da = image->data[3];
|
||||
|
||||
sr = src->data[0];
|
||||
sg = src->data[1];
|
||||
@@ -255,14 +253,30 @@ RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness)
|
||||
} else {
|
||||
int tmp;
|
||||
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
tmp= (*sa * opaqueness)/256;
|
||||
*dr = (((int)*dr *(int)(255-tmp)) + ((int)*sr *(int)tmp))/256;
|
||||
*dg = (((int)*dg *(int)(255-tmp)) + ((int)*sg *(int)tmp))/256;
|
||||
*db = (((int)*db *(int)(255-tmp)) + ((int)*sb *(int)tmp))/256;
|
||||
if (image->data[3]) {
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
tmp = (*sa * opaqueness)/256;
|
||||
*dr = (((int)*dr * (255-tmp)) + ((int)*sr * tmp))/256;
|
||||
*dg = (((int)*dg * (255-tmp)) + ((int)*sg * tmp))/256;
|
||||
*db = (((int)*db * (255-tmp)) + ((int)*sb * tmp))/256;
|
||||
*da |= tmp;
|
||||
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
sa++;
|
||||
da++;
|
||||
}
|
||||
} else {
|
||||
for (i=0; i<image->width*image->height; i++) {
|
||||
tmp = (*sa * opaqueness)/256;
|
||||
*dr = (((int)*dr * (255-tmp)) + ((int)*sr * tmp))/256;
|
||||
*dg = (((int)*dg * (255-tmp)) + ((int)*sg * tmp))/256;
|
||||
*db = (((int)*db * (255-tmp)) + ((int)*sb * tmp))/256;
|
||||
|
||||
dr++; dg++; db++;
|
||||
sr++; sg++; sb++;
|
||||
sa++;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef OP
|
||||
|
||||
49
wrlib/save.c
Normal file
49
wrlib/save.c
Normal file
@@ -0,0 +1,49 @@
|
||||
/* save.c - save image to file
|
||||
*
|
||||
* Raster graphics library
|
||||
*
|
||||
* Copyright (c) 1998 Alfredo K. Kojima
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Library General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Library General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Library General Public
|
||||
* License along with this library; if not, write to the Free
|
||||
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
|
||||
extern Bool RSaveXPM(RImage *image, char *filename);
|
||||
|
||||
|
||||
Bool
|
||||
RSaveImage(RImage *image, char *filename, char *format)
|
||||
{
|
||||
if (strcmp(format, "XPM")!=0) {
|
||||
RErrorCode = RERR_BADFORMAT;
|
||||
return False;
|
||||
}
|
||||
return RSaveXPM(image, filename);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
#include <stdio.h>
|
||||
|
||||
Display *dpy;
|
||||
@@ -57,12 +56,12 @@ void main(int argc, char **argv)
|
||||
#endif
|
||||
|
||||
if (!img) {
|
||||
puts(RErrorString);
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
new = RLoadImage(ctx, "tile.xpm", 0);
|
||||
if (!new) {
|
||||
puts(RErrorString);
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
RCombineArea(new, img, 0, 0, img->width, img->height, 8, 8);
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -9,6 +8,7 @@
|
||||
#include <sys/time.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
Display *dpy;
|
||||
RContext *ctx;
|
||||
char *ProgName;
|
||||
@@ -63,7 +63,7 @@ testDraw()
|
||||
* in the second slot, and also save a copy for later use. */
|
||||
icon = RLoadImage(ctx, "ballot_box.xpm", 0);
|
||||
if (!icon) {
|
||||
puts(RErrorString);
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
RCombineArea(img, icon, 0, 0, icon->width, icon->height, 8, 8);
|
||||
@@ -538,7 +538,7 @@ void main(int argc, char **argv)
|
||||
|
||||
if (!ctx) {
|
||||
printf("could not initialize graphics library context: %s\n",
|
||||
RErrorString);
|
||||
RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -546,10 +546,10 @@ void main(int argc, char **argv)
|
||||
testDraw();
|
||||
|
||||
testBevel();
|
||||
/*
|
||||
|
||||
drawClip();
|
||||
|
||||
benchmark();
|
||||
*/
|
||||
/* benchmark();*/
|
||||
|
||||
getchar();
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -116,7 +116,7 @@ void main(int argc, char **argv)
|
||||
|
||||
if (!ctx) {
|
||||
printf("could not initialize graphics library context: %s\n",
|
||||
RErrorString);
|
||||
RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@@ -139,14 +139,15 @@ void main(int argc, char **argv)
|
||||
|
||||
val.background_pixel = ctx->black;
|
||||
val.colormap = ctx->cmap;
|
||||
val.backing_store = Always;
|
||||
#ifdef BENCH
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 250, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel, &val);
|
||||
CWColormap|CWBackPixel|CWBackingStore, &val);
|
||||
#else
|
||||
win = XCreateWindow(dpy, DefaultRootWindow(dpy), 10, 10, 750, 250,
|
||||
0, ctx->depth, InputOutput, ctx->visual,
|
||||
CWColormap|CWBackPixel, &val);
|
||||
CWColormap|CWBackPixel|CWBackingStore, &val);
|
||||
#endif
|
||||
XMapRaised(dpy, win);
|
||||
XFlush(dpy);
|
||||
|
||||
@@ -57,7 +57,7 @@ RLoadTIFF(RContext *context, char *file, int index)
|
||||
i = index;
|
||||
while (i>0) {
|
||||
if (!TIFFReadDirectory(tif)) {
|
||||
sprintf(RErrorString, "bad index %i for file \"%s\"", index, file);
|
||||
RErrorCode = RERR_BADINDEX;
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
@@ -76,7 +76,7 @@ RLoadTIFF(RContext *context, char *file, int index)
|
||||
amode = (extrasamples == 1 && sampleinfo[0] == EXTRASAMPLE_ASSOCALPHA);
|
||||
|
||||
if (width<1 || height<1) {
|
||||
sprintf(RErrorString, "bad data in file \"%s\"", file);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
TIFFClose(tif);
|
||||
return NULL;
|
||||
}
|
||||
@@ -85,10 +85,10 @@ RLoadTIFF(RContext *context, char *file, int index)
|
||||
ptr = data = (uint32*)_TIFFmalloc(width * height * sizeof(uint32));
|
||||
|
||||
if (!data) {
|
||||
sprintf(RErrorString, "out of memory");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
} else {
|
||||
if (!TIFFReadRGBAImage(tif, width, height, data, 0)) {
|
||||
sprintf(RErrorString, "error reading file \"%s\"", file);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
} else {
|
||||
|
||||
/* convert data */
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
|
||||
#include "wraster.h"
|
||||
|
||||
#include <X11/Xlib.h>
|
||||
#include "wraster.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "tile.xpm"
|
||||
@@ -32,11 +31,11 @@ void main(int argc, char **argv)
|
||||
img = RLoadImage(ctx, argv[1], argc>2 ? atol(argv[2]) : 0);
|
||||
|
||||
if (!img) {
|
||||
puts(RErrorString);
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
if (!RConvertImage(ctx, img, &pix)) {
|
||||
puts(RErrorString);
|
||||
puts(RMessageForError(RErrorCode));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,8 @@
|
||||
#define RLRASTER_H_
|
||||
|
||||
|
||||
/* version of the header for the library: 0.8 */
|
||||
#define WRASTER_HEADER_VERSION 8
|
||||
/* version of the header for the library: 0.10 */
|
||||
#define WRASTER_HEADER_VERSION 10
|
||||
|
||||
#ifdef HAVE_ALLOCA_H
|
||||
#include <alloca.h>
|
||||
@@ -158,9 +158,11 @@ typedef struct RImage {
|
||||
*/
|
||||
typedef struct RXImage {
|
||||
XImage *image;
|
||||
|
||||
/* Private data. Do not access */
|
||||
#ifdef XSHM
|
||||
XShmSegmentInfo info;
|
||||
int is_shared;
|
||||
char is_shared;
|
||||
#endif
|
||||
} RXImage;
|
||||
|
||||
@@ -216,6 +218,22 @@ enum {
|
||||
|
||||
|
||||
|
||||
/* error codes */
|
||||
#define RERR_NONE 0
|
||||
#define RERR_OPEN 1 /* cant open file */
|
||||
#define RERR_READ 2 /* error reading from file */
|
||||
#define RERR_WRITE 3 /* error writing to file */
|
||||
#define RERR_NOMEMORY 4 /* out of memory */
|
||||
#define RERR_NOCOLOR 5 /* out of color cells */
|
||||
#define RERR_BADIMAGEFILE 6 /* image file is corrupted or invalid */
|
||||
#define RERR_BADFORMAT 7 /* image file format is unknown */
|
||||
#define RERR_BADINDEX 8 /* no such image index in file */
|
||||
|
||||
#define RERR_BADVISUALID 16 /* invalid visual ID requested for context */
|
||||
|
||||
#define RERR_XERROR 127 /* internal X error */
|
||||
#define RERR_INTERNAL 128 /* should not happen */
|
||||
|
||||
|
||||
/*
|
||||
* Returns a NULL terminated array of strings containing the
|
||||
@@ -231,6 +249,7 @@ void RFreeStringList(char **list);
|
||||
RContext *RCreateContext(Display *dpy, int screen_number,
|
||||
RContextAttributes *attribs);
|
||||
|
||||
void RDestroyContext(RContext *context);
|
||||
|
||||
Bool RGetClosestXColor(RContext *context, RColor *color, XColor *retColor);
|
||||
|
||||
@@ -251,6 +270,10 @@ void RDestroyImage(RImage *image);
|
||||
|
||||
RImage *RGetImageFromXPMData(RContext *context, char **data);
|
||||
|
||||
/*
|
||||
* RImage storing
|
||||
*/
|
||||
Bool RSaveImage(RImage *image, char *filename, char *format);
|
||||
|
||||
/*
|
||||
* Area manipulation
|
||||
@@ -320,9 +343,9 @@ void RHSVtoRGB(RHSVColor *hsv, RColor *rgb);
|
||||
/*
|
||||
* Painting
|
||||
*/
|
||||
int RClearImage(RImage *image, RColor *color);
|
||||
void RClearImage(RImage *image, RColor *color);
|
||||
|
||||
int RBevelImage(RImage *image, int bevel_type);
|
||||
void RBevelImage(RImage *image, int bevel_type);
|
||||
|
||||
RImage *RRenderGradient(unsigned width, unsigned height, RColor *from,
|
||||
RColor *to, int style);
|
||||
@@ -343,7 +366,7 @@ int RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap,
|
||||
/*
|
||||
* misc. utilities
|
||||
*/
|
||||
RXImage *RCreateXImage(RContext *context, int depth,
|
||||
RXImage *RCreateXImage(RContext *context, int depth,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
void RDestroyXImage(RContext *context, RXImage *ximage);
|
||||
@@ -352,13 +375,12 @@ void RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage,
|
||||
int src_x, int src_y, int dest_x, int dest_y,
|
||||
unsigned width, unsigned height);
|
||||
|
||||
/* do not free the returned string! */
|
||||
const char *RMessageForError(int errorCode);
|
||||
|
||||
|
||||
/****** Global Variables *******/
|
||||
|
||||
/*
|
||||
* Where error strings are stored
|
||||
*/
|
||||
extern char RErrorString[];
|
||||
|
||||
extern int RErrorCode;
|
||||
|
||||
#endif
|
||||
|
||||
@@ -56,8 +56,6 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
|
||||
int rshift, gshift, bshift;
|
||||
int rmask, gmask, bmask;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
assert(image!=NULL);
|
||||
assert(image->format==ZPixmap);
|
||||
assert(!mask || mask->format==ZPixmap);
|
||||
@@ -69,9 +67,7 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
|
||||
|
||||
|
||||
/* I don't know why, but XGetImage() for pixmaps don't set the
|
||||
* {red,green,blue}_mask values correctly. This will not
|
||||
* work for imageis of depth different than the root window
|
||||
* one used in wrlib
|
||||
* {red,green,blue}_mask values correctly.
|
||||
*/
|
||||
if (context->depth==image->depth) {
|
||||
rmask = context->visual->red_mask;
|
||||
@@ -100,12 +96,25 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
|
||||
#define NORMALIZE_BLUE(pixel) ((bshift>0) ? ((pixel) & bmask) >> bshift \
|
||||
: ((pixel) & bmask) << -bshift)
|
||||
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
*(r++) = NORMALIZE_RED(pixel);
|
||||
*(g++) = NORMALIZE_GREEN(pixel);
|
||||
*(b++) = NORMALIZE_BLUE(pixel);
|
||||
if (image->depth==1) {
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
if (pixel) {
|
||||
*(r++) = *(g++) = *(b++) = 0;
|
||||
} else {
|
||||
*(r++) = *(g++) = *(b++) = 0xff;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (y = 0; y < image->height; y++) {
|
||||
for (x = 0; x < image->width; x++) {
|
||||
pixel = XGetPixel(image, x, y);
|
||||
*(r++) = NORMALIZE_RED(pixel);
|
||||
*(g++) = NORMALIZE_GREEN(pixel);
|
||||
*(b++) = NORMALIZE_BLUE(pixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +124,7 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
|
||||
if (XGetPixel(mask, x, y)) {
|
||||
*(a++) = 0xff;
|
||||
} else {
|
||||
*(a++) = 0xff;
|
||||
*(a++) = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +143,6 @@ RCreateImageFromDrawable(RContext *context, Drawable drawable, Pixmap mask)
|
||||
int foo;
|
||||
Window baz;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
|
||||
assert(drawable!=None);
|
||||
|
||||
@@ -147,7 +155,7 @@ RCreateImageFromDrawable(RContext *context, Drawable drawable, Pixmap mask)
|
||||
ZPixmap);
|
||||
|
||||
if (!pimg) {
|
||||
sprintf(RErrorString, "could not get image");
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
mimg = NULL;
|
||||
|
||||
55
wrlib/xpm.c
55
wrlib/xpm.c
@@ -45,25 +45,37 @@ RGetImageFromXPMData(RContext *context, char **data)
|
||||
int i;
|
||||
int transp=-1;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
if (XpmCreateXpmImageFromData(data, &xpm, (XpmInfo *)NULL)!=XpmSuccess) {
|
||||
sprintf(RErrorString, "error converting XPM data");
|
||||
i = XpmCreateXpmImageFromData(data, &xpm, (XpmInfo *)NULL);
|
||||
if (i!=XpmSuccess) {
|
||||
switch (i) {
|
||||
case XpmOpenFailed:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case XpmFileInvalid:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
case XpmNoMemory:
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height<1 || xpm.width < 1) {
|
||||
sprintf(RErrorString, "can't convert XPM data. Size too weird");
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xpm.colorTable==NULL) {
|
||||
sprintf(RErrorString, "error converting XPM data");
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
sprintf(RErrorString, ":could not create RImage");
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
@@ -77,7 +89,7 @@ RGetImageFromXPMData(RContext *context, char **data)
|
||||
free(color_table[i]);
|
||||
}
|
||||
RDestroyImage(image);
|
||||
sprintf(RErrorString, "out of memory while converting XPM data");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
@@ -141,26 +153,37 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
int i;
|
||||
int transp=-1;
|
||||
|
||||
RErrorString[0] = 0;
|
||||
if (XpmReadFileToXpmImage(file, &xpm, (XpmInfo *)NULL)!=XpmSuccess) {
|
||||
sprintf(RErrorString, "error loading XPM file \"%s\"", file);
|
||||
i = XpmReadFileToXpmImage(file, &xpm, (XpmInfo *)NULL);
|
||||
if (i!=XpmSuccess) {
|
||||
switch (i) {
|
||||
case XpmOpenFailed:
|
||||
RErrorCode = RERR_OPEN;
|
||||
break;
|
||||
case XpmFileInvalid:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
case XpmNoMemory:
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
break;
|
||||
default:
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
if (xpm.height<1 || xpm.width < 1) {
|
||||
sprintf(RErrorString, "can't load XPM file \"%s\". Size too weird",
|
||||
file);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (xpm.colorTable==NULL) {
|
||||
sprintf(RErrorString, "error loading XPM file \"%s\"", file);
|
||||
RErrorCode = RERR_BADIMAGEFILE;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
image = RCreateImage(xpm.width, xpm.height, True);
|
||||
if (!image) {
|
||||
strcat(RErrorString, ":could not create RImage");
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
@@ -174,8 +197,7 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
free(color_table[i]);
|
||||
}
|
||||
RDestroyImage(image);
|
||||
sprintf(RErrorString, "out of memory while loading file \"%s\"",
|
||||
file);
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
XpmFreeXpmImage(&xpm);
|
||||
return NULL;
|
||||
}
|
||||
@@ -224,5 +246,4 @@ RLoadXPM(RContext *context, char *file, int index)
|
||||
return image;
|
||||
}
|
||||
|
||||
|
||||
#endif /* USE_XPM */
|
||||
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
|
||||
#ifdef XSHM
|
||||
|
||||
static int shmError;
|
||||
|
||||
static int (*oldErrorHandler)();
|
||||
@@ -52,6 +53,8 @@ errorHandler(Display *dpy, XErrorEvent *err)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -59,26 +62,27 @@ RXImage*
|
||||
RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
||||
{
|
||||
RXImage *rximg;
|
||||
Visual *visual = context->visual;
|
||||
|
||||
rximg = malloc(sizeof(RXImage));
|
||||
if (!rximg) {
|
||||
sprintf(RErrorString, "out of memory trying to create XImage");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef XSHM
|
||||
rximg->image = XCreateImage(context->dpy, context->visual, depth,
|
||||
rximg->image = XCreateImage(context->dpy, visual, depth,
|
||||
ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "error creating XImage");
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "out of memory trying to create XImage");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -86,42 +90,44 @@ RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
||||
if (!context->attribs->use_shared_memory) {
|
||||
retry_without_shm:
|
||||
rximg->is_shared = 0;
|
||||
rximg->image = XCreateImage(context->dpy, context->visual, depth,
|
||||
rximg->image = XCreateImage(context->dpy, visual, depth,
|
||||
ZPixmap, 0, NULL, width, height, 8, 0);
|
||||
if (!rximg->image) {
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "error creating XImage");
|
||||
RErrorCode = RERR_XERROR;
|
||||
return NULL;
|
||||
}
|
||||
rximg->image->data = malloc(rximg->image->bytes_per_line*height);
|
||||
if (!rximg->image->data) {
|
||||
XDestroyImage(rximg->image);
|
||||
free(rximg);
|
||||
sprintf(RErrorString, "out of memory trying to create XImage");
|
||||
RErrorCode = RERR_NOMEMORY;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
rximg->is_shared = 1;
|
||||
|
||||
rximg->image = XShmCreateImage(context->dpy, context->visual, depth,
|
||||
rximg->info.readOnly = False;
|
||||
|
||||
rximg->image = XShmCreateImage(context->dpy, visual, depth,
|
||||
ZPixmap, NULL, &rximg->info, width,
|
||||
height);
|
||||
|
||||
rximg->info.shmid = shmget(IPC_PRIVATE,
|
||||
rximg->image->bytes_per_line*height,
|
||||
IPC_CREAT|0770);
|
||||
IPC_CREAT|0666);
|
||||
if (rximg->info.shmid < 0) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
perror("wrlib:could not allocate shared memory segment:");
|
||||
perror("wrlib:could not allocate shared memory segment");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
||||
rximg->info.shmaddr = shmat(rximg->info.shmid, 0, 0);
|
||||
if (rximg->info.shmaddr == (void*)-1) {
|
||||
if ((int)rximg->info.shmaddr < 0) {
|
||||
context->attribs->use_shared_memory = 0;
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl:");
|
||||
perror("wrlib:shmctl");
|
||||
perror("wrlib:could not allocate shared memory");
|
||||
XDestroyImage(rximg->image);
|
||||
goto retry_without_shm;
|
||||
@@ -141,13 +147,12 @@ RCreateXImage(RContext *context, int depth, unsigned width, unsigned height)
|
||||
context->attribs->use_shared_memory = 0;
|
||||
XDestroyImage(rximg->image);
|
||||
if (shmdt(rximg->info.shmaddr) < 0)
|
||||
perror("wrlib:shmdt:");
|
||||
perror("wrlib:shmdt");
|
||||
if (shmctl(rximg->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl:");
|
||||
perror("wrlib:shmctl");
|
||||
printf("wrlib:error attaching shared memory segment to XImage\n");
|
||||
goto retry_without_shm;
|
||||
}
|
||||
|
||||
}
|
||||
#endif /* XSHM */
|
||||
|
||||
@@ -160,20 +165,19 @@ RDestroyXImage(RContext *context, RXImage *rximage)
|
||||
{
|
||||
#ifndef XSHM
|
||||
XDestroyImage(rximage->image);
|
||||
free(rximage);
|
||||
#else /* XSHM */
|
||||
if (rximage->is_shared) {
|
||||
XSync(context->dpy, False);
|
||||
XShmDetach(context->dpy, &rximage->info);
|
||||
XDestroyImage(rximage->image);
|
||||
if (shmdt(rximage->info.shmaddr) < 0)
|
||||
perror("wrlib:shmdt:");
|
||||
perror("wrlib:shmdt");
|
||||
if (shmctl(rximage->info.shmid, IPC_RMID, 0) < 0)
|
||||
perror("wrlib:shmctl:");
|
||||
perror("wrlib:shmctl");
|
||||
} else {
|
||||
XDestroyImage(rximage->image);
|
||||
}
|
||||
#endif
|
||||
free(rximage);
|
||||
}
|
||||
|
||||
|
||||
@@ -197,3 +201,19 @@ RPutXImage(RContext *context, Drawable d, GC gc, RXImage *ximage, int src_x,
|
||||
#endif /* XSHM */
|
||||
}
|
||||
|
||||
|
||||
#ifdef XSHM
|
||||
Pixmap
|
||||
R_CreateXImageMappedPixmap(RContext *context, RXImage *rximage)
|
||||
{
|
||||
Pixmap pix;
|
||||
|
||||
pix = XShmCreatePixmap(context->dpy, context->drawable,
|
||||
rximage->image->data, &rximage->info,
|
||||
rximage->image->width, rximage->image->height,
|
||||
rximage->image->depth);
|
||||
|
||||
return pix;
|
||||
}
|
||||
|
||||
#endif /* XSHM */
|
||||
|
||||
Reference in New Issue
Block a user