diff options
l--------- | .direnv/flake-profile | 2 | ||||
-rw-r--r-- | .direnv/flake-profile.rc | 20 | ||||
-rw-r--r-- | src/decode.rs | 69 | ||||
-rw-r--r-- | src/encode.rs | 44 | ||||
-rw-r--r-- | src/lib.rs | 16 | ||||
-rw-r--r-- | src/rle.rs | 89 | ||||
-rw-r--r-- | tests/serde.rs | 22 |
7 files changed, 224 insertions, 38 deletions
diff --git a/.direnv/flake-profile b/.direnv/flake-profile index 624f00f..0e6e742 120000 --- a/.direnv/flake-profile +++ b/.direnv/flake-profile | |||
@@ -1 +1 @@ | |||
/nix/store/hk8227smba1l2lrk4np5fqy2hkb0jaf3-nix-shell-env \ No newline at end of file | /nix/store/q3bk2x9q1g2xnah8j9l9xpl2037ks0xv-nix-shell-env \ No newline at end of file | ||
diff --git a/.direnv/flake-profile.rc b/.direnv/flake-profile.rc index 49f03d2..3796858 100644 --- a/.direnv/flake-profile.rc +++ b/.direnv/flake-profile.rc | |||
@@ -32,7 +32,7 @@ NIX_CC=/nix/store/i9a3zzf2spmw67jppvkj2yavnbka62id-gcc-wrapper-10.2.0 | |||
32 | export NIX_CC | 32 | export NIX_CC |
33 | NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu=1 | 33 | NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu=1 |
34 | export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu | 34 | export NIX_CC_WRAPPER_TARGET_HOST_x86_64_unknown_linux_gnu |
35 | NIX_CFLAGS_COMPILE=' -frandom-seed=hk8227smba -isystem /nix/store/91ym2jzh08470r4jb1d5pmh22vg2bpck-openssl-1.1.1i-dev/include -isystem /nix/store/saiwalr8jq58mbyipkn824r93gjjnw5x-ncurses-6.2-dev/include -isystem /nix/store/91ym2jzh08470r4jb1d5pmh22vg2bpck-openssl-1.1.1i-dev/include -isystem /nix/store/saiwalr8jq58mbyipkn824r93gjjnw5x-ncurses-6.2-dev/include' | 35 | NIX_CFLAGS_COMPILE=' -frandom-seed=q3bk2x9q1g' |
36 | export NIX_CFLAGS_COMPILE | 36 | export NIX_CFLAGS_COMPILE |
37 | NIX_ENFORCE_NO_NATIVE=1 | 37 | NIX_ENFORCE_NO_NATIVE=1 |
38 | export NIX_ENFORCE_NO_NATIVE | 38 | export NIX_ENFORCE_NO_NATIVE |
@@ -40,7 +40,7 @@ NIX_HARDENING_ENABLE='fortify stackprotector pic strictoverflow format relro bin | |||
40 | export NIX_HARDENING_ENABLE | 40 | export NIX_HARDENING_ENABLE |
41 | NIX_INDENT_MAKE=1 | 41 | NIX_INDENT_MAKE=1 |
42 | export NIX_INDENT_MAKE | 42 | export NIX_INDENT_MAKE |
43 | NIX_LDFLAGS='-rpath /home/np/code/rust/obi/outputs/out/lib64 -rpath /home/np/code/rust/obi/outputs/out/lib -L/nix/store/ni0nxz7jnd3scrfqsdr6cragl95fqmyb-rust-1.50.0-nightly-2020-12-22-bb1fbbf84/lib -L/nix/store/kchm26396krqwdn2dkx6l0hb79lwlhr1-openssl-1.1.1i/lib -L/nix/store/d3nz4c5xf1bqz8rwr8m4gbsrny9ffidk-ncurses-6.2/lib -L/nix/store/ni0nxz7jnd3scrfqsdr6cragl95fqmyb-rust-1.50.0-nightly-2020-12-22-bb1fbbf84/lib -L/nix/store/kchm26396krqwdn2dkx6l0hb79lwlhr1-openssl-1.1.1i/lib -L/nix/store/d3nz4c5xf1bqz8rwr8m4gbsrny9ffidk-ncurses-6.2/lib' | 43 | NIX_LDFLAGS='-rpath /home/np/code/rust/obi/outputs/out/lib64 -rpath /home/np/code/rust/obi/outputs/out/lib -L/nix/store/58syiz9158g5s53gjh8f5b89bhhp1m0s-rust-1.53.0-nightly-2021-03-30-74874a690/lib -L/nix/store/58syiz9158g5s53gjh8f5b89bhhp1m0s-rust-1.53.0-nightly-2021-03-30-74874a690/lib' |
44 | export NIX_LDFLAGS | 44 | export NIX_LDFLAGS |
45 | NIX_LIB64_IN_SELF_RPATH=1 | 45 | NIX_LIB64_IN_SELF_RPATH=1 |
46 | NIX_NO_SELF_RPATH=1 | 46 | NIX_NO_SELF_RPATH=1 |
@@ -55,7 +55,7 @@ export OBJDUMP | |||
55 | OPTERR=1 | 55 | OPTERR=1 |
56 | OPTIND=1 | 56 | OPTIND=1 |
57 | OSTYPE=linux-gnu | 57 | OSTYPE=linux-gnu |
58 | PATH=/nix/store/ni0nxz7jnd3scrfqsdr6cragl95fqmyb-rust-1.50.0-nightly-2020-12-22-bb1fbbf84/bin:/nix/store/pj3m562kh9lr7wjk3hlyandhd1qpapgh-rust-analyzer-unstable-2021-02-22/bin:/nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0/bin:/nix/store/71707dbkha4mryph7ywp48wi2r1sc0hf-openssl-1.1.1i-bin/bin:/nix/store/saiwalr8jq58mbyipkn824r93gjjnw5x-ncurses-6.2-dev/bin:/nix/store/d3nz4c5xf1bqz8rwr8m4gbsrny9ffidk-ncurses-6.2/bin:/nix/store/d7lyvmvzf1a8qqhsxhdc3r6dwbdmfcap-patchelf-0.12/bin:/nix/store/i9a3zzf2spmw67jppvkj2yavnbka62id-gcc-wrapper-10.2.0/bin:/nix/store/wxri3dc14yd1w997vjfvsnn6qml64l4r-gcc-10.2.0/bin:/nix/store/fr2k1vwmyd5ngmb3y0v090nh21nn6gqp-glibc-2.32-35-bin/bin:/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32/bin:/nix/store/f4w8p656gg6v2k1v0whwmyk09kz3k8ic-binutils-wrapper-2.35.1/bin:/nix/store/9f8y44vmjnwdjvzlff0gm3f3g6ycyyqy-binutils-2.35.1/bin:/nix/store/fr2k1vwmyd5ngmb3y0v090nh21nn6gqp-glibc-2.32-35-bin/bin:/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32/bin:/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32/bin:/nix/store/nq9l23mrm8irvl9qvxgvxqqkm5sfnc9d-findutils-4.7.0/bin:/nix/store/7yq29nnglh2s576n7vdmzqryym22f8rj-diffutils-3.7/bin:/nix/store/0839nqri8w69c91amlsq9bawaqlzpmh9-gnused-4.8/bin:/nix/store/wmiyjdsaydyv024al5ddqd3liljrfvk7-gnugrep-3.6/bin:/nix/store/snmar11l5w9jrxva2s5d6143nqmdgzqb-gawk-5.1.0/bin:/nix/store/cisss0pcfh72kmnsv4qa6h41wcwb9mkv-gnutar-1.32/bin:/nix/store/prdifiyrxwgf6sp4rwmrqvfdnvf72gw2-gzip-1.10/bin:/nix/store/pp9shwhcdxxbhgp96fcaj0g8x5g54zrl-bzip2-1.0.6.0.1-bin/bin:/nix/store/fydw5vhlhpq438cxv4vwpa8pf8p8fv5s-gnumake-4.3/bin:/nix/store/yyy7wr7r9jwjjqkr1yn643g3wzv010zd-bash-4.4-p23/bin:/nix/store/qcw3qagp709qwfza259zqss5qh4wg789-patch-2.7.6/bin:/nix/store/q0jqhjabwaaak30l4sq3z0xi6jrkpnbn-xz-5.2.5-bin/bin | 58 | PATH=/nix/store/58syiz9158g5s53gjh8f5b89bhhp1m0s-rust-1.53.0-nightly-2021-03-30-74874a690/bin:/nix/store/pj3m562kh9lr7wjk3hlyandhd1qpapgh-rust-analyzer-unstable-2021-02-22/bin:/nix/store/rfx0jz6pr3n2dcxm99finhbp99v45qx4-rustfmt-1.49.0/bin:/nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0/bin:/nix/store/d7lyvmvzf1a8qqhsxhdc3r6dwbdmfcap-patchelf-0.12/bin:/nix/store/i9a3zzf2spmw67jppvkj2yavnbka62id-gcc-wrapper-10.2.0/bin:/nix/store/wxri3dc14yd1w997vjfvsnn6qml64l4r-gcc-10.2.0/bin:/nix/store/fr2k1vwmyd5ngmb3y0v090nh21nn6gqp-glibc-2.32-35-bin/bin:/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32/bin:/nix/store/f4w8p656gg6v2k1v0whwmyk09kz3k8ic-binutils-wrapper-2.35.1/bin:/nix/store/9f8y44vmjnwdjvzlff0gm3f3g6ycyyqy-binutils-2.35.1/bin:/nix/store/fr2k1vwmyd5ngmb3y0v090nh21nn6gqp-glibc-2.32-35-bin/bin:/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32/bin:/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32/bin:/nix/store/nq9l23mrm8irvl9qvxgvxqqkm5sfnc9d-findutils-4.7.0/bin:/nix/store/7yq29nnglh2s576n7vdmzqryym22f8rj-diffutils-3.7/bin:/nix/store/0839nqri8w69c91amlsq9bawaqlzpmh9-gnused-4.8/bin:/nix/store/wmiyjdsaydyv024al5ddqd3liljrfvk7-gnugrep-3.6/bin:/nix/store/snmar11l5w9jrxva2s5d6143nqmdgzqb-gawk-5.1.0/bin:/nix/store/cisss0pcfh72kmnsv4qa6h41wcwb9mkv-gnutar-1.32/bin:/nix/store/prdifiyrxwgf6sp4rwmrqvfdnvf72gw2-gzip-1.10/bin:/nix/store/pp9shwhcdxxbhgp96fcaj0g8x5g54zrl-bzip2-1.0.6.0.1-bin/bin:/nix/store/fydw5vhlhpq438cxv4vwpa8pf8p8fv5s-gnumake-4.3/bin:/nix/store/yyy7wr7r9jwjjqkr1yn643g3wzv010zd-bash-4.4-p23/bin:/nix/store/qcw3qagp709qwfza259zqss5qh4wg789-patch-2.7.6/bin:/nix/store/q0jqhjabwaaak30l4sq3z0xi6jrkpnbn-xz-5.2.5-bin/bin |
59 | export PATH | 59 | export PATH |
60 | PIPESTATUS=([0]="0") | 60 | PIPESTATUS=([0]="0") |
61 | PS4='+ ' | 61 | PS4='+ ' |
@@ -63,7 +63,11 @@ RANLIB=ranlib | |||
63 | export RANLIB | 63 | export RANLIB |
64 | READELF=readelf | 64 | READELF=readelf |
65 | export READELF | 65 | export READELF |
66 | RUST_SRC_PATH=/nix/store/ncxadjgpdacbf69yhpgwvwnqhmh5yk96-rust-lib-src | 66 | RUST_BACKTRACE=1 |
67 | export RUST_BACKTRACE | ||
68 | RUST_LOG=info | ||
69 | export RUST_LOG | ||
70 | RUST_SRC_PATH=/nix/store/m0k4il8v2wv0c7nniqndcxh72qmzvvg2-rust-src-1.53.0-nightly-2021-03-30-74874a690/lib/rustlib/src/rust/library | ||
67 | export RUST_SRC_PATH | 71 | export RUST_SRC_PATH |
68 | SHELL=/nix/store/yyy7wr7r9jwjjqkr1yn643g3wzv010zd-bash-4.4-p23/bin/bash | 72 | SHELL=/nix/store/yyy7wr7r9jwjjqkr1yn643g3wzv010zd-bash-4.4-p23/bin/bash |
69 | export SHELL | 73 | export SHELL |
@@ -75,7 +79,7 @@ STRINGS=strings | |||
75 | export STRINGS | 79 | export STRINGS |
76 | STRIP=strip | 80 | STRIP=strip |
77 | export STRIP | 81 | export STRIP |
78 | XDG_DATA_DIRS=/nix/store/ni0nxz7jnd3scrfqsdr6cragl95fqmyb-rust-1.50.0-nightly-2020-12-22-bb1fbbf84/share:/nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0/share:/nix/store/d3nz4c5xf1bqz8rwr8m4gbsrny9ffidk-ncurses-6.2/share:/nix/store/d7lyvmvzf1a8qqhsxhdc3r6dwbdmfcap-patchelf-0.12/share | 82 | XDG_DATA_DIRS=/nix/store/58syiz9158g5s53gjh8f5b89bhhp1m0s-rust-1.53.0-nightly-2021-03-30-74874a690/share:/nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0/share:/nix/store/d7lyvmvzf1a8qqhsxhdc3r6dwbdmfcap-patchelf-0.12/share |
79 | export XDG_DATA_DIRS | 83 | export XDG_DATA_DIRS |
80 | _=export | 84 | _=export |
81 | buildInputs= | 85 | buildInputs= |
@@ -115,7 +119,7 @@ fixupOutputHooks=([0]="if [ -z \"\${dontPatchELF-}\" ]; then patchELF \"\$prefix | |||
115 | initialPath='/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32 /nix/store/nq9l23mrm8irvl9qvxgvxqqkm5sfnc9d-findutils-4.7.0 /nix/store/7yq29nnglh2s576n7vdmzqryym22f8rj-diffutils-3.7 /nix/store/0839nqri8w69c91amlsq9bawaqlzpmh9-gnused-4.8 /nix/store/wmiyjdsaydyv024al5ddqd3liljrfvk7-gnugrep-3.6 /nix/store/snmar11l5w9jrxva2s5d6143nqmdgzqb-gawk-5.1.0 /nix/store/cisss0pcfh72kmnsv4qa6h41wcwb9mkv-gnutar-1.32 /nix/store/prdifiyrxwgf6sp4rwmrqvfdnvf72gw2-gzip-1.10 /nix/store/pp9shwhcdxxbhgp96fcaj0g8x5g54zrl-bzip2-1.0.6.0.1-bin /nix/store/fydw5vhlhpq438cxv4vwpa8pf8p8fv5s-gnumake-4.3 /nix/store/yyy7wr7r9jwjjqkr1yn643g3wzv010zd-bash-4.4-p23 /nix/store/qcw3qagp709qwfza259zqss5qh4wg789-patch-2.7.6 /nix/store/q0jqhjabwaaak30l4sq3z0xi6jrkpnbn-xz-5.2.5-bin' | 119 | initialPath='/nix/store/ypsd29c5hgj1x7xz5ddffanxw5d8fh7b-coreutils-8.32 /nix/store/nq9l23mrm8irvl9qvxgvxqqkm5sfnc9d-findutils-4.7.0 /nix/store/7yq29nnglh2s576n7vdmzqryym22f8rj-diffutils-3.7 /nix/store/0839nqri8w69c91amlsq9bawaqlzpmh9-gnused-4.8 /nix/store/wmiyjdsaydyv024al5ddqd3liljrfvk7-gnugrep-3.6 /nix/store/snmar11l5w9jrxva2s5d6143nqmdgzqb-gawk-5.1.0 /nix/store/cisss0pcfh72kmnsv4qa6h41wcwb9mkv-gnutar-1.32 /nix/store/prdifiyrxwgf6sp4rwmrqvfdnvf72gw2-gzip-1.10 /nix/store/pp9shwhcdxxbhgp96fcaj0g8x5g54zrl-bzip2-1.0.6.0.1-bin /nix/store/fydw5vhlhpq438cxv4vwpa8pf8p8fv5s-gnumake-4.3 /nix/store/yyy7wr7r9jwjjqkr1yn643g3wzv010zd-bash-4.4-p23 /nix/store/qcw3qagp709qwfza259zqss5qh4wg789-patch-2.7.6 /nix/store/q0jqhjabwaaak30l4sq3z0xi6jrkpnbn-xz-5.2.5-bin' |
116 | name=nix-shell | 120 | name=nix-shell |
117 | export name | 121 | export name |
118 | nativeBuildInputs='/nix/store/ni0nxz7jnd3scrfqsdr6cragl95fqmyb-rust-1.50.0-nightly-2020-12-22-bb1fbbf84 /nix/store/pgzjwsl6ilg93ifsx70ck5l2yv85fknm-rust-src-1.50.0-nightly-2020-12-22-bb1fbbf84 /nix/store/pj3m562kh9lr7wjk3hlyandhd1qpapgh-rust-analyzer-unstable-2021-02-22 /nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0 /nix/store/91ym2jzh08470r4jb1d5pmh22vg2bpck-openssl-1.1.1i-dev /nix/store/saiwalr8jq58mbyipkn824r93gjjnw5x-ncurses-6.2-dev' | 122 | nativeBuildInputs='/nix/store/58syiz9158g5s53gjh8f5b89bhhp1m0s-rust-1.53.0-nightly-2021-03-30-74874a690 /nix/store/m0k4il8v2wv0c7nniqndcxh72qmzvvg2-rust-src-1.53.0-nightly-2021-03-30-74874a690 /nix/store/pj3m562kh9lr7wjk3hlyandhd1qpapgh-rust-analyzer-unstable-2021-02-22 /nix/store/rfx0jz6pr3n2dcxm99finhbp99v45qx4-rustfmt-1.49.0 /nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0' |
119 | export nativeBuildInputs | 123 | export nativeBuildInputs |
120 | nobuildPhase=$'echo\necho "This derivation is not meant to be built, aborting";\necho\nexit 1\n' | 124 | nobuildPhase=$'echo\necho "This derivation is not meant to be built, aborting";\necho\nexit 1\n' |
121 | export nobuildPhase | 125 | export nobuildPhase |
@@ -137,7 +141,7 @@ export patches | |||
137 | phases=nobuildPhase | 141 | phases=nobuildPhase |
138 | export phases | 142 | export phases |
139 | pkg=/nix/store/i9a3zzf2spmw67jppvkj2yavnbka62id-gcc-wrapper-10.2.0 | 143 | pkg=/nix/store/i9a3zzf2spmw67jppvkj2yavnbka62id-gcc-wrapper-10.2.0 |
140 | pkgsBuildHost=([0]="/nix/store/ni0nxz7jnd3scrfqsdr6cragl95fqmyb-rust-1.50.0-nightly-2020-12-22-bb1fbbf84" [1]="/nix/store/pgzjwsl6ilg93ifsx70ck5l2yv85fknm-rust-src-1.50.0-nightly-2020-12-22-bb1fbbf84" [2]="/nix/store/pj3m562kh9lr7wjk3hlyandhd1qpapgh-rust-analyzer-unstable-2021-02-22" [3]="/nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0" [4]="/nix/store/91ym2jzh08470r4jb1d5pmh22vg2bpck-openssl-1.1.1i-dev" [5]="/nix/store/71707dbkha4mryph7ywp48wi2r1sc0hf-openssl-1.1.1i-bin" [6]="/nix/store/kchm26396krqwdn2dkx6l0hb79lwlhr1-openssl-1.1.1i" [7]="/nix/store/saiwalr8jq58mbyipkn824r93gjjnw5x-ncurses-6.2-dev" [8]="/nix/store/d3nz4c5xf1bqz8rwr8m4gbsrny9ffidk-ncurses-6.2" [9]="/nix/store/d7lyvmvzf1a8qqhsxhdc3r6dwbdmfcap-patchelf-0.12" [10]="/nix/store/mjjy30kxz775bhhi6j9phw81qh6dsbrf-move-docs.sh" [11]="/nix/store/kxw6q8v6isaqjm702d71n2421cxamq68-make-symlinks-relative.sh" [12]="/nix/store/cl3qd985p1yxyfkj96v0hqxiy3w69xq5-compress-man-pages.sh" [13]="/nix/store/h54dzwd7rdh2jlcv91424csl6d0ccgjy-strip.sh" [14]="/nix/store/bnj8d7mvbkg3vdb07yz74yhl3g107qq5-patch-shebangs.sh" [15]="/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh" [16]="/nix/store/8zxndz5ag0p6s526c2xyllhk1nrn4c3i-audit-tmpdir.sh" [17]="/nix/store/c8n9kcdddp9np665xz6ri61b383nxvz8-move-systemd-user-units.sh" [18]="/nix/store/1i5y55x4b4m9qkx5dqbmr1r6bvrqbanw-multiple-outputs.sh" [19]="/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh" [20]="/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh" [21]="/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh" [22]="/nix/store/pr6nzbscdpg94yvr151lrif2kg0csx7b-reproducible-builds.sh" [23]="/nix/store/i9a3zzf2spmw67jppvkj2yavnbka62id-gcc-wrapper-10.2.0" [24]="/nix/store/f4w8p656gg6v2k1v0whwmyk09kz3k8ic-binutils-wrapper-2.35.1") | 144 | pkgsBuildHost=([0]="/nix/store/58syiz9158g5s53gjh8f5b89bhhp1m0s-rust-1.53.0-nightly-2021-03-30-74874a690" [1]="/nix/store/m0k4il8v2wv0c7nniqndcxh72qmzvvg2-rust-src-1.53.0-nightly-2021-03-30-74874a690" [2]="/nix/store/pj3m562kh9lr7wjk3hlyandhd1qpapgh-rust-analyzer-unstable-2021-02-22" [3]="/nix/store/rfx0jz6pr3n2dcxm99finhbp99v45qx4-rustfmt-1.49.0" [4]="/nix/store/9p0yf4yzsc8by6xviags56c3mb3fxkkw-cargo-1.49.0" [5]="/nix/store/d7lyvmvzf1a8qqhsxhdc3r6dwbdmfcap-patchelf-0.12" [6]="/nix/store/mjjy30kxz775bhhi6j9phw81qh6dsbrf-move-docs.sh" [7]="/nix/store/kxw6q8v6isaqjm702d71n2421cxamq68-make-symlinks-relative.sh" [8]="/nix/store/cl3qd985p1yxyfkj96v0hqxiy3w69xq5-compress-man-pages.sh" [9]="/nix/store/h54dzwd7rdh2jlcv91424csl6d0ccgjy-strip.sh" [10]="/nix/store/bnj8d7mvbkg3vdb07yz74yhl3g107qq5-patch-shebangs.sh" [11]="/nix/store/cickvswrvann041nqxb0rxilc46svw1n-prune-libtool-files.sh" [12]="/nix/store/8zxndz5ag0p6s526c2xyllhk1nrn4c3i-audit-tmpdir.sh" [13]="/nix/store/c8n9kcdddp9np665xz6ri61b383nxvz8-move-systemd-user-units.sh" [14]="/nix/store/1i5y55x4b4m9qkx5dqbmr1r6bvrqbanw-multiple-outputs.sh" [15]="/nix/store/kd4xwxjpjxi71jkm6ka0np72if9rm3y0-move-sbin.sh" [16]="/nix/store/fyaryjvghbkpfnsyw97hb3lyb37s1pd6-move-lib64.sh" [17]="/nix/store/ngg1cv31c8c7bcm2n8ww4g06nq7s4zhm-set-source-date-epoch-to-latest.sh" [18]="/nix/store/pr6nzbscdpg94yvr151lrif2kg0csx7b-reproducible-builds.sh" [19]="/nix/store/i9a3zzf2spmw67jppvkj2yavnbka62id-gcc-wrapper-10.2.0" [20]="/nix/store/f4w8p656gg6v2k1v0whwmyk09kz3k8ic-binutils-wrapper-2.35.1") |
141 | postFixupHooks=([0]="_multioutPropagateDev") | 145 | postFixupHooks=([0]="_multioutPropagateDev") |
142 | postUnpackHooks=([0]="_updateSourceDateEpochFromSourceRoot") | 146 | postUnpackHooks=([0]="_updateSourceDateEpochFromSourceRoot") |
143 | preConfigureHooks=([0]="_multioutConfig") | 147 | preConfigureHooks=([0]="_multioutConfig") |
@@ -1496,7 +1500,7 @@ updateSourceDateEpoch () | |||
1496 | fi | 1500 | fi |
1497 | } | 1501 | } |
1498 | 1502 | ||
1499 | export NIX_BUILD_TOP="$(mktemp -d --tmpdir nix-shell.XXXXXX)" | 1503 | export NIX_BUILD_TOP="$(mktemp -d -t nix-shell.XXXXXX)" |
1500 | export TMP="$NIX_BUILD_TOP" | 1504 | export TMP="$NIX_BUILD_TOP" |
1501 | export TMPDIR="$NIX_BUILD_TOP" | 1505 | export TMPDIR="$NIX_BUILD_TOP" |
1502 | export TEMP="$NIX_BUILD_TOP" | 1506 | export TEMP="$NIX_BUILD_TOP" |
diff --git a/src/decode.rs b/src/decode.rs index a9abd37..9c6a065 100644 --- a/src/decode.rs +++ b/src/decode.rs | |||
@@ -4,7 +4,7 @@ use bitvec::prelude::*; | |||
4 | use byteorder::{LittleEndian, ReadBytesExt}; | 4 | use byteorder::{LittleEndian, ReadBytesExt}; |
5 | 5 | ||
6 | use crate::error::{OBIError, OBIResult}; | 6 | use crate::error::{OBIError, OBIResult}; |
7 | use crate::{FileHeader, Image, ImageInfoHeader}; | 7 | use crate::{CompressionType, FileHeader, Image, ImageInfoHeader}; |
8 | 8 | ||
9 | pub fn decode_image(obi_data: &mut Cursor<Vec<u8>>) -> OBIResult<Image> { | 9 | pub fn decode_image(obi_data: &mut Cursor<Vec<u8>>) -> OBIResult<Image> { |
10 | // file header | 10 | // file header |
@@ -43,22 +43,59 @@ pub fn decode_image(obi_data: &mut Cursor<Vec<u8>>) -> OBIResult<Image> { | |||
43 | post_compression_size, | 43 | post_compression_size, |
44 | }; | 44 | }; |
45 | 45 | ||
46 | // pixmap data | 46 | let data: Vec<bool> = match CompressionType::from_u32(compression_type) { |
47 | let mut data_bytes = vec![]; | 47 | CompressionType::RLE => { |
48 | obi_data | 48 | let mut rest = vec![]; |
49 | .read_to_end(&mut data_bytes) | 49 | let mut lengths = vec![]; |
50 | .map_err(|_| OBIError::Decode)?; | 50 | loop { |
51 | let data = data_bytes | 51 | let l = obi_data |
52 | .iter() | 52 | .read_u32::<LittleEndian>() |
53 | .map(|&b| { | 53 | .map_err(|_| OBIError::Encode)?; |
54 | BitVec::<Lsb0, u8>::from_element(b) | 54 | if l == 0 { |
55 | .into_iter() | 55 | break; |
56 | .map(|e| e as bool) | 56 | } |
57 | .collect::<Vec<bool>>() | 57 | lengths.push(l); |
58 | }) | 58 | } |
59 | .flatten() | 59 | obi_data |
60 | .collect::<Vec<_>>(); | 60 | .read_to_end(&mut rest) |
61 | .map_err(|_| OBIError::Decode)?; | ||
62 | let data_points = rest | ||
63 | .iter() | ||
64 | .map(|&b| { | ||
65 | BitVec::<Lsb0, u8>::from_element(b) | ||
66 | .into_iter() | ||
67 | .map(|e| e as bool) | ||
68 | .collect::<Vec<bool>>() | ||
69 | }) | ||
70 | .flatten() | ||
71 | .collect::<Vec<bool>>(); | ||
61 | 72 | ||
73 | let data = data_points | ||
74 | .into_iter() | ||
75 | .zip(lengths) | ||
76 | .map(|(d, l)| vec![d; l as usize]) | ||
77 | .flatten() | ||
78 | .collect::<Vec<bool>>(); | ||
79 | data | ||
80 | } | ||
81 | _ => { | ||
82 | let mut rest = vec![]; | ||
83 | obi_data | ||
84 | .read_to_end(&mut rest) | ||
85 | .map_err(|_| OBIError::Decode)?; | ||
86 | let data_points = rest | ||
87 | .iter() | ||
88 | .map(|&b| { | ||
89 | BitVec::<Lsb0, u8>::from_element(b) | ||
90 | .into_iter() | ||
91 | .map(|e| e as bool) | ||
92 | .collect::<Vec<bool>>() | ||
93 | }) | ||
94 | .flatten() | ||
95 | .collect::<Vec<_>>(); | ||
96 | data_points | ||
97 | } | ||
98 | }; | ||
62 | return Ok(Image { | 99 | return Ok(Image { |
63 | file_header, | 100 | file_header, |
64 | image_info_header, | 101 | image_info_header, |
diff --git a/src/encode.rs b/src/encode.rs index a8c58e0..30edc49 100644 --- a/src/encode.rs +++ b/src/encode.rs | |||
@@ -3,8 +3,11 @@ use std::borrow::Borrow; | |||
3 | use bitvec::{prelude::*, vec::BitVec}; | 3 | use bitvec::{prelude::*, vec::BitVec}; |
4 | use byteorder::{LittleEndian, WriteBytesExt}; | 4 | use byteorder::{LittleEndian, WriteBytesExt}; |
5 | 5 | ||
6 | use crate::error::{OBIError, OBIResult}; | 6 | use crate::{ |
7 | use crate::Image; | 7 | error::{OBIError, OBIResult}, |
8 | rle::RLE, | ||
9 | CompressionType, Image, | ||
10 | }; | ||
8 | 11 | ||
9 | pub fn encode_image<I>(obi_image: I) -> OBIResult<Vec<u8>> | 12 | pub fn encode_image<I>(obi_image: I) -> OBIResult<Vec<u8>> |
10 | where | 13 | where |
@@ -40,17 +43,38 @@ where | |||
40 | .write_u32::<LittleEndian>(image_info_header.post_compression_size) | 43 | .write_u32::<LittleEndian>(image_info_header.post_compression_size) |
41 | .map_err(|_| OBIError::Encode)?; | 44 | .map_err(|_| OBIError::Encode)?; |
42 | 45 | ||
46 | let write_pixel_data = |pixels: &Vec<bool>, obi_data: &mut Vec<u8>| -> OBIResult<()> { | ||
47 | for byte in pixels.chunks(8) { | ||
48 | let mut bv = BitVec::<Lsb0, u8>::new(); | ||
49 | for &b in byte { | ||
50 | bv.push(b) | ||
51 | } | ||
52 | obi_data | ||
53 | .write_u8(bv.load::<u8>()) | ||
54 | .map_err(|_| OBIError::Encode)?; | ||
55 | } | ||
56 | Ok(()) | ||
57 | }; | ||
58 | |||
43 | // pixmap data | 59 | // pixmap data |
44 | let pixmap = &obi_image.data; | 60 | let pixmap = &obi_image.data; |
45 | for byte in pixmap.chunks(8) { | 61 | match CompressionType::from_u32(obi_image.image_info_header.compression_type) { |
46 | let mut bv = BitVec::<Lsb0, u8>::new(); | 62 | CompressionType::RLE => { |
47 | for &b in byte { | 63 | let (data_points, lengths): (Vec<_>, Vec<_>) = pixmap.compress().into_iter().unzip(); |
48 | bv.push(b); | 64 | for l in lengths { |
65 | obi_data | ||
66 | .write_u32::<LittleEndian>(l as u32) | ||
67 | .map_err(|_| OBIError::Encode)?; | ||
68 | } | ||
69 | // end length sequence with zero | ||
70 | obi_data | ||
71 | .write_u32::<LittleEndian>(0) | ||
72 | .map_err(|_| OBIError::Encode)?; | ||
73 | // begin data point sequence | ||
74 | write_pixel_data(&data_points, &mut obi_data)?; | ||
49 | } | 75 | } |
50 | obi_data | 76 | _ => write_pixel_data(pixmap, &mut obi_data)?, |
51 | .write_u8(bv.load::<u8>()) | 77 | }; |
52 | .map_err(|_| OBIError::Encode)?; | ||
53 | } | ||
54 | 78 | ||
55 | return Ok(obi_data); | 79 | return Ok(obi_data); |
56 | } | 80 | } |
@@ -7,8 +7,10 @@ use std::io; | |||
7 | mod decode; | 7 | mod decode; |
8 | mod encode; | 8 | mod encode; |
9 | pub mod error; | 9 | pub mod error; |
10 | mod rle; | ||
10 | 11 | ||
11 | use crate::error::{OBIError, OBIResult}; | 12 | use error::{OBIError, OBIResult}; |
13 | use rle::RLE; | ||
12 | 14 | ||
13 | #[non_exhaustive] | 15 | #[non_exhaustive] |
14 | #[derive(Copy, Clone, Debug, PartialEq)] | 16 | #[derive(Copy, Clone, Debug, PartialEq)] |
@@ -83,6 +85,14 @@ impl CompressionType { | |||
83 | _ => panic!("Invalid compression algorithm"), | 85 | _ => panic!("Invalid compression algorithm"), |
84 | } | 86 | } |
85 | } | 87 | } |
88 | pub fn to_u32(self) -> u32 { | ||
89 | match self { | ||
90 | CompressionType::None => 0, | ||
91 | CompressionType::RLE => 1, | ||
92 | CompressionType::Kosinki => 10, | ||
93 | _ => panic!("Invalid compression algorithm"), | ||
94 | } | ||
95 | } | ||
86 | } | 96 | } |
87 | 97 | ||
88 | #[derive(Debug)] | 98 | #[derive(Debug)] |
@@ -111,6 +121,10 @@ impl Image { | |||
111 | } | 121 | } |
112 | } | 122 | } |
113 | 123 | ||
124 | pub fn use_compression(&mut self, comp: CompressionType) { | ||
125 | self.image_info_header.compression_type = comp.to_u32(); | ||
126 | } | ||
127 | |||
114 | pub fn width(&self) -> u32 { | 128 | pub fn width(&self) -> u32 { |
115 | self.image_info_header.width | 129 | self.image_info_header.width |
116 | } | 130 | } |
diff --git a/src/rle.rs b/src/rle.rs new file mode 100644 index 0000000..f6d1e05 --- /dev/null +++ b/src/rle.rs | |||
@@ -0,0 +1,89 @@ | |||
1 | pub trait RLE { | ||
2 | type Data; | ||
3 | fn compress(&self) -> Vec<Run<Self::Data>>; | ||
4 | fn decompress(runs: Vec<Run<Self::Data>>) -> Vec<Self::Data>; | ||
5 | } | ||
6 | |||
7 | pub type Run<T> = (T, usize); | ||
8 | |||
9 | impl<T> RLE for Vec<T> | ||
10 | where | ||
11 | T: Clone + PartialEq, | ||
12 | { | ||
13 | type Data = T; | ||
14 | fn compress(&self) -> Vec<Run<Self::Data>> { | ||
15 | let mut runs = vec![]; | ||
16 | if self.is_empty() { | ||
17 | return runs; | ||
18 | } | ||
19 | let mut idx = 0; | ||
20 | loop { | ||
21 | let first = &self[idx]; | ||
22 | let run_length = self[idx..].iter().take_while(|&item| item == first).count(); | ||
23 | |||
24 | runs.push((first.clone(), run_length)); | ||
25 | |||
26 | idx += run_length; | ||
27 | if idx > self.len() - 1 { | ||
28 | break; | ||
29 | } | ||
30 | } | ||
31 | runs | ||
32 | } | ||
33 | fn decompress(runs: Vec<Run<Self::Data>>) -> Vec<Self::Data> { | ||
34 | runs.into_iter() | ||
35 | .map(|(item, size)| vec![item; size]) | ||
36 | .flatten() | ||
37 | .collect() | ||
38 | } | ||
39 | } | ||
40 | |||
41 | #[cfg(test)] | ||
42 | mod tests { | ||
43 | use super::*; | ||
44 | #[test] | ||
45 | fn singleton() { | ||
46 | let data = "a".chars().collect::<Vec<_>>(); | ||
47 | assert_eq!(Vec::<char>::compress(&data), vec![('a', 1),]); | ||
48 | } | ||
49 | #[test] | ||
50 | fn identity() { | ||
51 | let data = "aabbccddaabbaa".chars().collect::<Vec<_>>(); | ||
52 | assert_eq!(Vec::<char>::decompress(data.compress()), data); | ||
53 | } | ||
54 | #[test] | ||
55 | fn repeated_singleton() { | ||
56 | let data = "aaaaaaaaaaaaa".chars().collect::<Vec<_>>(); | ||
57 | assert_eq!(Vec::<char>::compress(&data), vec![('a', 13),]); | ||
58 | } | ||
59 | #[test] | ||
60 | fn empty_runs() { | ||
61 | let data = "".chars().collect::<Vec<_>>(); | ||
62 | assert!(data.compress().is_empty()); | ||
63 | } | ||
64 | #[test] | ||
65 | fn empty_decompress() { | ||
66 | assert!(Vec::<char>::decompress(vec![]).is_empty()); | ||
67 | } | ||
68 | #[test] | ||
69 | fn check_runs1() { | ||
70 | let data = "aaaabbbbcccc".chars().collect::<Vec<_>>(); | ||
71 | assert_eq!(data.compress(), vec![('a', 4), ('b', 4), ('c', 4)]); | ||
72 | } | ||
73 | #[test] | ||
74 | fn check_runs2() { | ||
75 | let data = "aabbccddaabbaa".chars().collect::<Vec<_>>(); | ||
76 | assert_eq!( | ||
77 | data.compress(), | ||
78 | vec![ | ||
79 | ('a', 2), | ||
80 | ('b', 2), | ||
81 | ('c', 2), | ||
82 | ('d', 2), | ||
83 | ('a', 2), | ||
84 | ('b', 2), | ||
85 | ('a', 2) | ||
86 | ] | ||
87 | ); | ||
88 | } | ||
89 | } | ||
diff --git a/tests/serde.rs b/tests/serde.rs index 295b8d0..3701707 100644 --- a/tests/serde.rs +++ b/tests/serde.rs | |||
@@ -11,13 +11,14 @@ fn size_of_image_info_header() { | |||
11 | 11 | ||
12 | #[test] | 12 | #[test] |
13 | fn compression() { | 13 | fn compression() { |
14 | let img = Image::new(50, 5); | 14 | let mut img = Image::new(50, 5); |
15 | img.use_compression(CompressionType::RLE); | ||
15 | let encoded = img.encode().unwrap(); | 16 | let encoded = img.encode().unwrap(); |
16 | let mut cursor = Cursor::new(encoded); | 17 | let mut cursor = Cursor::new(encoded); |
17 | let decoded = Image::decode(&mut cursor).unwrap(); | 18 | let decoded = Image::decode(&mut cursor).unwrap(); |
18 | assert_eq!( | 19 | assert_eq!( |
19 | CompressionType::from_u32(decoded.image_info_header.compression_type), | 20 | CompressionType::from_u32(decoded.image_info_header.compression_type), |
20 | CompressionType::None | 21 | CompressionType::RLE |
21 | ); | 22 | ); |
22 | } | 23 | } |
23 | 24 | ||
@@ -42,3 +43,20 @@ fn size_round_nearest() { | |||
42 | assert_eq!(decoded.image_info_header.width, 50); | 43 | assert_eq!(decoded.image_info_header.width, 50); |
43 | assert_eq!(decoded.image_info_header.height, 5); | 44 | assert_eq!(decoded.image_info_header.height, 5); |
44 | } | 45 | } |
46 | |||
47 | #[test] | ||
48 | fn size_compressed() { | ||
49 | let mut img = Image::new(100, 80); | ||
50 | img.use_compression(CompressionType::RLE); | ||
51 | let encoded = img.encode().unwrap(); | ||
52 | // 26 - headers | ||
53 | // 4 - first and only length | ||
54 | // 4 - separator zero | ||
55 | // 1 - first and only data point | ||
56 | assert_eq!(encoded.len(), 26 + 4 + 4 + 1); | ||
57 | let mut cursor = Cursor::new(encoded); | ||
58 | let decoded = Image::decode(&mut cursor).unwrap(); | ||
59 | assert_eq!(decoded.image_info_header.width, 100); | ||
60 | assert_eq!(decoded.image_info_header.height, 80); | ||
61 | assert!(decoded.data.iter().all(|x| !*x)); | ||
62 | } | ||