Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pack/huffencode.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1993-2011 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* David Korn <[email protected]> *
18
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* huffman coding encoding
23
*
24
* David Korn
25
* AT&T Laboratories
26
*/
27
28
#include "huffman.h"
29
30
#define END (1<<CHAR_BIT)
31
32
static long lastid = 1;
33
static long id = 0x8000;
34
static int bits[END+1];
35
static unsigned char *outend;
36
static unsigned char *outbuff;
37
static int putbuff(Sfio_t*,unsigned char*);
38
39
#define putbits(buff,left,bits,n) (left+=(n),buff=((buff<<(n))|(bits)))
40
#define outchars(fp,buff,left,outp,n) while(left>=CHAR_BIT)\
41
{ \
42
left-=CHAR_BIT; \
43
*outp++ = buff>>left; \
44
if(outp>=outend) \
45
{ \
46
if((n=putbuff(fp,outp)) < 0) \
47
return(-1); \
48
hp->outsize += n; \
49
outp = outbuff; \
50
} \
51
}
52
53
/*
54
* encode <size> bytes of <infile> using <hp> encoding and write
55
* result to <outfile>
56
* encode until end-of-file of <size> < 0.
57
*/
58
59
Sfoff_t huffencode(register Huff_t *hp,Sfio_t *infile,Sfio_t *outfile,int size)
60
{
61
register long buffer;
62
register int left, i, c;
63
register unsigned char *inbuff;
64
register int n;
65
register unsigned char *outp;
66
register Sfio_t *fp = outfile;
67
if(hp->id != lastid)
68
{
69
/* compute the bit patterns for each character */
70
for (n=0, i=hp->maxlev; i>0; i--)
71
{
72
for (c=0; c<=END; c++)
73
if (hp->length[c] == i)
74
bits[c] = n++;
75
n >>= 1;
76
}
77
if(!hp->id)
78
hp->id = id++;
79
lastid = hp->id;
80
}
81
buffer = hp->buffer;
82
left = hp->left;
83
hp->outsize = 0;
84
if(!(outp=outbuff=(unsigned char*)sfreserve(fp,SF_UNBOUND,SF_LOCKR)))
85
return(-1);
86
outend = outp + sfvalue(fp);
87
do
88
{
89
if(!(inbuff=(unsigned char*)sfreserve(infile,SF_UNBOUND,0)))
90
{
91
if((n=sfvalue(infile))==0)
92
{
93
c = END;
94
goto endof;
95
}
96
return(-1);
97
}
98
n = sfvalue(infile);
99
if(size>=0 && size<n)
100
n = size;
101
while(n-- > 0)
102
{
103
c = *inbuff++;
104
endof:
105
i = hp->length[c];
106
putbits(buffer,left,bits[c],i);
107
outchars(fp,buffer,left,outp,i);
108
}
109
if(size>0 && n && (size -=n)<=0)
110
goto done;
111
}
112
while (c != END);
113
if(left)
114
{
115
i = CHAR_BIT-left;
116
putbits(buffer,left,0,i);
117
outchars(fp,buffer,left,outp,i);
118
buffer = 0;
119
}
120
done:
121
hp->buffer = buffer;
122
hp->left = left;
123
n = outp - outbuff;
124
hp->outsize += n;
125
if(sfwrite(fp,outbuff,n)<0)
126
return(-1);
127
return(hp->outsize);
128
}
129
130
static int putbuff(register Sfio_t *fp,register unsigned char *outp)
131
{
132
register int n = outp - outbuff;
133
if(sfwrite(fp,outbuff,n)< 0)
134
return(-1);
135
if(!(outbuff=(unsigned char*)sfreserve(fp,SF_UNBOUND,SF_LOCKR)))
136
return(-1);
137
outend = outbuff+(n=sfvalue(fp));
138
return(n);
139
}
140
141
142