Exemplo n.º 1
0
        private static unsafe void BrotliBuildMetaBlock(ref MemoryManager m,
                                                        byte *ringbuffer,
                                                        size_t pos,
                                                        size_t mask,
                                                        BrotliEncoderParams *params_,
                                                        byte prev_byte,
                                                        byte prev_byte2,
                                                        Command *cmds,
                                                        size_t num_commands,
                                                        ContextType literal_context_mode,
                                                        MetaBlockSplit *mb)
        {
            /* Histogram ids need to fit in one byte. */
            size_t             kMaxNumberOfHistograms = 256;
            HistogramDistance *distance_histograms;
            HistogramLiteral * literal_histograms;
            ContextType *      literal_context_modes = null;
            size_t             literal_histograms_size;
            size_t             distance_histograms_size;
            size_t             i;
            size_t             literal_context_multiplier = 1;

            BrotliSplitBlock(ref m, cmds, num_commands,
                             ringbuffer, pos, mask, params_,
                             &mb->literal_split,
                             &mb->command_split,
                             &mb->distance_split);

            if (!params_->disable_literal_context_modeling)
            {
                literal_context_multiplier = 1 << BROTLI_LITERAL_CONTEXT_BITS;
                literal_context_modes      =
                    (ContextType *)BrotliAllocate(ref m, mb->literal_split.num_types * sizeof(ContextType));
                for (i = 0; i < mb->literal_split.num_types; ++i)
                {
                    literal_context_modes[i] = literal_context_mode;
                }
            }

            literal_histograms_size =
                mb->literal_split.num_types * literal_context_multiplier;
            literal_histograms =
                (HistogramLiteral *)BrotliAllocate(ref m, literal_histograms_size * sizeof(HistogramLiteral));
            HistogramLiteral.ClearHistograms(literal_histograms, literal_histograms_size);

            distance_histograms_size =
                mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS;
            distance_histograms =
                (HistogramDistance *)BrotliAllocate(ref m, distance_histograms_size * sizeof(HistogramDistance));
            HistogramDistance.ClearHistograms(distance_histograms, distance_histograms_size);

            mb->command_histograms_size = mb->command_split.num_types;
            mb->command_histograms      =
                (HistogramCommand *)BrotliAllocate(ref m, mb->command_histograms_size * sizeof(HistogramCommand));
            HistogramCommand.ClearHistograms(mb->command_histograms, mb->command_histograms_size);

            BrotliBuildHistogramsWithContext(cmds, num_commands,
                                             &mb->literal_split, &mb->command_split, &mb->distance_split,
                                             ringbuffer, pos, mask, prev_byte, prev_byte2, literal_context_modes,
                                             literal_histograms, mb->command_histograms, distance_histograms);
            BrotliFree(ref m, literal_context_modes);

            mb->literal_context_map_size =
                mb->literal_split.num_types << BROTLI_LITERAL_CONTEXT_BITS;
            mb->literal_context_map =
                (uint *)BrotliAllocate(ref m, mb->literal_context_map_size * sizeof(uint));

            mb->literal_histograms_size = mb->literal_context_map_size;
            mb->literal_histograms      =
                (HistogramLiteral *)BrotliAllocate(ref m, mb->literal_histograms_size * sizeof(HistogramLiteral));

            ClusterLiteral.BrotliClusterHistograms(ref m, literal_histograms, literal_histograms_size,
                                                   kMaxNumberOfHistograms, mb->literal_histograms,
                                                   &mb->literal_histograms_size, mb->literal_context_map);
            BrotliFree(ref m, literal_histograms);

            if (params_->disable_literal_context_modeling)
            {
                /* Distribute assignment to all contexts. */
                for (i = mb->literal_split.num_types; i != 0;)
                {
                    size_t j = 0;
                    i--;
                    for (; j < (1 << BROTLI_LITERAL_CONTEXT_BITS); j++)
                    {
                        mb->literal_context_map[(i << BROTLI_LITERAL_CONTEXT_BITS) + j] =
                            mb->literal_context_map[i];
                    }
                }
            }

            mb->distance_context_map_size =
                mb->distance_split.num_types << BROTLI_DISTANCE_CONTEXT_BITS;
            mb->distance_context_map =
                (uint *)BrotliAllocate(ref m, mb->distance_context_map_size * sizeof(uint));

            mb->distance_histograms_size = mb->distance_context_map_size;
            mb->distance_histograms      =
                (HistogramDistance *)BrotliAllocate(ref m, mb->distance_histograms_size * sizeof(HistogramDistance));

            ClusterDistance.BrotliClusterHistograms(ref m, distance_histograms,
                                                    mb->distance_context_map_size,
                                                    kMaxNumberOfHistograms,
                                                    mb->distance_histograms,
                                                    &mb->distance_histograms_size,
                                                    mb->distance_context_map);
            BrotliFree(ref m, distance_histograms);
        }