Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/engine/anti.c
diff options
context:
space:
mode:
authorBernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
committer Bernie Innocenti <bernie@codewiz.org>2010-05-03 21:53:47 (GMT)
commit1030dc837b10a03a02a85d5504cbeec168ce49e2 (patch)
tree698eefa87ac437deaf36a4141b326f8ce7986692 /src/engine/anti.c
Import XaoS r489 (trunk after version 3.5)
Diffstat (limited to 'src/engine/anti.c')
-rw-r--r--src/engine/anti.c358
1 files changed, 358 insertions, 0 deletions
diff --git a/src/engine/anti.c b/src/engine/anti.c
new file mode 100644
index 0000000..819d33e
--- /dev/null
+++ b/src/engine/anti.c
@@ -0,0 +1,358 @@
+#include <config.h>
+#ifndef _plan9_
+#ifndef __cplusplus
+#include <math.h>
+#endif
+#ifndef NO_MALLOC_H
+#include <malloc.h>
+#endif
+#include <string.h>
+#include <config.h>
+#include <stdio.h>
+#ifdef HAVE_ALLOCA_H
+#include <alloca.h>
+#endif
+#include <stdlib.h>
+#else
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#endif
+#include <xerror.h>
+#include <filter.h>
+#include <fractal.h>
+#include <xthread.h>
+struct antidata {
+ int shift;
+};
+static int requirement(struct filter *f, struct requirements *r)
+{
+ f->req = *r;
+ r->nimages = 1;
+ r->supportedmask = TRUECOLOR24 | TRUECOLOR | TRUECOLOR16 | GRAYSCALE;
+ return (f->next->action->requirement(f->next, r));
+}
+
+static int initialize(struct filter *f, struct initdata *i)
+{
+ struct antidata *s = (struct antidata *) f->data;
+ if (i->image->width * i->image->height * i->image->bytesperpixel * 2 *
+ 16 > 15 * 1024 * 1024) {
+ s->shift = 1;
+ } else {
+ s->shift = 2;
+ }
+ inhermisc(f, i);
+ if (!inherimage
+ (f, i, TOUCHIMAGE | IMAGEDATA,
+ (int) (((unsigned int) i->image->width) << s->shift),
+ (int) (((unsigned int) i->image->height) << s->shift), NULL, 0,
+ 0))
+ return 0;
+ if (i->image == NULL) {
+ return 0;
+ }
+ return (f->previous->action->initialize(f->previous, i));
+}
+
+static struct filter *getinstance(CONST struct filteraction *a)
+{
+ struct filter *f = createfilter(a);
+ struct antidata *i = (struct antidata *) calloc(1, sizeof(*i));
+ f->childimage = NULL;
+ f->data = i;
+ f->name = "Antialiasing";
+ return (f);
+}
+
+static void destroyinstance(struct filter *f)
+{
+ destroyinheredimage(f);
+ free(f->data);
+ free(f);
+}
+
+static void antigray(void *data, struct taskinfo *task, int r1, int r2)
+{
+ struct filter *f = (struct filter *) data;
+ struct image *srci = f->childimage, *desti = f->image;
+ struct antidata *s = (struct antidata *) f->data;
+ register unsigned char *src;
+ unsigned char *destend, *dest;
+ unsigned int ystart, y;
+ unsigned int xstart;
+ register unsigned int sum;
+ unsigned int xstep = (1U << (s->shift));
+ int i;
+ for (i = r1; i < r2; i++) {
+ dest = (unsigned char *) desti->currlines[i];
+ destend = dest + desti->width;
+ ystart = ((unsigned int) i) << s->shift;
+ xstart = 0;
+ for (; dest < destend; dest++) {
+ if (xstep > 2) {
+ sum = 0;
+ for (y = 0; y < 4; y++) {
+ src =
+ (unsigned char *) srci->currlines[y + ystart] +
+ xstart;
+ sum += (unsigned int) src[0];
+ sum += (unsigned int) src[1];
+ sum += (unsigned int) src[2];
+ sum += (unsigned int) src[3];
+ }
+ sum >>= 4;
+ } else {
+ src = (unsigned char *) srci->currlines[ystart] + xstart;
+ sum = (unsigned int) src[0];
+ sum += (unsigned int) src[1];
+ src =
+ (unsigned char *) srci->currlines[ystart + 1] + xstart;
+ sum += (unsigned int) src[0];
+ sum += (unsigned int) src[1];
+ sum >>= 2;
+ }
+ *dest = (pixel8_t) sum;
+ xstart += xstep;
+ }
+ }
+}
+
+#ifdef STRUECOLOR24
+static void anti24(void *data, struct taskinfo *task, int r1, int r2)
+{
+ struct filter *f = (struct filter *) data;
+ struct image *srci = f->childimage, *desti = f->image;
+ struct antidata *s = (struct antidata *) f->data;
+ register unsigned char *src;
+ unsigned char *destend, *dest;
+ unsigned int ystart, y;
+ unsigned int xstart;
+ register unsigned int sum;
+ unsigned int xstep = ((1U << s->shift) - 1) * 3;
+ int c = 0;
+ int i;
+ if (!srci->palette->info.truec.byteexact) {
+ x_fatalerror
+ ("Antialiasing filter:Unsupported colormask! Ask authors to add support for this :)");
+ }
+ for (i = r1; i < r2; i++) {
+ dest = (unsigned char *) desti->currlines[i];
+ destend = dest + desti->width * 3;
+ ystart = ((unsigned int) i) << s->shift;
+ xstart = 0;
+ c = 1;
+ for (; dest < destend; dest++) {
+ if (s->shift > 1) {
+ sum = 0;
+ for (y = 0; y < 4; y++) {
+ src =
+ (unsigned char *) srci->currlines[y + ystart] +
+ xstart;
+ sum += (unsigned int) src[0];
+ sum += (unsigned int) src[3];
+ sum += (unsigned int) src[6];
+ sum += (unsigned int) src[9];
+ }
+ sum >>= 4;
+ } else {
+ src = (unsigned char *) srci->currlines[ystart] + xstart;
+ sum = (unsigned int) src[0];
+ sum += (unsigned int) src[3];
+ src =
+ (unsigned char *) srci->currlines[ystart + 1] + xstart;
+ sum += (unsigned int) src[0];
+ sum += (unsigned int) src[3];
+ sum >>= 2;
+ }
+ *dest = (unsigned char) sum;
+ if (c == 3)
+ c = 0, xstart += xstep;
+ c++;
+ xstart++;
+ }
+ }
+}
+#endif
+#ifdef SUPPORT16
+#define MASKR1 ((unsigned int)((31+31744)+(31*65536*32)))
+#define MASKR2 ((unsigned int)((31+31744)*(65536/32)+31))
+
+#define MASKRH1 (31+31744)
+#define MASKRH2 (31*32)
+static void anti16(void *data, struct taskinfo *task, int r1, int r2)
+{
+ struct filter *f = (struct filter *) data;
+ struct image *srci = f->childimage, *desti = f->image;
+ struct antidata *s = (struct antidata *) f->data;
+ register unsigned int *src;
+ unsigned short *destend, *dest;
+ int ystart, y;
+ int xstart;
+ register unsigned int sum1 = 0, sum2 = 0, sum;
+ unsigned int xstep = 1U << (s->shift - 1);
+ int i;
+ unsigned int mask1 =
+ (srci->palette->info.truec.
+ mask2 | (srci->palette->info.truec.mask1 << 16)) >> 4;
+ unsigned int mask2 =
+ srci->palette->info.truec.mask1 | (srci->palette->info.truec.
+ mask2 << 16);
+ for (i = r1; i < r2; i++) {
+ dest = (unsigned short *) desti->currlines[i];
+ destend = dest + desti->width;
+ ystart = ((unsigned int) i) << s->shift;
+ xstart = 0;
+ for (; dest < destend; dest++) {
+ if (xstep > 2) {
+ sum1 = sum2 = 0;
+ for (y = 0; y < 4; y++) {
+ src =
+ (unsigned int *) srci->currlines[y + ystart] +
+ xstart;
+ sum1 += ((unsigned int) src[0] >> 4) & mask1;
+ sum2 += ((unsigned int) src[0] >> 4) & mask2;
+ sum1 += (unsigned int) src[1] & mask1;
+ sum2 += (unsigned int) src[1] & mask2;
+ }
+ sum = ((sum1 >> 4) + (sum2 >> 16)) >> 4;
+ sum1 = (sum2 + (sum1 >> 12)) >> 4;
+ } else {
+ src = (unsigned int *) srci->currlines[ystart] + xstart;
+ sum1 = ((unsigned int) src[0] >> 4) & mask1;
+ sum2 = (unsigned int) src[0] & mask2;
+ src =
+ (unsigned int *) srci->currlines[ystart + 1] + xstart;
+ sum1 += ((unsigned int) src[0] >> 4) & mask1;
+ sum2 += (unsigned int) src[0] & mask2;
+ sum = ((sum1 << 4) + (sum2 >> 16)) >> 2;
+ sum1 = (sum2 + (sum1 >> 12)) >> 2;
+ }
+ *dest =
+ (sum & srci->palette->info.truec.
+ mask2) | (sum1 & srci->palette->info.truec.mask1);
+ xstart += xstep;
+ }
+ }
+}
+#endif
+
+
+#define MASK1 0x00ff00ff
+static void anti32(void *data, struct taskinfo *task, int r1, int r2)
+{
+ struct filter *f = (struct filter *) data;
+ struct image *srci = f->childimage, *desti = f->image;
+ struct antidata *s = (struct antidata *) f->data;
+ register unsigned int *src;
+ unsigned int *destend, *dest;
+ unsigned int ystart, y;
+ unsigned int xstart;
+ register unsigned int sum1 = 0, sum2 = 0;
+ unsigned int xstep = 1U << s->shift;
+ int i;
+ if (!srci->palette->info.truec.byteexact) {
+ x_fatalerror
+ ("Antialiasing filter:Unsupported colormask2! ask authors to add support for this :)");
+ }
+ for (i = r1; i < r2; i++) {
+ dest = (unsigned int *) desti->currlines[i];
+ destend = dest + desti->width;
+ ystart = ((unsigned int) i) << s->shift;
+ xstart = 0;
+ for (; dest < destend; dest++) {
+ if (xstep > 2) {
+ sum1 = sum2 = 0;
+ for (y = 0; y < 4; y++) {
+ src =
+ (unsigned int *) srci->currlines[y + ystart] +
+ xstart;
+ sum1 += (unsigned int) src[0] & MASK1;
+ sum2 += ((unsigned int) src[0] >> 8) & MASK1;
+ sum1 += (unsigned int) src[1] & MASK1;
+ sum2 += ((unsigned int) src[1] >> 8) & MASK1;
+ sum1 += (unsigned int) src[2] & MASK1;
+ sum2 += ((unsigned int) src[2] >> 8) & MASK1;
+ sum1 += (unsigned int) src[3] & MASK1;
+ sum2 += ((unsigned int) src[3] >> 8) & MASK1;
+ }
+ sum1 >>= 4;
+ sum2 >>= 4;
+ } else {
+ src = (unsigned int *) srci->currlines[ystart] + xstart;
+ sum1 = (unsigned int) src[0] & MASK1;
+ sum2 = ((unsigned int) src[0] >> 8) & MASK1;
+ sum1 += (unsigned int) src[1] & MASK1;
+ sum2 += ((unsigned int) src[1] >> 8) & MASK1;
+ src =
+ (unsigned int *) srci->currlines[ystart + 1] + xstart;
+ sum1 += (unsigned int) src[0] & MASK1;
+ sum2 += ((unsigned int) src[0] >> 8) & MASK1;
+ sum1 += (unsigned int) src[1] & MASK1;
+ sum2 += ((unsigned int) src[1] >> 8) & MASK1;
+ sum1 >>= 2;
+ sum2 >>= 2;
+ }
+ *dest = (sum1 & MASK1) | ((sum2 & MASK1) << 8);
+ xstart += xstep;
+ }
+ }
+}
+
+static int doit(struct filter *f, int flags, int time1)
+{
+ int val;
+ updateinheredimage(f);
+ val = f->previous->action->doit(f->previous, flags, time1);
+ switch (f->image->palette->type) {
+ case GRAYSCALE:
+ xth_function(antigray, f, f->image->height);
+ break;
+#ifdef STRUECOLOR24
+ case TRUECOLOR24:
+ xth_function(anti24, f, f->image->height);
+ break;
+#endif
+#ifdef SUPPORT16
+ case TRUECOLOR16:
+ xth_function(anti16, f, f->image->height);
+ break;
+#endif
+ case TRUECOLOR:
+ xth_function(anti32, f, f->image->height);
+ break;
+ }
+ xth_sync();
+ return val;
+}
+
+static void convertup(struct filter *f, int *x, int *y)
+{
+ struct antidata *s = (struct antidata *) f->data;
+ *x >>= s->shift;
+ *y >>= s->shift;
+ f->next->action->convertup(f->next, x, y);
+}
+
+static void convertdown(struct filter *f, int *x, int *y)
+{
+ struct antidata *s = (struct antidata *) f->data;
+ *x <<= s->shift;
+ *y <<= s->shift;
+ f->previous->action->convertdown(f->previous, x, y);
+}
+
+
+CONST struct filteraction antialias_filter = {
+ "Antialiasing",
+ "anti",
+ 0,
+ getinstance,
+ destroyinstance,
+ doit,
+ requirement,
+ initialize,
+ convertup,
+ convertdown,
+ NULL,
+};