Hi
Has anyone coded something to generate and read QR codes?
Is there an interface to an existing library that can be used in asm? :rolleyes:
Biterider
https://github.com/nayuki/QR-Code-generator
https://www.nayuki.io/page/qr-code-generator-library#compared-to-competitors (half a dozen libraries described)
some one posted the dll's and QT5 gui front end for zint https://www.planetsquires.com/protect/forum/index.php?topic=4675.0
Quote from: jack on November 21, 2022, 08:40:58 AM
some one posted the dll's and QT5 gui front end for zint https://www.planetsquires.com/protect/forum/index.php?topic=4675.0
libzint.dll at 760kBytes. Ridiculously bloated for such a simple task :cool:
About 40 years ago I wrote a barcode generator in 68000 Assembly, but I've lost the source :sad:
A fast and compact QR Code encoding library - https://github.com/fukuchi/libqrencode or https://github.com/fukuchi/libqrencode/archive/refs/tags/v4.1.1.zip
Quote from: LiaoMi on November 22, 2022, 08:39:15 AM
A fast and compact QR Code encoding library - https://github.com/fukuchi/libqrencode or https://github.com/fukuchi/libqrencode/archive/refs/tags/v4.1.1.zip
Can you make a DLL out of that? My C/C++ installation is broken :sad:
here's the 64-bit dll
but there were a number of warnings while compiling
Thanks, Jack. In the meantime, I found a 32-bit version here (https://www.dll-files.com/libqrencode.dll.html), and it works:
include \masm32\MasmBasic\MasmBasic.inc
Init
Dll "libqrencode.dll"
Declare QRcode_APIVersionString
PrintLine QRcode_APIVersionString()
EndOfCode
Output: 3.9.0
Yours is version 4.1.1 (tests attached)
sure
Thanks a lot, Jack :thumbsup:
There is documentation here (https://fukuchi.org/works/qrencode/manual/qrencode_8h.html), e.g. for QRcode_encodeString (https://fukuchi.org/works/qrencode/manual/qrencode_8h.html#a4cebc3c670efe1b8866b14c42737fc8f)
Usage example here (https://www.gambas-it.org/smf/index.php?topic=2864.5;wap2) :cool:
Hi
I've been experimenting a bit with the Nayuki project. Very straight forward API and easy to translate. :thumbsup:
I had to do a bit of tweaking replacing CRT functions to build the static libraries, but in the end everything works as expected.
Biterider
Quote from: Biterider on November 22, 2022, 11:13:48 PM
I've been experimenting a bit with the Nayuki project. Very straight forward API and easy to translate. :thumbsup:
Great. I am playing with libqrencode.dll, QRcode_encodeString does return a bitmap handle (?), but I can't get it to display anything :sad:
P.S.: This doc (https://fukuchi.org/works/qrencode/manual/structQRcode.html) says it's not a bitmap handle but rather a pointer to a structure :rolleyes:
QRCODE STRUCT
qrcVersion dd ?
qrcWidth dd ?
qrcData dd ?
QRCODE ENDS
qrcData points to an array of chars; only bit 0 is relevant, it's black or white (not surprisingly).
One C example parsing data
https://gist.github.com/syohex/b1aa695dc6ac5dced139
Yep, that's it, thanks Timo :thumbsup:
int v = (*data & 1) ? 1 : 0;
Quote from: Biterider on November 22, 2022, 11:13:48 PM
I've been experimenting a bit with the Nayuki project.
How big is the dll?
Hi JJ
I compiled the source code to create static libraries.
The 64-bit .lib file is 48 KB.
Biterider
Biterider, did you also build qrencode.exe the command-line front-end ?
did you use Visual studio ?
I tried building zint with visual C but failed due to the library dependencies of libpng and zlib, even though I had built said libraries, but no matter what I tried I could not get it to work
Hi jack
I just built the static libraries and compiled the .h file.
As mentioned, I had to remove all CRT dependencies and replace C functions with ObjMem procedures.
To render the QR-Code first run qrcodegen_encodeText and then draw it using standard GDI APIs.
Method Application.OnPaint, uses xsi, wParam:WPARAM, lParam:LPARAM
local PS:PAINTSTRUCT, hDC:HDC, Rct:RECT
local qrcode[qrcodegen_BUFFER_LEN_MAX]:BYTE, tempBuffer[qrcodegen_BUFFER_LEN_MAX]:BYTE
QR_BORDER = 4
QR_OFFSET_X = 25
QR_OFFSET_Y = 25
QR_CELL_SIZE = 5
SetObject xsi
mov hDC, $invoke(BeginPaint, [xsi].hWnd, addr PS)
invoke GetClientRect, [xsi].hWnd, addr Rct
invoke DrawEdge, hDC, addr Rct, EDGE_SUNKEN, BF_RECT
invoke qrcodegen_encodeText, $OfsCStrA("Hello ObjAsm World", 21h), addr tempBuffer, addr qrcode, \
qrcodegen_Ecc_LOW, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, \
qrcodegen_Mask_AUTO, TRUE
.if eax != FALSE
invoke QrDraw, hDC, addr qrcode, QR_OFFSET_X, QR_OFFSET_Y, QR_CELL_SIZE, QR_BORDER
.endif
invoke EndPaint, [xsi].hWnd, addr PS
xor eax, eax
MethodEnd
QrDraw proc uses xbx xdi xsi hDC:HDC, pQrCode:POINTER, sdX:SDWORD, sdY:SDWORD, dSize:DWORD, dBorder:DWORD
local Rct:RECT, dQrSize:DWORD, hBlackBrush:HBRUSH
local qrcode[qrcodegen_BUFFER_LEN_MAX]:BYTE, tempBuffer[qrcodegen_BUFFER_LEN_MAX]:BYTE
mov eax, sizeof(qrcode)
invoke qrcodegen_getSize, pQrCode
mov dQrSize, eax
mov ecx, dBorder
shl ecx, 1
add eax, ecx
mov ecx, dSize
xor edx, edx
mul ecx
mrm Rct.left, sdX, edx
add edx, eax
mov Rct.right, edx
mrm Rct.top, sdY, edx
add edx, eax
mov Rct.bottom, edx
invoke GetStockObject, WHITE_BRUSH
lea xdx, Rct
invoke FillRect, hDC, xdx, xax
invoke GetStockObject, BLACK_BRUSH
mov hBlackBrush, xax
xor edi, edi
.while edi < dQrSize
xor ebx, ebx
.while ebx < dQrSize
invoke qrcodegen_getModule, pQrCode, ebx, edi
.if eax != 0
mov eax, ebx
add eax, QR_BORDER
mov ecx, QR_CELL_SIZE
xor edx, edx
mul ecx
add eax, QR_OFFSET_X
mov Rct.left, eax
add eax, QR_CELL_SIZE
mov Rct.right, eax
mov eax, edi
add eax, QR_BORDER
mov ecx, QR_CELL_SIZE
xor edx, edx
mul ecx
add eax, QR_OFFSET_Y
mov Rct.top, eax
add eax, QR_CELL_SIZE
mov Rct.bottom, eax
lea xdx, Rct
invoke FillRect, hDC, xdx, hBlackBrush
.endif
inc ebx
.endw
inc edi
.endw
ret
QrDraw endp
Attached the .inc file and the 2 libraries. ObjMem.lib is required! :biggrin:
Biterider
My version - special thanks to Jack (http://masm32.com/board/index.php?topic=10504.0) :thup:
Hi
Long text UTF-8 test. :biggrin:
Biterider
Nice :thumbsup:
QuoteThe coldest place in the world is the Russian village of Oymyakon. This village is located in the East. About 500 (five hundred) people live there. In the winter the usual temperature is minus fifty (50) degrees Celsius. Once it was minus 71 degrees in the village! But the inhabitants of the village were used to the cold. Everyone knows each other here. Everyone helps each other out.
Just did the same. Looks like Russian.
The coldest place in the world is the Russian village of Oymyakon. This village is located in the East. About 500 (five hundred) people live there. In winter, the usual temperature is minus 50 (fifty) degrees. Once in this village it was minus 71 (seventy one) degrees! But the villagers got used to the cold. Here everyone knows each other. Everyone helps each other.
Used a tool called "CODETWO".
Hi
The original text is a learning text and comes from here (https://www.russischgratis.com/russischer-text-anfaenger-kaeltestes-dorf-der-welt.php#:~:text=00%3A00-,%D0%A1%D0%B0%D0%BC%D1%8B%D0%B9%20%D1%85%D0%BE%D0%BB%D0%BE%D0%B4%D0%BD%D1%8B%D0%B9%20%D0%B3%D0%BE%D1%80%D0%BE%D0%B4%20%D0%BD%D0%B0%20%D0%97%D0%B5%D0%BC%D0%BB%D0%B5,-Das%20k%C3%A4lteste%20Dorf).
Biterider
Hi Hutch
Thanks for the tip about the CODETWO Desktop Reader. Works well here and saves me time on testing. :thumbsup:
Biterider
Hi Biterider,
What's your character limit?
Quote from: jj2007 on November 24, 2022, 01:03:06 PMThere are several sizes reported on the web:
QuoteModel 1 (https://www.qrcode.com/en/codes/model12.html):
The original QR Code, a code capable of coding 1,167 numerals with its maximum version being 14 (73 x 73 modules)
Model 2
This code can encode up to 7,089 numerals with its maximum version being 40 (177 x 177 modules).
https://blinq.me/blog/what-size-should-a-qr-code-be
QuoteA QR code can store up to 4,296 alphanumeric characters of arbitrary text. The text can be anything from contact information, a URL, or even a telephone number.
Hi JJ
It depends on what you are encoding:
getNumRawDataModules: (from Source code)
Returns the number of data bits that can be stored in a QR Code of the given version number, after
all function modules are excluded. This includes remainder bits, so it might not be a multiple of 8.
The result is in the range [208, 29648]. This could be implemented as a 40-entry lookup table.
That means if you encode ASCII chars in the range "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" that are stored as indices (shorter than 8 bits) you have a huge capacity. It decreases rapidly if you choose other encodings.
Biterider
Hi JJ
Further reading in the qrcodegen.h file:
Quote* In the most optimistic case, a QR Code at version 40 with low ECC
* can hold any UTF-8 string up to 2953 bytes, or any alphanumeric string
* up to 4296 characters, or any digit string up to 7089 characters.
* These numbers represent the hard upper limit of the QR Code standard.
Biterider
Hi Biterider, yes, that makes sense, thanks :thumbsup:
That QR-Code-generator is quite small about 9 kB with Pelles C
Later i might give msvc info
Quote from: TimoVJL on November 25, 2022, 03:40:08 AM
That QR-Code-generator is quite small about 9 kB with Pelles C
9kB for the call to GetProcAddress, or for a call to the import library?
https://www.nayuki.io/page/qr-code-generator-library
just static library code size.
hello TimoVJL :smiley:
your C code compiles without complaints with the mingw toolchain, I built a dll and it's size before stripping was 92,324 bytes, after strip --strip-unneeded the size was 22,300 bytes
congratulations on the clean C code :thumbsup:
-- edit -- the size of qrcodegen-demo.exe after stripping was 59K compiled with mingw
Quote from: TimoVJL on November 25, 2022, 03:40:08 AM
That QR-Code-generator is quite small about 9 kB with Pelles C
It does look very interesting :thumbsup:
qrcodegen_na.exe is 21kBytes, though.
from static lib .text:
pFile Data Description Value
00000474 00002486 Size Of RawData 9350
from .obj
.textpFile Data Description Value
00000074 00001A1D Size Of RawData 6685
.datapFile Data Description Value
pFile Data Description Value
00000024 00000004 Size Of RawData 4
.rdatapFile Data Description Value
0000004C 000001F6 Size Of RawData 502
can't give easily same from msvc made .obj / .lib, as it have COMDATs.
But if it so important, i might collect that data someway.
like 11936 bytes of code and data.
dll done with Pelles C and using msvcrt.
includelib qrcodegen_na_msvcrt
qrcodegen_Mask_AUTO = -1
qrcodegen_encodeText PROTO C :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
qrcodegen_Ecc_HIGH=3
qrcodegen_VERSION_MIN=1 ; The minimum version number supported in the QR Code Model 2 standard
qrcodegen_VERSION_MAX=40 ; The maximum version number supported in the QR Code Model 2 standard
qrcodegen_BUFFER_LEN_MAX=3917
...
.DATA?
qrcode db qrcodegen_BUFFER_LEN_MAX dup(?)
tempBuffer db qrcodegen_BUFFER_LEN_MAX dup(?)
.CODE
LoadQR:
mov pData, offset qrcode
invoke qrcodegen_encodeText, Chr$("https://www.nayuki.io/"), addr tempBuffer, addr qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, TRUE
So far, so good: this does not throw an exception, and there is some stuff in the qrcode buffer. But how to get the width & height, and how is that "stuff" encoded?
// Prints the given QR Code to the console.
static void printQr(const uint8_t qrcode[]) {
int size = qrcodegen_getSize(qrcode);
int border = 4;
for (int y = -border; y < size + border; y++) {
for (int x = -border; x < size + border; x++) {
fputs((qrcodegen_getModule(qrcode, x, y) ? "##" : " "), stdout);
}
fputs("\n", stdout);
}
fputs("\n", stdout);
}
Hi JJ
I posted the asm code above...
Here again, a bit refined
QrDraw proc uses xbx xdi xsi hDC:HDC, pQrCode:POINTER, sdX:SDWORD, sdY:SDWORD, dSize:DWORD, dBorder:DWORD
local Rct:RECT, dQrSize:DWORD, hBlackBrush:HBRUSH
mov esi, dSize
invoke qrcodegen_getSize, pQrCode
mov dQrSize, eax
mov ecx, dBorder
shl ecx, 1
add eax, ecx
xor edx, edx
mul esi
mrm Rct.left, sdX, edx
add edx, eax
mov Rct.right, edx
mrm Rct.top, sdY, edx
add edx, eax
mov Rct.bottom, edx
invoke GetStockObject, WHITE_BRUSH
lea xdx, Rct
invoke FillRect, hDC, xdx, xax
invoke GetStockObject, BLACK_BRUSH
mov hBlackBrush, xax
xor edi, edi
.while edi < dQrSize
xor ebx, ebx
.while ebx < dQrSize
invoke qrcodegen_getModule, pQrCode, ebx, edi
.if eax != 0
mov eax, ebx
add eax, dBorder
xor edx, edx
mul esi
add eax, sdX
mov Rct.left, eax
add eax, esi
mov Rct.right, eax
mov eax, edi
add eax, dBorder
xor edx, edx
mul esi
add eax, sdY
mov Rct.top, eax
add eax, esi
mov Rct.bottom, eax
lea xdx, Rct
invoke FillRect, hDC, xdx, hBlackBrush
.endif
inc ebx
.endw
inc edi
.endw
ret
QrDraw endp
A regular call looks like
invoke QrDraw, hDC, addr QrCode, QR_OFFSET_X, QR_OFFSET_Y, QR_CELL_SIZE, QR_BORDER
with
QR_BORDER = 4
QR_OFFSET_X = 25
QR_OFFSET_Y = 25
QR_CELL_SIZE = 5
Biterider
I wonder if QR could be used to backup small programs on paper and then restored?
say that you split an exe for example into chunks and then create the QR's and print them on paper for backup, how many bytes per page could be saved ?
see https://stackoverflow.com/questions/11065415/how-much-data-information-can-we-save-store-in-a-qr-code
Quote from: Biterider on November 25, 2022, 05:44:25 PM
Hi JJ
I posted the asm code above...
Here again, a bit refined
Hi Biterider,
I am awfully sorry, but even my third attempt to install ObjAsm32 failed, so I am a bit lost...
I've tried hard some years ago, then again some months ago, and now today. There are always cryptic error messages :sad:
C:\Masm32\ObjAsm32\Examples\Demo02>make.bat
Project: Demo02
Compiling resources...
Building resource object...
Assembling project...
Linking object modules...
***************************
********** ERROR **********
***************************
C:\Masm32\ObjAsm32\Examples\Demo02>
P.S.:
\Masm32\ObjAsm32\Examples\Demo04\Demo04.asm assembled with make.bat, but the exe complains about htmlhelp.dll missing
Demo05.obj : error LNK2001: unresolved external symbol _HtmlHelpA@16
Demo06: lots of errors, e.g. error A2175:invalid qualified type : TBBUTTONINFO
Demo07, 8, 9: cannot open file : C:\Masm32\Include\CrtDll.inc
Demo11 & 16: \Masm32\Include\Windows.inc(21860) : error A2191:cannot include structure in self DEBUG MODE : ACTIVE -> WND
Demo14
assembles fine but I have no idea what the 2560 byte exe is supposed to do.
\Masm32\ObjAsm32\Projects\XTreeView\Make.bat: error LNK2001: unresolved external symbol _HtmlHelpA@16
...
Quote from: jj2007 on November 26, 2022, 12:53:14 AM
but even my third attempt to install ObjAsm32 failed
:thumbsup: Good try
Quote from: jj2007 on November 26, 2022, 12:53:14 AM
, so I am a bit lost...
Yes. It's not longer ObjAsm32, but ObjAsm-C.1 (https://github.com/ObjAsm)
Quote from: HSE on November 26, 2022, 01:56:37 AMIt's not longer ObjAsm32, but ObjAsm-C.1 (https://github.com/ObjAsm)
Ok, thanks. However, I can't see an installer in the 127MB I just downloaded :sad:
Quote from: jj2007 on November 26, 2022, 02:00:30 AM
Quote from: HSE on November 26, 2022, 01:56:37 AMIt's not longer ObjAsm32, but ObjAsm-C.1 (https://github.com/ObjAsm)
Ok, thanks. However, I can't see an installer in the 127MB I just downloaded :sad:
Anyway ObjAsm32 must work.
; Thanx to Vortex for his work
;
; To expand the lib definition file:
; link /DLL /def:crtdll.def /NOENTRY /subsystem:windows crtdll.obj
printf PROTO C :DWORD, :VARARG
sprintf PROTO C :DWORD,:DWORD, :VARARG
sscanf PROTO C :DWORD,:DWORD, :VARARG
Quote from: HSE on November 26, 2022, 02:05:41 AMAnyway ObjAsm32 must work.
With CrtDLL.inc, Demo07:
C:\Masm32\ObjAsm32\Code\Objects\DialogPassword.inc(68) : error A2109:only white space or comment can follow backslash
StringW(32): Macro Called From
$OfsCStrW(5): Macro Called From
$OfsCStr(2): Macro Called From
C:\Masm32\ObjAsm32\Code\Objects\DialogPassword.inc(68): Include File
And many other errors...
Demo08: \Masm32\ObjAsm32\Code\Objects\Rebar.inc(107) : error A2175:invalid qualified type : TBBUTTONINFO plus 26 other errors.
Mmm. My installation was a little "tuned" several times. and a lot during lockdown for an specific project.
No single example is building now, only the big project. Project have 1.7MB of code, perhaps 30000 loc :biggrin: :biggrin: :biggrin:
Quote from: TimoVJL on November 25, 2022, 06:19:31 AM
https://www.nayuki.io/page/qr-code-generator-library
just static library code size.
This is good stuff, Timo, but it's an import library that depends on the presence of qrcodegen_na_msvcrt.dll. The only functions used there are memmove and strstr - if you could eliminate them, the DLL would no longer be needed.
Actually dlls was just for examples, so everyone can try them.
Static libraries are usually difficult cases for too many programmers, as they often have linking time problems.
Quote from: TimoVJL on November 26, 2022, 08:40:05 AM
Actually dlls was just for examples, so everyone can try them.
Static libraries are usually difficult cases for too many programmers, as they often have linking time problems.
Real static libraries are ok. What makes trouble are
import libraries. They are fake. Most of the Masm32 SDK "static" libraries link to C:\Windows\System32\ DLLs - no problem, as these DLLs are always present on a Windows machine. But as soon as you import functions from a DLL that happens to sit only in your QR code folder, the exe doesn't work any more if you move it to a different folder.
I've run some tests comparing:
a) Jack's version: libqrencode32Jack.dll, 62974 bytes of 22.11.22, 03:15:50
b) Timo's version: qrcodegen_na_msvcrt.lib, 4648 bytes of 25.11.22, 00:48:34
Both support strings up to 2933 bytes, Timo's version up to 2940 or so. However, the codes generated by Jack's dll are slightly more easy to recognise by my smartphone reader.
Sources & executables here (http://masm32.com/board/index.php?topic=10504.msg115953#msg115953)
Hi Jack
Quote from: jack on November 25, 2022, 11:38:32 PM
I wonder if QR could be used to backup small programs on paper and then restored?
This reminds me of an old project that works perfectly https://ollydbg.de/Paperbak/ (https://ollydbg.de/Paperbak/).
I found this when I was looking for the "PaperBack" https://github.com/cyphar/paperback (https://github.com/cyphar/paperback) :tongue:
Biterider
a static library made with msvc 2022
i haven't tested it.
Original code:
* Copyright (c) Project Nayuki. (MIT License)
* https://www.nayuki.io/page/qr-code-generator-library
EDIT
static library test, asm code borrowed from jj2007model flat, c
.486
includelib qrcodegen_na
qrcodegen_Mask_AUTO = -1
qrcodegen_encodeText PROTO C :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
qrcodegen_Ecc_HIGH=3
qrcodegen_VERSION_MIN=1 ; The minimum version number supported in the QR Code Model 2 standard
qrcodegen_VERSION_MAX=40 ; The maximum version number supported in the QR Code Model 2 standard
qrcodegen_BUFFER_LEN_MAX=3917
;...
.DATA
stext db "https://www.nayuki.io/",0
.DATA?
qrcode db qrcodegen_BUFFER_LEN_MAX dup(?)
tempBuffer db qrcodegen_BUFFER_LEN_MAX dup(?)
.CODE
mainCRTStartup:
LoadQR:
;mov pData, offset qrcode
invoke qrcodegen_encodeText, addr stext, addr tempBuffer, addr qrcode,
qrcodegen_Ecc_HIGH, qrcodegen_VERSION_MIN, qrcodegen_VERSION_MAX, qrcodegen_Mask_AUTO, 1
ret
END LoadQR
Quote from: jack on November 25, 2022, 11:38:32 PM
I wonder if QR could be used to backup small programs on paper and then restored?
say that you split an exe for example into chunks and then create the QR's and print them on paper for backup, how many bytes per page could be saved ?
see https://stackoverflow.com/questions/11065415/how-much-data-information-can-we-save-store-in-a-qr-code
That reminds me of spy novels, sending info by microscopic size secret documents
But uncompressed source it's limited to contain lot of repeated strings triple or more space
Especially asm snippet Unrolled many times for speed
Hi JJ!
Quote from: jj2007 on November 26, 2022, 02:09:53 AM
Demo14 assembles fine but I have no idea what the 2560 byte exe is supposed to do.
Some little demos show things in DebugCenter. If DebugCenter fail to open You will see nothing.
LATER: but
apparently Demo14 fail :thumbsup:
MORE LATER: what fail is my memory :biggrin: :biggrin: I don't used make.bat with ObjAsm32!
To see something, program must be assembled in debug mode (like RadAsm Project state). To use make.bat, must be replaced OA32_ASM_RLS with OA32_ASM_DBG inside it.
Quote from: jj2007 on November 26, 2022, 02:09:53 AM
With CrtDLL.inc, Demo07:
Demo08: ...
I found a more pristine ObjAsm32 installation, and I obtain exactly your same errors :biggrin:
You have ObjAsm32 running. Congratulations!!
Regards, HSE
Just in case, Demo14 work perfectly (see above)
And Demo8 work with TBBUTTONINFOW and HtmlHelpA (perhaps it's not original Masm32SDK's htmlhelp.lib)
In Graph2D.inc just replaced function CRTDLL_snprintf. That was an old discussion (http://masm32.com/board/index.php?topic=633.msg5161#msg5161) I don't remember :biggrin: :biggrin: