commit 478b53f935264bdfe4efe394f8d804a1361a6770
parent ab3493cd565f6dd620016469b5dcbc84f89b881d
Author: Mattias Andrée <maandree@kth.se>
Date: Sat, 8 Apr 2017 13:57:36 +0200
Document memory requirements, minor style fixes, more use of BUFSIZ, fix warnings, and fix potential buffer overflow
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat:
28 files changed, 137 insertions(+), 45 deletions(-)
diff --git a/man/blind-compress.1 b/man/blind-compress.1
@@ -18,6 +18,10 @@ It is recommended to combine
.B blind-compress
with
.BR "lz4 -1" .
+.SH REQUIREMENTS
+.B blind-compress
+requires enough free memory to load two full frames into
+memory. A frame requires 32 bytes per pixel it contains.
.SH SEE ALSO
.BR blind (7),
.BR blind-decompress (1),
diff --git a/man/blind-crop.1 b/man/blind-crop.1
@@ -49,6 +49,21 @@ pixels rightward of the output video's left-most pixel,
and the subvideo's top-most pixel will be positioned
.I top
pixels downward of the output video's left-most pixel.
+.SH REQUIREMENTS
+.B blind-crop
+requires enough free memory to load two full frames into
+memory, one of the size of the source video's frames,
+and one of the size of the target video's frames. However,
+if
+.B -s
+or
+.B -S
+is used, only memory for one full frame, of the size of
+the source video's frames, are required. A frame requires
+32 bytes per pixel it contains.
+.B blind-crop
+has not been optimised for memory usage, but instead
+for code simplicity.
.SH SEE ALSO
.BR blind (7),
.BR blind-extend (1)
diff --git a/man/blind-decompress.1 b/man/blind-decompress.1
@@ -7,6 +7,10 @@ blind-decompress - Decompress a video compressed by blind-compress(1)
.B blind-decompress
removes compressed added by
.BR blind-compress (1).
+.SH REQUIREMENTS
+.B blind-decompress
+requires enough free memory to load one full frame into
+memory. A frame requires 32 bytes per pixel it contains.
.SH SEE ALSO
.BR blind (7),
.BR blind-compress (1),
diff --git a/man/blind-extend.1 b/man/blind-extend.1
@@ -52,6 +52,15 @@ of the input videos in the new room, such that the
right-most part of the video has is put side-by-side
with the left-most part of the video, and analogously
for the other sides.
+.SH REQUIREMENTS
+.B blind-extend
+requires enough free memory to load two full frames into
+memory, one of the size of the source video's frames,
+and one of the size of the target video's frames. A frame
+requires 32 bytes per pixel it contains.
+.B blind-extend
+has not been optimised for memory usage, but instead
+for code simplicity.
.SH SEE ALSO
.BR blind (7),
.BR blind-crop (1)
diff --git a/man/blind-flip.1 b/man/blind-flip.1
@@ -7,6 +7,10 @@ blind-flip - Mirror a video vertically
.B blind-flip
reads a video from stdin and prints it, mirrored
vertically, to stdout.
+.SH REQUIREMENTS
+.B blind-flip
+requires enough free memory to load one full frame into
+memory. A frame requires 32 bytes per pixel it contains.
.SH SEE ALSO
.BR blind (7),
.BR blind-flop (1),
diff --git a/man/blind-flop.1 b/man/blind-flop.1
@@ -7,6 +7,11 @@ blind-flop - Mirror a video horizontally
.B blind-flop
reads a video from stdin and prints it, mirrored
horizontally, to stdout.
+.SH REQUIREMENTS
+.B blind-flop
+requires enough free memory to load two frame rows into memory.
+A frame row requires 32 bytes per pixel it contains, that is,
+32 bytes times the width of the video in pixel.
.SH SEE ALSO
.BR blind (7),
.BR blind-flip (1),
diff --git a/man/blind-gauss-blur.1 b/man/blind-gauss-blur.1
@@ -72,6 +72,10 @@ specified.
Use the Y value (multiplied by the alpha value) from
.I sd-stream
as the standard deviation all channels.
+.SH REQUIREMENTS
+.B blind-compress
+requires enough free memory to load three full frames into
+memory. A frame requires 32 bytes per pixel it contains.
.SH SEE ALSO
.BR blind (7),
.BR blind-single-colour (1),
diff --git a/man/blind-repeat.1 b/man/blind-repeat.1
@@ -33,6 +33,12 @@ will read stdin into memory; you are highly discouraged
from using this unless stdin is a single frame, or known
to only be a very small number of frames, is it can
potentially use all of the computer's memory.
+.SH REQUIREMENTS
+.B blind-repeat
+requires enough free memory to load the entire video
+into memory if it is read from stdin. A frame requires
+32 bytes per pixel it contains. So for a 720p video at
+25 Hz, 1 GB is reached in just below 1.5 seconds.
.SH SEE ALSO
.BR blind (7),
.BR blind-from-image (1)
diff --git a/man/blind-rotate-180.1 b/man/blind-rotate-180.1
@@ -7,6 +7,17 @@ blind-rotate-180 - Rotate a video 180 degrees
.B blind-rotate-180
reads a video from stdin and prints it, rotated
180 degrees, to stdout.
+.SH REQUIREMENTS
+.B blind-rotate-180
+is implemented as a shell script pipeline of
+.BR blind-flip (1)
+and
+.BR blind-flop (1),
+see those for details on requirements.
+.B blind-rotate-180
+is not been optimised for memory usage, but instead
+for code simplicity, however, it does not exceed the
+optimum greatly.
.SH SEE ALSO
.BR blind (7),
.BR blind-rotate-90 (1),
diff --git a/man/blind-rotate-270.1 b/man/blind-rotate-270.1
@@ -8,6 +8,16 @@ blind-rotate-270 - Rotate a video 270 degrees clockwise
reads a video from stdin and prints it, rotated
270 degrees clockwise (90 degrees anti-clockwise),
to stdout.
+.SH REQUIREMENTS
+.B blind-rotate-270
+is implemented as a shell script pipeline of
+.BR blind-flop (1)
+and
+.BR blind-transpose (1),
+see those for details on requirements.
+.B blind-rotate-270
+is not been optimised for memory usage, but instead
+for code simplicity.
.SH SEE ALSO
.BR blind (7),
.BR blind-rotate-90 (1),
diff --git a/man/blind-rotate-90.1 b/man/blind-rotate-90.1
@@ -7,6 +7,16 @@ blind-rotate-90 - Rotate a video 90 degrees clockwise
.B blind-rotate-90
reads a video from stdin and prints it, rotated
90 degrees clockwise, to stdout.
+.SH REQUIREMENTS
+.B blind-rotate-90
+is implemented as a shell script pipeline of
+.BR blind-transpose (1)
+and
+.BR blind-flop (1),
+see those for details on requirements.
+.B blind-rotate-90
+is not been optimised for memory usage, but instead
+for code simplicity.
.SH SEE ALSO
.BR blind (7),
.BR blind-rotate-180 (1),
diff --git a/man/blind-transpose.1 b/man/blind-transpose.1
@@ -10,6 +10,13 @@ transposed, to stdout.
.P
To transpose a videos means to swap the
X and Y coordinates.
+.SH REQUIREMENTS
+.B blind-transpose
+requires enough free memory to load two full frames into
+memory. A frame requires 32 bytes per pixel it contains.
+.B blind-transpose
+has not been optimised for memory usage, but instead
+for code simplicity.
.SH SEE ALSO
.BR blind (7),
.BR blind-flip (1),
diff --git a/src/arg.h b/src/arg.h
@@ -73,9 +73,9 @@ extern char *argv0;
(&argv[0][1]) :\
(argc--, argv++, argv[0])))
-#define LNGARG() &argv[0][0]
+#define UARGF() EARGF(usage())
-#define EARG() EARGF(usage())
+#define LNGARG() &argv[0][0]
#define ENOFLAGS(...) ARGBEGIN {\
default:\
diff --git a/src/blind-colour-srgb.c b/src/blind-colour-srgb.c
@@ -12,7 +12,7 @@ main(int argc, char *argv[])
ARGBEGIN {
case 'd':
- depth = etoi_flag('d', EARG(), 1, 64);
+ depth = etoi_flag('d', UARGF(), 1, 64);
break;
case 'l':
linear = 1;
diff --git a/src/blind-compress.c b/src/blind-compress.c
@@ -51,7 +51,6 @@ main(int argc, char *argv[])
buf[0] = emalloc(n);
buf[1] = ecalloc(1, n);
- memcpy(buf[0], stream.buf, stream.ptr);
for (i = 0; eread_frame(&stream, buf[i], n); i ^= 1) {
parts = compare(buf[i], buf[i ^ 1], n, &cmp, &cmpsize);
for (off = part = 0; part < parts; part += 2) {
diff --git a/src/blind-concat.c b/src/blind-concat.c
@@ -209,10 +209,10 @@ main(int argc, char *argv[])
ARGBEGIN {
case 'o':
- output_file = EARG();
+ output_file = UARGF();
break;
case 'j':
- jobs = etozu_flag('j', EARG(), 1, SHRT_MAX);
+ jobs = etozu_flag('j', UARGF(), 1, SHRT_MAX);
break;
default:
usage();
diff --git a/src/blind-crop.c b/src/blind-crop.c
@@ -77,7 +77,6 @@ main(int argc, char *argv[])
right_start = left + orown;
right = irown - right_start;
- memcpy(buf, stream.buf, ptr = stream.ptr);
while (eread_frame(&stream, buf, n)) {
if (tile) {
for (ptr = y = 0; y < stream.height; y++) {
diff --git a/src/blind-extend.c b/src/blind-extend.c
@@ -14,23 +14,23 @@ main(int argc, char *argv[])
{
struct stream stream;
char *buf, *image;
- size_t ptr, n, m, imgw, imgh, rown;
+ size_t n, m, imgw, imgh, rown;
size_t xoff, yoff, h, x, y;
size_t left = 0, right = 0, top = 0, bottom = 0;
int tile = 0;
ARGBEGIN {
case 'l':
- left = etozu_flag('l', EARG(), 0, SIZE_MAX);
+ left = etozu_flag('l', UARGF(), 0, SIZE_MAX);
break;
case 'r':
- right = etozu_flag('r', EARG(), 0, SIZE_MAX);
+ right = etozu_flag('r', UARGF(), 0, SIZE_MAX);
break;
case 'a':
- top = etozu_flag('a', EARG(), 0, SIZE_MAX);
+ top = etozu_flag('a', UARGF(), 0, SIZE_MAX);
break;
case 'b':
- bottom = etozu_flag('b', EARG(), 0, SIZE_MAX);
+ bottom = etozu_flag('b', UARGF(), 0, SIZE_MAX);
break;
case 't':
tile = 1;
@@ -80,7 +80,6 @@ main(int argc, char *argv[])
xoff = (rown - left % rown) % rown;
yoff = (stream.height - top % stream.height) % stream.height;
- memcpy(buf, stream.buf, ptr = stream.ptr);
while (eread_frame(&stream, buf, n)) {
if (!tile) {
for (y = 0; y < stream.height; y++)
diff --git a/src/blind-flip.c b/src/blind-flip.c
@@ -26,7 +26,6 @@ main(int argc, char *argv[])
n = stream.height * (row_size = stream.width * stream.pixel_size);
buf = emalloc(n);
- memcpy(buf, stream.buf, stream.ptr);
while (eread_frame(&stream, buf, n))
for (ptr = n; ptr;)
ewriteall(STDOUT_FILENO, buf + (ptr -= row_size), row_size, "<stdout>");
diff --git a/src/blind-flop.c b/src/blind-flop.c
@@ -30,7 +30,6 @@ main(int argc, char *argv[])
image = emalloc(n);
m = n - stream.pixel_size;
- memcpy(buf, stream.buf, stream.ptr);
while (eread_row(&stream, buf, n)) {
for (i = 0; i < stream.pixel_size; i++)
for (j = 0; j < n; j += stream.pixel_size)
diff --git a/src/blind-from-video.c b/src/blind-from-video.c
@@ -172,7 +172,7 @@ convert(const char *infile, int outfd, const char *outfile, size_t width, size_t
if (dup2(pipe_rw[1], STDOUT_FILENO) == -1)
eprintf("dup2:");
close(pipe_rw[1]);
- execvp("ffmpeg", cmd);
+ execvp("ffmpeg", (char **)(void *)cmd);
eprintf("exec ffmpeg:");
}
@@ -221,13 +221,13 @@ main(int argc, char *argv[])
skip_length = 1;
break;
case 'r':
- frame_rate = EARG();
+ frame_rate = UARGF();
break;
case 'w':
- width = etozu_flag('w', EARG(), 1, SIZE_MAX);
+ width = etozu_flag('w', UARGF(), 1, SIZE_MAX);
break;
case 'h':
- height = etozu_flag('h', EARG(), 1, SIZE_MAX);
+ height = etozu_flag('h', UARGF(), 1, SIZE_MAX);
break;
default:
usage();
diff --git a/src/blind-gauss-blur.c b/src/blind-gauss-blur.c
@@ -317,10 +317,10 @@ main(int argc, char *argv[])
measure_y_only = 1;
break;
case 'j':
- jobs = etozu_flag('j', EARG(), 1, SHRT_MAX);
+ jobs = etozu_flag('j', UARGF(), 1, SHRT_MAX);
break;
case 's':
- arg = EARG();
+ arg = UARGF();
if (!strcmp(arg, "auto"))
auto_spread = 1;
else
diff --git a/src/blind-single-colour.c b/src/blind-single-colour.c
@@ -16,7 +16,7 @@ main(int argc, char *argv[])
struct stream stream;
double X, Y, Z, alpha = 1;
size_t x, y, n;
- pixel_t buf[1024];
+ pixel_t buf[BUFSIZ / 4];
ssize_t r;
int inf = 0;
char *arg;
@@ -27,17 +27,17 @@ main(int argc, char *argv[])
ARGBEGIN {
case 'f':
- arg = EARG();
+ arg = UARGF();
if (!strcmp(arg, "inf"))
inf = 1, stream.frames = 0;
else
stream.frames = etozu_flag('f', arg, 1, SIZE_MAX);
break;
case 'w':
- stream.width = etozu_flag('w', EARG(), 1, SIZE_MAX);
+ stream.width = etozu_flag('w', UARGF(), 1, SIZE_MAX);
break;
case 'h':
- stream.height = etozu_flag('h', EARG(), 1, SIZE_MAX);
+ stream.height = etozu_flag('h', UARGF(), 1, SIZE_MAX);
break;
default:
usage();
diff --git a/src/blind-to-image.c b/src/blind-to-image.c
@@ -91,7 +91,7 @@ main(int argc, char *argv[])
ARGBEGIN {
case 'd':
- depth = etoi_flag('d', EARG(), 1, 64);
+ depth = etoi_flag('d', UARGF(), 1, 64);
break;
case 'f':
farbfeld = 1;
diff --git a/src/blind-to-video.c b/src/blind-to-video.c
@@ -123,7 +123,7 @@ main(int argc, char *argv[])
if (dup2(pipe_rw[0], STDIN_FILENO) == -1)
eprintf("dup2:");
close(pipe_rw[0]);
- execvp("ffmpeg", cmd);
+ execvp("ffmpeg", (char **)(void *)cmd);
eprintf("exec ffmpeg:");
}
diff --git a/src/blind-transpose.c b/src/blind-transpose.c
@@ -35,7 +35,6 @@ main(int argc, char *argv[])
srch *= ps;
srcw *= dx = imgw * ps;
imgw *= ps;
- memcpy(buf, stream.buf, stream.ptr);
while (eread_frame(&stream, buf, n)) {
for (b = y = 0; y < srch; y += ps)
for (x = 0; x < srcw; x += dx)
diff --git a/src/stream.c b/src/stream.c
@@ -32,14 +32,11 @@ eninit_stream(int status, struct stream *stream)
}
*p = '\0';
- w = strchr(stream->buf, ' ');
- if (!w)
+ if (!(w = strchr(stream->buf, ' ')))
goto bad_format;
- h = strchr(w + 1, ' ');
- if (!h)
+ if (!(h = strchr(w + 1, ' ')))
goto bad_format;
- f = strchr(h + 1, ' ');
- if (!f)
+ if (!(f = strchr(h + 1, ' ')))
goto bad_format;
*w++ = *h++ = *f++ = '\0';
@@ -89,6 +86,8 @@ eninit_stream(int status, struct stream *stream)
enset_pixel_size(status, stream);
+ stream->xptr = 0;
+
return;
bad_format:
enprintf(status, "%s: file format not supported\n", stream->file);
@@ -181,19 +180,29 @@ enread_frame(int status, struct stream *stream, void *buf, size_t n)
{
char *buffer = buf;
ssize_t r;
- for (; stream->ptr < n; stream->ptr += (size_t)r) {
- r = read(stream->fd, buffer + stream->ptr, n - stream->ptr);
+ size_t m;
+
+ if (stream->ptr) {
+ m = stream->ptr < n ? stream->ptr : n;
+ memcpy(buffer + stream->xptr, stream->buf, m);
+ memmove(stream->buf, stream->buf + m, stream->ptr -= m);
+ stream->xptr += m;
+ }
+
+ for (; stream->xptr < n; stream->xptr += (size_t)r) {
+ r = read(stream->fd, buffer + stream->xptr, n - stream->xptr);
if (r < 0) {
enprintf(status, "read %s:", stream->file);
} else if (r == 0) {
- if (!stream->ptr)
+ if (!stream->xptr)
break;
enprintf(status, "%s: incomplete frame", stream->file);
}
}
- if (!stream->ptr)
+
+ if (!stream->xptr)
return 0;
- stream->ptr -= n;
+ stream->xptr -= n;
return 1;
}
diff --git a/src/stream.h b/src/stream.h
@@ -36,8 +36,7 @@
#define process_multiple_streams(...) nprocess_multiple_streams(1, __VA_ARGS__)
#define process_each_frame_two_streams(...) nprocess_each_frame_two_streams(1, __VA_ARGS__)
-struct stream
-{
+struct stream {
size_t frames;
size_t width;
size_t height;
@@ -45,7 +44,8 @@ struct stream
char pixfmt[32];
int fd;
size_t ptr;
- char buf[4096];
+ size_t xptr;
+ char buf[BUFSIZ];
const char *file;
size_t headlen;
};
@@ -62,13 +62,13 @@ void encheck_compat(int status, const struct stream *a, const struct stream *b);
int enread_frame(int status, struct stream *stream, void *buf, size_t n);
void nprocess_each_frame_segmented(int status, struct stream *stream, int output_fd, const char* output_fname,
- void (*process)(struct stream *stream, size_t n, size_t frame));
+ void (*process)(struct stream *stream, size_t n, size_t frame));
void nprocess_two_streams(int status, struct stream *left, struct stream *right, int output_fd, const char* output_fname,
- void (*process)(struct stream *left, struct stream *right, size_t n));
+ void (*process)(struct stream *left, struct stream *right, size_t n));
void nprocess_multiple_streams(int status, struct stream *streams, size_t n_streams, int output_fd, const char* output_fname,
- void (*process)(struct stream *streams, size_t n_streams, size_t n));
+ void (*process)(struct stream *streams, size_t n_streams, size_t n));
void nprocess_each_frame_two_streams(int status, struct stream *left, struct stream *right, int output_fd, const char* output_fname,
void (*process)(char *restrict output, char *restrict lbuf, char *restrict rbuf,