Skip to content

Commit

Permalink
finilised and documented the code
Browse files Browse the repository at this point in the history
  • Loading branch information
karimkohel committed Jun 16, 2020
1 parent 143b57f commit 3b31383
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 36 deletions.
Binary file modified DCW
Binary file not shown.
11 changes: 5 additions & 6 deletions DCW.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,22 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
// #include <assert.h>
#include "errhandling.h"
#include "linkedQ.h"
#include "tree.h"
#include "hashtable.h"
#include "general.h"
#include "main.h"

// ----The Delightful Compression Wizard----
//
// WELCOME
// for documentation, developement and commit history, the github repo
// for Usage, documentation, developement and commit history, the github repo
// github.com/karimkohel/DCW should be publically available
// by the time of this review.
//
// NOTICE:
// -to build on Visual Studio, the header files should be pointed to in the project properties
// menu under C/C++ > all options > include directories.
// -to build on Visual Studio: the header files should be pointed to in the project properties
// menu under C/C++ > all options -> additional include directories.
//
// -and to turn off the extra security checks by adding _CRT_SECURE_NO_WARNINGS into the
// preprocessor definitions in project > project properties > C/C++ > preprocessor.
Expand All @@ -30,7 +29,7 @@
// -> mohamed osama
// -> aly khaled anas
// -> omar tamer
//
// -> amr mekky
//


Expand Down
41 changes: 29 additions & 12 deletions general.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ int greet(){
}

