Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/engine/emboss.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/emboss.c')
-rw-r--r--src/engine/emboss.c266
1 files changed, 266 insertions, 0 deletions
diff --git a/src/engine/emboss.c b/src/engine/emboss.c
new file mode 100644
index 0000000..f5bef92
--- /dev/null
+++ b/src/engine/emboss.c
@@ -0,0 +1,266 @@
+#include <config.h>
+#ifndef _plan9_
+#ifdef NO_MALLOC_H
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#include <stdio.h>
+#else
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#endif
+#include <filter.h>
+#include <fractal.h>
+#include <xthread.h>
+struct embossdata {
+ struct palette *savedpalette, *palette;
+ int xdist, ydist;
+ unsigned int table[512];
+};
+static int requirement(struct filter *f, struct requirements *r)
+{
+ f->req = *r;
+ r->nimages = 1;
+ r->flags &= ~(IMAGEDATA);
+ r->supportedmask =
+ GRAYSCALE | C256 | TRUECOLOR24 | TRUECOLOR | TRUECOLOR16;
+
+ return (f->next->action->requirement(f->next, r));
+}
+
+static int initialize(struct filter *f, struct initdata *i)
+{
+ int x;
+ struct embossdata *s = (struct embossdata *) f->data;
+ inhermisc(f, i);
+ s->palette->size = 256 / 32;
+ for (x = 0; x < 256 / 32; x++)
+ s->palette->pixels[x] = x * 32;
+#define SSTEP (32*8/64)
+#define SSTEP2 (32*8/256)
+ if (datalost(f, i) || i->image->version != f->imageversion) {
+ if (s->savedpalette == NULL)
+ s->savedpalette = clonepalette(i->image->palette);
+ mkgraypalette(i->image->palette);
+ if (i->image->palette->type & (C256 | GRAYSCALE)) {
+ for (x = 0; x < 256; x++) {
+ int dist = (x + SSTEP - 1) / SSTEP;
+ dist += 32;
+ if (dist > 63)
+ dist = 63;
+ s->table[x] = i->image->palette->pixels[dist];
+ }
+ for (x = 256; x < 512; x++) {
+ int dist = -(512 - x + SSTEP - 1) / SSTEP;
+ dist += 32;
+ if (dist < 0)
+ dist = 0;
+ s->table[x] = i->image->palette->pixels[dist];
+ }
+ } else {
+ for (x = 0; x < 256; x++) {
+ int dist = (x + SSTEP2 - 1) / SSTEP2;
+ dist += 128;
+ if (dist > 255)
+ dist = 255;
+ s->table[x] =
+ ((dist >> i->image->palette->info.truec.
+ rprec) << i->image->palette->info.truec.
+ rshift) | ((dist >> i->image->palette->info.
+ truec.gprec) << i->image->palette->
+ info.truec.
+ gshift) | ((dist >>
+ i->image->palette->info.truec.bprec)
+ <<
+ i->image->palette->info.truec.bshift);
+
+ }
+ for (x = 256; x < 512; x++) {
+ int dist = -(512 - x + SSTEP2 - 1) / SSTEP2;
+ dist += 128;
+ if (dist < 0)
+ dist = 0;
+ s->table[x] =
+ ((dist >> i->image->palette->info.truec.
+ rprec) << i->image->palette->info.truec.
+ rshift) | ((dist >> i->image->palette->info.
+ truec.gprec) << i->image->palette->
+ info.truec.
+ gshift) | ((dist >>
+ i->image->palette->info.truec.bprec)
+ <<
+ i->image->palette->info.truec.bshift);
+ }
+ }
+ }
+ s->xdist = (int) (0.1 / i->image->pixelwidth);
+ s->ydist = (int) (0.1 / i->image->pixelwidth);
+ if (s->xdist < 1)
+ s->xdist = 1;
+ if (s->ydist < 1)
+ s->ydist = 1;
+ if (!inherimage
+ (f, i, TOUCHIMAGE, i->image->width + s->xdist,
+ i->image->height + s->ydist, s->palette, 0, 0))
+ return 0;
+ clear_image(f->image);
+ setfractalpalette(f, s->savedpalette);
+ return (f->previous->action->initialize(f->previous, i));
+}
+
+static struct filter *getinstance(CONST struct filteraction *a)
+{
+ struct filter *f = createfilter(a);
+ struct embossdata *i = (struct embossdata *) calloc(1, sizeof(*i));
+ i->savedpalette = NULL;
+ i->palette =
+ createpalette(0, 256, GRAYSCALE, 0, 256, NULL, NULL, NULL, NULL,
+ NULL);
+ f->childimage = NULL;
+ f->data = i;
+ f->name = "Emboss";
+ return (f);
+}
+
+static void emboss8(void *data, struct taskinfo *task, int r1, int r2)
+{
+ pixel8_t *src, *srcend, *src2;
+ pixel8_t *dest;
+ struct filter *f = (struct filter *) data;
+ struct embossdata *s = (struct embossdata *) f->data;
+ int i;
+ unsigned int *table = s->table;
+ for (i = r1; i < r2; i++) {
+ src = f->childimage->currlines[i];
+ src2 = f->childimage->currlines[i + s->ydist] + s->xdist;
+ srcend = src + f->image->width;
+ dest = f->image->currlines[i];
+ while (src < srcend) {
+ *dest = table[((int) *src2 - (int) *src) & 511];
+ src++;
+ src2++;
+ dest++;
+ }
+ }
+}
+
+#ifdef SUPPORT16
+static void emboss16(void *data, struct taskinfo *task, int r1, int r2)
+{
+ pixel8_t *src, *srcend, *src2;
+ pixel16_t *dest;
+ struct filter *f = (struct filter *) data;
+ struct embossdata *s = (struct embossdata *) f->data;
+ int i;
+ unsigned int *table = s->table;
+ for (i = r1; i < r2; i++) {
+ src = f->childimage->currlines[i];
+ src2 = f->childimage->currlines[i + s->ydist] + s->xdist;
+ srcend = src + f->image->width;
+ dest = (pixel16_t *) f->image->currlines[i];
+ while (src < srcend) {
+ *dest = table[((int) *src2 - (int) *src) & 511];
+ src++;
+ src2++;
+ dest++;
+ }
+ }
+}
+#endif
+#ifdef STRUECOLOR24
+static void emboss24(void *data, struct taskinfo *task, int r1, int r2)
+{
+ pixel8_t *src, *srcend, *src2;
+ pixel8_t *dest;
+ struct filter *f = (struct filter *) data;
+ struct embossdata *s = (struct embossdata *) f->data;
+ int i;
+ unsigned int *table = s->table;
+ for (i = r1; i < r2; i++) {
+ src = f->childimage->currlines[i];
+ src2 = f->childimage->currlines[i + s->ydist] + s->xdist;
+ srcend = src + f->image->width;
+ dest = (pixel8_t *) f->image->currlines[i];
+ while (src < srcend) {
+ *dest = *(dest + 1) = *(dest + 2) =
+ table[((int) *src2 - (int) *src) & 511];
+ src++;
+ src2++;
+ dest += 3;
+ }
+ }
+}
+#endif
+static void emboss32(void *data, struct taskinfo *task, int r1, int r2)
+{
+ pixel8_t *src, *srcend, *src2;
+ pixel32_t *dest;
+ struct filter *f = (struct filter *) data;
+ struct embossdata *s = (struct embossdata *) f->data;
+ int i;
+ unsigned int *table = s->table;
+ for (i = r1; i < r2; i++) {
+ src = f->childimage->currlines[i];
+ src2 = f->childimage->currlines[i + s->ydist] + s->xdist;
+ srcend = src + f->image->width;
+ dest = (pixel32_t *) f->image->currlines[i];
+ while (src < srcend) {
+ *dest = table[((int) *src2 - (int) *src) & 511];
+ src++;
+ src2++;
+ dest++;
+ }
+ }
+}
+
+static void destroyinstance(struct filter *f)
+{
+ struct embossdata *i = (struct embossdata *) f->data;
+ if (i->savedpalette != NULL)
+ destroypalette(i->savedpalette);
+ destroypalette(i->palette);
+ destroyinheredimage(f);
+ free(f->data);
+ free(f);
+}
+
+static int doit(struct filter *f, int flags, int time1)
+{
+ int val;
+ int time = time1;
+ updateinheredimage(f);
+ val = f->previous->action->doit(f->previous, flags, time);
+ drivercall(*f->image,
+ xth_function(emboss8, f, f->image->height),
+ xth_function(emboss16, f, f->image->height),
+ xth_function(emboss24, f, f->image->height),
+ xth_function(emboss32, f, f->image->height));
+ xth_sync();
+ return val;
+}
+
+static void myremovefilter(struct filter *f)
+{
+ struct embossdata *s = (struct embossdata *) f->data;
+ if (s->savedpalette != NULL) {
+ restorepalette(f->image->palette, s->savedpalette);
+ destroypalette(s->savedpalette);
+ s->savedpalette = NULL;
+ }
+}
+
+CONST struct filteraction emboss_filter = {
+ "Emboss",
+ "emboss",
+ 0,
+ getinstance,
+ destroyinstance,
+ doit,
+ requirement,
+ initialize,
+ convertupgeneric,
+ convertdowngeneric,
+ myremovefilter
+};