-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Functionality to split encoding/decoding of colors and symbols #91
Changes from all commits
32b9ffa
4067532
db0812c
e7fdfe3
4f9622f
55dbf68
33b6cef
80a668c
6b58b25
2e7e3aa
2c6319d
36676d7
be36c02
fcb214d
2f491ef
88c30e0
8c3b0a7
a05d414
af823fd
9f6600d
55299de
196a893
7206b91
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
+ − | 6bit/4cecc30f.png | |
+ − | b/4cecc30f.png | |
+ − | b/ex2434.jpg | |
+ − | b/ex380.jpg | |
+ − | b/scan2434.jpg | |
+ − | b/tr_0.png |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,9 +101,11 @@ namespace { | |
} | ||
|
||
template <typename FilenameIterable> | ||
int encode(const FilenameIterable& infiles, const std::string& outpath, int ecc, int color_bits, int compression_level, bool no_fountain) | ||
int encode(const FilenameIterable& infiles, const std::string& outpath, int ecc, int color_bits, int compression_level, bool legacy_mode, bool no_fountain) | ||
{ | ||
Encoder en(ecc, cimbar::Config::symbol_bits(), color_bits); | ||
if (legacy_mode) | ||
en.set_legacy_mode(); | ||
for (const string& f : infiles) | ||
{ | ||
if (f.empty()) | ||
|
@@ -117,7 +119,7 @@ int encode(const FilenameIterable& infiles, const std::string& outpath, int ecc, | |
} | ||
|
||
template <typename FilenameIterable> | ||
int decode(const FilenameIterable& infiles, const std::function<int(cv::UMat, bool, bool)>& decode, bool no_deskew, bool undistort, int preprocess, bool color_correct) | ||
int decode(const FilenameIterable& infiles, const std::function<int(cv::UMat, bool, int)>& decodefun, bool no_deskew, bool undistort, int preprocess, int color_correct) | ||
{ | ||
int err = 0; | ||
for (const string& inf : infiles) | ||
|
@@ -150,17 +152,19 @@ int decode(const FilenameIterable& infiles, const std::function<int(cv::UMat, bo | |
shouldPreprocess = true; | ||
} | ||
|
||
int bytes = decode(img, shouldPreprocess, color_correct); | ||
int bytes = decodefun(img, shouldPreprocess, color_correct); | ||
if (!bytes) | ||
err |= 4; | ||
} | ||
return err; | ||
} | ||
|
||
// see also "decodefun" for non-fountain decodes, defined as a lambda inline below. | ||
// this one needs its own function since it's a template (: | ||
template <typename SINK> | ||
std::function<int(cv::UMat,bool,bool)> fountain_decode_fun(SINK& sink, Decoder& d) | ||
std::function<int(cv::UMat,bool,int)> fountain_decode_fun(SINK& sink, Decoder& d) | ||
{ | ||
return [&sink, &d] (cv::UMat m, bool pre, bool cc) { | ||
return [&sink, &d] (cv::UMat m, bool pre, int cc) { | ||
return d.decode_fountain(m, sink, pre, cc); | ||
}; | ||
} | ||
|
@@ -177,8 +181,10 @@ int main(int argc, char** argv) | |
("o,out", "Output file prefix (encoding) or directory (decoding).", cxxopts::value<string>()) | ||
("c,color-bits", "Color bits. [0-3]", cxxopts::value<int>()->default_value(turbo::str::str(colorBits))) | ||
("e,ecc", "ECC level", cxxopts::value<unsigned>()->default_value(turbo::str::str(ecc))) | ||
("m,mode", "Select a cimbar mode. B (the default) is new to 0.6.x. 4C is the 0.5.x config. [B,4C]", cxxopts::value<string>()->default_value("B")) | ||
("z,compression", "Compression level. 0 == no compression.", cxxopts::value<int>()->default_value(turbo::str::str(compressionLevel))) | ||
("color-correct", "Toggle decoding color correction. 1 == on. 0 == off.", cxxopts::value<int>()->default_value("1")) | ||
("color-correct", "Toggle decoding color correction. 2 == full (fountain mode only). 1 == simple. 0 == off.", cxxopts::value<int>()->default_value("2")) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Leaning towards removing the old ("simple") color-correct logic. It's nice that it can be run under more conditions, but in its current form it's just not good enough to be useful. |
||
("color-correction-file", "Debug -- save color correction matrix generated during fountain decode, or use it for non-fountain decodes", cxxopts::value<string>()) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is used for doing a two-pass manual debug/verification process:
|
||
("encode", "Run the encoder!", cxxopts::value<bool>()) | ||
("no-deskew", "Skip the deskew step -- treat input image as already extracted.", cxxopts::value<bool>()) | ||
("no-fountain", "Disable fountain encode/decode. Will also disable compression.", cxxopts::value<bool>()) | ||
|
@@ -216,48 +222,70 @@ int main(int argc, char** argv) | |
compressionLevel = result["compression"].as<int>(); | ||
ecc = result["ecc"].as<unsigned>(); | ||
|
||
bool legacy_mode = false; | ||
if (result.count("mode")) | ||
{ | ||
string mode = result["mode"].as<string>(); | ||
legacy_mode = (mode == "4c") or (mode == "4C"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
} | ||
|
||
if (encodeFlag) | ||
{ | ||
if (useStdin) | ||
return encode(StdinLineReader(), outpath, ecc, colorBits, compressionLevel, no_fountain); | ||
return encode(StdinLineReader(), outpath, ecc, colorBits, compressionLevel, legacy_mode, no_fountain); | ||
else | ||
return encode(infiles, outpath, ecc, colorBits, compressionLevel, no_fountain); | ||
return encode(infiles, outpath, ecc, colorBits, compressionLevel, legacy_mode, no_fountain); | ||
} | ||
|
||
// else, decode | ||
bool no_deskew = result.count("no-deskew"); | ||
bool undistort = result.count("undistort"); | ||
int color_correct = result["color-correct"].as<int>(); | ||
string color_correction_file; | ||
if (result.count("color-correction-file")) | ||
color_correction_file = result["color-correction-file"].as<string>(); | ||
int preprocess = result["preprocess"].as<int>(); | ||
|
||
Decoder d(ecc, colorBits); | ||
unsigned color_mode = legacy_mode? 0 : 1; | ||
bool coupled = legacy_mode; | ||
Decoder d(ecc, colorBits, color_mode, coupled); | ||
|
||
if (no_fountain) | ||
{ | ||
if (not color_correction_file.empty()) | ||
d.load_ccm(color_correction_file); | ||
|
||
// simpler encoding, just the basics + ECC. No compression, fountain codes, etc. | ||
std::ofstream f(outpath); | ||
std::function<int(cv::UMat,bool,bool)> fun = [&f, &d] (cv::UMat m, bool pre, bool cc) { | ||
std::function<int(cv::UMat,bool,int)> decodefun = [&f, &d] (cv::UMat m, bool pre, int cc) { | ||
return d.decode(m, f, pre, cc); | ||
}; | ||
if (useStdin) | ||
return decode(StdinLineReader(), fun, no_deskew, undistort, preprocess, color_correct); | ||
return decode(StdinLineReader(), decodefun, no_deskew, undistort, preprocess, color_correct); | ||
else | ||
return decode(infiles, fun, no_deskew, undistort, preprocess, color_correct); | ||
return decode(infiles, decodefun, no_deskew, undistort, preprocess, color_correct); | ||
} | ||
|
||
// else, the good stuff | ||
unsigned chunkSize = cimbar::Config::fountain_chunk_size(ecc); | ||
int res = -200; | ||
|
||
unsigned chunkSize = cimbar::Config::fountain_chunk_size(ecc, colorBits+cimbar::Config::symbol_bits(), legacy_mode); | ||
if (compressionLevel <= 0) | ||
{ | ||
fountain_decoder_sink<std::ofstream> sink(outpath, chunkSize, true); | ||
return decode(infiles, fountain_decode_fun(sink, d), no_deskew, undistort, preprocess, color_correct); | ||
res = decode(infiles, fountain_decode_fun(sink, d), no_deskew, undistort, preprocess, color_correct); | ||
} | ||
else // default case, all bells and whistles | ||
{ | ||
fountain_decoder_sink<cimbar::zstd_decompressor<std::ofstream>> sink(outpath, chunkSize, true); | ||
|
||
// else -- default case, all bells and whistles | ||
fountain_decoder_sink<cimbar::zstd_decompressor<std::ofstream>> sink(outpath, chunkSize, true); | ||
if (useStdin) | ||
res = decode(StdinLineReader(), fountain_decode_fun(sink, d), no_deskew, undistort, preprocess, color_correct); | ||
else | ||
res = decode(infiles, fountain_decode_fun(sink, d), no_deskew, undistort, preprocess, color_correct); | ||
} | ||
if (not color_correction_file.empty()) | ||
d.save_ccm(color_correction_file); | ||
|
||
if (useStdin) | ||
return decode(StdinLineReader(), fountain_decode_fun(sink, d), no_deskew, undistort, preprocess, color_correct); | ||
else | ||
return decode(infiles, fountain_decode_fun(sink, d), no_deskew, undistort, preprocess, color_correct); | ||
return res; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is currently the toggle for the old mode (interleaved symbol/color bits). It probably needs to be refactored into a config option, but for now this works.