// Copyright 2007 Ian Elliot
//
// This file is part of Shoelacer.
//
// Shoelacer is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 3 of the License, or
// (at your option) any later version.
//
// Shoelacer is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with Shoelacer. If not, see .
//
// ALTHOUGH this specific file is licensed, the output of Shoelacer
// which may or may not include text very similar to this file is in
// no way restricted, guarenteed, or licensed.
//
// File begins after the first carrot: ^
static unsigned char lz[]={
// 0 1 2 3 4 5 6 7 8 9 A B C D E F
/*0*/ 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4,
/*1*/ 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
/*2*/ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
/*3*/ 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
/*4*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
/*5*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
/*6*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
/*7*/ 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
/*8*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/*9*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/*A*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/*B*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/*C*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/*D*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/*E*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
/*F*/ 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
};
unsigned int shoelacer_encode(SHOELACER_MODEL* model,unsigned char* text,unsigned char* code,unsigned int textLen,unsigned int codeMax) {
unsigned int reg=0;
unsigned short int index;
unsigned char sh=0;
unsigned char c,rl,vl,v,t,a,s,i,u,ls,n=1,f;
unsigned short int d;
unsigned char* codeLim=code+codeMax;
unsigned char* textLim=text+textLen;
index=model->init_index;
encode_start:
if (text==textLim) goto encode_textlim;
c=*text++;
s=c;
i=0;
vl=model->data[index]; // Rice coding
u=model->data[index+2];
do {
if (s==model->data[index+3+i]) break;
i++;
} while (idata[index+1]);
if (i>=model->data[index+1] || i==u) {
// Encode the symbol as an unaccounted value
c=u;
f=1;
} else {
c=i;
f=0;
}
rl=c>>vl;
v=c&((1<=8) {
rl-=8;
reg<<=8;
if (code==codeLim) goto encode_end;
*code++=reg>>sh;
}
t=rl+1;
sh+=t;
reg<<=t;
reg|=1;
if (sh>=8) {
if (code==codeLim) goto encode_end;
sh-=8;
*code++=(unsigned char)(reg>>sh);
}
reg<<=vl;
reg|=v;
sh+=vl;
if (sh>=8) {
sh-=8;
if (code==codeLim) goto encode_end;
*code++=reg>>sh;
}
if (f) {
reg<<=8;
reg|=s;
if (code==codeLim) goto encode_end;
*code++=reg>>sh;
}
if (n) n=0; else {
a=ls+s;
d=ls^model->hash[a];
ls=model->data[d];
if ((a&((1<<(8-DIST_BITS))-1)) == (ls>>DIST_BITS)) index=model->index[ls&((1<init_index;
}
ls=s;
goto encode_start;
encode_end:
return codeMax;
encode_textlim:
if (sh>8) {
if (code==codeLim) goto encode_end;
sh-=8;
*code++=reg>>sh;
}
if (sh) {
if (code==codeLim) goto encode_end;
*code++=reg<<(8-sh);
}
return codeMax-(codeLim-code);
}
unsigned int shoelacer_decode(SHOELACER_MODEL* model,unsigned char* text,unsigned char* code,unsigned int textMax,unsigned int codeLen) {
unsigned short int d,reg=0;
unsigned char sh=0;
unsigned char c,vl,v,l,rl,t,n=1,lv;
unsigned char* tLim=text+textMax;
unsigned char* cLim=code+codeLen;
unsigned short int index=model->init_index;
decode_start:
if (sh<8)
if (code!=cLim) {
sh+=8;
reg<<=8; reg|=*code++;
c=reg>>(sh-8);
} else
if (reg&((1<>(sh-8);
rl=0;
while (!c)
if (code!=cLim) {
rl+=8;
reg<<=8; reg|=*code++;
c=reg>>(sh-8);
} else if (reg&((1<data[index];
if (sh<8)
if (code!=cLim) {
sh+=8;
reg<<=8; reg|=*code++;
v=(reg>>(sh-8));
} else {
v=reg<<=8-sh;
sh=8;
}
else
v=(reg>>(sh-8));
sh-=vl;
v>>=8-vl;
v|=rl<data[index+2]) { // If it's an unaccounted value
if (sh<8)
if (code!=cLim) {
sh+=8;
reg<<=8; reg|=*code++;
v=(reg>>(sh-8));
} else {
v=reg<<=(8-sh);
sh=8;
}
else
v=reg>>(sh-8);
*text++=v;
if (code!=cLim) {
reg<<=8; reg|=*code++;
c=reg>>(sh-8);
} else if (reg&((1<data[index+3+v];
*text++=v;
}
if (n) n=0; else {
rl=lv+v;
d=lv^model->hash[rl];
vl=model->data[d];
if ((rl&((1<<(8-DIST_BITS))-1)) == (vl>>DIST_BITS)) { index=model->index[vl&((1<init_index;
}
lv=v;
if (text==tLim) return textMax;
goto decode_start;
decode_end:
return textMax-(tLim-text);
}