home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Format CD 28
/
amigaformatcd28.iso
/
-seriously_amiga-
/
archivers
/
arcppc
/
src
/
rcs
/
arcpack.c,v
< prev
next >
Wrap
Text File
|
1998-04-23
|
15KB
|
715 lines
head 1.11;
branch ;
access ;
symbols patch1:1.11;
locks ; strict;
comment @ * @;
1.11
date 88.07.31.18.52.08; author hyc; state Exp;
branches ;
next 1.10;
1.10
date 88.07.05.16.56.02; author hyc; state Exp;
branches ;
next 1.9;
1.9
date 88.06.02.16.27.36; author hyc; state Exp;
branches ;
next 1.8;
1.8
date 88.06.02.00.51.05; author hyc; state Exp;
branches ;
next 1.7;
1.7
date 88.06.01.19.57.05; author hyc; state Exp;
branches ;
next 1.6;
1.6
date 88.06.01.18.10.51; author hyc; state Exp;
branches ;
next 1.5;
1.5
date 88.06.01.16.09.00; author hyc; state Exp;
branches ;
next 1.4;
1.4
date 88.06.01.14.45.52; author hyc; state Exp;
branches ;
next 1.3;
1.3
date 88.04.11.18.57.00; author hyc; state Exp;
branches ;
next 1.2;
1.2
date 88.04.11.18.38.15; author hyc; state Exp;
branches ;
next 1.1;
1.1
date 88.04.11.18.27.10; author hyc; state Exp;
branches ;
next ;
desc
@@
1.11
log
@Fix declarations, fix bomb after storing zero length files
@
text
@/*
* $Header: arcpack.c,v 1.10 88/07/05 16:56:02 hyc Locked $
*/
/* ARC - Archive utility - ARCPACK
Version 3.49, created on 04/21/87 at 11:26:51
(C) COPYRIGHT 1985-87 by System Enhancement Associates; ALL RIGHTS RESERVED
By: Thom Henderson
Description:
This file contains the routines used to compress a file
when placing it in an archive.
Language:
Computer Innovations Optimizing C86
*/
#include <stdio.h>
#include "arc.h"
#if MTS
#include <ctype.h>
#endif
void setcode(), sqinit_cm(), sqputc_cm(), init_cm(), putc_cm();
void filecopy(), abort(), putc_tst(), init_sq(), scan_sq();
int getch(), addcrc();
/* stuff for non-repeat packing */
#define DLE 0x90 /* repeat sequence marker */
static unsigned char state; /* current packing state */
/* non-repeat packing states */
#define NOHIST 0 /* don't consider previous input */
#define SENTCHAR 1 /* lastchar set, no lookahead yet */
#define SENDNEWC 2 /* run over, send new char next */
#define SENDCNT 3 /* newchar set, send count next */
/* packing results */
static long stdlen; /* length for standard packing */
static short crcval; /* CRC check value */
void
pack(f, t, hdr) /* pack file into an archive */
FILE *f, *t; /* source, destination */
struct heads *hdr; /* pointer to header data */
{
int c; /* one character of stream */
long ncrlen; /* length after packing */
long huflen; /* length after squeezing */
long lzwlen; /* length after crunching */
long pred_sq(), file_sq(); /* stuff for squeezing */
long pred_cm(), sqpred_cm(); /* dynamic crunching cleanup */
long tloc, ftell(); /* start of output */
int getch();
int getc_ncr();
void putc_pak();
/* first pass - see which method is best */
tloc = ftell(t); /* note start of output */
if (!nocomp) { /* if storage kludge not active */
if (note) {
printf(" analyzing, ");
fflush(stdout);
}
state = NOHIST; /* initialize ncr packing */
stdlen = ncrlen = 0; /* reset size counters */
crcval = 0; /* initialize CRC check value */
setcode(); /* initialize encryption */
init_sq(); /* initialize for squeeze scan */
if (dosquash) {
sqinit_cm();
while ((c = getch(f)) != EOF) { /* for each byte of file */
ncrlen++; /* one more packed byte */
scan_sq(c); /* see what squeezing can do */
sqputc_cm(c, t); /* see what squashing
* can do */
}
lzwlen = sqpred_cm(t);
} else {
init_cm(t); /* initialize for crunching */
while ((c = getc_ncr(f)) != EOF) { /* for each byte of file */
ncrlen++; /* one more packed byte */
scan_sq(c); /* see what squeezing can do */
putc_cm(c, t); /* see what crunching can do */
}
lzwlen = pred_cm(t); /* finish up after crunching */
}
huflen = pred_sq(); /* finish up after squeezing */
} else { /* else kludge the method */
stdlen = 0; /* make standard look best */
ncrlen = huflen = lzwlen = 1;
}
/* standard set-ups common to all methods */
fseek(f, 0L, 0); /* rewind input */
hdr->crc = crcval; /* note CRC check value */
hdr->length = stdlen; /* set actual file length */
state = NOHIST; /* reinitialize ncr packing */
setcode(); /* reinitialize encryption */
/* choose and use the shortest method */
if (kludge && note)
printf("\n\tS:%ld P:%ld S:%ld C:%ld,\t ",
stdlen, ncrlen, huflen, lzwlen);
if (stdlen <= ncrlen && stdlen <= huflen && stdlen <= lzwlen) {
if (note) {
printf("storing, "); /* store without compression */
fflush(stdout);
}
hdrver = 2; /* note packing method */
fseek(t, tloc, 0); /* reset output for new method */
stdlen = crcval = 0; /* recalc these for kludge */
while ((c = getch(f)) != EOF) /* store it straight */
putc_pak(c, t);
hdr->crc = crcval;
hdr->length = hdr->size = stdlen;
} else if (ncrlen < lzwlen && ncrlen < huflen) {
if (note) {
printf("packing, "); /* pack with repeat
fflush(stdout); * suppression */
}
hdrver = 3; /* note packing method */
hdr->size = ncrlen; /* set data length */
fseek(t, tloc, 0); /* reset output for new method */
while ((c = getc_ncr(f)) != EOF)
putc_pak(c, t);
} else if (huflen < lzwlen) {
if (note) {
printf("squeezing, ");
fflush(stdout);
}
hdrver = 4; /* note packing method */
fseek(t, tloc, 0); /* reset output for new method */
hdr->size = file_sq(f, t); /* note final size */
} else {
if (note)
printf(dosquash ? "squashed, " : "crunched, ");
hdrver = dosquash ? 9 : 8;
hdr->size = lzwlen; /* size should not change */
}
/* standard cleanups common to all methods */
if (note)
printf("done. (%ld%%)\n",hdr->length == 0 ?
0L : 100L - (100L*hdr->size)/hdr->length);
}
/*
* Non-repeat compression - text is passed through normally, except that a
* run of more than two is encoded as:
*
* <char> <DLE> <count>
*
* Special case: a count of zero indicates that the DLE is really a DLE, not a
* repeat marker.
*/
int
getc_ncr(f) /* get bytes with collapsed runs */
FILE *f; /* file to get from */
{
static int lastc; /* value returned on last call */
static int repcnt; /* repetition counter */
static int c; /* latest value seen */
switch (state) { /* depends on our state */
case NOHIST: /* no relevant history */
state = SENTCHAR;
return lastc = getch(f); /* remember the value next
* time */
case SENTCHAR: /* char was sent. look ahead */
switch (lastc) {/* action depends on char */
case DLE: /* if we sent a real DLE */
state = NOHIST; /* then start over again */
return 0; /* but note that the DLE was real */
case EOF: /* EOF is always a special case */
return EOF;
default: /* else test for a repeat */
for (repcnt = 1; (c = getch(f)) == lastc && repcnt < 255; repcnt++);
/* find end of run */
switch (repcnt) { /* action depends on run size */
case 1:/* not a repeat */
return lastc = c; /* but remember value
* next time */
case 2:/* a repeat, but too short */
state = SENDNEWC; /* send the second one
* next time */
return lastc;
default: /* a run - compress it */
state = SENDCNT; /* send repeat count
* next time */
return DLE; /* send repeat marker this
* time */
}
}
case SENDNEWC: /* send second char of short run */
state = SENTCHAR;
return lastc = c;
case SENDCNT: /* sent DLE, now send count */
state = SENDNEWC;
return repcnt;
default:
abort("Bug - bad ncr state\n");
}
}
int
getch(f) /* special get char for packing */
FILE *f; /* file to get from */
{
int c; /* a char from the file */
#if !DOS
static int cr = 0; /* add \r before \n ? */
if (cr) {
c = '\n';
#if MTS
c = toascii(c);
#endif
crcval = addcrc(crcval, c);
stdlen++;
cr = 0;
return (c);
}
#endif
if ((c = fgetc(f)) != EOF) { /* if not the end of file */
#if !DOS
if (!image && (c == '\n')) {
c = '\r';
cr = 1;
}
#endif
#if MTS
if (!image)
c = toascii(c);
#endif
crcval = addcrc(crcval, c); /* then update CRC check
* value */
stdlen++; /* and bump length counter */
}
return c;
}
void
putc_pak(c, f) /* put a packed byte into archive */
char c; /* byte to put */
FILE *f; /* archive to put it in */
{
unsigned char code();
putc_tst(code(c), f); /* put encoded byte, with checks */
}
@
1.10
log
@Fix printout problem when storing zero length files.
@
text
@d2 1
a2 1
* $Header: arcpack.c,v 1.9 88/06/02 16:27:36 hyc Locked $
d27 1
a27 1
void filecopy(), abort(), putc_tst();
a156 3
if (!hdr->length) /* oops. zero length files bombed... */
hdr->length=hdr->size=1;
d158 2
a159 1
printf("done. (%ld%%)\n",100L - (100L*hdr->size)/hdr->length);
@
1.9
log
@Minor fixes & speedups
@
text
@d2 1
a2 1
* $Header: arcpack.c,v 1.8 88/06/02 00:51:05 hyc Locked $
d156 3
@
1.8
log
@Re-introduce Huffman Squeezing
@
text
@d2 1
a2 1
* $Header: arcpack.c,v 1.7 88/06/01 19:57:05 hyc Locked $
a59 2
char tnam[STRLEN]; /* temporary name buffer */
FILE *crn = NULL; /* temporary crunch file */
a72 2
sprintf(tnam, "%s.CRN", arctemp);
crn = fopen(tnam, "w+b");
d84 1
a84 1
sqputc_cm(c, crn); /* see what squashing
d87 1
a87 1
lzwlen = sqpred_cm(crn);
d89 1
a89 1
init_cm(crn); /* initialize for crunching */
d94 1
a94 1
putc_cm(c, crn); /* see what crunching can do */
d96 1
a96 1
lzwlen = pred_cm(crn); /* finish up after crunching */
d115 1
a115 1
printf("\n\tS:%ld P:%ld S: %ld C:%ld,\t ",
d118 1
a118 1
if (stdlen <= ncrlen && stdlen <= lzwlen && stdlen <= huflen) {
d146 1
d149 2
a150 4
if (note) {
printf(dosquash ? "squashing, " : "crunching, ");
fflush(stdout);
}
a152 2
fseek(crn, 0L, 0);
filecopy(crn, t, lzwlen);
a155 8
if (crn) {
fclose(crn);
if(unlink(tnam) && warn) {
printf("Cannot delete temporary file %s\n", tnam);
nerrs++;
}
}
@
1.7
log
@Changed compilation conditionals
@
text
@d2 1
a2 1
* $Header: arcpack.c,v 1.6 88/06/01 18:10:51 hyc Locked $
d55 1
d57 1
d60 2
d75 2
d81 1
d87 2
a88 1
sqputc_cm(c, t); /* see what squashing
d91 1
a91 1
lzwlen = sqpred_cm(t);
d93 1
a93 1
init_cm(t); /* initialize for crunching */
d97 2
a98 1
putc_cm(c, t); /* see what crunching can do */
d100 1
a100 1
lzwlen = pred_cm(t); /* finish up after crunching */
d102 1
d105 1
a105 1
ncrlen = lzwlen = 1;
d119 2
a120 1
printf("\n\tS:%ld P:%ld C:%ld,\t ", stdlen, ncrlen, lzwlen);
d122 1
a122 1
if (stdlen <= ncrlen && stdlen <= lzwlen) {
d134 2
a135 2
} else if (ncrlen < lzwlen) {
if (note)
d137 2
a138 1
* suppression */
d144 7
d152 4
a155 2
if (note)
printf(dosquash ? "squashed, " : "crunched, ");
d158 2
d163 8
@
1.6
log
@Merge ARC 5.21 changes
@
text
@d2 1
a2 1
* $Header: arcpack.c,v 1.5 88/06/01 16:09:00 hyc Locked $
d22 1
a22 1
#ifdef MTS
d218 1
a218 1
#ifndef DOS
d223 1
a223 1
#ifdef MTS
d234 1
a234 1
#ifndef DOS
d240 1
a240 1
#ifdef MTS
@
1.5
log
@Merge Atari ST code
@
text
@d2 1
a2 1
* $Header: arcpack.c,v 1.4 88/06/01 14:45:52 hyc Locked $
d5 15
a19 14
/*
* ARC - Archive utility - ARCPACK
*
* Version 3.46, created on 10/23/86 at 17:47:06
*
* (C) COPYRIGHT 1985,86 by System Enhancement Associates; ALL RIGHTS RESERVED
*
* By: Thom Henderson
*
* Description: This file contains the routines used to compress a file when
* placing it in an archive.
*
* Language: Computer Innovations Optimizing C86
*/
a117 8
#ifdef MSDOS
if (nocomp) { /* store only kludge skips things */
stdlen = crcval = 0; /* recalc these for kludge */
while ((c = getch(f)) != EOF) /* store it straight */
putc_pak(c, t);
} else
filecopy(f, t, stdlen); /* else use fast file copier */
#else
a120 1
#endif
d142 1
a142 1
printf("done.\n");
@
1.4
log
@Fixed declarations
@
text
@d2 1
a2 1
* $Header: arcpack.c,v 1.6 88/04/19 01:40:09 hyc Exp $
d76 1
a76 1
sqinit_cm(f, t);
d84 1
a84 1
init_cm(f, t); /* initialize for crunching */
d226 1
a226 1
#ifndef MSDOS
d242 1
a242 1
#ifndef MSDOS
@
1.3
log
@fixed a typo...
@
text
@d2 1
a2 16
* $Log: arcpack.c,v $
* Revision 1.2 88/04/11 18:38:15 hyc
* added support for squashing, re-synch with MTS
*
* Revision 1.1 88/04/11 18:27:10 hyc
* Initial revision
*
* Revision 1.1 87/12/19 04:05:16 hyc
* Initial revision
*
* Revision 1.3 87/08/13 17:05:11 hyc
* Run thru indent, fixed some signed vs. unsigned problems
* with bp <-> buf, and inbuf and localbuf...
* Revision 1.2 87/07/21 08:57:19 hyc *** empty
* log message ***
*
d25 4
d44 2
a45 2
static LONG stdlen; /* length for standard packing */
static INT crcval; /* CRC check value */
d47 1
a47 1
INT
d52 8
a59 8
INT c; /* one character of stream */
LONG ncrlen; /* length after packing */
LONG lzwlen; /* length after crunching */
LONG pred_cm(), sqpred_cm(); /* dynamic crunching cleanup */
LONG tloc, ftell(); /* start of output */
INT getch();
INT getc_ncr();
INT putc_pak();
d117 1
d124 5
d163 1
a163 1
INT
d167 3
a169 3
static INT lastc; /* value returned on last call */
static INT repcnt; /* repetition counter */
static INT c; /* latest value seen */
d221 1
a221 1
INT
d225 1
a225 1
INT c; /* a char from the file */
d227 1
a227 1
static INT cr = 0; /* add \r before \n ? */
d259 1
a259 1
INT
d264 1
@
1.2
log
@added support for squashing, re-synch with MTS
@
text
@d3 3
d88 1
a88 1
while ((c = getch(f) != EOF) { /* for each byte of file */
@
1.1
log
@Initial revision
@
text
@d3 3
d63 1
a63 1
LONG pred_cm(); /* dynamic crunching cleanup */
d83 16
a98 5
init_cm(f, t); /* initialize for crunching */
while ((c = getc_ncr(f)) != EOF) { /* for each byte of file */
ncrlen++; /* one more packed byte */
putc_cm(c, t); /* see what crunching can do */
a99 1
lzwlen = pred_cm(t); /* finish up after crunching */
d135 1
a135 1
printf("packing, "); /* pack with repeat *
d144 2
a145 2
printf("crunched, ");
hdrver = 8;
d176 1
a176 1
return lastc = getch(f); /* remember the value next *
d194 2
a195 2
return lastc = c;
/* but remember value * next time */
d198 2
a199 2
state = SENDNEWC;
/* send the second one * next time */
d203 4
a206 4
state = SENDCNT;
/* send repeat count * next time */
return DLE;
/* send repeat marker this * time */
d223 1
a223 1
static INT
d254 1
a254 1
crcval = addcrc(crcval, c); /* then update CRC check *
@