usaa21/sk2a/compressor.c
2022-01-24 00:03:00 +01:00

137 lines
2.5 KiB
C

#define _GNU_SOURCE
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "compressor.h"
#define BUFSIZE 2000000
#define BSIZE 9
int mycompress(char* buff,int size,char* outbuf){
//memcpy(outbuf,buff,size);
int k = 0;
int head = 0;
while(head < size && buff[head] > 0 ){
//
//
// Kod inspirovany riesenim
// pana Ing. Daniela Hladeka
// 2019 Technical University of Kosice
//
//
int bufferSize = BSIZE;
if (head < bufferSize){
bufferSize = head;
}
char* searchBuffer = buff + head - bufferSize;
char* window = buff + head;
int lookAheadSize = BSIZE;
if((size - head) < lookAheadSize){
lookAheadSize = BSIZE - head;
}
int wsz = BSIZE;
int msz = wsz;
if (bufferSize < wsz){
msz = bufferSize;
}
int offset = -1;
int size = -1;
for(int i = 1; i<msz; i++){
char* r = memmem(searchBuffer, bufferSize, window, i);
if(r > 0){
offset = bufferSize - ( r - searchBuffer );
size = i+1;
}else {
break;
}
}
if(size > 0){
sprintf(&outbuf[k],"%d%d%c",offset,size-1,buff[head+size-1]);
k+=3;
head+=size;
}else {
sprintf(&outbuf[k],"00%c",buff[head]);
k+=3;
head+=1;
}
}
return k;
}
void compress(FILE* infile,FILE* outfile){
char buffer[BUFSIZE];
memset(buffer,0,BUFSIZE);
while(1){
int insize = fread(buffer,sizeof(char),BUFSIZE,infile);
if (insize == 0){
if (feof(infile)){
// end of file
break;
}
assert(!ferror(infile));
}
char outbuf[BUFSIZE*2];
// Doplnte implementaciu kompresie.
int outsize = mycompress(buffer,insize,outbuf);
if (outsize > 0){
fwrite(outbuf,sizeof(char),outsize,outfile);
}
}
}
void decompress(FILE* infile,FILE* outfile){
char code[3];
char buffer[BUFSIZE];
int size = 0;
int k = 0;
fseek(infile, 0, SEEK_END);
long fileSize = ftell(infile);
fseek(infile, 0, SEEK_SET);
printf("size: %ld\n", fileSize);
char letter;
while(!feof(infile)){
size = 0;
memset(buffer,0,BUFSIZE);
for(int j = 0; j < 4096; j++){
fread(code, sizeof(char), 3, infile);
int offset = atoi(code);
int length = atoi(&code[1]);
letter = code[2];
offset=(offset-length)/10;
if(offset == 0){
buffer[size] = letter;
size++;
}else {
for(int i = 0; i < length; i++){
buffer[size] = buffer[size-offset];
size++;
}
buffer[size] = letter;
size++;
}
printf("%d\n",k);
k+=3;
}
fwrite(buffer, sizeof(char), size-1, outfile);
}
}