Merge branch 'master' of labs.phundrak.fr:phundrak/lzw-assignment
This commit is contained in:
commit
bbfb669781
@ -10,9 +10,9 @@ using vuint16 = vector<uint16_t>;
|
|||||||
using vuchar = vector<uchar>;
|
using vuchar = vector<uchar>;
|
||||||
using ustring = std::basic_string<unsigned char>;
|
using ustring = std::basic_string<unsigned char>;
|
||||||
|
|
||||||
int max(const int t_n) { return ipow(2, t_n) - 1; }
|
[[nodiscard]] int max(const int t_n) { return ipow(2, t_n) - 1; }
|
||||||
|
|
||||||
constexpr uint16_t mask_n(int t_nb_bits) {
|
[[nodiscard]] constexpr uint16_t mask_n(int t_nb_bits) {
|
||||||
if (t_nb_bits == 0) {
|
if (t_nb_bits == 0) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -31,14 +31,14 @@ constexpr uint16_t masks[17] = {
|
|||||||
// packing //
|
// packing //
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
vuchar pack(const vuint16 &t_input) {
|
[[nodiscard]] vuchar pack(const vuint16 &t_input) {
|
||||||
vuchar vec{};
|
vuchar vec{};
|
||||||
return pack_n(t_input.begin(), t_input.end(), vec, 9);
|
return pack_n(t_input.begin(), t_input.end(), vec, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
vuchar pack_n(const vuint16::const_iterator t_input_begin,
|
[[nodiscard]] vuchar pack_n(const vuint16::const_iterator t_input_begin,
|
||||||
const vuint16::const_iterator t_input_end, vuchar &t_res,
|
const vuint16::const_iterator t_input_end,
|
||||||
int t_n) {
|
vuchar &t_res, int t_n) {
|
||||||
if (t_n == 16) {
|
if (t_n == 16) {
|
||||||
return pack_16(t_input_begin, t_input_end, t_res);
|
return pack_16(t_input_begin, t_input_end, t_res);
|
||||||
}
|
}
|
||||||
@ -107,8 +107,9 @@ vuchar pack_n(const vuint16::const_iterator t_input_begin,
|
|||||||
return t_res;
|
return t_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
vuchar pack_16(const vuint16::const_iterator t_input_begin,
|
[[nodiscard]] vuchar pack_16(const vuint16::const_iterator t_input_begin,
|
||||||
const vuint16::const_iterator t_input_end, vuchar &t_res) {
|
const vuint16::const_iterator t_input_end,
|
||||||
|
vuchar &t_res) {
|
||||||
std::for_each(t_input_begin, t_input_end, [&t_res](const auto value) {
|
std::for_each(t_input_begin, t_input_end, [&t_res](const auto value) {
|
||||||
t_res.push_back(static_cast<uchar>(value >> 8 & 0xFFU));
|
t_res.push_back(static_cast<uchar>(value >> 8 & 0xFFU));
|
||||||
t_res.push_back(static_cast<uchar>(value & 0xFFU));
|
t_res.push_back(static_cast<uchar>(value & 0xFFU));
|
||||||
@ -120,13 +121,14 @@ vuchar pack_16(const vuint16::const_iterator t_input_begin,
|
|||||||
// unpacking //
|
// unpacking //
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
vuint16 unpack(ustring &&t_input) {
|
[[nodiscard]] vuint16 unpack(ustring &&t_input) {
|
||||||
vuint16 vec{};
|
vuint16 vec{};
|
||||||
return unpack_n(t_input.begin(), t_input.end(), vec, 9);
|
return unpack_n(t_input.begin(), t_input.end(), vec, 9);
|
||||||
}
|
}
|
||||||
|
|
||||||
vuint16 unpack_n(const ustring::const_iterator t_begin,
|
[[nodiscard]] vuint16 unpack_n(const ustring::const_iterator t_begin,
|
||||||
const ustring::const_iterator t_end, vuint16 &t_res, int t_n) {
|
const ustring::const_iterator t_end,
|
||||||
|
vuint16 &t_res, int t_n) {
|
||||||
if (t_n == 16) {
|
if (t_n == 16) {
|
||||||
return unpack_16(t_begin, t_end, t_res);
|
return unpack_16(t_begin, t_end, t_res);
|
||||||
}
|
}
|
||||||
@ -165,8 +167,9 @@ vuint16 unpack_n(const ustring::const_iterator t_begin,
|
|||||||
return t_res;
|
return t_res;
|
||||||
}
|
}
|
||||||
|
|
||||||
vuint16 unpack_16(const ustring::const_iterator t_begin,
|
[[nodiscard]] vuint16 unpack_16(const ustring::const_iterator t_begin,
|
||||||
const ustring::const_iterator t_end, vuint16 &t_res) {
|
const ustring::const_iterator t_end,
|
||||||
|
vuint16 &t_res) {
|
||||||
for (auto it = t_begin; it < t_end; ++it) {
|
for (auto it = t_begin; it < t_end; ++it) {
|
||||||
t_res.push_back(static_cast<uint16_t>(*it << 8 | *++it));
|
t_res.push_back(static_cast<uint16_t>(*it << 8 | *++it));
|
||||||
}
|
}
|
||||||
|
@ -5,24 +5,28 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
std::vector<unsigned char> pack(const std::vector<std::uint16_t> &);
|
[[nodiscard]] std::vector<unsigned char>
|
||||||
|
pack(const std::vector<std::uint16_t> &);
|
||||||
|
|
||||||
std::vector<unsigned char> pack_n(std::vector<std::uint16_t>::const_iterator,
|
[[nodiscard]] std::vector<unsigned char>
|
||||||
std::vector<std::uint16_t>::const_iterator,
|
pack_n(std::vector<std::uint16_t>::const_iterator,
|
||||||
std::vector<unsigned char> &, int);
|
std::vector<std::uint16_t>::const_iterator, std::vector<unsigned char> &,
|
||||||
|
int);
|
||||||
|
|
||||||
std::vector<unsigned char> pack_16(std::vector<std::uint16_t>::const_iterator,
|
[[nodiscard]] std::vector<unsigned char>
|
||||||
|
pack_16(std::vector<std::uint16_t>::const_iterator,
|
||||||
std::vector<std::uint16_t>::const_iterator,
|
std::vector<std::uint16_t>::const_iterator,
|
||||||
std::vector<unsigned char> &);
|
std::vector<unsigned char> &);
|
||||||
|
|
||||||
std::vector<std::uint16_t> unpack(std::basic_string<unsigned char> &&);
|
[[nodiscard]] std::vector<std::uint16_t>
|
||||||
|
unpack(std::basic_string<unsigned char> &&);
|
||||||
|
|
||||||
std::vector<std::uint16_t>
|
[[nodiscard]] std::vector<std::uint16_t>
|
||||||
unpack_n(std::basic_string<unsigned char>::const_iterator t_begin,
|
unpack_n(std::basic_string<unsigned char>::const_iterator t_begin,
|
||||||
std::basic_string<unsigned char>::const_iterator t_end,
|
std::basic_string<unsigned char>::const_iterator t_end,
|
||||||
std::vector<std::uint16_t> &, int t_n);
|
std::vector<std::uint16_t> &, int t_n);
|
||||||
|
|
||||||
std::vector<std::uint16_t>
|
[[nodiscard]] std::vector<std::uint16_t>
|
||||||
unpack_16(std::basic_string<unsigned char>::const_iterator,
|
unpack_16(std::basic_string<unsigned char>::const_iterator,
|
||||||
std::basic_string<unsigned char>::const_iterator,
|
std::basic_string<unsigned char>::const_iterator,
|
||||||
std::vector<std::uint16_t> &);
|
std::vector<std::uint16_t> &);
|
||||||
|
@ -6,7 +6,7 @@ using dic_comp_t = std::map<std::pair<uint16_t, uint8_t>, uint16_t>;
|
|||||||
using ustring = std::basic_string<unsigned char>;
|
using ustring = std::basic_string<unsigned char>;
|
||||||
using p_ustring = std::shared_ptr<ustring>;
|
using p_ustring = std::shared_ptr<ustring>;
|
||||||
|
|
||||||
int ipow(int base, int exp) {
|
[[nodiscard]] int ipow(int base, int exp) {
|
||||||
int result = 1;
|
int result = 1;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
if (exp & 1) {
|
if (exp & 1) {
|
||||||
@ -21,20 +21,21 @@ int ipow(int base, int exp) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<bool, uint16_t> dico(dic_comp_t &t_dictionary,
|
[[nodiscard]] std::pair<bool, uint16_t>
|
||||||
const uint16_t t_nr_chaine, const uint8_t t_c) {
|
dico(dic_comp_t &t_dictionary, const uint16_t t_nr_chaine, const uint8_t t_c) {
|
||||||
if (t_nr_chaine == 0xFFFF) {
|
if (t_nr_chaine == 0xFFFF) {
|
||||||
return std::make_pair(true, t_c);
|
return std::make_pair(true, t_c);
|
||||||
}
|
}
|
||||||
auto &e = t_dictionary[std::make_pair(t_nr_chaine, t_c)];
|
auto &e = t_dictionary[std::make_pair(t_nr_chaine, t_c)];
|
||||||
if(e != 0)
|
if (e != 0)
|
||||||
return std::make_pair(true, e);
|
return std::make_pair(true, e);
|
||||||
e = static_cast<uint16_t>(t_dictionary.size() + 255);
|
e = static_cast<uint16_t>(t_dictionary.size() + 255);
|
||||||
return std::make_pair(false, e);
|
return std::make_pair(false, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
ustring dico_uncompress(std::map<uint16_t, ustring> &t_dict,
|
[[nodiscard]] ustring dico_uncompress(std::map<uint16_t, ustring> &t_dict,
|
||||||
const uint16_t t_code, const uint16_t t_old) {
|
const uint16_t t_code,
|
||||||
|
const uint16_t t_old) {
|
||||||
// le code existe dans le dictionnaire s’il est < 256
|
// le code existe dans le dictionnaire s’il est < 256
|
||||||
if (t_code < 256) {
|
if (t_code < 256) {
|
||||||
ustring e{static_cast<unsigned char>(t_code)};
|
ustring e{static_cast<unsigned char>(t_code)};
|
||||||
|
@ -5,13 +5,13 @@
|
|||||||
#include <map>
|
#include <map>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
int ipow(int, int);
|
[[nodiscard]] int ipow(int, int);
|
||||||
|
|
||||||
std::pair<bool, std::uint16_t>
|
[[nodiscard]] std::pair<bool, std::uint16_t>
|
||||||
dico(std::map<std::pair<std::uint16_t, std::uint8_t>, std::uint16_t> &,
|
dico(std::map<std::pair<std::uint16_t, std::uint8_t>, std::uint16_t> &,
|
||||||
const std::uint16_t, const std::uint8_t);
|
const std::uint16_t, const std::uint8_t);
|
||||||
|
|
||||||
std::basic_string<unsigned char>
|
[[nodiscard]] std::basic_string<unsigned char>
|
||||||
dico_uncompress(std::map<std::uint16_t, std::basic_string<unsigned char>> &,
|
dico_uncompress(std::map<std::uint16_t, std::basic_string<unsigned char>> &,
|
||||||
const std::uint16_t, const std::uint16_t);
|
const std::uint16_t, const std::uint16_t);
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ using ustring = std::basic_string<unsigned char>;
|
|||||||
using dict_t = std::map<std::pair<uint16_t, uint8_t>, uint16_t>;
|
using dict_t = std::map<std::pair<uint16_t, uint8_t>, uint16_t>;
|
||||||
using std::printf;
|
using std::printf;
|
||||||
|
|
||||||
ustring read_file(const string &filename) {
|
[[nodiscard]] ustring read_file(const string &filename) {
|
||||||
std::ifstream file{filename, ios::binary};
|
std::ifstream file{filename, ios::binary};
|
||||||
assert(file);
|
assert(file);
|
||||||
file.unsetf(ios::skipws);
|
file.unsetf(ios::skipws);
|
||||||
@ -32,7 +32,7 @@ ustring read_file(const string &filename) {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
vvuint16 lzw_compress(ustring &&t_text) {
|
[[nodiscard]] vvuint16 lzw_compress(ustring &&t_text) {
|
||||||
vvuint16 res{};
|
vvuint16 res{};
|
||||||
const auto DICT_MAX = static_cast<size_t>(ipow(2, 14) - 256); /* 16 bits */
|
const auto DICT_MAX = static_cast<size_t>(ipow(2, 14) - 256); /* 16 bits */
|
||||||
uint16_t w = 0xFFFF;
|
uint16_t w = 0xFFFF;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
std::vector<std::vector<std::uint16_t>>
|
[[nodiscard]] std::vector<std::vector<std::uint16_t>>
|
||||||
lzw_compress(std::basic_string<unsigned char> &&);
|
lzw_compress(std::basic_string<unsigned char> &&);
|
||||||
|
|
||||||
void compress(const std::string &, const char *);
|
void compress(const std::string &, const char *);
|
||||||
|
@ -37,7 +37,8 @@ Options available:\n\
|
|||||||
\t\"_uncompresed\" will be added");
|
\t\"_uncompresed\" will be added");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<string, string, bool> process_args(int t_argc, char *t_argv[]) {
|
[[nodiscard]] std::tuple<string, string, bool> process_args(int t_argc,
|
||||||
|
char *t_argv[]) {
|
||||||
auto ret = std::make_tuple(string{}, string{}, true);
|
auto ret = std::make_tuple(string{}, string{}, true);
|
||||||
while (true) {
|
while (true) {
|
||||||
int option_index = 0;
|
int option_index = 0;
|
||||||
@ -82,7 +83,7 @@ std::tuple<string, string, bool> process_args(int t_argc, char *t_argv[]) {
|
|||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
const auto [input_path, output_path, compressing] = process_args(argc, argv);
|
const auto [input_path, output_path, compressing] = process_args(argc, argv);
|
||||||
if(input_path.empty()) {
|
if (input_path.empty()) {
|
||||||
help();
|
help();
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ using std::vector;
|
|||||||
using ustring = std::basic_string<unsigned char>;
|
using ustring = std::basic_string<unsigned char>;
|
||||||
using vuint16 = vector<uint16_t>;
|
using vuint16 = vector<uint16_t>;
|
||||||
|
|
||||||
ustring lzw_uncompress(vuint16 &&t_compressed) {
|
[[nodiscard]] ustring lzw_uncompress(vuint16 &&t_compressed) {
|
||||||
ustring ret{};
|
ustring ret{};
|
||||||
uint16_t old = 0;
|
uint16_t old = 0;
|
||||||
std::map<uint16_t, ustring> dict{};
|
std::map<uint16_t, ustring> dict{};
|
||||||
|
@ -6,10 +6,11 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
std::basic_string<unsigned char> lzw_uncompress(std::vector<std::uint16_t> &&);
|
[[nodiscard]] std::basic_string<unsigned char>
|
||||||
|
lzw_uncompress(std::vector<std::uint16_t> &&);
|
||||||
|
|
||||||
void uncompress(const std::string &, const char *);
|
void uncompress(const std::string &, const char *);
|
||||||
|
|
||||||
void uncompress_chunk(FILE *, std::ofstream&);
|
void uncompress_chunk(FILE *, std::ofstream &);
|
||||||
|
|
||||||
#endif /* LZW_SRC_UNCOMPRESS_H_ */
|
#endif /* LZW_SRC_UNCOMPRESS_H_ */
|
||||||
|
Loading…
Reference in New Issue
Block a user