-
-
Notifications
You must be signed in to change notification settings - Fork 67
/
Copy pathqrcode.ps.src
1468 lines (1368 loc) · 60.2 KB
/
qrcode.ps.src
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
% Barcode Writer in Pure PostScript
% https://bwipp.terryburton.co.uk
%
% Copyright (c) 2004-2024 Terry Burton
%
% $Id$
%
% Permission is hereby granted, free of charge, to any
% person obtaining a copy of this software and associated
% documentation files (the "Software"), to deal in the
% Software without restriction, including without
% limitation the rights to use, copy, modify, merge,
% publish, distribute, sublicense, and/or sell copies of
% the Software, and to permit persons to whom the Software
% is furnished to do so, subject to the following
% conditions:
%
% The above copyright notice and this permission notice
% shall be included in all copies or substantial portions
% of the Software.
%
% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY
% KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
% THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
% PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
% THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
% DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
% CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
% CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
% IN THE SOFTWARE.
% --BEGIN ENCODER qrcode--
% --REQUIRES preamble loadctx unloadctx raiseerror processoptions parseinput renmatrix--
% --DESC: QR Code
% --EXAM: http://goo.gl/0bis
% --EXOP: eclevel=M
% --RNDR: renmatrix
/setpacking where {pop currentpacking true setpacking} if
10 dict
dup /loadctx dup /uk.co.terryburton.bwipp findresource put
dup /unloadctx dup /uk.co.terryburton.bwipp findresource put
dup /raiseerror dup /uk.co.terryburton.bwipp findresource put
dup /processoptions dup /uk.co.terryburton.bwipp findresource put
dup /parseinput dup /uk.co.terryburton.bwipp findresource put
dup /renmatrix dup /uk.co.terryburton.bwipp findresource put
begin
/qrcode {
20 dict begin
/ctx null def
/dontdraw false def
/format (unset) def % full or micro. rMQR symbols are specified using version
/version (unset) def % 1-40 or M1-M4 or R7x43, etc
/eclevel (unset) def % full: L, M, Q, H; micro: L, M, Q; rmqr: M, H
/fixedeclevel false def
/parse false def
/parsefnc false def
/mask -1 def
/suppresskanjimode false def
//processoptions exec /options exch def
/barcode exch def
/qrcode //loadctx exec
barcode () eq {
/bwipp.qrcodeEmptyData (The data must not be empty) //raiseerror exec
} if
% If version is supplied and format is not given then set format to correspond
version (unset) ne {
format (unset) eq {
(full)
version 0 1 getinterval (M) eq { pop (micro) } if
version 0 1 getinterval (R) eq { pop (rmqr) } if
/format exch def
} if
} {
format (unset) eq { /format (full) def } if % Default to full
} ifelse
format (full) ne format (micro) ne format (rmqr) ne and and {
/bwipp.qrcodeInvalidFormat (The format must be either full, micro or rmqr) //raiseerror exec
} if
format (rmqr) eq version (unset) eq and {
/bwipp.qrcodeRMQRwithoutVersion (A version must be provided for RMQR) //raiseerror exec
} if
% Default error correction level
eclevel (unset) eq {/eclevel format (micro) ne {(M)} {(L)} ifelse def} if
eclevel (L) ne eclevel (M) ne eclevel (Q) ne eclevel (H) ne and and and {
/bwipp.qrcodeInvalidEClevel (Error correction level must be either L, M, Q, or H) //raiseerror exec
} if
mask -1 ne format (rmqr) eq and {
/bwipp.qrcodeRMQRmask (A mask cannot be supplied for RMQR) //raiseerror exec
} if
mask -1 ne {
mask 1 lt mask format (full) eq {8} {4} ifelse gt or {
/bwipp.qrcodeBadMask (An invalid mask was supplied) //raiseerror exec
} if
} if
% Parse the input
/fn1 -1 def
/fncvals <<
/parse parse
/parsefnc parsefnc
/eci true
(FNC1) fn1
>> def
/msg barcode fncvals //parseinput exec def
/msglen msg length def
% If FNC1 in first position then escape % as %%
/fnc1first false def
msglen 0 gt {
msg 0 get fn1 eq {
/fnc1first true def
/msg [ msg 1 msglen 1 sub getinterval { dup 37 eq {dup} if } forall ] def
/msglen msg length def
} if
} if
{ % context
% Enumerate vergrps
[
/v1to9 /v10to26 /v27to40
/vM1 /vM2 /vM3 /vM4
/vR7x43 /vR7x59 /vR7x77 /vR7x99 /vR7x139
/vR9x43 /vR9x59 /vR9x77 /vR9x99 /vR9x139
/vR11x27 /vR11x43 /vR11x59 /vR11x77 /vR11x99 /vR11x139
/vR13x27 /vR13x43 /vR13x59 /vR13x77 /vR13x99 /vR13x139
/vR15x43 /vR15x59 /vR15x77 /vR15x99 /vR15x139
/vR17x43 /vR17x59 /vR17x77 /vR17x99 /vR17x139
] 0 exch {1 index def 1 add} forall pop
% Convert from input into message bitstream
%
% Modes: (N)umeric, (A)lphanumeric, (B)yte, (K)anji, (E)CI
%
/N 0 def /A 1 def /B 2 def /K 3 def /E 4 def
/Nexcl <<
[
16#30 1 16#39 {} for
] {-1} forall
>> def
/Aexcl <<
[
16#20 16#24 16#25 16#2A 16#2B 16#2D 16#2E 16#2F 16#3A
16#41 1 16#5A {} for
fn1
] {-1} forall
>> def
% Binary exclusives calculated from "not others"
/Kexcl <<
[
16#81 1 16#9F {} for
16#E0 1 16#EB {} for
] {-1} forall
>> def
/mids [
% N A B K E
[ (0001) (0010) (0100) (1000) (0111) ] % v1to9
[ (0001) (0010) (0100) (1000) (0111) ] % v10to26
[ (0001) (0010) (0100) (1000) (0111) ] % v27to40
[ () -1 -1 -1 -1 ] % vM1
[ (0) (1) -1 -1 -1 ] % vM2
[ (00) (01) (10) (11) -1 ] % vM3
[ (000) (001) (010) (011) -1 ] % vM4
32 {
[ (001) (010) (011) (100) (111) ] % rMQR
} repeat
] def
/cclens [ % N A B K
[ 10 9 8 8 ] % v1to9
[ 12 11 16 10 ] % v10to26
[ 14 13 16 12 ] % v27to40
[ 3 -1 -1 -1 ] % vM1
[ 4 3 -1 -1 ] % vM2
[ 5 4 4 3 ] % vM3
[ 6 5 5 4 ] % vM4
[ 4 3 3 2 ] % vR7x43
[ 5 5 4 3 ] % vR7x59
[ 6 5 5 4 ] % vR7x77
[ 7 6 5 5 ] % vR7x99
[ 7 6 6 5 ] % vR7x139
[ 5 5 4 3 ] % vR9x43
[ 6 5 5 4 ] % vR9x59
[ 7 6 5 5 ] % vR9x77
[ 7 6 6 5 ] % vR9x99
[ 8 7 6 6 ] % vR9x139
[ 4 4 3 2 ] % vR11x27
[ 6 5 5 4 ] % vR11x43
[ 7 6 5 5 ] % vR11x59
[ 7 6 6 5 ] % vR11x77
[ 8 7 6 6 ] % vR11x99
[ 8 7 7 6 ] % vR11x139
[ 5 5 4 3 ] % vR13x27
[ 6 6 5 5 ] % vR13x43
[ 7 6 6 5 ] % vR13x59
[ 7 7 6 6 ] % vR13x77
[ 8 7 7 6 ] % vR13x99
[ 8 8 7 7 ] % vR13x139
[ 7 6 6 5 ] % vR15x43
[ 7 7 6 5 ] % vR15x59
[ 8 7 7 6 ] % vR15x77
[ 8 7 7 6 ] % vR15x99
[ 9 8 7 7 ] % vR15x139
[ 7 6 6 5 ] % vR17x43
[ 8 7 6 6 ] % vR17x59
[ 8 7 7 6 ] % vR17x77
[ 8 8 7 6 ] % vR17x99
[ 9 8 8 7 ] % vR17x139
] def
/termlens [
3 {
4 % Full
} repeat
3 % vM1
5 % vM2
7 % vM3
9 % vM4
32 {
3 % rMQR
} repeat
] def
/padstrs [ (11101100) (00010001) ] def
% Alphanumeric character to value map
/charmap (0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ $%*+-./:) def
/charvals 44 dict def
0 1 44 {dup charmap exch get exch charvals 3 1 roll put} for
} ctxdef
% Encoding functions
/tobin {
string dup length 1 sub 0 exch 1 exch {1 index exch 48 put} for
dup 3 -1 roll 2 2 index length string cvrs dup length 2 index length exch sub exch putinterval
} def
/encA {
/in exch def
fnc1first { % FNC1 as %
/in [ in { dup fn1 eq {pop 37} if } forall ] def
} if
/out in length 11 mul 2 idiv 1 add string def
/k 0 def /m 0 def {
k in length eq {exit} if
k in length 1 sub lt {
charvals in k get get 45 mul charvals in k 1 add get get add 11 tobin
/k k 2 add def
} { % Final character
charvals in k get get 6 tobin
/k k 1 add def
} ifelse
dup out exch m exch putinterval
length m add /m exch def
} loop
out 0 m getinterval
} def
/encN {
/in exch def
/out in length 10 mul 3 idiv 1 add string def
/k 0 def /m 0 def {
k in length eq {exit} if
k in length 2 sub lt {
in k 3 getinterval 0 exch {exch 10 mul 48 sub add} forall 10 tobin
/k k 3 add def
} {
k in length 2 sub eq { % Two final digits
in k 2 getinterval 0 exch {exch 10 mul 48 sub add} forall 7 tobin
/k k 2 add def
} { % One final digit
in k 1 getinterval 0 exch {exch 10 mul 48 sub add} forall 4 tobin
/k k 1 add def
} ifelse
} ifelse
dup out exch m exch putinterval
length m add /m exch def
} loop
out 0 m getinterval
} def
/encB {
/in exch def
fnc1first { % FNC1 as GS
/in [ in { dup fn1 eq {pop 29} if } forall ] def
} if
/out in length 8 mul string def
0 1 in length 1 sub {
/k exch def
in k get cvi 8 tobin
out k 8 mul 3 -1 roll putinterval
} for
out
} def
/encK {
/in exch def
/out in length 2 idiv 13 mul string def
/k 0 def /m 0 def {
k in length eq {exit} if
in k get 256 mul in k 1 add get add
dup 16#E040 lt {16#8140} {16#C140} ifelse sub
dup -8 bitshift 16#C0 mul exch 16#00FF and add
13 tobin dup out exch m exch putinterval
length m add /m exch def
/k k 2 add def
} loop
out
} def
/encE {
0 get neg 1000000 sub
dup 000127 le { % ECI 000000 - 000127
8 tobin
} { dup 016383 le { % ECI 000128 - 016383
2#1000000000000000 add 16 tobin
} { % ECI 016384 - 999999
2#110000000000000000000000 add 24 tobin
} ifelse } ifelse
} def
/encfuncs [ /encN /encA /encB /encK /encE ] def
/addtobits {
dup bits j 3 -1 roll putinterval
length j add /j exch def
} def
/numNs [ msglen {0} repeat 0 ] def
/numAs [ msglen {0} repeat 0 ] def
/numAorNs [ msglen {0} repeat 0 ] def
/numBs [ msglen {0} repeat 0 ] def
/numKs [ msglen {0} repeat 0 ] def
/nextNs [ msglen {0} repeat 9999 ] def
/nextBs [ msglen {0} repeat 9999 ] def
/nextAs [ msglen {0} repeat 9999 ] def
/nextKs [ msglen {0} repeat 9999 ] def
/isECI msglen array def
msglen 1 sub -1 0 {
/i exch def
/barchar msg i get def
Kexcl barchar known suppresskanjimode not and {
i 1 add msglen lt { barchar 256 mul msg i 1 add get add } { 0 } ifelse
dup % Double byte:
dup dup 16#8140 ge exch 16#9FFC le and exch % 8140-9FFC or
dup 16#E040 ge exch 16#EBBF le and or exch % E040-EBBF
16#FF and % Low byte:
dup dup 16#40 ge exch 16#FC le and exch 16#7F ne % 40-FC except !7F
and and {
nextKs i 0 put
numKs i numKs i 2 add get 1 add put
} {
nextKs i nextKs i 1 add get 1 add put
} ifelse
} {
nextKs i nextKs i 1 add get 1 add put
} ifelse
Nexcl barchar known {
nextNs i 0 put
numNs i numNs i 1 add get 1 add put
numAorNs i numAorNs i 1 add get 1 add put
} {
nextNs i nextNs i 1 add get 1 add put
} ifelse
Aexcl barchar known {
nextAs i 0 put
numAs i numAs i 1 add get 1 add put
numAorNs i numAorNs i 1 add get 1 add put
} {
nextAs i nextAs i 1 add get 1 add put
} ifelse
isECI i barchar -1000000 le put
} for
0 1 msglen 1 sub { % Scan forward to set any "2nd byte 1st byte" Kanji matches to zero
/i exch def
numKs i get 0 gt {
numKs i 1 add 0 put
nextKs i 1 add nextKs i 1 add get 1 add put
} if
} for
msglen 1 sub -1 0 { % Finally scan backwards again to set numBs/nextBs from "not others"
/i exch def
numNs i get numAs i get numKs i get add add 0 eq isECI i get not and {
nextBs i 0 put
numBs i numBs i 1 add get 1 add put
} {
nextBs i nextBs i 1 add get 1 add put
} ifelse
} for
/KbeforeB {numK exch ver get ge nextBs numK 2 mul i add get 0 eq and} def
/KbeforeA {numK exch ver get ge nextAs numK 2 mul i add get 0 eq and} def
/KbeforeN {numK exch ver get ge nextNs numK 2 mul i add get 0 eq and} def
/KbeforeE {numK exch ver get ge numK 2 mul i add msglen eq and} def
/AbeforeK {numA exch ver get ge nextKs numA i add get 0 eq and} def
/AbeforeB {numA exch ver get ge nextBs numA i add get 0 eq and} def
/AbeforeN {numA exch ver get ge nextNs numA i add get 0 eq and} def
/AbeforeE {numA exch ver get ge numA i add msglen eq and} def
/NbeforeK {numN exch ver get ge nextKs numN i add get 0 eq and} def
/NbeforeB {numN exch ver get ge nextBs numN i add get 0 eq and} def
/NbeforeA {numN exch ver get ge nextAs numN i add get 0 eq and} def
/NbeforeE {numN exch ver get ge numN i add msglen eq and} def
/AorNbeforeB {numAorN exch ver get ge nextBs numAorN i add get 0 eq and} def
/AorNbeforeE {numAorN exch ver get ge numAorN i add msglen eq and} def
/nextNslt { nextNs i get msglen ge { pop true } { numNs nextNs i get i add get exch ver get lt } ifelse } def
% Elements of the encoded message have differing lengths based on the
% resulting symbol size. The symbol sizes with different element lengths
% are batched into vergrps. To pick the smallest symbol that holds our
% content we encode the message according to each available vergrp, based
% on the format of symbol.
% Determine which groups we need to encode
{
/versetmap <<
(full) <<
0 1 9 { 10 2 string cvrs v1to9 } for
10 1 26 { 10 2 string cvrs v10to26 } for
27 1 40 { 10 2 string cvrs v27to40 } for
>>
(micro) <<
(M1) vM1 (M2) vM2 (M3) vM3 (M4) vM4
>>
(rmqr) <<
(R7x43) vR7x43 (R7x59) vR7x59 (R7x77) vR7x77 (R7x99) vR7x99 (R7x139) vR7x139
(R9x43) vR9x43 (R9x59) vR9x59 (R9x77) vR9x77 (R9x99) vR9x99 (R9x139) vR9x139
(R11x27) vR11x27 (R11x43) vR11x43 (R11x59) vR11x59 (R11x77) vR11x77 (R11x99) vR11x99 (R11x139) vR11x139
(R13x27) vR13x27 (R13x43) vR13x43 (R13x59) vR13x59 (R13x77) vR13x77 (R13x99) vR13x99 (R13x139) vR13x139
(R15x43) vR15x43 (R15x59) vR15x59 (R15x77) vR15x77 (R15x99) vR15x99 (R15x139) vR15x139
(R17x43) vR17x43 (R17x59) vR17x59 (R17x77) vR17x77 (R17x99) vR17x99 (R17x139) vR17x139
>>
>> def
/versetfull [v1to9 v10to26 v27to40] def
/versetmicro [vM1 vM2 vM3 vM4] def
} ctxdef
version (unset) ne {
% A specific version of symbol is given so encode in just the corresponding vergrp
versetmap format get version 2 copy known not {
pop pop
format (full) eq {
/bwipp.qrcodeInvalidFullVersion (Valid versions for QR Code symbols are 1 to 40) //raiseerror exec
} {
format (micro) eq {
/bwipp.qrcodeInvalidMicroVersion (Valid versions for Micro QR Code symbols are M1 to M4) //raiseerror exec
} { % rmqr
/bwipp.qrcodeInvalidRMQRversion (Invalid version for an RMQR symbol) //raiseerror exec
} ifelse } ifelse
} if
get [ exch ] /verset exch def
} {
% Just the format is specified so encode in each vergrp for the type of symbol
format (full) eq { /verset versetfull def } if
format (micro) eq { /verset versetmicro def } if
% rMQR symbols are accessed with an explicit version
} ifelse
% Encode unterminated bitstream for each compatible vergrp separately
/msgbits [ 39 {-1} repeat ] def
/e 10000 def
% Number of before characters per vergrp, depending on current mode, for optimising modes
% Generated by contrib/development/build-qr-mode-optim-arrs.php
% Full Micro R7 R9 R11 R13 R15 R17
{
/mode0forceKB [ 1 1 1 e e 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] def
/mode0forceA [ 1 1 1 e 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] def
/mode0forceN [ 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1] def
/mode0NbeforeB [ 4 4 5 e e 2 3 2 2 3 3 3 2 3 3 3 3 2 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3] def
/modeBKbeforeB [ 9 12 13 e e 4 6 4 5 6 6 6 5 6 6 6 7 4 6 6 6 7 7 5 6 6 7 7 7 6 6 7 7 7 6 7 7 7 8] def
/modeBKbeforeA [ 8 10 11 e e 4 5 4 5 5 6 6 5 5 6 6 6 4 5 6 6 6 6 5 6 6 6 6 7 6 6 6 6 7 6 6 6 7 7] def
/modeBKbeforeN [ 8 9 11 e e 3 5 3 4 5 5 5 4 5 5 5 6 3 5 5 5 6 6 4 5 5 6 6 6 5 5 6 6 7 5 6 6 6 7] def
/modeBKbeforeE [ 5 5 6 e e 2 3 2 3 3 3 3 3 3 3 3 4 2 3 3 3 4 4 3 3 3 4 4 4 3 3 4 4 4 3 4 4 4 4] def
/modeBAbeforeK [11 12 14 e e 5 7 5 6 7 8 8 6 7 8 8 8 6 7 8 8 8 8 6 8 8 8 8 9 8 8 8 8 9 8 8 8 9 9] def
/modeBAbeforeB [11 15 16 e e 6 7 6 7 7 8 8 7 7 8 8 8 6 7 8 8 8 9 7 8 8 8 9 9 8 8 9 9 9 8 8 9 9 10] def
/modeBAbeforeN [12 13 15 e e 6 8 6 7 8 8 8 7 8 8 8 9 6 8 8 8 9 9 7 8 8 9 9 10 8 9 9 9 10 8 9 9 10 10] def
/modeBAbeforeE [ 6 7 8 e e 3 4 3 4 4 4 4 4 4 4 4 5 4 4 4 4 5 5 4 4 4 5 5 5 4 5 5 5 5 4 5 5 5 5] def
/modeBNbeforeK [ 6 7 8 e e 3 4 3 4 4 5 5 4 4 5 5 5 3 4 5 5 5 5 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 5] def
/modeBNbeforeB [ 6 8 9 e e 3 4 3 4 4 5 5 4 4 5 5 5 3 4 5 5 5 5 4 4 5 5 5 5 5 5 5 5 5 5 5 5 5 6] def
/modeBNbeforeA [ 6 7 8 e e 3 4 3 4 4 5 5 4 4 5 5 5 4 4 5 5 5 5 4 5 5 5 5 5 5 5 5 5 6 5 5 5 5 6] def
/modeBNbeforeE [ 3 4 4 e e 2 3 2 2 3 3 3 2 3 3 3 3 2 3 3 3 3 3 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3] def
/modeANbeforeA [13 15 17 e 5 7 9 7 8 9 9 9 8 9 9 9 11 7 9 9 9 11 11 8 9 9 10 11 11 9 10 11 11 11 9 11 11 11 11] def
/modeANbeforeB [13 17 18 e e 7 9 7 8 9 9 9 8 9 9 9 10 7 9 9 9 10 11 8 9 9 9 11 11 9 9 11 11 11 9 10 11 11 11] def
/modeANbeforeE [ 7 8 9 e 3 4 5 4 5 5 5 5 5 5 5 5 6 4 5 5 5 6 6 5 5 5 5 6 6 5 5 6 6 6 5 6 6 6 6] def
} ctxdef
verset {
/ver exch def
% Derive optimal sequence
/mode -1 def /seq [] def /i 0 def {
i msglen ge {exit} if
/numK numKs i get def
/numB numBs i get def
/numA numAs i get def
/numN numNs i get def
/numAorN numAorNs i get def
/eci isECI i get def
ver vM1 eq numA 1 ge and {/seq -1 def exit} if
ver vM1 eq numB 1 ge and {/seq -1 def exit} if
ver vM1 eq numK 1 ge and {/seq -1 def exit} if
ver vM1 eq eci and {/seq -1 def exit} if
ver vM2 eq numB 1 ge and {/seq -1 def exit} if
ver vM2 eq numK 1 ge and {/seq -1 def exit} if
ver vM2 eq eci and {/seq -1 def exit} if
ver vM3 eq eci and {/seq -1 def exit} if
ver vM4 eq eci and {/seq -1 def exit} if
{ % common exit
eci {
E exit
} if
mode -1 eq { % Set initial mode (or mode after ECI)
mode0forceKB KbeforeA {K exit} if
mode0forceKB KbeforeN {K exit} if
modeBKbeforeE KbeforeB {K exit} if % Re-using modeB KbeforeE array
mode0forceKB KbeforeE {K exit} if
numK 1 ge {B exit} if
mode0NbeforeB NbeforeK {N exit} if
mode0NbeforeB NbeforeB {N exit} if
mode0forceKB NbeforeB {B exit} if
modeANbeforeE NbeforeA {N exit} if % Re-using modeA NbeforeE array
mode0forceN NbeforeE {N exit} if
modeBAbeforeE AbeforeK {A exit} if % Re-using modeB AbeforeE array
modeBAbeforeE AorNbeforeB {A exit} if % Re-using modeB AbeforeE array
mode0forceA AorNbeforeE {A exit} if
B exit
} if
mode B eq {
modeBKbeforeB KbeforeB {K exit} if
modeBKbeforeA KbeforeA {K exit} if
modeBKbeforeN KbeforeN {K exit} if
modeBKbeforeE KbeforeE {K exit} if
modeBAbeforeK AbeforeK {A exit} if
modeBAbeforeB AbeforeB {A exit} if
modeBAbeforeN AbeforeN {A exit} if
modeBAbeforeE AbeforeE {A exit} if
modeBNbeforeK NbeforeK {N exit} if
modeBNbeforeB NbeforeB {N exit} if
modeBNbeforeA NbeforeA {N exit} if
modeBNbeforeE NbeforeE {N exit} if
modeBAbeforeE AorNbeforeE numAorN modeBAbeforeN ver get le and { % If A/N sequence at end and short
modeBNbeforeA nextNslt {A exit} if % And next N sequence shorter than NbeforeA
} if
B exit
} if
mode A eq {
numK 1 ge {K exit} if
numB 1 ge {B exit} if
modeANbeforeA NbeforeA {N exit} if
modeANbeforeB NbeforeB {N exit} if
modeANbeforeE NbeforeE {N exit} if
numA 1 ge numN 1 ge or {A exit} if
B exit
} if
mode N eq {
numK 1 ge {K exit} if
numB 1 ge {B exit} if
numA 1 ge {A exit} if
numN 1 ge {N exit} if
B exit
} if
mode K eq {
numB 1 ge {B exit} if
numA 1 ge {A exit} if
numN 1 ge {N exit} if
numK 1 ge {K exit} if
B exit
} if
} loop
dup K eq fnc1first and {pop B} if % No kanji with fnc1first
dup mode eq { % Same mode encode directly
pop
/dat msg i mode K eq {2} {1} ifelse getinterval def
/seq [
seq aload pop
[ exch aload pop dat aload pop ]
] def
} { % Change mode
/mode exch def
mode K eq {K msg i numK 2 mul getinterval} if
mode B eq {B msg i numB getinterval} if
mode A eq {A msg i numA getinterval} if
mode N eq {N msg i numN getinterval} if
mode E eq {E msg i 1 getinterval /mode -1 def} if
/dat exch def /sw exch def
/seq [ seq aload pop sw dat ] def
} ifelse
/i i dat length add def
} loop
% Encode the sequence
{ % common exit
seq -1 eq {exit} if % Sequence not available
/bits 23648 string def
/j 0 def
fnc1first {
ver vR7x43 lt { (0101) } { (101) } ifelse addtobits
} if
/abort false def
0 2 seq length 1 sub {
/i exch def
/mode seq i get def
mids ver get mode get addtobits
/chars seq i 1 add get def
/charslen chars length mode K eq {2 idiv} if def
mode E ne {
/cclen cclens ver get mode get def
charslen 2 cclen exp cvi ge { % Too many characters for cc indicator
/abort true def exit
} if
charslen cclen tobin addtobits
} if
chars encfuncs mode get load exec addtobits
} for
abort {exit} if
/bits bits 0 j getinterval def
msgbits ver bits put
exit
} loop
} forall
% Lookup the most appropriate symbol specification
{
/metrics [
% format vers vergrp rows cols align modules error codewords error correction blocks
% L M Q H L1 L2 M1 M2 Q1 Q2 H1 H2
[ (micro) (M1) vM1 11 11 98 99 36 [ 2 99 99 99 ] [ 1 0 -1 -1 -1 -1 -1 -1 ] ]
[ (micro) (M2) vM2 13 13 98 99 80 [ 5 6 99 99 ] [ 1 0 1 0 -1 -1 -1 -1 ] ]
[ (micro) (M3) vM3 15 15 98 99 132 [ 6 8 99 99 ] [ 1 0 1 0 -1 -1 -1 -1 ] ]
[ (micro) (M4) vM4 17 17 98 99 192 [ 8 10 14 99 ] [ 1 0 1 0 1 0 -1 -1 ] ]
[ (full) (1) v1to9 21 21 98 99 208 [ 7 10 13 17 ] [ 1 0 1 0 1 0 1 0 ] ]
[ (full) (2) v1to9 25 25 18 99 359 [ 10 16 22 28 ] [ 1 0 1 0 1 0 1 0 ] ]
[ (full) (3) v1to9 29 29 22 99 567 [ 15 26 36 44 ] [ 1 0 1 0 2 0 2 0 ] ]
[ (full) (4) v1to9 33 33 26 99 807 [ 20 36 52 64 ] [ 1 0 2 0 2 0 4 0 ] ]
[ (full) (5) v1to9 37 37 30 99 1079 [ 26 48 72 88 ] [ 1 0 2 0 2 2 2 2 ] ]
[ (full) (6) v1to9 41 41 34 99 1383 [ 36 64 96 112 ] [ 2 0 4 0 4 0 4 0 ] ]
[ (full) (7) v1to9 45 45 22 38 1568 [ 40 72 108 130 ] [ 2 0 4 0 2 4 4 1 ] ]
[ (full) (8) v1to9 49 49 24 42 1936 [ 48 88 132 156 ] [ 2 0 2 2 4 2 4 2 ] ]
[ (full) (9) v1to9 53 53 26 46 2336 [ 60 110 160 192 ] [ 2 0 3 2 4 4 4 4 ] ]
[ (full) (10) v10to26 57 57 28 50 2768 [ 72 130 192 224 ] [ 2 2 4 1 6 2 6 2 ] ]
[ (full) (11) v10to26 61 61 30 54 3232 [ 80 150 224 264 ] [ 4 0 1 4 4 4 3 8 ] ]
[ (full) (12) v10to26 65 65 32 58 3728 [ 96 176 260 308 ] [ 2 2 6 2 4 6 7 4 ] ]
[ (full) (13) v10to26 69 69 34 62 4256 [ 104 198 288 352 ] [ 4 0 8 1 8 4 12 4 ] ]
[ (full) (14) v10to26 73 73 26 46 4651 [ 120 216 320 384 ] [ 3 1 4 5 11 5 11 5 ] ]
[ (full) (15) v10to26 77 77 26 48 5243 [ 132 240 360 432 ] [ 5 1 5 5 5 7 11 7 ] ]
[ (full) (16) v10to26 81 81 26 50 5867 [ 144 280 408 480 ] [ 5 1 7 3 15 2 3 13 ] ]
[ (full) (17) v10to26 85 85 30 54 6523 [ 168 308 448 532 ] [ 1 5 10 1 1 15 2 17 ] ]
[ (full) (18) v10to26 89 89 30 56 7211 [ 180 338 504 588 ] [ 5 1 9 4 17 1 2 19 ] ]
[ (full) (19) v10to26 93 93 30 58 7931 [ 196 364 546 650 ] [ 3 4 3 11 17 4 9 16 ] ]
[ (full) (20) v10to26 97 97 34 62 8683 [ 224 416 600 700 ] [ 3 5 3 13 15 5 15 10 ] ]
[ (full) (21) v10to26 101 101 28 50 9252 [ 224 442 644 750 ] [ 4 4 17 0 17 6 19 6 ] ]
[ (full) (22) v10to26 105 105 26 50 10068 [ 252 476 690 816 ] [ 2 7 17 0 7 16 34 0 ] ]
[ (full) (23) v10to26 109 109 30 54 10916 [ 270 504 750 900 ] [ 4 5 4 14 11 14 16 14 ] ]
[ (full) (24) v10to26 113 113 28 54 11796 [ 300 560 810 960 ] [ 6 4 6 14 11 16 30 2 ] ]
[ (full) (25) v10to26 117 117 32 58 12708 [ 312 588 870 1050 ] [ 8 4 8 13 7 22 22 13 ] ]
[ (full) (26) v10to26 121 121 30 58 13652 [ 336 644 952 1110 ] [ 10 2 19 4 28 6 33 4 ] ]
[ (full) (27) v27to40 125 125 34 62 14628 [ 360 700 1020 1200 ] [ 8 4 22 3 8 26 12 28 ] ]
[ (full) (28) v27to40 129 129 26 50 15371 [ 390 728 1050 1260 ] [ 3 10 3 23 4 31 11 31 ] ]
[ (full) (29) v27to40 133 133 30 54 16411 [ 420 784 1140 1350 ] [ 7 7 21 7 1 37 19 26 ] ]
[ (full) (30) v27to40 137 137 26 52 17483 [ 450 812 1200 1440 ] [ 5 10 19 10 15 25 23 25 ] ]
[ (full) (31) v27to40 141 141 30 56 18587 [ 480 868 1290 1530 ] [ 13 3 2 29 42 1 23 28 ] ]
[ (full) (32) v27to40 145 145 34 60 19723 [ 510 924 1350 1620 ] [ 17 0 10 23 10 35 19 35 ] ]
[ (full) (33) v27to40 149 149 30 58 20891 [ 540 980 1440 1710 ] [ 17 1 14 21 29 19 11 46 ] ]
[ (full) (34) v27to40 153 153 34 62 22091 [ 570 1036 1530 1800 ] [ 13 6 14 23 44 7 59 1 ] ]
[ (full) (35) v27to40 157 157 30 54 23008 [ 570 1064 1590 1890 ] [ 12 7 12 26 39 14 22 41 ] ]
[ (full) (36) v27to40 161 161 24 50 24272 [ 600 1120 1680 1980 ] [ 6 14 6 34 46 10 2 64 ] ]
[ (full) (37) v27to40 165 165 28 54 25568 [ 630 1204 1770 2100 ] [ 17 4 29 14 49 10 24 46 ] ]
[ (full) (38) v27to40 169 169 32 58 26896 [ 660 1260 1860 2220 ] [ 4 18 13 32 48 14 42 32 ] ]
[ (full) (39) v27to40 173 173 26 54 28256 [ 720 1316 1950 2310 ] [ 20 4 40 7 43 22 10 67 ] ]
[ (full) (40) v27to40 177 177 30 58 29648 [ 750 1372 2040 2430 ] [ 19 6 18 31 34 34 20 61 ] ]
[ (rmqr) (R7x43) vR7x43 7 43 22 99 104 [ 99 7 99 10 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R7x59) vR7x59 7 59 20 40 171 [ 99 9 99 14 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R7x77) vR7x77 7 77 26 52 261 [ 99 12 99 22 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R7x99) vR7x99 7 99 24 50 358 [ 99 16 99 30 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R7x139) vR7x139 7 139 28 56 545 [ 99 24 99 44 ] [ -1 -1 1 0 -1 -1 2 0 ] ]
[ (rmqr) (R9x43) vR9x43 9 43 22 99 170 [ 99 9 99 14 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R9x59) vR9x59 9 59 20 40 267 [ 99 12 99 22 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R9x77) vR9x77 9 77 26 52 393 [ 99 18 99 32 ] [ -1 -1 1 0 -1 -1 1 1 ] ]
[ (rmqr) (R9x99) vR9x99 9 99 24 50 532 [ 99 24 99 44 ] [ -1 -1 1 0 -1 -1 2 0 ] ]
[ (rmqr) (R9x139) vR9x139 9 139 28 56 797 [ 99 36 99 66 ] [ -1 -1 1 1 -1 -1 3 0 ] ]
[ (rmqr) (R11x27) vR11x27 11 27 98 99 122 [ 99 8 99 10 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R11x43) vR11x43 11 43 22 99 249 [ 99 12 99 20 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R11x59) vR11x59 11 59 20 40 376 [ 99 16 99 32 ] [ -1 -1 1 0 -1 -1 1 1 ] ]
[ (rmqr) (R11x77) vR11x77 11 77 26 52 538 [ 99 24 99 44 ] [ -1 -1 1 0 -1 -1 1 1 ] ]
[ (rmqr) (R11x99) vR11x99 11 99 24 50 719 [ 99 32 99 60 ] [ -1 -1 1 1 -1 -1 1 1 ] ]
[ (rmqr) (R11x139) vR11x139 11 139 28 56 1062 [ 99 48 99 90 ] [ -1 -1 2 0 -1 -1 3 0 ] ]
[ (rmqr) (R13x27) vR13x27 13 27 98 99 172 [ 99 9 99 14 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R13x43) vR13x43 13 43 22 99 329 [ 99 14 99 28 ] [ -1 -1 1 0 -1 -1 1 0 ] ]
[ (rmqr) (R13x59) vR13x59 13 59 20 40 486 [ 99 22 99 40 ] [ -1 -1 1 0 -1 -1 2 0 ] ]
[ (rmqr) (R13x77) vR13x77 13 77 26 52 684 [ 99 32 99 56 ] [ -1 -1 1 1 -1 -1 1 1 ] ]
[ (rmqr) (R13x99) vR13x99 13 99 24 50 907 [ 99 40 99 78 ] [ -1 -1 1 1 -1 -1 1 2 ] ]
[ (rmqr) (R13x139) vR13x139 13 139 28 56 1328 [ 99 60 99 112 ] [ -1 -1 2 1 -1 -1 2 2 ] ]
[ (rmqr) (R15x43) vR15x43 15 43 22 99 409 [ 99 18 99 36 ] [ -1 -1 1 0 -1 -1 1 1 ] ]
[ (rmqr) (R15x59) vR15x59 15 59 20 40 596 [ 99 26 99 48 ] [ -1 -1 1 0 -1 -1 2 0 ] ]
[ (rmqr) (R15x77) vR15x77 15 77 26 52 830 [ 99 36 99 72 ] [ -1 -1 1 1 -1 -1 2 1 ] ]
[ (rmqr) (R15x99) vR15x99 15 99 24 50 1095 [ 99 48 99 88 ] [ -1 -1 2 0 -1 -1 4 0 ] ]
[ (rmqr) (R15x139) vR15x139 15 139 28 56 1594 [ 99 72 99 130 ] [ -1 -1 2 1 -1 -1 1 4 ] ]
[ (rmqr) (R17x43) vR17x43 17 43 22 99 489 [ 99 22 99 40 ] [ -1 -1 1 0 -1 -1 1 1 ] ]
[ (rmqr) (R17x59) vR17x59 17 59 20 40 706 [ 99 32 99 60 ] [ -1 -1 2 0 -1 -1 2 0 ] ]
[ (rmqr) (R17x77) vR17x77 17 77 26 52 976 [ 99 44 99 84 ] [ -1 -1 2 0 -1 -1 1 2 ] ]
[ (rmqr) (R17x99) vR17x99 17 99 24 50 1283 [ 99 60 99 104 ] [ -1 -1 2 1 -1 -1 4 0 ] ]
[ (rmqr) (R17x139) vR17x139 17 139 28 56 1860 [ 99 80 99 156 ] [ -1 -1 4 0 -1 -1 2 4 ] ]
] def
} ctxdef
/eclval (LMQH) eclevel search pop length exch pop exch pop def
0 1 metrics length 1 sub {
/i exch def
/m metrics i get def
/frmt m 0 get def % Format of the symbol
/vers m 1 get def % Version of symbol
/vergrp m 2 get def % Version group
/verind i 44 sub def % Version indicator for rMQR format info
/rows m 3 get def % Length of side
/cols m 4 get def % Length of side
/asp2 m 5 get def % Position of second alignment symbol
/asp3 m 6 get def % Position of third alignment symbol
/nmod m 7 get def % Number of modules
/ncws nmod 8 idiv def % Total number of codewords
/rbit nmod 8 mod def % Number of remainder bits
/lc4b false def % Last data codeword is 4 bits long
vers (M1) eq vers (M3) eq or { % Adjustments for M1 and M3 symbols
/ncws ncws 1 add def
/rbit 0 def
/lc4b true def
} if
/ecws m 8 get eclval get def % Number of error correction codewords
/dcws ncws ecws sub def % Number of data codewords
/dmod dcws 8 mul lc4b {4} {0} ifelse sub def % Number of data modules
/ecb1 m 9 get eclval 2 mul get def % First error correction blocks
/ecb2 m 9 get eclval 2 mul 1 add get def % Second error correction blocks
/okay true def
format frmt ne {/okay false def} if % The format must match that supplied
frmt (micro) eq fnc1first and {/okay false def} if % FNC1 mode is only available in full and rmqr
version (unset) ne version vers ne and {/okay false def} if % The version must match that supplied
ecb1 -1 eq ecb2 -1 eq or {/okay false def} if % Error correction level must be valid
/verbits msgbits vergrp get def
verbits -1 eq { % Bitstream must be available
/okay false def
} {
verbits length dmod gt {/okay false def} if % and fit into data modules
} ifelse
/term (000000000) 0 termlens vergrp get getinterval def
okay {exit} if
} for
okay not {
/bwipp.qrcodeNoValidSymbol (Maximum length exceeded or invalid content) //raiseerror exec
} if
/format frmt def
/version vers def
/msgbits verbits def
% Opportunistically raise the error level if a better fit to the matrix is possible
fixedeclevel not {
eclval 1 add 1 3 {
/eclval_ exch def
/ecws_ m 8 get eclval_ get def % Number of error correction codewords
/dcws_ ncws ecws_ sub def % Number of data codewords
/dmod_ dcws_ 8 mul lc4b {4} {0} ifelse sub def % Number of data modules
/ecb1_ m 9 get eclval_ 2 mul get def % First error correction blocks
/ecb2_ m 9 get eclval_ 2 mul 1 add get def % Second error correction blocks
/okay true def
ecb1_ -1 eq ecb2_ -1 eq or {/okay false def} if % Error correction level must be valid
msgbits length dmod_ gt {/okay false def} if % and fit into data modules
okay {
/eclval eclval_ def
/dcws dcws_ def
/dmod dmod_ def
/ecb1 ecb1_ def
/ecb2 ecb2_ def
} if
} for
} if
/dcpb dcws ecb1 ecb2 add idiv def % Base data codewords per block
/ecpb ncws ecb1 ecb2 add idiv dcpb sub def % Error correction codewords per block
% Complete the message bits by adding the terminator, truncated if necessary
/term term 0 dmod msgbits length sub term length 2 copy gt {exch} if pop getinterval def
msgbits length term length add string
dup 0 msgbits putinterval
dup msgbits length term putinterval
/msgbits exch def
% Expand the message bits by adding padding as necessary
/pad dmod string def
0 1 pad length 1 sub {pad exch 48 put} for
pad 0 msgbits putinterval
/padnum 0 def
msgbits length 8 div ceiling 8 mul cvi 8 dmod lc4b {5} {1} ifelse sub {
pad exch padstrs padnum get putinterval
/padnum padnum 1 add 2 mod def
} for
% Evaluate the padded message into codewords
/cws dcws array def
0 1 cws length 1 sub {
/c exch def
/bpcw 8 def
lc4b c cws length 1 sub eq and {/bpcw 4 def} if
/cwb pad c 8 mul bpcw getinterval def
/cw 0 def
0 1 bpcw 1 sub {
/i exch def
/cw cw 2 bpcw i sub 1 sub exp cvi cwb i get 48 sub mul add def
} for
cws c cw put
} for
% Short final data byte in M1 and M3 symbols has high-order value
lc4b {cws cws length 1 sub 2 copy get 4 bitshift put} if
options /debugcws known { /bwipp.debugcws cws //raiseerror exec } if
% Calculate the log and anti-log tables
{
/rsalog [ 1 255 { dup 2 mul dup 256 ge {285 xor} if } repeat ] def
/rslog 256 array def
1 1 255 {dup rsalog exch get exch rslog 3 1 roll put} for
} ctxdef
% Function to calculate the product in the field
/rsprod {
2 copy 0 ne exch 0 ne and {
rslog exch get exch rslog exch get add 255 mod rsalog exch get
} {
pop pop 0
} ifelse
} def
% Generate the coefficients for the Reed-Solomon algorithm
/coeffs [ 1 ecpb {0} repeat ] def
0 1 ecpb 1 sub {
/i exch def
coeffs i 1 add coeffs i get put
i -1 1 {
/j exch def
coeffs j coeffs j 1 sub get coeffs j get rsalog i get rsprod xor put
} for
coeffs 0 coeffs 0 get rsalog i get rsprod put
} for
/coeffs coeffs 0 coeffs length 1 sub getinterval def
% Reed-Solomon algorithm to derive the error correction codewords
/rscodes {
/rscws exch def
/rsnd rscws length def
/rscws [ rscws aload pop ecpb {0} repeat ] def
0 1 rsnd 1 sub {
/m exch def
/k rscws m get def
0 1 ecpb 1 sub {
/j exch def
rscws m j add 1 add coeffs ecpb j sub 1 sub get k rsprod rscws m j add 1 add get xor put
} for
} for
rscws rsnd ecpb getinterval
} def
% Divide codewords into two groups of blocks and calculate the error correction codewords
/dcwsb ecb1 ecb2 add array def
/ecwsb ecb1 ecb2 add array def
0 1 ecb1 1 sub { % First group of blocks has smaller number of data codewords
/i exch def
dcwsb i cws i dcpb mul dcpb getinterval put
ecwsb i dcwsb i get rscodes put
} for
0 1 ecb2 1 sub { % Second group of blocks has larger number of data codewords
/i exch def
dcwsb ecb1 i add cws ecb1 dcpb mul i dcpb 1 add mul add dcpb 1 add getinterval put
ecwsb ecb1 i add dcwsb ecb1 i add get rscodes put
} for
% Reassemble the codewords
/cws ncws array def
/cw 0 def
0 1 dcpb { % Interleave the data codeword blocks
/i exch def
0 1 ecb1 ecb2 add 1 sub {
/j exch def
i dcwsb j get length lt { % Ignore the end of short blocks
cws cw dcwsb j get i get put
/cw cw 1 add def
} if
} for
} for
0 1 ecpb 1 sub { % Interleave the error codeword blocks
/i exch def
0 1 ecb1 ecb2 add 1 sub {
/j exch def
cws cw ecwsb j get i get put
/cw cw 1 add def
} for
} for
% Extend codewords by one if there are remainder bits
rbit 0 gt {
/pad cws length 1 add array def
pad 0 cws putinterval
pad pad length 1 sub 0 put
/cws pad def
} if
% Fixups for the short final data byte in M1 and M3 symbols
lc4b {
cws dcws 1 sub 2 copy get -4 bitshift put
dcws 1 sub 1 ncws 2 sub {
/i exch def
cws i cws i get 15 and 4 bitshift put
cws i cws i 1 add get -4 bitshift 15 and cws i get or put
} for
cws ncws 1 sub cws ncws 1 sub get 15 and 4 bitshift put
} if
options /debugecc known { /bwipp.debugecc cws //raiseerror exec } if
% Create the bitmap
/pixs [ rows cols mul {-1} repeat ] def
/qmv {cols mul add} def
% Timing patterns
format (full) eq {
8 1 cols 9 sub {
/i exch def
pixs i 6 qmv i 1 add 2 mod put
pixs 6 i qmv i 1 add 2 mod put
} for
} if
format (micro) eq {
8 1 cols 1 sub {
/i exch def
pixs i 0 qmv i 1 add 2 mod put
pixs 0 i qmv i 1 add 2 mod put
} for
} if
format (rmqr) eq {
3 1 cols 4 sub { % Along top and bottom
/i exch def
pixs i 0 qmv i 1 add 2 mod put
pixs i rows 1 sub qmv i 1 add 2 mod put
} for
3 1 rows 4 sub { % Along left and right
/i exch def
pixs 0 i qmv i 1 add 2 mod put
pixs cols 1 sub i qmv i 1 add 2 mod put
} for
asp2 1 sub asp3 asp2 sub cols 13 sub { % Down interior
/i exch def
3 1 rows 4 sub {
/j exch def
pixs i j qmv j 1 add 2 mod put
} for
} for
} if
% Finder patterns
{
/fpat [
[ 1 1 1 1 1 1 1 0 ]
[ 1 0 0 0 0 0 1 0 ]
[ 1 0 1 1 1 0 1 0 ]
[ 1 0 1 1 1 0 1 0 ]
[ 1 0 1 1 1 0 1 0 ]
[ 1 0 0 0 0 0 1 0 ]
[ 1 1 1 1 1 1 1 0 ]
[ 0 0 0 0 0 0 0 0 ]
] def
/fsubpat [
[ 1 1 1 1 1 9 9 9 ]
[ 1 0 0 0 1 9 9 9 ]
[ 1 0 1 0 1 9 9 9 ]
[ 1 0 0 0 1 9 9 9 ]
[ 1 1 1 1 1 9 9 9 ]
[ 9 9 9 9 9 9 9 9 ]
[ 9 9 9 9 9 9 9 9 ]