Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "bzlib_private.h"
00023
00024
00025 #define WEIGHTOF(zz0) ((zz0) & 0xffffff00)
00026 #define DEPTHOF(zz1) ((zz1) & 0x000000ff)
00027 #define MYMAX(zz2,zz3) ((zz2) > (zz3) ? (zz2) : (zz3))
00028
00029 #define ADDWEIGHTS(zw1,zw2) \
00030 (WEIGHTOF(zw1)+WEIGHTOF(zw2)) | \
00031 (1 + MYMAX(DEPTHOF(zw1),DEPTHOF(zw2)))
00032
00033 #define UPHEAP(z) \
00034 { \
00035 Int32 zz, tmp; \
00036 zz = z; tmp = heap[zz]; \
00037 while (weight[tmp] < weight[heap[zz >> 1]]) { \
00038 heap[zz] = heap[zz >> 1]; \
00039 zz >>= 1; \
00040 } \
00041 heap[zz] = tmp; \
00042 }
00043
00044 #define DOWNHEAP(z) \
00045 { \
00046 Int32 zz, yy, tmp; \
00047 zz = z; tmp = heap[zz]; \
00048 while (True) { \
00049 yy = zz << 1; \
00050 if (yy > nHeap) break; \
00051 if (yy < nHeap && \
00052 weight[heap[yy+1]] < weight[heap[yy]]) \
00053 yy++; \
00054 if (weight[tmp] < weight[heap[yy]]) break; \
00055 heap[zz] = heap[yy]; \
00056 zz = yy; \
00057 } \
00058 heap[zz] = tmp; \
00059 }
00060
00061
00062
00063 void BZ2_hbMakeCodeLengths ( UChar *len,
00064 Int32 *freq,
00065 Int32 alphaSize,
00066 Int32 maxLen )
00067 {
00068
00069
00070
00071
00072 Int32 nNodes, nHeap, n1, n2, i, j, k;
00073 Bool tooLong;
00074
00075 Int32 heap [ BZ_MAX_ALPHA_SIZE + 2 ];
00076 Int32 weight [ BZ_MAX_ALPHA_SIZE * 2 ];
00077 Int32 parent [ BZ_MAX_ALPHA_SIZE * 2 ];
00078
00079 for (i = 0; i < alphaSize; i++)
00080 weight[i+1] = (freq[i] == 0 ? 1 : freq[i]) << 8;
00081
00082 while (True) {
00083
00084 nNodes = alphaSize;
00085 nHeap = 0;
00086
00087 heap[0] = 0;
00088 weight[0] = 0;
00089 parent[0] = -2;
00090
00091 for (i = 1; i <= alphaSize; i++) {
00092 parent[i] = -1;
00093 nHeap++;
00094 heap[nHeap] = i;
00095 UPHEAP(nHeap);
00096 }
00097
00098 AssertH( nHeap < (BZ_MAX_ALPHA_SIZE+2), 2001 );
00099
00100 while (nHeap > 1) {
00101 n1 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
00102 n2 = heap[1]; heap[1] = heap[nHeap]; nHeap--; DOWNHEAP(1);
00103 nNodes++;
00104 parent[n1] = parent[n2] = nNodes;
00105 weight[nNodes] = ADDWEIGHTS(weight[n1], weight[n2]);
00106 parent[nNodes] = -1;
00107 nHeap++;
00108 heap[nHeap] = nNodes;
00109 UPHEAP(nHeap);
00110 }
00111
00112 AssertH( nNodes < (BZ_MAX_ALPHA_SIZE * 2), 2002 );
00113
00114 tooLong = False;
00115 for (i = 1; i <= alphaSize; i++) {
00116 j = 0;
00117 k = i;
00118 while (parent[k] >= 0) { k = parent[k]; j++; }
00119 len[i-1] = j;
00120 if (j > maxLen) tooLong = True;
00121 }
00122
00123 if (! tooLong) break;
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 for (i = 1; i <= alphaSize; i++) {
00143 j = weight[i] >> 8;
00144 j = 1 + (j / 2);
00145 weight[i] = j << 8;
00146 }
00147 }
00148 }
00149
00150
00151
00152 void BZ2_hbAssignCodes ( Int32 *code,
00153 UChar *length,
00154 Int32 minLen,
00155 Int32 maxLen,
00156 Int32 alphaSize )
00157 {
00158 Int32 n, vec, i;
00159
00160 vec = 0;
00161 for (n = minLen; n <= maxLen; n++) {
00162 for (i = 0; i < alphaSize; i++)
00163 if (length[i] == n) { code[i] = vec; vec++; };
00164 vec <<= 1;
00165 }
00166 }
00167
00168
00169
00170 void BZ2_hbCreateDecodeTables ( Int32 *limit,
00171 Int32 *base,
00172 Int32 *perm,
00173 UChar *length,
00174 Int32 minLen,
00175 Int32 maxLen,
00176 Int32 alphaSize )
00177 {
00178 Int32 pp, i, j, vec;
00179
00180 pp = 0;
00181 for (i = minLen; i <= maxLen; i++)
00182 for (j = 0; j < alphaSize; j++)
00183 if (length[j] == i) { perm[pp] = j; pp++; };
00184
00185 for (i = 0; i < BZ_MAX_CODE_LEN; i++) base[i] = 0;
00186 for (i = 0; i < alphaSize; i++) base[length[i]+1]++;
00187
00188 for (i = 1; i < BZ_MAX_CODE_LEN; i++) base[i] += base[i-1];
00189
00190 for (i = 0; i < BZ_MAX_CODE_LEN; i++) limit[i] = 0;
00191 vec = 0;
00192
00193 for (i = minLen; i <= maxLen; i++) {
00194 vec += (base[i+1] - base[i]);
00195 limit[i] = vec-1;
00196 vec <<= 1;
00197 }
00198 for (i = minLen + 1; i <= maxLen; i++)
00199 base[i] = ((limit[i-1] + 1) << 1) - base[i];
00200 }
00201
00202
00203
00204
00205