-
Notifications
You must be signed in to change notification settings - Fork 0
/
ahed.cpp
155 lines (127 loc) · 3.85 KB
/
ahed.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
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
/*
* Autor: Jordan Jarolim (xjarol03)
* Datum: 16.2.2017
* Soubor: ahed.c
* Komentar: Implementace knihovny pro adaptivni huffmanovo kodovani
*/
#include <iostream>
#include <stdio.h>
#include <bitset>
#include "ahed.hpp"
#include "tree.hpp"
#include "code.hpp"
using namespace std;
/* Nazev:
* AHEDEncoding
* Cinnost:
* Funkce koduje vstupni soubor do vystupniho souboru a porizuje zaznam o kodovani.
* Parametry:
* ahed - zaznam o kodovani
* inputFile - vstupni soubor (nekodovany)
* outputFile - vystupní soubor (kodovany)
* Navratova hodnota:
* 0 - kodovani probehlo v poradku
* -1 - pri kodovani nastala chyba
*/
int AHEDEncoding(tAHED *ahed, FILE *inputFile, FILE *outputFile)
{
int64_t symbol;
Code *code = new Code;
Tree::root = Tree::nyt = new Tree(ROOT, INIT_WEIGHT, INIT_ORDER, NULL, NULL, NULL);
vector<int64_t> output;
tuple<vector<int64_t>, Tree*> foundSymbol;
int64_t outputSize = 0, inputSize = 0;
while ((symbol = fgetc(inputFile)) != EOF)
{
inputSize++;
code->coding(symbol, &output);
}
/* save final codes */
foundSymbol = code->getCode(NYT);
output.insert(output.end(), get<0>(foundSymbol).begin(), get<0>(foundSymbol).end());
output.push_back(Tree::peof);
/* get vector of booleans */
vector<bool> finalOutput;
for (auto i: output){
if (i == MOVE_LEFT){
finalOutput.push_back(0);
}
else if (i == MOVE_RIGHT){
finalOutput.push_back(1);
}
else if (i == Tree::peof){
bitset<16> transformedChar(i);
for (size_t j = 0; j < transformedChar.size(); ++j) {
finalOutput.push_back(transformedChar[j]);
}
}
else{
bitset<8> transformedChar(i);
for (size_t j = 0; j < transformedChar.size(); ++j) {
finalOutput.push_back(transformedChar[j]);
}
}
}
vector<bool> oneChar;
char c = 0;
/* push all complete bytes */
for (int j = 0; j < finalOutput.size() - finalOutput.size()%8; j += 8){
for (int k = 0; k < 8; k++){
oneChar.push_back(finalOutput[j+k]);
}
/* write each complete byte into a file */
c = 0;
for(int i = 0; i < 8; i++)
c += (oneChar[i] << i);
if(outputFile)
fprintf(outputFile, "%c", c);
else
cout<<c;
outputSize++;
oneChar.clear();
}
/* push incomplete byte */
for (unsigned long m = (finalOutput.size() - finalOutput.size()%8); m < finalOutput.size(); m++){
oneChar.push_back(finalOutput[m]);
}
/* fill incomplete byte with 0s */
for (unsigned long m = 0; m < 8 - finalOutput.size()%8; m++){
oneChar.push_back(0);
}
/* write into a file */
c = 0;
for(int i = 0; i < 8; i++)
c += (oneChar[i] << i);
if(outputFile)
fprintf(outputFile, "%c", c);
else
cout<<c;
outputSize++;
oneChar.clear();
ahed->uncodedSize = inputSize;
ahed->codedSize = outputSize;
delete(code);
delete(Tree::root);
return AHEDOK;
}
/* Nazev:
* AHEDDecoding
* Cinnost:
* Funkce dekoduje vstupni soubor do vystupniho souboru a porizuje zaznam o dekodovani.
* Parametry:
* ahed - zaznam o dekodovani
* inputFile - vstupni soubor (kodovany)
* outputFile - vystupní soubor (nekodovany)
* Navratova hodnota:
* 0 - dekodovani probehlo v poradku
* -1 - pri dekodovani nastala chyba
*/
int AHEDDecoding(tAHED *ahed, FILE *inputFile, FILE *outputFile)
{
Code *code = new Code;
Tree::root = Tree::nyt = new Tree(ROOT, INIT_WEIGHT, INIT_ORDER, NULL, NULL, NULL);
code->decoding(ahed, inputFile, outputFile);
delete(code);
delete(Tree::root);
return AHEDOK;
}