Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions crates/core/src/ar/bch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ const BCH_127_INDEX_OF: [i32; 128] = [
// Public decoders for short codes (parity-65, hamming-63).
// =====================================================================

/// Decode a 3×3 parity(6,5) matrix code, returning the marker ID.
pub fn decode_parity65(code_raw: u64) -> Result<u64, &'static str> {
const PARITY65_DECODER_TABLE: [i8; 64] = [
0, -1, -1, 3, -1, 5, 6, -1, -1, 9, 10, -1, 12, -1, -1, 15, -1, 17, 18, -1, 20, -1, -1, 23,
Expand All @@ -106,6 +107,7 @@ pub fn decode_parity65(code_raw: u64) -> Result<u64, &'static str> {
}
}

/// Decode a 3×3 Hamming(6,3) matrix code, returning the ID and corrected-error count.
pub fn decode_hamming63(code_raw: u64) -> Result<(u64, i32), &'static str> {
const HAMMING63_DECODER_TABLE: [i8; 64] = [
0, 0, 0, 1, 0, 1, 1, 1, 0, 2, 4, -1, -1, 5, 3, 1, 0, 2, -1, 6, 7, -1, 3, 1, 2, 2, 3, 2, 3,
Expand Down
3 changes: 3 additions & 0 deletions crates/core/src/ar/image_proc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ impl ARImageProcInfo {
}
}

/// Scalar horizontal box-blur pass over a grayscale image.
pub fn box_filter_h_scalar(
data: &[u8],
image_temp_u16: &mut [u16],
Expand All @@ -340,6 +341,7 @@ pub fn box_filter_h_scalar(
}
}

