From 414be1eea1a3758acd52857f4870b27f0903c130 Mon Sep 17 00:00:00 2001 From: Terry Burton Date: Mon, 25 Nov 2024 14:10:43 +0000 Subject: [PATCH] maxicode: Switch to new encoder by default --- src/maxicode.ps.src | 328 ++++++++++++++++---------------- tests/ps_tests/maxicode.ps.test | 32 ++-- 2 files changed, 182 insertions(+), 178 deletions(-) diff --git a/src/maxicode.ps.src b/src/maxicode.ps.src index ea65d338..22a43a33 100644 --- a/src/maxicode.ps.src +++ b/src/maxicode.ps.src @@ -54,7 +54,7 @@ begin /sam -1 def /parse false def /parsefnc false def - /newencoder false def + /legacyencoder false def //processoptions exec /options exch def /barcode exch def @@ -79,8 +79,8 @@ begin } if } if - /encoding (legacy) def - newencoder {/encoding (new) def} if + /encoding (new) def + legacyencoder {/encoding (legacy) def} if /maxicode //loadctx exec @@ -287,190 +287,194 @@ begin /maxlen mode 5 eq {77} {mode 3 le {84} {93} ifelse} ifelse def + % + % TODO: Support for this encoder will be dropped in the near future. If + % you require it then let your reason be known. + % encoding (legacy) eq { - % Compute numeric runlengths - /nseq [ msglen 1 add {0} repeat ] def - msglen 1 sub -1 0 { - /i exch def - msg i get dup 48 ge exch 57 le and { - nseq i nseq i 1 add get 1 add put - } { - nseq i 0 put - } ifelse - } for - /nseq nseq 0 msglen getinterval def - - % Encode the message from ASCII to codewords - /prefixinset { - 0 { - 2 copy exch length ge {exit} if - 2 copy get 3 index exch known {1 add} {exit} ifelse - } loop - exch pop exch pop - } def + % Compute numeric runlengths + /nseq [ msglen 1 add {0} repeat ] def + msglen 1 sub -1 0 { + /i exch def + msg i get dup 48 ge exch 57 le and { + nseq i nseq i 1 add get 1 add put + } { + nseq i 0 put + } ifelse + } for + /nseq nseq 0 msglen getinterval def + + % Encode the message from ASCII to codewords + /prefixinset { + 0 { + 2 copy exch length ge {exit} if + 2 copy get 3 index exch known {1 add} {exit} ifelse + } loop + exch pop exch pop + } def - /enc { - exch get out exch j exch put - /j j 1 add def - } def + /enc { + exch get out exch j exch put + /j j 1 add def + } def - /out 144 array def - /i 0 def /j 0 def /cset (seta) def - { % loop - % Exit when no characters remain latching back to A if necessary - i msglen eq { - cset (seta) ne cset (setb) ne and out length maxlen lt and { - la cset load enc - /cset (seta) def - } if - exit - } if - { % not a loop but common exit point - % Immediately encode an ECI - msg i get -1000000 le { - eci cset load enc - msg i get neg 1000000 sub - dup 000031 le { % ECI 000000 - 000031 - 63 and - 1 array astore - } { dup 001023 le { % ECI 000032 - 001023 - dup -6 bitshift 31 and 32 or exch - 63 and - 2 array astore - } { dup 032767 le { % ECI 001024 - 032767 - dup -12 bitshift 47 and 48 or exch - dup -6 bitshift 63 and exch - 63 and - 3 array astore - } { % ECI 032768 - 999999 - dup -18 bitshift 55 and 56 or exch - dup -12 bitshift 63 and exch - dup -6 bitshift 63 and exch - 63 and - 4 array astore - } ifelse } ifelse } ifelse - dup out exch j exch putinterval - length j add /j exch def - /i i 1 add def + /out 144 array def + /i 0 def /j 0 def /cset (seta) def + { % loop + % Exit when no characters remain latching back to A if necessary + i msglen eq { + cset (seta) ne cset (setb) ne and out length maxlen lt and { + la cset load enc + /cset (seta) def + } if exit } if + { % not a loop but common exit point + % Immediately encode an ECI + msg i get -1000000 le { + eci cset load enc + msg i get neg 1000000 sub + dup 000031 le { % ECI 000000 - 000031 + 63 and + 1 array astore + } { dup 001023 le { % ECI 000032 - 001023 + dup -6 bitshift 31 and 32 or exch + 63 and + 2 array astore + } { dup 032767 le { % ECI 001024 - 032767 + dup -12 bitshift 47 and 48 or exch + dup -6 bitshift 63 and exch + 63 and + 3 array astore + } { % ECI 032768 - 999999 + dup -18 bitshift 55 and 56 or exch + dup -12 bitshift 63 and exch + dup -6 bitshift 63 and exch + 63 and + 4 array astore + } ifelse } ifelse } ifelse + dup out exch j exch putinterval + length j add /j exch def + /i i 1 add def + exit + } if - % If 9 numerals available then use NS - nseq i get 9 ge { - msg i 9 getinterval 0 exch {48 sub add 10 mul} forall 10 idiv - 4 { dup 63 and exch -6 bitshift } repeat cset load ns get - 0 2 10 {index} for 6 array astore 7 1 roll 6 {pop} repeat - out exch j exch putinterval - /i i 9 add def - /j j 6 add def - exit - } if + % If 9 numerals available then use NS + nseq i get 9 ge { + msg i 9 getinterval 0 exch {48 sub add 10 mul} forall 10 idiv + 4 { dup 63 and exch -6 bitshift } repeat cset load ns get + 0 2 10 {index} for 6 array astore 7 1 roll 6 {pop} repeat + out exch j exch putinterval + /i i 9 add def + /j j 6 add def + exit + } if - % Read next three characters - /char1 msg i get def - /char2 i 1 add msglen lt {msg i 1 add get} {-99} ifelse def - /char3 i 2 add msglen lt {msg i 2 add get} {-99} ifelse def + % Read next three characters + /char1 msg i get def + /char2 i 1 add msglen lt {msg i 1 add get} {-99} ifelse def + /char3 i 2 add msglen lt {msg i 2 add get} {-99} ifelse def - % If current mode is sufficient then directly encode - cset load char1 known { - char1 cset load enc - /i i 1 add def - exit - } if + % If current mode is sufficient then directly encode + cset load char1 known { + char1 cset load enc + /i i 1 add def + exit + } if + + % For switching from A to B + cset (seta) eq setb char1 known and { + setb char2 known { + lb seta enc + /cset (setb) def + } { + sb seta enc + char1 setb enc + /i i 1 add def + } ifelse + exit + } if - % For switching from A to B - cset (seta) eq setb char1 known and { - setb char2 known { - lb seta enc + % For switching from B to A encode according to length of prefix + cset (setb) eq seta char1 known and { + /p seta msg i 4 msglen i sub 2 copy gt {exch} if pop getinterval prefixinset def + p 1 eq { + sa setb enc + char1 seta enc + /i i 1 add def + } if + p 2 eq { + sa2 setb enc + char1 seta enc + char2 seta enc + /i i 2 add def + } if + p 3 eq { + sa3 setb enc + char1 seta enc + char2 seta enc + char3 seta enc + /i i 3 add def + } if + p 4 ge { + la setb enc + /cset (seta) def + } if + exit + } if + + % If character is in A or B then directly latch + seta char1 known { + la cset load enc + /cset (seta) def + exit + } if + setb char1 known { + lb cset load enc /cset (setb) def - } { - sb seta enc - char1 setb enc - /i i 1 add def - } ifelse - exit - } if + exit + } if + + % Determine which one of sets C, D or E the character is in + setc char1 known {/setx (setc) def /sx sc def /lkx lkc def} if + setd char1 known {/setx (setd) def /sx sd def /lkx lkd def} if + sete char1 known {/setx (sete) def /sx se def /lkx lke def} if - % For switching from B to A encode according to length of prefix - cset (setb) eq seta char1 known and { - /p seta msg i 4 msglen i sub 2 copy gt {exch} if pop getinterval prefixinset def + % Encode according to the length of the prefix + /p setx load msg i 4 msglen i sub 2 copy gt {exch} if pop getinterval prefixinset def p 1 eq { - sa setb enc - char1 seta enc + sx cset load enc + char1 setx load enc /i i 1 add def } if p 2 eq { - sa2 setb enc - char1 seta enc - char2 seta enc + sx cset load enc + char1 setx load enc + sx cset load enc + char2 setx load enc /i i 2 add def } if p 3 eq { - sa3 setb enc - char1 seta enc - char2 seta enc - char3 seta enc + sx cset load enc + char1 setx load enc + sx cset load enc + char2 setx load enc + sx cset load enc + char3 setx load enc /i i 3 add def } if p 4 ge { - la setb enc - /cset (seta) def + sx cset load enc + lkx setx load enc + /cset setx def } if - exit - } if - % If character is in A or B then directly latch - seta char1 known { - la cset load enc - /cset (seta) def - exit - } if - setb char1 known { - lb cset load enc - /cset (setb) def exit - } if - - % Determine which one of sets C, D or E the character is in - setc char1 known {/setx (setc) def /sx sc def /lkx lkc def} if - setd char1 known {/setx (setd) def /sx sd def /lkx lkd def} if - sete char1 known {/setx (sete) def /sx se def /lkx lke def} if - - % Encode according to the length of the prefix - /p setx load msg i 4 msglen i sub 2 copy gt {exch} if pop getinterval prefixinset def - p 1 eq { - sx cset load enc - char1 setx load enc - /i i 1 add def - } if - p 2 eq { - sx cset load enc - char1 setx load enc - sx cset load enc - char2 setx load enc - /i i 2 add def - } if - p 3 eq { - sx cset load enc - char1 setx load enc - sx cset load enc - char2 setx load enc - sx cset load enc - char3 setx load enc - /i i 3 add def - } if - p 4 ge { - sx cset load enc - lkx setx load enc - /cset setx def - } if - - exit - } loop % out - } loop - /encmsg out 0 j getinterval def - /padval cset load pad get def + } loop % out + } loop + /encmsg out 0 j getinterval def + /padval cset load pad get def } if diff --git a/tests/ps_tests/maxicode.ps.test b/tests/ps_tests/maxicode.ps.test index e6ac9195..83a9c910 100644 --- a/tests/ps_tests/maxicode.ps.test +++ b/tests/ps_tests/maxicode.ps.test @@ -33,17 +33,17 @@ { % With zeroing on input ([\)>^03001^02996152380000^029840^029001^0291Z00004951^029UPSN^02906X610^029159^0291234567^0291/1^029^029Y^029634 ALPHA DR^029PITTSBURGH^029PA^030^004) - (mode=2 parse debugcws newencoder) maxicode + (mode=2 parse debugcws) maxicode } uszeropad debugIsEqual { % Without ([\)>^03001^0299615238^029840^029001^0291Z00004951^029UPSN^02906X610^029159^0291234567^0291/1^029^029Y^029634 ALPHA DR^029PITTSBURGH^029PA^030^004) - (mode=2 parse debugcws newencoder) maxicode + (mode=2 parse debugcws) maxicode } uszeropad debugIsEqual { % A pure A/B example that could be one codeword less (should SHB instead of LCHB then SHA): (b..A) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 59 2 46 46 1 33 33 33 33 17 28 48 20 45 62 22 14 12 49 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 @@ -52,7 +52,7 @@ { % Here's an A/B (and NS) example which could be one codeword less (immediate LCHB on "b" between NS segments instead of SHB and then LCHB after 2nd NS): (A123456789b123456789bbbA) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 1 31 7 22 60 52 21 63 2 16 27 40 34 32 50 55 12 11 42 31 7 22 60 52 21 2 2 2 63 1 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 @@ -61,7 +61,7 @@ { % Don't stay in mode A when mode D or even C would be more efficient. (^192^224^224^224^192^224^224^224^192^224^224^224^192^224^224^224^192^224^224^224^192) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 60 0 61 61 0 0 0 60 0 52 57 14 53 29 37 0 27 40 3 0 0 0 60 0 0 0 0 60 0 0 0 0 60 0 0 0 0 60 0 58 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 @@ -70,7 +70,7 @@ { % Numeric Sequence (123456789) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 31 7 22 60 52 21 33 33 33 46 53 45 48 29 51 38 37 61 52 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 @@ -79,7 +79,7 @@ { % Space only ( ) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 32 33 33 33 33 33 33 33 33 54 16 60 62 34 38 62 44 55 20 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 @@ -88,7 +88,7 @@ { % ECI only (should probably error on this) (^ECI000899) - (mode=4 parse parsefnc debugcws newencoder) maxicode + (mode=4 parse parsefnc debugcws) maxicode } [ 4 27 46 3 33 33 33 33 33 33 58 49 57 27 48 19 62 32 46 56 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 @@ -97,7 +97,7 @@ { % Exercise all modes and most shifts (^ECI000899ABabcdeAabcdABCabcdABabc^192^192 ^192^224^224^028^224^001^001^001^029^00112345678a123456789aABCDa^192^224^001^192^001^224^030^004) - (mode=4 parse parsefnc debugcws newencoder) maxicode + (mode=4 parse parsefnc debugcws) maxicode } [ 4 27 46 3 1 2 63 1 2 3 38 38 35 0 26 1 39 15 42 36 4 5 59 1 1 2 3 4 57 1 2 3 1 2 3 4 56 1 2 1 2 3 60 60 0 0 59 0 61 61 0 0 28 0 62 62 1 1 1 33 1 58 49 50 51 52 53 54 55 56 59 1 31 7 22 60 52 21 59 1 1 2 3 4 59 1 60 0 61 0 62 62 1 60 0 1 @@ -106,7 +106,7 @@ { % Maximum length code set A (138 digits) (999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999) - (mode=4 debugcws newencoder) maxicode + (mode=4 debugcws) maxicode } [ 4 57 57 57 31 59 38 44 39 63 30 31 14 60 14 21 51 5 26 37 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 39 63 31 59 38 44 @@ -115,7 +115,7 @@ { % Maximum length code set C (^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128^128) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 60 60 48 48 48 48 48 48 48 12 26 9 17 60 18 39 3 11 30 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 48 @@ -124,7 +124,7 @@ { % Maximum length code set E (^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001^001) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 62 62 1 1 1 1 1 1 1 31 18 1 19 34 61 34 5 37 55 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 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 @@ -133,7 +133,7 @@ { % Code set E pad (28) (^001^001^001^001) - (mode=4 parse debugcws newencoder) maxicode + (mode=4 parse debugcws) maxicode } [ 4 62 62 1 1 1 1 28 28 28 40 50 10 56 19 40 42 62 33 13 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 28 @@ -142,7 +142,7 @@ { % Exit SCM loop on first ECI and add remaining back later to avoid ECIs being replaced with NUL ([^041>^03001^02996999999999^029840^029333^029^ECI000003A) - (mode=2 parse parsefnc debugcws newencoder) maxicode + (mode=2 parse parsefnc debugcws) maxicode } [50 63 9 43 57 30 2 18 55 20 47 30 3 41 62 27 45 42 6 32 59 42 41 59 40 30 48 49 29 57 54 27 3 1 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 @@ -179,7 +179,7 @@ % Figures -(THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...) (mode=4 dontdraw newencoder) % Figure 2 (and L1), same +(THIS IS A 93 CHARACTER CODE SET A MESSAGE THAT FILLS A MODE 4, UNAPPENDED, MAXICODE SYMBOL...) (mode=4 dontdraw) % Figure 2 (and L1), same [ 0 1 1 1 1 1 0 1 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 1 0 0 1 1 1 0 0 0 1 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 0 1 0 1 0 0 0 0 0 0 0 @@ -216,7 +216,7 @@ 0 0 1 0 1 1 0 0 0 0 0 0 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1 0 0 0 ] eq_tmpl -([\)>^03001^02996152382802^029840^029001^0291Z00004951^029UPSN^02906X610^029159^0291234567^0291/1^029^029Y^029634 ALPHA DR^029PITTSBURGH^029PA^030^004) (mode=2 parse dontdraw newencoder) % Figure B2, not same, different encodation +([\)>^03001^02996152382802^029840^029001^0291Z00004951^029UPSN^02906X610^029159^0291234567^0291/1^029^029Y^029634 ALPHA DR^029PITTSBURGH^029PA^030^004) (mode=2 parse dontdraw) % Figure B2, not same, different encodation [ 1 1 0 1 0 1 1 1 0 1 1 0 1 1 1 1 1 0 1 1 1 1 1 1 1 0 1 1 1 1 0 1 0 1 0 1 0 1 0 1 1 1 0 0 0 0 1 1 0 1 1 0 0 0 0 1 0 0 1 0