Skip to content

Commit fea813c

Browse files
committed
Optimized LZW with help of Bit String
1 parent ef68ee1 commit fea813c

File tree

1 file changed

+25
-19
lines changed

1 file changed

+25
-19
lines changed

Compressors/LZW/LZW.h

Lines changed: 25 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,17 @@
77
#include "../../Utils/BinaryIO.h"
88
#include "../../Utils/Converter.h"
99
#include "Utils.h"
10+
#include <bit_string.h>
1011

11-
12+
/**
13+
* Lempel–Ziv–Welch Compression Algorithm
14+
*/
1215
class LZW {
1316

17+
static const uint32_t BYTE = 8;
18+
1419
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);
1621
for (int i = 0; i < 256; ++i) {
1722
std::string s(1, i);
1823
encodingDictionary[s] = i;
@@ -21,7 +26,7 @@ class LZW {
2126
}
2227

2328
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);
2530
for (int i = 0; i < 256; ++i) {
2631
std::string s(1, i);
2732
decodingDictionary[i] = s;
@@ -35,30 +40,31 @@ class LZW {
3540
static void encode(const std::string& filename, const std::string& outputFileName) {
3641

3742
auto dictionary = initializeEncodingDictionary();
38-
uint32_t currentWordLength;
3943

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));
4147

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;
4552

4653
// if not found in dictionary
4754
if (dictionary.find(currentMatch) == dictionary.end()) {
4855
dictionary[currentMatch] = dictionary.size();
4956
currentWordLength = numberOfBitsToStoreRangeOf(dictionary.size());
5057
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;
5360
}
5461

5562
}
5663

5764
// save last matched word
5865
currentWordLength = numberOfBitsToStoreRangeOf(dictionary.size());
59-
bitString += Converter::bits_ToBitString(dictionary[currentMatch], currentWordLength);
66+
encodedData.append_uint_32(dictionary[currentMatch], currentWordLength);
6067

61-
std::string encodedData = Converter::bitString_ToRealBinary(bitString);
6268
remove(outputFileName.c_str()); // Remove Output File If Exists
6369
BinaryIO::write(outputFileName, encodedData);
6470
}
@@ -68,10 +74,10 @@ class LZW {
6874

6975
auto dictionary = initializeDecodingDictionary();
7076

71-
std::string toBeDecompressed = Converter::string_ToBitString(BinaryIO::readString(filename));
77+
bit_string toBeDecompressed = BinaryIO::readBitString(filename);
7278

7379
std::string decoded;
74-
uint32_t index;
80+
decoded.reserve(toBeDecompressed.size()/BYTE);
7581
uint32_t currentWordLength = numberOfBitsToStoreRangeOf(dictionary.size());
7682
for (int i = 0; i < toBeDecompressed.length(); i += currentWordLength) {
7783

@@ -82,17 +88,17 @@ class LZW {
8288

8389
currentWordLength = numberOfBitsToStoreRangeOf(dictionary.size() + 1);
8490

85-
index = Converter::bitString_ToInt(toBeDecompressed.substr(i, currentWordLength));
91+
uint32_t index = toBeDecompressed.substr(i, currentWordLength).to_uint_32();
8692

8793
// The last char in the previous entry is not added, as its value is the first char of the next entry
8894
if (i != 0) {
89-
char lastCharInPreviousEntry = dictionary[index][0];
95+
uint8_t lastCharInPreviousEntry = dictionary[index].front();
9096
dictionary[dictionary.size() - 1] += lastCharInPreviousEntry;
9197
}
9298

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);
96102

97103
}
98104

0 commit comments

Comments
 (0)