Skip to content

Commit f11a0f2

Browse files
committed
Add fhwrap: Wrap farbfeld filters.
1 parent 56ee2b7 commit f11a0f2

File tree

3 files changed

+163
-6
lines changed

3 files changed

+163
-6
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
fhinfo
22
fhpack
33
fhunpack
4+
fhwrap
45

56
test/frames/*
67
test/oframes/*

Makefile

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,21 @@ CC ?= cc
33
CFLAGS ?= -O2
44
CPPLAGS += -pedantic -Wall -Wextra
55

6+
DESTDIR=/usr/local
7+
68
# Don't change after here.
79
# Or do. I am not your mom.
8-
BINS=fhinfo fhpack fhunpack
10+
BINS=fhinfo fhpack fhunpack fhwrap
911
DEP=src/farbherd.h
1012

1113
all: $(BINS)
1214

13-
fhinfo: src/fhinfo.c $(DEP)
14-
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ src/$@.c
15-
fhpack: src/fhpack.c $(DEP)
16-
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ src/$@.c
17-
fhunpack: src/fhunpack.c $(DEP)
15+
$(BINS): $(DEP)
1816
$(CC) $(CPPFLAGS) $(CFLAGS) $(LDFLAGS) -o $@ src/$@.c
1917

18+
.PHONY:
19+
install: $(BINS)
20+
mkdir -p $(DESTDIR)/bin
21+
install $(BINS) $(DESTDIR)/bin
2022
clean:
2123
rm -f $(BINS)

src/fhwrap.c

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
// fhwrap: Unpack a farbherd stream into a farbfeld stream, pipe it to a binary, repack.
2+
//
3+
// License:
4+
// farbherd - animation format & tools, designed to be similar to farbfeld.
5+
// Written in 2018 by 20kdc <[email protected]>, vifino <[email protected]> and contributors.
6+
//
7+
// To the extent possible under law, the author(s) have dedicated all copyright and related and neighboring rights to this software to the public domain worldwide.
8+
// This software is distributed without any warranty.
9+
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
10+
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>.
11+
12+
#include <stdio.h>
13+
#include <stdlib.h>
14+
#include <string.h>
15+
#include <sys/types.h>
16+
#include <unistd.h>
17+
#include <sys/wait.h>
18+
#include <err.h>
19+
20+
#include "farbherd.h"
21+
22+
void run_worker(uint16_t *input, uint16_t *output, size_t bufsz, farbfeld_header_t head, int argc, char* argv[]) {
23+
int infd[2];
24+
if (pipe(infd) == -1) {
25+
fprintf(stderr, "Failed to create input pipe.\n");
26+
_exit(1);
27+
}
28+
29+
pid_t writer = fork();
30+
if (writer == 0) {
31+
// writer child.
32+
FILE* f = fdopen(infd[1], "w");
33+
if (!f)
34+
err(2, "Failed to open pipe");
35+
farbherd_write_farbfeld_header(f, head);
36+
fwrite(input, bufsz, 1, f);
37+
fclose(f);
38+
_exit(0);
39+
}
40+
// parent
41+
close(infd[1]); // child took care of it.
42+
43+
int outfd[2];
44+
if (pipe(outfd) == -1) {
45+
fprintf(stderr, "Failed to create output pipe.\n");
46+
_exit(1);
47+
}
48+
49+
int exit;
50+
pid_t filter = fork();
51+
if (filter == 0) {
52+
// child.
53+
close(outfd[0]); // close reading end of output
54+
55+
dup2(infd[0], 0); // get stdin from parent
56+
dup2(outfd[1], 1); // write to parent
57+
58+
// no longer needed
59+
close(infd[0]);
60+
close(outfd[1]);
61+
62+
// Do the thing.
63+
if(execvp(argv[0], argv))
64+
err(1, "Failed to execute child");
65+
}
66+
67+
// parent.
68+
close(infd[0]); // close reading end of input
69+
close(outfd[1]); // close writing end of output
70+
71+
FILE* f = fdopen(outfd[0], "r");
72+
if (!f)
73+
err(2, "Failed to open pipe");
74+
75+
farbfeld_header_t rhead;
76+
if (farbherd_read_farbfeld_header(f, &rhead)) {
77+
fprintf(stderr, "Failed to read worker farbfeld header.\n");
78+
_exit(1);
79+
}
80+
if ((rhead.width != head.width) || (rhead.height != rhead.height)) {
81+
fprintf(stderr, "Worker returned wrong farbfeld canvas size?\n");
82+
_exit(1);
83+
}
84+
if (farbherd_read_buffer(f, output, bufsz)) {
85+
fprintf(stderr, "Worker failed to write frame?\n");
86+
_exit(1);
87+
}
88+
89+
int status = 0;
90+
pid_t wpid;
91+
int workers = 2;
92+
while (workers) {
93+
wpid = wait(&status);
94+
if (!wpid)
95+
err(2, "Wait error");
96+
workers--;
97+
}
98+
}
99+
100+
int main(int argc, char ** argv) {
101+
if ((argc < 2)) {
102+
fprintf(stderr, "Usage: %s [cmd..]\n", argv[0]);
103+
return 1;
104+
}
105+
106+
farbherd_header_t head;
107+
if (farbherd_read_farbherd_header(stdin, &head)) {
108+
fputs("Failed to read farbherd header\n", stderr);
109+
return 1;
110+
}
111+
farbherd_write_farbherd_header(stdout, head);
112+
fflush(stdout);
113+
114+
size_t datasize = farbherd_datasize(head.imageHead);
115+
fprintf(stderr, "%i x %i @ %i / %i\n", head.imageHead.width, head.imageHead.height, head.frameTimeMul, head.frameTimeDiv);
116+
uint16_t* work_in = 0;
117+
uint16_t* work_out = 0;
118+
uint16_t* outbuf = 0;
119+
if (datasize) {
120+
work_in = calloc(1, datasize);
121+
work_out = calloc(1, datasize);
122+
if (!work_in && !work_out) {
123+
fputs("Failed to allocate workspace memory\n", stderr);
124+
return 1;
125+
}
126+
outbuf = malloc(datasize);
127+
if (!outbuf) {
128+
fputs("Failed to allocate workspace memory\n", stderr);
129+
return 1;
130+
}
131+
}
132+
133+
farbherd_frame_t inputframe;
134+
if (farbherd_init_farbherd_frame(&inputframe, head)) {
135+
fputs("Failed to allocate incoming frame memory\n", stderr);
136+
return 1;
137+
}
138+
139+
while (1) {
140+
// Read farbherd frame.
141+
if (farbherd_read_farbherd_frame(stdin, &inputframe, head))
142+
return 0;
143+
farbherd_apply_delta(work_in, inputframe.deltas, datasize);
144+
145+
// Run the buffer through the worker filter.
146+
run_worker(inputframe.deltas, outbuf, datasize, head.imageHead, argc, argv + 1);
147+
148+
// Write out the completed frame.
149+
farbherd_calc_apply_delta(work_out, outbuf, datasize);
150+
fwrite(outbuf, datasize, 1, stdout);
151+
fflush(stdout);
152+
}
153+
return 0;
154+
}

0 commit comments

Comments
 (0)