|
|
1.1 ! root 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.