137 lines
2.6 KiB
C
137 lines
2.6 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);
|
|
}
|
|
|
|
|
|
}
|
|
|