Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/engine/interlace.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/engine/interlace.c')
-rw-r--r--src/engine/interlace.c134
1 files changed, 134 insertions, 0 deletions
diff --git a/src/engine/interlace.c b/src/engine/interlace.c
new file mode 100644
index 0000000..0971a5a
--- /dev/null
+++ b/src/engine/interlace.c
@@ -0,0 +1,134 @@
+#include <config.h>
+#ifndef _plan9_
+#ifdef NO_MALLOC_H
+#include <stdlib.h>
+#else
+#include <malloc.h>
+#endif
+#include <stdio.h> /*for NULL */
+#include <string.h> /*for memcpy */
+#else
+#include <u.h>
+#include <libc.h>
+#include <stdio.h>
+#endif
+#include <filter.h>
+struct intdata {
+ unsigned char *lastent;
+ int changed;
+ int first;
+};
+static int requirement(struct filter *f, struct requirements *r)
+{
+ r->nimages = 1;
+ r->flags |= IMAGEDATA;
+ return (f->next->action->requirement(f->next, r));
+}
+
+static int initialize(struct filter *f, struct initdata *i)
+{
+ int x;
+ struct intdata *d = (struct intdata *) f->data;
+ pixel_t **lines1 =
+ (pixel_t **) malloc(sizeof(*lines1) * i->image->height / 2),
+ **lines2 =
+ (pixel_t **) malloc(sizeof(*lines2) * i->image->height / 2);
+ if (lines1 == NULL)
+ return 0;
+ inhermisc(f, i);
+ d->first = 1;
+ if (lines2 == NULL) {
+ free(lines1);
+ return 0;
+ }
+ if (f->childimage != NULL)
+ destroy_image(f->childimage);
+ f->image = i->image;
+ f->image->flags |= PROTECTBUFFERS;
+ i->flags |= DATALOST;
+ for (x = 0; x < (i->image->height) / 2; x++) {
+ lines1[x] = i->image->currlines[x * 2];
+ lines2[x] = i->image->currlines[x * 2 + 1];
+ }
+ f->childimage = i->image =
+ create_image_lines(i->image->width, (i->image->height) / 2, 2,
+ lines1, lines2, i->image->palette, NULL,
+ FREELINES | PROTECTBUFFERS,
+ f->image->pixelwidth,
+ f->image->pixelheight * 2);
+ if (i->image == NULL) {
+ free(lines1);
+ free(lines2);
+ return 0;
+ }
+ return (f->previous->action->initialize(f->previous, i));
+}
+
+static struct filter *getinstance(CONST struct filteraction *a)
+{
+ struct filter *f = createfilter(a);
+ struct intdata *i = (struct intdata *) calloc(1, sizeof(*i));
+ f->data = i;
+ f->name = "Interlace filter";
+ return (f);
+}
+
+static void destroyinstance(struct filter *f)
+{
+ free(f->data);
+ if (f->childimage != NULL)
+ destroy_image(f->childimage);
+ free(f);
+}
+
+static int doit(struct filter *f, int flags, int time)
+{
+ struct intdata *i = (struct intdata *) f->data;
+ int val;
+ if (!(f->req.flags & IMAGEDATA)
+ && f->childimage->currlines[0] == i->lastent)
+ f->childimage->flip(f->childimage);
+ i->lastent = f->childimage->currlines[0];
+ val = f->previous->action->doit(f->previous, flags, time);
+ if (i->first) {
+ int y;
+ for (y = 0; y < f->childimage->height; y++)
+ memcpy(f->childimage->oldlines[y], f->childimage->currlines[y],
+ f->childimage->width * f->childimage->bytesperpixel);
+ i->first = 0;
+ }
+ if (val & CHANGED)
+ i->changed = 1, val |= ANIMATION;
+ else {
+ if (i->changed)
+ val |= CHANGED;
+ i->changed = 0;
+ }
+ return (val);
+}
+
+static void convertup(struct filter *f, int *x, int *y)
+{
+ *y *= 2;
+ f->next->action->convertup(f->next, x, y);
+}
+
+static void convertdown(struct filter *f, int *x, int *y)
+{
+ *y /= 2;
+ f->previous->action->convertdown(f->previous, x, y);
+}
+
+CONST struct filteraction interlace_filter = {
+ "Interlace filter",
+ "interlace",
+ 0,
+ getinstance,
+ destroyinstance,
+ doit,
+ requirement,
+ initialize,
+ convertup,
+ convertdown,
+ NULL
+};