home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 28 / amigaformatcd28.iso / -seriously_amiga- / archivers / arcppc / src / rcs / arcpack.c,v < prev    next >
Text File  |  1998-04-23  |  15KB  |  715 lines

  1. head     1.11;
  2. branch   ;
  3. access   ;
  4. symbols  patch1:1.11;
  5. locks    ; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.11
  10. date     88.07.31.18.52.08;  author hyc;  state Exp;
  11. branches ;
  12. next     1.10;
  13.  
  14. 1.10
  15. date     88.07.05.16.56.02;  author hyc;  state Exp;
  16. branches ;
  17. next     1.9;
  18.  
  19. 1.9
  20. date     88.06.02.16.27.36;  author hyc;  state Exp;
  21. branches ;
  22. next     1.8;
  23.  
  24. 1.8
  25. date     88.06.02.00.51.05;  author hyc;  state Exp;
  26. branches ;
  27. next     1.7;
  28.  
  29. 1.7
  30. date     88.06.01.19.57.05;  author hyc;  state Exp;
  31. branches ;
  32. next     1.6;
  33.  
  34. 1.6
  35. date     88.06.01.18.10.51;  author hyc;  state Exp;
  36. branches ;
  37. next     1.5;
  38.  
  39. 1.5
  40. date     88.06.01.16.09.00;  author hyc;  state Exp;
  41. branches ;
  42. next     1.4;
  43.  
  44. 1.4
  45. date     88.06.01.14.45.52;  author hyc;  state Exp;
  46. branches ;
  47. next     1.3;
  48.  
  49. 1.3
  50. date     88.04.11.18.57.00;  author hyc;  state Exp;
  51. branches ;
  52. next     1.2;
  53.  
  54. 1.2
  55. date     88.04.11.18.38.15;  author hyc;  state Exp;
  56. branches ;
  57. next     1.1;
  58.  
  59. 1.1
  60. date     88.04.11.18.27.10;  author hyc;  state Exp;
  61. branches ;
  62. next     ;
  63.  
  64.  
  65. desc
  66. @@
  67.  
  68.  
  69. 1.11
  70. log
  71. @Fix declarations, fix bomb after storing zero length files
  72. @
  73. text
  74. @/*
  75.  * $Header: arcpack.c,v 1.10 88/07/05 16:56:02 hyc Locked $
  76.  */
  77.  
  78. /*  ARC - Archive utility - ARCPACK
  79.  
  80.     Version 3.49, created on 04/21/87 at 11:26:51
  81.  
  82. (C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
  83.  
  84.     By:     Thom Henderson
  85.  
  86.     Description:
  87.      This file contains the routines used to compress a file
  88.      when placing it in an archive.
  89.  
  90.     Language:
  91.      Computer Innovations Optimizing C86
  92. */
  93. #include <stdio.h>
  94. #include "arc.h"
  95. #if    MTS
  96. #include <ctype.h>
  97. #endif
  98.  
  99. void    setcode(), sqinit_cm(), sqputc_cm(), init_cm(), putc_cm();
  100. void    filecopy(), abort(), putc_tst(), init_sq(), scan_sq();
  101. int    getch(), addcrc();
  102.  
  103. /* stuff for non-repeat packing */
  104.  
  105. #define DLE 0x90        /* repeat sequence marker */
  106.  
  107. static unsigned char state;    /* current packing state */
  108.  
  109. /* non-repeat packing states */
  110.  
  111. #define NOHIST  0        /* don't consider previous input */
  112. #define SENTCHAR 1        /* lastchar set, no lookahead yet */
  113. #define SENDNEWC 2        /* run over, send new char next */
  114. #define SENDCNT 3        /* newchar set, send count next */
  115.  
  116. /* packing results */
  117.  
  118. static long     stdlen;        /* length for standard packing */
  119. static short    crcval;        /* CRC check value */
  120.  
  121. void
  122. pack(f, t, hdr)            /* pack file into an archive */
  123.     FILE           *f, *t;    /* source, destination */
  124.     struct heads   *hdr;    /* pointer to header data */
  125. {
  126.     int             c;    /* one character of stream */
  127.     long            ncrlen;    /* length after packing */
  128.     long        huflen;    /* length after squeezing */
  129.     long            lzwlen;    /* length after crunching */
  130.     long        pred_sq(), file_sq();    /* stuff for squeezing */
  131.     long            pred_cm(), sqpred_cm();    /* dynamic crunching cleanup */
  132.     long            tloc, ftell();    /* start of output */
  133.     int        getch();
  134.     int             getc_ncr();
  135.     void            putc_pak();
  136.  
  137.     /* first pass - see which method is best */
  138.  
  139.     tloc = ftell(t);    /* note start of output */
  140.  
  141.     if (!nocomp) {        /* if storage kludge not active */
  142.         if (note) {
  143.             printf(" analyzing, ");
  144.             fflush(stdout);
  145.         }
  146.         state = NOHIST;    /* initialize ncr packing */
  147.         stdlen = ncrlen = 0;    /* reset size counters */
  148.         crcval = 0;    /* initialize CRC check value */
  149.         setcode();    /* initialize encryption */
  150.         init_sq();    /* initialize for squeeze scan */
  151.  
  152.         if (dosquash) {
  153.             sqinit_cm();
  154.             while ((c = getch(f)) != EOF) {    /* for each byte of file */
  155.                 ncrlen++;    /* one more packed byte */
  156.                 scan_sq(c);    /* see what squeezing can do */
  157.                 sqputc_cm(c, t);    /* see what squashing
  158.                              * can do */
  159.             }
  160.             lzwlen = sqpred_cm(t);
  161.         } else {
  162.             init_cm(t);    /* initialize for crunching */
  163.     
  164.             while ((c = getc_ncr(f)) != EOF) {    /* for each byte of file */
  165.                 ncrlen++;    /* one more packed byte */
  166.                 scan_sq(c);    /* see what squeezing can do */
  167.                 putc_cm(c, t);    /* see what crunching can do */
  168.             }
  169.             lzwlen = pred_cm(t);    /* finish up after crunching */
  170.         }
  171.         huflen = pred_sq();    /* finish up after squeezing */
  172.     } else {        /* else kludge the method */
  173.         stdlen = 0;    /* make standard look best */
  174.         ncrlen = huflen = lzwlen = 1;
  175.     }
  176.  
  177.     /* standard set-ups common to all methods */
  178.  
  179.     fseek(f, 0L, 0);    /* rewind input */
  180.     hdr->crc = crcval;    /* note CRC check value */
  181.     hdr->length = stdlen;    /* set actual file length */
  182.     state = NOHIST;        /* reinitialize ncr packing */
  183.     setcode();        /* reinitialize encryption */
  184.  
  185.     /* choose and use the shortest method */
  186.  
  187.     if (kludge && note)
  188.         printf("\n\tS:%ld  P:%ld  S:%ld  C:%ld,\t ",
  189.             stdlen, ncrlen, huflen, lzwlen);
  190.  
  191.     if (stdlen <= ncrlen && stdlen <= huflen && stdlen <= lzwlen) {
  192.         if (note) {
  193.             printf("storing, ");    /* store without compression */
  194.             fflush(stdout);
  195.         }
  196.         hdrver = 2;    /* note packing method */
  197.         fseek(t, tloc, 0);    /* reset output for new method */
  198.         stdlen = crcval = 0;    /* recalc these for kludge */
  199.         while ((c = getch(f)) != EOF)    /* store it straight */
  200.             putc_pak(c, t);
  201.         hdr->crc = crcval;
  202.         hdr->length = hdr->size = stdlen;
  203.     } else if (ncrlen < lzwlen && ncrlen < huflen) {
  204.         if (note) {
  205.             printf("packing, ");    /* pack with repeat
  206.             fflush(stdout);         * suppression */
  207.         }
  208.         hdrver = 3;    /* note packing method */
  209.         hdr->size = ncrlen;    /* set data length */
  210.         fseek(t, tloc, 0);    /* reset output for new method */
  211.         while ((c = getc_ncr(f)) != EOF)
  212.             putc_pak(c, t);
  213.     } else if (huflen < lzwlen) {
  214.         if (note) {
  215.             printf("squeezing, ");
  216.             fflush(stdout);
  217.         }
  218.         hdrver = 4;    /* note packing method */
  219.         fseek(t, tloc, 0);    /* reset output for new method */
  220.         hdr->size = file_sq(f, t);    /* note final size */
  221.     } else {
  222.         if (note)
  223.             printf(dosquash ? "squashed, " : "crunched, ");
  224.         hdrver = dosquash ? 9 : 8;
  225.         hdr->size = lzwlen;    /* size should not change */
  226.     }
  227.  
  228.     /* standard cleanups common to all methods */
  229.  
  230.     if (note)
  231.         printf("done. (%ld%%)\n",hdr->length == 0 ?
  232.                 0L : 100L - (100L*hdr->size)/hdr->length);
  233. }
  234.  
  235. /*
  236.  * Non-repeat compression - text is passed through normally, except that a
  237.  * run of more than two is encoded as:
  238.  * 
  239.  * <char> <DLE> <count>
  240.  * 
  241.  * Special case: a count of zero indicates that the DLE is really a DLE, not a
  242.  * repeat marker.
  243.  */
  244.  
  245. int
  246. getc_ncr(f)            /* get bytes with collapsed runs */
  247.     FILE           *f;    /* file to get from */
  248. {
  249.     static int      lastc;    /* value returned on last call */
  250.     static int      repcnt;    /* repetition counter */
  251.     static int      c;    /* latest value seen */
  252.  
  253.     switch (state) {    /* depends on our state */
  254.     case NOHIST:        /* no relevant history */
  255.         state = SENTCHAR;
  256.         return lastc = getch(f);    /* remember the value next
  257.                          * time */
  258.  
  259.     case SENTCHAR:        /* char was sent. look ahead */
  260.         switch (lastc) {/* action depends on char */
  261.         case DLE:    /* if we sent a real DLE */
  262.             state = NOHIST;    /* then start over again */
  263.             return 0;    /* but note that the DLE was real */
  264.  
  265.         case EOF:    /* EOF is always a special case */
  266.             return EOF;
  267.  
  268.         default:    /* else test for a repeat */
  269.             for (repcnt = 1; (c = getch(f)) == lastc && repcnt < 255; repcnt++);
  270.             /* find end of run */
  271.  
  272.             switch (repcnt) {    /* action depends on run size */
  273.             case 1:/* not a repeat */
  274.                 return lastc = c;    /* but remember value
  275.                              * next time */
  276.  
  277.             case 2:/* a repeat, but too short */
  278.                 state = SENDNEWC;    /* send the second one
  279.                              * next time */
  280.                 return lastc;
  281.  
  282.             default:    /* a run - compress it */
  283.                 state = SENDCNT;    /* send repeat count
  284.                              * next time */
  285.                 return DLE;    /* send repeat marker this
  286.                          * time */
  287.             }
  288.         }
  289.  
  290.     case SENDNEWC:        /* send second char of short run */
  291.         state = SENTCHAR;
  292.         return lastc = c;
  293.  
  294.     case SENDCNT:        /* sent DLE, now send count */
  295.         state = SENDNEWC;
  296.         return repcnt;
  297.  
  298.     default:
  299.         abort("Bug - bad ncr state\n");
  300.     }
  301. }
  302.  
  303. int
  304. getch(f)            /* special get char for packing */
  305.     FILE           *f;    /* file to get from */
  306. {
  307.     int        c;    /* a char from the file */
  308. #if    !DOS
  309.     static int      cr = 0;    /* add \r before \n ? */
  310.  
  311.     if (cr) {
  312.         c = '\n';
  313. #if    MTS
  314.         c = toascii(c);
  315. #endif
  316.         crcval = addcrc(crcval, c);
  317.         stdlen++;
  318.         cr = 0;
  319.         return (c);
  320.     }
  321. #endif
  322.  
  323.     if ((c = fgetc(f)) != EOF) {    /* if not the end of file */
  324. #if    !DOS
  325.         if (!image && (c == '\n')) {
  326.             c = '\r';
  327.             cr = 1;
  328.         }
  329. #endif
  330. #if    MTS
  331.         if (!image)
  332.             c = toascii(c);
  333. #endif
  334.         crcval = addcrc(crcval, c);    /* then update CRC check
  335.                          * value */
  336.         stdlen++;    /* and bump length counter */
  337.     }
  338.     return c;
  339. }
  340.  
  341. void
  342. putc_pak(c, f)            /* put a packed byte into archive */
  343.     char            c;    /* byte to put */
  344.     FILE           *f;    /* archive to put it in */
  345. {
  346.     unsigned char        code();
  347.     putc_tst(code(c), f);    /* put encoded byte, with checks */
  348. }
  349. @
  350.  
  351.  
  352. 1.10
  353. log
  354. @Fix printout problem when storing zero length files.
  355. @
  356. text
  357. @d2 1
  358. a2 1
  359.  * $Header: arcpack.c,v 1.9 88/06/02 16:27:36 hyc Locked $
  360. d27 1
  361. a27 1
  362. void    filecopy(), abort(), putc_tst();
  363. a156 3
  364.     if (!hdr->length)    /* oops. zero length files bombed... */
  365.         hdr->length=hdr->size=1;
  366.  
  367. d158 2
  368. a159 1
  369.         printf("done. (%ld%%)\n",100L - (100L*hdr->size)/hdr->length);
  370. @
  371.  
  372.  
  373. 1.9
  374. log
  375. @Minor fixes & speedups
  376. @
  377. text
  378. @d2 1
  379. a2 1
  380.  * $Header: arcpack.c,v 1.8 88/06/02 00:51:05 hyc Locked $
  381. d156 3
  382. @
  383.  
  384.  
  385. 1.8
  386. log
  387. @Re-introduce Huffman Squeezing
  388. @
  389. text
  390. @d2 1
  391. a2 1
  392.  * $Header: arcpack.c,v 1.7 88/06/01 19:57:05 hyc Locked $
  393. a59 2
  394.     char        tnam[STRLEN];    /* temporary name buffer */
  395.     FILE           *crn = NULL;    /* temporary crunch file */
  396. a72 2
  397.         sprintf(tnam, "%s.CRN", arctemp);
  398.         crn = fopen(tnam, "w+b");
  399. d84 1
  400. a84 1
  401.                 sqputc_cm(c, crn);    /* see what squashing
  402. d87 1
  403. a87 1
  404.             lzwlen = sqpred_cm(crn);
  405. d89 1
  406. a89 1
  407.             init_cm(crn);    /* initialize for crunching */
  408. d94 1
  409. a94 1
  410.                 putc_cm(c, crn);    /* see what crunching can do */
  411. d96 1
  412. a96 1
  413.             lzwlen = pred_cm(crn);    /* finish up after crunching */
  414. d115 1
  415. a115 1
  416.         printf("\n\tS:%ld  P:%ld  S: %ld C:%ld,\t ",
  417. d118 1
  418. a118 1
  419.     if (stdlen <= ncrlen && stdlen <= lzwlen && stdlen <= huflen) {
  420. d146 1
  421. d149 2
  422. a150 4
  423.         if (note) {
  424.             printf(dosquash ? "squashing, " : "crunching, ");
  425.             fflush(stdout);
  426.         }
  427. a152 2
  428.         fseek(crn, 0L, 0);
  429.         filecopy(crn, t, lzwlen);
  430. a155 8
  431.  
  432.     if (crn) {
  433.         fclose(crn);
  434.         if(unlink(tnam) && warn) {
  435.             printf("Cannot delete temporary file %s\n", tnam);
  436.             nerrs++;
  437.         }
  438.     }
  439. @
  440.  
  441.  
  442. 1.7
  443. log
  444. @Changed compilation conditionals
  445. @
  446. text
  447. @d2 1
  448. a2 1
  449.  * $Header: arcpack.c,v 1.6 88/06/01 18:10:51 hyc Locked $
  450. d55 1
  451. d57 1
  452. d60 2
  453. d75 2
  454. d81 1
  455. d87 2
  456. a88 1
  457.                 sqputc_cm(c, t);    /* see what squashing
  458. d91 1
  459. a91 1
  460.             lzwlen = sqpred_cm(t);
  461. d93 1
  462. a93 1
  463.             init_cm(t);    /* initialize for crunching */
  464. d97 2
  465. a98 1
  466.                 putc_cm(c, t);    /* see what crunching can do */
  467. d100 1
  468. a100 1
  469.             lzwlen = pred_cm(t);    /* finish up after crunching */
  470. d102 1
  471. d105 1
  472. a105 1
  473.         ncrlen = lzwlen = 1;
  474. d119 2
  475. a120 1
  476.         printf("\n\tS:%ld  P:%ld  C:%ld,\t ", stdlen, ncrlen, lzwlen);
  477. d122 1
  478. a122 1
  479.     if (stdlen <= ncrlen && stdlen <= lzwlen) {
  480. d134 2
  481. a135 2
  482.     } else if (ncrlen < lzwlen) {
  483.         if (note)
  484. d137 2
  485. a138 1
  486.                          * suppression */
  487. d144 7
  488. d152 4
  489. a155 2
  490.         if (note)
  491.             printf(dosquash ? "squashed, " : "crunched, ");
  492. d158 2
  493. d163 8
  494. @
  495.  
  496.  
  497. 1.6
  498. log
  499. @Merge ARC 5.21 changes
  500. @
  501. text
  502. @d2 1
  503. a2 1
  504.  * $Header: arcpack.c,v 1.5 88/06/01 16:09:00 hyc Locked $
  505. d22 1
  506. a22 1
  507. #ifdef MTS
  508. d218 1
  509. a218 1
  510. #ifndef DOS
  511. d223 1
  512. a223 1
  513. #ifdef MTS
  514. d234 1
  515. a234 1
  516. #ifndef DOS
  517. d240 1
  518. a240 1
  519. #ifdef MTS
  520. @
  521.  
  522.  
  523. 1.5
  524. log
  525. @Merge Atari ST code
  526. @
  527. text
  528. @d2 1
  529. a2 1
  530.  * $Header: arcpack.c,v 1.4 88/06/01 14:45:52 hyc Locked $
  531. d5 15
  532. a19 14
  533. /*
  534.  * ARC - Archive utility - ARCPACK
  535.  * 
  536.  * Version 3.46, created on 10/23/86 at 17:47:06
  537.  * 
  538.  * (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
  539.  * 
  540.  * By:  Thom Henderson
  541.  * 
  542.  * Description: This file contains the routines used to compress a file when
  543.  * placing it in an archive.
  544.  * 
  545.  * Language: Computer Innovations Optimizing C86
  546.  */
  547. a117 8
  548. #ifdef MSDOS
  549.         if (nocomp) {    /* store only kludge skips things */
  550.             stdlen = crcval = 0;    /* recalc these for kludge */
  551.             while ((c = getch(f)) != EOF)    /* store it straight */
  552.                 putc_pak(c, t);
  553.         } else
  554.             filecopy(f, t, stdlen);    /* else use fast file copier */
  555. #else
  556. a120 1
  557. #endif
  558. d142 1
  559. a142 1
  560.         printf("done.\n");
  561. @
  562.  
  563.  
  564. 1.4
  565. log
  566. @Fixed declarations
  567. @
  568. text
  569. @d2 1
  570. a2 1
  571.  * $Header: arcpack.c,v 1.6 88/04/19 01:40:09 hyc Exp $
  572. d76 1
  573. a76 1
  574.             sqinit_cm(f, t);
  575. d84 1
  576. a84 1
  577.             init_cm(f, t);    /* initialize for crunching */
  578. d226 1
  579. a226 1
  580. #ifndef MSDOS
  581. d242 1
  582. a242 1
  583. #ifndef MSDOS
  584. @
  585.  
  586.  
  587. 1.3
  588. log
  589. @fixed a typo...
  590. @
  591. text
  592. @d2 1
  593. a2 16
  594.  * $Log:    arcpack.c,v $
  595.  * Revision 1.2  88/04/11  18:38:15  hyc
  596.  * added support for squashing, re-synch with MTS
  597.  * 
  598.  * Revision 1.1  88/04/11  18:27:10  hyc
  599.  * Initial revision
  600.  * 
  601.  * Revision 1.1  87/12/19  04:05:16  hyc
  602.  * Initial revision
  603.  * 
  604.  * Revision 1.3  87/08/13  17:05:11  hyc
  605.  * Run thru indent, fixed some signed vs. unsigned problems
  606.  * with bp <-> buf, and inbuf and localbuf...
  607.  *  Revision 1.2  87/07/21  08:57:19  hyc *** empty
  608.  * log message ***
  609.  * 
  610. d25 4
  611. d44 2
  612. a45 2
  613. static LONG     stdlen;        /* length for standard packing */
  614. static INT      crcval;        /* CRC check value */
  615. d47 1
  616. a47 1
  617. INT
  618. d52 8
  619. a59 8
  620.     INT             c;    /* one character of stream */
  621.     LONG            ncrlen;    /* length after packing */
  622.     LONG            lzwlen;    /* length after crunching */
  623.     LONG            pred_cm(), sqpred_cm();    /* dynamic crunching cleanup */
  624.     LONG            tloc, ftell();    /* start of output */
  625.     INT             getch();
  626.     INT             getc_ncr();
  627.     INT             putc_pak();
  628. d117 1
  629. d124 5
  630. d163 1
  631. a163 1
  632. INT
  633. d167 3
  634. a169 3
  635.     static INT      lastc;    /* value returned on last call */
  636.     static INT      repcnt;    /* repetition counter */
  637.     static INT      c;    /* latest value seen */
  638. d221 1
  639. a221 1
  640. INT
  641. d225 1
  642. a225 1
  643.     INT             c;    /* a char from the file */
  644. d227 1
  645. a227 1
  646.     static INT      cr = 0;    /* add \r before \n ? */
  647. d259 1
  648. a259 1
  649. INT
  650. d264 1
  651. @
  652.  
  653.  
  654. 1.2
  655. log
  656. @added support for squashing, re-synch with MTS
  657. @
  658. text
  659. @d3 3
  660. d88 1
  661. a88 1
  662.             while ((c = getch(f) != EOF) {    /* for each byte of file */
  663. @
  664.  
  665.  
  666. 1.1
  667. log
  668. @Initial revision
  669. @
  670. text
  671. @d3 3
  672. d63 1
  673. a63 1
  674.     LONG            pred_cm();    /* dynamic crunching cleanup */
  675. d83 16
  676. a98 5
  677.         init_cm(f, t);    /* initialize for crunching */
  678.  
  679.         while ((c = getc_ncr(f)) != EOF) {    /* for each byte of file */
  680.             ncrlen++;    /* one more packed byte */
  681.             putc_cm(c, t);    /* see what crunching can do */
  682. a99 1
  683.         lzwlen = pred_cm(t);    /* finish up after crunching */
  684. d135 1
  685. a135 1
  686.             printf("packing, ");    /* pack with repeat *
  687. d144 2
  688. a145 2
  689.             printf("crunched, ");
  690.         hdrver = 8;
  691. d176 1
  692. a176 1
  693.         return lastc = getch(f);    /* remember the value next *
  694. d194 2
  695. a195 2
  696.                 return lastc = c;
  697.                 /* but remember value * next time */
  698. d198 2
  699. a199 2
  700.                 state = SENDNEWC;
  701.                 /* send the second one * next time */
  702. d203 4
  703. a206 4
  704.                 state = SENDCNT;
  705.                 /* send repeat count * next time */
  706.                 return DLE;
  707.                 /* send repeat marker this * time */
  708. d223 1
  709. a223 1
  710. static          INT
  711. d254 1
  712. a254 1
  713.         crcval = addcrc(crcval, c);    /* then update CRC check *
  714. @
  715.