// Copyright 2015, Joe Tsai. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE.md file. package brotli const ( // RFC section 3.5. // This is the maximum bit-width of a prefix code. // Thus, it is okay to use uint32 to store codes. maxPrefixBits = 15 // RFC section 3.3. // The size of the alphabet for various prefix codes. numLitSyms = 256 // Literal symbols maxNumDistSyms = 16 + 120 + (48 << 3) // Distance symbols numIaCSyms = 704 // Insert-and-copy length symbols numBlkCntSyms = 26 // Block count symbols maxNumBlkTypeSyms = 256 + 2 // Block type symbols maxNumCtxMapSyms = 256 + 16 // Context map symbols // This should be the max of each of the constants above. maxNumAlphabetSyms = numIaCSyms ) var ( // RFC section 3.4. // Prefix code lengths for simple codes. simpleLens1 = [1]uint{0} simpleLens2 = [2]uint{1, 1} simpleLens3 = [3]uint{1, 2, 2} simpleLens4a = [4]uint{2, 2, 2, 2} simpleLens4b = [4]uint{1, 2, 3, 3} // RFC section 3.5. // Prefix code lengths for complex codes as they appear in the stream. complexLens = [18]uint{ 1, 2, 3, 4, 0, 5, 17, 6, 16, 7, 8, 9, 10, 11, 12, 13, 14, 15, } ) type rangeCode struct { base uint32 // Starting base offset of the range bits uint32 // Bit-width of a subsequent integer to add to base offset } var ( // RFC section 5. // LUT to convert an insert symbol to an actual insert length. insLenRanges []rangeCode // RFC section 5. // LUT to convert an copy symbol to an actual copy length. cpyLenRanges []rangeCode // RFC section 6. // LUT to convert an block-type length symbol to an actual length. blkLenRanges []rangeCode // RFC section 7.3. // LUT to convert RLE symbol to an actual repeat length. maxRLERanges []rangeCode ) type prefixCode struct { sym uint32 // The symbol being mapped val uint32 // Value of the prefix code (must be in [0..1< maxNumAlphabetSyms { panic("maximum alphabet size is not updated") } } if maxNumAlphabetSyms >= 1<= 1< 17: code = prefixCode{sym: i, val: (i-17)<<1 | 1, len: 4} // Symbols: 18..24 case i < 17: code = prefixCode{sym: i, val: (i-8)<<4 | 1, len: 7} // Symbols: 9..15 default: code = prefixCode{sym: i, val: (i-17)<<4 | 1, len: 7} // Symbols: 17 } codeWinBits = append(codeWinBits, code) } codeWinBits[0].sym = 0 // Invalid code "1000100" to use symbol zero decWinBits.Init(codeWinBits, false) encWinBits.Init(codeWinBits) // Prefix code for reading counts in RFC section 9.2. // This is used for: NBLTYPESL, NBLTYPESI, NBLTYPESD, NTREESL, and NTREESD. codeCounts = []prefixCode{{sym: 1, val: 0, len: 1}} code := codeCounts[len(codeCounts)-1] for i := uint32(0); i < 8; i++ { for j := uint32(0); j < 1<> 3 // Lower 3 bits cpySym += r64 & 0x07 // Upper 3 bits iacLUT[iacSym].ins = insLenRanges[insSym] iacLUT[iacSym].cpy = cpyLenRanges[cpySym] } // RFC section 4. // The first 16 symbols modify a previously seen symbol. Thus, we can create // a table to determine which distance to use and how much to modify it by. for distSym := range distShortLUT { var index, delta int switch { case distSym < 4: index, delta = distSym, 0 case distSym < 10: index, delta = 0, distSym/2-1 case distSym < 16: index, delta = 1, distSym/2-4 } if distSym%2 == 0 { delta *= -1 } distShortLUT[distSym].index = index distShortLUT[distSym].delta = delta } // RFC section 4. // Longer distances are computed according the equation in the RFC. // To reduce computation during runtime, we precompute as much of the output // as possible. Thus, we compute the final distance using the following: // rec := distLongLUT[NPOSTFIX][distSym - (16+NDIRECT)] // distance := NDIRECT + rec.base + ReadBits(rec.bits)<> uint(npostfix) lcode := distSym & postfixMask nbits := 1 + distSym>>uint(npostfix+1) offset := ((2 + (hcode & 1)) << uint(nbits)) - 4 distLongLUT[npostfix][distSym] = rangeCode{ base: uint32(offset<