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
pack12 defined in line 94; used 6 times
pack6bit defined in line 161; used 1 times

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

ENDMARK1 defined in line 30; used 1 times
  • in line 53
ENDMARK2 defined in line 31; used 1 times
  • in line 53
Last modified: 1986-01-20
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 951
Valid CSS Valid XHTML 1.0 Strict