Annotation of 43BSD/contrib/news/src/decode.c, revision 1.1.1.1

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: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.