Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /***
- The Decompression Suite
- Written by Divingkatae
- 666th post on Jul Edition
- (c)2016, 2017 Divingkatae.
- ***/
- #include <iostream>
- #include <fstream>
- #include <cstdio>
- #include <unistd.h>
- #include <fcntl.h>
- #include <cstring>
- #include <cstdlib>
- #include <cstddef>
- #include <sys/stat.h>
- #include <unordered_map>
- #include <map>
- #include <map>
- #include <bitset>
- int packbits_rle_decompress(char *get_infile, char *get_outfile, char *get_offset);
- int plain_8b_rle_decompress(char *get_infile, char *get_outfile, char *get_offset);
- int plain_4b_rle_decompress(char *get_infile, char *get_outfile, char *get_offset);
- int lzw_decompress(char *get_infile, char *get_outfile, char *get_offset);
- int huffman_decompress(char *get_infile, char *get_outfile, char *get_offset);
- int fileLength(char* filename);
- typedef struct huffman_node{
- unsigned int freq;
- char data;
- bool left_right;
- } huffman_node;
- typedef huffman_node* NodePtr;
- using namespace std;
- int main(int argc, char *argv[])
- {
- if ( argc < 5 ){
- printf("An incorrect command argument was entered. Please check the documentation before continuing. \n");
- exit (1);
- }
- else{
- char *test_input = argv[1];
- printf("\n Compare this: %s \n", test_input);
- if (strcmp("packbits", test_input) == 0){
- printf("Time to decompress a PackBits compressed file. \n");
- packbits_rle_decompress(argv[2], argv[3], argv[4]);
- }
- else if (strcmp("fourbrle", test_input) == 0){
- printf("Time to decompress a Niblet RLE compressed file. \n");
- plain_4b_rle_decompress(argv[2], argv[3], argv[4]);
- }
- else if (strcmp("lzw", test_input) == 0){
- printf("Time to decompress an LZW compressed file. \n");
- lzw_decompress(argv[2], argv[3], argv[4]);
- }
- else if (strcmp("huffman", test_input) == 0){
- printf("Time to decompress a Huffman compressed file. \n");
- huffman_decompress(argv[2], argv[3], argv[4]);
- }
- else{
- printf("Time to decompress a generic RLE compressed file. \n");
- plain_8b_rle_decompress(argv[2], argv[3], argv[4]);
- }
- }
- return 0;
- }
- //Get the size of the file. This time, it's portable. Well...more portable.
- int fileLength(char* filename){
- ifstream mySource;
- mySource.open(filename, ios_base::binary);
- mySource.seekg(0,ios_base::end);
- int size = mySource.tellg();
- mySource.close();
- return size;
- }
- int packbits_rle_decompress(char *get_infile, char *get_outfile, char *get_offset){
- int offset_a = 0; //Starting offset
- unsigned char test_case = 0; //used for getting the test case
- unsigned char dump_char = 0; //dump this into a file
- //int test_arg3_length = 0; //where to begin searching in the file
- printf("\n Input: %s, Output: %s, Offset: %s", get_infile, get_outfile, get_offset);
- FILE* inFile = fopen(get_infile, "rb");
- FILE* outFile = fopen(get_outfile, "wb");
- //Get the offset to begin the decompression
- int get_size = fileLength(get_infile);
- fseek(inFile, 0, SEEK_SET);
- //Make sure we aren't reading a nonexistant or empty file first
- if (get_size < 1){
- printf("There was no data in the input file.");
- exit(1);
- }
- else{
- printf("\n Time to decompress %d bytes \n", get_size);
- //test_arg3_length = (unsigned)strlen(get_offset);
- offset_a = atoi(get_offset);
- printf("\n Offset: %d \n Now decompressing...", offset_a);
- while (offset_a < get_size)
- {
- //Read the file line by line
- fseek (inFile, (offset_a), SEEK_SET );
- fread(&test_case,1,1,inFile);
- if (test_case >= 128){
- test_case = 256 - test_case;
- for (int offset_b = 0; offset_b <= test_case; offset_b++){
- fseek (inFile, (offset_a + 1), SEEK_SET );
- fread(&dump_char,1,1,inFile);
- fwrite(&dump_char, 1, 1, outFile);
- }
- offset_a ++;
- }
- else{
- int offset_b;
- for (offset_b = 0; offset_b <= test_case; offset_b++){
- fseek (inFile, (offset_a + offset_b + 1), SEEK_SET );
- fread(&dump_char,1,1,inFile);
- fwrite(&dump_char,1,1,outFile);
- }
- offset_a += offset_b;
- }
- offset_a ++;
- }
- fclose(inFile);
- fclose(outFile);
- }
- return 0;
- }
- int plain_8b_rle_decompress(char *get_infile, char *get_outfile, char *get_offset){
- int offset_a = 0; //Starting offset
- unsigned char test_case = 0; //used for getting the test case
- unsigned char dump_char = 0; //dump this into a file
- //int test_arg3_length = 0; //where to begin searching in the file
- printf("\n Input: %s, Output: %s, Offset: %s", get_infile, get_outfile, get_offset);
- FILE* inFile = fopen(get_infile, "rb");
- FILE* outFile = fopen(get_outfile, "wb");
- //Get the offset to begin the decompression
- int get_size = fileLength(get_infile);
- fseek(inFile, 0, SEEK_SET);
- //Make sure we aren't reading a nonexistant or empty file first
- if (get_size < 1){
- printf("There was no data in the input file.");
- exit(1);
- }
- else{
- printf("\n Time to decompress %d bytes \n", get_size);
- //test_arg3_length = (unsigned)strlen(get_offset);
- offset_a = atoi(get_offset);
- printf("\n Offset: %d \n", offset_a);
- while (offset_a < get_size)
- {
- //Read the file line by line
- fseek (inFile, (offset_a), SEEK_SET );
- fread(&test_case,1,1,inFile);
- //Get the character to dump in
- offset_a++;
- fseek (inFile, (offset_a), SEEK_SET );
- fread(&dump_char,1,1,inFile);
- for (int offset_b = 0; offset_b <= test_case; offset_b++){
- fwrite(&dump_char, 1, 1, outFile);
- }
- offset_a++;
- }
- fclose(inFile);
- fclose(outFile);
- }
- return 0;
- }
- int plain_4b_rle_decompress(char *get_infile, char *get_outfile, char *get_offset){
- int offset_a = 0; //Starting offset
- unsigned char test_case = 0; //used for getting the test case
- unsigned char dump_char = 0; //dump this into a file
- //int test_arg3_length = 0; //where to begin searching in the file
- printf("\n Input: %s, Output: %s, Offset: %s", get_infile, get_outfile, get_offset);
- FILE* inFile = fopen(get_infile, "rb");
- FILE* outFile = fopen(get_outfile, "wb");
- //Get the offset to begin the decompression
- int get_size = fileLength(get_infile);
- fseek(inFile, 0, SEEK_SET);
- //Make sure we aren't reading a nonexistant or empty file first
- if (get_size < 1){
- printf("There was no data in the input file.");
- exit(1);
- }
- else{
- printf("\n Time to decompress %d bytes \n", get_size);
- //test_arg3_length = (unsigned)strlen(get_offset);
- offset_a = atoi(get_offset);
- printf("\n Offset: %d \n", offset_a);
- while (offset_a < get_size)
- {
- //Read the file line by line
- fseek (inFile, (offset_a), SEEK_SET );
- fread(&test_case,1,1,inFile);
- unsigned char test_backup = test_case; //Store the value to put in
- test_case = (test_case & 0xf0) >> 4;
- dump_char = (test_backup & 0x0f);
- for (int offset_b = 0; offset_b <= test_case; offset_b++){
- fwrite(&dump_char, 1, 1, outFile);
- }
- offset_a++;
- }
- fclose(inFile);
- fclose(outFile);
- }
- return 0;
- }
- /**
- int packbits_rle_compress(char *get_infile, char *get_outfile, char *get_offset){
- int offset_a = 0; //Starting offset
- unsigned char test_case = 0; //used for getting the test case
- unsigned char dump_char = 0; //dump this into a file
- FILE* inFile = fopen(get_infile, "rb");
- FILE* outFile = fopen(get_outfile, "wb");
- //Make sure we aren't reading a nonexistant or empty file first
- if (fileLength(inFile) < 1){
- printf("There was no data in the input file.");
- exit(1);
- }
- else{
- }
- return 0;
- }
- **/
- int lzw_decompress(char *get_infile, char *get_outfile, char *get_offset){
- int offset_a = 0; //Starting offset
- string entry; //string for dictionary entries
- //int dict_size = 256; - Unused variable
- //char * result; - Unused variable
- std::string work_string;
- uint16_t code_a;
- //char get_char1; - Unused variable
- uint16_t max_code = 32767;
- std::unordered_map<uint16_t, std::string> mymap( (max_code * 11) / 10 );
- printf("\n Input: %s, Output: %s, Offset: %s", get_infile, get_outfile, get_offset);
- FILE* inFile = fopen(get_infile, "rb");
- FILE* outFile = fopen(get_outfile, "wb"); //Where to have the outpit stored
- int get_size = fileLength(get_infile);
- if (get_size < 1){
- printf("There was no data in the input file.");
- exit(1);
- }
- else{
- //Fill the dictionary with 1-character strings
- offset_a = atoi(get_offset);
- for (int i = 0; i < 256; i ++){
- mymap[i] = string(1, i);
- }
- //fseek (inFile, offset_a, SEEK_SET);
- //fread(&work_string,1,1,inFile);
- //fwrite(&work_string, 1, 1, outFile);
- //offset_a++;
- uint16_t next_code = 257;
- fseek (inFile, offset_a, SEEK_SET);
- for (int i = 0; i < get_size; i ++){
- fread(&code_a,1,2,inFile);
- if(mymap.find(code_a) == mymap.end()){
- mymap[code_a] = work_string + work_string[0];
- }
- fwrite(&mymap[code_a], 1, sizeof(mymap[code_a]), outFile);
- if (work_string.size() && next_code <= max_code){
- mymap[next_code++] = work_string + mymap[code_a][0];
- }
- offset_a += 2;
- work_string = mymap[code_a];
- }
- fclose(inFile);
- fclose(outFile);
- }
- return 0;
- }
- int huffman_decompress(char *get_infile, char *get_outfile, char *get_offset){
- //TO DO list:
- //Proper memory allocation
- //Bitwise IO (since Huffman does bit level compression)
- int offset_a = 0; //Starting offset
- huffman_node base_node = {0, 0, NULL}; //Root node
- unsigned char used_bits = 0;
- unsigned char dump_char = 0; //dump this into a file
- //int test_arg3_length = 0; //where to begin searching in the file
- printf("\n Input: %s, Output: %s, Offset: %s", get_infile, get_outfile, get_offset);
- FILE* inFile = fopen(get_infile, "rb");
- FILE* outFile = fopen(get_outfile, "wb");
- //Get the offset to begin the decompression
- int get_size = fileLength(get_infile);
- //An unrolled version of the data saving code
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.freq,1,sizeof(unsigned int),inFile);
- offset_a += sizeof(unsigned int);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.data,1,sizeof(char),inFile);
- offset_a += sizeof(char);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.left_right,1,sizeof(bool),inFile);
- offset_a += sizeof(bool);
- fseek(inFile, offset_a, SEEK_SET);
- //Make sure we aren't reading a nonexistant or empty file first
- if (get_size < 1){
- printf("There was no data in the input file.");
- exit(1);
- }
- else{
- printf("\n Time to decompress %d bytes \n", get_size);
- //test_arg3_length = (unsigned)strlen(get_offset);
- offset_a = atoi(get_offset);
- std::map <char*, char> store_chars_here;
- //Try to not make a size limitation immediately
- char * temp_array = (char*) malloc(sizeof(char) * get_size);
- char * result_array = (char*) malloc(sizeof(char) * get_size);
- char * new_char_array = (char*) malloc(sizeof(char) * get_size);
- printf("\n Offset: %d \n", offset_a);
- while (offset_a < get_size)
- {
- fseek (inFile, (offset_a), SEEK_SET );
- fread(&new_char_array,1,1,inFile);
- fwrite(&dump_char, 1, (sizeof(result_array) / sizeof(result_array[0])), outFile);
- temp_array = new_char_array;
- strcat(temp_array, new_char_array);
- const char * get_result;
- if (base_node.freq > 0){
- //0 = left, 1 = right
- if(base_node.left_right == 0) {
- get_result = &(base_node.data);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.freq,1,sizeof(unsigned int),inFile);
- offset_a += sizeof(unsigned int);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.data,1,sizeof(char),inFile);
- offset_a += sizeof(char);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.left_right,1,sizeof(bool),inFile);
- offset_a += sizeof(bool);
- fseek (inFile, offset_a, SEEK_SET );
- strcat(result_array, get_result);
- strcat(temp_array, result_array);
- }
- else if(base_node.left_right == 1) {
- get_result = &(base_node.data);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.freq,1,sizeof(unsigned int),inFile);
- offset_a += sizeof(unsigned int);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.data,1,sizeof(char),inFile);
- offset_a += sizeof(char);
- fseek(inFile, offset_a, SEEK_SET);
- fread(&base_node.left_right,1,sizeof(bool),inFile);
- offset_a += sizeof(bool);
- fseek (inFile, (offset_a), SEEK_SET );
- strcat(result_array, get_result);
- strcat(temp_array, result_array);
- }
- }
- else {
- get_result = &(base_node.data);
- strcat(result_array, get_result);
- fwrite(result_array, 1, (sizeof(result_array) / sizeof(result_array[0])), outFile);
- free(temp_array);
- temp_array = nullptr;
- }
- offset_a++;
- }
- fclose(inFile);
- fclose(outFile);
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement