Fixed error correction bytes number to write in final bytes array

Added exclipt size_t to unsigned conversion
Fixed google test in Visual Studio
This commit is contained in:
Dmitriy Shishkov 2021-12-21 14:04:40 +03:00
parent a1b6a84410
commit d9f9a26bde
No known key found for this signature in database
GPG Key ID: 14358F96FCDD8060
15 changed files with 73 additions and 51 deletions

View File

@ -1,14 +1,14 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.31911.196
# Visual Studio Version 17
VisualStudioVersion = 17.0.32014.148
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "QRCodeLibrary", "QRCodeLibrary\QRCodeLibrary.vcxproj", "{B1126767-CDF7-4831-8B08-85BF457DB4E2}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests\tests.vcxproj", "{96CDAF28-007A-4900-B24E-E21676713543}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "Demo", "Demo\Demo.vcxproj", "{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tests", "tests\tests.vcxproj", "{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|x64 = Debug|x64
@ -25,14 +25,6 @@ Global
{B1126767-CDF7-4831-8B08-85BF457DB4E2}.Release|x64.Build.0 = Release|x64
{B1126767-CDF7-4831-8B08-85BF457DB4E2}.Release|x86.ActiveCfg = Release|Win32
{B1126767-CDF7-4831-8B08-85BF457DB4E2}.Release|x86.Build.0 = Release|Win32
{96CDAF28-007A-4900-B24E-E21676713543}.Debug|x64.ActiveCfg = Debug|x64
{96CDAF28-007A-4900-B24E-E21676713543}.Debug|x64.Build.0 = Debug|x64
{96CDAF28-007A-4900-B24E-E21676713543}.Debug|x86.ActiveCfg = Debug|Win32
{96CDAF28-007A-4900-B24E-E21676713543}.Debug|x86.Build.0 = Debug|Win32
{96CDAF28-007A-4900-B24E-E21676713543}.Release|x64.ActiveCfg = Release|x64
{96CDAF28-007A-4900-B24E-E21676713543}.Release|x64.Build.0 = Release|x64
{96CDAF28-007A-4900-B24E-E21676713543}.Release|x86.ActiveCfg = Release|Win32
{96CDAF28-007A-4900-B24E-E21676713543}.Release|x86.Build.0 = Release|Win32
{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Debug|x64.ActiveCfg = Debug|x64
{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Debug|x64.Build.0 = Debug|x64
{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Debug|x86.ActiveCfg = Debug|Win32
@ -41,6 +33,14 @@ Global
{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Release|x64.Build.0 = Release|x64
{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Release|x86.ActiveCfg = Release|Win32
{B2AE1AC2-8D6A-4990-A6A7-E96E3AE6E6EA}.Release|x86.Build.0 = Release|Win32
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x64.ActiveCfg = Debug|x64
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x64.Build.0 = Debug|x64
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x86.ActiveCfg = Debug|Win32
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Debug|x86.Build.0 = Debug|Win32
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x64.ActiveCfg = Release|x64
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x64.Build.0 = Release|x64
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x86.ActiveCfg = Release|Win32
{3E0B17AF-839B-4963-BD22-7F2C8E87CE65}.Release|x86.Build.0 = Release|Win32
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE

View File

@ -4,6 +4,8 @@
#include <string>
#include <stdexcept>
#include "utils.hpp"
using namespace std;
constexpr unsigned ceil_div(unsigned a, unsigned b) {
@ -15,7 +17,7 @@ class BitArray
{
public:
BitArray(unsigned size_ = 0) : size{ size_ }, v(ceil_div(size_, 8), 0) {};
BitArray(const vector<unsigned char>& input) : size(input.size() * 8), v{ input } {};
BitArray(const vector<unsigned char>& input) : size(to_U(input.size()) * 8), v{ input } {};
operator std::string() const;

View File

@ -2,19 +2,20 @@
#include "DataBlocks.hpp"
#include "Tables.hpp"
#include "utils.hpp"
vector<unsigned char>& DataBlocks::compose_joined_data_and_EC_blocks()
{
vector<pair<unsigned, unsigned>>data_block_sizes;
divide_to_blocks(data_block_sizes, e_data.size(), Tables::data_blocks_number.at(corr_lvl).at(version));
divide_to_blocks(data_block_sizes, to_U(e_data.size()), Tables::data_blocks_number.at(corr_lvl).at(version));
unsigned EC_bytes_number = Tables::correction_bytes_num.at(corr_lvl).at(version);
vector<vector<unsigned char>> EC_blocks(data_block_sizes.size(), vector<unsigned char>());
for (unsigned i = 0; i < data_block_sizes.size(); i++)
compose_EC_bytes(EC_blocks[i], e_data.cbegin() + data_block_sizes[i].second, EC_bytes_number, data_block_sizes[i].first);
join_data_and_EC_blocks(data, e_data, data_block_sizes, EC_blocks);
join_data_and_EC_blocks(data, e_data, data_block_sizes, EC_blocks, EC_bytes_number);
return data;
}
@ -59,7 +60,7 @@ unsigned get_db_byte_index(unsigned block_index, unsigned byte_index, const vect
return db_sizes[block_index].second + byte_index;
}
void DataBlocks::join_data_and_EC_blocks(vector<unsigned char>& res, const vector<unsigned char>& e_data, const vector<pair<unsigned, unsigned>>& db_sizes, const vector<vector<unsigned char>>& ec_codes)
void DataBlocks::join_data_and_EC_blocks(vector<unsigned char>& res, const vector<unsigned char>& e_data, const vector<pair<unsigned, unsigned>>& db_sizes, const vector<vector<unsigned char>>& ec_codes, unsigned ec_bytes_number)
{
if (ec_codes.size())
res.reserve(e_data.size() + ec_codes.at(0).size() * ec_codes.size());
@ -72,7 +73,7 @@ void DataBlocks::join_data_and_EC_blocks(vector<unsigned char>& res, const vecto
res.push_back(e_data[get_db_byte_index(j, i, db_sizes)]);
if (ec_codes.size())
for (unsigned i = 0; i < ec_codes.at(0).size(); i++)
for (unsigned i = 0; i < ec_bytes_number; i++)
for (unsigned j = 0; j < ec_codes.size(); j++)
res.push_back(ec_codes[j][i]);
}

View File

@ -16,7 +16,7 @@ public:
static void divide_to_blocks(vector<pair<unsigned, unsigned>>& db_sizes, unsigned data_size, unsigned db_number);
static void compose_EC_bytes(vector<unsigned char>& res, const vector<unsigned char>::const_iterator& src, unsigned corr_bytes_num, unsigned db_size);
static void join_data_and_EC_blocks(vector<unsigned char>&res, const vector<unsigned char>& e_data, const vector<pair<unsigned, unsigned>>& db_sizes, const vector<vector<unsigned char>>& ec_codes);
static void join_data_and_EC_blocks(vector<unsigned char>&res, const vector<unsigned char>& e_data, const vector<pair<unsigned, unsigned>>& db_sizes, const vector<vector<unsigned char>>& ec_codes, unsigned ec_bytes_number);
private:
const vector<unsigned char>& e_data;

View File

@ -2,12 +2,13 @@
#include "Encoder.hpp"
#include "Tables.hpp"
#include "utils.hpp"
#include <stdexcept>
BitArray& Encoder::encode()
{
unsigned encoded_bit_num = calculate_encoded_input_size(input.size(), method);
unsigned encoded_bit_num = calculate_encoded_input_size(to_U(input.size()), method);
unsigned metadata_bit_num = calculate_metadata_size(method, ((version < 0) ? 0 : version));
if (version < 0) {
@ -22,7 +23,7 @@ BitArray& Encoder::encode()
e.resize(Tables::max_capability.at(corr_lvl).at(version));
write_metadata(input.size(), metadata_bit_num - 4, method, e);
write_metadata(to_U(input.size()), metadata_bit_num - 4, method, e);
encode_input(metadata_bit_num);
pad_data(e, metadata_bit_num + encoded_bit_num);
@ -71,10 +72,10 @@ void Encoder::encode_numeric(const string& input, BitArray& out, unsigned offset
if (input.size() % 3 == 2) {
int bin = stoi(input.substr(input.size() - 2, 2));
out.set(offset + input.size() / 3 * 10, bin, 7);
out.set(offset + to_U(input.size()) / 3 * 10, bin, 7);
}
else if (input.size() % 3 == 1)
out.set(offset + input.size() / 3 * 10, input[input.size() - 1] - '0', 4);
out.set(offset + to_U(input.size()) / 3 * 10, input[input.size() - 1] - '0', 4);
}
void Encoder::encode_alphabetic(const string& input, BitArray& out, unsigned offset)
@ -86,7 +87,7 @@ void Encoder::encode_alphabetic(const string& input, BitArray& out, unsigned off
if (input.size() % 2 == 1) {
int bin = encode_char(input[input.size() - 1]);
out.set(offset + input.size() / 2 * 11, bin, 6);
out.set(offset + to_U(input.size()) / 2 * 11, bin, 6);
}
}

View File

@ -6,6 +6,7 @@
#include "Method.hpp"
#include "BitArray.hpp"
#include "utils.hpp"
using namespace std;
@ -86,7 +87,7 @@ constexpr unsigned Encoder::calculate_encoded_input_size(unsigned input_size, QR
template <typename T, size_t N>
constexpr unsigned upper_index(const array<T, N> arr, T val) {
unsigned count = arr.size(), s = 0, e = 0, step = 0;
unsigned count = to_U(arr.size()), s = 0, e = 0, step = 0;
while (count > 0) {
step = count / 2;
@ -101,4 +102,4 @@ constexpr unsigned upper_index(const array<T, N> arr, T val) {
}
return s;
}
}

View File

@ -161,6 +161,7 @@
<ClInclude Include="QRMatrix.hpp" />
<ClInclude Include="Tables.hpp" />
<ClInclude Include="TritMatrix.hpp" />
<ClInclude Include="utils.hpp" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="BitArray.cpp" />

View File

@ -45,6 +45,9 @@
<ClInclude Include="QRMatrix.hpp">
<Filter>Header Files</Filter>
</ClInclude>
<ClInclude Include="utils.hpp">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<ClCompile Include="pch.cpp">

View File

@ -2,6 +2,7 @@
#include "QRMatrix.hpp"
#include "Tables.hpp"
#include "utils.hpp"
void QRMatrix::draw_patterns()
{
@ -14,8 +15,8 @@ void QRMatrix::draw_patterns()
void QRMatrix::draw_finder_patterns()
{
draw_finder_square(0, 0);
draw_finder_square(c.size() - 7, 0);
draw_finder_square(0, c.size() - 7);
draw_finder_square(to_U(c.size()) - 7, 0);
draw_finder_square(0, to_U(c.size()) - 7);
draw_finder_square_separators();
}
@ -34,13 +35,13 @@ void QRMatrix::draw_finder_square(unsigned y, unsigned x)
void QRMatrix::draw_finder_square_separators()
{
set(7, 0, 0b0000000, 7);
set(7, c.size() - 7, 0b0000000, 7);
set(c.size() - 8, 0, 0b0000000, 7);
set(7, to_U(c.size()) - 7, 0b0000000, 7);
set(to_U(c.size()) - 8, 0, 0b0000000, 7);
for (unsigned i = 0; i < 8; i++) {
set(i, 7, 0);
set(i, c.size() - 8, 0);
set(c.size() - 8 + i, 7, 0);
set(i, to_U(c.size()) - 8, 0);
set(to_U(c.size()) - 8 + i, 7, 0);
}
}
@ -48,7 +49,7 @@ void QRMatrix::draw_alignment_patters()
{
auto& coordinates = Tables::alignment_patterns_coordinates.at(version);
for (unsigned i = 0; i < coordinates.size(); i++) {
unsigned s = i, e = coordinates.size();
unsigned s = i, e = to_U(coordinates.size());
if (coordinates[i] == 6)
s++, e--;
@ -81,7 +82,7 @@ void QRMatrix::draw_timing_patterns()
void QRMatrix::draw_dark_module()
{
set(c.size() - 8, 8, 1);
set(to_U(c.size()) - 8, 8, 1);
}
void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n)
@ -90,14 +91,14 @@ void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n)
const auto& v_codes = Tables::version_codes.at(version-6);
for (unsigned i = 0; i < 3; i++)
for (unsigned j = 0; j < 6; j++) {
set(c.size() - 11 + i, j, (v_codes.at(i) >> (6 - 1 - j)) & 1);
set(j, c.size() - 11 + i, (v_codes.at(i) >> (6 - 1 - j)) & 1);
set(to_U(c.size()) - 11 + i, j, (v_codes.at(i) >> (6 - 1 - j)) & 1);
set(j, to_U(c.size()) - 11 + i, (v_codes.at(i) >> (6 - 1 - j)) & 1);
}
}
unsigned code = Tables::corr_lvl_and_mask_codes.at(corr_lvl)[mask_n];
unsigned y1 = 8, y2 = c.size() - 1, x1 = 0, x2 = 8;
unsigned y1 = 8, y2 = to_U(c.size()) - 1, x1 = 0, x2 = 8;
for (unsigned i = 0; i < 15; i++) {
set(y1, x1, (code >> (15 - 1 - i)) & 1);
set(y2, x2, (code >> (15 - 1 - i)) & 1);
@ -112,7 +113,7 @@ void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n)
}
if (y2 > c.size() - 8) y2--;
if (y2 == c.size() - 8) { y2 = 8; x2 = c.size() - 8; }
if (y2 == to_U(c.size()) - 8) { y2 = 8; x2 = to_U(c.size()) - 8; }
else if (y2 == 8)
x2++;
@ -123,7 +124,7 @@ void QRMatrix::place_metadata(CorrectionLevel corr_lvl, unsigned char mask_n)
void QRMatrix::place_data(const BitArray& data, unsigned char mask_n)
{
unsigned y = c.size() - 1;
unsigned y = to_U(c.size()) - 1;
unsigned x = y;
unsigned step = 0;
bool horiz_dir = true;

10
QRCodeLibrary/utils.hpp Normal file
View File

@ -0,0 +1,10 @@
#pragma once
#include <type_traits>
#include <limits>
constexpr unsigned to_U(size_t val) {
if (val > (std::numeric_limits<unsigned int>::max)())
throw std::runtime_error("Too big number to convert it to unsigned int" + std::to_string(val));
return static_cast<unsigned>(val);
}

View File

@ -40,7 +40,7 @@ TEST(DataBlocksTests, JoinsDataAndECBlocks) {
{ 235, 159, 5, 173, 24, 147, 59, 33, 106, 40, 255, 172, 82, 2, 131, 32, 178, 236 }
};
DataBlocks::join_data_and_EC_blocks(joined, e_data, d_b_sizes, EC_blocks);
DataBlocks::join_data_and_EC_blocks(joined, e_data, d_b_sizes, EC_blocks, 18);
const vector<unsigned char>res{
67, 246, 182, 70, 85, 246, 230, 247, 70, 66, 247, 118, 134, 7, 119,

View File

@ -3,6 +3,7 @@
#define private public
#include "../QRCodeLibrary/Encoder.hpp"
#include "../QRCodeLibrary/utils.hpp"
/* upper_index function */
@ -65,29 +66,29 @@ TEST(EncoderTests, DetermitesVersion) {
TEST(EncoderTests, WritesMetadata) {
string expected("010001100100");
BitArray arr(expected.size());
BitArray arr(to_U(expected.size()));
Encoder::write_metadata(100, expected.size() - 4, QRCodeMethod::Byte, arr);
Encoder::write_metadata(100, to_U(expected.size()) - 4, QRCodeMethod::Byte, arr);
EXPECT_EQ(std::string(arr), expected);
}
TEST(EncoderTests, EncodesNumeric) {
BitArray tmp(string("00110110001110000100101001").size());
BitArray tmp(to_U(string("00110110001110000100101001").size()));
Encoder::encode_numeric("8675309", tmp, 2);
EXPECT_EQ(std::string(tmp), "00110110001110000100101001");
}
TEST(EncoderTests, EncodesAlphabetic) {
BitArray tmp(string("0000110000101101111000110100010111001011011100010011010100001101").size());
BitArray tmp(to_U(string("0000110000101101111000110100010111001011011100010011010100001101").size()));
Encoder::encode_alphabetic("HELLO WORLD", tmp, 3);
EXPECT_EQ(std::string(tmp), "0000110000101101111000110100010111001011011100010011010100001101");
}
TEST(EncoderTests, EncodesBytes) {
BitArray tmp(string("0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010").size());
BitArray tmp(to_U(string("0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010").size()));
Encoder::encode_byte(u8"Дмитрий Шишков", tmp, 4);
EXPECT_EQ(std::string(tmp), "0000110100001001010011010000101111001101000010111000110100011000001011010001100000001101000010111000110100001011100100100000110100001010100011010000101110001101000110001000110100001011101011010000101111101101000010110010");

View File

@ -1,4 +1,4 @@
#include "gtest/gtest.h"
#include "pch.h"
int main(int argc, char **argv)
{

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn" version="1.8.1.4" targetFramework="native" />
<package id="Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn" version="1.8.1.5" targetFramework="native" />
</packages>

View File

@ -19,9 +19,9 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{96cdaf28-007a-4900-b24e-e21676713543}</ProjectGuid>
<ProjectGuid>{3e0b17af-839b-4963-bd22-7f2c8e87ce65}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<WindowsTargetPlatformVersion>10.0.19041.0</WindowsTargetPlatformVersion>
<ConfigurationType>Application</ConfigurationType>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
@ -39,14 +39,15 @@
<ClCompile Include="BitArray_test.cpp" />
<ClCompile Include="DataBlocks_test.cpp" />
<ClCompile Include="Encoder_test.cpp" />
<ClCompile Include="main_tests.cpp" />
<ClCompile Include="Method_test.cpp" />
<ClCompile Include="QRCode_test.cpp" />
<ClCompile Include="pch.cpp">
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Create</PrecompiledHeader>
<PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
</ClCompile>
<ClCompile Include="QRCode_test.cpp" />
<ClCompile Include="QRMatrix_test.cpp" />
<ClCompile Include="TritMatrix_test.cpp" />
</ItemGroup>
@ -61,7 +62,7 @@
<ItemDefinitionGroup />
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
<Import Project="..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets" Condition="Exists('..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" />
<Import Project="..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.5\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets" Condition="Exists('..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.5\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" />
</ImportGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
@ -129,6 +130,6 @@
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.4\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets'))" />
<Error Condition="!Exists('..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.5\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.1.8.1.5\build\native\Microsoft.googletest.v140.windesktop.msvcstl.static.rt-dyn.targets'))" />
</Target>
</Project>