Skip to content

Commit 473072c

Browse files
committed
Mostly done, just gotta put it on a calculator
1 parent 70aaee4 commit 473072c

File tree

4 files changed

+61
-38
lines changed

4 files changed

+61
-38
lines changed

badapple.sh

Lines changed: 12 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -3,29 +3,30 @@
33
W=80
44
H=64
55
VID_SIZE="${W}x${H}"
6-
FPS=30
6+
FPS=20
77

88
# Download video
9+
echo "Downloading video..."
910
youtube-dl https://www.youtube.com/watch?v=FtutLA63Cp8 -o bad
1011

12+
echo "Converting video..."
1113
# Convert video to two tone black and white
12-
# This approach had too much dithering
13-
#ffmpeg -hide_banner -loglevel error -y -i bad.mkv -vf "fps=$FPS,scale=$VID_SIZE,format=monob" -sws_dither none -f rawvideo worse
14-
15-
# This approach has weird jagged edges and I don't like it much either, oh well...
16-
ffmpeg -hide_banner -loglevel error -y -i bad.mkv -f lavfi -i color=gray -f lavfi -i color=black -f lavfi -i color=white -lavfi "fps=$FPS,scale=320:240,threshold,scale=$VID_SIZE,format=monob" -sws_dither none -f rawvideo bad_mono
14+
ffmpeg -hide_banner -loglevel error -y -i bad.mkv -vf "fps=$FPS,scale=$VID_SIZE,format=monob" -f rawvideo bad_mono
15+
du -bsh bad_mono | cut -f -1
1716

1817
# Script to encode the video
19-
python3 videnc.py
20-
21-
# Compare file sizes
22-
du -bsh bad_mono bad_mono.enc
18+
echo "Encoding video..."
19+
python3 videnc.py $W $H
20+
du -bsh bad_mono.enc | cut -f -1
2321

2422
# Compile decoder
25-
cc decoder/main.c -o decoder/decoder
23+
echo "Compiling decoder..."
24+
cc -DW=$W -DH=$H -DNDEBUG -O2 decoder/main.c -o decoder/decoder
2625

2726
# Test decoder against original data
27+
echo "Testing decoder..."
2828
decoder/decoder | cmp - bad_mono
2929

3030
# Display decoded video
31+
echo "Displaying decoded video..."
3132
decoder/decoder | ffplay -hide_banner -loglevel error -f rawvideo -pixel_format monob -video_size $VID_SIZE -framerate $FPS pipe:

decoder/main.c

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,8 @@
33
#include <stdint.h>
44
#include <stdio.h>
55
#include <stdlib.h>
6+
#include <string.h>
67

7-
#define W (80)
8-
#define H (64)
98
#define PIXELS (W * H)
109
#define VRAM_BYTES (PIXELS / 8)
1110
#define MIN_RLE_SIZE (PIXELS / 128)
@@ -15,7 +14,7 @@ static uint8_t buf[MIN_RLE_SIZE] = {0};
1514
static uint16_t pixels = 0;
1615
static FILE *f = NULL;
1716

18-
static void full() { assert(fread(vram, VRAM_BYTES, 1, f) == 1); }
17+
static void full() { fread(vram, VRAM_BYTES, 1, f); }
1918

2019
#include "rle_dec.h"
2120
#include "rle_dec_d.h"
@@ -24,12 +23,12 @@ static void full_rle() {
2423
pixels = 0;
2524
// By reading a lot at once this will
2625
// mean less read calls
27-
assert(fread(buf, MIN_RLE_SIZE, 1, f) == 1);
26+
fread(buf, MIN_RLE_SIZE, 1, f);
2827
for (uint8_t i = 0; i < MIN_RLE_SIZE; i++) {
2928
rle_dec(buf[i]);
3029
}
3130
while (pixels < PIXELS) {
32-
assert(fread(buf, 1, 1, f) == 1);
31+
fread(buf, 1, 1, f);
3332
rle_dec(buf[0]);
3433
}
3534
}
@@ -38,16 +37,18 @@ static void delta() {
3837
pixels = 0;
3938
// By reading a lot at once this will
4039
// mean less read calls
41-
assert(fread(buf, MIN_RLE_SIZE, 1, f) == 1);
40+
fread(buf, MIN_RLE_SIZE, 1, f);
4241
for (uint8_t i = 0; i < MIN_RLE_SIZE; i++) {
4342
rle_dec_d(buf[i]);
4443
}
4544
while (pixels < PIXELS) {
46-
assert(fread(buf, 1, 1, f) == 1);
45+
fread(buf, 1, 1, f);
4746
rle_dec_d(buf[0]);
4847
}
4948
}
5049

