-
-
Notifications
You must be signed in to change notification settings - Fork 67
/
Copy pathazteccode.ps.src
863 lines (772 loc) · 31.2 KB
/
azteccode.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
% 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 azteccode--
% --REQUIRES preamble loadctx unloadctx raiseerror processoptions parseinput renmatrix--
% --DESC: Aztec Code
% --EXAM: This is Aztec Code
% --EXOP: format=full
% --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
/azteccode {
20 dict begin
/ctx null def
/dontdraw false def
/format (full) def % full, compact or rune
/readerinit false def
/layers -1 def
/eclevel 23 def
/ecaddchars 3 def
/raw false def
/parse false def
/parsefnc false def
//processoptions exec /options exch def
/barcode exch def
/azteccode //loadctx exec
barcode () eq {
/bwipp.aztecEmptyData (The data must not be empty) //raiseerror exec
} if
eclevel 5 lt eclevel 95 gt or {
/bwipp.aztecInvalidEClevel (The EC percentage must be from 5 to 95) //raiseerror exec
} if
ecaddchars 3 lt {
/bwipp.aztecInvalidECaddChars (The number of additional EC codewords must be 3 or more) //raiseerror exec
} if
format (full) ne format (compact) ne format (rune) ne and and {
/bwipp.aztecInvalidFormat (The format must be either full, compact or rune) //raiseerror exec
} if
format (full) eq {
readerinit layers 1 lt layers 22 gt or and {
/bwipp.aztecFullInitInvalidLayers (Full-range symbols for reader programming must specify from 1 to 22 layers) //raiseerror exec
} if
layers -1 ne layers 1 lt layers 32 gt or and {
/bwipp.aztecFullInvalidLayers (Layers for full-range symbols must be from 1 to 32) //raiseerror exec
} if
} if
format (compact) eq {
readerinit {
layers -1 ne layers 1 ne and {
/bwipp.aztecCompactInitInvalidLayers (Compact symbols for reader programming must have 1 layer) //raiseerror exec
} if
/layers 1 def
} if
layers -1 ne layers 1 lt layers 4 gt or and {
/bwipp.aztecCompactInvalidLayers (Layers for compact symbols must be from 1 to 4) //raiseerror exec
} if
} if
format (rune) eq {
layers -1 ne {
/bwipp.aztecRuneInvalidLayers (It is not valid to specify layers for runes) //raiseerror exec
} if
readerinit {
/bwipp.aztecRuneReaderInit (Reader initialisation is not compactible with Aztec Runes) //raiseerror exec
} if
barcode length 0 eq {
/bwipp.aztecRuneNotNumeric (Aztec runes must be numeric) //raiseerror exec
} if
barcode {
dup 48 lt exch 57 gt or {
/bwipp.aztecRuneNotNumeric (Aztec runes must be numeric) //raiseerror exec
} if
} forall
barcode cvi dup 0 lt exch 255 gt or {
/bwipp.aztecRuneInvalid (Aztec runes must be 0 to 255) //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
{
% State key: "U"pper, "L"ower, "M"ixed, "P"unctuation, "D"igit, "B"inary
/U 0 def /L 1 def /M 2 def /P 3 def /D 4 def /B 5 def
% Special function characters
/lu -2 def /ll -3 def /lm -4 def
/lp -5 def /ld -6 def /su -7 def
/sp -8 def /sb -9 def /fl -10 def
/p2 -11 def /p3 -12 def /p4 -13 def /p5 -14 def
% Character maps for each state
/charmaps [
% U L M P D
[ sp sp sp fl sp ] % 0
[ 32 32 32 13 32 ] % 1
[ (A) (a) 1 p2 (0) ] % 2 p2 = CR LF
[ (B) (b) 2 p3 (1) ] % 3 p3 = ". "
[ (C) (c) 3 p4 (2) ] % 4 p4 = ", "
[ (D) (d) 4 p5 (3) ] % 5 p5 = ": "
[ (E) (e) 5 (!) (4) ] % 6
[ (F) (f) 6 (") (5) ] % 7
[ (G) (g) 7 (#) (6) ] % 8
[ (H) (h) 8 ($) (7) ] % 9
[ (I) (i) 9 (%) (8) ] % 10
[ (J) (j) 10 (&) (9) ] % 11
[ (K) (k) 11 (') (,) ] % 12
[ (L) (l) 12 40 (.) ] % 13
[ (M) (m) 13 41 lu ] % 14
[ (N) (n) 27 (*) su ] % 15
[ (O) (o) 28 (+) -99 ] % 16
[ (P) (p) 29 (,) -99 ] % 17
[ (Q) (q) 30 (-) -99 ] % 18
[ (R) (r) 31 (.) -99 ] % 19
[ (S) (s) (@) (/) -99 ] % 20
[ (T) (t) 92 (:) -99 ] % 21
[ (U) (u) (^) (;) -99 ] % 22
[ (V) (v) (_) (<) -99 ] % 23
[ (W) (w) (`) (=) -99 ] % 24
[ (X) (x) (|) (>) -99 ] % 25
[ (Y) (y) (~) (?) -99 ] % 26
[ (Z) (z) 127 ([) -99 ] % 27
[ ll su ll (]) -99 ] % 28
[ lm lm lu ({) -99 ] % 29
[ ld ld lp (}) -99 ] % 30
[ sb sb sb lu -99 ] % 31
] def
% Invert charmaps to give character to value maps for each state
/charvals [ 32 dict 32 dict 32 dict 32 dict 16 dict ] def
0 1 charmaps length 1 sub {
/i exch def
/encs charmaps i get def
0 1 4 {
/j exch def
encs j get dup type /stringtype eq {0 get} if % convert string to ASCII if required
charvals j get exch i put
} for
} for
% Punctuation compression
/pcomp <<
<0d0a> p2 % CR LF
(. ) p3
(, ) p4
(: ) p5
>> def
/e 1000000 def % "Empty"
/latlen [ % Bit length of latch between states
% To: U L M P D B From
[ 0 5 5 10 5 10 ] % U
[ 9 0 5 10 5 10 ] % L
[ 5 5 0 5 10 10 ] % M
[ 5 10 10 0 10 15 ] % P
[ 4 9 9 14 0 14 ] % D
[ 0 0 0 0 0 0 ] % B
] def
/latseq [ % Latch sequences between states
% To: U L M P D B From
[ [] [ll] [lm] [lm lp] [ld] [sb] ] % U
[ [ld lu] [] [lm] [lm lp] [ld] [sb] ] % L
[ [lu] [ll] [] [lp] [lu ld] [sb] ] % M
[ [lu] [lu ll] [lu lm] [] [lu ld] [lu sb] ] % P
[ [lu] [lu ll] [lu lm] [lu lm lp] [] [lu sb] ] % D
[ [lu] [ll] [lm] [] [] [] ] % B
] def
/shftlen [ % Bit length of shift to state
% To: U L M P D From
[ e e e 5 e ] % U
[ 5 e e 5 e ] % L
[ e e e 5 e ] % M
[ e e e e e ] % P
[ 4 e e 4 e ] % D
] def
} ctxdef
% Convert from input into message bitstream
/msgbits () def
format (rune) ne raw and {/msgbits barcode def} if
format (rune) ne raw not and {
/charsize {
dup 0 ge {
% U L M P D B
pop [ 5 5 5 5 4 8 ] exch get
} { % FNC or ECI in P
exch pop
dup fn1 eq { % FNC1: PS{Flg(0)} + 3
pop 8
} { % ECI: PS{Flg(n)} + 3 + 4n
neg 1000000 sub dup 0 eq {pop 1} if
ln 10 ln div cvi 1 add 4 mul 8 add
} ifelse
} ifelse
} def
% U L M P D B
/curlen [ 0 e e e e e ] def
/curseq [ [] [] [] [] [] [] ] def
/backto U def % U
/lastchar () def
% Derive the optimal sequences ending in each state
msg {
/char exch def
% Check for optimisations in the current sequences by latching from x to y
{ % loop
/imp false def
[ U L M P D B ] {
/x exch def
[ U L M P D B ] {
/y exch def
x B ne y backto eq or { % Only B -> backto
/cost curlen x get latlen x get y get add def
cost curlen y get lt {
curlen y cost put
curseq y [
curseq x get aload pop
latseq x get y get aload pop
] put
y B eq { % Set backto to previous state
/backto x P eq x D eq or {U} {x} ifelse def
} if
/imp true def
} if
} if
} forall
} forall
imp not {exit} if % Repeat unless no improvement
} loop
% Determine optimal next sequences for each valid encoding
/nxtlen [ e e e e e e ] def
/nxtseq 6 array def
[ U L M P D B ] {
/x exch def
{ % loop for common exit
% Skip states that cannot encode character
char 0 ge {
x B ne {charvals x get char known not {exit} if} if
} {
x P ne {exit} if % Only P can encode FNC1 and ECI
} ifelse
% Extend directly
/cost curlen x get x char charsize add def
cost nxtlen x get lt {
nxtlen x cost put
nxtseq x [ curseq x get aload pop char ] put
} if
% Optimise for direct shifts from y to x
x B eq {exit} if % B is treated as a latch
[ U L M P D ] {
/y exch def
x y ne {
/cost curlen y get shftlen y get x get add x char charsize add def
cost nxtlen y get lt {
nxtlen y cost put
nxtseq y [
curseq y get aload pop
x U eq {su} {sp} ifelse
char
] put
} if
} if
} forall
exit
} loop
} forall
% Optimise using P compression
lastchar () ne char 0 ge and {
/pchars 2 string dup 0 lastchar put dup 1 char put def
pcomp pchars known {
[ U L M P D ] {
/i exch def
/inP true def % U and L can't encode CR, comma, dot or colon
i M eq { % M can encode CR
lastchar 13 eq { /inP false def } if
} {
i D eq { % D can encode comma and dot
lastchar 44 eq lastchar 46 eq or { /inP false def } if
} if
} ifelse
inP curlen i get nxtlen i get lt and {
/curseqi curseq i get def
/lastld false def
/lastsp false def
/lastidx -1 def
curseqi length 1 sub -1 0 { % Search backwards for lastchar
/idx exch def
/ch curseqi idx get def
lastidx -1 eq {
ch lastchar eq {
/lastidx idx def
idx 0 gt {
curseqi idx 1 sub get sp eq { /lastsp true def } if % Preceded by P/S
} if
} if
} { % Found lastchar, check latch
ch 0 lt ch ld ge and { % If have latch
i P eq {
ch ld eq { /lastld true def } if % Set flag if D/L for adjustment below
} {
ch lp ne { /inP lastsp def } if % If not P/L only in P if have P/S
} ifelse
exit
} if
} ifelse
} for
inP lastidx 0 ge and {
nxtlen i curlen i get put
lastidx curseqi length 1 sub lt { % If lastchar not at end of sequence
i P eq {
lastld { nxtlen i nxtlen i get 1 add put } if % Adjust count if D/L
% Move lastchar to end and replace
nxtseq i [ curseqi aload pop curseqi length lastidx sub -1 roll pop pcomp pchars get ] put
} {
% Replace lastchar in situ
nxtseq i [ curseqi aload pop ] put
nxtseq i get lastidx pcomp pchars get put
} ifelse
} {
nxtseq i [ curseqi aload pop pop pcomp pchars get ] put
} ifelse
} if
} if
} forall
} if
} if
% Account for binary extension for 32 or more bytes
nxtseq B get null ne {
/numbytes 0 def
nxtseq B get {
sb eq {0} {numbytes 1 add} ifelse /numbytes exch def
} forall
numbytes 32 eq {nxtlen B nxtlen B get 11 add put} if
} if
/curlen nxtlen def
/curseq nxtseq def
/lastchar char 0 ge {char} {()} ifelse def
} forall
% Select the optimal sequence
/minseq e def
[ U L M P D B ] {
/i exch def
curlen i get minseq lt {
/minseq curlen i get def
/seq curseq i get def
} if
} forall
% 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
/encu {charvals U get exch get 5 tobin} def
/encl {charvals L get exch get 5 tobin} def
/encm {charvals M get exch get 5 tobin} def
/encd {charvals D get exch get 4 tobin} def
/encp {
dup fn1 eq { % FNC1: Flg(0)
pop (00000000)
} {
dup -1000000 le { % ECI: Flg(n) + n-Digits
neg 1000000 sub dup dup 0 eq {pop 1} if
ln 10 ln div cvi
dup 1 add 4 mul 8 add string
dup 0 (00000) putinterval % Flg(n)
dup 2 index 1 add 3 tobin 5 exch putinterval % len
3 1 roll -1 0 { % ECI digits in "Digit" encoding
4 mul 8 add exch
dup 10 idiv 3 index 4 2 roll
10 mod 2 add 4 tobin putinterval
} for
pop
} {
charvals P get exch get 5 tobin
} ifelse } ifelse
} def
/encfuncs [ /encu /encl /encm /encp /encd ] def
/addtomsgbits {
/v exch def
msgbits j v putinterval
/j j v length add def
} def
% Encode the sequence
/state U def
/msgbits minseq string def
/i 0 def /j 0 def {
i seq length ge {exit} if
state B ne {
/char seq i get def
% Encode character
char encfuncs state get load exec addtomsgbits
/i i 1 add def
% Encode shifted next character
char su eq char sp eq or {
seq i get char su eq {encu} {encp} ifelse addtomsgbits
/i i 1 add def
} if
% Latches to new state
char lu eq {/state U def} if
char ll eq {/state L def} if
char lm eq {/state M def} if
char lp eq {/state P def} if
char ld eq {/state D def} if
char sb eq {/state B def} if
} { % Binary
% Find number of bytes before latch or end
/numbytes 0 def {
i numbytes add seq length ge {exit} if
seq i numbytes add get 0 lt {exit} if
/numbytes numbytes 1 add def
} loop
% Encode length
numbytes 31 le {
numbytes 5 tobin addtomsgbits
} {
0 5 tobin addtomsgbits
numbytes 31 sub 11 tobin addtomsgbits
} ifelse
% Encode bytes
numbytes {
seq i get 8 tobin addtomsgbits
/i i 1 add def
} repeat
% Return to previous state as indicated
i seq length lt {
/char seq i get def
/i i 1 add def
char lu eq {/state U def} if
char ll eq {/state L def} if
char lm eq {/state M def} if
} if
} ifelse
} loop
} if
% Lookup the most appropriate symbol specification
{
/metrics [
[ (rune) 0 0 0 6 ] % Special metric for rune symbols
[ (compact) 1 1 17 6 ] [ (full) 1 1 21 6 ] [ (compact) 2 0 40 6 ]
[ (full) 2 1 48 6 ] [ (compact) 3 0 51 8 ] [ (full) 3 1 60 8 ]
[ (compact) 4 0 76 8 ] [ (full) 4 1 88 8 ] [ (full) 5 1 120 8 ]
[ (full) 6 1 156 8 ] [ (full) 7 1 196 8 ] [ (full) 8 1 240 8 ]
[ (full) 9 1 230 10 ] [ (full) 10 1 272 10 ] [ (full) 11 1 316 10 ]
[ (full) 12 1 364 10 ] [ (full) 13 1 416 10 ] [ (full) 14 1 470 10 ]
[ (full) 15 1 528 10 ] [ (full) 16 1 588 10 ] [ (full) 17 1 652 10 ]
[ (full) 18 1 720 10 ] [ (full) 19 1 790 10 ] [ (full) 20 1 864 10 ]
[ (full) 21 1 940 10 ] [ (full) 22 1 1020 10 ] [ (full) 23 0 920 12 ]
[ (full) 24 0 992 12 ] [ (full) 25 0 1066 12 ] [ (full) 26 0 1144 12 ]
[ (full) 27 0 1224 12 ] [ (full) 28 0 1306 12 ] [ (full) 29 0 1392 12 ]
[ (full) 30 0 1480 12 ] [ (full) 31 0 1570 12 ] [ (full) 32 0 1664 12 ]
] def
} ctxdef
metrics {
/m exch def
/frmt m 0 get def % Format of the symbol
/mlyr m 1 get def % Data layers
/icap m 2 get def % Reader initialisation capable
/ncws m 3 get def % Total of codewords
/bpcw m 4 get def % Bits per codeword
/numecw ncws eclevel mul 100 div ecaddchars add ceiling cvi def
msgbits length 0 eq {/numecw 0 def} if % Error correction codewords
/numdcw ncws numecw sub def % Data codewords
/okay true def
format frmt ne {/okay false def} if
readerinit icap 1 ne and {/okay false def} if
layers -1 ne layers mlyr ne and {/okay false def} if
msgbits length bpcw div ceiling cvi numdcw gt {/okay false def} if
okay {exit} if
} forall
okay not {
/bwipp.aztecNoValidSymbol (Maximum length exceeded) //raiseerror exec
} if
/layers mlyr def
% Expand message bits into codewords avoiding codewords with all zeros or all ones
/allzero {dup length (000000000000) 0 3 -1 roll getinterval eq} def
/allones {dup length (111111111111) 0 3 -1 roll getinterval eq} def
/cws ncws array def
/m 0 def /c 0 def
{
msgbits length m le {exit} if
msgbits length m sub bpcw ge {
/cwb msgbits m bpcw 1 sub getinterval def % All but last bit
/cwf msgbits m bpcw add 1 sub 1 getinterval def % Last bit
cwb allzero {/cwf (1) def /m m 1 sub def} if % Flip last bit to avoid zeros
cwb allones {/cwf (0) def /m m 1 sub def} if % Flip last bit to avoid ones
% Concatenate the bits
12 string dup 0 cwb putinterval
dup bpcw 1 sub cwf putinterval
0 bpcw getinterval
/cwb exch def
} { % Final codeword
/cwb msgbits m msgbits length m sub getinterval def
/cwb (111111111111) 12 string copy dup 0 cwb putinterval 0 bpcw getinterval def
cwb allones {cwb cwb length 1 sub (0) putinterval} if % Prevent all ones
} ifelse
% Conversion of binary data into byte array
/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
/m m bpcw add def
/c c 1 add def
} loop
/cws cws 0 c getinterval def
options /debugcws known { /bwipp.debugcws cws //raiseerror exec } if
% Reed-Solomon algorithm
/rscodes {
/rspm exch def
/rsgf exch def
/rsnc exch def
/rscws exch def
% Calculate the log and anti-log tables
/rsalog [ 1 rsgf 1 sub { dup 2 mul dup rsgf ge {rspm xor} if } repeat ] def
/rslog rsgf array def
1 1 rsgf 1 sub {dup rsalog exch get exch rslog 3 1 roll put} for
% 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 rsgf 1 sub mod rsalog exch get
} {
pop pop 0
} ifelse
} def
% Generate the coefficients
/coeffs [ 1 rsnc {0} repeat ] def
1 1 rsnc {
/i exch def
coeffs i coeffs i 1 sub get put
i 1 sub -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
% Extend the input with the error correction values
/nd rscws length def
/rscws [ rscws aload pop rsnc {0} repeat 0 ] def
0 1 nd 1 sub {
/k exch rscws exch get rscws nd get xor def
0 1 rsnc 1 sub {
/j exch def
rscws nd j add rscws nd j add 1 add get k coeffs rsnc j sub 1 sub get rsprod xor put
} for
} for
% Return all but the last codeword
rscws 0 rscws length 1 sub getinterval
} def
% Create the codewords and bit string for the mode
format (full) eq {
/mode layers 1 sub 11 bitshift cws length 1 sub add def
readerinit {/mode mode 2#0000010000000000 or def} if
/mode [
mode 2#1111000000000000 and -12 bitshift
mode 2#0000111100000000 and -8 bitshift
mode 2#0000000011110000 and -4 bitshift
mode 2#0000000000001111 and
] def
/mode mode 6 16 19 rscodes def
} if
format (compact) eq {
/mode layers 1 sub 6 bitshift cws length 1 sub add def
readerinit {/mode mode 2#00100000 or def} if
/mode [
mode 2#11110000 and -4 bitshift
mode 2#00001111 and
] def
/mode mode 5 16 19 rscodes def
} if
format (rune) eq {
/mode barcode cvi def
/mode [
mode 2#11110000 and -4 bitshift
mode 2#00001111 and
] def
/mode mode 5 16 19 rscodes def
/mode [mode {2#1010 xor} forall] def % Invert alternate bits
} if
/modebits mode length 4 mul string def
0 1 modebits length 1 sub {modebits exch (0) putinterval} for
0 1 mode length 1 sub {
/i exch def
modebits mode i get 2 4 string cvrs dup length 4 exch sub 4 i mul add exch putinterval
} for
% Extend the data codewords with error correction codewords to create the bit string for the data
{
/rsparams [
[] [] [] [] [] []
[ 64 67 ] % 6-bit codewords
[]
[ 256 301 ] % 8-bit codewords
[]
[ 1024 1033 ] % 10-bit codewords
[]
[ 4096 4201 ] % 12-bit codewords
] def
} ctxdef
/cws cws ncws cws length sub rsparams bpcw get aload pop rscodes def
format (full) eq {
/databits layers layers mul 16 mul layers 112 mul add string def
} {
/databits layers layers mul 16 mul layers 88 mul add string def
} ifelse
0 1 databits length 1 sub {databits exch (0) putinterval} for
0 1 ncws 1 sub {
/i exch def
databits cws i get 2 bpcw string cvrs
dup length bpcw exch sub bpcw i mul add databits length ncws bpcw mul sub add
exch putinterval
} for
% Move to a point in the cartesian plane centered on the bullseye
/cmv {size mul sub mid add} def
% Move to a bit position within a layer
/lmv {
/lbit exch def
/llyr exch def
/lwid fw llyr 4 mul add def
/ldir lbit 2 idiv lwid idiv def
ldir 0 eq { % Top
lwid 1 sub 2 idiv neg 1 add lbit 2 idiv lwid mod add
fw 1 sub 2 idiv llyr 2 mul add lbit 2 mod add
cmv
} if
ldir 1 eq { % Right
fw 2 idiv llyr 2 mul add lbit 2 mod add
lwid 1 sub 2 idiv 1 sub lbit 2 idiv lwid mod sub
cmv
} if
ldir 2 eq { % Bottom
lwid 2 idiv neg 1 add lbit 2 idiv lwid mod add neg
fw 2 idiv llyr 2 mul add lbit 2 mod add neg
cmv
} if
ldir 3 eq { % Left
fw 1 sub 2 idiv llyr 2 mul add lbit 2 mod add neg
lwid 2 idiv 1 sub lbit 2 idiv lwid mod sub neg
cmv
} if
} def
% Create the pixel map
% For full symbols we disregard the reference grid at this stage
format (full) eq {/fw 12 def} {/fw 9 def} ifelse
/size fw layers 4 mul add 2 add def
/pixs [size size mul {-1} repeat] def
/mid size 1 sub 2 idiv size mul size 1 sub 2 idiv add def
% Data layers
/i 0 def
1 1 layers {
/layer exch def
0 1 fw layer 4 mul add 8 mul 1 sub {
/pos exch def
pixs layer pos lmv databits databits length i sub 1 sub get 48 sub put
/i i 1 add def
} for
} for
% For full symbols expand the pixel map by inserting the reference grid
format (full) eq {
/fw 13 def
/size fw layers 4 mul add 2 add layers 10.5 add 7.5 div 1 sub cvi 2 mul add def
/mid size size mul 2 idiv def
/npixs [size size mul {-2} repeat] def
0 16 size 2 idiv {
/i exch def
0 1 size 1 sub {
/j exch def
npixs size 2 idiv neg j add i cmv [size 2 idiv j add i add 1 add 2 mod] putinterval
npixs size 2 idiv neg j add i neg cmv [size 2 idiv j add i add 1 add 2 mod] putinterval
npixs i size 2 idiv neg j add cmv [size 2 idiv j add i add 1 add 2 mod] putinterval
npixs i neg size 2 idiv neg j add cmv [size 2 idiv j add i add 1 add 2 mod] putinterval
} for
} for
/j 0 def
0 1 npixs length 1 sub {
/i exch def
npixs i get -2 eq {
npixs i pixs j get put
/j j 1 add def
} if
} for
/pixs npixs def
} if
% Finder pattern
/fw fw 2 idiv def
fw neg 1 fw {
/i exch def
fw neg 1 fw {
/j exch def
pixs i j cmv
i abs j abs gt {i abs} {j abs} ifelse 1 add 2 mod
put
} for
} for
% Orientation bits
[ [ fw 1 add neg fw 1 ] [ fw 1 add neg fw 1 add 1 ]
[ fw neg fw 1 add 1 ] [ fw 1 add fw 1 add 1 ]
[ fw 1 add fw 1 ] [ fw 1 add fw neg 1 ]
[ fw fw 1 add 0 ] [ fw 1 add fw 1 add neg 0 ]
[ fw fw 1 add neg 0 ] [ fw neg fw 1 add neg 0 ]
[ fw 1 add neg fw 1 add neg 0 ] [ fw 1 add neg fw neg 0 ]
] {pixs exch aload pop 3 1 roll cmv exch put} forall
% Mode ring
{
/modemapfull [
[-5 7] [-4 7] [-3 7] [-2 7] [-1 7] [ 1 7] [ 2 7] [ 3 7] [ 4 7] [ 5 7]
[ 7 5] [ 7 4] [ 7 3] [ 7 2] [ 7 1] [ 7 -1] [ 7 -2] [ 7 -3] [ 7 -4] [ 7 -5]
[ 5 -7] [ 4 -7] [ 3 -7] [ 2 -7] [ 1 -7] [-1 -7] [-2 -7] [-3 -7] [-4 -7] [-5 -7]
[-7 -5] [-7 -4] [-7 -3] [-7 -2] [-7 -1] [-7 1] [-7 2] [-7 3] [-7 4] [-7 5]
] def
/modemapcompact [
[-3 5] [-2 5] [-1 5] [ 0 5] [ 1 5] [ 2 5] [ 3 5]
[ 5 3] [ 5 2] [ 5 1] [ 5 0] [ 5 -1] [ 5 -2] [ 5 -3]
[ 3 -5] [ 2 -5] [ 1 -5] [ 0 -5] [-1 -5] [-2 -5] [-3 -5]
[-5 -3] [-5 -2] [-5 -1] [-5 0] [-5 1] [-5 2] [-5 3]
] def
} ctxdef
/modemap format (full) eq {modemapfull} {modemapcompact} ifelse def
0 1 modemap length 1 sub {
pixs modemap 2 index get aload pop cmv modebits 3 index get 48 sub put
pop
} for
<<
/ren /renmatrix
/pixs pixs
/pixx size
/pixy size
/height size 2 mul 72 div
/width size 2 mul 72 div
/opt options
>>
dontdraw not //renmatrix if
//unloadctx exec
end
}
[/barcode] {null def} forall
bind def
/azteccode dup load /uk.co.terryburton.bwipp defineresource pop
end
/setpacking where {pop setpacking} if
% --END ENCODER azteccode--