From d150bbcc5a4f9a92606b2bc70e9ca8b3f87f078e Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 24 May 2020 21:43:46 +0800 Subject: [PATCH] add wasm qr decode --- deno_wasm_qr/decodeqr/Cargo.lock | 517 ++++++++++++++++++++++++ deno_wasm_qr/decodeqr/Cargo.toml | 18 + deno_wasm_qr/decodeqr/build.sh | 1 + deno_wasm_qr/decodeqr/src/lib.rs | 25 ++ deno_wasm_qr/decodeqr/src/sample_qr.png | Bin 0 -> 5944 bytes deno_wasm_qr/parse_qr.ts | 14 + 6 files changed, 575 insertions(+) create mode 100644 deno_wasm_qr/decodeqr/Cargo.lock create mode 100644 deno_wasm_qr/decodeqr/Cargo.toml create mode 100644 deno_wasm_qr/decodeqr/build.sh create mode 100644 deno_wasm_qr/decodeqr/src/lib.rs create mode 100644 deno_wasm_qr/decodeqr/src/sample_qr.png create mode 100644 deno_wasm_qr/parse_qr.ts diff --git a/deno_wasm_qr/decodeqr/Cargo.lock b/deno_wasm_qr/decodeqr/Cargo.lock new file mode 100644 index 0000000..cd75747 --- /dev/null +++ b/deno_wasm_qr/decodeqr/Cargo.lock @@ -0,0 +1,517 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "addr2line" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a49806b9dadc843c61e7c97e72490ad7f7220ae249012fbda9ad0609457c0543" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler32" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5d2e7343e7fc9de883d1b0341e0b13970f764c14101234857d2ddafa1cb1cac2" + +[[package]] +name = "autocfg" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8aac770f1885fd7e387acedd76065302551364496e46b3dd00860b2f8359b9d" + +[[package]] +name = "backtrace" +version = "0.3.48" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0df2f85c8a2abbe3b7d7e748052fdd9b76a0458fdeb16ad4223f5eca78c7c130" +dependencies = [ + "addr2line", + "cfg-if", + "libc", + "object", + "rustc-demangle", +] + +[[package]] +name = "bardecoder" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c89ae2e2ca1c95717eea500a89d26d69ff9298e97c6c61be9a61f8a0119dcfa" +dependencies = [ + "failure", + "failure_derive", + "image", + "log", + "newtype_derive", +] + +[[package]] +name = "bitflags" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" + +[[package]] +name = "byteorder" +version = "1.3.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" + +[[package]] +name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "color_quant" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0dbbb57365263e881e805dc77d94697c9118fd94d8da011240555aa7b23445bd" + +[[package]] +name = "crc32fast" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba125de2af0df55319f41944744ad91c71113bf74a4646efff39afe1f6842db1" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "crossbeam-deque" +version = "0.7.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9f02af974daeee82218205558e51ec8768b48cf524bd01d550abe5573a608285" +dependencies = [ + "crossbeam-epoch", + "crossbeam-utils", + "maybe-uninit", +] + +[[package]] +name = "crossbeam-epoch" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "058ed274caafc1f60c4997b5fc07bf7dc7cca454af7c6e81edffe5f33f70dace" +dependencies = [ + "autocfg", + "cfg-if", + "crossbeam-utils", + "lazy_static", + "maybe-uninit", + "memoffset", + "scopeguard", +] + +[[package]] +name = "crossbeam-queue" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c695eeca1e7173472a32221542ae469b3e9aac3a4fc81f7696bcad82029493db" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + +[[package]] +name = "crossbeam-utils" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" +dependencies = [ + "autocfg", + "cfg-if", + "lazy_static", +] + +[[package]] +name = "decodeqr" +version = "0.1.0" +dependencies = [ + "bardecoder", + "image", +] + +[[package]] +name = "deflate" +version = "0.7.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "707b6a7b384888a70c8d2e8650b3e60170dfc6a67bb4aa67b6dfca57af4bedb4" +dependencies = [ + "adler32", + "byteorder", +] + +[[package]] +name = "either" +version = "1.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb1f6b1ce1c140482ea30ddd3335fc0024ac7ee112895426e0a629a6c20adfe3" + +[[package]] +name = "failure" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86" +dependencies = [ + "backtrace", + "failure_derive", +] + +[[package]] +name = "failure_derive" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4" +dependencies = [ + "proc-macro2 1.0.17", + "quote 1.0.6", + "syn 1.0.23", + "synstructure", +] + +[[package]] +name = "gif" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "471d90201b3b223f3451cd4ad53e34295f16a1df17b1edf3736d47761c3981af" +dependencies = [ + "color_quant", + "lzw", +] + +[[package]] +name = "gimli" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bcc8e0c9bce37868955864dbecd2b1ab2bdf967e6f28066d65aaac620444b65c" + +[[package]] +name = "hermit-abi" +version = "0.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "91780f809e750b0a89f5544be56617ff6b1227ee485bcb06ebe10cdf89bd3b71" +dependencies = [ + "libc", +] + +[[package]] +name = "image" +version = "0.22.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08ed2ada878397b045454ac7cfb011d73132c59f31a955d230bd1f1c2e68eb4a" +dependencies = [ + "byteorder", + "gif", + "jpeg-decoder", + "num-iter", + "num-rational", + "num-traits", + "png", + "scoped_threadpool", + "tiff", +] + +[[package]] +name = "inflate" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1cdb29978cc5797bd8dcc8e5bf7de604891df2a8dc576973d71a281e916db2ff" +dependencies = [ + "adler32", +] + +[[package]] +name = "jpeg-decoder" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5b47b4c4e017b01abdc5bcc126d2d1002e5a75bbe3ce73f9f4f311a916363704" +dependencies = [ + "byteorder", + "rayon", +] + +[[package]] +name = "lazy_static" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" + +[[package]] +name = "libc" +version = "0.2.70" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3baa92041a6fec78c687fa0cc2b3fae8884f743d672cf551bed1d6dac6988d0f" + +[[package]] +name = "log" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" +dependencies = [ + "cfg-if", +] + +[[package]] +name = "lzw" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d947cbb889ed21c2a84be6ffbaebf5b4e0f4340638cba0444907e38b56be084" + +[[package]] +name = "maybe-uninit" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" + +[[package]] +name = "memoffset" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b4fc2c02a7e374099d4ee95a193111f72d2110197fe200272371758f6c3643d8" +dependencies = [ + "autocfg", +] + +[[package]] +name = "newtype_derive" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac8cd24d9f185bb7223958d8c1ff7a961b74b1953fd05dba7cc568a63b3861ec" +dependencies = [ + "rustc_version", +] + +[[package]] +name = "num-derive" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eafd0b45c5537c3ba526f79d3e75120036502bebacbb3f3220914067ce39dbf2" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "syn 0.15.44", +] + +[[package]] +name = "num-integer" +version = "0.1.42" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f6ea62e9d81a77cd3ee9a2a5b9b609447857f3d358704331e4ef39eb247fcba" +dependencies = [ + "autocfg", + "num-traits", +] + +[[package]] +name = "num-iter" +version = "0.1.40" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dfb0800a0291891dd9f4fe7bd9c19384f98f7fbe0cd0f39a2c6b88b9868bbc00" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-rational" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c000134b5dbf44adc5cb772486d335293351644b801551abe8f75c84cfa4aef" +dependencies = [ + "autocfg", + "num-integer", + "num-traits", +] + +[[package]] +name = "num-traits" +version = "0.2.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096" +dependencies = [ + "autocfg", +] + +[[package]] +name = "num_cpus" +version = "1.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3" +dependencies = [ + "hermit-abi", + "libc", +] + +[[package]] +name = "object" +version = "0.19.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cbca9424c482ee628fa549d9c812e2cd22f1180b9222c9200fdfa6eb31aecb2" + +[[package]] +name = "png" +version = "0.15.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef859a23054bbfee7811284275ae522f0434a3c8e7f4b74bd4a35ae7e1c4a283" +dependencies = [ + "bitflags", + "crc32fast", + "deflate", + "inflate", +] + +[[package]] +name = "proc-macro2" +version = "0.4.30" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759" +dependencies = [ + "unicode-xid 0.1.0", +] + +[[package]] +name = "proc-macro2" +version = "1.0.17" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1502d12e458c49a4c9cbff560d0fe0060c252bc29799ed94ca2ed4bb665a0101" +dependencies = [ + "unicode-xid 0.2.0", +] + +[[package]] +name = "quote" +version = "0.6.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" +dependencies = [ + "proc-macro2 0.4.30", +] + +[[package]] +name = "quote" +version = "1.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54a21852a652ad6f610c9510194f398ff6f8692e334fd1145fed931f7fbe44ea" +dependencies = [ + "proc-macro2 1.0.17", +] + +[[package]] +name = "rayon" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db6ce3297f9c85e16621bb8cca38a06779ffc31bb8184e1be4bed2be4678a098" +dependencies = [ + "crossbeam-deque", + "either", + "rayon-core", +] + +[[package]] +name = "rayon-core" +version = "1.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a89b46efaf957e52b18062fb2f4660f8b8a4dde1807ca002690868ef2c85a9" +dependencies = [ + "crossbeam-deque", + "crossbeam-queue", + "crossbeam-utils", + "lazy_static", + "num_cpus", +] + +[[package]] +name = "rustc-demangle" +version = "0.1.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783" + +[[package]] +name = "rustc_version" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c5f5376ea5e30ce23c03eb77cbe4962b988deead10910c372b226388b594c084" +dependencies = [ + "semver", +] + +[[package]] +name = "scoped_threadpool" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8" + +[[package]] +name = "scopeguard" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" + +[[package]] +name = "semver" +version = "0.1.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d4f410fedcf71af0345d7607d246e7ad15faaadd49d240ee3b24e5dc21a820ac" + +[[package]] +name = "syn" +version = "0.15.44" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" +dependencies = [ + "proc-macro2 0.4.30", + "quote 0.6.13", + "unicode-xid 0.1.0", +] + +[[package]] +name = "syn" +version = "1.0.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95b5f192649e48a5302a13f2feb224df883b98933222369e4b3b0fe2a5447269" +dependencies = [ + "proc-macro2 1.0.17", + "quote 1.0.6", + "unicode-xid 0.2.0", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +dependencies = [ + "proc-macro2 1.0.17", + "quote 1.0.6", + "syn 1.0.23", + "unicode-xid 0.2.0", +] + +[[package]] +name = "tiff" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d7b7c2cfc4742bd8a32f2e614339dd8ce30dbcf676bb262bd63a2327bc5df57d" +dependencies = [ + "byteorder", + "lzw", + "num-derive", + "num-traits", +] + +[[package]] +name = "unicode-xid" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc" + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" diff --git a/deno_wasm_qr/decodeqr/Cargo.toml b/deno_wasm_qr/decodeqr/Cargo.toml new file mode 100644 index 0000000..5c482ba --- /dev/null +++ b/deno_wasm_qr/decodeqr/Cargo.toml @@ -0,0 +1,18 @@ +[package] +name = "decodeqr" +version = "0.1.0" +authors = ["Hatter Jiang "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[lib] +crate-type =["cdylib"] + +[dependencies] +bardecoder = "0.2.2" +image = "0.22" + +[profile.release] +lto = true +#opt-level = 'z' diff --git a/deno_wasm_qr/decodeqr/build.sh b/deno_wasm_qr/decodeqr/build.sh new file mode 100644 index 0000000..b878198 --- /dev/null +++ b/deno_wasm_qr/decodeqr/build.sh @@ -0,0 +1 @@ +cargo build --target wasm32-unknown-unknown diff --git a/deno_wasm_qr/decodeqr/src/lib.rs b/deno_wasm_qr/decodeqr/src/lib.rs new file mode 100644 index 0000000..c4073e7 --- /dev/null +++ b/deno_wasm_qr/decodeqr/src/lib.rs @@ -0,0 +1,25 @@ +use std::ffi::CString; +use std::os::raw::c_char; + +pub const SAMPLE_QR_BYTES: &[u8] = std::include_bytes!("sample_qr.png"); + +#[no_mangle] +pub extern "C" fn parse_default_qr() -> *mut c_char { + let s = CString::new(parse_qr()).unwrap(); + s.into_raw() +} + +pub fn parse_qr() -> String { + let img = image::load_from_memory(SAMPLE_QR_BYTES).unwrap(); + + let decoder = bardecoder::default_decoder(); + + let mut ret = vec![]; + let results = decoder.decode(&img); + for result in results { + let qr = result.unwrap(); + println!("{}", qr); + ret.push(qr); + } + ret.join(",") +} diff --git a/deno_wasm_qr/decodeqr/src/sample_qr.png b/deno_wasm_qr/decodeqr/src/sample_qr.png new file mode 100644 index 0000000000000000000000000000000000000000..e89f932c9198c963d22617fc4821819f74f3c1d3 GIT binary patch literal 5944 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