home *** CD-ROM | disk | FTP | other *** search
/ rtsi.com / 2014.01.www.rtsi.com.tar / www.rtsi.com / OS9 / OSK / APPS / macutils.lzh / MACUTILS / MACUNPACK / sit.c < prev    next >
C/C++ Source or Header  |  1996-02-02  |  20KB  |  848 lines

  1. #include "macunpack.h"
  2. #ifdef SIT
  3. #include "globals.h"
  4. #include "sit.h"
  5. #include "crc.h"
  6. #include "../util/util.h"
  7. #include "../fileio/machdr.h"
  8. #include "../fileio/wrfile.h"
  9. #include "../fileio/kind.h"
  10. #include "../util/masks.h"
  11. #include "huffman.h"
  12.  
  13. extern void de_compress();
  14. extern void core_compress();
  15. extern void de_huffman();
  16. extern void de_huffman_end();
  17. extern void read_tree();
  18. extern void set_huffman();
  19. extern void de_lzah();
  20. extern unsigned char (*lzah_getbyte)();
  21.  
  22. typedef struct methodinfo {
  23.     char *name;
  24.     int number;
  25. };
  26.  
  27. static struct methodinfo methods[] = {
  28.     {"NoComp",  nocomp},
  29.     {"RLE",     rle},
  30.     {"LZC",     lzc},
  31.     {"Huffman", huffman},
  32.     {"LZAH",    lzah},
  33.     {"FixHuf",  fixhuf},
  34.     {"MW",      mw},
  35. };
  36. static int sit_nodeptr;
  37.  
  38. static int readsithdr();
  39. static int sit_filehdr();
  40. static int sit_valid();
  41. static int sit_checkm();
  42. static char *sit_methname();
  43. static void sit_folder();
  44. static void sit_unstuff();
  45. static void sit_wrfile();
  46. static void sit_skip();
  47. static void sit_nocomp();
  48. static void sit_rle();
  49. static void sit_lzc();
  50. static void sit_huffman();
  51. static void sit_lzah();
  52. static unsigned char sit_getbyte();
  53. static void sit_fixhuf();
  54. static void sit_dosplit();
  55. static void sit_mw();
  56. static void sit_mw_out();
  57. static int sit_mw_in();
  58.  
  59. static short code6[258] = {
  60.    1024,  512,  256,  256,  256,  256,  128,  128,
  61.     128,  128,  128,  128,  128,  128,  128,  128,
  62.     128,  128,   64,   64,   64,   64,   64,   64,
  63.      64,   64,   64,   64,   64,   64,   64,   64,
  64.      64,   64,   64,   64,   64,   64,   64,   64,
  65.      64,   64,   64,   64,   64,   64,   64,   64,
  66.      64,   64,   32,   32,   32,   32,   32,   32,
  67.      32,   32,   32,   32,   32,   32,   32,   32,
  68.      32,   32,   16,   16,   16,   16,   16,   16,
  69.      16,   16,   16,   16,   16,   16,   16,   16,
  70.      16,   16,   16,   16,   16,   16,   16,   16,
  71.      16,   16,   16,   16,   16,   16,   16,   16,
  72.      16,   16,   16,   16,   16,   16,   16,   16,
  73.      16,   16,   16,   16,   16,   16,   16,   16,
  74.      16,   16,   16,    8,    8,   16,   16,    8,
  75.       8,    8,    8,    8,    8,    8,    8,    8,
  76.       8,    8,    8,    8,    8,    8,    8,    8,
  77.       8,    8,    8,    8,    8,    8,    8,    8,
  78.       8,    8,    8,    8,    8,    8,    8,    8,
  79.       8,    8,    8,    8,    8,    8,    8,    4,
  80.       4,    4,    4,    4,    4,    4,    4,    4,
  81.       4,    4,    4,    4,    4,    4,    4,    4,
  82.       4,    4,    4,    4,    4,    4,    4,    4,
  83.       4,    4,    4,    4,    4,    4,    4,    4,
  84.       4,    4,    4,    4,    4,    4,    4,    4,
  85.       4,    4,    4,    4,    4,    4,    4,    4,
  86.       4,    4,    4,    4,    4,    4,    4,    4,
  87.       4,    4,    4,    4,    4,    4,    4,    4,
  88.       4,    4,    4,    4,    4,    4,    4,    4,
  89.       4,    4,    4,    4,    4,    4,    4,    4,
  90.       4,    4,    4,    4,    4,    4,    4,    4,
  91.       4,    4,    4,    4,    4,    4,    1,    1,
  92.       1,    1};
  93. static char sit_buffer[32768];
  94. static short sit_dict[16385];
  95. static unsigned long sit_avail;
  96. static int sit_bits_avail;
  97.  
  98. void sit()
  99. {
  100.     struct sitHdr sithdr;
  101.     struct fileHdr filehdr;
  102.     int i;
  103.  
  104.     set_huffman(HUFF_BE);
  105.     core_compress((char *)NULL);
  106.     updcrc = arc_updcrc;
  107.     crcinit = arc_crcinit;
  108.     if(readsithdr(&sithdr) == 0) {
  109.     (void)fprintf(stderr, "Can't read file header\n");
  110. #ifdef SCAN
  111.     do_error("macunpack: Can't read file header");
  112. #endif /* SCAN */
  113.     exit(1);
  114.     }
  115.  
  116.     for(i = 0; i < sithdr.numFiles; i++) {
  117.     if(sit_filehdr(&filehdr, 0) == -1) {
  118.         (void)fprintf(stderr, "Can't read file header #%d\n", i+1);
  119. #ifdef SCAN
  120.         do_error("macunpack: Can't read file header");
  121. #endif /* SCAN */
  122.         exit(1);
  123.     }
  124.     if(!sit_valid(filehdr)) {
  125.         continue;
  126.     }
  127.     if(filehdr.compRMethod == sfolder) {
  128.         sit_folder(text);
  129.     } else {
  130.         sit_unstuff(filehdr);
  131.     }
  132.     }
  133. }
  134.  
  135. static int readsithdr(s)
  136. struct sitHdr *s;
  137. {
  138.     char temp[SITHDRSIZE];
  139.  
  140.     if(fread(temp, 1, SITHDRSIZE, infp) != SITHDRSIZE) {
  141.     return 0;
  142.     }
  143.  
  144.     if(strncmp(temp + S_SIGNATURE,  "SIT!", 4) != 0 ||
  145.     strncmp(temp + S_SIGNATURE2, "rLau", 4) != 0) {
  146.     (void)fprintf(stderr, "Not a StuffIt file\n");
  147.     return 0;
  148.     }
  149.  
  150.     s->numFiles = get2(temp + S_NUMFILES);
  151.     s->arcLength = get4(temp + S_ARCLENGTH);
  152.  
  153.     return 1;
  154. }
  155.  
  156. static int sit_filehdr(f, skip)
  157. struct fileHdr *f;
  158. int skip;
  159. {
  160.     register int i;
  161.     unsigned long crc;
  162.     int n;
  163.     char hdr[FILEHDRSIZE];
  164.     char ftype[5], fauth[5];
  165.  
  166.     for(i = 0; i < INFOBYTES; i++) {
  167.     info[i] = '\0';
  168.     }
  169.     if(fread(hdr, 1, FILEHDRSIZE, infp) != FILEHDRSIZE) {
  170.     (void)fprintf(stderr, "Can't read file header\n");
  171.     return -1;
  172.     }
  173.     crc = INIT_CRC;
  174.     crc = (*updcrc)(crc, hdr, FILEHDRSIZE - 2);
  175.  
  176.     f->hdrCRC = get2(hdr + F_HDRCRC);
  177.     if(f->hdrCRC != crc) {
  178.     (void)fprintf(stderr, "Header CRC mismatch: got 0x%04x, need 0x%04x\n",
  179.         f->hdrCRC & WORDMASK, (int)crc);
  180.     return -1;
  181.     }
  182.  
  183.     n = hdr[F_FNAME] & BYTEMASK;
  184.     if(n > F_NAMELEN) {
  185.     n = F_NAMELEN;
  186.     }
  187.     info[I_NAMEOFF] = n;
  188.     copy(info + I_NAMEOFF + 1, hdr + F_FNAME + 1, n);
  189.     transname(hdr + F_FNAME + 1, text, n);
  190.  
  191.     f->compRMethod = hdr[F_COMPRMETHOD];
  192.     f->compDMethod = hdr[F_COMPDMETHOD];
  193.     f->rsrcLength = get4(hdr + F_RSRCLENGTH);
  194.     f->dataLength = get4(hdr + F_DATALENGTH);
  195.     f->compRLength = get4(hdr + F_COMPRLENGTH);
  196.     f->compDLength = get4(hdr + F_COMPDLENGTH);
  197.     f->rsrcCRC = get2(hdr + F_RSRCCRC);
  198.     f->dataCRC = get2(hdr + F_DATACRC);
  199.  
  200.     write_it = !skip;
  201.     if(list && !skip) {
  202.     if(f->compRMethod != efolder) {
  203.         do_indent(indent);
  204.     }
  205.     if(f->compRMethod == sfolder) {
  206.         (void)fprintf(stderr, "folder=\"%s\"", text);
  207.     } else if(f->compRMethod != efolder) {
  208.         transname(hdr + F_FTYPE, ftype, 4);
  209.         transname(hdr + F_CREATOR, fauth, 4);
  210.         (void)fprintf(stderr,
  211.             "name=\"%s\", type=%4.4s, author=%4.4s, data=%ld, rsrc=%ld",
  212.             text, ftype, fauth,
  213.             (long)f->dataLength, (long)f->rsrcLength);
  214.     }
  215.     if(info_only) {
  216.         write_it = 0;
  217.     }
  218.     if(f->compRMethod != efolder) {
  219.         if(query) {
  220.         write_it = do_query();
  221.         } else {
  222.         (void)fputc('\n', stderr);
  223.         }
  224.     }
  225.     }
  226.  
  227.     if(write_it) {
  228.     define_name(text);
  229.  
  230.     if(f->compRMethod != sfolder) {
  231.         copy(info + I_TYPEOFF, hdr + F_FTYPE, 4);
  232.         copy(info + I_AUTHOFF, hdr + F_CREATOR, 4);
  233.         copy(info + I_FLAGOFF, hdr + F_FNDRFLAGS, 2);
  234.         copy(info + I_DLENOFF, hdr + F_DATALENGTH, 4);
  235.         copy(info + I_RLENOFF, hdr + F_RSRCLENGTH, 4);
  236.         copy(info + I_CTIMOFF, hdr + F_CREATIONDATE, 4);
  237.         copy(info + I_MTIMOFF, hdr + F_MODDATE, 4);
  238.     }
  239.     }
  240.     return 1;
  241. }
  242.  
  243. static int sit_valid(f)
  244. struct fileHdr f;
  245. {
  246.     int fr = f.compRMethod, fd = f.compDMethod;
  247.  
  248.     if(fr == sfolder || fr == efolder) {
  249.     return 1;
  250.     }
  251.     if((fr & prot) || (fd & prot)) {
  252.     (void)fprintf(stderr, "\tFile is password protected");
  253. #ifdef SCAN
  254.     do_idf("", PROTECTED);
  255. #endif /* SCAN */
  256.     } else if(fr >= prot || fd >= prot) {
  257.     (void)fprintf(stderr, "\tUnknown stuffit flags: %x %x", fr, fd);
  258. #ifdef SCAN
  259.     do_idf("", UNKNOWN);
  260. #endif /* SCAN */
  261.     } else if(((1 << fr) & sknown) && ((1 << fd) & sknown)) {
  262.     if(sit_checkm(fr) && sit_checkm(fd)) {
  263.         return 1;
  264.     }
  265.     if(!sit_checkm(fr)) {
  266.         (void)fprintf(stderr, "\tMethod \"%s\" not implemented",
  267.             sit_methname(fr));
  268.     } else {
  269.         (void)fprintf(stderr, "\tMethod \"%s\" not implemented",
  270.             sit_methname(fd));
  271.     }
  272. #ifdef SCAN
  273.     do_idf("", UNKNOWN);
  274. #endif /* SCAN */
  275.     } else {
  276.     (void)fprintf(stderr, "\tUnknown compression methods: %x %x", fr, fd);
  277. #ifdef SCAN
  278.     do_idf("", UNKNOWN);
  279. #endif /* SCAN */
  280.     }
  281.     (void)fprintf(stderr, ", skipping file.\n");
  282.     sit_skip(f.compRLength);
  283.     sit_skip(f.compDLength);
  284.     return 0;
  285. }
  286.  
  287. static int sit_checkm(f)
  288. int f;
  289. {
  290.     switch(f) {
  291.     case nocomp:
  292.     return 1;
  293.     case rle:
  294.     return 1;
  295.     case lzc:
  296.     return 1;
  297.     case huffman:
  298.     return 1;
  299.     case lzah:
  300.     return 1;
  301.     case fixhuf:
  302.     return 1;
  303.     case mw:
  304.     return 1;
  305.     default:
  306.     return 0;
  307.     }
  308.     /* NOTREACHED */
  309. }
  310.  
  311. static char *sit_methname(n)
  312. int n;
  313. {
  314. int i, nmeths;
  315.     nmeths = sizeof(methods) / sizeof(struct methodinfo);
  316.     for(i = 0; i < nmeths; i++) {
  317.     if(methods[i].number == n) {
  318.         return methods[i].name;
  319.     }
  320.     }
  321.     return NULL;
  322. }
  323.  
  324. static void sit_folder(name)
  325. char *name;
  326. {
  327.     int i, recurse;
  328.     char loc_name[64];
  329.     struct fileHdr filehdr;
  330.  
  331.     for(i = 0; i < 64; i++) {
  332.     loc_name[i] = name[i];
  333.     }
  334.     if(write_it || info_only) {
  335.     if(write_it) {
  336.         do_mkdir(text, info);
  337.     }
  338.     indent++;
  339.     while(1) {
  340.         if(sit_filehdr(&filehdr, 0) == -1) {
  341.         (void)fprintf(stderr, "Can't read file header #%d\n", i+1);
  342. #ifdef SCAN
  343.         do_error("macunpack: Can't read file header");
  344. #endif /* SCAN */
  345.         exit(1);
  346.         }
  347.         if(!sit_valid(filehdr)) {
  348.         continue;
  349.         }
  350.         if(filehdr.compRMethod == sfolder) {
  351.         sit_folder(text);
  352.         } else if(filehdr.compRMethod == efolder) {
  353.         break;
  354.         } else {
  355.         sit_unstuff(filehdr);
  356.         }
  357.     }
  358.     if(write_it) {
  359.         enddir();
  360.     }
  361.     indent--;
  362.     if(list) {
  363.         do_indent(indent);
  364.         (void)fprintf(stderr, "leaving folder \"%s\"\n", loc_name);
  365.     }
  366.     } else {
  367.     recurse = 0;
  368.     while(1) {
  369.         if(sit_filehdr(&filehdr, 1) == -1) {
  370.         (void)fprintf(stderr, "Can't read file header #%d\n", i+1);
  371. #ifdef SCAN
  372.         do_error("macunpack: Can't read file header");
  373. #endif /* SCAN */
  374.         exit(1);
  375.         }
  376.         if(filehdr.compRMethod == sfolder) {
  377.         recurse++;
  378.         } else if(filehdr.compRMethod == efolder) {
  379.         recurse--;
  380.         if(recurse < 0) {
  381.             break;
  382.         }
  383.         } else {
  384.         sit_skip(filehdr.compRLength);
  385.         sit_skip(filehdr.compDLength);
  386.         }
  387.     }
  388.     }
  389. }
  390.  
  391. static void sit_unstuff(filehdr)
  392. struct fileHdr filehdr;
  393. {
  394.     unsigned long crc;
  395.  
  396.     if(write_it) {
  397.     start_info(info, filehdr.rsrcLength, filehdr.dataLength);
  398.     }
  399.     if(verbose) {
  400.     (void)fprintf(stderr, "\tRsrc: ");
  401.     }
  402.     if(write_it) {
  403.     start_rsrc();
  404.     }
  405.     sit_wrfile(filehdr.compRLength, filehdr.rsrcLength, filehdr.compRMethod);
  406.     if(write_it) {
  407.     crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.rsrcLength);
  408.     if(filehdr.rsrcCRC != crc) {
  409.         (void)fprintf(stderr,
  410.         "CRC error on resource fork: need 0x%04x, got 0x%04x\n",
  411.         filehdr.rsrcCRC, (int)crc);
  412. #ifdef SCAN
  413.         do_error("macunpack: CRC error on resource fork");
  414. #endif /* SCAN */
  415.         exit(1);
  416.     }
  417.     }
  418.     if(verbose) {
  419.     (void)fprintf(stderr, ", Data: ");
  420.     }
  421.     if(write_it) {
  422.     start_data();
  423.     }
  424.     sit_wrfile(filehdr.compDLength, filehdr.dataLength, filehdr.compDMethod);
  425.     if(write_it) {
  426.     crc = (*updcrc)(INIT_CRC, out_buffer, filehdr.dataLength);
  427.     if(filehdr.dataCRC != crc) {
  428.         (void)fprintf(stderr,
  429.         "CRC error on data fork: need 0x%04x, got 0x%04x\n",
  430.         filehdr.dataCRC, (int)crc);
  431. #ifdef SCAN
  432.         do_error("macunpack: CRC error on data fork");
  433. #endif /* SCAN */
  434.         exit(1);
  435.     }
  436.     end_file();
  437.     }
  438.     if(verbose) {
  439.     (void)fprintf(stderr, ".\n");
  440.     }
  441. }
  442.  
  443. static void sit_wrfile(ibytes, obytes, type)
  444. unsigned long ibytes, obytes;
  445. unsigned char type;
  446. {
  447.     if(ibytes == 0) {
  448.     if(verbose) {
  449.         (void)fprintf(stderr, "empty");
  450.     }
  451.     return;
  452.     }
  453.     switch(type) {
  454.     case nocomp:        /* no compression */
  455.     if(verbose) {
  456.         (void)fprintf(stderr, "No compression");
  457.     }
  458.     if(write_it) {
  459.         sit_nocomp(ibytes);
  460.     } else {
  461.         sit_skip(ibytes);
  462.     }
  463.     break;
  464.     case rle:        /* run length encoding */
  465.     if(verbose) {
  466.         (void)fprintf(stderr,
  467.             "RLE compressed (%4.1f%%)", 100.0 * ibytes / obytes);
  468.     }
  469.     if(write_it) {
  470.         sit_rle(ibytes);
  471.     } else {
  472.         sit_skip(ibytes);
  473.     }
  474.     break;
  475.     case lzc:            /* LZC compression */
  476.     if(verbose) {
  477.         (void)fprintf(stderr,
  478.             "LZC compressed (%4.1f%%)", 100.0 * ibytes / obytes);
  479.     }
  480.     if(write_it) {
  481.         sit_lzc(ibytes);
  482.     } else {
  483.         sit_skip(ibytes);
  484.     }
  485.     break;
  486.     case huffman:        /* Huffman compression */
  487.     if(verbose) {
  488.         (void)fprintf(stderr,
  489.             "Huffman compressed (%4.1f%%)", 100.0 * ibytes / obytes);
  490.     }
  491.     if(write_it) {
  492.         sit_huffman(obytes);
  493.     } else {
  494.         sit_skip(ibytes);
  495.     }
  496.     break;
  497.     case lzah:            /* LZAH compression */
  498.     if(verbose) {
  499.         (void)fprintf(stderr,
  500.             "LZAH compressed (%4.1f%%)", 100.0 * ibytes / obytes);
  501.     }
  502.     if(write_it) {
  503.         sit_lzah(obytes);
  504.     } else {
  505.         sit_skip(ibytes);
  506.     }
  507.     break;
  508.     case fixhuf:        /* FixHuf compression */
  509.     if(verbose) {
  510.         (void)fprintf(stderr,
  511.             "FixHuf compressed (%4.1f%%)", 100.0 * ibytes / obytes);
  512.     }
  513.     if(write_it) {
  514.         sit_fixhuf(ibytes);
  515.     } else {
  516.         sit_skip(ibytes);
  517.     }
  518.     break;
  519.     case mw:            /* MW compression */
  520.     if(verbose) {
  521.         (void)fprintf(stderr,
  522.             "MW compressed (%4.1f%%)", 100.0 * ibytes / obytes);
  523.     }
  524.     if(write_it) {
  525.         sit_mw(ibytes);
  526.     } else {
  527.         sit_skip(ibytes);
  528.     }
  529.     break;
  530.     default:
  531.     (void)fprintf(stderr, "Unknown compression method %2x\n", type);
  532. #ifdef SCAN
  533.     do_idf("", UNKNOWN);
  534. #endif /* SCAN */
  535.     exit(1);
  536.     }
  537. }
  538.  
  539. /* skip stuffit file */
  540. static void sit_skip(ibytes)
  541. unsigned long ibytes;
  542. {
  543.     while(ibytes != 0) {
  544.     if(getc(infp) == EOF) {
  545.         (void)fprintf(stderr, "Premature EOF\n");
  546. #ifdef SCAN
  547.         do_error("macunpack: Premature EOF");
  548. #endif /* SCAN */
  549.         exit(1);
  550.     }
  551.     ibytes--;
  552.     }
  553. }
  554.  
  555. /*---------------------------------------------------------------------------*/
  556. /*    Method 0: No compression                         */
  557. /*---------------------------------------------------------------------------*/
  558. static void sit_nocomp(ibytes)
  559. unsigned long ibytes;
  560. {
  561.     int n;
  562.  
  563.     n = fread(out_buffer, 1, (int)ibytes, infp);
  564.     if(n != ibytes) {
  565.     (void)fprintf(stderr, "Premature EOF\n");
  566. #ifdef SCAN
  567.     do_error("macunpack: Premature EOF");
  568. #endif /* SCAN */
  569.     exit(1);
  570.     }
  571. }
  572.  
  573. /*---------------------------------------------------------------------------*/
  574. /*    Method 1: Run length encoding                         */
  575. /*---------------------------------------------------------------------------*/
  576. static void sit_rle(ibytes)
  577. unsigned long ibytes;
  578. {
  579.     int ch, lastch, n, i;
  580.  
  581.     while(ibytes != 0) {
  582.     ch = getb(infp) & BYTEMASK;
  583.     ibytes--;
  584.     if(ch == ESC) {
  585.         n = (getb(infp) & BYTEMASK) - 1;
  586.         ibytes--;
  587.         if(n < 0) {
  588.         *out_ptr++ = ESC;
  589.         lastch = ESC;
  590.         n = 1;
  591.         } else {
  592.         for(i = 0; i < n; i++) {
  593.             *out_ptr++ = lastch;
  594.         }
  595.         }
  596.     } else {
  597.         *out_ptr++ = ch;
  598.         lastch = ch;
  599.     }
  600.     }
  601. }
  602.  
  603. /*---------------------------------------------------------------------------*/
  604. /*    Method 2: LZC compressed                         */
  605. /*---------------------------------------------------------------------------*/
  606. static void sit_lzc(ibytes)
  607. unsigned long ibytes;
  608. {
  609.     de_compress(ibytes, 14);
  610. }
  611.  
  612. /*---------------------------------------------------------------------------*/
  613. /*    Method 3: Huffman compressed                         */
  614. /*---------------------------------------------------------------------------*/
  615. static void sit_huffman(obytes)
  616. unsigned long obytes;
  617. {
  618.     read_tree();
  619.     de_huffman(obytes);
  620. }
  621.  
  622. /*---------------------------------------------------------------------------*/
  623. /*    Method 5: LZ compression plus adaptive Huffman encoding             */
  624. /*---------------------------------------------------------------------------*/
  625. static void sit_lzah(obytes)
  626. unsigned long obytes;
  627. {
  628.     lzah_getbyte = sit_getbyte;
  629.     de_lzah(obytes);
  630. }
  631.  
  632. static unsigned char sit_getbyte()
  633. {
  634.     return getb(infp);
  635. }
  636.  
  637. /*---------------------------------------------------------------------------*/
  638. /*    Method 6: Compression with a fixed Huffman encoding             */
  639. /*---------------------------------------------------------------------------*/
  640. static void sit_fixhuf(ibytes)
  641. unsigned long ibytes;
  642. {
  643.     int i, sum, codes, sym, num;
  644.     char byte_int[4], byte_short[2];
  645.     long size;
  646.     int sign;
  647.     char *tmp_ptr, *ptr, *end_ptr;
  648.  
  649.     sum = 0;
  650.     for(i = 0; i < 258; i++) {
  651.     sum += code6[i];
  652.     nodelist[i + 1].flag = 1;
  653.     }
  654.     sit_nodeptr = 258;
  655.     sit_dosplit(0, sum, 1, 258);
  656.     while(ibytes > 0) {
  657.     if(fread(byte_int, 1, 4, infp) != 4) {
  658.         (void)fprintf(stderr, "Premature EOF\n");
  659. #ifdef SCAN
  660.         do_error("Premature EOF");
  661. #endif /* SCAN */
  662.         exit(1);
  663.     }
  664.     ibytes -= 4;
  665.     size = (long)get4(byte_int);
  666.     sign = 0;
  667.     if(size < 0) {
  668.         size = - size;
  669.         sign = 1;
  670.     }
  671.     size -= 4;
  672.     if(sign) {
  673.         ibytes -= size;
  674.         if(fread(sit_buffer, 1, (int)size, infp) != size) {
  675.         (void)fprintf(stderr, "Premature EOF\n");
  676. #ifdef SCAN
  677.         do_error("Premature EOF");
  678. #endif /* SCAN */
  679.         exit(1);
  680.         }
  681.     } else {
  682.         ibytes -= size;
  683.         if(fread(byte_int, 1, 4, infp) != 4) {
  684.         (void)fprintf(stderr, "Premature EOF\n");
  685. #ifdef SCAN
  686.         do_error("Premature EOF");
  687. #endif /* SCAN */
  688.         exit(1);
  689.         }
  690.         size -= 4;
  691.         if(fread(byte_short, 1, 2, infp) != 2) {
  692.         (void)fprintf(stderr, "Premature EOF\n");
  693. #ifdef SCAN
  694.         do_error("Premature EOF");
  695. #endif /* SCAN */
  696.         exit(1);
  697.         }
  698.         size -= 2;
  699.         codes = get2(byte_short);
  700.         for(i = 1; i <= codes; i++) {
  701.         nodelist[i].byte = getb(infp);
  702.         }
  703.         size -= codes;
  704.         clrhuff();
  705.         nodelist[257].byte = 0x100;
  706.         nodelist[258].byte = 0x100;
  707.         tmp_ptr = out_ptr;
  708.         out_ptr = &(sit_buffer[0]);
  709.         bytesread = 0;
  710.         de_huffman_end(0x100);
  711.         while(bytesread < size) {
  712.         (void)getb(infp);
  713.         bytesread++;
  714.         }
  715.         size = get4(byte_int);
  716.         out_ptr = tmp_ptr;
  717.     }
  718.     ptr = sit_buffer;
  719.     end_ptr = ptr + size;
  720.     while(ptr < end_ptr) {
  721.         num = *ptr++ & BYTEMASK;
  722.         if(num < 0x80) {
  723.         while(num-- >= 0) {
  724.             *out_ptr++ = *ptr++;
  725.         }
  726.         } else if(num != 0x80) {
  727.         sym = *ptr++;
  728.         while(num++ <= 0x100) {
  729.             *out_ptr++ = sym;
  730.         }
  731.         }
  732.     }
  733.     }
  734. }
  735.  
  736. static void sit_dosplit(ptr, sum, low, upp)
  737. int ptr, sum, low, upp;
  738. {
  739.     int i, locsum;
  740.  
  741.     sum = sum / 2;
  742.     locsum = 0;
  743.     i = low;
  744.     while(locsum < sum) {
  745.     locsum += code6[i++ - 1];
  746.     }
  747.     if(low == i - 1) {
  748.     nodelist[ptr].zero = nodelist + low;
  749.     } else {
  750.     nodelist[ptr].zero = nodelist + ++sit_nodeptr;
  751.     sit_dosplit(sit_nodeptr, sum, low, i - 1);
  752.     }
  753.     if(upp == i) {
  754.     nodelist[ptr].one = nodelist + upp;
  755.     } else {
  756.     nodelist[ptr].one = nodelist + ++sit_nodeptr;
  757.     sit_dosplit(sit_nodeptr, sum, i, upp);
  758.     }
  759. }
  760.  
  761. /*---------------------------------------------------------------------------*/
  762. /*    Method 8: Compression with a MW encoding                 */
  763. /*---------------------------------------------------------------------------*/
  764. static void sit_mw(ibytes)
  765. unsigned long ibytes;
  766. {
  767.     int ptr;
  768.     int max, max1, bits;
  769.     char *out_buf;
  770.  
  771.     out_buf = out_buffer;
  772.     sit_bits_avail = 0;
  773.     sit_avail = 0;
  774. start_over:
  775.     max = 256;
  776.     max1 = max + max;
  777.     bits = 9;
  778.     ptr = sit_mw_in(bits, &ibytes);
  779.     if(ptr == max) {
  780.     goto start_over;
  781.     }
  782.     if(ptr > max || ptr < 0) {
  783.     out_buffer = out_buf;
  784.     return;
  785.     }
  786.     sit_dict[255] = ptr;
  787.     sit_mw_out(ptr);
  788.     while(1) {
  789.     ptr = sit_mw_in(bits, &ibytes);
  790.     if(ptr == max) {
  791.         goto start_over;
  792.     }
  793.     if(ptr > max || ptr < 0) {
  794.         out_buffer = out_buf;
  795.         return;
  796.     }
  797.     sit_dict[max++] = ptr;
  798.     if(max == max1) {
  799.         max1 <<= 1;
  800.         bits++;
  801.     }
  802.     sit_mw_out(ptr);
  803.     }
  804. }
  805.  
  806. static void sit_mw_out(ptr)
  807. int ptr;
  808. {
  809.     int stack_ptr;
  810.     int stack[16384];
  811.  
  812.     stack_ptr = 1;
  813.     stack[0] = ptr;
  814.     while(stack_ptr) {
  815.     ptr = stack[--stack_ptr];
  816.     while(ptr >= 256) {
  817.         stack[stack_ptr++] = sit_dict[ptr];
  818.         ptr = sit_dict[ptr - 1];
  819.     }
  820.     *out_buffer++ = ptr;
  821.     }
  822. }
  823.  
  824. static int sit_mw_in(bits, ibytes)
  825. int bits;
  826. unsigned long *ibytes;
  827. {
  828.     int res, res1;
  829.  
  830.     while(bits > sit_bits_avail) {
  831.     if(*ibytes == 0) {
  832.         return -1;
  833.     }
  834.     (*ibytes)--;
  835.     sit_avail += (getb(infp) & BYTEMASK) << sit_bits_avail;
  836.     sit_bits_avail += 8;
  837.     }
  838.     res1 = sit_avail >> bits;
  839.     res = sit_avail ^ (res1 << bits);
  840.     sit_avail = res1;
  841.     sit_bits_avail -= bits;
  842.     return res;
  843. }
  844.  
  845. #else /* SIT */
  846. int sit; /* keep lint and some compilers happy */
  847. #endif /* SIT */
  848.