private unsafe int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) { int index = 0; int num5 = n; while (true) { int *numPtr1 = &(this.c[b[bindex + index]]); numPtr1[0]++; index++; num5--; if (num5 == 0) { if (this.c[0] == n) { t[0] = -1; m[0] = 0; return(0); } int num8 = m[0]; int num6 = 1; while ((num6 <= 15) && (this.c[num6] == 0)) { num6++; } int num7 = num6; if (num8 < num6) { num8 = num6; } num5 = 15; while ((num5 != 0) && (this.c[num5] == 0)) { num5--; } int num3 = num5; if (num8 > num5) { num8 = num5; } m[0] = num8; int num14 = 1 << (num6 & 0x1f); while (num6 < num5) { num14 -= this.c[num6]; if (num14 < 0) { return(-3); } num6++; num14 = num14 << 1; } num14 -= this.c[num5]; if (num14 < 0) { return(-3); } int *numPtr2 = &(this.c[num5]); numPtr2[0] += num14; this.x[1] = num6 = 0; index = 1; int num13 = 2; while (--num5 != 0) { int num18 = num6 + this.c[index]; this.x[num13] = num6 = num18; num13++; index++; } num5 = 0; index = 0; while (true) { num6 = b[bindex + index]; if (num6 != 0) { int num16; int *numPtr3 = &(this.x[num6]); numPtr3[0] = (num16 = numPtr3[0]) + 1; v[num16] = num5; } index++; if (++num5 >= n) { n = this.x[num3]; this.x[0] = num5 = 0; index = 0; int num4 = -1; int bits = -num8; this.u[0] = 0; int num11 = 0; int num15 = 0; while (num7 <= num3) { int num = this.c[num7]; while (true) { if (num-- == 0) { num7++; break; } while (true) { int num2; if (num7 <= (bits + num8)) { this.r[1] = (sbyte)(num7 - bits); if (index >= n) { this.r[0] = 0xc0; } else if (v[index] < s) { this.r[0] = (v[index] >= 0x100) ? 0x60 : 0; this.r[2] = v[index++]; } else { this.r[0] = (sbyte)((e[v[index] - s] + 0x10) + 0x40); this.r[2] = d[v[index++] - s]; } num2 = 1 << ((num7 - bits) & 0x1f); num6 = SharedUtils.URShift(num5, bits); while (true) { if (num6 >= num15) { num6 = 1 << ((num7 - 1) & 0x1f); while (true) { if ((num5 & num6) == 0) { num5 ^= num6; for (int i = (1 << (bits & 0x1f)) - 1; (num5 & i) != this.x[num4]; i = (1 << (bits & 0x1f)) - 1) { num4--; bits -= num8; } break; } num5 ^= num6; num6 = SharedUtils.URShift(num6, 1); } break; } Array.Copy(this.r, 0, hp, (num11 + num6) * 3, 3); num6 += num2; } break; } num4++; bits += num8; num15 = num3 - bits; num15 = (num15 <= num8) ? num15 : num8; if ((num2 = 1 << ((num6 = num7 - bits) & 0x1f)) > (num + 1)) { num2 -= num + 1; num13 = num7; if (num6 < num15) { while (++num6 < num15) { int num19 = num2 << 1; if ((num2 = num19) <= this.c[++num13]) { break; } num2 -= this.c[num13]; } } } num15 = 1 << (num6 & 0x1f); if ((hn[0] + num15) > 0x5a0) { return(-3); } this.u[num4] = num11 = hn[0]; int *numPtr4 = hn; numPtr4[0] += num15; if (num4 == 0) { t[0] = num11; } else { this.x[num4] = num5; this.r[0] = (sbyte)num6; this.r[1] = (sbyte)num8; num6 = SharedUtils.URShift(num5, bits - num8); this.r[2] = (num11 - this.u[num4 - 1]) - num6; Array.Copy(this.r, 0, hp, (this.u[num4 - 1] + num6) * 3, 3); } } } } return(((num14 == 0) || (num3 == 1)) ? 0 : -5); } } } } }
internal StaticTree staticTree; // the corresponding static tree /// <summary> /// Map from a distance to a distance code. /// </summary> /// <remarks> /// No side effects. _dist_code[256] and _dist_code[257] are never used. /// </remarks> internal static int DistanceCode(int dist) { return((dist < 256) ? _dist_code[dist] : _dist_code[256 + SharedUtils.URShift(dist, 7)]); }
internal int[] x; // bit offsets, then code stack private int huft_build(int[] b, int bindex, int n, int s, int[] d, int[] e, int[] t, int[] m, int[] hp, int[] hn, int[] v) { // Given a list of code lengths and a maximum table size, make a set of // tables to decode that set of codes. Return Z_OK on success, Z_BUF_ERROR // if the given code set is incomplete (the tables are still built in this // case), Z_DATA_ERROR if the input is invalid (an over-subscribed set of // lengths), or Z_MEM_ERROR if not enough memory. int a; // counter for codes of length k int f; // i repeats in table every f entries int g; // maximum code length int h; // table level int i; // counter, current code int j; // counter int k; // number of bits in current code int l; // bits per table (returned in m) int mask; // (1 << w) - 1, to avoid cc -O bug on HP int p; // pointer into c[], b[], or v[] int q; // points to current table int w; // bits before this table == (l * h) int xp; // pointer into x int y; // number of dummy codes added int z; // number of entries in current table // Generate counts for each bit length p = 0; i = n; do { c[b[bindex + p]]++; p++; i--; // assume all entries <= BMAX } while (i != 0); if (c[0] == n) { // null input--all zero length codes t[0] = -1; m[0] = 0; return(Z_OK); } // Find minimum and maximum length, bound *m by those l = m[0]; for (j = 1; j <= BMAX; j++) { if (c[j] != 0) { break; } } k = j; // minimum code length if (l < j) { l = j; } for (i = BMAX; i != 0; i--) { if (c[i] != 0) { break; } } g = i; // maximum code length if (l > i) { l = i; } m[0] = l; // Adjust last length count to fill out codes, if needed for (y = 1 << j; j < i; j++, y <<= 1) { if ((y -= c[j]) < 0) { return(Z_DATA_ERROR); } } if ((y -= c[i]) < 0) { return(Z_DATA_ERROR); } c[i] += y; // Generate starting offsets into the value table for each length x[1] = j = 0; p = 1; xp = 2; while (--i != 0) { // note that i == g from above x[xp] = (j += c[p]); xp++; p++; } // Make a table of values in order of bit lengths i = 0; p = 0; do { if ((j = b[bindex + p]) != 0) { v[x[j]++] = i; } p++; } while (++i < n); n = x[g]; // set n to length of v // Generate the Huffman codes and for each, make the table entries x[0] = i = 0; // first Huffman code is zero p = 0; // grab values in bit order h = -1; // no tables yet--level -1 w = -l; // bits decoded == (l * h) u[0] = 0; // just to keep compilers happy q = 0; // ditto z = 0; // ditto // go through the bit lengths (k already is bits in shortest code) for (; k <= g; k++) { a = c[k]; while (a-- != 0) { // here i is the Huffman code of length k bits for value *p // make tables up to required level while (k > w + l) { h++; w += l; // previous table always l bits // compute minimum size table less than or equal to l bits z = g - w; z = (z > l) ? l : z; // table size upper limit if ((f = 1 << (j = k - w)) > a + 1) { // try a k-w bit table // too few codes for k-w bit table f -= (a + 1); // deduct codes from patterns left xp = k; if (j < z) { while (++j < z) { // try smaller tables up to z bits if ((f <<= 1) <= c[++xp]) { break; // enough codes to use up j bits } f -= c[xp]; // else deduct codes from patterns } } } z = 1 << j; // table entries for j-bit table // allocate new table if (hn[0] + z > MANY) { // (note: doesn't matter for fixed) return(Z_DATA_ERROR); // overflow of MANY } u[h] = q = hn[0]; // DEBUG hn[0] += z; // connect to last table, if there is one if (h != 0) { x[h] = i; // save pattern for backing up r[0] = (sbyte)j; // bits in this table r[1] = (sbyte)l; // bits to dump before this table j = SharedUtils.URShift(i, (w - l)); r[2] = (q - u[h - 1] - j); // offset to this table Array.Copy(r, 0, hp, (u[h - 1] + j) * 3, 3); // connect to last table } else { t[0] = q; // first table is returned result } } // set up table entry in r r[1] = (sbyte)(k - w); if (p >= n) { r[0] = 128 + 64; // out of values--invalid code } else if (v[p] < s) { r[0] = (sbyte)(v[p] < 256 ? 0 : 32 + 64); // 256 is end-of-block r[2] = v[p++]; // simple code is just the value } else { r[0] = (sbyte)(e[v[p] - s] + 16 + 64); // non-simple--look up in lists r[2] = d[v[p++] - s]; } // fill code-like entries with r f = 1 << (k - w); for (j = SharedUtils.URShift(i, w); j < z; j += f) { Array.Copy(r, 0, hp, (q + j) * 3, 3); } // backwards increment the k-bit code i for (j = 1 << (k - 1); (i & j) != 0; j = SharedUtils.URShift(j, 1)) { i ^= j; } i ^= j; // backup over finished tables mask = (1 << w) - 1; // needed on HP, cc -O bug while ((i & mask) != x[h]) { h--; // don't need to update q w -= l; mask = (1 << w) - 1; } } } // Return Z_BUF_ERROR if we were given an incomplete table return(y != 0 && g != 1 ? Z_BUF_ERROR : Z_OK); }