Skip to content

Commit f5607a3

Browse files
committed
Add test to validate we can survive giving the fountain sink the wrong data
... since we're using that as the detection mechanism for auto-detect. Also, a simplification to Decoder::do_decode()
1 parent 7b11358 commit f5607a3

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

src/lib/encoder/Decoder.h

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,6 @@ inline unsigned Decoder::do_decode(CimbReader& reader, STREAM& ostream, bool leg
8080
colorPositions.resize(reader.num_reads()); // the number of cells == reader.num_reads(). Can we calculate this from config at compile time? Do we care?
8181

8282
unsigned bitsPerSymbol = cimbar::Config::symbol_bits();
83-
unsigned bytesDecoded = 0;
8483
{
8584
bitbuffer symbolBits(cimbar::Config::capacity(bitsPerSymbol));
8685
// read symbols first
@@ -116,8 +115,8 @@ inline unsigned Decoder::do_decode(CimbReader& reader, STREAM& ostream, bool leg
116115
}
117116

118117
reed_solomon_stream rss(ostream, _eccBytes, _eccBlockSize);
119-
bytesDecoded += colorBits.flush(rss); // will return the pos after this flush(), which includes the previous flush()...
120-
return bytesDecoded;
118+
// flush() will return the (good) cumulative bytes written to the underlying stream
119+
return colorBits.flush(rss);
121120
}
122121

123122
template <typename STREAM>

src/lib/encoder/test/EncoderRoundTripTest.cpp

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,42 @@ TEST_CASE( "EncoderRoundTripTest/testFountain.Pad", "[unit]" )
4646

4747
std::string decodedContents = File(tempdir.path() / "0.626").read_all();
4848
assertEquals( "hello", decodedContents );
49+
50+
assertEquals( 1, fds.num_done() );
51+
}
52+
53+
TEST_CASE( "EncoderRoundTripTest/testFountain.SinkMismatch", "[unit]" )
54+
{
55+
MakeTempDirectory tempdir;
56+
57+
std::string inputFile = tempdir.path() / "hello.txt";
58+
std::string outPrefix = tempdir.path() / "encoder.fountain";
59+
60+
{
61+
std::ofstream f(inputFile);
62+
f << "hello"; // 5 bytes!
63+
}
64+
65+
// will be padded so the fountain encoding is happy. The encoded image looks suspiciously non-random!
66+
Encoder enc(30, 4, 2);
67+
assertEquals( 1, enc.encode_fountain(inputFile, outPrefix) );
68+
69+
uint64_t hash = 0xeecc8800efce8c48;
70+
std::string path = fmt::format("{}_0.png", outPrefix);
71+
cv::Mat encodedImg = cv::imread(path);
72+
cv::cvtColor(encodedImg, encodedImg, cv::COLOR_BGR2RGB);
73+
assertEquals( hash, image_hash::average_hash(encodedImg) );
74+
75+
// decoder
76+
Decoder dec(30);
77+
// sink with a mismatched fountain_chunk_size
78+
// importantly, the sink expects a *larger* chunk than we'll give it...
79+
fountain_decoder_sink<cimbar::zstd_decompressor<std::ofstream>> fds(tempdir.path(), cimbar::Config::fountain_chunk_size(30, 6, true));
80+
81+
unsigned bytesDecoded = dec.decode_fountain(encodedImg, fds, 1);
82+
assertEquals( 7500, bytesDecoded );
83+
84+
assertEquals( 0, fds.num_done() );
4985
}
5086

5187
TEST_CASE( "EncoderRoundTripTest/testStreaming", "[unit]" )

0 commit comments

Comments
 (0)