From a30475fc0f715465d13dddfd7f473997c738dc95 Mon Sep 17 00:00:00 2001 From: kojima Date: Fri, 14 Jan 2000 16:39:15 +0000 Subject: [PATCH] changed format of RImage, added x86 speicfic optimized code --- wrlib/Makefile.am | 16 +- wrlib/Makefile.in | 18 +- wrlib/context.c | 16 +- wrlib/convert.c | 769 ++++++++++++++++++------------------------- wrlib/convolve.c | 227 ++++++------- wrlib/draw.c | 104 +++--- wrlib/gif.c | 3 +- wrlib/gradient.c | 212 +++++------- wrlib/jpeg.c | 59 ++-- wrlib/misc.c | 62 ++-- wrlib/nxpm.c | 44 ++- wrlib/png.c | 20 +- wrlib/ppm.c | 37 ++- wrlib/raster.c | 475 +++++++++++++------------- wrlib/scale.c | 136 ++++---- wrlib/testgrad.c | 4 +- wrlib/tiff.c | 26 +- wrlib/tile.xpm | 244 +++++++------- wrlib/view.c | 10 +- wrlib/wraster.h | 19 +- wrlib/x86_specific.c | 285 ++++++++++++++++ wrlib/xpixmap.c | 27 +- wrlib/xpm.c | 38 +-- 23 files changed, 1527 insertions(+), 1324 deletions(-) create mode 100644 wrlib/x86_specific.c diff --git a/wrlib/Makefile.am b/wrlib/Makefile.am index fcf3f194..69b88546 100644 --- a/wrlib/Makefile.am +++ b/wrlib/Makefile.am @@ -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 @@ -59,6 +71,6 @@ testdraw_SOURCES = testdraw.c testdraw_LDADD = $(LIBLIST) -libwraster_la_LIBADD = @ALLOCA@ +libwraster_la_LIBADD = @ALLOCA@ diff --git a/wrlib/Makefile.in b/wrlib/Makefile.in index d6cec636..26834063 100644 --- a/wrlib/Makefile.in +++ b/wrlib/Makefile.in @@ -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@ @@ -125,7 +125,7 @@ testdraw_SOURCES = testdraw.c testdraw_LDADD = $(LIBLIST) -libwraster_la_LIBADD = @ALLOCA@ +libwraster_la_LIBADD = @ALLOCA@ mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs CONFIG_HEADER = ../src/config.h CONFIG_CLEAN_FILES = @@ -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: diff --git a/wrlib/context.c b/wrlib/context.c index 2772176e..9ddebba4 100644 --- a/wrlib/context.c +++ b/wrlib/context.c @@ -443,10 +443,12 @@ setupPseudoColorColormap(RContext *context) if (theMap >= 0 && allocateStandardPseudoColor(context, &maps[theMap])) { - + context->std_rgb_map = XAllocStandardColormap(); *context->std_rgb_map = maps[theMap]; + + context->cmap = context->std_rgb_map->colormap; XFree(maps); @@ -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; diff --git a/wrlib/convert.c b/wrlib/convert.c index 54ed6385..f0b46b9e 100644 --- a/wrlib/convert.c +++ b/wrlib/convert.c @@ -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 @@ -20,23 +20,6 @@ */ #include -/* AIX requires this to be the first thing in the file. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX -# pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -#endif - #include #include @@ -46,14 +29,40 @@ char *alloca (); #include +#ifdef BENCH +#include "bench.h" +#endif + #include "wraster.h" #ifdef XSHM -Pixmap R_CreateXImageMappedPixmap(RContext *context, RXImage *ximage); +extern Pixmap R_CreateXImageMappedPixmap(RContext *context, RXImage *ximage); #endif +#ifdef ASM_X86_MMX + +extern int x86_check_mmx(); + +extern void x86_TrueColor_32_to_16(unsigned char *image, + unsigned short *ximage, + short *err, short *nerr, + short *rtable, short *gtable, + short *btable, + int dr, int dg, int db, + unsigned int roffs, + unsigned int goffs, + unsigned int boffs, + int width, int height, + int line_offset); + + + +#endif /* X86_ASM */ + + + typedef struct RConversionTable { unsigned short table[256]; unsigned short index; @@ -137,171 +146,100 @@ computeStdTable(unsigned int mult, unsigned int max) return tmp->table; } +/***************************************************************************/ -static RXImage* -image2TrueColorD16(RContext *ctx, RImage *image) +static void +convertTrueColor_generic(RXImage *ximg, RImage *image, + char *err, char *nerr, + const short *rtable, + const short *gtable, + const short *btable, + const int dr, const int dg, const int db, + const unsigned short roffs, + const unsigned short goffs, + const unsigned short boffs) { - RXImage *ximg; - register int x, y, r, g, b; - unsigned char *red, *grn, *blu; - 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) { - return NULL; - } - - red = image->data[0]; - grn = image->data[1]; - blu = image->data[2]; + char *terr; + int x, y, r, g, b; + int pixel; + int rer, ger, ber; + unsigned char *ptr = image->data; + int channels = image->format == RRGBAFormat ? 4 : 3; - roffs = ctx->red_offset; - goffs = ctx->green_offset; - boffs = ctx->blue_offset; - - rmask = ctx->visual->red_mask >> roffs; - gmask = ctx->visual->green_mask >> goffs; - bmask = ctx->visual->blue_mask >> boffs; + /* convert and dither the image to XImage */ + for (y=0; yheight; y++) { + nerr[0] = 0; + nerr[1] = 0; + nerr[2] = 0; + for (x=0; xwidth; x++, ptr+=channels) { - rtable = computeTable(rmask); - gtable = computeTable(gmask); - btable = computeTable(bmask); + /* reduce pixel */ + pixel = *ptr + err[x]; + if (pixel<0) pixel=0; else if (pixel>0xff) pixel=0xff; + r = rtable[pixel]; + /* calc error */ + rer = pixel - r*dr; - if (rtable==NULL || gtable==NULL || btable==NULL) { - RErrorCode = RERR_NOMEMORY; - RDestroyXImage(ctx, ximg); - return NULL; + /* reduce pixel */ + pixel = *(ptr+1) + err[x+1]; + if (pixel<0) pixel=0; else if (pixel>0xff) pixel=0xff; + g = gtable[pixel]; + /* calc error */ + ger = pixel - g*dg; + + /* reduce pixel */ + pixel = *(ptr+2) + err[x+2]; + if (pixel<0) pixel=0; else if (pixel>0xff) pixel=0xff; + b = btable[pixel]; + /* calc error */ + ber = pixel - b*db; + + + pixel = (r<image, x, y, pixel); + + /* distribute error */ + r = (rer*3)/8; + g = (ger*3)/8; + b = (ber*3)/8; + /* x+1, y */ + err[x+3*1]+=r; + err[x+1+3*1]+=g; + err[x+2+3*1]+=b; + /* x, y+1 */ + nerr[x]+=r; + nerr[x+1]+=g; + nerr[x+2]+=b; + /* x+1, y+1 */ + nerr[x+3*1]=rer-2*r; + nerr[x+1+3*1]=ger-2*g; + nerr[x+2+3*1]=ber-2*b; + } + /* skip to next line */ + terr = err; + err = nerr; + nerr = terr; } - - { - /* dither */ - short *rerr, *gerr, *berr; - short *nrerr, *ngerr, *nberr; - short *terr; - unsigned short *dataP; - int line_offset; - int rer, ger, ber; - const int dr=0xff/rmask; - const int dg=0xff/gmask; - const int db=0xff/bmask; - - 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) { - RErrorCode = RERR_NOMEMORY; - RDestroyXImage(ctx, ximg); - return NULL; - } - for (x=0; xwidth; x++) { - rerr[x] = red[x]; - gerr[x] = grn[x]; - berr[x] = blu[x]; - } - rerr[x] = gerr[x] = berr[x] = 0; - - dataP = (unsigned short*)ximg->image->data; - line_offset = ximg->image->bytes_per_line - image->width * 2; - - /* convert and dither the image to XImage */ - for (y=0, ofs=0; yheight; y++) { - if (yheight-1) { - int x1; - for (x=0, x1=ofs+image->width; xwidth; x++, x1++) { - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; - } - /* last column */ - x1--; - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; - } - for (x=0; xwidth; x++) { - /* reduce pixel */ - 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]]; - - *(dataP++) = (r<width; - /*(char*)dataP += line_offset;*/ - dataP = (unsigned short *)((char *)dataP + line_offset); - - /* skip to next line */ - terr = rerr; - rerr = nrerr; - nrerr = terr; - - terr = gerr; - gerr = ngerr; - ngerr = terr; - - terr = berr; - berr = nberr; - nberr = terr; - } - } - return ximg; } + + static RXImage* image2TrueColor(RContext *ctx, RImage *image) { RXImage *ximg; - register int x, y, r, g, b; - unsigned char *red, *grn, *blu; - unsigned long pixel; unsigned short rmask, gmask, bmask; unsigned short roffs, goffs, boffs; unsigned short *rtable, *gtable, *btable; - int ofs; + int channels = (image->format == RRGBAFormat ? 4 : 3); ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height); if (!ximg) { return NULL; } - red = image->data[0]; - grn = image->data[1]; - blu = image->data[2]; - roffs = ctx->red_offset; goffs = ctx->green_offset; boffs = ctx->blue_offset; @@ -310,25 +248,6 @@ image2TrueColor(RContext *ctx, RImage *image) gmask = ctx->visual->green_mask >> goffs; bmask = ctx->visual->blue_mask >> boffs; -#if 0 - /* this do not seem to increase speed. Only 0.06 second faster in - * rendering a 800x600 image to pixmap. 1.12 sec instead of 1.18. - * But does not require a 256*256*256 lookup table. - */ - if (ctx->depth==24) { -#ifdef DEBUG - puts("true color match for 24bpp"); -#endif - for (y=0; y < image->height; y++) { - for (x=0; x < image->width; x++) { - pixel = (*(red++)<image, x, y, pixel); - } - } - return ximg; - } -#endif - rtable = computeTable(rmask); gtable = computeTable(gmask); btable = computeTable(bmask); @@ -339,27 +258,29 @@ image2TrueColor(RContext *ctx, RImage *image) return NULL; } + if (ctx->attribs->render_mode==RBestMatchRendering) { + int ofs, r, g, b; + int x, y; + unsigned long pixel; + unsigned char *ptr = image->data; + /* fake match */ #ifdef DEBUG puts("true color match"); #endif for (y=0, ofs=0; y < image->height; y++) { - for (x=0; x < image->width; x++, ofs++) { + for (x=0; x < image->width; x++, ofs+=channels-3) { /* reduce pixel */ - r = rtable[red[ofs]]; - g = gtable[grn[ofs]]; - b = btable[blu[ofs]]; + r = rtable[ptr[ofs++]]; + g = gtable[ptr[ofs++]]; + b = btable[ptr[ofs++]]; pixel = (r<image, x, y, pixel); } } } else { /* dither */ - 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; @@ -367,91 +288,78 @@ image2TrueColor(RContext *ctx, RImage *image) #ifdef DEBUG puts("true color dither"); #endif - 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) { - RErrorCode = RERR_NOMEMORY; - RDestroyXImage(ctx, ximg); - return NULL; - } - for (x=0; xwidth; 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, ofs=0; yheight; y++) { - if (yheight-1) { - int x1; - for (x=0, x1=ofs+image->width; xwidth; x++, x1++) { - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; - } - /* last column */ - x1--; - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; + +#ifdef BENCH + cycle_bench(1); +#endif + +#ifdef ASM_X86_MMX + if (ctx->depth == 16 && image->format == RRGBAFormat + && x86_check_mmx()) { + short *err; + short *nerr; + + err = malloc(8*(image->width+3)); + nerr = malloc(8*(image->width+3)); + if (!err || !nerr) { + if (nerr) + free(nerr); + RErrorCode = RERR_NOMEMORY; + RDestroyXImage(ctx, ximg); + return NULL; } - for (x=0; xwidth; x++) { - /* reduce pixel */ - 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; + memset(err, 0, 8*(image->width+3)); + memset(nerr, 0, 8*(image->width+3)); + + x86_TrueColor_32_to_16(image->data, + (unsigned short*)ximg->image->data, + err+8, nerr+8, + rtable, gtable, btable, + dr, dg, db, + roffs, goffs, boffs, + image->width, image->height, + ximg->image->bytes_per_line - 2*image->width); - r = rtable[rerr[x]]; - g = gtable[gerr[x]]; - b = btable[berr[x]]; + free(err); + free(nerr); + } else +#endif /* ASM_X86_MMX */ + { + char *err; + char *nerr; + int ch = image->format == RRGBAFormat ? 4 : 3; - pixel = (r<image, x, y, pixel); - /* calc error */ - rer = rerr[x] - r*dr; - ger = gerr[x] - g*dg; - ber = berr[x] - b*db; - - /* distribute error */ - 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; + err = malloc(ch*(image->width+2)); + nerr = malloc(ch*(image->width+2)); + if (!err || !nerr) { + if (nerr) + free(nerr); + RErrorCode = RERR_NOMEMORY; + RDestroyXImage(ctx, ximg); + return NULL; } - ofs+=image->width; - /* skip to next line */ - terr = rerr; - rerr = nrerr; - nrerr = terr; + + memset(err, 0, ch*(image->width+2)); + memset(nerr, 0, ch*(image->width+2)); - terr = gerr; - gerr = ngerr; - ngerr = terr; - - terr = berr; - berr = nberr; - nberr = terr; + convertTrueColor_generic(ximg, image, err, nerr, + rtable, gtable, btable, + dr, dg, db, roffs, goffs, boffs); + free(err); + free(nerr); } + } + +#ifdef BENCH + cycle_bench(0); +#endif + return ximg; } +/***************************************************************************/ static RXImage* @@ -459,7 +367,7 @@ image2PseudoColor(RContext *ctx, RImage *image) { RXImage *ximg; register int x, y, r, g, b; - unsigned char *red, *grn, *blu; + unsigned char *ptr; unsigned long pixel; const int cpc=ctx->attribs->colors_per_channel; const unsigned short rmask = cpc-1; /* different sizes could be used */ @@ -469,6 +377,7 @@ image2PseudoColor(RContext *ctx, RImage *image) const int cpccpc = cpc*cpc; unsigned char *data; int ofs; + int channels = image->format == RRGBAFormat ? 4 : 3; /*register unsigned char maxrgb = 0xff;*/ ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height); @@ -476,9 +385,7 @@ image2PseudoColor(RContext *ctx, RImage *image) return NULL; } - red = image->data[0]; - grn = image->data[1]; - blu = image->data[2]; + ptr = image->data; data = (unsigned char *)ximg->image->data; @@ -498,12 +405,12 @@ image2PseudoColor(RContext *ctx, RImage *image) #ifdef DEBUG printf("pseudo color match with %d colors per channel\n", cpc); #endif - for (y=0, ofs = 0; yheight; y++) { - for (x=0; xwidth; x++, ofs++) { + for (y=0; yheight; y++) { + for (x=0; xwidth; x++, ptr+=channels-1) { /* reduce pixel */ - r = rtable[red[ofs]]; - g = gtable[grn[ofs]]; - b = btable[blu[ofs]]; + r = rtable[*ptr++]; + g = gtable[*ptr++]; + b = btable[*ptr++]; pixel = r*cpccpc + g*cpc + b; /*data[ofs] = ctx->colors[pixel].pixel;*/ XPutPixel(ximg->image, x, y, ctx->colors[pixel].pixel); @@ -511,118 +418,95 @@ image2PseudoColor(RContext *ctx, RImage *image) } } else { /* dither */ - short *rerr, *gerr, *berr; - short *nrerr, *ngerr, *nberr; + short *err; + short *nerr; short *terr; int rer, ger, ber; const int dr=0xff/rmask; const int dg=0xff/gmask; const int db=0xff/bmask; + int i; #ifdef DEBUG printf("pseudo color dithering with %d colors per channel\n", cpc); #endif - 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) { + err = (short*)malloc(3*(image->width+2)*sizeof(short)); + nerr = (short*)malloc(3*(image->width+2)*sizeof(short)); + if (!err || !nerr) { + if (nerr) + free(nerr); RErrorCode = RERR_NOMEMORY; RDestroyXImage(ctx, ximg); return NULL; } - for (x=0; xwidth; x++) { - rerr[x] = red[x]; - gerr[x] = grn[x]; - berr[x] = blu[x]; + for (x=0, i=0; xwidth*3; x+=channels-3) { + err[i++] = ptr[x++]; + err[i++] = ptr[x++]; + err[i++] = ptr[x++]; } - rerr[x] = gerr[x] = berr[x] = 0; + err[x++] = err[x++] = err[x++] = 0; /* convert and dither the image to XImage */ - for (y=0, ofs=0; yheight; y++) { + for (ofs=0, y=0; yheight; y++) { if (yheight-1) { int x1; - for (x=0, x1=ofs+image->width; xwidth; x++, x1++) { - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; + for (x=0, x1=((y+1)*image->width)*channels; + xwidth*3; x1+=channels-3) { + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; } /* last column */ - x1--; - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; + x1-=channels; + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; } - for (x=0; xwidth; x++, ofs++) { + for (x=0; xwidth*3; x+=3, ofs++) { /* reduce pixel */ - 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; + if (err[x]>0xff) err[x]=0xff; else if (err[x]<0) err[x]=0; + if (err[x+1]>0xff) err[x+1]=0xff; else if (err[x+1]<0) err[x+1]=0; + if (err[x+2]>0xff) err[x+2]=0xff; else if (err[x+2]<0) err[x+2]=0; - r = rtable[rerr[x]]; - g = gtable[gerr[x]]; - b = btable[berr[x]]; + r = rtable[err[x]]; + g = gtable[err[x+1]]; + b = btable[err[x+2]]; pixel = r*cpccpc + g*cpc + b; - /*data[ofs] = ctx->colors[pixel].pixel;*/ - XPutPixel(ximg->image, x, y, ctx->colors[pixel].pixel); + data[ofs] = ctx->colors[pixel].pixel; /* calc error */ - rer = rerr[x] - r*dr; - ger = gerr[x] - g*dg; - ber = berr[x] - b*db; + rer = err[x] - r*dr; + ger = err[x+1] - g*dg; + ber = err[x+2] - b*db; /* distribute error */ - rerr[x+1]+=(rer*7)/16; - gerr[x+1]+=(ger*7)/16; - berr[x+1]+=(ber*7)/16; + err[x+3*1]+=(rer*7)/16; + err[x+1+3*1]+=(ger*7)/16; + err[x+2+3*1]+=(ber*7)/16; - nrerr[x]+=(rer*5)/16; - ngerr[x]+=(ger*5)/16; - nberr[x]+=(ber*5)/16; + nerr[x]+=(rer*5)/16; + nerr[x]+=(ger*5)/16; + nerr[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; + nerr[x-3*1]+=(rer*3)/16; + nerr[x-(3*1)+1]+=(ger*3)/16; + nerr[x-(3*1)+2]+=(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; - 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; -#endif + nerr[x+3*1]+=rer/16; + nerr[x+1+3*1]+=ger/16; + nerr[x+2+3*1]+=ber/16; } /* skip to next line */ - terr = rerr; - rerr = nrerr; - nrerr = terr; - - terr = gerr; - gerr = ngerr; - ngerr = terr; - - terr = berr; - berr = nberr; - nberr = terr; + terr = err; + err = nerr; + nerr = terr; + + ofs += ximg->image->bytes_per_line - image->width; } + free(err); + free(nerr); } ximg->image->data = (char*)data; @@ -638,12 +522,12 @@ image2StandardPseudoColor(RContext *ctx, RImage *image) { RXImage *ximg; register int x, y, r, g, b; - unsigned char *red, *grn, *blu; + unsigned char *ptr; unsigned long pixel; unsigned char *data; unsigned int *rtable, *gtable, *btable; unsigned int base_pixel = ctx->std_rgb_map->base_pixel; - int ofs; + int channels = image->format == RRGBAFormat ? 4 : 3; /*register unsigned char maxrgb = 0xff;*/ ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height); @@ -651,13 +535,11 @@ image2StandardPseudoColor(RContext *ctx, RImage *image) return NULL; } - red = image->data[0]; - grn = image->data[1]; - blu = image->data[2]; + ptr = image->data; data = (unsigned char *)ximg->image->data; - + rtable = computeStdTable(ctx->std_rgb_map->red_mult, ctx->std_rgb_map->red_max); @@ -675,109 +557,107 @@ image2StandardPseudoColor(RContext *ctx, RImage *image) if (ctx->attribs->render_mode == RBestMatchRendering) { - for (y=0, ofs = 0; yheight; y++) { - for (x=0; xwidth; x++, ofs++) { + for (y=0; yheight; y++) { + for (x=0; xwidth; x++, ptr+=channels-3) { /* reduce pixel */ - - pixel = (rtable[red[ofs]] + gtable[grn[ofs]] - + btable[blu[ofs]] + base_pixel) & 0xffffffff; + pixel = (rtable[*ptr++] + gtable[*ptr++] + + btable[*ptr++] + base_pixel) & 0xffffffff; XPutPixel(ximg->image, x, y, pixel); } } } else { /* dither */ - short *rerr, *gerr, *berr; - short *nrerr, *ngerr, *nberr; + short *err, *nerr; short *terr; int rer, ger, ber; + int x1, ofs; #ifdef DEBUG printf("pseudo color dithering with %d colors per channel\n", cpc); #endif - 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) { + err = (short*)malloc(3*(image->width+2)*sizeof(short)); + nerr = (short*)malloc(3*(image->width+2)*sizeof(short)); + if (!err || !nerr) { + if (nerr) + free(nerr); RErrorCode = RERR_NOMEMORY; RDestroyXImage(ctx, ximg); return NULL; } - for (x=0; xwidth; x++) { - rerr[x] = red[x]; - gerr[x] = grn[x]; - berr[x] = blu[x]; + for (x=0, x1=0; xwidth*3; x1+=channels-3) { + err[x++] = ptr[x1++]; + err[x++] = ptr[x1++]; + err[x++] = ptr[x1++]; } - rerr[x] = gerr[x] = berr[x] = 0; + err[x++] = err[x++] = err[x++] = 0; /* convert and dither the image to XImage */ for (y=0, ofs=0; yheight; y++) { if (yheight-1) { int x1; - for (x=0, x1=ofs+image->width; xwidth; x++, x1++) { - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; + for (x=0, x1=(y+1)*image->width*channels; + xwidth*3; + x1+=channels-3) { + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; } /* last column */ - x1--; - nrerr[x] = red[x1]; - ngerr[x] = grn[x1]; - nberr[x] = blu[x1]; + x1-=channels; + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; + nerr[x++] = ptr[x1++]; } - for (x=0; xwidth; x++, ofs++) { + for (x=0; xwidth*3; x+=3, ofs++) { /* reduce pixel */ - 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; + if (err[x]>0xff) err[x]=0xff; else if (err[x]<0) err[x]=0; + if (err[x+1]>0xff) err[x+1]=0xff; else if (err[x+1]<0) err[x+1]=0; + if (err[x+2]>0xff) err[x+2]=0xff; else if (err[x+2]<0) err[x+2]=0; - r = rtable[rerr[x]]; - g = gtable[gerr[x]]; - b = btable[berr[x]]; + r = rtable[err[x]]; + g = gtable[err[x+1]]; + b = btable[err[x+2]]; pixel = r + g + b; + data[ofs] = base_pixel + pixel; +/* XPutPixel(ximg->image, x, y, pixel+base_pixel); + */ /* calc error */ - rer = rerr[x] - (ctx->colors[pixel].red>>8); - ger = gerr[x] - (ctx->colors[pixel].green>>8); - ber = berr[x] - (ctx->colors[pixel].blue>>8); + rer = err[x] - (ctx->colors[pixel].red>>8); + ger = err[x+1] - (ctx->colors[pixel].green>>8); + ber = err[x+2] - (ctx->colors[pixel].blue>>8); /* 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; + err[x+3*1]+=(rer*7)/16; + err[x+1+3*1]+=(ger*7)/16; + err[x+2+3*1]+=(ber*7)/16; + + nerr[x]+=(rer*5)/16; + nerr[x+1]+=(ger*5)/16; + nerr[x+2]+=(ber*5)/16; if (x>0) { - nrerr[x-1]+=(rer*3)/16; - ngerr[x-1]+=(ger*3)/16; - nberr[x-1]+=(ber*3)/16; + nerr[x-3*1]+=(rer*3)/16; + nerr[x-3*1+1]+=(ger*3)/16; + nerr[x-3*1+2]+=(ber*3)/16; } - nrerr[x+1]+=rer/16; - ngerr[x+1]+=ger/16; - nberr[x+1]+=ber/16; + nerr[x+3*1]+=rer/16; + nerr[x+1+3*1]+=ger/16; + nerr[x+2+3*1]+=ber/16; } /* skip to next line */ - terr = rerr; - rerr = nrerr; - nrerr = terr; + terr = err; + err = nerr; + nerr = terr; - terr = gerr; - gerr = ngerr; - ngerr = terr; - - terr = berr; - berr = nberr; - nberr = terr; + ofs += ximg->image->bytes_per_line - image->width; } + free(err); + free(nerr); } ximg->image->data = (char*)data; @@ -791,12 +671,13 @@ image2GrayScale(RContext *ctx, RImage *image) { RXImage *ximg; register int x, y, g; - unsigned char *red, *grn, *blu; + unsigned char *ptr; const int cpc=ctx->attribs->colors_per_channel; unsigned short gmask; unsigned short *table; unsigned char *data; - int ofs; + int channels = image->format == RRGBAFormat ? 4 : 3; + /*register unsigned char maxrgb = 0xff;*/ ximg = RCreateXImage(ctx, ctx->depth, image->width, image->height); @@ -804,9 +685,7 @@ image2GrayScale(RContext *ctx, RImage *image) return NULL; } - red = image->data[0]; - grn = image->data[1]; - blu = image->data[2]; + ptr = image->data; data = (unsigned char *)ximg->image->data; @@ -828,10 +707,10 @@ image2GrayScale(RContext *ctx, RImage *image) #ifdef DEBUG printf("grayscale match with %d colors per channel\n", cpc); #endif - for (y=0, ofs = 0; yheight; y++) { - for (x=0; xwidth; x++, ofs++) { + for (y=0; yheight; y++) { + for (x=0; xwidth; x++) { /* reduce pixel */ - g = table[(red[ofs]*30+grn[ofs]*59+blu[ofs]*11)/100]; + g = table[(*ptr++ * 30 + *ptr++ * 59 + *ptr++ * 11)/100]; /*data[ofs] = ctx->colors[g].pixel;*/ XPutPixel(ximg->image, x, y, ctx->colors[g].pixel); @@ -848,29 +727,33 @@ image2GrayScale(RContext *ctx, RImage *image) #ifdef DEBUG printf("grayscale dither with %d colors per channel\n", cpc); #endif - gerr = (short*)alloca((image->width+2)*sizeof(short)); - ngerr = (short*)alloca((image->width+2)*sizeof(short)); + gerr = (short*)malloc((image->width+2)*sizeof(short)); + ngerr = (short*)malloc((image->width+2)*sizeof(short)); if (!gerr || !ngerr) { + if (ngerr) + free(ngerr); RErrorCode = RERR_NOMEMORY; RDestroyXImage(ctx, ximg); return NULL; } for (x=0; xwidth; x++) { - gerr[x] = (red[x]*30 + grn[x]*59 + blu[x]*11)/100; + gerr[x] = (ptr[x*3]*30 + ptr[x*3+1]*59 + ptr[x*3+2]*11)/100; } gerr[x] = 0; /* convert and dither the image to XImage */ - for (y=0, ofs=0; yheight; y++) { + for (y=0; yheight; y++) { if (yheight-1) { int x1; - for (x=0, x1=ofs+image->width; xwidth; x++, x1++) { - ngerr[x] = (red[x1]*30 + grn[x1]*59 + blu[x1]*11)/100; + for (x=0, x1=(y+1)*image->width*3; + xwidth; + x1+=channels-3) { + ngerr[x] = (ptr[x1++]*30 + ptr[x1++]*59 + ptr[x1++]*11)/100; } /* last column */ - x1--; - ngerr[x] = (red[x1]*30 + grn[x1]*59 + blu[x1]*11)/100; + x1-=channels; + ngerr[x] = (ptr[x1++]*30 + ptr[x1++]*59 + ptr[x1++]*11)/100; } - for (x=0; xwidth; x++, ofs++) { + for (x=0; xwidth; x++) { /* reduce pixel */ if (gerr[x]>0xff) gerr[x]=0xff; else if (gerr[x]<0) gerr[x]=0; @@ -895,6 +778,8 @@ image2GrayScale(RContext *ctx, RImage *image) gerr = ngerr; ngerr = terr; } + free(gerr); + free(ngerr); } ximg->image->data = (char*)data; @@ -913,12 +798,12 @@ image2Bitmap(RContext *ctx, RImage *image, int threshold) if (!ximg) { return NULL; } - alpha = image->data[3]; + alpha = image->data+3; for (y = 0; y < image->height; y++) { for (x = 0; x < image->width; x++) { XPutPixel(ximg->image, x, y, (*alpha <= threshold ? 0 : 1)); - alpha++; + alpha+=4; } } @@ -942,11 +827,7 @@ RConvertImage(RContext *context, RImage *image, Pixmap *pixmap) /* clear error message */ if (context->vclass == TrueColor) { - if (context->attribs->render_mode == RDitheredRendering - && (context->depth == 15 || context->depth == 16)) - ximg = image2TrueColorD16(context, image); - else - ximg = image2TrueColor(context, image); + ximg = image2TrueColor(context, image); } else if (context->vclass == PseudoColor || context->vclass == StaticColor) { @@ -962,9 +843,6 @@ RConvertImage(RContext *context, RImage *image, Pixmap *pixmap) } if (!ximg) { -#ifdef C_ALLOCA - alloca(0); -#endif return False; } @@ -1002,9 +880,6 @@ RConvertImage(RContext *context, RImage *image, Pixmap *pixmap) RDestroyXImage(context, ximg); -#ifdef C_ALLOCA - alloca(0); -#endif return True; } @@ -1025,7 +900,7 @@ RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap, if (!RConvertImage(context, image, pixmap)) return False; - if (image->data[3]==NULL) { + if (image->format==RRGBFormat) { *mask = None; return True; } @@ -1033,9 +908,6 @@ RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap, ximg = image2Bitmap(context, image, threshold); if (!ximg) { -#ifdef C_ALLOCA - alloca(0); -#endif return False; } *mask = XCreatePixmap(context->dpy, context->drawable, image->width, @@ -1049,9 +921,6 @@ RConvertImageMask(RContext *context, RImage *image, Pixmap *pixmap, image->width, image->height); RDestroyXImage(context, ximg); -#ifdef C_ALLOCA - alloca(0); -#endif return True; } diff --git a/wrlib/convolve.c b/wrlib/convolve.c index fb2b45d6..08f4237c 100644 --- a/wrlib/convolve.c +++ b/wrlib/convolve.c @@ -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 -/* AIX requires this to be the first thing in the file. */ -#ifdef __GNUC__ -# define alloca __builtin_alloca -#else -# if HAVE_ALLOCA_H -# include -# else -# ifdef _AIX -# pragma alloca -# else -# ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -# endif -# endif -# endif -#endif - #include #include @@ -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; xwidth; 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; - - for (y=1; yheight-1; y++) { - pr[w-1] = r[w-1]; - pg[w-1] = g[w-1]; - pb[w-1] = b[w-1]; +#define MASK(prev, cur, next, ch)\ + (*(prev-ch) + *prev + *(prev+ch)\ + +*(cur-ch) + 2 * *cur + *(cur+ch)\ + +*(next-ch) + *next + *(next+ch)) / 10 - pr[0] = *(r++); - pg[0] = *(g++); - pb[0] = *(b++); - - for (x=1; xwidth-1; x++) { - tmp = *r; - *(r++) = MASK(r,pr,x); - pr[x] = tmp; - - tmp = *g; - *(g++) = MASK(g,pg,x); - pg[x] = tmp; - - tmp = *b; - *(b++) = MASK(b,pb,x); - pb[x] = tmp; + memcpy(pptr, image->data, image->width * ch); + + ptr = image->data; + nptr = ptr + image->width*ch; + tmpp = pptr; + + if (ch == 3) { + ptr+=3; + nptr+=3; + pptr+=3; + + for (y = 1; y < image->height-1; y++) { + + 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; } - r++; - g++; - b++; - } + } else { + ptr+=4; + nptr+=4; + pptr+=4; -#undef MASK + 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; + } + } -#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]; - - w = image->width; + ptr = image->data; + + + w = image->width*ch; for (y=0; yheight - 1; y++) { for (x=0; xwidth - 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 * *g + 3 * *(g + w); - *(g++) = v/6; - - v = 3 * *b + 3 * *(b + w); - *(b++) = 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; + + ptr+= ch; } /* last line */ for (x=0; xwidth - 1; x++) { - v = 3 * *r + 3 * *(r + 1); - *(r++) = v/6; - - v = 3 * *g + 3 * *(g + 1); - *(g++) = v/6; - - v = 3 * *b + 3 * *(b + 1); - *(b++) = 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; + + ptr+= ch; } return True; diff --git a/wrlib/draw.c b/wrlib/draw.c index bbcc9c12..fc2df662 100644 --- a/wrlib/draw.c +++ b/wrlib/draw.c @@ -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, } } - diff --git a/wrlib/gif.c b/wrlib/gif.c index 0a98ebb8..3719c4d8 100644 --- a/wrlib/gif.c +++ b/wrlib/gif.c @@ -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; } diff --git a/wrlib/gradient.c b/wrlib/gradient.c index cfaad316..885b3fe6 100644 --- a/wrlib/gradient.c +++ b/wrlib/gradient.c @@ -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>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; idata[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; @@ -190,14 +185,23 @@ renderVGradient(unsigned width, unsigned height, int r0, int g0, int b0, dr = ((rf-r0)<<16)/(int)height; dg = ((gf-g0)<<16)/(int)height; db = ((bf-b0)<<16)/(int)height; + for (i=0; i>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; jdata[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; ydata[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; idata[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>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>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; idata[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>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; xgreen << 16; b = colors[i]->blue << 16; } - for (j=k; j>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; xdata[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; diff --git a/wrlib/jpeg.c b/wrlib/jpeg.c index 3995fb6d..33e73f5c 100644 --- a/wrlib/jpeg.c +++ b/wrlib/jpeg.c @@ -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; iflags.optimize_for_speed) { + while (cinfo.output_scanline < cinfo.output_height) { + jpeg_read_scanlines(&cinfo, buffer,(JDIMENSION) 1); + bptr = buffer[0]; + for (i=0; i #include @@ -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; iformat == RRGBAFormat) { + d++; + } } } } - const char* RMessageForError(int errorCode) { @@ -172,4 +191,3 @@ RMessageForError(int errorCode) return "internal error"; } } - diff --git a/wrlib/nxpm.c b/wrlib/nxpm.c index 4bd0e151..560350cd 100644 --- a/wrlib/nxpm.c +++ b/wrlib/nxpm.c @@ -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; idata[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; idata[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++) { diff --git a/wrlib/png.c b/wrlib/png.c index 9924fb41..fa0c83c7 100644 --- a/wrlib/png.c +++ b/wrlib/png.c @@ -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; ydata[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 { diff --git a/wrlib/raster.c b/wrlib/raster.c index 70879714..b2f1e3a8 100644 --- a/wrlib/raster.c +++ b/wrlib/raster.c @@ -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; - - dr = new_image->data[0]; - dg = new_image->data[1]; - db = new_image->data[2]; - da = new_image->data[3]; - + total_line_size = image->width * (HAS_ALPHA(image) ? 4 : 3); + line_size = width * (HAS_ALPHA(image) ? 4 : 3); + + ofs = x*(HAS_ALPHA(image) ? 4 : 3); + for (i=0; iwidth; - 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]; - - 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); + 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; + + 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; iheight*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; iheight*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; iheight*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; iwidth*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; iwidth*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; iwidth*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; ywidth - 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; ywidth - 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; ydata + 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; ydata[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; iwidth*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; } } diff --git a/wrlib/scale.c b/wrlib/scale.c index 7c611380..6cf68d8d 100644 --- a/wrlib/scale.c +++ b/wrlib/scale.c @@ -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; ywidth*(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>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; ywidth*(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>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,9 +432,11 @@ 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); /* create intermediate image to hold horizontal zoom */ @@ -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,62 +569,46 @@ 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) { free(contrib[i].p); @@ -642,7 +616,7 @@ RSmoothScaleImage(RImage *src, unsigned new_width, unsigned new_height) free(contrib); RDestroyImage(tmp); - + return dst; } diff --git a/wrlib/testgrad.c b/wrlib/testgrad.c index 2624f113..b7b426ad 100644 --- a/wrlib/testgrad.c +++ b/wrlib/testgrad.c @@ -10,6 +10,7 @@ #include #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); diff --git a/wrlib/tiff.c b/wrlib/tiff.c index bd67d703..9b9ba9dc 100644 --- a/wrlib/tiff.c +++ b/wrlib/tiff.c @@ -47,6 +47,7 @@ RLoadTIFF(RContext *context, char *file, int index) uint32 *data, *ptr; uint16 extrasamples; uint16 *sampleinfo; + int ch; tif = TIFFOpen(file, "r"); @@ -93,14 +94,19 @@ 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; diff --git a/wrlib/tile.xpm b/wrlib/tile.xpm index df4882ab..82b3927a 100644 --- a/wrlib/tile.xpm +++ b/wrlib/tile.xpm @@ -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#", +".###############################################################" +}; diff --git a/wrlib/view.c b/wrlib/view.c index 8dcb14ab..990a9879 100644 --- a/wrlib/view.c +++ b/wrlib/view.c @@ -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 @@ -53,16 +53,18 @@ int main(int argc, char **argv) puts(RMessageForError(RErrorCode)); 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); } diff --git a/wrlib/wraster.h b/wrlib/wraster.h index e3634c60..7917d3c5 100644 --- a/wrlib/wraster.h +++ b/wrlib/wraster.h @@ -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 @@ -145,6 +145,7 @@ typedef struct RContext { struct { unsigned int use_shared_pixmap:1; + unsigned int optimize_for_speed:1; } flags; } RContext; @@ -174,14 +175,23 @@ typedef struct RSegment { int x1, y1, x2, y2; } 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; @@ -198,7 +208,6 @@ typedef struct RXImage { #endif } RXImage; - /* image display modes */ enum { @@ -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 diff --git a/wrlib/x86_specific.c b/wrlib/x86_specific.c new file mode 100644 index 00000000..80595442 --- /dev/null +++ b/wrlib/x86_specific.c @@ -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 + + +#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 = >able[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<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 */ + diff --git a/wrlib/xpixmap.c b/wrlib/xpixmap.c index 92885230..6a81668c 100644 --- a/wrlib/xpixmap.c +++ b/wrlib/xpixmap.c @@ -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; } } } diff --git a/wrlib/xpm.c b/wrlib/xpm.c index a0058639..664e4bd5 100644 --- a/wrlib/xpm.c +++ b/wrlib/xpm.c @@ -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; idata[0]; - g = image->data[1]; - b = image->data[2]; - a = image->data[3]; - for (i=0; idata; + for (i=0; i