예제 #1
0
 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>();
 }
예제 #2
0
        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));
            }
        }
예제 #3
0
 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]);
             }
         }
     }
 }
예제 #4
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);
            }
        }
예제 #5
0
        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])));
                            }
                        }
                    }
                }
            }
        }
예제 #6
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_);
                        }
                    }
                }
            }
        }
예제 #7
0
        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]);
                            }
                        }
                    }
                }
            }
        }
예제 #8
0
        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);
            }
        }
예제 #9
0
        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);
            }
        }
예제 #10
0
        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);
            }
        }
예제 #11
0
        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);
            }
        }