1 /*
2 * Copyright (C) 2017-2018 Team Kodi
3 * This file is part of Kodi - https://kodi.tv
4 *
5 * SPDX-License-Identifier: GPL-2.0-or-later
6 * See LICENSES/README.md for more information.
7 */
8
9 #include "BitstreamWriter.h"
10
CBitstreamWriter(uint8_t * buffer,unsigned int buffer_size,int writer_le)11 CBitstreamWriter::CBitstreamWriter(uint8_t *buffer, unsigned int buffer_size, int writer_le)
12 : writer_le(writer_le)
13 , bit_buf(0)
14 , bit_left(32)
15 , buf(buffer)
16 , buf_ptr(buf)
17 {
18 }
19
WriteBits(int n,unsigned int value)20 void CBitstreamWriter::WriteBits(int n, unsigned int value)
21 {
22 // Write up to 32 bits into a bitstream.
23 unsigned int bit_buf;
24 int bit_left;
25
26 if (n == 32)
27 {
28 // Write exactly 32 bits into a bitstream.
29 // danger, recursion in play.
30 int lo = value & 0xffff;
31 int hi = value >> 16;
32 if (writer_le)
33 {
34 WriteBits(16, lo);
35 WriteBits(16, hi);
36 }
37 else
38 {
39 WriteBits(16, hi);
40 WriteBits(16, lo);
41 }
42 return;
43 }
44
45 bit_buf = this->bit_buf;
46 bit_left = this->bit_left;
47
48 if (writer_le)
49 {
50 bit_buf |= value << (32 - bit_left);
51 if (n >= bit_left) {
52 BS_WL32(buf_ptr, bit_buf);
53 buf_ptr += 4;
54 bit_buf = (bit_left == 32) ? 0 : value >> bit_left;
55 bit_left += 32;
56 }
57 bit_left -= n;
58 }
59 else
60 {
61 if (n < bit_left) {
62 bit_buf = (bit_buf << n) | value;
63 bit_left -= n;
64 }
65 else {
66 bit_buf <<= bit_left;
67 bit_buf |= value >> (n - bit_left);
68 BS_WB32(buf_ptr, bit_buf);
69 buf_ptr += 4;
70 bit_left += 32 - n;
71 bit_buf = value;
72 }
73 }
74
75 this->bit_buf = bit_buf;
76 this->bit_left = bit_left;
77 }
78
SkipBits(int n)79 void CBitstreamWriter::SkipBits(int n)
80 {
81 // Skip the given number of bits.
82 // Must only be used if the actual values in the bitstream do not matter.
83 // If n is 0 the behavior is undefined.
84 bit_left -= n;
85 buf_ptr -= 4 * (bit_left >> 5);
86 bit_left &= 31;
87 }
88
FlushBits()89 void CBitstreamWriter::FlushBits()
90 {
91 if (!writer_le)
92 {
93 if (bit_left < 32)
94 bit_buf <<= bit_left;
95 }
96 while (bit_left < 32)
97 {
98
99 if (writer_le)
100 {
101 *buf_ptr++ = bit_buf;
102 bit_buf >>= 8;
103 }
104 else
105 {
106 *buf_ptr++ = bit_buf >> 24;
107 bit_buf <<= 8;
108 }
109 bit_left += 8;
110 }
111 bit_left = 32;
112 bit_buf = 0;
113 }
114