Deleted 3 unused C private functions, deleted 1 associated test case.
This commit is contained in:
parent
562f478d26
commit
9e9eaf488e
|
@ -51,7 +51,6 @@ static int numTestCases = 0;
|
|||
// Prototypes of private functions under test
|
||||
extern const int8_t ECC_CODEWORDS_PER_BLOCK[4][41];
|
||||
extern const int8_t NUM_ERROR_CORRECTION_BLOCKS[4][41];
|
||||
int getTextProperties(const char *text, bool *isNumeric, bool *isAlphanumeric, int *textBits);
|
||||
void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen);
|
||||
void appendErrorCorrection(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]);
|
||||
int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl);
|
||||
|
@ -69,64 +68,6 @@ int calcSegmentBitLength(enum qrcodegen_Mode mode, size_t numChars);
|
|||
|
||||
/*---- Test cases ----*/
|
||||
|
||||
static void testGetTextProperties(void) {
|
||||
bool isNumeric, isAlphanumeric;
|
||||
int textLen, textBits;
|
||||
|
||||
textLen = getTextProperties("", &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen == 0 && isNumeric && isAlphanumeric && textBits == 0);
|
||||
numTestCases++;
|
||||
|
||||
textLen = getTextProperties("0", &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen == 1 && isNumeric && isAlphanumeric && textBits == 4);
|
||||
numTestCases++;
|
||||
|
||||
textLen = getTextProperties("768", &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen == 3 && isNumeric && isAlphanumeric && textBits == 10);
|
||||
numTestCases++;
|
||||
|
||||
textLen = getTextProperties("A1", &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen == 2 && !isNumeric && isAlphanumeric && textBits == 11);
|
||||
numTestCases++;
|
||||
|
||||
textLen = getTextProperties("THE: QUICK+/*BROWN$FOX.", &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen == 23 && !isNumeric && isAlphanumeric && textBits == 127);
|
||||
numTestCases++;
|
||||
|
||||
textLen = getTextProperties("aB 9", &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen == 4 && !isNumeric && !isAlphanumeric && textBits == 32);
|
||||
numTestCases++;
|
||||
|
||||
char text[32769];
|
||||
|
||||
memset(text, '5', sizeof(text));
|
||||
text[32768] = '\0';
|
||||
textLen = getTextProperties(text, &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen < 0);
|
||||
numTestCases++;
|
||||
|
||||
memset(text, '1', sizeof(text));
|
||||
text[32767] = '\0';
|
||||
textLen = getTextProperties(text, &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert((109224L > INT_MAX && textLen < 0) ||
|
||||
(109224L <= INT_MAX && textLen == 32767 && isNumeric && isAlphanumeric && textBits == 109224L));
|
||||
numTestCases++;
|
||||
|
||||
memset(text, 'a', sizeof(text));
|
||||
text[4095] = '\0';
|
||||
textLen = getTextProperties(text, &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert(textLen == 4095 && !isNumeric && !isAlphanumeric && textBits == 32760);
|
||||
numTestCases++;
|
||||
|
||||
memset(text, 'a', sizeof(text));
|
||||
text[32767] = '\0';
|
||||
textLen = getTextProperties(text, &isNumeric, &isAlphanumeric, &textBits);
|
||||
assert((262136L > INT_MAX && textLen < 0) ||
|
||||
(262136L <= INT_MAX && textLen == 32767 && !isNumeric && !isAlphanumeric && textBits == 262136L));
|
||||
numTestCases++;
|
||||
}
|
||||
|
||||
|
||||
static void testAppendBitsToBuffer(void) {
|
||||
{
|
||||
uint8_t buf[1] = {0};
|
||||
|
@ -1033,7 +974,6 @@ static void testMakeEci(void) {
|
|||
|
||||
int main(void) {
|
||||
srand(time(NULL));
|
||||
testGetTextProperties();
|
||||
testAppendBitsToBuffer();
|
||||
testAppendErrorCorrection();
|
||||
testGetNumDataCodewords();
|
||||
|
|
119
c/qrcodegen.c
119
c/qrcodegen.c
|
@ -58,11 +58,6 @@
|
|||
// - They are completely thread-safe if the caller does not give the
|
||||
// same writable buffer to concurrent calls to these functions.
|
||||
|
||||
testable int getTextProperties(const char *text, bool *isNumeric, bool *isAlphanumeric, int *textBits);
|
||||
static int fitVersionToData(int minVersion, int maxVersion, enum qrcodegen_Ecc ecl,
|
||||
int dataLen, int dataBitLen, int ver1To9LenBits, int ver10To26LenBits, int ver27To40LenBits);
|
||||
static void encodeQrCodeTail(uint8_t dataAndQrcode[], int bitLen, uint8_t tempBuffer[],
|
||||
int version, enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, bool boostEcl);
|
||||
testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen);
|
||||
|
||||
testable void appendErrorCorrection(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]);
|
||||
|
@ -184,120 +179,6 @@ bool qrcodegen_encodeBinary(uint8_t dataAndTemp[], size_t dataLen, uint8_t qrcod
|
|||
}
|
||||
|
||||
|
||||
// Scans the given string, returns the number of characters, and sets output variables.
|
||||
// Returns a negative number if the length would exceed INT16_MAX or textBits would exceed INT_MAX.
|
||||
// Note that INT16_MAX <= 32767 <= INT_MAX and INT16_MAX < 65535 <= SIZE_MAX.
|
||||
// If the return value is negative, then the pointees of output arguments might not be set.
|
||||
testable int getTextProperties(const char *text, bool *isNumeric, bool *isAlphanumeric, int *textBits) {
|
||||
int textLen = 0;
|
||||
*isNumeric = true;
|
||||
*isAlphanumeric = true;
|
||||
for (const char *p = text; *p != '\0'; p++, textLen++) { // Read every character
|
||||
if (textLen >= INT16_MAX)
|
||||
return -1;
|
||||
char c = *p;
|
||||
if (c < '0' || c > '9') {
|
||||
*isNumeric = false;
|
||||
*isAlphanumeric &= strchr(ALPHANUMERIC_CHARSET, c) != NULL;
|
||||
}
|
||||
}
|
||||
|
||||
long tempBits;
|
||||
if (*isNumeric)
|
||||
tempBits = textLen * 3L + (textLen + 2L) / 3;
|
||||
else if (*isAlphanumeric)
|
||||
tempBits = textLen * 5L + (textLen + 1L) / 2;
|
||||
else // Binary mode
|
||||
tempBits = textLen * 8L;
|
||||
|
||||
if (tempBits > INT_MAX)
|
||||
return -1;
|
||||
*textBits = (int)tempBits;
|
||||
return textLen;
|
||||
}
|
||||
|
||||
|
||||
// Returns the minimum possible version in the given range to fit one
|
||||
// segment with the given characteristics, or 0 if no version fits the data.
|
||||
static int fitVersionToData(int minVersion, int maxVersion, enum qrcodegen_Ecc ecl,
|
||||
int dataLen, int dataBitLen, int ver1To9LenBits, int ver10To26LenBits, int ver27To40LenBits) {
|
||||
|
||||
assert(qrcodegen_VERSION_MIN <= minVersion && minVersion <= maxVersion && maxVersion <= qrcodegen_VERSION_MAX);
|
||||
assert(0 <= (int)ecl && (int)ecl <= 3);
|
||||
assert(dataLen >= 0 && dataBitLen >= 0);
|
||||
assert(1 <= ver1To9LenBits && ver1To9LenBits <= 16);
|
||||
assert(1 <= ver10To26LenBits && ver10To26LenBits <= 16);
|
||||
assert(1 <= ver27To40LenBits && ver27To40LenBits <= 16);
|
||||
|
||||
for (int version = minVersion; ; version++) {
|
||||
int lengthBits;
|
||||
if (version <= 9) lengthBits = ver1To9LenBits;
|
||||
else if (version <= 26) lengthBits = ver10To26LenBits;
|
||||
else lengthBits = ver27To40LenBits;
|
||||
if (dataLen < (1L << lengthBits)) {
|
||||
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8; // Number of data bits available
|
||||
int header = 4 + lengthBits;
|
||||
if (dataBitLen <= INT_MAX - header && header + dataBitLen <= dataCapacityBits)
|
||||
return version; // This version number is found to be suitable
|
||||
}
|
||||
if (version >= maxVersion) // All versions in the range could not fit the given data
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Given a data bit sequence in dataAndQrcode without terminator or padding or ECC, plus the given QR Code
|
||||
// encoding parameters, this function handles ECC level boosting, bit stream termination and padding,
|
||||
// ECC computation, and block interleaving. Then the function renders the QR Code symbol back to the array
|
||||
// dataAndQrcode and handles automatic mask selection. The initial bit length must fit the given version and
|
||||
// ECC level, and each of the two arrays must have length at least qrcodegen_BUFFER_LEN_FOR_VERSION(version).
|
||||
static void encodeQrCodeTail(uint8_t dataAndQrcode[], int bitLen, uint8_t tempBuffer[],
|
||||
int version, enum qrcodegen_Ecc ecl, enum qrcodegen_Mask mask, bool boostEcl) {
|
||||
|
||||
if (boostEcl) {
|
||||
if (bitLen <= getNumDataCodewords(version, qrcodegen_Ecc_MEDIUM ) * 8) ecl = qrcodegen_Ecc_MEDIUM ;
|
||||
if (bitLen <= getNumDataCodewords(version, qrcodegen_Ecc_QUARTILE) * 8) ecl = qrcodegen_Ecc_QUARTILE;
|
||||
if (bitLen <= getNumDataCodewords(version, qrcodegen_Ecc_HIGH ) * 8) ecl = qrcodegen_Ecc_HIGH ;
|
||||
}
|
||||
int dataCapacityBits = getNumDataCodewords(version, ecl) * 8;
|
||||
|
||||
// Add terminator, bit padding, byte padding
|
||||
int terminatorBits = dataCapacityBits - bitLen;
|
||||
if (terminatorBits > 4)
|
||||
terminatorBits = 4;
|
||||
appendBitsToBuffer(0, terminatorBits, dataAndQrcode, &bitLen);
|
||||
appendBitsToBuffer(0, (8 - bitLen % 8) % 8, dataAndQrcode, &bitLen);
|
||||
for (uint8_t padByte = 0xEC; bitLen < dataCapacityBits; padByte ^= 0xEC ^ 0x11)
|
||||
appendBitsToBuffer(padByte, 8, dataAndQrcode, &bitLen);
|
||||
assert(bitLen % 8 == 0);
|
||||
|
||||
// Draw function and data codeword modules
|
||||
appendErrorCorrection(dataAndQrcode, version, ecl, tempBuffer);
|
||||
initializeFunctionModules(version, dataAndQrcode);
|
||||
drawCodewords(tempBuffer, getNumRawDataModules(version) / 8, dataAndQrcode);
|
||||
drawWhiteFunctionModules(dataAndQrcode, version);
|
||||
initializeFunctionModules(version, tempBuffer);
|
||||
|
||||
// Handle masking
|
||||
if (mask == qrcodegen_Mask_AUTO) { // Automatically choose best mask
|
||||
long minPenalty = LONG_MAX;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
drawFormatBits(ecl, (enum qrcodegen_Mask)i, dataAndQrcode);
|
||||
applyMask(tempBuffer, dataAndQrcode, (enum qrcodegen_Mask)i);
|
||||
long penalty = getPenaltyScore(dataAndQrcode);
|
||||
if (penalty < minPenalty) {
|
||||
mask = (enum qrcodegen_Mask)i;
|
||||
minPenalty = penalty;
|
||||
}
|
||||
applyMask(tempBuffer, dataAndQrcode, (enum qrcodegen_Mask)i); // Undoes the mask due to XOR
|
||||
}
|
||||
}
|
||||
assert(0 <= (int)mask && (int)mask <= 7);
|
||||
drawFormatBits(ecl, mask, dataAndQrcode);
|
||||
applyMask(tempBuffer, dataAndQrcode, mask);
|
||||
}
|
||||
|
||||
|
||||
// Appends the given sequence of bits to the given byte-based bit buffer, increasing the bit length.
|
||||
testable void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bitLen) {
|
||||
assert(0 <= numBits && numBits <= 16 && (unsigned long)val >> numBits == 0);
|
||||
|
|
Loading…
Reference in New Issue