2018-04-05 16:47:07 +00:00
|
|
|
|
/**
|
|
|
|
|
* \file main.cc
|
|
|
|
|
* \brief Main file
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "compress.hh"
|
2018-04-10 08:39:41 +00:00
|
|
|
|
#include "getopt.h"
|
2018-03-21 00:22:05 +00:00
|
|
|
|
|
|
|
|
|
using std::printf;
|
|
|
|
|
using std::puts;
|
|
|
|
|
|
2018-04-02 17:39:53 +00:00
|
|
|
|
// custom types ///////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
Dictionnaire :
|
|
|
|
|
<
|
|
|
|
|
<
|
|
|
|
|
numéro chaine précédente,
|
|
|
|
|
caractère ASCII
|
|
|
|
|
>
|
|
|
|
|
numéro chaine courante
|
|
|
|
|
>
|
|
|
|
|
*/
|
|
|
|
|
using dic_t = std::map<std::pair<uint32_t, uint8_t>, uint32_t>;
|
|
|
|
|
using ustring = std::basic_string<uint8_t>; // chaine non encodée
|
2018-04-10 08:39:41 +00:00
|
|
|
|
using uvec = std::vector<uint32_t>; // chaine encodée
|
|
|
|
|
|
2018-04-10 09:25:24 +00:00
|
|
|
|
/**
|
|
|
|
|
* \brief Affichage d’aide
|
|
|
|
|
*/
|
2018-04-10 08:39:41 +00:00
|
|
|
|
void help() {
|
|
|
|
|
puts("Usage:");
|
|
|
|
|
puts("lzw [-options] [-i path] [-o path]");
|
|
|
|
|
puts("\tThe default action is to compress the input file to a .lzw file");
|
|
|
|
|
puts("\tin which the directory in which the software is executed.");
|
|
|
|
|
puts("\tOptions available:");
|
|
|
|
|
puts("\t-i\tpath to the input file (mandatory)");
|
|
|
|
|
puts("\t-o\tpath to the output file (if the file already exists, it will");
|
|
|
|
|
puts("\t\tbe overwritten). Default: input path + \".lzw\"");
|
|
|
|
|
puts("\t-c\tcompress the input file");
|
|
|
|
|
puts("\t-d\tdecompresses the input file to the output file. If no output");
|
|
|
|
|
puts("\t\tpath has not been entered and if the input file ends with ");
|
|
|
|
|
puts("\t\t\".lzw\", the extension \".lzw\" will be removed; otherwise, the ");
|
|
|
|
|
puts("\t\textension \".uncompresed\" will be added");
|
|
|
|
|
}
|
2018-04-02 17:39:53 +00:00
|
|
|
|
|
2018-03-21 00:22:05 +00:00
|
|
|
|
int main(int argc, char *argv[]) {
|
2018-04-10 08:39:41 +00:00
|
|
|
|
#ifdef Debug
|
|
|
|
|
for (int i = 0; i < argc; ++i)
|
|
|
|
|
printf("argv[%d] = %s\n", i, argv[i]);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
std::string input_path{};
|
|
|
|
|
std::string output_path{};
|
|
|
|
|
bool compressing = true;
|
|
|
|
|
|
|
|
|
|
while (1) {
|
|
|
|
|
int option_index = 0;
|
|
|
|
|
static struct option long_options[] = {
|
|
|
|
|
{"help", no_argument, nullptr, 'h'},
|
|
|
|
|
{"input", required_argument, nullptr, 'i'},
|
|
|
|
|
{"output", required_argument, nullptr, 'o'},
|
|
|
|
|
{"compress", no_argument, nullptr, 'c'},
|
|
|
|
|
{"uncompress", no_argument, nullptr, 'u'},
|
|
|
|
|
{0, 0, 0, 0}};
|
|
|
|
|
int c = getopt_long(argc, argv, "hi:o:cu", long_options, &option_index);
|
|
|
|
|
if (c == -1)
|
|
|
|
|
break;
|
|
|
|
|
switch (c) {
|
|
|
|
|
case 0: {
|
|
|
|
|
#ifdef Debug
|
|
|
|
|
printf("\noption %s", long_options[option_index].name);
|
|
|
|
|
if (optarg) {
|
|
|
|
|
printf(" with arg %s\n", optarg);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'h': {
|
|
|
|
|
#ifdef Debug
|
|
|
|
|
printf("From main - option --help passed\n");
|
|
|
|
|
#endif
|
|
|
|
|
help();
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
case 'i': {
|
|
|
|
|
#ifdef Debug
|
|
|
|
|
printf("From main - option --input with value '%s'\n", optarg);
|
|
|
|
|
#endif
|
|
|
|
|
input_path = optarg;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'o': {
|
|
|
|
|
#ifdef Debug
|
|
|
|
|
printf("From main - option --output with value '%s'\n", optarg);
|
|
|
|
|
#endif
|
|
|
|
|
output_path = optarg;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'c': {
|
|
|
|
|
#ifdef Debug
|
|
|
|
|
printf("From main - option --compress\n");
|
|
|
|
|
#endif
|
|
|
|
|
compressing = true;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case 'u': {
|
|
|
|
|
#ifdef Debug
|
|
|
|
|
printf("From main - option --uncompress\n");
|
|
|
|
|
#endif
|
|
|
|
|
compressing = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case '?': {
|
|
|
|
|
puts("Error: unknown parameter.");
|
|
|
|
|
#ifdef Debug
|
|
|
|
|
printf("From main - option -?\n");
|
|
|
|
|
#endif
|
|
|
|
|
help();
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
}
|
2018-03-21 00:22:05 +00:00
|
|
|
|
}
|
|
|
|
|
|
2018-04-10 08:39:41 +00:00
|
|
|
|
if (input_path == "") {
|
|
|
|
|
puts("Error: no input file specified");
|
|
|
|
|
return 2;
|
|
|
|
|
}
|
2018-03-21 00:22:05 +00:00
|
|
|
|
|
2018-04-10 08:39:41 +00:00
|
|
|
|
if (compressing) {
|
2018-04-10 09:25:24 +00:00
|
|
|
|
/*
|
|
|
|
|
TODO:
|
|
|
|
|
- compresser le fichier d’entrée morceaux par morceaux, 16Ko à la fois
|
|
|
|
|
- écrire la taille du segment compressé, puis le segment compressé
|
|
|
|
|
- multithreading
|
|
|
|
|
- compression multiple : nombre de compressions puis fichier compressé
|
|
|
|
|
- bit-packing, limiter la taille du dictionnaire pour un certain nombre de
|
|
|
|
|
bits.
|
|
|
|
|
*/
|
2018-04-10 08:39:41 +00:00
|
|
|
|
compress(input_path, output_path.c_str());
|
|
|
|
|
} else {
|
|
|
|
|
puts("Not yet implemented :(");
|
2018-04-10 09:25:24 +00:00
|
|
|
|
/*
|
|
|
|
|
Inversion des types du dictionnaire pour retrouver les chaînes plus aisément
|
|
|
|
|
*/
|
2018-04-10 08:39:41 +00:00
|
|
|
|
}
|
2018-03-21 00:22:05 +00:00
|
|
|
|
|
|
|
|
|
return 0;
|
2018-03-20 20:41:46 +00:00
|
|
|
|
}
|