diff options
Diffstat (limited to 'vendor/github.com/skip2')
-rw-r--r-- | vendor/github.com/skip2/go-qrcode/README.md | 30 | ||||
-rw-r--r-- | vendor/github.com/skip2/go-qrcode/encoder.go | 35 | ||||
-rw-r--r-- | vendor/github.com/skip2/go-qrcode/go.mod | 3 | ||||
-rw-r--r-- | vendor/github.com/skip2/go-qrcode/qrcode.go | 67 | ||||
-rw-r--r-- | vendor/github.com/skip2/go-qrcode/regular_symbol.go | 10 |
5 files changed, 105 insertions, 40 deletions
diff --git a/vendor/github.com/skip2/go-qrcode/README.md b/vendor/github.com/skip2/go-qrcode/README.md index 8281ed3e..0a800b72 100644 --- a/vendor/github.com/skip2/go-qrcode/README.md +++ b/vendor/github.com/skip2/go-qrcode/README.md @@ -18,26 +18,20 @@ A command-line tool `qrcode` will be built into `$GOPATH/bin/`. import qrcode "github.com/skip2/go-qrcode" -- **Create a PNG image:** +- **Create a 256x256 PNG image:** var png []byte png, err := qrcode.Encode("https://example.org", qrcode.Medium, 256) -- **Create a PNG image and write to a file:** +- **Create a 256x256 PNG image and write to a file:** err := qrcode.WriteFile("https://example.org", qrcode.Medium, 256, "qr.png") -- **Create a PNG image with custom colors and write to file:** +- **Create a 256x256 PNG image with custom colors and write to file:** err := qrcode.WriteColorFile("https://example.org", qrcode.Medium, 256, color.Black, color.White, "qr.png") -All examples use the qrcode.Medium error Recovery Level and create a fixed -256x256px size QR Code. The last function creates a white on black instead of black -on white QR Code. - -The maximum capacity of a QR Code varies according to the content encoded and -the error recovery level. The maximum capacity is 2,953 bytes, 4,296 -alphanumeric characters, 7,089 numeric digits, or a combination of these. +All examples use the qrcode.Medium error Recovery Level and create a fixed 256x256px size QR Code. The last function creates a white on black instead of black on white QR Code. ## Documentation @@ -56,10 +50,13 @@ qrcode -- QR Code encoder in Go https://github.com/skip2/go-qrcode Flags: + -d disable QR Code border + -i invert black and white -o string - out PNG file prefix, empty for stdout + out PNG file prefix, empty for stdout -s int - image size (pixel) (default 256) + image size (pixel) (default 256) + -t print as text-art on stdout Usage: 1. Arguments except for flags are joined by " " and used to generate QR code. @@ -71,7 +68,16 @@ Usage: 2. Save to file if "display" not available: qrcode "homepage: https://github.com/skip2/go-qrcode" > out.png + ``` +## Maximum capacity +The maximum capacity of a QR Code varies according to the content encoded and the error recovery level. The maximum capacity is 2,953 bytes, 4,296 alphanumeric characters, 7,089 numeric digits, or a combination of these. + +## Borderless QR Codes + +To aid QR Code reading software, QR codes have a built in whitespace border. + +If you know what you're doing, and don't want a border, see https://gist.github.com/skip2/7e3d8a82f5317df9be437f8ec8ec0b7d for how to do it. It's still recommended you include a border manually. ## Links diff --git a/vendor/github.com/skip2/go-qrcode/encoder.go b/vendor/github.com/skip2/go-qrcode/encoder.go index 713378c0..6a809cfe 100644 --- a/vendor/github.com/skip2/go-qrcode/encoder.go +++ b/vendor/github.com/skip2/go-qrcode/encoder.go @@ -172,7 +172,7 @@ func (d *dataEncoder) encode(data []byte) (*bitset.Bitset, error) { } // Classify data into unoptimised segments. - d.classifyDataModes() + highestRequiredMode := d.classifyDataModes() // Optimise segments. err := d.optimiseDataModes() @@ -180,6 +180,25 @@ func (d *dataEncoder) encode(data []byte) (*bitset.Bitset, error) { return nil, err } + // Check if a single byte encoded segment would be more efficient. + optimizedLength := 0 + for _, s := range d.optimised { + length, err := d.encodedLength(s.dataMode, len(s.data)) + if err != nil { + return nil, err + } + optimizedLength += length + } + + singleByteSegmentLength, err := d.encodedLength(highestRequiredMode, len(d.data)) + if err != nil { + return nil, err + } + + if singleByteSegmentLength <= optimizedLength { + d.optimised = []segment{segment{dataMode: highestRequiredMode, data: d.data}} + } + // Encode data. encoded := bitset.New() for _, s := range d.optimised { @@ -192,9 +211,15 @@ func (d *dataEncoder) encode(data []byte) (*bitset.Bitset, error) { // classifyDataModes classifies the raw data into unoptimised segments. // e.g. "123ZZ#!#!" => // [numeric, 3, "123"] [alphanumeric, 2, "ZZ"] [byte, 4, "#!#!"]. -func (d *dataEncoder) classifyDataModes() { +// +// Returns the highest data mode needed to encode the data. e.g. for a mixed +// numeric/alphanumeric input, the highest is alphanumeric. +// +// dataModeNone < dataModeNumeric < dataModeAlphanumeric < dataModeByte +func (d *dataEncoder) classifyDataModes() dataMode { var start int mode := dataModeNone + highestRequiredMode := mode for i, v := range d.data { newMode := dataModeNone @@ -217,9 +242,15 @@ func (d *dataEncoder) classifyDataModes() { mode = newMode } + + if newMode > highestRequiredMode { + highestRequiredMode = newMode + } } d.actual = append(d.actual, segment{dataMode: mode, data: d.data[start:len(d.data)]}) + + return highestRequiredMode } // optimiseDataModes optimises the list of segments to reduce the overall output diff --git a/vendor/github.com/skip2/go-qrcode/go.mod b/vendor/github.com/skip2/go-qrcode/go.mod new file mode 100644 index 00000000..a915813d --- /dev/null +++ b/vendor/github.com/skip2/go-qrcode/go.mod @@ -0,0 +1,3 @@ +module github.com/skip2/go-qrcode + +go 1.13 diff --git a/vendor/github.com/skip2/go-qrcode/qrcode.go b/vendor/github.com/skip2/go-qrcode/qrcode.go index 9428d863..d0541bcb 100644 --- a/vendor/github.com/skip2/go-qrcode/qrcode.go +++ b/vendor/github.com/skip2/go-qrcode/qrcode.go @@ -51,6 +51,7 @@ package qrcode import ( "bytes" "errors" + "fmt" "image" "image/color" "image/png" @@ -135,6 +136,9 @@ type QRCode struct { ForegroundColor color.Color BackgroundColor color.Color + // Disable the QR Code border. + DisableBorder bool + encoder *dataEncoder version qrCodeVersion @@ -193,12 +197,16 @@ func New(content string, level RecoveryLevel) (*QRCode, error) { version: *chosenVersion, } - q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len())) - return q, nil } -func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QRCode, error) { +// NewWithForcedVersion constructs a QRCode of a specific version. +// +// var q *qrcode.QRCode +// q, err := qrcode.NewWithForcedVersion("my content", 25, qrcode.Medium) +// +// An error occurs in case of invalid version. +func NewWithForcedVersion(content string, version int, level RecoveryLevel) (*QRCode, error) { var encoder *dataEncoder switch { @@ -209,7 +217,7 @@ func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QR case version >= 27 && version <= 40: encoder = newDataEncoder(dataEncoderType27To40) default: - log.Fatalf("Invalid version %d (expected 1-40 inclusive)", version) + return nil, fmt.Errorf("Invalid version %d (expected 1-40 inclusive)", version) } var encoded *bitset.Bitset @@ -225,6 +233,13 @@ func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QR return nil, errors.New("cannot find QR Code version") } + if encoded.Len() > chosenVersion.numDataBits() { + return nil, fmt.Errorf("Cannot encode QR code: content too large for fixed size QR Code version %d (encoded length is %d bits, maximum length is %d bits)", + version, + encoded.Len(), + chosenVersion.numDataBits()) + } + q := &QRCode{ Content: content, @@ -239,8 +254,6 @@ func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QR version: *chosenVersion, } - q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len())) - return q, nil } @@ -251,6 +264,9 @@ func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QR // The bitmap includes the required "quiet zone" around the QR Code to aid // decoding. func (q *QRCode) Bitmap() [][]bool { + // Build QR code. + q.encode() + return q.symbol.bitmap() } @@ -268,6 +284,9 @@ func (q *QRCode) Bitmap() [][]bool { // negative number to increase the scale of the image. e.g. a size of -5 causes // each module (QR Code "pixel") to be 5px in size. func (q *QRCode) Image(size int) image.Image { + // Build QR code. + q.encode() + // Minimum pixels (both width and height) required. realSize := q.symbol.size @@ -282,12 +301,7 @@ func (q *QRCode) Image(size int) image.Image { size = realSize } - // Size of each module drawn. - pixelsPerModule := size / realSize - - // Center the symbol within the image. - offset := (size - realSize*pixelsPerModule) / 2 - + // Output image. rect := image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{size, size}} // Saves a few bytes to have them in this order @@ -295,18 +309,21 @@ func (q *QRCode) Image(size int) image.Image { img := image.NewPaletted(rect, p) fgClr := uint8(img.Palette.Index(q.ForegroundColor)) + // QR code bitmap. bitmap := q.symbol.bitmap() - for y, row := range bitmap { - for x, v := range row { + + // Map each image pixel to the nearest QR code module. + modulesPerPixel := float64(realSize) / float64(size) + for y := 0; y < size; y++ { + y2 := int(float64(y) * modulesPerPixel) + for x := 0; x < size; x++ { + x2 := int(float64(x) * modulesPerPixel) + + v := bitmap[y2][x2] + if v { - startX := x*pixelsPerModule + offset - startY := y*pixelsPerModule + offset - for i := startX; i < startX+pixelsPerModule; i++ { - for j := startY; j < startY+pixelsPerModule; j++ { - pos := img.PixOffset(i, j) - img.Pix[pos] = fgClr - } - } + pos := img.PixOffset(x, y) + img.Pix[pos] = fgClr } } } @@ -371,7 +388,9 @@ func (q *QRCode) WriteFile(size int, filename string) error { // encode completes the steps required to encode the QR Code. These include // adding the terminator bits and padding, splitting the data into blocks and // applying the error correction, and selecting the best data mask. -func (q *QRCode) encode(numTerminatorBits int) { +func (q *QRCode) encode() { + numTerminatorBits := q.version.numTerminatorBitsRequired(q.data.Len()) + q.addTerminatorBits(numTerminatorBits) q.addPadding() @@ -384,7 +403,7 @@ func (q *QRCode) encode(numTerminatorBits int) { var s *symbol var err error - s, err = buildRegularSymbol(q.version, mask, encoded) + s, err = buildRegularSymbol(q.version, mask, encoded, !q.DisableBorder) if err != nil { log.Panic(err.Error()) diff --git a/vendor/github.com/skip2/go-qrcode/regular_symbol.go b/vendor/github.com/skip2/go-qrcode/regular_symbol.go index 134be18e..51eb148d 100644 --- a/vendor/github.com/skip2/go-qrcode/regular_symbol.go +++ b/vendor/github.com/skip2/go-qrcode/regular_symbol.go @@ -105,13 +105,19 @@ var ( ) func buildRegularSymbol(version qrCodeVersion, mask int, - data *bitset.Bitset) (*symbol, error) { + data *bitset.Bitset, includeQuietZone bool) (*symbol, error) { + + quietZoneSize := 0 + if includeQuietZone { + quietZoneSize = version.quietZoneSize() + } + m := ®ularSymbol{ version: version, mask: mask, data: data, - symbol: newSymbol(version.symbolSize(), version.quietZoneSize()), + symbol: newSymbol(version.symbolSize(), quietZoneSize), size: version.symbolSize(), } |