Skip to content

Commit

Permalink
rust: add writer API
Browse files Browse the repository at this point in the history
  • Loading branch information
axxel committed Mar 13, 2024
1 parent 204f0cf commit 554309e
Show file tree
Hide file tree
Showing 10 changed files with 357 additions and 101 deletions.
4 changes: 3 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,12 @@ jobs:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
os: [ubuntu-latest, macos-13, windows-latest]

steps:
- uses: actions/checkout@v4
with:
submodules: true

- name: Lint
working-directory: wrappers/rust
Expand Down
4 changes: 2 additions & 2 deletions core/src/WriteBarcode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ struct CreatorOptions::Data

mutable std::unique_ptr<zint_symbol> zint;

#if __cplusplus <= 201703L
#if __cplusplus <= 201703L || defined(__APPLE__)
Data(BarcodeFormat f) : format(f) {}
#endif
};
Expand Down Expand Up @@ -283,7 +283,7 @@ struct SetCommonWriterOptions
zint->output_options |= opts.withQuietZones() ? BARCODE_QUIET_ZONES : BARCODE_NO_QUIET_ZONES;

if (opts.scale())
zint->scale = opts.scale();
zint->scale = opts.scale() / 2.f;
else if (opts.sizeHint()) {
int size = std::max(zint->width, zint->rows);
zint->scale = std::max(1, int(float(opts.sizeHint()) / size)) / 2.f;
Expand Down
5 changes: 2 additions & 3 deletions wrappers/rust/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "zxing-cpp"
version = "0.3.0"
version = "0.4.0"
edition = "2021"
# authors = ["Axel Waggershauser <[email protected]>"]
license = "Apache-2.0"
Expand All @@ -10,9 +10,8 @@ readme = "README.md"
keywords = ["zxing", "barcode", "barcode_reader", "ffi"]
categories = ["api-bindings", "computer-vision"]
exclude = [
"core/**/*Write*",
"core/**/*Writer*",
"core/**/*Encode*",
"core/src/libzint/**",
]

[lib]
Expand Down
30 changes: 19 additions & 11 deletions wrappers/rust/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,34 +15,42 @@ In your Cargo.toml:
# `bundled` causes cargo to compile and statically link an up to
# date version of the c++ core library. This is the most convenient
# and safe way to build the library.
zxing-cpp = { version = "0.3.0", features = ["bundled", "image"] }
zxing-cpp = { version = "0.4.0", features = ["bundled", "image"] }
```

Simple example usage:
Simple example reading some barcodes from a jpg file:

```rust
use zxingcpp::{BarcodeFormat, BarcodeReader, ImageView};
use zxingcpp::BarcodeFormat;

fn main() -> anyhow::Result<()> {
let image = image::open("some-image-file.jpg")?;
let reader = BarcodeReader::new()

let read_barcodes = zxingcpp::read()
.formats(BarcodeFormat::QRCode | BarcodeFormat::LinearCodes)
.try_invert(false);

let barcodes = reader.read(&image)?;
let barcodes = read_barcodes.from(&image)?;

if barcodes.is_empty() {
println!("No barcode found.");
} else {
for barcode in barcodes {
println!("{}: {}", barcode.format(), barcode.text());
}
for barcode in barcodes {
println!("{}: {}", barcode.format(), barcode.text());
}

Ok(())
}
```

Simple example creating a barcode and writing it to a svg file:
```rust
fn main() -> anyhow::Result<()> {
let svg = zxingcpp::create(zxingcpp::BarcodeFormat::QRCode)
.from_str("https://github.com/zxing-cpp/zxing-cpp")?
.to_svg_with(&zxingcpp::write().scale(5))?;
std::fs::write("zxingcpp.svg", svg)?;
Ok(())
}
```

Note: This should currently be considered a pre-release. The API may change slightly to be even more
"rusty" depending on community feedback.

Expand Down
4 changes: 3 additions & 1 deletion wrappers/rust/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,10 @@ fn main() -> miette::Result<()> {
let mut dst = cmake::Config::new("core")
.define("BUILD_SHARED_LIBS", "OFF")
.define("BUILD_READERS", "ON")
.define("BUILD_WRITERS", "OFF")
.define("BUILD_WRITERS", "NEW")
.define("BUILD_EXPERIMENTAL_API", "ON")
.define("BUILD_C_API", "ON")
.define("ZXING_USE_BUNDLED_ZINT", "ON")
.define("CMAKE_CXX_STANDARD", "20")
.build();
dst.push("lib");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ fn main() -> anyhow::Result<()> {
let iv = ImageView::from_slice(&lum_img, lum_img.width(), lum_img.height(), ImageFormat::Lum)?;

let formats = BarcodeFormats::from_str(formats.unwrap_or_default())?;
let reader = BarcodeReader::new()
let read_barcodes = BarcodeReader::new()
.formats(formats)
.try_harder(!fast)
.try_invert(!fast)
Expand All @@ -27,9 +27,9 @@ fn main() -> anyhow::Result<()> {
.return_errors(true);

#[cfg(feature = "image")]
let barcodes = reader.read(&image)?;
let barcodes = read_barcodes.from(&image)?;
#[cfg(not(feature = "image"))]
let barcodes = reader.read(iv)?;
let barcodes = read_barcodes.from(iv)?;

if barcodes.is_empty() {
println!("No barcode found.");
Expand Down
25 changes: 25 additions & 0 deletions wrappers/rust/examples/demo_writer.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/*
* Copyright 2024 Axel Waggershauser
*/
// SPDX-License-Identifier: Apache-2.0

use image;
use std::fs;
use zxingcpp::*;

fn main() -> anyhow::Result<()> {
let text = std::env::args().nth(1).expect("no input text provided");
let format = std::env::args().nth(2).expect("no format provided");
let filename = std::env::args().nth(3).expect("no output file name provided");

let create_barcode = create(BarcodeFormat::from_str(format)?);
let bc = create_barcode.from_str(text)?;

if filename.ends_with(".svg") {
fs::write(filename, bc.to_svg_with(&write().with_hrt(true))?).expect("Unable to write file");
} else {
image::GrayImage::from(&bc.to_image_with(&write().scale(4))?).save(filename)?;
}

Ok(())
}
44 changes: 44 additions & 0 deletions wrappers/rust/src/bindings.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ pub struct ZXing_Image {
pub struct ZXing_ReaderOptions {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ZXing_CreatorOptions {
_unused: [u8; 0],
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ZXing_WriterOptions {
_unused: [u8; 0],
}
pub const ZXing_ImageFormat_None: ZXing_ImageFormat = 0;
pub const ZXing_ImageFormat_Lum: ZXing_ImageFormat = 16777216;
pub const ZXing_ImageFormat_LumA: ZXing_ImageFormat = 33554432;
Expand Down Expand Up @@ -188,6 +198,40 @@ extern "C" {
pub fn ZXing_ReaderOptions_getMaxNumberOfSymbols(opts: *const ZXing_ReaderOptions) -> ::core::ffi::c_int;
pub fn ZXing_ReadBarcode(iv: *const ZXing_ImageView, opts: *const ZXing_ReaderOptions) -> *mut ZXing_Barcode;
pub fn ZXing_ReadBarcodes(iv: *const ZXing_ImageView, opts: *const ZXing_ReaderOptions) -> *mut ZXing_Barcodes;
pub fn ZXing_CreatorOptions_new(format: ZXing_BarcodeFormat) -> *mut ZXing_CreatorOptions;
pub fn ZXing_CreatorOptions_delete(opts: *mut ZXing_CreatorOptions);
pub fn ZXing_CreatorOptions_setFormat(opts: *mut ZXing_CreatorOptions, format: ZXing_BarcodeFormat);
pub fn ZXing_CreatorOptions_getFormat(opts: *const ZXing_CreatorOptions) -> ZXing_BarcodeFormat;
pub fn ZXing_CreatorOptions_setReaderInit(opts: *mut ZXing_CreatorOptions, readerInit: bool);
pub fn ZXing_CreatorOptions_getReaderInit(opts: *const ZXing_CreatorOptions) -> bool;
pub fn ZXing_CreatorOptions_setForceSquareDataMatrix(opts: *mut ZXing_CreatorOptions, forceSquareDataMatrix: bool);
pub fn ZXing_CreatorOptions_getForceSquareDataMatrix(opts: *const ZXing_CreatorOptions) -> bool;
pub fn ZXing_CreatorOptions_setEcLevel(opts: *mut ZXing_CreatorOptions, ecLevel: *const ::core::ffi::c_char);
pub fn ZXing_CreatorOptions_getEcLevel(opts: *const ZXing_CreatorOptions) -> *mut ::core::ffi::c_char;
pub fn ZXing_WriterOptions_new() -> *mut ZXing_WriterOptions;
pub fn ZXing_WriterOptions_delete(opts: *mut ZXing_WriterOptions);
pub fn ZXing_WriterOptions_setScale(opts: *mut ZXing_WriterOptions, scale: ::core::ffi::c_int);
pub fn ZXing_WriterOptions_getScale(opts: *const ZXing_WriterOptions) -> ::core::ffi::c_int;
pub fn ZXing_WriterOptions_setSizeHint(opts: *mut ZXing_WriterOptions, sizeHint: ::core::ffi::c_int);
pub fn ZXing_WriterOptions_getSizeHint(opts: *const ZXing_WriterOptions) -> ::core::ffi::c_int;
pub fn ZXing_WriterOptions_setRotate(opts: *mut ZXing_WriterOptions, rotate: ::core::ffi::c_int);
pub fn ZXing_WriterOptions_getRotate(opts: *const ZXing_WriterOptions) -> ::core::ffi::c_int;
pub fn ZXing_WriterOptions_setWithHRT(opts: *mut ZXing_WriterOptions, withHRT: bool);
pub fn ZXing_WriterOptions_getWithHRT(opts: *const ZXing_WriterOptions) -> bool;
pub fn ZXing_WriterOptions_setWithQuietZones(opts: *mut ZXing_WriterOptions, withQuietZones: bool);
pub fn ZXing_WriterOptions_getWithQuietZones(opts: *const ZXing_WriterOptions) -> bool;
pub fn ZXing_CreateBarcodeFromText(
data: *const ::core::ffi::c_char,
size: ::core::ffi::c_int,
opts: *const ZXing_CreatorOptions,
) -> *mut ZXing_Barcode;
pub fn ZXing_CreateBarcodeFromBytes(
data: *const ::core::ffi::c_void,
size: ::core::ffi::c_int,
opts: *const ZXing_CreatorOptions,
) -> *mut ZXing_Barcode;
pub fn ZXing_WriteBarcodeToSVG(barcode: *const ZXing_Barcode, opts: *const ZXing_WriterOptions) -> *mut ::core::ffi::c_char;
pub fn ZXing_WriteBarcodeToImage(barcode: *const ZXing_Barcode, opts: *const ZXing_WriterOptions) -> *mut ZXing_Image;
pub fn ZXing_LastErrorMsg() -> *mut ::core::ffi::c_char;
pub fn ZXing_free(ptr: *mut ::core::ffi::c_void);
}
Loading

0 comments on commit 554309e

Please sign in to comment.