From 796f4818944ea3a3e0926dd55bc951f5d489ed59 Mon Sep 17 00:00:00 2001 From: sz Date: Wed, 31 Jan 2024 01:18:04 -0600 Subject: [PATCH] `fountain_chunks_per_frame()` config function needs to return "10" for 0.5.x The config namespace is reaching its limits. Going to need a rewrite... --- src/exe/cimbar/cimbar.cpp | 2 +- src/exe/cimbar_recv/recv.cpp | 2 +- src/lib/cimb_translator/CimbWriter.cpp | 2 +- src/lib/cimb_translator/Config.cpp | 4 ++-- src/lib/cimb_translator/Config.h | 9 ++++----- src/lib/cimb_translator/test/CimbReaderTest.cpp | 4 ++-- src/lib/cimbar_js/cimbar_js.cpp | 4 ++-- src/lib/encoder/Decoder.h | 6 ++++-- src/lib/encoder/Encoder.h | 2 +- src/lib/encoder/SimpleEncoder.h | 8 ++++---- src/lib/encoder/test/EncoderRoundTripTest.cpp | 4 ++-- src/lib/encoder/test/EncoderTest.cpp | 4 ++-- 12 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/exe/cimbar/cimbar.cpp b/src/exe/cimbar/cimbar.cpp index 98bae5a..c97c6fb 100644 --- a/src/exe/cimbar/cimbar.cpp +++ b/src/exe/cimbar/cimbar.cpp @@ -269,7 +269,7 @@ int main(int argc, char** argv) // else, the good stuff int res = -200; - unsigned chunkSize = cimbar::Config::fountain_chunk_size(ecc, colorBits+cimbar::Config::symbol_bits()); + unsigned chunkSize = cimbar::Config::fountain_chunk_size(ecc, colorBits+cimbar::Config::symbol_bits(), legacy_mode); if (compressionLevel <= 0) { fountain_decoder_sink sink(outpath, chunkSize, true); diff --git a/src/exe/cimbar_recv/recv.cpp b/src/exe/cimbar_recv/recv.cpp index 446c94b..5ad1e27 100644 --- a/src/exe/cimbar_recv/recv.cpp +++ b/src/exe/cimbar_recv/recv.cpp @@ -107,7 +107,7 @@ int main(int argc, char** argv) unsigned color_mode = legacy_mode? 0 : 1; Decoder dec(-1, -1, color_mode, legacy_mode); - unsigned chunkSize = cimbar::Config::fountain_chunk_size(ecc, colorBits+cimbar::Config::symbol_bits()); + unsigned chunkSize = cimbar::Config::fountain_chunk_size(ecc, colorBits+cimbar::Config::symbol_bits(), legacy_mode); fountain_decoder_sink> sink(outpath, chunkSize); cv::Mat mat; diff --git a/src/lib/cimb_translator/CimbWriter.cpp b/src/lib/cimb_translator/CimbWriter.cpp index a102545..1ebf52c 100644 --- a/src/lib/cimb_translator/CimbWriter.cpp +++ b/src/lib/cimb_translator/CimbWriter.cpp @@ -36,7 +36,7 @@ namespace { } CimbWriter::CimbWriter(unsigned symbol_bits, unsigned color_bits, bool dark, unsigned color_mode, int size) - : _positions(Config::cell_spacing(), Config::cells_per_col(), Config::cell_offset(), Config::corner_padding(), Config::interleave_blocks(), Config::interleave_partitions(symbol_bits+color_bits)) + : _positions(Config::cell_spacing(), Config::cells_per_col(), Config::cell_offset(), Config::corner_padding(), Config::interleave_blocks(), Config::interleave_partitions()) , _encoder(symbol_bits, color_bits, dark, color_mode) { if (size > cimbar::Config::image_size()) diff --git a/src/lib/cimb_translator/Config.cpp b/src/lib/cimb_translator/Config.cpp index 5df01b0..84ac398 100644 --- a/src/lib/cimb_translator/Config.cpp +++ b/src/lib/cimb_translator/Config.cpp @@ -26,13 +26,13 @@ unsigned Config::corner_padding() return lrint(54.0 / cell_spacing()); } -unsigned Config::fountain_chunk_size(unsigned ecc, unsigned bitspercell) +unsigned Config::fountain_chunk_size(unsigned ecc, unsigned bitspercell, bool legacy_mode) { // TODO: sanity checks? // this should neatly split into fountain_chunks_per_frame() [ex: 10] chunks per frame. // the other reasonable settings for fountain_chunks_per_frame are `2` and `5` const unsigned eccBlockSize = ecc_block_size(); - return capacity(bitspercell) * (eccBlockSize-ecc) / eccBlockSize / fountain_chunks_per_frame(bitspercell); + return capacity(bitspercell) * (eccBlockSize-ecc) / eccBlockSize / fountain_chunks_per_frame(bitspercell, legacy_mode); } } diff --git a/src/lib/cimb_translator/Config.h b/src/lib/cimb_translator/Config.h index 476355e..0fb7ec4 100644 --- a/src/lib/cimb_translator/Config.h +++ b/src/lib/cimb_translator/Config.h @@ -89,18 +89,17 @@ namespace cimbar return ecc_block_size(); } - static constexpr unsigned interleave_partitions(unsigned bitspercell=0) + static constexpr unsigned interleave_partitions() { - //return bitspercell; return 2; } - static constexpr unsigned fountain_chunks_per_frame(unsigned bitspercell=0) + static constexpr unsigned fountain_chunks_per_frame(unsigned bitspercell, bool legacy_mode) { - return bitspercell << 1; + return legacy_mode? 10 : bitspercell << 1; } - static unsigned fountain_chunk_size(unsigned ecc, unsigned bitspercell); + static unsigned fountain_chunk_size(unsigned ecc, unsigned bitspercell, bool legacy_mode); static constexpr unsigned compression_level() { diff --git a/src/lib/cimb_translator/test/CimbReaderTest.cpp b/src/lib/cimb_translator/test/CimbReaderTest.cpp index 3295f0d..557c82e 100644 --- a/src/lib/cimb_translator/test/CimbReaderTest.cpp +++ b/src/lib/cimb_translator/test/CimbReaderTest.cpp @@ -149,7 +149,7 @@ TEST_CASE( "CimbReaderTest/testCCM", "[unit]" ) // and compute it from the symbols, but that seems like overkill for this test. FountainMetadata md(0, 23586, 7); cr.update_metadata((char*)md.data(), md.md_size); - cr.init_ccm(2, cimbar::Config::interleave_blocks(), cimbar::Config::interleave_partitions(6), cimbar::Config::fountain_chunks_per_frame(6)); + cr.init_ccm(2, cimbar::Config::interleave_blocks(), cimbar::Config::interleave_partitions(), cimbar::Config::fountain_chunks_per_frame(6, false)); assertTrue( decoder._ccm.active() ); @@ -203,7 +203,7 @@ TEST_CASE( "CimbReaderTest/testCCM.VeryNecessary", "[unit]" ) // and compute it from the symbols, but that seems like overkill for this test. FountainMetadata md(0, 23586, 7); cr.update_metadata((char*)md.data(), md.md_size); - cr.init_ccm(2, cimbar::Config::interleave_blocks(), cimbar::Config::interleave_partitions(6), cimbar::Config::fountain_chunks_per_frame(6)); + cr.init_ccm(2, cimbar::Config::interleave_blocks(), cimbar::Config::interleave_partitions(), cimbar::Config::fountain_chunks_per_frame(6, false)); assertTrue( decoder._ccm.active() ); diff --git a/src/lib/cimbar_js/cimbar_js.cpp b/src/lib/cimbar_js/cimbar_js.cpp index a4dad2b..1b1deb0 100644 --- a/src/lib/cimbar_js/cimbar_js.cpp +++ b/src/lib/cimbar_js/cimbar_js.cpp @@ -72,7 +72,7 @@ int next_frame() // color blocks will contribute to this total, but only symbols used for the initial calculation. // ... this way, if the color decode is failing, we don't get "stuck" rendering a single frame. unsigned required = _fes->blocks_required(); - if (required > cimbar::Config::fountain_chunks_per_frame(cimbar::Config::symbol_bits())) + if (required > cimbar::Config::fountain_chunks_per_frame(cimbar::Config::symbol_bits(), _legacyMode)) required = required*5; if (_fes->block_count() > required) { @@ -136,7 +136,7 @@ int configure(unsigned color_bits, unsigned ecc, int compression, bool legacy_mo // try to refresh the stream if (_window and _fes) { - unsigned buff_size_new = cimbar::Config::fountain_chunk_size(_ecc, cimbar::Config::symbol_bits() + _colorBits); + unsigned buff_size_new = cimbar::Config::fountain_chunk_size(_ecc, cimbar::Config::symbol_bits() + _colorBits, _legacyMode); if (!_fes->restart_and_resize_buffer(buff_size_new)) { // if the data is too small, we should throw out _fes -- and clear the canvas. diff --git a/src/lib/encoder/Decoder.h b/src/lib/encoder/Decoder.h index 665f74f..8ed51a2 100644 --- a/src/lib/encoder/Decoder.h +++ b/src/lib/encoder/Decoder.h @@ -42,6 +42,7 @@ class Decoder unsigned _colorBits; unsigned _bitsPerOp; bool _coupled; + unsigned _colorMode; unsigned _interleaveBlocks; unsigned _interleavePartitions; CimbDecoder _decoder; @@ -53,8 +54,9 @@ inline Decoder::Decoder(int ecc_bytes, int color_bits, unsigned color_mode, bool , _colorBits(color_bits >= 0? color_bits : cimbar::Config::color_bits()) , _bitsPerOp(cimbar::Config::symbol_bits() + _colorBits) , _coupled(coupled) + , _colorMode(color_mode) , _interleaveBlocks(interleave? cimbar::Config::interleave_blocks() : 0) - , _interleavePartitions(cimbar::Config::interleave_partitions(_bitsPerOp)) + , _interleavePartitions(cimbar::Config::interleave_partitions()) , _decoder(cimbar::Config::symbol_bits(), _colorBits, color_mode, cimbar::Config::dark(), 0xFF) { } @@ -107,7 +109,7 @@ inline unsigned Decoder::do_decode(CimbReader& reader, STREAM& ostream) } // do color correction init, now that we (hopefully) have some fountain headers from the symbol decode - reader.init_ccm(_colorBits, _interleaveBlocks, _interleavePartitions, cimbar::Config::fountain_chunks_per_frame(_bitsPerOp)); + reader.init_ccm(_colorBits, _interleaveBlocks, _interleavePartitions, cimbar::Config::fountain_chunks_per_frame(_bitsPerOp, _coupled and _colorMode==0)); bitbuffer colorBits(cimbar::Config::capacity(_colorBits)); // then decode colors. diff --git a/src/lib/encoder/Encoder.h b/src/lib/encoder/Encoder.h index 398e3af..9f16b40 100644 --- a/src/lib/encoder/Encoder.h +++ b/src/lib/encoder/Encoder.h @@ -50,7 +50,7 @@ inline unsigned Encoder::encode_fountain(const std::string& filename, const std: // if fountain_chunks_per_frame() is 10, the fountain_chunk_size will be 750. // we calculate requiredFrames based only on symbol bits, to avoid the situation where the color decode is failing while we're // refusing to generate additional frames... - unsigned requiredFrames = fes->blocks_required() * redundancy / cimbar::Config::fountain_chunks_per_frame(_bitsPerSymbol); + unsigned requiredFrames = fes->blocks_required() * redundancy / cimbar::Config::fountain_chunks_per_frame(_bitsPerSymbol, _coupled and _colorMode==0); if (requiredFrames == 0) requiredFrames = 1; diff --git a/src/lib/encoder/SimpleEncoder.h b/src/lib/encoder/SimpleEncoder.h index 089f424..b333680 100644 --- a/src/lib/encoder/SimpleEncoder.h +++ b/src/lib/encoder/SimpleEncoder.h @@ -49,14 +49,14 @@ inline SimpleEncoder::SimpleEncoder(int ecc_bytes, unsigned bits_per_symbol, int , _bitsPerSymbol(bits_per_symbol? bits_per_symbol : cimbar::Config::symbol_bits()) , _bitsPerColor(bits_per_color >= 0? bits_per_color : cimbar::Config::color_bits()) , _dark(cimbar::Config::dark()) - , _coupled(true) + , _coupled(false) , _colorMode(cimbar::Config::color_mode()) { } inline void SimpleEncoder::set_legacy_mode() { - _coupled = false; + _coupled = true; _colorMode = 0; } @@ -68,7 +68,7 @@ inline void SimpleEncoder::set_encode_id(uint8_t encode_id) template inline std::optional SimpleEncoder::encode_next(STREAM& stream, int canvas_size) { - if (!_coupled) + if (_coupled) return encode_next_coupled(stream, canvas_size); if (!stream.good()) @@ -166,7 +166,7 @@ inline std::optional SimpleEncoder::encode_next_coupled(STREAM& stream, template inline fountain_encoder_stream::ptr SimpleEncoder::create_fountain_encoder(STREAM& stream, int compression_level) { - unsigned chunk_size = cimbar::Config::fountain_chunk_size(_eccBytes, _bitsPerColor + _bitsPerSymbol); + unsigned chunk_size = cimbar::Config::fountain_chunk_size(_eccBytes, _bitsPerColor + _bitsPerSymbol, (_colorMode==0 and _coupled)); std::stringstream ss; if (compression_level <= 0) diff --git a/src/lib/encoder/test/EncoderRoundTripTest.cpp b/src/lib/encoder/test/EncoderRoundTripTest.cpp index 15f00dd..f0f4d17 100644 --- a/src/lib/encoder/test/EncoderRoundTripTest.cpp +++ b/src/lib/encoder/test/EncoderRoundTripTest.cpp @@ -39,7 +39,7 @@ TEST_CASE( "EncoderRoundTripTest/testFountain.Pad", "[unit]" ) // decoder Decoder dec(30); - fountain_decoder_sink> fds(tempdir.path(), cimbar::Config::fountain_chunk_size(30, 6)); + fountain_decoder_sink> fds(tempdir.path(), cimbar::Config::fountain_chunk_size(30, 6, false)); unsigned bytesDecoded = dec.decode_fountain(encodedImg, fds); assertEquals( 7500, bytesDecoded ); @@ -63,7 +63,7 @@ TEST_CASE( "EncoderRoundTripTest/testStreaming", "[unit]" ) // create decoder Decoder dec(30); - fountain_decoder_sink> fds(tempdir.path(), cimbar::Config::fountain_chunk_size(30, 6)); + fountain_decoder_sink> fds(tempdir.path(), cimbar::Config::fountain_chunk_size(30, 6, false)); // encode frames, then pass to decoder for (int i = 0; i < 100; ++i) diff --git a/src/lib/encoder/test/EncoderTest.cpp b/src/lib/encoder/test/EncoderTest.cpp index 17f7feb..60afa67 100644 --- a/src/lib/encoder/test/EncoderTest.cpp +++ b/src/lib/encoder/test/EncoderTest.cpp @@ -47,9 +47,9 @@ TEST_CASE( "EncoderTest/testFountain.4c", "[unit]" ) Encoder enc(40, 4, 2); enc.set_legacy_mode(); - assertEquals( 4, enc.encode_fountain(inputFile, outPrefix, 0) ); + assertEquals( 3, enc.encode_fountain(inputFile, outPrefix, 0) ); - std::vector hashes = {0x3f16ce63e424b9e2, 0x8f809de57607a92b, 0xb8d41fc26c0ca107, 0xb84c6d8ac21d6a43}; + std::vector hashes = {0xbb1cc62b662abfe5, 0xf586f6466a5b194, 0x8c2f0f40e6ecb08b}; for (unsigned i = 0; i < hashes.size(); ++i) { DYNAMIC_SECTION( "are we correct? : " << i )