void load_file_in(Q_t *q, FILE *file, long *count){

//loads the input file in the priority Q as a frequency table
char c;
long counter = 0;
long wait = 10000000;
Expand Down Expand Up @@ -77,8 +77,8 @@ void encode_tree(node_t *node, char code[], char *codes_table[]){
return; // base exit case for children of leaf nodes

if(leaf_node(node))
codes_table[((int)node->data)] = code;

codes_table[((int)node->data)] = code;// place the code of that char in it's equvilant ascii number
// as a table index

encode_tree(node->left, strcat2(code, "0"), codes_table);
encode_tree(node->right, strcat2(code, "1"), codes_table);
Expand All @@ -92,11 +92,13 @@ void get_codes(node_t *root, char *table[]){
tmp_code[0] = '\0';
encode_tree(root, tmp_code, table);

// print_table(table);
// print_table(table); // can be used for debugging and checking out the codes table
}

node_t *load_in_tree(Q_t *q){

//handles the steps of creating the tree by deQing and enQing and returns the last node to enter the Q

node_t *tmp_node1 = NULL;
node_t *tmp_node2 = NULL;
node_t *joined_node = NULL;
Expand All @@ -109,6 +111,7 @@ node_t *load_in_tree(Q_t *q){
}

void trim_str(char *str, int offset){
//trims the string from the beginning up to a certain offset
int len = strlen(str);
for(int i=0; i<(len-offset+1); i++){
str[i] = str[offset+i];
Expand All @@ -123,7 +126,7 @@ int encode_file(FILE *in_file, char *table[], int tree_hight, FILE *comp_file, c
char in_c;
int out_c;
char out_c2;
char *buffer = (char *)malloc(tree_hight*tree_hight*sizeof(char));
char *buffer = (char *)malloc(tree_hight*tree_hight*sizeof(char));//buffer to store bits of the codes combined
buffer[0] = '\0'; // the string starts with garbage value for some reason
char tmp[9];
int len;
Expand All @@ -135,7 +138,7 @@ int encode_file(FILE *in_file, char *table[], int tree_hight, FILE *comp_file, c

while(len > 7){
strncpy(tmp, buffer, BYTE_SIZE);
out_c = strtol(tmp, 0, 2);
out_c = strtol(tmp, 0, 2); // converts from binary to decimal
out_c2 = out_c;
fwrite(&out_c2, sizeof(char), 1, comp_file);
trim_str(buffer, BYTE_SIZE);
Expand All @@ -144,23 +147,23 @@ int encode_file(FILE *in_file, char *table[], int tree_hight, FILE *comp_file, c
}
}

*extra_bits = buffer;
*extra_bits = buffer;//return the extra bits by refrence to be written sepperatly in the start of file
return count;
}

void write_extra_bits(FILE *file, char *bits){
// write the extra bits to a file
int len = strlen(bits);
for(int i=0; i<len+1; i++){
fwrite(&bits[i], sizeof(char), 1, file);
}
}

void serialize(node_t *root, FILE *file){
// serializes the tree in the file

if (root == NULL){
// fwrite(root, sizeof(node_t), 1, file);
return;
}
if(root == NULL)
return;

fwrite(root, sizeof(node_t), 1, file);
serialize(root->left, file);
Expand All @@ -180,6 +183,7 @@ void deserialize(node_t *root, FILE *file) {
}

void get_extra_bits(FILE *file, char *bits){
// reads the extra bits from a file
for(int i=0; i<BYTE_SIZE; i++){
fread(&bits[i], sizeof(char), 1, file);
if(bits[i] == '\0')
Expand All @@ -188,7 +192,8 @@ void get_extra_bits(FILE *file, char *bits){
}

void atob(char* buffer, int c){
//(CRDTS)//got the function idea from https://www.programmingsimplified.com/c/source-code/c-program-convert-decimal-to-binary
//(CRDTS)
//got the function idea from https://www.programmingsimplified.com/c/source-code/c-program-convert-decimal-to-binary
// had to learn about binary operators and shifting bits,
// bitwise and all around to pull this off
// the awesome name i gave this function however is 100% mine
Expand All @@ -206,6 +211,11 @@ void atob(char* buffer, int c){
}

char decode(char *bits, node_t *root, int *offset){
//given a string of bits with length above the max code length,
// will travers down the deserialized tree we got back in the direction of
// the the code bit by bit until a leaf node is found, trims the used up code for the
// string that lead to this node then reterns the character in the node
// and the offset of how much bits it took ;

int len = strlen(bits);
int j = 1;
Expand All @@ -231,6 +241,10 @@ char decode(char *bits, node_t *root, int *offset){

void get_bits(node_t *root, FILE *comp_file, int tree_h, FILE *out_file, char *extra_bits){

//reads the compressed file and whenever the number of bits generated from the characters in it
// is above the hight of the tree we decode the bits and write the character in the resulting
// decompressed file

char c;
char out_c;
char *bits = (char *)malloc(sizeof(char)*tree_h*tree_h);
Expand Down Expand Up @@ -259,6 +273,9 @@ void get_bits(node_t *root, FILE *comp_file, int tree_h, FILE *out_file, char *e
}
}

//then the exra bits are added to whats left of the bits generated and untill they are
// finished we find the characeters they code

strcat(bits, extra_bits);
len = strlen(bits);

Expand Down
7 changes: 4 additions & 3 deletions hashtable.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#define TABLESIZE 255

// while thinking that a map is the best solution to store huffman codes with a O(1) acces time
// as the app must acces the codes so much times and speed is of the essence.
// as the app must acces the codes so much and time is of the essence.
// i found out that i don't have to implement a hash function for my table, i can just use the ascii
// table indices instead of hashing my own. what a nifty little hack.

Expand All @@ -17,14 +17,15 @@ void init_table(char *table[]){

void print_table(char *table[]){
for(int i=0; i<TABLESIZE; i++){
if(table[i] != NULL)
if(table[i])
printf("%d - %s - %c\n", i, table[i], i);
}
}

void free_table(char *table[]){
for(int i=0; i<TABLESIZE; i++){
free(table[i]);
if(table[i])
free(table[i]);
}
}

Expand Down
27 changes: 15 additions & 12 deletions linkedQ.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,15 +93,6 @@ void sort_list(node_t *head){
}
}

// void free_list(node_t *head){
// node_t *tmp;
// while(head != NULL){
// tmp = head;
// head = head->next;
// free(tmp);
// }
// }

bool insert_node_first(node_t **head, node_t *node){
if((*head) == NULL || node == NULL)
return false;
Expand All @@ -126,6 +117,15 @@ bool remove_node_first(node_t **head, node_t **node){
return true;
}

// void free_list(node_t *head){
// node_t *tmp;
// while(head != NULL){
// tmp = head;
// head = head->next;
// free(tmp);
// }
// }

//////////////////////// END OF LINKED LIST DS //////////////////
///////////////////// Q DS USING LINKED LIST ///////////////////

Expand All @@ -138,9 +138,10 @@ typedef struct Q_t{
tail = NULL;
}

~Q_t(){
// free_list(head);
}
// ~Q_t(){
// free_list(head);
// }

}Q_t;

bool enQ(Q_t* q, char item, node_t *node){
Expand Down Expand Up @@ -175,6 +176,8 @@ bool enQ(Q_t* q, char item, node_t *node){

bool deQ(Q_t* q, node_t **node){

// when the Q is empty, will return false to stop the deQing and set the garbage node to NULL;

if(q->head == NULL){
(*node) = NULL;
return false;
Expand Down
7 changes: 4 additions & 3 deletions main.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ void compress(const char *in_file_name, const char *out_file_name){
clock_t start_time = clock();

Q_t q;

FILE *in_file = fopen(in_file_name, "rb");
fcheck(in_file, 1);
FILE *out_file = fopen(out_file_name, "wb");
Expand All @@ -28,15 +29,15 @@ void compress(const char *in_file_name, const char *out_file_name){

int tree_hight = find_hight(tree_root);

char buffer[8] = "0000000";
write_extra_bits(out_file, buffer);
char buffer[8] = "0000000"; // this buffer holds a place in the beginning of the file for the
write_extra_bits(out_file, buffer);// extra bits that we will put in later

serialize(tree_root, out_file);

char *extra_bits;
int out_count = encode_file(in_file, code_table, tree_hight, out_file, &extra_bits);

fseek(out_file, 0, SEEK_SET);
fseek(out_file, 0, SEEK_SET);// seek to start and place the extra bits we got
write_extra_bits(out_file, extra_bits);


Expand Down
3 changes: 3 additions & 0 deletions tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ bool leaf_node(node_t *node){

node_t *join_nodes(node_t *node1, node_t *node2){

// take 2 nodes, join them as siblings under one parant, simple.

node_t *new_node = create_node('\0');
if(new_node == NULL)
return NULL;
Expand All @@ -36,6 +38,7 @@ void printPostorder(node_t *root){
}

void free_tree(node_t *node){
// no memory waste what so ever
if(node == NULL)
return;

Expand Down

0 comments on commit 3b31383

Please sign in to comment.