Coder Social home page Coder Social logo

nayuki / qr-code-generator Goto Github PK

View Code? Open in Web Editor NEW
5.1K 5.1K 1.1K 1.37 MB

High-quality QR Code generator library in Java, TypeScript/JavaScript, Python, Rust, C++, C.

Home Page: https://www.nayuki.io/page/qr-code-generator-library

Java 35.03% Python 8.28% HTML 1.32% C++ 9.12% C 16.24% Makefile 0.81% Rust 19.20% TypeScript 9.78% Shell 0.22%
c c-plus-plus java javascript library python qr qr-code qr-generator rust typescript

qr-code-generator's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

qr-code-generator's Issues

Feature Request: Please consider expanding project scope to include decoding

First off, I really like what you've done with your QR-code-generator project.

I came across your work while searching (web + GH + BB) for pure python-based programs to handle QR code decoding / encoding. Much as you describe in your writeup [1], I found a lot of projects with sub-optimal dev choices---too many external dependencies, insufficient documentation (internal comments and external manuals / examples), incomplete or unfaithful compliance with Denso-Wave and ISO/IEC 18004 standards (models 1&2)---some don't even implement Reed-Solomon. Anyway, kudos to you for a really clean and concise project:

  • for clearly defined API;
  • for simultaneous / equal coverage across four in-demand languages;
  • for complete coverage of all 40 versions and 4 EC levels;
  • for avoidance of magic constants;
  • for flexible (MIT) license selection; and
  • for sensible choices about what portions of encoding are included in your library (ie, 3-11 of your "generation procedure" [1]) and what are left up to implementation by library user.

In short, thanks for what you've shared with the O/S community here.

All that being said, I hope to motivate you to please consider expanding your project to include decoding of QR-Codes. If anything, there's an even more limited ecosystem of open-source QR-code decoders, compared to that of QR-Code encoders. In the python world, at least, there's pretty much only ZBar (or a multitude of projects which depend upon it); and ZBar's last stable release was in 2009, with no code checkins since 2012 (and it doesn't support modern Python). Of course, there's also a Python port of ZXing (from native Java), but ZXing is a large (~70k LOC!), all-encompassing framework. While there are obviously additional decoders in your other target languages (JS, Java, C++), I believe there are similarly fewer choices there, compared to the situation with encoders.

Given what I can sense of your philosophy with this project, I assume you'd consider any type of QR-code image manipulation (necessary for "full-stack" decoding from the analog world) to be well outside of scope, and I'm not suggesting otherwise as part of this feature request: scope would still exclude image capture, deskewing / perspective-correction / contrast-tuning, and (finally) conversion of pixels into a vector QR-code (ie, SVG). For example, just as you provide the 'to_svg_str()' function in your QRCode class as the final output stage (after which user-code takes over to otherwise manipulate QR codes), perhaps the appropriate scope to accept input for decoding would be a similar 'from_svg_str()' function, or just a logical 2D numeric array (representing input to be decoded). This would leave all bitmap->vector image manipulation external to your library, and instead in user-supplied code (through custom libraries, PIL/imagemagick, opencv3, etc).

I look forward to your consideration of this feature request, though it significantly expands the scope of your library. If it's beyond the itch you're proverbially scratching here, I'll continue to enjoy using your library for encoding only.

Thanks, and best wishes for continued success with this (and other) projects!

[1] https://www.nayuki.io/page/qr-code-generator-library

needs different names for the C vs. C++ libs

AFAICS:

C lib: libqrcodegen.a
C++ lib: libqrcodegen.a

Which would conflict when both installed in /usr/lib (to use this lib)

Debian (as I found out, I am not the maintainer of the package) has https://sources.debian.org/src/qr-code-generator/1.4.0-1/debian/patches/cpp-lib.patch/?hl=25#L25 as a patch to rename the C++ lib to libqrcodegencpp.

[ and it also invents a shared library, this is not ideal, but... Probably because unox uses the lib, too - could have built against a static library, too.... ]

