diff --git a/kernel/trunk/const.inc b/kernel/trunk/const.inc index 07ffa57c3..e77cdde30 100644 --- a/kernel/trunk/const.inc +++ b/kernel/trunk/const.inc @@ -284,7 +284,7 @@ MEM_AMOUNT = OS_BASE + 0x000FE8C SYS_SHUTDOWN = OS_BASE + 0x000FF00 -TMP_STACK_TOP = 0x008CC00 +TMP_STACK_TOP = 0x0096F00 sys_proc = OS_BASE + 0x008E000 diff --git a/kernel/trunk/core/syscall.inc b/kernel/trunk/core/syscall.inc index 4beea74c4..b8e4eb11e 100644 --- a/kernel/trunk/core/syscall.inc +++ b/kernel/trunk/core/syscall.inc @@ -175,7 +175,7 @@ iglobal dd sys_socket ; 75-reserved for new stack dd sys_protocols ; 76-reserved for new stack dd sys_posix ; posix support - dd undefined_syscall ; 78-free + dd syscall_qrcode ; 78-QR code dd undefined_syscall ; 79-free dd sys_fileSystemUnicode ; 80-File system interface for different encodings diff --git a/kernel/trunk/kernel.asm b/kernel/trunk/kernel.asm index 0c5d3c563..9ff18cc6b 100644 --- a/kernel/trunk/kernel.asm +++ b/kernel/trunk/kernel.asm @@ -4430,6 +4430,8 @@ sys_apm: ret ; ----------------------------------------- +include 'qrcode.inc' + align 4 undefined_syscall: ; Undefined system call mov [esp + SYSCALL_STACK.eax], -1 diff --git a/kernel/trunk/qrcode.inc b/kernel/trunk/qrcode.inc new file mode 100644 index 000000000..ac04e8266 --- /dev/null +++ b/kernel/trunk/qrcode.inc @@ -0,0 +1,2153 @@ +iglobal + places db 6,0,0,0,0,0,0 + + dark dd 0 + lite dd 0ffffffH + unus dd 02H + ddat dd 01H + ldat dd 0fffffeH + resr dd 0fffffdH +endg + + +uglobal + version DD 1 DUP (?) + mode DD 1 DUP (?) + maxcodewords DD 1 DUP (?) + eclevel DD 1 DUP (?) + maskpattern DD 1 DUP (?) + size DD 1 DUP (?) + size2 DD 1 DUP (?) + genpoly DB 32 DUP (?) + versionstring DD 18 DUP (?) + formatstring DD 16 DUP (?) + message DB 154 DUP (?) + datcodewords DB 0e84H DUP (?) + ileaveddata DB 0e84H DUP (?) + matrix DD 31330 DUP (?) +endg + + +;system function 78: prepare QR code +;input: eax = 78 +; ebx = pointer to payload data +; ecx = length of payload data +; edx = pointer to buffer at least (31330 * 3) bytes long +; to hold the QR code as a 24-bit RGB bitmap +;output: if QR code generation failed: +; eax = -1 +; otherwise: +; eax = number of pixels per side of QR code +; bitmap is copied to buffer starting at [edx] + +syscall_qrcode: + stdcall is_region_userspace, edx, 31330 * 3 + jnz .error + push edx + + push -1 + push -1 + push ecx + push ebx + call makeQR + cmp eax, -1 + je .error + push eax + call reducematrix + mov eax, [esp] + imul eax, eax + imul eax, eax, 3 + mov ecx, eax + mov esi, matrix + mov edi, [esp + 4] + rep movsb + pop eax + pop edx + mov [esp + SYSCALL_STACK.eax], eax + ret + +.error: + mov [esp + SYSCALL_STACK.eax], -1 + ret + +DARK equ 0 +CMSK equ 0FFFF00H + +makeQR: +;input: 4 dwords in the stack +; top argument is pointer to input data +; 2nd argument is length of input data, as number of bytes +; 3rd argument indicates extended channel interpretation mode +; -1 - no ECI +; 22 - windows-1251 +; 26 - utf8 +; (see list of ECI indicators at the bottom of this file) +; note: there is no ECI indicator for code page 866 +; 4th argument is not used currently +; planned to use it to indicate if negative +; (white on black) QR code is desired +;output: if QR code could not be made, eax = -1 +; otherwise, eax = size of QR code, as number of pixels per side +; matrix variable contains QR code as RGBA bitmap + +;---------local variable declarations---------- + _ecwords EQU [ebp] + _bytechars1 EQU [ebp + 4] + _alphachars2 EQU [ebp + 8] + _numchars3 EQU [ebp + 12] + _leadalpha21 EQU [ebp + 16] + _totalblocks EQU [ebp + 20] + _g1b EQU [ebp + 24] ;number of group 1 blocks + _g1dc EQU [ebp + 28] ;data codewords per block + _g2b EQU [ebp + 32] ;number of group 2 blocks + _g2dc EQU [ebp + 36] ;data codewords per block + _wordssofar EQU [ebp + 40] +_requiredbitslength EQU [ebp + 44] + _charcountlength EQU [ebp + 48] + _thisblockwords10 EQU [ebp + 52] + _thisblock12 EQU [ebp + 56] ;block counter + _unusedbits EQU [ebp + 60] + _ord20 EQU [ebp + 64] ;polynomial division cycle counter + ;caller's ebp here 68 + ;return address here 72 + _theinput EQU [ebp + 76] ;address of input data + _theinputlength EQU [ebp + 80] + _theecimode EQU [ebp + 84] + _makenegative EQU [ebp + 88] ;not used +;---------end of local variable declarations---------- +EBPNUMBER EQU 68 + push ebp + lea ebp, dword [esp - EBPNUMBER] + sub esp, EBPNUMBER - 4 + push esi + and dword _requiredbitslength, 0 +;return -1 if input length is more than absolute maximum + or eax, - 1 + cmp dword _theinputlength, 7089 + ja makeQR_end +;------------------ +;figure out if input is numeric, alphanumeric, or +;binary, and set [mode] variable accordingly + and dword [mode], 0 + mov ebx, dword _theinputlength + dec ebx + cld + mov esi, dword _theinput +findmodeloop: + lodsb + push eax + call alphaindex + cmp eax, 9 + jle @f + mov dword [mode], 1 + cmp eax, 46 + jl @f + mov dword [mode], 2 + jmp findmodeloopend +@@: + dec ebx + jns findmodeloop +findmodeloopend: +;------------------ +;backslashes (\) need escaping in QR code, +;so they count double towards input length + cmp dword _theecimode, -1 + je countslashloopend + mov ebx, dword _theinputlength + cld + mov esi, dword _theinput +countslashloop: + lodsb + cmp al, 92 + jne @f + inc dword _theinputlength +@@: + dec ebx + jns countslashloop +countslashloopend: +;------------------ +;return -1 if mode is 1 or 2 and input +;length is more than respective maxima + or eax, -1 + cmp dword [mode], 1 + jne @f + cmp dword _theinputlength, 4296 + ja makeQR_end +@@: + cmp dword [mode], 2 + jne @f + cmp dword _theinputlength, 2953 + ja makeQR_end +@@: +;------------------ + and dword _unusedbits, 0 + and dword _charcountlength, 0 + mov dword [version], 1 +findversionloop: + mov dword [eclevel], 3 +findeclevelloop: + mov eax, dword [version] + ;same as eax = 21 + (version - 1) * 4 + lea eax, dword [eax * 4 + 17] + mov dword [size], eax + imul eax, eax + mov dword [size2], eax +;fill matrix with unused pixels + mov ecx, eax ; 31330 + mov eax, dword [unus] + mov edi, matrix + cld + rep stosd +;-------------- + call reserveareas + call drawversion + call drawfinders + call drawtiming + call drawalign + call drawdarkmodule +;-------------- +;count unused pixels in matrix; these are +;the pixels which will carry input and EC data + xor ecx, ecx + mov eax, dword [size2] +countunusedloop: + mov ebx, dword [matrix + eax * 4] + cmp ebx, dword [unus] + jne @f + inc ecx +@@: + dec eax + jns countunusedloop + mov dword _unusedbits, ecx +;------------- + ;mov ecx, dword _unusedbits + shr ecx, 3 + mov dword [maxcodewords], ecx + + call getcharcountlength + movzx eax, al + mov dword _charcountlength, eax + + call numdatacodewords + movzx eax, ax + shl eax, 3 + mov dword _requiredbitslength, eax +;------------- +;begin computing capacity of current QR code + ;mov ebx, dword _requiredbitslength + + mov ebx, eax + sub ebx, 4 + cmp dword _theecimode, -1 + je @f + sub ebx, 12 +@@: + sub ebx, dword _charcountlength + ;mov dword _avail ableb its5, ebx + push ebx + + mov eax, ebx + add eax, ebx + add eax, ebx + cdq + mov ecx, 10 + idiv ecx +;calculated maximum number of characters this +;QR code can contain, if it is numeric + mov dword _numchars3, eax + + mov eax, [esp] + add eax, eax + cdq + mov ecx, 11 + idiv ecx +;calculated maximum number of characters this +;QR code can contain, if it is alphanumeric + mov dword _alphachars2, eax + + pop eax + sar eax, 3 +;calculated maximum number of bytes this +;QR code can contain, if it is binary + mov dword _bytechars1, eax + +;it is possible to pre compute and look up the +;three previous results, which only depend on +;version and error correction level, however I +;prefer to calculate them explicitly + + +;break out of the loop if current version and +;EC level are sufficient to contain the input + cmp dword [mode], 0 + jne @f + mov eax, dword _numchars3 + cmp eax, dword _theinputlength + jge Loopfinished +@@: + cmp dword [mode], 1 + jne @f + mov eax, dword _alphachars2 + cmp eax, dword _theinputlength + jge Loopfinished +@@: + cmp dword [mode], 2 + jne @f + mov eax, dword _bytechars1 + cmp eax, dword _theinputlength + jge Loopfinished +@@: + dec dword [eclevel] + cmp dword [eclevel], 0 + jnl findeclevelloop + inc dword [version] + cmp dword [version], 40 + jng findversionloop +Loopfinished: +;-------------- +;return -1 if version is greater than 40, which is +;the maximum for QR codes +;this should never happen, because of the prior checks +;regarding input length + or eax, - 1 + cmp dword [version], 40 + ja makeQR_end +;-------------- +;reset data structures in case +;they have been used previously + cld + mov ecx, 5 ; 929 + xor eax, eax + mov edi, datcodewords + rep stosd + mov ecx, 5 ; 929 + mov edi, ileaveddata + rep stosd +;--------------- +;add ECI mode indicator if necessary +;see page 24 of ISO/IEC 18004:2015 + cmp dword _theecimode, 999999 + jng @f + mov dword _theecimode, -1 +@@: + cmp dword _theecimode, -1 + je eciskip + push dword 4 + push dword 7 + push datcodewords + call appendtobitset + mov eax, dword _theecimode + cmp eax, 127 + jg @f + push 8 + and eax, 127 + jmp addeci +@@: + cmp eax, 16383 + jg @f + push 16 + and eax, 16383 + or eax, 32768 + jmp addeci +@@: + push 24 + and eax, 2097151 + or eax, 12582912 +addeci: + push eax + push datcodewords + call appendtobitset +eciskip: +;----------------- +;add mode indicator + mov eax, dword [mode] + movzx eax, byte [modeindicators + eax] + push 4 + push eax + push datcodewords + call appendtobitset +;add length-of-input marker + push dword _charcountlength + push dword _theinputlength + push datcodewords + call appendtobitset +;------------------- +;prepare registers for data acquisition + cld + mov esi, dword _theinput + mov edi, esi + add edi, dword _theinputlength +;------------------- +;mode 0: acquire numeric data + cmp dword [mode], 0 + jne mode0loopend + ;cld + ;mov esi, dword _theinput + ;mov edi, esi + ;add edi, dword _theinputlength +mode0loop: + mov ebx, edi + sub ebx, esi + lodsb + sub al, 48 + cmp ebx, 1 + jne @f + push 4 + jmp mode0next +@@: + cmp ebx, 2 + jne @f + imul eax, eax, 10 + mov ebx, eax + lodsb + sub al, 48 + add eax, ebx + push 7 + jmp mode0next +@@: + cmp ebx, 3 + jl mode0next + imul eax, eax, 100 + mov ebx, eax + lodsb + sub al, 48 + imul eax, eax, 10 + add ebx,eax + lodsb + sub al, 48 + add eax, ebx + push 10 +mode0next: + push eax + push datcodewords + call appendtobitset + cmp esi, edi + jnge mode0loop +mode0loopend: +;------------------- +;mode 1: acquire alphanumeric data + cmp dword [mode], 1 + jne skipmode1 + ;cld + ;mov esi, dword _theinput + ;mov edi, esi + ;add edi, dword _theinputlength +mode1loop: + mov ebx, edi + sub ebx, esi + lodsb + push eax + call alphaindex + cmp ebx, 2 + jnae @f + imul eax, 45 + mov edx, eax + lodsb + push eax + call alphaindex + add eax, edx + push dword 11 + jmp mode1next +@@: + push dword 6 +mode1next: + push eax + push dword datcodewords + call appendtobitset + cmp esi, edi + jb mode1loop +skipmode1: +;------------------- +;mode 2: acquire binary data + cmp dword [mode], 2 + jne skipmode2 + ;cld + ;mov esi, dword _theinput + ;mov edi, esi + ;add edi, dword _theinputlength +mode2loop: + lodsb + push dword 8 + push eax + push datcodewords +;if ECI mode is not default and input contains a +;backslash, escape it in the QR code by doubling it up + cmp dword _theecimode, -1 + je @f + cmp eax, 92 + jne @f + push dword 8 + push eax + push dword datcodewords + call appendtobitset +@@: + call appendtobitset + cmp esi, edi + jb mode2loop +skipmode2: +;---------------- +;if number of payload bits so far is less than capacity, +;!!! append four 0s to terminate !!! (emphasis intentional) +;or append 0s up to full capacity, whichever happens first + mov eax, dword _requiredbitslength + sub eax, dword [datcodewords + 4] + cmp eax, 4 + jle @f + mov al, 4 +@@: + push eax + push 0 + push datcodewords + call appendtobitset +;if number of payload bits so far is not multiple of 8, +;append 0s until it is + mov al, 8 + sub al, byte [datcodewords + 8] + and eax, 7 + jz @f + push eax + push 0 + push datcodewords + call appendtobitset +@@: +;------------- +;add repeating padding {236, 17} if necessary to fill capacity + mov esi, 236 + mov edi, 17 + push ebp + mov ebp, dword _requiredbitslength + sar ebp, 3 + sub ebp, dword [datcodewords] +paddingloop: + cmp ebp, 0 + jng paddingloopend + push 8 + push esi + push datcodewords + call appendtobitset + xchg esi, edi + dec ebp + jmp paddingloop +paddingloopend: + pop ebp +;--------------------- +;prepare some local variables + call numblocksingroup2; movzx eax, al + mov dword _g2b, eax + call numblocksingroup1; movzx eax, al + mov dword _g1b, eax + mov eax, dword _g1b + add eax, dword _g2b + mov dword _totalblocks, eax + call group1datacodewords; movzx eax, al + mov dword _g1dc, eax + call group2datacodewords; movzx eax, al + mov dword _g2dc, eax + call eccodewordsperblock + mov dword _ecwords, eax + and dword _wordssofar, 0 + + push dword _ecwords + call makeECgenerator + and dword _thisblock12, 0 +processblockloop: + mov ebx, dword _g1dc + mov eax, dword _thisblock12 + cmp eax, dword _g1b + jl @f + mov ebx, dword _g2dc +@@: +;determined how many codewords this block must contain + mov dword _thisblockwords10, ebx + +;clear the array that is used to +;calculate error correction codewords + cld + mov ecx, 76 ; 154 + xor eax, eax + mov edi, message + rep stosw + +;copy this block's data to the array in reverse order +;with leading 0s required for next computation + mov edi, message + add edi, dword _ecwords + mov ecx, dword _thisblockwords10 + mov esi, datcodewords + 9 + add esi, dword _wordssofar +;also increase the counter of codewords processed so far + add dword _wordssofar, ecx + dec ecx + add esi, ecx +@@: + movsb + dec esi + dec esi + dec ecx + jns @b + +;---------------- + mov eax, dword _thisblockwords10 + mov ecx, dword _ecwords + lea eax, dword [ecx + eax - 1] + mov dword _ord20, eax +errorcorrectionloop: + mov eax, dword _ord20 + movzx eax, byte [message + eax] + test eax, eax +;if lead exponent is 0, skip this polynomial division cycle + jz errorcorrectionnext + +;calculate lead value for this polynomial division cycle + mov eax, dword _ord20 + movzx eax, byte [message + eax] + mov al, byte [mod285antilogs + eax] + mov byte _leadalpha21, al + +;perform one cycle of dividing this block's codewords by the +;EC generator polynomial, using Galois Field 256 arithmetic + mov ecx, dword _ord20 + mov edi, dword _ecwords + sub ecx, edi +polydivisionloop: + movzx eax, byte [genpoly + edi] + movzx edx, byte _leadalpha21 + add eax, edx + cdq + mov esi, 255 + idiv esi + movzx eax, byte [mod285logs + edx] + mov edx, edi + movzx ebx, byte [message + edx + ecx] + xor ebx, eax + mov byte [message + edi + ecx], bl + dec edi + jns polydivisionloop +;------------------ +errorcorrectionnext: + dec dword _ord20 + mov eax, dword _ord20 + cmp eax, dword _ecwords + jnl errorcorrectionloop + +;store error correction data + mov edi, dword _ecwords + mov esi, dword message + dec edi + add esi, edi + std +@@: + lodsb + push 8 + push eax + push datcodewords + call appendtobitset + dec edi + jns @b + cld +;------------ + inc dword _thisblock12 + mov eax, dword _thisblock12 + cmp eax, dword _totalblocks + jnge processblockloop +;------------ +;interleave data + xor esi, esi +ileavegroup1loop: + xor edi, edi +ileavegroup1_innerloop: + mov ecx, edi + sub ecx, dword _g1b + cmp edi, dword _g1b + jnle @f + xor ecx, ecx +@@: + mov eax, edi + imul eax, dword _g1dc + add eax, esi + movzx eax, byte [datcodewords + eax + ecx + 9] + push 8 + push eax + push ileaveddata + call appendtobitset + inc edi + cmp edi, dword _totalblocks + jnge ileavegroup1_innerloop + + inc esi + cmp esi, dword _g1dc + jnge ileavegroup1loop + + + cmp dword _g2dc, 0 + jle skipgroup2 + +;interleave data from group 2 + mov esi, 1 +group2loop: + mov ecx, esi + mov eax, dword _g1dc + imul eax, dword _g1b + imul ecx, dword _g2dc + movzx eax, byte [datcodewords + eax + ecx + 8] + push 8 + push eax + push ileaveddata + call appendtobitset + inc esi + cmp esi, dword _g2b + jng group2loop +skipgroup2: + +;interleave error correction data + mov eax, dword _g1b + mov ecx, dword _g2b + imul eax, dword _g1dc + imul ecx, dword _g2dc + add eax, ecx + push eax; startecwords + call eccodewordsperblock + push eax; bk + push 0; n + push 0; i +ix EQU dword [esp] +jx EQU dword [esp + 4] +bk EQU [esp + 8] +startecwords EQU [esp + 12] +ileaveloop2: + mov ix, 0 +ileaveloop1: + xor edx,edx + mov eax, ix + imul dword bk + add eax, startecwords + mov ecx, jx + movzx eax, byte [datcodewords + 9 + eax + ecx] + push 8 + push eax + push ileaveddata + call appendtobitset + inc ix + mov eax, ix + cmp eax, dword _totalblocks + jnge ileaveloop1 + inc jx + mov eax, jx + cmp eax, bk + jnge ileaveloop2 + sub esp, 16 ; discard last 4 local variables +;------------------ +;if there are any unused pixels left over, +;fill the corresponding data with 0s + mov eax, dword _unusedbits + sub eax, dword [ileaveddata + 4] + cmp eax, 0 + jle @f + push dword eax + push dword 0 + push ileaveddata + call appendtobitset +@@: +;----------------- +;draw interleaved data, +;find which mask pattern minimizes penalty score, +;apply mask, +;return size of QR code + call drawdata + call minimalpenaltymask + mov dword [maskpattern], eax + push dword eax + call mask + mov eax, dword [size] +makeQR_end: + pop esi + add ebp, EBPNUMBER + leave + ret 16 + + +drawdata: +;input: nothing +;output: matrix is modified +col EQU edx +row EQU ebx +ix EQU ecx +godown EQU edi +oddcol EQU ebp + push ebp + xor godown, godown + xor ix, ix + mov col, dword [size] + dec col + mov row, col +drawdataloop: + + mov eax, row + mul byte [size] + add eax, col + mov esi, dword [matrix + eax * 4] + cmp esi, dword [unus] + jne skipdraw + push ebx + push ecx + push eax + mov eax, ix + call getdrawbit + pop ecx + mov dword [matrix + ecx * 4], eax + pop ecx + pop ebx + inc ix +skipdraw: + mov oddcol,col + and oddcol,1 + cmp col, 6 + jge @f + xor oddcol, 1 +@@: + cmp oddcol, 1 + je isoddcol + dec col + jmp testrow0 +isoddcol: + inc col + and godown, 1 + jz @f + inc row + jmp testrow0 +@@: + dec row +testrow0: + cmp row, 0 + jge testrowsize + or godown, 1 + xor row, row + cmp col, 8 + jne @f + dec col +@@: + dec col + dec col +testrowsize: + cmp row, dword [size] + jnae drawdataloopend + xor godown, godown + mov row, dword [size] + dec row + dec col + dec col + cmp col, 5 + jne @f + dec col +@@: + cmp col, 6 + jne drawdataloopend + dec col + dec col +drawdataloopend: + cmp ix, dword [datcodewords + 4] + jnae drawdataloop + pop ebp + ret + + + + +mask: +;input: eax = mask type +;output: matrix is modified + pop ecx + pop eax + push ecx +;remove the above to change calling convention +col EQU ecx +row EQU edx + push eax + push 0 +push eax + call drawformat + xor col, col +maskloopcol: + xor row, row +masklooprow: + mov eax, row + mul cl + push eax ;save result: row * column + push edx + cdq + mov ebx, 3 + idiv ebx + mov eax, edx + pop edx + push eax; save result: (row * column) mod 3 + mov eax, dword [esp + 12] + cmp al, 7 + jg @f + jmp dword [maskbjumps + eax * 4] +@@: + pop ebx + jmp endmasks +bmask0: + mov ebx, row + add ebx, col + and bl, 1 + xor ebx, 1 + jmp bmaskdone +bmask1: + mov ebx, row + and bl, 1 + xor ebx, 1 + jmp bmaskdone +bmask2: + mov eax, col + mov bl, 3 + div bl + xor ebx, ebx + cmp ah, 0 + setz bl + jmp bmaskdone +bmask3: + mov eax, col + add eax, row + mov bl, 3 + div bl + xor ebx, ebx + cmp ah, 0 + setz bl + jmp bmaskdone +bmask4: + mov eax, col + mov ebx, 3 + div bl + mov ebx, row + shr ebx, 1 + add bl, al + and bl, 1 + xor ebx, 1 + jmp bmaskdone +bmask5: + mov eax, dword [esp] + mov ebx, dword [esp+4] + and ebx, 1 + add ebx, eax + setz bl + jmp bmaskdone +bmask6: + mov eax, dword [esp] + mov ebx, dword [esp+4] + and ebx, 1 + add ebx, eax + and ebx, 1 + setz bl + jmp bmaskdone +bmask7: + mov eax, dword [esp] + mov ebx, row + add ebx, col + and ebx, 1 + add ebx, eax + and ebx, 1 + setz bl +bmaskdone: + pop eax ;discard result + pop eax ;discard result + mov dword [esp], ebx + mov eax, row + imul byte [size] + add eax, col + mov ebx, eax + mov eax, dword [matrix + ebx * 4] + cmp eax, dword [unus] + jne @f + mov eax, dword [ldat] +@@: + and dword [esp], 1 + jz endflip + cmp eax, dword [ddat] + jne @f + mov eax, dword [ldat] + jmp endflip +@@: + cmp eax, dword [ldat] + jne endflip + mov eax, dword [ddat] +endflip: + mov dword [matrix + ebx * 4], eax + inc row + cmp row, dword [size] + jnge masklooprow + inc col + cmp col, dword [size] + jnge maskloopcol +endmasks: + pop eax + pop eax + ret +maskbjumps: + dd bmask0 + dd bmask1 + dd bmask2 + dd bmask3 + dd bmask4 + dd bmask5 + dd bmask6 + dd bmask7 + + +getratiopenalty: +;input: nothing +;output: eax = penalty score from B/W ratio of QR code +darks EQU ebx + xor darks, darks + mov ecx, dword [size2] +countdarksloop: + mov eax, dword [matrix + ix * 4] + and eax, CMSK + jnz @f + inc darks +@@: + dec ecx + jns countdarksloop + + imul eax, darks, 100 + mov ecx, DWORD [size2] + cdq + idiv ecx + sub eax, 50 + jns @f + neg eax +@@: + xor ecx, ecx + cmp eax, 5 + jle @f +ratioloop: + inc ecx + sub eax, 5 + cmp eax, 5 + jg ratioloop +@@: + imul eax, ecx, 10 + ret + + +gettotalpenalty: +;input: nothing +;output: eax = total penalty score of QR code + call getblockpenalty + push eax + call getstraightpenalty + push eax + call getsequencepenalty + push eax + call getratiopenalty + pop ebx + add eax, ebx + pop ebx + add eax, ebx + pop ebx + add eax, ebx + ret + + + +getsequencepenalty: +;input: nothing +;output: eax = penalty score for rule 3 of current QR code +ix EQU ebx +penalty EQU esi +col EQU dword [esp] +row EQU dword [esp + 4] + xor penalty, penalty + push 0 + push 0 +seqloopA: + mov col, 10 +seqloopB: + xor edi, edi + xor ix, ix +seqloopC: + mov eax, col + sub eax, ix + mov ecx, row + imul ecx, dword [size] + add eax, ecx + mov eax, dword [matrix + eax * 4] + and eax, CMSK + cmp eax, dword [sequence + ix * 4] + jne @f + inc edi +@@: + cmp eax, dword [sequence + ix * 4 + 16] + jne @f + add edi, 16 +@@: + mov eax, col + sub eax, ix + imul eax, dword [size] + add eax, row + mov eax, dword [matrix + eax * 4] + and eax, CMSK + cmp eax, dword [sequence + ix * 4] + jne @f + add edi, 256 +@@: + cmp eax, dword [sequence + ix * 4 + 16] + jne @f + add edi, 4096 +@@: + inc ix + cmp ix, 10 + jng seqloopC + push ecx + xor ecx, ecx +incpenaltyloop: + mov eax, edi + shr eax, cl + and eax, 15 + cmp eax, 11 + jl @f + inc penalty +@@: + add cl, 4 + cmp cl, 12 + jle incpenaltyloop + pop ecx + inc col + mov eax, col + cmp eax, dword [size] + jnge seqloopB + inc row + mov eax, row + cmp eax, dword [size] + jnge seqloopA + pop eax + pop eax + imul eax, penalty, 40 + ret + + + +minimalpenaltymask: +;input: nothing +;output: al = number of mask pattern that minimizes +; penalty score for current QR code + mov ecx,0 + sub esp, 8 +mpmloop: + push ecx + mov eax, ecx + push eax + call mask + call gettotalpenalty + pop ecx + cmp ecx, 0 + jne @f + mov dword [esp], ecx + mov dword [esp + 4], eax +@@: + mov edx, dword [esp + 4] + cmp eax, edx + jge @f + mov dword [esp + 4], eax + mov dword [esp], ecx +@@: + push ecx + mov eax, ecx + push eax + call mask + pop ecx + inc ecx + cmp ecx, 8 + jl mpmloop + pop eax + pop edx + ret + + +reserveareas: +;input: nothing +;output: some parts of matrix are marked as reserved +; so the data drawing algorithm will skip them + push dword [resr] + push 9 + push 0 + push 0 + call fillbox + push dword [resr] + push 8 + mov eax, dword [size] + sub eax, 8 + push eax + push 1 + call fillbox + push dword [resr] + push 8 + push 1 + mov eax, dword [size] + sub eax, 8 + push eax + call fillbox + cmp dword [version], 7 + jl @f + push dword [resr] + push 3 + mov eax, dword [size] + sub eax, 11 + push eax + push 0 + call fillbox + push dword [resr] + push 3 + mov eax, dword [size] + sub eax, 11 + push eax + push 3 + call fillbox + push dword [resr] + push 3 + push 0 + mov eax, dword [size] + sub eax, 11 + push eax + call fillbox + push dword [resr] + push 3 + push 3 + mov eax, dword [size] + sub eax, 11 + push eax + call fillbox +@@: + ret + + +drawformat: +;input: eax = type of mask +;output: formatstring array is modified +; format info is drawn in matrix +;uses eax ebx ecx edx esi + pop ecx + pop eax + push ecx +ix EQU ecx + xor ix, ix + mov ebx, dword [eclevel] + shl ebx, 3 + add eax, ebx +dfloop1: + mov ebx, 1 + shl ebx, cl + movzx edx, word [formatstrings + eax * 2] + mov esi, dword [dark] + and ebx, edx + jnz @f + mov esi, dword [lite] +@@: + mov ebx, 14 + sub ebx, ix + mov dword [formatstring + ebx * 4], esi + inc ix + cmp ix, 14 + jle dfloop1 + +row EQU edx + xor ix, ix + mov row, dword [size] +dfloop2: + dec row + mov eax, row + imul byte [size] + mov ebx, dword [formatstring + ix * 4] + inc ix + mov dword [matrix + 32 + eax * 4], ebx + cmp row, 7 + jne @f + dec row +@@: + mov ebx, dword [size] + sub ebx, 7 + cmp row, ebx + jne @f + mov row, 9 +@@: + cmp row, 0 + jge dfloop2 + +col EQU edx + xor ix, ix + xor col, col + mov eax, dword [size] + shl eax, 5 +dfloop3: + mov ebx, dword [formatstring + ix * 4] + inc ix + mov dword [matrix + eax + col * 4], ebx + cmp col, 5 + jne @f + inc col +@@: + cmp col, 7 + jne @f + mov col, dword [size] + sub col, 9 +@@: + inc col + cmp col, dword [size] + jnge dfloop3 + ret + + +drawtiming: +;input: nothing +;output: timing pattern is drawn in matrix + mov eax, 8 + mov ebx, dword [size] + mov esi, ebx + sub ebx, eax +dtloop: + mov ecx, dword [dark] + test eax, 1 + jz @f + mov ecx, dword [lite] +@@: + mov edx, 6 + imul edx, esi + add edx, eax + mov [matrix + edx * 4], ecx + mov edx, eax + imul edx, esi + add edx, 6 + mov [matrix + edx * 4], ecx + inc eax + cmp eax, ebx + jl dtloop + ret + + +fillbox: +;input: 4 dwords in the stack: startx, starty, boxsize, content +;output: a filled box is drawn in matrix + pop esi; return address + pop edi + pop eax + pop ecx + pop edx + push esi; save return address + push ebp; save previous base pointer + mov ebp, edi + shl ebp, 2 + mov esi, eax + add edi, ecx + shl edi, 2 + add esi, ecx + movzx ecx, byte [size] + mul cl + imul esi, ecx +fbloop: + mov ebx, ebp +@@: + mov [matrix + ebx + eax * 4], edx + add ebx, 4 + cmp edi, ebx + jg @b + add eax, ecx + cmp esi, eax + jg fbloop + pop ebp; restore previous base pointer + ret + + +numblocksingroup2: +;input: nothing +;output: eax = number of blocks in group 2 of QR code + mov edx, 2 + jmp lbt +group1datacodewords: +;input: nothing +;output: eax = number of data codewords in group 1 of QR code + mov edx, 1 + jmp lbt +numblocksingroup1: +;input: nothing +;output: eax = number of blocks in group 1 of QR code + mov edx, 0 +lbt: + mov eax, dword [version] + dec eax + imul eax, eax, 12 + imul ecx, dword [eclevel], 3 + add eax, edx + movzx eax, byte [bigtable + ecx + eax] + ret + + +group2datacodewords: +;input: nothing +;output: eax = number of data codewords in group 2 of QR code + call numblocksingroup2 + test eax, eax + jz @f + call group1datacodewords + inc eax +@@: + ret + + +eccodewordsperblock: +;input: nothing +;output: eax = number of EC codewords per block + call numdatacodewords + mov esi, DWORD [maxcodewords] + sub esi, eax + call numblocksingroup1 + mov edi, eax + call numblocksingroup2 + add edi, eax + mov eax, esi + cdq + idiv edi + ret + + +numdatacodewords: +;input: nothing +;output: eax = number of data codewords in QR code + call group1datacodewords + mov esi, eax + call numblocksingroup1 + imul esi, eax + call group2datacodewords + mov edi, eax + call numblocksingroup2 + imul edi, eax + add esi, edi + mov eax, esi + ret + +alphaindex: +;input: al +;output: eax = index of input in alphamode table, or 46 if not found + pop ecx + pop eax + push ecx + xor ecx, ecx +@@: + cmp [alphamode + ecx], al + je @f + inc cl + cmp cl, 46 + jl @b +@@: + mov eax, ecx + ret + + +mem7 db 7 + +drawalign: +;input: nothing +;output: alignment patterns (small squares) are drawn in matrix + mov eax, dword [version] + cmp al, 1 + jle drawalign_end + push eax + shl al, 2 + add al, 10 + mov byte [places + 1], al + pop eax + mov ebx, eax + idiv byte [mem7] + and eax, 255 + cmp al, 0 + je startloop + cmp al, 1 + jg case2 + inc bl + jmp @f +case2: + cmp al, 2 + jg case3 + sub bl, 4 + jmp @f +case3: + cmp al, 3 + jg case4 + sub bl, 10 +@@: + shl bl, 1 + jmp da_endcases +case4: + cmp al, 4 + jg case5 + sub bl, 28 + jmp @f +case5: + sub bl, 34 +@@: + mov bl, byte [diffs + ebx] +da_endcases: + mov ecx, 1 +@@: + mov dl, byte [places + ecx] + sub dl, bl + mov byte [places + 1 + ecx], dl + inc ecx + cmp ecx, eax + jle @b +startloop: + xor ecx, ecx +da_loop1: + xor edx, edx +da_loop2: + cmp cl, 0 + jne @f + cmp dl, 1 + jle da_continue +@@: + cmp cl, 1 + jne @f + cmp dl, 0 + je da_continue +@@: + push edx + push ecx + push dword [dark] + push 1 + movzx edx, byte [places + edx] + push edx + movzx ecx, byte [places + ecx] + push ecx + dec edx + dec ecx + push dword [lite] + push 3 + push edx + push ecx + dec ecx + dec edx + push dword [dark] + push 5 + push edx + push ecx + call fillbox + call fillbox + call fillbox + pop ecx + pop edx +da_continue: + inc dl + cmp dl, 7 + jge @f + cmp byte [places + edx], 0 + je @f + jmp da_loop2 +@@: + inc cl + cmp cl, 7 + jge @f + cmp byte [places + ecx], 0 + je @f + jmp da_loop1 +@@: +drawalign_end: + ret + +drawdarkmodule: +;input: nothing +;output: fixed dark module is drawn in matrix + push dword [dark] + push dword 1 + mov eax, dword [size] + sub eax, 8 + push eax + push dword 8 + call fillbox + ret + +getcharcountlength: +;input: nothing +;output: eax = length of character count marker, in bits + mov eax, [mode] + xor ebx, ebx + cmp [version], 9 + setg bl + cmp [version], 26 + setg cl + add bl, cl + shl bl, 2 + add ebx, charcountlengths + xlatb + ret + + +appendtobitset: +;input: ebx = pointer to bitset +; eax = data to add +; ecx = number of low-order bits from eax to add +;output: bitset is modified + pop ecx + pop ebx + pop eax + xchg ecx, dword [esp] +;remove the above to change calling convention +mbs EQU ebx +numbits EQu ecx + push ebp + dec numbits +appendloop: + mov edx, eax + shr edx, cl + push numbits + mov ecx, 7 + sub cl, byte [mbs + 8] + mov ebp, 1 + shl ebp, cl + mov ecx, dword [mbs] + add ecx, 9 + xchg ebp, ecx + and edx, 1 + jz @f + or byte [mbs + ebp], cl + jmp appenddone +@@: + not ecx + and byte [mbs + ebp], cl +appenddone: + pop numbits + inc dword [mbs + 4] + inc byte [mbs + 8] + and byte [mbs + 8], 7 + jnz @f + inc dword [mbs] +@@: + dec numbits + cmp numbits, 0 + jge appendloop + pop ebp + ret + + +drawfinders: +;input: nothing +;output: finder patterns (large squares) are drawn in matrix + push dword [lite] + push 8 + push 0 + push 0 + call fillbox + push dword [dark] + push 7 + push 0 + push 0 + call fillbox + push dword [lite] + push 5 + push 1 + push 1 + call fillbox + push dword [dark] + push 3 + push 2 + push 2 + call fillbox + push dword [lite] + push 8 + mov eax, dword [size] + sub eax, 8 + push eax + push 0 + call fillbox + push dword [dark] + push 7 + mov eax, dword [size] + sub eax, 7 + push eax + push 0 + call fillbox + push dword [lite] + push 5 + mov eax, dword [size] + sub eax, 6 + push eax + push 1 + call fillbox + push dword [dark] + push 3 + mov eax, dword [size] + sub eax, 5 + push eax + push 2 + call fillbox + push dword [lite] + push 8 + push 0 + mov eax, dword [size] + sub eax, 8 + push eax + call fillbox + push dword [dark] + push 7 + push 0 + mov eax, dword [size] + sub eax, 7 + push eax + call fillbox + push dword [lite] + push 5 + push 1 + mov eax, dword [size] + sub eax, 6 + push eax + call fillbox + push dword [dark] + push 3 + push 2 + mov eax, dword [size] + sub eax, 5 + push eax + call fillbox + ret + + +getdrawbit: +;input: eax = index of desired bit from ileaveddata +;output: eax = [ddat] if bit is 1, [ldat] otherwise +;pop ebx +;pop eax +;pop eax +;push ebx +;remove the above to change calling convention + mov ebx, eax + shr eax, 3 + and ebx, 7 + mov ecx, 7 + sub ecx, ebx + mov bl, byte [ileaveddata + 9 + eax] + shr bx, cl + mov eax, dword [ddat] + and ebx, 1 + jnz @f + mov eax, dword [ldat] +@@: + ret + +drawversion: +;input: nothing +;output: version info is drawn in matrix + mov ebx, dword [version] + cmp bx, 7 + jnge drawversion_end + sub bx, 7 + mov ebx, dword [versionstrings + ebx * 4] + xor ecx, ecx +drawverloop: + mov eax, 1 + shl ax, cl + and ax, bx + mov eax, dword [dark] + jnz @f + mov eax, dword [lite] +@@: + mov dword [versionstring + ecx * 4], eax + inc ecx + cmp ecx, 17 + jng drawverloop + xor ecx, ecx + xor ebx, ebx ;col + mov edx, dword [size] + sub dl, 8 + push edx +putversion1: + mov edx, dword [size] + sub edx, 11 ;row +putversion2: + mov eax, edx + mul byte [size] + add eax, ebx + push ebx + mov ebx, dword [versionstring + ecx * 4] + mov dword [matrix + eax * 4], ebx + pop ebx + push edx + mov eax, ebx + mul byte [size] + add eax, edx + mov edx, dword [versionstring + ecx * 4] + mov dword [matrix + eax * 4], edx + inc cx + pop edx + inc edx + cmp edx, dword [esp] + jl putversion2 + inc bx + cmp bx, 6 + jl putversion1 + pop edx +drawversion_end: + ret + +makeECgenerator: +;input: eax = desired order of EC generator polynomial +;output: genpoly array is modified + pop ecx + pop eax + push ecx +;remove the above to change calling convention + mov [genpoly], 0 + push eax + cld + mov ecx, 31 + mov edi, genpoly + xor eax, eax + rep stosb + mov ecx, 2 +ecgenloop: + push ecx + mov eax, ecx + dec eax + push eax + std + mov esi, genpoly - 1 + add esi, ecx + mov edi, esi + inc edi + rep movsb + mov al, [genpoly] + add eax, [esp] + cmp eax, 255 + jnge @f + sub eax, 255 + cmp eax, 255 + jnge @f + sub eax, 255 +@@: + mov [genpoly], al + inc cl +xorloop: + mov ebx, genpoly + mov eax, ecx + xlatb + mov dh, al + mov al, cl + inc eax + xlatb + add eax, [esp] + cmp eax, 255 + jnge @f + sub eax, 255 + cmp eax, 255 + jnge @f + sub eax, 255 +@@: + mov ebx, mod285logs + xlatb + mov dl, al + mov al, dh + xlatb + xor al, dl + mov ebx, mod285antilogs + xlatb + mov byte [genpoly + ecx], al + inc cl + cmp ecx, dword [esp + 4] + jl xorloop + pop ecx + pop ecx + inc cl + cmp cl, byte [esp] + jle ecgenloop + pop eax +end2: + cld + ret + +getblockpenalty: +;input: nothing +;output: eax = penalty score from squares + mov esi, 0 + mov ebx, [size] + dec bl + dec bl +sqloop2: + mov ecx, [size] + dec cl + dec cl +sqloop: + mov eax, ecx + imul byte [size] + add eax, ebx + mov edx, [matrix + eax * 4] + and edx, CMSK + mov edi, edx + mov edx, [matrix + 4 + eax * 4] + and edx, CMSK + cmp edx, edi + jne @f + add eax, [size] + mov edx, [matrix + eax * 4] + and edx, CMSK + cmp edx, edi + jne @f + mov edx, [matrix + 4 + eax * 4] + and edx, CMSK + cmp edx, edi + jne @f + add esi, 3 +@@: + dec ecx + cmp ecx, 0 + jge sqloop + dec ebx + cmp ebx, 0 + jge sqloop2 + mov eax, esi + ret + +getstraightpenalty: +;input: nothing +;output: eax = penalty score of qr code for +; straight runs of identical pixels + mov esi, 0 ; penalty + mov edi, 3 ; flags 1=new row, 2= new column + mov ecx, dword [size] + sub ecx, 5 +gsploop2: + mov ebx, dword [size] + sub ebx, 5 +gsploop1: + mov eax, ecx + imul byte [size] + add eax, ebx + push ecx + mov edx, dword [matrix + eax * 4] + and edx, CMSK + mov ecx, dword [matrix + 4 + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightrow + mov ecx, dword [matrix + 8 + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightrow + mov ecx, dword [matrix + 12 + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightrow + mov ecx, dword [matrix + 16 + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightrow + inc esi + test edi, 1 + jz @f + inc esi + inc esi +@@: + and edi, 2 + jmp @f +nostraightrow: + or edi, 1 +@@: + pop ecx + mov eax, ebx + imul byte [size] + add eax, ecx + push ecx + mov edx, dword [matrix + eax * 4] + and edx, CMSK + add eax, dword [size] + mov ecx, dword [matrix + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightcol + add eax, dword [size] + mov ecx, dword [matrix + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightcol + add eax, dword [size] + mov ecx, dword [matrix + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightcol + add eax, dword [size] + mov ecx, dword [matrix + eax * 4] + and ecx, CMSK + cmp edx, ecx + jne nostraightcol + inc esi + test edi, 2 + jz @f + inc esi + inc esi +@@: + and edi, 1 + jmp @f +nostraightcol: + or edi, 2 +@@: + pop ecx + dec ebx + cmp ebx, 0 + jge gsploop1 + mov edi, 3 + dec ecx + cmp ecx, 0 + jge gsploop2 + mov eax, esi + ret + + +;kolibrios_drawtowindow: +;;input: nothing +; call reducematrix +; mov eax, 7 +; mov ebx, matrix +; mov ecx, [size] +; shl ecx, 16 +; add ecx, [size] +; mov edx, 40 +; shl edx, 16 +; add edx, 80 +; int 0x40 +; ret + + +reducematrix: +;input: nothing +;reduces matrix from rgba to 3-byte rgb +;for use in KolibriOS system function 7 + mov ecx, [size2] + dec ecx + mov esi, matrix + mov edi, esi +redloop: + lodsd + mov bx, 0 + cmp al, 5 + jb @f + mov bx, 0xffff +@@: + xchg ax, bx + stosw + stosb + dec ecx + jns redloop + ret + +iglobal + +versionstrings dd 0x7C94, 0x85BC, 0x9A99, 0xA4D3, 0xBBF6 + dd 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78, 0x1145D + dd 0x12A17, 0x13532, 0x149A6, 0x15683, 0x168C9, 0x177EC + dd 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E, 0x1CC1A, 0x1D33F + dd 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA, 0x2379F + dd 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69 + +formatstrings dw 0x77C4, 0x72F3, 0x7DAA, 0x789D, 0x662F + dw 0x6318, 0x6C41, 0x6976, 0x5412, 0x5125, 0x5E7C + dw 0x5B4B, 0x45F9, 0x40CE, 0x4F97, 0x4AA0, 0x355F + dw 0x3068, 0x3F31, 0x3A06, 0x24B4, 0x2183, 0x2EDA + dw 0x2BED, 0x1689, 0x13BE, 0x1CE7, 0x19D0, 0x762 + dw 0x255, 0xD0C, 0x83B + +mod285logs db 1, 2, 4, 8, 16, 32, 64, 128, 29, 58, 116, 232 + db 205, 135, 19, 38, 76, 152, 45, 90, 180, 117, 234, 201 + db 143, 3, 6, 12, 24, 48, 96, 192, 157, 39, 78, 156, 37 + db 74, 148, 53, 106, 212, 181, 119, 238, 193, 159, 35 + db 70, 140, 5, 10, 20, 40, 80, 160, 93, 186, 105, 210 + db 185, 111, 222, 161, 95, 190, 97, 194, 153, 47, 94 + db 188, 101, 202, 137, 15, 30, 60, 120, 240, 253, 231 + db 211, 187, 107, 214, 177, 127, 254, 225, 223, 163, 91 + db 182, 113, 226, 217, 175, 67, 134, 17, 34, 68, 136, 13 + db 26, 52, 104, 208, 189, 103, 206, 129, 31, 62, 124, 248 + db 237, 199, 147, 59, 118, 236, 197, 151, 51, 102, 204 + db 133, 23, 46, 92, 184, 109, 218, 169, 79, 158, 33, 66 + db 132, 21, 42, 84, 168, 77, 154, 41, 82, 164, 85, 170 + db 73, 146, 57, 114, 228, 213, 183, 115, 230, 209, 191 + db 99, 198, 145, 63, 126, 252, 229, 215, 179, 123, 246 + db 241, 255, 227, 219, 171, 75, 150, 49, 98, 196, 149 + db 55, 110, 220, 165, 87, 174, 65, 130, 25, 50, 100, 200 + db 141, 7, 14, 28, 56, 112, 224, 221, 167, 83, 166, 81 + db 162, 89, 178, 121, 242, 249, 239, 195, 155, 43, 86 + db 172, 69, 138, 9, 18, 36, 72, 144, 61, 122, 244, 245 + db 247, 243, 251, 235, 203, 139, 11, 22, 44, 88, 176, 125 + db 250, 233, 207, 131, 27, 54, 108, 216, 173, 71, 142, 1 + +mod285antilogs db 0, 0, 1, 25, 2, 50, 26, 198, 3, 223, 51, 238 + db 27, 104, 199, 75, 4, 100, 224, 14, 52 + db 141, 239, 129, 28, 193, 105, 248, 200, 8, 76, 113, 5 + db 138, 101, 47, 225, 36, 15, 33, 53, 147, 142, 218, 240 + db 18, 130, 69, 29, 181, 194, 125, 106, 39, 249, 185, 201 + db 154, 9, 120, 77, 228, 114, 166, 6, 191, 139, 98, 102, 221 + db 48, 253, 226, 152, 37, 179, 16, 145, 34, 136, 54, 208 + db 148, 206, 143, 150, 219, 189, 241, 210, 19, 92, 131, 56 + db 70, 64, 30, 66, 182, 163, 195, 72, 126, 110, 107, 58, 40 + db 84, 250, 133, 186, 61, 202, 94, 155, 159, 10, 21, 121 + db 43, 78, 212, 229, 172, 115, 243, 167, 87, 7, 112, 192 + db 247, 140, 128, 99, 13, 103, 74, 222, 237, 49, 197, 254, 24 + db 227, 165, 153, 119, 38, 184, 180, 124, 17, 68, 146, 217 + db 35, 32, 137, 46, 55, 63, 209, 91, 149, 188, 207, 205, 144 + db 135, 151, 178, 220, 252, 190, 97, 242, 86, 211, 171, 20 + db 42, 93, 158, 132, 60, 57, 83, 71, 109, 65, 162, 31, 45, 67 + db 216, 183, 123, 164, 118, 196, 23, 73, 236, 127, 12, 111 + db 246, 108, 161, 59, 82, 41, 157, 85, 170, 251, 96, 134, 177 + db 187, 204, 62, 90, 203, 89, 95, 176, 156, 169, 160, 81, 11 + db 245, 22, 235, 122, 117, 44, 215, 79, 174, 213, 233, 230 + db 231, 173, 232, 116, 214, 244, 234, 168, 80, 88, 175 + +;bigtable (blocks by version and ec level) +;rowmajor - version +;rowminor - eclevel +;columns: number of blocks in group 1, +; number of data codewords in each of group 1's blocks, +; number of blocks in group 2, +bigtable db 1,19,0,1,16,0,1,13,0,1,9,0,1,34,0,1,28,0,1,22,0 + db 1,16,0,1,55,0,1,44,0,2,17,0,2,13,0,1,80 + db 0,2,32,0,2,24,0,4,9,0,1,108,0,2,43,0,2,15,2,2,11 + db 2,2,68,0,4,27,0,4,19,0,4,15,0,2,78,0,4 + db 31,0,2,14,4,4,13,1,2,97,0,2,38,2,4,18,2,4,14,2,2 + db 116,0,3,36,2,4,16,4,4,12,4,2,68,2,4,43 + db 1,6,19,2,6,15,2,4,81,0,1,50,4,4,22,4,3,12,8,2,92 + db 2,6,36,2,4,20,6,7,14,4,4,107,0,8,37,1,8 + db 20,4,12,11,4,3,115,1,4,40,5,11,16,5,11,12,5,5,87 + db 1,5,41,5,5,24,7,11,12,7,5,98,1,7,45,3 + db 15,19,2,3,15,13,1,107,5,10,46,1,1,22,15,2,14,17 + db 5,120,1,9,43,4,17,22,1,2,14,19,3,113,4,3 + db 44,11,17,21,4,9,13,16,3,107,5,3,41,13,15,24,5,15 + db 15,10,4,116,4,17,42,0,17,22,6,19,16,6,2 + db 111,7,17,46,0,7,24,16,34,13,0,4,121,5,4,47,14,11 + db 24,14,16,15,14,6,117,4,6,45,14,11,24,16 + db 30,16,2,8,106,4,8,47,13,7,24,22,22,15,13,10,114 + db 2,19,46,4,28,22,6,33,16,4,8,122,4,22,45 + db 3,8,23,26,12,15,28,3,117,10,3,45,23,4,24,31,11 + db 15,31,7,116,7,21,45,7,1,23,37,19,15,26,5 + db 115,10,19,47,10,15,24,25,23,15,25,13,115,3,2,46 + db 29,42,24,1,23,15,28,17,115,0,10,46,23,10 + db 24,35,19,15,35,17,115,1,14,46,21,29,24,19,11,15 + db 46,13,115,6,14,46,23,44,24,7,59,16,1,12 + db 121,7,12,47,26,39,24,14,22,15,41,6,121,14,6,47 + db 34,46,24,10,2,15,64,17,122,4,29,46,14,49 + db 24,10,24,15,46,4,122,18,13,46,32,48,24,14,42,15 + db 32,20,117,4,40,47,7,43,24,22,10,15,67,19 + db 118,6,18,47,31,34,24,34,20,15,61 + +charcountlengths db 10,9,8,8,12,11,16,10,14,13,16,12 + +modeindicators db 1,2,4,8,7 + +diffs db 24,24,26,26,26,28,28 + +alphamode db '0123456789ABCDEFGHIJKL' + db 'MNOPQRSTUVWXYZ $%*+-./:', 0 + +DARK equ 0 +CMSK equ 0FFFF00H + +;1 dark, 1 light, 3 dark, 1 light, 1 dark +;preceded or followed by 4 light +sequence dd CMSK, CMSK, CMSK, CMSK + dd DARK, CMSK, DARK, DARK, DARK, DARK + dd CMSK, DARK, CMSK, CMSK, CMSK, CMSK + +endg \ No newline at end of file diff --git a/programs/other/qrclipboard/qrclipboard.asm b/programs/other/qrclipboard/qrclipboard.asm new file mode 100644 index 000000000..64657a564 --- /dev/null +++ b/programs/other/qrclipboard/qrclipboard.asm @@ -0,0 +1,218 @@ +; QR code generator from clipbboard +; +; This program uses code from someone else's program, so the notice below +; is kept for compliance purposes. + + +;***************************************************************************** +; Read the data from the clipboard +; Copyright (c) 2013, Marat Zakiyanov aka Mario79, aka Mario +; All rights reserved. +; +; Redistribution and use in source and binary forms, with or without +; modification, are permitted provided that the following conditions are met: +; * Redistributions of source code must retain the above copyright +; notice, this list of conditions and the following disclaimer. +; * Redistributions in binary form must reproduce the above copyright +; notice, this list of conditions and the following disclaimer in the +; documentation and/or other materials provided with the distribution. +; * Neither the name of the nor the +; names of its contributors may be used to endorse or promote products +; derived from this software without specific prior written permission. +; +; THIS SOFTWARE IS PROVIDED BY Marat Zakiyanov ''AS IS'' AND ANY +; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +; WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +; DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY +; DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +; (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND +; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +;****************************************************************************** + use32 + org 0x0 + + db 'MENUET01' + dd 0x01 + dd START + dd IM_END + dd I_END + dd stacktop + dd 0x0 + dd 0x0 +;--------------------------------------------------------------------- +include 'macros.inc' + +START: + mcall 68,11 +red: + call draw_window +still: + mcall 10 + + cmp eax,1 + je red + cmp eax,2 + je key + cmp eax,3 + je button + + jmp still + +key: + mcall 2 + jmp still + +button: + mcall 17 + cmp ah,2 + je .read_button + cmp ah,1 + jne still +.exit: + mcall -1 + +.read_button: + call draw_clipboard + jmp still + +draw_window: + mcall 12,1 + xor esi,esi + mcall 0,<0,600>,<0,400>,0x13FFFFFF,,title + mcall 8,<20,150>,<40,20>,2,0xCCCCCC + mcall 4,<25,47>,0x90000000,read_button_text + mcall 12,2 + ret + +draw_clipboard: + mcall 54,0 + cmp eax,-1 + je exit + + test eax,eax + jz exit + + mov [slots_number],eax + dec eax + mov [current_slot],eax + + mov [text_coordinates],dword 10 shl 16+70 +start: + xor eax,eax + mov [current_slot_data],eax + mcall 54,1,[current_slot] + + cmp eax,-1 + je .no_relevant_data + + cmp eax,1 + jne @f + +.no_relevant_data: + mov edx,no_relevant_data_text + mov esi,no_relevant_data_text.end-no_relevant_data_text + jmp print +.no_relevant_data_1: + mov edx,no_relevant_data_text_1 + mov esi,no_relevant_data_text_1.end-no_relevant_data_text_1 + jmp print +.no_relevant_data_2: + mov edx,no_relevant_data_text_2 + mov esi,no_relevant_data_text_2.end-no_relevant_data_text_2 + jmp print +@@: + mov [current_slot_data],eax + mov eax,[current_slot_data] + mov esi,[eax] + sub esi,12 + add eax,4 + cmp [eax],dword 2 + jge .no_relevant_data_1 + add eax,4 + ;cmp [eax],dword 1 ; cp866 + ;je .no_relevant_data_2 ; + + + ;push 0 + cmp [eax], dword 0 + jne @f + ; push 26 + jmp skip2 +@@: + cmp [eax], dword 2 + jne @f + ;push 22 + jmp skip2 +@@: + + +skip2: + + add eax,4 +mov edx, matrix + mov ebx, eax + mov ecx, esi + mov eax, 78 + int 0x40 + +mov ebx, matrix + mov ecx, eax + shl ecx, 16 + add ecx, eax + mov eax, 7 + mov edx, 40 + shl edx, 16 + add edx, 80 + int 0x40 +doneQR: +print: + mov ecx,[current_slot_data] + test ecx,ecx + jz @f +@@: + add [text_coordinates],dword 15 + dec dword [current_slot] + dec dword [slots_number] +exit: + ret + + +;--------------------------------------------------------------------- +title: + db 'Make QR code from the clipboard ',0 +read_button_text: + db 'Make QR code ',0 +no_relevant_data_text: + db '',0 +.end: +no_relevant_data_text_1: + db '',0 +.end: +no_relevant_data_text_2: + db '',0 +.end: +;--------------------------------------------------------------------- +IM_END: +slots_number: + rd 1 +text_coordinates: + rd 1 +current_slot: + rd 1 +current_slot_data: + rd 1 + +;---------------------- + +matrix DD 31330 * 3 DUP (?) + +;-------------------------------------- + rb 5555 +stacktop: + rb 4 +;--------------------------------------------------------------------- +I_END: +;--------------------------------------------------------------------- \ No newline at end of file