
|
This code is part of 2 dimentional code family, it's in fact a code with several rows which can encode up to 2700 bytes what explain its name of "Portable Document File". The encoding is done in two stages : first the datas are converted to "codeword" (High level encoding) then those are converted to bars and spaces patterns. (Low level encoding) Moreover an error correction system with several levels is included, it allows to reconstitute badly printed, erased, fuzzy or torn off datas. In the continuation of this talk, the word "codeword" will be shortened into CW.
|
S t a r t
|
L1 |
D15 |
D14 |
R1 |
S t o p
|
|
L2 |
D13 |
D12 |
R2 |
||
|
L3 |
D11 |
D10 |
R3 |
||
|
L4 |
D9 |
D8 |
R4 |
||
|
L5 |
D7 |
D6 |
R5 |
||
|
L6 |
D5 |
D4 |
R6 |
||
|
L7 |
D3 |
D2 |
R7 |
||
|
L8 |
D1 |
D0 |
R8 |
||
|
L9 |
C3 |
C2 |
R9 |
||
|
L10 |
C1 |
C0 |
R10 |
D15 = length descriptor (16 in this sample)
D0
= padding
D1 a D14 = datas
L1 a L10 = left side CW
R1
a R10 = right side CW
C0 a C3 = error correction, level 1