Resize functionality to the QR code.

Right now in the current implementation, the output of the qrCode depends on the version. Is there a way where we can leverage the current implementation and generate qr code based on user input Eg generate 200*200 pixel QR code?

Tag releases

Please tag your releases, so they can be seen on GitHub. If you have none, let's create some. 😄

There, you may also provide a minified version of the JS version. 😄

New release?

I think that it would be good to flush currently committed changes and make new release :)

Looks like already at least few distributions are no longer using regular 1.5.0.

Operator = function is unavailable in qrcodegen::QrSegment

Thanks for this library!
I could not compile the C++ variant on Visual Studio 2013, 64bit

error C2582: 'operator =' function is unavailable in 'qrcodegen::QrSegment' (C:\DEVELOPMENT\ioxp.git\src\common\cv\qrcodegen\QrCode.cpp)
...
QrCode.cpp(59) : see reference to function template instantiation 'std::vector<qrcodegen::QrSegment,std::allocator<_Ty>>::vector(std::initializer_listqrcodegen::QrSegment,const std::allocator<_Ty> &)' being compiled
...
QrCode.cpp(53) : see reference to class template instantiation 'std::vector<qrcodegen::QrSegment,std::allocator<_Ty>>' being compiled

The operator = is not available because of the non-static const members in QrSegment and QrSegment::Mode.

Wrong architecture (C++; MacOS)

I am using MacOSX and I get the following error:

Undefined symbols for architecture x86_64:
  "qrcodegen::QrCode::encodeText(char const*, qrcodegen::QrCode::Ecc)", referenced from:
      _main in qrgenerator-237992.o
  "qrcodegen::QrCode::getModule(int, int) const", referenced from:
      _main in qrgenerator-237992.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

I use g++ as my compiler

Feature: embed image/logo

Many other QR generators (typically online versions) give an option to trade some redundancy data for the option of embedding an image in the middle of the QR code - would this be possible?

Just an idea for a "nice to have" feature, probably shouldn't be too hard to implement (apart from validating the image to make sure it doesn't ruin the readability of the data in any way).

The drawing itself could be done similarly to what's discussed in this answer: https://stackoverflow.com/a/11148571 seeing as you already use BufferedImage in the toImage function.

How to save the generated QR code image?

Hi. Thanks for publishing this useful library.

I want to use it in C++. The QrCodeGeneratorDemo.cpp only shows how to print it in the console. Is there any way to save the image instead of printing in the console?

Thanks for your works

I use your qrcodegen C++ codes in my recently project.
It's a test program running on an Android based device, which start up directly from init process(configured in init.factory-mode.rc).

Great Thanks for your works!

BR

Siwei Xu(at Hangzhou, China)

need help

How qrcode are generated tell me that and in which c compiler you are compiling your code i want to know that?

Make Java generator as a library

Thanks for this lightweight QR code generator!

Are you interested in making Java generator as a library? I can add gradle/maven config and make platform specific features (like Android specific feature) if you wish.

Some warnings

When compiling with x86_64-w64-mingw32-gcc (GCC) 6.3.0

$ make
/usr/bin/x86_64-w64-mingw32-gcc.exe -std=c99 -O3 -Wall -fPIC -shared -o libqrcodegen.so qrcodegen.c

qrcodegen.c: In function 'numCharCountBits':
qrcodegen.c:1023:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
qrcodegen.c:1017:83: warning: 'i' may be used uninitialized in this function [-Wmaybe-uninitialized]
   case qrcodegen_Mode_ALPHANUMERIC: { const int temp[] = { 9, 11, 13}; return temp[i]; }
                                                                               ~~~~^~~
qrcodegen.c: In function 'drawFormatBits':
qrcodegen.c:435:14: warning: 'data' may be used uninitialized in this function [-Wmaybe-uninitialized]
  data = data << 3 | (int)mask;  // ecl-derived value is uint2, mask is uint3
         ~~~~~^~~~
