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 }