Continued implementing C library by adding low-level QR Code get/set functions.

This commit is contained in:
Project Nayuki 2017-04-17 18:02:14 +00:00
parent 18a10b6b99
commit f18ababe0d
2 changed files with 64 additions and 0 deletions

View File

@ -30,6 +30,10 @@
/*---- Forward declarations for private functions ----*/ /*---- Forward declarations for private functions ----*/
static bool getModule(const uint8_t qrcode[], int size, int x, int y);
static void setModule(uint8_t qrcode[], int size, int x, int y, bool isBlack);
static void setModuleBounded(uint8_t qrcode[], int size, int x, int y, bool isBlack);
static void calcReedSolomonGenerator(int degree, uint8_t result[]); static void calcReedSolomonGenerator(int degree, uint8_t result[]);
static void calcReedSolomonRemainder(const uint8_t data[], int dataLen, const uint8_t generator[], int degree, uint8_t result[]); static void calcReedSolomonRemainder(const uint8_t data[], int dataLen, const uint8_t generator[], int degree, uint8_t result[]);
static uint8_t finiteFieldMultiply(uint8_t x, uint8_t y); static uint8_t finiteFieldMultiply(uint8_t x, uint8_t y);
@ -73,6 +77,50 @@ bool qrcodegen_isNumeric(const char *text) {
} }
// Public function - see documentation comment in header file.
int qrcodegen_getSize(int version) {
assert(1 <= version && version <= 40);
return version * 4 + 17;
}
// Public function - see documentation comment in header file.
bool qrcodegen_getModule(const uint8_t qrcode[], int version, int x, int y) {
int size = qrcodegen_getSize(version);
return (0 <= x && x < size && 0 <= y && y < size) && getModule(qrcode, size, x, y);
}
// Gets the module at the given coordinates, which must be in bounds.
static bool getModule(const uint8_t qrcode[], int size, int x, int y) {
assert(21 <= size && size <= 177 && 0 <= x && x < size && 0 <= y && y < size);
int index = y * size + x;
int bitIndex = index & 7;
int byteIndex = index >> 3;
return ((qrcode[byteIndex] >> bitIndex) & 1) != 0;
}
// Sets the module at the given coordinates, which must be in bounds.
static void setModule(uint8_t qrcode[], int size, int x, int y, bool isBlack) {
assert(21 <= size && size <= 177 && 0 <= x && x < size && 0 <= y && y < size);
int index = y * size + x;
int bitIndex = index & 7;
int byteIndex = index >> 3;
if (isBlack)
qrcode[byteIndex] |= 1 << bitIndex;
else
qrcode[byteIndex] &= (1 << bitIndex) ^ 0xFF;
}
// Sets the module at the given coordinates, doing nothing if out of bounds.
static void setModuleBounded(uint8_t qrcode[], int size, int x, int y, bool isBlack) {
if (0 <= x && x < size && 0 <= y && y < size)
setModule(qrcode, size, x, y, isBlack);
}
// Calculates the Reed-Solomon generator polynomial of the given degree, storing in result[0 : degree]. // Calculates the Reed-Solomon generator polynomial of the given degree, storing in result[0 : degree].
static void calcReedSolomonGenerator(int degree, uint8_t result[]) { static void calcReedSolomonGenerator(int degree, uint8_t result[]) {
// Start with the monomial x^0 // Start with the monomial x^0

View File

@ -37,3 +37,19 @@ bool qrcodegen_isAlphanumeric(const char *text);
* Tests whether the given string can be encoded in numeric mode. * Tests whether the given string can be encoded in numeric mode.
*/ */
bool qrcodegen_isNumeric(const char *text); bool qrcodegen_isNumeric(const char *text);
/*
* Returns the side length of any QR Code of the given version.
* The version must be in the range [1, 40]. The result is in the range [21, 177].
* Note that the length of any QR Code byte buffer must be at least ceil(size^2 / 8).
*/
int qrcodegen_getSize(int version);
/*
* Returns the color of the module (pixel) at the given coordinates, which is either
* true for white or false for black. The top left corner has the coordinates (x=0, y=0).
* If the given coordinates are out of bounds, then false (white) is returned.
*/
bool qrcodegen_getModule(const uint8_t qrcode[], int version, int x, int y);