prefix.h revision 26fa459c
126fa459cSmrg/* Copyright 2013 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/* Functions for encoding of integers into prefix codes the amount of extra
826fa459cSmrg   bits, and the actual values of the extra bits. */
926fa459cSmrg
1026fa459cSmrg#ifndef BROTLI_ENC_PREFIX_H_
1126fa459cSmrg#define BROTLI_ENC_PREFIX_H_
1226fa459cSmrg
1326fa459cSmrg#include "../common/constants.h"
1426fa459cSmrg#include "../common/platform.h"
1526fa459cSmrg#include <brotli/types.h>
1626fa459cSmrg#include "./fast_log.h"
1726fa459cSmrg
1826fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus)
1926fa459cSmrgextern "C" {
2026fa459cSmrg#endif
2126fa459cSmrg
2226fa459cSmrg/* Here distance_code is an intermediate code, i.e. one of the special codes or
2326fa459cSmrg   the actual distance increased by BROTLI_NUM_DISTANCE_SHORT_CODES - 1. */
2426fa459cSmrgstatic BROTLI_INLINE void PrefixEncodeCopyDistance(size_t distance_code,
2526fa459cSmrg                                                   size_t num_direct_codes,
2626fa459cSmrg                                                   size_t postfix_bits,
2726fa459cSmrg                                                   uint16_t* code,
2826fa459cSmrg                                                   uint32_t* extra_bits) {
2926fa459cSmrg  if (distance_code < BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes) {
3026fa459cSmrg    *code = (uint16_t)distance_code;
3126fa459cSmrg    *extra_bits = 0;
3226fa459cSmrg    return;
3326fa459cSmrg  } else {
3426fa459cSmrg    size_t dist = ((size_t)1 << (postfix_bits + 2u)) +
3526fa459cSmrg        (distance_code - BROTLI_NUM_DISTANCE_SHORT_CODES - num_direct_codes);
3626fa459cSmrg    size_t bucket = Log2FloorNonZero(dist) - 1;
3726fa459cSmrg    size_t postfix_mask = (1u << postfix_bits) - 1;
3826fa459cSmrg    size_t postfix = dist & postfix_mask;
3926fa459cSmrg    size_t prefix = (dist >> bucket) & 1;
4026fa459cSmrg    size_t offset = (2 + prefix) << bucket;
4126fa459cSmrg    size_t nbits = bucket - postfix_bits;
4226fa459cSmrg    *code = (uint16_t)((nbits << 10) |
4326fa459cSmrg        (BROTLI_NUM_DISTANCE_SHORT_CODES + num_direct_codes +
4426fa459cSmrg         ((2 * (nbits - 1) + prefix) << postfix_bits) + postfix));
4526fa459cSmrg    *extra_bits = (uint32_t)((dist - offset) >> postfix_bits);
4626fa459cSmrg  }
4726fa459cSmrg}
4826fa459cSmrg
4926fa459cSmrg#if defined(__cplusplus) || defined(c_plusplus)
5026fa459cSmrg}  /* extern "C" */
5126fa459cSmrg#endif
5226fa459cSmrg
5326fa459cSmrg#endif  /* BROTLI_ENC_PREFIX_H_ */
54