Skip to content

Commit 22e460a

Browse files
committed
Pre-compute numeric runs to avoid O(n^2) complexity
1 parent 85f295c commit 22e460a

3 files changed

Lines changed: 83 additions & 53 deletions

File tree

src/codablockf.ps.src

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -265,27 +265,42 @@ begin
265265
} if
266266

267267
%
268-
% Determine digit runlength and characters from given position
269-
%
268+
% Pre-compute setC digit runlength from each position; two parity
269+
% arrays because FNC1 only counts when s is even. Position after an
270+
% FNC4 is its second byte, so numsscr exits there.
271+
%
272+
/numsAtNEven [ msglen 1 add {0} repeat ] def
273+
/numsAtSEven [ msglen 1 add {0} repeat ] def
274+
/numsAtNOdd [ msglen 1 add {0} repeat ] def
275+
/numsAtSOdd [ msglen 1 add {0} repeat ] def
276+
msglen 1 sub -1 0 {
277+
/i exch def
278+
/ch msg i get def
279+
i 0 ne { msg i 1 sub get //codablockf.fn4 eq } { false } ifelse {
280+
numsAtNEven i 0 put numsAtSEven i 0 put
281+
numsAtNOdd i 0 put numsAtSOdd i 0 put
282+
} {
283+
setc ch known not {
284+
numsAtNEven i 0 put numsAtSEven i 0 put
285+
numsAtNOdd i 0 put numsAtSOdd i 0 put
286+
} {
287+
ch //codablockf.fn1 eq {
288+
numsAtNEven i 1 numsAtNEven i 1 add get add put
289+
numsAtSEven i 2 numsAtSEven i 1 add get add put
290+
numsAtNOdd i 0 put
291+
numsAtSOdd i 0 put
292+
} {
293+
numsAtNEven i 1 numsAtNOdd i 1 add get add put
294+
numsAtSEven i 1 numsAtSOdd i 1 add get add put
295+
numsAtNOdd i 1 numsAtNEven i 1 add get add put
296+
numsAtSOdd i 1 numsAtSEven i 1 add get add put
297+
} ifelse
298+
} ifelse
299+
} ifelse
300+
} for
270301
/numsscr {
271-
/n 0 def /s 0 def
272-
/p exch def {
273-
p msglen ge {exit} if
274-
p 0 ne { % Check not 2nd byte of FNC4
275-
msg p 1 sub get //codablockf.fn4 eq {exit} if
276-
} if
277-
msg p get
278-
dup setc exch known not {pop exit} if
279-
//codablockf.fn1 eq {
280-
% FNC1 in odd position of run like two digits
281-
s 2 mod 0 eq {/s s 1 add def} {exit} ifelse
282-
} if
283-
/n n 1 add def
284-
/s s 1 add def
285-
/p p 1 add def
286-
} loop
287-
n s
288-
} def
302+
dup numsAtNEven exch get exch numsAtSEven exch get
303+
} bind def
289304

290305
%
291306
% Encoding for each alphabet

src/code128.ps.src

Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -383,25 +383,28 @@ begin
383383
/msglen msg length def
384384

385385
%
386-
% Determine digit runlength from given position
387-
%
388-
/numsscr {
389-
/s 0 def
390-
/p exch def {
391-
p msglen ge {exit} if
392-
msg p get
393-
dup setc exch known not {pop exit} if
394-
dup -1 le {
395-
% FNC1 in odd position of run like two digits
396-
//code128.fn1 eq s 2 mod 0 eq and {/s s 1 add def} {exit} ifelse
386+
% Pre-compute setC digit runlength from each position; two parity
387+
% arrays because FNC1 only counts when s is even.
388+
%
389+
/numsAtEven [ msglen 1 add {0} repeat ] def
390+
/numsAtOdd [ msglen 1 add {0} repeat ] def
391+
msglen 1 sub -1 0 {
392+
/i exch def
393+
/c msg i get def
394+
c //code128.fn1 eq {
395+
numsAtEven i 2 numsAtEven i 1 add get add put
396+
numsAtOdd i 0 put
397+
} {
398+
c 48 ge c 57 le and {
399+
numsAtEven i 1 numsAtOdd i 1 add get add put
400+
numsAtOdd i 1 numsAtEven i 1 add get add put
397401
} {
398-
pop
402+
numsAtEven i 0 put
403+
numsAtOdd i 0 put
399404
} ifelse
400-
/s s 1 add def
401-
/p p 1 add def
402-
} loop
403-
s
404-
} def
405+
} ifelse
406+
} for
407+
/numsscr { numsAtEven exch get } bind def
405408

406409
%
407410
% Encoding for each alphabet

src/code16k.ps.src

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -357,24 +357,36 @@ begin
357357
/msglen msg length def
358358

359359
%
360-
% Determine digit runlength and characters from given position
360+
% Pre-compute setC digit runlength from each position; two parity
361+
% arrays because FNC1 only counts when s is even.
361362
%
363+
/numsAtNEven [ msglen 1 add {0} repeat ] def
364+
/numsAtSEven [ msglen 1 add {0} repeat ] def
365+
/numsAtNOdd [ msglen 1 add {0} repeat ] def
366+
/numsAtSOdd [ msglen 1 add {0} repeat ] def
367+
msglen 1 sub -1 0 {
368+
/i exch def
369+
/ch msg i get def
370+
setc ch known not {
371+
numsAtNEven i 0 put numsAtSEven i 0 put
372+
numsAtNOdd i 0 put numsAtSOdd i 0 put
373+
} {
374+
ch //code16k.fn1 eq {
375+
numsAtNEven i 1 numsAtNEven i 1 add get add put
376+
numsAtSEven i 2 numsAtSEven i 1 add get add put
377+
numsAtNOdd i 0 put
378+
numsAtSOdd i 0 put
379+
} {
380+
numsAtNEven i 1 numsAtNOdd i 1 add get add put
381+
numsAtSEven i 1 numsAtSOdd i 1 add get add put
382+
numsAtNOdd i 1 numsAtNEven i 1 add get add put
383+
numsAtSOdd i 1 numsAtSEven i 1 add get add put
384+
} ifelse
385+
} ifelse
386+
} for
362387
/numsscr {
363-
/n 0 def /s 0 def
364-
/p exch def {
365-
p msglen ge {exit} if
366-
msg p get
367-
dup setc exch known not {pop exit} if
368-
//code16k.fn1 eq {
369-
% FNC1 in odd position of run like two digits
370-
s 2 mod 0 eq {/s s 1 add def} {exit} ifelse
371-
} if
372-
/n n 1 add def
373-
/s s 1 add def
374-
/p p 1 add def
375-
} loop
376-
n s
377-
} def
388+
dup numsAtNEven exch get exch numsAtSEven exch get
389+
} bind def
378390

379391
%
380392
% Encoding for each alphabet

0 commit comments

Comments
 (0)