2 * Copyright (c) 2018, Alliance for Open Media. All rights reserved
4 * This source code is subject to the terms of the BSD 2 Clause License and
5 * the Alliance for Open Media Patent License 1.0. If the BSD 2 Clause License
6 * was not distributed with this source code in the LICENSE file, you can
7 * obtain it at www.aomedia.org/license/software. If the Alliance for Open
8 * Media Patent License 1.0 was not distributed with this source code in the
9 * PATENTS file, you can obtain it at www.aomedia.org/license/patent.
13 #include "aom/aom_integer.h"
15 static const size_t kMaximumLeb128Size
= 8;
16 static const uint8_t kLeb128ByteMask
= 0x7f; // Binary: 01111111
18 // Disallow values larger than 32-bits to ensure consistent behavior on 32 and
19 // 64 bit targets: value is typically used to determine buffer allocation size
21 static const uint64_t kMaximumLeb128Value
= UINT32_MAX
;
23 size_t aom_uleb_size_in_bytes(uint64_t value
) {
27 } while ((value
>>= 7) != 0);
31 int aom_uleb_decode(const uint8_t *buffer
, size_t available
, uint64_t *value
,
33 if (buffer
&& value
) {
35 for (size_t i
= 0; i
< kMaximumLeb128Size
&& i
< available
; ++i
) {
36 const uint8_t decoded_byte
= *(buffer
+ i
) & kLeb128ByteMask
;
37 *value
|= ((uint64_t)decoded_byte
) << (i
* 7);
38 if ((*(buffer
+ i
) >> 7) == 0) {
43 // Fail on values larger than 32-bits to ensure consistent behavior on
44 // 32 and 64 bit targets: value is typically used to determine buffer
46 if (*value
> UINT32_MAX
) return -1;
53 // If we get here, either the buffer/value pointers were invalid,
54 // or we ran over the available space
58 int aom_uleb_encode(uint64_t value
, size_t available
, uint8_t *coded_value
,
60 const size_t leb_size
= aom_uleb_size_in_bytes(value
);
61 if (value
> kMaximumLeb128Value
|| leb_size
> kMaximumLeb128Size
||
62 leb_size
> available
|| !coded_value
|| !coded_size
) {
66 for (size_t i
= 0; i
< leb_size
; ++i
) {
67 uint8_t byte
= value
& 0x7f;
70 if (value
!= 0) byte
|= 0x80; // Signal that more bytes follow.
72 *(coded_value
+ i
) = byte
;
75 *coded_size
= leb_size
;
79 int aom_uleb_encode_fixed_size(uint64_t value
, size_t available
,
80 size_t pad_to_size
, uint8_t *coded_value
,
82 if (value
> kMaximumLeb128Value
|| !coded_value
|| !coded_size
||
83 available
< pad_to_size
|| pad_to_size
> kMaximumLeb128Size
) {
86 const uint64_t limit
= 1ULL << (7 * pad_to_size
);
88 // Can't encode 'value' within 'pad_to_size' bytes
92 for (size_t i
= 0; i
< pad_to_size
; ++i
) {
93 uint8_t byte
= value
& 0x7f;
96 if (i
< pad_to_size
- 1) byte
|= 0x80; // Signal that more bytes follow.
98 *(coded_value
+ i
) = byte
;
103 *coded_size
= pad_to_size
;