Skip to content

Commit c992946

Browse files
committed
Use BitArray for codeword blocks
1 parent d237ca6 commit c992946

File tree

3 files changed

+90
-8
lines changed

3 files changed

+90
-8
lines changed
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
using System;
2+
using System.Collections;
3+
using System.Linq;
4+
using System.Text;
5+
6+
namespace QRCoder
7+
{
8+
/// <summary>
9+
/// Helper methods for <see cref="BitArray"/>.
10+
/// </summary>
11+
internal static class BitArrayExtensions
12+
{
13+
/// Copies a specified number of elements from one <see cref="BitArray"/> to another starting at the specified offsets.
14+
/// </summary>
15+
/// <param name="source">The source <see cref="BitArray"/> from which elements will be copied.</param>
16+
/// <param name="sourceOffset">The zero-based index in the source <see cref="BitArray"/> at which copying begins.</param>
17+
/// <param name="destination">The destination <see cref="BitArray"/> to which elements will be copied.</param>
18+
/// <param name="destinationOffset">The zero-based index in the destination <see cref="BitArray"/> at which storing begins.</param>
19+
/// <param name="count">The number of elements to copy.</param>
20+
/// <returns>The index in the destination <see cref="BitArray"/> immediately following the last copied element.</returns>
21+
public static int CopyTo(this BitArray source, int sourceOffset, BitArray destination, int destinationOffset, int count)
22+
{
23+
for (int i = 0; i < count; i++)
24+
{
25+
destination[destinationOffset + i] = source[sourceOffset + i];
26+
}
27+
return destinationOffset + count;
28+
}
29+
30+
/// <summary>
31+
/// Copies a specified number of elements from one <see cref="BitArray"/> to another starting at the specified offsets,
32+
/// and reverses every set of 8 bits during the copy operation.
33+
/// </summary>
34+
/// <param name="source">The source <see cref="BitArray"/> from which elements will be copied.</param>
35+
/// <param name="sourceOffset">The zero-based index in the source <see cref="BitArray"/> at which copying begins.</param>
36+
/// <param name="destination">The destination <see cref="BitArray"/> to which elements will be copied.</param>
37+
/// <param name="destinationOffset">The zero-based index in the destination <see cref="BitArray"/> at which storing begins.</param>
38+
/// <param name="count">The number of elements to copy. Must be a multiple of 8.</param>
39+
/// <returns>The index in the destination <see cref="BitArray"/> immediately following the last copied element.</returns>
40+
public static int CopyToRev8(this BitArray source, int sourceOffset, BitArray destination, int destinationOffset, int count)
41+
{
42+
if (count % 8 != 0)
43+
{
44+
throw new ArgumentException("Count must be a multiple of 8.", nameof(count));
45+
}
46+
47+
for (int i = 0; i < count; i += 8)
48+
{
49+
// Reverse the current set of 8 bits
50+
for (int j = 0; j < 8; j++)
51+
{
52+
destination[destinationOffset + i + j] = source[sourceOffset + i + (7 - j)];
53+
}
54+
}
55+
56+
return destinationOffset + count;
57+
}
58+
59+
}
60+
}

QRCoder/QRCodeGenerator.CodewordBlock.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1-
namespace QRCoder
1+
using System.Collections;
2+
3+
namespace QRCoder
24
{
35
public partial class QRCodeGenerator
46
{
@@ -13,16 +15,31 @@ private struct CodewordBlock
1315
/// </summary>
1416
/// <param name="codeWords">The array of data codewords for this block. Data codewords carry the actual information.</param>
1517
/// <param name="eccWords">The array of error correction codewords for this block. These codewords help recover the data if the QR code is damaged.</param>
16-
public CodewordBlock(byte[] codeWords, byte[] eccWords)
18+
public CodewordBlock(/* byte[] codeWordsArray, */ BitArray codeWords, int codeWordsOffset, int codeWordsLength, byte[] eccWords)
1719
{
20+
//this.CodeWordsArray = codeWordsArray;
1821
this.CodeWords = codeWords;
22+
this.CodeWordsOffset = codeWordsOffset;
23+
this.CodeWordsLength = codeWordsLength;
1924
this.ECCWords = eccWords;
2025
}
2126

27+
//public byte[] CodeWordsArray { get; }
28+
2229
/// <summary>
2330
/// Gets the data codewords associated with this block.
2431
/// </summary>
25-
public byte[] CodeWords { get; }
32+
public BitArray CodeWords { get; }
33+
34+
/// <summary>
35+
/// Gets the offset of the data codewords in the BitArray.
36+
/// </summary>
37+
public int CodeWordsOffset { get; }
38+
39+
/// <summary>
40+
/// Gets the length of the data codewords in the BitArray.
41+
/// </summary>
42+
public int CodeWordsLength { get; }
2643

2744
/// <summary>
2845
/// Gets the error correction codewords associated with this block.

QRCoder/QRCodeGenerator.cs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ private static QRCodeData GenerateQrCode(BitArray bitArray, ECCLevel eccLevel, i
234234
for (var i = 0; i < Math.Max(eccInfo.CodewordsInGroup1, eccInfo.CodewordsInGroup2); i++)
235235
{
236236
foreach (var codeBlock in codeWordWithECC)
237-
if (codeBlock.CodeWords.Length > i)
237+
if (codeBlock.CodeWordsLength / 8 > i)
238238
interleavedLength += 8;
239239
}
240240
for (var i = 0; i < eccInfo.ECCPerBlock; i++)
@@ -251,8 +251,10 @@ private static QRCodeData GenerateQrCode(BitArray bitArray, ECCLevel eccLevel, i
251251
for (var i = 0; i < Math.Max(eccInfo.CodewordsInGroup1, eccInfo.CodewordsInGroup2); i++)
252252
{
253253
foreach (var codeBlock in codeWordWithECC)
254-
if (codeBlock.CodeWords.Length > i)
255-
pos = DecToBin(codeBlock.CodeWords[i], 8, interleavedData, pos);
254+
{
255+
if (codeBlock.CodeWordsLength / 8 > i)
256+
pos = codeBlock.CodeWords.CopyTo(i * 8 + codeBlock.CodeWordsOffset, interleavedData, pos, 8);
257+
}
256258
}
257259
for (var i = 0; i < eccInfo.ECCPerBlock; i++)
258260
{
@@ -290,10 +292,13 @@ void AddCodeWordBlocks(int blockNum, int blocksInGroup, int codewordsInGroup, Bi
290292
var groupLength = codewordsInGroup * 8;
291293
for (var i = 0; i < blocksInGroup; i++)
292294
{
293-
var bitBlockList = BinaryStringToBitBlockByteList(bitArray2, offset2, groupLength);
295+
//var bitBlockList = BinaryStringToBitBlockByteList(bitArray2, offset2, groupLength);
294296
var eccWordList = CalculateECCWords(bitArray2, offset2, groupLength, eccInfo);
295297
codeWordWithECC.Add(new CodewordBlock(
296-
bitBlockList,
298+
//bitBlockList,
299+
bitArray2,
300+
offset2,
301+
groupLength,
297302
eccWordList)
298303
);
299304
offset2 += groupLength;

0 commit comments

Comments
 (0)