This commit is contained in:
Bohdan Kapliuk 2025-01-12 17:38:06 +02:00
parent 7eb6729b57
commit ae858980c5

View File

@ -24,6 +24,7 @@ int read_file(const char* filename, unsigned char** data, size_t* size) {
fclose(file); fclose(file);
return 0; return 0;
} }
int write_file(const char* filename, const unsigned char* data, size_t size) { int write_file(const char* filename, const unsigned char* data, size_t size) {
FILE* file = fopen(filename, "wb"); FILE* file = fopen(filename, "wb");
if (!file) return -1; if (!file) return -1;
@ -33,23 +34,26 @@ int write_file(const char* filename, const unsigned char* data, size_t size) {
return 0; return 0;
} }
//RLE // RLE Compression
int compress_1(const char* input_file_name, const char* output_file_name) { int compress_1(const char* input_file_name, const char* output_file_name) {
size_t size; size_t size;
unsigned char* data; unsigned char* data;
if (read_file(input_file_name, &data, &size) != 0) return -1; if (read_file(input_file_name, &data, &size) != 0) return -1;
FILE* output = fopen(output_file_name, "w");
FILE* output = fopen(output_file_name, "wb");
if (!output) { if (!output) {
free(data); free(data);
return -1; return -1;
} }
for (size_t i = 0; i < size;) { for (size_t i = 0; i < size;) {
unsigned char byte = data[i]; unsigned char byte = data[i];
size_t count = 1; size_t count = 1;
while (i + count < size && data[i + count] == byte && count < 255) { while (i + count < size && data[i + count] == byte && count < 255) {
count++; count++;
} }
fprintf(output, "%c%zu", byte, (int)count); fputc(byte, output);
fputc(count, output);
i += count; i += count;
} }
@ -58,12 +62,14 @@ int compress_1(const char* input_file_name, const char* output_file_name) {
free(data); free(data);
return 0; return 0;
} }
// RLE Decompression
int decompress_1(const char* input_file_name, const char* output_file_name) { int decompress_1(const char* input_file_name, const char* output_file_name) {
size_t size; size_t size;
unsigned char* data; unsigned char* data;
if (read_file(input_file_name, &data, &size) != 0) return -1; if (read_file(input_file_name, &data, &size) != 0) return -1;
unsigned char* decompressed = malloc(size * 255); unsigned char* decompressed = malloc(size * 255); // Allocate a large enough buffer
if (!decompressed) { if (!decompressed) {
free(data); free(data);
return -1; return -1;
@ -72,21 +78,8 @@ int decompress_1(const char* input_file_name, const char* output_file_name) {
size_t write_idx = 0; size_t write_idx = 0;
for (size_t i = 0; i < size;) { for (size_t i = 0; i < size;) {
unsigned char byte = data[i++]; unsigned char byte = data[i++];
size_t count = 0; unsigned char count = data[i++];
while (i < size && isdigit(data[i])) {
count = count * 10 + (data[i++] - '0');
}
for (size_t j = 0; j < count; j++) { for (size_t j = 0; j < count; j++) {
if (write_idx >= size * 255) {
size_t new_size = write_idx * 2;
unsigned char* new_buffer = realloc(decompressed, new_size);
if (!new_buffer) {
free(decompressed);
free(data);
return -1;
}
decompressed = new_buffer;
}
decompressed[write_idx++] = byte; decompressed[write_idx++] = byte;
} }
} }
@ -95,9 +88,8 @@ int decompress_1(const char* input_file_name, const char* output_file_name) {
free(data); free(data);
free(decompressed); free(decompressed);
return result == 0 ? (int)write_idx : -1; return result == 0 ? 0 : -1;
} }
// LZ78 // LZ78
int compress_2(const char* input_file_name, const char* output_file_name) { int compress_2(const char* input_file_name, const char* output_file_name) {
unsigned char* data; unsigned char* data;