1: #include <stdio.h>
2:
3: #ifdef SCCSID
4: static char *SccsId = "@(#)decode.c 1.3 5/15/85";
5: #endif /* SCCSID */
6:
7: /*
8: * This program is the inverse of encode
9: *
10: * It collects runs of 12 characters, combines pairs of those
11: * to form 6 13 bit numbers, extracts the top bit of each of
12: * those to make a 13th 6 bit character, and splits each of
13: * the remaining 6 12 bit numbers to form 12 6 bit ones.
14: *
15: * The strings of 6 bit numbers are collected into groups of
16: * 4 and converted into 3 8 bit characters.
17: *
18: * Now all that would be trivial, if we didn't need to worry
19: * about ending all this correctly. About 1/2 of the following
20: * program wouldn't be here if the ending didn't matter....
21: */
22:
23: /*
24: * the following pair of characters can never occur as a pair
25: * in legal input (since (90 * 91 + 90) > 2^13) - they are
26: * noticed at the beginning of a 12 char block, and serve to
27: * indicate that this block is the terminator. The character
28: * immediately following is the (expanded) terminator length.
29: */
30: #define ENDMARK1 ((90*91 + 90) / 91)
31: #define ENDMARK2 ((90*91 + 90) % 91)
32:
33: main()
34: {
35: register c;
36: register char *p;
37: register i;
38: register first = 1;
39: register cnt = 0;
40: int errcnt = 0;
41: char b12[12];
42: char c12[12];
43:
44: p = b12;
45: i = 12;
46:
47: while ((c = getchar()) != EOF) {
48: if (c < ' ' || c >= (' ' + 91)) {
49: if (errcnt++ == 0)
50: fprintf(stderr, "decode: Bad data\n");
51: continue;
52: }
53: if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
54: cnt = c - ' ';
55: i = 12;
56: p -= 2;
57: continue;
58: }
59: *p++ = c - ' ';
60: if (--i == 0) {
61: if (p == &b12[12]) {
62: if (!first)
63: pack12(c12, 12, 0);
64: else
65: first = 0;
66: p = c12;
67: } else {
68: pack12(b12, 12, 0);
69: p = b12;
70: }
71: i = 12;
72: }
73: }
74:
75: if (p >= &b12[0] && p < &b12[12]) {
76: if (!first)
77: pack12(c12, 12, i == 12 ? cnt : 0);
78: } else
79: pack12(b12, 12, i == 12 ? cnt : 0);
80:
81: if (i != 12) {
82: if (p >= &b12[0] && p < &b12[12])
83: pack12(b12, 12-i, cnt);
84: else
85: pack12(c12, 12-i, cnt);
86: }
87:
88: exit(0);
89: }
90:
91: static char b4[4];
92: static int cnt = 0;
93:
94: pack12(p, n, last)
95: register char *p;
96: register n;
97: int last;
98: {
99: register i;
100: register char *q;
101: char b13[13];
102:
103: {
104: register c;
105: register c13;
106:
107: q = b13;
108: c13 = 0;
109:
110: for (i = 0; i < n; i += 2) {
111: c = *p++ * 91;
112: c += *p++;
113: c13 <<= 1;
114: if (c & (1 << 12))
115: c13 |= 1;
116: *q++ = (c >> 6) & 0x3f;
117: *q++ = c & 0x3f;
118: }
119: *q++ = c13;
120: if (last)
121: q = &b13[last];
122: }
123:
124: p = b13;
125: n = q - p;
126: i = cnt;
127: q = &b4[cnt];
128:
129: while (--n > 0) {
130: *q++ = *p++;
131: if (++i == 4) {
132: char b3[3];
133: register char *b = b4;
134:
135: /* inline expansion of pack6bit, to save calls ... */
136:
137: q = b3;
138: *q++ = (b[0] << 2) | ((b[1] >> 4) & 0x3);
139: *q++ = (b[1] << 4) | ((b[2] >> 2) & 0xf);
140: *q = (b[2] << 6) | (b[3] & 0x3f);
141:
142: q = b3;
143: while (--i > 0)
144: putchar(*q++);
145:
146: q = b4;
147: }
148: }
149:
150: *q++ = *p++; /* the last octet */
151: ++i;
152:
153: if (last || i == 4) {
154: pack6bit(b4, i, last);
155: i = 0;
156: }
157:
158: cnt = i;
159: }
160:
161: pack6bit(p, n, last)
162: register char *p;
163: register int n;
164: int last;
165: {
166: register char *q;
167: register i = 3;
168: char b3[3];
169:
170: if (last) {
171: i = p[n-1];
172: if (i >= 3) {
173: fprintf(stderr, "Badly encoded file\n");
174: i = 3; /* do the best we can */
175: }
176: }
177:
178: q = b3;
179: *q++ = (p[0] << 2) | ((p[1] >> 4) & 0x3);
180: *q++ = (p[1] << 4) | ((p[2] >> 2) & 0xf);
181: *q = (p[2] << 6) | (p[3] & 0x3f);
182:
183: q = b3;
184:
185: while (--i >= 0)
186: putchar(*q++);
187: }
Defined functions
main
defined in line
33;
never used
Defined variables
SccsId
defined in line
4;
never used
b4
defined in line
91; used 4 times
cnt
defined in line
92; used 9 times
Defined macros