pokecrystal-board/tools/lz/main.c
2020-05-24 12:29:05 -04:00

55 lines
2.3 KiB
C

#include "proto.h"
int main (int argc, char ** argv) {
struct options options = get_options(argc, argv);
unsigned short size;
unsigned char * file_buffer = read_file_into_buffer(options.input, &size);
struct command * commands;
if (options.mode & 2) {
unsigned short original_size = size, remainder;
commands = get_commands_from_file(file_buffer, &size, &remainder);
if (!commands) error_exit(1, "invalid command stream");
if (options.mode == 2) {
unsigned char * uncompressed = get_uncompressed_data(commands, file_buffer, &size);
if (!uncompressed) error_exit(1, "output data is too large");
write_raw_data_to_file(options.output, uncompressed, size);
free(uncompressed);
} else
write_commands_and_padding_to_textfile(options.output, commands, size, file_buffer, original_size - remainder, remainder);
} else {
commands = compress(file_buffer, &size, options.method);
(options.mode ? write_commands_to_textfile : write_commands_to_file)(options.output, commands, size, file_buffer, options.alignment);
}
free(file_buffer);
free(commands);
return 0;
}
struct command * compress (const unsigned char * data, unsigned short * size, unsigned method) {
unsigned char * bitflipped = malloc(*size);
unsigned current;
for (current = 0; current < *size; current ++) bitflipped[current] = bit_flipping_table[data[current]];
const struct compressor * compressor = compressors;
struct command * result;
if (method < COMPRESSION_METHODS) {
while (method >= compressor -> methods) method -= (compressor ++) -> methods;
result = compressor -> function(data, bitflipped, size, method);
} else {
struct command * compressed_sequences[COMPRESSION_METHODS];
unsigned short lengths[COMPRESSION_METHODS];
unsigned flags = 0;
for (current = 0; current < COMPRESSION_METHODS; current ++) {
lengths[current] = *size;
if (flags == compressor -> methods) {
flags = 0;
compressor ++;
}
compressed_sequences[current] = compressor -> function(data, bitflipped, lengths + current, flags ++);
}
result = select_optimal_sequence(compressed_sequences, lengths, size);
for (current = 0; current < COMPRESSION_METHODS; current ++) free(compressed_sequences[current]);
}
free(bitflipped);
return result;
}