Compare commits

...

21 Commits

Author SHA1 Message Date
Michael Ochmann 6794e1cf59 fixed `help2man` 11 months ago
Michael Ochmann cf4f8faa37 code quality: minor structural changes 2 years ago
Michael Ochmann df1c3a78ba code quality: consolidated helpers to single header 2 years ago
Michael Ochmann b99850c042 code quality: removed duplicate c++ standard 2 years ago
Michael Ochmann 17edd0512a code quality: deleted copy assignment operators 2 years ago
Michael Ochmann d56b9ef2b2 Merge pull request 'Release Version 1.1.0' (#1) from feature/v1.1.0 into master 2 years ago
Michael Ochmann f9654cc253 readme: added basic project information 2 years ago
Michael Ochmann 425a0f0b66 code quality: made unused switch cases more obvious 2 years ago
Michael Ochmann 4d7a7bfd69 code quality: making all the pixel based renderers `final` 2 years ago
Michael Ochmann d3850939cd code quality: getting rid of `std::vector` of all the renderers 2 years ago
Michael Ochmann 98b1cddd79 code quality: deleted copy & move constructors 2 years ago
Michael Ochmann 576bdf8430 code quality: more code cleanup 2 years ago
Michael Ochmann 6f3827427b PixelRenderer: now respecting the specified output size exactly 2 years ago
Michael Ochmann cfc0d276dc SVGRenderer: removed redundant `std::stringstream` 2 years ago
Michael Ochmann 61f308fb03 fixed `ARCH` detection in `cmake` 2 years ago
Michael Ochmann 2a8e54610b added man page support 2 years ago
Michael Ochmann dd45505f21 changed sizing of svgs 2 years ago
Michael Ochmann 7d8092aee6 added more pixel base renderers: 2 years ago
Michael Ochmann 0c7c830d5b minor cleanup 2 years ago
Michael Ochmann 63c018e28b now printing help when called without stdin and without any parameter 2 years ago
Michael Ochmann df98a2279e now exporting files with extension appended 2 years ago
  1. 20
      CMakeLists.txt
  2. 51
      README.md
  3. 459
      docs/logo_qr.svg
  4. 74
      main.cpp
  5. 58
      src/QR.cpp
  6. 37
      src/QR.hpp
  7. 6
      src/Renderer.hpp
  8. 21
      src/renderers/BMPRenderer.hpp
  9. 11
      src/renderers/ConsoleRenderer.hpp
  10. 21
      src/renderers/JPGRenderer.hpp
  11. 4
      src/renderers/PNGRenderer.hpp
  12. 34
      src/renderers/PixelRenderer.hpp
  13. 15
      src/renderers/SVGRenderer.hpp
  14. 12
      src/util.hpp

@ -1,6 +1,10 @@
cmake_minimum_required(VERSION 3.14...3.25) cmake_minimum_required(VERSION 3.14...3.25)
set (CXX_STANDARD 23) project(
qr
VERSION 1.1.0
LANGUAGES CXX
)
if (DEFINED ENV{ARCH}) if (DEFINED ENV{ARCH})
set(ARCH $ENV{ARCH}) set(ARCH $ENV{ARCH})
@ -10,12 +14,6 @@ endif()
set(EXE_NAME "qr_${CMAKE_PROJECT_VERSION}-${ARCH}") set(EXE_NAME "qr_${CMAKE_PROJECT_VERSION}-${ARCH}")
project(
qr
VERSION 1.0.1
LANGUAGES CXX
)
message(STATUS "ARCH:: ${ARCH}") message(STATUS "ARCH:: ${ARCH}")
configure_file(main.cpp main_substitute.cpp) configure_file(main.cpp main_substitute.cpp)
@ -27,5 +25,13 @@ set_target_properties(qr PROPERTIES OUTPUT_NAME ${EXE_NAME})
target_compile_options(qr PUBLIC -Wall -std=c++20 -arch ${ARCH}) target_compile_options(qr PUBLIC -Wall -std=c++20 -arch ${ARCH})
target_include_directories(qr PRIVATE src lib) target_include_directories(qr PRIVATE src lib)
add_custom_target(man ALL)
add_custom_command(
TARGET man
COMMAND help2man -h "-h" -v "-v" -o qr.7 ./${EXE_NAME}
COMMAND gzip -f qr.7
)
install(TARGETS qr RUNTIME DESTINATION bin) install(TARGETS qr RUNTIME DESTINATION bin)
install(PROGRAMS build/${EXE_NAME} DESTINATION bin RENAME qr) install(PROGRAMS build/${EXE_NAME} DESTINATION bin RENAME qr)
install(FILES build/qr.7.gz DESTINATION /usr/local/share/man/man7/)

@ -3,3 +3,54 @@
![qr](docs/logo_qr.svg) ![qr](docs/logo_qr.svg)
## Usage
This software currently supports outputting to the following formats:
* svg
* PNG
* JPG
* Bitmap
or directly to the console, as kind of an *"ascii art"*.
after installing via `make install`, you can read more in the man page by calling `man qr`.
### Options
```
-f --format output file format. can be one of "cli, png, svg, jpg, bmp"
-h --help show this help
-i --input take data from this argument instead of stdin
-o --output output file name without extension
-s --size desired output file size in pixels
-t --type output QR code type. can be one of "small, medium, large"
-v --version shows version info
```
### Examples
```bash
bash> qr -i "this is from parameter" -f png -s 512 -o my_qrcode_file
bash> echo "this is from stdin" | qr -t small -f png -s 512 -o my_qrcode_file_with_low_ecc
```
## Installation
You can just pick the newest version from the ["Releases" page][releases], or build the software yourself.
### Building
You will need:
* cmake
* make
* a modern C++ compiler that supports `c++20`
```bash
# clone the repo
bash ~/> git clone https://git.mike-ochmann.de/MassiveDynamic/qr.git
# move into the repository
bash ~/> cd qr
# create the build directory and move into it
bash ~/qr> mkdir build && cd build
# run `cmake`
bash ~/qr/build> cmake ..
# make and install the software
bash ~/qr/build> make install
```
[releases]: releases/

@ -1,231 +1,232 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="qrcode" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <!-- Generator: Massive Dynamic qr, massivedynamic::SVGRenderer -->
viewBox="0 0 64 64" xml:space="preserve"> <svg version="1.1" id="qrcode" xmlns="http://www.w3.org/2000/svg" x="0" y="0"
<rect x="0" y="0" width="64" height="64" style="fill: white;" /> viewBox="0 0 128 128" width="128" height="128" xml:space="preserve">
<rect x="2.78261" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="0" y="0" width="128" height="128" style="fill: white;" />
<rect x="5.56522" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="11.1304" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="16.6957" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="33.3913" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="44.5217" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="89.0435" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="2.78261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="5.56522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="5.56522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="5.56522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="11.1304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="5.56522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="11.1304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="5.56522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="11.1304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="5.56522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="11.1304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="5.56522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="11.1304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="5.56522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="11.1304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="11.1304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="8.34783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="16.6957" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="11.1304" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="22.2609" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="13.913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="16.6957" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="27.8261" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="16.6957" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="33.3913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="16.6957" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="33.3913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="16.6957" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="33.3913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="16.6957" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="33.3913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="16.6957" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="33.3913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="33.3913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="5.56522" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="11.1304" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="16.6957" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="33.3913" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="44.5217" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="89.0435" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="19.4783" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="22.2609" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="38.9565" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="22.2609" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="44.5217" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="22.2609" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="44.5217" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="44.5217" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="22.2609" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="44.5217" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="25.0435" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="50.087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="5.56522" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="11.1304" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="16.6957" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="22.2609" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="33.3913" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="44.5217" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="38.9565" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="77.913" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="27.8261" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="55.6522" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="30.6087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="61.2174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="16.6957" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="22.2609" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="33.3913" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="44.5217" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="38.9565" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="77.913" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="33.3913" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="66.7826" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="5.56522" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="11.1304" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="36.1739" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="72.3478" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="44.5217" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="38.9565" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="89.0435" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="77.913" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="5.56522" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="11.1304" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="16.6957" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="33.3913" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="38.9565" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="44.5217" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="77.913" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="41.7391" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="89.0435" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="83.4783" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="44.5217" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="89.0435" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="44.5217" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="89.0435" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="38.9565" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="77.913" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="44.5217" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="89.0435" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="47.3043" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="94.6087" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="25.0435" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="27.8261" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="50.087" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="30.6087" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="55.6522" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="36.1739" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="61.2174" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="38.9565" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="72.3478" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="77.913" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="50.087" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="100.174" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="52.8696" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="105.739" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="41.7391" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="47.3043" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="83.4783" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="94.6087" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="55.6522" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="105.739" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="58.4348" y="55.6522" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="111.304" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="2.78261" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="116.87" y="111.304" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="5.56522" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="5.56522" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="8.34783" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="11.1304" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="11.1304" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="16.6957" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="13.913" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="22.2609" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="16.6957" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="27.8261" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="19.4783" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="33.3913" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="33.3913" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="38.9565" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="38.9565" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="66.7826" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="50.087" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="77.913" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="52.8696" y="58.4348" width="2.78261" height="2.78261" style="fill: black; stroke: black; stroke-width: 0.1%;" /> <rect x="100.174" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
<rect x="105.739" y="116.87" width="5.56522" height="5.56522" style="fill: black; stroke: black; stroke-width: 0.1%;" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 28 KiB

After

Width:  |  Height:  |  Size: 28 KiB

@ -3,29 +3,50 @@
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
#include "QR.hpp" #include <qrcodegen.hpp>
#define UNUSED(var) (void) var; #include "util.hpp"
#include "QR.hpp"
// Version is injected through cmake // Version is injected through cmake
constexpr const char* VERSION = "@qr_VERSION@"; constexpr const char* VERSION = "@qr_VERSION@";
void printHelp() { void printHelp() {
std::string helpText = R"EOF( std::string helpText = R"EOF(
(C) 2023, MikO <miko@massivedynamic.eu>
a tool for generating QR codes
Released under MIT license.
Usage: qr is a tool for generating QR codes from the commandline
-f --format output file format. can be one of "cli, png, svg"
Usage: qr [OPTION]... --input "data to encapsulate"
*Caveats*
With no `--input` parameter defined, read STDIN
In pixel based renderers (i.e. PNG), the output code may not be exactly
centered, as the amount of segment may not correspond to the specified
output size.
Options:
-f --format output file format. can be one of "cli, png, svg, jpg, bmp"
-h --help show this help -h --help show this help
-i --input take data from this argument instead of stdin -i --input take data from this argument instead of stdin
-o --output output file name -o --output output file name without extension
-s --size desired output file size in pixels -s --size desired output file size in pixels
-t --type output QR code type. can be one of "small, medium, large" -t --type output QR code type. can be one of "small, medium, large"
-v --version shows version info
Examples:
qr -i "this is from parameter" -f png -s 512 -o my_qrcode_file
echo "this is from stdin" | qr -t small -f png -s 512 -o my_qrcode_file_with_low_ecc
In pixel based renderers (i.e. PNG), the output size may not be exactly as Copyright:
specified but be the nearest multiple of the actual cell size for the QR code. (C) 2023, MikO <miko@massivedynamic.eu>
*License*
Released under MIT license
Report bugs and issues at out issue tracker:
https://git.mike-ochmann.de/MassiveDynamic/qr/issues
)EOF"; )EOF";
std::cout << "qr " << VERSION; std::cout << "qr " << VERSION;
std::cout << helpText << std::endl; std::cout << helpText << std::endl;
@ -43,22 +64,26 @@ int main(int argc, char* argv[]) {
{"size", required_argument, nullptr, 's'}, {"size", required_argument, nullptr, 's'},
{"type", required_argument, nullptr, 't'}, {"type", required_argument, nullptr, 't'},
{"format", required_argument, nullptr, 'f'}, {"format", required_argument, nullptr, 'f'},
{"version", no_argument, nullptr, 'v'},
{nullptr} {nullptr}
}; };
std::string outputFile; std::string outputFile;
std::string paramData;
size_t segmentSize = 0; size_t segmentSize = 0;
massivedynamic::Type type = massivedynamic::Type::MEDIUM;
massivedynamic::Format format = massivedynamic::Format::CONSOLE;
bool fromStdin = true; bool fromStdin = true;
std::string paramData = ""; bool anyParameterSet = false;
qrcodegen::QrCode::Ecc type = qrcodegen::QrCode::Ecc::LOW;
massivedynamic::Format format = massivedynamic::Format::CONSOLE;
for(;;) { for(;;) {
int index = -1; int index = -1;
int result = getopt_long(argc, argv, "ho:s:t:f:i:", options, &index); int result = getopt_long(argc, argv, "vho:s:t:f:i:", options, &index);
if (result == -1) if (result == -1)
break; break;
anyParameterSet = true;
const option* opt = &options[index]; const option* opt = &options[index];
UNUSED(opt); UNUSED(opt);
switch(result) { switch(result) {
@ -74,12 +99,13 @@ int main(int argc, char* argv[]) {
case 't': { case 't': {
std::string value = optarg; std::string value = optarg;
if (value == "small") if (value == "small")
type = massivedynamic::Type::SMALL; type = qrcodegen::QrCode::Ecc::LOW;
else if (value == "medium") else if (value == "medium")
type = massivedynamic::Type::MEDIUM; type = qrcodegen::QrCode::Ecc::MEDIUM;
else if (value == "large") else if (value == "large")
type = massivedynamic::Type::LARGE; type = qrcodegen::QrCode::Ecc::HIGH;
else { else {
std::cerr << "ERROR: type (-t, --type) has to be one of 'small', 'medium' or 'large'" << std::endl;
printHelp(); printHelp();
return 1; return 1;
} }
@ -87,12 +113,17 @@ int main(int argc, char* argv[]) {
} }
case 'f': { case 'f': {
std::string value = optarg; std::string value = optarg;
static_assert(massivedynamic::FormatLength == 5, "exhaustive formats: did you miss to add something here?");
if (value == "cli") if (value == "cli")
format = massivedynamic::Format::CONSOLE; format = massivedynamic::Format::CONSOLE;
else if (value == "svg") else if (value == "svg")
format = massivedynamic::Format::SVG; format = massivedynamic::Format::SVG;
else if (value == "png") else if (value == "png")
format = massivedynamic::Format::PNG; format = massivedynamic::Format::PNG;
else if (value == "jpg")
format = massivedynamic::Format::JPG;
else if (value == "bmp")
format = massivedynamic::Format::BMP;
else { else {
printHelp(); printHelp();
return 1; return 1;
@ -104,6 +135,10 @@ int main(int argc, char* argv[]) {
paramData = optarg; paramData = optarg;
break; break;
} }
case 'v': {
std::cout << "qr " << VERSION << std::endl;
exit(0);
}
case 'h': case 'h':
default: default:
printHelp(); printHelp();
@ -127,6 +162,8 @@ int main(int argc, char* argv[]) {
if (isatty(fileno(stdin)) || data.str().empty()) { if (isatty(fileno(stdin)) || data.str().empty()) {
std::cerr << "ERROR: no data from stdinput." << std::endl; std::cerr << "ERROR: no data from stdinput." << std::endl;
if(!anyParameterSet)
printHelp();
exit(1); exit(1);
} }
} else } else
@ -142,7 +179,8 @@ int main(int argc, char* argv[]) {
return 1; return 1;
} }
std::unique_ptr<massivedynamic::QR> qr = std::make_unique<massivedynamic::QR>(data.str(), outputFile, segmentSize, type, format); std::unique_ptr<massivedynamic::QR> qr = std::make_unique<massivedynamic::QR>(data.str(), outputFile, segmentSize, type);
qr->render(format);
return 0; return 0;
} }

@ -1,45 +1,39 @@
#include <iostream> #include <iostream>
#include <vector> #include <vector>
#include "qrcodegen.hpp" #include <cassert>
#include "QR.hpp"
#include "ConsoleRenderer.hpp"
#include "PNGRenderer.hpp"
#include "SVGRenderer.hpp"
namespace massivedynamic {
QR::QR(const std::string& data, std::string outputFile, size_t size, Type type, Format format) : outputFile(std::move(outputFile)) {
qrcodegen::QrCode::Ecc errorCorrectionLevel = qrcodegen::QrCode::Ecc::HIGH;
switch(type) { #include "QR.hpp"
case Type::SMALL:
errorCorrectionLevel = qrcodegen::QrCode::Ecc::LOW;
break;
case Type::MEDIUM:
errorCorrectionLevel = qrcodegen::QrCode::Ecc::MEDIUM;
break;
default:
case Type::LARGE:
errorCorrectionLevel = qrcodegen::QrCode::Ecc::HIGH;
break;
}
qrcodegen::QrCode qr = qrcodegen::QrCode::encodeText(data.c_str(), errorCorrectionLevel); #include "renderers/ConsoleRenderer.hpp"
#include "renderers/PNGRenderer.hpp"
#include "renderers/SVGRenderer.hpp"
#include "renderers/JPGRenderer.hpp"
#include "renderers/BMPRenderer.hpp"
this->renderers.insert({Format::CONSOLE, std::make_unique<ConsoleRenderer>(this->pixels, qr.getSize(), size)}); namespace massivedynamic {
this->renderers.insert({Format::PNG, std::make_unique<PNGRenderer>(this->pixels, qr.getSize(), size)});
this->renderers.insert({Format::SVG, std::make_unique<SVGRenderer>(this->pixels, qr.getSize(), size)});
QR::QR(const std::string& data, std::string outputFile, size_t size, qrcodegen::QrCode::Ecc type) : outputFile(std::move(outputFile)),
qr(qrcodegen::QrCode::encodeText(data.c_str(), type)), size(size) {
this->pixels.reserve(this->qr.getSize() * this->qr.getSize());
// this is inherently stupid, but "qrcodegen::QrCode" does not give access to the
// `segments` vector member and the class itself is marked final.
for (int y = 0; y < qr.getSize(); y++) { for (int y = 0; y < qr.getSize(); y++) {
for (int x = 0; x < qr.getSize(); x++) { for (int x = 0; x < qr.getSize(); x++)
bool isFilled = qr.getModule(x, y); this->pixels.push_back(qr.getModule(x, y));
this->pixels.push_back(isFilled ? true : false);
} }
} }
this->renderers.at(format)->render(this->outputFile); void QR::render(Format format) {
static_assert(FormatLength == 5, "exhaustive formats: did you miss to add something here?");
switch(format) {
case Format::CONSOLE : this->renderTyped<ConsoleRenderer>(); break;
case Format::PNG : this->renderTyped<PNGRenderer>(); break;
case Format::SVG : this->renderTyped<SVGRenderer>(); break;
case Format::JPG : this->renderTyped<JPGRenderer>(); break;
case Format::BMP : this->renderTyped<BMPRenderer>(); break;
UNUSED_CASE(Format::END);
}
} }
} }

@ -2,33 +2,42 @@
#include <vector> #include <vector>
#include <string> #include <string>
#include <memory> #include <qrcodegen.hpp>
#include <unordered_map>
#include "qrcodegen.hpp" #include "util.hpp"
#include "Renderer.hpp" #include "Renderer.hpp"
namespace massivedynamic { namespace massivedynamic {
typedef uint32_t Color;
enum class Type {
SMALL,
MEDIUM,
LARGE
};
enum class Format { enum class Format {
CONSOLE, CONSOLE,
SVG, SVG,
PNG PNG,
JPG,
BMP,
END
}; };
constexpr size_t FormatLength = static_cast<size_t>(Format::END);
class QR { class QR {
private: private:
std::string outputFile; std::string outputFile;
std::vector<bool> pixels; std::vector<bool> pixels;
std::unordered_map<Format, std::unique_ptr<Renderer>> renderers; qrcodegen::QrCode qr;
size_t size;
public: public:
QR(const std::string& data, std::string outputFile, size_t size, Type type, Format format); QR(const std::string& data, std::string outputFile, size_t size, qrcodegen::QrCode::Ecc type);
QR(const QR&&) = delete;
QR(QR&) = delete;
~QR() = default;
QR& operator=(const QR&) = delete;
void render(Format format);
template<typename T>
void renderTyped() {
T renderer = T(this->pixels, this->qr.getSize(), this->size);
renderer.render(this->outputFile);
}
}; };
} }

@ -1,6 +1,8 @@
#pragma once #pragma once
#include <vector> #include <vector>
#include <string>
#include <cstddef>
namespace massivedynamic { namespace massivedynamic {
@ -11,7 +13,11 @@ class Renderer {
size_t targetSize; size_t targetSize;
public: public:
Renderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : pixels(pixels), sourceSize(sourceSize), targetSize(targetSize) {} Renderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : pixels(pixels), sourceSize(sourceSize), targetSize(targetSize) {}
Renderer(const Renderer&&) = delete;
Renderer(Renderer&) = delete;
virtual ~Renderer() = default; virtual ~Renderer() = default;
Renderer& operator=(const Renderer&) = delete;
virtual void render(const std::string& filename) = 0; virtual void render(const std::string& filename) = 0;
}; };

@ -0,0 +1,21 @@
#pragma once
#include <string>
#include "PixelRenderer.hpp"
namespace massivedynamic {
class BMPRenderer final : public PixelRenderer {
public:
BMPRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : PixelRenderer(pixels, sourceSize, targetSize) {}
virtual void render(const std::string& filename) override {
this->generateBuffer();
stbi_write_bmp((filename + ".bmp").c_str(), targetSize, targetSize, 4, this->bitmap.data());
}
};
}

@ -1,5 +1,7 @@
#pragma once #pragma once
#include <iomanip>
#include "Renderer.hpp" #include "Renderer.hpp"
namespace massivedynamic { namespace massivedynamic {
@ -10,18 +12,17 @@ class ConsoleRenderer : public Renderer {
virtual void render(const std::string&) override { virtual void render(const std::string&) override {
int border = 1; int border = 1;
std::cout << std::string(border, '\n'); std::cout << std::setfill('\n') << std::setw(border) << "";
for (int y = 0; y < sourceSize; y++) { for (int y = 0; y < sourceSize; y++) {
std::cout << std::string(border * 2, ' '); std::cout << std::string(border * 2, ' ');
for (int x = 0; x < sourceSize; x++) { for (int x = 0; x < sourceSize; x++) {
bool isFilled = pixels.at(y * sourceSize + x); bool isFilled = pixels.at(y * sourceSize + x);
std::cout << (isFilled ? "██" : " "); std::cout << (isFilled ? "██" : " ");
} }
std::cout << std::string(border * 2, ' '); std::cout << std::setfill(' ') << std::setw(border * 2) << '\n';
std::cout << '\n';
} }
std::cout << std::string(border, '\n'); std::cout << std::setfill('\n') << std::setw(border) << "";
std::cout << std::endl; std::cout.flush();
} }
}; };

@ -0,0 +1,21 @@
#pragma once
#include <string>
#include "PixelRenderer.hpp"
namespace massivedynamic {
class JPGRenderer final: public PixelRenderer {
public:
JPGRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : PixelRenderer(pixels, sourceSize, targetSize) {}
virtual void render(const std::string& filename) override {
this->generateBuffer();
stbi_write_jpg((filename + ".jpg").c_str(), targetSize, targetSize, 4, this->bitmap.data(), sizeof(Color) * targetSize);
}
};
}

@ -6,14 +6,14 @@
namespace massivedynamic { namespace massivedynamic {
class PNGRenderer : public PixelRenderer { class PNGRenderer final: public PixelRenderer {
public: public:
PNGRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : PixelRenderer(pixels, sourceSize, targetSize) {} PNGRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : PixelRenderer(pixels, sourceSize, targetSize) {}
virtual void render(const std::string& filename) override { virtual void render(const std::string& filename) override {
this->generateBuffer(); this->generateBuffer();
stbi_write_png(filename.c_str(), targetSize, targetSize, 4, this->bitmap.data(), sizeof(Color) * targetSize); stbi_write_png((filename + ".png").c_str(), targetSize, targetSize, 4, this->bitmap.data(), sizeof(Color) * targetSize);
} }
}; };

@ -2,29 +2,29 @@
#include <math.h> #include <math.h>
#include <iostream> #include <iostream>
#include <cassert>
#include "Renderer.hpp"
#define STB_IMAGE_WRITE_IMPLEMENTATION #define STB_IMAGE_WRITE_IMPLEMENTATION
#include "stb_image_write.hpp" #include <stb_image_write.hpp>
#include "util.hpp"
#include "Renderer.hpp"
namespace massivedynamic { namespace massivedynamic {
typedef uint32_t Color;
class PixelRenderer : public Renderer { class PixelRenderer : public Renderer {
protected: protected:
size_t pixelSize; size_t pixelSize;
size_t border;
std::vector<Color> bitmap; std::vector<Color> bitmap;
void drawPixelScaled(size_t x, size_t y, Color color) { void drawPixelScaled(size_t x, size_t y, Color color) {
size_t pixelSize = this->pixelSize; size_t pixelSize = this->pixelSize;
if (pixelSize < 1) { assert(pixelSize > 1 && "ERROR: output file size is too small");
std::cerr << "ERROR: output file size is too small" << std::endl;
exit(1);
}
size_t absoluteX = pixelSize * x + pixelSize; size_t absoluteX = pixelSize * x + this->border;
size_t absoluteY = pixelSize * y + pixelSize; size_t absoluteY = pixelSize * y + this->border;
for (size_t localY = absoluteY; localY < absoluteY + pixelSize; localY++) { for (size_t localY = absoluteY; localY < absoluteY + pixelSize; localY++) {
for (size_t localX = absoluteX; localX < absoluteX + pixelSize; localX++) { for (size_t localX = absoluteX; localX < absoluteX + pixelSize; localX++) {
@ -38,17 +38,13 @@ namespace massivedynamic {
WHITE = 0xFFFFFFFF WHITE = 0xFFFFFFFF
}; };
PixelRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) : Renderer(pixels, sourceSize, targetSize), pixelSize(0) { PixelRenderer(const std::vector<bool>& pixels, size_t sourceSize, size_t targetSize) :
this->targetSize = this->targetSize == 0 ? (sourceSize + 2) * 2 : this->targetSize; Renderer(pixels, sourceSize, targetSize == 0 ? (sourceSize + 2) * 2 : targetSize),
pixelSize(round(static_cast<float>(this->targetSize) / static_cast<float>(this->sourceSize + 2))),
// here we make shure, `targetSize` will be a multiple of `sourceSize` border(round(static_cast<float>(this->targetSize - this->pixelSize * this->sourceSize) / 2.0f)),
this->pixelSize = round(static_cast<float>(this->targetSize) / static_cast<float>(this->sourceSize + 2)); bitmap(std::vector<Color>(this->targetSize * this->targetSize, Colors::WHITE)) {}
this->targetSize = (this->sourceSize + 2) * this->pixelSize;
this->bitmap = std::vector<Color>(this->targetSize * this->targetSize, Colors::WHITE);
}
void generateBuffer() { virtual void generateBuffer() {
for (size_t y = 0; y < sourceSize; y++) { for (size_t y = 0; y < sourceSize; y++) {
for (size_t x = 0; x < sourceSize; x++) { for (size_t x = 0; x < sourceSize; x++) {
if (!pixels.at(y * sourceSize + x)) if (!pixels.at(y * sourceSize + x))

@ -17,14 +17,16 @@ namespace massivedynamic {
this->targetSize = sourceSize * (2 * SVGRenderer::BORDER_WIDTH); this->targetSize = sourceSize * (2 * SVGRenderer::BORDER_WIDTH);
} }
virtual void render(const std::string& filename) override { virtual void render(const std::string& filename) override {
std::stringstream file; std::ofstream file;
file.open(filename + ".svg");
std::string base = R"EOF(<?xml version="1.0" encoding="utf-8"?> std::string base = R"EOF(<?xml version="1.0" encoding="utf-8"?>
<svg version="1.1" id="qrcode" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" <!-- Generator: Massive Dynamic qr, massivedynamic::SVGRenderer -->
<svg version="1.1" id="qrcode" xmlns="http://www.w3.org/2000/svg" x="0" y="0"
)EOF"; )EOF";
file << base; file << base;
file << "viewBox=\"0 0 " << this->targetSize << " " << this->targetSize << "\" xml:space=\"preserve\">" << '\n'; file << "viewBox=\"0 0 " << this->targetSize << " " << this->targetSize << "\" width=\"" << this->targetSize << "\" height=\"" << this->targetSize << "\" xml:space=\"preserve\">" << '\n';
file << " <rect x=\"0\" y=\"0\" width=\"" << this->targetSize << "\" height=\"" << this->targetSize << "\" style=\"fill: white;\" />" << '\n'; file << " <rect x=\"0\" y=\"0\" width=\"" << this->targetSize << "\" height=\"" << this->targetSize << "\" style=\"fill: white;\" />" << '\n';
float pixelSize = static_cast<float>(this->targetSize) / static_cast<float>(this->sourceSize + 2); float pixelSize = static_cast<float>(this->targetSize) / static_cast<float>(this->sourceSize + 2);
@ -38,12 +40,9 @@ namespace massivedynamic {
} }
} }
file << "</svg>" << std::endl; file << "</svg>\n";
std::ofstream outFile; file.close();
outFile.open(filename);
outFile << file.str();
outFile.close();
} }
}; };

@ -0,0 +1,12 @@
#pragma once
#include <stdint.h>
#define UNUSED(var) (void) var;
#define UNUSED_CASE(name) case name: break;
namespace massivedynamic {
using Color = uint32_t;
}
Loading…
Cancel
Save