blind-compress.c - blind - suckless command-line video editing utility
(HTM) git clone git://git.suckless.org/blind
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
(DIR) LICENSE
---
blind-compress.c (1552B)
---
1 /* See LICENSE file for copyright and license details. */
2 #include "common.h"
3
4 USAGE("")
5
6 static size_t
7 compare(const char *restrict new, const char *restrict old, size_t n, size_t **cmp, size_t *cmpsize)
8 {
9 size_t i, start1, start2, ptr, same, diff;
10 for (ptr = i = 0; i < n;) {
11 for (start1 = i; i < n && old[i] == new[i]; i++);
12 for (start2 = i; i < n && old[i] != new[i]; i++);
13 same = start2 - start1;
14 diff = i - start2;
15 if (ptr && same < 2 * sizeof(size_t) && same + diff <= SIZE_MAX - (*cmp)[ptr - 1]) {
16 (*cmp)[ptr - 1] += same + diff;
17 } else {
18 if (ptr + 2 > *cmpsize)
19 *cmp = erealloc2(*cmp, *cmpsize += 128, sizeof(size_t));
20 (*cmp)[ptr++] = same;
21 (*cmp)[ptr++] = diff;
22 }
23 }
24 return ptr;
25 }
26
27 int
28 main(int argc, char *argv[])
29 {
30 struct stream stream;
31 char *buf[2];
32 size_t parts, part, off;
33 int i;
34 size_t *cmp = NULL;
35 size_t cmpsize = 0;
36
37 UNOFLAGS(argc);
38
39 eopen_stream(&stream, NULL);
40 echeck_dimensions(&stream, WIDTH | HEIGHT, NULL);
41 fprint_stream_head(stdout, &stream);
42 efflush(stdout, "<stdout>");
43
44 buf[0] = emalloc(stream.frame_size);
45 buf[1] = ecalloc(1, stream.frame_size);
46
47 for (i = 0; eread_frame(&stream, buf[i]); i ^= 1) {
48 parts = compare(buf[i], buf[i ^ 1], stream.frame_size, &cmp, &cmpsize);
49 for (off = part = 0; part < parts; part += 2) {
50 off += cmp[part];
51 ewriteall(STDOUT_FILENO, cmp + part, 2 * sizeof(size_t), "<stdout>");
52 ewriteall(STDOUT_FILENO, buf[i] + off, cmp[part + 1], "<stdout>");
53 off += cmp[part + 1];
54 }
55 }
56
57 free(cmp);
58 free(buf[0]);
59 free(buf[1]);
60 return 0;
61 }