Beispiel #1
0
        private static unsafe void BrotliBuildMetaBlockGreedyInternal(
            ref MemoryManager m, byte *ringbuffer, size_t pos, size_t mask,
            byte prev_byte, byte prev_byte2, ContextType literal_context_mode,
            size_t num_contexts, uint *static_context_map,
            Command *commands, size_t n_commands, MetaBlockSplit *mb)
        {
            lit_blocks_union      lit_blocks = new lit_blocks_union();
            BlockSplitterCommand  cmd_blocks;
            BlockSplitterDistance dist_blocks;
            size_t num_literals = 0;
            size_t i;

            for (i = 0; i < n_commands; ++i)
            {
                num_literals += commands[i].insert_len_;
            }

            if (num_contexts == 1)
            {
                BlockSplitterLiteral.InitBlockSplitter(ref m, (BlockSplitterLiteral *)&lit_blocks, 256, 512, 400.0,
                                                       num_literals, &mb->literal_split, &mb->literal_histograms,
                                                       &mb->literal_histograms_size);
            }
            else
            {
                InitContextBlockSplitter(ref m, &lit_blocks.ctx, 256, num_contexts, 512, 400.0,
                                         num_literals, &mb->literal_split, &mb->literal_histograms,
                                         &mb->literal_histograms_size);
            }
            BlockSplitterCommand.InitBlockSplitter(ref m, &cmd_blocks, BROTLI_NUM_COMMAND_SYMBOLS, 1024,
                                                   500.0, n_commands, &mb->command_split, &mb->command_histograms,
                                                   &mb->command_histograms_size);
            BlockSplitterDistance.InitBlockSplitter(ref m, &dist_blocks, 64, 512, 100.0, n_commands,
                                                    &mb->distance_split, &mb->distance_histograms,
                                                    &mb->distance_histograms_size);

            for (i = 0; i < n_commands; ++i)
            {
                Command cmd = commands[i];
                size_t  j;
                BlockSplitterCommand.BlockSplitterAddSymbol(&cmd_blocks, cmd.cmd_prefix_);
                for (j = cmd.insert_len_; j != 0; --j)
                {
                    byte literal = ringbuffer[pos & mask];
                    if (num_contexts == 1)
                    {
                        BlockSplitterLiteral.BlockSplitterAddSymbol((BlockSplitterLiteral *)&lit_blocks, literal);
                    }
                    else
                    {
                        size_t context = Context(prev_byte, prev_byte2, literal_context_mode);
                        ContextBlockSplitterAddSymbol(&lit_blocks.ctx, ref m, literal,
                                                      static_context_map[context]);
                    }
                    prev_byte2 = prev_byte;
                    prev_byte  = literal;
                    ++pos;
                }
                pos += CommandCopyLen(&cmd);
                if (CommandCopyLen(&cmd) != 0)
                {
                    prev_byte2 = ringbuffer[(pos - 2) & mask];
                    prev_byte  = ringbuffer[(pos - 1) & mask];
                    if (cmd.cmd_prefix_ >= 128)
                    {
                        BlockSplitterDistance.BlockSplitterAddSymbol(&dist_blocks, cmd.dist_prefix_);
                    }
                }
            }

            if (num_contexts == 1)
            {
                BlockSplitterLiteral.BlockSplitterFinishBlock(
                    (BlockSplitterLiteral *)&lit_blocks, /* is_final = */ true);
            }
            else
            {
                ContextBlockSplitterFinishBlock(
                    &lit_blocks.ctx, ref m, /* is_final = */ true);
            }
            BlockSplitterCommand.BlockSplitterFinishBlock(&cmd_blocks, /* is_final = */ true);
            BlockSplitterDistance.BlockSplitterFinishBlock(&dist_blocks, /* is_final = */ true);

            if (num_contexts > 1)
            {
                MapStaticContexts(ref m, num_contexts, static_context_map, mb);
            }
        }
Beispiel #2
0
        private static unsafe void BrotliSplitBlock(ref MemoryManager m,
                                                    Command *cmds,
                                                    size_t num_commands,
                                                    byte *data,
                                                    size_t pos,
                                                    size_t mask,
                                                    BrotliEncoderParams *params_,
                                                    BlockSplit *literal_split,
                                                    BlockSplit *insert_and_copy_split,
                                                    BlockSplit *dist_split)
        {
            {
                size_t literals_count = CountLiterals(cmds, num_commands);
                byte * literals       = (byte *)BrotliAllocate(ref m, literals_count * sizeof(byte));

                /* Create a continuous array of literals. */
                CopyLiteralsToByteArray(cmds, num_commands, data, pos, mask, literals);

                /* Create the block split on the array of literals.
                 * Literal histograms have alphabet size 256. */
                BlockSplitterLiteral.SplitByteVector(
                    ref m, literals, literals_count,
                    kSymbolsPerLiteralHistogram, kMaxLiteralHistograms,
                    kLiteralStrideLength, kLiteralBlockSwitchCost, params_,
                    literal_split);

                BrotliFree(ref m, literals);
            }

            {
                /* Compute prefix codes for commands. */
                ushort *insert_and_copy_codes = (ushort *)BrotliAllocate(ref m, num_commands * sizeof(ushort));
                size_t  i;

                for (i = 0; i < num_commands; ++i)
                {
                    insert_and_copy_codes[i] = cmds[i].cmd_prefix_;
                }
                /* Create the block split on the array of command prefixes. */
                BlockSplitterCommand.SplitByteVector(
                    ref m, insert_and_copy_codes, num_commands,
                    kSymbolsPerCommandHistogram, kMaxCommandHistograms,
                    kCommandStrideLength, kCommandBlockSwitchCost, params_,
                    insert_and_copy_split);

                /* TODO: reuse for distances? */
                BrotliFree(ref m, insert_and_copy_codes);
            }

            {
                /* Create a continuous array of distance prefixes. */
                ushort *distance_prefixes = (ushort *)BrotliAllocate(ref m, num_commands * sizeof(ushort));
                size_t  j = 0;
                size_t  i;

                for (i = 0; i < num_commands; ++i)
                {
                    Command *cmd = &cmds[i];
                    if (CommandCopyLen(cmd) != 0 && cmd->cmd_prefix_ >= 128)
                    {
                        distance_prefixes[j++] = cmd->dist_prefix_;
                    }
                }
                /* Create the block split on the array of distance prefixes. */
                BlockSplitterDistance.SplitByteVector(
                    ref m, distance_prefixes, j,
                    kSymbolsPerDistanceHistogram, kMaxCommandHistograms,
                    kCommandStrideLength, kDistanceBlockSwitchCost, params_,
                    dist_split);

                BrotliFree(ref m, distance_prefixes);
            }
        }