Ocean
MicroQRCode.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) Meta Platforms, Inc. and affiliates.
3  *
4  * This source code is licensed under the MIT license found in the
5  * LICENSE file in the root directory of this source tree.
6  */
7 
8 #pragma once
9 
11 
12 namespace Ocean
13 {
14 
15 namespace CV
16 {
17 
18 namespace Detector
19 {
20 
21 namespace QRCodes
22 {
23 
24 /// Forward declaration
25 class MicroQRCode;
26 
27 /// Definition of a vector of Micro QR codes
28 typedef std::vector<MicroQRCode> MicroQRCodes;
29 
30 /**
31  * Definition of a Micro QR code
32  * @ingroup cvdetectorqrcodes
33  */
34 class MicroQRCode final : public QRCodeBase
35 {
36  friend class MicroQRCodeEncoder;
37  friend class MicroQRCodeDecoder;
38 
39  public:
40 
41  /// Indicates the smallest valid version number of Micro QR codes.
42  static constexpr unsigned int MIN_VERSION = 1u;
43 
44  /// Indicates the largest valid version number of Micro QR codes.
45  static constexpr unsigned int MAX_VERSION = 4u;
46 
47  public:
48 
49  /**
50  * Creates an invalid Micro QR code instance
51  */
52  MicroQRCode() = default;
53 
54  /**
55  * Returns whether this is a valid QR code instance
56  * @return True if this is a valid QR code instance, otherwise false
57  */
58  inline bool isValid() const override;
59 
60  /**
61  * Returns the version of the Micro QR code as a string
62  * @return The version string
63  */
64  inline std::string versionString() const override;
65 
66  /**
67  * Returns the number of modules per side of the Micro QR code
68  * @return The number of modules per side
69  */
70  inline unsigned int modulesPerSide() const override;
71 
72  /**
73  * Computes the number of modules per side of a Micro QR code given its version
74  * @param version The version number for which the number of modules per side will be computed, range: [MIN_VERSION, MAX_VERSION]
75  * @return The number of modules per side
76  */
77  static inline unsigned int modulesPerSide(const unsigned int version);
78 
79  /**
80  * Unpacks a Micro QR code symbol number into the version number and error correction capacity
81  * @param symbolNumber The symbol number, range: [0, 7]
82  * @param version The version number, range: [MIN_VERSION, MAX_VERSION]
83  * @param errorCorrectionCapacity The error correction capacity, one of `ECC_DETECTION_ONLY`, `ECC_07`, `ECC_15`, or `ECC_25`
84  * @return True if the symbol number is valid and the version and error correction capacity were successfully unpacked, otherwise false
85  */
86  static inline bool unpackSymbolNumber(const unsigned int symbolNumber, unsigned int& version, ErrorCorrectionCapacity& errorCorrectionCapacity);
87 
88  protected:
89 
90  /**
91  * Creates a Micro QR code instance
92  * @param data The plain data of this QR code, must be valid
93  * @param encodingMode The encoding mode that was used to encode the data, must not be `EM_INVALID_ENCODING_MODE`
94  * @param errorCorrectionCapacity The error correction capacity that was used to generate this Micro QR code, must not be `ECC_INVALID`
95  * @param modules The modules of the Micro QR code that store the data, must be valid
96  * @param version The version of the Micro QR code, range: [MIN_VERSION, MAX_VERSION]
97  * @sa MicroQRCodeEncoder, QRCodeDecoder
98  */
99  inline explicit MicroQRCode(std::vector<uint8_t>&& data, const EncodingMode encodingMode, const ErrorCorrectionCapacity errorCorrectionCapacity, std::vector<uint8_t>&& modules, const unsigned int version);
100 };
101 
102 inline MicroQRCode::MicroQRCode(std::vector<uint8_t>&& data, const EncodingMode encodingMode, const ErrorCorrectionCapacity errorCorrectionCapacity, std::vector<uint8_t>&& modules, const unsigned int version) :
103  QRCodeBase(CT_MICRO, std::move(data), encodingMode, errorCorrectionCapacity, std::move(modules), version)
104 {
105  ocean_assert(isValid());
106 }
107 
108 inline bool MicroQRCode::isValid() const
109 {
110  if (codeType_ != CT_MICRO)
111  {
112  return false;
113  }
114 
116  {
117  return false;
118  }
119 
120  if (data_.empty() || modules_.empty())
121  {
122  return false;
123  }
124 
125  // Version and version-specific format checks
126  if (version_ == 1u && encodingMode_ != EM_NUMERIC)
127  {
128  return false;
129  }
130 
132  {
133  return false;
134  }
135 
137  {
138  return false;
139  }
140 
142  {
143  return false;
144  }
145 
146  if (errorCorrectionCapacity_ == ECC_25 && version_ != 4u)
147  {
148  return false;
149  }
150 
152  {
153  return false;
154  }
155 
156  if (version_ < MIN_VERSION || version_ > MAX_VERSION)
157  {
158  ocean_assert(false && "This should never happen!");
159  return false;
160  }
161 
162  if (modules_.size() != modulesPerSide() * modulesPerSide())
163  {
164  ocean_assert(false && "This should never happen!");
165  return false;
166  }
167 
168  return true;
169 }
170 
171 inline std::string MicroQRCode::versionString() const
172 {
173  return "M" + QRCodeBase::versionString();
174 }
175 
176 inline unsigned int MicroQRCode::modulesPerSide() const
177 {
178  return modulesPerSide(version());
179 }
180 
181 inline unsigned int MicroQRCode::modulesPerSide(const unsigned int version)
182 {
183  if (version >= MIN_VERSION && version <= MAX_VERSION)
184  {
185  return 2u * version + 9u;
186  }
187 
188  return 0u;
189 }
190 
191 inline bool MicroQRCode::unpackSymbolNumber(const unsigned int symbolNumber, unsigned int& version, MicroQRCode::ErrorCorrectionCapacity& errorCorrectionCapacity)
192 {
193  if (symbolNumber > 7u)
194  {
195  return false;
196  }
197 
198  if (symbolNumber == 0u)
199  {
200  version = 1u;
202  return true;
203  }
204 
205  if (symbolNumber == 7u)
206  {
207  version = 4u;
209  return true;
210  }
211 
212  version = (symbolNumber + 3u) / 2u;
213  errorCorrectionCapacity = (symbolNumber % 2u == 1u) ? ECC_07 : ECC_15;
214 
215  return true;
216 }
217 
218 } // namespace QRCodes
219 
220 } // namespace Detector
221 
222 } // namespace CV
223 
224 } // namespace Ocean
Definition of a QR code decoder.
Definition: MicroQRCodeDecoder.h:31
This class implements an encoder and decoder for QR codes.
Definition: MicroQRCodeEncoder.h:37
Definition of a Micro QR code.
Definition: MicroQRCode.h:35
MicroQRCode()=default
Creates an invalid Micro QR code instance.
bool isValid() const override
Returns whether this is a valid QR code instance.
Definition: MicroQRCode.h:108
std::string versionString() const override
Returns the version of the Micro QR code as a string.
Definition: MicroQRCode.h:171
static constexpr unsigned int MIN_VERSION
Indicates the smallest valid version number of Micro QR codes.
Definition: MicroQRCode.h:42
static bool unpackSymbolNumber(const unsigned int symbolNumber, unsigned int &version, ErrorCorrectionCapacity &errorCorrectionCapacity)
Unpacks a Micro QR code symbol number into the version number and error correction capacity.
Definition: MicroQRCode.h:191
unsigned int modulesPerSide() const override
Returns the number of modules per side of the Micro QR code.
Definition: MicroQRCode.h:176
static constexpr unsigned int MAX_VERSION
Indicates the largest valid version number of Micro QR codes.
Definition: MicroQRCode.h:45
Base class for QR code implementations.
Definition: QRCodeBase.h:32
CodeType codeType_
The variant of this QR code.
Definition: QRCodeBase.h:246
std::vector< uint8_t > data_
The plain data.
Definition: QRCodeBase.h:249
ErrorCorrectionCapacity errorCorrectionCapacity_
The error correction capacity that was used to generated this QR code.
Definition: QRCodeBase.h:255
const std::vector< uint8_t > & modules() const
Returns the modules of this QR code The modules are stored in a vector and will have modulesPerSide()...
Definition: QRCodeBase.h:290
std::vector< uint8_t > modules_
The modules of the QR code that store the data.
Definition: QRCodeBase.h:258
@ CT_MICRO
Indicates a Micro QR codes.
Definition: QRCodeBase.h:45
virtual std::string versionString() const
Returns the version of the QR code as a string.
Definition: QRCodeBase.h:310
unsigned int version() const
Returns the version of the QR code.
Definition: QRCodeBase.h:305
unsigned int version_
The version of the QR code.
Definition: QRCodeBase.h:261
const std::vector< uint8_t > & data() const
Returns a constant reference to the plain data of the QR code.
Definition: QRCodeBase.h:280
EncodingMode
Definition of encoding modes.
Definition: QRCodeBase.h:72
@ EM_ALPHANUMERIC
Mode that supports A-Z, 0-9 and a few others, cf. ALPHANUMERIC_CHARSET
Definition: QRCodeBase.h:76
@ EM_NUMERIC
Mode that supports digits 0-9.
Definition: QRCodeBase.h:74
@ EM_BYTE
Mode that represents data as a sequence of bytes.
Definition: QRCodeBase.h:78
@ EM_INVALID_ENCODING_MODE
Indicator for an invalid encoding mode.
Definition: QRCodeBase.h:92
ErrorCorrectionCapacity
Enumeration of the levels of error correction The value of the enums correspond to the standard-defin...
Definition: QRCodeBase.h:53
@ ECC_15
Indicates that 15% of the modules reserved error correction.
Definition: QRCodeBase.h:57
@ ECC_30
Indicates that 30% of the modules reserved error correction.
Definition: QRCodeBase.h:61
@ ECC_25
Indicates that 25% of the modules reserved error correction.
Definition: QRCodeBase.h:59
@ ECC_INVALID
Indicator for an invalid error correction capacity.
Definition: QRCodeBase.h:65
@ ECC_07
Indicates that 7% of the modules reserved error correction.
Definition: QRCodeBase.h:55
@ ECC_DETECTION_ONLY
Indicates that the capacity is limited to error detection only (used only by Micro QR Code version M1...
Definition: QRCodeBase.h:63
ErrorCorrectionCapacity errorCorrectionCapacity() const
Returns the error correction capacity of the QR code.
Definition: QRCodeBase.h:300
EncodingMode encodingMode_
The encoding mode that was used to generate this QR code.
Definition: QRCodeBase.h:252
EncodingMode encodingMode() const
Returns the encoding mode of the QR code.
Definition: QRCodeBase.h:295
std::vector< MicroQRCode > MicroQRCodes
Definition of a vector of Micro QR codes.
Definition: MicroQRCode.h:25
std::vector< QRCode > QRCodes
Definition of a vector of QR codes.
Definition: QRCode.h:25
The namespace covering the entire Ocean framework.
Definition: Accessor.h:15