(lengths: number[], pos: number, nlengths: number, maxbits: number)
| 30 | */ |
| 31 | export class HuffTools { |
| 32 | public static make(lengths: number[], pos: number, nlengths: number, maxbits: number): Huffman { |
| 33 | const counts: number[] = []; |
| 34 | const tmp: number[] = []; |
| 35 | if (maxbits > 32) { |
| 36 | throw new FormatError('Invalid huffman'); |
| 37 | } |
| 38 | for (let i: number = 0; i < maxbits; i++) { |
| 39 | counts.push(0); |
| 40 | tmp.push(0); |
| 41 | } |
| 42 | for (let i: number = 0; i < nlengths; i++) { |
| 43 | const p: number = lengths[i + pos]; |
| 44 | if (p >= maxbits) { |
| 45 | throw new FormatError('Invalid huffman'); |
| 46 | } |
| 47 | counts[p]++; |
| 48 | } |
| 49 | let code: number = 0; |
| 50 | for (let i: number = 1; i < maxbits - 1; i++) { |
| 51 | code = (code + counts[i]) << 1; |
| 52 | tmp[i] = code; |
| 53 | } |
| 54 | const bits: Map<number, number> = new Map<number, number>(); |
| 55 | for (let i: number = 0; i < nlengths; i++) { |
| 56 | const l: number = lengths[i + pos]; |
| 57 | if (l !== 0) { |
| 58 | const n: number = tmp[l - 1]; |
| 59 | tmp[l - 1] = n + 1; |
| 60 | bits.set((n << 5) | l, i); |
| 61 | } |
| 62 | } |
| 63 | return HuffTools._treeCompress( |
| 64 | new NeedBit(HuffTools._treeMake(bits, maxbits, 0, 1), HuffTools._treeMake(bits, maxbits, 1, 1)) |
| 65 | ); |
| 66 | } |
| 67 | |
| 68 | private static _treeMake(bits: Map<number, number>, maxbits: number, v: number, len: number): Huffman { |
| 69 | if (len > maxbits) { |
no test coverage detected