Skip to content

Commit

Permalink
maxicode: tweak newencoder to filter states based on data
Browse files Browse the repository at this point in the history
  • Loading branch information
gitlost committed Nov 12, 2024
1 parent 5ae614c commit 8f07935
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 29 deletions.
72 changes: 45 additions & 27 deletions src/maxicode.ps.src
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,7 @@ begin
[ (Z) (z) 218 250 26 ] % 26
[ eci eci eci eci eci ] % 27
[ 28 28 28 28 pad ] % 28
[ 29 29 29 29 pad ] % 29
[ 29 29 29 29 pd2 ] % 29
[ 30 30 30 30 27 ] % 30
[ ns ns ns ns ns ] % 31
[ ( ) ({) 219 251 28 ] % 32
Expand Down Expand Up @@ -469,6 +469,27 @@ begin

encoding (new) eq {

% Check states needed (apart from A, which for typical data is always used)
/haveb false def /havec false def /haved false def /havee false def
/havei false def % ECI
0 1 msglen 1 sub {
msg exch get /c exch def
c -1000000 le {
/havei true def
} { c 28 lt c 30 gt or c 32 ne and { % FS, GS, RS and space in all code sets
setb c known { /haveb true def } if
setc c known { /havec true def } if
setd c known { /haved true def } if
sete c known { /havee true def } if
} if
} ifelse
} for

% Code sets with a pad code are first pick
% A B E C D
/priority [0 haveb {1} if havee {4} if havec {2} if haved {3} if] def
/priority_rest priority 1 priority length 1 sub getinterval def % May be empty

% Prior code set Later code set
% A B C D E
/latch_sequence [[[ ][63 ][58 ][58 ][58 ]] % A
Expand Down Expand Up @@ -516,21 +537,21 @@ begin
seta msg n 2 add get get} def % Shift 3 A

% Table of operations - operating table?
/op_tab [ % predicate applicable sets encoding
<< /can {eci 1 ge } /intake 1 /output {out_eci} /sets 2#11111 /enc {27 enc_eci } >> % ECI ABCDE
<< /can {digits 9 ge } /intake 9 /output {6 } /sets 2#11111 /enc {31 enc_ns } >> % NS ABCDE
<< /can {seta c known} /intake 1 /output {1 } /sets 2#00001 /enc { seta c get} >> % A A
<< /can {setb c known} /intake 1 /output {1 } /sets 2#00010 /enc { setb c get} >> % B B
<< /can {setc c known} /intake 1 /output {1 } /sets 2#00100 /enc { setc c get} >> % C C
<< /can {setd c known} /intake 1 /output {1 } /sets 2#01000 /enc { setd c get} >> % D D
<< /can {sete c known} /intake 1 /output {1 } /sets 2#10000 /enc { sete c get} >> % E E
<< /can {num_a 1 ge } /intake 1 /output {2 } /sets 2#00010 /enc {59 seta c get} >> % SHA B
<< /can {num_a 2 ge } /intake 2 /output {3 } /sets 2#00010 /enc {56 enc_sha2 } >> % SHA2 B
<< /can {num_a 3 ge } /intake 3 /output {4 } /sets 2#00010 /enc {57 enc_sha3 } >> % SHA3 B
<< /can {setb c known} /intake 1 /output {2 } /sets 2#00001 /enc {59 setb c get} >> % SHB A
<< /can {setc c known} /intake 1 /output {2 } /sets 2#11011 /enc {60 setc c get} >> % SHC ABCDE
<< /can {setd c known} /intake 1 /output {2 } /sets 2#10111 /enc {61 setd c get} >> % SHD ABCDE
<< /can {sete c known} /intake 1 /output {2 } /sets 2#01111 /enc {62 sete c get} >> % SHE ABCDE
/op_tab [ % predicate applicable sets encoding
havei { << /can {c -1000000 le} /intake 1 /output {out_eci} /sets 2#11111 /enc {27 enc_eci } >> } if % ECI1 ABCDE
<< /can {digits 9 ge } /intake 9 /output {6 } /sets 2#11111 /enc {31 enc_ns } >> % NS ABCDE
<< /can {seta c known } /intake 1 /output {1 } /sets 2#00001 /enc { seta c get} >> % A A
haveb { << /can {setb c known } /intake 1 /output {1 } /sets 2#00010 /enc { setb c get} >> } if % B B
havec { << /can {setc c known } /intake 1 /output {1 } /sets 2#00100 /enc { setc c get} >> } if % C C
haved { << /can {setd c known } /intake 1 /output {1 } /sets 2#01000 /enc { setd c get} >> } if % D D
havee { << /can {sete c known } /intake 1 /output {1 } /sets 2#10000 /enc { sete c get} >> } if % E E
<< /can {num_a 1 ge } /intake 1 /output {2 } /sets 2#00010 /enc {59 seta c get} >> % SHA B
<< /can {num_a 2 ge } /intake 2 /output {3 } /sets 2#00010 /enc {56 enc_sha2 } >> % SHA2 B
<< /can {num_a 3 ge } /intake 3 /output {4 } /sets 2#00010 /enc {57 enc_sha3 } >> % SHA3 B
haveb { << /can {setb c known } /intake 1 /output {2 } /sets 2#00001 /enc {59 setb c get} >> } if % SHB A
havec { << /can {setc c known } /intake 1 /output {2 } /sets 2#11011 /enc {60 setc c get} >> } if % SHC ABCDE
haved { << /can {setd c known } /intake 1 /output {2 } /sets 2#10111 /enc {61 setd c get} >> } if % SHD ABCDE
havee { << /can {sete c known } /intake 1 /output {2 } /sets 2#01111 /enc {62 sete c get} >> } if % SHE ABCDE
] def

% Add idx to each entry
Expand Down Expand Up @@ -560,15 +581,14 @@ begin
} forall
} def

% Unrolled loop to get the best prior code set using a row of
% Loop to get the best prior code set using a row of
% best encoded lengths and a row of latch sequence lengths.
/get_best_origin {
/latch_length_s latch_length state get def
best_length_0 0 get latch_length_s 0 get add /orglen exch def 0
best_length_0 1 get latch_length_s 1 get add dup orglen lt {/orglen exch def pop 1} {pop} ifelse
best_length_0 2 get latch_length_s 2 get add dup orglen lt {/orglen exch def pop 2} {pop} ifelse
best_length_0 3 get latch_length_s 3 get add dup orglen lt {/orglen exch def pop 3} {pop} ifelse
best_length_0 4 get latch_length_s 4 get add dup orglen lt {/orglen exch def pop 4} {pop} ifelse
best_length_0 0 get latch_length_s 0 get add /orglen exch def 0
priority_rest {
/p exch def best_length_0 p get latch_length_s p get add dup orglen lt {/orglen exch def pop p} {pop} ifelse
} forall
} def

/digits 0 def % Number of contiguous digits seen
Expand All @@ -579,10 +599,9 @@ begin
/n exch def % Input index
/c msg n get def % Input character

% Keep tabs on digits, characters in code set a, and ECI type
% Keep tabs on digits and characters in code set A
/digits c 48 ge c 58 lt and {digits 1 add} {0} ifelse def
/num_a seta c known {num_a 1 add} {0} ifelse def
/eci c -1000000 le {out_eci } {0} ifelse def

% Get rows of interest
/path_op_0 path_op n get def
Expand All @@ -591,14 +610,13 @@ begin
/best_origin_0 best_origin n 15 and get def

% Get best encoded lengths, then best prior code sets
0 1 4 {/state exch def best_length_0 state get_best_length put} for
0 1 4 {/state exch def best_origin_0 state get_best_origin put} for
priority {/state exch def best_length_0 state get_best_length put} forall
priority {/state exch def best_origin_0 state get_best_origin put} forall
} for

/n msglen def

% Get the best code set to end with. Code sets with a pad code are first pick
/priority [0 1 4 2 3] def
0 max_int priority {dup best_length_0 exch get dup 3 index lt {4 2 roll} if pop pop} forall
/j exch def
/state exch def
Expand Down
67 changes: 65 additions & 2 deletions tests/ps_tests/maxicode.ps.test
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
33 33 33 33 33 33 33 33 55 56 56 45 53 41 57 9 17 61 9 41 13 12 3 23 10 25 23 42 54 28 13 1
20 36 43 17 24 60 6 50 50 29 36 49 11 43 19 33]
20 36 43 17 24 60 6 50 50 29 36 49 11 43 19 33] debugIsEqual

{ % 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)
Expand All @@ -68,7 +68,70 @@
33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33 33
33 33 33 33 33 33 33 33 60 60 40 40 9 9 43 43 14 14 50 50 12 12 53 53 57 57 58 58 36 36 28 28
10 10 53 53 37 37 30 30 14 14 5 5 31 31 40 40] debugIsEqual
10 10 53 53 37 37 30 30 14 14 5 5 31 31 40 40] debugIsEqual

{ % Space only
( )
(mode=4 parse debugcws newencoder) 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
33 33 33 33 33 33 33 33 60 60 40 40 9 9 43 43 14 14 50 50 12 12 53 53 57 57 58 58 36 36 28 28
10 10 53 53 37 37 30 30 14 14 5 5 31 31 40 40] debugIsEqual

{ % ECI only (should probably error on this)
(^ECI000899)
(mode=4 parse parsefnc debugcws newencoder) 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
33 33 33 33 33 33 33 33 60 60 40 40 9 9 43 43 14 14 50 50 12 12 53 53 57 57 58 58 36 36 28 28
10 10 53 53 37 37 30 30 14 14 5 5 31 31 40 40] debugIsEqual

{ % 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
} [ 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
61 0 34 4 28 28 28 28 63 31 17 20 53 47 62 22 34 28 56 57 13 2 31 58 13 29 7 59 32 26 27 26
0 42 46 21 35 56 52 11 61 22 7 42 33 4 36 26] debugIsEqual

{ % Maximum length code set A (138 digits)
(999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999)
(mode=4 debugcws newencoder) 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
39 63 31 59 38 44 39 63 24 23 0 48 38 28 46 35 4 58 37 58 39 20 7 28 25 31 54 31 31 32 10 17
9 28 7 28 19 14 40 44 4 58 57 12 37 17 0 48] debugIsEqual

{ % 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
} [ 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
48 48 48 48 48 48 48 48 37 37 7 7 55 55 33 33 27 27 62 62 30 30 18 18 12 12 42 42 25 25 54 54
17 17 18 18 58 58 51 51 27 27 41 41 16 16 7 7] debugIsEqual

{ % 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
} [ 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
1 1 1 1 1 1 1 1 59 59 19 19 18 18 21 21 28 28 39 39 24 24 41 41 49 49 55 55 11 11 56 56
20 20 41 41 9 9 60 60 28 28 10 10 62 62 19 19] debugIsEqual

{ % Code set E pad (28)
(^001^001^001^001)
(mode=4 parse debugcws newencoder) 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
28 28 28 28 28 28 28 28 26 26 45 45 49 49 38 38 31 31 5 5 44 44 43 43 7 7 12 12 1 1 62 62
58 58 43 43 57 57 13 13 31 31 29 29 53 53 45 45] debugIsEqual

% Figures

Expand Down

0 comments on commit 8f07935

Please sign in to comment.