Skip to content

Split alphanumeric encoding from QRCodeGenerator, split encoding tables #590

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: master
Choose a base branch
from

Conversation

Shane32
Copy link
Contributor

@Shane32 Shane32 commented Apr 6, 2025

Refactoring for readability, maybe as prep to add Micro QR code support; no functional changes; no public API changes. Also made a few other inconsequential changes; see notes below.

Note that tests are not all passing locally for me anymore, probably due to PNG encoding not being stable across .NET versions/frameworks

@Shane32 Shane32 changed the title Split QRCodeGenerator further Splits QR table constants into a separate file Apr 6, 2025
@Shane32 Shane32 marked this pull request as ready for review April 6, 2025 16:19
@Shane32 Shane32 marked this pull request as draft April 6, 2025 16:19
@Shane32 Shane32 marked this pull request as ready for review April 6, 2025 18:24
@Shane32 Shane32 changed the title Splits QR table constants into a separate file Split alphanumeric encoding from QRCodeGenerator, split encoding tables Apr 7, 2025
/// <summary>
/// Checks if a character is present in the alphanumeric encoding table.
/// </summary>
public static bool CanEncode(char c) => IsInRange(c, 'A', 'Z') || Array.IndexOf(_alphanumEncTable, c) >= 0;
Copy link
Contributor Author

@Shane32 Shane32 Apr 7, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed from IsInRange(c, 'A', 'Z') || _alphanumEncTable.Contains(c) to eliminate LINQ use

var localAlphanumEncDict = new Dictionary<char, int>(45);
// Add 0-9
for (char c = '0'; c <= '9'; c++)
localAlphanumEncDict.Add(c, c - '0');
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed from localAlphanumEncDict.Add($"{i}"[0], i); to eliminate string encoding

/// <returns>A dictionary where keys are QR code version numbers and values are AlignmentPattern structures detailing the positions of alignment patterns for each version.</returns>
private static Dictionary<int, AlignmentPattern> CreateAlignmentPatternTable()
{
var alignmentPatternBaseValues = new int[] { 0, 0, 0, 0, 0, 0, 0, 6, 18, 0, 0, 0, 0, 0, 6, 22, 0, 0, 0, 0, 0, 6, 26, 0, 0, 0, 0, 0, 6, 30, 0, 0, 0, 0, 0, 6, 34, 0, 0, 0, 0, 0, 6, 22, 38, 0, 0, 0, 0, 6, 24, 42, 0, 0, 0, 0, 6, 26, 46, 0, 0, 0, 0, 6, 28, 50, 0, 0, 0, 0, 6, 30, 54, 0, 0, 0, 0, 6, 32, 58, 0, 0, 0, 0, 6, 34, 62, 0, 0, 0, 0, 6, 26, 46, 66, 0, 0, 0, 6, 26, 48, 70, 0, 0, 0, 6, 26, 50, 74, 0, 0, 0, 6, 30, 54, 78, 0, 0, 0, 6, 30, 56, 82, 0, 0, 0, 6, 30, 58, 86, 0, 0, 0, 6, 34, 62, 90, 0, 0, 0, 6, 28, 50, 72, 94, 0, 0, 6, 26, 50, 74, 98, 0, 0, 6, 30, 54, 78, 102, 0, 0, 6, 28, 54, 80, 106, 0, 0, 6, 32, 58, 84, 110, 0, 0, 6, 30, 58, 86, 114, 0, 0, 6, 34, 62, 90, 118, 0, 0, 6, 26, 50, 74, 98, 122, 0, 6, 30, 54, 78, 102, 126, 0, 6, 26, 52, 78, 104, 130, 0, 6, 30, 56, 82, 108, 134, 0, 6, 34, 60, 86, 112, 138, 0, 6, 30, 58, 86, 114, 142, 0, 6, 34, 62, 90, 118, 146, 0, 6, 30, 54, 78, 102, 126, 150, 6, 24, 50, 76, 102, 128, 154, 6, 28, 54, 80, 106, 132, 158, 6, 32, 58, 84, 110, 136, 162, 6, 26, 54, 82, 110, 138, 166, 6, 30, 58, 86, 114, 142, 170 };
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move from static field so that array is not retained in memory after creating the dictionary

@@ -113,7 +113,6 @@ public void can_render_pngbyte_qrcode_color_without_quietzones()
var result = HelperFunctions.ByteArrayToHash(pngCodeGfx);
result.ShouldBe("07f760b3eb54901840b094d31e299713");
#else
File.WriteAllBytes(@"C:\Temp\pngbyte_35.png", pngCodeGfx);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

seems to be a temporary line of code, crashing local tests when C:\Temp does not exist

@Shane32
Copy link
Contributor Author

Shane32 commented Apr 12, 2025

@codebude Ready for review please. This is pretty basic refactoring, further code-splitting QRCodeGenerator.cs and improving readability. The goal is to be able to cleanly add the Micro QR code tables into CapacityTables.cs in a future PR without affecting any existing functionality.

@Shane32 Shane32 requested a review from gfoidl April 12, 2025 04:30
Copy link
Contributor

@gfoidl gfoidl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a little calc-simplification, otherwise LGTM (codewise, I don't know these constants good enough to judge about them).

/// This is particularly necessary when performing multiplications in the field which can result in exponents exceeding the field's maximum.
/// </summary>
public static int ShrinkAlphaExp(int alphaExp)
=> (alphaExp % 256) + (alphaExp / 256);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed from:

=> (int)((alphaExp % 256) + Math.Floor((double)(alphaExp / 256)));

Since the conversion to double had taken place AFTER integer division, the Math.Floor and casts were pointless, so they are now removed. Thanks @gfoidl for noticing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants