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
|
/* See LICENSE file for copyright and license details. */
#ifndef TYPE
#include "common.h"
USAGE("[-alp] matrix-stream")
static int skip_alpha = 0;
static int linear = 0;
static int per_pixel = 0;
static size_t dim;
#define FILE "blind-affine-colour.c"
#include "define-functions.h"
int
main(int argc, char *argv[])
{
struct stream colour, matrix;
void (*process)(struct stream *colour, struct stream *matrix);
size_t h;
ARGBEGIN {
case 'a':
skip_alpha = 1;
break;
case 'l':
linear = 1;
break;
case 'p':
per_pixel = 1;
break;
default:
usage();
} ARGEND;
if (argc != 1)
usage();
eopen_stream(&colour, NULL);
eopen_stream(&matrix, argv[0]);
SELECT_PROCESS_FUNCTION(&colour);
if (strcmp(colour.pixfmt, matrix.pixfmt))
eprintf("videos use incompatible pixel formats\n");
dim = colour.n_chan - (size_t)skip_alpha + (size_t)!linear;
h = matrix.height, matrix.height = dim;
echeck_dimensions(&matrix, WIDTH | HEIGHT, "matrix");
matrix.height = h;
if (per_pixel) {
if (matrix.height != dim * colour.height || matrix.width != dim * colour.width)
eprintf("the matrice should have the size %zux%zu, but are %zux%zu",
dim * colour.height, dim * colour.width, matrix.height, matrix.width);
} else {
if (matrix.height != dim || matrix.width != dim)
eprintf("the matrice should have the size %zux%zu, but are %zux%zu",
dim, dim, matrix.height, matrix.width);
}
fprint_stream_head(stdout, &colour);
efflush(stdout, "<stdout>");
process(&colour, &matrix);
return 0;
}
#else
static void
PROCESS(struct stream *colour, struct stream *matrix)
{
char *mbuf;
TYPE *mat, *pixel, V[5], M[ELEMENTSOF(V)][ELEMENTSOF(V)];
size_t ptr, i, j, w, x = 0, y = 0, cn;
mbuf = emalloc2(dim, matrix->row_size);
mat = (TYPE *)mbuf;
w = matrix->width * matrix->n_chan;
cn = colour->n_chan - (size_t)skip_alpha;
memset(M, 0, sizeof(M));
for (i = 0; i < ELEMENTSOF(V); i++)
M[i][i] = V[i] = 1;
do {
for (ptr = 0; ptr + colour->pixel_size <= colour->ptr; x = (x + 1) % colour->width, ptr += colour->pixel_size) {
if (!x) {
if (!y && !eread_segment(matrix, mbuf, dim * matrix->row_size))
break;
if (!per_pixel) {
if (!y) {
mat = (TYPE *)mbuf;
for (i = 0; i < dim; i++, mat += w)
for (j = 0; j < dim; j++)
M[i][j] = mat[j * matrix->n_chan + 1]
* mat[(j + 1) * matrix->n_chan - 1];
}
y = (y + 1) % colour->height;
}
}
if (per_pixel) {
mat = (TYPE *)(mbuf + x * dim * matrix->pixel_size);
for (i = 0; i < dim; i++, mat += w)
for (j = 0; j < dim; j++)
M[i][j] = mat[j * matrix->n_chan + 1]
* mat[(j + 1) * matrix->n_chan - 1];
}
pixel = (TYPE *)(colour->buf + ptr);
for (i = 0; i < dim; i++) {
V[i] = 0;
for (j = 0; j < cn; j++)
V[i] += M[i][j] * pixel[j];
for (; j < dim; j++)
V[i] += M[i][j];
}
for (i = 0; i < cn; i++)
pixel[i] = V[i] / V[cn];
}
ewriteall(STDOUT_FILENO, colour->buf, ptr, "<stdout>");
memmove(colour->buf, colour->buf + ptr, colour->ptr -= ptr);
} while (eread_stream(colour, SIZE_MAX));
if (colour->ptr)
eprintf("%s: incomplete frame\n", colour->file);
free(mbuf);
}
#endif
|