1
0
mirror of https://github.com/gryf/wmaker.git synced 2025-12-19 04:20:27 +01:00

changed format of RImage, added x86 speicfic optimized code

This commit is contained in:
kojima
2000-01-14 16:39:15 +00:00
parent f2de1c9dcf
commit a30475fc0f
23 changed files with 1527 additions and 1324 deletions

View File

@@ -4,7 +4,7 @@ AUTOMAKE_OPTIONS = no-dependencies
lib_LTLIBRARIES = libwraster.la
libwraster_la_LDFLAGS = -version-info 4:0:3
libwraster_la_LDFLAGS = -version-info 5:0:0
bin_SCRIPTS = get-wraster-flags
@@ -28,6 +28,7 @@ libwraster_la_SOURCES = \
gradient.c \
xpixmap.c \
convert.c \
x86_specific.c \
context.c \
misc.c \
scale.c \
@@ -42,6 +43,17 @@ libwraster_la_SOURCES = \
gif.c
# cant compile asm stuff with optimizations
x86_specific.lo: x86_specific.c
$(LTCOMPILE) -O0 -c $<
x86_specific.o: x86_specific.c
$(COMPILE) -O0 -c $<
INCLUDES = @DFLAGS@ @HEADER_SEARCH_PATH@
LIBLIST = $(top_builddir)/wrlib/libwraster.la @LIBRARY_SEARCH_PATH@ @GFXLIBS@ @XLIBS@ -lm

View File

@@ -97,7 +97,7 @@ AUTOMAKE_OPTIONS = no-dependencies
lib_LTLIBRARIES = libwraster.la
libwraster_la_LDFLAGS = -version-info 4:0:3
libwraster_la_LDFLAGS = -version-info 5:0:0
bin_SCRIPTS = get-wraster-flags
@@ -106,7 +106,7 @@ noinst_PROGRAMS = testgrad testdraw view
EXTRA_DIST = test.png tile.xpm ballot_box.xpm
include_HEADERS = wraster.h
libwraster_la_SOURCES = LookupCmap.c StdCmap.c StdCmap.h CrCmap.c DelCmap.c CmapAlloc.c raster.c draw.c color.c load.c save.c gradient.c xpixmap.c convert.c context.c misc.c scale.c convolve.c nxpm.c xpm.c xutil.c ppm.c png.c jpeg.c tiff.c gif.c
libwraster_la_SOURCES = LookupCmap.c StdCmap.c StdCmap.h CrCmap.c DelCmap.c CmapAlloc.c raster.c draw.c color.c load.c save.c gradient.c xpixmap.c convert.c x86_specific.c context.c misc.c scale.c convolve.c nxpm.c xpm.c xutil.c ppm.c png.c jpeg.c tiff.c gif.c
INCLUDES = @DFLAGS@ @HEADER_SEARCH_PATH@
@@ -142,8 +142,9 @@ X_PRE_LIBS = @X_PRE_LIBS@
libwraster_la_DEPENDENCIES = @ALLOCA@
libwraster_la_OBJECTS = LookupCmap.lo StdCmap.lo CrCmap.lo DelCmap.lo \
CmapAlloc.lo raster.lo draw.lo color.lo load.lo save.lo gradient.lo \
xpixmap.lo convert.lo context.lo misc.lo scale.lo convolve.lo nxpm.lo \
xpm.lo xutil.lo ppm.lo png.lo jpeg.lo tiff.lo gif.lo
xpixmap.lo convert.lo x86_specific.lo context.lo misc.lo scale.lo \
convolve.lo nxpm.lo xpm.lo xutil.lo ppm.lo png.lo jpeg.lo tiff.lo \
gif.lo
PROGRAMS = $(noinst_PROGRAMS)
testgrad_OBJECTS = testgrad.o
@@ -434,6 +435,13 @@ mostlyclean-generic distclean-generic clean-generic \
maintainer-clean-generic clean mostlyclean distclean maintainer-clean
# cant compile asm stuff with optimizations
x86_specific.lo: x86_specific.c
$(LTCOMPILE) -O0 -c $<
x86_specific.o: x86_specific.c
$(COMPILE) -O0 -c $<
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

View File

