// Copyright 2011 The Go Authors.  All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// Package coding implements low-level QR coding details.
package coding // import "rsc.io/qr/coding" import ( ) // Field is the field for QR error correction. var Field = gf256.NewField(0x11d, 2) // A Version represents a QR version. // The version specifies the size of the QR code: // a QR code with version v has 4v+17 pixels on a side. // Versions number from 1 to 40: the larger the version, // the more information the code can store. type Version int const MinVersion = 1 const MaxVersion = 40 func ( Version) () string { return strconv.Itoa(int()) } func ( Version) () int { if <= 9 { return 0 } if <= 26 { return 1 } return 2 } // DataBytes returns the number of data bytes that can be // stored in a QR code with the given version and level. func ( Version) ( Level) int { := &vtab[] := &.level[] return .bytes - .nblock*.check } // Encoding implements a QR data encoding scheme. // The implementations--Numeric, Alphanumeric, and String--specify // the character set and the mapping from UTF-8 to code bits. // The more restrictive the mode, the fewer code bits are needed. type Encoding interface { Check() error Bits(v Version) int Encode(b *Bits, v Version) } type Bits struct { b []byte nbit int } func ( *Bits) () { .b = .b[:0] .nbit = 0 } func ( *Bits) () int { return .nbit } func ( *Bits) () []byte { if .nbit%8 != 0 { panic("fractional byte") } return .b } func ( *Bits) ( []byte) { if .nbit%8 != 0 { panic("fractional byte") } .b = append(.b, ...) .nbit += 8 * len() } func ( *Bits) ( uint, int) { for > 0 { := if > 8 { = 8 } if .nbit%8 == 0 { .b = append(.b, 0) } else { := -.nbit & 7 if > { = } } .nbit += := uint( - ) .b[len(.b)-1] |= uint8( >> << uint(-.nbit&7)) -= >> << -= } } // Num is the encoding for numeric data. // The only valid characters are the decimal digits 0 through 9. type Num string func ( Num) () string { return fmt.Sprintf("Num(%#q)", string()) } func ( Num) () error { for , := range { if < '0' || '9' < { return fmt.Errorf("non-numeric string %#q", string()) } } return nil } var numLen = [3]int{10, 12, 14} func ( Num) ( Version) int { return 4 + numLen[.sizeClass()] + (10*len()+2)/3 } func ( Num) ( *Bits, Version) { .Write(1, 4) .Write(uint(len()), numLen[.sizeClass()]) var int for = 0; +3 <= len(); += 3 { := uint([]-'0')*100 + uint([+1]-'0')*10 + uint([+2]-'0') .Write(, 10) } switch len() - { case 1: := uint([] - '0') .Write(, 4) case 2: := uint([]-'0')*10 + uint([+1]-'0') .Write(, 7) } } // Alpha is the encoding for alphanumeric data. // The valid characters are 0-9A-Z$%*+-./: and space. type Alpha string const alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:" func ( Alpha) () string { return fmt.Sprintf("Alpha(%#q)", string()) } func ( Alpha) () error { for , := range { if strings.IndexRune(alphabet, ) < 0 { return fmt.Errorf("non-alphanumeric string %#q", string()) } } return nil } var alphaLen = [3]int{9, 11, 13} func ( Alpha) ( Version) int { return 4 + alphaLen[.sizeClass()] + (11*len()+1)/2 } func ( Alpha) ( *Bits, Version) { .Write(2, 4) .Write(uint(len()), alphaLen[.sizeClass()]) var int for = 0; +2 <= len(); += 2 { := uint(strings.IndexRune(alphabet, rune([])))*45 + uint(strings.IndexRune(alphabet, rune([+1]))) .Write(, 11) } if < len() { := uint(strings.IndexRune(alphabet, rune([]))) .Write(, 6) } } // String is the encoding for 8-bit data. All bytes are valid. type String string func ( String) () string { return fmt.Sprintf("String(%#q)", string()) } func ( String) () error { return nil } var stringLen = [3]int{8, 16, 16} func ( String) ( Version) int { return 4 + stringLen[.sizeClass()] + 8*len() } func ( String) ( *Bits, Version) { .Write(4, 4) .Write(uint(len()), stringLen[.sizeClass()]) for := 0; < len(); ++ { .Write(uint([]), 8) } } // A Pixel describes a single pixel in a QR code. type Pixel uint32 const ( Black Pixel = 1 << iota Invert ) func ( Pixel) () uint { return uint( >> 6) } func ( uint) Pixel { return Pixel( << 6) } func ( PixelRole) () Pixel { return Pixel( << 2) } func ( Pixel) () PixelRole { return PixelRole(>>2) & 15 } func ( Pixel) () string { := .Role().String() if &Black != 0 { += "+black" } if &Invert != 0 { += "+invert" } += "+" + strconv.FormatUint(uint64(.Offset()), 10) return } // A PixelRole describes the role of a QR pixel. type PixelRole uint32 const ( _ PixelRole = iota Position // position squares (large) Alignment // alignment squares (small) Timing // timing strip between position squares Format // format metadata PVersion // version pattern Unused // unused pixel Data // data bit Check // error correction check bit Extra ) var roles = []string{ "", "position", "alignment", "timing", "format", "pversion", "unused", "data", "check", "extra", } func ( PixelRole) () string { if Position <= && <= Check { return roles[] } return strconv.Itoa(int()) } // A Level represents a QR error correction level. // From least to most tolerant of errors, they are L, M, Q, H. type Level int const ( L Level = iota M Q H ) func ( Level) () string { if L <= && <= H { return "LMQH"[ : +1] } return strconv.Itoa(int()) } // A Code is a square pixel grid. type Code struct { Bitmap []byte // 1 is black, 0 is white Size int // number of pixels on a side Stride int // number of bytes per row } func ( *Code) (, int) bool { return 0 <= && < .Size && 0 <= && < .Size && .Bitmap[*.Stride+/8]&(1<<uint(7-&7)) != 0 } // A Mask describes a mask that is applied to the QR // code to avoid QR artifacts being interpreted as // alignment and timing patterns (such as the squares // in the corners). Valid masks are integers from 0 to 7. type Mask int // http://www.swetake.com/qr/qr5_en.html var mfunc = []func(int, int) bool{ func(, int) bool { return (+)%2 == 0 }, func(, int) bool { return %2 == 0 }, func(, int) bool { return %3 == 0 }, func(, int) bool { return (+)%3 == 0 }, func(, int) bool { return (/2+/3)%2 == 0 }, func(, int) bool { return *%2+*%3 == 0 }, func(, int) bool { return (*%2+*%3)%2 == 0 }, func(, int) bool { return (*%3+(+)%2)%2 == 0 }, } func ( Mask) (, int) bool { if < 0 { return false } return mfunc[](, ) } // A Plan describes how to construct a QR code // with a specific version, level, and mask. type Plan struct { Version Version Level Level Mask Mask DataBytes int // number of data bytes CheckBytes int // number of error correcting (checksum) bytes Blocks int // number of data blocks Pixel [][]Pixel // pixel map } // NewPlan returns a Plan for a QR code with the given // version, level, and mask. func ( Version, Level, Mask) (*Plan, error) { , := vplan() if != nil { return nil, } if := fplan(, , ); != nil { return nil, } if := lplan(, , ); != nil { return nil, } if := mplan(, ); != nil { return nil, } return , nil } func ( *Bits) ( int) { if < 0 { panic("qr: invalid pad size") } if <= 4 { .Write(0, ) } else { .Write(0, 4) -= 4 -= -.Bits() & 7 .Write(0, -.Bits()&7) := / 8 for := 0; < ; += 2 { .Write(0xec, 8) if +1 >= { break } .Write(0x11, 8) } } } func ( *Bits) ( Version, Level) { := .DataBytes() if .nbit < *8 { .Pad(*8 - .nbit) } if .nbit != *8 { panic("qr: too much data") } := .Bytes() := &vtab[] := &.level[] := / .nblock := % .nblock := make([]byte, .check) := gf256.NewRSEncoder(Field, .check) for := 0; < .nblock; ++ { if == .nblock- { ++ } .ECC([:], ) .Append() = [:] } if len(.Bytes()) != .bytes { panic("qr: internal error") } } func ( *Plan) ( ...Encoding) (*Code, error) { var Bits for , := range { if := .Check(); != nil { return nil, } .Encode(&, .Version) } if .Bits() > .DataBytes*8 { return nil, fmt.Errorf("cannot encode %d bits into %d-bit code", .Bits(), .DataBytes*8) } .AddCheckBytes(.Version, .Level) := .Bytes() // Now we have the checksum bytes and the data bytes. // Construct the actual code. := &Code{Size: len(.Pixel), Stride: (len(.Pixel) + 7) &^ 7} .Bitmap = make([]byte, .Stride*.Size) := .Bitmap for , := range .Pixel { for , := range { switch .Role() { case Data, Check: := .Offset() if [/8]&(1<<uint(7-&7)) != 0 { ^= Black } } if &Black != 0 { [/8] |= 1 << uint(7-&7) } } = [.Stride:] } return , nil } // A version describes metadata associated with a version. type version struct { apos int astride int bytes int pattern int level [4]level } type level struct { nblock int check int } var vtab = []version{ {}, {100, 100, 26, 0x0, [4]level{{1, 7}, {1, 10}, {1, 13}, {1, 17}}}, // 1 {16, 100, 44, 0x0, [4]level{{1, 10}, {1, 16}, {1, 22}, {1, 28}}}, // 2 {20, 100, 70, 0x0, [4]level{{1, 15}, {1, 26}, {2, 18}, {2, 22}}}, // 3 {24, 100, 100, 0x0, [4]level{{1, 20}, {2, 18}, {2, 26}, {4, 16}}}, // 4 {28, 100, 134, 0x0, [4]level{{1, 26}, {2, 24}, {4, 18}, {4, 22}}}, // 5 {32, 100, 172, 0x0, [4]level{{2, 18}, {4, 16}, {4, 24}, {4, 28}}}, // 6 {20, 16, 196, 0x7c94, [4]level{{2, 20}, {4, 18}, {6, 18}, {5, 26}}}, // 7 {22, 18, 242, 0x85bc, [4]level{{2, 24}, {4, 22}, {6, 22}, {6, 26}}}, // 8 {24, 20, 292, 0x9a99, [4]level{{2, 30}, {5, 22}, {8, 20}, {8, 24}}}, // 9 {26, 22, 346, 0xa4d3, [4]level{{4, 18}, {5, 26}, {8, 24}, {8, 28}}}, // 10 {28, 24, 404, 0xbbf6, [4]level{{4, 20}, {5, 30}, {8, 28}, {11, 24}}}, // 11 {30, 26, 466, 0xc762, [4]level{{4, 24}, {8, 22}, {10, 26}, {11, 28}}}, // 12 {32, 28, 532, 0xd847, [4]level{{4, 26}, {9, 22}, {12, 24}, {16, 22}}}, // 13 {24, 20, 581, 0xe60d, [4]level{{4, 30}, {9, 24}, {16, 20}, {16, 24}}}, // 14 {24, 22, 655, 0xf928, [4]level{{6, 22}, {10, 24}, {12, 30}, {18, 24}}}, // 15 {24, 24, 733, 0x10b78, [4]level{{6, 24}, {10, 28}, {17, 24}, {16, 30}}}, // 16 {28, 24, 815, 0x1145d, [4]level{{6, 28}, {11, 28}, {16, 28}, {19, 28}}}, // 17 {28, 26, 901, 0x12a17, [4]level{{6, 30}, {13, 26}, {18, 28}, {21, 28}}}, // 18 {28, 28, 991, 0x13532, [4]level{{7, 28}, {14, 26}, {21, 26}, {25, 26}}}, // 19 {32, 28, 1085, 0x149a6, [4]level{{8, 28}, {16, 26}, {20, 30}, {25, 28}}}, // 20 {26, 22, 1156, 0x15683, [4]level{{8, 28}, {17, 26}, {23, 28}, {25, 30}}}, // 21 {24, 24, 1258, 0x168c9, [4]level{{9, 28}, {17, 28}, {23, 30}, {34, 24}}}, // 22 {28, 24, 1364, 0x177ec, [4]level{{9, 30}, {18, 28}, {25, 30}, {30, 30}}}, // 23 {26, 26, 1474, 0x18ec4, [4]level{{10, 30}, {20, 28}, {27, 30}, {32, 30}}}, // 24 {30, 26, 1588, 0x191e1, [4]level{{12, 26}, {21, 28}, {29, 30}, {35, 30}}}, // 25 {28, 28, 1706, 0x1afab, [4]level{{12, 28}, {23, 28}, {34, 28}, {37, 30}}}, // 26 {32, 28, 1828, 0x1b08e, [4]level{{12, 30}, {25, 28}, {34, 30}, {40, 30}}}, // 27 {24, 24, 1921, 0x1cc1a, [4]level{{13, 30}, {26, 28}, {35, 30}, {42, 30}}}, // 28 {28, 24, 2051, 0x1d33f, [4]level{{14, 30}, {28, 28}, {38, 30}, {45, 30}}}, // 29 {24, 26, 2185, 0x1ed75, [4]level{{15, 30}, {29, 28}, {40, 30}, {48, 30}}}, // 30 {28, 26, 2323, 0x1f250, [4]level{{16, 30}, {31, 28}, {43, 30}, {51, 30}}}, // 31 {32, 26, 2465, 0x209d5, [4]level{{17, 30}, {33, 28}, {45, 30}, {54, 30}}}, // 32 {28, 28, 2611, 0x216f0, [4]level{{18, 30}, {35, 28}, {48, 30}, {57, 30}}}, // 33 {32, 28, 2761, 0x228ba, [4]level{{19, 30}, {37, 28}, {51, 30}, {60, 30}}}, // 34 {28, 24, 2876, 0x2379f, [4]level{{19, 30}, {38, 28}, {53, 30}, {63, 30}}}, // 35 {22, 26, 3034, 0x24b0b, [4]level{{20, 30}, {40, 28}, {56, 30}, {66, 30}}}, // 36 {26, 26, 3196, 0x2542e, [4]level{{21, 30}, {43, 28}, {59, 30}, {70, 30}}}, // 37 {30, 26, 3362, 0x26a64, [4]level{{22, 30}, {45, 28}, {62, 30}, {74, 30}}}, // 38 {24, 28, 3532, 0x27541, [4]level{{24, 30}, {47, 28}, {65, 30}, {77, 30}}}, // 39 {28, 28, 3706, 0x28c69, [4]level{{25, 30}, {49, 28}, {68, 30}, {81, 30}}}, // 40 } func ( int) [][]Pixel { := make([][]Pixel, ) := make([]Pixel, *) for := range { [], = [:], [:] } return } // vplan creates a Plan for the given version. func ( Version) (*Plan, error) { := &Plan{Version: } if < 1 || > 40 { return nil, fmt.Errorf("invalid QR version %d", int()) } := 17 + int()*4 := grid() .Pixel = // Timing markers (overwritten by boxes). const = 6 // timing is in row/column 6 (counting from 0) for := range { := Timing.Pixel() if &1 == 0 { |= Black } [][] = [][] = } // Position boxes. posBox(, 0, 0) posBox(, -7, 0) posBox(, 0, -7) // Alignment boxes. := &vtab[] for := 4; +5 < ; { for := 4; +5 < ; { // don't overwrite timing markers if ( < 7 && < 7) || ( < 7 && +5 >= -7) || (+5 >= -7 && < 7) { } else { alignBox(, , ) } if == 4 { = .apos } else { += .astride } } if == 4 { = .apos } else { += .astride } } // Version pattern. := vtab[].pattern if != 0 { := for := 0; < 6; ++ { for := 0; < 3; ++ { := PVersion.Pixel() if &1 != 0 { |= Black } [-11+][] = [][-11+] = >>= 1 } } } // One lonely black pixel [-8][8] = Unused.Pixel() | Black return , nil } // fplan adds the format pixels func ( Level, Mask, *Plan) error { // Format pixels. := uint32(^1) << 13 // level: L=01, M=00, Q=11, H=10 |= uint32() << 10 // mask const = 0x537 := for := 14; >= 10; -- { if &(1<<uint()) != 0 { ^= << uint(-10) } } |= := uint32(0x5412) := len(.Pixel) for := uint(0); < 15; ++ { := Format.Pixel() + OffsetPixel() if (>>)&1 == 1 { |= Black } if (>>)&1 == 1 { ^= Invert | Black } // top left switch { case < 6: .Pixel[][8] = case < 8: .Pixel[+1][8] = case < 9: .Pixel[8][7] = default: .Pixel[8][14-] = } // bottom right switch { case < 8: .Pixel[8][-1-int()] = default: .Pixel[-1-int(14-)][8] = } } return nil } // lplan edits a version-only Plan to add information // about the error correction levels. func ( Version, Level, *Plan) error { .Level = := vtab[].level[].nblock := vtab[].level[].check := (vtab[].bytes - *) / := (vtab[].bytes - *) % := (* + ) * 8 := * * 8 .DataBytes = vtab[].bytes - * .CheckBytes = * .Blocks = // Make data + checksum pixels. := make([]Pixel, ) for := range { [] = Data.Pixel() | OffsetPixel(uint()) } := make([]Pixel, ) for := range { [] = Check.Pixel() | OffsetPixel(uint(+)) } // Split into blocks. := make([][]Pixel, ) := make([][]Pixel, ) for := 0; < ; ++ { // The last few blocks have an extra data byte (8 pixels). := if >= - { ++ } [], = [0:*8], [*8:] [], = [0:*8], [*8:] } if len() != 0 || len() != 0 { panic("data/check math") } // Build up bit sequence, taking first byte of each block, // then second byte, and so on. Then checksums. := make([]Pixel, +) := for := 0; < +1; ++ { for , := range { if *8 < len() { copy(, [*8:(+1)*8]) = [8:] } } } for := 0; < ; ++ { for , := range { if *8 < len() { copy(, [*8:(+1)*8]) = [8:] } } } if len() != 0 { panic("dst math") } // Sweep up pair of columns, // then down, assigning to right then left pixel. // Repeat. // See Figure 2 of http://www.pclviewer.com/rs2/qrtopology.htm := len(.Pixel) := make([]Pixel, 7) for := range { [] = Extra.Pixel() } := append(, ...) for := ; > 0; { for := - 1; >= 0; -- { if .Pixel[][-1].Role() == 0 { .Pixel[][-1], = [0], [1:] } if .Pixel[][-2].Role() == 0 { .Pixel[][-2], = [0], [1:] } } -= 2 if == 7 { // vertical timing strip -- } for := 0; < ; ++ { if .Pixel[][-1].Role() == 0 { .Pixel[][-1], = [0], [1:] } if .Pixel[][-2].Role() == 0 { .Pixel[][-2], = [0], [1:] } } -= 2 } return nil } // mplan edits a version+level-only Plan to add the mask. func ( Mask, *Plan) error { .Mask = for , := range .Pixel { for , := range { if := .Role(); ( == Data || == Check || == Extra) && .Mask.Invert(, ) { [] ^= Black | Invert } } } return nil } // posBox draws a position (large) box at upper left x, y. func ( [][]Pixel, , int) { := Position.Pixel() // box for := 0; < 7; ++ { for := 0; < 7; ++ { := if == 0 || == 6 || == 0 || == 6 || 2 <= && <= 4 && 2 <= && <= 4 { |= Black } [+][+] = } } // white border for := -1; < 8; ++ { if 0 <= + && + < len() { if > 0 { [+][-1] = } if +7 < len() { [+][+7] = } } } for := -1; < 8; ++ { if 0 <= + && + < len() { if > 0 { [-1][+] = } if +7 < len() { [+7][+] = } } } } // alignBox draw an alignment (small) box at upper left x, y. func ( [][]Pixel, , int) { // box := Alignment.Pixel() for := 0; < 5; ++ { for := 0; < 5; ++ { := if == 0 || == 4 || == 0 || == 4 || == 2 && == 2 { |= Black } [+][+] = } } }