3 # scan13 - utility to read bar codes from EPS files.
5 # Should be able to handle all EAN-13 variants including ISBN with UPC5
9 # scan13 <filename.eps>
11 # Copyright (C) 2007 Judah Milgram
13 # This program is free software; you can redistribute it and/or
14 # modify it under the terms of the GNU General Public License
15 # as published by the Free Software Foundation; either version 2
16 # of the License, or (at your option) any later version.
18 # Because this program copies a portion of itself into its output
19 # file, its output files are also copyright the author and licensed
20 # under the GPL. Relevant provisions of the GPL notwithstanding,
21 # the author licenses users to use and redistribute output files
22 # generated by this program without restriction.
24 # This program is distributed in the hope that it will be useful,
25 # but WITHOUT ANY WARRANTY; without even the implied warranty of
26 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
27 # GNU General Public License for more details.
29 # You should have received a copy of the GNU General Public License along
30 # with this program; if not, write to the Free Software Foundation, Inc.,
31 # 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
45 STRIPCOMMAND
= "pstopnm -pbm -stdout -portrait -ysize %d -xborder 0 -yborder 0 %%s 2> /dev/null | pnmcut -top %d -bottom %d" % (YSIZE
,YSIZE
/2,YSIZE
/2)
47 EPSFILE
= re
.compile(".*\.eps",re
.I
)
50 if not EPSFILE
.match(f
):
52 tempfil
= tempfile
.mktemp()
53 s
= os
.popen("%s > %s" % (STRIPCOMMAND
%f,tempfil
)).readline()
54 z
= Image
.open(tempfil
)
59 pixels
.append(pix
[i
,0])
63 def pixels2bars(pixels
):
66 for i
in range(1,len(pixels
)):
67 if pixels
[i
]!= pixels
[i
-1]:
74 # reduce to module widths
75 i
,a
= ean13index(bars
)
77 for j
in range(len(bars
)):
78 bars
[j
] = int(round(bars
[j
]/float(a
)))
82 return (ean13bars
,upc5bars
)
85 # Looking for 3 bars in ean13 right guard
87 # then first two bars in upc5 left guard
88 for i
in range(len(bars
)):
89 candidates
= bars
[i
:i
+5]
90 a
= min(candidates
[:3] + candidates
[4:])
91 b
= max(candidates
[:3] + candidates
[4:])
95 # sorry for the hard-coded magic number (8) ...
96 if abs(1-float(a
)/b
) < err
and c
> nlong
*a
:
101 def ean13index(bars
):
102 # index of EAN13 guard bars and module size
103 for i
in range(len(bars
)):
104 candidates
= bars
[i
:i
+3]
108 if abs(1-float(a
)/b
) < err
:
116 bits
.extend(bar
*[val
])
122 bits
= "".join(map(str,bits
))
123 for i
in range(len(productcode
.UPC5BITS
)):
124 dict = productcode
.UPC5BITS
[i
]
131 def ean13digit(bits
):
132 bits
= "".join(map(str,bits
))
133 for i
in range(len(productcode
.EAN13BITS
)):
134 dict = productcode
.EAN13BITS
[i
]
141 if __name__
=="__main__":
145 COPYRIGHT
="(C) 2007 J. Milgram"
146 VERSIONDATE
= "Feb 2007"
147 MAINTAINER
= "bookland-bugs@cgpp.com"
148 WARNING
= "This is free software and comes with NO WARRANTY"
150 sys
.stderr
.write("%s\n" % WARNING
)
154 pixels
= eps2pixels(filnam
)
155 ean13bars
,upc5bars
= pixels2bars(pixels
)
156 ean13bits
= bars2bits(ean13bars
)
157 upc5bits
= bars2bits(upc5bars
)
166 digit
,parity
= ean13digit(ean13bits
[i0
:i1
])
167 ean13digits
.append(digit
)
168 ean13pattern
.append(parity
)
169 for i
in range(6,12):
170 i0
= i
*7 + NLEFT
+ NCENTER
171 i1
= (i
+1)*7 + NLEFT
+ NCENTER
172 digit
,parity
=ean13digit(ean13bits
[i0
:i1
])
173 ean13digits
.append(digit
)
174 ean13pattern
.append(parity
)
175 ean13pattern
= "".join(ean13pattern
)
176 checkDigit
= productcode
.EAN13PARITY
.index(ean13pattern
)
177 ean13digits
.insert(0,checkDigit
)
178 ean13
= "".join(map(str,ean13digits
))
184 # 9 = 7 bits + 2 "delineators"
187 digit
,parity
= upc5digit(upc5bits
[i0
:i0
+7])
188 upc5digits
.append(digit
)
189 upc5pattern
.append(parity
)
190 upc5
= "".join(map(str,upc5digits
))