125 lines
2.7 KiB
C
125 lines
2.7 KiB
C
#include <fonts.h>
|
|
#include <render.h>
|
|
|
|
// Local function: Get next nibble.
|
|
static int ctr=0; // offset for next nibble
|
|
static int hilo=0; // 0= high nibble next, 1=low nibble next
|
|
const uint8_t * data;
|
|
static char gnn(){ // Get next nibble
|
|
static int byte;
|
|
int val;
|
|
if(hilo==1)
|
|
ctr++;
|
|
hilo=1-hilo;
|
|
if(hilo==1){
|
|
if(efont.type==FONT_EXTERNAL){
|
|
byte=_getFontData(GET_DATA,0);
|
|
}else{
|
|
byte=data[ctr];
|
|
};
|
|
val=byte>>4;
|
|
}else{
|
|
val=byte&0x0f;
|
|
};
|
|
return val;
|
|
};
|
|
|
|
// Local function: Unpack "long run".
|
|
int upl(int off){
|
|
int retval;
|
|
|
|
while((retval=gnn())==0){
|
|
off++;
|
|
};
|
|
while(off-->0){
|
|
retval=retval<<4;
|
|
retval+=gnn();
|
|
};
|
|
return retval;
|
|
};
|
|
|
|
|
|
uint8_t * pk_decode(const uint8_t * ldata,int * len){
|
|
ctr=0;hilo=0;
|
|
data=ldata;
|
|
int length=*len; // Length of character bytestream
|
|
int height; // Height of character in bytes
|
|
int hoff; // bit position for non-integer heights
|
|
uint8_t * bufptr=charBuf; // Output buffer for decoded character
|
|
|
|
height=(font->u8Height-1)/8+1;
|
|
hoff=font->u8Height%8;
|
|
|
|
#define DYN (12) // Decoder parameter: Fixed value for now.
|
|
int repeat=0; // Decoder internal: repeat colum?
|
|
int curbit=0; // Decoder internal: current bit (1 or 0)
|
|
int pos=0; // Decoder internal: current bit position (0..7)
|
|
int nyb; // Decoder internal: current nibble / value
|
|
|
|
if(efont.type==FONT_EXTERNAL){
|
|
if(_getFontData(PEEK_DATA,0)>>4 == 14){ // Char starts with 1-bits.
|
|
gnn();
|
|
curbit=1;
|
|
};
|
|
}else{
|
|
if(data[ctr]>>4 == 14){ // Char starts with 1-bits.
|
|
gnn();
|
|
curbit=1;
|
|
};
|
|
};
|
|
|
|
while(ctr<length){ /* Iterate the whole input stream */
|
|
|
|
/* Get next encoded nibble and decode */
|
|
nyb=gnn();
|
|
|
|
if(nyb==15){
|
|
repeat++;
|
|
continue;
|
|
}else if(nyb==14){
|
|
nyb=upl(0);
|
|
nyb+=1;
|
|
repeat+=nyb;
|
|
continue;
|
|
}else if(nyb>DYN){
|
|
nyb=(16*(nyb-DYN-1))+gnn()+DYN+1;
|
|
}else if(nyb==0){
|
|
nyb=upl(1);
|
|
nyb+=(16*(13-DYN)+DYN)-16;
|
|
};
|
|
|
|
/* Generate & output bits */
|
|
|
|
while(nyb-->0){
|
|
if(pos==0) // Clear each byte before we start.
|
|
*bufptr=0;
|
|
if(curbit==1){
|
|
*bufptr|=1<<(7-pos);
|
|
};
|
|
pos++;
|
|
if(((bufptr-charBuf)%height)==(height-1) && (pos==hoff)){
|
|
// Finish incomplete last byte per column
|
|
pos=8;
|
|
};
|
|
|
|
if(pos==8){
|
|
bufptr++;
|
|
if((bufptr-charBuf)%height==0){ // End of column?
|
|
while(repeat>0){
|
|
for(int y=0;y<height;y++){
|
|
bufptr[0]=bufptr[-height];
|
|
bufptr++;
|
|
};
|
|
repeat--;
|
|
};
|
|
};
|
|
pos=0;
|
|
};
|
|
};
|
|
curbit=1-curbit;
|
|
};
|
|
|
|
*len=(bufptr-charBuf)/height; // return size of output buffer.
|
|
return charBuf;
|
|
};
|