mirror of
https://github.com/starovoid/rxing.git
synced 2026-07-26 04:12:34 +00:00
detector builds but does not work
This commit is contained in:
@@ -29,12 +29,12 @@ impl BitMatrix {
|
|||||||
|
|
||||||
pub fn findBoundingBox(
|
pub fn findBoundingBox(
|
||||||
&self,
|
&self,
|
||||||
left: &mut u32,
|
left: u32,
|
||||||
top: &mut u32,
|
top: u32,
|
||||||
width: &mut u32,
|
width: u32,
|
||||||
height: &mut u32,
|
height: u32,
|
||||||
minSize: u32,
|
minSize: u32,
|
||||||
) -> bool {
|
) -> (bool, u32, u32, u32, u32) {
|
||||||
todo!()
|
todo!()
|
||||||
// let right;
|
// let right;
|
||||||
// let bottom;
|
// let bottom;
|
||||||
|
|||||||
@@ -177,7 +177,7 @@ pub trait BitMatrixCursorTrait {
|
|||||||
todo!()
|
todo!()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn readPatternFromBlack<T>(&self, maxWhitePrefix: i32, range: Option<u32>) -> Option<T> {
|
fn readPatternFromBlack<T>(&mut self, maxWhitePrefix: i32, range: Option<u32>) -> Option<T> {
|
||||||
let range = range.unwrap_or(0);
|
let range = range.unwrap_or(0);
|
||||||
if (maxWhitePrefix != 0
|
if (maxWhitePrefix != 0
|
||||||
&& self.isWhite()
|
&& self.isWhite()
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ pub mod edge_tracer;
|
|||||||
pub mod fast_edge_to_edge_counter;
|
pub mod fast_edge_to_edge_counter;
|
||||||
pub mod matrix;
|
pub mod matrix;
|
||||||
pub mod pattern;
|
pub mod pattern;
|
||||||
|
mod qr_formatinformation;
|
||||||
pub mod regression_line;
|
pub mod regression_line;
|
||||||
pub mod regression_line_trait;
|
pub mod regression_line_trait;
|
||||||
pub mod step_result;
|
pub mod step_result;
|
||||||
|
|||||||
22
src/common/cpp_essentials/qr_formatinformation.rs
Normal file
22
src/common/cpp_essentials/qr_formatinformation.rs
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
use crate::qrcode::decoder::FormatInformation;
|
||||||
|
|
||||||
|
impl FormatInformation {
|
||||||
|
pub fn DecodeMQR(formatInfoBits: u32) -> Self {
|
||||||
|
unimplemented!()
|
||||||
|
// // We don't use the additional masking (with 0x4445) to work around potentially non complying MicroQRCode encoders
|
||||||
|
// auto fi = FindBestFormatInfo(0, FORMAT_INFO_DECODE_LOOKUP_MICRO, {formatInfoBits, MirrorBits(formatInfoBits)});
|
||||||
|
|
||||||
|
// constexpr uint8_t BITS_TO_VERSION[] = {1, 2, 2, 3, 3, 4, 4, 4};
|
||||||
|
|
||||||
|
// // Bits 2/3/4 contain both error correction level and version, 0/1 contain mask.
|
||||||
|
// fi.ecLevel = ECLevelFromBits((fi.index >> 2) & 0x07, true);
|
||||||
|
// fi.dataMask = static_cast<uint8_t>(fi.index & 0x03);
|
||||||
|
// fi.microVersion = BITS_TO_VERSION[(fi.index >> 2) & 0x07];
|
||||||
|
// fi.isMirrored = fi.bitsIndex == 1;
|
||||||
|
|
||||||
|
// return fi;
|
||||||
|
}
|
||||||
|
pub fn isValid(&self) -> bool {
|
||||||
|
unimplemented!()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,7 +5,7 @@ use crate::{
|
|||||||
},
|
},
|
||||||
dimension, point_g, point_i,
|
dimension, point_g, point_i,
|
||||||
qrcode::{
|
qrcode::{
|
||||||
decoder::{Version, VersionRef},
|
decoder::{FormatInformation, Version, VersionRef},
|
||||||
detector::QRCodeDetectorResult,
|
detector::QRCodeDetectorResult,
|
||||||
},
|
},
|
||||||
Exceptions,
|
Exceptions,
|
||||||
@@ -757,26 +757,21 @@ pub fn DetectPureQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
|
|||||||
// SaveAsPBM(image, "weg.pbm");
|
// SaveAsPBM(image, "weg.pbm");
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
const MIN_MODULES: u32 = Version::DimensionOfVersion(1, false);
|
let MIN_MODULES: u32 = Version::DimensionOfVersion(1, false);
|
||||||
const MAX_MODULES: u32 = Version::DimensionOfVersion(40, false);
|
let MAX_MODULES: u32 = Version::DimensionOfVersion(40, false);
|
||||||
|
|
||||||
let left;
|
let (found, left, top, width, height) = image.findBoundingBox(0, 0, 0, 0, MIN_MODULES);
|
||||||
let top;
|
|
||||||
let width;
|
|
||||||
let height;
|
|
||||||
|
|
||||||
if (!image.findBoundingBox(left, top, width, height, MIN_MODULES)
|
if (!found || (width as i32 - height as i32).abs() > 1) {
|
||||||
|| (*width as i32 - *height as i32).abs() > 1)
|
|
||||||
{
|
|
||||||
return Err(Exceptions::NOT_FOUND);
|
return Err(Exceptions::NOT_FOUND);
|
||||||
}
|
}
|
||||||
let right = *left + *width - 1;
|
let right = left + width - 1;
|
||||||
let bottom = *top + *height - 1;
|
let bottom = top + height - 1;
|
||||||
|
|
||||||
let tl = point_i(*left, *top);
|
let tl = point_i(left, top);
|
||||||
let tr = point_i(right, *top);
|
let tr = point_i(right, top);
|
||||||
let bl = point_i(*left, bottom);
|
let bl = point_i(left, bottom);
|
||||||
let diagonal: Pattern;
|
let mut diagonal: Pattern = Vec::default();
|
||||||
// allow corners be moved one pixel inside to accommodate for possible aliasing artifacts
|
// allow corners be moved one pixel inside to accommodate for possible aliasing artifacts
|
||||||
for [p, d] in [
|
for [p, d] in [
|
||||||
[tl, point_i(1, 1)],
|
[tl, point_i(1, 1)],
|
||||||
@@ -785,10 +780,11 @@ pub fn DetectPureQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
|
|||||||
] {
|
] {
|
||||||
// for (auto [p, d] : {std::pair(tl, PointI{1, 1}), {tr, {-1, 1}}, {bl, {1, -1}}}) {
|
// for (auto [p, d] : {std::pair(tl, PointI{1, 1}), {tr, {-1, 1}}, {bl, {1, -1}}}) {
|
||||||
diagonal = EdgeTracer::new(image, p, d)
|
diagonal = EdgeTracer::new(image, p, d)
|
||||||
.readPatternFromBlack(1, Some(*width / 3 + 1))
|
.readPatternFromBlack(1, Some(width / 3 + 1))
|
||||||
.ok_or(Exceptions::NOT_FOUND)?;
|
.ok_or(Exceptions::NOT_FOUND)?;
|
||||||
// diagonal = BitMatrixCursorI(image, p, d).readPatternFromBlack<Pattern>(1, width / 3 + 1);
|
// diagonal = BitMatrixCursorI(image, p, d).readPatternFromBlack<Pattern>(1, width / 3 + 1);
|
||||||
let view = PatternView::new(&diagonal.into());
|
let diag_hld = diagonal.clone().into();
|
||||||
|
let view = PatternView::new(&diag_hld);
|
||||||
if (!(IsPattern(&view, &PATTERN, None, 0.0, 0.0, None) != 0.0)) {
|
if (!(IsPattern(&view, &PATTERN, None, 0.0, 0.0, None) != 0.0)) {
|
||||||
return Err(Exceptions::NOT_FOUND);
|
return Err(Exceptions::NOT_FOUND);
|
||||||
}
|
}
|
||||||
@@ -808,12 +804,12 @@ pub fn DetectPureQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
|
|||||||
)
|
)
|
||||||
.dim;
|
.dim;
|
||||||
|
|
||||||
let moduleSize: f32 = ((*width) as f32) / dimension as f32;
|
let moduleSize: f32 = ((width) as f32) / dimension as f32;
|
||||||
if (dimension < MIN_MODULES as i32
|
if (dimension < MIN_MODULES as i32
|
||||||
|| dimension > MAX_MODULES as i32
|
|| dimension > MAX_MODULES as i32
|
||||||
|| !image.is_in(point(
|
|| !image.is_in(point(
|
||||||
*left as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize as f32,
|
left as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize as f32,
|
||||||
*top as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize,
|
top as f32 + moduleSize / 2.0 + (dimension - 1) as f32 * moduleSize,
|
||||||
)))
|
)))
|
||||||
{
|
{
|
||||||
return Err(Exceptions::NOT_FOUND);
|
return Err(Exceptions::NOT_FOUND);
|
||||||
@@ -828,123 +824,197 @@ pub fn DetectPureQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
|
|||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
// Now just read off the bits (this is a crop + subsample)
|
// Now just read off the bits (this is a crop + subsample)
|
||||||
Ok(QRCodeDetectorResult {
|
Ok(QRCodeDetectorResult::new(
|
||||||
bit_source: image.Deflate(
|
image.Deflate(
|
||||||
dimension as u32,
|
dimension as u32,
|
||||||
dimension as u32,
|
dimension as u32,
|
||||||
*top as f32 + moduleSize / 2.0,
|
top as f32 + moduleSize / 2.0,
|
||||||
*left as f32 + moduleSize / 2.0,
|
left as f32 + moduleSize / 2.0,
|
||||||
moduleSize,
|
moduleSize,
|
||||||
)?,
|
)?,
|
||||||
result_points: vec![
|
vec![
|
||||||
point_i(*left, *top),
|
point_i(left, top),
|
||||||
point_i(right, *top),
|
point_i(right, top),
|
||||||
point_i(right, bottom),
|
point_i(right, bottom),
|
||||||
point_i(*left, bottom),
|
point_i(left, bottom),
|
||||||
],
|
],
|
||||||
})
|
))
|
||||||
|
|
||||||
// return {Deflate(image, dimension, dimension, top + moduleSize / 2, left + moduleSize / 2, moduleSize),
|
// return {Deflate(image, dimension, dimension, top + moduleSize / 2, left + moduleSize / 2, moduleSize),
|
||||||
// {{left, top}, {right, top}, {right, bottom}, {left, bottom}}};
|
// {{left, top}, {right, top}, {right, bottom}, {left, bottom}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn DetectPureMQR( image:&BitMatrix) -> Result<QRCodeDetectorResult>
|
pub fn DetectPureMQR(image: &BitMatrix) -> Result<QRCodeDetectorResult> {
|
||||||
{
|
type Pattern = [PatternType; 5];
|
||||||
using Pattern = std::array<PatternView::value_type, PATTERN.size()>;
|
|
||||||
|
|
||||||
constexpr int MIN_MODULES = Version::DimensionOfVersion(1, true);
|
let MIN_MODULES = Version::DimensionOfVersion(1, true);
|
||||||
constexpr int MAX_MODULES = Version::DimensionOfVersion(4, true);
|
let MAX_MODULES = Version::DimensionOfVersion(4, true);
|
||||||
|
|
||||||
int left, top, width, height;
|
let (found, left, top, width, height) = image.findBoundingBox(0, 0, 0, 0, MIN_MODULES);
|
||||||
if (!image.findBoundingBox(left, top, width, height, MIN_MODULES) || std::abs(width - height) > 1)
|
|
||||||
return {};
|
|
||||||
int right = left + width - 1;
|
|
||||||
int bottom = top + height - 1;
|
|
||||||
|
|
||||||
// allow corners be moved one pixel inside to accommodate for possible aliasing artifacts
|
// int left, top, width, height;
|
||||||
auto diagonal = BitMatrixCursorI(image, {left, top}, {1, 1}).readPatternFromBlack<Pattern>(1);
|
if (!found || (width as i32 - height as i32).abs() > 1) {
|
||||||
if (!IsPattern(diagonal, PATTERN))
|
return Err(Exceptions::NOT_FOUND);
|
||||||
return {};
|
}
|
||||||
|
let right = left + width - 1;
|
||||||
|
let bottom = top + height - 1;
|
||||||
|
|
||||||
auto fpWidth = Reduce(diagonal);
|
// allow corners be moved one pixel inside to accommodate for possible aliasing artifacts
|
||||||
float moduleSize = float(fpWidth) / 7;
|
let diagonal = EdgeTracer::new(&image, point_i(left, top), point_i(1, 1))
|
||||||
int dimension = narrow_cast<int>(std::lround(width / moduleSize));
|
.readPatternFromBlack(1, None)
|
||||||
|
.ok_or(Exceptions::ILLEGAL_STATE)?;
|
||||||
|
if (!(IsPattern(diagonal, &PATTERN, None, 0.0, 0.0, None) != 0.0)) {
|
||||||
|
return Err(Exceptions::NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
if (dimension < MIN_MODULES || dimension > MAX_MODULES ||
|
let fpWidth = (diagonal.into_iter().sum::<u16>());
|
||||||
!image.isIn(PointF{left + moduleSize / 2 + (dimension - 1) * moduleSize,
|
let moduleSize: f32 = (fpWidth as f32) / 7.0;
|
||||||
top + moduleSize / 2 + (dimension - 1) * moduleSize}))
|
let dimension = (width as f32 / moduleSize).floor() as u32;
|
||||||
return {};
|
|
||||||
|
|
||||||
// #ifdef PRINT_DEBUG
|
if (dimension < MIN_MODULES
|
||||||
// LogMatrix log;
|
|| dimension > MAX_MODULES
|
||||||
// LogMatrixWriter lmw(log, image, 5, "grid2.pnm");
|
|| !image.is_in(point(
|
||||||
// for (int y = 0; y < dimension; y++)
|
left as f32 + moduleSize as f32 / 2.0 + (dimension - 1) as f32 * moduleSize,
|
||||||
// for (int x = 0; x < dimension; x++)
|
top as f32 + moduleSize as f32 / 2.0 + (dimension - 1) as f32 * moduleSize,
|
||||||
// log(PointF(left + (x + .5f) * moduleSize, top + (y + .5f) * moduleSize));
|
)))
|
||||||
// #endif
|
{
|
||||||
|
return Err(Exceptions::NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
// Now just read off the bits (this is a crop + subsample)
|
// #ifdef PRINT_DEBUG
|
||||||
return {Deflate(image, dimension, dimension, top + moduleSize / 2, left + moduleSize / 2, moduleSize),
|
// LogMatrix log;
|
||||||
{{left, top}, {right, top}, {right, bottom}, {left, bottom}}};
|
// LogMatrixWriter lmw(log, image, 5, "grid2.pnm");
|
||||||
|
// for (int y = 0; y < dimension; y++)
|
||||||
|
// for (int x = 0; x < dimension; x++)
|
||||||
|
// log(PointF(left + (x + .5f) * moduleSize, top + (y + .5f) * moduleSize));
|
||||||
|
// #endif
|
||||||
|
|
||||||
|
// Now just read off the bits (this is a crop + subsample)
|
||||||
|
Ok(QRCodeDetectorResult::new(
|
||||||
|
image.Deflate(
|
||||||
|
dimension,
|
||||||
|
dimension,
|
||||||
|
top as f32 + moduleSize / 2.0,
|
||||||
|
left as f32 + moduleSize / 2.0,
|
||||||
|
moduleSize,
|
||||||
|
)?,
|
||||||
|
vec![
|
||||||
|
point_i(left, top),
|
||||||
|
point_i(right, top),
|
||||||
|
point_i(right, bottom),
|
||||||
|
point_i(left, bottom),
|
||||||
|
],
|
||||||
|
))
|
||||||
|
// return {Deflate(image, dimension, dimension, top + moduleSize / 2, left + moduleSize / 2, moduleSize),
|
||||||
|
// {{left, top}, {right, top}, {right, bottom}, {left, bottom}}};
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn SampleMQR( image:&BitMatrix, fp:ConcentricPattern) -> Result<QRCodeDetectorResult>
|
pub fn SampleMQR(image: &BitMatrix, fp: ConcentricPattern) -> Result<QRCodeDetectorResult> {
|
||||||
{
|
let Some(fpQuad) = FindConcentricPatternCorners(image, fp.p, fp.size, 2) else {
|
||||||
auto fpQuad = FindConcentricPatternCorners(image, fp, fp.size, 2);
|
return Err(Exceptions::NOT_FOUND);
|
||||||
if (!fpQuad)
|
};
|
||||||
return {};
|
|
||||||
|
|
||||||
auto srcQuad = Rectangle(7, 7, 0.5);
|
let srcQuad = Quadrilateral::rectangle(7, 7, Some(0.5));
|
||||||
|
|
||||||
// #if defined(_MSVC_LANG) // TODO: see MSVC issue https://developercommunity.visualstudio.com/t/constexpr-object-is-unable-to-be-used-as/10035065
|
// #if defined(_MSVC_LANG) // TODO: see MSVC issue https://developercommunity.visualstudio.com/t/constexpr-object-is-unable-to-be-used-as/10035065
|
||||||
// static
|
// static
|
||||||
// #else
|
// #else
|
||||||
// constexpr
|
// constexpr
|
||||||
// #endif
|
// #endif
|
||||||
const PointI FORMAT_INFO_COORDS[] = {{0, 8}, {1, 8}, {2, 8}, {3, 8}, {4, 8}, {5, 8}, {6, 8}, {7, 8}, {8, 8},
|
let FORMAT_INFO_COORDS: [Point; 17] = [
|
||||||
{8, 7}, {8, 6}, {8, 5}, {8, 4}, {8, 3}, {8, 2}, {8, 1}, {8, 0}};
|
point_i(0, 8),
|
||||||
|
point_i(1, 8),
|
||||||
|
point_i(2, 8),
|
||||||
|
point_i(3, 8),
|
||||||
|
point_i(4, 8),
|
||||||
|
point_i(5, 8),
|
||||||
|
point_i(6, 8),
|
||||||
|
point_i(7, 8),
|
||||||
|
point_i(8, 8),
|
||||||
|
point_i(8, 7),
|
||||||
|
point_i(8, 6),
|
||||||
|
point_i(8, 5),
|
||||||
|
point_i(8, 4),
|
||||||
|
point_i(8, 3),
|
||||||
|
point_i(8, 2),
|
||||||
|
point_i(8, 1),
|
||||||
|
point_i(8, 0),
|
||||||
|
];
|
||||||
|
|
||||||
FormatInformation bestFI;
|
let mut bestFI = FormatInformation::default();
|
||||||
PerspectiveTransform bestPT;
|
let mut bestPT = PerspectiveTransform::quadrilateralToQuadrilateral(
|
||||||
|
srcQuad,
|
||||||
|
fpQuad.rotated_corners(Some(0), None),
|
||||||
|
)?;
|
||||||
|
|
||||||
for (int i = 0; i < 4; ++i) {
|
for i in 0..4 {
|
||||||
auto mod2Pix = PerspectiveTransform(srcQuad, RotatedCorners(*fpQuad, i));
|
// for (int i = 0; i < 4; ++i) {
|
||||||
|
let mod2Pix = PerspectiveTransform::quadrilateralToQuadrilateral(
|
||||||
|
srcQuad,
|
||||||
|
fpQuad.rotated_corners(Some(i), None),
|
||||||
|
)?;
|
||||||
|
|
||||||
auto check = [&](int i, bool checkOne) {
|
let check = |i, checkOne: bool| {
|
||||||
auto p = mod2Pix(centered(FORMAT_INFO_COORDS[i]));
|
let p = mod2Pix.transform_point(Point::centered(FORMAT_INFO_COORDS[i]));
|
||||||
return image.isIn(p) && (!checkOne || image.get(p));
|
return image.is_in(p) && (!checkOne || image.get_point(p));
|
||||||
};
|
};
|
||||||
|
|
||||||
// check that we see both innermost timing pattern modules
|
// check that we see both innermost timing pattern modules
|
||||||
if (!check(0, true) || !check(8, false) || !check(16, true))
|
if (!check(0, true) || !check(8, false) || !check(16, true)) {
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
int formatInfoBits = 0;
|
let mut formatInfoBits = 0;
|
||||||
for (int i = 1; i <= 15; ++i)
|
for i in 1..=15
|
||||||
AppendBit(formatInfoBits, image.get(mod2Pix(centered(FORMAT_INFO_COORDS[i]))));
|
// for (int i = 1; i <= 15; ++i)
|
||||||
|
{
|
||||||
|
AppendBit(
|
||||||
|
&mut formatInfoBits,
|
||||||
|
image.get_point(mod2Pix.transform_point(Point::centered(FORMAT_INFO_COORDS[i]))),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
auto fi = FormatInformation::DecodeMQR(formatInfoBits);
|
let fi = FormatInformation::DecodeMQR(formatInfoBits as u32);
|
||||||
if (fi.hammingDistance < bestFI.hammingDistance) {
|
if (fi.hammingDistance < bestFI.hammingDistance) {
|
||||||
bestFI = fi;
|
bestFI = fi;
|
||||||
bestPT = mod2Pix;
|
bestPT = mod2Pix;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bestFI.isValid())
|
if (!bestFI.isValid()) {
|
||||||
return {};
|
return Err(Exceptions::NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
const int dim = Version::DimensionOfVersion(bestFI.microVersion, true);
|
let dim: u32 = Version::DimensionOfVersion(bestFI.microVersion, true);
|
||||||
|
|
||||||
// check that we are in fact not looking at a corner of a non-micro QRCode symbol
|
// check that we are in fact not looking at a corner of a non-micro QRCode symbol
|
||||||
// we accept at most 1/3rd black pixels in the quite zone (in a QRCode symbol we expect about 1/2).
|
// we accept at most 1/3rd black pixels in the quite zone (in a QRCode symbol we expect about 1/2).
|
||||||
int blackPixels = 0;
|
let mut blackPixels = 0;
|
||||||
for (int i = 0; i < dim; ++i) {
|
for i in 0..dim {
|
||||||
auto px = bestPT(centered(PointI{i, dim}));
|
// for (int i = 0; i < dim; ++i) {
|
||||||
auto py = bestPT(centered(PointI{dim, i}));
|
let px = bestPT.transform_point(Point::centered(point_i(i, dim)));
|
||||||
blackPixels += (image.isIn(px) && image.get(px)) + (image.isIn(py) && image.get(py));
|
let py = bestPT.transform_point(Point::centered(point_i(dim, i)));
|
||||||
}
|
blackPixels += u32::from((image.is_in(px) && image.get_point(px)))
|
||||||
if (blackPixels > 2 * dim / 3)
|
+ u32::from((image.is_in(py) && image.get_point(py)));
|
||||||
return {};
|
}
|
||||||
|
if (blackPixels > 2 * dim / 3) {
|
||||||
|
return Err(Exceptions::NOT_FOUND);
|
||||||
|
}
|
||||||
|
|
||||||
return SampleGrid(image, dim, dim, bestPT);
|
let grid_sampler = DefaultGridSampler::default();
|
||||||
|
Ok(QRCodeDetectorResult::new(
|
||||||
|
grid_sampler.sample_grid(
|
||||||
|
image,
|
||||||
|
dim,
|
||||||
|
dim,
|
||||||
|
&[SamplerControl {
|
||||||
|
p0: point_i(0, dim as u32),
|
||||||
|
p1: point_i(0, dim as u32),
|
||||||
|
transform: bestPT,
|
||||||
|
}],
|
||||||
|
)?,
|
||||||
|
Vec::default(),
|
||||||
|
))
|
||||||
|
|
||||||
|
// SampleGrid(image, dim, dim, bestPT)
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,7 @@ pub enum ErrorCorrectionLevel {
|
|||||||
Q, //0x03
|
Q, //0x03
|
||||||
/** H = ~30% correction */
|
/** H = ~30% correction */
|
||||||
H, //0x02
|
H, //0x02
|
||||||
|
Invalid,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ErrorCorrectionLevel {
|
impl ErrorCorrectionLevel {
|
||||||
@@ -60,6 +61,7 @@ impl ErrorCorrectionLevel {
|
|||||||
ErrorCorrectionLevel::M => 0x00,
|
ErrorCorrectionLevel::M => 0x00,
|
||||||
ErrorCorrectionLevel::Q => 0x03,
|
ErrorCorrectionLevel::Q => 0x03,
|
||||||
ErrorCorrectionLevel::H => 0x02,
|
ErrorCorrectionLevel::H => 0x02,
|
||||||
|
ErrorCorrectionLevel::Invalid => 0x00,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -69,6 +71,7 @@ impl ErrorCorrectionLevel {
|
|||||||
ErrorCorrectionLevel::M => 1,
|
ErrorCorrectionLevel::M => 1,
|
||||||
ErrorCorrectionLevel::Q => 2,
|
ErrorCorrectionLevel::Q => 2,
|
||||||
ErrorCorrectionLevel::H => 3,
|
ErrorCorrectionLevel::H => 3,
|
||||||
|
ErrorCorrectionLevel::Invalid => 100,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -68,8 +68,21 @@ const FORMAT_INFO_DECODE_LOOKUP: [[u32; 2]; 32] = [
|
|||||||
*/
|
*/
|
||||||
#[derive(Hash, Eq, PartialEq, Debug)]
|
#[derive(Hash, Eq, PartialEq, Debug)]
|
||||||
pub struct FormatInformation {
|
pub struct FormatInformation {
|
||||||
error_correction_level: ErrorCorrectionLevel,
|
pub hammingDistance: u32,
|
||||||
data_mask: u8,
|
pub error_correction_level: ErrorCorrectionLevel,
|
||||||
|
pub data_mask: u8,
|
||||||
|
pub microVersion: u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Default for FormatInformation {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self {
|
||||||
|
hammingDistance: 255,
|
||||||
|
error_correction_level: ErrorCorrectionLevel::Invalid,
|
||||||
|
data_mask: Default::default(),
|
||||||
|
microVersion: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FormatInformation {
|
impl FormatInformation {
|
||||||
@@ -79,6 +92,8 @@ impl FormatInformation {
|
|||||||
// Bottom 3 bits
|
// Bottom 3 bits
|
||||||
let dataMask = format_info & 0x07;
|
let dataMask = format_info & 0x07;
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
|
hammingDistance: 255,
|
||||||
|
microVersion: 0,
|
||||||
error_correction_level: errorCorrectionLevel,
|
error_correction_level: errorCorrectionLevel,
|
||||||
data_mask: dataMask,
|
data_mask: dataMask,
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -89,16 +89,16 @@ impl Version {
|
|||||||
17 + 4 * self.versionNumber
|
17 + 4 * self.versionNumber
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn DimensionOfVersion(version: u32, is_micro: bool) -> u32 {
|
pub fn DimensionOfVersion(version: u32, is_micro: bool) -> u32 {
|
||||||
Self::DimensionOffset(is_micro) + Self::DimensionStep(is_micro) * version
|
Self::DimensionOffset(is_micro) + Self::DimensionStep(is_micro) * version
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn DimensionOffset(is_micro: bool) -> u32 {
|
pub fn DimensionOffset(is_micro: bool) -> u32 {
|
||||||
todo!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub const fn DimensionStep(is_micro: bool) -> u32 {
|
pub fn DimensionStep(is_micro: bool) -> u32 {
|
||||||
todo!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn getECBlocksForLevel(&self, ecLevel: ErrorCorrectionLevel) -> &ECBlocks {
|
pub fn getECBlocksForLevel(&self, ecLevel: ErrorCorrectionLevel) -> &ECBlocks {
|
||||||
|
|||||||
Reference in New Issue
Block a user