mirror of
https://github.com/openharmony/third_party_qrcodegen.git
synced 2026-07-01 23:34:05 -04:00
Renamed functions and variables, and updated comments, thus synchronizing the C language version with the previous changeset.
This commit is contained in:
+24
-24
@@ -49,9 +49,9 @@ void appendBitsToBuffer(unsigned int val, int numBits, uint8_t buffer[], int *bi
|
||||
void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ecc ecl, uint8_t result[]);
|
||||
int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl);
|
||||
int getNumRawDataModules(int version);
|
||||
void calcReedSolomonGenerator(int degree, uint8_t result[]);
|
||||
void calcReedSolomonRemainder(const uint8_t data[], int dataLen, const uint8_t generator[], int degree, uint8_t result[]);
|
||||
uint8_t finiteFieldMultiply(uint8_t x, uint8_t y);
|
||||
void reedSolomonComputeDivisor(int degree, uint8_t result[]);
|
||||
void reedSolomonComputeRemainder(const uint8_t data[], int dataLen, const uint8_t generator[], int degree, uint8_t result[]);
|
||||
uint8_t reedSolomonMultiply(uint8_t x, uint8_t y);
|
||||
void initializeFunctionModules(int version, uint8_t qrcode[]);
|
||||
int getAlignmentPatternPositions(int version, uint8_t result[7]);
|
||||
bool getModule(const uint8_t qrcode[], int x, int y);
|
||||
@@ -116,12 +116,12 @@ static uint8_t *addEccAndInterleaveReference(const uint8_t *data, int version, e
|
||||
// Split data into blocks and append ECC to each block
|
||||
uint8_t **blocks = malloc(numBlocks * sizeof(uint8_t*));
|
||||
uint8_t *generator = malloc(blockEccLen * sizeof(uint8_t));
|
||||
calcReedSolomonGenerator(blockEccLen, generator);
|
||||
reedSolomonComputeDivisor(blockEccLen, generator);
|
||||
for (int i = 0, k = 0; i < numBlocks; i++) {
|
||||
uint8_t *block = malloc((shortBlockLen + 1) * sizeof(uint8_t));
|
||||
int datLen = shortBlockLen - blockEccLen + (i < numShortBlocks ? 0 : 1);
|
||||
memcpy(block, &data[k], datLen * sizeof(uint8_t));
|
||||
calcReedSolomonRemainder(&data[k], datLen, generator, blockEccLen, &block[shortBlockLen + 1 - blockEccLen]);
|
||||
reedSolomonComputeRemainder(&data[k], datLen, generator, blockEccLen, &block[shortBlockLen + 1 - blockEccLen]);
|
||||
k += datLen;
|
||||
blocks[i] = block;
|
||||
}
|
||||
@@ -235,19 +235,19 @@ static void testGetNumRawDataModules(void) {
|
||||
}
|
||||
|
||||
|
||||
static void testCalcReedSolomonGenerator(void) {
|
||||
static void testReedSolomonComputeDivisor(void) {
|
||||
uint8_t generator[30];
|
||||
|
||||
calcReedSolomonGenerator(1, generator);
|
||||
reedSolomonComputeDivisor(1, generator);
|
||||
assert(generator[0] == 0x01);
|
||||
numTestCases++;
|
||||
|
||||
calcReedSolomonGenerator(2, generator);
|
||||
reedSolomonComputeDivisor(2, generator);
|
||||
assert(generator[0] == 0x03);
|
||||
assert(generator[1] == 0x02);
|
||||
numTestCases++;
|
||||
|
||||
calcReedSolomonGenerator(5, generator);
|
||||
reedSolomonComputeDivisor(5, generator);
|
||||
assert(generator[0] == 0x1F);
|
||||
assert(generator[1] == 0xC6);
|
||||
assert(generator[2] == 0x3F);
|
||||
@@ -255,7 +255,7 @@ static void testCalcReedSolomonGenerator(void) {
|
||||
assert(generator[4] == 0x74);
|
||||
numTestCases++;
|
||||
|
||||
calcReedSolomonGenerator(30, generator);
|
||||
reedSolomonComputeDivisor(30, generator);
|
||||
assert(generator[ 0] == 0xD4);
|
||||
assert(generator[ 1] == 0xF6);
|
||||
assert(generator[ 5] == 0xC0);
|
||||
@@ -268,13 +268,13 @@ static void testCalcReedSolomonGenerator(void) {
|
||||
}
|
||||
|
||||
|
||||
static void testCalcReedSolomonRemainder(void) {
|
||||
static void testReedSolomonComputeRemainder(void) {
|
||||
{
|
||||
uint8_t data[1];
|
||||
uint8_t generator[3];
|
||||
uint8_t remainder[ARRAY_LENGTH(generator)];
|
||||
calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
|
||||
calcReedSolomonRemainder(data, 0, generator, ARRAY_LENGTH(generator), remainder);
|
||||
reedSolomonComputeDivisor(ARRAY_LENGTH(generator), generator);
|
||||
reedSolomonComputeRemainder(data, 0, generator, ARRAY_LENGTH(generator), remainder);
|
||||
assert(remainder[0] == 0);
|
||||
assert(remainder[1] == 0);
|
||||
assert(remainder[2] == 0);
|
||||
@@ -284,8 +284,8 @@ static void testCalcReedSolomonRemainder(void) {
|
||||
uint8_t data[2] = {0, 1};
|
||||
uint8_t generator[4];
|
||||
uint8_t remainder[ARRAY_LENGTH(generator)];
|
||||
calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
|
||||
calcReedSolomonRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
|
||||
reedSolomonComputeDivisor(ARRAY_LENGTH(generator), generator);
|
||||
reedSolomonComputeRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
|
||||
assert(remainder[0] == generator[0]);
|
||||
assert(remainder[1] == generator[1]);
|
||||
assert(remainder[2] == generator[2]);
|
||||
@@ -296,8 +296,8 @@ static void testCalcReedSolomonRemainder(void) {
|
||||
uint8_t data[5] = {0x03, 0x3A, 0x60, 0x12, 0xC7};
|
||||
uint8_t generator[5];
|
||||
uint8_t remainder[ARRAY_LENGTH(generator)];
|
||||
calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
|
||||
calcReedSolomonRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
|
||||
reedSolomonComputeDivisor(ARRAY_LENGTH(generator), generator);
|
||||
reedSolomonComputeRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
|
||||
assert(remainder[0] == 0xCB);
|
||||
assert(remainder[1] == 0x36);
|
||||
assert(remainder[2] == 0x16);
|
||||
@@ -315,8 +315,8 @@ static void testCalcReedSolomonRemainder(void) {
|
||||
};
|
||||
uint8_t generator[30];
|
||||
uint8_t remainder[ARRAY_LENGTH(generator)];
|
||||
calcReedSolomonGenerator(ARRAY_LENGTH(generator), generator);
|
||||
calcReedSolomonRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
|
||||
reedSolomonComputeDivisor(ARRAY_LENGTH(generator), generator);
|
||||
reedSolomonComputeRemainder(data, ARRAY_LENGTH(data), generator, ARRAY_LENGTH(generator), remainder);
|
||||
assert(remainder[ 0] == 0xCE);
|
||||
assert(remainder[ 1] == 0xF0);
|
||||
assert(remainder[ 2] == 0x31);
|
||||
@@ -333,7 +333,7 @@ static void testCalcReedSolomonRemainder(void) {
|
||||
}
|
||||
|
||||
|
||||
static void testFiniteFieldMultiply(void) {
|
||||
static void testReedSolomonMultiply(void) {
|
||||
const uint8_t cases[][3] = {
|
||||
{0x00, 0x00, 0x00},
|
||||
{0x01, 0x01, 0x01},
|
||||
@@ -354,7 +354,7 @@ static void testFiniteFieldMultiply(void) {
|
||||
};
|
||||
for (size_t i = 0; i < ARRAY_LENGTH(cases); i++) {
|
||||
const uint8_t *tc = cases[i];
|
||||
assert(finiteFieldMultiply(tc[0], tc[1]) == tc[2]);
|
||||
assert(reedSolomonMultiply(tc[0], tc[1]) == tc[2]);
|
||||
numTestCases++;
|
||||
}
|
||||
}
|
||||
@@ -1054,9 +1054,9 @@ int main(void) {
|
||||
testAddEccAndInterleave();
|
||||
testGetNumDataCodewords();
|
||||
testGetNumRawDataModules();
|
||||
testCalcReedSolomonGenerator();
|
||||
testCalcReedSolomonRemainder();
|
||||
testFiniteFieldMultiply();
|
||||
testReedSolomonComputeDivisor();
|
||||
testReedSolomonComputeRemainder();
|
||||
testReedSolomonMultiply();
|
||||
testInitializeFunctionModulesEtc();
|
||||
testGetAlignmentPatternPositions();
|
||||
testGetSetModule();
|
||||
|
||||
+22
-21
@@ -58,10 +58,10 @@ testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ec
|
||||
testable int getNumDataCodewords(int version, enum qrcodegen_Ecc ecl);
|
||||
testable int getNumRawDataModules(int ver);
|
||||
|
||||
testable void calcReedSolomonGenerator(int degree, uint8_t result[]);
|
||||
testable void calcReedSolomonRemainder(const uint8_t data[], int dataLen,
|
||||
testable void reedSolomonComputeDivisor(int degree, uint8_t result[]);
|
||||
testable void reedSolomonComputeRemainder(const uint8_t data[], int dataLen,
|
||||
const uint8_t generator[], int degree, uint8_t result[]);
|
||||
testable uint8_t finiteFieldMultiply(uint8_t x, uint8_t y);
|
||||
testable uint8_t reedSolomonMultiply(uint8_t x, uint8_t y);
|
||||
|
||||
testable void initializeFunctionModules(int version, uint8_t qrcode[]);
|
||||
static void drawWhiteFunctionModules(uint8_t qrcode[], int version);
|
||||
@@ -301,13 +301,13 @@ testable void addEccAndInterleave(uint8_t data[], int version, enum qrcodegen_Ec
|
||||
|
||||
// Split data into blocks, calculate ECC, and interleave
|
||||
// (not concatenate) the bytes into a single sequence
|
||||
uint8_t generator[qrcodegen_REED_SOLOMON_DEGREE_MAX];
|
||||
calcReedSolomonGenerator(blockEccLen, generator);
|
||||
uint8_t rsdiv[qrcodegen_REED_SOLOMON_DEGREE_MAX];
|
||||
reedSolomonComputeDivisor(blockEccLen, rsdiv);
|
||||
const uint8_t *dat = data;
|
||||
for (int i = 0; i < numBlocks; i++) {
|
||||
int datLen = shortBlockDataLen + (i < numShortBlocks ? 0 : 1);
|
||||
uint8_t *ecc = &data[dataLen]; // Temporary storage
|
||||
calcReedSolomonRemainder(dat, datLen, generator, blockEccLen, ecc);
|
||||
reedSolomonComputeRemainder(dat, datLen, rsdiv, blockEccLen, ecc);
|
||||
for (int j = 0, k = i; j < datLen; j++, k += numBlocks) { // Copy data
|
||||
if (j == shortBlockDataLen)
|
||||
k -= numShortBlocks;
|
||||
@@ -350,43 +350,44 @@ testable int getNumRawDataModules(int ver) {
|
||||
|
||||
/*---- Reed-Solomon ECC generator functions ----*/
|
||||
|
||||
// Calculates the Reed-Solomon generator polynomial of the given degree, storing in result[0 : degree].
|
||||
testable void calcReedSolomonGenerator(int degree, uint8_t result[]) {
|
||||
// Start with the monomial x^0
|
||||
// Computes a Reed-Solomon ECC generator polynomial for the given degree, storing in result[0 : degree].
|
||||
// This could be implemented as a lookup table over all possible parameter values, instead of as an algorithm.
|
||||
testable void reedSolomonComputeDivisor(int degree, uint8_t result[]) {
|
||||
assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX);
|
||||
// Polynomial coefficients are stored from highest to lowest power, excluding the leading term which is always 1.
|
||||
// For example the polynomial x^3 + 255x^2 + 8x + 93 is stored as the uint8 array {255, 8, 93}.
|
||||
memset(result, 0, degree * sizeof(result[0]));
|
||||
result[degree - 1] = 1;
|
||||
result[degree - 1] = 1; // Start off with the monomial x^0
|
||||
|
||||
// Compute the product polynomial (x - r^0) * (x - r^1) * (x - r^2) * ... * (x - r^{degree-1}),
|
||||
// drop the highest term, and store the rest of the coefficients in order of descending powers.
|
||||
// drop the highest monomial term which is always 1x^degree.
|
||||
// Note that r = 0x02, which is a generator element of this field GF(2^8/0x11D).
|
||||
uint8_t root = 1;
|
||||
for (int i = 0; i < degree; i++) {
|
||||
// Multiply the current product by (x - r^i)
|
||||
for (int j = 0; j < degree; j++) {
|
||||
result[j] = finiteFieldMultiply(result[j], root);
|
||||
result[j] = reedSolomonMultiply(result[j], root);
|
||||
if (j + 1 < degree)
|
||||
result[j] ^= result[j + 1];
|
||||
}
|
||||
root = finiteFieldMultiply(root, 0x02);
|
||||
root = reedSolomonMultiply(root, 0x02);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Calculates the remainder of the polynomial data[0 : dataLen] when divided by the generator[0 : degree], where all
|
||||
// polynomials are in big endian and the generator has an implicit leading 1 term, storing the result in result[0 : degree].
|
||||
testable void calcReedSolomonRemainder(const uint8_t data[], int dataLen,
|
||||
// Computes the Reed-Solomon error correction codeword for the given data and divisor polynomials.
|
||||
// The remainder when data[0 : dataLen] is divided by divisor[0 : degree] is stored in result[0 : degree].
|
||||
// All polynomials are in big endian, and the generator has an implicit leading 1 term.
|
||||
testable void reedSolomonComputeRemainder(const uint8_t data[], int dataLen,
|
||||
const uint8_t generator[], int degree, uint8_t result[]) {
|
||||
|
||||
// Perform polynomial division
|
||||
assert(1 <= degree && degree <= qrcodegen_REED_SOLOMON_DEGREE_MAX);
|
||||
memset(result, 0, degree * sizeof(result[0]));
|
||||
for (int i = 0; i < dataLen; i++) {
|
||||
for (int i = 0; i < dataLen; i++) { // Polynomial division
|
||||
uint8_t factor = data[i] ^ result[0];
|
||||
memmove(&result[0], &result[1], (degree - 1) * sizeof(result[0]));
|
||||
result[degree - 1] = 0;
|
||||
for (int j = 0; j < degree; j++)
|
||||
result[j] ^= finiteFieldMultiply(generator[j], factor);
|
||||
result[j] ^= reedSolomonMultiply(generator[j], factor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -395,7 +396,7 @@ testable void calcReedSolomonRemainder(const uint8_t data[], int dataLen,
|
||||
|
||||
// Returns the product of the two given field elements modulo GF(2^8/0x11D).
|
||||
// All inputs are valid. This could be implemented as a 256*256 lookup table.
|
||||
testable uint8_t finiteFieldMultiply(uint8_t x, uint8_t y) {
|
||||
testable uint8_t reedSolomonMultiply(uint8_t x, uint8_t y) {
|
||||
// Russian peasant multiplication
|
||||
uint8_t z = 0;
|
||||
for (int i = 7; i >= 0; i--) {
|
||||
|
||||
Reference in New Issue
Block a user