Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/engine/interlace.c
blob: 0971a5ad793730f42bdb34d2ec5c266f3fea7f54 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
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
};