forked from mplough/borescope_stream
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathborescope_stream.rl
More file actions
161 lines (132 loc) · 3.66 KB
/
borescope_stream.rl
File metadata and controls
161 lines (132 loc) · 3.66 KB
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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <stdio.h>
#include <string>
#include <vector>
struct State {
int cs;
std::vector<char> header;
std::vector<char> image;
bool output_jpeg = false;
bool write_files = false;
size_t image_size = 0;
uint32_t frame_number = 0;
int n = 0;
};
/*
The header is 41 bytes.
9 bytes - "BoundaryS"
4 bytes - always 00 00 01 00
4 bytes - length of image (FFD8 to FFD9, inclusive)
4 bytes - ?
4 bytes - frame number
4 bytes - frame number again?
4 bytes - always 01 00 01 00
4 bytes - always 00 05 00 00
4 bytes - always d0 02 00 00
All 4-byte values are sent in little-endian byte order.
This bothers me because NETWORK BYTE ORDER IS BIG ENDIAN.
*/
%%{
machine borescope;
access fsm->;
action done_begin {
fsm->header.clear();
fsm->image.clear();
fsm->image_size = 0;
fsm->frame_number = 0;
}
action done_end {
// first, remove the characters accepted while writing the jpeg
// but while we were really in end (yay nondeterminism)
fsm->n++;
for (int i=0; i<8; i++)
fsm->image.pop_back();
fprintf(stderr, "%08zx ", fsm->image_size);
fprintf(stderr, "%08lx ", fsm->image.size());
fprintf(stderr, "%8d ", fsm->frame_number);
fprintf(stderr, "%8d ", fsm->n);
// undo the borescope's intentional image corruption as described at
// https://mkarr.github.io/20200616_boroscope
fsm->image[fsm->image.size() / 2] = ~fsm->image[fsm->image.size() / 2];
if (fsm->output_jpeg) {
// write jpeg data with depstech header and footer stripped
fwrite(fsm->image.data(), fsm->image.size(), 1, stdout);
}
if (fsm->write_files) {
char name_buf[50];
sprintf(name_buf, "frame_%06d.log", fsm->n);
FILE *fp = fopen(name_buf, "wb");
fwrite(fsm->image.data(), fsm->image.size(), 1, fp);
fclose(fp);
}
fprintf(stderr, "\n");
}
action byte_header {
fsm->header.push_back(fc);
}
action done_header {
for(auto c : fsm->header)
fprintf(stderr, "%02x ", c);
}
action byte_jpeg {
fsm->image.push_back(fc);
}
action byte_image_size {
fsm->image_size >>= 8;
fsm->image_size |= (uint32_t) fc << 24;
}
image_size = any{4} $byte_image_size;
action byte_frame_number {
fsm->frame_number >>= 8;
fsm->frame_number |= (uint32_t) fc << 24;
}
frame_number = any{4} $byte_frame_number;
begin = ('BoundaryS') @done_begin;
end = ('BoundaryE') @done_end;
header = (
any{4} # always 00 00 01 00
image_size
any{4}
frame_number
any{4}
any{4}
any{4}
any{4}
) $byte_header @done_header;
jpeg = (any* -- end) $byte_jpeg;
main := (begin header jpeg end)*;
}%%
%% write data;
void boundary_init(State *fsm) {
%% write init;
}
void boundary_execute(State *fsm, char c) {
const char *p = &c;
const char *pe = p + 1;
%% write exec;
}
int main(int argc, char **argv)
{
State fsm;
for (int i=1; i<argc; i++) {
if (std::string(argv[i]) == "--jpeg") {
fsm.output_jpeg = true;
}
else if (std::string(argv[i]) == "--write-files") {
fsm.write_files = true;
}
else {
printf("The option '%s' is not valid\n", argv[i]);
return 1;
}
}
boundary_init(&fsm);
for (;;) {
int c = getchar();
if (c == EOF) {
printf("got eof\n");
break;
}
boundary_execute(&fsm, (char)c);
}
return 0;
}