github.com/andybalholm/brotli@v1.0.6/state.go (about)

     1  package brotli
     2  
     3  import "io"
     4  
     5  /* Copyright 2015 Google Inc. All Rights Reserved.
     6  
     7     Distributed under MIT license.
     8     See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
     9  */
    10  
    11  /* Brotli state for partial streaming decoding. */
    12  const (
    13  	stateUninited = iota
    14  	stateLargeWindowBits
    15  	stateInitialize
    16  	stateMetablockBegin
    17  	stateMetablockHeader
    18  	stateMetablockHeader2
    19  	stateContextModes
    20  	stateCommandBegin
    21  	stateCommandInner
    22  	stateCommandPostDecodeLiterals
    23  	stateCommandPostWrapCopy
    24  	stateUncompressed
    25  	stateMetadata
    26  	stateCommandInnerWrite
    27  	stateMetablockDone
    28  	stateCommandPostWrite1
    29  	stateCommandPostWrite2
    30  	stateHuffmanCode0
    31  	stateHuffmanCode1
    32  	stateHuffmanCode2
    33  	stateHuffmanCode3
    34  	stateContextMap1
    35  	stateContextMap2
    36  	stateTreeGroup
    37  	stateDone
    38  )
    39  
    40  const (
    41  	stateMetablockHeaderNone = iota
    42  	stateMetablockHeaderEmpty
    43  	stateMetablockHeaderNibbles
    44  	stateMetablockHeaderSize
    45  	stateMetablockHeaderUncompressed
    46  	stateMetablockHeaderReserved
    47  	stateMetablockHeaderBytes
    48  	stateMetablockHeaderMetadata
    49  )
    50  
    51  const (
    52  	stateUncompressedNone = iota
    53  	stateUncompressedWrite
    54  )
    55  
    56  const (
    57  	stateTreeGroupNone = iota
    58  	stateTreeGroupLoop
    59  )
    60  
    61  const (
    62  	stateContextMapNone = iota
    63  	stateContextMapReadPrefix
    64  	stateContextMapHuffman
    65  	stateContextMapDecode
    66  	stateContextMapTransform
    67  )
    68  
    69  const (
    70  	stateHuffmanNone = iota
    71  	stateHuffmanSimpleSize
    72  	stateHuffmanSimpleRead
    73  	stateHuffmanSimpleBuild
    74  	stateHuffmanComplex
    75  	stateHuffmanLengthSymbols
    76  )
    77  
    78  const (
    79  	stateDecodeUint8None = iota
    80  	stateDecodeUint8Short
    81  	stateDecodeUint8Long
    82  )
    83  
    84  const (
    85  	stateReadBlockLengthNone = iota
    86  	stateReadBlockLengthSuffix
    87  )
    88  
    89  type Reader struct {
    90  	src io.Reader
    91  	buf []byte // scratch space for reading from src
    92  	in  []byte // current chunk to decode; usually aliases buf
    93  
    94  	state        int
    95  	loop_counter int
    96  	br           bitReader
    97  	buffer       struct {
    98  		u64 uint64
    99  		u8  [8]byte
   100  	}
   101  	buffer_length               uint32
   102  	pos                         int
   103  	max_backward_distance       int
   104  	max_distance                int
   105  	ringbuffer_size             int
   106  	ringbuffer_mask             int
   107  	dist_rb_idx                 int
   108  	dist_rb                     [4]int
   109  	error_code                  int
   110  	sub_loop_counter            uint32
   111  	ringbuffer                  []byte
   112  	ringbuffer_end              []byte
   113  	htree_command               []huffmanCode
   114  	context_lookup              []byte
   115  	context_map_slice           []byte
   116  	dist_context_map_slice      []byte
   117  	literal_hgroup              huffmanTreeGroup
   118  	insert_copy_hgroup          huffmanTreeGroup
   119  	distance_hgroup             huffmanTreeGroup
   120  	block_type_trees            []huffmanCode
   121  	block_len_trees             []huffmanCode
   122  	trivial_literal_context     int
   123  	distance_context            int
   124  	meta_block_remaining_len    int
   125  	block_length_index          uint32
   126  	block_length                [3]uint32
   127  	num_block_types             [3]uint32
   128  	block_type_rb               [6]uint32
   129  	distance_postfix_bits       uint32
   130  	num_direct_distance_codes   uint32
   131  	distance_postfix_mask       int
   132  	num_dist_htrees             uint32
   133  	dist_context_map            []byte
   134  	literal_htree               []huffmanCode
   135  	dist_htree_index            byte
   136  	repeat_code_len             uint32
   137  	prev_code_len               uint32
   138  	copy_length                 int
   139  	distance_code               int
   140  	rb_roundtrips               uint
   141  	partial_pos_out             uint
   142  	symbol                      uint32
   143  	repeat                      uint32
   144  	space                       uint32
   145  	table                       [32]huffmanCode
   146  	symbol_lists                symbolList
   147  	symbols_lists_array         [huffmanMaxCodeLength + 1 + numCommandSymbols]uint16
   148  	next_symbol                 [32]int
   149  	code_length_code_lengths    [codeLengthCodes]byte
   150  	code_length_histo           [16]uint16
   151  	htree_index                 int
   152  	next                        []huffmanCode
   153  	context_index               uint32
   154  	max_run_length_prefix       uint32
   155  	code                        uint32
   156  	context_map_table           [huffmanMaxSize272]huffmanCode
   157  	substate_metablock_header   int
   158  	substate_tree_group         int
   159  	substate_context_map        int
   160  	substate_uncompressed       int
   161  	substate_huffman            int
   162  	substate_decode_uint8       int
   163  	substate_read_block_length  int
   164  	is_last_metablock           uint
   165  	is_uncompressed             uint
   166  	is_metadata                 uint
   167  	should_wrap_ringbuffer      uint
   168  	canny_ringbuffer_allocation uint
   169  	large_window                bool
   170  	size_nibbles                uint
   171  	window_bits                 uint32
   172  	new_ringbuffer_size         int
   173  	num_literal_htrees          uint32
   174  	context_map                 []byte
   175  	context_modes               []byte
   176  	dictionary                  *dictionary
   177  	transforms                  *transforms
   178  	trivial_literal_contexts    [8]uint32
   179  }
   180  
   181  func decoderStateInit(s *Reader) bool {
   182  	s.error_code = 0 /* BROTLI_DECODER_NO_ERROR */
   183  
   184  	initBitReader(&s.br)
   185  	s.state = stateUninited
   186  	s.large_window = false
   187  	s.substate_metablock_header = stateMetablockHeaderNone
   188  	s.substate_tree_group = stateTreeGroupNone
   189  	s.substate_context_map = stateContextMapNone
   190  	s.substate_uncompressed = stateUncompressedNone
   191  	s.substate_huffman = stateHuffmanNone
   192  	s.substate_decode_uint8 = stateDecodeUint8None
   193  	s.substate_read_block_length = stateReadBlockLengthNone
   194  
   195  	s.buffer_length = 0
   196  	s.loop_counter = 0
   197  	s.pos = 0
   198  	s.rb_roundtrips = 0
   199  	s.partial_pos_out = 0
   200  
   201  	s.block_type_trees = nil
   202  	s.block_len_trees = nil
   203  	s.ringbuffer_size = 0
   204  	s.new_ringbuffer_size = 0
   205  	s.ringbuffer_mask = 0
   206  
   207  	s.context_map = nil
   208  	s.context_modes = nil
   209  	s.dist_context_map = nil
   210  	s.context_map_slice = nil
   211  	s.dist_context_map_slice = nil
   212  
   213  	s.sub_loop_counter = 0
   214  
   215  	s.literal_hgroup.codes = nil
   216  	s.literal_hgroup.htrees = nil
   217  	s.insert_copy_hgroup.codes = nil
   218  	s.insert_copy_hgroup.htrees = nil
   219  	s.distance_hgroup.codes = nil
   220  	s.distance_hgroup.htrees = nil
   221  
   222  	s.is_last_metablock = 0
   223  	s.is_uncompressed = 0
   224  	s.is_metadata = 0
   225  	s.should_wrap_ringbuffer = 0
   226  	s.canny_ringbuffer_allocation = 1
   227  
   228  	s.window_bits = 0
   229  	s.max_distance = 0
   230  	s.dist_rb[0] = 16
   231  	s.dist_rb[1] = 15
   232  	s.dist_rb[2] = 11
   233  	s.dist_rb[3] = 4
   234  	s.dist_rb_idx = 0
   235  	s.block_type_trees = nil
   236  	s.block_len_trees = nil
   237  
   238  	s.symbol_lists.storage = s.symbols_lists_array[:]
   239  	s.symbol_lists.offset = huffmanMaxCodeLength + 1
   240  
   241  	s.dictionary = getDictionary()
   242  	s.transforms = getTransforms()
   243  
   244  	return true
   245  }
   246  
   247  func decoderStateMetablockBegin(s *Reader) {
   248  	s.meta_block_remaining_len = 0
   249  	s.block_length[0] = 1 << 24
   250  	s.block_length[1] = 1 << 24
   251  	s.block_length[2] = 1 << 24
   252  	s.num_block_types[0] = 1
   253  	s.num_block_types[1] = 1
   254  	s.num_block_types[2] = 1
   255  	s.block_type_rb[0] = 1
   256  	s.block_type_rb[1] = 0
   257  	s.block_type_rb[2] = 1
   258  	s.block_type_rb[3] = 0
   259  	s.block_type_rb[4] = 1
   260  	s.block_type_rb[5] = 0
   261  	s.context_map = nil
   262  	s.context_modes = nil
   263  	s.dist_context_map = nil
   264  	s.context_map_slice = nil
   265  	s.literal_htree = nil
   266  	s.dist_context_map_slice = nil
   267  	s.dist_htree_index = 0
   268  	s.context_lookup = nil
   269  	s.literal_hgroup.codes = nil
   270  	s.literal_hgroup.htrees = nil
   271  	s.insert_copy_hgroup.codes = nil
   272  	s.insert_copy_hgroup.htrees = nil
   273  	s.distance_hgroup.codes = nil
   274  	s.distance_hgroup.htrees = nil
   275  }
   276  
   277  func decoderStateCleanupAfterMetablock(s *Reader) {
   278  	s.context_modes = nil
   279  	s.context_map = nil
   280  	s.dist_context_map = nil
   281  	s.literal_hgroup.htrees = nil
   282  	s.insert_copy_hgroup.htrees = nil
   283  	s.distance_hgroup.htrees = nil
   284  }
   285  
   286  func decoderHuffmanTreeGroupInit(s *Reader, group *huffmanTreeGroup, alphabet_size uint32, max_symbol uint32, ntrees uint32) bool {
   287  	var max_table_size uint = uint(kMaxHuffmanTableSize[(alphabet_size+31)>>5])
   288  	group.alphabet_size = uint16(alphabet_size)
   289  	group.max_symbol = uint16(max_symbol)
   290  	group.num_htrees = uint16(ntrees)
   291  	group.htrees = make([][]huffmanCode, ntrees)
   292  	group.codes = make([]huffmanCode, (uint(ntrees) * max_table_size))
   293  	return !(group.codes == nil)
   294  }