Skip to content
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

Update cimbar_js UI with "mode B" toggle + docs #92

Merged
merged 7 commits into from
Feb 22, 2024
Merged

Conversation

sz3
Copy link
Owner

@sz3 sz3 commented Feb 19, 2024

A fast-follow to #91. Combined, these will be 0.6.0.

  1. instead of "4-color/8-color", the toggle is now "Mode B", "Mode 4C". The default is B.
  2. long-overdue docs updates!
  3. make the ccm matrix a static threadlocal. This averts a longstanding ( 🙃 ) race condition in CFC where multiple threads might simultaneously update their (shared) CimbDecoder instance with unknowable results. This is arguably a bug in CFC, but for now at least I'm going to experiment with using a threadlocal.

@sz3 sz3 force-pushed the 0.6-mode-switch branch 2 times, most recently from 11a82b5 to f50572b Compare February 22, 2024 03:47
Base automatically changed from mode-b to master February 22, 2024 03:52
sz3 added 7 commits February 21, 2024 21:53
We're replacing the old 8-color config in the UI with the 0.6 version of
8x8 4-color -- "mode B". The old (0.5) 4-color config will be "mode 4C",
kept for backwards compatibility reasons.
…nity

There are more efficient ways to do incremental builds, but this is
convenient.
There are other ways to pass this around, but this is the simplest
change. The old way was a race condition in CFC. 😱

Probably will want to revisit this in the future. The shared global
state feels a big gross.
Includes:
* new performance numbers. Very exciting. Very cool. Ambient lighting
helps!
* deprecating the old 8-color mode ("mode 8C" under the new naming
scheme). This simplifies things, and a newer, faster format is waiting
in the wings...
* misc updates based on what I've learned
+ a single letter option for `cimbar` cli encode mode?
@sz3 sz3 marked this pull request as ready for review February 22, 2024 03:54
* There are 16 possible symbols per tile, encoding 4 bits
* There are 4 or 8 possible colors, encoding an additional 2-3 bits per tile.
* These 6-7 bits per tile work out to a maximum of 9300-10850 bytes per barcode, though in practice this number is reduced by error correction.
* These 6 bits per tile work out to a maximum of 9300 bytes per barcode, though in practice this number is reduced by error correction.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing 8-color mode numbers.

* The default ecc setting is 30/155, which is how we go from 9300 -> 7500 bytes of real data for a 4-color cimbar image.
* Reed Solomon is not perfect for this use case -- specifically, it corrects byte errors, and cimbar errors tend to involve 1-3 bits at a time. However, since Reed Solomon implementations are ubiquitous, it is currently in use.

## Current sustained benchmark

* 4-color cimbar with ecc=30:
* `mode B` (8x8 4-color) cimbar with ecc=30/155:
* 4,689,084 bytes (after compression) in 44s -> 852 kilobits/s (~106 KB/s)
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually using the same sample file, but the compression level is different. I was encouraged to see mode B holding its own, though I do think it might be slightly more sensitive than the old mode (4C) as far as "best case" performance is concerned.

* removed in 0.6.0. 8-color has always been inconsistent, and needs future research

* *beta* `mode S` (5x5 4-color) cimbar with ecc=40/216 (note: not finalized, and requires a special build)
* safely >1 Mbit/s
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A teaser!

* 8-color cimbar should be considered a prototype within a prototype. It is considerably more sensitive to lighting conditions and color tints.
* to this end, lower ecc settings *can* provide better burst rates. I've aimed for a balance of performance and reliability.
* cimbar `mode B` is preferred, and should be the most reliable.
* The older `mode 4C` *may* give more consistent transfer speeds in certain scenarios, but is mostly included for backwards-compatibility reasons.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.


* other notes:
* having better lighting in the frame often leads to better results -- this is why cimbar.org has a (mostly) white background. cfc uses android's auto-exposure, auto-focus, etc (it's a very simple app). Good ambient light -- or a white background -- can lead to more consitent quality frame capture.
* having better lighting in the frame often leads to better results -- this is why cimbar.org has a (mostly) white background. cfc uses android's auto-exposure, auto-focus, etc (it's a demo app). Good ambient light -- or a white background -- can lead to more consitent quality frame capture.
* screen brightness on the sender is good, but ambient light is better.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When benchmarking mode B, I was reminded of the importance of ambient lighting for optimal performance (i.e. being in a brighter room). I don't know/remember enough about optics to say whether this is a function of auto-exposure behavior, or a more fundamental physical constraint.

* because of the lighting/exposure question, landscape *may* be better than portrait.
* cfc currently has a low resolution, so the cimbar frame should take up as much of the display as possible (trust the guide brackets)
* the cimbar frame should take up as much of the display as possible (trust the guide brackets)
* the format is designed to decode at resolutions as low as 700x700, but performance may suffer.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In running some experiments for the 5x5 configuration (and 8x8 as the control), I was able to shrink the encoded image incrementally down to 700x700 without seeing significant performance degradation. This was a loose goal of the initial 8x8, but I wasn't sure where the limit actually was.

