-
Notifications
You must be signed in to change notification settings - Fork 1
/
rle.h
104 lines (89 loc) · 1.73 KB
/
rle.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
/*
Run length encoding of mostly zero bits
Copyright 2021 Ahmet Inan <xdsopl@gmail.com>
*/
#pragma once
#include "vli.h"
struct rle_reader {
struct vli_reader *vli;
int cnt;
};
struct rle_writer {
struct vli_writer *vli;
int cnt;
};
struct rle_reader *rle_reader(struct vli_reader *vli)
{
struct rle_reader *rle = malloc(sizeof(struct rle_reader));
rle->vli = vli;
rle->cnt = 0;
return rle;
}
struct rle_writer *rle_writer(struct vli_writer *vli)
{
struct rle_writer *rle = malloc(sizeof(struct rle_writer));
rle->vli = vli;
rle->cnt = 0;
return rle;
}
int rle_flush(struct rle_writer *rle)
{
return rle->cnt = put_vli(rle->vli, rle->cnt);
}
void delete_rle_reader(struct rle_reader *rle)
{
if (rle->cnt > 1)
fprintf(stderr, "%d zeros not read.\n", rle->cnt);
free(rle);
}
void delete_rle_writer(struct rle_writer *rle)
{
if (rle->cnt > 0)
fprintf(stderr, "forgot to flush counter for %d zeros.\n", rle->cnt);
free(rle);
}
int put_rle(struct rle_writer *rle, int b)
{
if (rle->cnt < 0)
return rle->cnt;
if (b)
return rle->cnt = put_vli(rle->vli, rle->cnt);
rle->cnt++;
return 0;
}
int get_rle(struct rle_reader *rle)
{
if (rle->cnt < 0)
return rle->cnt;
if (!rle->cnt) {
rle->cnt = get_vli(rle->vli);
if (rle->cnt < 0)
return rle->cnt;
return !rle->cnt;
}
return rle->cnt-- == 1;
}
int rle_put_bit(struct rle_writer *rle, int bit)
{
if (rle->cnt < 0)
return rle->cnt;
if (rle->cnt > 0) {
int ret = put_rle(rle, 1);
if (ret)
return ret;
}
return vli_put_bit(rle->vli, bit);
}
int rle_get_bit(struct rle_reader *rle)
{
if (rle->cnt < 0)
return rle->cnt;
if (rle->cnt > 0) {
int ret = get_rle(rle);
if (ret < 0)
return ret;
if (ret != 1)
return -1;
}
return vli_get_bit(rle->vli);
}