no message

This commit is contained in:
SilicaAndPina 2020-10-17 15:43:09 +13:00
parent 318cd09f5a
commit 9bea79554f
2 changed files with 725 additions and 0 deletions

691
CHOVY-KIRK/tlzrc.c Normal file
View File

@ -0,0 +1,691 @@
// Copyright (C) 2013 tpu
// Copyright (C) 2015 Hykem <hykem@hotmail.com>
// Licensed under the terms of the GNU GPL, version 3
// http://www.gnu.org/licenses/gpl-3.0.txt
#include "tlzrc.h"
static u8 text_buf[65536];
static int t_start, t_end, t_fill, sp_fill;
static int t_len, t_pos;
static int prev[65536], next[65536];
static int root[65536];
/*
LZRC decoder
*/
static u8 rc_getbyte(LZRC_DECODE *rc)
{
if (rc->in_ptr == rc->in_len) {
printf("End of input!\n");
exit(-1);
}
return rc->input[rc->in_ptr++];
}
static void rc_putbyte(LZRC_DECODE *rc, u8 byte)
{
if (rc->out_ptr == rc->out_len) {
printf("Output overflow!\n");
exit(-1);
}
rc->output[rc->out_ptr++] = byte;
}
static void rc_init(LZRC_DECODE *rc, void *out, int out_len, void *in, int in_len)
{
rc->input = in;
rc->in_len = in_len;
rc->in_ptr = 0;
rc->output = out;
rc->out_len = out_len;
rc->out_ptr = 0;
rc->range = 0xffffffff;
rc->lc = rc_getbyte(rc);
rc->code = (rc_getbyte(rc)<<24) |
(rc_getbyte(rc)<<16) |
(rc_getbyte(rc)<< 8) |
(rc_getbyte(rc)<< 0) ;
rc->out_code = 0xffffffff;
memset(rc->bm_literal, 0x80, 2048);
memset(rc->bm_dist_bits, 0x80, 312);
memset(rc->bm_dist, 0x80, 144);
memset(rc->bm_match, 0x80, 64);
memset(rc->bm_len, 0x80, 248);
}
static void normalize(LZRC_DECODE *rc)
{
if (rc->range < 0x01000000) {
rc->range <<= 8;
rc->code = (rc->code << 8) + rc->input[rc->in_ptr];
rc->in_ptr++;
}
}
static int rc_bit(LZRC_DECODE *rc, u8 *prob)
{
u32 bound;
normalize(rc);
bound = (rc->range >> 8) * (*prob);
*prob -= *prob >> 3;
if (rc->code < bound) {
rc->range = bound;
*prob += 31;
return 1;
} else {
rc->code -= bound;
rc->range -= bound;
return 0;
}
}
static int rc_bittree(LZRC_DECODE *rc, u8 *probs, int limit)
{
int number = 1;
do {
number = (number << 1) + rc_bit(rc, probs + number);
} while(number < limit);
return number;
}
static int rc_number(LZRC_DECODE *rc, u8 *prob, int n)
{
int i, number = 1;
if (n > 3) {
number = (number << 1) + rc_bit(rc, prob + 3);
if (n > 4) {
number = (number << 1) + rc_bit(rc, prob + 3);
if (n > 5) {
normalize(rc);
for (i = 0; i < n - 5; i++)
{
rc->range >>= 1;
number <<= 1;
if (rc->code < rc->range) {
number += 1;
} else {
rc->code -= rc->range;
}
}
}
}
}
if (n > 0) {
number = (number << 1) + rc_bit(rc, prob);
if (n > 1) {
number = (number << 1) + rc_bit(rc, prob + 1);
if(n > 2) {
number = (number << 1) + rc_bit(rc, prob + 2);
}
}
}
return number;
}
__declspec(dllexport) int lzrc_decompress(void *out, int out_len, void *in, int in_len)
{
LZRC_DECODE rc;
int match_step, rc_state, len_state, dist_state;
int i, bit, byte, last_byte;
int match_len, len_bits;
int match_dist, dist_bits, limit;
u8 *match_src;
int round = -1;
rc_init(&rc, out, out_len, in, in_len);
if (rc.lc & 0x80) {
memcpy(rc.output, rc.input + 5, rc.code);
return rc.code;
}
rc_state = 0;
last_byte = 0;
while (1)
{
round += 1;
match_step = 0;
bit = rc_bit(&rc, &rc.bm_match[rc_state][match_step]);
if (bit == 0)
{
if (rc_state > 0)
rc_state -= 1;
byte = rc_bittree(&rc, &rc.bm_literal[((last_byte >> rc.lc) & 0x07)][0], 0x100);
byte -= 0x100;
rc_putbyte(&rc, byte);
}
else
{
len_bits = 0;
for (i = 0; i < 7; i++)
{
match_step += 1;
bit = rc_bit(&rc, &rc.bm_match[rc_state][match_step]);
if (bit == 0)
break;
len_bits += 1;
}
if(len_bits == 0) {
match_len = 1;
} else {
len_state = ((len_bits - 1) << 2) + ((rc.out_ptr << (len_bits - 1)) & 0x03);
match_len = rc_number(&rc, &rc.bm_len[rc_state][len_state], len_bits);
if (match_len == 0xFF) {
return rc.out_ptr;
}
}
dist_state = 0;
limit = 8;
if (match_len > 2) {
dist_state += 7;
limit = 44;
}
dist_bits = rc_bittree(&rc, &rc.bm_dist_bits[len_bits][dist_state], limit);
dist_bits -= limit;
if (dist_bits > 0) {
match_dist = rc_number(&rc, &rc.bm_dist[dist_bits][0], dist_bits);
} else {
match_dist = 1;
}
if (match_dist > rc.out_ptr || match_dist < 0) {
printf("match_dist out of range! %08x\n", match_dist);
return -1;
}
match_src = rc.output + rc.out_ptr - match_dist;
for (i = 0; i < match_len + 1; i++) {
rc_putbyte(&rc, *match_src++);
}
rc_state = 6 + ((rc.out_ptr + 1) & 1);
}
last_byte = rc.output[rc.out_ptr - 1];
}
}
/*
LZRC encoder
*/
static u8 re_getbyte(LZRC_DECODE *re)
{
if (re->in_ptr == re->in_len) {
printf("End of input!\n");
exit(-1);
}
return re->input[re->in_ptr++];
}
static void re_putbyte(LZRC_DECODE *re, u8 byte)
{
if (re->out_ptr == re->out_len) {
printf("Output overflow!\n");
exit(-1);
}
re->output[re->out_ptr++] = byte;
}
static void re_init(LZRC_DECODE *re, void *out, int out_len, void *in, int in_len)
{
re->input = in;
re->in_len = in_len;
re->in_ptr = 0;
re->output = out;
re->out_len = out_len;
re->out_ptr = 0;
re->range = 0xffffffff;
re->code = 0x00000000;
re->lc = 5;
re->out_code = 0xffffffff;
re_putbyte(re, re->lc);
memset(re->bm_literal, 0x80, 2048);
memset(re->bm_dist_bits, 0x80, 312);
memset(re->bm_dist, 0x80, 144);
memset(re->bm_match, 0x80, 64);
memset(re->bm_len, 0x80, 248);
}
static void re_flush(LZRC_DECODE *re)
{
re_putbyte(re, (re->out_code) & 0xff);
re_putbyte(re, (re->code >> 24) & 0xff);
re_putbyte(re, (re->code >> 16) & 0xff);
re_putbyte(re, (re->code >> 8) & 0xff);
re_putbyte(re, (re->code >> 0) & 0xff);
}
static void re_normalize(LZRC_DECODE *re)
{
if (re->range < 0x01000000) {
if (re->out_code != 0xffffffff) {
if (re->out_code > 255)
{
int p, old_c;
p = re->out_ptr - 1;
do {
old_c = re->output[p];
re->output[p] += 1;
p -= 1;
} while (old_c == 0xff);
}
re_putbyte(re, re->out_code & 0xff);
}
re->out_code = (re->code >> 24) & 0xff;
re->range <<= 8;
re->code <<= 8;
}
}
static void re_bit(LZRC_DECODE *re, u8 *prob, int bit)
{
u32 bound;
u32 old_r, old_c;
u8 old_p;
re_normalize(re);
old_r = re->range;
old_c = re->code;
old_p = *prob;
bound = (re->range >> 8) * (*prob);
*prob -= *prob >> 3;
if (bit) {
re->range = bound;
*prob += 31;
} else {
re->code += bound;
if (re->code < old_c)
re->out_code += 1;
re->range -= bound;
}
}
static void re_bittree(LZRC_DECODE *re, u8 *probs, int limit, int number)
{
int n, tmp, bit;
number += limit;
tmp = number;
n = 0;
while (tmp > 1) {
tmp >>= 1;
n++;
}
do {
tmp = number >> n;
bit = (number >> (n - 1)) & 1;
re_bit(re, probs + tmp, bit);
n -= 1;
} while (n);
}
static void re_number(LZRC_DECODE *re, u8 *prob, int n, int number)
{
int i;
u32 old_c;
i = 1;
if (n > 3) {
re_bit(re, prob + 3, (number >> (n - i)) & 1);
i += 1;
if (n > 4) {
re_bit(re, prob + 3, (number >> (n - i)) & 1);
i += 1;
if (n > 5) {
re_normalize(re);
for (i = 3; i < n - 2; i++) {
re->range >>= 1;
if (((number >> (n - i)) & 1) == 0) {
old_c = re->code;
re->code += re->range;
if (re->code < old_c)
re->out_code += 1;
}
}
}
}
}
if (n > 0) {
re_bit(re, prob + 0, (number >> (n - i - 0)) & 1);
if (n > 1) {
re_bit(re, prob + 1, (number >> (n - i - 1)) & 1);
if (n > 2) {
re_bit(re, prob + 2, (number >> (n - i - 2)) & 1);
}
}
}
}
static void init_tree(void)
{
int i;
for (i = 0; i < 65536; i++)
{
root[i] = -1;
prev[i] = -1;
next[i] = -1;
}
t_start = 0;
t_end = 0;
t_fill = 0;
sp_fill = 0;
}
static void remove_node(LZRC_DECODE *re, int p)
{
int t, q;
if (prev[p] == -1)
return;
t = text_buf[p + 0];
t = (t << 8) | text_buf[p + 1];
q = next[p];
if (q != -1)
prev[q] = prev[p];
if (prev[p] == -2)
root[t] = q;
else
next[prev[p]] = q;
prev[p] = -1;
next[p] = -1;
}
static int insert_node(LZRC_DECODE *re, int pos, int *match_len, int *match_dist, int do_cmp)
{
u8 *src, *win;
int i, t, p;
int content_size;
src = text_buf + pos;
win = text_buf + t_start;
content_size = (t_fill < pos) ? (65280 + t_fill - pos) : (t_fill - pos);
t_len = 1;
t_pos = 0;
*match_len = t_len;
*match_dist = t_pos;
if (re->in_ptr == re->in_len) {
*match_len = 256;
return 0;
}
if (re->in_ptr == (re->in_len - 1))
return 0;
t = src[0];
t = (t << 8) | src[1];
if (root[t] == -1)
{
root[t] = pos;
prev[pos] = -2;
next[pos] = -1;
return 0;
}
p = root[t];
root[t] = pos;
prev[pos] = -2;
next[pos] = p;
if (p != -1)
prev[p] = pos;
while (do_cmp == 1 && p != -1)
{
for (i = 0; (i < 255 && i < content_size); i++) {
if (src[i] != text_buf[p + i])
break;
}
if (i > t_len) {
t_len = i;
t_pos = pos - p;
} else if (i == t_len) {
int mp = pos - p;
if (mp < 0)
mp += 65280;
if (mp < t_pos) {
t_len = i;
t_pos = pos-p;
}
}
if (i == 255) {
remove_node(re, p);
break;
}
p = next[p];
}
*match_len = t_len;
*match_dist = t_pos;
return 1;
}
static void fill_buffer(LZRC_DECODE *re)
{
int content_size, back_size, front_size;
if (sp_fill == re->in_len)
return;
content_size = (t_fill < t_end) ? (65280 + t_fill - t_end) : (t_fill - t_end);
if (content_size >= 509)
return;
if (t_fill < t_start) {
back_size = t_start - t_fill - 1;
if (sp_fill + back_size > re->in_len)
back_size = re->in_len - sp_fill;
memcpy(text_buf + t_fill, re->input + sp_fill, back_size);
sp_fill += back_size;
t_fill += back_size;
} else {
back_size = 65280 - t_fill;
if (t_start == 0)
back_size -= 1;
if (sp_fill + back_size > re->in_len)
back_size = re->in_len - sp_fill;
memcpy(text_buf + t_fill, re->input + sp_fill, back_size);
sp_fill += back_size;
t_fill += back_size;
front_size = t_start;
if (t_start != 0)
front_size -= 1;
if (sp_fill + front_size > re->in_len)
front_size = re->in_len - sp_fill;
memcpy(text_buf, re->input + sp_fill, front_size);
sp_fill += front_size;
memcpy(text_buf + 65280, text_buf, 255);
t_fill += front_size;
if (t_fill >= 65280)
t_fill -= 65280;
}
}
static void update_tree(LZRC_DECODE *re, int length)
{
int i, win_size;
int tmp_len, tmp_pos;
win_size = (t_end >= t_start) ? (t_end - t_start) : (65280 + t_end - t_start);
for (i = 0; i < length; i++)
{
if (win_size == 16384) {
remove_node(re, t_start);
t_start += 1;
if (t_start == 65280)
t_start = 0;
} else {
win_size += 1;
}
if (i > 0) {
insert_node(re, t_end, &tmp_len, &tmp_pos, 0);
}
t_end += 1;
if (t_end >= 65280)
t_end -= 65280;
}
}
static void re_find_match(LZRC_DECODE *re, int *match_len, int *match_dist)
{
int cp, win_p, i, j;
u8 *pbuf, *cbuf;
cp = re->in_ptr;
if (cp == re->in_len) {
*match_len = 256;
return;
} else {
*match_len = 1;
}
win_p = (cp < 16384) ? cp : 16384;
for (i = 1; i <= win_p; i++) {
j = 0;
cbuf = re->input + cp;
pbuf = cbuf - i;
while ((j < 255) && (cp + j < re->in_len) && (pbuf[j] == cbuf[j]))
j += 1;
if (j >= 2 && *match_len < j) {
*match_len = j;
*match_dist = i;
}
}
}
__declspec(dllexport) int lzrc_compress(void *out, int out_len, void *in, int in_len)
{
LZRC_DECODE re;
int match_step, re_state, len_state, dist_state;
int i, byte, last_byte;
int match_len, len_bits;
int match_dist, dist_bits, limit;
int round = -1;
re_init(&re, out, out_len, in, in_len);
init_tree();
re_state = 0;
last_byte = 0;
match_len = 0;
match_dist = 0;
while (1)
{
round += 1;
match_step = 0;
fill_buffer(&re);
insert_node(&re, t_end, &match_len, &match_dist, 1);
if (match_len < 256) {
if (match_len < 4 && match_dist > 255)
match_len = 1;
update_tree(&re, match_len);
}
if (match_len == 1 || (match_len < 4 && match_dist > 255))
{
re_bit(&re, &re.bm_match[re_state][match_step], 0);
if (re_state > 0)
re_state -= 1;
byte = re_getbyte(&re);
re_bittree(&re, &re.bm_literal[((last_byte >> re.lc) & 0x07)][0], 0x100, byte);
} else {
re_bit(&re, &re.bm_match[re_state][match_step], 1);
len_bits = 0;
for (i = 1; i < 8; i++) {
match_step += 1;
if ((match_len - 1) < (1 << i))
break;
re_bit(&re, &re.bm_match[re_state][match_step], 1);
len_bits += 1;
}
if (i != 8) {
re_bit(&re, &re.bm_match[re_state][match_step], 0);
}
if (len_bits > 0) {
len_state = ((len_bits - 1) << 2) + ((re.in_ptr << (len_bits - 1)) & 0x03);
re_number(&re, &re.bm_len[re_state][len_state], len_bits, (match_len - 1));
if (match_len == 0x100) {
re_normalize(&re);
re_flush(&re);
return re.out_ptr;
}
}
dist_state = 0;
limit = 8;
if (match_len > 3) {
dist_state += 7;
limit = 44;
}
dist_bits = 0;
while ((match_dist >> dist_bits) !=1 ) {
dist_bits += 1;
}
re_bittree(&re, &re.bm_dist_bits[len_bits][dist_state], limit, dist_bits);
if (dist_bits > 0) {
re_number(&re, &re.bm_dist[dist_bits][0], dist_bits, match_dist);
}
re.in_ptr += match_len;
re_state = 6 + ((re.in_ptr + 1) & 1);
}
last_byte = re.input[re.in_ptr - 1];
}
}

34
CHOVY-KIRK/tlzrc.h Normal file
View File

@ -0,0 +1,34 @@
// Copyright (C) 2013 tpu
// Copyright (C) 2015 Hykem <hykem@hotmail.com>
// Licensed under the terms of the GNU GPL, version 3
// http://www.gnu.org/licenses/gpl-3.0.txt
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#include "utils.h"
typedef struct {
u8 *input;
int in_ptr;
int in_len;
u8 *output;
int out_ptr;
int out_len;
u32 range;
u32 code;
u32 out_code;
u8 lc;
u8 bm_literal[8][256];
u8 bm_dist_bits[8][39];
u8 bm_dist[18][8];
u8 bm_match[8][8];
u8 bm_len[8][31];
} LZRC_DECODE;
__declspec(dllexport) int lzrc_compress(void *out, int out_len, void *in, int in_len);
__declspec(dllexport) int lzrc_decompress(void *out, int out_len, void *in, int in_len);