126fa459cSmrg/* Copyright 2015 Google Inc. All Rights Reserved.
226fa459cSmrg
326fa459cSmrg   Distributed under MIT license.
426fa459cSmrg   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
526fa459cSmrg*/
626fa459cSmrg
726fa459cSmrg/* Algorithms for distributing the literals and commands of a metablock between
826fa459cSmrg   block types and contexts. */
926fa459cSmrg
1026fa459cSmrg#ifndef BROTLI_ENC_METABLOCK_H_
1126fa459cSmrg#define BROTLI_ENC_METABLOCK_H_
1226fa459cSmrg
1326fa459cSmrg#include "../common/context.h"
1426fa459cSmrg#include "../common/platform.h"
1526fa459cSmrg#include <brotli/types.h>
1626fa459cSmrg#include "./block_splitter.h"
1726fa459cSmrg#include "./command.h"
1826fa459cSmrg#include "./histogram.h"
1926fa459cSmrg#include "./memory.h"
2026fa459cSmrg#include "./quality.h"
2126fa459cSmrg
2226fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus)
2326fa459cSmrgextern "C" {
2426fa459cSmrg#endif
2526fa459cSmrg
2626fa459cSmrgtypedef struct MetaBlockSplit {
2726fa459cSmrg  BlockSplit literal_split;
2826fa459cSmrg  BlockSplit command_split;
2926fa459cSmrg  BlockSplit distance_split;
3026fa459cSmrg  uint32_t* literal_context_map;
3126fa459cSmrg  size_t literal_context_map_size;
3226fa459cSmrg  uint32_t* distance_context_map;
3326fa459cSmrg  size_t distance_context_map_size;
3426fa459cSmrg  HistogramLiteral* literal_histograms;
3526fa459cSmrg  size_t literal_histograms_size;
3626fa459cSmrg  HistogramCommand* command_histograms;
3726fa459cSmrg  size_t command_histograms_size;
3826fa459cSmrg  HistogramDistance* distance_histograms;
3926fa459cSmrg  size_t distance_histograms_size;
4026fa459cSmrg} MetaBlockSplit;
4126fa459cSmrg
4226fa459cSmrgstatic BROTLI_INLINE void InitMetaBlockSplit(MetaBlockSplit* mb) {
4326fa459cSmrg  BrotliInitBlockSplit(&mb->literal_split);
4426fa459cSmrg  BrotliInitBlockSplit(&mb->command_split);
4526fa459cSmrg  BrotliInitBlockSplit(&mb->distance_split);
4626fa459cSmrg  mb->literal_context_map = 0;
4726fa459cSmrg  mb->literal_context_map_size = 0;
4826fa459cSmrg  mb->distance_context_map = 0;
4926fa459cSmrg  mb->distance_context_map_size = 0;
5026fa459cSmrg  mb->literal_histograms = 0;
5126fa459cSmrg  mb->literal_histograms_size = 0;
5226fa459cSmrg  mb->command_histograms = 0;
5326fa459cSmrg  mb->command_histograms_size = 0;
5426fa459cSmrg  mb->distance_histograms = 0;
5526fa459cSmrg  mb->distance_histograms_size = 0;
5626fa459cSmrg}
5726fa459cSmrg
5826fa459cSmrgstatic BROTLI_INLINE void DestroyMetaBlockSplit(
5926fa459cSmrg    MemoryManager* m, MetaBlockSplit* mb) {
6026fa459cSmrg  BrotliDestroyBlockSplit(m, &mb->literal_split);
6126fa459cSmrg  BrotliDestroyBlockSplit(m, &mb->command_split);
6226fa459cSmrg  BrotliDestroyBlockSplit(m, &mb->distance_split);
6326fa459cSmrg  BROTLI_FREE(m, mb->literal_context_map);
6426fa459cSmrg  BROTLI_FREE(m, mb->distance_context_map);
6526fa459cSmrg  BROTLI_FREE(m, mb->literal_histograms);
6626fa459cSmrg  BROTLI_FREE(m, mb->command_histograms);
6726fa459cSmrg  BROTLI_FREE(m, mb->distance_histograms);
6826fa459cSmrg}
6926fa459cSmrg
7026fa459cSmrg/* Uses the slow shortest-path block splitter and does context clustering.
7126fa459cSmrg   The distance parameters are dynamically selected based on the commands
7226fa459cSmrg   which get recomputed under the new distance parameters. The new distance
7326fa459cSmrg   parameters are stored into *params. */
7426fa459cSmrgBROTLI_INTERNAL void BrotliBuildMetaBlock(MemoryManager* m,
7526fa459cSmrg                                          const uint8_t* ringbuffer,
7626fa459cSmrg                                          const size_t pos,
7726fa459cSmrg                                          const size_t mask,
7826fa459cSmrg                                          BrotliEncoderParams* params,
7926fa459cSmrg                                          uint8_t prev_byte,
8026fa459cSmrg                                          uint8_t prev_byte2,
8126fa459cSmrg                                          Command* cmds,
8226fa459cSmrg                                          size_t num_commands,
8326fa459cSmrg                                          ContextType literal_context_mode,
8426fa459cSmrg                                          MetaBlockSplit* mb);
8526fa459cSmrg
8626fa459cSmrg/* Uses a fast greedy block splitter that tries to merge current block with the
8726fa459cSmrg   last or the second last block and uses a static context clustering which
8826fa459cSmrg   is the same for all block types. */
8926fa459cSmrgBROTLI_INTERNAL void BrotliBuildMetaBlockGreedy(
9026fa459cSmrg    MemoryManager* m, const uint8_t* ringbuffer, size_t pos, size_t mask,
9126fa459cSmrg    uint8_t prev_byte, uint8_t prev_byte2, ContextLut literal_context_lut,
9226fa459cSmrg    size_t num_contexts, const uint32_t* static_context_map,
9326fa459cSmrg    const Command* commands, size_t n_commands, MetaBlockSplit* mb);
9426fa459cSmrg
9526fa459cSmrgBROTLI_INTERNAL void BrotliOptimizeHistograms(uint32_t num_distance_codes,
9626fa459cSmrg                                              MetaBlockSplit* mb);
9726fa459cSmrg
9826fa459cSmrgBROTLI_INTERNAL void BrotliInitDistanceParams(BrotliEncoderParams* params,
9926fa459cSmrg    uint32_t npostfix, uint32_t ndirect);
10026fa459cSmrg
10126fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus)
10226fa459cSmrg}  /* extern "C" */
10326fa459cSmrg#endif
10426fa459cSmrg
10526fa459cSmrg#endif  /* BROTLI_ENC_METABLOCK_H_ */
106