-
Notifications
You must be signed in to change notification settings - Fork 1
/
vpp.h
132 lines (106 loc) · 3 KB
/
vpp.h
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
#ifndef VPP_HEADER
#define VPP_HEADER
#ifdef __cplusplus
extern "C" {
#endif
#include <stdio.h>
FILE* vpp_init_input(const char* filename, int* w, int* h, int* d);
int vpp_init_inputs(int n, FILE** files, const char** filenames, int* w, int* h, int* d);
FILE* vpp_init_output(const char* filename, int w, int h, int d);
int vpp_read_frame(FILE* in, float* frame, int w, int h, int d);
int vpp_write_frame(FILE* out, float* frame, int w, int h, int d);
#ifdef VPP_IMPLEMENTATION
#include <string.h>
#include <fcntl.h> // open, fnctl
#define VPP_TAG "VPP"
static FILE* open_input(const char* filename)
{
// open the file is non blocking mode in case this is a pipe
// we don't want to block on opening pipes since the other end
// will block until we open it (causing deadlocks with 2 pipes)
int fd = !strcmp(filename, "-") ? 0 : open(filename, O_RDONLY, O_NONBLOCK);
if (fd == -1)
return NULL;
int flags = fcntl(fd, F_GETFL, 0);
fcntl(fd, F_SETFL, flags & ~O_NONBLOCK);
FILE* in = fdopen(fd, "rb");
if (in)
setvbuf(in, NULL, _IONBF, 0);
return in;
}
static int read_header(FILE* in, int* w, int* h, int*d )
{
char tag[4];
if (!fread(tag, sizeof(tag), 1, in) || strncmp(tag, VPP_TAG, 4) != 0)
return 0;
if ( !fread(w, sizeof*w, 1, in)
|| !fread(h, sizeof*h, 1, in)
|| !fread(d, sizeof*d, 1, in))
return 0;
if (*w <= 0 || *h <= 0 || *d <= 0)
return 0;
return 1;
}
FILE* vpp_init_input(const char* filename, int* w, int* h, int* d)
{
FILE* in = open_input(filename);
if (in && !read_header(in, w, h, d)) {
fclose(in);
return NULL;
}
return in;
}
int vpp_init_inputs(int n, FILE** files, const char** filenames, int* w, int* h, int* d)
{
for (int i = 0; i < n; i++) {
files[i] = NULL;
}
for (int i = 0; i < n; i++) {
if (!(files[i] = open_input(filenames[i])))
goto err;
}
for (int i = 0; i < n; i++) {
if (!read_header(files[i], w+i, h+i, d+i)) {
goto err;
}
}
return 1;
err:
for (int i = 0; i < n; i++) {
if (files[i])
fclose(files[i]);
}
return 0;
}
FILE* vpp_init_output(const char* filename, int w, int h, int d)
{
char tag[4] = {VPP_TAG};
FILE* out = !strcmp(filename, "-") ? stdout : fopen(filename, "wb");
setvbuf(out, NULL, _IONBF, 0);
if (!out)
goto err;
if (!fwrite(tag, sizeof(tag), 1, out))
goto err;
if ( !fwrite(&w, sizeof w, 1, out)
|| !fwrite(&h, sizeof h, 1, out)
|| !fwrite(&d, sizeof d, 1, out))
goto err;
return out;
err:
if (out)
fclose(out);
return NULL;
}
int vpp_read_frame(FILE* in, float* frame, int w, int h, int d)
{
return fread(frame, sizeof*frame, w*h*d, in) == (size_t) w*h*d;
}
int vpp_write_frame(FILE* out, float* frame, int w, int h, int d)
{
return fwrite(frame, sizeof*frame, w*h*d, out) == (size_t) w*h*d;
}
#endif
#ifdef __cplusplus
}
#endif
#endif