/// Scalar vertical box-blur pass over a grayscale image.
pub fn box_filter_v_scalar(
image_temp_u16: &[u16],
image2: &mut [u8],
Expand Down Expand Up @@ -403,6 +405,7 @@ pub fn rgba_to_gray(rgba: &[u8]) -> Vec<u8> {
rgba_to_gray_scalar(rgba)
}

/// Scalar RGBA → grayscale (luminance) conversion.
pub fn rgba_to_gray_scalar(rgba: &[u8]) -> Vec<u8> {
let mut gray = Vec::with_capacity(rgba.len() / 4);
for chunk in rgba.chunks_exact(4) {
Expand Down
7 changes: 7 additions & 0 deletions crates/core/src/ar/labeling.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,24 @@ use crate::arlog_e;
use crate::types::{ARLabelInfo, ARdouble};
use log::trace;

/// Size of the labeling pass scratch work buffer.
pub const AR_LABELING_WORK_SIZE: usize = 1024 * 32;

#[derive(Debug, PartialEq, Clone, Copy)]
/// Which luminance polarity to trace during connected-component labeling.
pub enum LabelingMode {
/// Trace dark regions on a lighter background.
BlackRegion,
/// Trace light regions on a darker background.
WhiteRegion,
}

#[derive(Debug, PartialEq, Clone, Copy)]
/// Whether to process the full frame or a half-resolution field.
pub enum ImageProcMode {
/// Process the full-resolution frame.
FrameImage,
/// Process a single interlaced half-resolution field.
FieldImage, // Handles interlaced half-resolution fields
}

Expand Down
9 changes: 9 additions & 0 deletions crates/core/src/ar/marker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,16 +40,25 @@
use crate::types::{ARLabelInfo, ARMarkerInfo2, ARPixelFormat, ARdouble};
use crate::{arlog_d, arlog_e};

/// Maximum area in pixels for a candidate marker region.
pub const AR_AREA_MAX: i32 = 100000;
/// Minimum area in pixels for a candidate marker region.
pub const AR_AREA_MIN: i32 = 70;
/// Maximum line-fitting error for accepting a region as a square.
pub const AR_SQUARE_FIT_THRESH: f64 = 0.05;
/// Maximum contour chain length traced per region.
pub const AR_CHAIN_MAX: usize = 10000;
/// Maximum number of square candidates per frame.
pub const AR_SQUARE_MAX: usize = 30;
/// Default confidence threshold for accepting a pattern match.
pub const AR_CONFIDENCE_CUTOFF_DEFAULT: f64 = 0.5;

#[derive(Debug, PartialEq, Clone, Copy)]
/// Whether to process the full frame or a half-resolution field.
pub enum ImageProcMode {
/// Process the full-resolution frame.
FrameImage = 0,
/// Process a single interlaced half-resolution field.
FieldImage = 1,
}

Expand Down
16 changes: 16 additions & 0 deletions crates/core/src/ar/math.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ use std::ops::Mul;
#[repr(C)]
#[derive(Default)]
pub struct ARMat {
/// Row-major matrix elements.
pub m: Vec<ARdouble>,
/// Number of rows.
pub row: i32,
/// Number of columns.
pub clm: i32,
}

Expand Down Expand Up @@ -298,6 +301,7 @@ pub fn household(x: &mut [ARdouble]) -> ARdouble {
-s
}

/// QR decomposition of `a` in place, accumulating the diagonal into `dv`.
pub fn qrm(a: &mut ARMat, dv: &mut [ARdouble]) -> Result<(), &'static str> {
let dim = a.row as usize;
if dim != a.clm as usize || dim < 2 || dv.len() != dim {
Expand Down Expand Up @@ -397,6 +401,7 @@ pub fn qrm(a: &mut ARMat, dv: &mut [ARdouble]) -> Result<(), &'static str> {

impl ARMat {
#[allow(clippy::needless_range_loop)]
/// Compute the per-column mean vector of the matrix.
pub fn ex(&self, mean: &mut [ARdouble]) -> Result<(), &'static str> {
let row = self.row as usize;
let clm = self.clm as usize;
Expand All @@ -421,6 +426,7 @@ impl ARMat {
}

#[allow(clippy::needless_range_loop)]
/// Subtract `mean` from every row, centering the data in place.
pub fn center(&mut self, mean: &[ARdouble]) -> Result<(), &'static str> {
let row = self.row as usize;
let clm = self.clm as usize;
Expand All @@ -436,6 +442,7 @@ impl ARMat {
Ok(())
}

/// Compute `X · Xᵀ` into `output`.
pub fn x_by_xt(&self, output: &mut ARMat) -> Result<(), &'static str> {
let row = self.row as usize;
let clm = self.clm as usize;
Expand All @@ -459,6 +466,7 @@ impl ARMat {
Ok(())
}

/// Compute `Xᵀ · X` into `output`.
pub fn xt_by_x(&self, output: &mut ARMat) -> Result<(), &'static str> {
let row = self.row as usize;
let clm = self.clm as usize;
Expand All @@ -482,6 +490,7 @@ impl ARMat {
Ok(())
}

/// Compute the eigenvalues and eigenvectors of the (symmetric) matrix.
pub fn ev_create(
&self,
u: &ARMat,
Expand Down Expand Up @@ -527,6 +536,7 @@ impl ARMat {
Ok(())
}

/// Internal principal-component-analysis worker shared by the PCA entry points.
pub fn pca_internal(
&self,
output: &mut ARMat,
Expand Down Expand Up @@ -577,6 +587,7 @@ impl ARMat {
Ok(())
}

/// Compute the principal components of the data matrix.
pub fn pca(
&self,
evec: &mut ARMat,
Expand Down Expand Up @@ -653,8 +664,11 @@ impl<'b> Mul<&'b ARMat> for &ARMat {
#[repr(C)]
#[derive(Default)]
pub struct ARMatf {
/// Row-major matrix elements (single precision).
pub m: Vec<f32>,
/// Number of rows.
pub row: i32,
/// Number of columns.
pub clm: i32,
}

Expand Down Expand Up @@ -706,7 +720,9 @@ impl<'b> Mul<&'b ARMatf> for &ARMatf {
#[repr(C)]
#[derive(Default)]
pub struct ARVec {
/// Vector elements.
pub v: Vec<ARdouble>,
/// Number of columns.
pub clm: i32,
}

Expand Down
4 changes: 4 additions & 0 deletions crates/core/src/ar/matrix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,13 @@ pub(crate) const AR_GLOBAL_ID_INNER_SIZE: usize = 3;
/// Results of a matrix code decoding attempt.
#[derive(Debug, Clone, PartialEq)]
pub struct MatrixCodeResult {
/// Decoded marker ID.
pub id: i32,
/// Orientation (0–3) at which the code matched.
pub dir: i32,
/// Confidence factor of the match (0.0–1.0).
pub cf: f64,
/// Number of bit errors corrected during decoding.
pub error_corrected: i32,
}

Expand Down
8 changes: 8 additions & 0 deletions crates/core/src/ar/pattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,9 @@ use std::fs::File;
use std::io::{BufWriter, Error, ErrorKind, Result as IoResult, Write};
use std::path::Path;

/// Maximum number of patterns a handle can hold.
pub const AR_PATT_NUM_MAX: i32 = 50;
/// Default pattern edge size in samples.
pub const AR_PATT_SIZE1: i32 = 16;

// Standard sample factor used in ARToolKit for pattern extraction
Expand All @@ -53,8 +55,11 @@ const AR_PATT_SAMPLE_FACTOR1: usize = 4;
// Ensure these match your actual definitions in WebARKitLib-rs.
const AR_IMAGE_PROC_FRAME_IMAGE: i32 = 0;
const AR_IMAGE_PROC_FIELD_IMAGE: i32 = 1;
/// Template matching mode: colour.
pub const AR_TEMPLATE_MATCHING_COLOR: i32 = 0;
/// Template matching mode: mono (luminance).
pub const AR_TEMPLATE_MATCHING_MONO: i32 = 1;
/// Minimum contrast required to accept an extracted pattern.
pub const AR_PATT_CONTRAST_THRESH1: ARdouble = 5.0;

impl ARPattHandle {
Expand Down Expand Up @@ -507,6 +512,7 @@ pub fn pattern_match(
}

#[allow(clippy::needless_range_loop)]
/// Compute the 3×3 homography mapping the unit square to the marker's screen quad.
pub fn get_cpara(
world: &[[ARdouble; 2]; 4],
vertex: &[[ARdouble; 2]; 4],
Expand Down Expand Up @@ -1046,6 +1052,7 @@ pub fn ar_patt_get_image2(
Ok(())
}

/// Identify a square marker by matching its extracted pattern against loaded templates.
pub fn ar_patt_get_id(
patt_handle: &ARPattHandle,
patt_detect_mode: i32,
Expand Down Expand Up @@ -1077,6 +1084,7 @@ fn dot_product(a: &[i16], b: &[i16]) -> i64 {
dot_product_scalar(a, b)
}

/// Scalar dot product of two `i16` slices.
pub fn dot_product_scalar(a: &[i16], b: &[i16]) -> i64 {
let mut sum = 0i64;
for i in 0..a.len() {
Expand Down
5 changes: 5 additions & 0 deletions crates/core/src/ar/pose.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,13 +41,15 @@ use crate::icp::{
use crate::types::{AR3DHandle, ARMarkerInfo, ARParam, ARdouble};
// use log::debug; // Removed unused import

/// Allocate an `AR3DHandle` for pose estimation from the given camera parameters.
pub fn ar_3d_create_handle(ar_param: &ARParam) -> Result<*mut AR3DHandle, &'static str> {
let icp_handle = icp_create_handle(&ar_param.mat)?;
let mut handle = Box::new(AR3DHandle::default());
handle.icp_handle = icp_handle;
Ok(Box::into_raw(handle))
}

/// Free an `AR3DHandle` and null the pointer.
pub fn ar_3d_delete_handle(handle: &mut *mut AR3DHandle) -> Result<(), &'static str> {
if handle.is_null() {
return Err("Null AR3DHandle");
Expand All @@ -61,6 +63,7 @@ pub fn ar_3d_delete_handle(handle: &mut *mut AR3DHandle) -> Result<(), &'static
Ok(())
}

/// Estimate the 3×4 pose of a square marker of the given side length.
pub fn ar_get_trans_mat_square(
handle: &AR3DHandle,
marker_info: &ARMarkerInfo,
Expand Down Expand Up @@ -129,6 +132,7 @@ pub fn ar_get_trans_mat_square(
}
}

/// Estimate a square marker's pose using the previous frame's pose as a seed.
pub fn ar_get_trans_mat_square_cont(
handle: &AR3DHandle,
marker_info: &ARMarkerInfo,
Expand Down Expand Up @@ -186,6 +190,7 @@ pub fn ar_get_trans_mat_square_cont(
}
}

/// Estimate a 3×4 pose from 2D–3D correspondences via iterative refinement.
pub fn ar_get_trans_mat(
handle: &AR3DHandle,
init_conv: &[[ARdouble; 4]; 3],
Expand Down
8 changes: 8 additions & 0 deletions crates/core/src/arlog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -126,9 +126,13 @@
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(i32)]
pub enum ArLogLevel {
/// Debug level — per-frame rejections and trace detail.
Debug = 0,
/// Info level — one-shot informational events.
Info = 1,
/// Warn level — recoverable anomalies.
Warn = 2,
/// Error level — misconfiguration / wiring errors.
Error = 3,
/// Release-info: unconditional informational output with no `[level]` prefix.
/// Routed through target `"arlog::rel"`.
Expand Down Expand Up @@ -178,21 +182,25 @@ pub fn ar_log_level() -> ArLogLevel {
pub const AR_LOG_REL_TARGET: &str = "arlog::rel";

#[macro_export]
/// Log a debug-level message (per-frame trace detail).
macro_rules! arlog_d {
($($arg:tt)*) => { ::log::debug!($($arg)*); };
}

#[macro_export]
/// Log an info-level message (one-shot events).
macro_rules! arlog_i {
($($arg:tt)*) => { ::log::info!($($arg)*); };
}

#[macro_export]
/// Log a warning-level message (recoverable anomalies).
macro_rules! arlog_w {
($($arg:tt)*) => { ::log::warn!($($arg)*); };
}

#[macro_export]
/// Log an error-level message (misconfiguration / wiring errors).
macro_rules! arlog_e {
($($arg:tt)*) => { ::log::error!($($arg)*); };
}
Expand Down
6 changes: 6 additions & 0 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,12 @@
//! use webarkitlib_rs::marker::ar_detect_marker as ar_detect_marker_compat;
//! ```

// Every `pub` item in the crate is documented (#226). CI's
// `clippy -D warnings` escalates this lint, so a new undocumented public
// item fails the build. Bindgen-generated FFI bindings opt out locally with
// their own `#![allow(missing_docs)]` (see `kpm::kpm_ffi`).
#![warn(missing_docs)]

pub mod ar;
pub mod ar2;
pub mod arlog;
Expand Down
Loading
Loading