/* Copyright 2016 Google Inc. All Rights Reserved.

   Distributed under MIT license.
   See file LICENSE for detail or copy at https://opensource.org/licenses/MIT
*/

/**
 * @file
 * Common constants used in decoder and encoder API.
 */

#ifndef BROTLI_COMMON_CONSTANTS_H_
#define BROTLI_COMMON_CONSTANTS_H_

#include "./platform.h"
#include <brotli/types.h>

/* Specification: 7.3. Encoding of the context map */
#define BROTLI_CONTEXT_MAP_MAX_RLE 16

/* Specification: 2. Compressed representation overview */
#define BROTLI_MAX_NUMBER_OF_BLOCK_TYPES 256

/* Specification: 3.3. Alphabet sizes: insert-and-copy length */
#define BROTLI_NUM_LITERAL_SYMBOLS 256
#define BROTLI_NUM_COMMAND_SYMBOLS 704
#define BROTLI_NUM_BLOCK_LEN_SYMBOLS 26
#define BROTLI_MAX_CONTEXT_MAP_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + \
                                        BROTLI_CONTEXT_MAP_MAX_RLE)
#define BROTLI_MAX_BLOCK_TYPE_SYMBOLS (BROTLI_MAX_NUMBER_OF_BLOCK_TYPES + 2)

/* Specification: 3.5. Complex prefix codes */
#define BROTLI_REPEAT_PREVIOUS_CODE_LENGTH 16
#define BROTLI_REPEAT_ZERO_CODE_LENGTH 17
#define BROTLI_CODE_LENGTH_CODES (BROTLI_REPEAT_ZERO_CODE_LENGTH + 1)
/* "code length of 8 is repeated" */
#define BROTLI_INITIAL_REPEATED_CODE_LENGTH 8

/* "Large Window Brotli" */

/**
 * The theoretical maximum number of distance bits specified for large window
 * brotli, for 64-bit encoders and decoders. Even when in practice 32-bit
 * encoders and decoders only support up to 30 max distance bits, the value is
 * set to 62 because it affects the large window brotli file format.
 * Specifically, it affects the encoding of simple huffman tree for distances,
 * see Specification RFC 7932 chapter 3.4.
 */
#define BROTLI_LARGE_MAX_DISTANCE_BITS 62U
#define BROTLI_LARGE_MIN_WBITS 10
/**
 * The maximum supported large brotli window bits by the encoder and decoder.
 * Large window brotli allows up to 62 bits, however the current encoder and
 * decoder, designed for 32-bit integers, only support up to 30 bits maximum.
 */
#define BROTLI_LARGE_MAX_WBITS 30

/* Specification: 4. Encoding of distances */
#define BROTLI_NUM_DISTANCE_SHORT_CODES 16
/**
 * Maximal number of "postfix" bits.
 *
 * Number of "postfix" bits is stored as 2 bits in meta-block header.
 */
#define BROTLI_MAX_NPOSTFIX 3
#define BROTLI_MAX_NDIRECT 120
#define BROTLI_MAX_DISTANCE_BITS 24U
#define BROTLI_DISTANCE_ALPHABET_SIZE(NPOSTFIX, NDIRECT, MAXNBITS) ( \
    BROTLI_NUM_DISTANCE_SHORT_CODES + (NDIRECT) +                    \
    ((MAXNBITS) << ((NPOSTFIX) + 1)))
/* BROTLI_NUM_DISTANCE_SYMBOLS == 1128 */
#define BROTLI_NUM_DISTANCE_SYMBOLS \
    BROTLI_DISTANCE_ALPHABET_SIZE(  \
        BROTLI_MAX_NDIRECT, BROTLI_MAX_NPOSTFIX, BROTLI_LARGE_MAX_DISTANCE_BITS)

/* ((1 << 26) - 4) is the maximal distance that can be expressed in RFC 7932
   brotli stream using NPOSTFIX = 0 and NDIRECT = 0. With other NPOSTFIX and
   NDIRECT values distances up to ((1 << 29) + 88) could be expressed. */
#define BROTLI_MAX_DISTANCE 0x3FFFFFC

/* ((1 << 31) - 4) is the safe distance limit. Using this number as a limit
   allows safe distance calculation without overflows, given the distance
   alphabet size is limited to corresponding size
   (see kLargeWindowDistanceCodeLimits). */
#define BROTLI_MAX_ALLOWED_DISTANCE 0x7FFFFFFC

/* 7.1. Context modes and context ID lookup for literals */
/* "context IDs for literals are in the range of 0..63" */
#define BROTLI_LITERAL_CONTEXT_BITS 6

