@@ -267,13 +267,13 @@ protected void encode() {
267
267
eciProcess (); // Get ECI mode
268
268
269
269
if (eciMode == 20 ) {
270
- /* Shift-JIS encoding, use Kanji mode */
271
- Charset c = Charset .forName ("Shift_JIS" );
270
+ /* Shift-JIS encoding, 2-byte Kanji characters need to be combined */
271
+ Charset sjis = Charset .forName ("Shift_JIS" );
272
272
inputData = new int [content .length ()];
273
273
for (i = 0 ; i < inputData .length ; i ++) {
274
274
CharBuffer buffer = CharBuffer .wrap (content , i , i + 1 );
275
- byte [] bytes = c .encode (buffer ).array ();
276
- int value = (bytes .length == 2 ? ((bytes [0 ] & 0xff ) << 8 ) | (bytes [1 ] & 0xff ) : bytes [0 ]);
275
+ byte [] bytes = sjis .encode (buffer ).array ();
276
+ int value = (bytes .length == 2 && bytes [ 1 ] != 0 ? ((bytes [0 ] & 0xff ) << 8 ) | (bytes [1 ] & 0xff ) : bytes [0 ]);
277
277
inputData [i ] = value ;
278
278
}
279
279
} else {
@@ -592,53 +592,52 @@ private static int getBinaryLength(int version, QrMode[] inputModeUnoptimized, i
592
592
switch (inputMode [i ]) {
593
593
case KANJI :
594
594
count += tribus (version , 8 , 10 , 12 );
595
- count += (blockLength (i , inputMode ) * 13 );
595
+ count += (blockLength (i , inputMode ) * 13 ); // 2-byte SJIS character -> 13 bits
596
596
break ;
597
597
case BINARY :
598
598
count += tribus (version , 8 , 16 , 16 );
599
599
for (j = i ; j < (i + blockLength (i , inputMode )); j ++) {
600
600
if (inputData [j ] > 0xff ) {
601
- count += 16 ;
601
+ count += 16 ; // actually a 2-byte SJIS character
602
602
} else {
603
- count += 8 ;
603
+ count += 8 ; // just a normal byte
604
604
}
605
605
}
606
606
break ;
607
607
case ALPHANUM :
608
608
count += tribus (version , 9 , 11 , 13 );
609
609
alphaLength = blockLength (i , inputMode );
610
- // In GS1 and alphanumeric mode % becomes %%
611
610
if (gs1 ) {
612
611
for (j = i ; j < (i + alphaLength ); j ++) {
613
612
if (inputData [j ] == '%' ) {
614
- percent ++;
613
+ percent ++; // in GS1 and alphanumeric mode % becomes %%
615
614
}
616
615
}
617
616
}
618
617
alphaLength += percent ;
619
618
switch (alphaLength % 2 ) {
620
619
case 0 :
621
- count += (alphaLength / 2 ) * 11 ;
620
+ count += (alphaLength / 2 ) * 11 ; // 2 characters -> 11 bits
622
621
break ;
623
622
case 1 :
624
- count += ((alphaLength - 1 ) / 2 ) * 11 ;
625
- count += 6 ;
623
+ count += ((alphaLength - 1 ) / 2 ) * 11 ; // 2 characters -> 11 bits
624
+ count += 6 ; // trailing character -> 6 bits
626
625
break ;
627
626
}
628
627
break ;
629
628
case NUMERIC :
630
629
count += tribus (version , 10 , 12 , 14 );
631
630
switch (blockLength (i , inputMode ) % 3 ) {
632
631
case 0 :
633
- count += (blockLength (i , inputMode ) / 3 ) * 10 ;
632
+ count += (blockLength (i , inputMode ) / 3 ) * 10 ; // 3 digits -> 10 bits
634
633
break ;
635
634
case 1 :
636
- count += ((blockLength (i , inputMode ) - 1 ) / 3 ) * 10 ;
637
- count += 4 ;
635
+ count += ((blockLength (i , inputMode ) - 1 ) / 3 ) * 10 ; // 3 digits -> 10 bits
636
+ count += 4 ; // trailing digit -> 4 bits
638
637
break ;
639
638
case 2 :
640
- count += ((blockLength (i , inputMode ) - 2 ) / 3 ) * 10 ;
641
- count += 7 ;
639
+ count += ((blockLength (i , inputMode ) - 2 ) / 3 ) * 10 ; // 3 digits -> 10 bits
640
+ count += 7 ; // trailing 2 digits -> 7 bits
642
641
break ;
643
642
}
644
643
break ;
@@ -686,7 +685,7 @@ private static QrMode[] applyOptimisation(int version, QrMode[] inputMode) {
686
685
687
686
if (blockCount > 1 ) {
688
687
// Search forward
689
- for (i = 0 ; i <= ( blockCount - 2 ) ; i ++) {
688
+ for (i = 0 ; i < blockCount - 1 ; i ++) {
690
689
if (blockMode [i ] == QrMode .BINARY ) {
691
690
switch (blockMode [i + 1 ]) {
692
691
case KANJI :
@@ -894,19 +893,35 @@ private void qrBinary(int[] datastream, int version, int target_binlen, QrMode[]
894
893
/* Mode indicator */
895
894
binary .append ("0100" );
896
895
897
- /* Character count indicator */
898
- binaryAppend (short_data_block_length , tribus (version , 8 , 16 , 16 ), binary );
896
+ /* Character count indicator (watch for packed 2-byte values, Kanji prior to optimization) */
897
+ int bytes = 0 ;
898
+ for (i = 0 ; i < short_data_block_length ; i ++) {
899
+ int b = inputData [position + i ];
900
+ bytes += (b > 0xff ? 2 : 1 );
901
+ }
902
+ binaryAppend (bytes , tribus (version , 8 , 16 , 16 ), binary );
899
903
900
904
info ("BYTE " );
901
905
902
906
/* Character representation */
903
907
for (i = 0 ; i < short_data_block_length ; i ++) {
904
908
int b = inputData [position + i ];
905
- if (b == FNC1 ) {
906
- b = 0x1d ; /* FNC1 */
909
+ if (b > 0xff ) {
910
+ // actually 2 packed Kanji bytes
911
+ int b1 = b >> 8 ;
912
+ int b2 = b & 0xff ;
913
+ binaryAppend (b1 , 8 , binary );
914
+ infoSpace (b1 );
915
+ binaryAppend (b2 , 8 , binary );
916
+ infoSpace (b2 );
917
+ } else {
918
+ // a single byte
919
+ if (b == FNC1 ) {
920
+ b = 0x1d ; /* FNC1 */
921
+ }
922
+ binaryAppend (b , 8 , binary );
923
+ infoSpace (b );
907
924
}
908
- binaryAppend (b , 8 , binary );
909
- infoSpace (b );
910
925
}
911
926
912
927
break ;
0 commit comments