home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff319.lzh
/
CNewsSrc
/
cnews.orig.lzh
/
input
/
c7decode.c
< prev
next >
Wrap
C/C++ Source or Header
|
1989-06-27
|
3KB
|
186 lines
#include <stdio.h>
/*
* This program is the inverse of encode
*
* It collects runs of 12 characters, combines pairs of those
* to form 6 13 bit numbers, extracts the top bit of each of
* those to make a 13th 6 bit character, and splits each of
* the remaining 6 12 bit numbers to form 12 6 bit ones.
*
* The strings of 6 bit numbers are collected into groups of
* 4 and converted into 3 8 bit characters.
*
* Now all that would be trivial, if we didn't need to worry
* about ending all this correctly. About 1/2 of the following
* program wouldn't be here if the ending didn't matter....
*/
/*
* the following pair of characters can never occur as a pair
* in legal input (since (90 * 91 + 90) > 2^13) - they are
* noticed at the beginning of a 12 char block, and serve to
* indicate that this block is the terminator. The character
* immediately following is the (expanded) terminator length.
*/
#define ENDMARK1 ((90*91 + 90) / 91)
#define ENDMARK2 ((90*91 + 90) % 91)
int errcnt = 0;
main()
{
register c;
register char *p;
register i;
register first = 1;
register cnt = 0;
char b12[12];
char c12[12];
p = b12;
i = 12;
while ((c = getchar()) != EOF) {
if (c < ' ' || c >= (' ' + 91)) {
if (errcnt++ == 0)
fprintf(stderr, "c7decode: Bad data\n");
continue;
}
if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
cnt = c - ' ';
i = 12;
p -= 2;
continue;
}
*p++ = c - ' ';
if (--i == 0) {
if (p == &b12[12]) {
if (!first)
pack12(c12, 12, 0);
else
first = 0;
p = c12;
} else {
pack12(b12, 12, 0);
p = b12;
}
i = 12;
}
}
if (p >= &b12[0] && p < &b12[12]) {
if (!first)
pack12(c12, 12, i == 12 ? cnt : 0);
} else
pack12(b12, 12, i == 12 ? cnt : 0);
if (i != 12) {
if (p >= &b12[0] && p < &b12[12])
pack12(b12, 12-i, cnt);
else
pack12(c12, 12-i, cnt);
}
exit((errcnt > 0) ? 1 : 0);
}
static char b4[4];
static int cnt = 0;
pack12(p, n, last)
register char *p;
register n;
int last;
{
register i;
register char *q;
char b13[13];
{
register c;
register c13;
q = b13;
c13 = 0;
for (i = 0; i < n; i += 2) {
c = *p++ * 91;
c += *p++;
c13 <<= 1;
if (c & (1 << 12))
c13 |= 1;
*q++ = (c >> 6) & 0x3f;
*q++ = c & 0x3f;
}
*q++ = c13;
if (last)
q = &b13[last];
}
p = b13;
n = q - p;
i = cnt;
q = &b4[cnt];
while (--n > 0) {
*q++ = *p++;
if (++i == 4) {
char b3[3];
register char *b = b4;
/* inline expansion of pack6bit, to save calls ... */
q = b3;
*q++ = (b[0] << 2) | ((b[1] >> 4) & 0x3);
*q++ = (b[1] << 4) | ((b[2] >> 2) & 0xf);
*q = (b[2] << 6) | (b[3] & 0x3f);
q = b3;
while (--i > 0)
putchar(*q++);
q = b4;
}
}
*q++ = *p++; /* the last octet */
++i;
if (last || i == 4) {
pack6bit(b4, i, last);
i = 0;
}
cnt = i;
}
pack6bit(p, n, last)
register char *p;
register int n;
int last;
{
register char *q;
register i = 3;
char b3[3];
if (last) {
i = p[n-1];
if (i >= 3) {
fprintf(stderr, "c7decode: Badly encoded file\n");
errcnt++;
i = 3; /* do the best we can */
}
}
q = b3;
*q++ = (p[0] << 2) | ((p[1] >> 4) & 0x3);
*q++ = (p[1] << 4) | ((p[2] >> 2) & 0xf);
*q = (p[2] << 6) | (p[3] & 0x3f);
q = b3;
while (--i >= 0)
putchar(*q++);
}