EASYAIuniappNewUI/node_modules/qrcode-reader/src/databr.js
2025-02-08 18:50:38 +08:00

274 lines
8.0 KiB
JavaScript

/*
Ported to JavaScript by Lazar Laszlo 2011
lazarsoft@gmail.com, www.lazarsoft.info
*/
/*
*
* Copyright 2007 ZXing authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import {qrcode} from './qrcode';
export default function QRCodeDataBlockReader(blocks, version, numErrorCorrectionCode) {
this.blockPointer = 0;
this.bitPointer = 7;
this.dataLength = 0;
this.blocks = blocks;
this.numErrorCorrectionCode = numErrorCorrectionCode;
if (version <= 9)
this.dataLengthMode = 0;
else if (version >= 10 && version <= 26)
this.dataLengthMode = 1;
else if (version >= 27 && version <= 40)
this.dataLengthMode = 2;
}
QRCodeDataBlockReader.prototype.getNextBits = function(numBits) {
var bits = 0;
if (numBits < this.bitPointer + 1) {
// next word fits into current data block
var mask = 0;
for (var i = 0; i < numBits; i++) {
mask += (1 << i);
}
mask <<= (this.bitPointer - numBits + 1);
bits = (this.blocks[this.blockPointer] & mask) >> (this.bitPointer - numBits + 1);
this.bitPointer -= numBits;
return bits;
} else if (numBits < this.bitPointer + 1 + 8) {
// next word crosses 2 data blocks
var mask1 = 0;
for (var i = 0; i < this.bitPointer + 1; i++) {
mask1 += (1 << i);
}
bits = (this.blocks[this.blockPointer] & mask1) << (numBits - (this.bitPointer + 1));
this.blockPointer++;
bits += ((this.blocks[this.blockPointer]) >> (8 - (numBits - (this.bitPointer + 1))));
this.bitPointer = this.bitPointer - numBits % 8;
if (this.bitPointer < 0) {
this.bitPointer = 8 + this.bitPointer;
}
return bits;
} else if (numBits < this.bitPointer + 1 + 16) {
// next word crosses 3 data blocks
var mask1 = 0; // mask of first block
var mask3 = 0; // mask of 3rd block
//bitPointer + 1 : number of bits of the 1st block
//8 : number of the 2nd block (note that use already 8bits because next word uses 3 data blocks)
//numBits - (bitPointer + 1 + 8) : number of bits of the 3rd block
for (var i = 0; i < this.bitPointer + 1; i++) {
mask1 += (1 << i);
}
var bitsFirstBlock = (this.blocks[this.blockPointer] & mask1) << (numBits - (this.bitPointer + 1));
this.blockPointer++;
var bitsSecondBlock = this.blocks[this.blockPointer] << (numBits - (this.bitPointer + 1 + 8));
this.blockPointer++;
for (var i = 0; i < numBits - (this.bitPointer + 1 + 8); i++) {
mask3 += (1 << i);
}
mask3 <<= 8 - (numBits - (this.bitPointer + 1 + 8));
var bitsThirdBlock = (this.blocks[this.blockPointer] & mask3) >> (8 - (numBits - (this.bitPointer + 1 + 8)));
bits = bitsFirstBlock + bitsSecondBlock + bitsThirdBlock;
this.bitPointer = this.bitPointer - (numBits - 8) % 8;
if (this.bitPointer < 0) {
this.bitPointer = 8 + this.bitPointer;
}
return bits;
} else {
return 0;
}
};
QRCodeDataBlockReader.prototype.NextMode = function() {
if ((this.blockPointer > this.blocks.length - this.numErrorCorrectionCode - 2))
return 0;
else
return this.getNextBits(4);
};
QRCodeDataBlockReader.prototype.getDataLength = function(modeIndicator) {
var index = 0;
while (true) {
if ((modeIndicator >> index) == 1)
break;
index++;
}
return this.getNextBits(qrcode.sizeOfDataLengthInfo[this.dataLengthMode][index]);
};
QRCodeDataBlockReader.prototype.getRomanAndFigureString = function(dataLength) {
var length = dataLength;
var intData = 0;
var strData = "";
var tableRomanAndFigure = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', ' ', '$', '%', '*', '+', '-', '.', '/', ':'];
do {
if (length > 1) {
intData = this.getNextBits(11);
var firstLetter = Math.floor(intData / 45);
var secondLetter = intData % 45;
strData += tableRomanAndFigure[firstLetter];
strData += tableRomanAndFigure[secondLetter];
length -= 2;
} else if (length == 1) {
intData = this.getNextBits(6);
strData += tableRomanAndFigure[intData];
length -= 1;
}
}
while (length > 0);
return strData;
};
QRCodeDataBlockReader.prototype.getFigureString = function(dataLength) {
var length = dataLength;
var intData = 0;
var strData = "";
do {
if (length >= 3) {
intData = this.getNextBits(10);
if (intData < 100)
strData += "0";
if (intData < 10)
strData += "0";
length -= 3;
} else if (length == 2) {
intData = this.getNextBits(7);
if (intData < 10)
strData += "0";
length -= 2;
} else if (length == 1) {
intData = this.getNextBits(4);
length -= 1;
}
strData += intData;
}
while (length > 0);
return strData;
};
QRCodeDataBlockReader.prototype.get8bitByteArray = function(dataLength) {
var length = dataLength;
var intData = 0;
var output = [];
do {
intData = this.getNextBits(8);
output.push(intData);
length--;
}
while (length > 0);
return output;
};
QRCodeDataBlockReader.prototype.getKanjiString = function(dataLength) {
var length = dataLength;
var intData = 0;
var unicodeString = "";
do {
intData = this.getNextBits(13);
var lowerByte = intData % 0xC0;
var higherByte = intData / 0xC0;
var tempWord = (higherByte << 8) + lowerByte;
var shiftjisWord = 0;
if (tempWord + 0x8140 <= 0x9FFC) {
// between 8140 - 9FFC on Shift_JIS character set
shiftjisWord = tempWord + 0x8140;
} else {
// between E040 - EBBF on Shift_JIS character set
shiftjisWord = tempWord + 0xC140;
}
unicodeString += String.fromCharCode(shiftjisWord);
length--;
}
while (length > 0);
return unicodeString;
};
Object.defineProperty(QRCodeDataBlockReader.prototype, "DataByte", {
get: function() {
var output = [];
var MODE_NUMBER = 1;
var MODE_ROMAN_AND_NUMBER = 2;
var MODE_8BIT_BYTE = 4;
var MODE_KANJI = 8;
do {
var mode = this.NextMode();
if (mode == 0) {
if (output.length > 0)
break;
else
throw "Empty data block";
}
//if (mode != 1 && mode != 2 && mode != 4 && mode != 8)
//}
if (mode != MODE_NUMBER && mode != MODE_ROMAN_AND_NUMBER && mode != MODE_8BIT_BYTE && mode != MODE_KANJI && mode != 7) {
/* canvas.println("Invalid mode: " + mode);
mode = guessMode(mode);
canvas.println("Guessed mode: " + mode); */
throw "Invalid mode: " + mode + " in (block:" + this.blockPointer + " bit:" + this.bitPointer + ")";
}
var dataLength = this.getDataLength(mode);
if (dataLength < 1)
throw "Invalid data length: " + dataLength;
switch (mode) {
case MODE_NUMBER:
var temp_str = this.getFigureString(dataLength);
var ta = new Array(temp_str.length);
for (var j = 0; j < temp_str.length; j++)
ta[j] = temp_str.charCodeAt(j);
output.push(ta);
break;
case MODE_ROMAN_AND_NUMBER:
var temp_str = this.getRomanAndFigureString(dataLength);
var ta = new Array(temp_str.length);
for (var j = 0; j < temp_str.length; j++)
ta[j] = temp_str.charCodeAt(j);
output.push(ta);
break;
case MODE_8BIT_BYTE:
var temp_sbyteArray3 = this.get8bitByteArray(dataLength);
output.push(temp_sbyteArray3);
break;
case MODE_KANJI:
var temp_str = this.getKanjiString(dataLength);
output.push(temp_str);
break;
}
//
}
while (true);
return output;
}
});