7
7
#include " ../../Utils/BinaryIO.h"
8
8
#include " ../../Utils/Converter.h"
9
9
#include " Utils.h"
10
+ #include < bit_string.h>
10
11
11
-
12
+ /* *
13
+ * Lempel–Ziv–Welch Compression Algorithm
14
+ */
12
15
class LZW {
13
16
17
+ static const uint32_t BYTE = 8 ;
18
+
14
19
static std::unordered_map<std::string, uint32_t > initializeEncodingDictionary () {
15
- std::unordered_map<std::string, uint32_t > encodingDictionary;
20
+ std::unordered_map<std::string, uint32_t > encodingDictionary ( 256 ) ;
16
21
for (int i = 0 ; i < 256 ; ++i) {
17
22
std::string s (1 , i);
18
23
encodingDictionary[s] = i;
@@ -21,7 +26,7 @@ class LZW {
21
26
}
22
27
23
28
static std::unordered_map<uint32_t , std::string> initializeDecodingDictionary () {
24
- std::unordered_map<uint32_t , std::string> decodingDictionary;
29
+ std::unordered_map<uint32_t , std::string> decodingDictionary ( 256 ) ;
25
30
for (int i = 0 ; i < 256 ; ++i) {
26
31
std::string s (1 , i);
27
32
decodingDictionary[i] = s;
@@ -35,30 +40,31 @@ class LZW {
35
40
static void encode (const std::string& filename, const std::string& outputFileName) {
36
41
37
42
auto dictionary = initializeEncodingDictionary ();
38
- uint32_t currentWordLength;
39
43
40
- std::string toBeCompressedString = BinaryIO::readString (filename);
44
+ std::string toBeCompressed = BinaryIO::readString (filename);
45
+ bit_string encodedData;
46
+ encodedData.reserve (toBeCompressed.size () / (4 * BYTE));
41
47
42
- std::string currentMatch, bitString;
43
- for (char c : toBeCompressedString) {
44
- currentMatch += c;
48
+ uint32_t currentWordLength;
49
+ std::string currentMatch;
50
+ for (uint8_t byte : toBeCompressed) {
51
+ currentMatch += byte;
45
52
46
53
// if not found in dictionary
47
54
if (dictionary.find (currentMatch) == dictionary.end ()) {
48
55
dictionary[currentMatch] = dictionary.size ();
49
56
currentWordLength = numberOfBitsToStoreRangeOf (dictionary.size ());
50
57
currentMatch.pop_back ();
51
- bitString += Converter::bits_ToBitString (dictionary[currentMatch], currentWordLength);
52
- currentMatch = c ;
58
+ encodedData. append_uint_32 (dictionary[currentMatch], currentWordLength);
59
+ currentMatch = byte ;
53
60
}
54
61
55
62
}
56
63
57
64
// save last matched word
58
65
currentWordLength = numberOfBitsToStoreRangeOf (dictionary.size ());
59
- bitString += Converter::bits_ToBitString (dictionary[currentMatch], currentWordLength);
66
+ encodedData. append_uint_32 (dictionary[currentMatch], currentWordLength);
60
67
61
- std::string encodedData = Converter::bitString_ToRealBinary (bitString);
62
68
remove (outputFileName.c_str ()); // Remove Output File If Exists
63
69
BinaryIO::write (outputFileName, encodedData);
64
70
}
@@ -68,10 +74,10 @@ class LZW {
68
74
69
75
auto dictionary = initializeDecodingDictionary ();
70
76
71
- std::string toBeDecompressed = Converter::string_ToBitString ( BinaryIO::readString (filename) );
77
+ bit_string toBeDecompressed = BinaryIO::readBitString (filename);
72
78
73
79
std::string decoded;
74
- uint32_t index ;
80
+ decoded. reserve (toBeDecompressed. size ()/BYTE) ;
75
81
uint32_t currentWordLength = numberOfBitsToStoreRangeOf (dictionary.size ());
76
82
for (int i = 0 ; i < toBeDecompressed.length (); i += currentWordLength) {
77
83
@@ -82,17 +88,17 @@ class LZW {
82
88
83
89
currentWordLength = numberOfBitsToStoreRangeOf (dictionary.size () + 1 );
84
90
85
- index = Converter::bitString_ToInt ( toBeDecompressed.substr (i, currentWordLength));
91
+ uint32_t index = toBeDecompressed.substr (i, currentWordLength). to_uint_32 ( );
86
92
87
93
// The last char in the previous entry is not added, as its value is the first char of the next entry
88
94
if (i != 0 ) {
89
- char lastCharInPreviousEntry = dictionary[index][ 0 ] ;
95
+ uint8_t lastCharInPreviousEntry = dictionary[index]. front () ;
90
96
dictionary[dictionary.size () - 1 ] += lastCharInPreviousEntry;
91
97
}
92
98
93
- std::string out = dictionary[index];
94
- decoded += out ;
95
- dictionary[dictionary.size ()] = out ;
99
+ std::string word = dictionary[index];
100
+ decoded += word ;
101
+ dictionary[dictionary.size ()] = std::move (word) ;
96
102
97
103
}
98
104
0 commit comments