#include #include #include #include #include #include "compressor.h" #define BUFSIZE 1024 char* leftRotatebyOne(char arr[BUFSIZE * 2]){ char* result = (char*) calloc(strlen(arr), sizeof(char)); char temp = arr[0]; for (int i = 0; i < strlen(arr) - 1; i++) arr[i] = arr[i + 1]; arr[strlen(arr)-1] = temp; strcpy(result, arr); return result; } char* bwt_compress(char buffer[BUFSIZE * 2]){ char* encoded = (char*) calloc(BUFSIZE * 2, sizeof(char)); char rotate_temp[BUFSIZE * 2]; for(int i = 0; i < strlen(buffer); i++) rotate_temp[i] = buffer[i]; rotate_temp[strlen(buffer)] = '\0'; char* rotation[strlen(buffer)]; for(int i = 0; i < strlen(buffer); i++) rotation[i] = (char*) calloc(BUFSIZE * 2, sizeof(char)); for(int i = 0; i < strlen(buffer); i++) strcpy(rotation[i], leftRotatebyOne(rotate_temp)); char* temp = (char*) calloc(BUFSIZE * 2, sizeof(char)); for(int i = 0; i < strlen(buffer); i++){ for(int j = 0; j < strlen(buffer) - i - 1; j++){ if(strcmp(rotation[j], rotation[j+1]) > 0){ strcpy(temp, rotation[j]); strcpy(rotation[j], rotation[j+1]); strcpy(rotation[j+1], temp); } } } for(int i = 0; i < strlen(buffer); i++) { strncat(encoded, &rotation[i][strlen(rotation[i]) - 1], 1); if(strcmp(rotation[i], buffer) == 0) { char str[100]; for(int j = 0; j < 100; j++) str[j] = '\0'; sprintf(str, "%d", i); FILE* num = fopen("num.txt", "w"); fwrite(str, sizeof(char), strlen(str), num); } } return encoded; } char* run_length(char buffer[BUFSIZE]){ char* encoded = (char*) calloc(BUFSIZE * 2, sizeof(char)); int counter = 1; int i = 1; while(i < strlen(buffer)+1){ for(; i < strlen(buffer)+1; i++){ if(buffer[i] == buffer[i-1]) counter++; else { char* temp = (char*) calloc(5, sizeof(char)); sprintf(temp, "%d", counter); strncat(encoded, temp, strlen(temp)); strncat(encoded, &buffer[i-1], 1); i++; counter = 1; break; } } } return encoded; } void compress(FILE* infile,FILE* outfile){ char buffer[BUFSIZE]; memset(buffer,0,BUFSIZE); while(1) { int insize = (int) fread(buffer, sizeof(char), BUFSIZE, infile); if (insize == 0) { if (feof(infile)) { // end of file break; } assert(!ferror(infile)); } char outbuf[BUFSIZE*2]; strncpy(outbuf, run_length(bwt_compress(buffer)), BUFSIZE*2-1); fwrite(outbuf,sizeof(char), strlen(outbuf),outfile); } } char* bwt_decompress(char buffer[BUFSIZE * 2]){ char* decoded = (char*) calloc(BUFSIZE * 2, sizeof(char)); char rotation[strlen(buffer)][BUFSIZE * 2]; for(int i = 0; i < strlen(buffer); i++) { for (int j = 0; j < strlen(buffer) + 1; j++) { if(j != strlen(buffer)) rotation[i][j] = ' '; else rotation[i][j] = '\0'; } } for(int i = 0; i < strlen(buffer); i++) { for (int j = 0; j < strlen(buffer) + 1; j++) { rotation[j][strlen(buffer) - 1 - i] = buffer[j]; } char *temp = (char *) calloc(BUFSIZE * 2, sizeof(char)); for (int iterator = 0; iterator < strlen(buffer); iterator++) { for (int j = 0; j < strlen(buffer) - 1 - iterator; j++) { if (strcmp(rotation[j], rotation[j + 1]) > 0) { strcpy(temp, rotation[j]); strcpy(rotation[j], rotation[j + 1]); strcpy(rotation[j + 1], temp); } } } } FILE* num = fopen("num.txt", "r"); char number[100]; for(int i = 0; i < 100; i++) number[i] = '\0'; fread(number, sizeof(char), 100, num); strcpy(decoded, rotation[atoi(number)]); return decoded; } char* run_length_decompress(char buffer[BUFSIZE * 2]){ char* decoded = (char*) calloc(BUFSIZE, sizeof(char)); int i = 0; while(i < strlen(buffer)){ char* temp = (char*) calloc(5, sizeof(char)); for(; i < strlen(buffer); i++){ if(isdigit(buffer[i])){ strncat(temp, &buffer[i], 1); } else{ for(int j = 0; j < atoi(temp); j++) strncat(decoded, &buffer[i], 1); i++; break; } } memset(temp, '\0', 5); } return decoded; } void decompress(FILE* infile,FILE* outfile){ char buffer[BUFSIZE * 2]; memset(buffer, 0, BUFSIZE*2); while(1){ int insize = (int)fread(buffer,sizeof(char),BUFSIZE * 2,infile); if (insize == 0){ if (feof(infile)){ // end of file break; } assert(!ferror(infile)); } char outbuf[BUFSIZE]; strncpy(outbuf, bwt_decompress(run_length_decompress(buffer)), BUFSIZE-1); fwrite(outbuf,sizeof(char), strlen(outbuf),outfile); } }