Annotation of sbbs/sbbs2/fido/lzh.c, revision 1.1

1.1     ! root        1: /* LZH.C */
        !             2: 
        !             3: /* Digital Dynamics conversion of 1988 LZH (LHarc) encoding functions  */
        !             4: /* Based on Japanese version 29-NOV-1988                                                               */
        !             5: /* LZSS coded by Haruhiko Okumura                                                                              */
        !             6: /* Adaptive Huffman Coding coded by Haruyasu Yoshizaki                                 */
        !             7: 
        !             8: 
        !             9: #include <stdio.h>
        !            10: #include <stdlib.h>
        !            11: #include <string.h>
        !            12: #include <ctype.h>
        !            13: #ifndef __WATCOMC__
        !            14:        #include <alloc.h>
        !            15: #endif
        !            16: 
        !            17: /****************************************************************************/
        !            18: /* Memory allocation macros for various compilers and environments                     */
        !            19: /* MALLOC is used for allocations of 64k or less                                                       */
        !            20: /* FREE is used to free buffers allocated with MALLOC                                          */
        !            21: /* LMALLOC is used for allocations of possibly larger than 64k                         */
        !            22: /* LFREE is used to free buffers allocated with LMALLOC                                        */
        !            23: /* REALLOC is used to re-size a previously MALLOCed or LMALLOCed buffer        */
        !            24: /****************************************************************************/
        !            25: #if defined(__COMPACT__) || defined(__LARGE__) || defined(__HUGE__)
        !            26:        #if defined(__TURBOC__)
        !            27:                #define REALLOC(x,y) farrealloc(x,y)
        !            28:                #define LMALLOC(x) farmalloc(x)
        !            29:                #define MALLOC(x) farmalloc(x)
        !            30:                #define LFREE(x) farfree(x)
        !            31:                #define FREE(x) farfree(x)
        !            32:        #elif defined(__WATCOMC__)
        !            33:                #define REALLOC realloc
        !            34:                #define LMALLOC(x) halloc(x,1)  /* far heap, but slow */
        !            35:                #define MALLOC malloc                   /* far heap, but 64k max */
        !            36:                #define LFREE hfree
        !            37:                #define FREE free
        !            38:        #else   /* Other 16-bit Compiler */
        !            39:                #define REALLOC realloc
        !            40:                #define LMALLOC malloc
        !            41:                #define MALLOC malloc
        !            42:                #define LFREE free
        !            43:                #define FREE free
        !            44:        #endif
        !            45: #else          /* 32-bit Compiler or Small Memory Model */
        !            46:        #define REALLOC realloc
        !            47:        #define LMALLOC malloc
        !            48:        #define MALLOC malloc
        !            49:        #define LFREE free
        !            50:        #define FREE free
        !            51: #endif
        !            52: 
        !            53: 
        !            54: 
        !            55: typedef unsigned char uchar;
        !            56: 
        !            57: /* LZSS Parameters */
        !            58: 
        !            59: #define LZH_N                  4096    /* Size of string buffer */
        !            60: #define LZH_F                  60              /* Size of look-ahead buffer */
        !            61: #define LZH_THRESHOLD  2
        !            62: #define LZH_NIL                LZH_N   /* End of tree's node  */
        !            63: 
        !            64: #ifdef LZH_DYNAMIC_BUF
        !            65: 
        !            66: unsigned char *lzh_text_buf;
        !            67: short int      lzh_match_position, lzh_match_length,
        !            68:          *lzh_lson, *lzh_rson, *lzh_dad;
        !            69: 
        !            70: #else
        !            71: 
        !            72: unsigned char lzh_text_buf[LZH_N + LZH_F - 1];
        !            73: short int        lzh_match_position, lzh_match_length,
        !            74:                lzh_lson[LZH_N + 1], lzh_rson[LZH_N + 257], lzh_dad[LZH_N + 1];
        !            75: 
        !            76: #endif
        !            77: 
        !            78: 
        !            79: void lzh_init_tree(void)  /* Initializing tree */
        !            80: {
        !            81:        short int  i;
        !            82: 
        !            83:        for (i = LZH_N + 1; i <= LZH_N + 256; i++)
        !            84:                lzh_rson[i] = LZH_NIL;                  /* root */
        !            85:        for (i = 0; i < LZH_N; i++)
        !            86:                lzh_dad[i] = LZH_NIL;                   /* node */
        !            87: }
        !            88: 
        !            89: /******************************/
        !            90: /* Inserting node to the tree */
        !            91: /* Only used during encoding  */
        !            92: /******************************/
        !            93: void lzh_insert_node(short int r)
        !            94: {
        !            95:        short int  i, p, cmp;
        !            96:        unsigned char  *key;
        !            97:        unsigned c;
        !            98: 
        !            99:        cmp = 1;
        !           100:        key = lzh_text_buf+r;
        !           101:        p = LZH_N + 1 + key[0];
        !           102:        lzh_rson[r] = lzh_lson[r] = LZH_NIL;
        !           103:        lzh_match_length = 0;
        !           104:        for ( ; ; ) {
        !           105:                if (cmp >= 0) {
        !           106:                        if (lzh_rson[p] != LZH_NIL)
        !           107:                                p = lzh_rson[p];
        !           108:                        else {
        !           109:                                lzh_rson[p] = r;
        !           110:                                lzh_dad[r] = p;
        !           111:                                return;
        !           112:                        }
        !           113:                } else {
        !           114:                        if (lzh_lson[p] != LZH_NIL)
        !           115:                                p = lzh_lson[p];
        !           116:                        else {
        !           117:                                lzh_lson[p] = r;
        !           118:                                lzh_dad[r] = p;
        !           119:                                return;
        !           120:                        }
        !           121:                }
        !           122:                for (i = 1; i < LZH_F; i++)
        !           123:                        if ((cmp = key[i] - lzh_text_buf[p + i]) != 0)
        !           124:                                break;
        !           125:                if (i > LZH_THRESHOLD) {
        !           126:                        if (i > lzh_match_length) {
        !           127:                                lzh_match_position = ((r - p) & (LZH_N - 1)) - 1;
        !           128:                                if ((lzh_match_length = i) >= LZH_F)
        !           129:                                        break;
        !           130:                        }
        !           131:                        if (i == lzh_match_length) {
        !           132:                                if ((c = ((r - p) & (LZH_N - 1)) - 1) < lzh_match_position) {
        !           133:                                        lzh_match_position = c;
        !           134:                                }
        !           135:                        }
        !           136:                }
        !           137:        }
        !           138:        lzh_dad[r] = lzh_dad[p];
        !           139:        lzh_lson[r] = lzh_lson[p];
        !           140:        lzh_rson[r] = lzh_rson[p];
        !           141:        lzh_dad[lzh_lson[p]] = r;
        !           142:        lzh_dad[lzh_rson[p]] = r;
        !           143:        if (lzh_rson[lzh_dad[p]] == p)
        !           144:                lzh_rson[lzh_dad[p]] = r;
        !           145:        else
        !           146:                lzh_lson[lzh_dad[p]] = r;
        !           147:        lzh_dad[p] = LZH_NIL;  /* remove p */
        !           148: }
        !           149: 
        !           150: void lzh_delete_node(short int p)  /* Deleting node from the tree */
        !           151: {
        !           152:        short int  q;
        !           153: 
        !           154:        if (lzh_dad[p] == LZH_NIL)
        !           155:                return;                 /* unregistered */
        !           156:        if (lzh_rson[p] == LZH_NIL)
        !           157:                q = lzh_lson[p];
        !           158:        else
        !           159:        if (lzh_lson[p] == LZH_NIL)
        !           160:                q = lzh_rson[p];
        !           161:        else {
        !           162:                q = lzh_lson[p];
        !           163:                if (lzh_rson[q] != LZH_NIL) {
        !           164:                        do {
        !           165:                                q = lzh_rson[q];
        !           166:                        } while (lzh_rson[q] != LZH_NIL);
        !           167:                        lzh_rson[lzh_dad[q]] = lzh_lson[q];
        !           168:                        lzh_dad[lzh_lson[q]] = lzh_dad[q];
        !           169:                        lzh_lson[q] = lzh_lson[p];
        !           170:                        lzh_dad[lzh_lson[p]] = q;
        !           171:                }
        !           172:                lzh_rson[q] = lzh_rson[p];
        !           173:                lzh_dad[lzh_rson[p]] = q;
        !           174:        }
        !           175:        lzh_dad[q] = lzh_dad[p];
        !           176:        if (lzh_rson[lzh_dad[p]] == p)
        !           177:                lzh_rson[lzh_dad[p]] = q;
        !           178:        else
        !           179:                lzh_lson[lzh_dad[p]] = q;
        !           180:        lzh_dad[p] = LZH_NIL;
        !           181: }
        !           182: 
        !           183: /* Huffman coding parameters */
        !           184: 
        !           185: #define LZH_N_CHAR             (256 - LZH_THRESHOLD + LZH_F)
        !           186:                                        /* character code (= 0..LZH_N_CHAR-1) */
        !           187: #define LZH_T          (LZH_N_CHAR * 2 - 1)    /* Size of table */
        !           188: #define LZH_R          (LZH_T - 1)             /* root position */
        !           189: #define MAX_FREQ       0x8000
        !           190:                                        /* update when cumulative frequency */
        !           191:                                        /* reaches to this value */
        !           192: 
        !           193: /*
        !           194:  * Tables for encoding/decoding upper 6 bits of
        !           195:  * sliding dictionary pointer
        !           196:  */
        !           197: /* encoder table */
        !           198: uchar lzh_p_len[64] = {
        !           199:        0x03, 0x04, 0x04, 0x04, 0x05, 0x05, 0x05, 0x05,
        !           200:        0x05, 0x05, 0x05, 0x05, 0x06, 0x06, 0x06, 0x06,
        !           201:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           202:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           203:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           204:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           205:        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !           206:        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08
        !           207: };
        !           208: 
        !           209: uchar lzh_p_code[64] = {
        !           210:        0x00, 0x20, 0x30, 0x40, 0x50, 0x58, 0x60, 0x68,
        !           211:        0x70, 0x78, 0x80, 0x88, 0x90, 0x94, 0x98, 0x9C,
        !           212:        0xA0, 0xA4, 0xA8, 0xAC, 0xB0, 0xB4, 0xB8, 0xBC,
        !           213:        0xC0, 0xC2, 0xC4, 0xC6, 0xC8, 0xCA, 0xCC, 0xCE,
        !           214:        0xD0, 0xD2, 0xD4, 0xD6, 0xD8, 0xDA, 0xDC, 0xDE,
        !           215:        0xE0, 0xE2, 0xE4, 0xE6, 0xE8, 0xEA, 0xEC, 0xEE,
        !           216:        0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7,
        !           217:        0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF
        !           218: };
        !           219: 
        !           220: /* decoder table */
        !           221: uchar lzh_d_code[256] = {
        !           222:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           223:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           224:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           225:        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
        !           226:        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        !           227:        0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
        !           228:        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !           229:        0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02,
        !           230:        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
        !           231:        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
        !           232:        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !           233:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           234:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           235:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           236:        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !           237:        0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09, 0x09,
        !           238:        0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A, 0x0A,
        !           239:        0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B, 0x0B,
        !           240:        0x0C, 0x0C, 0x0C, 0x0C, 0x0D, 0x0D, 0x0D, 0x0D,
        !           241:        0x0E, 0x0E, 0x0E, 0x0E, 0x0F, 0x0F, 0x0F, 0x0F,
        !           242:        0x10, 0x10, 0x10, 0x10, 0x11, 0x11, 0x11, 0x11,
        !           243:        0x12, 0x12, 0x12, 0x12, 0x13, 0x13, 0x13, 0x13,
        !           244:        0x14, 0x14, 0x14, 0x14, 0x15, 0x15, 0x15, 0x15,
        !           245:        0x16, 0x16, 0x16, 0x16, 0x17, 0x17, 0x17, 0x17,
        !           246:        0x18, 0x18, 0x19, 0x19, 0x1A, 0x1A, 0x1B, 0x1B,
        !           247:        0x1C, 0x1C, 0x1D, 0x1D, 0x1E, 0x1E, 0x1F, 0x1F,
        !           248:        0x20, 0x20, 0x21, 0x21, 0x22, 0x22, 0x23, 0x23,
        !           249:        0x24, 0x24, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
        !           250:        0x28, 0x28, 0x29, 0x29, 0x2A, 0x2A, 0x2B, 0x2B,
        !           251:        0x2C, 0x2C, 0x2D, 0x2D, 0x2E, 0x2E, 0x2F, 0x2F,
        !           252:        0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37,
        !           253:        0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
        !           254: };
        !           255: 
        !           256: uchar lzh_d_len[256] = {
        !           257:        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
        !           258:        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
        !           259:        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
        !           260:        0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03,
        !           261:        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !           262:        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !           263:        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !           264:        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !           265:        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !           266:        0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04, 0x04,
        !           267:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           268:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           269:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           270:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           271:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           272:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           273:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           274:        0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
        !           275:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           276:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           277:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           278:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           279:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           280:        0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06, 0x06,
        !           281:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           282:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           283:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           284:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           285:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           286:        0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
        !           287:        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !           288:        0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08,
        !           289: };
        !           290: 
        !           291: #ifdef LZH_DYNAMIC_BUF
        !           292: 
        !           293: unsigned short *lzh_freq=NULL;  /* cumulative freq table */
        !           294: 
        !           295: /*
        !           296:  * pointing parent nodes.
        !           297:  * area [LZH_T..(LZH_T + LZH_N_CHAR - 1)] are pointers for leaves
        !           298:  */
        !           299: short int *lzh_prnt=NULL;
        !           300: 
        !           301: /* pointing children nodes (son[], son[] + 1)*/
        !           302: short int *lzh_son=NULL;
        !           303: 
        !           304: #else  /* STATIC */
        !           305: 
        !           306: unsigned short lzh_freq[LZH_T + 1];   /* cumulative freq table */
        !           307: short int lzh_prnt[LZH_T + LZH_N_CHAR];
        !           308: short int lzh_son[LZH_T + 1];            /* bug fixed by Digital Dynamics */
        !           309: 
        !           310: #endif
        !           311: 
        !           312: 
        !           313: unsigned short lzh_getbuf = 0;         /* Was just "unsigned" fixed 04/12/95 */
        !           314: uchar lzh_getlen = 0;
        !           315: 
        !           316: int lzh_getbit(uchar *inbuf, long *incnt, long inlen)    /* get one bit */
        !           317: {
        !           318:        short int i;
        !           319: 
        !           320:        while (lzh_getlen <= 8) {
        !           321:                if((*incnt)>=inlen)
        !           322:                        i=0;
        !           323:                else
        !           324:                        i=inbuf[(*incnt)++];
        !           325:                lzh_getbuf |= i << (8 - lzh_getlen);
        !           326:                lzh_getlen += 8;
        !           327:        }
        !           328:        i = lzh_getbuf;
        !           329:        lzh_getbuf <<= 1;
        !           330:        lzh_getlen--;
        !           331:        return (i < 0);
        !           332: }
        !           333: 
        !           334: short int lzh_getbyte(uchar *inbuf, long *incnt, long inlen)   /* get a byte */
        !           335: {
        !           336:        unsigned short i;
        !           337: 
        !           338:        while (lzh_getlen <= 8) {
        !           339:                if((*incnt)>=inlen)
        !           340:                        i=0;
        !           341:                else
        !           342:                        i=inbuf[(*incnt)++];
        !           343:                lzh_getbuf |= i << (8 - lzh_getlen);
        !           344:                lzh_getlen += 8;
        !           345:        }
        !           346:        i = lzh_getbuf;
        !           347:        lzh_getbuf <<= 8;
        !           348:        lzh_getlen -= 8;
        !           349:        return i >> 8;
        !           350: }
        !           351: 
        !           352: unsigned lzh_putbuf = 0;
        !           353: uchar lzh_putlen = 0;
        !           354: 
        !           355: /* output c bits */
        !           356: void lzh_putcode(short int l, unsigned short c, uchar *outbuf, long *outlen)
        !           357: {
        !           358:        lzh_putbuf |= c >> lzh_putlen;
        !           359:        if ((lzh_putlen += l) >= 8) {
        !           360:                outbuf[(*outlen)++]=(lzh_putbuf >> 8);
        !           361:                if ((lzh_putlen -= 8) >= 8) {
        !           362:                        outbuf[(*outlen)++]=lzh_putbuf;
        !           363:                        lzh_putlen -= 8;
        !           364:                        lzh_putbuf = c << (l - lzh_putlen);
        !           365:                } else {
        !           366:                        lzh_putbuf <<= 8;
        !           367:                }
        !           368:        }
        !           369: }
        !           370: 
        !           371: 
        !           372: /* initialize freq tree */
        !           373: 
        !           374: void lzh_start_huff()
        !           375: {
        !           376:        short int i, j;
        !           377: 
        !           378: lzh_getbuf = 0;        /* Added by Digital Dynamics for repeating operations */
        !           379: lzh_getlen = 0;
        !           380: lzh_putbuf = 0;
        !           381: lzh_putlen = 0;
        !           382: 
        !           383:        for (i = 0; i < LZH_N_CHAR; i++) {
        !           384:                lzh_freq[i] = 1;
        !           385:                lzh_son[i] = i + LZH_T;
        !           386:                lzh_prnt[i + LZH_T] = i;
        !           387:        }
        !           388:        i = 0; j = LZH_N_CHAR;
        !           389:        while (j <= LZH_R) {
        !           390:                lzh_freq[j] = lzh_freq[i] + lzh_freq[i + 1];
        !           391:                lzh_son[j] = i;
        !           392:                lzh_prnt[i] = lzh_prnt[i + 1] = j;
        !           393:                i += 2; j++;
        !           394:        }
        !           395:        lzh_freq[LZH_T] = 0xffff;
        !           396:     lzh_prnt[LZH_R] = 0;
        !           397: }
        !           398: 
        !           399: 
        !           400: /* reconstruct freq tree */
        !           401: 
        !           402: void lzh_reconst()
        !           403: {
        !           404:        short int i, j, k;
        !           405:        unsigned short f, l;
        !           406: 
        !           407:        /* halven cumulative freq for leaf nodes */
        !           408:        j = 0;
        !           409:        for (i = 0; i < LZH_T; i++) {
        !           410:                if (lzh_son[i] >= LZH_T) {
        !           411:                        lzh_freq[j] = (lzh_freq[i] + 1) / 2;
        !           412:                        lzh_son[j] = lzh_son[i];
        !           413:                        j++;
        !           414:                }
        !           415:        }
        !           416:        /* make a tree : first, connect children nodes */
        !           417:        for (i = 0, j = LZH_N_CHAR; j < LZH_T; i += 2, j++) {
        !           418:                k = i + 1;
        !           419:                f = lzh_freq[j] = lzh_freq[i] + lzh_freq[k];
        !           420:                for (k = j - 1; f < lzh_freq[k]; k--);
        !           421:                k++;
        !           422:                l = (j - k) * 2;
        !           423:                
        !           424:                /* movmem() is Turbo-C dependent
        !           425:                   rewritten to memmove() by Kenji */
        !           426:                
        !           427:                /* movmem(&lzh_freq[k], &lzh_freq[k + 1], l); */
        !           428:                (void)memmove(lzh_freq+k+1,lzh_freq+k, l);
        !           429:                lzh_freq[k] = f;
        !           430:                /* movmem(&lzh_son[k], &lzh_son[k + 1], l); */
        !           431:                (void)memmove(lzh_son+k+1,lzh_son+k, l);
        !           432:                lzh_son[k] = i;
        !           433:        }
        !           434:        /* connect parent nodes */
        !           435:        for (i = 0; i < LZH_T; i++) {
        !           436:                if ((k = lzh_son[i]) >= LZH_T) {
        !           437:                        lzh_prnt[k] = i;
        !           438:                } else {
        !           439:                        lzh_prnt[k] = lzh_prnt[k + 1] = i;
        !           440:                }
        !           441:        }
        !           442: }
        !           443: 
        !           444: /* update freq tree */
        !           445: 
        !           446: void lzh_update(short int c)
        !           447: {
        !           448:        short int i, j, k, l;
        !           449: 
        !           450:        if (lzh_freq[LZH_R] == MAX_FREQ) {
        !           451:                lzh_reconst();
        !           452:        }
        !           453:        c = lzh_prnt[c + LZH_T];
        !           454:        do {
        !           455:                k = ++lzh_freq[c];
        !           456: 
        !           457:                /* swap nodes to keep the tree freq-ordered */
        !           458:                if (k > lzh_freq[l = c + 1]) {
        !           459:                        while (k > lzh_freq[++l]);
        !           460:                        l--;
        !           461:                        lzh_freq[c] = lzh_freq[l];
        !           462:                        lzh_freq[l] = k;
        !           463: 
        !           464:                        i = lzh_son[c];
        !           465:                        lzh_prnt[i] = l;
        !           466:                        if (i < LZH_T) lzh_prnt[i + 1] = l;
        !           467: 
        !           468:                        j = lzh_son[l];
        !           469:                        lzh_son[l] = i;
        !           470: 
        !           471:                        lzh_prnt[j] = c;
        !           472:                        if (j < LZH_T) lzh_prnt[j + 1] = c;
        !           473:                        lzh_son[c] = j;
        !           474: 
        !           475:                        c = l;
        !           476:                }
        !           477:        } while ((c = lzh_prnt[c]) != 0);       /* do it until reaching the root */
        !           478: }
        !           479: 
        !           480: unsigned short lzh_code, lzh_len;
        !           481: 
        !           482: void lzh_encode_char(unsigned short c, uchar *outbuf, long *outlen)
        !           483: {
        !           484:        unsigned short i;
        !           485:        short int j, k;
        !           486: 
        !           487:        i = 0;
        !           488:        j = 0;
        !           489:        k = lzh_prnt[c + LZH_T];
        !           490: 
        !           491:        /* search connections from leaf node to the root */
        !           492:        do {
        !           493:                i >>= 1;
        !           494: 
        !           495:                /*
        !           496:                if node's address is odd, output 1
        !           497:                else output 0
        !           498:                */
        !           499:                if (k & 1) i += 0x8000;
        !           500: 
        !           501:                j++;
        !           502:        } while ((k = lzh_prnt[k]) != LZH_R);
        !           503:        lzh_putcode(j, i, outbuf, outlen);
        !           504:        lzh_code = i;
        !           505:        lzh_len = j;
        !           506:        lzh_update(c);
        !           507: }
        !           508: 
        !           509: void lzh_encode_position(unsigned short c, uchar *outbuf, long *outlen)
        !           510: {
        !           511:        unsigned short i;
        !           512: 
        !           513:        /* output upper 6 bits with encoding */
        !           514:        i = c >> 6;
        !           515:        lzh_putcode(lzh_p_len[i], (unsigned)lzh_p_code[i] << 8, outbuf, outlen);
        !           516: 
        !           517:        /* output lower 6 bits directly */
        !           518:        lzh_putcode(6, (c & 0x3f) << 10, outbuf, outlen);
        !           519: }
        !           520: 
        !           521: void lzh_encode_end(uchar *outbuf, long *outlen)
        !           522: {
        !           523:        if (lzh_putlen) {
        !           524:                outbuf[(*outlen)++]=(lzh_putbuf >> 8);
        !           525:        }
        !           526: }
        !           527: 
        !           528: short int lzh_decode_char(uchar *inbuf, long *incnt, long inlen)
        !           529: {
        !           530:        unsigned short c;
        !           531: 
        !           532:        c = lzh_son[LZH_R];
        !           533: 
        !           534:        /*
        !           535:         * start searching tree from the root to leaves.
        !           536:         * choose node #(lzh_son[]) if input bit == 0
        !           537:         * else choose #(lzh_son[]+1) (input bit == 1)
        !           538:         */
        !           539:        while (c < LZH_T) {
        !           540:                c += lzh_getbit(inbuf,incnt,inlen);
        !           541:                c = lzh_son[c];
        !           542:        }
        !           543:        c -= LZH_T;
        !           544:        lzh_update(c);
        !           545:        return c;
        !           546: }
        !           547: 
        !           548: short int lzh_decode_position(uchar *inbuf, long *incnt, long inlen)
        !           549: {
        !           550:        unsigned short i, j, c;
        !           551: 
        !           552:        /* decode upper 6 bits from given table */
        !           553:        i = lzh_getbyte(inbuf,incnt,inlen);
        !           554:        c = (unsigned)lzh_d_code[i] << 6;
        !           555:        j = lzh_d_len[i];
        !           556: 
        !           557:        /* input lower 6 bits directly */
        !           558:        j -= 2;
        !           559:        while (j--) {
        !           560:                i = (i << 1) + lzh_getbit(inbuf,incnt,inlen);
        !           561:        }
        !           562:        return c | i & 0x3f;
        !           563: }
        !           564: 
        !           565: /* Compression */
        !           566: 
        !           567: /* Encoding/Compressing */
        !           568: /* Returns length of outbuf */
        !           569: long lzh_encode(uchar *inbuf, long inlen, uchar *outbuf)
        !           570: {
        !           571:        short int  i, c, len, r, s, last_match_length;
        !           572:        long incnt,outlen; /* textsize=0; */
        !           573: 
        !           574: #ifdef LZH_DYNAMIC_BUF
        !           575: 
        !           576:        if((lzh_text_buf=(uchar *)MALLOC(LZH_N + LZH_F - 1))==NULL)
        !           577:                return(-1);
        !           578:        if((lzh_freq=(unsigned short*)MALLOC((LZH_T + 1)*sizeof(unsigned short)))==NULL) {
        !           579:                FREE(lzh_text_buf);
        !           580:                return(-1); }
        !           581:        if((lzh_prnt=(short *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(short)))==NULL) {
        !           582:                FREE(lzh_text_buf);
        !           583:                FREE(lzh_freq);
        !           584:                return(-1); }
        !           585:        if((lzh_son=(short *)MALLOC((LZH_T + 1) * sizeof(short)))==NULL) {
        !           586:                FREE(lzh_text_buf);
        !           587:                FREE(lzh_prnt);
        !           588:                FREE(lzh_freq);
        !           589:                return(-1); }
        !           590:        if((lzh_lson=(short *)MALLOC((LZH_N + 1)*sizeof(short)))==NULL) {
        !           591:                FREE(lzh_text_buf);
        !           592:                FREE(lzh_prnt);
        !           593:                FREE(lzh_freq);
        !           594:                FREE(lzh_son);
        !           595:                return(-1); }
        !           596:        if((lzh_rson=(short *)MALLOC((LZH_N + 257)*sizeof(short)))==NULL) {
        !           597:                FREE(lzh_text_buf);
        !           598:                FREE(lzh_prnt);
        !           599:                FREE(lzh_freq);
        !           600:                FREE(lzh_son);
        !           601:                FREE(lzh_lson);
        !           602:                return(-1); }
        !           603:        if((lzh_dad=(short *)MALLOC((LZH_N + 1)*sizeof(short)))==NULL) {
        !           604:                FREE(lzh_text_buf);
        !           605:                FREE(lzh_prnt);
        !           606:                FREE(lzh_freq);
        !           607:                FREE(lzh_son);
        !           608:         FREE(lzh_lson);
        !           609:                FREE(lzh_rson);
        !           610:                return(-1); }
        !           611: #endif
        !           612: 
        !           613:        incnt=0;
        !           614:        memcpy(outbuf,&inlen,sizeof(inlen));
        !           615:        outlen=sizeof(inlen);
        !           616:        if(!inlen) {
        !           617: #ifdef LZH_DYNAMIC_BUF
        !           618:                FREE(lzh_text_buf);
        !           619:                FREE(lzh_prnt);
        !           620:                FREE(lzh_freq);
        !           621:                FREE(lzh_son);
        !           622:         FREE(lzh_lson);
        !           623:         FREE(lzh_rson);
        !           624:                FREE(lzh_dad);
        !           625: #endif
        !           626:                return(outlen); }
        !           627:        lzh_start_huff();
        !           628:        lzh_init_tree();
        !           629:        s = 0;
        !           630:        r = LZH_N - LZH_F;
        !           631:        for (i = s; i < r; i++)
        !           632:                lzh_text_buf[i] = ' ';
        !           633:        for (len = 0; len < LZH_F && incnt<inlen; len++)
        !           634:                lzh_text_buf[r + len] = inbuf[incnt++];
        !           635:        /* textsize = len; */
        !           636:        for (i = 1; i <= LZH_F; i++)
        !           637:                lzh_insert_node(r - i);
        !           638:        lzh_insert_node(r);
        !           639:        do {
        !           640:                if (lzh_match_length > len)
        !           641:                        lzh_match_length = len;
        !           642:                if (lzh_match_length <= LZH_THRESHOLD) {
        !           643:                        lzh_match_length = 1;
        !           644:                        lzh_encode_char(lzh_text_buf[r],outbuf,&outlen);
        !           645:                } else {
        !           646:                        lzh_encode_char(255 - LZH_THRESHOLD + lzh_match_length
        !           647:                                ,outbuf,&outlen);
        !           648:                        lzh_encode_position(lzh_match_position
        !           649:                                ,outbuf,&outlen);
        !           650:                }
        !           651:                last_match_length = lzh_match_length;
        !           652:                for (i = 0; i < last_match_length && incnt<inlen; i++) {
        !           653:                        lzh_delete_node(s);
        !           654:                        c=inbuf[incnt++];
        !           655:                        lzh_text_buf[s] = c;
        !           656:                        if (s < LZH_F - 1)
        !           657:                                lzh_text_buf[s + LZH_N] = c;
        !           658:                        s = (s + 1) & (LZH_N - 1);
        !           659:                        r = (r + 1) & (LZH_N - 1);
        !           660:                        lzh_insert_node(r);
        !           661:                }
        !           662: /***
        !           663:                if ((textsize += i) > printcount) {
        !           664:                        printf("%12ld\r", textsize);
        !           665:                        printcount += 1024;
        !           666:                }
        !           667: ***/
        !           668:                while (i++ < last_match_length) {
        !           669:                        lzh_delete_node(s);
        !           670:                        s = (s + 1) & (LZH_N - 1);
        !           671:                        r = (r + 1) & (LZH_N - 1);
        !           672:                        if (--len) lzh_insert_node(r);
        !           673:                }
        !           674:        } while (len > 0);
        !           675:        lzh_encode_end(outbuf,&outlen);
        !           676: /*
        !           677:        printf("input: %ld (%ld) bytes\n", inlen,textsize);
        !           678:        printf("output: %ld bytes\n", outlen);
        !           679:        printf("output/input: %.3f\n", (double)outlen / inlen);
        !           680: */
        !           681: 
        !           682: #ifdef LZH_DYNAMIC_BUF
        !           683:        FREE(lzh_text_buf);
        !           684:        FREE(lzh_prnt);
        !           685:        FREE(lzh_freq);
        !           686:        FREE(lzh_son);
        !           687:        FREE(lzh_lson);
        !           688:        FREE(lzh_rson);
        !           689:        FREE(lzh_dad);
        !           690: #endif
        !           691: 
        !           692:        return(outlen);
        !           693: }
        !           694: 
        !           695: /* Decoding/Uncompressing */
        !           696: /* Returns length of outbuf */
        !           697: long lzh_decode(uchar *inbuf, long inlen, uchar *outbuf)
        !           698: {
        !           699:        short int  i, j, k, r, c;
        !           700:        unsigned long int  count;
        !           701:        long incnt,textsize;
        !           702: 
        !           703: #ifdef LZH_DYNAMIC_BUF
        !           704: 
        !           705:        if((lzh_text_buf=(uchar *)MALLOC((LZH_N + LZH_F - 1)*2))==NULL)
        !           706:                return(-1);
        !           707:        if((lzh_freq=(unsigned short *)MALLOC((LZH_T + 1)*sizeof(unsigned short)))
        !           708:                ==NULL) {
        !           709:                FREE(lzh_text_buf);
        !           710:                return(-1); }
        !           711:        if((lzh_prnt=(short *)MALLOC((LZH_T + LZH_N_CHAR)*sizeof(short)))==NULL) {
        !           712:                FREE(lzh_text_buf);
        !           713:                FREE(lzh_freq);
        !           714:                return(-1); }
        !           715:        if((lzh_son=(short *)MALLOC((LZH_T + 1) * sizeof(short)))==NULL) {
        !           716:                FREE(lzh_text_buf);
        !           717:                FREE(lzh_prnt);
        !           718:                FREE(lzh_freq);
        !           719:                return(-1); }
        !           720: 
        !           721: #endif
        !           722: 
        !           723:        incnt=0;
        !           724:        memcpy(&textsize,inbuf,sizeof(textsize));
        !           725:        incnt+=sizeof(textsize);
        !           726:        if (textsize == 0) {
        !           727: #ifdef LZH_DYNAMIC_BUF
        !           728:                FREE(lzh_text_buf);
        !           729:                FREE(lzh_prnt);
        !           730:                FREE(lzh_freq);
        !           731:                FREE(lzh_son);
        !           732: #endif
        !           733:                return(textsize); }
        !           734:        lzh_start_huff();
        !           735:        for (i = 0; i < LZH_N - LZH_F; i++)
        !           736:                *(lzh_text_buf+i) = ' ';
        !           737:        r = LZH_N - LZH_F;
        !           738:     for (count = 0; count < textsize; ) {
        !           739:                c = lzh_decode_char(inbuf,&incnt,inlen);
        !           740:                if (c < 256) {
        !           741:                        outbuf[count]=c;
        !           742: #if 0
        !           743:                        if(r>(LZH_N + LZH_F - 1) || r<0) {
        !           744:                                printf("Overflow! (%d)\n",r);
        !           745:                                getch();
        !           746:                                exit(-1); }
        !           747: #endif
        !           748:                        *(lzh_text_buf+r) = c;
        !           749:                        r++;
        !           750:                        r &= (LZH_N - 1);
        !           751:                        count++;
        !           752:                } else {
        !           753:                        i = (r - lzh_decode_position(inbuf,&incnt,inlen) - 1)
        !           754:                                & (LZH_N - 1);
        !           755:                        j = c - 255 + LZH_THRESHOLD;
        !           756:                        for (k = 0; k < j && count<textsize; k++) {
        !           757:                                c = lzh_text_buf[(i + k) & (LZH_N - 1)];
        !           758:                                outbuf[count]=c;
        !           759: #if 0
        !           760:                                if(r>(LZH_N + LZH_F - 1) || r<0) {
        !           761:                                        printf("Overflow! (%d)\n",r);
        !           762:                                        exit(-1); }
        !           763: #endif
        !           764:                                *(lzh_text_buf+r) = c;
        !           765:                                r++;
        !           766:                                r &= (LZH_N - 1);
        !           767:                                count++;
        !           768:                        }
        !           769:                }
        !           770:        }
        !           771: /***
        !           772:        printf("%12ld\n", count);
        !           773: ***/
        !           774: 
        !           775: #ifdef LZH_DYNAMIC_BUF
        !           776:        FREE(lzh_text_buf);
        !           777:        FREE(lzh_prnt);
        !           778:        FREE(lzh_freq);
        !           779:        FREE(lzh_son);
        !           780: #endif
        !           781: 
        !           782: return(count);
        !           783: }
        !           784: 
        !           785: 

unix.superglobalmegacorp.com

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