@ -59,7 +59,7 @@ namespace qrcodegen {
// QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
// QR Code version is automatically chosen for the output. The ECC level of the result may be higher than the
// ecl argument if it can be done without increasing the version.
// ecl argument if it can be done without increasing the version.
public static encodeText ( text : string , ecl : QrCode.Ecc ) : QrCode {
public static encodeText ( text : string , ecl : QrCode.Ecc ) : QrCode {
le t segs : Array < QrSegment > = qrcodegen . QrSegment . makeSegments ( text ) ;
cons t segs : Array < QrSegment > = qrcodegen . QrSegment . makeSegments ( text ) ;
return QrCode . encodeSegments ( segs , ecl ) ;
return QrCode . encodeSegments ( segs , ecl ) ;
}
}
@ -69,7 +69,7 @@ namespace qrcodegen {
// bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
// bytes allowed is 2953. The smallest possible QR Code version is automatically chosen for the output.
// The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
// The ECC level of the result may be higher than the ecl argument if it can be done without increasing the version.
public static encodeBinary ( data : Array < byte > , ecl : QrCode.Ecc ) : QrCode {
public static encodeBinary ( data : Array < byte > , ecl : QrCode.Ecc ) : QrCode {
le t seg : QrSegment = qrcodegen . QrSegment . makeBytes ( data ) ;
cons t seg : QrSegment = qrcodegen . QrSegment . makeBytes ( data ) ;
return QrCode . encodeSegments ( [ seg ] , ecl ) ;
return QrCode . encodeSegments ( [ seg ] , ecl ) ;
}
}
@ -97,8 +97,8 @@ namespace qrcodegen {
let version : int ;
let version : int ;
let dataUsedBits : int ;
let dataUsedBits : int ;
for ( version = minVersion ; ; version ++ ) {
for ( version = minVersion ; ; version ++ ) {
le t dataCapacityBits : int = QrCode . getNumDataCodewords ( version , ecl ) * 8 ; // Number of data bits available
cons t dataCapacityBits : int = QrCode . getNumDataCodewords ( version , ecl ) * 8 ; // Number of data bits available
le t usedBits : number = QrSegment . getTotalBits ( segs , version ) ;
cons t usedBits : number = QrSegment . getTotalBits ( segs , version ) ;
if ( usedBits <= dataCapacityBits ) {
if ( usedBits <= dataCapacityBits ) {
dataUsedBits = usedBits ;
dataUsedBits = usedBits ;
break ; // This version number is found to be suitable
break ; // This version number is found to be suitable
@ -108,24 +108,24 @@ namespace qrcodegen {
}
}
// Increase the error correction level while the data still fits in the current version number
// Increase the error correction level while the data still fits in the current version number
for ( le t newEcl of [ QrCode . Ecc . MEDIUM , QrCode . Ecc . QUARTILE , QrCode . Ecc . HIGH ] ) { // From low to high
for ( cons t newEcl of [ QrCode . Ecc . MEDIUM , QrCode . Ecc . QUARTILE , QrCode . Ecc . HIGH ] ) { // From low to high
if ( boostEcl && dataUsedBits <= QrCode . getNumDataCodewords ( version , newEcl ) * 8 )
if ( boostEcl && dataUsedBits <= QrCode . getNumDataCodewords ( version , newEcl ) * 8 )
ecl = newEcl ;
ecl = newEcl ;
}
}
// Concatenate all segments to create the data bit string
// Concatenate all segments to create the data bit string
let bb = new BitBuffer ( ) ;
let bb = new BitBuffer ( ) ;
for ( le t seg of segs ) {
for ( cons t seg of segs ) {
bb . appendBits ( seg . mode . modeBits , 4 ) ;
bb . appendBits ( seg . mode . modeBits , 4 ) ;
bb . appendBits ( seg . numChars , seg . mode . numCharCountBits ( version ) ) ;
bb . appendBits ( seg . numChars , seg . mode . numCharCountBits ( version ) ) ;
for ( le t b of seg . getData ( ) )
for ( cons t b of seg . getData ( ) )
bb . push ( b ) ;
bb . push ( b ) ;
}
}
if ( bb . length != dataUsedBits )
if ( bb . length != dataUsedBits )
throw "Assertion error" ;
throw "Assertion error" ;
// Add terminator and pad up to a byte if applicable
// Add terminator and pad up to a byte if applicable
le t dataCapacityBits : int = QrCode . getNumDataCodewords ( version , ecl ) * 8 ;
cons t dataCapacityBits : int = QrCode . getNumDataCodewords ( version , ecl ) * 8 ;
if ( bb . length > dataCapacityBits )
if ( bb . length > dataCapacityBits )
throw "Assertion error" ;
throw "Assertion error" ;
bb . appendBits ( 0 , Math . min ( 4 , dataCapacityBits - bb . length ) ) ;
bb . appendBits ( 0 , Math . min ( 4 , dataCapacityBits - bb . length ) ) ;
@ -202,7 +202,7 @@ namespace qrcodegen {
// Compute ECC, draw modules
// Compute ECC, draw modules
this . drawFunctionPatterns ( ) ;
this . drawFunctionPatterns ( ) ;
le t allCodewords : Array < byte > = this . addEccAndInterleave ( dataCodewords ) ;
cons t allCodewords : Array < byte > = this . addEccAndInterleave ( dataCodewords ) ;
this . drawCodewords ( allCodewords ) ;
this . drawCodewords ( allCodewords ) ;
// Do masking
// Do masking
@ -211,7 +211,7 @@ namespace qrcodegen {
for ( let i = 0 ; i < 8 ; i ++ ) {
for ( let i = 0 ; i < 8 ; i ++ ) {
this . drawFormatBits ( i ) ;
this . drawFormatBits ( i ) ;
this . applyMask ( i ) ;
this . applyMask ( i ) ;
le t penalty : int = this . getPenaltyScore ( ) ;
cons t penalty : int = this . getPenaltyScore ( ) ;
if ( penalty < minPenalty ) {
if ( penalty < minPenalty ) {
mask = i ;
mask = i ;
minPenalty = penalty ;
minPenalty = penalty ;
@ -248,7 +248,7 @@ namespace qrcodegen {
public drawCanvas ( scale : int , border : int , canvas : HTMLCanvasElement ) : void {
public drawCanvas ( scale : int , border : int , canvas : HTMLCanvasElement ) : void {
if ( scale <= 0 || border < 0 )
if ( scale <= 0 || border < 0 )
throw "Value out of range" ;
throw "Value out of range" ;
le t width : int = ( this . size + border * 2 ) * scale ;
cons t width : int = ( this . size + border * 2 ) * scale ;
canvas . width = width ;
canvas . width = width ;
canvas . height = width ;
canvas . height = width ;
let ctx = canvas . getContext ( "2d" ) as CanvasRenderingContext2D ;
let ctx = canvas . getContext ( "2d" ) as CanvasRenderingContext2D ;
@ -299,8 +299,8 @@ namespace qrcodegen {
this . drawFinderPattern ( 3 , this . size - 4 ) ;
this . drawFinderPattern ( 3 , this . size - 4 ) ;
// Draw numerous alignment patterns
// Draw numerous alignment patterns
le t alignPatPos : Array < int > = this . getAlignmentPatternPositions ( ) ;
cons t alignPatPos : Array < int > = this . getAlignmentPatternPositions ( ) ;
le t numAlign : int = alignPatPos . length ;
cons t numAlign : int = alignPatPos . length ;
for ( let i = 0 ; i < numAlign ; i ++ ) {
for ( let i = 0 ; i < numAlign ; i ++ ) {
for ( let j = 0 ; j < numAlign ; j ++ ) {
for ( let j = 0 ; j < numAlign ; j ++ ) {
// Don't draw on the three finder corners
// Don't draw on the three finder corners
@ -361,9 +361,9 @@ namespace qrcodegen {
// Draw two copies
// Draw two copies
for ( let i = 0 ; i < 18 ; i ++ ) {
for ( let i = 0 ; i < 18 ; i ++ ) {
le t bt : boolean = getBit ( bits , i ) ;
cons t bt : boolean = getBit ( bits , i ) ;
le t a : int = this . size - 11 + i % 3 ;
cons t a : int = this . size - 11 + i % 3 ;
le t b : int = Math . floor ( i / 3 ) ;
cons t b : int = Math . floor ( i / 3 ) ;
this . setFunctionModule ( a , b , bt ) ;
this . setFunctionModule ( a , b , bt ) ;
this . setFunctionModule ( b , a , bt ) ;
this . setFunctionModule ( b , a , bt ) ;
}
}
@ -375,9 +375,9 @@ namespace qrcodegen {
private drawFinderPattern ( x : int , y : int ) : void {
private drawFinderPattern ( x : int , y : int ) : void {
for ( let dy = - 4 ; dy <= 4 ; dy ++ ) {
for ( let dy = - 4 ; dy <= 4 ; dy ++ ) {
for ( let dx = - 4 ; dx <= 4 ; dx ++ ) {
for ( let dx = - 4 ; dx <= 4 ; dx ++ ) {
le t dist : int = Math . max ( Math . abs ( dx ) , Math . abs ( dy ) ) ; // Chebyshev/infinity norm
cons t dist : int = Math . max ( Math . abs ( dx ) , Math . abs ( dy ) ) ; // Chebyshev/infinity norm
le t xx : int = x + dx ;
cons t xx : int = x + dx ;
le t yy : int = y + dy ;
cons t yy : int = y + dy ;
if ( 0 <= xx && xx < this . size && 0 <= yy && yy < this . size )
if ( 0 <= xx && xx < this . size && 0 <= yy && yy < this . size )
this . setFunctionModule ( xx , yy , dist != 2 && dist != 4 ) ;
this . setFunctionModule ( xx , yy , dist != 2 && dist != 4 ) ;
}
}
@ -414,19 +414,19 @@ namespace qrcodegen {
throw "Invalid argument" ;
throw "Invalid argument" ;
// Calculate parameter numbers
// Calculate parameter numbers
le t numBlocks : int = QrCode . NUM_ERROR_CORRECTION_BLOCKS [ ecl . ordinal ] [ ver ] ;
cons t numBlocks : int = QrCode . NUM_ERROR_CORRECTION_BLOCKS [ ecl . ordinal ] [ ver ] ;
le t blockEccLen : int = QrCode . ECC_CODEWORDS_PER_BLOCK [ ecl . ordinal ] [ ver ] ;
cons t blockEccLen : int = QrCode . ECC_CODEWORDS_PER_BLOCK [ ecl . ordinal ] [ ver ] ;
le t rawCodewords : int = Math . floor ( QrCode . getNumRawDataModules ( ver ) / 8 ) ;
cons t rawCodewords : int = Math . floor ( QrCode . getNumRawDataModules ( ver ) / 8 ) ;
le t numShortBlocks : int = numBlocks - rawCodewords % numBlocks ;
cons t numShortBlocks : int = numBlocks - rawCodewords % numBlocks ;
le t shortBlockLen : int = Math . floor ( rawCodewords / numBlocks ) ;
cons t shortBlockLen : int = Math . floor ( rawCodewords / numBlocks ) ;
// Split data into blocks and append ECC to each block
// Split data into blocks and append ECC to each block
let blocks : Array < Array < byte > > = [ ] ;
let blocks : Array < Array < byte > > = [ ] ;
le t rs = new ReedSolomonGenerator ( blockEccLen ) ;
cons t rs = new ReedSolomonGenerator ( blockEccLen ) ;
for ( let i = 0 , k = 0 ; i < numBlocks ; i ++ ) {
for ( let i = 0 , k = 0 ; i < numBlocks ; i ++ ) {
let dat : Array < byte > = data . slice ( k , k + shortBlockLen - blockEccLen + ( i < numShortBlocks ? 0 : 1 ) ) ;
let dat : Array < byte > = data . slice ( k , k + shortBlockLen - blockEccLen + ( i < numShortBlocks ? 0 : 1 ) ) ;
k += dat . length ;
k += dat . length ;
le t ecc : Array < byte > = rs . getRemainder ( dat ) ;
cons t ecc : Array < byte > = rs . getRemainder ( dat ) ;
if ( i < numShortBlocks )
if ( i < numShortBlocks )
dat . push ( 0 ) ;
dat . push ( 0 ) ;
blocks . push ( dat . concat ( ecc ) ) ;
blocks . push ( dat . concat ( ecc ) ) ;
@ -459,9 +459,9 @@ namespace qrcodegen {
right = 5 ;
right = 5 ;
for ( let vert = 0 ; vert < this . size ; vert ++ ) { // Vertical counter
for ( let vert = 0 ; vert < this . size ; vert ++ ) { // Vertical counter
for ( let j = 0 ; j < 2 ; j ++ ) {
for ( let j = 0 ; j < 2 ; j ++ ) {
le t x : int = right - j ; // Actual x coordinate
cons t x : int = right - j ; // Actual x coordinate
le t upward : boolean = ( ( right + 1 ) & 2 ) == 0 ;
cons t upward : boolean = ( ( right + 1 ) & 2 ) == 0 ;
le t y : int = upward ? this . size - 1 - vert : vert ; // Actual y coordinate
cons t y : int = upward ? this . size - 1 - vert : vert ; // Actual y coordinate
if ( ! this . isFunction [ y ] [ x ] && i < data . length * 8 ) {
if ( ! this . isFunction [ y ] [ x ] && i < data . length * 8 ) {
this . module s [ y ] [ x ] = getBit ( data [ i >>> 3 ] , 7 - ( i & 7 ) ) ;
this . module s [ y ] [ x ] = getBit ( data [ i >>> 3 ] , 7 - ( i & 7 ) ) ;
i ++ ;
i ++ ;
@ -566,7 +566,7 @@ namespace qrcodegen {
// 2*2 blocks of modules having same color
// 2*2 blocks of modules having same color
for ( let y = 0 ; y < this . size - 1 ; y ++ ) {
for ( let y = 0 ; y < this . size - 1 ; y ++ ) {
for ( let x = 0 ; x < this . size - 1 ; x ++ ) {
for ( let x = 0 ; x < this . size - 1 ; x ++ ) {
le t color : boolean = this . module s [ y ] [ x ] ;
cons t color : boolean = this . module s [ y ] [ x ] ;
if ( color == this . module s [ y ] [ x + 1 ] &&
if ( color == this . module s [ y ] [ x + 1 ] &&
color == this . module s [ y + 1 ] [ x ] &&
color == this . module s [ y + 1 ] [ x ] &&
color == this . module s [ y + 1 ] [ x + 1 ] )
color == this . module s [ y + 1 ] [ x + 1 ] )
@ -576,15 +576,15 @@ namespace qrcodegen {
// Balance of black and white modules
// Balance of black and white modules
let black : int = 0 ;
let black : int = 0 ;
for ( le t row of this . module s ) {
for ( cons t row of this . module s ) {
for ( le t color of row ) {
for ( cons t color of row ) {
if ( color )
if ( color )
black ++ ;
black ++ ;
}
}
}
}
le t total : int = this . size * this . size ; // Note that size is odd, so black/total != 1/2
cons t total : int = this . size * this . size ; // Note that size is odd, so black/total != 1/2
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
// Compute the smallest integer k >= 0 such that (45-5k)% <= black/total <= (55+5k)%
le t k : int = Math . ceil ( Math . abs ( black * 20 - total * 10 ) / total ) - 1 ;
cons t k : int = Math . ceil ( Math . abs ( black * 20 - total * 10 ) / total ) - 1 ;
result += k * QrCode . PENALTY_N4 ;
result += k * QrCode . PENALTY_N4 ;
return result ;
return result ;
}
}
@ -599,8 +599,8 @@ namespace qrcodegen {
if ( this . version == 1 )
if ( this . version == 1 )
return [ ] ;
return [ ] ;
else {
else {
le t numAlign : int = Math . floor ( this . version / 7 ) + 2 ;
cons t numAlign : int = Math . floor ( this . version / 7 ) + 2 ;
le t step : int = ( this . version == 32 ) ? 26 :
cons t step : int = ( this . version == 32 ) ? 26 :
Math . ceil ( ( this . size - 13 ) / ( numAlign * 2 - 2 ) ) * 2 ;
Math . ceil ( ( this . size - 13 ) / ( numAlign * 2 - 2 ) ) * 2 ;
let result : Array < int > = [ 6 ] ;
let result : Array < int > = [ 6 ] ;
for ( let pos = this . size - 7 ; result . length < numAlign ; pos -= step )
for ( let pos = this . size - 7 ; result . length < numAlign ; pos -= step )
@ -618,7 +618,7 @@ namespace qrcodegen {
throw "Version number out of range" ;
throw "Version number out of range" ;
let result : int = ( 16 * ver + 128 ) * ver + 64 ;
let result : int = ( 16 * ver + 128 ) * ver + 64 ;
if ( ver >= 2 ) {
if ( ver >= 2 ) {
le t numAlign : int = Math . floor ( ver / 7 ) + 2 ;
cons t numAlign : int = Math . floor ( ver / 7 ) + 2 ;
result -= ( 25 * numAlign - 10 ) * numAlign - 55 ;
result -= ( 25 * numAlign - 10 ) * numAlign - 55 ;
if ( ver >= 7 )
if ( ver >= 7 )
result -= 36 ;
result -= 36 ;
@ -718,7 +718,7 @@ namespace qrcodegen {
// can be converted to UTF-8 bytes and encoded as a byte mode segment.
// can be converted to UTF-8 bytes and encoded as a byte mode segment.
public static makeBytes ( data : Array < byte > ) : QrSegment {
public static makeBytes ( data : Array < byte > ) : QrSegment {
let bb = new BitBuffer ( ) ;
let bb = new BitBuffer ( ) ;
for ( le t b of data )
for ( cons t b of data )
bb . appendBits ( b , 8 ) ;
bb . appendBits ( b , 8 ) ;
return new QrSegment ( QrSegment . Mode . BYTE , data . length , bb ) ;
return new QrSegment ( QrSegment . Mode . BYTE , data . length , bb ) ;
}
}
@ -730,7 +730,7 @@ namespace qrcodegen {
throw "String contains non-numeric characters" ;
throw "String contains non-numeric characters" ;
let bb = new BitBuffer ( ) ;
let bb = new BitBuffer ( ) ;
for ( let i = 0 ; i < digits . length ; ) { // Consume up to 3 digits per iteration
for ( let i = 0 ; i < digits . length ; ) { // Consume up to 3 digits per iteration
le t n : int = Math . min ( digits . length - i , 3 ) ;
cons t n : int = Math . min ( digits . length - i , 3 ) ;
bb . appendBits ( parseInt ( digits . substr ( i , n ) , 10 ) , n * 3 + 1 ) ;
bb . appendBits ( parseInt ( digits . substr ( i , n ) , 10 ) , n * 3 + 1 ) ;
i += n ;
i += n ;
}
}
@ -827,8 +827,8 @@ namespace qrcodegen {
// the given version. The result is infinity if a segment has too many characters to fit its length field.
// the given version. The result is infinity if a segment has too many characters to fit its length field.
public static getTotalBits ( segs : Array < QrSegment > , version : int ) : number {
public static getTotalBits ( segs : Array < QrSegment > , version : int ) : number {
let result : number = 0 ;
let result : number = 0 ;
for ( le t seg of segs ) {
for ( cons t seg of segs ) {
le t ccbits : int = seg . mode . numCharCountBits ( version ) ;
cons t ccbits : int = seg . mode . numCharCountBits ( version ) ;
if ( seg . numChars >= ( 1 << ccbits ) )
if ( seg . numChars >= ( 1 << ccbits ) )
return Infinity ; // The segment's length doesn't fit the field's bit width
return Infinity ; // The segment's length doesn't fit the field's bit width
result += 4 + ccbits + seg . bitData . length ;
result += 4 + ccbits + seg . bitData . length ;
@ -922,8 +922,8 @@ namespace qrcodegen {
public getRemainder ( data : Array < byte > ) : Array < byte > {
public getRemainder ( data : Array < byte > ) : Array < byte > {
// Compute the remainder by performing polynomial division
// Compute the remainder by performing polynomial division
let result : Array < byte > = this . coefficients . map ( _ = > 0 ) ;
let result : Array < byte > = this . coefficients . map ( _ = > 0 ) ;
for ( le t b of data ) {
for ( cons t b of data ) {
le t factor : byte = b ^ ( result . shift ( ) as int ) ;
cons t factor : byte = b ^ ( result . shift ( ) as int ) ;
result . push ( 0 ) ;
result . push ( 0 ) ;
for ( let i = 0 ; i < result . length ; i ++ )
for ( let i = 0 ; i < result . length ; i ++ )
result [ i ] ^= ReedSolomonGenerator . multiply ( this . coefficients [ i ] , factor ) ;
result [ i ] ^= ReedSolomonGenerator . multiply ( this . coefficients [ i ] , factor ) ;