diff --git a/src/common/cpp_essentials/base_extentions/qrcode_version.rs b/src/common/cpp_essentials/base_extentions/qrcode_version.rs index e0415a3..a61fb44 100644 --- a/src/common/cpp_essentials/base_extentions/qrcode_version.rs +++ b/src/common/cpp_essentials/base_extentions/qrcode_version.rs @@ -16,6 +16,16 @@ use crate::Exceptions; // } impl Version { + pub fn FromDimension(dimension: u32) -> Result { + todo!() + // bool isMicro = dimension < 21; + // if (dimension % DimensionStep(isMicro) != 1) { + // //throw std::invalid_argument("Unexpected dimension"); + // return nullptr; + // } + // return FromNumber((dimension - DimensionOffset(isMicro)) / DimensionStep(isMicro), isMicro); + } + pub fn DimensionOfVersion(version: u32, is_micro: bool) -> u32 { Self::DimensionOffset(is_micro) + Self::DimensionStep(is_micro) * version } diff --git a/src/qrcode/cpp_port/bitmatrix_parser.rs b/src/qrcode/cpp_port/bitmatrix_parser.rs index 40a98e8..3c33ac8 100644 --- a/src/qrcode/cpp_port/bitmatrix_parser.rs +++ b/src/qrcode/cpp_port/bitmatrix_parser.rs @@ -10,6 +10,8 @@ use crate::{ Exceptions, }; +use super::detector::AppendBit; + pub fn getBit(bitMatrix: &BitMatrix, x: u32, y: u32, mirrored: Option) -> bool { let mirrored = mirrored.unwrap_or(false); if mirrored { @@ -29,27 +31,33 @@ pub fn hasValidDimension(bitMatrix: &BitMatrix, isMicro: bool) -> bool { } pub fn ReadVersion(bitMatrix: &BitMatrix) -> Result { - todo!() - // int dimension = bitMatrix.height(); + let dimension = bitMatrix.height(); - // const Version* version = Version::FromDimension(dimension); + let mut version = Version::FromDimension(dimension)?; - // if (!version || version->versionNumber() < 7) - // return version; + if (version.getVersionNumber() < 7) { + return Ok(version); + } - // for (bool mirror : {false, true}) { - // // Read top-right/bottom-left version info: 3 wide by 6 tall (depending on mirrored) - // int versionBits = 0; - // for (int y = 5; y >= 0; --y) - // for (int x = dimension - 9; x >= dimension - 11; --x) - // AppendBit(versionBits, getBit(bitMatrix, x, y, mirror)); + for mirror in [false, true] { + // for (bool mirror : {false, true}) { + // Read top-right/bottom-left version info: 3 wide by 6 tall (depending on mirrored) + let mut versionBits = 0; + for y in (0..=5).rev() { + // for (int y = 5; y >= 0; --y) { + for x in ((dimension - 11)..=(dimension - 9)).rev() { + // for (int x = dimension - 9; x >= dimension - 11; --x) { + AppendBit(&mut versionBits, getBit(bitMatrix, x, y, Some(mirror))); + } + } - // version = Version::DecodeVersionInformation(versionBits); - // if (version && version->dimension() == dimension) - // return version; - // } + version = Version::DecodeVersionInformation(versionBits, 0)?; // THIS MIGHT BE WRONG todo!() + if (version.getDimensionForVersion() == dimension) { + return Ok(version); + } + } - // return nullptr; + return Err(Exceptions::FORMAT); } pub fn ReadFormatInformation(bitMatrix: &BitMatrix, isMicro: bool) -> Result { diff --git a/src/qrcode/cpp_port/detector.rs b/src/qrcode/cpp_port/detector.rs index d95fc64..ac34c16 100644 --- a/src/qrcode/cpp_port/detector.rs +++ b/src/qrcode/cpp_port/detector.rs @@ -448,7 +448,7 @@ pub fn ReadVersion( Version::DecodeVersionInformation(bits[0], bits[1]) } -fn AppendBit(val: &mut i32, bit: bool) { +pub fn AppendBit(val: &mut i32, bit: bool) { *val <<= 1; *val |= i32::from(bit) diff --git a/src/qrcode/decoder/mode.rs b/src/qrcode/decoder/mode.rs index b7b2b51..47e97fc 100644 --- a/src/qrcode/decoder/mode.rs +++ b/src/qrcode/decoder/mode.rs @@ -167,7 +167,34 @@ impl Mode { * count of characters that will follow encoded in this Mode */ pub fn CharacterCountBits(&self, version: &Version) -> u32 { - todo!() + let number = version.getVersionNumber() as usize; + if (version.isMicroQRCode()) { + match (self) { + Mode::NUMERIC=> return [3, 4, 5, 6][number - 1], + Mode::ALPHANUMERIC=> return [3, 4, 5][number - 2], + Mode::BYTE=> return [4, 5][number - 3], + Mode::KANJI | //=> [[fallthrough]], + Mode::HANZI=> return [3, 4][number - 3], + _=> return 0, + } + } + + let i = if (number <= 9) { + 0 + } else if (number <= 26) { + 1 + } else { + 2 + }; + + match (self) { + Mode::NUMERIC=> return [10, 12, 14][i], + Mode::ALPHANUMERIC=> return [9, 11, 13][i], + Mode::BYTE=> return [8, 16, 16][i], + Mode::KANJI| // [[fallthrough]]; + Mode::HANZI=> return [8, 10, 12][i], + _=> return 0, + } } }