@@ -448,6 +448,8 @@ setupPseudoColorColormap(RContext *context)
*context->std_rgb_map = maps[theMap];
context->cmap = context->std_rgb_map->colormap;
XFree(maps);
return True;
@@ -510,6 +512,14 @@ gatherconfig(RContext *context, int screen_n)
context->attribs->colors_per_channel = i;
}
}
ptr = mygetenv("WRASTER_OPTIMIZE_FOR_SPEED", screen_n);
if (ptr) {
context->flags.optimize_for_speed = 1;
} else {
context->flags.optimize_for_speed = 0;
}
}
@@ -601,9 +611,9 @@ RCreateContext(Display *dpy, int screen_number, RContextAttributes *attribs)
/* get configuration from environment variables */
gatherconfig(context, screen_number);
#ifndef BENCH
_wraster_change_filter(context->attribs->scaling_filter);
#endif
if ((context->attribs->flags & RC_VisualID)) {
XVisualInfo *vinfo, templ;
int nret;

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,7 @@
/*
* Raster graphics library
*
* Copyright (c) 1997 Alfredo K. Kojima
* Copyright (c) 1997-2000 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
@@ -20,23 +20,6 @@
#include <config.h>
/* AIX requires this to be the first thing in the file. */
#ifdef __GNUC__
# define alloca __builtin_alloca
#else
# if HAVE_ALLOCA_H
# include <alloca.h>
# else
# ifdef _AIX
# pragma alloca
# else
# ifndef alloca /* predefined by HP cc +Olibcalls */
char *alloca ();
# endif
# endif
# endif
#endif
#include <stdlib.h>
#include <stdio.h>
@@ -57,84 +40,92 @@ int
RBlurImage(RImage *image)
{
register int x, y;
register int w, tmp;
unsigned char *r, *g, *b, *a;
unsigned char *pr=NULL, *pg=NULL, *pb=NULL, *pa=NULL;
register int tmp;
unsigned char *ptr, *nptr;
unsigned char *pptr=NULL, *tmpp;
int ch = image->format == RRGBAFormat ? 4 : 3;
#define MASK(c,pc,p) ((*c+ *c + *(c-1) + *(c+1) + pc[p] + pc[p-1] + pc[p+1] \
+ *(c+w) + *(c+w-1) + *(c+w+1))/10)
pr = (unsigned char*)alloca(image->width*sizeof(char));
if (!pr)
goto outofmem;
pg = (unsigned char*)alloca(image->width*sizeof(char));
if (!pg)
goto outofmem;
pb = (unsigned char*)alloca(image->width*sizeof(char));
if (!pb)
goto outofmem;
pa = (unsigned char*)alloca(image->width*sizeof(char));
if (!pa)
goto outofmem;
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
for (x=0; x<image->width; x++) {
pr[x] = *(r++);
pg[x] = *(g++);
pb[x] = *(b++);
pptr = malloc(image->width * ch);
if (!pptr) {
RErrorCode = RERR_NOMEMORY;
return False;
}
w = image->width;
#define MASK(prev, cur, next, ch)\
(*(prev-ch) + *prev + *(prev+ch)\
+*(cur-ch) + 2 * *cur + *(cur+ch)\
+*(next-ch) + *next + *(next+ch)) / 10
for (y=1; y<image->height-1; y++) {
pr[w-1] = r[w-1];
pg[w-1] = g[w-1];
pb[w-1] = b[w-1];
memcpy(pptr, image->data, image->width * ch);
pr[0] = *(r++);
pg[0] = *(g++);
pb[0] = *(b++);
ptr = image->data;
nptr = ptr + image->width*ch;
tmpp = pptr;
for (x=1; x<image->width-1; x++) {
tmp = *r;
*(r++) = MASK(r,pr,x);
pr[x] = tmp;
if (ch == 3) {
ptr+=3;
nptr+=3;
pptr+=3;
tmp = *g;
*(g++) = MASK(g,pg,x);
pg[x] = tmp;
for (y = 1; y < image->height-1; y++) {
tmp = *b;
*(b++) = MASK(b,pb,x);
pb[x] = tmp;
for (x = 1; x < image->width-1; x++) {
tmp = *ptr;
*ptr = MASK(pptr, ptr, nptr, 3);
*pptr = tmp;
ptr++; nptr++; pptr++;
tmp = *ptr;
*ptr = MASK(pptr, ptr, nptr, 3);
*pptr = tmp;
ptr++; nptr++; pptr++;
tmp = *ptr;
*ptr = MASK(pptr, ptr, nptr, 3);
*pptr = tmp;
ptr++; nptr++; pptr++;
}
pptr = tmpp;
ptr+=6;
nptr+=6;
pptr+=6;
}
} else {
ptr+=4;
nptr+=4;
pptr+=4;
for (y = 1; y < image->height-1; y++) {
for (x = 1; x < image->width-1; x++) {
tmp = *ptr;
*ptr = MASK(pptr, ptr, nptr, 4);
*pptr = tmp;
ptr++; nptr++; pptr++;
tmp = *ptr;
*ptr = MASK(pptr, ptr, nptr, 4);
*pptr = tmp;
ptr++; nptr++; pptr++;
tmp = *ptr;
*ptr = MASK(pptr, ptr, nptr, 4);
*pptr = tmp;
ptr++; nptr++; pptr++;
tmp = *ptr;
*ptr = MASK(pptr, ptr, nptr, 4);
*pptr = tmp;
ptr++; nptr++; pptr++;
}
pptr = tmpp;
ptr+=8;
nptr+=8;
pptr+=8;
}
r++;
g++;
b++;
}
#undef MASK
#ifdef C_ALLOCA
alloca(0);
#endif
return True;
outofmem:
RErrorCode = RERR_NOMEMORY;
#ifdef C_ALLOCA
alloca(0);
#endif
return False;
}
@@ -273,47 +264,45 @@ RSmoothImage(RImage *image)
{
register int x, y;
register int v, w;
unsigned char *r, *g, *b, *a;
unsigned char *ptr;
int ch = image->format == RRGBAFormat;
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
ptr = image->data;
w = image->width;
w = image->width*ch;
for (y=0; y<image->height - 1; y++) {
for (x=0; x<image->width - 1; x++) {
v = *r + 2 * *(r + 1) + 2 * *(r + w) + *(r + w + 1);
*(r++) = v/6;
v = *ptr + 2 * *(ptr + ch) + 2 * *(ptr + w) + *(ptr + w + ch);
*ptr = v/6;
v = *(ptr+1) + 2 * *(ptr+1 + ch) + 2 * *(ptr+1 + w) + *(ptr+1 + w + ch);
*(ptr+1) = v/6;
v = *ptr + 2 * *(ptr+2 + ch) + 2 * *(ptr+2 + w) + *(ptr+2 + w + ch);
*(ptr+2) = v/6;
v = *g + 2 * *(g + 1) + 2 * *(g + w) + *(g + w + 1);
*(g++) = v/6;
v = *b + 2 * *(b + 1) + 2 * *(b + w) + *(b + w + 1);
*(b++) = v/6;
ptr+= ch;
}
/* last column */
v = 3 * *r + 3 * *(r + w);
*(r++) = v/6;
v = 3 * *ptr + 3 * *(ptr + w);
*ptr = v/6;
v = 3 * *ptr + 3 * *(ptr+1 + w);
*(ptr+1) = v/6;
v = 3 * *ptr + 3 * *(ptr+2 + w);
*(ptr+2) = v/6;
v = 3 * *g + 3 * *(g + w);
*(g++) = v/6;
v = 3 * *b + 3 * *(b + w);
*(b++) = v/6;
ptr+= ch;
}
/* last line */
for (x=0; x<image->width - 1; x++) {
v = 3 * *r + 3 * *(r + 1);
*(r++) = v/6;
v = 3 * *ptr + 3 * *(ptr + ch);
*ptr = v/6;
v = 3 * *(ptr+1) + 3 * *(ptr+1 + ch);
*(ptr+1) = v/6;
v = 3 * *(ptr+2) + 3 * *(ptr+2 + ch);
*(ptr+2) = v/6;
v = 3 * *g + 3 * *(g + 1);
*(g++) = v/6;
v = 3 * *b + 3 * *(b + 1);
*(b++) = v/6;
ptr+= ch;
}
return True;

View File

@@ -3,6 +3,7 @@
* Raster graphics library
*
* Copyright (c) 1998 Dan Pascu
* Copyright (c) 2000 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
@@ -46,15 +47,20 @@ RGetPixel(RImage *image, int x, int y, RColor *color)
|| y < 0 || y >= image->height)
return False;
ofs = y*image->width + x;
color->red = image->data[0][ofs];
color->green = image->data[1][ofs];
color->blue = image->data[2][ofs];
/* If the image does not have alpha channel, we consider alpha 255 */
if (image->data[3])
color->alpha = image->data[3][ofs];
else
color->alpha = 255;
if (image->format == RRGBAFormat) {
ofs = (y*image->width + x) * 4;
color->red = image->data[ofs];
color->green = image->data[ofs++];
color->blue = image->data[ofs++];
color->alpha = image->data[ofs];
} else {
ofs = (y*image->width + x) * 3;
color->red = image->data[ofs++];
color->green = image->data[ofs++];
color->blue = image->data[ofs++];
/* If the image does not have alpha channel, we consider alpha 255 */
color->alpha = 255;
}
return True;
}
@@ -63,26 +69,26 @@ RGetPixel(RImage *image, int x, int y, RColor *color)
void
RPutPixel(RImage *image, int x, int y, RColor *color)
{
int ofs;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *ptr;
assert(image!=NULL);
assert(color!=NULL);
if (x < 0 || x >= image->width || y < 0 || y >= image->height)
return;
ofs = y*image->width + x;
sr = image->data[0] + ofs;
sg = image->data[1] + ofs;
sb = image->data[2] + ofs;
sa = image->data[3] + ofs;
if (image->format == RRGBAFormat) {
ptr = image->data + (y*image->width + x) * 4;
} else {
ptr = image->data + (y*image->width + x) * 3;
}
if (color->alpha==255) {
*sr = color->red;
*sg = color->green;
*sb = color->blue;
if (image->data[3])
*sa = 255;
*ptr++ = color->red;
*ptr++ = color->green;
*ptr++ = color->blue;
if (image->format == RRGBAFormat) {
*ptr = 255;
}
} else {
register int alpha, nalpha, r, g, b;
@@ -92,11 +98,12 @@ RPutPixel(RImage *image, int x, int y, RColor *color)
alpha = color->alpha;
nalpha = 255 - alpha;
*sr = (((int)*sr * nalpha) + (r * alpha))/256;
*sg = (((int)*sg * nalpha) + (g * alpha))/256;
*sb = (((int)*sb * nalpha) + (b * alpha))/256;
if (image->data[3])
*sa = alpha + ((int)*sa * nalpha)/256;
*ptr++ = (((int)*ptr * nalpha) + (r * alpha))/256;
*ptr++ = (((int)*ptr * nalpha) + (g * alpha))/256;
*ptr++ = (((int)*ptr * nalpha) + (b * alpha))/256;
if (image->format == RRGBAFormat) {
*ptr = alpha + ((int)*ptr * nalpha)/256;
}
}
}
@@ -106,15 +113,15 @@ operatePixel(RImage *image, int ofs, int operation, RColor *color)
{
unsigned char *sr, *sg, *sb, *sa;
register int alpha, nalpha, tmp;
int hasAlpha = image->data[3]!=NULL;
int hasAlpha = image->format == RRGBAFormat;
alpha = color->alpha;
nalpha = 255 - alpha;
sr = image->data[0] + ofs;
sg = image->data[1] + ofs;
sb = image->data[2] + ofs;
sa = image->data[3] + ofs;
sr = image->data + ofs*(hasAlpha ? 4 : 3);
sg = image->data + ofs*(hasAlpha ? 4 : 3) + 1;
sb = image->data + ofs*(hasAlpha ? 4 : 3) + 2;
sa = image->data + ofs*(hasAlpha ? 4 : 3) + 3;
switch (operation) {
case RClearOperation:
@@ -335,31 +342,35 @@ genericLine(RImage *image, int x0, int y0, int x1, int y1, RColor *color,
last = (polyline) ? du-1 : du;
if (color->alpha==255 || operation==RCopyOperation) {
unsigned char *sr, *sg, *sb, *sa;
unsigned char *ptr;
i = y0*image->width + x0;
sr = image->data[0] + i;
sg = image->data[1] + i;
sb = image->data[2] + i;
sa = image->data[3] + i;
if (image->format == RRGBAFormat)
i = (y0*image->width + x0) * 4;
else
i = (y0*image->width + x0) * 3;
ptr = image->data + i;
for (i=0; i<=last; i++) {
/* Draw the pixel */
*sr = color->red;
*sg = color->green;
*sb = color->blue;
if (image->data[3])
*sa = 255;
*ptr = color->red;
*(ptr+1) = color->green;
*(ptr+2) = color->blue;
if (image->format == RRGBAFormat)
*(ptr+3) = 255;
/* Compute error for NeXT Step */
err += dv2;
if (err >= du) {
sr += vofs; sg += vofs;
sb += vofs; sa += vofs;
if (image->format == RRGBAFormat)
ptr += vofs*4;
else
ptr += vofs*3;
err -= du2;
}
sr += uofs; sg += uofs;
sb += uofs; sa += uofs;
if (image->format == RRGBAFormat)
ptr += uofs*4;
else
ptr += uofs*3;
}
} else {
register int ofs = y0*image->width + x0;
@@ -592,4 +603,3 @@ ROperateSegments(RImage *image, int operation, RSegment *segs,
}
}

View File

@@ -44,6 +44,7 @@ RImage*
RLoadGIF(RContext *context, char *file, int index)
{
RImage *image = NULL;
#if 0
GifFileType *gif = NULL;
GifPixelType *buffer = NULL;
int i, j, k, ofs = 0;
@@ -208,7 +209,7 @@ did_not_get_any_errors:
if (gif)
DGifCloseFile(gif);
#endif
return image;
}

View File

@@ -2,7 +2,7 @@
*
* Raster graphics library
*
* Copyright (c) 1997 Alfredo K. Kojima
* Copyright (c) 1997-2000 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
@@ -116,15 +116,13 @@ renderHGradient(unsigned width, unsigned height, int r0, int g0, int b0,
int i;
unsigned long r, g, b, dr, dg, db;
RImage *image;
unsigned char *rp, *gp, *bp;
unsigned char *ptr;
image = RCreateImage(width, height, False);
if (!image) {
return NULL;
}
rp = image->data[0];
gp = image->data[1];
bp = image->data[2];
ptr = image->data;
r = r0 << 16;
g = g0 << 16;
@@ -135,20 +133,17 @@ renderHGradient(unsigned width, unsigned height, int r0, int g0, int b0,
db = ((bf-b0)<<16)/(int)width;
/* render the first line */
for (i=0; i<width; i++) {
*(rp++) = (unsigned char)(r>>16);
*(gp++) = (unsigned char)(g>>16);
*(bp++) = (unsigned char)(b>>16);
*(ptr++) = (unsigned char)(r>>16);
*(ptr++) = (unsigned char)(g>>16);
*(ptr++) = (unsigned char)(b>>16);
r += dr;
g += dg;
b += db;
}
/* copy the first line to the other lines */
for (i=1; i<height; i++) {
memcpy(&(image->data[0][i*width]), image->data[0], width);
memcpy(&(image->data[1][i*width]), image->data[1], width);
memcpy(&(image->data[2][i*width]), image->data[2], width);
memcpy(&(image->data[i*width*3]), image->data, width*3);
}
return image;
}
@@ -170,18 +165,18 @@ static RImage*
renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0,
int rf, int gf, int bf)
{
int i;
int i, j;
unsigned long r, g, b, dr, dg, db;
RImage *image;
unsigned char *rp, *gp, *bp;
unsigned char *ptr;
unsigned int *iptr;
unsigned char rr, gg, bb;
image = RCreateImage(width, height, False);
if (!image) {
return NULL;
}
rp = image->data[0];
gp = image->data[1];
bp = image->data[2];
iptr = (unsigned int*)ptr = image->data;
r = r0<<16;
g = g0<<16;
@@ -191,13 +186,22 @@ renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0,
dg = ((gf-g0)<<16)/(int)height;
db = ((bf-b0)<<16)/(int)height;
for (i=0; i<height; i++) {
memset(rp, (unsigned char)(r>>16), width);
memset(gp, (unsigned char)(g>>16), width);
memset(bp, (unsigned char)(b>>16), width);
rp+=width;
gp+=width;
bp+=width;
rr = r>>16;
gg = g>>16;
bb = b>>16;
for (j=0; j<width/4; j++) {
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
}
switch (width%4) {
case 3: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
case 2: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
case 1: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
}
r+=dr;
g+=dg;
b+=db;
@@ -219,67 +223,6 @@ renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0,
* None
*----------------------------------------------------------------------
*/
#if 0
/* 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,
int rf, int gf, int bf)
{
int x, y;
float from_red,from_green,from_blue;
float to_red,to_green,to_blue;
float dr,dg,db,dx,dy,w,h,xred,yred,xgreen,ygreen,xblue,yblue;
RImage *image;
unsigned char *rp, *gp, *bp;
image = RCreateImage(width, height, False);
if (!image) {
return NULL;
}
rp = image->data[0];
gp = image->data[1];
bp = image->data[2];
from_red = (float)r0;
from_green = (float)g0;
from_blue = (float)b0;
to_red = (float)rf;
to_green = (float)gf;
to_blue = (float)bf;
w = (float) width;
h = (float) height;
dr = (to_red - from_red);
dg = (to_green - from_green);
db = (to_blue - from_blue);
for (y=0; y<height; y++) {
dy = y / h;
yred = dr * dy + from_red;
ygreen = dg * dy + from_green;
yblue = db * dy + from_blue;
for (x=0; x<width; x++) {
dx = x / w;
xred = dr * dx + from_red;
xgreen = dg * dx + from_green;
xblue = db * dx + from_blue;
*(rp++) = (unsigned char)((xred + yred)/2);
*(gp++) = (unsigned char)((xgreen + ygreen)/2);
*(bp++) = (unsigned char)((xblue + yblue)/2);
}
}
return image;
}
#endif
static RImage*
@@ -287,8 +230,8 @@ renderDGradient(unsigned width, unsigned height, int r0, int g0, int b0,
int rf, int gf, int bf)
{
RImage *image, *tmp;
float a;
int i, offset;
unsigned long a;
int i, j, offset;
if (width == 1)
return renderVGradient(width, height, r0, g0, b0, rf, gf, bf);
@@ -306,14 +249,13 @@ renderDGradient(unsigned width, unsigned height, int r0, int g0, int b0,
return NULL;
}
a = ((float)(width - 1))/((float)(height - 1));
a = (((width - 1)<<16) / ((height - 1)<<16)) * 3;
width *= 3;
/* copy the first line to the other lines with corresponding offset */
for (i=0; i<height; i++) {
offset = (int)(a*i+0.5);
memcpy(&(image->data[0][i*width]), &(tmp->data[0][offset]), width);
memcpy(&(image->data[1][i*width]), &(tmp->data[1][offset]), width);
memcpy(&(image->data[2][i*width]), &(tmp->data[2][offset]), width);
for (i=0, j=0, offset = 0; i<height; i++, j+= width) {
offset += a;
memcpy(&(image->data[j]), &(tmp->data[(offset>>16)]), width);
}
RDestroyImage(tmp);
return image;
@@ -326,7 +268,7 @@ renderMHGradient(unsigned width, unsigned height, RColor **colors, int count)
int i, j, k;
unsigned long r, g, b, dr, dg, db;
RImage *image;
unsigned char *rp, *gp, *bp;
unsigned char *ptr;
unsigned width2;
@@ -336,9 +278,7 @@ renderMHGradient(unsigned width, unsigned height, RColor **colors, int count)
if (!image) {
return NULL;
}
rp = image->data[0];
gp = image->data[1];
bp = image->data[2];
ptr = image->data;
if (count > width)
count = width;
@@ -360,9 +300,9 @@ renderMHGradient(unsigned width, unsigned height, RColor **colors, int count)
dg = ((int)(colors[i]->green - colors[i-1]->green)<<16)/(int)width2;
db = ((int)(colors[i]->blue - colors[i-1]->blue) <<16)/(int)width2;
for (j=0; j<width2; j++) {
*(rp++) = (unsigned char)(r>>16);
*(gp++) = (unsigned char)(g>>16);
*(bp++) = (unsigned char)(b>>16);
*ptr++ = (unsigned char)(r>>16);
*ptr++ = (unsigned char)(g>>16);
*ptr++ = (unsigned char)(b>>16);
r += dr;
g += dg;
b += db;
@@ -373,16 +313,14 @@ renderMHGradient(unsigned width, unsigned height, RColor **colors, int count)
b = colors[i]->blue << 16;
}
for (j=k; j<width; j++) {
*(rp++) = (unsigned char)(r>>16);
*(gp++) = (unsigned char)(g>>16);
*(bp++) = (unsigned char)(b>>16);
*ptr++ = (unsigned char)(r>>16);
*ptr++ = (unsigned char)(g>>16);
*ptr++ = (unsigned char)(b>>16);
}
/* copy the first line to the other lines */
for (i=1; i<height; i++) {
memcpy(&(image->data[0][i*width]), image->data[0], width);
memcpy(&(image->data[1][i*width]), image->data[1], width);
memcpy(&(image->data[2][i*width]), image->data[2], width);
memcpy(&(image->data[i*width*3]), image->data, width*3);
}
return image;
}
@@ -396,8 +334,10 @@ renderMVGradient(unsigned width, unsigned height, RColor **colors, int count)
int i, j, k;
unsigned long r, g, b, dr, dg, db;
RImage *image;
unsigned char *rp, *gp, *bp;
unsigned char *ptr, *tmp;
unsigned height2;
int x;
unsigned char rr, gg, bb;
assert(count > 2);
@@ -406,9 +346,7 @@ renderMVGradient(unsigned width, unsigned height, RColor **colors, int count)
if (!image) {
return NULL;
}
rp = image->data[0];
gp = image->data[1];
bp = image->data[2];
ptr = image->data;
if (count > height)
count = height;
@@ -428,13 +366,23 @@ renderMVGradient(unsigned width, unsigned height, RColor **colors, int count)
dr = ((int)(colors[i]->red - colors[i-1]->red) <<16)/(int)height2;
dg = ((int)(colors[i]->green - colors[i-1]->green)<<16)/(int)height2;
db = ((int)(colors[i]->blue - colors[i-1]->blue) <<16)/(int)height2;
for (j=0; j<height2; j++) {
memset(rp, (unsigned char)(r>>16), width);
memset(gp, (unsigned char)(g>>16), width);
memset(bp, (unsigned char)(b>>16), width);
rp+=width;
gp+=width;
bp+=width;
rr = r>>16;
gg = g>>16;
bb = b>>16;
for (x=0; x<width/4; x++) {
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
}
switch (width%4) {
case 3: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
case 2: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
case 1: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
}
r += dr;
g += dg;
b += db;
@@ -444,13 +392,27 @@ renderMVGradient(unsigned width, unsigned height, RColor **colors, int count)
g = colors[i]->green << 16;
b = colors[i]->blue << 16;
}
for (j=k; j<height; j++) {
memset(rp, (unsigned char)(r>>16), width);
memset(gp, (unsigned char)(g>>16), width);
memset(bp, (unsigned char)(b>>16), width);
rp+=width;
gp+=width;
bp+=width;
rr = r>>16;
gg = g>>16;
bb = b>>16;
tmp = ptr;
for (x=0; x<width/4; x++) {
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
*ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
}
switch (width%4) {
case 3: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
case 2: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
case 1: *ptr++ = rr; *ptr++ = gg; *ptr++ = bb;
}
for (j=k+1; j<width; j++) {
memcpy(ptr, tmp, width*3);
ptr += width*3;
}
return image;
@@ -498,10 +460,8 @@ renderMDGradient(unsigned width, unsigned height, RColor **colors, int count)
/* copy the first line to the other lines with corresponding offset */
for (i=0; i<height; i++) {
offset = (int)(a*i+0.5);
memcpy(&(image->data[0][i*width]), &(tmp->data[0][offset]), width);
memcpy(&(image->data[1][i*width]), &(tmp->data[1][offset]), width);
memcpy(&(image->data[2][i*width]), &(tmp->data[2][offset]), width);
offset = (int)(a*i+0.5)*3;
memcpy(&(image->data[i*width*3]), &(tmp->data[offset]), width*3);
}
RDestroyImage(tmp);
return image;

View File

@@ -77,8 +77,8 @@ typedef struct my_error_mgr * my_error_ptr;
* Here's the routine that will replace the standard error_exit method:
*/
void
my_error_exit (j_common_ptr cinfo)
static void
my_error_exit(j_common_ptr cinfo)
{
/* cinfo->err really points to a my_error_mgr struct, so coerce pointer */
my_error_ptr myerr = (my_error_ptr) cinfo->err;
@@ -97,9 +97,9 @@ RLoadJPEG(RContext *context, char *file_name, int index)
{
RImage *image = NULL;
struct jpeg_decompress_struct cinfo;
int i, j;
unsigned char *r, *g, *b;
JSAMPROW buffer[1];
int i;
unsigned char *ptr;
JSAMPROW buffer[1], bptr;
FILE *file;
/* We use our private extension JPEG error handler.
* Note that this struct must live as long as the main JPEG parameter
@@ -131,7 +131,7 @@ RLoadJPEG(RContext *context, char *file_name, int index)
jpeg_read_header(&cinfo, TRUE);
buffer[0] = (JSAMPROW)malloc(cinfo.image_width*cinfo.num_components);
bptr = buffer[0] = (JSAMPROW)malloc(cinfo.image_width*cinfo.num_components);
if (!buffer[0]) {
RErrorCode = RERR_NOMEMORY;
goto bye;
@@ -145,26 +145,47 @@ RLoadJPEG(RContext *context, char *file_name, int index)
cinfo.do_fancy_upsampling = FALSE;
cinfo.do_block_smoothing = FALSE;
jpeg_calc_output_dimensions(&cinfo);
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
if (context->flags.optimize_for_speed)
image = RCreateImage(cinfo.image_width, cinfo.image_height, True);
else
image = RCreateImage(cinfo.image_width, cinfo.image_height, False);
if (!image) {
RErrorCode = RERR_NOMEMORY;
goto bye;
}
jpeg_start_decompress(&cinfo);
r = image->data[0];
g = image->data[1];
b = image->data[2];
ptr = image->data;
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1);
for (i=0,j=0; i<cinfo.image_width; i++) {
if (cinfo.out_color_space==JCS_RGB) {
*(r++) = buffer[0][j++];
*(g++) = buffer[0][j++];
*(b++) = buffer[0][j++];
} else {
*(r++) = *(g++) = *(b++) = buffer[0][j++];
if (cinfo.out_color_space==JCS_RGB) {
if (context->flags.optimize_for_speed) {
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1);
bptr = buffer[0];
for (i=0; i<cinfo.image_width; i++) {
*ptr++ = *bptr++;
*ptr++ = *bptr++;
*ptr++ = *bptr++;
ptr++; /* skip alpha channel */
}
}
} else {
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1);
bptr = buffer[0];
memcpy(ptr, bptr, cinfo.image_width*3);
ptr += cinfo.image_width*3;
}
}
} else {
while (cinfo.output_scanline < cinfo.output_height) {
jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1);
bptr = buffer[0];
for (i=0; i<cinfo.image_width; i++) {
*ptr++ = *ptr++ = *ptr++ = *bptr++;
}
}
}

View File

@@ -1,7 +1,7 @@
/*
* Raster graphics library
*
* Copyright (c) 1997 Alfredo K. Kojima
* Copyright (c) 1997-2000 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
@@ -17,7 +17,6 @@
* 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 <stdlib.h>
@@ -92,24 +91,40 @@ RBevelImage(RImage *image, int bevel_type)
void
RClearImage(RImage *image, RColor *color)
{
int bytes;
bytes = image->width*image->height;
if (color->alpha==255) {
memset(image->data[0], color->red, bytes);
memset(image->data[1], color->green, bytes);
memset(image->data[2], color->blue, bytes);
if (image->data[3])
memset(image->data[3], 0xff, bytes);
if (image->format == RRGBAFormat) {
unsigned char *d = image->data;
int i;
for (i = 0; i < image->width; i++) {
*d++ = color->red;
*d++ = color->green;
*d++ = color->blue;
*d++ = 0xff;
}
for (i = 1; i < image->height; i++, d += image->width*4) {
memcpy(d, image->data, image->width*4);
}
} else {
unsigned char *d = image->data;
int i;
for (i = 0; i < image->width; i++) {
*d++ = color->red;
*d++ = color->green;
*d++ = color->blue;
}
for (i = 1; i < image->height; i++, d += image->width*3) {
memcpy(d, image->data, image->width*3);
}
}
} else {
register int i;
unsigned char *dr, *dg, *db;
int bytes = image->width*image->height;
int i;
unsigned char *d;
int alpha, nalpha, r, g, b;
dr = image->data[0];
dg = image->data[1];
db = image->data[2];
d = image->data;
alpha = color->alpha;
r = color->red * alpha;
@@ -118,15 +133,19 @@ RClearImage(RImage *image, RColor *color)
nalpha = 255 - alpha;
for (i=0; i<bytes; i++) {
*dr = (((int)*dr * nalpha) + r)/256;
*dg = (((int)*dg * nalpha) + g)/256;
*db = (((int)*db * nalpha) + b)/256;
dr++; dg++; db++;
*d = (((int)*d * nalpha) + r)/256;
d++;
*d = (((int)*d * nalpha) + g)/256;
d++;
*d = (((int)*d * nalpha) + b)/256;
d++;
if (image->format == RRGBAFormat) {
d++;
}
}
}
}
const char*
RMessageForError(int errorCode)
{
@@ -172,4 +191,3 @@ RMessageForError(int errorCode)
return "internal error";
}
}

View File

@@ -156,10 +156,13 @@ RGetImageFromXPMData(RContext *context, char **data)
return NULL;
}
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
r = image->data;
g = image->data+1;
b = image->data+2;
if (image->format == RRGBAFormat)
a = image->data+3;
else
a = NULL;
for (i=0; i<h; i++) {
if (csize==1) {
@@ -332,10 +335,13 @@ RLoadXPM(RContext *context, char *file, int index)
return NULL;
}
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
r = image->data;
g = image->data+1;
b = image->data+2;
if (image->format == RRGBAFormat)
a = image->data+3;
else
a = NULL;
for (i=0; i<h; i++) {
if (!fgets(buffer, bsize, f))
@@ -557,10 +563,13 @@ RSaveXPM(RImage *image, char *filename)
fprintf(file, "static char *image[] = {\n");
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
r = image->data;
g = image->data+1;
b = image->data+2;
if (image->format == RRGBAFormat)
a = image->data+3;
else
a = NULL;
/* first pass: make colormap for the image */
if (a)
@@ -595,11 +604,14 @@ RSaveXPM(RImage *image, char *filename)
i = 0;
outputcolormap(file, colormap, charsPerPixel);
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
r = image->data;
g = image->data+1;
b = image->data+2;
if (image->format == RRGBAFormat)
a = image->data+3;
else
a = NULL;
/* write data */
for (y = 0; y < image->height; y++) {

View File

@@ -65,7 +65,7 @@ RLoadPNG(RContext *context, char *file, int index)
png_uint_32 width, height;
int depth, junk, color_type;
png_bytep *png_rows;
unsigned char *r, *g, *b, *a;
unsigned char *ptr;
f = fopen(file, "r");
if (!f) {
@@ -207,27 +207,19 @@ RLoadPNG(RContext *context, char *file, int index)
fclose(f);
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
ptr = image->data;
/* convert to RImage */
if (alpha) {
for (y=0; y<height; y++) {
for (x=0, i=0; x<width; x++) {
*(r++) = *(png_rows[y]+i++);
*(g++) = *(png_rows[y]+i++);
*(b++) = *(png_rows[y]+i++);
*(a++) = *(png_rows[y]+i++);
for (x=0, i=width*4; x<i; x++, ptr++) {
*ptr = *(png_rows[y]+x);
}
}
} else {
for (y=0; y<height; y++) {
for (x=0, i=0; x<width; x++) {
*(r++) = *(png_rows[y]+i++);
*(g++) = *(png_rows[y]+i++);
*(b++) = *(png_rows[y]+i++);
for (x=0, i=width*3; x<i; x++, ptr++) {
*ptr = *(png_rows[y]+x);
}
}
}

View File

@@ -43,10 +43,27 @@ load_graymap(char *file_name, FILE *file, int w, int h, int max, int raw)
} else {
if (max<256) {
if (!fgets(image->data[0], w*h, file))
goto short_file;
memcpy(image->data[0], image->data[1], w*h);
memcpy(image->data[0], image->data[2], w*h);
int x, y;
char *buf, *ptr;
buf = malloc(w);
if (!buf) {
return NULL;
}
ptr = image->data;
for (y = 0; y < h; y++) {
if (!fgets(buf, w, file)) {
free(buf);
goto short_file;
}
for (x = 0; x < w; x++) {
*(ptr++) = buf[x];
*(ptr++) = buf[x];
*(ptr++) = buf[x];
}
}
free(buf);
} else {
}
@@ -66,15 +83,13 @@ load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
RImage *image;
int i;
char buf[3];
char *r, *g, *b;
char *ptr;
image = RCreateImage(w, h, 0);
if (!image) {
return NULL;
}
r = image->data[0];
g = image->data[1];
b = image->data[2];
ptr = image->data;
if (!raw) {
} else {
@@ -83,9 +98,9 @@ load_pixmap(char *file_name, FILE *file, int w, int h, int max, int raw)
while (i < w*h) {
if (fread(buf, 1, 3, file)!=3)
goto short_file;
*(r++) = buf[0];
*(g++) = buf[1];
*(b++) = buf[2];
*(ptr++) = buf[0];
*(ptr++) = buf[1];
*(ptr++) = buf[2];
i++;
}
} else {

View File

@@ -2,7 +2,7 @@
*
* Raster graphics library
*
* Copyright (c) 1997 Alfredo K. Kojima
* Copyright (c) 1997-2000 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
@@ -35,12 +35,13 @@ char *WRasterLibVersion="0.9";
int RErrorCode=RERR_NONE;
#define HAS_ALPHA(I) ((I)->format == RRGBAFormat)
RImage*
RCreateImage(unsigned width, unsigned height, int alpha)
{
RImage *image=NULL;
int i;
assert(width>0 && height>0);
@@ -53,22 +54,22 @@ RCreateImage(unsigned width, unsigned height, int alpha)
memset(image, 0, sizeof(RImage));
image->width = width;
image->height = height;
for (i=0; i<3+(alpha?1:0); i++) {
image->data[i] = malloc(width*height);
if (!image->data[i])
goto error;
if (alpha) {
image->format = RRGBAFormat;
} else {
image->format = RRGBFormat;
}
/* the +4 is to give extra bytes at the end of the buffer,
* so that we can optimize image conversion for MMX(tm).. see convert.c
*/
image->data = malloc(width * height * (alpha ? 4 : 3) + 4);
if (!image->data) {
RErrorCode = RERR_NOMEMORY;
free(image);
image = NULL;
}
return image;
error:
for (i=0; i<4; i++) {
if (image->data[i])
free(image->data[i]);
}
if (image)
free(image);
RErrorCode = RERR_NOMEMORY;
return NULL;
return image;
}
@@ -80,16 +81,13 @@ RCloneImage(RImage *image)
assert(image!=NULL);
new_image = RCreateImage(image->width, image->height, image->data[3]!=NULL);
new_image = RCreateImage(image->width, image->height, HAS_ALPHA(image));
if (!new_image)
return NULL;
new_image->background = image->background;
memcpy(new_image->data[0], image->data[0], image->width*image->height);
memcpy(new_image->data[1], image->data[1], image->width*image->height);
memcpy(new_image->data[2], image->data[2], image->width*image->height);
if (image->data[3])
memcpy(new_image->data[3], image->data[3], image->width*image->height);
memcpy(new_image->data, image->data,
image->width*image->height*(HAS_ALPHA(image) ? 4 : 3));
return new_image;
}
@@ -100,8 +98,7 @@ RGetSubImage(RImage *image, int x, int y, unsigned width, unsigned height)
{
int i, ofs;
RImage *new_image;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *dr, *dg, *db, *da;
unsigned total_line_size, line_size;
assert(image!=NULL);
assert(x>=0 && y>=0);
@@ -113,37 +110,20 @@ RGetSubImage(RImage *image, int x, int y, unsigned width, unsigned height)
if (y+height > image->height)
height = image->height-y;
new_image = RCreateImage(width, height, image->data[3]!=NULL);
new_image = RCreateImage(width, height, HAS_ALPHA(image));
if (!new_image)
return NULL;
new_image->background = image->background;
ofs = image->width*y+x;
sr = image->data[0]+ofs;
sg = image->data[1]+ofs;
sb = image->data[2]+ofs;
sa = image->data[3]+ofs;
total_line_size = image->width * (HAS_ALPHA(image) ? 4 : 3);
line_size = width * (HAS_ALPHA(image) ? 4 : 3);
dr = new_image->data[0];
dg = new_image->data[1];
db = new_image->data[2];
da = new_image->data[3];
ofs = x*(HAS_ALPHA(image) ? 4 : 3);
for (i=0; i<height; i++) {
memcpy(dr, sr, width);
memcpy(dg, sg, width);
memcpy(db, sb, width);
sr += image->width;
sg += image->width;
sb += image->width;
dr += width;
dg += width;
db += width;
if (da) {
memcpy(da, sa, width);
sa += image->width;
da += width;
}
memcpy(&new_image->data[i*line_size],
&image->data[i*total_line_size+ofs], line_size);
}
return new_image;
}
@@ -152,14 +132,9 @@ RGetSubImage(RImage *image, int x, int y, unsigned width, unsigned height)
void
RDestroyImage(RImage *image)
{
int i;
assert(image!=NULL);
for (i=0; i<4; i++) {
if (image->data[i])
free(image->data[i]);
}
free(image->data);
free(image);
}
@@ -174,41 +149,60 @@ RDestroyImage(RImage *image)
void
RCombineImages(RImage *image, RImage *src)
{
register int i;
unsigned char *dr, *dg, *db, *da;
unsigned char *sr, *sg, *sb, *sa;
int alpha, calpha;
assert(image->width == src->width);
assert(image->height == src->height);
dr = image->data[0];
dg = image->data[1];
db = image->data[2];
da = image->data[3];
if (!HAS_ALPHA(src)) {
if (!HAS_ALPHA(image)) {
memcpy(image->data, src->data, image->height*image->width*3);
} else {
int x, y;
unsigned char *d, *s;
sr = src->data[0];
sg = src->data[1];
sb = src->data[2];
sa = src->data[3];
if (!sa) {
memcpy(dr, sr, image->height*image->width);
memcpy(dg, sg, image->height*image->width);
memcpy(db, sb, image->height*image->width);
d = image->data;
s = src->data;
for (y = 0; y < image->height; y++) {
for (x = 0; x < image->width; x++) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
d++;
}
}
}
} else {
for (i=0; i<image->height*image->width; i++) {
alpha = *sa;
calpha = 255 - *sa;
*dr = (((int)*dr * calpha) + ((int)*sr * alpha))/256;
*dg = (((int)*dg * calpha) + ((int)*sg * alpha))/256;
*db = (((int)*db * calpha) + ((int)*sb * alpha))/256;
if (image->data[3])
*da++ |= *sa;
dr++; dg++; db++;
sr++; sg++; sb++;
sa++;
register int i;
unsigned char *d;
unsigned char *s;
int alpha, calpha;
d = image->data;
s = src->data;
if (!HAS_ALPHA(image)) {
for (i=0; i<image->height*image->width; i++) {
alpha = *(s+3);
calpha = 255 - alpha;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
d++; s++;
s++;
}
} else {
for (i=0; i<image->height*image->width; i++) {
alpha = *(s+3);
calpha = 255 - alpha;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
d++; s++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
d++; s++;
*d++ |= *s++;
}
}
}
}
@@ -220,62 +214,58 @@ void
RCombineImagesWithOpaqueness(RImage *image, RImage *src, int opaqueness)
{
register int i;
unsigned char *dr, *dg, *db, *da;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *d;
unsigned char *s;
int c_opaqueness;
assert(image->width == src->width);
assert(image->height == src->height);
dr = image->data[0];
dg = image->data[1];
db = image->data[2];
da = image->data[3];
sr = src->data[0];
sg = src->data[1];
sb = src->data[2];
sa = src->data[3];
d = image->data;
s = src->data;
c_opaqueness = 255 - opaqueness;
#define OP opaqueness
if (!src->data[3]) {
if (!HAS_ALPHA(src)) {
int dalpha = HAS_ALPHA(image);
#define COP c_opaqueness
for (i=0; i<image->width*image->height; i++) {
*dr = (((int)*dr *(int)COP) + ((int)*sr *(int)OP))/256;
*dg = (((int)*dg *(int)COP) + ((int)*sg *(int)OP))/256;
*db = (((int)*db *(int)COP) + ((int)*sb *(int)OP))/256;
dr++; dg++; db++;
sr++; sg++; sb++;
for (i=0; i < image->width*image->height; i++) {
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
d++; s++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
d++; s++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
d++; s++;
if (dalpha) {
d++;
}
}
#undef COP
} else {
int tmp;
if (image->data[3]) {
if (!HAS_ALPHA(image)) {
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++;
tmp = (*(s+3) * opaqueness)/256;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
d++; s++;
s++;
}
} 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++;
tmp = (*(s+3) * opaqueness)/256;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
d++; s++;
*d = (((int)*d * (255-tmp)) + ((int)*s * tmp))/256;
d++; s++;
*d |= tmp;
d++; s++;
}
}
}
@@ -288,8 +278,8 @@ RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
unsigned height, int dx, int dy)
{
int x, y, dwi, swi;
unsigned char *dr, *dg, *db;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *d;
unsigned char *s;
int alpha, calpha;
@@ -299,46 +289,70 @@ RCombineArea(RImage *image, RImage *src, int sx, int sy, unsigned width,
assert(sy + height <= src->height);
assert(sx + width <= src->width);
dr = image->data[0] + dy*(int)image->width + dx;
dg = image->data[1] + dy*(int)image->width + dx;
db = image->data[2] + dy*(int)image->width + dx;
sr = src->data[0] + sy*(int)src->width + sx;
sg = src->data[1] + sy*(int)src->width + sx;
sb = src->data[2] + sy*(int)src->width + sx;
sa = src->data[3] + sy*(int)src->width + sx;
swi = src->width - width;
dwi = image->width - width;
if (height > image->height - dy)
height = image->height - dy;
if (!src->data[3]) {
for (y=sy; y<height+sy; y++) {
for (x=sx; x<width+sx; x++) {
*(dr++) = *(sr++);
*(dg++) = *(sg++);
*(db++) = *(sb++);
if (!HAS_ALPHA(src)) {
if (!HAS_ALPHA(image)) {
swi = (src->width - width) * 3;
dwi = (image->width - width) * 3;
d = image->data + dy*(int)image->width*3 + dx;
s = src->data + sy*(int)src->width*3 + sx;
for (y=0; y < height; y++) {
memcpy(d, s, width*3);
d += dwi;
s += swi;
}
} else {
swi = (src->width - width) * 3;
dwi = (image->width - width) * 4;
d = image->data + dy*(int)image->width*4 + dx;
s = src->data + sy*(int)src->width*3 + sx;
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
*d++ = *s++;
*d++ = *s++;
*d++ = *s++;
d++;
}
d += dwi;
s += swi;
}
dr += dwi; dg += dwi; db += dwi;
sr += swi; sg += swi; sb += swi;
}
} else {
for (y=sy; y<height+sy; y++) {
for (x=sx; x<width+sx; x++) {
alpha = *sa;
int dalpha = HAS_ALPHA(image);
swi = (src->width - width) * 4;
s = src->data + sy*(int)src->width*4 + sx;
if (!HAS_ALPHA(image)) {
dwi = (image->width - width) * 3;
d = image->data + (dy*(int)image->width+dx)*3;
} else {
dwi = (image->width - width) * 4;
d = image->data + (dy*(int)image->width+dx)*4;
}
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
alpha = *(s+3);
calpha = 255 - alpha;
*dr = (((int)*dr * calpha) + ((int)*sr * alpha))/256;
*dg = (((int)*dg * calpha) + ((int)*sg * alpha))/256;
*db = (((int)*db * calpha) + ((int)*sb * alpha))/256;
dr++; dg++; db++;
sr++; sg++; sb++;
sa++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
s++; d++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
s++; d++;
*d = (((int)*d * calpha) + ((int)*s * alpha))/256;
s++; d++;
s++;
if (dalpha)
d++;
}
dr += dwi; dg += dwi; db += dwi;
sr += swi; sg += swi; sb += swi;
sa += swi;
d += dwi;
s += swi;
}
}
}
@@ -351,8 +365,9 @@ RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
{
int x, y, dwi, swi;
int c_opaqueness;
unsigned char *dr, *dg, *db;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *d;
unsigned char *s;
int dalpha = HAS_ALPHA(image);
assert(dy <= image->height);
assert(dx <= image->width);
@@ -360,17 +375,6 @@ RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
assert(sy <= height);
assert(sx <= width);
dr = image->data[0] + dy*image->width + dx;
dg = image->data[1] + dy*image->width + dx;
db = image->data[2] + dy*image->width + dx;
sr = src->data[0] + sy*src->width;
sg = src->data[1] + sy*src->width;
sb = src->data[2] + sy*src->width;
sa = src->data[3] + sy*src->width;
swi = src->width - width;
dwi = image->width - width;
/* clip */
width -= sx;
@@ -381,36 +385,51 @@ RCombineAreaWithOpaqueness(RImage *image, RImage *src, int sx, int sy,
c_opaqueness = 255 - opaqueness;
#define OP opaqueness
if (!src->data[3]) {
if (!HAS_ALPHA(src)) {
#define COP c_opaqueness
for (y=0; y<height; y++) {
for (x=0; x<width; x++) {
*dr = (((int)*dr *(int)COP) + ((int)*sr *(int)OP))/256;
*dg = (((int)*dg *(int)COP) + ((int)*sg *(int)OP))/256;
*db = (((int)*db *(int)COP) + ((int)*sb *(int)OP))/256;
dr++; dg++; db++;
sr++; sg++; sb++;
s = src->data + sy*src->width*3;
swi = (src->width - width) * 3;
if (dalpha) {
d = image->data + dy*image->width*4 + dx;
dwi = (image->width - width)*4;
} else {
d = image->data + dy*image->width*3 + dx;
dwi = (image->width - width)*3;
}
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
s++; d++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
s++; d++;
*d = (((int)*d *(int)COP) + ((int)*s *(int)OP))/256;
s++; d++;
if (dalpha)
d++;
}
dr += dwi; dg += dwi; db += dwi;
sr += swi; sg += swi; sb += swi;
d += dwi; s += swi;
}
#undef COP
} else {
int tmp;
for (y=0; y<height; y++) {
for (x=0; x<width; x++) {
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;
dr++; dg++; db++;
sr++; sg++; sb++;
sa++;
for (y=0; y < height; y++) {
for (x=0; x < width; x++) {
tmp= (*(s+3) * opaqueness)/256;
*d = (((int)*d *(int)(255-tmp)) + ((int)*s *(int)tmp))/256;
d++; s++;
*d = (((int)*d *(int)(255-tmp)) + ((int)*s *(int)tmp))/256;
d++; s++;
*d = (((int)*d *(int)(255-tmp)) + ((int)*s *(int)tmp))/256;
d++; s++;
s++;
if (dalpha)
d++;
}
dr += dwi; dg += dwi; db += dwi;
sr += swi; sg += swi; sb += swi;
sa += swi;
d += dwi; s += swi;
}
}
#undef OP
@@ -423,34 +442,37 @@ void
RCombineImageWithColor(RImage *image, RColor *color)
{
register int i;
unsigned char *dr, *dg, *db, *da;
unsigned char *d;
int alpha, nalpha, r, g, b;
dr = image->data[0];
dg = image->data[1];
db = image->data[2];
da = image->data[3];
d = image->data;
if (!da) {
/* Image has no alpha channel, so we consider it to be all 255 */
if (!HAS_ALPHA(image)) {
/* Image has no alpha channel, so we consider it to be all 255.
* Thus there are no transparent parts to be filled. */
return;
}
r = color->red;
g = color->green;
b = color->blue;
for (i=0; i<image->width*image->height; i++) {
alpha = *da;
for (i=0; i < image->width*image->height; i++) {
alpha = *(d+3);
nalpha = 255 - alpha;
*dr = (((int)*dr * alpha) + (r * nalpha))/256;
*dg = (((int)*dg * alpha) + (g * nalpha))/256;
*db = (((int)*db * alpha) + (b * nalpha))/256;
dr++; dg++; db++; da++;
*d = (((int)*d * alpha) + (r * nalpha))/256;
d++;
*d = (((int)*d * alpha) + (g * nalpha))/256;
d++;
*d = (((int)*d * alpha) + (b * nalpha))/256;
d++;
d++;
}
}
RImage*
RMakeTiledImage(RImage *tile, unsigned width, unsigned height)
{
@@ -458,47 +480,36 @@ RMakeTiledImage(RImage *tile, unsigned width, unsigned height)
unsigned w;
unsigned long tile_size = tile->width * tile->height;
unsigned long tx = 0;
int have_alpha = (tile->data[3]!=NULL);
RImage *image;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *dr, *dg, *db, *da;
unsigned char *s, *d;
if (width == tile->width && height == tile->height)
image = RCloneImage(tile);
else if (width <= tile->width && height <= tile->height)
image = RGetSubImage(tile, 0, 0, width, height);
else {
int has_alpha = HAS_ALPHA(tile);
image = RCreateImage(width, height, have_alpha);
image = RCreateImage(width, height, has_alpha);
dr = image->data[0];
dg = image->data[1];
db = image->data[2];
da = image->data[3];
sr = tile->data[0];
sg = tile->data[1];
sb = tile->data[2];
sa = tile->data[3];
d = image->data;
s = tile->data;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x += tile->width) {
w = (width - x < tile->width) ? width - x : tile->width;
memcpy(dr, sr+tx, w);
memcpy(dg, sg+tx, w);
memcpy(db, sb+tx, w);
if (have_alpha) {
memcpy(da, sa+tx, w);
da += w;
}
dr += w;
dg += w;
db += w;
if (has_alpha) {
w *= 3;
memcpy(d, s+tx*3, w);
} else {
w *= 4;
memcpy(d, s+tx*4, w);
}
d += w;
}
tx = (tx + tile->width) % tile_size;
}
}

View File

@@ -55,8 +55,8 @@ RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
int px, py;
register int x, y, t;
int dx, dy;
unsigned char *sr, *sg, *sb, *sa;
unsigned char *dr, *dg, *db, *da;
unsigned char *s;
unsigned char *d;
RImage *img;
assert(new_width >= 0 && new_height >= 0);
@@ -64,7 +64,7 @@ RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
if (new_width == image->width && new_height == image->height)
return RCloneImage(image);
img = RCreateImage(new_width, new_height, image->data[3]!=NULL);
img = RCreateImage(new_width, new_height, image->format==RRGBAFormat);
if (!img)
return NULL;
@@ -76,21 +76,15 @@ RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
py = 0;
dr = img->data[0];
dg = img->data[1];
db = img->data[2];
da = img->data[3];
d = img->data;
if (image->data[3]!=NULL) {
if (image->format == RRGBAFormat) {
int ot;
ot = -1;
for (y=0; y<new_height; y++) {
t = image->width*(py>>16);
sr = image->data[0]+t;
sg = image->data[1]+t;
sb = image->data[2]+t;
sa = image->data[3]+t;
s = image->data+t;
ot = t;
ox = 0;
@@ -98,18 +92,15 @@ RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
for (x=0; x<new_width; x++) {
px += dx;
*(dr++) = *sr;
*(dg++) = *sg;
*(db++) = *sb;
*(da++) = *sa;
*(d++) = *(s);
*(d++) = *(s+1);
*(d++) = *(s+2);
*(d++) = *(s+3);
t = (px - ox)>>16;
ox += t<<16;
sr += t;
sg += t;
sb += t;
sa += t;
s += t<<2; /* t*4 */
}
py += dy;
}
@@ -119,9 +110,7 @@ RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
for (y=0; y<new_height; y++) {
t = image->width*(py>>16);
sr = image->data[0]+t;
sg = image->data[1]+t;
sb = image->data[2]+t;
s = image->data+t;
ot = t;
ox = 0;
@@ -129,16 +118,14 @@ RScaleImage(RImage *image, unsigned new_width, unsigned new_height)
for (x=0; x<new_width; x++) {
px += dx;
*(dr++) = *sr;
*(dg++) = *sg;
*(db++) = *sb;
*(d++) = *(s);
*(d++) = *(s+1);
*(d++) = *(s+2);
t = (px-ox)>>16;
ox += t<<16;
sr += t;
sg += t;
sb += t;
s += (t<<1)+t; /* t*3 */
}
py += dy;
}
@@ -431,6 +418,9 @@ CLIST *contrib; /* array of contribution lists */
#define CLAMP(v,l,h) ((v)<(l) ? (l) : (v) > (h) ? (h) : v)
#include "bench.h"
RImage*
RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
{
@@ -442,8 +432,10 @@ RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
double width, fscale; /* filter calculation variables */
double rweight, gweight, bweight;
RImage *dst;
unsigned char *rp, *gp, *bp;
unsigned char *rsp, *gsp, *bsp;
unsigned char *p;
unsigned char *sp;
int sch = src->format == RRGBAFormat ? 4 : 3;
dst = RCreateImage(new_width, new_height, False);
@@ -475,11 +467,12 @@ RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].pixel = n*sch;
contrib[i].p[k].weight = rweight;
}
}
} else {
for(i = 0; i < new_width; ++i) {
contrib[i].n = 0;
contrib[i].p = (CONTRIB *)calloc((int) (fwidth * 2 + 1),
@@ -498,32 +491,29 @@ RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].pixel = n*sch;
contrib[i].p[k].weight = rweight;
}
}
}
/* apply filter to zoom horizontally from src to tmp */
rp = tmp->data[0];
gp = tmp->data[1];
bp = tmp->data[2];
p = tmp->data;
for(k = 0; k < tmp->height; ++k) {
rsp = src->data[0] + src->width*k;
gsp = src->data[1] + src->width*k;
bsp = src->data[2] + src->width*k;
sp = src->data + src->width*k*sch;
for(i = 0; i < tmp->width; ++i) {
rweight = gweight = bweight = 0.0;
for(j = 0; j < contrib[i].n; ++j) {
rweight += rsp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
gweight += gsp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
bweight += bsp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
rweight += sp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
gweight += sp[contrib[i].p[j].pixel+1] * contrib[i].p[j].weight;
bweight += sp[contrib[i].p[j].pixel+2] * contrib[i].p[j].weight;
}
*rp++ = CLAMP(rweight, 0, 255);
*gp++ = CLAMP(gweight, 0, 255);
*bp++ = CLAMP(bweight, 0, 255);
*p++ = CLAMP(rweight, 0, 255);
*p++ = CLAMP(gweight, 0, 255);
*p++ = CLAMP(bweight, 0, 255);
}
}
@@ -556,7 +546,7 @@ RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].pixel = n*3;
contrib[i].p[k].weight = rweight;
}
}
@@ -579,61 +569,45 @@ RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height)
n = j;
}
k = contrib[i].n++;
contrib[i].p[k].pixel = n;
contrib[i].p[k].pixel = n*3;
contrib[i].p[k].weight = rweight;
}
}
}
/* apply filter to zoom vertically from tmp to dst */
rsp = malloc(tmp->height);
gsp = malloc(tmp->height);
bsp = malloc(tmp->height);
sp = malloc(tmp->height*3);
for(k = 0; k < new_width; ++k) {
rp = dst->data[0] + k;
gp = dst->data[1] + k;
bp = dst->data[2] + k;
p = dst->data + k*3;
/* copy a column into a row */
{
int i;
unsigned char *p, *d;
d = rsp;
for(i = tmp->height, p = tmp->data[0] + k; i-- > 0;
p += tmp->width) {
*d++ = *p;
}
d = gsp;
for(i = tmp->height, p = tmp->data[1] + k; i-- > 0;
p += tmp->width) {
*d++ = *p;
}
d = bsp;
for(i = tmp->height, p = tmp->data[2] + k; i-- > 0;
p += tmp->width) {
d = sp;
for(i = tmp->height, p = tmp->data + k*3; i-- > 0;
p += tmp->width*3) {
*d++ = *p;
*d++ = *(p+1);
*d++ = *(p+2);
}
}
for(i = 0; i < new_height; ++i) {
rweight = gweight = bweight = 0.0;
for(j = 0; j < contrib[i].n; ++j) {
rweight += rsp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
gweight += gsp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
bweight += bsp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
rweight += sp[contrib[i].p[j].pixel] * contrib[i].p[j].weight;
gweight += sp[contrib[i].p[j].pixel+1] * contrib[i].p[j].weight;
bweight += sp[contrib[i].p[j].pixel+2] * contrib[i].p[j].weight;
}
*rp = CLAMP(rweight, 0, 255);
*gp = CLAMP(gweight, 0, 255);
*bp = CLAMP(bweight, 0, 255);
rp += new_width;
gp += new_width;
bp += new_width;
*p = CLAMP(rweight, 0, 255);
*(p+1) = CLAMP(gweight, 0, 255);
*(p+2) = CLAMP(bweight, 0, 255);
p += new_width*3;
}
}
free(rsp);
free(gsp);
free(bsp);
free(sp);
/* free the memory allocated for vertical filter weights */
for(i = 0; i < dst->height; ++i) {

View File

@@ -10,6 +10,7 @@
#include <time.h>
#endif
Display *dpy;
Window win;
RContext *ctx;
@@ -192,11 +193,12 @@ int main(int argc, char **argv)
imgh = RRenderMultiGradient(250, 250, colors, RGRD_HORIZONTAL);
imgv = RRenderMultiGradient(250, 250, colors, RGRD_VERTICAL);
imgd = RRenderMultiGradient(250, 250, colors, RGRD_DIAGONAL);
RConvertImage(ctx, imgh, &pix);
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 0, 0);
RConvertImage(ctx, imgv, &pix);
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 250, 0);
RConvertImage(ctx, imgd, &pix);
XCopyArea(dpy, pix, win, ctx->copy_gc, 0, 0, 250, 250, 500, 0);

View File

@@ -47,6 +47,7 @@ RLoadTIFF(RContext *context, char *file, int index)
uint32 *data, *ptr;
uint16 extrasamples;
uint16 *sampleinfo;
int ch;
tif = TIFFOpen(file, "r");
@@ -94,13 +95,18 @@ RLoadTIFF(RContext *context, char *file, int index)
/* convert data */
image = RCreateImage(width, height, alpha);
if (alpha)
ch = 4;
else
ch = 3;
if (image) {
int x, y;
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
r = image->data;
g = image->data+1;
b = image->data+2;
a = image->data+3;
/* data seems to be stored upside down */
data += width * (height-1);
@@ -114,16 +120,16 @@ RLoadTIFF(RContext *context, char *file, int index)
if (alpha) {
*(a) = (*data >> 24) & 0xff;
if (amode && (*a > 0)) {
*r = (*r * 255) / *(a);
*g = (*g * 255) / *(a);
*b = (*b * 255) / *(a);
if (amode && (*a > 0)) {
*r = (*r * 255) / *(a);
*g = (*g * 255) / *(a);
*b = (*b * 255) / *(a);
}
a++;
a+=4;
}
r++; g++; b++;
r+=ch; g+=ch; b+=ch;
data++;
}
data -= 2*width;

View File

@@ -1,121 +1,125 @@
/* XPM */
static char * image_name[] = {
"64 64 54 1",
" c white",
". c #000000000000",
"X c #514461856185",
"o c #A289A289B2CA",
"O c #A289A289A289",
"+ c #A2899248B2CA",
"@ c #9248A289A289",
"# c #A2899248A289",
"$ c #92489248A289",
"% c #924892489248",
"& c #92488207A289",
"* c #820792489248",
"= c #924882079248",
"- c #820782079248",
"; c #820782078207",
": c #820771C69248",
"> c #618551446185",
", c #9248A289B2CA",
"< c #92489248B2CA",
"1 c #82079248A289",
"2 c #82078207A289",
"3 c #71C682079248",
"4 c #71C682078207",
"5 c #514451446185",
"6 c #514451445144",
"7 c #820771C68207",
"8 c #410351445144",
"9 c #514441035144",
"0 c #71C671C69248",
"q c #71C671C68207",
"w c #71C671C671C6",
"e c #410341035144",
"r c #71C661858207",
"t c #618571C68207",
"y c #410351444103",
"u c #410341034103",
"i c #618571C671C6",
"p c #410330C24103",
"a c #30C241034103",
"s c #71C6618571C6",
"d c #6185618571C6",
"f c #618561858207",
"g c #30C230C230C2",
"h c #618561856185",
"j c #30C230C24103",
"k c #5144618571C6",
"l c #30C2410330C2",
"z c #6185514471C6",
"x c #208130C230C2",
"c c #30C2208130C2",
"v c #5144514471C6",
"b c #2081208130C2",
"n c #208120812081",
"m c #410330C25144",
" .",
" X.",
" oOoO+O+O+O+@#$+@#$#$#$$$#$$%&%&%&%&*&*&*=-=*=-=-=--;---;:;:;>.",
" oo@o,o@o@o@+@+@<@$@$@$@$@$1$$$*$*$*&*&*2*&*2*-*-*-----3-3-4-X.",
" oO+OoO#O+@#@#@#$#@#$#%#$$%$%$%&%&*=%&*=*=*=-=-=--;-;-;:;:;:;5.",
" ,ooo@+@+@+@+@<@#@<@$$$$$$$$$*$1$*&*&*&*&*2*---*-----3---4:4:6.",
" +O+O+O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=*=---=--;---;:;:4:;:45.",
" @o@o@o@+@+@<@$@$@$$$@$1$1$*$*$*&*&*2*=*2*-*-*-----4-3-4:4-4:6.",
" +O#O+@#@#@#$#$#$#%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:4745.",
" @+@+@+@+@<@#@$@$$$$$$$$$*$*$*&*&*&*&*2*---*-----3---4:4:4:4:8.",
" #O+@#$#@#$#$#$$%$$$%&%&%&%&*=*&*=-=-=---=--;:;-;:;:4:4:474:49.",
" @o@<@+@<@$@$@$$$$$1$1$*$*$*&*&*2*=*2*-*-*-----4-4-4:4:4:4:408.",
" +@#@#@#$#$#$$%#%$%&%$%&%&*=*&*=*=*=-=-=--;-;-;:;:;:;:474747q9.",
" @+@+@<@$$$@$$$$$1$$$*&*$*&*&*&*&*2*---------3-3-4:4:4:4:404q8.",
" #$#@#$#$#$$%$$$%&%&%&%&*=-&*=-=-=---=--;:;:;:;:4:4:474:47q7q9.",
" @#@<@$@$@$$$$$*$1$*$*$*&*&*2*-*2*-*-*-3---4-4-4:4:4:4:404q4q8.",
" #@#$#$#$$%$%$%&%$%&%&*=*=*=-=*=-=;=--;-;-;:;:47;:474747q7q7q9.",
" @<@$$$@$$$$$1$$$*&*&*&*&*&*=*2*---------4-3-4:4:4:4:404qq04q8.",
" #$#$#$$%$%$%&%&%&%&*=-&*=-=-=------;:;:;:;:4:4:47q747qqq7qqq9.",
" @$@$@$$$$$*$1$*$*$*&*&*2*-*-*---*-3-3-4-4-4:4:4:4:404q4q4qqq8.",
" #$#$$%$%$%&%&%&%&*=*=*=-=-=-=;=--;:;-;:;:474:474747q7q7qqwqw9.",
" $$@$$$$$*$$$*&*&*&*&*2*=*2*---------4-3-4:4:4:4:404qqq4qqqqqe.",
" #$$%$%$%&%&*&%&*=-&*=-=-=------;:;:;:;:4:4:47q7q7qqq7qqwrqqw9.",
" @$$$$$*$1$*&*$*2*&*2*-*-*-----3-3-4-4-4:4:404:404q4q4qqqqqtqy.",
" $%$%$%&%&%=%&*=*=*=-=-=--;=--;:;-;:;:474:474747q7q7qqwqwqwrwe.",
" $$$$*$1$*&*&*&*&*2*--2*-----3---4:3-4:4:4:4:404qqqqqqqqqtqtqu.",
" &%$%&%&*&*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqq7qqwrqrwrwrip.",
" $$*$*$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q404q4q4qtqqqiqtqiru.",
" $%&%&*=%&*=*=*=-=-=--;-;-;:;-;:;:474:47q747q7q7qqwqwqwrwrirwu.",
" *$1$*&*&*&*&*2*---*-----3---4:4:4:4:4:4:404qqqqqqqqqtqtqirira.",
" &%&*=*&*=-=*=-=-=--;---;:;:;:;:4:4:47q7q7qqqqqqwrqrwrwriririp.",
" *$*&*&*2*&*2*-*-*-----3-3-4-4-4:4:404q4q4qqq4qtqtqiqiqiriqira.",
" &*=*&*=*=*=-=-=--;-;-;:;:;:;:474:47q7q7q7q7qqwrwqwrwrirwrisip.",
" *&*&*&*&*2*---*-----3---4:4:4:4:404:404qqqqqqqqqtqtqiriririra.",
" =*&*=-=*=---=--;---;:;:4:;:474:47q7q7qqqqqqwrwrwrwriririsdrdp.",
" *&*2*=*2*-*-*-----4-3-4:4-4:4:404q4q4qqqqqtqtqiqiqiriqifirifa.",
" &*=*=*=-=-=--;-;-;:;:;:;:474747q7q7qqq7qqwrwqwrwrirwrisisisdp.",
" *&*&*2*---*-----3-3-4:4:4:4:404qq04qqqqqtqqqirtqiririririfida.",
" =-=-=---=--;:;-;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdrdsdddp.",
" *=*2*-*-*-----4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiriqifififidida.",
" =*=-=-=--;-;-;:;:4:;:474747q7q7qqwqwqwrwqwrwrirwrisdsisdsdsdp.",
" *2*---------4-3-4:4:4:4:404qq04qqqqqtqqqiririririririfidddddg.",
" =---=--;:;:;:;:4:4:474:47q7q7qqqqqqwrwrwrwriririsdsdsddddddhj.",
" *---*-3---4-4-4:4:4:4:404q4q4qqqqqtqtqiqiqiririfififidddidkdl.",
" =;=--;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrirwrisdsdsdsdsddhzhj.",
" --------4-3-4:4:4:4:404qq04qqqqqtqqqiririririfirifidddddddddx.",
" ---;:;:;:;:4:4:47q747qqq7qqwqqqwrwrirwriririsdsdsddddddhzhzhc.",
" --3-3-4-4-4:4:4:4:404q4q4qqqqqtqtqiriqiririfififidddddkdkdXdx.",
" -;:;-;:;:474:474747q7q7qqwqwqwrwrwrwrisisisdsdsdddsddhzhdhzhg.",
" ----4-3-4:4:4:4:404qqq4qqqqqtqtqiriririrififdfidddddkdddkzkdx.",
" :;:;:;:4:4:47q7q7qqq7qqwrqqwrwriririririsdsdsddddddhzhzhzhzXc.",
" 3-4-4-4:4:404:404q4q4qqqqqtqtqiriqiririfidididddddkdkdXdXdXzx.",
" -;:;:474:47q747q7q7qqwqwqwrwrirwrisisisdsdsddddddhzhdhzhzXzhc.",
" 4:4-4:4:4:4:404qqqqqqqqqtqtqiriririrififdfidddddkdddkzkdXzXzx.",
" :;:4:4:47q7q7qqq7qqwrqrwrwriririsirisdsdsddddddhzhzhzhzXzXzXc.",
" 4-4:4:404q404qqq4qtqqqiqtqiriqiririfidididddddkdkdXdXdXzXzXvx.",
" :474:47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddddddhzhzhzhzXzhzX>5c.",
" 4:4:4:4:404qqqqqqqqqtqtqiririririfiddfidddddkdddXzkdXzXzXvXzx.",
" :4:47q7q7qqqqqqwrwrwrwriririsdrisdddsddddddhzhzXzhzXzXzX>5>5c.",
" 4:404q4q4qqqqqtqtqiqiqiriqiririfidididddddkdkdXzXdXzXzXvXvXvx.",
" :47q7q7q7q7qqwrwqwrwrirwrisisisdsdsddhdddhzhzhzhzXzXzX>5>5>5b.",
" 404:404qqqqqqqqqiqtqiririririfidddidddddkdkdXzkzXzXzXvXv5vX5n.",
" >65656569698989y9e9u9ueumueupupapaplpgjgjgjgcgcgcgcxcbcncnbnb.",
" ..............................................................."};
static char *image_name[] = {
/* width height num_colors chars_per_pixel */
" 64 64 54 1",
/* colors */
". c #ffffff",
"# c #000000",
"a c #516161",
"b c #a2a2b2",
"c c #a2a2a2",
"d c #a292b2",
"e c #92a2a2",
"f c #a292a2",
"g c #9292a2",
"h c #929292",
"i c #9282a2",
"j c #829292",
"k c #928292",
"l c #828292",
"m c #828282",
"n c #827192",
"o c #615161",
"p c #92a2b2",
"q c #9292b2",
"r c #8292a2",
"s c #8282a2",
"t c #718292",
"u c #718282",
"v c #515161",
"w c #515151",
"x c #827182",
"y c #415151",
"z c #514151",
"A c #717192",
"B c #717182",
"C c #717171",
"D c #414151",
"E c #716182",
"F c #617182",
"G c #415141",
"H c #414141",
"I c #617171",
"J c #413041",
"K c #304141",
"L c #716171",
"M c #616171",
"N c #616182",
"O c #303030",
"P c #616161",
"Q c #303041",
"R c #516171",
"S c #304130",
"T c #615171",
"U c #203030",
"V c #302030",
"W c #515171",
"X c #202030",
"Y c #202020",
"Z c #413051",
/* pixels */
"...............................................................#",
"..............................................................a#",
"..bcbcdcdcdcdefgdefgfgfgggfgghihihihijijijklkjklklkllmlllmnmnmo#",
"..bbebpbebebededeqegegegegegrgggjgjgjijijsjijsjljljllllltltlula#",
"..bcdcbcfcdefefefgfefgfhfgghghghihijkhijkjkjklklkllmlmlmnmnmnmv#",
"..pbbbededededeqefeqegggggggggjgrgjijijijijsjllljllllltlllununw#",
"..dcdcdcdefgfefgfgfgghggghihihihijkjijklkjklllkllmlllmnmnunmnuv#",
"..ebebebededeqegegegggegrgrgjgjgjijijsjkjsjljljlllllultlunulunw#",
"..dcfcdefefefgfgfgfhfhghihghihijkjijkjkjklklkllmlmlmnmnmnmnuxuv#",
"..ededededeqefegegggggggggjgjgjijijijijsjllljllllltlllununununy#",
"..fcdefgfefgfgfgghggghihihihijkjijklklklllkllmnmlmnmnununuxunuz#",
"..ebeqedeqegegegggggrgrgjgjgjijijsjkjsjljljlllllululununununuAy#",
"..defefefgfgfgghfhghihghihijkjijkjkjklklkllmlmlmnmnmnmnuxuxuxBz#",
"..ededeqegggegggggrgggjijgjijijijijsjllllllllltltlununununuAuBy#",
"..fgfefgfgfgghggghihihihijklijklklklllkllmnmnmnmnununuxunuxBxBz#",
"..efeqegegegggggjgrgjgjgjijijsjljsjljljltlllululununununuAuBuBy#",
"..fefgfgfgghghghihghihijkjkjklkjklkmkllmlmlmnmnuxmnuxuxuxBxBxBz#",
"..eqegggegggggrgggjijijijijijkjsjlllllllllultlununununuAuBBAuBy#",
"..fgfgfgghghghihihihijklijklklkllllllmnmnmnmnununuxBxuxBBBxBBBz#",
"..egegegggggjgrgjgjgjijijsjljljllljltltlululununununuAuBuBuBBBy#",
"..fgfgghghghihihihijkjkjklklklkmkllmnmlmnmnuxunuxuxuxBxBxBBCBCz#",
"..ggegggggjgggjijijijijsjkjsjlllllllllultlununununuAuBBBuBBBBBD#",
"..fgghghghihijihijklijklklkllllllmnmnmnmnununuxBxBxBBBxBBCEBBCz#",
"..egggggjgrgjijgjsjijsjljljllllltltlululununuAunuAuBuBuBBBBBFBG#",
"..ghghghihihkhijkjkjklklkllmkllmnmlmnmnuxunuxuxuxBxBxBBCBCBCECD#",
"..ggggjgrgjijijijijsjllsjllllltllluntlununununuAuBBBBBBBBBFBFBH#",
"..ihghihijijijklkjklklkllmlllmnmnmnmnununuxBxBxBBBxBBCEBECECEIJ#",
"..ggjgjgjijijsjijsjljljllllltltlululununuAuBuAuBuBuBFBBBIBFBIEH#",
"..ghihijkhijkjkjklklkllmlmlmnmlmnmnuxunuxBxuxBxBxBBCBCBCECEIECH#",
"..jgrgjijijijijsjllljllllltlllununununununuAuBBBBBBBBBFBFBIEIEK#",
"..ihijkjijklkjklklkllmlllmnmnmnmnununuxBxBxBBBBBBCEBECECEIEIEIJ#",
"..jgjijijsjijsjljljllllltltlululununuAuBuBuBBBuBFBFBIBIBIEIBIEK#",
"..ijkjijkjkjklklkllmlmlmnmnmnmnuxunuxBxBxBxBxBBCECBCECEIECEILIJ#",
"..jijijijijsjllljllllltlllununununuAunuAuBBBBBBBBBFBFBIEIEIEIEK#",
"..kjijklkjklllkllmlllmnmnunmnuxunuxBxBxBBBBBBCECECECEIEIEILMEMJ#",
"..jijsjkjsjljljlllllultlunulununuAuBuBuBBBBBFBFBIBIBIEIBINIEINK#",
"..ijkjkjklklkllmlmlmnmnmnmnuxuxuxBxBxBBBxBBCECBCECEIECEILILILMJ#",
"..jijijsjllljllllltltlununununuAuBBAuBBBBBFBBBIEFBIEIEIEIEINIMK#",
"..klklklllkllmnmlmnmnununuxunuxBxBxBBBBBBCECECECEIEIEILMEMLMMMJ#",
"..jkjsjljljlllllululununununuAuBuBuBBBBBFBFBIBIBIEIBINININIMIMK#",
"..kjklklkllmlmlmnmnunmnuxuxuxBxBxBBCBCBCECBCECEIECEILMLILMLMLMJ#",
"..jsjlllllllllultlununununuAuBBAuBBBBBFBBBIEIEIEIEIEIEINIMMMMMO#",
"..klllkllmnmnmnmnununuxunuxBxBxBBBBBBCECECECEIEIEILMLMLMMMMMMPQ#",
"..jllljltlllululununununuAuBuBuBBBBBFBFBIBIBIEIEINININIMMMIMRMS#",
"..kmkllmnmlmnmnuxunuxuxuxBxBxBBCBCBCECECECEIECEILMLMLMLMLMMPTPQ#",
"..llllllllultlununununuAuBBAuBBBBBFBBBIEIEIEIEINIEINIMMMMMMMMMU#",
"..lllmnmnmnmnununuxBxuxBBBxBBCBBBCECEIECEIEIEILMLMLMMMMMMPTPTPV#",
"..lltltlululununununuAuBuBuBBBBBFBFBIEIBIEIEINININIMMMMMRMRMaMU#",
"..lmnmlmnmnuxunuxuxuxBxBxBBCBCBCECECECEILILILMLMLMMMLMMPTPMPTPO#",
"..llllultlununununuAuBBBuBBBBBFBFBIEIEIEIEININMNIMMMMMRMMMRTRMU#",
"..nmnmnmnununuxBxBxBBBxBBCEBBCECEIEIEIEIEILMLMLMMMMMMPTPTPTPTaV#",
"..tlululununuAunuAuBuBuBBBBBFBFBIEIBIEIEINIMIMIMMMMMRMRMaMaMaTU#",
"..lmnmnuxunuxBxuxBxBxBBCBCBCECEIECEILILILMLMLMMMMMMPTPMPTPTaTPV#",
"..unulununununuAuBBBBBBBBBFBFBIEIEIEIEININMNIMMMMMRMMMRTRMaTaTU#",
"..nmnununuxBxBxBBBxBBCEBECECEIEIEILIEILMLMLMMMMMMPTPTPTPTaTaTaV#",
"..ulununuAuBuAuBBBuBFBBBIBFBIEIBIEIEINIMIMIMMMMMRMRMaMaMaTaTaWU#",
"..nuxunuxBxBxBxBxBBCECBCECEIECEILILILMLMLMMMMMMPTPTPTPTaTPTaovV#",
"..ununununuAuBBBBBBBBBFBFBIEIEIEIEINIMMNIMMMMMRMMMaTRMaTaTaWaTU#",
"..nunuxBxBxBBBBBBCECECECEIEIEILMEILMMMLMMMMMMPTPTaTPTaTaTaovovV#",
"..unuAuBuBuBBBBBFBFBIBIBIEIBIEIEINIMIMIMMMMMRMRMaTaMaTaTaWaWaWU#",
"..nuxBxBxBxBxBBCECBCECEIECEILILILMLMLMMPMMMPTPTPTPTaTaTaovovovX#",
"..uAunuAuBBBBBBBBBIBFBIEIEIEIEINIMMMIMMMMMRMRMaTRTaTaTaWaWvWavY#",
"..owvwvwvwzwzyzyzGzDzHzHDHZHDHJHJKJKJSJOQOQOQOVOVOVOVUVXVYVYXYX#",
".###############################################################"
};

View File

@@ -20,12 +20,12 @@ int main(int argc, char **argv)
puts("cant open display");
exit(1);
}
attr.flags = RC_RenderMode | RC_ColorsPerChannel;
attr.render_mode = RDitheredRendering;
attr.colors_per_channel = 4;
ctx = RCreateContext(dpy, DefaultScreen(dpy), &attr);
if (argc<2)
img = RGetImageFromXPMData(ctx, image_name);
else
@@ -54,15 +54,17 @@ int main(int argc, char **argv)
exit(1);
}
printf("%ix%i\n", img->width, img->height);
win = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 10, 10,
img->width,
img->height, 0, 0, 0);
RDestroyImage(img);
XSetWindowBackgroundPixmap(dpy, win, pix);
XClearWindow(dpy, win);
XMapRaised(dpy, win);
XFlush(dpy);
getchar();
exit(0);
}

View File

@@ -39,8 +39,8 @@
#define RLRASTER_H_
/* version of the header for the library: 0.16 */
#define WRASTER_HEADER_VERSION 16
/* version of the header for the library: 0.20 */
#define WRASTER_HEADER_VERSION 20
#include <X11/Xlib.h>
@@ -145,6 +145,7 @@ typedef struct RContext {
struct {
unsigned int use_shared_pixmap:1;
unsigned int optimize_for_speed:1;
} flags;
} RContext;
@@ -175,13 +176,22 @@ typedef struct RSegment {
} RSegment;
/* image formats */
enum RImageFormat {
RRGBFormat,
RRGBAFormat
};
/*
* internal 24bit+alpha image representation
*/
typedef struct RImage {
unsigned char *data; /* image data RGBA or RGB */
unsigned width, height; /* size of the image */
enum RImageFormat format;
RColor background; /* background color */
unsigned char *data[4]; /* image data (R,G,B,A) */
} RImage;
@@ -199,7 +209,6 @@ typedef struct RXImage {
} RXImage;
/* image display modes */
enum {
RDitheredRendering = 0,
@@ -313,7 +322,7 @@ RImage *RLoadImage(RContext *context, char *file, int index);
void RDestroyImage(RImage *image);
RImage *RGetImageFromXPMData(RContext *context, char **data);
RImage *RGetImageFromXPMData(RContext *context, char **xpmData);
/*
* RImage storing

285
wrlib/x86_specific.c Normal file
View File

@@ -0,0 +1,285 @@
/* x86_convert.c - convert RImage to XImage with x86 optimizations
*
* Raster graphics library
*
* Copyright (c) 2000 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>
#ifdef ASM_X86_MMX
int
x86_check_mmx()
{
static int result = 1;
if (result >= 0)
return result;
result = 0;
#if 0
asm volatile
("pushfl \n" // check whether cpuid supported
"pop %%eax \n"
"movl %%eax, %%ebx \n"
"xorl 1<<21, %%eax \n"
"pushfl %%eax \n"
"popfd \n"
"pushfl \n"
"popl %%eax \n"
"xorl %%eax, %%ebx \n"
"andl 1<<21, %%eax \n"
"jz .NotPentium \n"
"xorl %%eax, %%eax \n"
"movl $1, %%eax \n"
"cpuid \n"
"test 1<<23, %%edx \n"
"jz .NotMMX \n"
"movl $1, %%0 \n"
".NotMMX: \n"
".Bye: \n"
".NotPentium: \n"
: "=rm" (result));
#endif
return result;
}
void
x86_TrueColor_32_to_16(unsigned char *image, // 8
unsigned short *ximage, // 12
short *err, // 16
short *nerr, // 20
short *rtable, // 24
short *gtable, // 28
short *btable, // 32
int dr, // 36
int dg, // 40
int db, // 44
unsigned int roffs, // 48
unsigned int goffs, // 52
unsigned int boffs, // 56
int width, // 60
int height, // 64
int line_offset) // 68
{
/*
int x; //-4
long long rrggbbaa;// -16
long long pixel; //-24
short *tmp_err; //-32
short *tmp_nerr; //-36
*/
asm volatile
(
"subl $64, %esp \n" // alloc some more stack
"pusha \n"
// pack dr, dg and db into mm6
"movl 36(%ebp), %eax \n"
"movl 40(%ebp), %ebx \n"
"movw %ax, -16(%ebp) \n"
"movw %bx, -14(%ebp) \n"
"movl 44(%ebp), %eax \n"
"movw $0, -10(%ebp) \n"
"movw %ax, -12(%ebp) \n"
"movq -16(%ebp), %mm6 \n" // dr dg db 0
// pack 4|4|4|4 into mm7, for shifting (/16)
"movl $0x00040004, -16(%ebp) \n"
"movl $0x00040004, -12(%ebp) \n"
"movq -16(%ebp), %mm7 \n"
// store constant values for using with mmx when dithering
"movl $0x00070007, -16(%ebp) \n"
"movl $0x00070007, -12(%ebp) \n"
"movq -16(%ebp), %mm5 \n"
"movl $0x00050005, -16(%ebp) \n"
"movl $0x00050005, -12(%ebp) \n"
"movq -16(%ebp), %mm4 \n"
"movl $0x00030003, -16(%ebp) \n"
"movl $0x00030003, -12(%ebp) \n"
"movq -16(%ebp), %mm3 \n"
// process 1 pixel / cycle, each component treated as 16bit
"movl 8(%ebp), %esi \n" // esi = image->data
".LoopY: \n"
"movl 60(%ebp), %eax \n"
"movl %eax, -4(%ebp) \n" // x = width
"movl 64(%ebp), %eax \n"
"decl %eax \n" // y--
"movl %eax, 64(%ebp) \n"
"js .End \n" // if y < 0, goto end
"andl $1, %eax \n"
"jz .LoopY_1 \n" // if (y&1) goto LoopY_1
".LoopY_0: \n"
"movl 16(%ebp), %ebx \n" // ebx = err
"movl %ebx, -36(%ebp) \n" // [-36] = err
"movl 20(%ebp), %eax \n" //
"movl %eax, -32(%ebp) \n" // [-32] = nerr
"jmp .LoopX \n"
".LoopY_1: \n"
"movl 20(%ebp), %ebx \n" // ebx = nerr
"movl %ebx, -36(%ebp) \n" // [-36] = nerr
"movl 16(%ebp), %eax \n" //
"movl %eax, -32(%ebp) \n" // [-32] = eerr
".LoopX: \n"
// calculate errors and pixel components
// depend on ebx, esi, mm6
"movq (%ebx), %mm1 \n" // mm1 = error[0..3]
"punpcklbw (%esi), %mm0 \n" // mm0 = image->data[0..3]
"psrlw $8, %mm0 \n" // fixup mm0
"paddusb %mm1, %mm0 \n" // mm0 = mm0 + mm1 (sat. to 255)
"movq %mm0, -24(%ebp) \n" // save the pixel
"movzwl -24(%ebp), %ecx \n" // ecx = pixel.red
"movl 24(%ebp), %edi \n" // edi = rtable
"leal (%edi, %ecx, 2), %eax \n" // eax = &rtable[pixel.red]
"movl (%eax), %edx \n" // edx = rtable[pixel.red]
"movw %dx, -16(%ebp) \n" // save rr
"movzwl -22(%ebp), %ecx \n" // ecx = pixel.green
"movl 28(%ebp), %edi \n" // edi = gtable
"leal (%edi, %ecx, 2), %eax \n" // eax = &gtable[pixel.green]
"movl (%eax), %edx \n" // ebx = gtable[pixel.green]
"movw %dx, -14(%ebp) \n" // save gg
"movzwl -20(%ebp), %ecx \n" // ecx = pixel.blue
"movl 32(%ebp), %edi \n" // ebx = btable
"leal (%edi, %ecx, 2), %eax \n" // eax = &btable[pixel.blue]
"movl (%eax), %edx \n" // ecx = btable[pixel.blue]
"movw %dx, -12(%ebp) \n" // save bb
"movw $0, -10(%ebp) \n" // save dummy aa
"movq -16(%ebp), %mm1 \n" // load mm1 with rrggbbaa
"pmullw %mm6, %mm1 \n" // mm1 = rr*dr|...
"psubsw %mm1, %mm0 \n" // error = pixel - mm1
// distribute the error
// depend on mm0, mm7, mm3, mm4, mm5
"movl -36(%ebp), %ebx \n"
"movq %mm0, %mm1 \n"
"pmullw %mm5, %mm1 \n" // mm1 = mm1*7
"psrlw %mm7, %mm1 \n" // mm1 = mm1/16
"paddw 8(%ebx), %mm1 \n"
"movq %mm1, 8(%ebx) \n" // err[x+1,y] = rer*7/16
"movl -32(%ebp), %ebx \n"
"movq %mm0, %mm1 \n"
"pmullw %mm4, %mm1 \n" // mm1 = mm1*5
"psrlw %mm7, %mm1 \n" // mm1 = mm1/16
"paddw -8(%ebx), %mm1 \n"
"movq %mm1, -8(%ebx) \n" // err[x-1,y+1] += rer*3/16
"movq %mm0, %mm1 \n"
"pmullw %mm3, %mm1 \n" // mm1 = mm1*3
"psrlw %mm7, %mm1 \n" // mm1 = mm1/16
"paddw 8(%ebx), %mm1 \n"
"movq %mm1, (%ebx) \n" // err[x,y+1] += rer*5/16
"psrlw %mm7, %mm0 \n" // mm0 = mm0/16
"movq %mm0, 8(%ebx) \n" // err[x+1,y+1] = rer/16
// calculate final pixel value and store
"movl 48(%ebp), %ecx \n"
"movw -16(%ebp), %ax \n"
"shlw %cl, %ax \n" //NP* ax = r<<roffs
"movl 52(%ebp), %ecx \n"
"movw -14(%ebp), %bx \n"
"shlw %cl, %bx \n" //NP*
"orw %bx, %ax \n"
"movl 56(%ebp), %ecx \n"
"movw -12(%ebp), %bx \n"
"shlw %cl, %bx \n" //NP*
"orw %bx, %ax \n"
"movl 12(%ebp), %edx \n"
"movw %ax, (%edx) \n"
"addl $2, %edx \n" // increment ximage
"movl %edx, 12(%ebp) \n"
// prepare for next iteration on X
"addl $8, -32(%ebp) \n" // nerr += 8
"movl -36(%ebp), %ebx \n"
"addl $8, %ebx \n"
"movl %ebx, -36(%ebp) \n" // ebx = err += 8
// Note: in the last pixel, this would cause an invalid memory access
// because, punpcklbw is used (which reads 8 bytes) and the last
// pixel is only 4 bytes. This is no problem because the image data
// was allocated with extra 4 bytes when created.
"addl $4, %esi \n" // image->data += 4
"decl -4(%ebp) \n" // x--
"jnz .LoopX \n" // if x>0, goto .LoopX
// depend on edx
"addl 68(%ebp), %edx \n" // add extra offset to ximage
"movl %edx, 12(%ebp) \n"
"jmp .LoopY \n"
".End: \n" // THE END
"emms \n"
"popa \n"
);
}
#endif /* ASM_X86_MMX */

View File

@@ -52,7 +52,7 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
RImage *img;
int x, y;
unsigned long pixel;
unsigned char *r, *g, *b, *a;
unsigned char *data;
int rshift, gshift, bshift;
int rmask, gmask, bmask;
@@ -84,10 +84,7 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
gshift = get_shifts(gmask) - 8;
bshift = get_shifts(bmask) - 8;
r = img->data[0];
g = img->data[1];
b = img->data[2];
a = img->data[3];
data = img->data;
#define NORMALIZE_RED(pixel) ((rshift>0) ? ((pixel) & rmask) >> rshift \
: ((pixel) & rmask) << -rshift)
@@ -101,9 +98,13 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
for (x = 0; x < image->width; x++) {
pixel = XGetPixel(image, x, y);
if (pixel) {
*(r++) = *(g++) = *(b++) = 0;
*data++ = 0;
*data++ = 0;
*data++ = 0;
} else {
*(r++) = *(g++) = *(b++) = 0xff;
*data++ = 0xff;
*data++ = 0xff;
*data++ = 0xff;
}
}
}
@@ -111,20 +112,20 @@ RCreateImageFromXImage(RContext *context, XImage *image, XImage *mask)
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);
*(data++) = NORMALIZE_RED(pixel);
*(data++) = NORMALIZE_GREEN(pixel);
*(data++) = NORMALIZE_BLUE(pixel);
}
}
}
if (mask && a) {
if (mask) {
for (y = 0; y < mask->height; y++) {
for (x = 0; x < mask->width; x++) {
if (XGetPixel(mask, x, y)) {
*(a++) = 0xff;
*(data++) = 0xff;
} else {
*(a++) = 0;
*(data++) = 0;
}
}
}

View File

@@ -33,18 +33,18 @@
#include "wraster.h"
RImage*
RGetImageFromXPMData(RContext *context, char **data)
RGetImageFromXPMData(RContext *context, char **xpmData)
{
Display *dpy = context->dpy;
Colormap cmap = context->cmap;
RImage *image;
XpmImage xpm;
unsigned char *color_table[4];
unsigned char *r, *g, *b, *a;
unsigned char *data;
int *p;
int i;
i = XpmCreateXpmImageFromData(data, &xpm, (XpmInfo *)NULL);
i = XpmCreateXpmImageFromData(xpmData, &xpm, (XpmInfo *)NULL);
if (i!=XpmSuccess) {
switch (i) {
case XpmOpenFailed:
@@ -136,18 +136,14 @@ RGetImageFromXPMData(RContext *context, char **data)
color_table[3][i] = 0xff;
}
}
memset(image->data[3], 255, xpm.width*xpm.height);
/* convert pixmap to RImage */
p = (int*)xpm.data;
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
data = image->data;
for (i=0; i<xpm.width*xpm.height; i++) {
*(r++)=color_table[0][*p];
*(g++)=color_table[1][*p];
*(b++)=color_table[2][*p];
*(a++)=color_table[3][*p];
*(data++)=color_table[0][*p];
*(data++)=color_table[1][*p];
*(data++)=color_table[2][*p];
*(data++)=color_table[3][*p];
p++;
}
for(i=0; i<4; i++) {
@@ -167,7 +163,7 @@ RLoadXPM(RContext *context, char *file, int index)
RImage *image;
XpmImage xpm;
unsigned char *color_table[4];
unsigned char *r, *g, *b, *a;
unsigned char *data;
int *p;
int i;
@@ -265,16 +261,12 @@ RLoadXPM(RContext *context, char *file, int index)
}
/* convert pixmap to RImage */
p = (int*)xpm.data;
r = image->data[0];
g = image->data[1];
b = image->data[2];
a = image->data[3];
for (i=0; i<xpm.width*xpm.height; i++) {
*(r++)=color_table[0][*p];
*(g++)=color_table[1][*p];
*(b++)=color_table[2][*p];
*(a++)=color_table[3][*p];
p++;
data = image->data;
for (i=0; i<xpm.width*xpm.height; i++, p++) {
*(data++)=color_table[0][*p];
*(data++)=color_table[1][*p];
*(data++)=color_table[2][*p];
*(data++)=color_table[3][*p];
}
for(i=0; i<4; i++) {
free(color_table[i]);