blob: 46c69ef893e11f62605bb9e4d47913e1f951c72f [file] [log] [blame]
// This is free and unencumbered software released into the public domain.
//
// Anyone is free to copy, modify, publish, use, compile, sell, or
// distribute this software, either in source code form or as a compiled
// binary, for any purpose, commercial or non-commercial, and by any
// means.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
FILE *input_file;
FILE *output_file;
int read_bitcounter;
int read_buffer;
int write_bitcounter;
int write_buffer;
static int read_bit()
{
if (read_bitcounter == 0) {
read_bitcounter = 8;
read_buffer = fgetc(input_file);
}
read_bitcounter--;
return (read_buffer >> read_bitcounter) & 1;
}
static void write_bit(int value)
{
write_bitcounter--;
if (value)
write_buffer |= 1 << write_bitcounter;
if (write_bitcounter == 0) {
fputc(write_buffer, output_file);
write_bitcounter = 8;
write_buffer = 0;
}
}
static int read_int(int bits)
{
int ret = 0;
while (bits-- > 0)
if (read_bit())
ret |= 1 << bits;
return ret;
}
static void write_zeros(int bits)
{
while (bits-- > 0)
write_bit(0);
}
int ice_uncompress()
{
read_bitcounter = 0;
read_buffer = 0;
write_bitcounter = 8;
write_buffer = 0;
int magic1_ok = read_int(32) == 0x49434543;
int magic2_ok = read_int(32) == 0x4f4d5052;
if (!magic1_ok || !magic2_ok) {
fprintf(stderr, "Missing ICECOMPR magic. Abort!\n");
return 1;
}
while (1)
{
if (read_bit()) {
write_zeros(read_int(2));
write_bit(1);
} else
if (read_bit()) {
write_zeros(read_int(5));
write_bit(1);
} else
if (read_bit()) {
write_zeros(read_int(8));
write_bit(1);
} else
if (read_bit()) {
int n = read_int(6);
while (n--)
write_bit(read_bit());
write_bit(1);
} else
if (read_bit()) {
write_zeros(read_int(23));
write_bit(1);
} else {
write_zeros(read_int(23));
break;
}
}
return 0;
}
void help()
{
printf("\n");
printf("Usage: iceuncompr [input-file [output-file]]\n");
printf("\n");
exit(1);
}
int main(int argc, char **argv)
{
input_file = stdin;
output_file = stdout;
int opt;
while ((opt = getopt(argc, argv, "v")) != -1)
{
switch (opt)
{
case 'v':
break;
default:
help();
}
}
if (optind < argc) {
input_file = fopen(argv[optind], "rb");
if (input_file == NULL) {
fprintf(stderr, "Failed to open input file `%s': %s\n", argv[optind], strerror(errno));
return 1;
}
optind++;
}
if (optind < argc) {
output_file = fopen(argv[optind], "wb");
if (output_file == NULL) {
fprintf(stderr, "Failed to open output file `%s': %s\n", argv[optind], strerror(errno));
return 1;
}
optind++;
}
if (optind != argc)
help();
if (optind != argc)
help();
return ice_uncompress();
}