11cb0ef41Sopenharmony_ci/* Copyright 2016 Google Inc. All Rights Reserved.
21cb0ef41Sopenharmony_ci
31cb0ef41Sopenharmony_ci   Distributed under MIT license.
41cb0ef41Sopenharmony_ci   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
51cb0ef41Sopenharmony_ci*/
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_ci/* Constants and formulas that affect speed-ratio trade-offs and thus define
81cb0ef41Sopenharmony_ci   quality levels. */
91cb0ef41Sopenharmony_ci
101cb0ef41Sopenharmony_ci#ifndef BROTLI_ENC_QUALITY_H_
111cb0ef41Sopenharmony_ci#define BROTLI_ENC_QUALITY_H_
121cb0ef41Sopenharmony_ci
131cb0ef41Sopenharmony_ci#include "../common/platform.h"
141cb0ef41Sopenharmony_ci#include <brotli/encode.h>
151cb0ef41Sopenharmony_ci#include "./params.h"
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci#define FAST_ONE_PASS_COMPRESSION_QUALITY 0
181cb0ef41Sopenharmony_ci#define FAST_TWO_PASS_COMPRESSION_QUALITY 1
191cb0ef41Sopenharmony_ci#define ZOPFLIFICATION_QUALITY 10
201cb0ef41Sopenharmony_ci#define HQ_ZOPFLIFICATION_QUALITY 11
211cb0ef41Sopenharmony_ci
221cb0ef41Sopenharmony_ci#define MAX_QUALITY_FOR_STATIC_ENTROPY_CODES 2
231cb0ef41Sopenharmony_ci#define MIN_QUALITY_FOR_BLOCK_SPLIT 4
241cb0ef41Sopenharmony_ci#define MIN_QUALITY_FOR_NONZERO_DISTANCE_PARAMS 4
251cb0ef41Sopenharmony_ci#define MIN_QUALITY_FOR_OPTIMIZE_HISTOGRAMS 4
261cb0ef41Sopenharmony_ci#define MIN_QUALITY_FOR_EXTENSIVE_REFERENCE_SEARCH 5
271cb0ef41Sopenharmony_ci#define MIN_QUALITY_FOR_CONTEXT_MODELING 5
281cb0ef41Sopenharmony_ci#define MIN_QUALITY_FOR_HQ_CONTEXT_MODELING 7
291cb0ef41Sopenharmony_ci#define MIN_QUALITY_FOR_HQ_BLOCK_SPLITTING 10
301cb0ef41Sopenharmony_ci
311cb0ef41Sopenharmony_ci/* For quality below MIN_QUALITY_FOR_BLOCK_SPLIT there is no block splitting,
321cb0ef41Sopenharmony_ci   so we buffer at most this much literals and commands. */
331cb0ef41Sopenharmony_ci#define MAX_NUM_DELAYED_SYMBOLS 0x2FFF
341cb0ef41Sopenharmony_ci
351cb0ef41Sopenharmony_ci/* Returns hash-table size for quality levels 0 and 1. */
361cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t MaxHashTableSize(int quality) {
371cb0ef41Sopenharmony_ci  return quality == FAST_ONE_PASS_COMPRESSION_QUALITY ? 1 << 15 : 1 << 17;
381cb0ef41Sopenharmony_ci}
391cb0ef41Sopenharmony_ci
401cb0ef41Sopenharmony_ci/* The maximum length for which the zopflification uses distinct distances. */
411cb0ef41Sopenharmony_ci#define MAX_ZOPFLI_LEN_QUALITY_10 150
421cb0ef41Sopenharmony_ci#define MAX_ZOPFLI_LEN_QUALITY_11 325
431cb0ef41Sopenharmony_ci
441cb0ef41Sopenharmony_ci/* Do not thoroughly search when a long copy is found. */
451cb0ef41Sopenharmony_ci#define BROTLI_LONG_COPY_QUICK_STEP 16384
461cb0ef41Sopenharmony_ci
471cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t MaxZopfliLen(const BrotliEncoderParams* params) {
481cb0ef41Sopenharmony_ci  return params->quality <= 10 ?
491cb0ef41Sopenharmony_ci      MAX_ZOPFLI_LEN_QUALITY_10 :
501cb0ef41Sopenharmony_ci      MAX_ZOPFLI_LEN_QUALITY_11;
511cb0ef41Sopenharmony_ci}
521cb0ef41Sopenharmony_ci
531cb0ef41Sopenharmony_ci/* Number of best candidates to evaluate to expand Zopfli chain. */
541cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t MaxZopfliCandidates(
551cb0ef41Sopenharmony_ci  const BrotliEncoderParams* params) {
561cb0ef41Sopenharmony_ci  return params->quality <= 10 ? 1 : 5;
571cb0ef41Sopenharmony_ci}
581cb0ef41Sopenharmony_ci
591cb0ef41Sopenharmony_cistatic BROTLI_INLINE void SanitizeParams(BrotliEncoderParams* params) {
601cb0ef41Sopenharmony_ci  params->quality = BROTLI_MIN(int, BROTLI_MAX_QUALITY,
611cb0ef41Sopenharmony_ci      BROTLI_MAX(int, BROTLI_MIN_QUALITY, params->quality));
621cb0ef41Sopenharmony_ci  if (params->quality <= MAX_QUALITY_FOR_STATIC_ENTROPY_CODES) {
631cb0ef41Sopenharmony_ci    params->large_window = BROTLI_FALSE;
641cb0ef41Sopenharmony_ci  }
651cb0ef41Sopenharmony_ci  if (params->lgwin < BROTLI_MIN_WINDOW_BITS) {
661cb0ef41Sopenharmony_ci    params->lgwin = BROTLI_MIN_WINDOW_BITS;
671cb0ef41Sopenharmony_ci  } else {
681cb0ef41Sopenharmony_ci    int max_lgwin = params->large_window ? BROTLI_LARGE_MAX_WINDOW_BITS :
691cb0ef41Sopenharmony_ci                                           BROTLI_MAX_WINDOW_BITS;
701cb0ef41Sopenharmony_ci    if (params->lgwin > max_lgwin) params->lgwin = max_lgwin;
711cb0ef41Sopenharmony_ci  }
721cb0ef41Sopenharmony_ci}
731cb0ef41Sopenharmony_ci
741cb0ef41Sopenharmony_ci/* Returns optimized lg_block value. */
751cb0ef41Sopenharmony_cistatic BROTLI_INLINE int ComputeLgBlock(const BrotliEncoderParams* params) {
761cb0ef41Sopenharmony_ci  int lgblock = params->lgblock;
771cb0ef41Sopenharmony_ci  if (params->quality == FAST_ONE_PASS_COMPRESSION_QUALITY ||
781cb0ef41Sopenharmony_ci      params->quality == FAST_TWO_PASS_COMPRESSION_QUALITY) {
791cb0ef41Sopenharmony_ci    lgblock = params->lgwin;
801cb0ef41Sopenharmony_ci  } else if (params->quality < MIN_QUALITY_FOR_BLOCK_SPLIT) {
811cb0ef41Sopenharmony_ci    lgblock = 14;
821cb0ef41Sopenharmony_ci  } else if (lgblock == 0) {
831cb0ef41Sopenharmony_ci    lgblock = 16;
841cb0ef41Sopenharmony_ci    if (params->quality >= 9 && params->lgwin > lgblock) {
851cb0ef41Sopenharmony_ci      lgblock = BROTLI_MIN(int, 18, params->lgwin);
861cb0ef41Sopenharmony_ci    }
871cb0ef41Sopenharmony_ci  } else {
881cb0ef41Sopenharmony_ci    lgblock = BROTLI_MIN(int, BROTLI_MAX_INPUT_BLOCK_BITS,
891cb0ef41Sopenharmony_ci        BROTLI_MAX(int, BROTLI_MIN_INPUT_BLOCK_BITS, lgblock));
901cb0ef41Sopenharmony_ci  }
911cb0ef41Sopenharmony_ci  return lgblock;
921cb0ef41Sopenharmony_ci}
931cb0ef41Sopenharmony_ci
941cb0ef41Sopenharmony_ci/* Returns log2 of the size of main ring buffer area.
951cb0ef41Sopenharmony_ci   Allocate at least lgwin + 1 bits for the ring buffer so that the newly
961cb0ef41Sopenharmony_ci   added block fits there completely and we still get lgwin bits and at least
971cb0ef41Sopenharmony_ci   read_block_size_bits + 1 bits because the copy tail length needs to be
981cb0ef41Sopenharmony_ci   smaller than ring-buffer size. */
991cb0ef41Sopenharmony_cistatic BROTLI_INLINE int ComputeRbBits(const BrotliEncoderParams* params) {
1001cb0ef41Sopenharmony_ci  return 1 + BROTLI_MAX(int, params->lgwin, params->lgblock);
1011cb0ef41Sopenharmony_ci}
1021cb0ef41Sopenharmony_ci
1031cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t MaxMetablockSize(
1041cb0ef41Sopenharmony_ci    const BrotliEncoderParams* params) {
1051cb0ef41Sopenharmony_ci  int bits =
1061cb0ef41Sopenharmony_ci      BROTLI_MIN(int, ComputeRbBits(params), BROTLI_MAX_INPUT_BLOCK_BITS);
1071cb0ef41Sopenharmony_ci  return (size_t)1 << bits;
1081cb0ef41Sopenharmony_ci}
1091cb0ef41Sopenharmony_ci
1101cb0ef41Sopenharmony_ci/* When searching for backward references and have not seen matches for a long
1111cb0ef41Sopenharmony_ci   time, we can skip some match lookups. Unsuccessful match lookups are very
1121cb0ef41Sopenharmony_ci   expensive and this kind of a heuristic speeds up compression quite a lot.
1131cb0ef41Sopenharmony_ci   At first 8 byte strides are taken and every second byte is put to hasher.
1141cb0ef41Sopenharmony_ci   After 4x more literals stride by 16 bytes, every put 4-th byte to hasher.
1151cb0ef41Sopenharmony_ci   Applied only to qualities 2 to 9. */
1161cb0ef41Sopenharmony_cistatic BROTLI_INLINE size_t LiteralSpreeLengthForSparseSearch(
1171cb0ef41Sopenharmony_ci    const BrotliEncoderParams* params) {
1181cb0ef41Sopenharmony_ci  return params->quality < 9 ? 64 : 512;
1191cb0ef41Sopenharmony_ci}
1201cb0ef41Sopenharmony_ci
1211cb0ef41Sopenharmony_cistatic BROTLI_INLINE void ChooseHasher(const BrotliEncoderParams* params,
1221cb0ef41Sopenharmony_ci                                       BrotliHasherParams* hparams) {
1231cb0ef41Sopenharmony_ci  if (params->quality > 9) {
1241cb0ef41Sopenharmony_ci    hparams->type = 10;
1251cb0ef41Sopenharmony_ci  } else if (params->quality == 4 && params->size_hint >= (1 << 20)) {
1261cb0ef41Sopenharmony_ci    hparams->type = 54;
1271cb0ef41Sopenharmony_ci  } else if (params->quality < 5) {
1281cb0ef41Sopenharmony_ci    hparams->type = params->quality;
1291cb0ef41Sopenharmony_ci  } else if (params->lgwin <= 16) {
1301cb0ef41Sopenharmony_ci    hparams->type = params->quality < 7 ? 40 : params->quality < 9 ? 41 : 42;
1311cb0ef41Sopenharmony_ci  } else if (params->size_hint >= (1 << 20) && params->lgwin >= 19) {
1321cb0ef41Sopenharmony_ci    hparams->type = 6;
1331cb0ef41Sopenharmony_ci    hparams->block_bits = params->quality - 1;
1341cb0ef41Sopenharmony_ci    hparams->bucket_bits = 15;
1351cb0ef41Sopenharmony_ci    hparams->hash_len = 5;
1361cb0ef41Sopenharmony_ci    hparams->num_last_distances_to_check =
1371cb0ef41Sopenharmony_ci        params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16;
1381cb0ef41Sopenharmony_ci  } else {
1391cb0ef41Sopenharmony_ci    hparams->type = 5;
1401cb0ef41Sopenharmony_ci    hparams->block_bits = params->quality - 1;
1411cb0ef41Sopenharmony_ci    hparams->bucket_bits = params->quality < 7 ? 14 : 15;
1421cb0ef41Sopenharmony_ci    hparams->num_last_distances_to_check =
1431cb0ef41Sopenharmony_ci        params->quality < 7 ? 4 : params->quality < 9 ? 10 : 16;
1441cb0ef41Sopenharmony_ci  }
1451cb0ef41Sopenharmony_ci
1461cb0ef41Sopenharmony_ci  if (params->lgwin > 24) {
1471cb0ef41Sopenharmony_ci    /* Different hashers for large window brotli: not for qualities <= 2,
1481cb0ef41Sopenharmony_ci       these are too fast for large window. Not for qualities >= 10: their
1491cb0ef41Sopenharmony_ci       hasher already works well with large window. So the changes are:
1501cb0ef41Sopenharmony_ci       H3 --> H35: for quality 3.
1511cb0ef41Sopenharmony_ci       H54 --> H55: for quality 4 with size hint > 1MB
1521cb0ef41Sopenharmony_ci       H6 --> H65: for qualities 5, 6, 7, 8, 9. */
1531cb0ef41Sopenharmony_ci    if (hparams->type == 3) {
1541cb0ef41Sopenharmony_ci      hparams->type = 35;
1551cb0ef41Sopenharmony_ci    }
1561cb0ef41Sopenharmony_ci    if (hparams->type == 54) {
1571cb0ef41Sopenharmony_ci      hparams->type = 55;
1581cb0ef41Sopenharmony_ci    }
1591cb0ef41Sopenharmony_ci    if (hparams->type == 6) {
1601cb0ef41Sopenharmony_ci      hparams->type = 65;
1611cb0ef41Sopenharmony_ci    }
1621cb0ef41Sopenharmony_ci  }
1631cb0ef41Sopenharmony_ci}
1641cb0ef41Sopenharmony_ci
1651cb0ef41Sopenharmony_ci#endif  /* BROTLI_ENC_QUALITY_H_ */
166