1
0
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:
dan
1998-10-21 14:43:47 +00:00
parent 9d2e6ef9f1
commit 9af1c6c415
222 changed files with 9132 additions and 4322 deletions

View File

@@ -15,6 +15,7 @@ libwraster_a_SOURCES = \
draw.c \
color.c \
load.c \
save.c \
gradient.c \
xpixmap.c \
convert.c \

View File

@@ -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

View File

@@ -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 */

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;
}

View File

@@ -130,7 +130,7 @@ RBlurImage(RImage *image)
return True;
outofmem:
sprintf(RErrorString, "out of memory");
RErrorCode = RERR_NOMEMORY;
#ifdef C_ALLOCA
alloca(0);
#endif

View File

@@ -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;

View File

@@ -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);

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}
}

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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;
}

View File

@@ -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
View 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);
}

View File

@@ -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);

View File

@@ -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();
}

View File

@@ -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);

View File

@@ -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 */

View File

@@ -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);
}

View File

@@ -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

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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 */