qrcodegen.c: In function 'applyMask':
qrcodegen.c:545:4: warning: 'invert' may be used uninitialized in this function [-Wmaybe-uninitialized]
    setModule(qrcode, x, y, val ^ invert);
    ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
qrcodegen.c: In function 'qrcodegen_encodeSegmentsAdvanced':
qrcodegen.c:931:3: warning: 'modeBits' may be used uninitialized in this function [-Wmaybe-uninitialized]
   appendBitsToBuffer(modeBits, 4, qrcode, &bitLen);
   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Add CMakeLists.txt file

It would make building on windows very easy, as some developers use cmake instead of autotools. I would be happy to contribute by providing a CMakeLists file.

/.../QrCode.cpp:400: error: 'INT32_MAX' was not declared in this scope int32_t minPenalty = INT32_MAX; ^

Hi!

Got the following compile error:

/.../QrCode.cpp:400: error: 'INT32_MAX' was not declared in this scope int32_t minPenalty = INT32_MAX; ^
For this line: int32_t minPenalty = INT32_MAX;
In int qrcodegen::QrCode::handleConstructorMasking(int mask)

when building with Android NDK. I think it is easy to fix, but since I am on Qt I will just replace all int32_t with qint32 and matching Qt primitives (to have portability for free), so my fix won't be useable by anyone else.

heap-buffer-overflow in the C implementation

I set up fuzzing for the project and quickly found a heap-buffer-overflow in the c implementation.

The fuzz target I wrote:

#include <stdbool.h>
#include <stdint.h>
#include "qrcodegen.h"

#ifdef __cplusplus
extern "C" {
#endif

int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {

  uint8_t qr0[qrcodegen_BUFFER_LEN_MAX];
  bool ok = qrcodegen_encodeBinary((uint8_t *) Data, Size, qr0, qrcodegen_Ecc_MEDIUM, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_4, true);
  if (!ok)
      return 1;

  return 0;
}

#ifdef __cplusplus
}
#endif

The ouput generated by libFuzzer and Address Sanitizer:

==11==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000091 at pc 0x00000055c694 bp 0x7ffcd6876f30 sp 0x7ffcd6876f28
WRITE of size 1 at 0x602000000091 thread T0
SCARINESS: 31 (1-byte-write-heap-buffer-overflow)
    #0 0x55c693 in addEccAndInterleave /src/libqrcodegen/c/qrcodegen.c:316:14
    #1 0x55c693 in qrcodegen_encodeSegmentsAdvanced /src/libqrcodegen/c/qrcodegen.c:259:2
    #2 0x55e43f in qrcodegen_encodeBinary /src/libqrcodegen/c/qrcodegen.c:179:9
    #3 0x55413d in LLVMFuzzerTestOneInput /src/libqrcodegen/c/encodeBinary_fuzzer.c:12:13
    #4 0x459d61 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
    #5 0x45bc65 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:743:3
    #6 0x45c229 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:792:3
    #7 0x44a638 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:824:6
    #8 0x474462 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
    #9 0x7efcb09d482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #10 0x41dcf8 in _start (/out/encodeBinary_fuzzer+0x41dcf8)

0x602000000091 is located 0 bytes to the right of 1-byte region [0x602000000090,0x602000000091)
allocated by thread T0 here:
    #0 0x5218fd in malloc /src/llvm-project/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
    #1 0x432b67 in operator new(unsigned long) (/out/encodeBinary_fuzzer+0x432b67)
    #2 0x45bc65 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:743:3
    #3 0x45c229 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:792:3
    #4 0x44a638 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:824:6
    #5 0x474462 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
    #6 0x7efcb09d482f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/libqrcodegen/c/qrcodegen.c:316:14 in addEccAndInterleave
Shadow bytes around the buggy address:
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff8000: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa 00 fa
=>0x0c047fff8010: fa fa[01]fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==11==ABORTING
MS: 0 ; base unit: 0000000000000000000000000000000000000000

