From 664037627db0161daabed979236f901d97b7ce23 Mon Sep 17 00:00:00 2001 From: fwcd Date: Mon, 24 Feb 2020 17:32:11 +0100 Subject: [PATCH] Port constants, ECC and miscellaneous structures to Swift --- swift/Sources/QRCodeGenerator/QRCode.swift | 50 ++++++++++++++ .../QRCodeGenerator/QRCodeConstants.swift | 52 ++++++++++++++ swift/Sources/QRCodeGenerator/QRCodeECC.swift | 47 +++++++++++++ .../QRCodeGenerator/QRCodeGenerator.swift | 3 - .../QRCodeGenerator/QRCodeMiscellaneous.swift | 67 +++++++++++++++++++ 5 files changed, 216 insertions(+), 3 deletions(-) create mode 100644 swift/Sources/QRCodeGenerator/QRCode.swift create mode 100644 swift/Sources/QRCodeGenerator/QRCodeConstants.swift create mode 100644 swift/Sources/QRCodeGenerator/QRCodeECC.swift delete mode 100644 swift/Sources/QRCodeGenerator/QRCodeGenerator.swift create mode 100644 swift/Sources/QRCodeGenerator/QRCodeMiscellaneous.swift diff --git a/swift/Sources/QRCodeGenerator/QRCode.swift b/swift/Sources/QRCodeGenerator/QRCode.swift new file mode 100644 index 0000000..90af367 --- /dev/null +++ b/swift/Sources/QRCodeGenerator/QRCode.swift @@ -0,0 +1,50 @@ +/* + * QR Code generator library (Swift) + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/qr-code-generator-library + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +struct QRCode { + // Scalar parameters: + + /// The version number of this QR Code, which is between 1 and 40 (inclusive). + /// This determines the size of this barcode. + private let version: QRCodeVersion + /// The width and height of this QR Code, measured in modules, between + /// 21 and 177 (inclusive). This is equal to version * 4 + 17. + private let size: Int + /// The error correction level used in this QR Code. + private let errorCorrectionLevel: QRCodeECC + /// The index of the mask pattern used in this QR Code, which is between 0 and 7 (inclusive). + /// Even if a QR Code is created with automatic masking requested (mask = None), + /// the resulting object still has a mask value between 0 and 7. + private let mask: Mask + + // Grids of modules/pixels, with dimensions of size*size: + + /// The modules of this QR Code (false = white, true = black). + /// Immutable after constructor finishes. Accessed through get_module(). + private let modules: [Bool] + + /// Indicates function modules that are not subjected to masking. Discarded when constructor finishes. + private let isFunction: [Bool] + + // TODO: Implement methods +} diff --git a/swift/Sources/QRCodeGenerator/QRCodeConstants.swift b/swift/Sources/QRCodeGenerator/QRCodeConstants.swift new file mode 100644 index 0000000..46b4400 --- /dev/null +++ b/swift/Sources/QRCodeGenerator/QRCodeConstants.swift @@ -0,0 +1,52 @@ +/* + * QR Code generator library (Swift) + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/qr-code-generator-library + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +/// The minimum version number supported in the QR Code Model 2 standard. +public let qrCodeMinVersion = QRCodeVersion(1) + +/// The maximum version number supported in the QR Code Model 2 standard. +public let qrCodeMaxVersion = QRCodeVersion(40) + +// For use in getPenaltyScore(), when evaluating which mask is best. +public let penaltyN1: Int = 3 +public let penaltyN2: Int = 3 +public let penaltyN3: Int = 40 +public let penaltyN4: Int = 10 + +public let eccCodewordsPerBlock: [[Int]] = [ + // Version: (note that index 0 is for padding, and is set to an illegal value) + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + [-1, 7, 10, 15, 20, 26, 18, 20, 24, 30, 18, 20, 24, 26, 30, 22, 24, 28, 30, 28, 28, 28, 28, 30, 30, 26, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], // Low + [-1, 10, 16, 26, 18, 24, 16, 18, 22, 22, 26, 30, 22, 22, 24, 24, 28, 28, 26, 26, 26, 26, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28], // Medium + [-1, 13, 22, 18, 26, 18, 24, 18, 22, 20, 24, 28, 26, 24, 20, 30, 24, 28, 28, 26, 30, 28, 30, 30, 30, 30, 28, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], // Quartile + [-1, 17, 28, 22, 16, 22, 28, 26, 26, 24, 28, 24, 28, 22, 24, 24, 30, 28, 28, 26, 28, 30, 24, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30, 30], // High +] + +public let numErrorCorrectionBlocks: [[Int]] = [ + // Version: (note that index 0 is for padding, and is set to an illegal value) + //0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40 Error correction level + [-1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 4, 4, 4, 4, 4, 6, 6, 6, 6, 7, 8, 8, 9, 9, 10, 12, 12, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 24, 25], // Low + [-1, 1, 1, 1, 2, 2, 4, 4, 4, 5, 5, 5, 8, 9, 9, 10, 10, 11, 13, 14, 16, 17, 17, 18, 20, 21, 23, 25, 26, 28, 29, 31, 33, 35, 37, 38, 40, 43, 45, 47, 49], // Medium + [-1, 1, 1, 2, 2, 4, 4, 6, 6, 8, 8, 8, 10, 12, 16, 12, 17, 16, 18, 21, 20, 23, 23, 25, 27, 29, 34, 34, 35, 38, 40, 43, 45, 48, 51, 53, 56, 59, 62, 65, 68], // Quartile + [-1, 1, 1, 2, 4, 4, 4, 5, 6, 8, 8, 11, 11, 16, 16, 18, 16, 19, 21, 25, 25, 25, 34, 30, 32, 35, 37, 40, 42, 45, 48, 51, 54, 57, 60, 63, 66, 70, 74, 77, 81], // High +] diff --git a/swift/Sources/QRCodeGenerator/QRCodeECC.swift b/swift/Sources/QRCodeGenerator/QRCodeECC.swift new file mode 100644 index 0000000..89c772e --- /dev/null +++ b/swift/Sources/QRCodeGenerator/QRCodeECC.swift @@ -0,0 +1,47 @@ +/* + * QR Code generator library (Swift) + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/qr-code-generator-library + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +/// The error correction level in a QR Code symbol. +public enum QRCodeECC: UInt { + /// The QR Code can tolerate about 7% erroneous codewords. + case low = 0 + /// The QR Code can tolerate about 15% erroneous codewords. + case medium = 1 + /// The QR Code can tolerate about 25% erroneous codewords. + case quartile = 2 + /// The QR Code can tolerate about 30% erroneous codewords. + case high = 3 + + /// Returns an unsigned 2-bit integer (in the range 0 to 3). + var ordinal: UInt { rawValue } + + /// Returns an unsigned 2-bit integer (in the range 0 to 3). + var formatBits: UInt32 { + switch self { + case .low: return 1 + case .medium: return 0 + case .quartile: return 3 + case .high: return 2 + } + } +} diff --git a/swift/Sources/QRCodeGenerator/QRCodeGenerator.swift b/swift/Sources/QRCodeGenerator/QRCodeGenerator.swift deleted file mode 100644 index b06425f..0000000 --- a/swift/Sources/QRCodeGenerator/QRCodeGenerator.swift +++ /dev/null @@ -1,3 +0,0 @@ -struct QRCodeGenerator { - var text = "Hello, World!" -} diff --git a/swift/Sources/QRCodeGenerator/QRCodeMiscellaneous.swift b/swift/Sources/QRCodeGenerator/QRCodeMiscellaneous.swift new file mode 100644 index 0000000..c5cd2ec --- /dev/null +++ b/swift/Sources/QRCodeGenerator/QRCodeMiscellaneous.swift @@ -0,0 +1,67 @@ +/* + * QR Code generator library (Swift) + * + * Copyright (c) Project Nayuki. (MIT License) + * https://www.nayuki.io/page/qr-code-generator-library + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * - The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * - The Software is provided "as is", without warranty of any kind, express or + * implied, including but not limited to the warranties of merchantability, + * fitness for a particular purpose and noninfringement. In no event shall the + * authors or copyright holders be liable for any claim, damages or other + * liability, whether in an action of contract, tort or otherwise, arising from, + * out of or in connection with the Software or the use or other dealings in the + * Software. + */ + +/// A number between 1 and 40 (inclusive). +public struct QRCodeVersion: Hashable, Comparable { + public let value: UInt8 + + public init(value: UInt8) { + assert(1 <= value && value <= 40, "Version number out of range") + self.value = value + } + + public static func <(lhs: QRCodeVersion, rhs: QRCodeVersion) -> Bool { + lhs.value < rhs.value + } +} + +/// A number between 0 and 7 (inclusive). +public struct QRCodeMask: Hashable { + public let value: UInt8 + + public init(value: UInt8) { + assert(value <= 7, "Mask value out of range") + self.value = value + } +} + +public enum QRCodeError: Error { + /// The error type when the supplied data does not fit any QR Code version. + /// + /// Ways to handle this exception include: + /// + /// - Decrease the error correction level if it was greater than `QRCodeECC.low`. + /// - If the `encodeSegmentsAdvanced()` function was called, then increase the maxversion + /// argument if it was less than `qrCodeMaxVersion`. (This advice does not apply to the + /// other factory functions because they search all versions up to `qrCodeMaxVersion`.) + /// - Split the text data into better or optimal segments in order to reduce the number of bits required. + /// - Change the text or binary data to be shorter. + /// - Change the text to fit the character set of a particular segment mode (e.g. alphanumeric). + /// - Propagate the error upward to the caller/user. + case dataTooLong(String) +} + +/// Returns true iff the i'th bit of x is set to 1. +func getBit(x: UInt32, i: UInt32) -> Bool { + (x >> i) & 1 != 0 +}