mirror of https://github.com/sz3/libcimbar
Decoder: when we known there's a mismatch between the fountain chunk size...
... and the fountain *stream* (sink)'s chunk size, we shouldn't send it the decoded bytes. It's not going to be able to do anything useful with them. Instead, we'll have a /dev/null style "null_stream" that just tracks how many bytes were written to it.
This commit is contained in:
parent
f5607a3761
commit
f1e136f143
|
@ -8,6 +8,7 @@
|
|||
#include "cimb_translator/Config.h"
|
||||
#include "cimb_translator/Interleave.h"
|
||||
#include "util/File.h"
|
||||
#include "util/null_stream.h"
|
||||
|
||||
#include <opencv2/opencv.hpp>
|
||||
#include <functional>
|
||||
|
@ -166,8 +167,22 @@ template <typename MAT, typename FOUNTAINSTREAM>
|
|||
inline unsigned Decoder::decode_fountain(const MAT& img, FOUNTAINSTREAM& ostream, unsigned color_mode, bool should_preprocess, int color_correction)
|
||||
{
|
||||
CimbReader reader(img, _decoder, color_mode, should_preprocess, color_correction);
|
||||
aligned_stream aligner(ostream, ostream.chunk_size(), 0, std::bind(&CimbReader::update_metadata, &reader, std::placeholders::_1, std::placeholders::_2));
|
||||
return do_decode(reader, aligner, color_mode==0);
|
||||
bool legacy_mode = color_mode == 0;
|
||||
unsigned chunk_size = cimbar::Config::fountain_chunk_size(_eccBytes, _bitsPerOp, legacy_mode);
|
||||
auto update_md_fun = std::bind(&CimbReader::update_metadata, &reader, std::placeholders::_1, std::placeholders::_2);
|
||||
|
||||
// we don't want to feed the fountain stream bad data, so we eat the decode if we have a mismatch
|
||||
// we still might succeed the decode, in which case (hopefully) the positive bytes we return will
|
||||
// tell our caller to fix the underlying ostream so the next round will work.
|
||||
if (ostream.chunk_size() != chunk_size)
|
||||
{
|
||||
null_stream devnull;
|
||||
aligned_stream aligner(devnull, chunk_size, 0, update_md_fun);
|
||||
return do_decode(reader, aligner, legacy_mode);
|
||||
}
|
||||
|
||||
aligned_stream aligner(ostream, ostream.chunk_size(), 0, update_md_fun);
|
||||
return do_decode(reader, aligner, legacy_mode);
|
||||
}
|
||||
|
||||
inline unsigned Decoder::decode(std::string filename, std::string output, unsigned color_mode)
|
||||
|
|
|
@ -88,7 +88,7 @@ protected:
|
|||
bool _good;
|
||||
};
|
||||
|
||||
inline std::ifstream& operator<<(std::ifstream& s, const ReedSolomon::BadChunk& chunk)
|
||||
inline std::ifstream& operator<<(std::ifstream& s, const ReedSolomon::BadChunk&)
|
||||
{
|
||||
return s;
|
||||
}
|
||||
|
|
|
@ -64,9 +64,10 @@ TEST_CASE( "EncoderRoundTripTest/testFountain.SinkMismatch", "[unit]" )
|
|||
|
||||
// will be padded so the fountain encoding is happy. The encoded image looks suspiciously non-random!
|
||||
Encoder enc(30, 4, 2);
|
||||
enc.set_legacy_mode();
|
||||
assertEquals( 1, enc.encode_fountain(inputFile, outPrefix) );
|
||||
|
||||
uint64_t hash = 0xeecc8800efce8c48;
|
||||
uint64_t hash = 0xaecc8c00efce8c28;
|
||||
std::string path = fmt::format("{}_0.png", outPrefix);
|
||||
cv::Mat encodedImg = cv::imread(path);
|
||||
cv::cvtColor(encodedImg, encodedImg, cv::COLOR_BGR2RGB);
|
||||
|
@ -75,10 +76,11 @@ TEST_CASE( "EncoderRoundTripTest/testFountain.SinkMismatch", "[unit]" )
|
|||
// decoder
|
||||
Decoder dec(30);
|
||||
// sink with a mismatched fountain_chunk_size
|
||||
// importantly, the sink expects a *larger* chunk than we'll give it...
|
||||
fountain_decoder_sink<cimbar::zstd_decompressor<std::ofstream>> fds(tempdir.path(), cimbar::Config::fountain_chunk_size(30, 6, true));
|
||||
// importantly, the sink expects a *smaller* chunk than we'll give it...
|
||||
// because that's a more interesting test...
|
||||
fountain_decoder_sink<cimbar::zstd_decompressor<std::ofstream>> fds(tempdir.path(), cimbar::Config::fountain_chunk_size(30, 6, false));
|
||||
|
||||
unsigned bytesDecoded = dec.decode_fountain(encodedImg, fds, 1);
|
||||
unsigned bytesDecoded = dec.decode_fountain(encodedImg, fds, 0);
|
||||
assertEquals( 7500, bytesDecoded );
|
||||
|
||||
assertEquals( 0, fds.num_done() );
|
||||
|
|
|
@ -0,0 +1,28 @@
|
|||
/* This code is subject to the terms of the Mozilla Public License, v.2.0. http://mozilla.org/MPL/2.0/. */
|
||||
#pragma once
|
||||
|
||||
class null_stream
|
||||
{
|
||||
public:
|
||||
null_stream()
|
||||
{}
|
||||
|
||||
null_stream& write(const char*, unsigned length)
|
||||
{
|
||||
_count += length;
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool good() const
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
long tellp() const
|
||||
{
|
||||
return _count;
|
||||
}
|
||||
|
||||
protected:
|
||||
long _count = 0;
|
||||
};
|
Loading…
Reference in New Issue