bug fixed as input stream was char and not unsigned char
This commit is contained in:
		
							parent
							
								
									ec85a4b978
								
							
						
					
					
						commit
						67a88aaf91
					
				| @ -29,7 +29,10 @@ using ustring = std::basic_string<unsigned char>; | |||||||
|  */ |  */ | ||||||
| [[nodiscard]] vuchar | [[nodiscard]] vuchar | ||||||
| pack_n(const vuint16::const_iterator t_input_begin, | pack_n(const vuint16::const_iterator t_input_begin, | ||||||
|        const vuint16::const_iterator t_input_end, const int t_n) { |            const vuint16::const_iterator t_input_end, const int t_n) { | ||||||
|  | #ifdef Debug | ||||||
|  |   std::printf("%d bits!\n", t_n); | ||||||
|  | #endif | ||||||
|   if (t_n == 16) { |   if (t_n == 16) { | ||||||
|     return pack_16(t_input_begin, t_input_end); |     return pack_16(t_input_begin, t_input_end); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -65,8 +65,11 @@ 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) { | ||||||
| 
 | #ifdef Debug | ||||||
|  |     std::printf("Code : %d\tNOT EMPTY\n", t_code); | ||||||
|  | #endif | ||||||
|     ustring e{static_cast<unsigned char>(t_code)}; |     ustring e{static_cast<unsigned char>(t_code)}; | ||||||
|  |     // 256 car on n'a pas encore tenté d'insérer de nouveau caractère
 | ||||||
|     if (t_old < 256) { |     if (t_old < 256) { | ||||||
|       t_dict[static_cast<uint16_t>(t_dict.size() + 256)] = |       t_dict[static_cast<uint16_t>(t_dict.size() + 256)] = | ||||||
|           static_cast<unsigned char>(t_old) + e; |           static_cast<unsigned char>(t_old) + e; | ||||||
| @ -82,6 +85,9 @@ ustring dico_uncompress(std::map<uint16_t, ustring> &t_dict, | |||||||
| 
 | 
 | ||||||
|   // le code existe dans le dictionnaire
 |   // le code existe dans le dictionnaire
 | ||||||
|   if (!e.empty()) { |   if (!e.empty()) { | ||||||
|  | #ifdef Debug | ||||||
|  |     std::printf("Code : %d\tNOT EMPTY\n", t_code); | ||||||
|  | #endif | ||||||
|     str += e[0]; |     str += e[0]; | ||||||
|     const uint16_t index = static_cast<uint16_t>(t_dict.size() + 256); |     const uint16_t index = static_cast<uint16_t>(t_dict.size() + 256); | ||||||
|     t_dict[index] = str; |     t_dict[index] = str; | ||||||
| @ -89,6 +95,9 @@ ustring dico_uncompress(std::map<uint16_t, ustring> &t_dict, | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   // le code n'existe pas encore dans le dictionnaire
 |   // le code n'existe pas encore dans le dictionnaire
 | ||||||
|  | #ifdef Debug | ||||||
|  |   std::printf("Code : %d\tEMPTY\n", t_code); | ||||||
|  | #endif | ||||||
|   str += str[0]; |   str += str[0]; | ||||||
|   e = str; |   e = str; | ||||||
|   t_dict[t_code] = e; |   t_dict[t_code] = e; | ||||||
|  | |||||||
| @ -15,7 +15,7 @@ using std::uint8_t; | |||||||
| using std::vector; | using std::vector; | ||||||
| using vuint16 = vector<uint16_t>; | using vuint16 = vector<uint16_t>; | ||||||
| using vvuint16 = vector<vuint16>; | using vvuint16 = vector<vuint16>; | ||||||
| using std::string; | 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; | ||||||
| @ -33,7 +33,7 @@ const size_t DICT_MAX = static_cast<size_t>(ipow(2, 17) - 256); /* 16 bits */ | |||||||
|  *  \param t_text Chaîne de caractères uint8_t représentant le fichier d'entrée |  *  \param t_text Chaîne de caractères uint8_t représentant le fichier d'entrée | ||||||
|  *  \return Vecteur de chunks (vecteurs de uint16_t) |  *  \return Vecteur de chunks (vecteurs de uint16_t) | ||||||
|  */ |  */ | ||||||
| vvuint16 lzw_compress(string &&t_text) { | vvuint16 lzw_compress(ustring &&t_text) { | ||||||
|   std::puts("Compressing..."); |   std::puts("Compressing..."); | ||||||
|   uint16_t w = 0xFFFF; |   uint16_t w = 0xFFFF; | ||||||
|   vuint16 chunk{}; |   vuint16 chunk{}; | ||||||
| @ -49,7 +49,7 @@ vvuint16 lzw_compress(string &&t_text) { | |||||||
|     if (const auto &[yes, pos] = dico(dict, w, static_cast<uint8_t>(c)); yes) { |     if (const auto &[yes, pos] = dico(dict, w, static_cast<uint8_t>(c)); yes) { | ||||||
|       w = pos; |       w = pos; | ||||||
|     } else { |     } else { | ||||||
|       chunk.push_back(static_cast<uint16_t>(w)); |       chunk.push_back(w); | ||||||
|       w = static_cast<uint16_t>(c); |       w = static_cast<uint16_t>(c); | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| @ -70,20 +70,26 @@ vvuint16 lzw_compress(string &&t_text) { | |||||||
|  *  \param[in] t_out_file Chemin vers le fichier de sortie |  *  \param[in] t_out_file Chemin vers le fichier de sortie | ||||||
|  */ |  */ | ||||||
| void compress(const std::string &t_in_file, const char *t_out_file) { | void compress(const std::string &t_in_file, const char *t_out_file) { | ||||||
|   std::ifstream input_file{t_in_file}; |   FILE *const input_file = fopen(t_in_file.c_str(), "rb"); | ||||||
|   assert(input_file.is_open()); |   assert(input_file); | ||||||
|   FILE *const out = (t_out_file != nullptr) ? fopen(t_out_file, "wb") |   FILE *const out = (t_out_file != nullptr) ? fopen(t_out_file, "wb") | ||||||
|                                             : fopen("output.lzw", "wb"); |                                             : fopen("output.lzw", "wb"); | ||||||
|   if (out == nullptr) { |   if (out == nullptr) { | ||||||
|     std::cerr << "Error at " << __FILE__ << ":" << __LINE__ - 4 |     std::cerr << "Error at " << __FILE__ << ":" << __LINE__ - 4 | ||||||
|               << ": could not open output file. Aborting...\n"; |               << ": could not open output file. Aborting...\n"; | ||||||
|     input_file.close(); |     // input_file.close();
 | ||||||
|  |     std::fclose(input_file); | ||||||
|     exit(1); |     exit(1); | ||||||
|   } |   } | ||||||
|   const auto compressed_text{ | 
 | ||||||
|       lzw_compress(std::string{std::istreambuf_iterator<char>(input_file), |   std::fseek(input_file, 0L, SEEK_END); | ||||||
|                                std::istreambuf_iterator<char>()})}; |   const auto file_size = static_cast<size_t>(ftell(input_file)); | ||||||
|  |   std::rewind(input_file); | ||||||
|  | 
 | ||||||
|  |   auto raw_text = std::make_unique<unsigned char[]>(file_size); | ||||||
|  |   std::fread(raw_text.get(), sizeof(unsigned char), file_size, input_file); | ||||||
|  |   const auto compressed_text(lzw_compress(ustring{raw_text.get(), &raw_text[file_size]})); | ||||||
|   write_file(out, compressed_text); |   write_file(out, compressed_text); | ||||||
|   fclose(out); |   fclose(out); | ||||||
|   input_file.close(); |   fclose(input_file); | ||||||
| } | } | ||||||
|  | |||||||
| @ -12,7 +12,8 @@ | |||||||
| #include <thread> | #include <thread> | ||||||
| 
 | 
 | ||||||
| /// \brief Compression d'une chaine de caractères
 | /// \brief Compression d'une chaine de caractères
 | ||||||
| std::vector<std::vector<std::uint16_t>> lzw_compress(std::string &&); | std::vector<std::vector<std::uint16_t>> | ||||||
|  | lzw_compress(std::basic_string<unsigned char> &&); | ||||||
| 
 | 
 | ||||||
| /// \brief Wrapper de \ref lzw_compress
 | /// \brief Wrapper de \ref lzw_compress
 | ||||||
| void compress(const std::string &, const char *); | void compress(const std::string &, const char *); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user