public static void __hx_ctor_encode_command_Command(global::encode.command.Command __hx_this) { __hx_this.dist_extra_ = new global::Array <uint>(); __hx_this.cmd_extra_ = new global::Array <uint>(); __hx_this.dist_prefix_ = new global::Array <uint>(); __hx_this.cmd_prefix_ = new global::Array <uint>(); }
public virtual bool WriteBrotliData(bool is_last, bool force_flush, global::Array <int> out_size, global::Array <object> output) { unchecked { int bytes = (this.input_pos_ - this.last_processed_pos_); uint[] data = this.ringbuffer_.start(); int mask = this.ringbuffer_.mask(); if ((bytes > this.input_block_size())) { return(false); } bool utf8_mode = ((this.params_.quality >= 9) && global::encode.Encode.IsMostlyUTF8(data, (this.last_processed_pos_ & mask), bytes, global::encode.Encode.kMinUTF8Ratio)); if ((this.literal_cost_ != null)) { if (utf8_mode) { global::encode.Literal_cost.EstimateBitCostsForLiteralsUTF8(this.last_processed_pos_, bytes, mask, this.literal_cost_mask_, data, this.literal_cost_); } else { global::encode.Literal_cost.EstimateBitCostsForLiterals(this.last_processed_pos_, bytes, mask, this.literal_cost_mask_, data, this.literal_cost_); } } global::Array <int> last_insert_len = new global::Array <int>(new int[] { this.last_insert_len_ }); global::Array <int> num_commands = new global::Array <int>(new int[] { this.num_commands_ }); global::Array <int> num_literals = new global::Array <int>(new int[] { this.num_literals_ }); global::encode.Backward_references.CreateBackwardReferences(bytes, this.last_processed_pos_, data, mask, this.literal_cost_, this.literal_cost_mask_, this.max_backward_distance_, this.params_.quality, this.hashers_, this.hash_type_, this.dist_cache_, last_insert_len, this.commands_, num_commands[0], num_commands, num_literals); this.last_insert_len_ = last_insert_len[0]; this.num_commands_ = num_commands[0]; this.num_literals_ = num_literals[0]; int max_length = ((int)(global::System.Math.Min(((double)((mask + 1))), ((double)((1 << global::encode.Encode.kMaxInputBlockBits)))))); if (((((!(is_last) && !(force_flush)) && (((this.params_.quality >= global::encode.Encode.kMinQualityForBlockSplit) || ((this.num_literals_ + this.num_commands_) < 12287)))) && ((this.num_commands_ + ((this.input_block_size() >> 1))) < this.cmd_buffer_size_)) && ((this.input_pos_ + this.input_block_size()) <= (this.last_flush_pos_ + max_length)))) { this.last_processed_pos_ = this.input_pos_; out_size[0] = 0; return(true); } if ((this.last_insert_len_ > 0)) { global::encode.command.Command command = new global::encode.command.Command(); command.Command1(this.last_insert_len_); this.commands_[this.num_commands_++] = command; this.num_literals_ += this.last_insert_len_; this.last_insert_len_ = 0; } return(this.WriteMetaBlockInternal(is_last, utf8_mode, out_size, output)); } }
public static void CopyCommandsToByteArray(global::Array <object> cmds, int num_commands, global::Array <uint> insert_and_copy_codes, global::Array <uint> distance_prefixes) { unchecked { int _g1 = 0; while ((_g1 < num_commands)) { global::encode.command.Command cmd = ((global::encode.command.Command)(cmds[_g1++])); insert_and_copy_codes.push(cmd.cmd_prefix_[0]); if (((cmd.copy_len_ > 0) && ((bool)((cmd.cmd_prefix_[0] >= 128))))) { distance_prefixes.push(cmd.dist_prefix_[0]); } } } }
public static void BuildMetaBlockGreedy(uint[] ringbuffer, int pos, int mask, global::Array <object> commands, int n_commands, global::encode.metablock.MetaBlockSplit mb) { unchecked { int num_literals = 0; { int _g1 = 0; while ((_g1 < n_commands)) { num_literals += ((global::encode.command.Command)(commands[_g1++])).insert_len_; } } global::encode.metablock.BlockSplitter lit_blocks = new global::encode.metablock.BlockSplitter(global::encode.Histogram_functions.HistogramLiteralInt, 256, 512, 400.0, num_literals, mb.literal_split, mb.literal_histograms); global::encode.metablock.BlockSplitter cmd_blocks = new global::encode.metablock.BlockSplitter(global::encode.Histogram_functions.HistogramCommandInt, 704, 1024, 500.0, n_commands, mb.command_split, mb.command_histograms); global::encode.metablock.BlockSplitter dist_blocks = new global::encode.metablock.BlockSplitter(global::encode.Histogram_functions.HistogramDistanceInt, 64, 512, 100.0, n_commands, mb.distance_split, mb.distance_histograms); { int _g11 = 0; while ((_g11 < n_commands)) { global::encode.command.Command cmd = ((global::encode.command.Command)(commands[_g11++])); cmd_blocks.AddSymbol(((int)(cmd.cmd_prefix_[0]))); { int _g3 = 0; int _g2 = cmd.insert_len_; while ((_g3 < _g2)) { ++_g3; lit_blocks.AddSymbol(((int)(((uint)(((uint[])(ringbuffer))[(pos & mask)]))))); ++pos; } } pos += cmd.copy_len_; if (((cmd.copy_len_ > 0) && ((bool)((cmd.cmd_prefix_[0] >= 128))))) { dist_blocks.AddSymbol(((int)(cmd.dist_prefix_[0]))); } } } lit_blocks.FinishBlock(true); cmd_blocks.FinishBlock(true); dist_blocks.FinishBlock(true); } }
public static void BuildHistograms(global::Array <object> cmds, int num_commands, global::encode.metablock.BlockSplit literal_split, global::encode.metablock.BlockSplit insert_and_copy_split, global::encode.metablock.BlockSplit dist_split, uint[] ringbuffer, int start_pos, int mask, uint prev_byte, uint prev_byte2, global::Array <int> context_modes, global::Array <object> literal_histograms, global::Array <object> insert_and_copy_histograms, global::Array <object> copy_dist_histograms) { unchecked { int pos = start_pos; global::encode.block_splitter.BlockSplitIterator literal_it = new global::encode.block_splitter.BlockSplitIterator(((global::encode.metablock.BlockSplit)(literal_split))); global::encode.block_splitter.BlockSplitIterator insert_and_copy_it = new global::encode.block_splitter.BlockSplitIterator(((global::encode.metablock.BlockSplit)(insert_and_copy_split))); global::encode.block_splitter.BlockSplitIterator dist_it = new global::encode.block_splitter.BlockSplitIterator(((global::encode.metablock.BlockSplit)(dist_split))); { int _g1 = 0; while ((_g1 < num_commands)) { global::encode.command.Command cmd = ((global::encode.command.Command)(cmds[_g1++])); insert_and_copy_it.Next(); ((global::encode.histogram.Histogram)(insert_and_copy_histograms[insert_and_copy_it.type_])).Add1(((int)(cmd.cmd_prefix_[0]))); { int _g3 = 0; int _g2 = cmd.insert_len_; while ((_g3 < _g2)) { ++_g3; literal_it.Next(); ((global::encode.histogram.Histogram)(literal_histograms[((int)(((uint)((global::encode.Context.ContextFunction(prev_byte, prev_byte2, context_modes[literal_it.type_]) + ((literal_it.type_ << 6)))))))])).Add1(((int)(((uint)(((uint[])(ringbuffer))[(pos & mask)]))))); prev_byte2 = prev_byte; prev_byte = ((uint)(((uint[])(ringbuffer))[(pos & mask)])); ++pos; } } pos += cmd.copy_len_; if ((cmd.copy_len_ > 0)) { prev_byte2 = ((uint)(((uint[])(ringbuffer))[((pos - 2) & mask)])); prev_byte = ((uint)(((uint[])(ringbuffer))[((pos - 1) & mask)])); if (((bool)((cmd.cmd_prefix_[0] >= 128)))) { dist_it.Next(); ((global::encode.histogram.Histogram)(copy_dist_histograms[(((dist_it.type_ << 2)) + cmd.DistanceContext())])).Add1(((int)(cmd.dist_prefix_[0]))); } } } } } }
public static void RecomputeDistancePrefixes(global::Array <object> cmds, int num_commands, int num_direct_distance_codes, int distance_postfix_bits) { unchecked { if (((num_direct_distance_codes == 0) && (distance_postfix_bits == 0))) { return; } { int _g1 = 0; while ((_g1 < num_commands)) { global::encode.command.Command cmd = ((global::encode.command.Command)(cmds[_g1++])); if (((cmd.copy_len_ > 0) && ((bool)((cmd.cmd_prefix_[0] >= 128))))) { global::encode.Prefix.PrefixEncodeCopyDistance(cmd.DistanceCode(), num_direct_distance_codes, distance_postfix_bits, cmd.dist_prefix_, cmd.dist_extra_); } } } } }
public static void BuildMetaBlockGreedyWithContexts(uint[] ringbuffer, int pos, int mask, uint prev_byte, uint prev_byte2, int literal_context_mode, int num_contexts, global::Array <int> static_context_map, global::Array <object> commands, int n_commands, global::encode.metablock.MetaBlockSplit mb) { unchecked { int num_literals = 0; { int _g1 = 0; while ((_g1 < n_commands)) { num_literals += ((global::encode.command.Command)(commands[_g1++])).insert_len_; } } global::encode.metablock.ContextBlockSplitter lit_blocks = new global::encode.metablock.ContextBlockSplitter(global::encode.Histogram_functions.HistogramLiteralInt, 256, num_contexts, 512, 400.0, num_literals, mb.literal_split, mb.literal_histograms); global::encode.metablock.BlockSplitter cmd_blocks = new global::encode.metablock.BlockSplitter(global::encode.Histogram_functions.HistogramCommandInt, 704, 1024, 500.0, n_commands, mb.command_split, mb.command_histograms); global::encode.metablock.BlockSplitter dist_blocks = new global::encode.metablock.BlockSplitter(global::encode.Histogram_functions.HistogramDistanceInt, 64, 512, 100.0, n_commands, mb.distance_split, mb.distance_histograms); { int _g11 = 0; while ((_g11 < n_commands)) { global::encode.command.Command cmd = ((global::encode.command.Command)(commands[_g11++])); cmd_blocks.AddSymbol(((int)(cmd.cmd_prefix_[0]))); { int _g3 = 0; int _g2 = cmd.insert_len_; while ((_g3 < _g2)) { ++_g3; uint literal = ((uint)(((uint[])(ringbuffer))[(pos & mask)])); lit_blocks.AddSymbol(((int)(literal)), static_context_map[((int)(global::encode.Context.ContextFunction(prev_byte, prev_byte2, literal_context_mode)))]); prev_byte2 = prev_byte; prev_byte = literal; ++pos; } } pos += cmd.copy_len_; if ((cmd.copy_len_ > 0)) { prev_byte2 = ((uint)(((uint[])(ringbuffer))[((pos - 2) & mask)])); prev_byte = ((uint)(((uint[])(ringbuffer))[((pos - 1) & mask)])); if ((((int)(cmd.cmd_prefix_[0])) >= 128)) { dist_blocks.AddSymbol(((int)(cmd.dist_prefix_[0]))); } } } } lit_blocks.FinishBlock(true); cmd_blocks.FinishBlock(true); dist_blocks.FinishBlock(true); mb.literal_context_map = global::FunctionMalloc.mallocInt((mb.literal_split.num_types << 6)); { int _g12 = 0; int _g = mb.literal_split.num_types; while ((_g12 < _g)) { int i = _g12++; { int _g31 = 0; while ((_g31 < 64)) { int j = _g31++; ((int[])(mb.literal_context_map))[(((i << 6)) + j)] = ((i * num_contexts) + static_context_map[j]); } } } } } }
public static bool StoreMetaBlockTrivial(uint[] input, int start_pos, int length, int mask, bool is_last, global::Array <object> commands, int n_commands, global::Array <int> storage_ix, uint[] storage, int storage_off) { unchecked { if (!(global::encode.Brotli_bit_stream.StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage))) { return(false); } if ((length == 0)) { global::encode.Brotli_bit_stream.JumpToByteBoundary(storage_ix, storage); return(true); } global::encode.histogram.Histogram lit_histo = global::encode.Histogram_functions.HistogramLiteral(); global::encode.histogram.Histogram cmd_histo = global::encode.Histogram_functions.HistogramCommand(); global::encode.histogram.Histogram dist_histo = global::encode.Histogram_functions.HistogramDistance(); int pos = start_pos; { int _g1 = 0; while ((_g1 < n_commands)) { global::encode.command.Command cmd = ((global::encode.command.Command)(commands[_g1++])); cmd_histo.Add1(((int)(cmd.cmd_prefix_[0]))); { int _g3 = 0; int _g2 = cmd.insert_len_; while ((_g3 < _g2)) { ++_g3; lit_histo.Add1(((int)(((uint)(((uint[])(input))[(pos & mask)]))))); ++pos; } } pos += cmd.copy_len_; if (((cmd.copy_len_ > 0) && ((bool)((cmd.cmd_prefix_[0] >= 128))))) { dist_histo.Add1(((int)(cmd.dist_prefix_[0]))); } } } global::encode.Write_bits.WriteBits(13, ((uint)(0)), storage_ix, storage); uint[] lit_depth = global::FunctionMalloc.mallocUInt(256); uint[] lit_bits = global::FunctionMalloc.mallocUInt(256); uint[] cmd_depth = global::FunctionMalloc.mallocUInt(704); uint[] cmd_bits = global::FunctionMalloc.mallocUInt(704); uint[] dist_depth = global::FunctionMalloc.mallocUInt(64); uint[] dist_bits = global::FunctionMalloc.mallocUInt(64); global::encode.Brotli_bit_stream.BuildAndStoreHuffmanTree(lit_histo.data_, 256, lit_depth, 0, lit_bits, 0, storage_ix, storage); global::encode.Brotli_bit_stream.BuildAndStoreHuffmanTree(cmd_histo.data_, 704, cmd_depth, 0, cmd_bits, 0, storage_ix, storage); global::encode.Brotli_bit_stream.BuildAndStoreHuffmanTree(dist_histo.data_, 64, dist_depth, 0, dist_bits, 0, storage_ix, storage); pos = start_pos; { int _g11 = 0; while ((_g11 < n_commands)) { global::encode.command.Command cmd1 = ((global::encode.command.Command)(commands[_g11++])); int cmd_code = ((int)(cmd1.cmd_prefix_[0])); int lennumextra = ((int)(((uint)(((uint)((((uint)(cmd1.cmd_extra_[0])) >> 16))))))); global::Array <uint> lenextra = cmd1.cmd_extra_; global::encode.Write_bits.WriteBits(((int)(((uint)(((uint[])(cmd_depth))[cmd_code])))), ((uint)(((uint[])(cmd_bits))[cmd_code])), storage_ix, storage); if ((lennumextra >= 32)) { global::encode.Write_bits.WriteBits((lennumextra - 32), lenextra[0], storage_ix, storage); } global::encode.Write_bits.WriteBits((((lennumextra < 32)) ? (lennumextra) : (32)), lenextra[1], storage_ix, storage); { int _g31 = 0; int _g21 = cmd1.insert_len_; while ((_g31 < _g21)) { ++_g31; uint literal = ((uint)(((uint[])(input))[(pos & mask)])); global::encode.Write_bits.WriteBits(((int)(((uint)(((uint[])(lit_depth))[((int)(literal))])))), ((uint)(((uint[])(lit_bits))[((int)(literal))])), storage_ix, storage); ++pos; } } pos += cmd1.copy_len_; if (((cmd1.copy_len_ > 0) && ((bool)((cmd1.cmd_prefix_[0] >= 128))))) { int dist_code = ((int)(cmd1.dist_prefix_[0])); int distnumextra = ((int)(((uint)(((uint)((((uint)(cmd1.dist_extra_[0])) >> 24))))))); int distextra = ((int)(((uint)((cmd1.dist_extra_[0] & 16777215))))); global::encode.Write_bits.WriteBits(((int)(((uint)(((uint[])(dist_depth))[dist_code])))), ((uint)(((uint[])(dist_bits))[dist_code])), storage_ix, storage); global::encode.Write_bits.WriteBits(distnumextra, ((uint)(distextra)), storage_ix, storage); } } } if (is_last) { global::encode.Brotli_bit_stream.JumpToByteBoundary(storage_ix, storage); } return(true); } }
public static bool StoreMetaBlock(uint[] input, int start_pos, int length, int mask, uint prev_byte, uint prev_byte2, bool is_last, int num_direct_distance_codes, int distance_postfix_bits, int literal_context_mode, global::Array <object> commands, int n_commands, global::encode.metablock.MetaBlockSplit mb, global::Array <int> storage_ix, uint[] storage) { unchecked { if (!(global::encode.Brotli_bit_stream.StoreCompressedMetaBlockHeader(is_last, length, storage_ix, storage))) { return(false); } if ((length == 0)) { global::encode.Brotli_bit_stream.JumpToByteBoundary(storage_ix, storage); return(true); } global::encode.brotli_bit_stream.BlockEncoder literal_enc = new global::encode.brotli_bit_stream.BlockEncoder(256, mb.literal_split.num_types, mb.literal_split.types, mb.literal_split.lengths); global::encode.brotli_bit_stream.BlockEncoder command_enc = new global::encode.brotli_bit_stream.BlockEncoder(704, mb.command_split.num_types, mb.command_split.types, mb.command_split.lengths); global::encode.brotli_bit_stream.BlockEncoder distance_enc = new global::encode.brotli_bit_stream.BlockEncoder(((16 + num_direct_distance_codes) + ((48 << distance_postfix_bits))), mb.distance_split.num_types, mb.distance_split.types, mb.distance_split.lengths); literal_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage); command_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage); distance_enc.BuildAndStoreBlockSwitchEntropyCodes(storage_ix, storage); global::encode.Write_bits.WriteBits(2, ((uint)(distance_postfix_bits)), storage_ix, storage); global::encode.Write_bits.WriteBits(4, ((uint)((num_direct_distance_codes >> distance_postfix_bits))), storage_ix, storage); { int _g1 = 0; int _g = mb.literal_split.num_types; while ((_g1 < _g)) { ++_g1; global::encode.Write_bits.WriteBits(2, ((uint)(literal_context_mode)), storage_ix, storage); } } if (((((int[])(mb.literal_context_map)) as global::System.Array).Length == 0)) { global::encode.Brotli_bit_stream.StoreTrivialContextMap(mb.literal_histograms.length, 6, storage_ix, storage); } else { global::encode.Brotli_bit_stream.EncodeContextMap(mb.literal_context_map, mb.literal_histograms.length, storage_ix, storage); } if (((((int[])(mb.distance_context_map)) as global::System.Array).Length == 0)) { global::encode.Brotli_bit_stream.StoreTrivialContextMap(mb.distance_histograms.length, 2, storage_ix, storage); } else { global::encode.Brotli_bit_stream.EncodeContextMap(mb.distance_context_map, mb.distance_histograms.length, storage_ix, storage); } literal_enc.BuildAndStoreEntropyCodes(mb.literal_histograms, storage_ix, storage); command_enc.BuildAndStoreEntropyCodes(mb.command_histograms, storage_ix, storage); distance_enc.BuildAndStoreEntropyCodes(mb.distance_histograms, storage_ix, storage); int pos = start_pos; { int _g11 = 0; while ((_g11 < n_commands)) { global::encode.command.Command cmd = ((global::encode.command.Command)(commands[_g11++])); int lennumextra = ((int)(((uint)(((uint)((((uint)(cmd.cmd_extra_[0])) >> 16))))))); global::Array <uint> lenextra = cmd.cmd_extra_; command_enc.StoreSymbol(((int)(cmd.cmd_prefix_[0])), storage_ix, storage); if ((lennumextra >= 32)) { global::encode.Write_bits.WriteBits((lennumextra - 32), lenextra[0], storage_ix, storage); } global::encode.Write_bits.WriteBits((((lennumextra < 32)) ? (lennumextra) : (32)), lenextra[1], storage_ix, storage); if (((((int[])(mb.literal_context_map)) as global::System.Array).Length == 0)) { int _g3 = 0; int _g2 = cmd.insert_len_; while ((_g3 < _g2)) { ++_g3; literal_enc.StoreSymbol(((int)(((uint)(((uint[])(input))[(pos & mask)])))), storage_ix, storage); ++pos; } } else { int _g31 = 0; int _g21 = cmd.insert_len_; while ((_g31 < _g21)) { ++_g31; int literal = ((int)(((uint)(((uint[])(input))[(pos & mask)])))); literal_enc.StoreSymbolWithContext(6, literal, ((int)(global::encode.Context.ContextFunction(prev_byte, prev_byte2, literal_context_mode))), mb.literal_context_map, storage_ix, storage); prev_byte2 = prev_byte; prev_byte = ((uint)(literal)); ++pos; } } pos += cmd.copy_len_; if ((cmd.copy_len_ > 0)) { prev_byte2 = ((uint)(((uint[])(input))[((pos - 2) & mask)])); prev_byte = ((uint)(((uint[])(input))[((pos - 1) & mask)])); if (((bool)((cmd.cmd_prefix_[0] >= 128)))) { int dist_code = ((int)(cmd.dist_prefix_[0])); int distnumextra = ((int)(((uint)(((uint)((((uint)(cmd.dist_extra_[0])) >> 24))))))); int distextra = ((int)(((uint)((cmd.dist_extra_[0] & 16777215))))); if (((((int[])(mb.distance_context_map)) as global::System.Array).Length == 0)) { distance_enc.StoreSymbol(dist_code, storage_ix, storage); } else { distance_enc.StoreSymbolWithContext(2, dist_code, cmd.DistanceContext(), mb.distance_context_map, storage_ix, storage); } global::encode.Write_bits.WriteBits(distnumextra, ((uint)(distextra)), storage_ix, storage); } } } } if (is_last) { global::encode.Brotli_bit_stream.JumpToByteBoundary(storage_ix, storage); } return(true); } }
public static void CreateBackwardReferences_HashLongestMatchQuickly(int num_bytes, int position, uint[] ringbuffer, int ringbuffer_mask, int max_backward_limit, int quality, global::encode.hash.HashLongestMatchQuickly hasher, int[] dist_cache, global::Array <int> last_insert_len, global::Array <object> commands, int commands_off, global::Array <int> num_commands, global::Array <int> num_literals) { unchecked { if (((num_bytes >= 3) && (position >= 3))) { hasher.Store(ringbuffer, ((position - 3) & ringbuffer_mask), (position - 3)); hasher.Store(ringbuffer, ((position - 2) & ringbuffer_mask), (position - 2)); hasher.Store(ringbuffer, ((position - 1) & ringbuffer_mask), (position - 1)); } int orig_commands_off = commands_off; int insert_length = last_insert_len[0]; int i = (position & ringbuffer_mask); int i_diff = (position - i); int i_end = (i + num_bytes); int random_heuristics_window_size = (((quality < 9)) ? (64) : (512)); int apply_random_heuristics = (i + random_heuristics_window_size); while (((i + 3) < i_end)) { int max_length = (i_end - i); int max_distance = ((int)(global::System.Math.Min(((double)((i + i_diff))), ((double)(max_backward_limit))))); global::Array <int> best_len = new global::Array <int>(new int[] { 0 }); global::Array <int> best_len_code = new global::Array <int>(new int[] { 0 }); global::Array <int> best_dist = new global::Array <int>(new int[] { 0 }); global::Array <double> best_score = new global::Array <double>(new double[] { 4.0 }); bool match_found = hasher.FindLongestMatch(ringbuffer, ringbuffer_mask, dist_cache, (i + i_diff), max_length, max_distance, best_len, best_len_code, best_dist, best_score); if (match_found) { int delayed_backward_references_in_row = 0; while (true) { --max_length; global::Array <int> best_len_2 = new global::Array <int>(new int[] { (((quality < 5)) ? (((int)(global::System.Math.Min(((double)((best_len[0] - 1))), ((double)(max_length)))))) : (0)) }); global::Array <int> best_len_code_2 = new global::Array <int>(new int[] { 0 }); global::Array <int> best_dist_2 = new global::Array <int>(new int[] { 0 }); global::Array <double> best_score_2 = new global::Array <double>(new double[] { 4.0 }); max_distance = ((int)(global::System.Math.Min(((double)(((i + i_diff) + 1))), ((double)(max_backward_limit))))); hasher.Store(ringbuffer, i, (i + i_diff)); match_found = hasher.FindLongestMatch(ringbuffer, ringbuffer_mask, dist_cache, ((i + i_diff) + 1), max_length, max_distance, best_len_2, best_len_code_2, best_dist_2, best_score_2); if ((match_found && (best_score_2[0] >= (best_score[0] + 7.0)))) { ++i; ++insert_length; best_len[0] = best_len_2[0]; best_len_code[0] = best_len_code_2[0]; best_dist[0] = best_dist_2[0]; best_score[0] = best_score_2[0]; if ((++delayed_backward_references_in_row < 4)) { continue; } } break; } apply_random_heuristics = ((i + (2 * best_len[0])) + random_heuristics_window_size); max_distance = ((int)(global::System.Math.Min(((double)((i + i_diff))), ((double)(max_backward_limit))))); int distance_code = global::encode.Backward_references.ComputeDistanceCode(best_dist[0], max_distance, quality, dist_cache); if (((best_dist[0] <= max_distance) && (distance_code > 0))) { ((int[])(dist_cache))[3] = ((int)(((int[])(dist_cache))[2])); ((int[])(dist_cache))[2] = ((int)(((int[])(dist_cache))[1])); ((int[])(dist_cache))[1] = ((int)(((int[])(dist_cache))[0])); ((int[])(dist_cache))[0] = best_dist[0]; } global::encode.command.Command command = new global::encode.command.Command(); command.Command4(insert_length, best_len[0], best_len_code[0], distance_code); commands[commands_off++] = command; num_literals[0] += insert_length; insert_length = 0; { int _g1 = 1; int _g = best_len[0]; while ((_g1 < _g)) { int j = _g1++; hasher.Store(ringbuffer, (i + j), ((i + i_diff) + j)); } } i += best_len[0]; } else { ++insert_length; hasher.Store(ringbuffer, i, (i + i_diff)); ++i; if ((i > apply_random_heuristics)) { if ((i > (apply_random_heuristics + (4 * random_heuristics_window_size)))) { int i_jump = ((int)(global::System.Math.Min(((double)((i + 16))), ((double)((i_end - 4)))))); while ((i < i_jump)) { hasher.Store(ringbuffer, i, (i + i_diff)); insert_length += 4; i += 4; } } else { int i_jump1 = ((int)(global::System.Math.Min(((double)((i + 8))), ((double)((i_end - 3)))))); while ((i < i_jump1)) { hasher.Store(ringbuffer, i, (i + i_diff)); insert_length += 2; i += 2; } } } } } insert_length += (i_end - i); last_insert_len[0] = insert_length; num_commands[0] += (commands_off - orig_commands_off); } }
public static void ZopfliIterate(int num_bytes, int position, uint[] ringbuffer, int ringbuffer_mask, int max_backward_limit, global::encode.backward_references.ZopfliCostModel model, int[] num_matches, global::Array <object> matches, int[] dist_cache, global::Array <int> last_insert_len, global::Array <object> commands, int commands_off, global::Array <int> num_commands, global::Array <int> num_literals) { unchecked { int orig_commands_off = commands_off; global::encode.backward_references.ZopfliNode[] nodes = global::FunctionMalloc.malloc_encode_backward_references_ZopfliNode(typeof(global::encode.backward_references.ZopfliNode), (num_bytes + 1)); ((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[0])).length = 0; ((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[0])).cost = ((double)(0)); global::DefaultFunctions.memcpy_Int(((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[0])).distance_cache, 0, dist_cache, 0, 4); global::encode.backward_references.StartPosQueue queue = new global::encode.backward_references.StartPosQueue(((int)(3))); double min_cost_cmd = model.GetMinCostCmd(); int cur_match_pos = 0; int i = 0; while (((i + 3) < num_bytes)) { int cur_ix = (position + i); int cur_ix_masked = (cur_ix & ringbuffer_mask); int max_distance = ((int)(global::System.Math.Min(((double)(cur_ix)), ((double)(max_backward_limit))))); int max_length = (num_bytes - i); queue.Push(i, (((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[i])).cost - model.GetLiteralCosts(0, i))); int min_len = global::encode.Backward_references.ComputeMinimumCopyLength(queue, nodes, model, i, min_cost_cmd); int k = 0; while (((k < 5) && (k < queue.size()))) { int start = queue.GetStartPos(k); double start_costdiff = (((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[start])).cost - model.GetLiteralCosts(0, start)); int[] dist_cache2 = ((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[start])).distance_cache; int best_len = (min_len - 1); { int _g = 0; while ((_g < 16)) { int j = _g++; int backward = (((int)(((int[])(dist_cache2))[global::encode.Hash.kDistanceCacheIndex[j]])) + global::encode.Hash.kDistanceCacheOffset[j]); int prev_ix = (cur_ix - backward); if ((prev_ix >= cur_ix)) { continue; } if ((backward > max_distance)) { continue; } prev_ix &= ringbuffer_mask; if (((((cur_ix_masked + best_len) > ringbuffer_mask) || ((prev_ix + best_len) > ringbuffer_mask)) || ((bool)((((uint)(((uint[])(ringbuffer))[(cur_ix_masked + best_len)])) != ((uint)(((uint[])(ringbuffer))[(prev_ix + best_len)]))))))) { continue; } { int _g2 = (best_len + 1); int _g1 = (global::encode.Find_match_length.FindMatchLengthWithLimit(ringbuffer, prev_ix, ringbuffer, cur_ix_masked, max_length) + 1); while ((_g2 < _g1)) { int l = _g2++; double cost = ((start_costdiff + model.GetCommandCost(j, l, (i - start))) + model.GetLiteralCosts(0, i)); if ((cost < ((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[(i + l)])).cost)) { global::encode.Backward_references.UpdateZopfliNode(nodes, 0, i, start, l, l, backward, j, max_distance, dist_cache2, cost); } best_len = l; } } } } if ((k >= 2)) { ++k; continue; } int len = min_len; { int _g11 = 0; int _g3 = ((int)(((int[])(num_matches))[i])); while ((_g11 < _g3)) { global::encode.hash.BackwardMatch match = ((global::encode.hash.BackwardMatch)(matches[(cur_match_pos + _g11++)])); int dist = match.distance; bool is_dictionary_match = (dist > max_distance); int dist_code = (dist + 15); int max_len = match.length(); if (((len < max_len) && ((is_dictionary_match || (max_len > 325))))) { len = max_len; } while ((len <= max_len)) { int len_code = ((is_dictionary_match) ? (match.length_code()) : (len)); double cost1 = ((start_costdiff + model.GetCommandCost(dist_code, len_code, (i - start))) + model.GetLiteralCosts(0, i)); if ((cost1 < ((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[(i + len)])).cost)) { global::encode.Backward_references.UpdateZopfliNode(nodes, 0, i, start, len, len_code, dist, dist_code, max_distance, dist_cache2, cost1); } ++len; } } } ++k; } cur_match_pos += ((int)(((int[])(num_matches))[i])); if (((((int)(((int[])(num_matches))[i])) == 1) && (((global::encode.hash.BackwardMatch)(matches[(cur_match_pos - 1)])).length() > 325))) { i += (((global::encode.hash.BackwardMatch)(matches[(cur_match_pos - 1)])).length() - 1); queue.Clear(); } ++i; } global::Array <int> backwards = new global::Array <int>(); int index = num_bytes; while ((((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[index])).cost == global::encode.Backward_references.kInfinity)) { --index; } while ((index > 0)) { int len1 = (((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[index])).length + ((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[index])).insert_length); backwards.push(len1); index -= len1; } global::Array <int> path = new global::Array <int>(); int i1 = backwards.length; while ((i1 > 0)) { path.push(backwards[(i1 - 1)]); --i1; } int pos = 0; { int _g12 = 0; int _g4 = path.length; while ((_g12 < _g4)) { int i2 = _g12++; global::encode.backward_references.ZopfliNode next = ((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[(pos + path[i2])])); int copy_length = next.length; int insert_length = next.insert_length; pos += insert_length; if ((i2 == 0)) { insert_length += last_insert_len[0]; } int distance = next.distance; int len_code1 = next.length_code; bool is_dictionary = (distance > ((int)(global::System.Math.Min(((double)((position + pos))), ((double)(max_backward_limit)))))); int dist_code1 = next.distance_code; global::encode.command.Command command = new global::encode.command.Command(); command.Command4(insert_length, copy_length, len_code1, dist_code1); commands[commands_off++] = command; if ((!(is_dictionary) && (dist_code1 > 0))) { ((int[])(dist_cache))[3] = ((int)(((int[])(dist_cache))[2])); ((int[])(dist_cache))[2] = ((int)(((int[])(dist_cache))[1])); ((int[])(dist_cache))[1] = ((int)(((int[])(dist_cache))[0])); ((int[])(dist_cache))[0] = distance; } num_literals[0] += insert_length; insert_length = 0; pos += copy_length; } } last_insert_len[0] = (num_bytes - pos); num_commands[0] += (commands_off - orig_commands_off); } }