/* 7.2. Context ID for distances */
#define BROTLI_DISTANCE_CONTEXT_BITS 2

/* 9.1. Format of the Stream Header */
/* Number of slack bytes for window size. Don't confuse
   with BROTLI_NUM_DISTANCE_SHORT_CODES. */
#define BROTLI_WINDOW_GAP 16
#define BROTLI_MAX_BACKWARD_LIMIT(W) (((size_t)1 << (W)) - BROTLI_WINDOW_GAP)

typedef struct BrotliDistanceCodeLimit {
  uint32_t max_alphabet_size;
  uint32_t max_distance;
} BrotliDistanceCodeLimit;

/* This function calculates maximal size of distance alphabet, such that the
   distances greater than the given values can not be represented.

   This limits are designed to support fast and safe 32-bit decoders.
   "32-bit" means that signed integer values up to ((1 << 31) - 1) could be
   safely expressed.

   Brotli distance alphabet symbols do not represent consecutive distance
   ranges. Each distance alphabet symbol (excluding direct distances and short
   codes), represent interleaved (for NPOSTFIX > 0) range of distances.
   A "group" of consecutive (1 << NPOSTFIX) symbols represent non-interleaved
   range. Two consecutive groups require the same amount of "extra bits".

   It is important that distance alphabet represents complete "groups".
   To avoid complex logic on encoder side about interleaved ranges
   it was decided to restrict both sides to complete distance code "groups".
 */
BROTLI_UNUSED_FUNCTION BrotliDistanceCodeLimit BrotliCalculateDistanceCodeLimit(
    uint32_t max_distance, uint32_t npostfix, uint32_t ndirect) {
  BrotliDistanceCodeLimit result;
  /* Marking this function as unused, because not all files
     including "constants.h" use it -> compiler warns about that. */
  BROTLI_UNUSED(&BrotliCalculateDistanceCodeLimit);
  if (max_distance <= ndirect) {
    /* This case never happens / exists only for the sake of completeness. */
    result.max_alphabet_size = max_distance + BROTLI_NUM_DISTANCE_SHORT_CODES;
    result.max_distance = max_distance;
    return result;
  } else {
    /* The first prohibited value. */
    uint32_t forbidden_distance = max_distance + 1;
    /* Subtract "directly" encoded region. */
    uint32_t offset = forbidden_distance - ndirect - 1;
    uint32_t ndistbits = 0;
    uint32_t tmp;
    uint32_t half;
    uint32_t group;
    /* Postfix for the last dcode in the group. */
    uint32_t postfix = (1u << npostfix) - 1;
    uint32_t extra;
    uint32_t start;
    /* Remove postfix and "head-start". */
    offset = (offset >> npostfix) + 4;
    /* Calculate the number of distance bits. */
    tmp = offset / 2;
    /* Poor-man's log2floor, to avoid extra dependencies. */
    while (tmp != 0) {ndistbits++; tmp = tmp >> 1;}
    /* One bit is covered with subrange addressing ("half"). */
    ndistbits--;
    /* Find subrange. */
    half = (offset >> ndistbits) & 1;
    /* Calculate the "group" part of dcode. */
    group = ((ndistbits - 1) << 1) | half;
    /* Calculated "group" covers the prohibited distance value. */
    if (group == 0) {
      /* This case is added for correctness; does not occur for limit > 128. */
      result.max_alphabet_size = ndirect + BROTLI_NUM_DISTANCE_SHORT_CODES;
      result.max_distance = ndirect;
      return result;
    }
    /* Decrement "group", so it is the last permitted "group". */
    group--;
    /* After group was decremented, ndistbits and half must be recalculated. */
    ndistbits = (group >> 1) + 1;
    /* The last available distance in the subrange has all extra bits set. */
    extra = (1u << ndistbits) - 1;
    /* Calculate region start. NB: ndistbits >= 1. */
    start = (1u << (ndistbits + 1)) - 4;
    /* Move to subregion. */
    start += (group & 1) << ndistbits;
    /* Calculate the alphabet size. */
    result.max_alphabet_size = ((group << npostfix) | postfix) + ndirect +
        BROTLI_NUM_DISTANCE_SHORT_CODES + 1;
    /* Calculate the maximal distance representable by alphabet. */
    result.max_distance = ((start + extra) << npostfix) + postfix + ndirect + 1;
    return result;
  }
}

#endif  /* BROTLI_COMMON_CONSTANTS_H_ */
