diff --git a/AK/BitStream.h b/AK/BitStream.h index 922e86da17..4cd2023e71 100644 --- a/AK/BitStream.h +++ b/AK/BitStream.h @@ -17,9 +17,9 @@ namespace AK { /// in big-endian order from another stream. class BigEndianInputBitStream : public Stream { public: - static ErrorOr> construct(MaybeOwned stream) + explicit BigEndianInputBitStream(MaybeOwned stream) + : m_stream(move(stream)) { - return adopt_nonnull_own_or_enomem(new BigEndianInputBitStream(move(stream))); } // ^Stream @@ -112,11 +112,6 @@ public: ALWAYS_INLINE bool is_aligned_to_byte_boundary() const { return m_bit_offset == 0; } private: - BigEndianInputBitStream(MaybeOwned stream) - : m_stream(move(stream)) - { - } - Optional m_current_byte; size_t m_bit_offset { 0 }; MaybeOwned m_stream; diff --git a/Tests/AK/TestBitStream.cpp b/Tests/AK/TestBitStream.cpp index b04b11d39e..92f1a6bf53 100644 --- a/Tests/AK/TestBitStream.cpp +++ b/Tests/AK/TestBitStream.cpp @@ -72,23 +72,23 @@ TEST_CASE(big_endian_bit_stream_input_output_match) // Note: The bit stream only ever reads from/writes to the underlying stream in one byte chunks, // so testing with sizes that will not trigger a write will yield unexpected results. auto bit_write_stream = MUST(BigEndianOutputBitStream::construct(MaybeOwned(*memory_stream))); - auto bit_read_stream = MUST(BigEndianInputBitStream::construct(MaybeOwned(*memory_stream))); + BigEndianInputBitStream bit_read_stream { MaybeOwned(*memory_stream) }; // Test two mirrored chunks of a fully mirrored pattern to check that we are not dropping bits. { MUST(bit_write_stream->write_bits(0b1111u, 4)); MUST(bit_write_stream->write_bits(0b1111u, 4)); - auto result = MUST(bit_read_stream->read_bits(4)); + auto result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b1111u, result); - result = MUST(bit_read_stream->read_bits(4)); + result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b1111u, result); } { MUST(bit_write_stream->write_bits(0b0000u, 4)); MUST(bit_write_stream->write_bits(0b0000u, 4)); - auto result = MUST(bit_read_stream->read_bits(4)); + auto result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b0000u, result); - result = MUST(bit_read_stream->read_bits(4)); + result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b0000u, result); } @@ -96,9 +96,9 @@ TEST_CASE(big_endian_bit_stream_input_output_match) { MUST(bit_write_stream->write_bits(0b1000u, 4)); MUST(bit_write_stream->write_bits(0b1000u, 4)); - auto result = MUST(bit_read_stream->read_bits(4)); + auto result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b1000u, result); - result = MUST(bit_read_stream->read_bits(4)); + result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b1000u, result); } @@ -106,16 +106,16 @@ TEST_CASE(big_endian_bit_stream_input_output_match) { MUST(bit_write_stream->write_bits(0b1000u, 4)); MUST(bit_write_stream->write_bits(0b0100u, 4)); - auto result = MUST(bit_read_stream->read_bits(4)); + auto result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b1000u, result); - result = MUST(bit_read_stream->read_bits(4)); + result = MUST(bit_read_stream.read_bits(4)); EXPECT_EQ(0b0100u, result); } // Test a pattern that spans multiple bytes. { MUST(bit_write_stream->write_bits(0b1101001000100001u, 16)); - auto result = MUST(bit_read_stream->read_bits(16)); + auto result = MUST(bit_read_stream.read_bits(16)); EXPECT_EQ(0b1101001000100001u, result); } } diff --git a/Userland/Libraries/LibAudio/FlacLoader.cpp b/Userland/Libraries/LibAudio/FlacLoader.cpp index 0d3decd763..d2ba2ed2cb 100644 --- a/Userland/Libraries/LibAudio/FlacLoader.cpp +++ b/Userland/Libraries/LibAudio/FlacLoader.cpp @@ -60,7 +60,7 @@ MaybeLoaderError FlacLoaderPlugin::initialize() // 11.5 STREAM MaybeLoaderError FlacLoaderPlugin::parse_header() { - auto bit_input = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*m_stream))); + BigEndianInputBitStream bit_input { MaybeOwned(*m_stream) }; // A mixture of VERIFY and the non-crashing TRY(). #define FLAC_VERIFY(check, category, msg) \ @@ -71,28 +71,28 @@ MaybeLoaderError FlacLoaderPlugin::parse_header() } while (0) // Magic number - u32 flac = LOADER_TRY(bit_input->read_bits(32)); + u32 flac = LOADER_TRY(bit_input.read_bits(32)); m_data_start_location += 4; FLAC_VERIFY(flac == 0x664C6143, LoaderError::Category::Format, "Magic number must be 'flaC'"); // "flaC" // Receive the streaminfo block - auto streaminfo = TRY(next_meta_block(*bit_input)); + auto streaminfo = TRY(next_meta_block(bit_input)); FLAC_VERIFY(streaminfo.type == FlacMetadataBlockType::STREAMINFO, LoaderError::Category::Format, "First block must be STREAMINFO"); auto streaminfo_data_memory = LOADER_TRY(FixedMemoryStream::construct(streaminfo.data.bytes())); - auto streaminfo_data = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*streaminfo_data_memory))); + BigEndianInputBitStream streaminfo_data { MaybeOwned(*streaminfo_data_memory) }; // 11.10 METADATA_BLOCK_STREAMINFO - m_min_block_size = LOADER_TRY(streaminfo_data->read_bits(16)); + m_min_block_size = LOADER_TRY(streaminfo_data.read_bits(16)); FLAC_VERIFY(m_min_block_size >= 16, LoaderError::Category::Format, "Minimum block size must be 16"); - m_max_block_size = LOADER_TRY(streaminfo_data->read_bits(16)); + m_max_block_size = LOADER_TRY(streaminfo_data.read_bits(16)); FLAC_VERIFY(m_max_block_size >= 16, LoaderError::Category::Format, "Maximum block size"); - m_min_frame_size = LOADER_TRY(streaminfo_data->read_bits(24)); - m_max_frame_size = LOADER_TRY(streaminfo_data->read_bits(24)); - m_sample_rate = LOADER_TRY(streaminfo_data->read_bits(20)); + m_min_frame_size = LOADER_TRY(streaminfo_data.read_bits(24)); + m_max_frame_size = LOADER_TRY(streaminfo_data.read_bits(24)); + m_sample_rate = LOADER_TRY(streaminfo_data.read_bits(20)); FLAC_VERIFY(m_sample_rate <= 655350, LoaderError::Category::Format, "Sample rate"); - m_num_channels = LOADER_TRY(streaminfo_data->read_bits(3)) + 1; // 0 = one channel + m_num_channels = LOADER_TRY(streaminfo_data.read_bits(3)) + 1; // 0 = one channel - u8 bits_per_sample = LOADER_TRY(streaminfo_data->read_bits(5)) + 1; + u8 bits_per_sample = LOADER_TRY(streaminfo_data.read_bits(5)) + 1; if (bits_per_sample == 8) { // FIXME: Signed/Unsigned issues? m_sample_format = PcmSampleFormat::Uint8; @@ -106,12 +106,12 @@ MaybeLoaderError FlacLoaderPlugin::parse_header() FLAC_VERIFY(false, LoaderError::Category::Format, "Sample bit depth invalid"); } - m_total_samples = LOADER_TRY(streaminfo_data->read_bits(36)); + m_total_samples = LOADER_TRY(streaminfo_data.read_bits(36)); FLAC_VERIFY(m_total_samples > 0, LoaderError::Category::Format, "Number of samples is zero"); // Parse checksum into a buffer first [[maybe_unused]] u128 md5_checksum; - VERIFY(streaminfo_data->is_aligned_to_byte_boundary()); - auto md5_bytes_read = LOADER_TRY(streaminfo_data->read(md5_checksum.bytes())); + VERIFY(streaminfo_data.is_aligned_to_byte_boundary()); + auto md5_bytes_read = LOADER_TRY(streaminfo_data.read(md5_checksum.bytes())); FLAC_VERIFY(md5_bytes_read.size() == md5_checksum.my_size(), LoaderError::Category::IO, "MD5 Checksum size"); md5_checksum.bytes().copy_to({ m_md5_checksum, sizeof(m_md5_checksum) }); @@ -120,7 +120,7 @@ MaybeLoaderError FlacLoaderPlugin::parse_header() [[maybe_unused]] u16 total_meta_blocks = meta_blocks_parsed; FlacRawMetadataBlock block = streaminfo; while (!block.is_last_block) { - block = TRY(next_meta_block(*bit_input)); + block = TRY(next_meta_block(bit_input)); switch (block.type) { case (FlacMetadataBlockType::SEEKTABLE): TRY(load_seektable(block)); @@ -150,30 +150,30 @@ MaybeLoaderError FlacLoaderPlugin::parse_header() MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block) { auto memory_stream = LOADER_TRY(FixedMemoryStream::construct(block.data.bytes())); - auto picture_block_bytes = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*memory_stream))); + BigEndianInputBitStream picture_block_bytes { MaybeOwned(*memory_stream) }; PictureData picture {}; - picture.type = static_cast(LOADER_TRY(picture_block_bytes->read_bits(32))); + picture.type = static_cast(LOADER_TRY(picture_block_bytes.read_bits(32))); - auto const mime_string_length = LOADER_TRY(picture_block_bytes->read_bits(32)); + auto const mime_string_length = LOADER_TRY(picture_block_bytes.read_bits(32)); // Note: We are seeking before reading the value to ensure that we stayed inside buffer's size. auto offset_before_seeking = memory_stream->offset(); LOADER_TRY(memory_stream->seek(mime_string_length, SeekMode::FromCurrentPosition)); picture.mime_string = { block.data.bytes().data() + offset_before_seeking, (size_t)mime_string_length }; - auto const description_string_length = LOADER_TRY(picture_block_bytes->read_bits(32)); + auto const description_string_length = LOADER_TRY(picture_block_bytes.read_bits(32)); offset_before_seeking = memory_stream->offset(); LOADER_TRY(memory_stream->seek(description_string_length, SeekMode::FromCurrentPosition)); picture.description_string = Vector { Span { reinterpret_cast(block.data.bytes().data() + offset_before_seeking), (size_t)description_string_length } }; - picture.width = LOADER_TRY(picture_block_bytes->read_bits(32)); - picture.height = LOADER_TRY(picture_block_bytes->read_bits(32)); + picture.width = LOADER_TRY(picture_block_bytes.read_bits(32)); + picture.height = LOADER_TRY(picture_block_bytes.read_bits(32)); - picture.color_depth = LOADER_TRY(picture_block_bytes->read_bits(32)); - picture.colors = LOADER_TRY(picture_block_bytes->read_bits(32)); + picture.color_depth = LOADER_TRY(picture_block_bytes.read_bits(32)); + picture.colors = LOADER_TRY(picture_block_bytes.read_bits(32)); - auto const picture_size = LOADER_TRY(picture_block_bytes->read_bits(32)); + auto const picture_size = LOADER_TRY(picture_block_bytes.read_bits(32)); offset_before_seeking = memory_stream->offset(); LOADER_TRY(memory_stream->seek(picture_size, SeekMode::FromCurrentPosition)); picture.data = Vector { Span { block.data.bytes().data() + offset_before_seeking, (size_t)picture_size } }; @@ -187,13 +187,13 @@ MaybeLoaderError FlacLoaderPlugin::load_picture(FlacRawMetadataBlock& block) MaybeLoaderError FlacLoaderPlugin::load_seektable(FlacRawMetadataBlock& block) { auto memory_stream = LOADER_TRY(FixedMemoryStream::construct(block.data.bytes())); - auto seektable_bytes = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*memory_stream))); + BigEndianInputBitStream seektable_bytes { MaybeOwned(*memory_stream) }; for (size_t i = 0; i < block.length / 18; ++i) { // 11.14. SEEKPOINT FlacSeekPoint seekpoint { - .sample_index = LOADER_TRY(seektable_bytes->read_bits(64)), - .byte_offset = LOADER_TRY(seektable_bytes->read_bits(64)), - .num_samples = LOADER_TRY(seektable_bytes->read_bits(16)) + .sample_index = LOADER_TRY(seektable_bytes.read_bits(64)), + .byte_offset = LOADER_TRY(seektable_bytes.read_bits(64)), + .num_samples = LOADER_TRY(seektable_bytes.read_bits(16)) }; m_seektable.append(seekpoint); } @@ -333,55 +333,55 @@ MaybeLoaderError FlacLoaderPlugin::next_frame(Span target_vector) } \ } while (0) - auto bit_stream = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*m_stream))); + BigEndianInputBitStream bit_stream { MaybeOwned(*m_stream) }; // TODO: Check the CRC-16 checksum (and others) by keeping track of read data // 11.22. FRAME_HEADER - u16 sync_code = LOADER_TRY(bit_stream->read_bits(14)); + u16 sync_code = LOADER_TRY(bit_stream.read_bits(14)); FLAC_VERIFY(sync_code == 0b11111111111110, LoaderError::Category::Format, "Sync code"); - bool reserved_bit = LOADER_TRY(bit_stream->read_bit()); + bool reserved_bit = LOADER_TRY(bit_stream.read_bit()); FLAC_VERIFY(reserved_bit == 0, LoaderError::Category::Format, "Reserved frame header bit"); // 11.22.2. BLOCKING STRATEGY - [[maybe_unused]] bool blocking_strategy = LOADER_TRY(bit_stream->read_bit()); + [[maybe_unused]] bool blocking_strategy = LOADER_TRY(bit_stream.read_bit()); - u32 sample_count = TRY(convert_sample_count_code(LOADER_TRY(bit_stream->read_bits(4)))); + u32 sample_count = TRY(convert_sample_count_code(LOADER_TRY(bit_stream.read_bits(4)))); - u32 frame_sample_rate = TRY(convert_sample_rate_code(LOADER_TRY(bit_stream->read_bits(4)))); + u32 frame_sample_rate = TRY(convert_sample_rate_code(LOADER_TRY(bit_stream.read_bits(4)))); - u8 channel_type_num = LOADER_TRY(bit_stream->read_bits(4)); + u8 channel_type_num = LOADER_TRY(bit_stream.read_bits(4)); FLAC_VERIFY(channel_type_num < 0b1011, LoaderError::Category::Format, "Channel assignment"); FlacFrameChannelType channel_type = (FlacFrameChannelType)channel_type_num; - PcmSampleFormat bit_depth = TRY(convert_bit_depth_code(LOADER_TRY(bit_stream->read_bits(3)))); + PcmSampleFormat bit_depth = TRY(convert_bit_depth_code(LOADER_TRY(bit_stream.read_bits(3)))); - reserved_bit = LOADER_TRY(bit_stream->read_bit()); + reserved_bit = LOADER_TRY(bit_stream.read_bit()); FLAC_VERIFY(reserved_bit == 0, LoaderError::Category::Format, "Reserved frame header end bit"); // 11.22.8. CODED NUMBER // FIXME: sample number can be 8-56 bits, frame number can be 8-48 bits - m_current_sample_or_frame = LOADER_TRY(read_utf8_char(*bit_stream)); + m_current_sample_or_frame = LOADER_TRY(read_utf8_char(bit_stream)); // Conditional header variables // 11.22.9. BLOCK SIZE INT if (sample_count == FLAC_BLOCKSIZE_AT_END_OF_HEADER_8) { - sample_count = LOADER_TRY(bit_stream->read_bits(8)) + 1; + sample_count = LOADER_TRY(bit_stream.read_bits(8)) + 1; } else if (sample_count == FLAC_BLOCKSIZE_AT_END_OF_HEADER_16) { - sample_count = LOADER_TRY(bit_stream->read_bits(16)) + 1; + sample_count = LOADER_TRY(bit_stream.read_bits(16)) + 1; } // 11.22.10. SAMPLE RATE INT if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_8) { - frame_sample_rate = LOADER_TRY(bit_stream->read_bits(8)) * 1000; + frame_sample_rate = LOADER_TRY(bit_stream.read_bits(8)) * 1000; } else if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_16) { - frame_sample_rate = LOADER_TRY(bit_stream->read_bits(16)); + frame_sample_rate = LOADER_TRY(bit_stream.read_bits(16)); } else if (frame_sample_rate == FLAC_SAMPLERATE_AT_END_OF_HEADER_16X10) { - frame_sample_rate = LOADER_TRY(bit_stream->read_bits(16)) * 10; + frame_sample_rate = LOADER_TRY(bit_stream.read_bits(16)) * 10; } // 11.22.11. FRAME CRC // TODO: check header checksum, see above - [[maybe_unused]] u8 checksum = LOADER_TRY(bit_stream->read_bits(8)); + [[maybe_unused]] u8 checksum = LOADER_TRY(bit_stream.read_bits(8)); dbgln_if(AFLACLOADER_DEBUG, "Frame: {} samples, {}bit {}Hz, channeltype {:x}, {} number {}, header checksum {}", sample_count, pcm_bits_per_sample(bit_depth), frame_sample_rate, channel_type_num, blocking_strategy ? "sample" : "frame", m_current_sample_or_frame, checksum); @@ -397,17 +397,17 @@ MaybeLoaderError FlacLoaderPlugin::next_frame(Span target_vector) current_subframes.ensure_capacity(subframe_count); for (u8 i = 0; i < subframe_count; ++i) { - FlacSubframeHeader new_subframe = TRY(next_subframe_header(*bit_stream, i)); - Vector subframe_samples = TRY(parse_subframe(new_subframe, *bit_stream)); + FlacSubframeHeader new_subframe = TRY(next_subframe_header(bit_stream, i)); + Vector subframe_samples = TRY(parse_subframe(new_subframe, bit_stream)); current_subframes.unchecked_append(move(subframe_samples)); } // 11.2. Overview ("The audio data is composed of...") - bit_stream->align_to_byte_boundary(); + bit_stream.align_to_byte_boundary(); // 11.23. FRAME_FOOTER // TODO: check checksum, see above - [[maybe_unused]] u16 footer_checksum = LOADER_TRY(bit_stream->read_bits(16)); + [[maybe_unused]] u16 footer_checksum = LOADER_TRY(bit_stream.read_bits(16)); dbgln_if(AFLACLOADER_DEBUG, "Subframe footer checksum: {}", footer_checksum); Vector left; diff --git a/Userland/Libraries/LibAudio/MP3Loader.cpp b/Userland/Libraries/LibAudio/MP3Loader.cpp index f6804fa5a0..693f680527 100644 --- a/Userland/Libraries/LibAudio/MP3Loader.cpp +++ b/Userland/Libraries/LibAudio/MP3Loader.cpp @@ -41,7 +41,7 @@ Result, LoaderError> MP3LoaderPlugin::create(Byte MaybeLoaderError MP3LoaderPlugin::initialize() { - m_bitstream = LOADER_TRY(BigEndianInputBitStream::construct(MaybeOwned(*m_stream))); + m_bitstream = LOADER_TRY(try_make(MaybeOwned(*m_stream))); TRY(synchronize()); @@ -242,12 +242,12 @@ ErrorOr MP3LoaderPlugin::read_frame_data(MP3::Header TRY(m_bit_reservoir.discard(old_reservoir_size - frame.main_data_begin)); - auto reservoir_stream = TRY(BigEndianInputBitStream::construct(MaybeOwned(m_bit_reservoir))); + BigEndianInputBitStream reservoir_stream { MaybeOwned(m_bit_reservoir) }; for (size_t granule_index = 0; granule_index < 2; granule_index++) { for (size_t channel_index = 0; channel_index < header.channel_count(); channel_index++) { - size_t scale_factor_size = TRY(read_scale_factors(frame, *reservoir_stream, granule_index, channel_index)); - TRY(read_huffman_data(frame, *reservoir_stream, granule_index, channel_index, scale_factor_size)); + size_t scale_factor_size = TRY(read_scale_factors(frame, reservoir_stream, granule_index, channel_index)); + TRY(read_huffman_data(frame, reservoir_stream, granule_index, channel_index, scale_factor_size)); if (frame.channels[channel_index].granules[granule_index].block_type == MP3::BlockType::Short) { reorder_samples(frame.channels[channel_index].granules[granule_index], frame.header.samplerate);