#include "fonts.h" #include "render.h" #include // 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 static const uint8_t *data; #define MAXCHR (30 * 20) static uint8_t charBuf[MAXCHR]; // Get next nibble static uint8_t gnn() { static uint8_t byte; uint8_t val; if (hilo == 1) ctr++; hilo = 1 - hilo; if (hilo == 1) { byte = data[ctr]; val = byte >> 4; } else { val = byte & 0x0f; }; return val; } // Local function: Unpack "long run". static int upl(int off) { int retval; while ((retval = gnn()) == 0) { off++; }; while (off-- > 0) { retval = retval << 4; retval += gnn(); }; return retval; } uint8_t *rad1o_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 = (rad1o_getFontHeight() - 1) / 8 + 1; hoff = rad1o_getFontHeight() % 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 (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; }