1 /* $NetBSD: huffman.c,v 1.1.1.2 2012/05/07 00:41:46 wiz Exp $ */
4 /*-------------------------------------------------------------*/
5 /*--- Huffman coding low-level stuff ---*/
7 /*-------------------------------------------------------------*/
9 /* ------------------------------------------------------------------
10 This file is part of bzip2/libbzip2, a program and library for
11 lossless, block-sorting data compression.
13 bzip2/libbzip2 version 1.0.6 of 6 September 2010
14 Copyright (C) 1996-2010 Julian Seward <jseward@bzip.org>
16 Please read the WARNING, DISCLAIMER and PATENTS sections in the
19 This program is released under the terms of the license contained
21 ------------------------------------------------------------------ */
24 #include "bzlib_private.h"
26 /*---------------------------------------------------*/
27 #define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
28 #define DEPTHOF(zz1) ((zz1) & 0x000000ff)
29 #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
31 #define ADDWEIGHTS(zw1,zw2) \
32 (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
33 (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
38 zz = z; tmp = heap[zz]; \
39 while (weight[tmp] < weight[heap[zz >> 1]]) { \
40 heap[zz] = heap[zz >> 1]; \
49 zz = z; tmp = heap[zz]; \
52 if (yy > nHeap) break; \
54 weight[heap[yy+1]] < weight[heap[yy]]) \
56 if (weight[tmp] < weight[heap[yy]]) break; \
57 heap[zz] = heap[yy]; \
64 /*---------------------------------------------------*/
65 void BZ2_hbMakeCodeLengths ( UChar
*len
,
71 Nodes and heap entries run from 1. Entry 0
72 for both the heap and nodes is a sentinel.
74 Int32 nNodes
, nHeap
, n1
, n2
, i
, j
, k
;
77 Int32 heap
[ BZ_MAX_ALPHA_SIZE
+ 2 ];
78 Int32 weight
[ BZ_MAX_ALPHA_SIZE
* 2 ];
79 Int32 parent
[ BZ_MAX_ALPHA_SIZE
* 2 ];
81 for (i
= 0; i
< alphaSize
; i
++)
82 weight
[i
+1] = (freq
[i
] == 0 ? 1 : freq
[i
]) << 8;
93 for (i
= 1; i
<= alphaSize
; i
++) {
100 AssertH( nHeap
< (BZ_MAX_ALPHA_SIZE
+2), 2001 );
103 n1
= heap
[1]; heap
[1] = heap
[nHeap
]; nHeap
--; DOWNHEAP(1);
104 n2
= heap
[1]; heap
[1] = heap
[nHeap
]; nHeap
--; DOWNHEAP(1);
106 parent
[n1
] = parent
[n2
] = nNodes
;
107 weight
[nNodes
] = ADDWEIGHTS(weight
[n1
], weight
[n2
]);
110 heap
[nHeap
] = nNodes
;
114 AssertH( nNodes
< (BZ_MAX_ALPHA_SIZE
* 2), 2002 );
117 for (i
= 1; i
<= alphaSize
; i
++) {
120 while (parent
[k
] >= 0) { k
= parent
[k
]; j
++; }
122 if (j
> maxLen
) tooLong
= True
;
125 if (! tooLong
) break;
127 /* 17 Oct 04: keep-going condition for the following loop used
128 to be 'i < alphaSize', which missed the last element,
129 theoretically leading to the possibility of the compressor
130 looping. However, this count-scaling step is only needed if
131 one of the generated Huffman code words is longer than
132 maxLen, which up to and including version 1.0.2 was 20 bits,
133 which is extremely unlikely. In version 1.0.3 maxLen was
134 changed to 17 bits, which has minimal effect on compression
135 ratio, but does mean this scaling step is used from time to
136 time, enough to verify that it works.
138 This means that bzip2-1.0.3 and later will only produce
139 Huffman codes with a maximum length of 17 bits. However, in
140 order to preserve backwards compatibility with bitstreams
141 produced by versions pre-1.0.3, the decompressor must still
142 handle lengths of up to 20. */
144 for (i
= 1; i
<= alphaSize
; i
++) {
153 /*---------------------------------------------------*/
154 void BZ2_hbAssignCodes ( Int32
*code
,
163 for (n
= minLen
; n
<= maxLen
; n
++) {
164 for (i
= 0; i
< alphaSize
; i
++)
165 if (length
[i
] == n
) { code
[i
] = vec
; vec
++; };
171 /*---------------------------------------------------*/
172 void BZ2_hbCreateDecodeTables ( Int32
*limit
,
183 for (i
= minLen
; i
<= maxLen
; i
++)
184 for (j
= 0; j
< alphaSize
; j
++)
185 if (length
[j
] == i
) { perm
[pp
] = j
; pp
++; };
187 for (i
= 0; i
< BZ_MAX_CODE_LEN
; i
++) base
[i
] = 0;
188 for (i
= 0; i
< alphaSize
; i
++) base
[length
[i
]+1]++;
190 for (i
= 1; i
< BZ_MAX_CODE_LEN
; i
++) base
[i
] += base
[i
-1];
192 for (i
= 0; i
< BZ_MAX_CODE_LEN
; i
++) limit
[i
] = 0;
195 for (i
= minLen
; i
<= maxLen
; i
++) {
196 vec
+= (base
[i
+1] - base
[i
]);
200 for (i
= minLen
+ 1; i
<= maxLen
; i
++)
201 base
[i
] = ((limit
[i
-1] + 1) << 1) - base
[i
];
205 /*-------------------------------------------------------------*/
206 /*--- end huffman.c ---*/
207 /*-------------------------------------------------------------*/