|
First table |
Second table |
Third table |
|
|
111 0 1 0 1 0 111 000000 |
11111 0 1 0 1 0 11 00000 |
11 0 1 0 1 0 11111 00000 |
|
|
1111 0 1 0 1 0 1111 0000 |
111111 0 1 0 1 0 111 000 |
111 0 1 0 1 0 111111 000 |
|
|
11111 0 1 0 1 0 11111 00 |
1111 0 1 0 1 00 1 000000 |
1 0 1 0 1 00 1111 000000 |
|
|
111 0 1 0 1 00 111 00000 |
11111 0 1 0 1 00 11 0000 |
11 0 1 0 1 00 11111 0000 |
|
|
..... |
..... |
..... |
|
Compaction mode |
Datas to encode |
Rate compaction |
|
"Byte" |
ASCII 0 to 255 | 1.2 byte per CW |
|
"Text" |
ASCII 9, 10, 13 & 32 a 127 | 2 characters per CW |
|
"Numeric" |
Only digits 0 to 9 | 2.9 digits per CW |
|
CW number : |
Function |
|
900 |
Switch to "Text" mode |
|
901 |
Switch to "Byte" mode |
|
902 |
Switch to "Numeric" mode |
|
903 a 912 |
Reserved |
|
913 |
Switch to "Octet" only for the next CW |
|
914 a 920 |
Reserved |
|
921 |
Initialization |
|
922 |
Terminator codeword for Macro PDF control block |
|
923 |
Sequence tag to identify the beginning of optional fields in the Macro PDF control block |
|
924 |
Switch to "Byte" mode (If the total number of byte is multiple of 6) |
|
925 |
Identifier for a user defined Extended Channel Interpretation (ECI) |
|
926 |
Identifier for a general purpose ECI format |
|
927 |
Identifier for an ECI of a character set or code page |
|
928 |
Macro marker CW to indicate the beginning of a Macro PDF Control Block |
The default sub-mode is "Uppercase", in this sub-mode 2 characters are encoded in each CW, here is characters tables :
|
Value |
Uppercase |
Lowercase |
Mixed |
Punctuation |
|
0 |
A |
a |
0 |
; |
|
1 |
B |
b |
1 |
< |
|
2 |
C |
c |
2 |
> |
|
3 |
D |
d |
3 |
@ |
|
4 |
E |
e |
4 |
[ |
|
5 |
F |
f |
5 |
\ |
|
6 |
G |
g |
6 |
] |
|
7 |
H |
h |
7 |
_ |
|
8 |
I |
I |
8 |
` (Quote) |
|
9 |
J |
j |
9 |
~ |
|
10 |
K |
k |
& |
! |
|
11 |
L |
l |
CR |
CR |
|
12 |
M |
m |
HT |
HT |
|
13 |
N |
n |
, |
, |
|
14 |
O |
o |
: |
: |
|
15 |
P |
p |
# |
LF |
|
16 |
Q |
q |
- |
- |
|
17 |
R |
r |
. |
. |
|
18 |
S |
s |
$ |
$ |
|
19 |
T |
t |
/ |
/ |
|
20 |
U |
u |
+ |
g |
|
21 |
V |
v |
% |
| |
|
22 |
W |
w |
* |
* |
|
23 |
X |
x |
= |
( |
|
24 |
Y |
y |
^ |
) |
|
25 |
Z |
z |
PUN |
? |
|
26 |
SP |
SP |
SP |
{ |
|
27 |
LOW |
T_UPP |
LOW |
} |
|
28 |
MIX |
MIX |
UPP |
' (Apostrophe) |
|
29 |
T_PUN |
T_PUN |
T_PUN |
UPP |
|
Sample, sequence to encode : Super ! S : 18, LOW : 27, u : 20, p : 15, e : 4, r : 17, SPACE
: 26, T_PUN : 29, ! : 10 |
|
Sample 1 : word to encode : alcool The sequence of bytes (in ASCII) is : 97, 108, 99,
111, 111, 108 Sample 2 : word to encode : alcoolique The sequence of bytes (in ASCII) is : 97, 108, 99,
111, 111, 108, 105, 113, 117, 101 |
|
Sample, sequence to encode : 01234 There will be thus 5 \ 3 + 1 = 2 CW |
|
Table used to encode |
X for the left side CW |
X for the right side CW |
|
1 |
(Number of rows -1) \ 3 |
Number of data columns - 1 |
|
2 |
(Security level x 3) |
(Number of rows -1) \ 3 |
|
3 |
Number of data columns - 1 |
(Security level x 3) |
|
Level |
Number of CWs required by
the correction |
Maximum number of data CWs |
|
0 |
2 |
925 |
|
1 |
4 |
923 |
|
2 |
8 |
919 |
|
3 |
16 |
911 |
|
4 |
32 |
895 |
|
5 |
64 |
863 |
|
6 |
128 |
799 |
|
7 |
256 |
671 |
|
8 |
512 |
415 |
|
Number of data CWs |
Advisable level |
|
1 a 40 |
2 |
|
41 a 160 |
3 |
|
161 a 320 |
4 |
|
321 a 863 |
5 |
For i = 0 To m - 1
t = (d(i) + c(k - 1)) Mod 929
For j = k - 1 To 0 Step -1
If j = 0 Then
c(j) = (929 - (t * a(j)) Mod 929) Mod 929
Else
c(j) = (c(j - 1) + 929 - (t * a(j)) Mod 929) Mod 929
End If
Next
Next
For j = 0 To k - 1
If c(j) <> 0 Then c(j) = 929 - c(j)
Next
Since we can create the bar code pattern it remains us to draw it on the screen and to print it on a paper sheet. Two approaches are possible :
It seems that there's no free bar code PDF417 font on the net. I've decided
consequently to draw this font and to propose it for download. Because there's 929 CWs
with 3 alternatives for each one obligate us to divide the 17 bits of a CW in
several parts. But divide by 17 ... hmmm ... a trick is necessary. If we
considere that the first bit is always "1"
and the last one "0", we can imagine a separator like "01"
and the remain is only 15 bits in each CW; we can then divide these 15
bits into 3 parts. There will be then 25 = 32 possible groups
affected to 32 characters of the font. The encoding software is in charge to
transform the 3 groups of each CW into a 3 characters string.
The font will
contain thus the following characters :
The string to send to the printer will look something like this : +*gfA*jhD*BAl*gCt*hjk*- and this for each row.
This font contains the 35 patterns describe above. The start row and end row codes embed a 2 modules margin. The height is equal to 3 modules which is the most current size.
|
Copy this file |
The software will evolve with 4 steps :
Because of the interaction between the different compaction modes and
the different sub-modes of the "text" mode it's difficult to make
a 100% optimization. Thus the software will split the string into "parts"
having the type "numeric", "text" or "byte" afterwards
it will change some parts for an other mode if the overload due to switch CWs is
greater than the compaction gain. We'll can't make allowance for all the parameters
like paddings, gain due to perfect multiple of 6, uni-character switch
or the switchs between the different sub-modes of the text mode : one would need for that several thousands of
programming lines.
Another difficulty comes from the size of the wielded
numbers, for example the "Modulo 900" operation applied on a 44 digits
number
generate an unavoidable overload error; the software will have to carry out
this calculation step by step.
|
|
Here is a small program
|
The PDF417$ function have about 500 lines, I thus don't reproduce
it here, you can retrieve it in the "form1.frm"
file which is with the above program ; with setup program, the "form1.frm" file is in the
program directory, "sources" sub-directory.
The function call is like this
: result$ = pdf417$(String$, Security%, ColNb%, ErrCode%)
with the
string to encode in String$, correction level in Security% (-1
= auto.), ColNb%
for the number of data columns in a row (<1 = auto.) and ErrCode% for retrieving
an eventual error code. these 3 last parameters are not required and are passed
by references; after the function return they contains the really used values. Values
of ErrCode% after the function return :
|
Click here ! |