1
1
use crate :: {
2
- error_correction:: CorrectionLevels , qr_errors:: EncodingError , QRError , QRGenerator ,
3
- QRSymbolTypes ,
2
+ error_correction:: CorrectionLevels , qr_errors:: EncodingError , sizer :: Sizer , QRError ,
3
+ QRGenerator , QRSymbolTypes ,
4
4
} ;
5
5
use bitvec:: { prelude:: * , vec:: BitVec } ;
6
6
use core:: iter:: Peekable ;
7
- use std:: collections:: HashMap ;
8
7
use itertools:: Itertools ;
8
+ use std:: collections:: HashMap ;
9
9
10
10
#[ derive( Eq , PartialEq , Clone , Copy , PartialOrd , Debug ) ]
11
11
pub enum EncodingModes {
@@ -77,14 +77,16 @@ impl<'a> Encoder<'a> {
77
77
// EncodingModes::Byte => self.encode_byte_run(&mut input_iter),
78
78
_ => unreachable ! ( ) ,
79
79
} ;
80
- self . output_data . append ( & mut self . sequence_preamble ( current_encoding, char_count) ) ;
80
+ self . output_data
81
+ . append ( & mut self . sequence_preamble ( current_encoding, char_count) ) ;
81
82
self . output_data . append ( & mut bit_run) ;
82
83
current_encoding = next_encoding;
83
84
}
84
85
85
86
self . output_data . append ( & mut self . terminator ( ) ) ;
86
- self . output_data . append ( & mut self . padding_to_codeword_boundary ( ) ) ;
87
- // self.output_data.append(&mut self.padding_codewords());
87
+ self . output_data
88
+ . append ( & mut self . padding_to_codeword_boundary ( ) ) ;
89
+ self . output_data . append ( & mut self . padding_codewords ( ) ?) ;
88
90
Ok ( ( ) )
89
91
}
90
92
@@ -247,22 +249,22 @@ impl<'a> Encoder<'a> {
247
249
EncodingModes :: AlphaNumeric => 1 ,
248
250
EncodingModes :: Byte => 2 ,
249
251
EncodingModes :: Kanji => 3 ,
250
- _ => unreachable ! ( )
252
+ _ => unreachable ! ( ) ,
251
253
} )
252
254
}
253
255
sequence_preamble. append ( & mut mode_indicator) ;
254
- } ,
256
+ }
255
257
Some ( QRSymbolTypes :: QRCode ) => {
256
258
let mut mode_indicator: BitVec < u8 , Msb0 > = match encoding {
257
259
EncodingModes :: Numeric => bitvec ! [ u8 , Msb0 ; 0 , 0 , 0 , 1 ] ,
258
260
EncodingModes :: AlphaNumeric => bitvec ! [ u8 , Msb0 ; 0 , 0 , 1 , 0 ] ,
259
261
EncodingModes :: Byte => bitvec ! [ u8 , Msb0 ; 0 , 1 , 0 , 0 ] ,
260
262
EncodingModes :: Kanji => bitvec ! [ u8 , Msb0 ; 1 , 0 , 0 , 0 ] ,
261
- _ => unreachable ! ( )
263
+ _ => unreachable ! ( ) ,
262
264
} ;
263
265
sequence_preamble. append ( & mut mode_indicator) ;
264
- } ,
265
- _ => unreachable ! ( )
266
+ }
267
+ _ => unreachable ! ( ) ,
266
268
} ;
267
269
268
270
let len_indicator_len: usize = match self . generator . options . qr_type {
@@ -272,35 +274,20 @@ impl<'a> Encoder<'a> {
272
274
EncodingModes :: AlphaNumeric => 1 + self . generator . options . version . unwrap ( ) ,
273
275
EncodingModes :: Byte => 1 + self . generator . options . version . unwrap ( ) ,
274
276
EncodingModes :: Kanji => self . generator . options . version . unwrap ( ) ,
275
- _ => unreachable ! ( )
277
+ _ => unreachable ! ( ) ,
276
278
} ) as usize
277
- } ,
278
- Some ( QRSymbolTypes :: QRCode ) => {
279
- match encoding {
280
- EncodingModes :: Numeric => HashMap :: from ( [
281
- ( 9 , 10 ) ,
282
- ( 26 , 12 ) ,
283
- ( 40 , 14 )
284
- ] ) ,
285
- EncodingModes :: AlphaNumeric => HashMap :: from ( [
286
- ( 9 , 9 ) ,
287
- ( 26 , 11 ) ,
288
- ( 40 , 13 )
289
- ] ) ,
290
- EncodingModes :: Byte => HashMap :: from ( [
291
- ( 9 , 8 ) ,
292
- ( 26 , 16 ) ,
293
- ( 40 , 16 )
294
- ] ) ,
295
- EncodingModes :: Kanji => HashMap :: from ( [
296
- ( 9 , 8 ) ,
297
- ( 26 , 10 ) ,
298
- ( 40 , 12 )
299
- ] ) ,
300
- _ => unreachable ! ( )
301
- } . get ( & self . size_estimate ) . unwrap ( ) . clone ( ) as usize
302
- } ,
303
- _ => unreachable ! ( )
279
+ }
280
+ Some ( QRSymbolTypes :: QRCode ) => match encoding {
281
+ EncodingModes :: Numeric => HashMap :: from ( [ ( 9 , 10 ) , ( 26 , 12 ) , ( 40 , 14 ) ] ) ,
282
+ EncodingModes :: AlphaNumeric => HashMap :: from ( [ ( 9 , 9 ) , ( 26 , 11 ) , ( 40 , 13 ) ] ) ,
283
+ EncodingModes :: Byte => HashMap :: from ( [ ( 9 , 8 ) , ( 26 , 16 ) , ( 40 , 16 ) ] ) ,
284
+ EncodingModes :: Kanji => HashMap :: from ( [ ( 9 , 8 ) , ( 26 , 10 ) , ( 40 , 12 ) ] ) ,
285
+ _ => unreachable ! ( ) ,
286
+ }
287
+ . get ( & self . size_estimate )
288
+ . unwrap ( )
289
+ . clone ( ) as usize ,
290
+ _ => unreachable ! ( ) ,
304
291
} ;
305
292
let mut len_indicator = bitvec ! [ u16 , Msb0 ; 0 ; len_indicator_len] ;
306
293
len_indicator[ 0 ..len_indicator_len] . store ( char_count) ;
@@ -311,17 +298,15 @@ impl<'a> Encoder<'a> {
311
298
312
299
fn terminator ( & self ) -> BitVec < u8 , Msb0 > {
313
300
let terminator_len = match self . generator . options . qr_type {
314
- Some ( QRSymbolTypes :: MicroQRCode ) => {
315
- match self . generator . options . version {
316
- Some ( 1 ) => 3 ,
317
- Some ( 2 ) => 5 ,
318
- Some ( 3 ) => 7 ,
319
- Some ( 4 ) => 9 ,
320
- _ => unreachable ! ( )
321
- }
301
+ Some ( QRSymbolTypes :: MicroQRCode ) => match self . generator . options . version {
302
+ Some ( 1 ) => 3 ,
303
+ Some ( 2 ) => 5 ,
304
+ Some ( 3 ) => 7 ,
305
+ Some ( 4 ) => 9 ,
306
+ _ => unreachable ! ( ) ,
322
307
} ,
323
308
Some ( QRSymbolTypes :: QRCode ) => 4 ,
324
- _ => unreachable ! ( )
309
+ _ => unreachable ! ( ) ,
325
310
} ;
326
311
327
312
bitvec ! [ u8 , Msb0 ; 0 ; terminator_len]
@@ -334,6 +319,36 @@ impl<'a> Encoder<'a> {
334
319
bitvec ! [ u8 , Msb0 ; 0 ; pad_len]
335
320
}
336
321
322
+ fn padding_codewords ( & self ) -> Result < BitVec < u8 , Msb0 > , EncodingError > {
323
+ let total_codewords = Sizer :: data_codeword_capacity (
324
+ self . generator . options . qr_type . as_ref ( ) . unwrap ( ) ,
325
+ self . generator . options . version . unwrap ( ) ,
326
+ self . generator . options . correction_level . as_ref ( ) . unwrap ( ) ,
327
+ ) ;
328
+
329
+ // Allow up to 4 bits more than the data capacity - that would just indicate a complete-full M1 or M3 code
330
+ if self . output_data . len ( ) > ( total_codewords * 8 ) + 4 {
331
+ return Err ( EncodingError :: new ( "Too much data for specified code size." ) ) ;
332
+ }
333
+
334
+ let padding_amount = total_codewords - self . output_data . len ( ) / 8 ;
335
+ let mut padding_codewords = bitvec ! [ u8 , Msb0 ; ] ;
336
+ for pad in 0 ..padding_amount {
337
+ if pad == padding_amount - 1 && self . generator . options . qr_type == Some ( QRSymbolTypes :: MicroQRCode ) && ( self . generator . options . version == Some ( 1 ) || self . generator . options . version == Some ( 3 ) ) {
338
+ padding_codewords. append ( & mut bitvec ! [ u8 , Msb0 ; 0 , 0 , 0 , 0 ] ) ;
339
+ }
340
+ else {
341
+ padding_codewords. append ( & mut match pad % 2 {
342
+ 0 => bitvec ! [ u8 , Msb0 ; 1 , 1 , 1 , 0 , 1 , 1 , 0 , 0 ] ,
343
+ 1 => bitvec ! [ u8 , Msb0 ; 0 , 0 , 0 , 1 , 0 , 0 , 0 , 1 ] ,
344
+ _ => unreachable ! ( )
345
+ } ) ;
346
+ }
347
+ }
348
+
349
+ Ok ( padding_codewords)
350
+ }
351
+
337
352
// Get a rough guess of how large a QR-code this will be. It doesn't need to be exact -
338
353
// we only care about the thresholds <=9, <=26 and over. Assume we're going to use Byte
339
354
// mode.
@@ -360,7 +375,7 @@ impl<'a> Encoder<'a> {
360
375
self . size_estimate = match size_estimate {
361
376
( 0 ..=9 ) => 9 ,
362
377
( 10 ..=26 ) => 26 ,
363
- ( 27 ..) => 40
378
+ ( 27 ..) => 40 ,
364
379
} ;
365
380
}
366
381
@@ -736,7 +751,7 @@ mod tests {
736
751
. chars ( )
737
752
. zip ( encoder. change_distances . iter ( ) )
738
753
. peekable ( ) ;
739
- let ( _, encoded_run) = Encoder :: encode_numeric_run ( & mut input) ;
754
+ let ( _, encoded_run, _ ) = Encoder :: encode_numeric_run ( & mut input) ;
740
755
741
756
assert_eq ! (
742
757
encoded_run. as_bitslice( ) ,
0 commit comments