diff --git a/src/alignpat.js b/src/alignpat.js index 967473f3..affa5a91 100644 --- a/src/alignpat.js +++ b/src/alignpat.js @@ -48,7 +48,7 @@ function AlignmentPattern(posX, posY, estimatedModuleSize) }); this.incrementCount = function() { - this.count++; + ++this.count; } this.aboutEquals=function( moduleSize, i, j) { @@ -65,13 +65,13 @@ function AlignmentPattern(posX, posY, estimatedModuleSize) function AlignmentPatternFinder( image, startX, startY, width, height, moduleSize, resultPointCallback) { this.image = image; - this.possibleCenters = new Array(); + this.possibleCenters = []; this.startX = startX; this.startY = startY; this.width = width; this.height = height; this.moduleSize = moduleSize; - this.crossCheckStateCount = new Array(0,0,0); + this.crossCheckStateCount = [0,0,0]; this.resultPointCallback = resultPointCallback; this.centerFromEnd=function(stateCount, end) @@ -82,7 +82,7 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu { var moduleSize = this.moduleSize; var maxVariance = moduleSize / 2.0; - for (var i = 0; i < 3; i++) + for (var i = 0; i < 3; ++i) { if (Math.abs(moduleSize - stateCount[i]) >= maxVariance) { @@ -106,8 +106,8 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu var i = startI; while (i >= 0 && image[centerJ + i*qrcode.width] && stateCount[1] <= maxCount) { - stateCount[1]++; - i--; + ++stateCount[1]; + --i; } // If already too many modules in this state or ran off the edge: if (i < 0 || stateCount[1] > maxCount) @@ -116,8 +116,8 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu } while (i >= 0 && !image[centerJ + i*qrcode.width] && stateCount[0] <= maxCount) { - stateCount[0]++; - i--; + ++stateCount[0]; + --i; } if (stateCount[0] > maxCount) { @@ -128,8 +128,8 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu i = startI + 1; while (i < maxI && image[centerJ + i*qrcode.width] && stateCount[1] <= maxCount) { - stateCount[1]++; - i++; + ++stateCount[1]; + ++i; } if (i == maxI || stateCount[1] > maxCount) { @@ -137,8 +137,8 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu } while (i < maxI && !image[centerJ + i*qrcode.width] && stateCount[2] <= maxCount) { - stateCount[2]++; - i++; + ++stateCount[2]; + ++i; } if (stateCount[2] > maxCount) { @@ -163,7 +163,7 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu { var estimatedModuleSize = (stateCount[0] + stateCount[1] + stateCount[2]) / 3.0; var max = this.possibleCenters.length; - for (var index = 0; index < max; index++) + for (var index = 0; index < max; ++index) { var center = this.possibleCenters[index]; // Look for about the same center and module size: @@ -191,8 +191,8 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu var middleI = startY + (height >> 1); // We are looking for black/white/black modules in 1:1:1 ratio; // this tracks the number of black/white/black modules seen so far - var stateCount = new Array(0,0,0); - for (var iGen = 0; iGen < height; iGen++) + var stateCount = [0,0,0]; + for (var iGen = 0; iGen < height; ++iGen) { // Search from middle outwards var i = middleI + ((iGen & 0x01) == 0?((iGen + 1) >> 1):- ((iGen + 1) >> 1)); @@ -205,7 +205,7 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu // white run continued to the left of the start point while (j < maxJ && !image[j + qrcode.width* i]) { - j++; + ++j; } var currentState = 0; while (j < maxJ) @@ -216,7 +216,7 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu if (currentState == 1) { // Counting black pixels - stateCount[currentState]++; + ++stateCount[currentState]; } else { @@ -240,7 +240,7 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu } else { - stateCount[++currentState]++; + ++stateCount[++currentState]; } } } @@ -250,11 +250,11 @@ function AlignmentPatternFinder( image, startX, startY, width, height, modu if (currentState == 1) { // Counting black pixels - currentState++; + ++currentState; } - stateCount[currentState]++; + ++stateCount[currentState]; } - j++; + ++j; } if (this.foundPatternCross(stateCount)) { diff --git a/src/bitmat.js b/src/bitmat.js index 5b007842..d4b0b874 100644 --- a/src/bitmat.js +++ b/src/bitmat.js @@ -36,12 +36,11 @@ function BitMatrix( width, height) var rowSize = width >> 5; if ((width & 0x1f) != 0) { - rowSize++; + ++rowSize; } this.rowSize = rowSize; this.bits = new Array(rowSize * height); - for(var i=0;i> 5)] |= 1 << (x & 0x1f); } diff --git a/src/bmparser.js b/src/bmparser.js index 51c6e85d..0593f1b6 100644 --- a/src/bmparser.js +++ b/src/bmparser.js @@ -48,7 +48,7 @@ function BitMatrixParser(bitMatrix) // Read top-left format info bits var formatInfoBits = 0; - for (var i = 0; i < 6; i++) + for (var i = 0; i < 6; ++i) { formatInfoBits = this.copyBit(i, 8, formatInfoBits); } @@ -57,7 +57,7 @@ function BitMatrixParser(bitMatrix) formatInfoBits = this.copyBit(8, 8, formatInfoBits); formatInfoBits = this.copyBit(8, 7, formatInfoBits); // .. and skip a bit in the timing pattern ... - for (var j = 5; j >= 0; j--) + for (var j = 5; j >= 0; --j) { formatInfoBits = this.copyBit(8, j, formatInfoBits); } @@ -72,11 +72,11 @@ function BitMatrixParser(bitMatrix) var dimension = this.bitMatrix.Dimension; formatInfoBits = 0; var iMin = dimension - 8; - for (var i = dimension - 1; i >= iMin; i--) + for (var i = dimension - 1; i >= iMin; --i) { formatInfoBits = this.copyBit(i, 8, formatInfoBits); } - for (var j = dimension - 7; j < dimension; j++) + for (var j = dimension - 7; j < dimension; ++j) { formatInfoBits = this.copyBit(8, j, formatInfoBits); } @@ -107,9 +107,9 @@ function BitMatrixParser(bitMatrix) // Read top-right version info: 3 wide by 6 tall var versionBits = 0; var ijMin = dimension - 11; - for (var j = 5; j >= 0; j--) + for (var j = 5; j >= 0; --j) { - for (var i = dimension - 9; i >= ijMin; i--) + for (var i = dimension - 9; i >= ijMin; --i) { versionBits = this.copyBit(i, j, versionBits); } @@ -123,9 +123,9 @@ function BitMatrixParser(bitMatrix) // Hmm, failed. Try bottom left: 6 wide by 3 tall versionBits = 0; - for (var i = 5; i >= 0; i--) + for (var i = 5; i >= 0; --i) { - for (var j = dimension - 9; j >= ijMin; j--) + for (var j = dimension - 9; j >= ijMin; --j) { versionBits = this.copyBit(i, j, versionBits); } @@ -164,19 +164,19 @@ function BitMatrixParser(bitMatrix) { // Skip whole column with vertical alignment pattern; // saves time and makes the other code proceed more cleanly - j--; + --j; } // Read alternatingly from bottom to top then top to bottom - for (var count = 0; count < dimension; count++) + for (var count = 0; count < dimension; ++count) { var i = readingUp?dimension - 1 - count:count; - for (var col = 0; col < 2; col++) + for (var col = 0; col < 2; ++col) { // Ignore bits covered by the function pattern if (!functionPattern.get_Renamed(j - col, i)) { // Read a bit - bitsRead++; + ++bitsRead; currentByte <<= 1; if (this.bitMatrix.get_Renamed(j - col, i)) { diff --git a/src/datablock.js b/src/datablock.js index 3cb277a8..7991cf90 100644 --- a/src/datablock.js +++ b/src/datablock.js @@ -53,7 +53,7 @@ DataBlock.getDataBlocks=function(rawCodewords, version, ecLevel) // First count the total number of data blocks var totalBlocks = 0; var ecBlockArray = ecBlocks.getECBlocks(); - for (var i = 0; i < ecBlockArray.length; i++) + for (var i = 0; i < ecBlockArray.length; ++i) { totalBlocks += ecBlockArray[i].Count; } @@ -61,10 +61,10 @@ DataBlock.getDataBlocks=function(rawCodewords, version, ecLevel) // Now establish DataBlocks of the appropriate size and number of data codewords var result = new Array(totalBlocks); var numResultBlocks = 0; - for (var j = 0; j < ecBlockArray.length; j++) + for (var j = 0; j < ecBlockArray.length; ++j) { var ecBlock = ecBlockArray[j]; - for (var i = 0; i < ecBlock.Count; i++) + for (var i = 0; i < ecBlock.Count; ++i) { var numDataCodewords = ecBlock.DataCodewords; var numBlockCodewords = ecBlocks.ECCodewordsPerBlock + numDataCodewords; @@ -83,31 +83,31 @@ DataBlock.getDataBlocks=function(rawCodewords, version, ecLevel) { break; } - longerBlocksStartAt--; + --longerBlocksStartAt; } - longerBlocksStartAt++; + ++longerBlocksStartAt; var shorterBlocksNumDataCodewords = shorterBlocksTotalCodewords - ecBlocks.ECCodewordsPerBlock; // The last elements of result may be 1 element longer; // first fill out as many elements as all of them have var rawCodewordsOffset = 0; - for (var i = 0; i < shorterBlocksNumDataCodewords; i++) + for (var i = 0; i < shorterBlocksNumDataCodewords; ++i) { - for (var j = 0; j < numResultBlocks; j++) + for (var j = 0; j < numResultBlocks; ++j) { result[j].codewords[i] = rawCodewords[rawCodewordsOffset++]; } } // Fill out the last data block in the longer ones - for (var j = longerBlocksStartAt; j < numResultBlocks; j++) + for (var j = longerBlocksStartAt; j < numResultBlocks; ++j) { result[j].codewords[shorterBlocksNumDataCodewords] = rawCodewords[rawCodewordsOffset++]; } // Now add in error correction blocks var max = result[0].codewords.length; - for (var i = shorterBlocksNumDataCodewords; i < max; i++) + for (var i = shorterBlocksNumDataCodewords; i < max; ++i) { - for (var j = 0; j < numResultBlocks; j++) + for (var j = 0; j < numResultBlocks; ++j) { var iOffset = j < longerBlocksStartAt?i:i + 1; result[j].codewords[iOffset] = rawCodewords[rawCodewordsOffset++]; diff --git a/src/databr.js b/src/databr.js index f40257f2..249b1028 100644 --- a/src/databr.js +++ b/src/databr.js @@ -22,315 +22,544 @@ * limitations under the License. */ +var shift_jis_table; -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; - - this.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; - } - } - this.NextMode=function() - { - if ((this.blockPointer > this.blocks.length - this.numErrorCorrectionCode - 2)) - return 0; - else - return this.getNextBits(4); - } - this.getDataLength=function( modeIndicator) - { - var index = 0; - while (true) - { - if ((modeIndicator >> index) == 1) - break; - index++; - } - - return this.getNextBits(qrcode.sizeOfDataLengthInfo[this.dataLengthMode][index]); - } - this.getRomanAndFigureString=function( dataLength) - { - var length = dataLength; - var intData = 0; - var strData = ""; - var tableRomanAndFigure = new Array('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; - } - this.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; - } - this.get8bitByteArray=function( dataLength) - { - var length = dataLength; - var intData = 0; - var output = new Array(); - - do - { - intData = this.getNextBits(8); - output.push( intData); - length--; - } - while (length > 0); - return output; - } - this.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; - } - - //var tempByte = new Array(0,0); - //tempByte[0] = (sbyte) (shiftjisWord >> 8); - //tempByte[1] = (sbyte) (shiftjisWord & 0xFF); - //unicodeString += new String(SystemUtils.ToCharArray(SystemUtils.ToByteArray(tempByte))); - unicodeString += String.fromCharCode(shiftjisWord); - length--; - } - while (length > 0); - - - return unicodeString; - } +function QRCodeDataBlockReader(blocks, version, numErrorCorrectionCode) { + this.blockPointer = 0; + this.bitOffset = 0; + 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; + this.require = function (url) { + var xhr = null; + if (window.ActiveXObject) { //IE + try { + // lte IE6 + xhr = new ActiveXObject("Msxml2.XMLHTTP"); + } catch (e) { + // lte IE5.5 + xhr = new ActiveXObject("Microsoft.XMLHTTP"); + } + } else if (window.XMLHttpRequest) { + //Firefox,Opera 8.0+,Safari,Chrome + xhr = new XMLHttpRequest(); + } + xhr.open("GET", url, false); + xhr.send(); + if (xhr.readyState == 4) { + if ((xhr.status / 100 == 2) || xhr.status == 0 || xhr.status == 304) { + var doc = document; + var myBody = doc.getElementsByTagName("BODY")[0]; + var myScript = doc.createElement("script"); + myScript.language = "javascript"; + myScript.type = "text/javascript"; + try { + myScript.appendChild(doc.createTextNode(xhr.responseText)); + } catch (ex) { + // lte IE8 + myScript.text = xhr.responseText; + } + myBody.appendChild(myScript); + } + } + } - this.parseECIValue = function () - { - var intData = 0; - var firstByte = this.getNextBits(8); - if ((firstByte & 0x80) == 0) { - intData = firstByte & 0x7F; - } - if ((firstByte & 0xC0) == 0x80) { - // two bytes - var secondByte = this.getNextBits(8); - intData = ((firstByte & 0x3F) << 8) | secondByte; - } - if ((firstByte & 0xE0) == 0xC0) { - // three bytes - var secondThirdBytes = this.getNextBits(8);; - intData = ((firstByte & 0x1F) << 16) | secondThirdBytes; - } - return intData; - } + this.getNextBits = function (numBits) { + var result = 0; - this.__defineGetter__("DataByte", function() - { - var output = new Array(); - var MODE_NUMBER = 1; - var MODE_ROMAN_AND_NUMBER = 2; - var MODE_8BIT_BYTE = 4; - var MODE_ECI = 7; - var MODE_KANJI = 8; - do - { - var mode = this.NextMode(); - //canvas.println("mode: " + mode); - if (mode == 0) - { - if (output.length > 0) - break; - else - throw "Empty data block"; - } - if (mode != MODE_NUMBER && mode != MODE_ROMAN_AND_NUMBER && mode != MODE_8BIT_BYTE && mode != MODE_KANJI && mode != MODE_ECI) - { - throw "Invalid mode: " + mode + " in (block:" + this.blockPointer + " bit:" + this.bitPointer + ")"; - } + // First, read remainder from current byte + if (this.bitOffset > 0) { + var bitsLeft = 8 - this.bitOffset; + var toRead = numBits < bitsLeft ? numBits : bitsLeft; + var bitsToNotRead = bitsLeft - toRead; + var mask = (0xFF >> (8 - toRead)) << bitsToNotRead; + result = (this.blocks[this.blockPointer] & mask) >> bitsToNotRead; + numBits -= toRead; + this.bitOffset += toRead; + if (this.bitOffset == 8) { + this.bitOffset = 0; + ++this.blockPointer; + } + } - if(mode == MODE_ECI) - { - var temp_sbyteArray3 = this.parseECIValue(); - //output.push(temp_sbyteArray3); - } - else - { + // Next read whole bytes + if (numBits > 0) { + while (numBits >= 8) { + result = (result << 8) | (this.blocks[this.blockPointer] & 0xFF); + ++this.blockPointer; + numBits -= 8; + } - 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 0) { + var bitsToNotRead = 8 - numBits; + var mask = (0xFF >> bitsToNotRead) << bitsToNotRead; + result = (result << numBits) | ((this.blocks[this.blockPointer] & mask) >> bitsToNotRead); + this.bitOffset += numBits; + } + } + return result; + } + this.NextMode = function () { + if ((this.blockPointer > this.blocks.length - this.numErrorCorrectionCode - 2)) + return 0; + else + return this.getNextBits(4); + } + this.sizeOfDataLengthInfo = [ + [0, 0, 0], + [10, 12, 14], // NUMERIC + [9, 11, 13], // ALPHANUMERIC + [0, 0, 0], // STRUCTURED_APPEND + [8, 16, 16], // BYTE + [0, 0, 0], // FNC1_FIRST_POSITION + [0, 0, 0], + [0, 0, 0], // ECI + [8, 10, 12], // KANJI + [0, 0, 0], // FNC1_SECOND_POSITION + [8, 10, 12]// HANZI + ]; + this.tableAplhaNumeric = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:".split(''); + this.getDataLength = function (modeIndicator) { + return this.getNextBits(this.sizeOfDataLengthInfo[modeIndicator][this.dataLengthMode]); + } + this.getAlphaNumericString = function (dataLength) { + var strData = ""; + do { + if (dataLength > 1) { + var intData = this.getNextBits(11); + var firstLetter = Math.floor(intData / 45); + var secondLetter = intData % 45; + strData += this.tableAplhaNumeric[firstLetter]; + strData += this.tableAplhaNumeric[secondLetter]; + dataLength -= 2; + } else if (dataLength == 1) { + strData += this.tableAplhaNumeric[this.getNextBits(6)]; + dataLength -= 1; + } + } while (dataLength > 0); + + return strData; + } + this.getNumericString = function (dataLength) { + var intData = 0; + var strData = ""; + do { + if (dataLength >= 3) { + intData = this.getNextBits(10); + if (intData < 100) + strData += "0"; + if (intData < 10) + strData += "0"; + dataLength -= 3; + } else if (dataLength == 2) { + intData = this.getNextBits(7); + if (intData < 10) + strData += "0"; + dataLength -= 2; + } else if (dataLength == 1) { + intData = this.getNextBits(4); + dataLength -= 1; + } + strData += intData; + } while (dataLength > 0); + + return strData; + } + this.defaultEncoding = this.ISO88591Encoding; + this.ISO88591Encoding = function (data) { + var output = ""; + for (var i = 0; i < data.length; ++i) { + output += String.fromCharCode(data[i]); + } + return output; + } + this.ShiftJISEncoding = function (data) { + var output = ""; + var tail = 0; + var character = 0; + + for (var i = 0; i < data.length; ++i) { + if (data[i] < 0x80) { + if (data[i] == 0x5C) + character = 0x00A5; + else if (data[i] == 0x7E) + character = 0x203E; + else + character = data[i]; + } else if ((data[i] >= 0xA1 && data[i] <= 0xDF)) { + character = data[i] + 0xFEC0; + } else if ((data[i] >= 0x81 && data[i] <= 0x9F) || (data[i] >= 0xE0 && data[i] <= 0xEA)) { + if (i == data.length - 1) + throw "Too few bytes." + var s1 = data[i]; + var s2 = data[++i]; + if ((s2 >= 0x40 && s2 <= 0x7E) || (s2 >= 0x80 && s2 <= 0xFC)) { + var t1 = (s1 < 0xE0 ? s1 - 0x81 : s1 - 0xC1); + var t2 = (s2 < 0x80 ? s2 - 0x40 : s2 - 0x41); + var c1 = 2 * t1 + (t2 < 0x5E ? 0 : 1); + var c2 = (t2 < 0x5E ? t2 : t2 - 0x5E); + if ((c1 <= 0x07) || (c1 >= 0x0F && c1 <= 0x53)) { + if (c2 < 0x7F) { + var tmp = 94 * c1 + c2; + character = 0xFFFD; + if (tmp < 1410) { + if (tmp < 690) { + if (!shift_jis_table) + this.require('shift_jis_table.js'); + character = shift_jis_table.jisx0208_2uni_page21[tmp]; + } + } else { + if (tmp < 7808) { + if (!shift_jis_table) + this.require('shift_jis_table.js'); + character = shift_jis_table.jisx0208_2uni_page30[tmp - 1410]; + } + } + } + } + } + } else if (data[i] >= 0xF0 && data[i] <= 0xF9) { + /* User-defined range. See + * Ken Lunde's "CJKV Information Processing", table 4-66, p. 206. */ + if (i == data.length - 1) + throw "Too few bytes." + var s1 = data[i]; + var s2 = data[++i]; + if ((s2 >= 0x40 && s2 <= 0x7E) || (s2 >= 0x80 && s2 <= 0xFC)) { + character = 0xE000 + 188 * (s1 - 0xF0) + (s2 < 0x80 ? s2 - 0x40 : s2 - 0x41); + } + } + output += String.fromCharCode(character); + } + return output; + } + this.UTF8Encoding = function (data) { + var output = ""; + var tail = 0; + var character = 0; + + for (var i = 0; i < data.length; ++i) { + if (tail-- > 0) { + if (data[i] >= 128 && data[i] <= 191) { //10XX XXXX + character = (character << 6) + (data[i] & 0x3F); + } else { + // TODO: malformed warning + } + } else { + if (data[i] <= 127) { //0XXX XXXX + tail = -1; + } else if (data[i] >= 192 && data[i] <= 223) { //110X XXXX + tail = 1; + } else if (data[i] >= 224 && data[i] <= 239) { //1110 XXXX + tail = 2; + } else if (data[i] >= 240 && data[i] <= 247) { //1111 0XXX + tail = 3; + } else if (data[i] >= 248 && data[i] <= 251) { //1111 10XX + tail = 4; + } else if (data[i] >= 252 && data[i] <= 253) { //1111 110X + tail = 5; + } else { + // TODO: malformed warning + } + character = data[i] & (0xFF >> (tail + 2)); + } + if (tail <= 0) { + output += String.fromCharCode(character); + } + } + return output; + } + this.guessEncoding = function (data) { + // For now, merely tries to distinguish ISO-8859-1, UTF-8 and Shift_JIS, + // which should be by far the most common encodings. + var length = data.length; + var canBeISO88591 = true; + var canBeShiftJIS = true; + var canBeUTF8 = true; + var utf8BytesLeft = 0; + //var utf8LowChars = 0; + var utf2BytesChars = 0; + var utf3BytesChars = 0; + var utf4BytesChars = 0; + var sjisBytesLeft = 0; + //var sjisLowChars = 0; + var sjisKatakanaChars = 0; + //var sjisDoubleBytesChars = 0; + var sjisCurKatakanaWordLength = 0; + var sjisCurDoubleBytesWordLength = 0; + var sjisMaxKatakanaWordLength = 0; + var sjisMaxDoubleBytesWordLength = 0; + //var isoLowChars = 0; + //var isoHighChars = 0; + var isoHighOther = 0; + + var utf8bom = data.length > 3 && + data[0] == 0xEF && + data[1] == 0xBB && + data[2] == 0xBF; + + for (var i = 0; + i < length && (canBeISO88591 || canBeShiftJIS || canBeUTF8); + ++i) { + + var value = data[i] & 0xFF; + + // UTF-8 stuff + if (canBeUTF8) { + if (utf8BytesLeft > 0) { + if ((value & 0x80) == 0) { + canBeUTF8 = false; + } else { + --utf8BytesLeft; + } + } else if ((value & 0x80) != 0) { + if ((value & 0x40) == 0) { + canBeUTF8 = false; + } else { + ++utf8BytesLeft; + if ((value & 0x20) == 0) { + ++utf2BytesChars; + } else { + ++utf8BytesLeft; + if ((value & 0x10) == 0) { + ++utf3BytesChars; + } else { + ++utf8BytesLeft; + if ((value & 0x08) == 0) { + ++utf4BytesChars; + } else { + canBeUTF8 = false; + } + } + } + } + } //else { + //++utf8LowChars; + //} + } + + // ISO-8859-1 stuff + if (canBeISO88591) { + if (value > 0x7F && value < 0xA0) { + canBeISO88591 = false; + } else if (value > 0x9F) { + if (value < 0xC0 || value == 0xD7 || value == 0xF7) { + ++isoHighOther; + } //else { + //++isoHighChars; + //} + } //else { + //++isoLowChars; + //} + } + + // Shift_JIS stuff + if (canBeShiftJIS) { + if (sjisBytesLeft > 0) { + if (value < 0x40 || value == 0x7F || value > 0xFC) { + canBeShiftJIS = false; + } else { + --sjisBytesLeft; + } + } else if (value == 0x80 || value == 0xA0 || value > 0xEF) { + canBeShiftJIS = false; + } else if (value > 0xA0 && value < 0xE0) { + ++sjisKatakanaChars; + sjisCurDoubleBytesWordLength = 0; + ++sjisCurKatakanaWordLength; + if (sjisCurKatakanaWordLength > sjisMaxKatakanaWordLength) { + sjisMaxKatakanaWordLength = sjisCurKatakanaWordLength; + } + } else if (value > 0x7F) { + ++sjisBytesLeft; + //+sjisDoubleBytesChars+; + sjisCurKatakanaWordLength = 0; + ++sjisCurDoubleBytesWordLength; + if (sjisCurDoubleBytesWordLength > sjisMaxDoubleBytesWordLength) { + sjisMaxDoubleBytesWordLength = sjisCurDoubleBytesWordLength; + } + } else { + //++sjisLowChars; + sjisCurKatakanaWordLength = 0; + sjisCurDoubleBytesWordLength = 0; + } + } + } + + if (canBeUTF8 && utf8BytesLeft > 0) { + canBeUTF8 = false; + } + if (canBeShiftJIS && sjisBytesLeft > 0) { + canBeShiftJIS = false; + } + + // Easy -- if there is BOM or at least 1 valid not-single byte character (and no evidence it can't be UTF-8), done + if (canBeUTF8 && (utf8bom || utf2BytesChars + utf3BytesChars + utf4BytesChars > 0)) { + return this.UTF8Encoding(data); + } + // Easy -- if assuming Shift_JIS or at least 3 valid consecutive not-ascii characters (and no evidence it can't be), done + if (canBeShiftJIS && (/*ASSUME_SHIFT_JIS || */ + sjisMaxKatakanaWordLength >= 3 || sjisMaxDoubleBytesWordLength >= 3)) { + return this.ShiftJISEncoding(data); + } + // Distinguishing Shift_JIS and ISO-8859-1 can be a little tough for short words. The crude heuristic is: + // - If we saw + // - only two consecutive katakana chars in the whole text, or + // - at least 10% of bytes that could be "upper" not-alphanumeric Latin1, + // - then we conclude Shift_JIS, else ISO-8859-1 + if (canBeISO88591 && canBeShiftJIS) { + return (sjisMaxKatakanaWordLength == 2 && sjisKatakanaChars == 2) || isoHighOther * 10 >= length + ? this.ShiftJISEncoding(data) : this.ISO88591Encoding(data); + } + + // Otherwise, try in order ISO-8859-1, Shift JIS, UTF-8 and fall back to default platform encoding + if (canBeISO88591) { + return this.ISO88591Encoding(data); + } + if (canBeShiftJIS) { + return this.ShiftJISEncoding(data); + } + if (canBeUTF8) { + return this.UTF8Encoding(data); + } + // Otherwise, we take a wild guess with platform encoding + return this.defaultEncoding(data); + } + this.get8bitByteArray = function (dataLength) { + var output = []; + do { + output.push(this.getNextBits(8)); + } while (--dataLength > 0); + return this.guessEncoding(output); + } + this.getKanjiString = function (dataLength) { + var unicodeString = ""; + do { + var intData = this.getNextBits(13); + var tempWord = ((intData / 0xC0) << 8) + intData % 0xC0; + // between 8140 - 9FFC on Shift_JIS character set + // between E040 - EBBF on Shift_JIS character set + tempWord += tempWord < 0x01F00 ? 0x08140 : 0x0C140; + unicodeString += this.ShiftJISEncoding([tempWord >> 8, tempWord & 0xFF]); + } while (--dataLength > 0); + + return unicodeString; + } + this.getHanziString = function (dataLength) { + var unicodeString = ""; + do { + var intData = this.getNextBits(13); + var tempWord = ((intData / 0x060) << 8) + (intData % 0x060); + unicodeString += String.fromCharCode(tempWord + (tempWord < 0x003BF ? 0x0A1A1 : 0x0A6A1)); + } while (--dataLength > 0); + + return unicodeString; + } + this.__defineGetter__("DataByte", function () { + var output = ""; + const MODE_NUMBERIC = 1; + const MODE_ALPHA_NUMBERIC = 2; + const MODE_STRUCTURED_APPEND = 3; + const MODE_8BIT_BYTE = 4; + const MODE_FNC1_FIRST_POSITION = 5; + const MODE_ECI = 7; + const MODE_KANJI = 8; + const MODE_FNC1_SECOND_POSITION = 9; + const MODE_HANZI = 10; // defined in GBT 18284-2000, may not be supported in foreign country + + const GB2312_SUBSET = 1; + var fc1InEffect = false; + var encoding; + do { + var mode = this.NextMode(); + if (mode == 0) { + if (output.length > 0) + break; + else + throw "Empty data block"; + } + if (mode == MODE_FNC1_FIRST_POSITION || mode == MODE_FNC1_SECOND_POSITION) { + // We do little with FNC1 except alter the parsed result a bit according to the spec + fc1InEffect = true; + } else if (mode == MODE_STRUCTURED_APPEND) { + // sequence number and parity is added later to the result metadata + // Read next 8 bits (symbol sequence #) and 8 bits (parity data), then continue + // TODO: store the metadata + var symbolSequence = this.getNextBits(8); + var parityData = this.getNextBits(8); + } else if (mode == MODE_ECI) { + // Count doesn't apply to ECI + var firstByte = this.getNextBits(8); + if ((firstByte & 0x80) == 0) { + // just one byte + encoding = firstByte & 0x7F; + } else if ((firstByte & 0xC0) == 0x80) { + // two bytes + var secondByte = this.getNextBits(8); + encoding = ((firstByte & 0x3F) << 8) | secondByte; + } else if ((firstByte & 0xE0) == 0xC0) { + // three bytes + var secondThirdBytes = this.getNextBits(16); + encoding = ((firstByte & 0x1F) << 16) | secondThirdBytes; + } else + throw "Invalid ECI Byte: " + firstByte; + // TODO: ECI encoding for MODE_8BIT_BYTE + } else { + // First handle Hanzi mode which does not start with character count + if (mode == MODE_HANZI) { + //chinese mode contains a sub set indicator right after mode indicator + var subset = this.getNextBits(4); + var countHanzi = this.getNextBits(this.getDataLength(mode)); + if (subset == GB2312_SUBSET) { + output += getHanziString(countHanzi); + } + } else { + dataLength = this.getDataLength(mode); + if (dataLength < 1) + throw "Invalid data length: " + dataLength; + switch (mode) { + case MODE_NUMBERIC: + output += this.getNumericString(dataLength); + break; + + case MODE_ALPHA_NUMBERIC: + var temp_str = this.getAlphaNumericString(dataLength); + if (fc1InEffect) { + for (var i = 0; i < temp_str.length; ++i) { + if (temp_str.charCodeAt(i) == '%') { + if (i < temp_str.length - 1 && temp_str.charCodeAt(i + 1) == '%') { + // %% is rendered as % + temp_str = temp_str.substring(0, i + 1) + temp_str.substring(i + 2); + } else { + // In alpha mode, % should be converted to FNC1 separator 0x1D + temp_str = temp_str.substring(0, i) + String.fromCharCode(0x1D) + temp_str.substring(i + 1); + } + } + } + } + output += temp_str; + break; + + case MODE_8BIT_BYTE: + output += this.get8bitByteArray(dataLength); + break; + + case MODE_KANJI: + output += this.getKanjiString(dataLength); + break; + default: + throw "Invalid mode: " + mode + " in (block:" + this.blockPointer + " bit:" + this.bitOffset + ")"; + } + } + } + } while (true); + return output; + }); } diff --git a/src/datamask.js b/src/datamask.js index 2f99523a..23077141 100644 --- a/src/datamask.js +++ b/src/datamask.js @@ -38,9 +38,9 @@ function DataMask000() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -59,9 +59,9 @@ function DataMask001() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -80,9 +80,9 @@ function DataMask010() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -101,9 +101,9 @@ function DataMask011() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -122,9 +122,9 @@ function DataMask100() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -143,9 +143,9 @@ function DataMask101() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -165,9 +165,9 @@ function DataMask110() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -186,9 +186,9 @@ function DataMask111() { this.unmaskBitMatrix=function(bits, dimension) { - for (var i = 0; i < dimension; i++) + for (var i = 0; i < dimension; ++i) { - for (var j = 0; j < dimension; j++) + for (var j = 0; j < dimension; ++j) { if (this.isMasked(i, j)) { @@ -203,5 +203,5 @@ function DataMask111() } } -DataMask.DATA_MASKS = new Array(new DataMask000(), new DataMask001(), new DataMask010(), new DataMask011(), new DataMask100(), new DataMask101(), new DataMask110(), new DataMask111()); +DataMask.DATA_MASKS = [new DataMask000(), new DataMask001(), new DataMask010(), new DataMask011(), new DataMask100(), new DataMask101(), new DataMask110(), new DataMask111()]; diff --git a/src/decoder.js b/src/decoder.js index d0c1ed57..f7435abc 100644 --- a/src/decoder.js +++ b/src/decoder.js @@ -31,7 +31,7 @@ Decoder.correctErrors=function( codewordBytes, numDataCodewords) var numCodewords = codewordBytes.length; // First read into an array of ints var codewordsInts = new Array(numCodewords); - for (var i = 0; i < numCodewords; i++) + for (var i = 0; i < numCodewords; ++i) { codewordsInts[i] = codewordBytes[i] & 0xFF; } @@ -48,7 +48,7 @@ Decoder.correctErrors=function( codewordBytes, numDataCodewords) } // Copy back into array of bytes -- only need to worry about the bytes that were data // We don't care about errors in the error-correction codewords - for (var i = 0; i < numDataCodewords; i++) + for (var i = 0; i < numDataCodewords; ++i) { codewordBytes[i] = codewordsInts[i]; } @@ -68,7 +68,7 @@ Decoder.decode=function(bits) // Count total number of data bytes var totalBytes = 0; - for (var i = 0; i < dataBlocks.length; i++) + for (var i = 0; i < dataBlocks.length; ++i) { totalBytes += dataBlocks[i].NumDataCodewords; } @@ -76,13 +76,13 @@ Decoder.decode=function(bits) var resultOffset = 0; // Error-correct and copy data blocks together into a stream of bytes - for (var j = 0; j < dataBlocks.length; j++) + for (var j = 0; j < dataBlocks.length; ++j) { var dataBlock = dataBlocks[j]; var codewordBytes = dataBlock.Codewords; var numDataCodewords = dataBlock.NumDataCodewords; Decoder.correctErrors(codewordBytes, numDataCodewords); - for (var i = 0; i < numDataCodewords; i++) + for (var i = 0; i < numDataCodewords; ++i) { resultBytes[resultOffset++] = codewordBytes[i]; } diff --git a/src/detector.js b/src/detector.js index 06c214a3..0b5c7a29 100644 --- a/src/detector.js +++ b/src/detector.js @@ -58,7 +58,7 @@ function PerspectiveTransform( a11, a21, a31, a12, a22, a32, a13, a23, a this. transformPoints2=function(xValues, yValues) { var n = xValues.length; - for (var i = 0; i < n; i++) + for (var i = 0; i < n; ++i) { var x = xValues[i]; var y = yValues[i]; @@ -158,14 +158,14 @@ function Detector(image) // In white pixels, looking for black if (this.image[realX + realY*qrcode.width]) { - state++; + ++state; } } else { if (!this.image[realX + realY*qrcode.width]) { - state++; + ++state; } } @@ -273,12 +273,12 @@ function Detector(image) // mod 4 case 0: - dimension++; + ++dimension; break; // 1? do nothing case 2: - dimension--; + --dimension; break; case 3: diff --git a/src/errorlevel.js b/src/errorlevel.js index 5ce2a276..fe4d226c 100644 --- a/src/errorlevel.js +++ b/src/errorlevel.js @@ -55,4 +55,4 @@ var L = new ErrorCorrectionLevel(0, 0x01, "L"); var M = new ErrorCorrectionLevel(1, 0x00, "M"); var Q = new ErrorCorrectionLevel(2, 0x03, "Q"); var H = new ErrorCorrectionLevel(3, 0x02, "H"); -var FOR_BITS = new Array( M, L, H, Q); \ No newline at end of file +var FOR_BITS = [M, L, H, Q]; \ No newline at end of file diff --git a/src/findpat.js b/src/findpat.js index 7f6ba898..d029e005 100644 --- a/src/findpat.js +++ b/src/findpat.js @@ -115,7 +115,7 @@ function FinderPattern(posX, posY, estimatedModuleSize) }); this.incrementCount = function() { - this.count++; + ++this.count; } this.aboutEquals=function( moduleSize, i, j) { @@ -150,10 +150,9 @@ function FinderPatternInfo(patternCenters) function FinderPatternFinder() { - this.image=null; this.possibleCenters = []; this.hasSkipped = false; - this.crossCheckStateCount = new Array(0,0,0,0,0); + this.crossCheckStateCount = [0,0,0,0,0]; this.resultPointCallback = null; this.__defineGetter__("CrossCheckStateCount", function() @@ -169,7 +168,7 @@ function FinderPatternFinder() this.foundPatternCross=function( stateCount) { var totalModuleSize = 0; - for (var i = 0; i < 5; i++) + for (var i = 0; i < 5; ++i) { var count = stateCount[i]; if (count == 0) @@ -191,38 +190,36 @@ function FinderPatternFinder() { return (end - stateCount[4] - stateCount[3]) - stateCount[2] / 2.0; } - this.crossCheckVertical=function( startI, centerJ, maxCount, originalStateCountTotal) + this.crossCheckVertical=function( startI, centerJ, maxCount, originalStateCountTotal, img) { - var image = this.image; - var maxI = qrcode.height; var stateCount = this.CrossCheckStateCount; // Start counting up from center var i = startI; - while (i >= 0 && image[centerJ + i*qrcode.width]) + while (i >= 0 && img[centerJ + i*qrcode.width]) { - stateCount[2]++; - i--; + ++stateCount[2]; + --i; } if (i < 0) { return NaN; } - while (i >= 0 && !image[centerJ +i*qrcode.width] && stateCount[1] <= maxCount) + while (i >= 0 && !img[centerJ +i*qrcode.width] && stateCount[1] <= maxCount) { - stateCount[1]++; - i--; + ++stateCount[1]; + --i; } // If already too many modules in this state or ran off the edge: if (i < 0 || stateCount[1] > maxCount) { return NaN; } - while (i >= 0 && image[centerJ + i*qrcode.width] && stateCount[0] <= maxCount) + while (i >= 0 && img[centerJ + i*qrcode.width] && stateCount[0] <= maxCount) { - stateCount[0]++; - i--; + ++stateCount[0]; + --i; } if (stateCount[0] > maxCount) { @@ -231,28 +228,28 @@ function FinderPatternFinder() // Now also count down from center i = startI + 1; - while (i < maxI && image[centerJ +i*qrcode.width]) + while (i < maxI && img[centerJ +i*qrcode.width]) { - stateCount[2]++; - i++; + ++stateCount[2]; + ++i; } if (i == maxI) { return NaN; } - while (i < maxI && !image[centerJ + i*qrcode.width] && stateCount[3] < maxCount) + while (i < maxI && !img[centerJ + i*qrcode.width] && stateCount[3] < maxCount) { - stateCount[3]++; - i++; + ++stateCount[3]; + ++i; } if (i == maxI || stateCount[3] >= maxCount) { return NaN; } - while (i < maxI && image[centerJ + i*qrcode.width] && stateCount[4] < maxCount) + while (i < maxI && img[centerJ + i*qrcode.width] && stateCount[4] < maxCount) { - stateCount[4]++; - i++; + ++stateCount[4]; + ++i; } if (stateCount[4] >= maxCount) { @@ -269,36 +266,34 @@ function FinderPatternFinder() return this.foundPatternCross(stateCount)?this.centerFromEnd(stateCount, i):NaN; } - this.crossCheckHorizontal=function( startJ, centerI, maxCount, originalStateCountTotal) - { - var image = this.image; - + this.crossCheckHorizontal=function( startJ, centerI, maxCount, originalStateCountTotal, img) + { var maxJ = qrcode.width; var stateCount = this.CrossCheckStateCount; var j = startJ; - while (j >= 0 && image[j+ centerI*qrcode.width]) + while (j >= 0 && img[j+ centerI*qrcode.width]) { - stateCount[2]++; - j--; + ++stateCount[2]; + --j; } if (j < 0) { return NaN; } - while (j >= 0 && !image[j+ centerI*qrcode.width] && stateCount[1] <= maxCount) + while (j >= 0 && !img[j+ centerI*qrcode.width] && stateCount[1] <= maxCount) { - stateCount[1]++; - j--; + ++stateCount[1]; + --j; } if (j < 0 || stateCount[1] > maxCount) { return NaN; } - while (j >= 0 && image[j+ centerI*qrcode.width] && stateCount[0] <= maxCount) + while (j >= 0 && img[j+ centerI*qrcode.width] && stateCount[0] <= maxCount) { - stateCount[0]++; - j--; + ++stateCount[0]; + --j; } if (stateCount[0] > maxCount) { @@ -306,28 +301,28 @@ function FinderPatternFinder() } j = startJ + 1; - while (j < maxJ && image[j+ centerI*qrcode.width]) + while (j < maxJ && img[j+ centerI*qrcode.width]) { - stateCount[2]++; - j++; + ++stateCount[2]; + ++j; } if (j == maxJ) { return NaN; } - while (j < maxJ && !image[j+ centerI*qrcode.width] && stateCount[3] < maxCount) + while (j < maxJ && !img[j+ centerI*qrcode.width] && stateCount[3] < maxCount) { - stateCount[3]++; - j++; + ++stateCount[3]; + ++j; } if (j == maxJ || stateCount[3] >= maxCount) { return NaN; } - while (j < maxJ && image[j+ centerI*qrcode.width] && stateCount[4] < maxCount) + while (j < maxJ && img[j+ centerI*qrcode.width] && stateCount[4] < maxCount) { - stateCount[4]++; - j++; + ++stateCount[4]; + ++j; } if (stateCount[4] >= maxCount) { @@ -344,21 +339,21 @@ function FinderPatternFinder() return this.foundPatternCross(stateCount)?this.centerFromEnd(stateCount, j):NaN; } - this.handlePossibleCenter=function( stateCount, i, j) + this.handlePossibleCenter=function( stateCount, i, j, img) { var stateCountTotal = stateCount[0] + stateCount[1] + stateCount[2] + stateCount[3] + stateCount[4]; var centerJ = this.centerFromEnd(stateCount, j); //float - var centerI = this.crossCheckVertical(i, Math.floor( centerJ), stateCount[2], stateCountTotal); //float + var centerI = this.crossCheckVertical(i, Math.floor( centerJ), stateCount[2], stateCountTotal, img); //float if (!isNaN(centerI)) { // Re-cross check - centerJ = this.crossCheckHorizontal(Math.floor( centerJ), Math.floor( centerI), stateCount[2], stateCountTotal); + centerJ = this.crossCheckHorizontal(Math.floor( centerJ), Math.floor( centerI), stateCount[2], stateCountTotal, img); if (!isNaN(centerJ)) { var estimatedModuleSize = stateCountTotal / 7.0; var found = false; var max = this.possibleCenters.length; - for (var index = 0; index < max; index++) + for (var index = 0; index < max; ++index) { var center = this.possibleCenters[index]; // Look for about the same center and module size: @@ -400,7 +395,7 @@ function FinderPatternFinder() // But we can only afford to do so if we have at least 4 possibilities to choose from var totalModuleSize = 0.0; var square = 0.0; - for (var i = 0; i < startSize; i++) + for (var i = 0; i < startSize; ++i) { //totalModuleSize += this.possibleCenters[i].EstimatedModuleSize; var centerValue=this.possibleCenters[i].EstimatedModuleSize; @@ -421,17 +416,17 @@ function FinderPatternFinder() }); var stdDev = Math.sqrt(square / startSize - average * average); - var limit = Math.max(0.2 * average, stdDev); - //for (var i = 0; i < this.possibleCenters.length && this.possibleCenters.length > 3; i++) - for (var i = this.possibleCenters.length - 1; i >= 0 ; i--) + var limit = Math.max(0.01 * average, stdDev); + for (var i = 0; i < this.possibleCenters.length && this.possibleCenters.length > 3; ) { var pattern = this.possibleCenters[i]; - //if (Math.abs(pattern.EstimatedModuleSize - average) > 0.2 * average) if (Math.abs(pattern.EstimatedModuleSize - average) > limit) { - //this.possibleCenters.remove(i); this.possibleCenters.splice(i,1); - //i--; + } + else + { + ++i; } } } @@ -446,7 +441,7 @@ function FinderPatternFinder() }); } - return new Array( this.possibleCenters[0], this.possibleCenters[1], this.possibleCenters[2]); + return [this.possibleCenters[0], this.possibleCenters[1], this.possibleCenters[2]]; } this.findRowSkip=function() @@ -457,7 +452,7 @@ function FinderPatternFinder() return 0; } var firstConfirmedCenter = null; - for (var i = 0; i < max; i++) + for (var i = 0; i < max; ++i) { var center = this.possibleCenters[i]; if (center.Count >= CENTER_QUORUM) @@ -486,12 +481,12 @@ function FinderPatternFinder() var confirmedCount = 0; var totalModuleSize = 0.0; var max = this.possibleCenters.length; - for (var i = 0; i < max; i++) + for (var i = 0; i < max; ++i) { var pattern = this.possibleCenters[i]; if (pattern.Count >= CENTER_QUORUM) { - confirmedCount++; + ++confirmedCount; totalModuleSize += pattern.EstimatedModuleSize; } } @@ -502,20 +497,19 @@ function FinderPatternFinder() // OK, we have at least 3 confirmed centers, but, it's possible that one is a "false positive" // and that we need to keep looking. We detect this by asking if the estimated module sizes // vary too much. We arbitrarily say that when the total deviation from average exceeds - // 5% of the total module size estimates, it's too much. + // 5‰ of the total module size estimates, it's too much. var average = totalModuleSize / max; var totalDeviation = 0.0; - for (var i = 0; i < max; i++) + for (var i = 0; i < max; ++i) { pattern = this.possibleCenters[i]; totalDeviation += Math.abs(pattern.EstimatedModuleSize - average); } - return totalDeviation <= 0.05 * totalModuleSize; + return totalDeviation <= 0.005 * totalModuleSize; } - this.findFinderPattern = function(image){ + this.findFinderPattern = function(img){ var tryHarder = false; - this.image=image; var maxI = qrcode.height; var maxJ = qrcode.width; var iSkip = Math.floor((3 * maxI) / (4 * MAX_MODULES)); @@ -525,7 +519,7 @@ function FinderPatternFinder() } var done = false; - var stateCount = new Array(5); + var stateCount = [0,0,0,0,0]; for (var i = iSkip - 1; i < maxI && !done; i += iSkip) { // Get a row of black/white values @@ -535,17 +529,17 @@ function FinderPatternFinder() stateCount[3] = 0; stateCount[4] = 0; var currentState = 0; - for (var j = 0; j < maxJ; j++) + for (var j = 0; j < maxJ; ++j) { - if (image[j+i*qrcode.width] ) + if (img[j+i*qrcode.width] ) { // Black pixel if ((currentState & 1) == 1) { // Counting white pixels - currentState++; + ++currentState; } - stateCount[currentState]++; + ++stateCount[currentState]; } else { @@ -559,7 +553,7 @@ function FinderPatternFinder() if (this.foundPatternCross(stateCount)) { // Yes - var confirmed = this.handlePossibleCenter(stateCount, i, j); + var confirmed = this.handlePossibleCenter(stateCount, i, j, img); if (confirmed) { // Start examining every other line. Checking each line turned out to be too @@ -590,12 +584,8 @@ function FinderPatternFinder() else { // Advance to next black pixel - do - { - j++; - } - while (j < maxJ && !image[j + i*qrcode.width]); - j--; // back up to that last white pixel + while (++j < maxJ && !img[j + i*qrcode.width]); + --j; // back up to that last white pixel } // Clear state to start looking again currentState = 0; @@ -618,19 +608,19 @@ function FinderPatternFinder() } else { - stateCount[++currentState]++; + ++stateCount[++currentState]; } } else { // Counting white pixels - stateCount[currentState]++; + ++stateCount[currentState]; } } } if (this.foundPatternCross(stateCount)) { - var confirmed = this.handlePossibleCenter(stateCount, i, maxJ); + var confirmed = this.handlePossibleCenter(stateCount, i, maxJ, img); if (confirmed) { iSkip = stateCount[0]; @@ -648,4 +638,4 @@ function FinderPatternFinder() return new FinderPatternInfo(patternInfo); }; -} \ No newline at end of file +} diff --git a/src/formatinf.js b/src/formatinf.js index 62266a4c..90511097 100644 --- a/src/formatinf.js +++ b/src/formatinf.js @@ -24,8 +24,8 @@ var FORMAT_INFO_MASK_QR = 0x5412; -var FORMAT_INFO_DECODE_LOOKUP = new Array(new Array(0x5412, 0x00), new Array(0x5125, 0x01), new Array(0x5E7C, 0x02), new Array(0x5B4B, 0x03), new Array(0x45F9, 0x04), new Array(0x40CE, 0x05), new Array(0x4F97, 0x06), new Array(0x4AA0, 0x07), new Array(0x77C4, 0x08), new Array(0x72F3, 0x09), new Array(0x7DAA, 0x0A), new Array(0x789D, 0x0B), new Array(0x662F, 0x0C), new Array(0x6318, 0x0D), new Array(0x6C41, 0x0E), new Array(0x6976, 0x0F), new Array(0x1689, 0x10), new Array(0x13BE, 0x11), new Array(0x1CE7, 0x12), new Array(0x19D0, 0x13), new Array(0x0762, 0x14), new Array(0x0255, 0x15), new Array(0x0D0C, 0x16), new Array(0x083B, 0x17), new Array(0x355F, 0x18), new Array(0x3068, 0x19), new Array(0x3F31, 0x1A), new Array(0x3A06, 0x1B), new Array(0x24B4, 0x1C), new Array(0x2183, 0x1D), new Array(0x2EDA, 0x1E), new Array(0x2BED, 0x1F)); -var BITS_SET_IN_HALF_BYTE = new Array(0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4); +var FORMAT_INFO_DECODE_LOOKUP = [[0x5412, 0x00], [0x5125, 0x01], [0x5E7C, 0x02], [0x5B4B, 0x03], [0x45F9, 0x04], [0x40CE, 0x05], [0x4F97, 0x06], [0x4AA0, 0x07], [0x77C4, 0x08], [0x72F3, 0x09], [0x7DAA, 0x0A], [0x789D, 0x0B], [0x662F, 0x0C], [0x6318, 0x0D], [0x6C41, 0x0E], [0x6976, 0x0F], [0x1689, 0x10], [0x13BE, 0x11], [0x1CE7, 0x12], [0x19D0, 0x13], [0x0762, 0x14], [0x0255, 0x15], [0x0D0C, 0x16], [0x083B, 0x17], [0x355F, 0x18], [0x3068, 0x19], [0x3F31, 0x1A], [0x3A06, 0x1B], [0x24B4, 0x1C], [0x2183, 0x1D], [0x2EDA, 0x1E], [0x2BED, 0x1F]]; +var BITS_SET_IN_HALF_BYTE = [0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4]; function FormatInformation(formatInfo) @@ -76,7 +76,7 @@ FormatInformation.doDecodeFormatInformation=function( maskedFormatInfo) // Find the int in FORMAT_INFO_DECODE_LOOKUP with fewest bits differing var bestDifference = 0xffffffff; var bestFormatInfo = 0; - for (var i = 0; i < FORMAT_INFO_DECODE_LOOKUP.length; i++) + for (var i = 0; i < FORMAT_INFO_DECODE_LOOKUP.length; ++i) { var decodeInfo = FORMAT_INFO_DECODE_LOOKUP[i]; var targetInfo = decodeInfo[0]; diff --git a/src/gf256.js b/src/gf256.js index 8eb6b617..8b20e43e 100644 --- a/src/gf256.js +++ b/src/gf256.js @@ -28,7 +28,7 @@ function GF256( primitive) this.expTable = new Array(256); this.logTable = new Array(256); var x = 1; - for (var i = 0; i < 256; i++) + for (var i = 0; i < 256; ++i) { this.expTable[i] = x; x <<= 1; // x = x * 2; we're assuming the generator alpha is 2 @@ -37,15 +37,13 @@ function GF256( primitive) x ^= primitive; } } - for (var i = 0; i < 255; i++) + for (var i = 0; i < 255; ++i) { this.logTable[this.expTable[i]] = i; } // logTable[0] == 0 but this should never be used - var at0=new Array(1);at0[0]=0; - this.zero = new GF256Poly(this, new Array(at0)); - var at1=new Array(1);at1[0]=1; - this.one = new GF256Poly(this, new Array(at1)); + this.zero = new GF256Poly(this, [[0]]); + this.one = new GF256Poly(this, [[1]]); this.__defineGetter__("Zero", function() { @@ -66,7 +64,7 @@ function GF256( primitive) return this.zero; } var coefficients = new Array(degree + 1); - for(var i=0;i> 16) & 0xff; g = (intVal >> 8) & 0xff; diff --git a/src/version.js b/src/version.js index 4e19c7f1..052ae52e 100644 --- a/src/version.js +++ b/src/version.js @@ -43,9 +43,9 @@ function ECBlocks( ecCodewordsPerBlock, ecBlocks1, ecBlocks2) { this.ecCodewordsPerBlock = ecCodewordsPerBlock; if(ecBlocks2) - this.ecBlocks = new Array(ecBlocks1, ecBlocks2); + this.ecBlocks = [ecBlocks1, ecBlocks2]; else - this.ecBlocks = new Array(ecBlocks1); + this.ecBlocks = [ecBlocks1]; this.__defineGetter__("ECCodewordsPerBlock", function() { @@ -60,7 +60,7 @@ function ECBlocks( ecCodewordsPerBlock, ecBlocks1, ecBlocks2) this.__defineGetter__("NumBlocks", function() { var total = 0; - for (var i = 0; i < this.ecBlocks.length; i++) + for (var i = 0; i < this.ecBlocks.length; ++i) { total += this.ecBlocks[i].length; } @@ -77,12 +77,12 @@ function Version( versionNumber, alignmentPatternCenters, ecBlocks1, ecBlocks { this.versionNumber = versionNumber; this.alignmentPatternCenters = alignmentPatternCenters; - this.ecBlocks = new Array(ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4); + this.ecBlocks = [ecBlocks1, ecBlocks2, ecBlocks3, ecBlocks4]; var total = 0; var ecCodewords = ecBlocks1.ECCodewordsPerBlock; var ecbArray = ecBlocks1.getECBlocks(); - for (var i = 0; i < ecbArray.length; i++) + for (var i = 0; i < ecbArray.length; ++i) { var ecBlock = ecbArray[i]; total += ecBlock.Count * (ecBlock.DataCodewords + ecCodewords); @@ -121,10 +121,10 @@ function Version( versionNumber, alignmentPatternCenters, ecBlocks1, ecBlocks // Alignment patterns var max = this.alignmentPatternCenters.length; - for (var x = 0; x < max; x++) + for (var x = 0; x < max; ++x) { var i = this.alignmentPatternCenters[x] - 2; - for (var y = 0; y < max; y++) + for (var y = 0; y < max; ++y) { if ((x == 0 && (y == 0 || y == max - 1)) || (x == max - 1 && y == 0)) { @@ -156,7 +156,7 @@ function Version( versionNumber, alignmentPatternCenters, ecBlocks1, ecBlocks } } -Version.VERSION_DECODE_INFO = new Array(0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683, 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69); +Version.VERSION_DECODE_INFO = [0x07C94, 0x085BC, 0x09A99, 0x0A4D3, 0x0BBF6, 0x0C762, 0x0D847, 0x0E60D, 0x0F928, 0x10B78, 0x1145D, 0x12A17, 0x13532, 0x149A6, 0x15683, 0x168C9, 0x177EC, 0x18EC4, 0x191E1, 0x1AFAB, 0x1B08E, 0x1CC1A, 0x1D33F, 0x1ED75, 0x1F250, 0x209D5, 0x216F0, 0x228BA, 0x2379F, 0x24B0B, 0x2542E, 0x26A64, 0x27541, 0x28C69]; Version.VERSIONS = buildVersions(); @@ -189,7 +189,7 @@ Version.decodeVersionInformation=function( versionBits) { var bestDifference = 0xffffffff; var bestVersion = 0; - for (var i = 0; i < Version.VERSION_DECODE_INFO.length; i++) + for (var i = 0; i < Version.VERSION_DECODE_INFO.length; ++i) { var targetVersion = Version.VERSION_DECODE_INFO[i]; // Do the version info bits match exactly? done. @@ -218,44 +218,44 @@ Version.decodeVersionInformation=function( versionBits) function buildVersions() { - return new Array(new Version(1, new Array(), new ECBlocks(7, new ECB(1, 19)), new ECBlocks(10, new ECB(1, 16)), new ECBlocks(13, new ECB(1, 13)), new ECBlocks(17, new ECB(1, 9))), - new Version(2, new Array(6, 18), new ECBlocks(10, new ECB(1, 34)), new ECBlocks(16, new ECB(1, 28)), new ECBlocks(22, new ECB(1, 22)), new ECBlocks(28, new ECB(1, 16))), - new Version(3, new Array(6, 22), new ECBlocks(15, new ECB(1, 55)), new ECBlocks(26, new ECB(1, 44)), new ECBlocks(18, new ECB(2, 17)), new ECBlocks(22, new ECB(2, 13))), - new Version(4, new Array(6, 26), new ECBlocks(20, new ECB(1, 80)), new ECBlocks(18, new ECB(2, 32)), new ECBlocks(26, new ECB(2, 24)), new ECBlocks(16, new ECB(4, 9))), - new Version(5, new Array(6, 30), new ECBlocks(26, new ECB(1, 108)), new ECBlocks(24, new ECB(2, 43)), new ECBlocks(18, new ECB(2, 15), new ECB(2, 16)), new ECBlocks(22, new ECB(2, 11), new ECB(2, 12))), - new Version(6, new Array(6, 34), new ECBlocks(18, new ECB(2, 68)), new ECBlocks(16, new ECB(4, 27)), new ECBlocks(24, new ECB(4, 19)), new ECBlocks(28, new ECB(4, 15))), - new Version(7, new Array(6, 22, 38), new ECBlocks(20, new ECB(2, 78)), new ECBlocks(18, new ECB(4, 31)), new ECBlocks(18, new ECB(2, 14), new ECB(4, 15)), new ECBlocks(26, new ECB(4, 13), new ECB(1, 14))), - new Version(8, new Array(6, 24, 42), new ECBlocks(24, new ECB(2, 97)), new ECBlocks(22, new ECB(2, 38), new ECB(2, 39)), new ECBlocks(22, new ECB(4, 18), new ECB(2, 19)), new ECBlocks(26, new ECB(4, 14), new ECB(2, 15))), - new Version(9, new Array(6, 26, 46), new ECBlocks(30, new ECB(2, 116)), new ECBlocks(22, new ECB(3, 36), new ECB(2, 37)), new ECBlocks(20, new ECB(4, 16), new ECB(4, 17)), new ECBlocks(24, new ECB(4, 12), new ECB(4, 13))), - new Version(10, new Array(6, 28, 50), new ECBlocks(18, new ECB(2, 68), new ECB(2, 69)), new ECBlocks(26, new ECB(4, 43), new ECB(1, 44)), new ECBlocks(24, new ECB(6, 19), new ECB(2, 20)), new ECBlocks(28, new ECB(6, 15), new ECB(2, 16))), - new Version(11, new Array(6, 30, 54), new ECBlocks(20, new ECB(4, 81)), new ECBlocks(30, new ECB(1, 50), new ECB(4, 51)), new ECBlocks(28, new ECB(4, 22), new ECB(4, 23)), new ECBlocks(24, new ECB(3, 12), new ECB(8, 13))), - new Version(12, new Array(6, 32, 58), new ECBlocks(24, new ECB(2, 92), new ECB(2, 93)), new ECBlocks(22, new ECB(6, 36), new ECB(2, 37)), new ECBlocks(26, new ECB(4, 20), new ECB(6, 21)), new ECBlocks(28, new ECB(7, 14), new ECB(4, 15))), - new Version(13, new Array(6, 34, 62), new ECBlocks(26, new ECB(4, 107)), new ECBlocks(22, new ECB(8, 37), new ECB(1, 38)), new ECBlocks(24, new ECB(8, 20), new ECB(4, 21)), new ECBlocks(22, new ECB(12, 11), new ECB(4, 12))), - new Version(14, new Array(6, 26, 46, 66), new ECBlocks(30, new ECB(3, 115), new ECB(1, 116)), new ECBlocks(24, new ECB(4, 40), new ECB(5, 41)), new ECBlocks(20, new ECB(11, 16), new ECB(5, 17)), new ECBlocks(24, new ECB(11, 12), new ECB(5, 13))), - new Version(15, new Array(6, 26, 48, 70), new ECBlocks(22, new ECB(5, 87), new ECB(1, 88)), new ECBlocks(24, new ECB(5, 41), new ECB(5, 42)), new ECBlocks(30, new ECB(5, 24), new ECB(7, 25)), new ECBlocks(24, new ECB(11, 12), new ECB(7, 13))), - new Version(16, new Array(6, 26, 50, 74), new ECBlocks(24, new ECB(5, 98), new ECB(1, 99)), new ECBlocks(28, new ECB(7, 45), new ECB(3, 46)), new ECBlocks(24, new ECB(15, 19), new ECB(2, 20)), new ECBlocks(30, new ECB(3, 15), new ECB(13, 16))), - new Version(17, new Array(6, 30, 54, 78), new ECBlocks(28, new ECB(1, 107), new ECB(5, 108)), new ECBlocks(28, new ECB(10, 46), new ECB(1, 47)), new ECBlocks(28, new ECB(1, 22), new ECB(15, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(17, 15))), - new Version(18, new Array(6, 30, 56, 82), new ECBlocks(30, new ECB(5, 120), new ECB(1, 121)), new ECBlocks(26, new ECB(9, 43), new ECB(4, 44)), new ECBlocks(28, new ECB(17, 22), new ECB(1, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(19, 15))), - new Version(19, new Array(6, 30, 58, 86), new ECBlocks(28, new ECB(3, 113), new ECB(4, 114)), new ECBlocks(26, new ECB(3, 44), new ECB(11, 45)), new ECBlocks(26, new ECB(17, 21), new ECB(4, 22)), new ECBlocks(26, new ECB(9, 13), new ECB(16, 14))), - new Version(20, new Array(6, 34, 62, 90), new ECBlocks(28, new ECB(3, 107), new ECB(5, 108)), new ECBlocks(26, new ECB(3, 41), new ECB(13, 42)), new ECBlocks(30, new ECB(15, 24), new ECB(5, 25)), new ECBlocks(28, new ECB(15, 15), new ECB(10, 16))), - new Version(21, new Array(6, 28, 50, 72, 94), new ECBlocks(28, new ECB(4, 116), new ECB(4, 117)), new ECBlocks(26, new ECB(17, 42)), new ECBlocks(28, new ECB(17, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(19, 16), new ECB(6, 17))), - new Version(22, new Array(6, 26, 50, 74, 98), new ECBlocks(28, new ECB(2, 111), new ECB(7, 112)), new ECBlocks(28, new ECB(17, 46)), new ECBlocks(30, new ECB(7, 24), new ECB(16, 25)), new ECBlocks(24, new ECB(34, 13))), - new Version(23, new Array(6, 30, 54, 74, 102), new ECBlocks(30, new ECB(4, 121), new ECB(5, 122)), new ECBlocks(28, new ECB(4, 47), new ECB(14, 48)), new ECBlocks(30, new ECB(11, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(16, 15), new ECB(14, 16))), - new Version(24, new Array(6, 28, 54, 80, 106), new ECBlocks(30, new ECB(6, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(6, 45), new ECB(14, 46)), new ECBlocks(30, new ECB(11, 24), new ECB(16, 25)), new ECBlocks(30, new ECB(30, 16), new ECB(2, 17))), - new Version(25, new Array(6, 32, 58, 84, 110), new ECBlocks(26, new ECB(8, 106), new ECB(4, 107)), new ECBlocks(28, new ECB(8, 47), new ECB(13, 48)), new ECBlocks(30, new ECB(7, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(22, 15), new ECB(13, 16))), - new Version(26, new Array(6, 30, 58, 86, 114), new ECBlocks(28, new ECB(10, 114), new ECB(2, 115)), new ECBlocks(28, new ECB(19, 46), new ECB(4, 47)), new ECBlocks(28, new ECB(28, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(33, 16), new ECB(4, 17))), - new Version(27, new Array(6, 34, 62, 90, 118), new ECBlocks(30, new ECB(8, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(22, 45), new ECB(3, 46)), new ECBlocks(30, new ECB(8, 23), new ECB(26, 24)), new ECBlocks(30, new ECB(12, 15), new ECB(28, 16))), - new Version(28, new Array(6, 26, 50, 74, 98, 122), new ECBlocks(30, new ECB(3, 117), new ECB(10, 118)), new ECBlocks(28, new ECB(3, 45), new ECB(23, 46)), new ECBlocks(30, new ECB(4, 24), new ECB(31, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(31, 16))), - new Version(29, new Array(6, 30, 54, 78, 102, 126), new ECBlocks(30, new ECB(7, 116), new ECB(7, 117)), new ECBlocks(28, new ECB(21, 45), new ECB(7, 46)), new ECBlocks(30, new ECB(1, 23), new ECB(37, 24)), new ECBlocks(30, new ECB(19, 15), new ECB(26, 16))), - new Version(30, new Array(6, 26, 52, 78, 104, 130), new ECBlocks(30, new ECB(5, 115), new ECB(10, 116)), new ECBlocks(28, new ECB(19, 47), new ECB(10, 48)), new ECBlocks(30, new ECB(15, 24), new ECB(25, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(25, 16))), - new Version(31, new Array(6, 30, 56, 82, 108, 134), new ECBlocks(30, new ECB(13, 115), new ECB(3, 116)), new ECBlocks(28, new ECB(2, 46), new ECB(29, 47)), new ECBlocks(30, new ECB(42, 24), new ECB(1, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(28, 16))), - new Version(32, new Array(6, 34, 60, 86, 112, 138), new ECBlocks(30, new ECB(17, 115)), new ECBlocks(28, new ECB(10, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(10, 24), new ECB(35, 25)), new ECBlocks(30, new ECB(19, 15), new ECB(35, 16))), - new Version(33, new Array(6, 30, 58, 86, 114, 142), new ECBlocks(30, new ECB(17, 115), new ECB(1, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(21, 47)), new ECBlocks(30, new ECB(29, 24), new ECB(19, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(46, 16))), - new Version(34, new Array(6, 34, 62, 90, 118, 146), new ECBlocks(30, new ECB(13, 115), new ECB(6, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(44, 24), new ECB(7, 25)), new ECBlocks(30, new ECB(59, 16), new ECB(1, 17))), - new Version(35, new Array(6, 30, 54, 78, 102, 126, 150), new ECBlocks(30, new ECB(12, 121), new ECB(7, 122)), new ECBlocks(28, new ECB(12, 47), new ECB(26, 48)), new ECBlocks(30, new ECB(39, 24), new ECB(14, 25)),new ECBlocks(30, new ECB(22, 15), new ECB(41, 16))), - new Version(36, new Array(6, 24, 50, 76, 102, 128, 154), new ECBlocks(30, new ECB(6, 121), new ECB(14, 122)), new ECBlocks(28, new ECB(6, 47), new ECB(34, 48)), new ECBlocks(30, new ECB(46, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(2, 15), new ECB(64, 16))), - new Version(37, new Array(6, 28, 54, 80, 106, 132, 158), new ECBlocks(30, new ECB(17, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(29, 46), new ECB(14, 47)), new ECBlocks(30, new ECB(49, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(24, 15), new ECB(46, 16))), - new Version(38, new Array(6, 32, 58, 84, 110, 136, 162), new ECBlocks(30, new ECB(4, 122), new ECB(18, 123)), new ECBlocks(28, new ECB(13, 46), new ECB(32, 47)), new ECBlocks(30, new ECB(48, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(42, 15), new ECB(32, 16))), - new Version(39, new Array(6, 26, 54, 82, 110, 138, 166), new ECBlocks(30, new ECB(20, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(40, 47), new ECB(7, 48)), new ECBlocks(30, new ECB(43, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(10, 15), new ECB(67, 16))), - new Version(40, new Array(6, 30, 58, 86, 114, 142, 170), new ECBlocks(30, new ECB(19, 118), new ECB(6, 119)), new ECBlocks(28, new ECB(18, 47), new ECB(31, 48)), new ECBlocks(30, new ECB(34, 24), new ECB(34, 25)), new ECBlocks(30, new ECB(20, 15), new ECB(61, 16)))); + return [new Version(1, [], new ECBlocks(7, new ECB(1, 19)), new ECBlocks(10, new ECB(1, 16)), new ECBlocks(13, new ECB(1, 13)), new ECBlocks(17, new ECB(1, 9))), + new Version(2, [6, 18], new ECBlocks(10, new ECB(1, 34)), new ECBlocks(16, new ECB(1, 28)), new ECBlocks(22, new ECB(1, 22)), new ECBlocks(28, new ECB(1, 16))), + new Version(3, [6, 22], new ECBlocks(15, new ECB(1, 55)), new ECBlocks(26, new ECB(1, 44)), new ECBlocks(18, new ECB(2, 17)), new ECBlocks(22, new ECB(2, 13))), + new Version(4, [6, 26], new ECBlocks(20, new ECB(1, 80)), new ECBlocks(18, new ECB(2, 32)), new ECBlocks(26, new ECB(2, 24)), new ECBlocks(16, new ECB(4, 9))), + new Version(5, [6, 30], new ECBlocks(26, new ECB(1, 108)), new ECBlocks(24, new ECB(2, 43)), new ECBlocks(18, new ECB(2, 15), new ECB(2, 16)), new ECBlocks(22, new ECB(2, 11), new ECB(2, 12))), + new Version(6, [6, 34], new ECBlocks(18, new ECB(2, 68)), new ECBlocks(16, new ECB(4, 27)), new ECBlocks(24, new ECB(4, 19)), new ECBlocks(28, new ECB(4, 15))), + new Version(7, [6, 22, 38], new ECBlocks(20, new ECB(2, 78)), new ECBlocks(18, new ECB(4, 31)), new ECBlocks(18, new ECB(2, 14), new ECB(4, 15)), new ECBlocks(26, new ECB(4, 13), new ECB(1, 14))), + new Version(8, [6, 24, 42], new ECBlocks(24, new ECB(2, 97)), new ECBlocks(22, new ECB(2, 38), new ECB(2, 39)), new ECBlocks(22, new ECB(4, 18), new ECB(2, 19)), new ECBlocks(26, new ECB(4, 14), new ECB(2, 15))), + new Version(9, [6, 26, 46], new ECBlocks(30, new ECB(2, 116)), new ECBlocks(22, new ECB(3, 36), new ECB(2, 37)), new ECBlocks(20, new ECB(4, 16), new ECB(4, 17)), new ECBlocks(24, new ECB(4, 12), new ECB(4, 13))), + new Version(10, [6, 28, 50], new ECBlocks(18, new ECB(2, 68), new ECB(2, 69)), new ECBlocks(26, new ECB(4, 43), new ECB(1, 44)), new ECBlocks(24, new ECB(6, 19), new ECB(2, 20)), new ECBlocks(28, new ECB(6, 15), new ECB(2, 16))), + new Version(11, [6, 30, 54], new ECBlocks(20, new ECB(4, 81)), new ECBlocks(30, new ECB(1, 50), new ECB(4, 51)), new ECBlocks(28, new ECB(4, 22), new ECB(4, 23)), new ECBlocks(24, new ECB(3, 12), new ECB(8, 13))), + new Version(12, [6, 32, 58], new ECBlocks(24, new ECB(2, 92), new ECB(2, 93)), new ECBlocks(22, new ECB(6, 36), new ECB(2, 37)), new ECBlocks(26, new ECB(4, 20), new ECB(6, 21)), new ECBlocks(28, new ECB(7, 14), new ECB(4, 15))), + new Version(13, [6, 34, 62], new ECBlocks(26, new ECB(4, 107)), new ECBlocks(22, new ECB(8, 37), new ECB(1, 38)), new ECBlocks(24, new ECB(8, 20), new ECB(4, 21)), new ECBlocks(22, new ECB(12, 11), new ECB(4, 12))), + new Version(14, [6, 26, 46, 66], new ECBlocks(30, new ECB(3, 115), new ECB(1, 116)), new ECBlocks(24, new ECB(4, 40), new ECB(5, 41)), new ECBlocks(20, new ECB(11, 16), new ECB(5, 17)), new ECBlocks(24, new ECB(11, 12), new ECB(5, 13))), + new Version(15, [6, 26, 48, 70], new ECBlocks(22, new ECB(5, 87), new ECB(1, 88)), new ECBlocks(24, new ECB(5, 41), new ECB(5, 42)), new ECBlocks(30, new ECB(5, 24), new ECB(7, 25)), new ECBlocks(24, new ECB(11, 12), new ECB(7, 13))), + new Version(16, [6, 26, 50, 74], new ECBlocks(24, new ECB(5, 98), new ECB(1, 99)), new ECBlocks(28, new ECB(7, 45), new ECB(3, 46)), new ECBlocks(24, new ECB(15, 19), new ECB(2, 20)), new ECBlocks(30, new ECB(3, 15), new ECB(13, 16))), + new Version(17, [6, 30, 54, 78], new ECBlocks(28, new ECB(1, 107), new ECB(5, 108)), new ECBlocks(28, new ECB(10, 46), new ECB(1, 47)), new ECBlocks(28, new ECB(1, 22), new ECB(15, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(17, 15))), + new Version(18, [6, 30, 56, 82], new ECBlocks(30, new ECB(5, 120), new ECB(1, 121)), new ECBlocks(26, new ECB(9, 43), new ECB(4, 44)), new ECBlocks(28, new ECB(17, 22), new ECB(1, 23)), new ECBlocks(28, new ECB(2, 14), new ECB(19, 15))), + new Version(19, [6, 30, 58, 86], new ECBlocks(28, new ECB(3, 113), new ECB(4, 114)), new ECBlocks(26, new ECB(3, 44), new ECB(11, 45)), new ECBlocks(26, new ECB(17, 21), new ECB(4, 22)), new ECBlocks(26, new ECB(9, 13), new ECB(16, 14))), + new Version(20, [6, 34, 62, 90], new ECBlocks(28, new ECB(3, 107), new ECB(5, 108)), new ECBlocks(26, new ECB(3, 41), new ECB(13, 42)), new ECBlocks(30, new ECB(15, 24), new ECB(5, 25)), new ECBlocks(28, new ECB(15, 15), new ECB(10, 16))), + new Version(21, [6, 28, 50, 72, 94], new ECBlocks(28, new ECB(4, 116), new ECB(4, 117)), new ECBlocks(26, new ECB(17, 42)), new ECBlocks(28, new ECB(17, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(19, 16), new ECB(6, 17))), + new Version(22, [6, 26, 50, 74, 98], new ECBlocks(28, new ECB(2, 111), new ECB(7, 112)), new ECBlocks(28, new ECB(17, 46)), new ECBlocks(30, new ECB(7, 24), new ECB(16, 25)), new ECBlocks(24, new ECB(34, 13))), + new Version(23, [6, 30, 54, 74, 102], new ECBlocks(30, new ECB(4, 121), new ECB(5, 122)), new ECBlocks(28, new ECB(4, 47), new ECB(14, 48)), new ECBlocks(30, new ECB(11, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(16, 15), new ECB(14, 16))), + new Version(24, [6, 28, 54, 80, 106], new ECBlocks(30, new ECB(6, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(6, 45), new ECB(14, 46)), new ECBlocks(30, new ECB(11, 24), new ECB(16, 25)), new ECBlocks(30, new ECB(30, 16), new ECB(2, 17))), + new Version(25, [6, 32, 58, 84, 110], new ECBlocks(26, new ECB(8, 106), new ECB(4, 107)), new ECBlocks(28, new ECB(8, 47), new ECB(13, 48)), new ECBlocks(30, new ECB(7, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(22, 15), new ECB(13, 16))), + new Version(26, [6, 30, 58, 86, 114], new ECBlocks(28, new ECB(10, 114), new ECB(2, 115)), new ECBlocks(28, new ECB(19, 46), new ECB(4, 47)), new ECBlocks(28, new ECB(28, 22), new ECB(6, 23)), new ECBlocks(30, new ECB(33, 16), new ECB(4, 17))), + new Version(27, [6, 34, 62, 90, 118], new ECBlocks(30, new ECB(8, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(22, 45), new ECB(3, 46)), new ECBlocks(30, new ECB(8, 23), new ECB(26, 24)), new ECBlocks(30, new ECB(12, 15), new ECB(28, 16))), + new Version(28, [6, 26, 50, 74, 98, 122], new ECBlocks(30, new ECB(3, 117), new ECB(10, 118)), new ECBlocks(28, new ECB(3, 45), new ECB(23, 46)), new ECBlocks(30, new ECB(4, 24), new ECB(31, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(31, 16))), + new Version(29, [6, 30, 54, 78, 102, 126], new ECBlocks(30, new ECB(7, 116), new ECB(7, 117)), new ECBlocks(28, new ECB(21, 45), new ECB(7, 46)), new ECBlocks(30, new ECB(1, 23), new ECB(37, 24)), new ECBlocks(30, new ECB(19, 15), new ECB(26, 16))), + new Version(30, [6, 26, 52, 78, 104, 130], new ECBlocks(30, new ECB(5, 115), new ECB(10, 116)), new ECBlocks(28, new ECB(19, 47), new ECB(10, 48)), new ECBlocks(30, new ECB(15, 24), new ECB(25, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(25, 16))), + new Version(31, [6, 30, 56, 82, 108, 134], new ECBlocks(30, new ECB(13, 115), new ECB(3, 116)), new ECBlocks(28, new ECB(2, 46), new ECB(29, 47)), new ECBlocks(30, new ECB(42, 24), new ECB(1, 25)), new ECBlocks(30, new ECB(23, 15), new ECB(28, 16))), + new Version(32, [6, 34, 60, 86, 112, 138], new ECBlocks(30, new ECB(17, 115)), new ECBlocks(28, new ECB(10, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(10, 24), new ECB(35, 25)), new ECBlocks(30, new ECB(19, 15), new ECB(35, 16))), + new Version(33, [6, 30, 58, 86, 114, 142], new ECBlocks(30, new ECB(17, 115), new ECB(1, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(21, 47)), new ECBlocks(30, new ECB(29, 24), new ECB(19, 25)), new ECBlocks(30, new ECB(11, 15), new ECB(46, 16))), + new Version(34, [6, 34, 62, 90, 118, 146], new ECBlocks(30, new ECB(13, 115), new ECB(6, 116)), new ECBlocks(28, new ECB(14, 46), new ECB(23, 47)), new ECBlocks(30, new ECB(44, 24), new ECB(7, 25)), new ECBlocks(30, new ECB(59, 16), new ECB(1, 17))), + new Version(35, [6, 30, 54, 78, 102, 126, 150], new ECBlocks(30, new ECB(12, 121), new ECB(7, 122)), new ECBlocks(28, new ECB(12, 47), new ECB(26, 48)), new ECBlocks(30, new ECB(39, 24), new ECB(14, 25)),new ECBlocks(30, new ECB(22, 15), new ECB(41, 16))), + new Version(36, [6, 24, 50, 76, 102, 128, 154], new ECBlocks(30, new ECB(6, 121), new ECB(14, 122)), new ECBlocks(28, new ECB(6, 47), new ECB(34, 48)), new ECBlocks(30, new ECB(46, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(2, 15), new ECB(64, 16))), + new Version(37, [6, 28, 54, 80, 106, 132, 158], new ECBlocks(30, new ECB(17, 122), new ECB(4, 123)), new ECBlocks(28, new ECB(29, 46), new ECB(14, 47)), new ECBlocks(30, new ECB(49, 24), new ECB(10, 25)), new ECBlocks(30, new ECB(24, 15), new ECB(46, 16))), + new Version(38, [6, 32, 58, 84, 110, 136, 162], new ECBlocks(30, new ECB(4, 122), new ECB(18, 123)), new ECBlocks(28, new ECB(13, 46), new ECB(32, 47)), new ECBlocks(30, new ECB(48, 24), new ECB(14, 25)), new ECBlocks(30, new ECB(42, 15), new ECB(32, 16))), + new Version(39, [6, 26, 54, 82, 110, 138, 166], new ECBlocks(30, new ECB(20, 117), new ECB(4, 118)), new ECBlocks(28, new ECB(40, 47), new ECB(7, 48)), new ECBlocks(30, new ECB(43, 24), new ECB(22, 25)), new ECBlocks(30, new ECB(10, 15), new ECB(67, 16))), + new Version(40, [6, 30, 58, 86, 114, 142, 170], new ECBlocks(30, new ECB(19, 118), new ECB(6, 119)), new ECBlocks(28, new ECB(18, 47), new ECB(31, 48)), new ECBlocks(30, new ECB(34, 24), new ECB(34, 25)), new ECBlocks(30, new ECB(20, 15), new ECB(61, 16)))]; } \ No newline at end of file