1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245
|
/*
* Copyright 2017 Huy Cuong Nguyen
* Copyright 2013 ZXing authors
*/
// SPDX-License-Identifier: Apache-2.0
#include "BitMatrix.h"
#include "CharacterSet.h"
#include "DecoderResult.h"
#include "PseudoRandom.h"
#include "TextEncoder.h"
#include "aztec/AZDecoder.h"
#include "aztec/AZDetector.h"
#include "aztec/AZDetectorResult.h"
#include "aztec/AZEncoder.h"
#include "aztec/AZWriter.h"
#include <algorithm>
#include <utility>
namespace testing {
namespace internal {
bool operator==(const std::string& a, const std::wstring& b) {
return a.length() == b.length() && std::equal(a.begin(), a.end(), b.begin());
}
}
}
#include "gtest/gtest.h"
using namespace ZXing;
namespace {
// Shorthand to call Decode()
static DecoderResult parse(BitMatrix&& bits, bool compact, int nbDatablocks, int nbLayers)
{
return Aztec::Decode({{std::move(bits), {}}, compact, nbDatablocks, nbLayers, false /*readerInit*/, false /*isMirrored*/, 0 /*runeValue*/});
}
void TestEncodeDecode(const std::string& data, bool compact, int layers) {
Aztec::EncodeResult aztec = Aztec::Encoder::Encode(data, 25, Aztec::Encoder::DEFAULT_AZTEC_LAYERS);
ASSERT_EQ(aztec.compact, compact) << "Unexpected symbol format (compact)";
ASSERT_EQ(aztec.layers, layers) << "Unexpected nr. of layers";
DecoderResult res = parse(aztec.matrix.copy(), aztec.compact, aztec.codeWords, aztec.layers);
ASSERT_EQ(res.isValid(), true);
EXPECT_EQ(data, res.text());
// Check error correction by introducing a few minor errors
PseudoRandom random(0x12345678);
BitMatrix matrix = aztec.matrix.copy();
auto x = random.next(0, matrix.width() - 1);
auto y = random.next(0, 1);
matrix.flip(x, y);
x = random.next(0, matrix.width() - 1);
y = matrix.height() - 2 + random.next(0, 1);
matrix.flip(x, y);
x = random.next(0, 1);
y = random.next(0, matrix.height() - 1);
matrix.flip(x, y);
x = matrix.width() - 2 + random.next(0, 1);
y = random.next(0, matrix.height() - 1);
matrix.flip(x, y);
res = parse(std::move(matrix), aztec.compact, aztec.codeWords, aztec.layers);
ASSERT_EQ(res.isValid(), true);
EXPECT_EQ(data, res.text());
}
void TestWriter(const std::wstring& data, CharacterSet charset, int eccPercent, bool compact, int layers) {
// 1. Perform an encode-decode round-trip because it can be lossy.
// 2. Aztec Decoder currently always decodes the data with a LATIN-1 charset:
std::string textBytes = TextEncoder::FromUnicode(data, charset);
Aztec::Writer writer;
writer.setEncoding(charset);
writer.setEccPercent(eccPercent);
BitMatrix matrix = writer.encode(data, 0, 0);
Aztec::EncodeResult aztec = Aztec::Encoder::Encode(textBytes, eccPercent, Aztec::Encoder::DEFAULT_AZTEC_LAYERS);
EXPECT_EQ(aztec.compact, compact) << "Unexpected symbol format (compact)";
EXPECT_EQ(aztec.layers, layers) << "Unexpected nr. of layers";
EXPECT_EQ(aztec.matrix, matrix);
DecoderResult res = parse(matrix.copy(), aztec.compact, aztec.codeWords, aztec.layers);
EXPECT_EQ(res.isValid(), true);
EXPECT_EQ(res.content().bytes, ByteArray(textBytes));
// Check error correction by introducing up to eccPercent/2 errors
int ecWords = aztec.codeWords * eccPercent / 100 / 2;
PseudoRandom random(0x12345678);
for (int i = 0; i < ecWords; i++) {
// don't touch the core
int x = random.next(0, 1) == 1 ?
random.next(0, aztec.layers * 2 - 1)
: matrix.width() - 1 - random.next(0, aztec.layers * 2 - 1);
int y = random.next(0, 1) == 1 ?
random.next(0, aztec.layers * 2 - 1)
: matrix.height() - 1 - random.next(0, aztec.layers * 2 - 1);
matrix.flip(x, y);
}
res = parse(std::move(matrix), aztec.compact, aztec.codeWords, aztec.layers);
EXPECT_EQ(res.isValid(), true);
EXPECT_EQ(res.content().bytes, ByteArray(textBytes));
}
}
TEST(AZEncodeDecodeTest, EncodeDecode1)
{
TestEncodeDecode("Abc123!", true, 1);
}
TEST(AZEncodeDecodeTest, EncodeDecode2)
{
TestEncodeDecode("Lorem ipsum. http://test/", true, 2);
}
TEST(AZEncodeDecodeTest, EncodeDecode3)
{
TestEncodeDecode("AAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAANAAAAN", true, 3);
}
TEST(AZEncodeDecodeTest, EncodeDecode4)
{
TestEncodeDecode("http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384", true, 4);
}
TEST(AZEncodeDecodeTest, EncodeDecode5)
{
TestEncodeDecode("http://test/~!@#*^%&)__ ;:'\"[]{}\\|-+-=`1029384756<>/?abc"
"Four score and seven our forefathers brought forth", false, 5);
}
TEST(AZEncodeDecodeTest, EncodeDecode10)
{
TestEncodeDecode("In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam"
" cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum"
" est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue"
" auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla"
" ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id"
" elementum sapien dolor et diam.", false, 10);
}
TEST(AZEncodeDecodeTest, EncodeDecode23)
{
TestEncodeDecode("In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam"
" cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum"
" est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue"
" auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla"
" ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id"
" elementum sapien dolor et diam. Donec ac nunc sodales elit placerat eleifend."
" Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus"
" justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu"
" tristique ac, p.In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus"
" quis diam cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec"
" laoreet rutrum est, nec convallis mauris condimentum sit amet. Phasellus gravida,"
" justo et congue auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec"
" lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar"
" nisi, id elementum sapien dolor et diam. Donec ac nunc sodales elit placerat"
" eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra"
" fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo"
" diam, lobortis eu tristique ac, p. In ut magna vel mauris malesuada dictum. Nulla"
" ullamcorper metus quis diam cursus facilisis. Sed mollis quam id justo rutrum"
" sagittis. Donec laoreet rutrum est, nec convallis mauris condimentum sit amet."
" Phasellus gravida, justo et congue auctor, nisi ipsum viverra erat, eget hendrerit"
" felis turpis nec lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo"
" erat pulvinar nisi, id elementum sapien dolor et diam.", false, 23);
}
TEST(AZEncodeDecodeTest, EncodeDecode31)
{
TestEncodeDecode("In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus quis diam"
" cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec laoreet rutrum"
" est, nec convallis mauris condimentum sit amet. Phasellus gravida, justo et congue"
" auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec lorem. Nulla"
" ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar nisi, id"
" elementum sapien dolor et diam. Donec ac nunc sodales elit placerat eleifend."
" Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra fringilla, risus"
" justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo diam, lobortis eu"
" tristique ac, p.In ut magna vel mauris malesuada dictum. Nulla ullamcorper metus"
" quis diam cursus facilisis. Sed mollis quam id justo rutrum sagittis. Donec"
" laoreet rutrum est, nec convallis mauris condimentum sit amet. Phasellus gravida,"
" justo et congue auctor, nisi ipsum viverra erat, eget hendrerit felis turpis nec"
" lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo erat pulvinar"
" nisi, id elementum sapien dolor et diam. Donec ac nunc sodales elit placerat"
" eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at pharetra"
" fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est. Ut justo"
" diam, lobortis eu tristique ac, p. In ut magna vel mauris malesuada dictum. Nulla"
" ullamcorper metus quis diam cursus facilisis. Sed mollis quam id justo rutrum"
" sagittis. Donec laoreet rutrum est, nec convallis mauris condimentum sit amet."
" Phasellus gravida, justo et congue auctor, nisi ipsum viverra erat, eget hendrerit"
" felis turpis nec lorem. Nulla ultrices, elit pellentesque aliquet laoreet, justo"
" erat pulvinar nisi, id elementum sapien dolor et diam. Donec ac nunc sodales elit"
" placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula, massa at"
" pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus sed est."
" Ut justo diam, lobortis eu tristique ac, p.In ut magna vel mauris malesuada"
" dictum. Nulla ullamcorper metus quis diam cursus facilisis. Sed mollis quam id"
" justo rutrum sagittis. Donec laoreet rutrum est, nec convallis mauris condimentum"
" sit amet. Phasellus gravida, justo et congue auctor, nisi ipsum viverra erat,"
" eget hendrerit felis turpis nec lorem. Nulla ultrices, elit pellentesque aliquet"
" laoreet, justo erat pulvinar nisi, id elementum sapien dolor et diam. Donec ac"
" nunc sodales elit placerat eleifend. Sed ornare luctus ornare. Vestibulum vehicula,"
" massa at pharetra fringilla, risus justo faucibus erat, nec porttitor nibh tellus"
" sed est. Ut justo diam, lobortis eu tris. In ut magna vel mauris malesuada dictum."
" Nulla ullamcorper metus quis diam cursus facilisis. Sed mollis quam id justo rutrum"
" sagittis. Donec laoreet rutrum est, nec convallis mauris condimentum sit amet."
" Phasellus gravida, justo et congue auctor, nisi ipsum viverra erat, eget"
" hendrerit felis turpis nec lorem.", false, 31);
}
TEST(AZEncodeDecodeTest, AztecWriter)
{
//TestWriter(L"\x20AC 1 sample data.", CharacterSet::ISO8859_1, 25, true, 2);
//TestWriter(L"\x20AC 1 sample data.", CharacterSet::ISO8859_15, 25, true, 2);
TestWriter(L"\x20AC 1 sample data.", CharacterSet::UTF8, 25, true, 2);
TestWriter(L"\x20AC 1 sample data.", CharacterSet::UTF8, 100, true, 3);
TestWriter(L"\x20AC 1 sample data.", CharacterSet::UTF8, 300, true, 4);
TestWriter(L"\x20AC 1 sample data.", CharacterSet::UTF8, 500, false, 5);
// Test AztecWriter defaults
std::wstring data = L"In ut magna vel mauris malesuada";
BitMatrix matrix = Aztec::Writer().encode(data, 0, 0);
Aztec::EncodeResult aztec =
Aztec::Encoder::Encode(TextEncoder::FromUnicode(data, CharacterSet::ISO8859_1),
Aztec::Encoder::DEFAULT_EC_PERCENT, Aztec::Encoder::DEFAULT_AZTEC_LAYERS);
EXPECT_EQ(matrix, aztec.matrix);
}
TEST(AZEncodeDecodeTest, RunePure)
{
for(uint8_t word = 0; word < 255; word++) {
std::string data(1, word);
Aztec::EncodeResult aztec =
Aztec::Encoder::Encode(data, 0, Aztec::Encoder::AZTEC_RUNE_LAYERS);
auto result = Aztec::Detect(aztec.matrix, true, false);
EXPECT_TRUE(result.isValid());
EXPECT_EQ(result.nbDatablocks(), 0);
EXPECT_EQ(result.runeValue(), word);
}
}
|