Exemple #1
0
    public static global::Array <object> mallocArray_encode_hash_BackwardMatch(global::System.Type t, int a)
    {
        global::Array <object> arr = new global::Array <object>();

        {
            int _g1 = 0;
            while ((_g1 < a))
            {
                arr[_g1++] = new global::encode.hash.BackwardMatch();
            }
        }

        return(arr);
    }
        public virtual void FindAllMatches(uint[] data, int ring_buffer_mask, uint cur_ix, uint max_length, uint max_backward, int[] num_matches, int num_matches_off, global::Array <object> matches, int matches_off)
        {
            unchecked {
                global::Array <object> orig_matches = matches;
                int orig_matches_off = matches_off;
                int cur_ix_masked    = ((int)(((uint)((cur_ix & ring_buffer_mask)))));
                int best_len         = 1;
                int stop             = ((int)(((uint)((cur_ix - 64)))));
                if ((stop < 0))
                {
                    stop = 0;
                }

                int i = ((int)(((uint)((cur_ix - 1)))));
                while (((i > stop) && (best_len <= 2)))
                {
                    int prev_ix  = i;
                    int backward = ((int)(((uint)((cur_ix - prev_ix)))));
                    if (((bool)((backward > max_backward))))
                    {
                        break;
                    }

                    prev_ix &= ring_buffer_mask;
                    if ((((bool)((((uint)(((uint[])(data))[cur_ix_masked])) != ((uint)(((uint[])(data))[prev_ix]))))) || ((bool)((((uint)(((uint[])(data))[(cur_ix_masked + 1)])) != ((uint)(((uint[])(data))[(prev_ix + 1)])))))))
                    {
                        --i;
                        continue;
                    }

                    int len = global::encode.Find_match_length.FindMatchLengthWithLimit(data, prev_ix, data, cur_ix_masked, ((int)(max_length)));
                    if ((len > best_len))
                    {
                        best_len = len;
                        if ((len > 325))
                        {
                            matches = orig_matches;
                        }

                        global::encode.hash.BackwardMatch match = new global::encode.hash.BackwardMatch();
                        match.BackwardMatch2(backward, len);
                        matches[matches_off++] = match;
                    }

                    --i;
                }

                uint  key    = global::encode.Hash.Hash_(this.kBucketBits, data, cur_ix_masked);
                int[] bucket = ((int[][])(this.buckets_))[((int)(key))];
                int   down   = ((((bool)((((uint[])(this.num_))[((int)(key))] > this.kBlockSize)))) ? (((int)(((uint)((((uint[])(this.num_))[((int)(key))] - this.kBlockSize)))))) : (0));
                int   i1     = ((int)(((uint)((((uint[])(this.num_))[((int)(key))] - 1)))));
                while ((i1 >= down))
                {
                    int prev_ix1 = ((int[])(bucket))[((int)(((uint)((this.kBlockMask & i1)))))];
                    if ((prev_ix1 >= 0))
                    {
                        uint backward1 = ((uint)((cur_ix - prev_ix1)));
                        if (((bool)((backward1 > max_backward))))
                        {
                            break;
                        }

                        prev_ix1 &= ring_buffer_mask;
                        if (((((cur_ix_masked + best_len) > ring_buffer_mask) || ((prev_ix1 + best_len) > ring_buffer_mask)) || ((bool)((((uint)(((uint[])(data))[(cur_ix_masked + best_len)])) != ((uint)(((uint[])(data))[(prev_ix1 + best_len)])))))))
                        {
                            --i1;
                            continue;
                        }

                        int len1 = global::encode.Find_match_length.FindMatchLengthWithLimit(data, prev_ix1, data, cur_ix_masked, ((int)(max_length)));
                        if ((len1 > best_len))
                        {
                            best_len = len1;
                            if ((len1 > 325))
                            {
                                matches_off = orig_matches_off;
                            }

                            global::encode.hash.BackwardMatch match1 = new global::encode.hash.BackwardMatch();
                            match1.BackwardMatch2(((int)(backward1)), len1);
                            matches[matches_off++] = match1;
                        }
                    }

                    --i1;
                }

                int[] dict_matches = global::FunctionMalloc.mallocInt(38);
                global::DefaultFunctions.memset_Int(dict_matches, 0, 268435455, (((int[])(dict_matches)) as global::System.Array).Length);
                int minlen = ((int)(global::System.Math.Max(((double)(4)), ((double)((best_len + 1))))));
                if (global::encode.Static_dict.FindAllStaticDictionaryMatches(data, cur_ix_masked, minlen, dict_matches, 0))
                {
                    int maxlen = ((int)(global::System.Math.Min(((double)(37)), ((double)(max_length)))));
                    {
                        int _g1 = minlen;
                        while ((_g1 < maxlen))
                        {
                            int l       = _g1++;
                            int dict_id = ((int)(((int[])(dict_matches))[l]));
                            if ((dict_id < 268435455))
                            {
                                global::encode.hash.BackwardMatch match2 = new global::encode.hash.BackwardMatch();
                                match2.BackwardMatch3(((int)(((uint)((((uint)((max_backward + ((dict_id >> 5))))) + 1))))), l, (dict_id & 31));
                                matches[matches_off++] = match2;
                            }
                        }
                    }
                }

                ((int[])(num_matches))[num_matches_off] = (((int)(((int[])(num_matches))[num_matches_off])) + ((matches_off - orig_matches_off)));
            }
        }
Exemple #3
0
 public static void __hx_ctor_encode_hash_BackwardMatch(global::encode.hash.BackwardMatch __hx_this)
 {
 }
        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);
            }
        }