diff options
author | Rangi <35663410+Rangi42@users.noreply.github.com> | 2020-06-14 17:49:36 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-06-14 17:49:36 -0400 |
commit | 7f6bc3d3826fe7727bdc8714aa0295a712a548c3 (patch) | |
tree | aca0979818b88f0e27f18b95d87a006767cf89fb /tools/lz/main.c | |
parent | dd97bedd52f97122c0d4a06eb30c0b571ddda343 (diff) | |
parent | 0e5edf03ff4ba5ad0c6740eefd0e28ae5eca10c4 (diff) |
Merge pull request #50 from entrpntr/pics2
Switch to building binary pic files from pngs
Diffstat (limited to 'tools/lz/main.c')
-rw-r--r-- | tools/lz/main.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/tools/lz/main.c b/tools/lz/main.c new file mode 100644 index 00000000..62e6dc41 --- /dev/null +++ b/tools/lz/main.c @@ -0,0 +1,54 @@ +#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; +} |