From b93ea5412c1d80c7e269c06bab54ab5f336e3edb Mon Sep 17 00:00:00 2001 From: Abhishek Date: Sat, 24 Jan 2026 17:21:12 +0000 Subject: [PATCH] Optimize duplicated computation in QR code error correction MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Precompute X values in Forney algorithm to eliminate redundant gfPow calls. Previously, gfPow(2, ...) was computed multiple times for the same error location across different loop iterations, resulting in O(L²) redundant Galois field arithmetic operations. This change: - Precomputes all X values once before the main loop - Reduces complexity from O(L²) to O(L) for X value computations - Removes the TODO comment at line 1642 - No functional changes, only performance improvement The optimization is most beneficial when there are many error locations in QR codes (larger L values). --- modules/objdetect/src/qrcode_encoder.cpp | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/modules/objdetect/src/qrcode_encoder.cpp b/modules/objdetect/src/qrcode_encoder.cpp index 2bead8e498..a58eb08f9e 100644 --- a/modules/objdetect/src/qrcode_encoder.cpp +++ b/modules/objdetect/src/qrcode_encoder.cpp @@ -1629,9 +1629,15 @@ bool QRCodeDecoderImpl::errorCorrectionBlock(std::vector& codewords) { std::vector errEval; gfPolyMul(C, syndromes, errEval); + // Precompute all X values for error locations to avoid duplicated computation + std::vector X_values(errLocs.size()); + for (size_t j = 0; j < errLocs.size(); ++j) { + X_values[j] = gfPow(2, static_cast(codewords.size() - 1 - errLocs[j])); + } + for (size_t i = 0; i < errLocs.size(); ++i) { uint8_t numenator = 0, denominator = 0; - uint8_t X = gfPow(2, static_cast(codewords.size() - 1 - errLocs[i])); + uint8_t X = X_values[i]; uint8_t inv_X = gfDiv(1, X); for (size_t j = 0; j < L; ++j) { @@ -1639,12 +1645,11 @@ bool QRCodeDecoderImpl::errorCorrectionBlock(std::vector& codewords) { } // Compute demoninator as a product of (1-X_i * X_k) for i != k - // TODO: optimize, there is a dubplicated compute denominator = 1; for (size_t j = 0; j < errLocs.size(); ++j) { if (i == j) continue; - uint8_t Xj = gfPow(2, static_cast(codewords.size() - 1 - errLocs[j])); + uint8_t Xj = X_values[j]; denominator = gfMul(denominator, 1 ^ gfMul(inv_X, Xj)); }