#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define WINDOW_SIZE 1024 // 10-bit sliding window (2^10 = 1024)
#define MAX_LENGTH 15 // 4-bit length (2^4 - 1 = 15)
#define MIN_MATCH 3 // Minimum match length to encode as a pair
#define WINDOW_SIZE_N_BITS 10 // 10-bit sliding window
#define MAX_LENGTH_N_BITS 4 // 4-bit length
#define size_t unsigned int
#define uint8_t unsigned char
#define uint32_t unsigned int
uint8_t dict[WINDOW_SIZE+MAX_LENGTH+MIN_MATCH];
int dict_pos = 0;
int get_bit(const unsigned char *buffer, size_t bit_position) {
size_t byte_index = bit_position / 8;
size_t bit_offset = bit_position % 8;
return (buffer[byte_index] >> (7 - bit_offset)) & 0x01;
}
void set_bit(uint8_t *buffer, size_t bit_position, int value) {
size_t byte_index = bit_position / 8;
size_t bit_offset = bit_position % 8;
if (value) {
buffer[byte_index] |= (1 << (7 - bit_offset));
} else {
buffer[byte_index] &= ~(1 << (7 - bit_offset));
}
}
void lzss_decompress(const unsigned char *input, int input_size, unsigned char *output, int *output_size) {
int input_pos = 0;
int output_pos = 0;
uint8_t offset[2] = {0};
uint8_t length = 0;
uint8_t flag = 0;
while (input_pos < (input_size*8) ) {
// Read flag bit
flag = get_bit(input,input_pos++);
if (flag == 1) {
// Literal: read the next 8 bits
for (int i = 0; i < 8; i++) {
set_bit(output,output_pos++,get_bit(input,input_pos++));
}
dict[dict_pos++] = output[(output_pos-1)/8];
} else {
// Pair: read 10-bit offset and 4-bit length
for (int i = 0; i < WINDOW_SIZE_N_BITS; i++) {
set_bit(offset,i,get_bit(input,input_pos++));
}
for (int i = 0; i < MAX_LENGTH_N_BITS; i++) {
set_bit(&length,i,get_bit(input,input_pos++));
}
length +=2;
for (int i = 0; i < length; i++) {
output[(output_pos-1)/8] = dict[dict_pos-(unsigned int)offset[0]+i];
output_pos += 8;
dict[dict_pos++] = output[(output_pos-1)/8];
}
}
}
// *output_size = output_pos;
}
int main() {
// Write C code here
int size_out = 50;
unsigned char Buf_Out[1024]={0};
unsigned char Buf_in[1024]={0xFF,0x80,0x11,0xE2,0xC0,0x40,0x30,0x41,0xA0,0x11,0x29,0xA5,0x58,0x00,0x00};
lzss_decompress(Buf_in,15,Buf_Out,&size_out);
for (int i = 0; i < 20; i++) {
printf("%x ", Buf_Out[i]);
}
return 0;
}
I2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgoKI2RlZmluZSBXSU5ET1dfU0laRSAxMDI0ICAvLyAxMC1iaXQgc2xpZGluZyB3aW5kb3cgKDJeMTAgPSAxMDI0KQojZGVmaW5lIE1BWF9MRU5HVEggMTUgICAgIC8vIDQtYml0IGxlbmd0aCAoMl40IC0gMSA9IDE1KQojZGVmaW5lIE1JTl9NQVRDSCAzICAgICAgIC8vIE1pbmltdW0gbWF0Y2ggbGVuZ3RoIHRvIGVuY29kZSBhcyBhIHBhaXIKCiNkZWZpbmUgV0lORE9XX1NJWkVfTl9CSVRTIDEwICAvLyAxMC1iaXQgc2xpZGluZyB3aW5kb3cgCiNkZWZpbmUgTUFYX0xFTkdUSF9OX0JJVFMgNCAgICAgLy8gNC1iaXQgbGVuZ3RoIAoKI2RlZmluZSBzaXplX3QgdW5zaWduZWQgaW50CiNkZWZpbmUgdWludDhfdCB1bnNpZ25lZCBjaGFyCiNkZWZpbmUgdWludDMyX3QgdW5zaWduZWQgaW50Cgp1aW50OF90IGRpY3RbV0lORE9XX1NJWkUrTUFYX0xFTkdUSCtNSU5fTUFUQ0hdOwppbnQgZGljdF9wb3MgPSAwOwoKaW50IGdldF9iaXQoY29uc3QgdW5zaWduZWQgY2hhciAqYnVmZmVyLCBzaXplX3QgYml0X3Bvc2l0aW9uKSB7CiAgICBzaXplX3QgYnl0ZV9pbmRleCA9IGJpdF9wb3NpdGlvbiAvIDg7CiAgICBzaXplX3QgYml0X29mZnNldCA9IGJpdF9wb3NpdGlvbiAlIDg7CiAgICByZXR1cm4gKGJ1ZmZlcltieXRlX2luZGV4XSA+PiAoNyAtIGJpdF9vZmZzZXQpKSAmIDB4MDE7Cn0KCnZvaWQgc2V0X2JpdCh1aW50OF90ICpidWZmZXIsIHNpemVfdCBiaXRfcG9zaXRpb24sIGludCB2YWx1ZSkgewogICAgc2l6ZV90IGJ5dGVfaW5kZXggPSBiaXRfcG9zaXRpb24gLyA4OwogICAgc2l6ZV90IGJpdF9vZmZzZXQgPSBiaXRfcG9zaXRpb24gJSA4OwogICAgaWYgKHZhbHVlKSB7CiAgICAgICAgYnVmZmVyW2J5dGVfaW5kZXhdIHw9ICgxIDw8ICg3IC0gYml0X29mZnNldCkpOwogICAgfSBlbHNlIHsKICAgICAgICBidWZmZXJbYnl0ZV9pbmRleF0gJj0gfigxIDw8ICg3IC0gYml0X29mZnNldCkpOwogICAgfQp9CnZvaWQgbHpzc19kZWNvbXByZXNzKGNvbnN0IHVuc2lnbmVkIGNoYXIgKmlucHV0LCBpbnQgaW5wdXRfc2l6ZSwgdW5zaWduZWQgY2hhciAqb3V0cHV0LCBpbnQgKm91dHB1dF9zaXplKSB7CiAgICBpbnQgaW5wdXRfcG9zID0gMDsKICAgIGludCBvdXRwdXRfcG9zID0gMDsKICAgIHVpbnQ4X3Qgb2Zmc2V0WzJdID0gezB9OwogICAgdWludDhfdCBsZW5ndGggPSAwOwogICAgdWludDhfdCBmbGFnID0gMDsKICAgIAogICAgd2hpbGUgKGlucHV0X3BvcyA8IChpbnB1dF9zaXplKjgpICkgewogICAgICAgIC8vIFJlYWQgZmxhZyBiaXQKICAgICAgICBmbGFnID0gZ2V0X2JpdChpbnB1dCxpbnB1dF9wb3MrKyk7CiAgICAgICAgaWYgKGZsYWcgPT0gMSkgewogICAgICAgICAgICAvLyBMaXRlcmFsOiByZWFkIHRoZSBuZXh0IDggYml0cwogICAgICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IDg7IGkrKykgewogICAgICAgICAgICAgICAgc2V0X2JpdChvdXRwdXQsb3V0cHV0X3BvcysrLGdldF9iaXQoaW5wdXQsaW5wdXRfcG9zKyspKTsKICAgICAgICAgICAgfQogICAgICAgICAgICBkaWN0W2RpY3RfcG9zKytdID0gb3V0cHV0WyhvdXRwdXRfcG9zLTEpLzhdOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIC8vIFBhaXI6IHJlYWQgMTAtYml0IG9mZnNldCBhbmQgNC1iaXQgbGVuZ3RoCiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgV0lORE9XX1NJWkVfTl9CSVRTOyBpKyspIHsKICAgICAgICAgICAgICAgIHNldF9iaXQob2Zmc2V0LGksZ2V0X2JpdChpbnB1dCxpbnB1dF9wb3MrKykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgTUFYX0xFTkdUSF9OX0JJVFM7IGkrKykgewogICAgICAgICAgICAgICAgc2V0X2JpdCgmbGVuZ3RoLGksZ2V0X2JpdChpbnB1dCxpbnB1dF9wb3MrKykpOwogICAgICAgICAgICB9CiAgICAgICAgICAgIGxlbmd0aCArPTI7CiAgICAgICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKICAgICAgICAgICAgICAgIG91dHB1dFsob3V0cHV0X3Bvcy0xKS84XSA9IGRpY3RbZGljdF9wb3MtKHVuc2lnbmVkIGludClvZmZzZXRbMF0raV07CiAgICAgICAgICAgICAgICBvdXRwdXRfcG9zICs9IDg7CiAgICAgICAgICAgICAgICBkaWN0W2RpY3RfcG9zKytdID0gb3V0cHV0WyhvdXRwdXRfcG9zLTEpLzhdOwogICAgICAgICAgICAgICAgCiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICB9CgogICAgLy8gKm91dHB1dF9zaXplID0gb3V0cHV0X3BvczsKfQoKaW50IG1haW4oKSB7CiAgICAvLyBXcml0ZSBDIGNvZGUgaGVyZQogICAgaW50IHNpemVfb3V0ID0gNTA7CiAgICB1bnNpZ25lZCBjaGFyIEJ1Zl9PdXRbMTAyNF09ezB9OwogICAgdW5zaWduZWQgY2hhciBCdWZfaW5bMTAyNF09ezB4RkYsMHg4MCwweDExLDB4RTIsMHhDMCwweDQwLDB4MzAsMHg0MSwweEEwLDB4MTEsMHgyOSwweEE1LDB4NTgsMHgwMCwweDAwfTsKICAgIGx6c3NfZGVjb21wcmVzcyhCdWZfaW4sMTUsQnVmX091dCwmc2l6ZV9vdXQpOwogICAgIGZvciAoaW50IGkgPSAwOyBpIDwgMjA7IGkrKykgewogICAgICAgIHByaW50ZigiJXggIiwgQnVmX091dFtpXSk7CiAgICB9CgogICAgcmV0dXJuIDA7Cn0=