(lz) Progress

This commit is contained in:
neauoire 2023-11-18 19:34:58 -08:00
parent 0f9b7986c9
commit 59acd90b04
2 changed files with 38 additions and 48 deletions

View File

@ -22,23 +22,24 @@ uxn_lz_compress(const void *input, int input_size)
const unsigned char *dict, *dict_best = 0; const unsigned char *dict, *dict_best = 0;
const unsigned char *in = input, *start = in, *end = in + input_size; const unsigned char *in = input, *start = in, *end = in + input_size;
while(in != end) { while(in != end) {
/* Get available dictionary size (history of original output) */ /* Get available dictionary size (history of original output) */
dict_len = (int)(in - start); dict_len = (int)(in - start);
if(dict_len > 256) if(dict_len > 256)
dict_len = 256; dict_len = 256;
/* Size of the string to search for */ /* Size of the string to search for */
/* Limit string length to what we can fit in 14 bits, plus the minimum match length */ /* Limit string length to what we can fit in 14 bits, plus the minimum match length */
string_len = (int)(end - in); string_len = (int)(end - in);
if(string_len > 0x3FFF + MinMatchLength) if(string_len > 0x3FFF + MinMatchLength)
string_len = 0x3FFF + MinMatchLength; string_len = 0x3FFF + MinMatchLength;
/* DEBUG: printf("%04x %04x \n", dict_len, string_len); */
printf("DEBUG1: %04x %04x ", dict_len, string_len);
/* Iterate through the dictionary */ /* Iterate through the dictionary */
match_len = 0; match_len = 0;
dict = in - dict_len; dict = in - dict_len;
for(; dict_len; dict++, dict_len -= 1) {
printf("[%c]", in[0]);
for(; dict_len; dict++, dict_len--) {
/* Find common prefix length with the string */ /* Find common prefix length with the string */
/* If we reach the end of the string, this is the best possible match. End. */ /* If we reach the end of the string, this is the best possible match. End. */
for(i = 0;; i++) { for(i = 0;; i++) {
@ -48,17 +49,23 @@ uxn_lz_compress(const void *input, int input_size)
goto done_search; goto done_search;
} }
/* Dictionary repeats if we hit the end */ /* Dictionary repeats if we hit the end */
if(in[i] != dict[i % dict_len]) /* printf("(#%d, %04x, %c, %c)", i, in-raw, in[i], dict[i % dict_len]); */
if(in[i] != dict[i % dict_len]){
break; break;
} }
}
if(i > match_len) { if(i > match_len) {
match_len = i; match_len = i;
dict_best = dict; dict_best = dict;
} }
} }
done_search: done_search:
printf("-> %04x \n", match_len);
/* CPY */ /* CPY */
if(match_len >= MinMatchLength) { if(match_len >= MinMatchLength) {
@ -75,11 +82,12 @@ uxn_lz_compress(const void *input, int input_size)
*output_ptr++ = in - dict_best - 1; *output_ptr++ = in - dict_best - 1;
in += match_len; /* Advance input by size of the match */ in += match_len; /* Advance input by size of the match */
combine = 0; /* Disable combining previous literal, if any */ combine = 0; /* Disable combining previous literal, if any */
continue;
} }
/* LIT */ /* LIT */
else{
/* printf("LIT:%d\n", combine); */
/* Combine with previous literal */ /* Combine with previous literal */
if(combine) { if(combine) {
if(++*combine == 127) if(++*combine == 127)
@ -92,9 +100,13 @@ uxn_lz_compress(const void *input, int input_size)
/* The 0 here means literal of length 1. */ /* The 0 here means literal of length 1. */
*combine = 0; *combine = 0;
} }
/* Write 1 literal byte from the input to the output. */ /* Write 1 literal byte from the input to the output. */
*output_ptr++ = *in++; *output_ptr++ = *in++;
/* printf(">> %d\n", in-raw); */
} }
}
return (int)(output_ptr - mem); return (int)(output_ptr - mem);
} }

View File

@ -52,7 +52,7 @@
ADD2k NIP2 SWP2 ADD2k NIP2 SWP2
&w ( end* start* -- ) &w ( end* start* -- )
EQU2k ?&end
( | get available dictionary size ) ( | get available dictionary size )
DUP2 ;raw SUB2 #0100 LTH2k ?{ SWP2 } DUP2 ;raw SUB2 #0100 LTH2k ?{ SWP2 }
POP2 .dict-len STZ2 POP2 .dict-len STZ2
@ -71,6 +71,7 @@
LIT "[ #18 DEO LIT "[ #18 DEO
LDAk #18 DEO LDAk #18 DEO
LIT "] #18 DEO LIT "] #18 DEO
#0a18 DEO
&for1 ( for ; dict_len; dict++, dict_len-- ) &for1 ( for ; dict_len; dict++, dict_len-- )
.dict-len LDZ2 #0000 EQU2 ?&end-for1 .dict-len LDZ2 #0000 EQU2 ?&end-for1
@ -84,14 +85,6 @@
.dict LDZ2 .dict-best STZ2 .dict LDZ2 .dict-best STZ2
POP2 !&done-search } POP2 !&done-search }
( Dictionary repeats if we hit the end )
LIT "( #18 DEO
DUP phex/b #2018 DEO
OVR2 ;raw SUB2 phex #2018 DEO
ADD2k LDA #18 DEO #2018 DEO
DUP2 .dict-len LDZ2 DIV2k MUL2 SUB2 .dict LDZ2 ADD2 LDA #18 DEO
LIT ") #18 DEO #0a18 DEO
( in[i] != dict[i % dict_len] break; ) ( in[i] != dict[i % dict_len] break; )
( a ) ADD2k LDA STH ( a ) ADD2k LDA STH
( b ) DUP2 .dict-len LDZ2 DIV2k MUL2 SUB2 .dict LDZ2 ADD2 LDA STHr ( b ) DUP2 .dict-len LDZ2 DIV2k MUL2 SUB2 .dict LDZ2 ADD2 LDA STHr
@ -107,27 +100,12 @@
.dict LDZ2 INC2 .dict STZ2 .dict LDZ2 INC2 .dict STZ2
.dict-len LDZ2 #0001 SUB2 .dict-len STZ2 !&for1 .dict-len LDZ2 #0001 SUB2 .dict-len STZ2 !&for1
&end-for1 &end-for1
&done-search ( -- ) &done-search ( -- )
LIT "- #18 DEO
.match-len LDZ2 phex #0a18 DEO
( [ LIT &break $1 ] INCk ,&break STR #03 NEQ ?{ BREAK } )
( CPY ) .match-len LDZ2 #0003 GTH2 ?op-cpy ( CPY ) .match-len LDZ2 #0003 GTH2 ?op-cpy
( LIT ) op-lit ( LIT ) !op-lit
&end
LIT "> #18 DEO POP2 POP2 JMP2r
DUP2 ;raw SUB2 phex #0a18 DEO
#010f DEO BRK
NEQ2k ?&w
JMP2r
( (