@@ -56,7 +56,7 @@ public QRCodeData(string pathToRawData, Compression compressMode) : this(File.Re
5656 /// <param name="compressMode">The compression mode used for the raw data.</param>
5757 public QRCodeData ( byte [ ] rawData , Compression compressMode )
5858 {
59- //Decompress
59+ // Decompress
6060 if ( compressMode == Compression . Deflate )
6161 {
6262 using var input = new MemoryStream ( rawData ) ;
@@ -78,46 +78,53 @@ public QRCodeData(byte[] rawData, Compression compressMode)
7878 rawData = output . ToArray ( ) ;
7979 }
8080
81- if ( rawData . Length < 5 )
81+ const int HeaderLength = 5 ; // 4 bytes signature + 1 byte side length
82+
83+ if ( rawData . Length < HeaderLength )
8284 throw new InvalidDataException ( "Invalid raw data file. File too short." ) ;
83- if ( rawData [ 0 ] != 0x51 || rawData [ 1 ] != 0x52 || rawData [ 2 ] != 0x52 )
85+
86+ if ( rawData [ 0 ] != 0x51 || rawData [ 1 ] != 0x52 || rawData [ 2 ] != 0x52 || rawData [ 3 ] != 0 )
8487 throw new InvalidDataException ( "Invalid raw data file. Filetype doesn't match \" QRR\" ." ) ;
8588
8689 // Set QR code version from side length (includes 8-module quiet zone)
87- var sideLen = ( int ) rawData [ 4 ] ;
90+ int sideLen = rawData [ 4 ] ;
8891 if ( sideLen < 29 ) // Micro QR: sideLen = 19 + 2*(m-1), m in [1..4] -> versions -1..-4
8992 {
90- if ( ( ( sideLen - 19 ) & 1 ) ! = 0 )
93+ if ( sideLen < 19 || sideLen > 25 || ( sideLen & 1 ) = = 0 )
9194 throw new InvalidDataException ( "Invalid raw data file. Side length not valid for Micro QR." ) ;
92- var m = ( ( sideLen - 19 ) / 2 ) + 1 ;
93- Version = - m ;
95+
96+ Version = - ( ( sideLen - 17 ) >>> 1 ) ;
9497 }
9598 else // Standard QR: sideLen = 29 + 4*(v-1), v in [1..40]
9699 {
97- if ( ( ( sideLen - 29 ) % 4 ) != 0 )
100+ if ( sideLen > 185 || ( sideLen & 3 ) != 1 )
98101 throw new InvalidDataException ( "Invalid raw data file. Side length not valid for QR." ) ;
99- Version = ( ( sideLen - 29 ) / 4 ) + 1 ;
102+
103+ Version = ( sideLen - 25 ) >>> 2 ;
100104 }
101105
102- //Unpack
103- var modules = new Queue < bool > ( 8 * ( rawData . Length - 5 ) ) ;
104- for ( int j = 5 ; j < rawData . Length ; j ++ )
106+ int byteLength = ( sideLen * sideLen + 7 ) >>> 3 ;
107+ if ( rawData . Length < 5 + byteLength )
105108 {
106- var b = rawData [ j ] ;
107- for ( int i = 7 ; i >= 0 ; i -- )
108- {
109- modules . Enqueue ( ( b & ( 1 << i ) ) != 0 ) ;
110- }
109+ throw new InvalidDataException ( "Invalid raw data file. Not enough data." ) ;
111110 }
112111
113- //Build module matrix
112+ // Build module matrix
114113 ModuleMatrix = new List < BitArray > ( sideLen ) ;
114+ int bitIndex = HeaderLength * 8 ; // Skip header bytes
115+
115116 for ( int y = 0 ; y < sideLen ; y ++ )
116117 {
117- ModuleMatrix . Add ( new BitArray ( sideLen ) ) ;
118+ var row = new BitArray ( sideLen ) ;
119+ ModuleMatrix . Add ( row ) ;
120+
118121 for ( int x = 0 ; x < sideLen ; x ++ )
119122 {
120- ModuleMatrix [ y ] [ x ] = modules . Dequeue ( ) ;
123+ int byteIndex = bitIndex >>> 3 ;
124+ int mask = 1 << ( ~ bitIndex & 7 ) ;
125+ row [ x ] = ( rawData [ byteIndex ] & mask ) != 0 ;
126+
127+ bitIndex ++ ;
121128 }
122129 }
123130
0 commit comments