@@ -5,10 +5,10 @@

Behold: an experimental barcode format for air-gapped data transfer.

It can sustain speeds of 943+ kilobits/s (~118 KB/s) using just a computer monitor and a smartphone camera!
It can sustain speeds of 850 kilobits/s (~106 KB/s) using just a computer monitor and a smartphone camera!
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing 8-color means we also slow down on our benchmark here. Alas.

But this should be more representative than quoting an 8-color number most people probably couldn't get working -- so I prefer it.

@@ -31,7 +31,7 @@ No internet/bluetooth/NFC/etc is used. All data is transmitted through the camer

The code is written in C++, and developed/tested on amd64+linux, arm64+android (decoder only), and emscripten+WASM (encoder only). It probably works, or can be made to work, on other platforms.

Crucially, because the encoder compiles to asmjs and wasm, it can run on anything with a modern web browser. There are [releases](https://github.com/sz3/libcimbar/releases/latest) if you wish to run the encoder locally instead of via cimbar.org.
Crucially, because the encoder compiles to asmjs and wasm, it can run on anything with a modern web browser. For offline use, you can either install cimbar.org as a progressive web app, or [download the latest release](https://github.com/sz3/libcimbar/releases/latest) of `cimbar_js.html`, save it locally, and open it in your web browser.
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mentioning that cimbar.org is now a PWA. (just in time for apple to remove PWA support in Europe 🙃 )

@@ -177,6 +177,7 @@ int main(int argc, char** argv)
unsigned compressionLevel = cimbar::Config::compression_level();
unsigned ecc = cimbar::Config::ecc_bytes();
options.add_options()
("n,encode", "Run the encoder!", cxxopts::value<bool>())
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure about -n, but -e is already used for ecc. And I've seen unixtools commit worse crimes against the alphabet than this.

{
// testing purposes only.
// this returning a thread local would be fine, iff we only use it for debugging!
static thread_local color_correction _ccm;
return _ccm;
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The only interesting code change on this branch.

We've had a subtle(?) race condition in the CFC app ever since I introduced color correction -- this CimbDecoder object is shared across threads, which means that updating the ccm matrix is asking for trouble.

I could pass it around as a function param (implicitly threadlocal), but I want to experiment with static threadlocal a bit -- it might be useful for the Config object...

@@ -141,38 +141,38 @@
margin-top: 3px;
}
#nav-container .icon-bar:nth-of-type(1) {
background-color: #00ffff;
box-shadow: 0px 0px 5px #00ffff, 0px 0px 2px #00ffff;
background-color: #00ff00;
Copy link
Owner Author

@sz3 sz3 Feb 22, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this is to change the icons when we have mode B selected vs mode 4C. It's so subtle (swapping green/cyan) that I'm not sure that it's worth it. But having green up top and magenta at the bottom reflects the color order we're actually using, and I couldn't resist making it match. Call it an affectation

@sz3 sz3 merged commit a0178c2 into master Feb 22, 2024
8 checks passed
@sz3 sz3 deleted the 0.6-mode-switch branch February 22, 2024 04:16
sz3 added a commit that referenced this pull request Mar 13, 2024
a0178c2 Merge pull request #92 from sz3/0.6-mode-switch
4f73a9e Update sample image in README
656588b Add color change back for menu icon based on mode selection
ad8cda7 Cleanup some includes/comments
390041e Update docs for mode B!
95afff4 Switch ccm matrix to use a thread_local
347d231 Less && in package-wasm, so we can re-run the script with (some) impunity
dbf77a2 Update cimbar.js with 0.6 modes
7b54894 Merge pull request #91 from sz3/mode-b
7206b91 Use new samples submodule rev
196a893 Cleanup some includes/comments
55299de `fountain_chunks_per_frame()` config function needs to return "10" for 0.5.x
9f6600d Add toggle for old "4c" mode in the cimbar_js and the cli tools
af823fd Update tests, and add back some "legacy" (0.5.x = "4c") support for encoder
a05d414 Disable color decode "skip" logic
8c3b0a7 Make new color correction mode the default
88c30e0 Use Moore-Penrose least squares to compute our CCM
2f491ef Changes for the second-pass CCM+color decode
fcb214d Working towards proper color correction
be36c02 Add FountainHeader logic to CimbReader
36676d7 Update FountainMetadata to include the block_id
2c6319d Change default encode_id to 109, and return to older color calc?
2e7e3aa Change calc for required frames we generate for small files
6b58b25 Flush symbols/colors separately
80a668c Tweaks to Encoder default params
33b6cef Reintroduce the legacy decoder function
55dbf68 First pass at decoder for split symbols/colors
4f9622f Simplify loop
e7fdfe3 First pass at splitting symbol and color channels, encoder edition
db0812c WIP to vary fountain chunk size by number of symbol bits...
4067532 color_mode for encoder?
32b9ffa Experiment with a different color calculation?

git-subtree-dir: app/src/cpp/libcimbar
git-subtree-split: a0178c2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant