usaa21/sk2a/compressor.c

190 lines
5.3 KiB
C

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#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);
}
}