69 lines
1.6 KiB
C
69 lines
1.6 KiB
C
|
/* expand.c -- Byte Pair Encoding decompression */
|
||
|
/* Copyright 1996 Philip Gage */
|
||
|
|
||
|
/* Byte Pair Compression appeared in the September 1997
|
||
|
* issue of C/C++ Users Journal. The original source code
|
||
|
* may still be found at the web site of the magazine
|
||
|
* (www.cuj.com).
|
||
|
*
|
||
|
* The decompressor has been modified by me (Thiadmer
|
||
|
* Riemersma) to accept a string as input, instead of a
|
||
|
* complete file.
|
||
|
*/
|
||
|
#include <assert.h>
|
||
|
#include <stdio.h>
|
||
|
#include "sc.h"
|
||
|
|
||
|
#define STACKSIZE 16
|
||
|
|
||
|
SC_FUNC int strexpand(char *dest, unsigned char *source, int maxlen, unsigned char pairtable[128][2])
|
||
|
{
|
||
|
unsigned char stack[STACKSIZE];
|
||
|
short c, top = 0;
|
||
|
int len;
|
||
|
|
||
|
assert(maxlen > 0);
|
||
|
len = 1; /* already 1 byte for '\0' */
|
||
|
for (;;) {
|
||
|
|
||
|
/* Pop byte from stack or read byte from the input string */
|
||
|
if (top)
|
||
|
c = stack[--top];
|
||
|
else if ((c = *(unsigned char *)source++) == '\0')
|
||
|
break;
|
||
|
|
||
|
/* Push pair on stack or output byte to the output string */
|
||
|
if (c > 127) {
|
||
|
assert(top+2 <= STACKSIZE);
|
||
|
stack[top++] = pairtable[c-128][1];
|
||
|
stack[top++] = pairtable[c-128][0];
|
||
|
}
|
||
|
else {
|
||
|
len++;
|
||
|
if (maxlen > 1) { /* reserve one byte for the '\0' */
|
||
|
*dest++ = (char)c;
|
||
|
maxlen--;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
*dest = '\0';
|
||
|
return len; /* return number of bytes decoded */
|
||
|
}
|
||
|
|
||
|
#if 0 /*for testing*/
|
||
|
#include "sc5.scp"
|
||
|
|
||
|
int main (int argc, char **argv)
|
||
|
{
|
||
|
int i;
|
||
|
char str[128];
|
||
|
|
||
|
for (i=0; i<58; i++) {
|
||
|
strexpand(str, errmsg[i], sizeof str, SCPACK_TABLE);
|
||
|
printf("%s", str);
|
||
|
} /* for */
|
||
|
return 0;
|
||
|
}
|
||
|
#endif
|
||
|
|