50+
static void fill(uint8_t col) { memset(vram, col, VRAM_BYTES); }
51+
5152
int main() {
5253
f = fopen("bad_mono.enc", "rb");
5354
if (!f)
@@ -67,8 +68,14 @@ int main() {
6768
case 3: // Delta
6869
delta();
6970
break;
71+
case 4: // Clear screen
72+
fill(0x00);
73+
break;
74+
case 5: // Clear screen
75+
fill(0xFF);
76+
break;
7077
default:
71-
assert(69 == 420);
78+
assert(buf[0] > 5);
7279
break;
7380
}
7481
fwrite(vram, VRAM_BYTES, 1, stdout);

rle.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,13 @@ def rle_enc(byts):
3939
with open("bad_mono.rle", "wb") as w:
4040
for bts in rle_enc(byts): w.write(bts)
4141

42-
import heatshrink2
42+
#import heatshrink2
4343

44-
with heatshrink2.open('bad_mono.rle.bin', 'wb') as w:
45-
with open("bad_mono.rle", "rb") as f:
46-
w.write(f.read())
44+
#with heatshrink2.open('bad_mono.rle.bin', 'wb') as w:
45+
# with open("bad_mono.rle", "rb") as f:
46+
# w.write(f.read())
4747

48-
with heatshrink2.open('bad_mono.bin', 'wb') as w:
49-
with open("bad_mono", "rb") as f:
50-
w.write(f.read())
48+
#with heatshrink2.open('bad_mono.bin', 'wb') as w:
49+
# with open("bad_mono", "rb") as f:
50+
# w.write(f.read())
5151

videnc.py

Lines changed: 27 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
1+
import sys
12
from rle import rle_enc, bits
23

4+
BYTES_NUM = (int(sys.argv[1]) * int(sys.argv[2])) // 8
5+
36

47
def fullenc(b):
58
return b'\x01' + b
@@ -9,7 +12,7 @@ def fullenc_rle(b):
912
return b'\x02' + b''.join(rle_enc(b))
1013

1114

12-
def blank():
15+
def unchanged():
1316
return b'\x00'
1417

1518

@@ -27,26 +30,38 @@ def delta_rle(byts, prev):
2730
return b'\x03' + b''.join(rle_enc(xored))
2831

2932

33+
def blank(b):
34+
if b == b"\x00" * BYTES_NUM:
35+
return b'\x04'
36+
elif b == b"\xFF" * BYTES_NUM:
37+
return b'\x05'
38+
else:
39+
return None
40+
41+
3042
# Some more codes could be made:
3143
# Blank variants that SET a flat color rather than retain previous frames
3244
def encoder():
3345
prev_frame = None
3446

3547
with open("bad_mono", "rb") as f:
36-
while (byts := f.read((80 * 64) // 8)):
48+
while (byts := f.read(BYTES_NUM)):
3749
if byts == prev_frame:
38-
yield blank()
50+
yield unchanged()
3951
else:
40-
full = fullenc(byts)
41-
rle = fullenc_rle(byts)
42-
dlt = delta_rle(byts, prev_frame)
43-
44-
if dlt is not None and len(dlt) < len(rle) and len(dlt) < len(full):
45-
yield dlt
46-
elif len(rle) < len(full):
47-
yield rle
52+
blk = blank(byts)
53+
if blk is not None:
54+
yield blk
4855
else:
49-
yield full
56+
full = fullenc(byts)
57+
rle = fullenc_rle(byts)
58+
dlt = delta_rle(byts, prev_frame)
59+
if dlt is not None and len(dlt) < len(rle) and len(dlt) < len(full):
60+
yield dlt
61+
elif len(rle) < len(full):
62+
yield rle
63+
else:
64+
yield full
5065

5166
prev_frame = byts
5267

0 commit comments

Comments
 (0)