Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/cmd/pack/huffgethdr.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 routine to read a pack format header
23
*
24
* David Korn
25
* AT&T Laboratories
26
*/
27
28
#include "huffman.h"
29
#include <error.h>
30
31
#define END (1<<CHAR_BIT)
32
33
Huff_t *huffgethdr(register Sfio_t *infile)
34
{
35
register Huff_t* hp;
36
register int i, j, c;
37
/* allocate space for huffman tree */
38
if(!(hp=newof(0, Huff_t, 1, 0)))
39
{
40
errno = ENOMEM;
41
return((Huff_t*)0);
42
}
43
/* check two-byte header */
44
if(sfgetc(infile)!=HUFFMAG1 || sfgetc(infile)!=HUFFMAG2)
45
goto error;
46
/* get size of original file, */
47
for (i=0; i<4; i++)
48
hp->insize = (hp->insize<<CHAR_BIT)+ sfgetc(infile);
49
/* get number of levels in maxlev, */
50
hp->maxlev = sfgetc(infile);
51
if(hp->maxlev==0)
52
{
53
/* larger than 2**32 */
54
for (i=0; i<4; i++)
55
hp->insize = (hp->insize<<CHAR_BIT)+ sfgetc(infile);
56
hp->maxlev = sfgetc(infile);
57
}
58
if(hp->maxlev < 0 || hp->maxlev > HUFFLEV)
59
goto error;
60
/* get number of leaves on level i */
61
for (i=1; i<=hp->maxlev; i++)
62
{
63
if((c=sfgetc(infile)) < 0)
64
goto error;
65
hp->levcount[i] = c;
66
}
67
/* read in the characters and compute number of bits for each */
68
for(i=0; i <= END; i++)
69
hp->length[i] = 0;
70
hp->nchars = 0;
71
for (i=1; i<=hp->maxlev; i++)
72
{
73
j = hp->levcount[i];
74
if((hp->nchars += j) >=END)
75
goto error;
76
while (j-- > 0)
77
{
78
if((c=sfgetc(infile)) < 0)
79
goto error;
80
hp->length[c] = i;
81
}
82
}
83
if((c=sfgetc(infile)) < 0)
84
goto error;
85
hp->length[c] = i-1;
86
return(hp);
87
88
error:
89
huffend(hp);
90
return ((Huff_t*)0);
91
}
92
93