Skip to content

Commit cc12a82

Browse files
committed
Merge branch 'optimize_compression' of https://github.com/Shane32/QRCoder into optimize_compression
2 parents 46ca871 + bf79ddf commit cc12a82

File tree

2 files changed

+41
-12
lines changed

2 files changed

+41
-12
lines changed

QRCoder/QRCodeData.cs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -81,20 +81,30 @@ public QRCodeData(byte[] rawData, Compression compressMode)
8181
rawData = output.ToArray();
8282
}
8383

84-
var count = rawData.Length;
85-
86-
if (count < 5)
84+
if (rawData.Length < 5)
8785
throw new Exception("Invalid raw data file. File too short.");
8886
if (rawData[0] != 0x51 || rawData[1] != 0x52 || rawData[2] != 0x52)
8987
throw new Exception("Invalid raw data file. Filetype doesn't match \"QRR\".");
9088

91-
//Set QR code version
89+
// Set QR code version from side length (includes 8-module quiet zone)
9290
var sideLen = (int)rawData[4];
93-
Version = (sideLen - 21 - 8) / 4 + 1;
91+
if (sideLen < 29) // Micro QR: sideLen = 19 + 2*(m-1), m in [1..4] -> versions -1..-4
92+
{
93+
if (((sideLen - 19) & 1) != 0)
94+
throw new Exception("Invalid raw data file. Side length not valid for Micro QR.");
95+
var m = ((sideLen - 19) / 2) + 1;
96+
Version = -m;
97+
}
98+
else // Standard QR: sideLen = 29 + 4*(v-1), v in [1..40]
99+
{
100+
if (((sideLen - 29) % 4) != 0)
101+
throw new Exception("Invalid raw data file. Side length not valid for QR.");
102+
Version = ((sideLen - 29) / 4) + 1;
103+
}
94104

95105
//Unpack
96-
var modules = new Queue<bool>(8 * (count - 5));
97-
for (int j = 5; j < count; j++)
106+
var modules = new Queue<bool>(8 * (rawData.Length - 5));
107+
for (int j = 5; j < rawData.Length; j++)
98108
{
99109
var b = rawData[j];
100110
for (int i = 7; i >= 0; i--)
@@ -160,7 +170,8 @@ public byte[] GetRawData(Compression compressMode)
160170
dataQueue.Enqueue((bool)module ? 1 : 0);
161171
}
162172
}
163-
for (int i = 0; i < 8 - (ModuleMatrix.Count * ModuleMatrix.Count) % 8; i++)
173+
int mod = (int)(((uint)ModuleMatrix.Count * (uint)ModuleMatrix.Count) % 8);
174+
for (int i = 0; i < 8 - mod; i++)
164175
{
165176
dataQueue.Enqueue(0);
166177
}

QRCoderTests/QRGeneratorTests.cs

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -623,16 +623,35 @@ public SamplePayload(string data, QRCodeGenerator.ECCLevel eccLevel)
623623
public override string ToString() => _data;
624624
}
625625

626-
#if !NETFRAMEWORK // [Theory] is not supported in xunit < 2.0.0
627626
[Theory]
628627
[InlineData(QRCodeData.Compression.Uncompressed)]
629628
[InlineData(QRCodeData.Compression.Deflate)]
630629
[InlineData(QRCodeData.Compression.GZip)]
631630
public void can_save_and_load_qrcode_data(QRCodeData.Compression compressionMode)
632631
{
633632
// Arrange - Create a QR code
634-
var gen = new QRCodeGenerator();
635-
var originalQrData = gen.CreateQrCode("https://github.com/Shane32/QRCoder", ECCLevel.H);
633+
var originalQrData = QRCodeGenerator.GenerateQrCode("https://github.com/Shane32/QRCoder", ECCLevel.H);
634+
var originalMatrix = string.Join("", originalQrData.ModuleMatrix.Select(x => x.ToBitString()).ToArray());
635+
636+
// Act - Get raw data and reload it
637+
var rawData = originalQrData.GetRawData(compressionMode);
638+
var reloadedQrData = new QRCodeData(rawData, compressionMode);
639+
var reloadedMatrix = string.Join("", reloadedQrData.ModuleMatrix.Select(x => x.ToBitString()).ToArray());
640+
641+
// Assert - Verify the data matches
642+
reloadedQrData.Version.ShouldBe(originalQrData.Version);
643+
reloadedQrData.ModuleMatrix.Count.ShouldBe(originalQrData.ModuleMatrix.Count);
644+
reloadedMatrix.ShouldBe(originalMatrix);
645+
}
646+
647+
[Theory]
648+
[InlineData(QRCodeData.Compression.Uncompressed)]
649+
[InlineData(QRCodeData.Compression.Deflate)]
650+
[InlineData(QRCodeData.Compression.GZip)]
651+
public void can_save_and_load_micro_qrcode_data(QRCodeData.Compression compressionMode)
652+
{
653+
// Arrange - Create a QR code
654+
var originalQrData = QRCodeGenerator.GenerateMicroQrCode("abcd");
636655
var originalMatrix = string.Join("", originalQrData.ModuleMatrix.Select(x => x.ToBitString()).ToArray());
637656

638657
// Act - Get raw data and reload it
@@ -645,7 +664,6 @@ public void can_save_and_load_qrcode_data(QRCodeData.Compression compressionMode
645664
reloadedQrData.ModuleMatrix.Count.ShouldBe(originalQrData.ModuleMatrix.Count);
646665
reloadedMatrix.ShouldBe(originalMatrix);
647666
}
648-
#endif
649667
}
650668

651669
public static class ExtensionMethods

0 commit comments

Comments
 (0)