public static void __hx_ctor_encode_backward_references_ZopfliCostModel(global::encode.backward_references.ZopfliCostModel __hx_this) { }
public static void CreateBackwardReferences(int num_bytes, int position, uint[] ringbuffer, int ringbuffer_mask, double[] literal_cost, int literal_cost_mask, int max_backward_limit, int quality, global::encode.hash.Hashers hashers, int hash_type, 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 ((quality > 9)) { global::encode.hash.HashLongestMatch hasher = hashers.hash_h9; 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[] num_matches = global::FunctionMalloc.mallocInt(num_bytes); global::Array <object> matches = global::FunctionMalloc.mallocArray_encode_hash_BackwardMatch(typeof(global::encode.hash.BackwardMatch), (3 * num_bytes)); int cur_match_pos = 0; int i = 0; while (((i + 3) < num_bytes)) { int max_distance = ((int)(global::System.Math.Min(((double)((position + i))), ((double)(max_backward_limit))))); if ((matches.length < (cur_match_pos + 325))) { matches.concat(global::FunctionMalloc.mallocArray_encode_hash_BackwardMatch(typeof(global::encode.hash.BackwardMatch), ((cur_match_pos + 325) - matches.length))); } hasher.FindAllMatches(ringbuffer, ringbuffer_mask, ((uint)((position + i))), ((uint)((num_bytes - i))), ((uint)(max_distance)), num_matches, i, matches, cur_match_pos); hasher.Store(ringbuffer, ((position + i) & ringbuffer_mask), (position + i)); cur_match_pos += ((int)(((int[])(num_matches))[i])); if ((((int)(((int[])(num_matches))[i])) == 1)) { int match_len = ((global::encode.hash.BackwardMatch)(matches[(cur_match_pos - 1)])).length(); if ((match_len > 325)) { int _g1 = 1; while ((_g1 < match_len)) { ++_g1; ++i; hasher.Store(ringbuffer, ((position + i) & ringbuffer_mask), (position + i)); ((int[])(num_matches))[i] = 0; } } } ++i; } int orig_num_literals = num_literals[0]; int orig_last_insert_len = last_insert_len[0]; int[] orig_dist_cache = ((int[])(new int[4])); ((int[])(orig_dist_cache))[0] = ((int)(((int[])(dist_cache))[0])); ((int[])(orig_dist_cache))[1] = ((int)(((int[])(dist_cache))[1])); ((int[])(orig_dist_cache))[2] = ((int)(((int[])(dist_cache))[2])); ((int[])(orig_dist_cache))[3] = ((int)(((int[])(dist_cache))[3])); int orig_num_commands = num_commands[0]; { int _g11 = 0; while ((_g11 < 2)) { global::encode.backward_references.ZopfliCostModel model = new global::encode.backward_references.ZopfliCostModel(); if ((_g11++ == 0)) { model.SetFromLiteralCosts(num_bytes, position, literal_cost, literal_cost_mask); } else { model.SetFromCommands(num_bytes, position, ringbuffer, ringbuffer_mask, commands, ((commands_off + num_commands[0]) - orig_num_commands), orig_last_insert_len); } num_commands[0] = orig_num_commands; num_literals[0] = orig_num_literals; last_insert_len[0] = orig_last_insert_len; global::DefaultFunctions.memcpy_Int(dist_cache, 0, orig_dist_cache, 0, 4); global::encode.Backward_references.ZopfliIterate(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, model, num_matches, matches, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); } } return; } switch (hash_type) { case 1: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatchQuickly(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h1, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 2: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatchQuickly(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h2, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 3: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatchQuickly(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h3, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 4: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatchQuickly(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h4, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 5: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatch(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h5, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 6: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatch(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h6, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 7: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatch(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h7, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 8: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatch(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h8, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } case 9: { global::encode.Backward_references.CreateBackwardReferences_HashLongestMatch(num_bytes, position, ringbuffer, ringbuffer_mask, max_backward_limit, quality, hashers.hash_h9, dist_cache, last_insert_len, commands, commands_off, num_commands, num_literals); break; } default: { break; } } } }
public static int ComputeMinimumCopyLength(global::encode.backward_references.StartPosQueue queue, global::encode.backward_references.ZopfliNode[] nodes, global::encode.backward_references.ZopfliCostModel model, int pos, double min_cost_cmd) { unchecked { int start0 = queue.GetStartPos(0); double min_cost = ((((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[start0])).cost + model.GetLiteralCosts(start0, pos)) + min_cost_cmd); int len = 2; int next_len_bucket = 4; int next_len_offset = 10; while ((((pos + len) < (((global::encode.backward_references.ZopfliNode[])(nodes)) as global::System.Array).Length) && (((global::encode.backward_references.ZopfliNode)(((global::encode.backward_references.ZopfliNode[])(nodes))[(pos + len)])).cost <= min_cost))) { ++len; if ((len == next_len_offset)) { min_cost += 1.0; next_len_offset += next_len_bucket; next_len_bucket *= 2; } } return(len); } }
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); } }