You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

209 lines
6.5 KiB

/*
* Copyright 2017 Huy Cuong Nguyen
* Copyright 2008 ZXing authors
*/
// SPDX-License-Identifier: Apache-2.0
#include "qrcode/QRVersion.h"
#include "BitMatrix.h"
#include "BitMatrixIO.h"
#include "gtest/gtest.h"
using namespace ZXing;
using namespace ZXing::QRCode;
namespace {
void CheckVersion(const Version* version, int number, int dimension) {
ASSERT_NE(version, nullptr);
EXPECT_EQ(number, version->versionNumber());
if (number > 1 && version->isModel2()) {
EXPECT_FALSE(version->alignmentPatternCenters().empty());
}
EXPECT_EQ(dimension, version->dimension());
}
void DoTestVersion(int expectedVersion, int mask) {
auto version = Version::DecodeVersionInformation(mask);
ASSERT_NE(version, nullptr);
EXPECT_EQ(expectedVersion, version->versionNumber());
}
}
TEST(QRVersionTest, VersionForNumber)
{
auto version = Version::Model2(0);
EXPECT_EQ(version, nullptr) << "There is version with number 0";
for (int i = 1; i <= 40; i++) {
CheckVersion(Version::Model2(i), i, 4*i + 17);
}
}
TEST(QRVersionTest, GetProvisionalVersionForDimension)
{
for (int i = 1; i <= 40; i++) {
EXPECT_EQ(i, Version::Number(BitMatrix(4 * i + 17)));
}
}
TEST(QRVersionTest, DecodeVersionInformation)
{
// Spot check
DoTestVersion(7, 0x07C94);
DoTestVersion(12, 0x0C762);
DoTestVersion(17, 0x1145D);
DoTestVersion(22, 0x168C9);
DoTestVersion(27, 0x1B08E);
DoTestVersion(32, 0x209D5);
}
TEST(QRVersionTest, MicroVersionForNumber)
{
auto version = Version::Micro(0);
EXPECT_EQ(version, nullptr) << "There is version with number 0";
for (int i = 1; i <= 4; i++) {
CheckVersion(Version::Micro(i), i, 2 * i + 9);
}
}
TEST(QRVersionTest, GetProvisionalMicroVersionForDimension)
{
for (int i = 1; i <= 4; i++) {
EXPECT_EQ(i, Version::Number(BitMatrix(2 * i + 9)));
}
}
TEST(QRVersionTest, FunctionPattern)
{
auto testFinderPatternRegion = [](const BitMatrix& bitMatrix) {
for (int row = 0; row < 9; row++)
for (int col = 0; col < 9; col++)
EXPECT_TRUE(bitMatrix.get(col, row));
};
for (int i = 1; i <= 4; i++) {
const auto version = Version::Micro(i);
const auto functionPattern = version->buildFunctionPattern();
testFinderPatternRegion(functionPattern);
// Check timing pattern areas.
const auto dimension = version->dimension();
for (int row = dimension; row < functionPattern.height(); row++)
EXPECT_TRUE(functionPattern.get(0, row));
for (int col = dimension; col < functionPattern.width(); col++)
EXPECT_TRUE(functionPattern.get(col, 0));
}
}
namespace {
void CheckRMQRVersion(const Version* version, int number) {
ASSERT_NE(version, nullptr);
EXPECT_EQ(number, version->versionNumber());
EXPECT_EQ(Version::SymbolSize(number, Type::rMQR).x == 27, version->alignmentPatternCenters().empty());
}
}
TEST(QRVersionTest, RMQRVersionForNumber)
{
auto version = Version::rMQR(0);
EXPECT_EQ(version, nullptr) << "There is version with number 0";
for (int i = 1; i <= 32; i++) {
CheckRMQRVersion(Version::rMQR(i), i);
}
}
TEST(QRVersionTest, RMQRFunctionPattern)
{
{
const auto expected = ParseBitMatrix(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXX XXX XXXXXXXX\n"
"XXXXXXXXXXXX XXX XXXXXXXX\n"
"XXXXXXXXXXXX X XXXXXXXX\n"
"XXXXXXXXXXX XXX XXXXXXXX\n"
"XXXXXXXXXXX XXX XXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n",
'X', false);
const auto version = Version::rMQR(1); // R7x43
const auto functionPattern = version->buildFunctionPattern();
EXPECT_EQ(expected, functionPattern);
}
{
const auto expected = ParseBitMatrix(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXX XXX XX\n"
"XXXXXXXXXXXX XXX X\n"
"XXXXXXXXXXXX X XXXXXX X\n"
"XXXXXXXXXXX X XXXXXXXX\n"
"XXXXXXXXXXX X XXXXXXXX\n"
"XXXXXXXX XXX XXXXXXXX\n"
"XXXXXXXX XXX XXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n",
'X', false);
const auto version = Version::rMQR(6); // R9x43
const auto functionPattern = version->buildFunctionPattern();
EXPECT_EQ(expected, functionPattern);
}
{
const auto expected = ParseBitMatrix(
"XXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXX XX\n"
"XXXXXXXXXXXX X\n"
"XXXXXXXXXXXX X\n"
"XXXXXXXXXXX X\n"
"XXXXXXXXXXX XXXXXX X\n"
"XXXXXXXX XXXXXXXX\n"
"XXXXXXXX XXXXXXXX\n"
"X XXXXXXXX\n"
"XX XXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXX\n",
'X', false);
const auto version = Version::rMQR(11); // R11x27
const auto functionPattern = version->buildFunctionPattern();
EXPECT_EQ(expected, functionPattern);
}
{
const auto expected = ParseBitMatrix(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXX XXX XX\n"
"XXXXXXXXXXXX XXX X\n"
"XXXXXXXXXXXX X X\n"
"XXXXXXXXXXX X X\n"
"XXXXXXXXXXX X XXXXXX X\n"
"XXXXXXXX X XXXXXXXX\n"
"XXXXXXXX X XXXXXXXX\n"
"X XXX XXXXXXXX\n"
"XX XXX XXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n",
'X', false);
const auto version = Version::rMQR(12); // R11x43
const auto functionPattern = version->buildFunctionPattern();
EXPECT_EQ(expected, functionPattern);
}
{
const auto expected = ParseBitMatrix(
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n"
"XXXXXXXXXXXX XXX XXX XX\n"
"XXXXXXXXXXXX XXX XXX X\n"
"XXXXXXXXXXXX X X X\n"
"XXXXXXXXXXX X X X\n"
"XXXXXXXXXXX X X XXXXXX X\n"
"XXXXXXXX X X XXXXXXXX\n"
"XXXXXXXX X X XXXXXXXX\n"
"X XXX XXX XXXXXXXX\n"
"XX XXX XXX XXXXXXXX\n"
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX\n",
'X', false);
const auto version = Version::rMQR(13); // R11x59
const auto functionPattern = version->buildFunctionPattern();
EXPECT_EQ(expected, functionPattern);
}
}