-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrldecode.cpp
92 lines (76 loc) · 2.11 KB
/
rldecode.cpp
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
#include <limits>
#include "rldecode.h"
#include "common.h"
using namespace std;
int main (int argc, char **argv) {
// command line arguments
if (argc < 2 || argc > 3) {
usage(argv);
exit(1);
}
// set operation mode
int mode = STDOUT_MODE;
if (argc == 3) mode = OUTFILE_MODE;
// open files
ifstream infile;
infile.open(argv[1], ios::in | ios::binary);
if (!infile.is_open()) {
cerr << "Unable to open input file " << argv[1] << endl;
exit(1);
}
ofstream outfile;
if (mode == OUTFILE_MODE) {
outfile.open(argv[2], ios::out | ios::binary);
if (!outfile.is_open()) {
cerr << "Unable to open output file " << argv[2] << endl;
exit(1);
}
}
// perform decoding
decode(infile, outfile, mode);
// close files
infile.close();
if (outfile.is_open()) outfile.close();
return 0;
}
void decode(ifstream &infile, ofstream &outfile, int mode) {
// read the first character
char inbyte = 0;
if (!infile.read(&inbyte, 1)) {
if (infile.eof()) return; // empty file, do nothing
cerr << "Failed reading first character of input file" << endl;
exit(1);
}
char current_char = 0;
bool char_signed = numeric_limits<char>::is_signed;
unsigned int count = 0;
while (infile) {
// if first bit not set, print character
if ((char_signed && inbyte >= 0) || (!char_signed && inbyte < 0x80)) {
if (mode == STDOUT_MODE) cout << inbyte;
else outfile << inbyte;
current_char = inbyte;
infile.read(&inbyte, 1);
continue;
}
// otherwise get the number of characters
// strip first bit
count = inbyte & 0x7f;
int i = 1; // count how many 7 bit frames to shift
while (infile.read(&inbyte, 1) &&
((char_signed && inbyte < 0) ||
(!char_signed && inbyte >= 0x80))) {
unsigned int temp = inbyte & 0x7f;
temp <<= 7 * i++;
count |= temp;
}
if (mode == STDOUT_MODE) cout << "[" << count << "]";
else {
// need to add three but note we've already printed one
count += 2;
for (unsigned i = 0; i < count; ++i) {
outfile << current_char;
}
}
}
}