更新
This commit is contained in:
+273
@@ -0,0 +1,273 @@
|
||||
/*
|
||||
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;
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user