-
-
Notifications
You must be signed in to change notification settings - Fork 67
/
Copy pathchannelcode.ps.src
290 lines (267 loc) · 13.6 KB
/
channelcode.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
% 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 channelcode--
% --REQUIRES preamble loadctx unloadctx raiseerror processoptions renlinear--
% --DESC: Channel Code
% --EXAM: 3493
% --EXOP: height=0.5 includetext
% --RNDR: renlinear
/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 /renlinear dup /uk.co.terryburton.bwipp findresource put
begin
/channelcode {
20 dict begin % Confine variables to local scope
/ctx null def
/dontdraw false def
/shortfinder false def
/includetext false def
/includecheck false def
/height 1.0 def
//processoptions exec /options exch def
/barcode exch def
/channelcode //loadctx exec
% Validate the input
barcode length 2 lt barcode length 7 gt or {
/bwipp.channelcodeBadLength (Channel Code must be 2 to 7 digits) //raiseerror exec
} if
barcode {
dup 48 lt exch 57 gt or {
/bwipp.channelcodeBadCharacter (Channel Code must contain only digits) //raiseerror exec
} if
} forall
barcode cvi [ 26 292 3493 44072 576688 7742862 ] barcode length 2 sub get gt {
/bwipp.channelcodeTooBig (The Channel Code value is too big for the number of channels) //raiseerror exec
} if
% Tail-call optimisation FTW!
/loops1 { /s2max s1max 1 add s1 sub def /b1 1 def
s1 1 eq {nextb1} {loopb1} ifelse } def
/loopb1 { /b2max b1max 1 add b1 sub def /s2 1 def loops2 } def
/loops2 { /s3max s2max 1 add s2 sub def /b2 1 def
s1 b1 add s2 add 3 eq {nextb2} {loopb2} ifelse } def
/loopb2 { /b3max b2max 1 add b2 sub def /s3 1 def loops3 } def
/loops3 { /s4max s3max 1 add s3 sub def /b3 1 def
b1 s2 add b2 add s3 add 4 eq {nextb3} {loopb3} ifelse } def
/loopb3 { /b4max b3max 1 add b3 sub def /s4 1 def loops4 } def
/loops4 { /s5max s4max 1 add s4 sub def /b4 1 def
b2 s3 add b3 add s4 add 4 eq {nextb4} {loopb4} ifelse } def
/loopb4 { /b5max b4max 1 add b4 sub def /s5 1 def loops5 } def
/loops5 { /s6max s5max 1 add s5 sub def /b5 1 def
b3 s4 add b4 add s5 add 4 eq {nextb5} {loopb5} ifelse } def
/loopb5 { /b6max b5max 1 add b5 sub def /s6 1 def loops6 } def
/loops6 { /s7max s6max 1 add s6 sub def /b6 1 def
b4 s5 add b5 add s6 add 4 eq {nextb6} {loopb6} ifelse } def
/loopb6 { /b7max b6max 1 add b6 sub def /s7 1 def loops7 } def
/loops7 { /s8 s7max 1 add s7 sub def /b7 1 def
b5 s6 add b6 add s7 add 4 eq {nextb7} {loopb7} ifelse } def
/loopb7 { /b8 b7max 1 add b7 sub def
b6 s7 add b7 add s8 add b8 add 5 eq {nextb7} {chkchr} ifelse } def
/chkchr {
value target eq {
[s1 b1 s2 b2 s3 b3 s4 b4 s5 b5 s6 b6 s7 b7 s8 b8] exit
} if
/value value 1 add def
nextb7
} def
/nextb7 { /b7 b7 1 add def b7 b7max le {loopb7} {nexts7} ifelse } def
/nexts7 { /s7 s7 1 add def s7 s7max le {loops7} {nextb6} ifelse } def
/nextb6 { /b6 b6 1 add def b6 b6max le {loopb6} {nexts6} ifelse } def
/nexts6 { /s6 s6 1 add def s6 s6max le {loops6} {nextb5} ifelse } def
/nextb5 { /b5 b5 1 add def b5 b5max le {loopb5} {nexts5} ifelse } def
/nexts5 { /s5 s5 1 add def s5 s5max le {loops5} {nextb4} ifelse } def
/nextb4 { /b4 b4 1 add def b4 b4max le {loopb4} {nexts4} ifelse } def
/nexts4 { /s4 s4 1 add def s4 s4max le {loops4} {nextb3} ifelse } def
/nextb3 { /b3 b3 1 add def b3 b3max le {loopb3} {nexts3} ifelse } def
/nexts3 { /s3 s3 1 add def s3 s3max le {loops3} {nextb2} ifelse } def
/nextb2 { /b2 b2 1 add def b2 b2max le {loopb2} {nexts2} ifelse } def
/nexts2 { /s2 s2 1 add def s2 s2max le {loops2} {nextb1} ifelse } def
/nextb1 { /b1 b1 1 add def b1 b1max le {loopb1} {nexts1} ifelse } def
/nexts1 { /s1 s1 1 add def s1 s1max le {loops1} if } def
{
/memo [ % Accelerate generation of bar patterns
[ % CH3
[ 0 [1 1 1 1 1 2 1 2] [1 1 1 1 1 1 1 3] [1 1 1 1 1 3 2] [1 1 1 1 1 3 3] ]
]
[ % CH4
[ 0 [1 1 1 1 2 1 1 3] [1 1 1 1 1 1 1 4] [1 1 1 1 4 3 3] [1 1 1 1 4 4 4] ]
]
[ % CH5
[ 0 [1 1 1 2 1 1 2 3] [1 1 1 1 1 1 1 5] [1 1 1 5 4 4 4] [1 1 1 5 5 5 5] ]
]
[ % CH6
[ 0 [1 1 2 1 1 2 1 4] [1 1 1 1 1 1 1 6] [1 1 6 5 5 5 4] [1 1 6 6 6 6 6] ]
]
[ % CH7
[ 0 [1 2 1 1 2 1 1 5] [1 1 1 1 1 1 1 7] [1 7 6 6 6 5 5] [1 7 7 7 7 7 7] ]
[ 150000 [1 3 1 1 2 4 1 1] [1 1 3 1 2 3 2 1] [1 7 5 5 5 4 1] [1 7 7 5 5 4 2] ]
[ 300000 [1 1 4 2 1 1 1 3] [1 2 4 1 1 1 2 2] [1 7 7 4 3 3 3] [1 7 6 3 3 3 3] ]
[ 450000 [1 1 4 1 1 4 1 1] [1 3 2 1 2 1 2 2] [1 7 7 4 4 4 1] [1 7 5 4 4 3 3] ]
]
[ % CH8
[ 0 [2 1 1 2 1 1 2 5] [1 1 1 1 1 1 1 8] [8 7 7 7 6 6 6] [8 8 8 8 8 8 8] ]
[ 150000 [2 1 1 2 1 1 5 2] [1 1 2 1 5 2 1 2] [8 7 7 7 6 6 6] [8 8 8 7 7 3 2] ]
[ 300000 [2 1 1 4 2 2 2 1] [1 1 4 2 1 2 1 3] [8 7 7 7 4 3 2] [8 8 8 5 4 4 3] ]
[ 450000 [2 2 2 1 1 3 1 3] [1 1 2 1 1 2 4 3] [8 7 6 5 5 5 3] [8 8 8 7 7 7 6] ]
[ 600000 [2 3 1 1 4 2 1 1] [1 1 3 1 3 1 2 3] [8 7 5 5 5 2 1] [8 8 8 6 6 4 4] ]
[ 750000 [2 1 3 1 2 3 2 1] [1 2 1 1 3 4 1 2] [8 7 7 5 5 4 2] [8 8 7 7 7 5 2] ]
[ 900000 [2 2 1 4 1 2 2 1] [1 2 1 2 1 5 1 2] [8 7 6 6 3 3 2] [8 8 7 7 6 6 2] ]
[ 1050000 [2 4 1 1 1 2 2 2] [1 2 1 2 1 3 1 4] [8 7 4 4 4 4 3] [8 8 7 7 6 6 4] ]
[ 1200000 [2 2 1 5 2 1 1 1] [1 3 1 3 2 1 1 3] [8 7 6 6 2 1 1] [8 8 6 6 4 3 3] ]
[ 1350000 [2 2 1 3 3 1 1 2] [1 4 1 2 1 1 4 1] [8 7 6 6 4 2 2] [8 8 5 5 4 4 4] ]
[ 1500000 [3 1 2 2 2 1 1 3] [1 1 1 1 2 2 4 3] [8 6 6 5 4 3 3] [8 8 8 8 8 7 6] ]
[ 1650000 [3 2 1 2 3 1 2 1] [1 1 1 1 3 2 4 2] [8 6 5 5 4 2 2] [8 8 8 8 8 6 5] ]
[ 1800000 [3 1 1 3 2 3 1 1] [1 2 1 1 3 4 2 1] [8 6 6 6 4 3 1] [8 8 7 7 7 5 2] ]
[ 1950000 [3 2 1 2 1 2 2 2] [1 2 4 1 2 2 1 2] [8 6 5 5 4 4 3] [8 8 7 4 4 3 2] ]
[ 2100000 [3 1 2 1 4 2 1 1] [1 4 1 2 1 1 2 3] [8 6 6 5 5 2 1] [8 8 5 5 4 4 4] ]
[ 2250000 [4 1 1 4 1 1 2 1] [1 1 4 2 1 1 1 4] [8 5 5 5 2 2 2] [8 8 8 5 4 4 4] ]
[ 2400000 [4 3 1 2 1 2 1 1] [1 2 4 2 2 2 1 1] [8 5 3 3 2 2 1] [8 8 7 4 3 2 1] ]
[ 2550000 [5 1 1 1 1 1 3 2] [1 2 2 4 3 1 1 1] [8 4 4 4 4 4 4] [8 8 7 6 3 1 1] ]
[ 2700000 [1 1 3 6 1 1 1 1] [2 1 1 2 1 1 6 1] [8 8 8 6 1 1 1] [8 7 7 7 6 6 6] ]
[ 2850000 [1 1 1 2 2 3 2 3] [2 1 3 3 2 1 1 2] [8 8 8 8 7 6 4] [8 7 7 5 3 2 2] ]
[ 3000000 [1 2 3 3 3 1 1 1] [2 1 1 1 5 1 2 2] [8 8 7 5 3 1 1] [8 7 7 7 7 3 3] ]
[ 3150000 [1 3 1 2 2 2 3 1] [2 1 1 3 2 1 3 2] [8 8 6 6 5 4 3] [8 7 7 7 5 4 4] ]
[ 3300000 [1 5 1 1 3 1 1 2] [2 1 1 4 3 2 1 1] [8 8 4 4 4 2 2] [8 7 7 7 4 2 1] ]
[ 3450000 [1 1 2 2 2 5 1 1] [2 2 2 2 3 1 1 2] [8 8 8 7 6 5 1] [8 7 6 5 4 2 2] ]
[ 3600000 [1 2 1 1 3 4 2 1] [2 2 3 1 1 1 2 3] [8 8 7 7 7 5 2] [8 7 6 4 4 4 4] ]
[ 3750000 [1 1 2 1 1 5 3 1] [2 3 1 1 4 1 2 1] [8 8 8 7 7 7 3] [8 7 5 5 5 2 2] ]
[ 3900000 [1 3 1 2 4 2 1 1] [2 3 3 1 1 1 2 2] [8 8 6 6 5 2 1] [8 7 5 3 3 3 3] ]
[ 4050000 [1 3 1 2 3 1 2 2] [2 6 2 1 1 1 1 1] [8 8 6 6 5 3 3] [8 7 2 1 1 1 1] ]
[ 4200000 [2 1 1 2 1 2 2 4] [2 1 3 1 3 3 1 1] [8 7 7 7 6 6 5] [8 7 7 5 5 3 1] ]
[ 4350000 [2 2 1 4 1 2 2 1] [2 1 4 1 3 1 2 1] [8 7 6 6 3 3 2] [8 7 7 4 4 2 2] ]
[ 4500000 [2 1 1 1 2 1 3 4] [2 2 2 1 2 1 3 2] [8 7 7 7 7 6 6] [8 7 6 5 5 4 4] ]
[ 4650000 [2 4 2 1 2 2 1 1] [2 2 2 1 2 1 2 3] [8 7 4 3 3 2 1] [8 7 6 5 5 4 4] ]
[ 4800000 [2 3 2 1 1 2 2 2] [2 4 1 2 1 1 3 1] [8 7 5 4 4 4 3] [8 7 4 4 3 3 3] ]
[ 4950000 [3 2 2 1 2 1 1 3] [2 1 1 2 1 1 1 6] [8 6 5 4 4 3 3] [8 7 7 7 6 6 6] ]
[ 5100000 [3 2 1 1 1 3 3 1] [2 2 3 2 1 1 3 1] [8 6 5 5 5 5 3] [8 7 6 4 3 3 3] ]
[ 5250000 [4 1 2 1 2 2 1 2] [2 1 4 1 2 1 1 3] [8 5 5 4 4 3 2] [8 7 7 4 4 3 3] ]
[ 5400000 [5 1 2 1 2 1 1 2] [2 2 1 1 4 1 3 1] [8 4 4 3 3 2 2] [8 7 6 6 6 3 3] ]
[ 5550000 [1 1 4 4 1 2 1 1] [3 1 2 1 1 3 2 2] [8 8 8 5 2 2 1] [8 6 6 5 5 5 3] ]
[ 5700000 [1 2 1 1 2 1 3 4] [3 1 4 1 2 2 1 1] [8 8 7 7 7 6 6] [8 6 6 3 3 2 1] ]
[ 5850000 [1 1 3 3 2 2 2 1] [3 2 1 1 2 1 4 1] [8 8 8 6 4 3 2] [8 6 5 5 5 4 4] ]
[ 6000000 [1 4 3 1 1 2 1 2] [3 2 2 1 2 2 1 2] [8 8 5 3 3 3 2] [8 6 5 4 4 3 2] ]
[ 6150000 [2 1 1 4 1 2 1 3] [3 1 1 2 1 2 1 4] [8 7 7 7 4 4 3] [8 6 6 6 5 5 4] ]
[ 6300000 [2 2 2 1 3 2 2 1] [3 1 4 1 3 1 1 1] [8 7 6 5 5 3 2] [8 6 6 3 3 1 1] ]
[ 6450000 [2 5 1 3 1 1 1 1] [3 2 1 1 2 3 1 2] [8 7 3 3 1 1 1] [8 6 5 5 5 4 2] ]
[ 6600000 [3 2 3 1 2 1 2 1] [3 1 3 2 2 1 1 2] [8 6 5 3 3 2 2] [8 6 6 4 3 2 2] ]
[ 6750000 [4 1 2 2 1 1 3 1] [3 2 1 3 1 1 3 1] [8 5 5 4 3 3 3] [8 6 5 5 3 3 3] ]
[ 6900000 [1 2 1 4 2 2 2 1] [4 1 1 2 2 2 2 1] [8 8 7 7 4 3 2] [8 5 5 5 4 3 2] ]
[ 7050000 [1 2 5 2 1 2 1 1] [4 2 1 3 2 1 1 1] [8 8 7 3 2 2 1] [8 5 4 4 2 1 1] ]
[ 7200000 [2 2 2 1 3 1 3 1] [4 1 3 1 3 1 1 1] [8 7 6 5 5 3 3] [8 5 5 3 3 1 1] ]
[ 7350000 [3 1 4 2 1 1 1 2] [4 2 2 1 1 1 2 2] [8 6 6 3 2 2 2] [8 5 4 3 3 3 3] ]
[ 7500000 [1 1 1 4 1 1 3 3] [5 2 1 2 2 1 1 1] [8 8 8 8 5 5 5] [8 4 3 3 2 1 1] ]
[ 7650000 [5 2 1 2 1 2 1 1] [5 2 2 1 1 2 1 1] [8 4 3 3 2 2 1] [8 4 3 2 2 2 1] ]
]
] def
} ctxdef
/encode {
/chan exch def
/target exch def
% Lookup memoized starting value close to the target
memo chan 3 sub get {
/m exch def
m 0 get target gt {exit} if
/mv m 0 get def
/mb m 1 get def
/ms m 2 get def
/mbmax m 3 get def
/msmax m 4 get def
} forall
/value mv def
mb aload pop [/b8 /b7 /b6 /b5 /b4 /b3 /b2 /b1] {exch def} forall
ms aload pop [/s8 /s7 /s6 /s5 /s4 /s3 /s2 /s1] {exch def} forall
mbmax aload pop [/b7max /b6max /b5max /b4max /b3max /b2max /b1max] {exch def} forall
msmax aload pop [/s7max /s6max /s5max /s4max /s3max /s2max /s1max] {exch def} forall
1 {chkchr} repeat 8 chan sub 2 mul dup 16 exch sub getinterval
} def
/barlen barcode length def
% Determine finder
/finder shortfinder { [ 1 1 1 1 1 ] } { [ 1 1 1 1 1 1 1 1 1 ] } ifelse def
% Encode the main data
/data barcode cvi barlen 1 add encode def
% Determine check data
{
/mod23map [
[] []
[ 13 12 4 9 3 1 ]
[ 8 2 12 3 18 16 4 1 ]
[ 11 16 17 8 20 4 10 2 5 1 ]
[ 1 4 16 18 3 12 2 8 9 13 6 1 ]
[ 20 16 22 13 15 12 5 4 17 9 21 3 7 1 ]
[ 2 6 18 8 1 3 9 4 12 13 16 2 6 18 8 1 ]
] def
} ctxdef
/check [] def
includecheck {
/mod23 mod23map barlen get def
0
0 1 data length 1 sub {
dup data exch get 1 sub exch mod23 exch get mul add
} for
23 mod 3 encode /check exch def
} if
% Construct the symbol
/sbs [
finder aload pop
data aload pop
check aload pop
] def
% Create the human readable text
/txt barlen array def
0 1 barlen 1 sub {
/i exch def
txt i [barcode i 1 getinterval 0 0 () 0] put
} for
% Return the arguments
<<
/ren /renlinear
/sbs sbs
/bhs [sbs length 1 add 2 idiv {height} repeat]
/bbs [sbs length 1 add 2 idiv {0} repeat]
/txt txt
/textxalign (center)
/borderleft 1.0
/borderright 2.0
/opt options
>>
dontdraw not //renlinear if
//unloadctx exec
end
}
[/barcode] {null def} forall
bind def
/channelcode dup load /uk.co.terryburton.bwipp defineresource pop
end
/setpacking where {pop setpacking} if
% --END ENCODER channelcode--