#include #include #include #include #include #include #include #include #include #define BUFSIZE 512 // a single node, only having information for a single byte. struct Node { uint8_t byte; size_t occurences; unsigned frequencyPriority; }; // a combination of nodes. struct Heap { struct Heap *parent, *child0, *child1; struct Node **Nodes; bool isRoot; }; // global vars for Heaps and Nodes. struct Node* nodes; struct Heap* heaps; // initialize our nodes void initNodes(){ nodes = malloc(sizeof(struct Node)*256); heaps = malloc(sizeof(struct Heap)*256); // not sure if i might need more memory for heaps? for(int i = 0; i < 256; i++){ nodes[i].byte = i; nodes[i].occurences = 0; nodes[i].frequencyPriority = 0; heaps[i].isRoot = false; } } // stolen from stackoverflow // https://stackoverflow.com/questions/8236/how-do-you-determine-the-size-of-a-file-in-c off_t fsize(const char *filename) { struct stat st; if (stat(filename, &st) == 0) return st.st_size; fprintf(stderr, "Cannot determine size of %s: %s\n", filename, strerror(errno)); return -1; } void helper() { printf("huffman compression algorithm implementation for educational " "purposes.\n\nSyntax:\nhuffman -f fileToCompress\t\tcompress the " "given file\nhuffman -xf fileToDecompress\t\tdecompress the given " "file\nhuffman -h\t\t\t\tshow this help\nhuffman -v\t\t\t\tverbose\n"); } int main(int argc, char *argv[]) { int opt; bool extract_mode = false; bool verbose = false; bool debug = false; char *filestring = NULL; off_t filelen; FILE *fptrR = NULL; // file pointer for reading FILE *fptrW = NULL; // file pointer for writing while ((opt = getopt(argc, argv, "dvxhf:")) != -1) { if (debug) printf("optarg is: %s\n", optarg); switch (opt) { case 'v': verbose = true; break; case 'd': debug = true; break; case 'f': filestring = optarg; break; case 'h': helper(); exit(0); break; case 'x': extract_mode = true; break; default: fprintf(stderr, "Usage: %s [-dvhx -f] [file]\n", argv[0]); exit(EXIT_FAILURE); } } // Now optind (declared extern int by ) is the index of the first // non-option argument. If it is >= argc, there were no non-option arguments. if (verbose) printf("selected file: %s\n", filestring); if (filestring) { if(debug) printf("[DEBUG]processing given file argument.\n"); // open the given file in binary mode fptrR = fopen(filestring, "rb"); if (fptrR == NULL) { fprintf(stderr, "The given file does not exist or is unavailable.\n"); exit(EXIT_FAILURE); } filelen = fsize(filestring); if(verbose) printf("filesize: %ldB\n", filelen); } else { // empty filestring or filestring is NULL fprintf(stderr, "Usage: %s [-dvhx -f] [file]\n", argv[0]); exit(EXIT_FAILURE); } if (extract_mode) { printf("extracting is not yet implemented.\n"); // decompress the file } else { // compress the file if (verbose) printf("compressing file...\n"); // frequency analysis uint8_t buf [BUFSIZE]; // dump start of file if debugging // FIXME add conditions if the part to print is smaller than 512B if(debug){ printf("[DEBUG]First 512 bytes are:\n"); fread(buf, 1, BUFSIZE, fptrR); for(int i=0;i= 0)){ if(!feof(fptrR)) { // no EOF, but didn't read full buffer. Assuming an error printf("Error while reading file."); exit(EXIT_FAILURE); } else{ // reached EOF, finished break; } } else{ printf("Undefined behaviour while reading file.\n"); exit(EXIT_FAILURE); } fseek(fptrR, BUFSIZE, SEEK_CUR); } } fclose(fptrR); printf("\n"); if(debug) // wait for input to end. getchar(); exit(EXIT_SUCCESS); }