2 ** Decode seven-bit input into full binary output.
3 ** From @(#)decode.c 1.3 5/15/85, distributed with B2.11 News.
5 ** Collect runs of 12 seven-bit characters. Combine them in pairs to
6 ** make six 13-bit characters. Extract the top bit of each pair to make
7 ** a 13th six-bit character, and split the remaining six 12-bit
8 ** characters to form 12 six-bit characters. Collect four six-bit
9 ** characters and convert it to three eight-bit characters.
11 ** Got that? All the remaining work in this program is to get the
12 ** ending conditions right.
18 #include "inn/messages.h"
22 ** These characters can't appear in normal output, so we use them to
23 ** mark that the data that follows is the terminator. The character
24 ** immediately following this pair is the length of the terminator (which
25 ** otherwise might be indeterminable)
27 #define ENDMARK1 ((90 * 91 + 90) / 91)
28 #define ENDMARK2 ((90 * 91 + 90) % 91)
31 static char Buffer[4];
36 pack6(int n, int last)
43 if (last && (i = Buffer[n - 1]) >= 3) {
44 /* Do the best we can. */
45 warn("badly-terminated file");
49 b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
50 b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
51 b3[2] = (Buffer[2] << 6) | ( Buffer[3] & 0x3F);
52 for (q = b3; --i >= 0; )
58 pack12(char *p, int n, int last)
67 for (q = b13, c13 = 0, i = 0; i < n; i += 2) {
73 *q++ = (c >> 6) & 0x3F;
80 for (p = b13, n = q - p, i = count, q = &Buffer[count]; --n > 0; ) {
83 /* Inline expansion of pack6. */
84 b3[0] = (Buffer[0] << 2) | ((Buffer[1] >> 4) & 0x03);
85 b3[1] = (Buffer[1] << 4) | ((Buffer[2] >> 2) & 0x0F);
86 b3[2] = (Buffer[2] << 6) | ( Buffer[3] & 0x3F);
120 message_program_name = "decode";
123 for (i = 12, cnt = 0, first = 1; (c = getchar()) != EOF; ) {
124 if (c < ' ' || c >= ' ' + 91)
126 if (i == 10 && p[-1] == ENDMARK1 && p[-2] == ENDMARK2) {
151 pack12(c12, 12, i == 12 ? cnt : 0);
154 pack12(b12, 12, i == 12 ? cnt : 0);
157 pack12(base, 12 - i, cnt);