This bug is being triggered, with zero-length input, but it also occured when forcing the fuzzer to use bigger inputs (eg. putting if (Size < 40) return 0; as the first line.

C4458 warnings in QrCode.cpp

While compiling current master using VS2019 I'm getting the following warnings:

QrCode.cpp(262,39): warning C4458: declaration of 'mask' hides class member
QrCode.hpp(129,15): message : see declaration of 'qrcodegen::QrCode::mask'
QrCode.cpp(413,34): warning C4458: declaration of 'mask' hides class member
QrCode.hpp(129,15): message : see declaration of 'qrcodegen::QrCode::mask'

Color support

I am considering using your great library for my QR code generator browser add-on.

However I miss one feature: Could you maybe add color support for background and QR code itself?

As for the SVG changing it afterwards may be quite easy (though as an option it would not hurt anyway), but as for the Canvas that is not so easy.

Cross Platform Support For Cpp makefile (Unable to build on Windows)

Hi, currently I am trying to use this library for generating qr code from my cpp program complied with mingw64 on windows. But on using mingw32-make I get these errors:
mkdir -p .deps
touch .deps/timestamp
process_begin: CreateProcess(NULL, touch .deps/timestamp, ...) failed.
make (e=2): The system cannot find the file specified.
mingw32-make: *** [Makefile:82: .deps/timestamp] Error 2

Please help.. I think its due makefile thats written for linux...
Moderators and Contributors to this project Please add support for cmake or any other cross platform utilities..
Thanks..

Error in Makefile using (ar) utility for Mac.

The Makefile contains the following (on line 72)
$(LIBFILE): $(LIBOBJ) $(AR) -crs $@ -- $^
The command fails on MacOS High Sierra because the ar utility does not recognize the -- as valid syntax. Removing the double dash, solved the issue for me.

Allow different dot/square designs

I have seem some QR codes that for each black square, the squares edges are rounded. This makes for a different and more aesthetic look.
Attaching a picture to show what I mean.

To allow different designs of the squares would be really nice

2020-02-11 17_19_53-Photos

Base64 png for c++

Thanks a lot for this superb work!!!

I am trying to write node js addon in c++ and want to save QRcode image in base64 format.

I have to generate more than 100000 QR codes at once, any possible solution will be helpful.

Thanks in advance.

drawCanvas's scale parameter is confusing

qrElem.drawCanvas(scale, border, canvas);

The parameters:

  • scale – I thought 1 would maybe not increase the Camvas, but if you draw the result on 500px, this get's really blurry…
  • border – Just 0… I mean, this is not the quiet zone, this is a real black border or what? (Don't see a use case for that, but fine.)

Why can't I just pass in the pixel size of my wanted canvas?


Looking in the code I see that it somehow calculates the width based on some internal size. However, I have no idea what size is set there, as usually this lib is used for SVG generation – but SVGs hardly have a size, they scale… 🤔 (At least the user does not input any size.)

So what do I need to pass in to get a non-blurry canvas for a canvas of a given size?

I've also tried random big numbers, and it seems to fail around > 200 for that parameter.

qrcodegen.js doesnt support version 40 qrcodes

qrcodegen.js
line 560

if (version >= maxVersion)  // All versions in the range could not fit the given data
   throw "Data too long";

should be

if (version > maxVersion)  // All versions in the range could not fit the given data
   throw "Data too long";

C++ compile has warnings

When I compile the C++ version I get:

qr-code-generator\qrcode.cpp(429): warning C4701: potentially uninitialized local variable 'colorX' used
qr-code-generator\qrcode.cpp(433): warning C4701: potentially uninitialized local variable 'runX' used
qr-code-generator\qrcode.cpp(445): warning C4701: potentially uninitialized local variable 'colorY' used
qr-code-generator\qrcode.cpp(449): warning C4701: potentially uninitialized local variable 'runY' used

Also:

QR-Code-generator/BitBuffer.cpp: In member function 'std::vector<unsigned char> qrcodegen::BitBuffer::getBytes() const':
QR-Code-generator/BitBuffer.cpp:39:24: error: conversion to '__gnu_cxx::__alloc_traits<std::allocator<unsigned char> >::value_type {aka unsigned char}' from 'int' may alter its value [-Werror=conversion]
         result[i >> 3] |= (*this)[i] ? 1 << (7 - (i & 7)) : 0;
                        ^
QR-Code-generator/QrCode.cpp: In constructor 'qrcodegen::QrCode::ReedSolomonGenerator::ReedSolomonGenerator(int)':
QR-Code-generator/QrCode.cpp:696:36: error: conversion to '__gnu_cxx::__alloc_traits<std::allocator<unsigned char> >::value_type {aka unsigned char}' from 'int' may alter its value [-Werror=conversion]
                 coefficients.at(j) ^= coefficients.at(j + 1);
                                    ^
QR-Code-generator/QrCode.cpp: In member function 'std::vector<unsigned char> qrcodegen::QrCode::ReedSolomonGenerator::getRemainder(const std::vector<unsigned char>&) const':
QR-Code-generator/QrCode.cpp:713:26: error: conversion to '__gnu_cxx::__alloc_traits<std::allocator<unsigned char> >::value_type {aka unsigned char}' from 'int' may alter its value [-Werror=conversion]
             result.at(j) ^= multiply(coefficients.at(j), factor);

Format information generation and placement

I'm using qrduino by @tz1 to generate QR codes. In Qrduino, the format information is generated and inserted only after choosing a mask: https://github.com/tz1/qrduino/blob/master/qrencode.c#L523

In your project (C version) you have:

	if (mask == qrcodegen_Mask_AUTO) {  // Automatically choose best mask
		long minPenalty = LONG_MAX;
		for (int i = 0; i < 8; i++) {
			enum qrcodegen_Mask msk = (enum qrcodegen_Mask)i;
			drawFormatBits(ecl, msk, qrcode);
			applyMask(tempBuffer, qrcode, msk);

which seems to be inserting the format information with drawFormatBits before masking. Your web page here: https://www.nayuki.io/page/creating-a-qr-code-step-by-step

also suggests inserting the format string before masking: "Draw the actual format bits (adjacent to the finders):"

To try to find out which approach is correct, I had a look at the spec. According to page 18 of the spec (Information technology — Automatic identification and data capture techniques — QR Code 2005 bar code symbology specification), it says:

Step 6 Data masking

Apply the data masking patterns in turn to the encoding region of the symbol. Evaluate the results and select the pattern which optimizes the dark/light module balance and minimizes the occurrence of undesirable patterns.

Step 7 Format and version information

Generate the format information and (where applicable) the version information and complete the symbol.

Can you justify why you are calculating the format information and inserting it before the mask operation from the spec?

Originally I was going to report this as a bug to Qrduino, but although I don't understand why the format information would be omitted when calculating the penalties, it does look like Qrduino is correct to me from reading the spec. The illustration in figure 23 of the spec also seems to not show the format information when calculating the mask:
formatinfo
It just has blank white there. This is different from the thing you're showing on the web site, where you show penalties being calculated with the format information in place.

OSS-Fuzzing Support

I implemented a first version of OSS-Fuzzing support at https://github.com/dende/QR-Code-generator and https://github.com/dende/oss-fuzz/tree/libqrcodegen/projects/libqrcodegen.

If you're interested, you can want to you can merge my branch and give me feedback on the project integration at oss-fuzz so I can create a merge request there.

If you want to integrate into OSS-Fuzz, setting up fuzz targets with different configurations and for the C++ implementation would also be interesting

Output result in fixed size (javascripts)

Is it possible to change the demo so that the output image has a fixed size (for saving in png), let's say 350x350, 230x230, 120x120, etc. px? So that the picture does not increase after entering information.

Enhancement: 3x performance boost using block chars instead of canvas

Updates Per Second

Elements Canvas Div Block Chars
1 30 76
8 3 9

Tested Configuration

  • OS: Windows 10
  • Hardware: Dell XPS27 (3GHz i7 8GB RAM)
  • QR Code
    • Data: 985 random binary chars
    • Version: 40
    • ECC: LOW
    • Boost Ecc: OFF

** Other Considerations **

  • using a single canvas would probably not speed things up since most of the time is spend doing the drawing in drawCanvas
  • using a single div would probably speed things up since only one Dom update would be required for N QR codes on the screen
  • Canvas can't take advantage of web workers except in firefox

Code Changes

Here are the changes to add support for block characters (only tested this with binary data)

  1. Add a getter for modules:
        this.getModules = function() {  modules; };
  1. add this method to render using block characters instead of canvas
var QRCHARS = (function()  {        // https://en.wikipedia.org/wiki/Block_Elements
  var CHR_SPACE     = '&#x00A0;' ;  // white and white
  var CHR_LOWER     = '&#x2584;' ;  // white and black (Lower half block)		 
  var CHR_UPPER     = '&#x2580;' ;  // black and white (Upper half block)
  var CHR_BLOCK     = '&#x2588;' ;  // black and black (Full block)			  
  var BLOCK_HEIGHT  = 2             // each block char has 2 bits, upper and lower
  
  // imgBitMap[column][row]  true=BLACK, false=WHITE
  var qrCodeChars =  function(imgBitMap) {
    var result        = [];
    var height        = imgBitMap.length;
    var width         = imgBitMap[0].length;
    for(var row = 0; row < height; row += BLOCK_HEIGHT) {                     // blocks are 2 bits tall, top and bottom
      for(var col = 0; col < width; col += 1) {				       
        var bottom = row + 1 < height ? imgBitMap[col][row + 1] : false;      // bottom block is down one row in the image
        result.push( imgBitMap[col][row] ? ( bottom  ? CHR_BLOCK : CHR_UPPER ) : ( bottom  ? CHR_LOWER : CHR_SPACE ) )  ;     
      }
      result.push('<br/>');
    }  
    return result.join(''); 
  }
  return qrCodeChars;
})();
  1. Style the rendered block chars
<style>
div {
  font-family:Consolas,Monaco,Lucida Console,Liberation Mono,DejaVu Sans Mono,Bitstream Vera Sans Mono,Courier New, monospace;
  font-size:6px;
  line-height:1em; 
  letter-spacing:0em;   
  padding:30px;
  display:inline-block;
}
</style>
  1. Instead of calling qr.drawCanvas, render to a div like this:
      var el = document.createElement('div');
      el.innerHTML=QRCHARS(qr.getModules())     

QrSegmentAdvanced can produce sub-optimal results for Shift JIS

First off thanks for the super algorithm for optimizing encoding modes, which is now being used in a number of places in Zint.

An issue I noticed while adapting it is that Byte mode in computeCharacterModes() assumes UTF-8 encoding. For instance the "kanji/European" example string "こんにちwa、世界! αβγδ", which is fully encodable in Shift JIS, produces a segmentation of "K4 B2 K4 A1 K4", for a bit length of 239. A shorter segmentation is a single Shift JIS encoded segment "B27", with a bit length of 228.

global-buffer-overflow in the C++ implementation

The following fuzz target finds a global-buffer-overflow in the C++ implementation:

#include <cstdlib>
#include "QrCode.hpp"


extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
  if (Size < 2) {
    return 0;
  }

  auto ecc_byte = (int) Data[0];
  Data++;Size--;


  std::vector<uint8_t> dataVector(Data, Data + Size);
  qrcodegen::QrCode::Ecc ecl = static_cast<qrcodegen::QrCode::Ecc> (ecc_byte % 5);
  auto qr = qrcodegen::QrCode::encodeBinary(dataVector, ecl);

  return 0;
}

The first byte of the random input is used to randomize the error correction level.

==11==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000006011a5 at pc 0x00000055c719 bp 0x7fff9fa774f0 sp 0x7fff9fa774e8
READ of size 1 at 0x0000006011a5 thread T0
SCARINESS: 12 (1-byte-read-global-buffer-overflow)
    #0 0x55c718 in getNumDataCodewords /src/libqrcodegen/cpp/QrCode.cpp:733:5
    #1 0x55c718 in qrcodegen::QrCode::encodeSegments(std::__1::vector<qrcodegen::QrSegment, std::__1::allocator<qrcodegen::QrSegment> > const&, qrcodegen::QrCode::Ecc, int, int, int, bool) /src/libqrcodegen/cpp/QrCode.cpp:263:26
    #2 0x55d365 in qrcodegen::QrCode::encodeBinary(std::__1::vector<unsigned char, std::__1::allocator<unsigned char> > const&, qrcodegen::QrCode::Ecc) /src/libqrcodegen/cpp/QrCode.cpp:251:9
    #3 0x554ff4 in LLVMFuzzerTestOneInput /src/encode_binary_cpp_fuzzer.cpp:14:13
    #4 0x45aba1 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:556:15
    #5 0x45a2c5 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool*) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:470:3
    #6 0x45c667 in fuzzer::Fuzzer::MutateAndTestOne() /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:698:19
    #7 0x45d3f5 in fuzzer::Fuzzer::Loop(std::__Fuzzer::vector<fuzzer::SizedFile, fuzzer::fuzzer_allocator<fuzzer::SizedFile> >&) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerLoop.cpp:830:5
    #8 0x44b478 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerDriver.cpp:824:6
    #9 0x4752a2 in main /src/llvm-project/compiler-rt/lib/fuzzer/FuzzerMain.cpp:19:10
    #10 0x7fdb36a0582f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #11 0x41eb38 in _start (/out/encode_binary_cpp_fuzzer+0x41eb38)

0x0000006011a5 is located 59 bytes to the left of global variable '<string literal>' defined in 'QrCode.cpp:717:27' (0x6011e0) of size 28
  '<string literal>' is ascii string 'Version number out of range'
0x0000006011a5 is located 1 bytes to the right of global variable 'qrcodegen::QrCode::ECC_CODEWORDS_PER_BLOCK' defined in 'QrCode.cpp:829:22' (0x601100) of size 164
SUMMARY: AddressSanitizer: global-buffer-overflow /src/libqrcodegen/cpp/QrCode.cpp:733:5 in getNumDataCodewords

Pure JavaFX WriteImage code

added this code for my project ... so thought I would give it back to you .. I couldn't use any AWT classes which BufferedImage is ...

 public WritableImage toWritableImage(int scale, int border)
    {
        if (scale <= 0 || border < 0)
        {
            throw new IllegalArgumentException("Value out of range");
        }
        WritableImage image = new WritableImage((size + border * 2) * scale, (size + border * 2) * scale);
        for (int y = 0; y < image.getHeight(); y++)
        {
            for (int x = 0; x < image.getWidth(); x++)
            {
                boolean val = getModule(x / scale - border, y / scale - border);
                image.getPixelWriter().setColor(x, y, val ? Color.BLACK : Color.WHITE);
            }
        }
        return image;
    }

Converting qrcode to Raw image buffer (RGBA_8888)

Hello

Thank you for the amazing work. I have a requirement in my project where I have to generate QR code and display it on a screen, but I am stuck because I don't have any experience with graphics. Perhaps you can help me with this problem?

Problem: We have following API which takes the raw image buffer of pixels in the RGBA_8888 format and draw it in the screen. So I could use qrcodegen_encodeText("Helloworld", tempBuffer, qrcode, errCorLvl, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, true); and then how do I convert qrcode to Raw image buffer (C Structure RawImage_t shown below) with Pixel format RGBA_8888?

Following is the API and RawImage_t format description. I would really appreciate if you can give pointers on how to do this? Thanks a lot in advance.

**
 * @brief                   Draw a raw image buffer of pixels at (dx:dy) into a drawing buffer. This function requires a valid graphic context. The pixel format is fixed to RGBA_8888 (red channel  first in memory).
 */
Result DrawBufferOnScreen(
    GraphicContext_t graphicContext,  //Graphic context.
    const RawImage_t *pRawImage ,  // Raw image buffer to be drawn.
    int32_t dx,                                  //X coordinates of the top-left corner of the raw image
    int32_t dy);                               //  Y coordinates of the top-left corner of the raw  image 

typedef struct {
    void        *data;      /**< A buffer containing the pixels. */
    uint32_t    size;       /**< Size of the buffer. */
    uint32_t    pixelFormat;/**< Pixel format in RGBA_8888 */
    uint32_t    stride;     /**< Image stride (number of bytes in the buffer
                              between the beginning of a line and the beginning
                              of the next line). */
    uint32_t    width;      /**< Image width in pixels. */
    uint32_t    height;     /**< Image height in pixels. */
} RawImage_t, *RawImage_ptr;

Is it possible to set ECI header (encoding hint) when using BYTE mode

Hello,

we are using the javascript version of your library to generate QR code that contains binary data. We read such barcode in an Android application that uses Google Machine vision library (com.google.android.gms.vision.barcode package...).

The library does not correctly decode the binary payload. Googling around it appears that the machine vision library assumes that binary payload contains UTF8 bytes unless code contains an ECI header providing alternative encoding (in our case ISO-8859-1 will solve the issue). Is there any way we can set such ECI header using your javascript library.

We thank you for this project, as we found it well documented and easy to use.

Unresolved external symbol while compiling the example with Visual Studio 2017 C++

Hello,

I've used the code from the example to try out the library but compiler throws out an error saying there are unsupported external symbols for both of the lines in the example. I've included the directory where the source is located and it does not show any errors regarding the functions or variables.

My code:

 #include "stdafx.h"
 #include <string>
 #include <vector>
 #include "QrCode.hpp"
 using namespace qrcodegen;

 int main()
 {
 	// Simple operation
	QrCode qr0 = QrCode::encodeText("Hello, world!", QrCode::Ecc::MEDIUM);
	std::string svg = qr0.toSvgString(4);

	return 0;
}

image

Invalid encoding with certain strings in C++ version of the code

I've been running into problems with some text strings with the C++ version

I'm running on both x86 and ARM, so its not an architecture issue

Here's how I'm creating the QRCode

std::vector<QrSegment> segs = QrSegment::makeSegments(getQRString());
QrCode qr1 = QrCode::encodeSegments(segs, QrCode::Ecc::HIGH);
code = new QrCode(qr1, -1);
MSG("version = %d mask %d ECC %d\n", code->getVersion(), code->getMask(), code->getErrorCorrectionLevel().getOrdinal() )

This string will not encode correctly

This project aims to be the best, clearest library for generating QR Codes. My primary goals are flexible options and

Encoded on your website, using MEDIUM reports (which generates a correct QRCode) reprots

QR Code version = 7, mask pattern = 6, character count = 117, encoding mode = byte, error correction = level M, data bits = 948

however, the C++ code reports version 4, mask 2, ECC 1

Some strings work fine, but from the testing I've done, it looks like the code incorrectly transitions to different versions at different times to the website version, and encodings will fail

This string works, and reports version 6, mask 2, ECC 1

This project aims to be the best, clearest library for generating QR Codes. My primary goals

Javascript qrcodegen module is browser global only

It would be nice to also be able to load this module as

  • commonjs module (usage through webpack & browserify bundlers)
  • AMD module
    and also ensure distribution through npm.

This project provide some hints on how to provide "universal module definition"

To allow usage through commonjs, I just added a line to your code. But it would be better not to have to modify library code.

Bests,
Marc

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.