1 /* 2 * Copyright (c) 2024, Alliance for Open Media. All rights reserved 3 * 4 * This source code is subject to the terms of the BSD 3-Clause Clear License 5 * and the Alliance for Open Media Patent License 1.0. If the BSD 3-Clause Clear 6 * License was not distributed with this source code in the LICENSE file, you 7 * can obtain it at www.aomedia.org/license/software-license/bsd-3-c-c. If the 8 * Alliance for Open Media Patent License 1.0 was not distributed with this 9 * source code in the PATENTS file, you can obtain it at 10 * www.aomedia.org/license/patent. 11 */ 12 #ifndef COMMON_READ_BIT_BUFFER_H_ 13 #define COMMON_READ_BIT_BUFFER_H_ 14 15 #include <cstddef> 16 #include <cstdint> 17 #include <filesystem> 18 #include <fstream> 19 #include <memory> 20 #include <string> 21 #include <vector> 22 23 #include "absl/status/status.h" 24 #include "absl/types/span.h" 25 #include "iamf/obu/types.h" 26 27 namespace iamf_tools { 28 29 /*!\brief Abstract class representing a buffer to read bit from. 30 * 31 * Concrete subclasses should hold the actual storage of the data and 32 * implement `LoadBytesToBuffer()` to handle how data are loaded from the 33 * storage to the internal buffer. 34 */ 35 class ReadBitBuffer { 36 public: 37 /*!\brief Destructor.*/ 38 virtual ~ReadBitBuffer() = default; 39 40 /*!\brief Reads upper `num_bits` from buffer to lower `num_bits` of `output`. 41 * 42 * \param num_bits Number of upper bits to read from buffer. Maximum value of 43 * 64. 44 * \param output Unsigned literal from buffer will be written here. 45 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 46 * `num_bits > 64` or the buffer's bit offset is negative. 47 * `absl::ResourceExhaustedError()` if the buffer 48 * runs out of data and cannot get more from source before the desired 49 * `num_bits` are read. 50 */ 51 absl::Status ReadUnsignedLiteral(int num_bits, uint64_t& output); 52 53 /*!\brief Reads upper `num_bits` from buffer to lower `num_bits` of `output`. 54 * 55 * \param num_bits Number of upper bits to read from buffer. Maximum value of 56 * 32. 57 * \param output Unsigned literal from buffer will be written here. 58 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 59 * `num_bits > 32` or the buffer's bit offset is negative. 60 * `absl::ResourceExhaustedError()` if the buffer 61 * runs out of data and cannot get more from source before the desired 62 * `num_bits` are read. 63 */ 64 absl::Status ReadUnsignedLiteral(int num_bits, uint32_t& output); 65 66 /*!\brief Reads upper `num_bits` from buffer to lower `num_bits` of `output`. 67 * 68 * \param num_bits Number of upper bits to read from buffer. Maximum value of 69 * 16. 70 * \param output Unsigned literal from buffer will be written here. 71 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 72 * `num_bits > 16` or the buffer's bit offset is negative. 73 * `absl::ResourceExhaustedError()` if the buffer runs out of data 74 * and cannot get more from source before the desired `num_bits` are 75 * read. 76 */ 77 absl::Status ReadUnsignedLiteral(int num_bits, uint16_t& output); 78 79 /*!\brief Reads upper `num_bits` from buffer to lower `num_bits` of `output`. 80 * 81 * \param num_bits Number of upper bits to read from buffer. Maximum value of 82 * 8. 83 * \param output Unsigned literal from buffer will be written here. 84 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 85 * `num_bits > 8` or the buffer's bit offset is negative. 86 * `absl::ResourceExhaustedError()` if the buffer runs 87 * out of data and cannot get more from source before the desired 88 * `num_bits` are read. 89 */ 90 absl::Status ReadUnsignedLiteral(int num_bits, uint8_t& output); 91 92 /*!\brief Reads the signed 16 bit integer from the read buffer. 93 * 94 * \param output Signed 16 bit integer will be written here. 95 * \return `absl::OkStatus()` on success. `absl::ResourceExhaustedError()` if 96 * the buffer is exhausted before the signed 16 is fully read and 97 * source does not have the requisite data to complete the signed 16. 98 * `absl::InvalidArgumentError()` if the buffer's bit offset is 99 * negative. 100 */ 101 absl::Status ReadSigned16(int16_t& output); 102 103 /*!\brief Reads a null terminated string from the read buffer. 104 * 105 * \param output String will be written here. 106 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 107 * the string is not terminated within `kIamfMaxStringSize` bytes. 108 * `absl::Status::kResourceExhausted` if the buffer is exhausted 109 * before the string is terminated and source does not have the 110 * requisite data to complete the string. Other specific statuses on 111 * failure. 112 */ 113 absl::Status ReadString(std::string& output); 114 115 /*!\brief Reads an unsigned leb128 from buffer into `uleb128`. 116 * 117 * This version is useful when the caller does not care about the number of 118 * bytes used to encode the data in the bitstream. 119 * 120 * \param uleb128 Decoded unsigned leb128 from buffer will be written here. 121 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 122 * the consumed data from the buffer does not fit into the 32 bits of 123 * uleb128, or if the data in the buffer requires that we read more 124 * than `kMaxLeb128Size` bytes, or the buffer's bit offset is 125 * negative. `absl::ResourceExhaustedError()` if the buffer is 126 * exhausted before the uleb128 is fully read and source does not 127 * have the requisite data to complete the uleb128. 128 */ 129 absl::Status ReadULeb128(DecodedUleb128& uleb128); 130 131 /*!\brief Reads an unsigned leb128 from buffer into `uleb128`. 132 * 133 * This version also records the number of bytes used to store the encoded 134 * uleb128 in the bitstream. 135 * 136 * \param uleb128 Decoded unsigned leb128 from buffer will be written here. 137 * \param encoded_uleb128_size Number of bytes used to store the encoded 138 * uleb128 in the bitstream. 139 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 140 * the consumed data from the buffer does not fit into the 32 bits of 141 * uleb128, or if the data in the buffer requires that we read more 142 * than `kMaxLeb128Size` bytes, the buffer's bit offset is negative. 143 * `absl::ResourceExhaustedError()` if 144 * the buffer is exhausted before the uleb128 is fully read and 145 * source does not have the requisite data to complete the uleb128. 146 */ 147 absl::Status ReadULeb128(DecodedUleb128& uleb128, 148 int8_t& encoded_uleb128_size); 149 150 /*!\brief Reads the expandable size according to ISO 14496-1. 151 * 152 * \param max_class_size Maximum class size in bits. 153 * \param size_of_instance Size of instance according to the expandable size. 154 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 155 * the consumed data from the buffer does not fit into the 32 bit 156 * output, or if the data encoded is larger than the `max_class_size` 157 * bits, the buffer's bit offset is negative. 158 * `absl::ResourceExhaustedError()` if the buffer is exhausted 159 * before the expanded field is fully read and source does not have 160 * the requisite data to complete the expanded field. 161 */ 162 absl::Status ReadIso14496_1Expanded(uint32_t max_class_size, 163 uint32_t& size_of_instance); 164 165 /*!\brief Reads `uint8_t`s into the output span. 166 * 167 * \param output Span of `uint8_t`s to write to. 168 * \return `absl::OkStatus()` on success. `absl::ResourceExhaustedError()` if 169 * the buffer runs out of data and cannot get more from source before 170 * filling the span. `absl::InvalidArgumentError()` if the 171 * buffer's bit offset is negative. 172 */ 173 absl::Status ReadUint8Span(absl::Span<uint8_t> output); 174 175 /*!\brief Reads a boolean from buffer into `output`. 176 * 177 * \param output Boolean bit from buffer will be written here. 178 * \return `absl::OkStatus()` on success. `absl::ResourceExhaustedError()` if 179 * the buffer runs out of data and cannot get more from source before 180 * the desired boolean is read. `absl::InvalidArgumentError()` if the 181 * buffer's bit offset is negative. 182 */ 183 absl::Status ReadBoolean(bool& output); 184 185 /*!\brief Checks whether there is any data left in the buffer or source. 186 * 187 * \return `true` if there is some data left in the buffer or source that has 188 * not been consumed yet. `false` otherwise. 189 */ 190 bool IsDataAvailable() const; 191 192 /*!\brief Checks whether num_bytes_requested can be read. 193 * 194 * \param num_bytes_requested Desired number of bytes to read. 195 * \return `true` if the buffer has enough data to read the requested bytes. 196 * `false` otherwise. 197 */ 198 bool CanReadBytes(int64_t num_bytes_requested) const; 199 200 /*!\brief Returns the next reading position of the source in bits. 201 * 202 * \return Next reading position of the source in bits. 203 */ 204 int64_t Tell(); 205 206 /*!\brief Moves the next reading position in bits of the source. 207 * 208 * \param position Requested position in bits to move to. 209 * \return `absl::OkStatus()` on success. `absl::ResourceExhaustedError()` if 210 * the buffer runs out of data. `absl::InvalidArgumentError()` if 211 * the requested position is negative. 212 */ 213 absl::Status Seek(int64_t position); 214 215 protected: 216 /*!\brief Constructor. 217 * 218 * \param capacity Capacity of the internal buffer in bytes. 219 * \param source_size Size of the source data in bits. 220 */ 221 ReadBitBuffer(size_t capacity, int64_t source_size); 222 223 /*!\brief Internal reading function that reads `num_bits` from buffer. 224 * 225 * As a side effect buffer loading might happen. 226 * 227 * \param num_bits Number of upper bits to read from buffer. 228 * \param max_num_bits Maximum number of upper bits to read from buffer. 229 * \param output Output unsigned literal read from buffer. 230 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 231 * `num_bits > max_num_bits` or the buffer's bit offset is negative. 232 * `absl::ResourceExhaustedError()` if the buffer runs out of data 233 * and cannot get more from source before the desired `num_bits` 234 * are read. 235 */ 236 absl::Status ReadUnsignedLiteralInternal(int num_bits, int max_num_bits, 237 uint64_t& output); 238 /*!\brief Load bytes from source to the buffer. 239 * 240 * Subclasses of this class should implement the actual loading logic. 241 * 242 * \param starting_byte Starting byte to load from source. 243 * \param num_bytes Number of bytes to load. 244 * \return `absl::OkStatus()` on success. Other specific statuses (depending 245 * on the subclass) on failure. 246 */ 247 virtual absl::Status LoadBytesToBuffer(int64_t starting_byte, 248 int64_t num_bytes) = 0; 249 250 // Read buffer. 251 std::vector<uint8_t> bit_buffer_; 252 253 // Specifies the next bit to consume in the `bit_buffer_`. 254 int64_t buffer_bit_offset_ = 0; 255 256 // Size of the valid data in the buffer in bits. 257 int64_t buffer_size_ = 0; 258 259 // Size of the source data in bits. It may refer to the total file size 260 // for a file-based buffer, or the total memory size for a memory-based 261 // buffer. For a stream-based buffer, it is the current size of the source 262 // data, which is updated as bytes are pushed or flushed. 263 int64_t source_size_; 264 265 // Specifies the next bit to consume from the source data (the actual storage 266 // type is subclass-specific). 267 int64_t source_bit_offset_ = 0; 268 269 // Specifies whether a position returned by Tell() is valid. 270 bool is_position_valid_; 271 }; 272 273 /*!\brief Memory-based read bit buffer. 274 * 275 * The entire content of the source data is held as a vector inside the class. 276 * 277 * NOTICE: This is mostly useful for testing and processing small files, 278 * because it will hold the entire content in memory during its lifetime. 279 * For processing large (e.g. 2 GB) files, use the `FileBasedReadBitBuffer` 280 * for example. 281 */ 282 class MemoryBasedReadBitBuffer : public ReadBitBuffer { 283 public: 284 /*!\brief Creates an instance of a memory-based read bit buffer. 285 * 286 * \param capacity Capacity of the internal buffer in bytes. 287 * \param source Source span from which the buffer will load data. The 288 * entire contents will be copied into the constructed instance. 289 * \return Unique pointer of the created instance. `nullptr` if the creation 290 * fails. 291 */ 292 static std::unique_ptr<MemoryBasedReadBitBuffer> CreateFromSpan( 293 int64_t capacity, absl::Span<const uint8_t> source); 294 295 /*!\brief Destructor.*/ 296 ~MemoryBasedReadBitBuffer() override = default; 297 298 protected: 299 /*!\brief Protected constructor. Called by the factory method or subclasses. 300 * 301 * \param capacity Capacity of the internal buffer in bytes. 302 * \param source Source span from which the buffer will load data. The 303 * entire contents will be copied into the constructed instance. 304 */ 305 MemoryBasedReadBitBuffer(size_t capacity, absl::Span<const uint8_t> source); 306 /*!\brief Load bytes from the source vector to the buffer. 307 * 308 * \param starting_byte Starting byte to load from source. 309 * \param num_bytes Number of bytes to load. 310 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 311 * the start/ending position is invalid. 312 */ 313 absl::Status LoadBytesToBuffer(int64_t starting_byte, 314 int64_t num_bytes) override; 315 316 // Source data stored in a vector. 317 std::vector<uint8_t> source_vector_; 318 }; 319 320 /*!\brief File-based read bit buffer. 321 * 322 * The file is read and buffer loaded only when necessary. 323 */ 324 class FileBasedReadBitBuffer : public ReadBitBuffer { 325 public: 326 /*!\brief Creates an instance of a file-based read bit buffer. 327 * 328 * \param capacity Capacity of the internal buffer in bytes. 329 * \param file_path Path to the file to load the buffer from. 330 * \return Unique pointer of the created instance. `nullptr` if the creation 331 * fails. 332 */ 333 static std::unique_ptr<FileBasedReadBitBuffer> CreateFromFilePath( 334 int64_t capacity, const std::filesystem::path& file_path); 335 336 /*!\brief Destructor.*/ 337 ~FileBasedReadBitBuffer() override = default; 338 339 private: 340 /*!\brief Private constructor. Called by the factory method only. 341 * 342 * \param capacity Capacity of the internal buffer in bytes. 343 * \param source_size Total size of the file in bits. 344 * \param ifs Input file stream from which the buffer will load data. At most 345 * a buffer full of data will be read at a given time. 346 * 347 */ 348 FileBasedReadBitBuffer(size_t capacity, int64_t source_size, 349 std::ifstream&& ifs); 350 351 /*!\brief Load bytes from the source file to the buffer. 352 * 353 * \param starting_byte Starting byte to load from source. 354 * \param num_bytes Number of bytes to load. 355 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 356 * the file reading fails. 357 */ 358 absl::Status LoadBytesToBuffer(int64_t starting_byte, 359 int64_t num_bytes) override; 360 361 // Source data stored in a file stream. 362 std::ifstream source_ifs_; 363 }; 364 365 /*!\brief Stream-based read bit buffer. 366 * 367 * The buffer is loaded from a stream. The user should Create() the stream 368 * and push data to the buffer using PushBytes() as needed; calls to Read*() 369 * methods will read data from the stream and provide it to the caller, or else 370 * will instruct the caller to push more data if necessary. 371 */ 372 class StreamBasedReadBitBuffer : public MemoryBasedReadBitBuffer { 373 public: 374 /*!\brief Creates an instance of a stream-based read bit buffer. 375 * 376 * \param capacity Capacity of the internal buffer in bytes. 377 * \return Unique pointer of the created instance. `nullptr` if the creation 378 * fails. 379 */ 380 static std::unique_ptr<StreamBasedReadBitBuffer> Create(int64_t capacity); 381 382 /*!\brief Adds some chunk of data to StreamBasedReadBitBuffer. 383 * 384 * \param bytes Bytes to push. 385 * \return `absl::OkStatus()` on success. `absl::InvalidArgumentError()` if 386 * the stream push fails. 387 */ 388 absl::Status PushBytes(absl::Span<const uint8_t> bytes); 389 390 /*!\brief Flush already processed data from StreamBasedReadBitBuffer. 391 * 392 * Should be called whenever the caller no longer needs the first `num_bytes` 393 * of data. 394 * 395 * \param num_bytes Bytes to flush from StreamBasedReadBitBuffer 396 * \return `absl::OkStatus()` on success. Specific statuses on failure. 397 */ 398 absl::Status Flush(int64_t num_bytes); 399 400 /*!\brief Destructor.*/ 401 ~StreamBasedReadBitBuffer() override = default; 402 403 private: 404 /*!\brief Private constructor. 405 * 406 * \param capacity Capacity of the internal buffer in bytes. 407 * \param source_size Size of the source data in bits. 408 * 409 */ 410 StreamBasedReadBitBuffer(size_t capacity, int64_t source_size); 411 412 // Specifies the maximum size of the source data in bits. 413 int64_t max_source_size_; 414 }; 415 416 } // namespace iamf_tools 417 418 #endif // COMMON_READ_BIT_BUFFER_H_ 419