diff --git a/c/qrcodegen.c b/c/qrcodegen.c index cd4108c..0b7a357 100644 --- a/c/qrcodegen.c +++ b/c/qrcodegen.c @@ -32,24 +32,24 @@ /*---- Forward declarations for private functions ----*/ static void encodeQrCodeTail(uint8_t dataAndQrcode[], uint8_t tempBuffer[], int version, enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask); -static long getPenaltyScore(const uint8_t qrcode[], int size); +static long getPenaltyScore(const uint8_t qrcode[], int qrsize); static void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen); static int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl); -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 bool getModule(const uint8_t qrcode[], int qrsize, int x, int y); +static void setModule(uint8_t qrcode[], int qrsize, int x, int y, bool isBlack); +static void setModuleBounded(uint8_t qrcode[], int qrsize, int x, int y, bool isBlack); static void initializeFunctionModules(int version, uint8_t qrcode[]); static void drawWhiteFunctionModules(uint8_t qrcode[], int version); -static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[], int size); +static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[], int qrsize); static int getAlignmentPatternPositions(int version, uint8_t result[7]); -static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[], int size); +static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[], int qrsize); static void appendErrorCorrection(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]); static int getNumRawDataModules(int version); -static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], int size); -static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], int size, int mask); +static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], int qrsize); +static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], int qrsize, int mask); 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[]); @@ -287,15 +287,15 @@ static void encodeQrCodeTail(uint8_t dataAndQrcode[], uint8_t tempBuffer[], int // Calculates and returns the penalty score based on state of the given QR Code's current modules. // This is used by the automatic mask choice algorithm to find the mask pattern that yields the lowest score. -static long getPenaltyScore(const uint8_t qrcode[], int size) { +static long getPenaltyScore(const uint8_t qrcode[], int qrsize) { long result = 0; // Adjacent modules in row having same color - for (int y = 0; y < size; y++) { - bool colorX = getModule(qrcode, size, 0, y); - for (int x = 1, runX = 1; x < size; x++) { - if (getModule(qrcode, size, x, y) != colorX) { - colorX = getModule(qrcode, size, x, y); + for (int y = 0; y < qrsize; y++) { + bool colorX = getModule(qrcode, qrsize, 0, y); + for (int x = 1, runX = 1; x < qrsize; x++) { + if (getModule(qrcode, qrsize, x, y) != colorX) { + colorX = getModule(qrcode, qrsize, x, y); runX = 1; } else { runX++; @@ -307,11 +307,11 @@ static long getPenaltyScore(const uint8_t qrcode[], int size) { } } // Adjacent modules in column having same color - for (int x = 0; x < size; x++) { - bool colorY = getModule(qrcode, size, x, 0); - for (int y = 1, runY = 1; y < size; y++) { - if (getModule(qrcode, size, x, y) != colorY) { - colorY = getModule(qrcode, size, x, y); + for (int x = 0; x < qrsize; x++) { + bool colorY = getModule(qrcode, qrsize, x, 0); + for (int y = 1, runY = 1; y < qrsize; y++) { + if (getModule(qrcode, qrsize, x, y) != colorY) { + colorY = getModule(qrcode, qrsize, x, y); runY = 1; } else { runY++; @@ -324,28 +324,28 @@ static long getPenaltyScore(const uint8_t qrcode[], int size) { } // 2*2 blocks of modules having same color - for (int y = 0; y < size - 1; y++) { - for (int x = 0; x < size - 1; x++) { - bool color = getModule(qrcode, size, x, y); - if ( color == getModule(qrcode, size, x + 1, y) && - color == getModule(qrcode, size, x, y + 1) && - color == getModule(qrcode, size, x + 1, y + 1)) + for (int y = 0; y < qrsize - 1; y++) { + for (int x = 0; x < qrsize - 1; x++) { + bool color = getModule(qrcode, qrsize, x, y); + if ( color == getModule(qrcode, qrsize, x + 1, y) && + color == getModule(qrcode, qrsize, x, y + 1) && + color == getModule(qrcode, qrsize, x + 1, y + 1)) result += PENALTY_N2; } } // Finder-like pattern in rows - for (int y = 0; y < size; y++) { - for (int x = 0, bits = 0; x < size; x++) { - bits = ((bits << 1) & 0x7FF) | (getModule(qrcode, size, x, y) ? 1 : 0); + for (int y = 0; y < qrsize; y++) { + for (int x = 0, bits = 0; x < qrsize; x++) { + bits = ((bits << 1) & 0x7FF) | (getModule(qrcode, qrsize, x, y) ? 1 : 0); if (x >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated result += PENALTY_N3; } } // Finder-like pattern in columns - for (int x = 0; x < size; x++) { - for (int y = 0, bits = 0; y < size; y++) { - bits = ((bits << 1) & 0x7FF) | (getModule(qrcode, size, x, y) ? 1 : 0); + for (int x = 0; x < qrsize; x++) { + for (int y = 0, bits = 0; y < qrsize; y++) { + bits = ((bits << 1) & 0x7FF) | (getModule(qrcode, qrsize, x, y) ? 1 : 0); if (y >= 10 && (bits == 0x05D || bits == 0x5D0)) // Needs 11 bits accumulated result += PENALTY_N3; } @@ -353,13 +353,13 @@ static long getPenaltyScore(const uint8_t qrcode[], int size) { // Balance of black and white modules int black = 0; - for (int y = 0; y < size; y++) { - for (int x = 0; x < size; x++) { - if (getModule(qrcode, size, x, y)) + for (int y = 0; y < qrsize; y++) { + for (int x = 0; x < qrsize; x++) { + if (getModule(qrcode, qrsize, x, y)) black++; } } - int total = size * size; + int total = qrsize * qrsize; // Find smallest k such that (45-5k)% <= dark/total <= (55+5k)% for (int k = 0; black*20L < (9L-k)*total || black*20L > (11L+k)*total; k++) result += PENALTY_N4; @@ -395,15 +395,15 @@ int qrcodegen_getSize(int version) { // 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); + int qrsize = qrcodegen_getSize(version); + return (0 <= x && x < qrsize && 0 <= y && y < qrsize) && getModule(qrcode, qrsize, 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; +static bool getModule(const uint8_t qrcode[], int qrsize, int x, int y) { + assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize); + int index = y * qrsize + x; int bitIndex = index & 7; int byteIndex = index >> 3; return ((qrcode[byteIndex] >> bitIndex) & 1) != 0; @@ -411,9 +411,9 @@ static bool getModule(const uint8_t qrcode[], int size, int x, int y) { // 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; +static void setModule(uint8_t qrcode[], int qrsize, int x, int y, bool isBlack) { + assert(21 <= qrsize && qrsize <= 177 && 0 <= x && x < qrsize && 0 <= y && y < qrsize); + int index = y * qrsize + x; int bitIndex = index & 7; int byteIndex = index >> 3; if (isBlack) @@ -424,9 +424,9 @@ static void setModule(uint8_t qrcode[], int size, int x, int y, bool isBlack) { // 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); +static void setModuleBounded(uint8_t qrcode[], int qrsize, int x, int y, bool isBlack) { + if (0 <= x && x < qrsize && 0 <= y && y < qrsize) + setModule(qrcode, qrsize, x, y, isBlack); } @@ -437,17 +437,17 @@ static void setModuleBounded(uint8_t qrcode[], int size, int x, int y, bool isBl // then marks every function module in the QR Code as black. static void initializeFunctionModules(int version, uint8_t qrcode[]) { // Initialize QR Code - int size = qrcodegen_getSize(version); - memset(qrcode, 0, (size * size + 7) / 8 * sizeof(qrcode[0])); + int qrsize = qrcodegen_getSize(version); + memset(qrcode, 0, (qrsize * qrsize + 7) / 8 * sizeof(qrcode[0])); // Fill horizontal and vertical timing patterns - fillRectangle(6, 0, 1, size, qrcode, size); - fillRectangle(0, 6, size, 1, qrcode, size); + fillRectangle(6, 0, 1, qrsize, qrcode, qrsize); + fillRectangle(0, 6, qrsize, 1, qrcode, qrsize); // Fill 3 finder patterns (all corners except bottom right) and format bits - fillRectangle(0, 0, 9, 9, qrcode, size); - fillRectangle(size - 8, 0, 8, 9, qrcode, size); - fillRectangle(0, size - 8, 9, 8, qrcode, size); + fillRectangle(0, 0, 9, 9, qrcode, qrsize); + fillRectangle(qrsize - 8, 0, 8, 9, qrcode, qrsize); + fillRectangle(0, qrsize - 8, 9, 8, qrcode, qrsize); // Fill numerous alignment patterns uint8_t alignPatPos[7] = {0}; @@ -457,14 +457,14 @@ static void initializeFunctionModules(int version, uint8_t qrcode[]) { if ((i == 0 && j == 0) || (i == 0 && j == numAlign - 1) || (i == numAlign - 1 && j == 0)) continue; // Skip the three finder corners else - fillRectangle(alignPatPos[i] - 2, alignPatPos[j] - 2, 5, 5, qrcode, size); + fillRectangle(alignPatPos[i] - 2, alignPatPos[j] - 2, 5, 5, qrcode, qrsize); } } // Fill version if (version >= 7) { - fillRectangle(size - 11, 0, 3, 6, qrcode, size); - fillRectangle(0, size - 11, 6, 3, qrcode, size); + fillRectangle(qrsize - 11, 0, 3, 6, qrcode, qrsize); + fillRectangle(0, qrsize - 11, 6, 3, qrcode, qrsize); } } @@ -474,10 +474,10 @@ static void initializeFunctionModules(int version, uint8_t qrcode[]) { // marked black (namely by initializeFunctionModules()), because this may skip redrawing black function modules. static void drawWhiteFunctionModules(uint8_t qrcode[], int version) { // Draw horizontal and vertical timing patterns - int size = qrcodegen_getSize(version); - for (int i = 7; i < size - 7; i += 2) { - setModule(qrcode, size, 6, i, false); - setModule(qrcode, size, i, 6, false); + int qrsize = qrcodegen_getSize(version); + for (int i = 7; i < qrsize - 7; i += 2) { + setModule(qrcode, qrsize, 6, i, false); + setModule(qrcode, qrsize, i, 6, false); } // Draw 3 finder patterns @@ -487,9 +487,9 @@ static void drawWhiteFunctionModules(uint8_t qrcode[], int version) { if (abs(j) > dist) dist = abs(j); if (dist == 2 || dist == 4) { - setModuleBounded(qrcode, size, 3 + j, 3 + i, false); - setModuleBounded(qrcode, size, size - 4 + j, 3 + i, false); - setModuleBounded(qrcode, size, 3 + j, size - 4 + i, false); + setModuleBounded(qrcode, qrsize, 3 + j, 3 + i, false); + setModuleBounded(qrcode, qrsize, qrsize - 4 + j, 3 + i, false); + setModuleBounded(qrcode, qrsize, 3 + j, qrsize - 4 + i, false); } } } @@ -504,7 +504,7 @@ static void drawWhiteFunctionModules(uint8_t qrcode[], int version) { else { for (int k = -1; k <= 1; k++) { for (int l = -1; l <= 1; l++) - setModule(qrcode, size, alignPatPos[i] + l, alignPatPos[j] + k, k == 0 && l == 0); + setModule(qrcode, qrsize, alignPatPos[i] + l, alignPatPos[j] + k, k == 0 && l == 0); } } } @@ -522,9 +522,9 @@ static void drawWhiteFunctionModules(uint8_t qrcode[], int version) { // Draw two copies for (int i = 0; i < 6; i++) { for (int j = 0; j < 3; j++) { - int k = size - 11 + j; - setModule(qrcode, size, k, i, (data & 1) != 0); - setModule(qrcode, size, i, k, (data & 1) != 0); + int k = qrsize - 11 + j; + setModule(qrcode, qrsize, k, i, (data & 1) != 0); + setModule(qrcode, qrsize, i, k, (data & 1) != 0); data >>= 1; } } @@ -534,7 +534,7 @@ static void drawWhiteFunctionModules(uint8_t qrcode[], int version) { // Based on the given ECC level and mask, this calculates the format bits // and draws their black and white modules onto the given QR Code. -static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[], int size) { +static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uint8_t qrcode[], int qrsize) { // Calculate error correction code and pack bits assert(0 <= (int)mask && (int)mask <= 7); int data; @@ -555,19 +555,19 @@ static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uin // Draw first copy for (int i = 0; i <= 5; i++) - setModule(qrcode, size, 8, i, ((data >> i) & 1) != 0); - setModule(qrcode, size, 8, 7, ((data >> 6) & 1) != 0); - setModule(qrcode, size, 8, 8, ((data >> 7) & 1) != 0); - setModule(qrcode, size, 7, 8, ((data >> 8) & 1) != 0); + setModule(qrcode, qrsize, 8, i, ((data >> i) & 1) != 0); + setModule(qrcode, qrsize, 8, 7, ((data >> 6) & 1) != 0); + setModule(qrcode, qrsize, 8, 8, ((data >> 7) & 1) != 0); + setModule(qrcode, qrsize, 7, 8, ((data >> 8) & 1) != 0); for (int i = 9; i < 15; i++) - setModule(qrcode, size, 14 - i, 8, ((data >> i) & 1) != 0); + setModule(qrcode, qrsize, 14 - i, 8, ((data >> i) & 1) != 0); // Draw second copy for (int i = 0; i <= 7; i++) - setModule(qrcode, size, size - 1 - i, 8, ((data >> i) & 1) != 0); + setModule(qrcode, qrsize, qrsize - 1 - i, 8, ((data >> i) & 1) != 0); for (int i = 8; i < 15; i++) - setModule(qrcode, size, 8, size - 15 + i, ((data >> i) & 1) != 0); - setModule(qrcode, size, 8, size - 8, true); + setModule(qrcode, qrsize, 8, qrsize - 15 + i, ((data >> i) & 1) != 0); + setModule(qrcode, qrsize, 8, qrsize - 8, true); } @@ -576,14 +576,14 @@ static void drawFormatBits(enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, uin static int getAlignmentPatternPositions(int version, uint8_t result[7]) { if (version == 1) return 0; - int size = qrcodegen_getSize(version); + int qrsize = qrcodegen_getSize(version); int numAlign = version / 7 + 2; int step; if (version != 32) - step = (version * 4 + numAlign * 2 + 1) / (2 * numAlign - 2) * 2; // ceil((size - 13) / (2*numAlign - 2)) * 2 + step = (version * 4 + numAlign * 2 + 1) / (2 * numAlign - 2) * 2; // ceil((qrsize - 13) / (2*numAlign - 2)) * 2 else // C-C-C-Combo breaker! step = 26; - for (int i = numAlign - 1, pos = size - 7; i >= 1; i--, pos -= step) + for (int i = numAlign - 1, pos = qrsize - 7; i >= 1; i--, pos -= step) result[i] = pos; result[0] = 6; return numAlign; @@ -591,10 +591,10 @@ static int getAlignmentPatternPositions(int version, uint8_t result[7]) { // Sets every pixel in the range [left : left + width] * [top : top + height] to black. -static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[], int size) { +static void fillRectangle(int left, int top, int width, int height, uint8_t qrcode[], int qrsize) { for (int dy = 0; dy < height; dy++) { for (int dx = 0; dx < width; dx++) - setModule(qrcode, size, left + dx, top + dy, true); + setModule(qrcode, qrsize, left + dx, top + dy, true); } } @@ -659,20 +659,20 @@ static int getNumRawDataModules(int version) { // Draws the raw codewords (including data and ECC) onto the given QR Code. This requires the initial state of // the QR Code to be black at function modules and white at codeword modules (including unused remainder bits). -static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], int size) { +static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], int qrsize) { int i = 0; // Bit index into the data // Do the funny zigzag scan - for (int right = size - 1; right >= 1; right -= 2) { // Index of right column in each column pair + for (int right = qrsize - 1; right >= 1; right -= 2) { // Index of right column in each column pair if (right == 6) right = 5; - for (int vert = 0; vert < size; vert++) { // Vertical counter + for (int vert = 0; vert < qrsize; vert++) { // Vertical counter for (int j = 0; j < 2; j++) { int x = right - j; // Actual x coordinate bool upward = ((right + 1) & 2) == 0; - int y = upward ? size - 1 - vert : vert; // Actual y coordinate - if (!getModule(qrcode, size, x, y) && i < dataLen * 8) { + int y = upward ? qrsize - 1 - vert : vert; // Actual y coordinate + if (!getModule(qrcode, qrsize, x, y) && i < dataLen * 8) { bool black = ((data[i >> 3] >> (7 - (i & 7))) & 1) != 0; - setModule(qrcode, size, x, y, black); + setModule(qrcode, qrsize, x, y, black); i++; } // If there are any remainder bits (0 to 7), they are already @@ -691,11 +691,11 @@ static void drawCodewords(const uint8_t data[], int dataLen, uint8_t qrcode[], i // properties, calling applyMask(..., m) twice with the same value is equivalent to no change at all. // This means it is possible to apply a mask, undo it, and try another mask. Note that a final // well-formed QR Code symbol needs exactly one mask applied (not zero, not two, etc.). -static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], int size, int mask) { +static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], int qrsize, int mask) { assert(0 <= mask && mask <= 7); - for (int y = 0; y < size; y++) { - for (int x = 0; x < size; x++) { - if (getModule(functionModules, size, x, y)) + for (int y = 0; y < qrsize; y++) { + for (int x = 0; x < qrsize; x++) { + if (getModule(functionModules, qrsize, x, y)) continue; bool invert; switch (mask) { @@ -709,8 +709,8 @@ static void applyMask(const uint8_t functionModules[], uint8_t qrcode[], int siz case 7: invert = ((x + y) % 2 + x * y % 3) % 2 == 0; break; default: assert(false); } - bool val = getModule(qrcode, size, x, y); - setModule(qrcode, size, x, y, val ^ invert); + bool val = getModule(qrcode, qrsize, x, y); + setModule(qrcode, qrsize, x, y, val ^ invert); } } }