1
0
mirror of https://git.code.sf.net/p/zint/code synced 2026-09-22 12:12:37 +00:00

Initial revision

This commit is contained in:
factor
2008-07-13 21:15:55 +00:00
commit 52aa6fdb27
99 changed files with 24846 additions and 0 deletions
+351
View File
@@ -0,0 +1,351 @@
/* 2of5.c - Handles Code 2 of 5 barcodes */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
static char *C25MatrixTable[10] = {"113311", "311131", "131131", "331111", "113131", "313111",
"133111", "111331", "311311", "131311"};
static char *C25IndustTable[10] = {"1111313111", "3111111131", "1131111131", "3131111111", "1111311131",
"3111311111", "1131311111", "1111113131", "3111113111", "1131113111"};
static char *C25InterTable[10] = {"11331", "31113", "13113", "33111", "11313", "31311", "13311", "11133",
"31131", "13131"};
int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 2 of 5 Standard (Code 2 of 5 Matrix) */
int i, errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 80) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start character */
concat (dest, "411111");
for(i = 0; i <= strlen(source); i++) {
lookup(NESET, C25MatrixTable, source[i], dest);
}
/* Stop character */
concat (dest, "41111");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 2 of 5 Industrial */
int i, errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 45) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid character in data");
return errno;
}
/* start character */
concat (dest, "313111");
for(i = 0; i <= strlen(source); i++) {
lookup(NESET, C25IndustTable, source[i], dest);
}
/* Stop character */
concat (dest, "31113");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 2 of 5 IATA */
int i, errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 45) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start */
concat (dest, "1111");
for(i = 0; i < strlen(source); i++) {
lookup(NESET, C25IndustTable, source[i], dest);
}
/* stop */
concat (dest, "311");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 2 of 5 Data Logic */
int i, errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 80) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start character */
concat (dest, "1111");
for(i = 0; i <= strlen(source); i++) {
lookup(NESET, C25MatrixTable, source[i], dest);
}
/* Stop character */
concat (dest, "311");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 2 of 5 Interleaved */
int i, j, k, errno;
char bars[7], spaces[7], mixed[14], dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 90) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* Input must be an even number of characters for Interlaced 2 of 5 to work:
if an odd number of characters has been entered then add a leading zero */
if ((strlen(source)%2) != 0)
{
/* there are an odd number of input characters */
unsigned int length;
char temp[100];
length = strlen(source);
strcpy(temp, source);
source[0] = '0';
for(i = 0; i <= length; i++)
{
source[i + 1] = temp[i];
}
}
/* start character */
concat(dest, "1111");
for(i = 0; i < strlen(source); i+=2 )
{
/* look up the bars and the spaces and put them in two strings */
strcpy(bars, "");
lookup(NESET, C25InterTable, source[i], bars);
strcpy(spaces, "");
lookup(NESET, C25InterTable, source[i + 1], spaces);
/* then merge (interlace) the strings together */
k = 0;
for(j = 0; j <= 4; j++)
{
mixed[k] = bars[j]; k++;
mixed[k] = spaces[j]; k++;
}
mixed[k] = '\0';
concat (dest, mixed);
}
/* Stop character */
concat (dest, "311");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int itf14(struct zint_symbol *symbol, unsigned char source[])
{
int i, errno, h;
unsigned int count, check_digit;
errno = 0;
count = 0;
h = strlen(source);
if(h != 13) {
strcpy(symbol->errtxt, "error: input wrong length");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid character in data");
return errno;
}
/* Calculate the check digit - the same method used for EAN-13 */
for (i = h - 1; i >= 0; i--)
{
count += ctoi(source[i]);
if (!((i%2) == 0))
{
count += 2 * ctoi(source[i]);
}
}
check_digit = 10 - (count%10);
if (check_digit == 10) { check_digit = 0; }
source[h] = itoc(check_digit);
source[h + 1] = '\0';
errno = interleaved_two_of_five(symbol, source);
strcpy(symbol->text, source);
return errno;
}
int dpleit(struct zint_symbol *symbol, unsigned char source[])
{ /* Deutshe Post Leitcode */
int i, errno;
unsigned int h, count, check_digit;
errno = 0;
count = 0;
h = strlen(source);
if(h != 13) {
strcpy(symbol->errtxt, "error: input wrong length");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
for (i = h - 1; i >= 0; i--)
{
count += 4 * ctoi(source[i]);
if (!((i%2) == 0))
{
count += 5 * ctoi(source[i]);
}
}
check_digit = 10 - (count%10);
if (check_digit == 10) { check_digit = 0; }
source[h] = itoc(check_digit);
source[h + 1] = '\0';
errno = interleaved_two_of_five(symbol, source);
strcpy(symbol->text, source);
return errno;
}
int dpident(struct zint_symbol *symbol, unsigned char source[])
{ /* Deutsche Post Identcode */
int i, errno;
unsigned int h, count, check_digit;
count = 0;
h = strlen(source);
if(h != 11) {
strcpy(symbol->errtxt, "erro: input wrong length");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
for (i = h - 1; i >= 0; i--)
{
count += 4 * ctoi(source[i]);
if (!((i%2) == 0))
{
count += 5 * ctoi(source[i]);
}
}
check_digit = 10 - (count%10);
if (check_digit == 10) { check_digit = 0; }
source[h] = itoc(check_digit);
source[h + 1] = '\0';
errno = interleaved_two_of_five(symbol, source);
strcpy(symbol->text, source);
return errno;
}
+674
View File
@@ -0,0 +1,674 @@
GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
<http://www.gnu.org/licenses/>.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
+109
View File
@@ -0,0 +1,109 @@
Contents
--------
Here is a guide to which bit of source code does what.
2of5.c:
Matrix 2 of 5
Industrial 2 of 5
IATA 2 of 5
Data Logic
Interleaved 2 of 5
ITF-14
Deutche Post Leitcode
Deutche Post Identcode
auspost.c:
Australia Post Standard Customer Barcode
Australia Post Customer Barcode 2
Australia Post Customer Barcode 3
Australia Post Reply Paid Barcode
Australia Post Routing Barcode
Australia Post Redirect Barcode
aztec.c:
Aztec Mesa
code128.c:
Code 128
Code 128 Subset B
NVE-18
GS1-128 (UCC/EAN-128)
code16k.c:
Code 16k
code.c:
Code 11
Code 39
Pharmazentral Nummer (PZN)
Extended Code 39 (Code 39+)
Code 93
LOGMARS
composite.c:
CC-A Composite Symbology
CC-B Composite Symbology
CC-C Composite Symbology
dmatrix.c:
Data Matrix (Semacode)
imail.c:
USPS OneCode (Intelligent Mail)
maxicode.c:
UPS Maxicode
medical.c:
Pharma Code
Two Track Pharma Code
Codabar
pdf417.c:
PDF417
Truncated PDF417
MicroPDF417
plessey.c:
UK Plessey Code (bidirectional)
MSI Plessey (no check)
MSI Plessey (Mod 10 check)
MSI Plessey (Mod 11 check)
MSI Plessey (Mod 10 Mod 10 check)
MSI Plessey (Mod 10 Mod 11 check)
postal.c:
PostNet
PLANET
Facing Identification Mark (FIM)
Royal Mail 4-State Country Code (RM4SCC)
Korean Postal Authority Code (Disabled)
Flattermarken
qr.c:
QR Code (libqrencode)
rss.c:
GS1 DataBar (DataBar-14) (RSS-14)
GS1 DataBar Stacked (RSS-14 Stacked)
GS1 DataBar Stacked Omnidirectional (DataBar-14 Stacked Omnidirectional)
(RSS-14 Stacked Omnidirectional)
GS1 DataBar Limited (RSS Limited)
GS1 DataBar Expanded (RSS Expanded)
GS1 DataBar Expanded Stacked (RSS Expanded Stacked)
telepen.c:
Telepen ASCII
Telepen Numeric
upcean.c:
UPC-A
UPC-E
EAN-2 add-on
EAN-5 add-on
EAN-8
EAN-13
SBN (verification)
ISBN (verification)
ISBN-13 (verification)
+51
View File
@@ -0,0 +1,51 @@
# Linux makefile for libzint
#
# make compiles with QR Code support
# make libzint_noqr compiles without QR Code support
# make install copies to /usr/local/lib
# make uninstall removes library
# make clean cleans up a previous compilation and any object or editor files
#
CC := gcc
INCLUDE := -I/usr/local/include
COMMON:= common.c png.c library.c ps.c large.c reedsol.c
COMMON_OBJ:= common.o png.o library.o ps.o large.o reedsol.o
ONEDIM:= code.c code128.c 2of5.c upcean.c telepen.c medical.c plessey.c rss.c
ONEDIM_OBJ:= code.o code128.o 2of5.o upcean.o telepen.o medical.o plessey.o rss.o
POSTAL:= postal.c auspost.c imail.c
POSTAL_OBJ:= postal.o auspost.o imail.o
TWODIM:= code16k.c dmatrix.c dm200.c pdf417.c maxicode.c composite.c
TWODIM_OBJ:= code16k.o dmatrix.o dm200.o pdf417.o maxicode.o composite.o
LIBS:= `libpng12-config --I_opts --L_opts --ldflags` -lz -lm
libzint: code.c code128.c 2of5.c upcean.c medical.c telepen.c plessey.c postal.c auspost.c imail.c code16k.c dmatrix.c dm200.c reedsol.c pdf417.c maxicode.c rss.c common.c png.c library.c ps.c qr.c large.c composite.c
$(CC) -fPIC -g -c $(ONEDIM)
$(CC) -fPIC -g -c $(POSTAL)
$(CC) -fPIC -g -c $(TWODIM) qr.c
$(CC) -fPIC -g -c $(COMMON)
$(CC) -g -shared -Wl,-soname,libzint.so -o libzint.so.1.6.0 $(INCLUDE) $(COMMON_OBJ) $(ONEDIM_OBJ) $(TWODIM_OBJ) qr.o $(POSTAL_OBJ) $(LIBS) -lqrencode
libzint_noqr: code.c code128.c 2of5.c upcean.c medical.c telepen.c plessey.c postal.c auspost.c imail.c code16k.c dmatrix.c dm200.c reedsol.c pdf417.c maxicode.c rss.c common.c png.c library.c ps.c no_qr.c large.c composite.c
$(CC) -fPIC -g -c $(ONEDIM)
$(CC) -fPIC -g -c $(POSTAL)
$(CC) -fPIC -g -c $(TWODIM) no_qr.c
$(CC) -fPIC -g -c $(COMMON)
$(CC) -g -shared -Wl,-soname,libzint.so -o libzint.so.1.6.0 $(INCLUDE) $(COMMON_OBJ) $(ONEDIM_OBJ) $(TWODIM_OBJ) no_qr.o $(POSTAL_OBJ) $(LIBS)
.PHONY: install uninstall clean dist
install:
ldconfig -n $(PWD)
mv libzint.* /usr/local/lib
cp zint.h /usr/local/include
uninstall:
rm /usr/local/lib/libzint.*
rm /usr/local/include/zint.h
clean:
rm -f libzint.* *.o *.a *~
+240
View File
@@ -0,0 +1,240 @@
/* auspost.c - Handles Australia Post 4-State Barcode */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define GDSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz #"
static char *AusNTable[10] = {"00", "01", "02", "10", "11", "12", "20", "21", "22", "30"};
static char *AusCTable[64] = {"222", "300", "301", "302", "310", "311", "312", "320", "321", "322",
"000", "001", "002", "010", "011", "012", "020", "021", "022", "100", "101", "102", "110",
"111", "112", "120", "121", "122", "200", "201", "202", "210", "211", "212", "220", "221",
"023", "030", "031", "032", "033", "103", "113", "123", "130", "131", "132", "133", "203",
"213", "223", "230", "231", "232", "233", "303", "313", "323", "330", "331", "332", "333",
"003", "013"};
static char *AusBarTable[64] = {"000", "001", "002", "003", "010", "011", "012", "013", "020", "021",
"022", "023", "030", "031", "032", "033", "100", "101", "102", "103", "110", "111", "112",
"113", "120", "121", "122", "123", "130", "131", "132", "133", "200", "201", "202", "203",
"210", "211", "212", "213", "220", "221", "222", "223", "230", "231", "232", "233", "300",
"301", "302", "303", "310", "311", "312", "313", "320", "321", "322", "323", "330", "331",
"332", "333"};
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#include "reedsol.h"
void rs_error(char data_pattern[])
{
/* Adds Reed-Solomon error correction to auspost */
int reader, triple_writer;
char triple[31], inv_triple[31];
char result[5];
triple_writer = 0;
for(reader = 2; reader < strlen(data_pattern); reader+= 3)
{
triple[triple_writer] = 0;
switch(data_pattern[reader])
{
case '1': triple[triple_writer] += 16; break;
case '2': triple[triple_writer] += 32; break;
case '3': triple[triple_writer] += 48; break;
}
switch(data_pattern[reader + 1])
{
case '1': triple[triple_writer] += 4; break;
case '2': triple[triple_writer] += 8; break;
case '3': triple[triple_writer] += 12; break;
}
switch(data_pattern[reader + 2])
{
case '1': triple[triple_writer] += 1; break;
case '2': triple[triple_writer] += 2; break;
case '3': triple[triple_writer] += 3; break;
}
triple_writer++;
}
for(reader = 0; reader < triple_writer; reader++)
{
inv_triple[reader] = triple[(triple_writer - 1) - reader];
}
rs_init_gf(0x43);
rs_init_code(4, 1);
rs_encode(triple_writer, inv_triple, result);
for(reader = 4; reader > 0; reader--)
{
concat(data_pattern, AusBarTable[result[reader - 1]]);
}
}
int australia_post(struct zint_symbol *symbol, unsigned char source[])
{
/* Handles Australia Posts's 4 State Codes */
/* Customer Standard Barcode, Barcode 2 or Barcode 3 system determined automatically
(i.e. the FCC doesn't need to be specified by the user) dependent
on the length of the input string */
/* The contents of data_pattern conform to the following standard:
0 = Tracker, Ascender and Descender
1 = Tracker and Ascender
2 = Tracker and Descender
3 = Tracker only */
char data_pattern[200];
char fcc[3], dpid[10];
unsigned int loopey, reader;
int writer;
strcpy (data_pattern, "");
int errno;
errno = 0;
/* Do all of the length checking first to avoid stack smashing */
if(symbol->symbology == BARCODE_AUSPOST) {
/* Format control code (FCC) */
switch(strlen(source))
{
case 8: strcpy(fcc, "11"); break;
case 13: strcpy(fcc, "59"); break;
case 16: strcpy(fcc, "59"); errno = is_sane(NESET, source); break;
case 18: strcpy(fcc, "62"); break;
case 23: strcpy(fcc, "62"); errno = is_sane(NESET, source); break;
default: strcpy(symbol->errtxt, "error: auspost input is wrong length");
return ERROR_TOO_LONG;
break;
}
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
} else {
if(strlen(source) != 8) {
strcpy(symbol->errtxt, "error: auspost input is wrong length");
return ERROR_TOO_LONG;
}
switch(symbol->symbology) {
case BARCODE_AUSREPLY: strcpy(fcc, "45"); break;
case BARCODE_AUSROUTE: strcpy(fcc, "87"); break;
case BARCODE_AUSREDIRECT: strcpy(fcc, "92"); break;
}
}
errno = is_sane(GDSET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* Verifiy that the first 8 characters are numbers */
for(loopey = 0; loopey < 8; loopey++) {
dpid[loopey] = source[loopey];
}
dpid[8] = '\0';
errno = is_sane(NESET, dpid);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in DPID");
return errno;
}
/* Start character */
concat(data_pattern, "13");
/* Encode the FCC */
for(reader = 0; reader < 2; reader++)
{
lookup(NESET, AusNTable, fcc[reader], data_pattern);
}
/* printf("AUSPOST FCC: %s ", fcc); */
/* Delivery Point Identifier (DPID) */
for(reader = 0; reader < 8; reader++)
{
lookup(NESET, AusNTable, dpid[reader], data_pattern);
}
/* Customer Information */
if(strlen(source) > 8)
{
if((strlen(source) == 13) || (strlen(source) == 18)) {
for(reader = 8; reader < strlen(source); reader++) {
lookup(GDSET, AusCTable, source[reader], data_pattern);
}
}
if((strlen(source) == 16) || (strlen(source) == 23)) {
for(reader = 8; reader < strlen(source); reader++) {
lookup(NESET, AusNTable, source[reader], data_pattern);
}
}
}
/* Filler bar */
if(strlen(data_pattern) == 22) {
concat(data_pattern, "3");
}
if(strlen(data_pattern) == 37) {
concat(data_pattern, "3");
}
if(strlen(data_pattern) == 52) {
concat(data_pattern, "3");
}
/* Reed Solomon error correction */
rs_error(data_pattern);
/* Stop character */
concat(data_pattern, "13");
/* Turn the symbol into a bar pattern ready for plotting */
writer = 0;
for(loopey = 0; loopey < strlen(data_pattern); loopey++)
{
if((data_pattern[loopey] == '1') || (data_pattern[loopey] == '0'))
{
symbol->encoded_data[0][writer] = '1';
}
symbol->encoded_data[1][writer] = '1';
if((data_pattern[loopey] == '2') || (data_pattern[loopey] == '0'))
{
symbol->encoded_data[2][writer] = '1';
}
writer += 2;
}
symbol->row_height[0] = 4;
symbol->row_height[1] = 2;
symbol->row_height[2] = 4;
symbol->rows = 3;
symbol->width = writer - 1;
return errno;
}
+435
View File
@@ -0,0 +1,435 @@
/* code.c - Handles Code 11, 39, 39+ and 93 */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* In version 0.5 this file was 1,553 lines long! */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#define NASET "0123456789-"
static char *C11Table[11] = {"111121", "211121", "121121", "221111", "112121", "212111", "122111",
"111221", "211211", "211111", "112111"};
/* Code 39 tables checked against ISO/IEC 16388:2007 */
#define TCSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%abcd"
/* Incorporates Table A1 */
static char *C39Table[43] = { "1112212111", "2112111121", "1122111121", "2122111111", "1112211121",
"2112211111", "1122211111", "1112112121", "2112112111", "1122112111", "2111121121",
"1121121121", "2121121111", "1111221121", "2111221111", "1121221111", "1111122121",
"2111122111", "1121122111", "1111222111", "2111111221", "1121111221", "2121111211",
"1111211221", "2111211211", "1121211211", "1111112221", "2111112211", "1121112211",
"1111212211", "2211111121", "1221111121", "2221111111", "1211211121", "2211211111",
"1221211111", "1211112121", "2211112111", "1221112111", "1212121111", "1212111211",
"1211121211", "1112121211"};
/* Code 39 character assignments (Table 1) */
static char *EC39Ctrl[128] = {"%U", "$A", "$B", "$C", "$D", "$E", "$F", "$G", "$H", "$I", "$J", "$K",
"$L", "$M", "$N", "$O", "$P", "$Q", "$R", "$S", "$T", "$U", "$V", "$W", "$X", "$Y", "$Z",
"%A", "%B", "%C", "%D", "%E", " ", "/A", "/B", "/C", "/D", "/E", "/F", "/G", "/H", "/I", "/J",
"/K", "/L", "-", ".", "/O", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "/Z", "%F",
"%G", "%H", "%I", "%J", "%V", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "%K", "%L", "%M", "%N", "%O",
"%W", "+A", "+B", "+C", "+D", "+E", "+F", "+G", "+H", "+I", "+J", "+K", "+L", "+M", "+N", "+O",
"+P", "+Q", "+R", "+S", "+T", "+U", "+V", "+W", "+X", "+Y", "+Z", "%P", "%Q", "%R", "%S", "%T"};
/* Encoding the full ASCII character set in Code 39 (Table A2) */
static char *C93Ctrl[128] = {"bU", "aA", "aB", "aC", "aD", "aE", "aF", "aG", "aH", "aI", "aJ", "aK",
"aL", "aM", "aN", "aO", "aP", "aQ", "aR", "aS", "aT", "aU", "aV", "aW", "aX", "aY", "aZ",
"bA", "bB", "bC", "bD", "bE", " ", "cA", "cB", "cC", "cD", "cE", "cF", "cG", "cH", "cI", "cJ",
"cK", "cL", "cM", "cN", "cO", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "cZ", "bF",
"bG", "bH", "bI", "bJ", "bV", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M",
"N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z", "bK", "bL", "bM", "bN", "bO",
"bW", "dA", "dB", "dC", "dD", "dE", "dF", "dG", "dH", "dI", "dJ", "dK", "dL", "dM", "dN", "dO",
"dP", "dQ", "dR", "dS", "dT", "dU", "dV", "dW", "dX", "dY", "dZ", "bP", "bQ", "bR", "bS", "bT"};
static char *C93Table[47] = {"131112", "111213", "111312", "111411", "121113", "121212", "121311",
"111114", "131211", "141111", "211113", "211212", "211311", "221112", "221211", "231111",
"112113", "112212", "112311", "122112", "132111", "111123", "111222", "111321", "121122",
"131121", "212112", "212211", "211122", "211221", "221121", "222111", "112122", "112221",
"122121", "123111", "121131", "311112", "311211", "321111", "112131", "113121", "211131",
"121221", "312111", "311121", "122211"};
/* *********************** CODE 11 ******************** */
int code_11(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 11 */
unsigned int i;
int h, c_digit, c_weight, c_count, k_digit, k_weight, k_count;
int weight[1000], errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 80) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NASET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
c_weight = 1;
c_count = 0;
k_weight = 1;
k_count = 0;
/* start character */
concat (dest, "112211");
/* Draw main body of barcode */
for(i = 0; i < strlen(source); i++) {
lookup(NASET, C11Table, source[i], dest);
weight[i] = ctoi(source[i]);
}
/* Calculate C checksum */
for(h = (strlen(source) - 1); h >= 0; h--) {
c_count += (c_weight * weight[h]);
c_weight++;
if(c_weight > 10) {
c_weight = 1;
}
}
c_digit = c_count%11;
/* Draw C checksum */
lookup(NASET, C11Table, itoc(c_digit), dest);
weight[strlen(source)] = c_digit;
/* Calculate K checksum */
for(h = strlen(source); h >= 0; h--) {
k_count += (k_weight * weight[h]);
k_weight++;
if(k_weight > 9) {
k_weight = 1;
}
}
k_digit = k_count%11;
/* Draw K checksum */
lookup(NASET, C11Table, itoc(k_digit), dest);
/* Stop character */
concat (dest, "11221");
h = strlen(source);
source[h] = itoc(c_digit);
source[h + 1] = itoc(k_digit);
source[h + 2] = '\0';
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int c39(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 39 */
unsigned int i;
unsigned int counter;
char check_digit;
int h, errno;
char dest[1000];
errno = 0;
counter = 0;
strcpy(dest, "");
to_upper(source);
if(strlen(source) > 45) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(TCSET , source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* Start character */
concat(dest, "1211212111");
for(i = 0; i < strlen(source); i++) {
lookup(TCSET, C39Table, source[i], dest);
counter += posn(TCSET, source[i]);
}
if(((symbol->symbology == BARCODE_LOGMARS) || (symbol->symbology == BARCODE_CODE39_43)) || (symbol->symbology == BARCODE_EXCODE39_43)) {
counter = counter % 43;
if(counter < 10) {
check_digit = itoc(counter);
} else {
if(counter < 36) {
check_digit = (counter - 10) + 'A';
} else {
switch(counter) {
case 36: check_digit = '-'; break;
case 37: check_digit = '.'; break;
case 38: check_digit = ' '; break;
case 39: check_digit = '$'; break;
case 40: check_digit = '/'; break;
case 41: check_digit = '+'; break;
case 42: check_digit = 37; break;
}
}
}
lookup(TCSET, C39Table, check_digit, dest);
/* Display a space check digit as _, otherwise it looks like an error */
if(check_digit == ' ') {
check_digit = '_';
}
h = strlen(source);
source[h] = check_digit;
source[h + 1] = '\0';
}
/* Stop character */
concat (dest, "121121211");
if(symbol->symbology == BARCODE_LOGMARS) {
/* LOGMARS uses wider 'wide' bars than normal Code 39 */
for(i = 0; i < strlen(dest); i++) {
if(dest[i] == '2') {
dest[i] = '3';
}
}
}
expand(symbol, dest);
if((symbol->symbology == BARCODE_CODE39) || (symbol->symbology == BARCODE_CODE39_43)) {
strcpy(symbol->text, "*");
concat(symbol->text, source);
concat(symbol->text, "*");
} else {
strcpy(symbol->text, source);
}
return errno;
}
int pharmazentral(struct zint_symbol *symbol, unsigned char source[])
{ /* Pharmazentral Nummer (PZN) */
int i, errno;
unsigned int h, count, check_digit;
errno = 0;
count = 0;
h = strlen(source);
if(h != 6) {
strcpy(symbol->errtxt, "error: input wrong length");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
for (i = 0; i < h; i++)
{
count += (i + 2) * ctoi(source[i]);
}
for(i = h + 1; i >= 1; i--)
{
source[i] = source[i - 1];
}
source[0] = '-';
check_digit = count%11;
if (check_digit == 11) { check_digit = 0; }
source[h + 1] = itoc(check_digit);
source[h + 2] = '\0';
errno = c39(symbol, source);
strcpy(symbol->text, source);
return errno;
}
/* ************** EXTENDED CODE 39 *************** */
int ec39(struct zint_symbol *symbol, unsigned char source[])
{ /* Extended Code 39 - ISO/IEC 16388:2007 Annex A */
char buffer[100];
unsigned int i;
strcpy(buffer, "");
int ascii_value;
int errno;
errno = 0;
if(strlen(source) > 45) {
/* only stops strings which are far too long - actual length of the barcode
depends on the type of data being encoded - if it's too long it's picked up
by c39() */
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
for(i = 0; i < strlen(source); i++) {
if(source[i] > 127) {
/* Cannot encode extended ASCII */
strcpy(symbol->errtxt, "error: invalid characters in input data");
return ERROR_INVALID_DATA;
}
}
/* Creates a buffer string and places control characters into it */
for(i = 0; i < strlen(source); i++) {
ascii_value = source[i];
concat(buffer, EC39Ctrl[ascii_value]);
}
/* Then sends the buffer to the C39 function */
errno = c39(symbol, buffer);
strcpy(symbol->text, source);
return errno;
}
/* ******************** CODE 93 ******************* */
int c93(struct zint_symbol *symbol, unsigned char source[])
{ /* Code 93 is an advancement on Code 39 and the definition is a lot tighter */
/* TCSET includes the extra characters a, b, c and d to represent Code 93 specific
shift characters 1, 2, 3 and 4 respectively. These characters are never used by
c39() and ec39() */
unsigned int i;
int h, weight, c, k, values[100], errno;
char buffer[100], temp[2];
char set_copy[] = TCSET;
strcpy(buffer, "");
int ascii_value;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 45) {
/* This stops rediculously long input - the actual length of the barcode
depends on the type of data */
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
for(i = 0; i < strlen(source); i++) {
if(source[i] > 127) {
/* Cannot encode extended ASCII */
strcpy(symbol->errtxt, "error: invalid characters in input data");
return ERROR_INVALID_DATA;
}
}
/* Start character */
concat(dest, "111141");
/* Message Content */
for(i = 0; i < strlen(source); i++) {
ascii_value = source[i];
concat(buffer, C93Ctrl[ascii_value]);
}
/* Now we can check the true length of the barcode */
if(strlen(buffer) > 45) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
for(i = 0; i < strlen(buffer); i++) {
values[i] = posn(TCSET, buffer[i]);
}
/* Putting the data into dest[] is not done until after check digits are calculated */
/* Check digit C */
c = 0;
weight = 1;
for(h = strlen(buffer) - 1; h >= 0; h--)
{
c += values[h] * weight;
weight ++;
if(weight == 21)
{
weight = 1;
}
}
c = c % 47;
/* Because concat() requires a string as its second argument the check digit is converted
to a character which is then put in temp[] before being added to buffer[] - its
a bit long winded but avoids putting yet another function into common.c */
values[strlen(buffer)] = c;
temp[0] = set_copy[c];
temp[1] = '\0';
concat(buffer, temp);
/* Check digit K */
k = 0;
weight = 1;
for(h = strlen(buffer) - 1; h >= 0; h--)
{
k += values[h] * weight;
weight ++;
if(weight == 16)
{
weight = 1;
}
}
k = k % 47;
temp[0] = set_copy[k];
temp[1] = '\0';
concat(buffer, temp);
for(i = 0; i < strlen(buffer); i++) {
lookup(TCSET, C93Table, buffer[i], dest);
}
/* Stop character */
concat(dest, "1111411");
h = strlen(source);
source[h] = set_copy[c];
source[h + 1] = set_copy[k];
source[h + 2] = '\0';
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
+846
View File
@@ -0,0 +1,846 @@
/* code128.c - Handles Code 128 and derivatives */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
#define TRUE 1
#define FALSE 0
#define SHIFTA 90
#define LATCHA 91
#define SHIFTB 92
#define LATCHB 93
#define SHIFTC 94
#define LATCHC 95
#define AORB 96
#define ABORC 97
int list[2][170];
/* Code 128 tables checked against ISO/IEC 15417:2007 */
static char *C128Table[107] = {"212222", "222122", "222221", "121223", "121322", "131222", "122213",
"122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222",
"123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222",
"321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323",
"131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133",
"112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113",
"213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111",
"221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214",
"112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112",
"134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112",
"421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311",
"411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232",
"2331112"};
/* Code 128 character encodation - Table 1 */
int parunmodd(unsigned char llyth)
{
int modd;
modd = 0;
if(llyth <= 31) { modd = SHIFTA; }
if((llyth >= 32) && (llyth <= 95)) { modd = AORB; }
if((llyth >= 48) && (llyth <= 57)) { modd = ABORC; }
if((llyth >= 96) && (llyth <= 127)) { modd = SHIFTB; }
if((llyth >= 128) && (llyth <= 159)) { modd = SHIFTA; }
if((llyth >= 160) && (llyth <= 223)) { modd = AORB; }
if(llyth >= 224) { modd = SHIFTB; }
return modd;
}
void grwp(int *indexliste)
{
int i, j;
/* bring together same type blocks */
if(*(indexliste) > 1) {
i = 1;
while(i < *(indexliste)) {
if(list[1][i - 1] == list[1][i]) {
/* bring together */
list[0][i - 1] = list[0][i - 1] + list[0][i];
j = i + 1;
/* decreace the list */
while(j < *(indexliste)) {
list[0][j - 1] = list[0][j];
list[1][j - 1] = list[1][j];
j++;
}
*(indexliste) = *(indexliste) - 1;
i--;
}
i++;
}
}
}
void dxsmooth(int *indexliste)
{ /* Implements rules from ISO 15417 Annex E */
int i, this, last, next, length;
for(i = 0; i < *(indexliste); i++) {
this = list[1][i];
length = list[0][i];
if(i != 0) { last = list[1][i - 1]; } else { last = FALSE; }
if(i != *(indexliste) - 1) { next = list[1][i + 1]; } else { next = FALSE; }
if(i == 0) { /* first block */
if((*(indexliste) == 1) && ((length == 2) && (this == ABORC))) { /* Rule 1a */ list[1][i] = LATCHC; }
if(this == ABORC) {
if(length >= 4) {/* Rule 1b */ list[1][i] = LATCHC; } else { list[1][i] = AORB; this = AORB; }
}
if(this == SHIFTA) { /* Rule 1c */ list[1][i] = LATCHA; }
if((this == AORB) && (next == SHIFTA)) { /* Rule 1c */ list[1][i] = LATCHA; this = LATCHA; }
if(this == AORB) { /* Rule 1d */ list[1][i] = LATCHB; }
} else {
if((this == ABORC) && (length >= 4)) { /* Rule 3 */ list[1][i] = LATCHC; this = LATCHC; }
if(this == ABORC) { list[1][i] = AORB; this = AORB; }
if((this == AORB) && (last == LATCHA)) { list[1][i] = LATCHA; this = LATCHA; }
if((this == AORB) && (last == LATCHB)) { list[1][i] = LATCHB; this = LATCHB; }
if((this == AORB) && (next == SHIFTA)) { list[1][i] = LATCHA; this = LATCHA; }
if((this == AORB) && (next == SHIFTB)) { list[1][i] = LATCHB; this = LATCHB; }
if(this == AORB) { list[1][i] = LATCHB; this = LATCHB; }
if((this == SHIFTA) && (length > 1)) { /* Rule 4 */ list[1][i] = LATCHA; this = LATCHA; }
if((this == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; this = LATCHB; }
if((this == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; this = LATCHA; }
if((this == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; this = LATCHB; }
} /* Rule 2 is implimented elsewhere, Rule 6 is implied */
}
grwp(indexliste);
}
void c128_set_a(unsigned char source, char dest[], int values[], int *bar_chars)
{ /* Translate Code 128 Set A characters into barcodes */
/* This set handles all control characters NULL to US */
if(source > 127) {
concat(dest, C128Table[source + 64 - 128]);
values[(*bar_chars)] = source + 64 - 128;
} else {
concat(dest, C128Table[source + 64]);
values[(*bar_chars)] = source + 64;
}
(*bar_chars)++;
}
void c128_set_b(unsigned char source, char dest[], int values[], int *bar_chars)
{ /* Translate Code 128 Set B characters into barcodes */
/* This set handles all characters which are not part of long numbers and not control characters */
if(source > 127) {
concat(dest, C128Table[source - 32 - 128]);
values[(*bar_chars)] = source - 32 - 128;
} else {
concat(dest, C128Table[source - 32]);
values[(*bar_chars)] = source - 32;
}
(*bar_chars)++;
}
void c128_set_c(unsigned char source_a, unsigned char source_b, char dest[], int values[], int *bar_chars)
{ /* Translate Code 128 Set C characters into barcodes */
/* This set handles numbers in a compressed form */
int weight;
weight = (10 * ctoi(source_a)) + ctoi(source_b);
concat(dest, C128Table[weight]);
values[(*bar_chars)] = weight;
(*bar_chars)++;
}
int code_128(struct zint_symbol *symbol, unsigned char source[])
{ /* Handle Code 128 and NVE-18 */
int i, j, k, e_count, values[170], bar_characters, read, total_sum, nve_check;
int errornum, indexchaine, indexliste;
char set[170], fset[170], mode, last_set, last_fset;
float glyph_count;
char dest[1000];
errornum = 0;
strcpy(dest, "");
j = 0;
e_count = 0;
bar_characters = 0;
nve_check = 0;
for(i = 0; i < 170; i++) {
values[i] = 0;
set[i] = ' ';
fset[i] = ' ';
}
if(strlen(source) > 160) {
/* This only blocks rediculously long input - the actual length of the
resulting barcode depends on the type of data, so this is trapped later */
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
/* Add check digit if encoding an NVE18 symbol */
if(symbol->symbology == BARCODE_NVE18) {
errornum = is_sane(NESET, source);
if(errornum == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errornum;
}
if(strlen(source) != 17) {
strcpy(symbol->errtxt, "error: input wrong length");
return ERROR_TOO_LONG;
}
for(i = strlen(source) + 2; i > 1; i--) {
source[i] = source[i - 2];
}
source[0] = '0';
source[1] = '0';
total_sum = 0;
for(i = 0; i < 19; i++)
{
if((i % 2) == 0) {
total_sum += 3 * ctoi(source[i]);
} else {
total_sum += ctoi(source[i]);
}
}
nve_check = 10 - total_sum%10;
source[strlen(source) + 1] = '\0';
source[strlen(source)] = itoc(nve_check);
}
/* Detect extended ASCII characters */
for(i = 0; i < strlen(source); i++) {
if(source[i] >=128) {
fset[i] = 'f';
}
}
fset[i] = '\0';
/* Decide when to latch to extended mode - Annex E note 3 */
for(i = 0; i < strlen(source); i++) {
j = 0;
if(fset[i] == 'f') {
do {
j++;
} while(source[i + j] == 'f');
if((j >= 5) || ((j >= 3) && ((i + j) == strlen(source)))) {
for(k = 0; k <= j; k++) {
source[i + k] = 'F';
}
}
}
}
/* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */
indexliste = 0;
indexchaine = 0;
mode = parunmodd(source[indexchaine]);
if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) {
mode = AORB;
}
for(i = 0; i < 170; i++) {
list[0][i] = 0;
}
do {
list[1][indexliste] = mode;
while ((list[1][indexliste] == mode) && (indexchaine < strlen(source))) {
list[0][indexliste]++;
indexchaine++;
mode = parunmodd(source[indexchaine]);
if((symbol->symbology == BARCODE_CODE128B) && (mode == ABORC)) {
mode = AORB;
}
}
indexliste++;
} while (indexchaine < strlen(source));
dxsmooth(&indexliste);
/* Resolve odd length LATCHC blocks */
if((list[1][0] == LATCHC) && ((list[0][0] % 2) == 1)) {
/* Rule 2 */
list[0][1]++;
list[0][0]--;
}
if(indexliste > 1) {
for(i = 1; i < indexliste; i++) {
if((list[1][i] == LATCHC) && ((list[0][i] % 2) == 1)) {
/* Rule 3b */
list[0][i - 1]++;
list[0][i]--;
}
}
}
/* Put set data into set[] */
read = 0;
for(i = 0; i < indexliste; i++) {
for(j = 0; j < list[0][i]; j++) {
switch(list[1][i]) {
case SHIFTA: set[read] = 'a'; break;
case LATCHA: set[read] = 'A'; break;
case SHIFTB: set[read] = 'b'; break;
case LATCHB: set[read] = 'B'; break;
case LATCHC: set[read] = 'C'; break;
}
read++;
}
}
/* Now we can calculate how long the barcode is going to be - and stop it from
being too long */
last_set = ' ';
last_fset = ' ';
glyph_count = 0.0;
for(i = 0; i < strlen(source); i++) {
if((set[i] == 'a') || (set[i] == 'b')) {
glyph_count = glyph_count + 1.0;
}
if(fset[i] == 'f') {
glyph_count = glyph_count + 1.0;
}
if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) {
if(set[i] != last_set) {
last_set = set[i];
glyph_count = glyph_count + 1.0;
}
}
if(i == 0) {
if(fset[i] == 'F') {
last_fset = 'F';
glyph_count = glyph_count + 2.0;
}
} else {
if((fset[i] == 'F') && (fset[i - 1] != 'F')) {
last_fset = 'F';
glyph_count = glyph_count + 2.0;
}
if((fset[i] != 'F') && (fset[i - 1] == 'F')) {
last_fset = ' ';
glyph_count = glyph_count + 2.0;
}
}
if(set[i] == 'C') {
glyph_count = glyph_count + 0.5;
} else {
glyph_count = glyph_count + 1.0;
}
}
if(glyph_count > 80.0) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
/* So now we know what start character to use - we can get on with it! */
switch(set[0])
{
case 'A': /* Start A */
concat(dest, C128Table[103]);
values[0] = 103;
break;
case 'B': /* Start B */
concat(dest, C128Table[104]);
values[0] = 104;
break;
case 'C': /* Start C */
concat(dest, C128Table[105]);
values[0] = 105;
break;
}
bar_characters++;
if(symbol->symbology == BARCODE_NVE18) {
concat(dest, C128Table[102]);
values[1] = 102;
bar_characters++;
}
if(fset[0] == 'F') {
switch(set[0]) {
case 'A':
concat(dest, C128Table[101]);
concat(dest, C128Table[101]);
values[bar_characters] = 101;
values[bar_characters + 1] = 101;
break;
case 'B':
concat(dest, C128Table[100]);
concat(dest, C128Table[100]);
values[bar_characters] = 100;
values[bar_characters + 1] = 100;
break;
}
bar_characters += 2;
}
/* Encode the data */
read = 0;
do {
if((read != 0) && (set[read] != set[read - 1]))
{ /* Latch different code set */
switch(set[read])
{
case 'A': concat(dest, C128Table[101]);
values[bar_characters] = 101;
bar_characters++;
break;
case 'B': concat(dest, C128Table[100]);
values[bar_characters] = 100;
bar_characters++;
break;
case 'C': concat(dest, C128Table[99]);
values[bar_characters] = 99;
bar_characters++;
break;
}
}
if((read != 0) && (fset[read] != fset[read - 1])) {
if(fset[read] == 'F') {
/* Latch beginning of extended mode */
switch(set[0]) {
case 'A':
concat(dest, C128Table[101]);
concat(dest, C128Table[101]);
values[bar_characters] = 101;
values[bar_characters + 1] = 101;
break;
case 'B':
concat(dest, C128Table[100]);
concat(dest, C128Table[100]);
values[bar_characters] = 100;
values[bar_characters + 1] = 100;
break;
}
bar_characters += 2;
}
if(fset[read - 1] == 'F') {
/* Latch end of extended mode */
switch(set[0]) {
case 'A':
concat(dest, C128Table[101]);
concat(dest, C128Table[101]);
values[bar_characters] = 101;
values[bar_characters + 1] = 101;
break;
case 'B':
concat(dest, C128Table[100]);
concat(dest, C128Table[100]);
values[bar_characters] = 100;
values[bar_characters + 1] = 100;
break;
}
bar_characters += 2;
}
}
if(fset[i] == 'f') {
/* Shift extended mode */
switch(set[i]) {
case 'A':
concat(dest, C128Table[101]);
values[bar_characters] = 101;
break;
case 'B':
concat(dest, C128Table[100]);
values[bar_characters] = 100;
break;
}
bar_characters++;
}
if((set[i] == 'a') || (set[i] == 'b')) {
/* Insert shift character */
concat(dest, C128Table[98]);
values[bar_characters] = 98;
bar_characters++;
}
switch(set[read])
{ /* Encode data characters */
case 'A': c128_set_a(source[read], dest, values, &bar_characters);
read++;
break;
case 'B': c128_set_b(source[read], dest, values, &bar_characters);
read++;
break;
case 'C': c128_set_c(source[read], source[read + 1], dest, values, &bar_characters);
read += 2;
break;
}
} while (read < strlen(source));
/* check digit calculation */
total_sum = 0;
for(i = 0; i < bar_characters; i++)
{
if(i > 0)
{
values[i] *= i;
}
total_sum += values[i];
}
concat(dest, C128Table[total_sum%103]);
/* Stop character */
concat(dest, C128Table[106]);
expand(symbol, dest);
strcpy(symbol->text, source);
return errornum;
}
int ean_128(struct zint_symbol *symbol, unsigned char source[])
{ /* Handle EAN-128 (Now known as GS1-128) */
int i, j, k, e_count, values[170], bar_characters, read, total_sum;
int errornum, indexchaine, indexliste, ai_latch;
char set[170], mode, last_set, reduced[170], ai_string[4];
float glyph_count;
char dest[1000];
int last_ai, separator_row, linkage_flag;
errornum = 0;
strcpy(dest, "");
linkage_flag = 0;
j = 0;
e_count = 0;
bar_characters = 0;
separator_row = 0;
for(i = 0; i < 170; i++) {
values[i] = 0;
set[i] = ' ';
}
if(strlen(source) > 160) {
/* This only blocks rediculously long input - the actual length of the
resulting barcode depends on the type of data, so this is trapped later */
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
/* Detect extended ASCII characters */
for(i = 0; i < strlen(source); i++) {
if(source[i] >=128) {
strcpy(symbol->errtxt, "error: extended ASCII characters not supported by GS1-128");
return ERROR_INVALID_DATA;
}
}
if(source[0] != '[') {
strcpy(symbol->errtxt, "error: input string doesn't start with AI");
return ERROR_INVALID_DATA;
}
/* if part of a composite symbol make room for the separator pattern */
if(symbol->symbology == BARCODE_EAN128_CC) {
separator_row = symbol->rows;
symbol->row_height[symbol->rows] = 1;
symbol->rows += 1;
}
/* Resolve AI data - put resulting string in 'reduced' */
j = 0;
last_ai = 0;
ai_latch = 1;
for(i = 0; i < strlen(source); i++) {
if((source[i] != '[') && (source[i] != ']')) {
reduced[j] = source[i];
j++;
}
if(source[i] == '[') {
/* Start of an AI string */
if(ai_latch == 0) {
reduced[j] = '[';
j++;
}
ai_string[0] = source[i + 1];
ai_string[1] = source[i + 2];
ai_string[2] = '\0';
last_ai = atoi(ai_string);
ai_latch = 0;
/* The following values from GS1 specification figure 5.3.8.2.1 - 1
"Element Strings with Pre-Defined Length Using Application Identifiers" */
if((last_ai >= 0) && (last_ai <= 4)) { ai_latch = 1; }
if((last_ai >= 11) && (last_ai <= 20)) { ai_latch = 1; }
if(last_ai == 23) { ai_latch = 1; } /* legacy support - see 5.3.8.2.2 */
if((last_ai >= 31) && (last_ai <= 36)) { ai_latch = 1; }
if(last_ai == 41) { ai_latch = 1; }
}
/* The ']' character is simply dropped from the input */
}
reduced[j] = '\0';
/* the character '[' in the reduced string refers to the FNC1 character */
/* Note that no attempt is made to verify that the data to be encoded does
actually conform to the right data length - that is required of the person or
program inputting the data */
/* Decide on mode using same system as PDF417 and rules of ISO 15417 Annex E */
indexliste = 0;
indexchaine = 0;
mode = parunmodd(reduced[indexchaine]);
if(reduced[indexchaine] == '[') {
mode = ABORC;
}
for(i = 0; i < 170; i++) {
list[0][i] = 0;
}
do {
list[1][indexliste] = mode;
while ((list[1][indexliste] == mode) && (indexchaine < strlen(reduced))) {
list[0][indexliste]++;
indexchaine++;
mode = parunmodd(reduced[indexchaine]);
if(reduced[indexchaine] == '[') {
if(indexchaine % 2 == 0) {
mode = ABORC;
} else {
mode = AORB;
}
}
}
indexliste++;
} while (indexchaine < strlen(reduced));
dxsmooth(&indexliste);
/* Resolve odd length LATCHC blocks */
if((list[1][0] == LATCHC) && ((list[0][0] % 2) == 1)) {
/* Rule 2 */
list[0][1]++;
list[0][0]--;
}
if(indexliste > 1) {
for(i = 1; i < indexliste; i++) {
if((list[1][i] == LATCHC) && ((list[0][i] % 2) == 1)) {
/* Rule 3b */
list[0][i - 1]++;
list[0][i]--;
}
}
}
/* Put set data into set[] */
read = 0;
for(i = 0; i < indexliste; i++) {
for(j = 0; j < list[0][i]; j++) {
switch(list[1][i]) {
case SHIFTA: set[read] = 'a'; break;
case LATCHA: set[read] = 'A'; break;
case SHIFTB: set[read] = 'b'; break;
case LATCHB: set[read] = 'B'; break;
case LATCHC: set[read] = 'C'; break;
}
read++;
}
}
/* Now we can calculate how long the barcode is going to be - and stop it from
being too long */
last_set = ' ';
glyph_count = 0.0;
for(i = 0; i < strlen(reduced); i++) {
if((set[i] == 'a') || (set[i] == 'b')) {
glyph_count = glyph_count + 1.0;
}
if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) {
if(set[i] != last_set) {
last_set = set[i];
glyph_count = glyph_count + 1.0;
}
}
if(set[i] == 'C') {
glyph_count = glyph_count + 0.5;
} else {
glyph_count = glyph_count + 1.0;
}
}
if(glyph_count > 80.0) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
/* So now we know what start character to use - we can get on with it! */
switch(set[0])
{
case 'A': /* Start A */
concat(dest, C128Table[103]);
values[0] = 103;
break;
case 'B': /* Start B */
concat(dest, C128Table[104]);
values[0] = 104;
break;
case 'C': /* Start C */
concat(dest, C128Table[105]);
values[0] = 105;
break;
}
bar_characters++;
concat(dest, C128Table[102]);
values[1] = 102;
bar_characters++;
/* Encode the data */
read = 0;
do {
if((read != 0) && (set[read] != set[read - 1]))
{ /* Latch different code set */
switch(set[read])
{
case 'A': concat(dest, C128Table[101]);
values[bar_characters] = 101;
bar_characters++;
break;
case 'B': concat(dest, C128Table[100]);
values[bar_characters] = 100;
bar_characters++;
break;
case 'C': concat(dest, C128Table[99]);
values[bar_characters] = 99;
bar_characters++;
break;
}
}
if((set[i] == 'a') || (set[i] == 'b')) {
/* Insert shift character */
concat(dest, C128Table[98]);
values[bar_characters] = 98;
bar_characters++;
}
if(reduced[read] != '[') {
switch(set[read])
{ /* Encode data characters */
case 'A': c128_set_a(reduced[read], dest, values, &bar_characters);
read++;
break;
case 'B': c128_set_b(reduced[read], dest, values, &bar_characters);
read++;
break;
case 'C': c128_set_c(reduced[read], reduced[read + 1], dest, values, &bar_characters);
read += 2;
break;
}
} else {
concat(dest, C128Table[102]);
values[bar_characters] = 102;
bar_characters++;
read++;
}
} while (read < strlen(reduced));
/* "...note that the linkage flag is an extra code set character between
the last data character and the Symbol Check Character" (GS1 Specification) */
/* Linkage flags in GS1-128 are determined by ISO/IEC 24723 section 7.4 */
switch(symbol->option_1) {
case 1:
case 2:
/* CC-A or CC-B 2D component */
switch(set[strlen(reduced) - 1]) {
case 'A': linkage_flag = 100; break;
case 'B': linkage_flag = 99; break;
case 'C': linkage_flag = 101; break;
}
break;
case 3:
/* CC-C 2D component */
switch(set[strlen(reduced) - 1]) {
case 'A': linkage_flag = 99; break;
case 'B': linkage_flag = 101; break;
case 'C': linkage_flag = 100; break;
}
break;
}
if(linkage_flag != 0) {
concat(dest, C128Table[linkage_flag]);
values[bar_characters] = linkage_flag;
bar_characters++;
}
/* check digit calculation */
total_sum = 0;
for(i = 0; i < bar_characters; i++)
{
if(i > 0)
{
values[i] *= i;
}
total_sum += values[i];
}
concat(dest, C128Table[total_sum%103]);
/* Stop character */
concat(dest, C128Table[106]);
expand(symbol, dest);
/* Add the separator pattern for composite symbols */
if(symbol->symbology == BARCODE_EAN128_CC) {
for(i = 0; i < symbol->width; i++) {
if(symbol->encoded_data[separator_row + 1][i] != '1') {
symbol->encoded_data[separator_row][i] = '1';
}
}
}
for(i = 0; i <= strlen(source); i++) {
if((source[i] != '[') && (source[i] != ']')) {
symbol->text[i] = source[i];
}
if(source[i] == '[') {
symbol->text[i] = '(';
}
if(source[i] == ']') {
symbol->text[i] = ')';
}
}
return errornum;
}
+477
View File
@@ -0,0 +1,477 @@
/* code16k.c - Handles Code 16k stacked symbology */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Updated to comply with BS EN 12323:2005 */
/* up to 77 characters or 154 numbers */
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#define TRUE 1
#define FALSE 0
#define SHIFTA 90
#define LATCHA 91
#define SHIFTB 92
#define LATCHB 93
#define SHIFTC 94
#define LATCHC 95
#define AORB 96
#define ABORC 97
#define CANDB 98
#define CANDBB 99
int list[2][170];
/* EN 12323 Table 1 - "Code 16K" character encodations */
static char *C16KTable[107] = {"212222", "222122", "222221", "121223", "121322", "131222", "122213",
"122312", "132212", "221213", "221312", "231212", "112232", "122132", "122231", "113222",
"123122", "123221", "223211", "221132", "221231", "213212", "223112", "312131", "311222",
"321122", "321221", "312212", "322112", "322211", "212123", "212321", "232121", "111323",
"131123", "131321", "112313", "132113", "132311", "211313", "231113", "231311", "112133",
"112331", "132131", "113123", "113321", "133121", "313121", "211331", "231131", "213113",
"213311", "213131", "311123", "311321", "331121", "312113", "312311", "332111", "314111",
"221411", "431111", "111224", "111422", "121124", "121421", "141122", "141221", "112214",
"112412", "122114", "122411", "142112", "142211", "241211", "221114", "413111", "241112",
"134111", "111242", "121142", "121241", "114212", "124112", "124211", "411212", "421112",
"421211", "212141", "214121", "412121", "111143", "111341", "131141", "114113", "114311",
"411113", "411311", "113141", "114131", "311141", "411131", "211412", "211214", "211232",
"211133"};
/* EN 12323 Table 3 and Table 4 - Start patterns and stop patterns */
static char *C16KStartStop[8] = {"3211", "2221", "2122", "1411", "1132", "1231", "1114", "3112"};
/* EN 12323 Table 5 - Start and stop values defining row numbers */
static int C16KStartValues[16] = {0, 1, 2, 3, 4, 5, 6, 7, 0, 1, 2, 3, 4, 5, 6, 7};
static int C16KStopValues[16] = {0, 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, 7, 0, 1, 2, 3};
int parunmodd(unsigned char llyth);
void grwp(int *indexliste);
void reysmooth(int *indexliste)
{ /* Implements rules from EN 12323 */
int i, this, last, next, length;
for(i = 0; i < *(indexliste); i++) {
this = list[1][i];
length = list[0][i];
if(i != 0) { last = list[1][i - 1]; } else { last = FALSE; }
if(i != *(indexliste) - 1) { next = list[1][i + 1]; } else { next = FALSE; }
if(i == 0) { /* first block */
if((*(indexliste) == 1) && ((length == 2) && (this == ABORC))) { /* Rule 1a */ list[1][i] = LATCHC; }
if(this == ABORC) {
if(length >= 4) {/* Rule 1b */ list[1][i] = LATCHC; } else { list[1][i] = AORB; this = AORB; }
}
if(this == SHIFTA) { /* Rule 1c */ list[1][i] = LATCHA; }
if((this == AORB) && (next == SHIFTA)) { /* Rule 1c */ list[1][i] = LATCHA; this = LATCHA; }
if(this == AORB) { /* Rule 1d */ list[1][i] = LATCHB; }
} else {
if((this == ABORC) && (length >= 4)) { /* Rule 3 */ list[1][i] = LATCHC; this = LATCHC; }
if(this == ABORC) { list[1][i] = AORB; this = AORB; }
if((this == AORB) && (last == LATCHA)) { list[1][i] = LATCHA; this = LATCHA; }
if((this == AORB) && (last == LATCHB)) { list[1][i] = LATCHB; this = LATCHB; }
if((this == AORB) && (next == SHIFTA)) { list[1][i] = LATCHA; this = LATCHA; }
if((this == AORB) && (next == SHIFTB)) { list[1][i] = LATCHB; this = LATCHB; }
if(this == AORB) { list[1][i] = LATCHB; this = LATCHB; }
if((this == SHIFTA) && (length > 1)) { /* Rule 4 */ list[1][i] = LATCHA; this = LATCHA; }
if((this == SHIFTB) && (length > 1)) { /* Rule 5 */ list[1][i] = LATCHB; this = LATCHB; }
if((this == SHIFTA) && (last == LATCHA)) { list[1][i] = LATCHA; this = LATCHA; }
if((this == SHIFTB) && (last == LATCHB)) { list[1][i] = LATCHB; this = LATCHB; }
} /* Rule 2 is implimented elsewhere, Rule 6 is implied */
}
grwp(indexliste);
}
void c16k_set_a(unsigned char source, int values[], int *bar_chars)
{
if(source > 127) {
values[(*bar_chars)] = source + 64 - 128;
} else {
values[(*bar_chars)] = source + 64;
}
(*bar_chars)++;
}
void c16k_set_b(unsigned char source, int values[], int *bar_chars)
{
if(source > 127) {
values[(*bar_chars)] = source - 32 - 128;
} else {
values[(*bar_chars)] = source - 32;
}
(*bar_chars)++;
}
void c16k_set_c(unsigned char source_a, unsigned char source_b, int values[], int *bar_chars)
{
int weight;
weight = (10 * ctoi(source_a)) + ctoi(source_b);
values[(*bar_chars)] = weight;
(*bar_chars)++;
}
int code16k(struct zint_symbol *symbol, unsigned char source[])
{
char width_pattern[100];
int current_row, rows_needed, flip_flop, looper, first_check, second_check;
int indexliste, indexchaine, pads_needed;
char set[160], fset[160], mode, last_set, last_fset;
unsigned int i, j, k, m, e_count, read, mx_reader, writer;
unsigned int values[160];
unsigned int bar_characters;
strcpy(width_pattern, "");
float glyph_count;
int errornum, first_sum, second_sum;
errornum = 0;
if(strlen(source) > 157) {
strcpy(symbol->errtxt, "error: input too long");
return 6;
}
e_count = 0;
bar_characters = 0;
for(i = 0; i < 160; i++) {
values[i] = 0;
set[i] = ' ';
fset[i] = ' ';
}
/* Detect extended ASCII characters */
for(i = 0; i < strlen(source); i++) {
if(source[i] >=128) {
fset[i] = 'f';
}
}
fset[i] = '\0';
/* Decide when to latch to extended mode */
for(i = 0; i < strlen(source); i++) {
j = 0;
if(fset[i] == 'f') {
do {
j++;
} while(source[i + j] == 'f');
if((j >= 5) || ((j >= 3) && ((i + j) == strlen(source)))) {
for(k = 0; k <= j; k++) {
source[i + k] = 'F';
}
}
}
}
/* Detect mode A, B and C characters */
indexliste = 0;
indexchaine = 0;
mode = parunmodd(source[indexchaine]);
for(i = 0; i < 160; i++) {
list[0][i] = 0;
}
do {
list[1][indexliste] = mode;
while ((list[1][indexliste] == mode) && (indexchaine < strlen(source))) {
list[0][indexliste]++;
indexchaine++;
mode = parunmodd(source[indexchaine]);
}
indexliste++;
} while (indexchaine < strlen(source));
reysmooth(&indexliste);
/* Resolve odd length LATCHC blocks */
if((list[1][0] == LATCHC) && ((list[0][0] % 2) == 1)) {
for(i = 1; i <= indexliste; i++) {
list[0][i] = list[0][i - 1];
list[1][i] = list[1][i - 1];
}
list[0][1]--;
list[0][0] = 1;
list[1][0] = LATCHB;
indexliste++;
}
if(indexliste > 1) {
for(i = 1; i < indexliste; i++) {
if((list[1][i] == LATCHC) && ((list[0][i] % 2) == 1)) {
list[0][i - 1]++;
list[0][i]--;
}
}
}
/* Put set data into set[] */
read = 0;
for(i = 0; i < indexliste; i++) {
for(j = 0; j < list[0][i]; j++) {
switch(list[1][i]) {
case SHIFTA: set[read] = 'a'; break;
case LATCHA: set[read] = 'A'; break;
case SHIFTB: set[read] = 'b'; break;
case LATCHB: set[read] = 'B'; break;
case LATCHC: set[read] = 'C'; break;
}
read++;
}
}
/* Make sure the data will fit in the symbol */
last_set = ' ';
last_fset = ' ';
glyph_count = 0.0;
for(i = 0; i < strlen(source); i++) {
if((set[i] == 'a') || (set[i] == 'b')) {
glyph_count = glyph_count + 1.0;
}
if(fset[i] == 'f') {
glyph_count = glyph_count + 1.0;
}
if(((set[i] == 'A') || (set[i] == 'B')) || (set[i] == 'C')) {
if(set[i] != last_set) {
last_set = set[i];
glyph_count = glyph_count + 1.0;
}
}
if(i == 0) {
if((set[i] == 'B') && (set[1] == 'C')) {
glyph_count = glyph_count - 1.0;
}
if((set[i] == 'B') && (set[1] == 'B')) {
if(set[2] == 'C') {
glyph_count = glyph_count - 1.0;
}
}
if(fset[i] == 'F') {
last_fset = 'F';
glyph_count = glyph_count + 2.0;
}
} else {
if((fset[i] == 'F') && (fset[i - 1] != 'F')) {
last_fset = 'F';
glyph_count = glyph_count + 2.0;
}
if((fset[i] != 'F') && (fset[i - 1] == 'F')) {
last_fset = ' ';
glyph_count = glyph_count + 2.0;
}
}
if(set[i] == 'C') {
glyph_count = glyph_count + 0.5;
} else {
glyph_count = glyph_count + 1.0;
}
}
if(glyph_count > 77.0) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
/* Calculate how tall the symbol will be */
glyph_count = glyph_count + 2.0;
i = glyph_count;
rows_needed = (i/5);
if(i%5 > 0) { rows_needed++; }
/* start with the mode character - Table 2 */
m = 0;
switch(set[0]) {
case 'A': m = 0; break;
case 'B': m = 1; break;
case 'C': m = 2; break;
}
if((set[0] == 'B') && (set[1] == 'C')) { m = 5; }
if(((set[0] == 'B') && (set[1] == 'B')) && (set[2] == 'C')) { m = 6; }
values[bar_characters] = (7 * (rows_needed - 2)) + m; /* see 4.3.4.2 */
bar_characters++;
if(fset[0] == 'F') {
switch(set[0]) {
case 'A':
values[bar_characters] = 101;
values[bar_characters + 1] = 101;
break;
case 'B':
values[bar_characters] = 100;
values[bar_characters + 1] = 100;
break;
}
bar_characters += 2;
}
/* Encode the data */
read = 0;
do {
if((read != 0) && (set[read] != set[read - 1]))
{ /* Latch different code set */
switch(set[read])
{
case 'A':
values[bar_characters] = 101;
bar_characters++;
break;
case 'B':
values[bar_characters] = 100;
bar_characters++;
break;
case 'C':
if(!((read == 1) && (set[0] == 'B'))) { /* Not Mode C/Shift B */
if(!((read == 2) && ((set[0] == 'B') && (set[1] == 'B')))) {
/* Not Mode C/Double Shift B */
values[bar_characters] = 99;
bar_characters++;
}
}
break;
}
}
if((read != 0) && (fset[read] != fset[read - 1])) {
if(fset[read] == 'F') {
/* Latch beginning of extended mode */
switch(set[0]) {
case 'A':
values[bar_characters] = 101;
values[bar_characters + 1] = 101;
break;
case 'B':
values[bar_characters] = 100;
values[bar_characters + 1] = 100;
break;
}
bar_characters += 2;
}
if(fset[read - 1] == 'F') {
/* Latch end of extended mode */
switch(set[0]) {
case 'A':
values[bar_characters] = 101;
values[bar_characters + 1] = 101;
break;
case 'B':
values[bar_characters] = 100;
values[bar_characters + 1] = 100;
break;
}
bar_characters += 2;
}
}
if(fset[i] == 'f') {
/* Shift extended mode */
switch(set[i]) {
case 'A':
values[bar_characters] = 101;
break;
case 'B':
values[bar_characters] = 100;
break;
}
bar_characters++;
}
if((set[i] == 'a') || (set[i] == 'b')) {
/* Insert shift character */
values[bar_characters] = 98;
bar_characters++;
}
switch(set[read])
{ /* Encode data characters */
case 'A': c16k_set_a(source[read], values, &bar_characters);
read++;
break;
case 'B': c16k_set_b(source[read], values, &bar_characters);
read++;
break;
case 'C': c16k_set_c(source[read], source[read + 1], values, &bar_characters);
read += 2;
break;
}
} while (read < strlen(source));
pads_needed = 5 - ((bar_characters + 2) % 5);
if(pads_needed == 5) {
pads_needed = 0;
}
for(i = 0; i < pads_needed; i++) {
values[bar_characters] = 106;
bar_characters++;
}
first_sum = 0;
second_sum = 0;
for(i = 0; i < bar_characters; i++)
{
first_sum += (i+2) * values[i];
second_sum += (i+1) * values[i];
}
first_check = first_sum % 107;
second_sum += first_check * (bar_characters + 1);
second_check = second_sum % 107;
values[bar_characters] = first_check;
values[bar_characters + 1] = second_check;
bar_characters += 2;
for(current_row = 0; current_row < rows_needed; current_row++) {
strcpy(width_pattern, "");
concat(width_pattern, C16KStartStop[C16KStartValues[current_row]]);
concat(width_pattern, "1");
for(i = 0; i < 5; i++) {
concat(width_pattern, C16KTable[values[(current_row * 5) + i]]);
}
concat(width_pattern, C16KStartStop[C16KStopValues[current_row]]);
/* Write the information into the symbol */
writer = 0;
flip_flop = 1;
for (mx_reader = 0; mx_reader < strlen(width_pattern); mx_reader++) {
for(looper = 0; looper < ctoi(width_pattern[mx_reader]); looper++) {
if(flip_flop == 1) {
symbol->encoded_data[current_row][writer] = '1';
writer++; }
else {
symbol->encoded_data[current_row][writer] = '0';
writer++; }
}
if(flip_flop == 0) { flip_flop = 1; } else { flip_flop = 0; }
}
symbol->row_height[current_row] = 8;
}
symbol->rows = rows_needed;
symbol->width = 70;
return errornum;
}
+126
View File
@@ -0,0 +1,126 @@
/* common.c - Contains functions needed for a number of barcodes */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
#define SSET "0123456789ABCDEF"
void concat(char dest[], char source[])
{ /* Concatinates dest[] with the contents of source[], copying /0 as well */
unsigned int i, j;
j = strlen(dest);
for(i = 0; i <= strlen(source); i++) {
dest[i + j] = source[i]; }
}
int ctoi(char source)
{ /* Converts a character 0-9 to its equivalent integer value */
if((source >= '0') && (source <= '9'))
return (source - '0');
return(source - 'A' + 10);
}
char itoc(int source)
{ /* Converts an integer value to its hexadecimal character */
if ((source >= 0) && (source <= 9)) {
return ('0' + source); }
else {
return ('A' + (source - 10)); }
}
void to_upper(unsigned char source[])
{ /* Converts lower case characters to upper case in a string source[] */
unsigned int i;
for (i = 0; i < strlen(source); i++) {
if ((source[i] >= 'a') && (source[i] <= 'z')) {
source [i] = (source[i] - 'a') + 'A'; }
}
}
int is_sane(char test_string[], unsigned char source[])
{ /* Verifies that a string only uses valid characters */
unsigned int i, j, latch;
for(i = 0; i < strlen(source); i++) {
latch = FALSE;
for(j = 0; j < strlen(test_string); j++) {
if (source[i] == test_string[j]) { latch = TRUE; } }
if (!(latch)) {
return ERROR_INVALID_DATA; }
}
return 0;
}
int posn(char set_string[], char data)
{ /* Returns the position of data in set_string */
unsigned int i;
for(i = 0; i < strlen(set_string); i++) {
if (data == set_string[i]) { return i; } }
return 0;
}
void lookup(char set_string[], char *table[], char data, char dest[])
{ /* Replaces huge switch statements for looking up in tables */
unsigned int i;
for(i = 0; i < strlen(set_string); i++) {
if (data == set_string[i]) { concat(dest, table[i]); } }
}
void expand(struct zint_symbol *symbol, char data[])
{ /* Expands from a width pattern to a bit pattern */
int reader, writer, i;
char latch;
writer = 0;
latch = '1';
for(reader = 0; reader < strlen(data); reader++) {
for(i = 0; i < ctoi(data[reader]); i++) {
symbol->encoded_data[symbol->rows][writer] = latch;
writer++;
}
if(latch == '1') {
latch = '0';
} else {
latch = '1';
}
}
if(symbol->symbology != BARCODE_PHARMA) {
if(writer > symbol->width) {
symbol->width = writer;
}
} else {
/* Pharmacode One ends with a space - adjust for this */
if(writer > symbol->width + 2) {
symbol->width = writer - 2;
}
}
symbol->rows = symbol->rows + 1;
}
+38
View File
@@ -0,0 +1,38 @@
/* common.h - Header for all common functions in common.c */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart (zint@hotmail.co.uk)
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Used in some logic */
#define FALSE 0
#define TRUE 1
/* The most commonly used set */
#define NESET "0123456789"
#include "zint.h"
void concat(char dest[], char source[]);
int ctoi(char source);
char itoc(int source);
void to_upper(unsigned char source[]);
int is_sane(char test_string[], unsigned char source[]);
void lookup(char set_string[], char *table[], char data, char dest[]);
int posn(char set_string[], char data);
void expand(struct zint_symbol *symbol, char data[]);
+1916
View File
File diff suppressed because it is too large Load Diff
+62
View File
@@ -0,0 +1,62 @@
/* composite.c - Tables for UCC.EAN Composite Symbols */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define NUMERIC 110
#define ALPHA 97
#define ISOIEC 105
#define INVALID_CHAR 100
#define ANY_ENC 120
#define ALPHA_OR_ISO 121
/* CC-A component coefficients from ISO/IEC 24728:2006 Annex F */
static int ccaCoeffs[30] = {
/* k = 4 */
522, 568, 723, 809,
/* k = 5 */
427, 919, 460, 155, 566,
/* k = 6 */
861, 285, 19, 803, 17, 766,
/* k = 7 */
76, 925, 537, 597, 784, 691, 437,
/* k = 8 */
237, 308, 436, 284, 646, 653, 428, 379
};
/* rows, error codewords, k-offset of valid CC-A sizes from ISO/IEC 24723:2006 Table 9 */
static int ccaVariants[51] = {
5, 6, 7, 8, 9, 10, 12, 4, 5, 6, 7, 8, 3, 4, 5, 6, 7,
4, 4, 5, 5, 6, 6, 7, 4, 5, 6, 7, 7, 4, 5, 6, 7, 8,
0, 0, 4, 4, 9, 9, 15, 0, 4, 9, 15, 15, 0, 4, 9, 15, 22
};
/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24723:2006 tables 10 and 11 */
static int aRAPTable[68] = {
39, 1, 32, 8, 14, 43, 20, 11, 1, 5, 15, 21, 40, 43, 46, 34, 29,
0, 0, 0, 0, 0, 0, 0, 43, 33, 37, 47, 1, 20, 23, 2, 14, 9,
19, 33, 12, 40, 4, 23, 52, 23, 13, 17, 27, 33, 52, 3, 6, 46, 41,
6, 0, 3, 3, 3, 0, 3, 3, 0, 3, 6, 6, 0, 0, 0, 0, 3
};
/* Row Address Patterns are as defined in pdf417.h */
+961
View File
@@ -0,0 +1,961 @@
/**
*
* IEC16022 bar code generation
* Adrian Kennard, Andrews & Arnold Ltd
* with help from Cliff Hones on the RS coding
*
* (c) 2004 Adrian Kennard, Andrews & Arnold Ltd
* (c) 2006 Stefan Schmidt <stefan@datenfreihafen.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <malloc.h>
#include "reedsol.h"
#include "dm200.h"
static struct ecc200matrix_s {
int H, W;
int FH, FW;
int bytes;
int datablock, rsblock;
} ecc200matrix[] = {
10, 10, 10, 10, 3, 3, 5, //
12, 12, 12, 12, 5, 5, 7, //
8, 18, 8, 18, 5, 5, 7, //
14, 14, 14, 14, 8, 8, 10, //
8, 32, 8, 16, 10, 10, 11, //
16, 16, 16, 16, 12, 12, 12, //
12, 26, 12, 26, 16, 16, 14, //
18, 18, 18, 18, 18, 18, 14, //
20, 20, 20, 20, 22, 22, 18, //
12, 36, 12, 18, 22, 22, 18, //
22, 22, 22, 22, 30, 30, 20, //
16, 36, 16, 18, 32, 32, 24, //
24, 24, 24, 24, 36, 36, 24, //
26, 26, 26, 26, 44, 44, 28, //
16, 48, 16, 24, 49, 49, 28, //
32, 32, 16, 16, 62, 62, 36, //
36, 36, 18, 18, 86, 86, 42, //
40, 40, 20, 20, 114, 114, 48, //
44, 44, 22, 22, 144, 144, 56, //
48, 48, 24, 24, 174, 174, 68, //
52, 52, 26, 26, 204, 102, 42, //
64, 64, 16, 16, 280, 140, 56, //
72, 72, 18, 18, 368, 92, 36, //
80, 80, 20, 20, 456, 114, 48, //
88, 88, 22, 22, 576, 144, 56, //
96, 96, 24, 24, 696, 174, 68, //
104, 104, 26, 26, 816, 136, 56, //
120, 120, 20, 20, 1050, 175, 68, //
132, 132, 22, 22, 1304, 163, 62, //
144, 144, 24, 24, 1558, 156, 62, // 156*4+155*2
0 // terminate
};
// simple checked response malloc
static void *safemalloc(int n)
{
void *p = malloc(n);
if (!p) {
fprintf(stderr, "Malloc(%d) failed\n", n);
exit(1);
}
return p;
}
// Annex M placement alorithm low level
static void ecc200placementbit(int *array, int NR, int NC, int r, int c,
int p, char b)
{
if (r < 0) {
r += NR;
c += 4 - ((NR + 4) % 8);
}
if (c < 0) {
c += NC;
r += 4 - ((NC + 4) % 8);
}
array[r * NC + c] = (p << 3) + b;
}
static void ecc200placementblock(int *array, int NR, int NC, int r,
int c, int p)
{
ecc200placementbit(array, NR, NC, r - 2, c - 2, p, 7);
ecc200placementbit(array, NR, NC, r - 2, c - 1, p, 6);
ecc200placementbit(array, NR, NC, r - 1, c - 2, p, 5);
ecc200placementbit(array, NR, NC, r - 1, c - 1, p, 4);
ecc200placementbit(array, NR, NC, r - 1, c - 0, p, 3);
ecc200placementbit(array, NR, NC, r - 0, c - 2, p, 2);
ecc200placementbit(array, NR, NC, r - 0, c - 1, p, 1);
ecc200placementbit(array, NR, NC, r - 0, c - 0, p, 0);
}
static void ecc200placementcornerA(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 1, 1, p, 6);
ecc200placementbit(array, NR, NC, NR - 1, 2, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
}
static void ecc200placementcornerB(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 4, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 3, p, 3);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 2);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 1);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
}
static void ecc200placementcornerC(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 3, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 2, 0, p, 6);
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 2);
ecc200placementbit(array, NR, NC, 2, NC - 1, p, 1);
ecc200placementbit(array, NR, NC, 3, NC - 1, p, 0);
}
static void ecc200placementcornerD(int *array, int NR, int NC, int p)
{
ecc200placementbit(array, NR, NC, NR - 1, 0, p, 7);
ecc200placementbit(array, NR, NC, NR - 1, NC - 1, p, 6);
ecc200placementbit(array, NR, NC, 0, NC - 3, p, 5);
ecc200placementbit(array, NR, NC, 0, NC - 2, p, 4);
ecc200placementbit(array, NR, NC, 0, NC - 1, p, 3);
ecc200placementbit(array, NR, NC, 1, NC - 3, p, 2);
ecc200placementbit(array, NR, NC, 1, NC - 2, p, 1);
ecc200placementbit(array, NR, NC, 1, NC - 1, p, 0);
}
// Annex M placement alorithm main function
static void ecc200placement(int *array, int NR, int NC)
{
int r, c, p;
// invalidate
for (r = 0; r < NR; r++)
for (c = 0; c < NC; c++)
array[r * NC + c] = 0;
// start
p = 1;
r = 4;
c = 0;
do {
// check corner
if (r == NR && !c)
ecc200placementcornerA(array, NR, NC, p++);
if (r == NR - 2 && !c && NC % 4)
ecc200placementcornerB(array, NR, NC, p++);
if (r == NR - 2 && !c && (NC % 8) == 4)
ecc200placementcornerC(array, NR, NC, p++);
if (r == NR + 4 && c == 2 && !(NC % 8))
ecc200placementcornerD(array, NR, NC, p++);
// up/right
do {
if (r < NR && c >= 0 && !array[r * NC + c])
ecc200placementblock(array, NR, NC, r, c, p++);
r -= 2;
c += 2;
}
while (r >= 0 && c < NC);
r++;
c += 3;
// down/left
do {
if (r >= 0 && c < NC && !array[r * NC + c])
ecc200placementblock(array, NR, NC, r, c, p++);
r += 2;
c -= 2;
}
while (r < NR && c >= 0);
r += 3;
c++;
}
while (r < NR || c < NC);
// unfilled corner
if (!array[NR * NC - 1])
array[NR * NC - 1] = array[NR * NC - NC - 2] = 1;
}
// calculate and append ecc code, and if necessary interleave
static void ecc200(unsigned char *binary, int bytes, int datablock, int rsblock)
{
int blocks = (bytes + 2) / datablock, b;
rs_init_gf(0x12d);
rs_init_code(rsblock, 1);
for (b = 0; b < blocks; b++) {
unsigned char buf[256], ecc[256];
int n, p = 0;
for (n = b; n < bytes; n += blocks)
buf[p++] = binary[n];
rs_encode(p, buf, ecc);
p = rsblock - 1; // comes back reversed
for (n = b; n < rsblock * blocks; n += blocks)
binary[bytes + n] = ecc[p--];
}
}
/*
* perform encoding for ecc200, source s len sl, to target t len tl, using
* optional encoding control string e return 1 if OK, 0 if failed. Does all
* necessary padding to tl
*/
char ecc200encode(unsigned char *t, int tl, unsigned char *s, int sl,
char *encoding, int *lenp)
{
char enc = 'a'; // start in ASCII encoding mode
int tp = 0, sp = 0;
if (strlen(encoding) < sl) {
fprintf(stderr, "Encoding string too short\n");
return 0;
}
// do the encoding
while (sp < sl && tp < tl) {
char newenc = enc; // suggest new encoding
if (tl - tp <= 1 && (enc == 'c' || enc == 't') || tl - tp <= 2
&& enc == 'x')
enc = 'a'; // auto revert to ASCII
newenc = tolower(encoding[sp]);
switch (newenc) { // encode character
case 'c': // C40
case 't': // Text
case 'x': // X12
{
char out[6], p = 0;
const char *e,
*s2 = "!\"#$%&'()*+,-./:;<=>?@[\\]_",
*s3 = 0;
if (newenc == 'c') {
e = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
s3 = "`abcdefghijklmnopqrstuvwxyz{|}~\177";
}
if (newenc == 't') {
e = " 0123456789abcdefghijklmnopqrstuvwxyz";
s3 = "`ABCDEFGHIJKLMNOPQRSTUVWXYZ{|}~\177";
}
if (newenc == 'x')
e = " 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ\r*>";
do {
unsigned char c = s[sp++];
char *w;
if (c & 0x80) {
if (newenc == 'x') {
fprintf(stderr,
"Cannot encode char 0x%02X in X12\n",
c);
return 0;
}
c &= 0x7f;
out[p++] = 1;
out[p++] = 30;
}
w = strchr(e, c);
if (w)
out[p++] = ((w - e) + 3) % 40;
else {
if (newenc == 'x') {
fprintf(stderr,
"Cannot encode char 0x%02X in X12\n",
c);
return 0;
}
if (c < 32) { // shift 1
out[p++] = 0;
out[p++] = c;
} else {
w = strchr(s2, c);
if (w) { // shift 2
out[p++] = 1;
out[p++] =
(w - s2);
} else {
w = strchr(s3,
c);
if (w) {
out[p++]
= 2;
out[p++]
=
(w -
s3);
} else {
fprintf
(stderr,
"Could not encode 0x%02X, should \
not happen\n", c);
return
0;
}
}
}
}
if (p == 2 && tp + 2 == tl && sp == sl)
out[p++] = 0; // shift 1 pad at end
while (p >= 3) {
int v =
out[0] * 1600 +
out[1] * 40 + out[2] + 1;
if (enc != newenc) {
if (enc == 'c'
|| enc == 't'
|| enc == 'x')
t[tp++] = 254; // escape C40/text/X12
else if (enc == 'x')
t[tp++] = 0x7C; // escape EDIFACT
if (newenc == 'c')
t[tp++] = 230;
if (newenc == 't')
t[tp++] = 239;
if (newenc == 'x')
t[tp++] = 238;
enc = newenc;
}
t[tp++] = (v >> 8);
t[tp++] = (v & 0xFF);
p -= 3;
out[0] = out[3];
out[1] = out[4];
out[2] = out[5];
}
}
while (p && sp < sl);
}
break;
case 'e': // EDIFACT
{
unsigned char out[4], p = 0;
if (enc != newenc) { // can only be from C40/Text/X12
t[tp++] = 254;
enc = 'a';
}
while (sp < sl && tolower(encoding[sp]) == 'e'
&& p < 4)
out[p++] = s[sp++];
if (p < 4) {
out[p++] = 0x1F;
enc = 'a';
} // termination
t[tp] = ((s[0] & 0x3F) << 2);
t[tp++] |= ((s[1] & 0x30) >> 4);
t[tp] = ((s[1] & 0x0F) << 4);
if (p == 2)
tp++;
else {
t[tp++] |= ((s[2] & 0x3C) >> 2);
t[tp] = ((s[2] & 0x03) << 6);
t[tp++] |= (s[3] & 0x3F);
}
}
break;
case 'a': // ASCII
if (enc != newenc) {
if (enc == 'c' || enc == 't' || enc == 'x')
t[tp++] = 254; // escape C40/text/X12
else
t[tp++] = 0x7C; // escape EDIFACT
}
enc = 'a';
if (sl - sp >= 2 && isdigit(s[sp])
&& isdigit(s[sp + 1])) {
t[tp++] =
(s[sp] - '0') * 10 + s[sp + 1] - '0' + 130;
sp += 2;
} else if (s[sp] > 127) {
t[tp++] = 235;
t[tp++] = s[sp++] - 127;
} else
t[tp++] = s[sp++] + 1;
break;
case 'b': // Binary
{
int l = 0; // how much to encode
if (encoding) {
int p;
for (p = sp;
p < sl
&& tolower(encoding[p]) == 'b';
p++)
l++;
}
t[tp++] = 231; // base256
if (l < 250)
t[tp++] = l;
else {
t[tp++] = 249 + (l / 250);
t[tp++] = (l % 250);
}
while (l-- && tp < tl) {
t[tp] = s[sp++] + (((tp + 1) * 149) % 255) + 1; // see annex H
tp++;
}
enc = 'a'; // reverse to ASCII at end
}
break;
default:
fprintf(stderr, "Unknown encoding %c\n", newenc);
return 0; // failed
}
}
if (lenp)
*lenp = tp;
if (tp < tl && enc != 'a') {
if (enc == 'c' || enc == 'x' || enc == 't')
t[tp++] = 254; // escape X12/C40/Text
else
t[tp++] = 0x7C; // escape EDIFACT
}
if (tp < tl)
t[tp++] = 129; // pad
while (tp < tl) { // more padding
int v = 129 + (((tp + 1) * 149) % 253) + 1; // see Annex H
if (v > 254)
v -= 254;
t[tp++] = v;
}
if (tp > tl || sp < sl)
return 0; // did not fit
/*
* for (tp = 0; tp < tl; tp++) fprintf (stderr, "%02X ", t[tp]); \
* fprintf (stderr, "\n");
*/
return 1; // OK
}
// Auto encoding format functions
static char encchr[] = "ACTXEB";
enum {
E_ASCII,
E_C40,
E_TEXT,
E_X12,
E_EDIFACT,
E_BINARY,
E_MAX
};
unsigned char switchcost[E_MAX][E_MAX] = {
0, 1, 1, 1, 1, 2, // From E_ASCII
1, 0, 2, 2, 2, 3, // From E_C40
1, 2, 0, 2, 2, 3, // From E_TEXT
1, 2, 2, 0, 2, 3, // From E_X12
1, 2, 2, 2, 0, 3, // From E_EDIFACT
0, 1, 1, 1, 1, 0, // From E_BINARY
};
/*
* Creates a encoding list (malloc)
* returns encoding string
* if lenp not null, target len stored
* if error, null returned
* if exact specified, then assumes shortcuts applicable for exact fit
* in target
* 1. No unlatch to return to ASCII for last encoded byte after C40 or
* Text or X12
* 2. No unlatch to return to ASCII for last 1 or 2 encoded bytes after
* EDIFACT
* 3. Final C40 or text encoding exactly in last 2 bytes can have a shift
* 0 to pad to make a tripple
* Only use the encoding from an exact request if the len matches the target,
* otherwise free the result and try again with exact=0
*/
static char *encmake(int l, unsigned char *s, int *lenp, char exact)
{
char *encoding = 0;
int p = l;
char e;
struct {
// number of bytes of source that can be encoded in a row at this point
// using this encoding mode
short s;
// number of bytes of target generated encoding from this point to end if
// already in this encoding mode
short t;
} enc[MAXBARCODE][E_MAX];
memset(&enc, 0, sizeof(enc));
if (!l)
return ""; // no length
if (l > MAXBARCODE)
return 0; // not valid
while (p--) {
char b = 0, sub;
int sl, tl, bl, t;
// consider each encoding from this point
// ASCII
sl = tl = 1;
if (isdigit(s[p]) && p + 1 < l && isdigit(s[p + 1]))
sl = 2; // double digit
else if (s[p] & 0x80)
tl = 2; // high shifted
bl = 0;
if (p + sl < l)
for (e = 0; e < E_MAX; e++)
if (enc[p + sl][e].t && ((t = enc[p + sl][e].t +
switchcost[E_ASCII]
[e]) < bl || !bl)) {
bl = t;
b = e;
}
enc[p][E_ASCII].t = tl + bl;
enc[p][E_ASCII].s = sl;
if (bl && b == E_ASCII)
enc[p][b].s += enc[p + sl][b].s;
// C40
sub = tl = sl = 0;
do {
unsigned char c = s[p + sl++];
if (c & 0x80) { // shift + upper
sub += 2;
c &= 0x7F;
}
if (c != ' ' && !isdigit(c) && !isupper(c))
sub++; // shift
sub++;
while (sub >= 3) {
sub -= 3;
tl += 2;
}
} while (sub && p + sl < l);
if (exact && sub == 2 && p + sl == l) {
// special case, can encode last block with shift 0 at end (Is this
// valid when not end of target buffer?)
sub = 0;
tl += 2;
}
if (!sub) { // can encode C40
bl = 0;
if (p + sl < l)
for (e = 0; e < E_MAX; e++)
if (enc[p + sl][e].t
&&
((t =
enc[p + sl][e].t +
switchcost[E_C40][e]) < bl
|| !bl)) {
bl = t;
b = e;
}
if (exact && enc[p + sl][E_ASCII].t == 1 && 1 < bl) {
// special case, switch to ASCII for last bytes
bl = 1;
b = E_ASCII;
}
enc[p][E_C40].t = tl + bl;
enc[p][E_C40].s = sl;
if (bl && b == E_C40)
enc[p][b].s += enc[p + sl][b].s;
}
// Text
sub = tl = sl = 0;
do {
unsigned char c = s[p + sl++];
if (c & 0x80) { // shift + upper
sub += 2;
c &= 0x7F;
}
if (c != ' ' && !isdigit(c) && !islower(c))
sub++; // shift
sub++;
while (sub >= 3) {
sub -= 3;
tl += 2;
}
} while (sub && p + sl < l);
if (exact && sub == 2 && p + sl == l) {
// special case, can encode last block with shift 0 at end (Is this
// valid when not end of target buffer?)
sub = 0;
tl += 2;
}
if (!sub && sl) { // can encode Text
bl = 0;
if (p + sl < l)
for (e = 0; e < E_MAX; e++)
if (enc[p + sl][e].t
&&
((t =
enc[p + sl][e].t +
switchcost[E_TEXT][e]) < bl
|| !bl)) {
bl = t;
b = e;
}
if (exact && enc[p + sl][E_ASCII].t == 1 && 1 < bl) { // special case, switch to ASCII for last bytes
bl = 1;
b = E_ASCII;
}
enc[p][E_TEXT].t = tl + bl;
enc[p][E_TEXT].s = sl;
if (bl && b == E_TEXT)
enc[p][b].s += enc[p + sl][b].s;
}
// X12
sub = tl = sl = 0;
do {
unsigned char c = s[p + sl++];
if (c != 13 && c != '*' && c != '>' && c != ' '
&& !isdigit(c) && !isupper(c)) {
sl = 0;
break;
}
sub++;
while (sub >= 3) {
sub -= 3;
tl += 2;
}
} while (sub && p + sl < l);
if (!sub && sl) { // can encode X12
bl = 0;
if (p + sl < l)
for (e = 0; e < E_MAX; e++)
if (enc[p + sl][e].t
&&
((t =
enc[p + sl][e].t +
switchcost[E_X12][e]) < bl
|| !bl)) {
bl = t;
b = e;
}
if (exact && enc[p + sl][E_ASCII].t == 1 && 1 < bl) {
// special case, switch to ASCII for last bytes
bl = 1;
b = E_ASCII;
}
enc[p][E_X12].t = tl + bl;
enc[p][E_X12].s = sl;
if (bl && b == E_X12)
enc[p][b].s += enc[p + sl][b].s;
}
// EDIFACT
sl = bl = 0;
if (s[p + 0] >= 32 && s[p + 0] <= 94) { // can encode 1
char bs = 0;
if (p + 1 == l && (!bl || bl < 2)) {
bl = 2;
bs = 1;
} else
for (e = 0; e < E_MAX; e++)
if (e != E_EDIFACT && enc[p + 1][e].t
&&
((t =
2 + enc[p + 1][e].t +
switchcost[E_ASCII][e])
< bl || !bl)) // E_ASCII as allowed for unlatch
{
bs = 1;
bl = t;
b = e;
}
if (p + 1 < l && s[p + 1] >= 32 && s[p + 1] <= 94) { // can encode 2
if (p + 2 == l && (!bl || bl < 2)) {
bl = 3;
bs = 2;
} else
for (e = 0; e < E_MAX; e++)
if (e != E_EDIFACT
&& enc[p + 2][e].t
&&
((t =
3 + enc[p + 2][e].t +
switchcost[E_ASCII][e])
< bl || !bl)) // E_ASCII as allowed for unlatch
{
bs = 2;
bl = t;
b = e;
}
if (p + 2 < l && s[p + 2] >= 32 && s[p + 2] <= 94) { // can encode 3
if (p + 3 == l && (!bl || bl < 3)) {
bl = 3;
bs = 3;
} else
for (e = 0; e < E_MAX; e++)
if (e != E_EDIFACT
&& enc[p + 3][e].t
&&
((t =
3 + enc[p +
3][e].t +
switchcost
[E_ASCII][e])
< bl || !bl)) // E_ASCII as allowed for unlatch
{
bs = 3;
bl = t;
b = e;
}
if (p + 4 < l && s[p + 3] >= 32 && s[p + 3] <= 94) { // can encode 4
if (p + 4 == l
&& (!bl || bl < 3)) {
bl = 3;
bs = 4;
} else {
for (e = 0; e < E_MAX;
e++)
if (enc[p + 4]
[e].t
&&
((t =
3 +
enc[p +
4][e].
t +
switchcost
[E_EDIFACT]
[e]) < bl
|| !bl)) {
bs = 4;
bl = t;
b = e;
}
if (exact
&& enc[p +
4][E_ASCII].t
&& enc[p +
4][E_ASCII].
t <= 2
&& (t =
3 + enc[p +
4]
[E_ASCII].t) <
bl) {
// special case, switch to ASCII for last 1 ot two bytes
bs = 4;
bl = t;
b = E_ASCII;
}
}
}
}
}
enc[p][E_EDIFACT].t = bl;
enc[p][E_EDIFACT].s = bs;
if (bl && b == E_EDIFACT)
enc[p][b].s += enc[p + bs][b].s;
}
// Binary
bl = 0;
for (e = 0; e < E_MAX; e++)
if (enc[p + 1][e].t
&&
((t =
enc[p + 1][e].t + switchcost[E_BINARY][e] +
((e == E_BINARY
&& enc[p + 1][e].t == 249) ? 1 : 0))
< bl || !bl)) {
bl = t;
b = e;
}
enc[p][E_BINARY].t = 1 + bl;
enc[p][E_BINARY].s = 1;
if (bl && b == E_BINARY)
enc[p][b].s += enc[p + 1][b].s;
/*
* fprintf (stderr, "%d:", p); for (e = 0; e < E_MAX; e++) fprintf \
* (stderr, " %c*%d/%d", encchr[e], enc[p][e].s, enc[p][e].t); \
* fprintf (stderr, "\n");
*/
}
encoding = safemalloc(l + 1);
p = 0;
{
char cur = E_ASCII; // starts ASCII
while (p < l) {
int t, m = 0;
char b = 0;
for (e = 0; e < E_MAX; e++)
if (enc[p][e].t
&& ((t = enc[p][e].t + switchcost[cur][e]) <
m || t == m && e == cur || !m)) {
b = e;
m = t;
}
cur = b;
m = enc[p][b].s;
if (!p && lenp)
*lenp = enc[p][b].t;
while (p < l && m--)
encoding[p++] = encchr[b];
}
}
encoding[p] = 0;
return encoding;
}
/*
* Main encoding function
* Returns the grid (malloced) containing the matrix. L corner at 0,0.
* Takes suggested size in *Wptr, *Hptr, or 0,0. Fills in actual size.
* Takes barcodelen and barcode to be encoded
* Note, if *encodingptr is null, then fills with auto picked (malloced)
* encoding
* If lenp not null, then the length of encoded data before any final
* unlatch or pad is stored
* If maxp not null, then the max storage of this size code is stored
* If eccp not null, then the number of ecc bytes used in this size is
* stored
* Returns 0 on error (writes to stderr with details).
*/
unsigned char *iec16022ecc200(int *Wptr, int *Hptr, char **encodingptr,
int barcodelen, unsigned char *barcode,
int *lenp, int *maxp, int *eccp)
{
unsigned char binary[3000]; // encoded raw data and ecc to place in barcode
int W = 0, H = 0;
char *encoding = 0;
unsigned char *grid = 0;
struct ecc200matrix_s *matrix;
memset(binary, 0, sizeof(binary));
if (encodingptr)
encoding = *encodingptr;
if (Wptr)
W = *Wptr;
if (Hptr)
H = *Hptr;
// encoding
if (W) { // known size
for (matrix = ecc200matrix; matrix->W && (matrix->W != W ||
matrix->H != H);
matrix++) ;
if (!matrix->W) {
fprintf(stderr, "Invalid size %dx%d\n", W, H);
return 0;
}
if (!encoding) {
int len;
char *e = encmake(barcodelen, barcode, &len, 1);
if (e && len != matrix->bytes) { // try not an exact fit
free(e);
e = encmake(barcodelen, barcode, &len, 0);
if (len > matrix->bytes) {
fprintf(stderr,
"Cannot make barcode fit %dx%d\n",
W, H);
return 0;
}
}
encoding = e;
}
} else {
// find a suitable encoding
if (encoding == NULL)
encoding = encmake(barcodelen, barcode, NULL, 1);
if (encoding) { // find one that fits chosen encoding
for (matrix = ecc200matrix; matrix->W; matrix++)
if (ecc200encode
(binary, matrix->bytes, barcode, barcodelen,
encoding, 0))
break;
} else {
int len;
char *e;
e = encmake(barcodelen, barcode, &len, 1);
for (matrix = ecc200matrix;
matrix->W && matrix->bytes != len; matrix++) ;
if (e && !matrix->W) { // try for non exact fit
free(e);
e = encmake(barcodelen, barcode, &len, 0);
for (matrix = ecc200matrix;
matrix->W && matrix->bytes < len;
matrix++) ;
}
encoding = e;
}
if (!matrix->W) {
fprintf(stderr,
"Cannot find suitable size, barcode too long\n");
return 0;
}
W = matrix->W;
H = matrix->H;
}
if (!ecc200encode(binary, matrix->bytes, barcode, barcodelen,
encoding, lenp)) {
fprintf(stderr, "Barcode too long for %dx%d\n", W, H);
return 0;
}
// ecc code
ecc200(binary, matrix->bytes, matrix->datablock, matrix->rsblock);
{ // placement
int x, y, NC, NR, *places;
NC = W - 2 * (W / matrix->FW);
NR = H - 2 * (H / matrix->FH);
places = safemalloc(NC * NR * sizeof(int));
ecc200placement(places, NR, NC);
grid = safemalloc(W * H);
memset(grid, 0, W * H);
for (y = 0; y < H; y += matrix->FH) {
for (x = 0; x < W; x++)
grid[y * W + x] = 1;
for (x = 0; x < W; x += 2)
grid[(y + matrix->FH - 1) * W + x] = 1;
}
for (x = 0; x < W; x += matrix->FW) {
for (y = 0; y < H; y++)
grid[y * W + x] = 1;
for (y = 0; y < H; y += 2)
grid[y * W + x + matrix->FW - 1] = 1;
}
for (y = 0; y < NR; y++) {
for (x = 0; x < NC; x++) {
int v = places[(NR - y - 1) * NC + x];
//fprintf (stderr, "%4d", v);
if (v == 1 || v > 7
&& (binary[(v >> 3) - 1] & (1 << (v & 7))))
grid[(1 + y +
2 * (y / (matrix->FH - 2))) * W +
1 + x +
2 * (x / (matrix->FW - 2))] = 1;
}
//fprintf (stderr, "\n");
}
free(places);
}
if (Wptr)
*Wptr = W;
if (Hptr)
*Hptr = H;
if (encodingptr)
*encodingptr = encoding;
if (maxp)
*maxp = matrix->bytes;
if (eccp)
*eccp =
(matrix->bytes + 2) / matrix->datablock * matrix->rsblock;
return grid;
}
+47
View File
@@ -0,0 +1,47 @@
/**
*
* IEC16022 bar code generation
* Adrian Kennard, Andrews & Arnold Ltd
* with help from Cliff Hones on the RS coding
*
* (c) 2004 Adrian Kennard, Andrews & Arnold Ltd
* (c) 2006 Stefan Schmidt <stefan@datenfreihafen.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*
* Main encoding function
* Returns the grid (malloced) containing the matrix. L corner at 0,0.
* Takes suggested size in *Wptr, *Hptr, or 0,0. Fills in actual size.
* Takes barcodelen and barcode to be encoded
* Note, if *encodingptr is null, then fills with auto picked (malloced)
* encoding.
* If lenp not null, then the length of encoded data before any final unlatch
* or pad is stored.
* If maxp not null, then the max storage of this size code is stored
* If eccp not null, then the number of ecc bytes used in this size is stored
* Returns 0 on error (writes to stderr with details).
*
*/
#ifndef __IEC16022ECC200_H
#define __IEC16022ECC200_H
unsigned char *iec16022ecc200(int *Wptr, int *Hptr, char **encodingptr,
int barcodelen, unsigned char *barcode,
int *lenp, int *maxp, int *eccp);
#define MAXBARCODE 3116
#endif /* __IEC16022ECC200_H */
+181
View File
@@ -0,0 +1,181 @@
/* dmatrix.c - Handles Data Matrix 2-D symbology (IEC16022 ecc 200) */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This file is a hacked-up copy of:
* IEC16022 bar code generation by
* Adrian Kennard, Andrews & Arnold Ltd
* with help from Cliff Hones on the RS coding
*
* (c) 2004 Adrian Kennard, Andrews & Arnold Ltd
* (c) 2006 Stefan Schmidt <stefan@datenfreihafen.org>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* The original version of this code is available at:
http://www.datenfreihafen.org/projects/iec16022.html */
#define IEC16022_VERSION "0.2"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <malloc.h>
#include "dm200.h"
#include "common.h"
// simple checked response malloc
void *safemalloc(int n)
{
void *p = malloc(n);
if (!p) {
fprintf(stderr, "Malloc(%d) failed\n", n);
exit(1);
}
return p;
}
int dmatrix(struct zint_symbol *symbol, unsigned char source[])
{
int W = 0, H = 0;
int ecc = 0;
int barcodelen = 0;
char *encoding = 0;
int len = 0, maxlen = 0, ecclen = 0;
unsigned char *grid = 0;
char size[3], eccstr[3];
strcpy(size, "");
strcpy(eccstr, "200");
/* if (strlen(barcode) == 0) { // read from file
FILE *f = fopen(infile, "rb");
barcode = safemalloc(4001);
if (!f) {
strcpy(symbol->errtxt, "error: could not open file");
return 8;
}
barcodelen = fread(barcode, 1, 4000, f);
if (barcodelen < 0) {
strcpy(symbol->errtxt, "error: could not read file");
return 8;
}
barcode[barcodelen] = 0; // null terminate anyway
fclose(f);
} else */
barcodelen = strlen(source);
if(barcodelen > 780) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
// check parameters
if (strlen(size) != 0) {
char *x = strchr(size, 'x');
W = atoi(size);
if (x)
H = atoi(x + 1);
if (!H)
W = H;
}
if (eccstr)
ecc = atoi(eccstr);
if (W & 1) { // odd size
if (W != H || W < 9 || W > 49) {
strcpy(symbol->errtxt, "error: invalid Data Matrix size");
return ERROR_INVALID_OPTION;
}
if (!eccstr) {
if (W >= 17)
ecc = 140;
else if (W >= 13)
ecc = 100;
else if (W >= 11)
ecc = 80;
else
ecc = 0;
}
if (ecc && ecc != 50 && ecc != 80 && ecc != 100 && ecc != 140 ||
ecc == 50 && W < 11 || ecc == 80 && W < 13 || ecc == 100
&& W < 13 || ecc == 140 && W < 17) {
strcpy(symbol->errtxt, "error: invalid ecc value");
return ERROR_INVALID_OPTION;
}
} else if (W) { // even size
if (W < H) {
int t = W;
W = H;
H = t;
}
if (!eccstr)
ecc = 200;
if (ecc != 200) {
strcpy(symbol->errtxt, "error: invalid size for ecc 200");
return ERROR_INVALID_OPTION;
}
}
else { // auto size
if (!eccstr)
// default is even sizes only unless explicit ecc set to force odd
// sizes
ecc = 200;
}
// processing stamps
if ((W & 1) || ecc < 200) { // odd sizes
strcpy(symbol->errtxt, "error: odd sizes not supported");
return ERROR_INVALID_OPTION;
} else { // even sizes
grid =
iec16022ecc200(&W, &H, &encoding, barcodelen, source, &len,
&maxlen, &ecclen);
}
// output
if (!grid || !W) {
strcpy(symbol->errtxt, "error: Data Matrix encoding error");
return ERROR_ENCODING_PROBLEM;
}
int y;
/*for (y = H - 1; y >= 0; y--) {
int x;
for (x = 0; x < W; x++)
printf("%c",
grid[W * y + x] ? '*' : ' ');
printf("\n");
}*/
symbol->rows = H;
symbol->width = W;
for(y = H - 1; y >= 0; y--) {
int x;
for(x = 0; x < W; x++) {
if(grid[W * y + x]) {
symbol->encoded_data[(H - y) - 1][x] = '1'; }
else {
symbol->encoded_data[(H - y) - 1][x] = '0'; }
}
symbol->row_height[(H - y) - 1] = 1;
}
return 0;
}
+680
View File
@@ -0,0 +1,680 @@
/* imail.c - Handles Intelligent Mail (aka OneCode) for USPS */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* The function "USPS_MSB_Math_CRC11GenerateFrameCheckSequence"
is Copyright (C) 2006 United States Postal Service */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "common.h"
#include "large.h"
#define NASET "0123456789-"
/* The following lookup tables were generated using the code in Appendix C */
static unsigned short AppxD_I[1287] = { /* Appendix D Table 1 - 5 of 13 characters */
0x001F, 0x1F00, 0x002F, 0x1E80, 0x0037, 0x1D80, 0x003B, 0x1B80, 0x003D, 0x1780,
0x003E, 0x0F80, 0x004F, 0x1E40, 0x0057, 0x1D40, 0x005B, 0x1B40, 0x005D, 0x1740,
0x005E, 0x0F40, 0x0067, 0x1CC0, 0x006B, 0x1AC0, 0x006D, 0x16C0, 0x006E, 0x0EC0,
0x0073, 0x19C0, 0x0075, 0x15C0, 0x0076, 0x0DC0, 0x0079, 0x13C0, 0x007A, 0x0BC0,
0x007C, 0x07C0, 0x008F, 0x1E20, 0x0097, 0x1D20, 0x009B, 0x1B20, 0x009D, 0x1720,
0x009E, 0x0F20, 0x00A7, 0x1CA0, 0x00AB, 0x1AA0, 0x00AD, 0x16A0, 0x00AE, 0x0EA0,
0x00B3, 0x19A0, 0x00B5, 0x15A0, 0x00B6, 0x0DA0, 0x00B9, 0x13A0, 0x00BA, 0x0BA0,
0x00BC, 0x07A0, 0x00C7, 0x1C60, 0x00CB, 0x1A60, 0x00CD, 0x1660, 0x00CE, 0x0E60,
0x00D3, 0x1960, 0x00D5, 0x1560, 0x00D6, 0x0D60, 0x00D9, 0x1360, 0x00DA, 0x0B60,
0x00DC, 0x0760, 0x00E3, 0x18E0, 0x00E5, 0x14E0, 0x00E6, 0x0CE0, 0x00E9, 0x12E0,
0x00EA, 0x0AE0, 0x00EC, 0x06E0, 0x00F1, 0x11E0, 0x00F2, 0x09E0, 0x00F4, 0x05E0,
0x00F8, 0x03E0, 0x010F, 0x1E10, 0x0117, 0x1D10, 0x011B, 0x1B10, 0x011D, 0x1710,
0x011E, 0x0F10, 0x0127, 0x1C90, 0x012B, 0x1A90, 0x012D, 0x1690, 0x012E, 0x0E90,
0x0133, 0x1990, 0x0135, 0x1590, 0x0136, 0x0D90, 0x0139, 0x1390, 0x013A, 0x0B90,
0x013C, 0x0790, 0x0147, 0x1C50, 0x014B, 0x1A50, 0x014D, 0x1650, 0x014E, 0x0E50,
0x0153, 0x1950, 0x0155, 0x1550, 0x0156, 0x0D50, 0x0159, 0x1350, 0x015A, 0x0B50,
0x015C, 0x0750, 0x0163, 0x18D0, 0x0165, 0x14D0, 0x0166, 0x0CD0, 0x0169, 0x12D0,
0x016A, 0x0AD0, 0x016C, 0x06D0, 0x0171, 0x11D0, 0x0172, 0x09D0, 0x0174, 0x05D0,
0x0178, 0x03D0, 0x0187, 0x1C30, 0x018B, 0x1A30, 0x018D, 0x1630, 0x018E, 0x0E30,
0x0193, 0x1930, 0x0195, 0x1530, 0x0196, 0x0D30, 0x0199, 0x1330, 0x019A, 0x0B30,
0x019C, 0x0730, 0x01A3, 0x18B0, 0x01A5, 0x14B0, 0x01A6, 0x0CB0, 0x01A9, 0x12B0,
0x01AA, 0x0AB0, 0x01AC, 0x06B0, 0x01B1, 0x11B0, 0x01B2, 0x09B0, 0x01B4, 0x05B0,
0x01B8, 0x03B0, 0x01C3, 0x1870, 0x01C5, 0x1470, 0x01C6, 0x0C70, 0x01C9, 0x1270,
0x01CA, 0x0A70, 0x01CC, 0x0670, 0x01D1, 0x1170, 0x01D2, 0x0970, 0x01D4, 0x0570,
0x01D8, 0x0370, 0x01E1, 0x10F0, 0x01E2, 0x08F0, 0x01E4, 0x04F0, 0x01E8, 0x02F0,
0x020F, 0x1E08, 0x0217, 0x1D08, 0x021B, 0x1B08, 0x021D, 0x1708, 0x021E, 0x0F08,
0x0227, 0x1C88, 0x022B, 0x1A88, 0x022D, 0x1688, 0x022E, 0x0E88, 0x0233, 0x1988,
0x0235, 0x1588, 0x0236, 0x0D88, 0x0239, 0x1388, 0x023A, 0x0B88, 0x023C, 0x0788,
0x0247, 0x1C48, 0x024B, 0x1A48, 0x024D, 0x1648, 0x024E, 0x0E48, 0x0253, 0x1948,
0x0255, 0x1548, 0x0256, 0x0D48, 0x0259, 0x1348, 0x025A, 0x0B48, 0x025C, 0x0748,
0x0263, 0x18C8, 0x0265, 0x14C8, 0x0266, 0x0CC8, 0x0269, 0x12C8, 0x026A, 0x0AC8,
0x026C, 0x06C8, 0x0271, 0x11C8, 0x0272, 0x09C8, 0x0274, 0x05C8, 0x0278, 0x03C8,
0x0287, 0x1C28, 0x028B, 0x1A28, 0x028D, 0x1628, 0x028E, 0x0E28, 0x0293, 0x1928,
0x0295, 0x1528, 0x0296, 0x0D28, 0x0299, 0x1328, 0x029A, 0x0B28, 0x029C, 0x0728,
0x02A3, 0x18A8, 0x02A5, 0x14A8, 0x02A6, 0x0CA8, 0x02A9, 0x12A8, 0x02AA, 0x0AA8,
0x02AC, 0x06A8, 0x02B1, 0x11A8, 0x02B2, 0x09A8, 0x02B4, 0x05A8, 0x02B8, 0x03A8,
0x02C3, 0x1868, 0x02C5, 0x1468, 0x02C6, 0x0C68, 0x02C9, 0x1268, 0x02CA, 0x0A68,
0x02CC, 0x0668, 0x02D1, 0x1168, 0x02D2, 0x0968, 0x02D4, 0x0568, 0x02D8, 0x0368,
0x02E1, 0x10E8, 0x02E2, 0x08E8, 0x02E4, 0x04E8, 0x0307, 0x1C18, 0x030B, 0x1A18,
0x030D, 0x1618, 0x030E, 0x0E18, 0x0313, 0x1918, 0x0315, 0x1518, 0x0316, 0x0D18,
0x0319, 0x1318, 0x031A, 0x0B18, 0x031C, 0x0718, 0x0323, 0x1898, 0x0325, 0x1498,
0x0326, 0x0C98, 0x0329, 0x1298, 0x032A, 0x0A98, 0x032C, 0x0698, 0x0331, 0x1198,
0x0332, 0x0998, 0x0334, 0x0598, 0x0338, 0x0398, 0x0343, 0x1858, 0x0345, 0x1458,
0x0346, 0x0C58, 0x0349, 0x1258, 0x034A, 0x0A58, 0x034C, 0x0658, 0x0351, 0x1158,
0x0352, 0x0958, 0x0354, 0x0558, 0x0361, 0x10D8, 0x0362, 0x08D8, 0x0364, 0x04D8,
0x0383, 0x1838, 0x0385, 0x1438, 0x0386, 0x0C38, 0x0389, 0x1238, 0x038A, 0x0A38,
0x038C, 0x0638, 0x0391, 0x1138, 0x0392, 0x0938, 0x0394, 0x0538, 0x03A1, 0x10B8,
0x03A2, 0x08B8, 0x03A4, 0x04B8, 0x03C1, 0x1078, 0x03C2, 0x0878, 0x03C4, 0x0478,
0x040F, 0x1E04, 0x0417, 0x1D04, 0x041B, 0x1B04, 0x041D, 0x1704, 0x041E, 0x0F04,
0x0427, 0x1C84, 0x042B, 0x1A84, 0x042D, 0x1684, 0x042E, 0x0E84, 0x0433, 0x1984,
0x0435, 0x1584, 0x0436, 0x0D84, 0x0439, 0x1384, 0x043A, 0x0B84, 0x043C, 0x0784,
0x0447, 0x1C44, 0x044B, 0x1A44, 0x044D, 0x1644, 0x044E, 0x0E44, 0x0453, 0x1944,
0x0455, 0x1544, 0x0456, 0x0D44, 0x0459, 0x1344, 0x045A, 0x0B44, 0x045C, 0x0744,
0x0463, 0x18C4, 0x0465, 0x14C4, 0x0466, 0x0CC4, 0x0469, 0x12C4, 0x046A, 0x0AC4,
0x046C, 0x06C4, 0x0471, 0x11C4, 0x0472, 0x09C4, 0x0474, 0x05C4, 0x0487, 0x1C24,
0x048B, 0x1A24, 0x048D, 0x1624, 0x048E, 0x0E24, 0x0493, 0x1924, 0x0495, 0x1524,
0x0496, 0x0D24, 0x0499, 0x1324, 0x049A, 0x0B24, 0x049C, 0x0724, 0x04A3, 0x18A4,
0x04A5, 0x14A4, 0x04A6, 0x0CA4, 0x04A9, 0x12A4, 0x04AA, 0x0AA4, 0x04AC, 0x06A4,
0x04B1, 0x11A4, 0x04B2, 0x09A4, 0x04B4, 0x05A4, 0x04C3, 0x1864, 0x04C5, 0x1464,
0x04C6, 0x0C64, 0x04C9, 0x1264, 0x04CA, 0x0A64, 0x04CC, 0x0664, 0x04D1, 0x1164,
0x04D2, 0x0964, 0x04D4, 0x0564, 0x04E1, 0x10E4, 0x04E2, 0x08E4, 0x0507, 0x1C14,
0x050B, 0x1A14, 0x050D, 0x1614, 0x050E, 0x0E14, 0x0513, 0x1914, 0x0515, 0x1514,
0x0516, 0x0D14, 0x0519, 0x1314, 0x051A, 0x0B14, 0x051C, 0x0714, 0x0523, 0x1894,
0x0525, 0x1494, 0x0526, 0x0C94, 0x0529, 0x1294, 0x052A, 0x0A94, 0x052C, 0x0694,
0x0531, 0x1194, 0x0532, 0x0994, 0x0534, 0x0594, 0x0543, 0x1854, 0x0545, 0x1454,
0x0546, 0x0C54, 0x0549, 0x1254, 0x054A, 0x0A54, 0x054C, 0x0654, 0x0551, 0x1154,
0x0552, 0x0954, 0x0561, 0x10D4, 0x0562, 0x08D4, 0x0583, 0x1834, 0x0585, 0x1434,
0x0586, 0x0C34, 0x0589, 0x1234, 0x058A, 0x0A34, 0x058C, 0x0634, 0x0591, 0x1134,
0x0592, 0x0934, 0x05A1, 0x10B4, 0x05A2, 0x08B4, 0x05C1, 0x1074, 0x05C2, 0x0874,
0x0607, 0x1C0C, 0x060B, 0x1A0C, 0x060D, 0x160C, 0x060E, 0x0E0C, 0x0613, 0x190C,
0x0615, 0x150C, 0x0616, 0x0D0C, 0x0619, 0x130C, 0x061A, 0x0B0C, 0x061C, 0x070C,
0x0623, 0x188C, 0x0625, 0x148C, 0x0626, 0x0C8C, 0x0629, 0x128C, 0x062A, 0x0A8C,
0x062C, 0x068C, 0x0631, 0x118C, 0x0632, 0x098C, 0x0643, 0x184C, 0x0645, 0x144C,
0x0646, 0x0C4C, 0x0649, 0x124C, 0x064A, 0x0A4C, 0x0651, 0x114C, 0x0652, 0x094C,
0x0661, 0x10CC, 0x0662, 0x08CC, 0x0683, 0x182C, 0x0685, 0x142C, 0x0686, 0x0C2C,
0x0689, 0x122C, 0x068A, 0x0A2C, 0x0691, 0x112C, 0x0692, 0x092C, 0x06A1, 0x10AC,
0x06A2, 0x08AC, 0x06C1, 0x106C, 0x06C2, 0x086C, 0x0703, 0x181C, 0x0705, 0x141C,
0x0706, 0x0C1C, 0x0709, 0x121C, 0x070A, 0x0A1C, 0x0711, 0x111C, 0x0712, 0x091C,
0x0721, 0x109C, 0x0722, 0x089C, 0x0741, 0x105C, 0x0742, 0x085C, 0x0781, 0x103C,
0x0782, 0x083C, 0x080F, 0x1E02, 0x0817, 0x1D02, 0x081B, 0x1B02, 0x081D, 0x1702,
0x081E, 0x0F02, 0x0827, 0x1C82, 0x082B, 0x1A82, 0x082D, 0x1682, 0x082E, 0x0E82,
0x0833, 0x1982, 0x0835, 0x1582, 0x0836, 0x0D82, 0x0839, 0x1382, 0x083A, 0x0B82,
0x0847, 0x1C42, 0x084B, 0x1A42, 0x084D, 0x1642, 0x084E, 0x0E42, 0x0853, 0x1942,
0x0855, 0x1542, 0x0856, 0x0D42, 0x0859, 0x1342, 0x085A, 0x0B42, 0x0863, 0x18C2,
0x0865, 0x14C2, 0x0866, 0x0CC2, 0x0869, 0x12C2, 0x086A, 0x0AC2, 0x0871, 0x11C2,
0x0872, 0x09C2, 0x0887, 0x1C22, 0x088B, 0x1A22, 0x088D, 0x1622, 0x088E, 0x0E22,
0x0893, 0x1922, 0x0895, 0x1522, 0x0896, 0x0D22, 0x0899, 0x1322, 0x089A, 0x0B22,
0x08A3, 0x18A2, 0x08A5, 0x14A2, 0x08A6, 0x0CA2, 0x08A9, 0x12A2, 0x08AA, 0x0AA2,
0x08B1, 0x11A2, 0x08B2, 0x09A2, 0x08C3, 0x1862, 0x08C5, 0x1462, 0x08C6, 0x0C62,
0x08C9, 0x1262, 0x08CA, 0x0A62, 0x08D1, 0x1162, 0x08D2, 0x0962, 0x08E1, 0x10E2,
0x0907, 0x1C12, 0x090B, 0x1A12, 0x090D, 0x1612, 0x090E, 0x0E12, 0x0913, 0x1912,
0x0915, 0x1512, 0x0916, 0x0D12, 0x0919, 0x1312, 0x091A, 0x0B12, 0x0923, 0x1892,
0x0925, 0x1492, 0x0926, 0x0C92, 0x0929, 0x1292, 0x092A, 0x0A92, 0x0931, 0x1192,
0x0932, 0x0992, 0x0943, 0x1852, 0x0945, 0x1452, 0x0946, 0x0C52, 0x0949, 0x1252,
0x094A, 0x0A52, 0x0951, 0x1152, 0x0961, 0x10D2, 0x0983, 0x1832, 0x0985, 0x1432,
0x0986, 0x0C32, 0x0989, 0x1232, 0x098A, 0x0A32, 0x0991, 0x1132, 0x09A1, 0x10B2,
0x09C1, 0x1072, 0x0A07, 0x1C0A, 0x0A0B, 0x1A0A, 0x0A0D, 0x160A, 0x0A0E, 0x0E0A,
0x0A13, 0x190A, 0x0A15, 0x150A, 0x0A16, 0x0D0A, 0x0A19, 0x130A, 0x0A1A, 0x0B0A,
0x0A23, 0x188A, 0x0A25, 0x148A, 0x0A26, 0x0C8A, 0x0A29, 0x128A, 0x0A2A, 0x0A8A,
0x0A31, 0x118A, 0x0A43, 0x184A, 0x0A45, 0x144A, 0x0A46, 0x0C4A, 0x0A49, 0x124A,
0x0A51, 0x114A, 0x0A61, 0x10CA, 0x0A83, 0x182A, 0x0A85, 0x142A, 0x0A86, 0x0C2A,
0x0A89, 0x122A, 0x0A91, 0x112A, 0x0AA1, 0x10AA, 0x0AC1, 0x106A, 0x0B03, 0x181A,
0x0B05, 0x141A, 0x0B06, 0x0C1A, 0x0B09, 0x121A, 0x0B11, 0x111A, 0x0B21, 0x109A,
0x0B41, 0x105A, 0x0B81, 0x103A, 0x0C07, 0x1C06, 0x0C0B, 0x1A06, 0x0C0D, 0x1606,
0x0C0E, 0x0E06, 0x0C13, 0x1906, 0x0C15, 0x1506, 0x0C16, 0x0D06, 0x0C19, 0x1306,
0x0C23, 0x1886, 0x0C25, 0x1486, 0x0C26, 0x0C86, 0x0C29, 0x1286, 0x0C31, 0x1186,
0x0C43, 0x1846, 0x0C45, 0x1446, 0x0C49, 0x1246, 0x0C51, 0x1146, 0x0C61, 0x10C6,
0x0C83, 0x1826, 0x0C85, 0x1426, 0x0C89, 0x1226, 0x0C91, 0x1126, 0x0CA1, 0x10A6,
0x0CC1, 0x1066, 0x0D03, 0x1816, 0x0D05, 0x1416, 0x0D09, 0x1216, 0x0D11, 0x1116,
0x0D21, 0x1096, 0x0D41, 0x1056, 0x0D81, 0x1036, 0x0E03, 0x180E, 0x0E05, 0x140E,
0x0E09, 0x120E, 0x0E11, 0x110E, 0x0E21, 0x108E, 0x0E41, 0x104E, 0x0E81, 0x102E,
0x0F01, 0x101E, 0x100F, 0x1E01, 0x1017, 0x1D01, 0x101B, 0x1B01, 0x101D, 0x1701,
0x1027, 0x1C81, 0x102B, 0x1A81, 0x102D, 0x1681, 0x1033, 0x1981, 0x1035, 0x1581,
0x1039, 0x1381, 0x1047, 0x1C41, 0x104B, 0x1A41, 0x104D, 0x1641, 0x1053, 0x1941,
0x1055, 0x1541, 0x1059, 0x1341, 0x1063, 0x18C1, 0x1065, 0x14C1, 0x1069, 0x12C1,
0x1071, 0x11C1, 0x1087, 0x1C21, 0x108B, 0x1A21, 0x108D, 0x1621, 0x1093, 0x1921,
0x1095, 0x1521, 0x1099, 0x1321, 0x10A3, 0x18A1, 0x10A5, 0x14A1, 0x10A9, 0x12A1,
0x10B1, 0x11A1, 0x10C3, 0x1861, 0x10C5, 0x1461, 0x10C9, 0x1261, 0x10D1, 0x1161,
0x1107, 0x1C11, 0x110B, 0x1A11, 0x110D, 0x1611, 0x1113, 0x1911, 0x1115, 0x1511,
0x1119, 0x1311, 0x1123, 0x1891, 0x1125, 0x1491, 0x1129, 0x1291, 0x1131, 0x1191,
0x1143, 0x1851, 0x1145, 0x1451, 0x1149, 0x1251, 0x1183, 0x1831, 0x1185, 0x1431,
0x1189, 0x1231, 0x1207, 0x1C09, 0x120B, 0x1A09, 0x120D, 0x1609, 0x1213, 0x1909,
0x1215, 0x1509, 0x1219, 0x1309, 0x1223, 0x1889, 0x1225, 0x1489, 0x1229, 0x1289,
0x1243, 0x1849, 0x1245, 0x1449, 0x1283, 0x1829, 0x1285, 0x1429, 0x1303, 0x1819,
0x1305, 0x1419, 0x1407, 0x1C05, 0x140B, 0x1A05, 0x140D, 0x1605, 0x1413, 0x1905,
0x1415, 0x1505, 0x1423, 0x1885, 0x1425, 0x1485, 0x1443, 0x1845, 0x1483, 0x1825,
0x1503, 0x1815, 0x1603, 0x180D, 0x1807, 0x1C03, 0x180B, 0x1A03, 0x1813, 0x1903,
0x1823, 0x1883, 0x1843, 0x1445, 0x1249, 0x1151, 0x10E1, 0x0C46, 0x0A4A, 0x0952,
0x08E2, 0x064C, 0x0554, 0x04E4, 0x0358, 0x02E8, 0x01F0 };
static unsigned short AppxD_II[78] = { /* Appendix D Table II - 2 of 13 characters */
0x0003, 0x1800, 0x0005, 0x1400, 0x0006, 0x0C00, 0x0009, 0x1200, 0x000A, 0x0A00,
0x000C, 0x0600, 0x0011, 0x1100, 0x0012, 0x0900, 0x0014, 0x0500, 0x0018, 0x0300,
0x0021, 0x1080, 0x0022, 0x0880, 0x0024, 0x0480, 0x0028, 0x0280, 0x0030, 0x0180,
0x0041, 0x1040, 0x0042, 0x0840, 0x0044, 0x0440, 0x0048, 0x0240, 0x0050, 0x0140,
0x0060, 0x00C0, 0x0081, 0x1020, 0x0082, 0x0820, 0x0084, 0x0420, 0x0088, 0x0220,
0x0090, 0x0120, 0x0101, 0x1010, 0x0102, 0x0810, 0x0104, 0x0410, 0x0108, 0x0210,
0x0201, 0x1008, 0x0202, 0x0808, 0x0204, 0x0408, 0x0401, 0x1004, 0x0402, 0x0804,
0x0801, 0x1002, 0x1001, 0x0802, 0x0404, 0x0208, 0x0110, 0x00A0 };
static int AppxD_IV[130] = { /* Appendix D Table IV - Bar-to-Character Mapping (reverse lookup) */
67, 6, 78, 16, 86, 95, 34, 40, 45, 113, 117, 121, 62, 87, 18, 104, 41, 76, 57, 119, 115, 72, 97,
2, 127, 26, 105, 35, 122, 52, 114, 7, 24, 82, 68, 63, 94, 44, 77, 112, 70, 100, 39, 30, 107,
15, 125, 85, 10, 65, 54, 88, 20, 106, 46, 66, 8, 116, 29, 61, 99, 80, 90, 37, 123, 51, 25, 84,
129, 56, 4, 109, 96, 28, 36, 47, 11, 71, 33, 102, 21, 9, 17, 49, 124, 79, 64, 91, 42, 69, 53,
60, 14, 1, 27, 103, 126, 75, 89, 50, 120, 19, 32, 110, 92, 111, 130, 59, 31, 12, 81, 43, 55,
5, 74, 22, 101, 128, 58, 118, 48, 108, 38, 98, 93, 23, 83, 13, 73, 3 };
/***************************************************************************
** USPS_MSB_Math_CRC11GenerateFrameCheckSequence
**
** Inputs:
** ByteAttayPtr is the address of a 13 byte array holding 102 bytes which
** are right justified - ie: the leftmost 2 bits of the first byte do not
** hold data and must be set to zero.
**
** Outputs:
** return unsigned short - 11 bit Frame Check Sequence (right justified)
***************************************************************************/
extern unsigned short
USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr )
{
unsigned short GeneratorPolynomial = 0x0F35;
unsigned short FrameCheckSequence = 0x07FF;
unsigned short Data;
int ByteIndex, Bit;
/* Do most significant byte skipping the 2 most significant bits */
Data = *ByteArrayPtr << 5;
ByteArrayPtr++;
for ( Bit = 2; Bit < 8; Bit++ )
{
if ( (FrameCheckSequence ^ Data) & 0x400 )
FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
else
FrameCheckSequence = (FrameCheckSequence << 1);
FrameCheckSequence &= 0x7FF;
Data <<= 1;
}
/* Do rest of the bytes */
for ( ByteIndex = 1; ByteIndex < 13; ByteIndex++ )
{
Data = *ByteArrayPtr << 3;
ByteArrayPtr++;
for ( Bit = 0; Bit < 8; Bit++ )
{
if ( (FrameCheckSequence ^ Data) & 0x0400 ) {
FrameCheckSequence = (FrameCheckSequence << 1) ^ GeneratorPolynomial;
} else {
FrameCheckSequence = (FrameCheckSequence << 1);
}
FrameCheckSequence &= 0x7FF;
Data <<= 1;
}
}
return FrameCheckSequence;
}
void breakup(short int fcs_bit[], unsigned short usps_crc)
{
int i;
for(i = 0; i < 13; i++) {
fcs_bit[i] = 0;
}
if(usps_crc >= 4096) {
fcs_bit[12] = 1;
usps_crc -= 4096;
}
if(usps_crc >= 2048) {
fcs_bit[11] = 1;
usps_crc -= 2048;
}
if(usps_crc >= 1024) {
fcs_bit[10] = 1;
usps_crc -= 1024;
}
if(usps_crc >= 512) {
fcs_bit[9] = 1;
usps_crc -= 512;
}
if(usps_crc >= 256) {
fcs_bit[8] = 1;
usps_crc -= 256;
}
if(usps_crc >= 128) {
fcs_bit[7] = 1;
usps_crc -= 128;
}
if(usps_crc >= 64) {
fcs_bit[6] = 1;
usps_crc -= 64;
}
if(usps_crc >= 32) {
fcs_bit[5] = 1;
usps_crc -= 32;
}
if(usps_crc >= 16) {
fcs_bit[4] = 1;
usps_crc -= 16;
}
if(usps_crc >= 8) {
fcs_bit[3] = 1;
usps_crc -= 8;
}
if(usps_crc >= 4) {
fcs_bit[2] = 1;
usps_crc -= 4;
}
if(usps_crc >= 2) {
fcs_bit[1] = 1;
usps_crc -= 2;
}
if(usps_crc == 1) {
fcs_bit[0] = 1;
}
}
int imail(struct zint_symbol *symbol, unsigned char source[])
{
char data_pattern[200];
int errno;
errno = 0;
if(strlen(source) > 32) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NASET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
int i, j, read;
char zip[35], tracker[35], zip_adder[11], temp[2];
short int accum[112], x_reg[112], y_reg[112];
strcpy(zip, "");
strcpy(tracker, "");
unsigned char byte_array[13];
unsigned short usps_crc;
int codeword[10];
unsigned short characters[10];
short int bit_pattern[13], bar_map[130];
/* separate the tracking code from the routing code */
read = 0;
j = 0;
for(i = 0; i < strlen(source); i++) {
if(source[i] == '-') {
tracker[read] = '\0';
j = 1;
read = 0;
} else {
if(j == 0) {
/* reading tracker */
tracker[read] = source[i];
read++;
} else {
/* reading zip code */
zip[read] = source[i];
read++;
}
}
}
if(j == 0) {
tracker[read] = '\0';
} else {
zip[read] = '\0';
}
if(strlen(tracker) != 20) {
strcpy(symbol->errtxt, "error: invalid length tracking code");
return ERROR_INVALID_DATA;
}
if(strlen(zip) > 11) {
strcpy(symbol->errtxt, "error: invalid ZIP code");
return ERROR_INVALID_DATA;
}
/* *** Step 1 - Conversion of Data Fields into Binary Data *** */
/* Routing code first */
for(i = 0; i < 112; i++) {
accum[i] = 0;
}
for(read = 0; read < strlen(zip); read++) {
for(i = 0; i < 112; i++) {
x_reg[i] = accum[i];
}
for(i = 0; i < 9; i++) {
binary_add(accum, x_reg);
}
x_reg[0] = BCD[ctoi(zip[read]) * 4];
x_reg[1] = BCD[(ctoi(zip[read]) * 4) + 1];
x_reg[2] = BCD[(ctoi(zip[read]) * 4) + 2];
x_reg[3] = BCD[(ctoi(zip[read]) * 4) + 3];
for(i = 4; i < 112; i++) {
x_reg[i] = 0;
}
binary_add(accum, x_reg);
}
/* add weight to routing code */
for(i = 0; i < 112; i++) {
x_reg[i] = accum[i];
}
if(strlen(zip) > 9) {
strcpy(zip_adder, "1000100001");
} else {
if(strlen(zip) > 5) {
strcpy(zip_adder, "100001");
} else {
if(strlen(zip) > 0) {
strcpy(zip_adder, "1");
} else {
strcpy(zip_adder, "0");
}
}
}
for(i = 0; i < 112; i++) {
accum[i] = 0;
}
for(read = 0; read < strlen(zip_adder); read++) {
for(i = 0; i < 112; i++) {
y_reg[i] = accum[i];
}
for(i = 0; i < 9; i++) {
binary_add(accum, y_reg);
}
y_reg[0] = BCD[ctoi(zip_adder[read]) * 4];
y_reg[1] = BCD[(ctoi(zip_adder[read]) * 4) + 1];
y_reg[2] = BCD[(ctoi(zip_adder[read]) * 4) + 2];
y_reg[3] = BCD[(ctoi(zip_adder[read]) * 4) + 3];
for(i = 4; i < 112; i++) {
y_reg[i] = 0;
}
binary_add(accum, y_reg);
}
binary_add(accum, x_reg);
/* tracking code */
/* multiply by 10 */
for(i = 0; i < 112; i++) {
y_reg[i] = accum[i];
}
for(i = 0; i < 9; i++) {
binary_add(accum, y_reg);
}
/* add first digit of tracker */
y_reg[0] = BCD[ctoi(tracker[0]) * 4];
y_reg[1] = BCD[(ctoi(tracker[0]) * 4) + 1];
y_reg[2] = BCD[(ctoi(tracker[0]) * 4) + 2];
y_reg[3] = BCD[(ctoi(tracker[0]) * 4) + 3];
for(i = 4; i < 112; i++) {
y_reg[i] = 0;
}
binary_add(accum, y_reg);
/* multiply by 5 */
for(i = 0; i < 112; i++) {
y_reg[i] = accum[i];
}
for(i = 0; i < 4; i++) {
binary_add(accum, y_reg);
}
/* add second digit */
y_reg[0] = BCD[ctoi(tracker[1]) * 4];
y_reg[1] = BCD[(ctoi(tracker[1]) * 4) + 1];
y_reg[2] = BCD[(ctoi(tracker[1]) * 4) + 2];
y_reg[3] = BCD[(ctoi(tracker[1]) * 4) + 3];
for(i = 4; i < 112; i++) {
y_reg[i] = 0;
}
binary_add(accum, y_reg);
/* and then the rest */
for(read = 2; read < strlen(tracker); read++) {
for(i = 0; i < 112; i++) {
y_reg[i] = accum[i];
}
for(i = 0; i < 9; i++) {
binary_add(accum, y_reg);
}
y_reg[0] = BCD[ctoi(tracker[read]) * 4];
y_reg[1] = BCD[(ctoi(tracker[read]) * 4) + 1];
y_reg[2] = BCD[(ctoi(tracker[read]) * 4) + 2];
y_reg[3] = BCD[(ctoi(tracker[read]) * 4) + 3];
for(i = 4; i < 112; i++) {
y_reg[i] = 0;
}
binary_add(accum, y_reg);
}
/* printf("Binary data 1: ");
hex_dump(accum); */
/* *** Step 2 - Generation of 11-bit CRC on Binary Data *** */
accum[103] = 0;
accum[102] = 0;
strcpy(byte_array, "");
for(j = 0; j < 13; j++) {
i = 96 - (8 * j);
byte_array[j] = 0;
byte_array[j] += accum[i];
byte_array[j] += 2 * accum[i + 1];
byte_array[j] += 4 * accum[i + 2];
byte_array[j] += 8 * accum[i + 3];
byte_array[j] += 16 * accum[i + 4];
byte_array[j] += 32 * accum[i + 5];
byte_array[j] += 64 * accum[i + 6];
byte_array[j] += 128 * accum[i + 7];
}
usps_crc = USPS_MSB_Math_CRC11GenerateFrameCheckSequence(byte_array);
/* printf("FCS 2: %4.4X\n", usps_crc); */
/* *** Step 3 - Conversion from Binary Data to Codewords *** */
/* start with codeword J which is base 636 */
for(i = 0; i < 112; i++) {
x_reg[i] = 0;
y_reg[i] = 0;
}
x_reg[101] = 1;
x_reg[98] = 1;
x_reg[97] = 1;
x_reg[96] = 1;
x_reg[95] = 1;
x_reg[94] = 1;
for(i = 92; i >= 0; i--) {
y_reg[i] = islarger(accum, x_reg);
if(y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
}
codeword[9] = (accum[9] * 512) + (accum[8] * 256) + (accum[7] * 128) + (accum[6] * 64) +
(accum[5] * 32) + (accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) +
(accum[1] * 2) + accum[0];
/* then codewords I to B with base 1365 */
for(j = 8; j > 0; j--) {
for(i = 0; i < 112; i++) {
accum[i] = y_reg[i];
y_reg[i] = 0;
x_reg[i] = 0;
}
x_reg[101] = 1;
x_reg[99] = 1;
x_reg[97] = 1;
x_reg[95] = 1;
x_reg[93] = 1;
x_reg[91] = 1;
for(i = 91; i >= 0; i--) {
y_reg[i] = islarger(accum, x_reg);
if(y_reg[i] == 1) {
binary_subtract(accum, x_reg);
}
shiftdown(x_reg);
}
codeword[j] = (accum[10] * 1024) + (accum[9] * 512) + (accum[8] * 256) +
(accum[7] * 128) + (accum[6] * 64) + (accum[5] * 32) +
(accum[4] * 16) + (accum[3] * 8) + (accum[2] * 4) +
(accum[1] * 2) + accum[0];
}
codeword[0] = (y_reg[10] * 1024) + (y_reg[9] * 512) + (y_reg[8] * 256) +
(y_reg[7] * 128) + (y_reg[6] * 64) + (y_reg[5] * 32) +
(y_reg[4] * 16) + (y_reg[3] * 8) + (y_reg[2] * 4) +
(y_reg[1] * 2) + y_reg[0];
/* printf("Codewords 3: ");
for(i = 0; i < 10; i++) {
printf("%d ", codeword[i]);
}
printf("\n"); */
/* *** Step 4 - Inserting Additional Information into Codewords *** */
codeword[9] = codeword[9] * 2;
if(usps_crc >= 1024) {
codeword[0] += 659;
}
/* printf("Codewords 4b: ");
for(i = 0; i < 10; i++) {
printf("%d ", codeword[i]);
}
printf("\n"); */
/* *** Step 5 - Conversion from Codewords to Characters *** */
for(i = 0; i < 10; i++) {
if(codeword[i] < 1287) {
characters[i] = AppxD_I[codeword[i]];
} else {
characters[i] = AppxD_II[codeword[i] - 1287];
}
}
/* printf("Characters 5a: ");
for(i = 0; i < 10; i++) {
printf("%4.4X ", characters[i]);
}
printf("\n"); */
breakup(bit_pattern, usps_crc);
for(i = 0; i < 10; i++) {
if(bit_pattern[i] == 1) {
characters[i] = 0x1FFF - characters[i];
}
}
/* printf("Characters 5b: ");
for(i = 0; i < 10; i++) {
printf("%4.4X ", characters[i]);
}
printf("\n"); */
/* *** Step 6 - Conversion from Characters to the Intelligent Mail Barcode *** */
for(i = 0; i < 10; i++) {
breakup(bit_pattern, characters[i]);
for(j = 0; j < 13; j++) {
bar_map[AppxD_IV[(13 * i) + j] - 1] = bit_pattern[j];
}
}
strcpy(data_pattern, "");
temp[1] = '\0';
for(i = 0; i < 65; i++) {
j = 0;
if(bar_map[i] == 0)
j += 1;
if(bar_map[i + 65] == 0)
j += 2;
temp[0] = itoc(j);
concat(data_pattern, temp);
}
/* Translate 4-state data pattern to symbol */
read = 0;
for(i = 0; i < strlen(data_pattern); i++)
{
if((data_pattern[i] == '1') || (data_pattern[i] == '0'))
{
symbol->encoded_data[0][read] = '1';
}
symbol->encoded_data[1][read] = '1';
if((data_pattern[i] == '2') || (data_pattern[i] == '0'))
{
symbol->encoded_data[2][read] = '1';
}
read += 2;
}
symbol->row_height[0] = 2;
symbol->row_height[1] = 2;
symbol->row_height[2] = 2;
symbol->rows = 3;
symbol->width = read - 1;
return errno;
}
+225
View File
@@ -0,0 +1,225 @@
/* large.c - Handles binary manipulation of large numbers */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <string.h>
static short int BCD[40] = {
0, 0, 0, 0,
1, 0, 0, 0,
0, 1, 0, 0,
1, 1, 0, 0,
0, 0, 1, 0,
1, 0, 1, 0,
0, 1, 1, 0,
1, 1, 1, 0,
0, 0, 0, 1,
1, 0, 0, 1 };
void binary_add(short int accumulator[], short int input_buffer[])
{ /* Binary addition */
int i, carry, done;
carry = 0;
for(i = 0; i < 112; i++) {
done = 0;
if(((input_buffer[i] == 0) && (accumulator[i] == 0)) && ((carry == 0) && (done == 0))) {
accumulator[i] = 0;
carry = 0;
done = 1;
}
if(((input_buffer[i] == 0) && (accumulator[i] == 0)) && ((carry == 1) && (done == 0))) {
accumulator[i] = 1;
carry = 0;
done = 1;
}
if(((input_buffer[i] == 0) && (accumulator[i] == 1)) && ((carry == 0) && (done == 0))) {
accumulator[i] = 1;
carry = 0;
done = 1;
}
if(((input_buffer[i] == 0) && (accumulator[i] == 1)) && ((carry == 1) && (done == 0))) {
accumulator[i] = 0;
carry = 1;
done = 1;
}
if(((input_buffer[i] == 1) && (accumulator[i] == 0)) && ((carry == 0) && (done == 0))) {
accumulator[i] = 1;
carry = 0;
done = 1;
}
if(((input_buffer[i] == 1) && (accumulator[i] == 0)) && ((carry == 1) && (done == 0))) {
accumulator[i] = 0;
carry = 1;
done = 1;
}
if(((input_buffer[i] == 1) && (accumulator[i] == 1)) && ((carry == 0) && (done == 0))) {
accumulator[i] = 0;
carry = 1;
done = 1;
}
if(((input_buffer[i] == 1) && (accumulator[i] == 1)) && ((carry == 1) && (done == 0))) {
accumulator[i] = 1;
carry = 1;
done = 1;
}
}
}
void binary_subtract(short int accumulator[], short int input_buffer[])
{ /* 2's compliment subtraction */
/* take input_buffer from accumulator and put answer in accumulator */
int i;
short int sub_buffer[112];
for(i = 0; i < 112; i++) {
if(input_buffer[i] == 0) {
sub_buffer[i] = 1;
} else {
sub_buffer[i] = 0;
}
}
binary_add(accumulator, sub_buffer);
sub_buffer[0] = 1;
for(i = 1; i < 112; i++) {
sub_buffer[i] = 0;
}
binary_add(accumulator, sub_buffer);
}
void shiftdown(short int buffer[])
{
int i;
buffer[102] = 0;
buffer[103] = 0;
for(i = 0; i < 102; i++) {
buffer[i] = buffer[i + 1];
}
}
void shiftup(short int buffer[])
{
int i;
for(i = 102; i > 0; i--) {
buffer[i] = buffer[i - 1];
}
buffer[0] = 0;
}
short int islarger(short int accum[], short int reg[])
{
/* Returns 1 if accum[] is larger than reg[], else 0 */
int i, latch, larger;
latch = 0;
i = 103;
larger = 0;
do {
if((accum[i] == 1) && (reg[i] == 0)) {
latch = 1;
larger = 1;
}
if((accum[i] == 0) && (reg[i] == 1)) {
latch = 1;
}
i--;
} while ((latch == 0) && (i >= -1));
return larger;
}
void binary_load(short int reg[], char data[])
{
int read, i;
short int temp[112];
for(i = 0; i < 112; i++) {
reg[i] = 0;
}
for(read = 0; read < strlen(data); read++) {
for(i = 0; i < 112; i++) {
temp[i] = reg[i];
}
for(i = 0; i < 9; i++) {
binary_add(reg, temp);
}
temp[0] = BCD[ctoi(data[read]) * 4];
temp[1] = BCD[(ctoi(data[read]) * 4) + 1];
temp[2] = BCD[(ctoi(data[read]) * 4) + 2];
temp[3] = BCD[(ctoi(data[read]) * 4) + 3];
for(i = 4; i < 112; i++) {
temp[i] = 0;
}
binary_add(reg, temp);
}
}
void hex_dump(short int input_buffer[])
{
int i, digit, byte_space;
byte_space = 1;
for(i = 100; i >= 0; i-=4) {
digit = 0;
digit += 1 * input_buffer[i];
digit += 2 * input_buffer[i + 1];
digit += 4 * input_buffer[i + 2];
digit += 8 * input_buffer[i + 3];
switch(digit) {
case 0: printf("0"); break;
case 1: printf("1"); break;
case 2: printf("2"); break;
case 3: printf("3"); break;
case 4: printf("4"); break;
case 5: printf("5"); break;
case 6: printf("6"); break;
case 7: printf("7"); break;
case 8: printf("8"); break;
case 9: printf("9"); break;
case 10: printf("A"); break;
case 11: printf("B"); break;
case 12: printf("C"); break;
case 13: printf("D"); break;
case 14: printf("E"); break;
case 15: printf("F"); break;
}
if(byte_space == 1) {
byte_space = 0;
} else {
byte_space = 1;
printf(" ");
}
}
printf("\n");
}
+42
View File
@@ -0,0 +1,42 @@
/* large.h - Handles binary manipulation of large numbers */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
static short int BCD[40] = {
0, 0, 0, 0,
1, 0, 0, 0,
0, 1, 0, 0,
1, 1, 0, 0,
0, 0, 1, 0,
1, 0, 1, 0,
0, 1, 1, 0,
1, 1, 1, 0,
0, 0, 0, 1,
1, 0, 0, 1 };
void binary_load(short int reg[], char data[]);
void binary_add(short int accumulator[], short int input_buffer[]);
void binary_subtract(short int accumulator[], short int input_buffer[]);
void shiftdown(short int buffer[]);
void shiftup(short int buffer[]);
short int islarger(short int accum[], short int reg[]);
void hex_dump(short int input_buffer[]);
+296
View File
@@ -0,0 +1,296 @@
/* library.c - external functions of libzint
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
struct zint_symbol *ZBarcode_Create()
{
struct zint_symbol *symbol;
int i, j;
symbol = malloc(sizeof(*symbol));
if (!symbol) return NULL;
memset(symbol, 0, sizeof(*symbol));
symbol->symbology = BARCODE_CODE128;
symbol->height = 0;
symbol->whitespace_width = 0;
symbol->border_width = 0;
symbol->output_options = 0;
symbol->rows = 0;
symbol->width = 0;
strcpy(symbol->fgcolour, "000000");
strcpy(symbol->bgcolour, "ffffff");
strcpy(symbol->outfile, "out.png");
symbol->option_1 = -1;
symbol->option_2 = 0;
strcpy(symbol->primary, "");
for(i = 0; i < 90; i++) {
for(j = 0; j < 1000; j++) {
symbol->encoded_data[i][j] = '0';
}
symbol->row_height[i] = 0;
}
return symbol;
}
int ZBarcode_Delete(struct zint_symbol *symbol)
{
free(symbol);
return 0;
}
extern int eanx(struct zint_symbol *symbol, unsigned char source[]); /* EAN system barcodes */
extern int c39(struct zint_symbol *symbol, unsigned char source[]); /* Code 3 from 9 (or Code 39) */
extern int pharmazentral(struct zint_symbol *symbol, unsigned char source[]); /* Pharmazentral Nummer (PZN) */
extern int ec39(struct zint_symbol *symbol, unsigned char source[]); /* Extended Code 3 from 9 (or Code 39+) */
extern int codabar(struct zint_symbol *symbol, unsigned char source[]); /* Codabar - a simple substitution cipher */
extern int matrix_two_of_five(struct zint_symbol *symbol, unsigned char source[]); /* Code 2 of 5 Standard (& Matrix) */
extern int industrial_two_of_five(struct zint_symbol *symbol, unsigned char source[]); /* Code 2 of 5 Industrial */
extern int iata_two_of_five(struct zint_symbol *symbol, unsigned char source[]); /* Code 2 of 5 IATA */
extern int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[]); /* Code 2 of 5 Interleaved */
extern int logic_two_of_five(struct zint_symbol *symbol, unsigned char source[]); /* Code 2 of 5 Data Logic */
extern int itf14(struct zint_symbol *symbol, unsigned char source[]); /* ITF-14 */
extern int dpleit(struct zint_symbol *symbol, unsigned char source[]); /* Deutsche Post Leitcode */
extern int dpident(struct zint_symbol *symbol, unsigned char source[]); /* Deutsche Post Identcode */
extern int c93(struct zint_symbol *symbol, unsigned char source[]); /* Code 93 - a re-working of Code 39+, generates 2 check digits */
extern int code_128(struct zint_symbol *symbol, unsigned char source[]); /* Code 128 and NVE-18 */
extern int ean_128(struct zint_symbol *symbol, unsigned char source[]); /* EAN-128 (GS1-128) */
extern int code_11(struct zint_symbol *symbol, unsigned char source[]); /* Code 11 */
extern int msi_plessey(struct zint_symbol *symbol, unsigned char source[]); /* MSI Plessey without check digit */
extern int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[]); /* MSI with check as on Barcode Island */
extern int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[]); /* MSI with two checks as Barcode Island */
extern int msi_plessey_mod11(struct zint_symbol *symbol, unsigned char source[]); /* MSI with Mod 11 check as Wikipedia */
extern int msi_plessey_mod1110(struct zint_symbol *symbol, unsigned char source[]); /* MSI with Mod 11 and Mod 10 */
extern int telepen(struct zint_symbol *symbol, unsigned char source[]); /* Telepen ASCII */
extern int telepen_num(struct zint_symbol *symbol, unsigned char source[]); /* Telepen Numeric */
extern int plessey(struct zint_symbol *symbol, unsigned char source[]); /* Plessey Code */
extern int pharma_one(struct zint_symbol *symbol, unsigned char source[]); /* Pharmacode One Track */
/* extern int korea(struct zint_symbol *symbol, unsigned char source[]); */
extern int flattermarken(struct zint_symbol *symbol, unsigned char source[]); /* Flattermarken */
extern int fim(struct zint_symbol *symbol, unsigned char source[]); /* Facing Identification Mark */
extern int pharma_two(struct zint_symbol *symbol, unsigned char source[]); /* Pharmacode Two Track */
extern int post_plot(struct zint_symbol *symbol, unsigned char source[]); /* Postnet */
extern int planet_plot(struct zint_symbol *symbol, unsigned char source[]); /* PLANET */
extern int imail(struct zint_symbol *symbol, unsigned char source[]); /* Intelligent Mail (aka USPS OneCode) */
extern int royal_plot(struct zint_symbol *symbol, unsigned char source[]); /* RM4SCC */
extern int australia_post(struct zint_symbol *symbol, unsigned char source[]); /* Australia Post 4-state */
extern int code16k(struct zint_symbol *symbol, unsigned char source[]); /* Code 16k */
extern int pdf417enc(struct zint_symbol *symbol, unsigned char source[]); /* PDF417 */
extern int dmatrix(struct zint_symbol *symbol, unsigned char source[]); /* Data Matrix (IEC16022) */
extern int qr_code(struct zint_symbol *symbol, unsigned char source[]); /* QR Code */
extern int micro_pdf417(struct zint_symbol *symbol, unsigned char source[]); /* Micro PDF417 */
extern int maxicode(struct zint_symbol *symbol, unsigned char source[]); /* Maxicode */
extern int rss14(struct zint_symbol *symbol, unsigned char source[]); /* RSS-14 */
extern int rsslimited(struct zint_symbol *symbol, unsigned char source[]); /* RSS Limited */
extern int rssexpanded(struct zint_symbol *symbol, unsigned char source[]); /* RSS Expanded */
extern int composite(struct zint_symbol *symbol, unsigned char source[]); /* Composite Symbology */
/* extern int aztec_mesa(struct zint_symbol *symbol, unsigned char source[]); */
/* extern int ultra_sample(struct zint_symbol *symbol, unsigned char source[]); */
extern int png_plot(struct zint_symbol *symbol);
extern int ps_plot(struct zint_symbol *symbol);
int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *input)
{
int errno;
errno = 0;
/* First check the symbology field */
if(symbol->symbology < 1) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; errno = WARN_INVALID_OPTION; }
/* symbol->symbologys 1 to 86 are defined by tbarcode */
if(symbol->symbology == 5) { symbol->symbology = BARCODE_C25MATRIX; }
if((symbol->symbology >= 10) && (symbol->symbology <= 12)) { symbol->symbology = BARCODE_EANX; }
if((symbol->symbology == 14) || (symbol->symbology == 15)) { symbol->symbology = BARCODE_EANX; }
if(symbol->symbology == 17) { symbol->symbology = BARCODE_UPCA; }
if(symbol->symbology == 19) { strcpy(symbol->errtxt, "Codabar 18 not supported, using Codabar"); symbol->symbology = BARCODE_CODABAR; errno = WARN_INVALID_OPTION; }
if(symbol->symbology == 24) { strcpy(symbol->errtxt, "Code 49 not supported, using Code 93"); symbol->symbology = BARCODE_CODE93; errno = WARN_INVALID_OPTION; }
if(symbol->symbology == 26) { symbol->symbology = BARCODE_UPCA; }
if(symbol->symbology == 27) { strcpy(symbol->errtxt, "UPCD1 not supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology == 33) { symbol->symbology = BARCODE_EAN128; }
if((symbol->symbology == 35) || (symbol->symbology == 36)) { symbol->symbology = BARCODE_UPCA; }
if((symbol->symbology == 38) || (symbol->symbology == 39)) { symbol->symbology = BARCODE_UPCE; }
if((symbol->symbology >= 41) && (symbol->symbology <= 45)) { symbol->symbology = BARCODE_POSTNET; }
if(symbol->symbology == 46) { symbol->symbology = BARCODE_PLESSEY; }
if(symbol->symbology == 48) { symbol->symbology = BARCODE_NVE18; }
if(symbol->symbology == 54) { strcpy(symbol->errtxt, "General Parcel Code not supported, using Code 128"); symbol->symbology = BARCODE_CODE128; errno = WARN_INVALID_OPTION; }
if((symbol->symbology == 59) || (symbol->symbology == 61)) { symbol->symbology = BARCODE_CODE128; }
if(symbol->symbology == 62) { symbol->symbology = BARCODE_CODE93; }
if((symbol->symbology == 64) || (symbol->symbology == 65)) { symbol->symbology = BARCODE_AUSPOST; }
if(symbol->symbology == 73) { strcpy(symbol->errtxt, "Codablock E not supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology == 74) { strcpy(symbol->errtxt, "Codablock F not supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology == 76) { strcpy(symbol->errtxt, "Japanese Postal Code not supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology == 77) { strcpy(symbol->errtxt, "Korean Postal Code not supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology == 78) { symbol->symbology = BARCODE_RSS14; }
if(symbol->symbology == 83) { symbol->symbology = BARCODE_PLANET; }
/* leave a gap for future expansion of tbarcode */
if((symbol->symbology >= 87) && (symbol->symbology <= 99)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128\n"); symbol->symbology = BARCODE_CODE128; errno = WARN_INVALID_OPTION; }
/* Everything from 100 up is Zint-specific */
if(symbol->symbology == 107) { strcpy(symbol->errtxt, "Aztec Code not yet supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology == 108) { strcpy(symbol->errtxt, "Supercode not yet supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology == 109) { strcpy(symbol->errtxt, "Ultracode not yet supported"); errno = ERROR_INVALID_OPTION; }
if(symbol->symbology >= 120) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; errno = WARN_INVALID_OPTION; }
if(errno > 4) {
return errno;
}
if(symbol->symbology == BARCODE_CODE16K) {
symbol->whitespace_width = 16;
symbol->border_width = 2;
symbol->output_options = BARCODE_BIND;
}
if(symbol->symbology == BARCODE_ITF14) {
symbol->whitespace_width = 20;
symbol->border_width = 8;
symbol->output_options = BARCODE_BOX;
}
switch(symbol->symbology) {
case BARCODE_C25MATRIX: errno = matrix_two_of_five(symbol, input); break;
case BARCODE_C25IND: errno = industrial_two_of_five(symbol, input); break;
case BARCODE_C25INTER: errno = interleaved_two_of_five(symbol, input); break;
case BARCODE_C25IATA: errno = iata_two_of_five(symbol, input); break;
case BARCODE_C25LOGIC: errno = logic_two_of_five(symbol, input); break;
case BARCODE_DPLEIT: errno = dpleit(symbol, input); break;
case BARCODE_DPIDENT: errno = dpident(symbol, input); break;
case BARCODE_UPCA: errno = eanx(symbol, input); break;
case BARCODE_UPCE: errno = eanx(symbol, input); break;
case BARCODE_EANX: errno = eanx(symbol, input); break;
case BARCODE_EAN128: errno = ean_128(symbol, input); break;
case BARCODE_CODE39: errno = c39(symbol, input); break;
case BARCODE_PZN: errno = pharmazentral(symbol, input); break;
case BARCODE_EXCODE39: errno = ec39(symbol, input); break;
case BARCODE_CODABAR: errno = codabar(symbol, input); break;
case BARCODE_CODE93: errno = c93(symbol, input); break;
case BARCODE_LOGMARS: errno = c39(symbol, input); break;
case BARCODE_CODE128: errno = code_128(symbol, input); break;
case BARCODE_CODE128B: errno = code_128(symbol, input); break;
case BARCODE_NVE18: errno = code_128(symbol, input); break;
case BARCODE_CODE11: errno = code_11(symbol, input); break;
case BARCODE_MSI_PLESSEY: errno = msi_plessey(symbol, input); break;
case BARCODE_MSI_10: errno = msi_plessey_mod10(symbol, input); break;
case BARCODE_MSI_10_10: errno = msi_plessey_mod1010(symbol, input); break;
case BARCODE_MSI_11: errno = msi_plessey_mod11(symbol, input); break;
case BARCODE_MSI_11_10: errno = msi_plessey_mod1110(symbol, input); break;
case BARCODE_TELEPEN: errno = telepen(symbol, input); break;
case BARCODE_TELEPEN_NUM: errno = telepen_num(symbol, input); break;
case BARCODE_PHARMA: errno = pharma_one(symbol, input); break;
case BARCODE_PLESSEY: errno = plessey(symbol, input); break;
case BARCODE_ITF14: errno = itf14(symbol, input); break;
/* case BARCODE_KOREAPOST: errno = korea(symbol, input); break; */
case BARCODE_FLAT: errno = flattermarken(symbol, input); break;
case BARCODE_FIM: errno = fim(symbol, input); break;
case BARCODE_POSTNET: errno = post_plot(symbol, input); break;
case BARCODE_PLANET: errno = planet_plot(symbol, input); break;
case BARCODE_RM4SCC: errno = royal_plot(symbol, input); break;
case BARCODE_AUSPOST: errno = australia_post(symbol, input); break;
case BARCODE_AUSREPLY: errno = australia_post(symbol, input); break;
case BARCODE_AUSROUTE: errno = australia_post(symbol, input); break;
case BARCODE_AUSREDIRECT: errno = australia_post(symbol, input); break;
case BARCODE_CODE16K: errno = code16k(symbol, input); break;
case BARCODE_PHARMA_TWO: errno = pharma_two(symbol, input); break;
case BARCODE_ONECODE: errno = imail(symbol, input); break;
case BARCODE_DATAMATRIX: errno = dmatrix(symbol, input); break;
case BARCODE_PDF417: errno = pdf417enc(symbol, input); break;
case BARCODE_PDF417TRUNC: errno = pdf417enc(symbol, input); break;
case BARCODE_QRCODE: errno = qr_code(symbol, input); break;
case BARCODE_MICROPDF417: errno = micro_pdf417(symbol, input); break;
case BARCODE_ISBNX: errno = eanx(symbol, input); break;
case BARCODE_CODE39_43: errno = c39(symbol, input); break;
case BARCODE_EXCODE39_43: errno = ec39(symbol, input); break;
case BARCODE_MAXICODE: errno = maxicode(symbol, input); break;
case BARCODE_RSS14: errno = rss14(symbol, input); break;
case BARCODE_RSS14STACK: errno = rss14(symbol, input); break;
case BARCODE_RSS14STACK_OMNI: errno = rss14(symbol, input); break;
case BARCODE_RSS_LTD: errno = rsslimited(symbol, input); break;
case BARCODE_RSS_EXP: errno = rssexpanded(symbol, input); break;
case BARCODE_RSS_EXPSTACK: errno = rssexpanded(symbol, input); break;
case BARCODE_EANX_CC: errno = composite(symbol, input); break;
case BARCODE_EAN128_CC: errno = composite(symbol, input); break;
case BARCODE_RSS14_CC: errno = composite(symbol, input); break;
case BARCODE_RSS_LTD_CC: errno = composite(symbol, input); break;
case BARCODE_RSS_EXP_CC: errno = composite(symbol, input); break;
case BARCODE_UPCA_CC: errno = composite(symbol, input); break;
case BARCODE_UPCE_CC: errno = composite(symbol, input); break;
case BARCODE_RSS14STACK_CC: errno = composite(symbol, input); break;
case BARCODE_RSS14_OMNI_CC: errno = composite(symbol, input); break;
case BARCODE_RSS_EXPSTACK_CC: errno = composite(symbol, input); break;
/* case BARCODE_AZTEC: errno = aztec_mesa(symbol, input); break; */
/* case BARCODE_ULTRA: errno = ultra(symbol, input); break; */
}
return errno;
}
int ZBarcode_Print(struct zint_symbol *symbol)
{
int errno;
char output[4];
if(strlen(symbol->outfile) > 3) {
output[0] = symbol->outfile[strlen(symbol->outfile) - 3];
output[1] = symbol->outfile[strlen(symbol->outfile) - 2];
output[2] = symbol->outfile[strlen(symbol->outfile) - 1];
output[3] = '\0';
to_upper(output);
if(!(strcmp(output, "PNG"))) {
if(symbol->symbology == BARCODE_MAXICODE) {
errno = maxi_png_plot(symbol);
} else {
errno = png_plot(symbol);
}
} else {
if(!(strcmp(output, "EPS"))) {
errno = ps_plot(symbol);
} else {
strcpy(symbol->errtxt, "error: unknown output format");
return ERROR_INVALID_OPTION;
}
}
} else {
strcpy(symbol->errtxt, "error: unknown output format");
return ERROR_INVALID_OPTION;
}
return errno;
}
int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input)
{
int errno;
errno = 0;
errno = ZBarcode_Encode(symbol, input);
if(errno != 0) {
return errno;
}
errno = ZBarcode_Print(symbol);
return errno;
}
+681
View File
@@ -0,0 +1,681 @@
/* maxicode.c - Handles Maxicode */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* This code has been thoroughly checked against ISO/IEC 16023:2000 */
#include "common.h"
#include "maxicode.h"
#include "reedsol.h"
#include <string.h>
int maxi_codeword[144];
void maxi_do_primary_check( )
{
/* Handles error correction of primary message */
char data[15];
char results[15];
int j;
int datalen = 10;
int ecclen = 10;
rs_init_gf(0x43);
rs_init_code(ecclen, 1);
for(j = 0; j < datalen; j += 1)
data[j] = maxi_codeword[j];
rs_encode(datalen, data, results);
for ( j = 0; j < ecclen; j += 1)
maxi_codeword[ datalen + j] = results[j];
}
void maxi_do_secondary_chk_odd( int ecclen )
{
/* Handles error correction of odd characters in secondary */
char data[100];
char results[30];
int j;
int datalen = 68;
rs_init_gf(0x43);
rs_init_code(ecclen, 1);
if (ecclen == 20)
datalen = 84;
for(j = 0; j < datalen; j += 1)
if ((j % 2) == 1) // odd
data[(j-1)/2] = maxi_codeword[j + 20];
rs_encode(datalen/2, data, results);
for ( j = 0; j < (ecclen); j += 1)
maxi_codeword[ datalen + (2 *j) + 1 + 20 ] = results[j];
}
void maxi_do_secondary_chk_even(int ecclen )
{
/* Handles error correction of even characters in secondary */
char data[100];
char results[30];
int j;
int datalen = 68;
if (ecclen == 20)
datalen = 84;
rs_init_gf(0x43);
rs_init_code(ecclen, 1);
for(j = 0; j < datalen + 1; j += 1)
if ((j % 2) == 0) // even
data[j/2] = maxi_codeword[j + 20];
rs_encode(datalen/2, data, results);
for ( j = 0; j < (ecclen); j += 1)
maxi_codeword[ datalen + (2 *j) + 20] = results[j];
}
int maxi_bump(int set[], int character[], int bump_posn)
{
/* Moves everything up so that a shift or latch can be inserted */
int i;
for(i = 143; i > bump_posn; i--) {
set[i] = set[i - 1];
character[i] = character[i - 1];
}
}
int maxi_text_process(int mode, unsigned char source[])
{
/* Format text according to Appendix A */
/* This code doesn't make use of [Lock in C], [Lock in D]
and [Lock in E] and so is not always the most efficient at
compressing data, but should suffice for most applications */
int set[144], character[144], i, j, done, count, length, current_set;
length = strlen(source);
if(length > 138) {
return ERROR_TOO_LONG;
}
for(i = 0; i < 144; i++) {
set[i] = -1;
character[i] = 0;
}
for (i = 0; i < length; i++) {
/* Look up characters in table from Appendix A - this gives
value and code set for most characters */
set[i] = maxiCodeSet[source[i]];
character[i] = maxiSymbolChar[source[i]];
}
/* If a character can be represented in more than one code set,
pick which version to use */
if(set[0] == 0) {
if(character[0] == 13) {
character[0] = 0;
}
set[0] = 1;
}
for(i = 1; i < length; i++) {
if(set[i] == 0) {
done = 0;
/* Special character */
if(character[i] == 13) {
/* Carriage Return */
if(set[i - 1] == 5) {
character[i] = 13;
set[i] = 5;
} else {
if((i != length - 1) && (set[i + 1] == 5)) {
character[i] = 13;
set[i] = 5;
} else {
character[i] = 0;
set[i] = 1;
}
}
done = 1;
}
if((character[i] == 28) && (done == 0)) {
/* FS */
if(set[i - 1] == 5) {
character[i] = 32;
set[i] = 5;
} else {
set[i] = set[i - 1];
}
done = 1;
}
if((character[i] == 29) && (done == 0)) {
/* GS */
if(set[i - 1] == 5) {
character[i] = 33;
set[i] = 5;
} else {
set[i] = set[i - 1];
}
done = 1;
}
if((character[i] == 30) && (done == 0)) {
/* RS */
if(set[i - 1] == 5) {
character[i] = 34;
set[i] = 5;
} else {
set[i] = set[i - 1];
}
done = 1;
}
if((character[i] == 32) && (done == 0)) {
/* Space */
if(set[i - 1] == 1) {
character[i] = 32;
set[i] = 1;
}
if(set[i - 1] == 2) {
character[i] = 47;
set[i] = 2;
}
if(set[i - 1] >= 3) {
if(i != length - 1) {
if(set[i + 1] == 1) {
character[i] = 32;
set[i] = 1;
}
if(set[i + 1] == 2) {
character[i] = 47;
set[i] = 2;
}
if(set[i + 1] >= 3) {
character[i] = 59;
set[i] = set[i - 1];
}
} else {
character[i] = 59;
set[i] = set[i - 1];
}
}
done = 1;
}
if((character[i] == 44) && (done == 0)) {
/* Comma */
if(set[i - 1] == 2) {
character[i] = 48;
set[i] = 2;
} else {
if((i != length - 1) && (set[i + 1] == 2)) {
character[i] = 48;
set[i] = 2;
} else {
set[i] = 1;
}
}
done = 1;
}
if((character[i] == 46) && (done == 0)) {
/* Full Stop */
if(set[i - 1] == 2) {
character[i] = 49;
set[i] = 2;
} else {
if((i != length - 1) && (set[i + 1] == 2)) {
character[i] = 49;
set[i] = 2;
} else {
set[i] = 1;
}
}
done = 1;
}
if((character[i] == 47) && (done == 0)) {
/* Slash */
if(set[i - 1] == 2) {
character[i] = 50;
set[i] = 2;
} else {
if((i != length - 1) && (set[i + 1] == 2)) {
character[i] = 50;
set[i] = 2;
} else {
set[i] = 1;
}
}
done = 1;
}
if((character[i] == 58) && (done == 0)) {
/* Colon */
if(set[i - 1] == 2) {
character[i] = 51;
set[i] = 2;
} else {
if((i != length - 1) && (set[i + 1] == 2)) {
character[i] = 51;
set[i] = 2;
} else {
set[i] = 1;
}
}
done = 1;
}
}
}
for(i = strlen(source); i < 144; i++) {
/* Add the padding */
if(set[length - 1] == 2) {
set[i] = 2;
} else {
set[i] = 1;
}
character[i] = 33;
}
/* Find candidates for number compression */
if((mode == 2) || (mode ==3)) { j = 0; } else { j = 9; }
/* Number compression not allowed in primary message */
count = 0;
for(i = j; i < 143; i++) {
if((set[i] == 1) && ((character[i] >= 48) && (character[i] <= 57))) {
/* Character is a number */
count++;
} else {
count = 0;
}
if(count == 9) {
/* Nine digits in a row can be compressed */
set[i] = 6;
set[i - 1] = 6;
set[i - 2] = 6;
set[i - 3] = 6;
set[i - 4] = 6;
set[i - 5] = 6;
set[i - 6] = 6;
set[i - 7] = 6;
set[i - 8] = 6;
count = 0;
}
}
/* Add shift and latch characters */
current_set = 1;
i = 0;
do {
if(set[i] != current_set) {
switch(set[i]) {
case 1:
if(set[i + 1] == 1) {
if(set[i + 2] == 1) {
if(set[i + 3] == 1) {
/* Latch A */
maxi_bump(set, character, i);
character[i] = 63;
current_set = 1;
length++;
} else {
/* 3 Shift A */
maxi_bump(set, character, i);
character[i] = 57;
length++;
i += 2;
}
} else {
/* 2 Shift A */
maxi_bump(set, character, i);
character[i] = 56;
length++;
i++;
}
} else {
/* Shift A */
maxi_bump(set, character, i);
character[i] = 59;
length++;
}
break;
case 2:
if(set[i + 1] == 2) {
/* Latch B */
maxi_bump(set, character, i);
character[i] = 63;
current_set = 2;
length++;
} else {
/* Shift B */
maxi_bump(set, character, i);
character[i] = 59;
length++;
}
break;
case 3:
/* Shift C */
maxi_bump(set, character, i);
character[i] = 60;
length++;
break;
case 4:
/* Shift D */
maxi_bump(set, character, i);
character[i] = 61;
length++;
break;
case 5:
/* Shift E */
maxi_bump(set, character, i);
character[i] = 62;
length++;
break;
case 6:
/* Number Compressed */
/* Do nothing */
break;
}
i++;
}
i++;
} while(i < 145);
/* Number compression has not been forgotten! - It's handled below */
i = 0;
do {
if (set[i] == 6) {
/* Number compression */
char substring[10];
int value;
for(j = 0; j < 10; j++) {
substring[j] = character[i + j];
}
substring[10] = '\0';
value = atoi(substring);
character[i] = 31; /* NS */
character[i + 1] = (value & 0x3f000000) >> 24;
character[i + 2] = (value & 0xfc0000) >> 18;
character[i + 3] = (value & 0x3f000) >> 12;
character[i + 4] = (value & 0xfc0) >> 6;
character[i + 5] = (value & 0x3f);
i += 6;
for(j = i; j < 140; j++) {
set[j] = set[j + 3];
character[j] = character[j + 3];
}
length -= 3;
} else {
i++;
}
} while (i <= 143);
if(((mode ==2) || (mode == 3)) && (length > 84)) {
return ERROR_TOO_LONG;
}
if(((mode == 4) || (mode == 6)) && (length > 93)) {
return ERROR_TOO_LONG;
}
if((mode == 5) && (length > 77)) {
return ERROR_TOO_LONG;
}
/* Copy the encoded text into the codeword array */
if((mode == 2) || (mode == 3)) {
for(i = 0; i < 84; i++) { /* secondary only */
maxi_codeword[i + 20] = character[i];
}
}
if((mode == 4) || (mode == 6)) {
for(i = 0; i < 9; i++) { /* primary */
maxi_codeword[i + 1] = character[i];
}
for(i = 0; i < 84; i++) { /* secondary */
maxi_codeword[i + 20] = character[i + 9];
}
}
if(mode == 5) {
for(i = 0; i < 9; i++) { /* primary */
maxi_codeword[i + 1] = character[i];
}
for(i = 0; i < 68; i++) { /* secondary */
maxi_codeword[i + 20] = character[i + 9];
}
}
return 0;
}
void maxi_do_primary_2(char postcode[], int country, int service)
{
/* Format structured primary for Mode 2 */
int postcode_length, postcode_num, i;
for(i = 0; i < 10; i++) {
if((postcode[i] <= '0') || (postcode[i] >= '9')) {
postcode[i] = '\0';
}
}
postcode_length = strlen(postcode);
postcode_num = atoi(postcode);
maxi_codeword[0] = ((postcode_num & 0x03) << 4) | 2;
maxi_codeword[1] = ((postcode_num & 0xfc) >> 2);
maxi_codeword[2] = ((postcode_num & 0x3f00) >> 8);
maxi_codeword[3] = ((postcode_num & 0xfc000) >> 14);
maxi_codeword[4] = ((postcode_num & 0x3f00000) >> 20);
maxi_codeword[5] = ((postcode_num & 0x3c000000) >> 26) | ((postcode_length & 0x3) << 4);
maxi_codeword[6] = ((postcode_length & 0x3c) >> 2) | ((country & 0x3) << 4);
maxi_codeword[7] = (country & 0xfc) >> 2;
maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2);
maxi_codeword[9] = ((service & 0x3f0) >> 4);
}
void maxi_do_primary_3(char postcode[], int country, int service)
{
/* Format structured primary for Mode 3 */
int i;
to_upper(postcode);
for(i = 0; i < strlen(postcode); i++) {
if((postcode[i] >= 65) && (postcode[i] <= 90)) {
/* (Capital) letters shifted to Code Set A values */
postcode[i] = postcode[i] - 64;
}
if(((postcode[i] == 27) || (postcode[i] == 31)) || ((postcode[i] == 33) || (postcode[i] >= 59))) {
/* Not a valid postcode character */
postcode[i] = ' ';
}
/* Input characters lower than 27 (NUL - SUB) in postcode are
interpreted as capital letters in Code Set A (e.g. LF becomes 'J') */
}
maxi_codeword[0] = ((postcode[5] & 0x03) << 4) | 3;
maxi_codeword[1] = ((postcode[4] & 0x03) << 4) | ((postcode[5] & 0x3c) >> 2);
maxi_codeword[2] = ((postcode[3] & 0x03) << 4) | ((postcode[4] & 0x3c) >> 2);
maxi_codeword[3] = ((postcode[2] & 0x03) << 4) | ((postcode[3] & 0x3c) >> 2);
maxi_codeword[4] = ((postcode[1] & 0x03) << 4) | ((postcode[2] & 0x3c) >> 2);
maxi_codeword[5] = ((postcode[0] & 0x03) << 4) | ((postcode[1] & 0x3c) >> 2);
maxi_codeword[6] = ((postcode[0] & 0x3c) >> 2) | ((country & 0x3) << 4);
maxi_codeword[7] = (country & 0xfc) >> 2;
maxi_codeword[8] = ((country & 0x300) >> 8) | ((service & 0xf) << 2);
maxi_codeword[9] = ((service & 0x3f0) >> 4);
}
int maxicode(struct zint_symbol *symbol, unsigned char source[])
{
int i, j, block, bit, mode, countrycode = 0, service = 0;
int bit_pattern[7], internal_error = 0, eclen;
char postcode[12], countrystr[4], servicestr[4];
mode = symbol->option_1;
strcpy(postcode, "");
strcpy(countrystr, "");
strcpy(servicestr, "");
for(i = 0; i < 145; i++) {
maxi_codeword[i] = 0;
}
if(mode == -1) { /* If mode is unspecified */
if(strlen(symbol->primary) == 0) {
mode = 4;
} else {
mode = 2;
for(i = 0; i < 10; i++) {
if((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) {
mode = 3;
}
}
}
}
if((mode < 2) || (mode > 6)) { /* Only codes 2 to 6 supported */
strcpy(symbol->errtxt, "Error: Invalid Maxicode Mode");
return ERROR_INVALID_OPTION;
}
if((mode == 2) || (mode == 3)) { /* Modes 2 and 3 need data in symbol->primary */
if(strlen(symbol->primary) != 15) {
strcpy(symbol->errtxt, "Error: Invalid Primary String");
return ERROR_INVALID_DATA;
}
for(i = 9; i < 15; i++) { /* check that country code and service are numeric */
if((symbol->primary[i] < 48) || (symbol->primary[i] > 57)) {
strcpy(symbol->errtxt, "Error: Invalid Primary String");
return ERROR_INVALID_DATA;
}
}
strncpy(postcode, symbol->primary, 9);
postcode[9] = '\0';
if(mode == 2) {
for(i = 0; i < 10; i++) {
if(postcode[i] == ' ') {
postcode[i] = '\0';
}
}
}
if(mode == 3) { postcode[6] = '\0'; }
countrystr[0] = symbol->primary[9];
countrystr[1] = symbol->primary[10];
countrystr[2] = symbol->primary[11];
countrystr[3] = '\0';
servicestr[0] = symbol->primary[12];
servicestr[1] = symbol->primary[13];
servicestr[2] = symbol->primary[14];
servicestr[3] = '\0';
countrycode = atoi(countrystr);
service = atoi(servicestr);
if(mode == 2) { maxi_do_primary_2(postcode, countrycode, service); }
if(mode == 3) { maxi_do_primary_3(postcode, countrycode, service); }
} else {
maxi_codeword[0] = mode;
}
i = maxi_text_process(mode, source);
if(i == ERROR_TOO_LONG ) {
strcpy(symbol->errtxt, "Error: Input data too long");
return i;
}
/* All the data is sorted - now do error correction */
maxi_do_primary_check(); /* always EEC */
if ( mode == 5 )
eclen = 56; // 68 data codewords , 56 error corrections
else
eclen = 40; // 84 data codewords, 40 error corrections
maxi_do_secondary_chk_even(eclen/2); // do error correction of even
maxi_do_secondary_chk_odd(eclen/2); // do error correction of odd
/* Copy data into symbol grid */
for(i = 0; i < 33; i++) {
for(j = 0; j < 30; j++) {
symbol->encoded_data[i][j] = '0';
block = (MaxiGrid[(i * 30) + j] + 5) / 6;
bit = (MaxiGrid[(i * 30) + j] + 5) % 6;
if(block != 0) {
bit_pattern[0] = (maxi_codeword[block - 1] & 0x20) >> 5;
bit_pattern[1] = (maxi_codeword[block - 1] & 0x10) >> 4;
bit_pattern[2] = (maxi_codeword[block - 1] & 0x8) >> 3;
bit_pattern[3] = (maxi_codeword[block - 1] & 0x4) >> 2;
bit_pattern[4] = (maxi_codeword[block - 1] & 0x2) >> 1;
bit_pattern[5] = (maxi_codeword[block - 1] & 0x1);
if(bit_pattern[bit] != 0) {
symbol->encoded_data[i][j] = '1';
}
}
}
}
/* Add orientation markings */
symbol->encoded_data[0][28] = '1'; // Top right filler
symbol->encoded_data[0][29] = '1';
symbol->encoded_data[9][10] = '1'; // Top left marker
symbol->encoded_data[9][11] = '1';
symbol->encoded_data[10][11] = '1';
symbol->encoded_data[15][7] = '1'; // Left hand marker
symbol->encoded_data[16][8] = '1';
symbol->encoded_data[16][20] = '1'; // Right hand marker
symbol->encoded_data[17][20] = '1';
symbol->encoded_data[22][10] = '1'; // Bottom left marker
symbol->encoded_data[23][10] = '1';
symbol->encoded_data[22][17] = '1'; // Bottom right marker
symbol->encoded_data[23][17] = '1';
symbol->width = 30;
symbol->rows = 33;
return internal_error;
}
+90
View File
@@ -0,0 +1,90 @@
/* maxicode.h - Handles Maxicode */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
static int MaxiGrid[990] = { /* ISO/IEC 16023 Figure 5 - MaxiCode Module Sequence */
122, 121, 128, 127, 134, 133, 140, 139, 146, 145, 152, 151, 158, 157, 164, 163, 170, 169, 176, 175, 182, 181, 188, 187, 194, 193, 200, 199, 0, 0,
124, 123, 130, 129, 136, 135, 142, 141, 148, 147, 154, 153, 160, 159, 166, 165, 172, 171, 178, 177, 184, 183, 190, 189, 196, 195, 202, 201, 817, 0,
126, 125, 132, 131, 138, 137, 144, 143, 150, 149, 156, 155, 162, 161, 168, 167, 174, 173, 180, 179, 186, 185, 192, 191, 198, 197, 204, 203, 819, 818,
284, 283, 278, 277, 272, 271, 266, 265, 260, 259, 254, 253, 248, 247, 242, 241, 236, 235, 230, 229, 224, 223, 218, 217, 212, 211, 206, 205, 820, 0,
286, 285, 280, 279, 274, 273, 268, 267, 262, 261, 256, 255, 250, 249, 244, 243, 238, 237, 232, 231, 226, 225, 220, 219, 214, 213, 208, 207, 822, 821,
288, 287, 282, 281, 276, 275, 270, 269, 264, 263, 258, 257, 252, 251, 246, 245, 240, 239, 234, 233, 228, 227, 222, 221, 216, 215, 210, 209, 823, 0,
290, 289, 296, 295, 302, 301, 308, 307, 314, 313, 320, 319, 326, 325, 332, 331, 338, 337, 344, 343, 350, 349, 356, 355, 362, 361, 368, 367, 825, 824,
292, 291, 298, 297, 304, 303, 310, 309, 316, 315, 322, 321, 328, 327, 334, 333, 340, 339, 346, 345, 352, 351, 358, 357, 364, 363, 370, 369, 826, 0,
294, 293, 300, 299, 306, 305, 312, 311, 318, 317, 324, 323, 330, 329, 336, 335, 342, 341, 348, 347, 354, 353, 360, 359, 366, 365, 372, 371, 828, 827,
410, 409, 404, 403, 398, 397, 392, 391, 80, 79, 0, 0, 14, 13, 38, 37, 3, 0, 45, 44, 110, 109, 386, 385, 380, 379, 374, 373, 829, 0,
412, 411, 406, 405, 400, 399, 394, 393, 82, 81, 41, 0, 16, 15, 40, 39, 4, 0, 0, 46, 112, 111, 388, 387, 382, 381, 376, 375, 831, 830,
414, 413, 408, 407, 402, 401, 396, 395, 84, 83, 42, 0, 0, 0, 0, 0, 6, 5, 48, 47, 114, 113, 390, 389, 384, 383, 378, 377, 832, 0,
416, 415, 422, 421, 428, 427, 104, 103, 56, 55, 17, 0, 0, 0, 0, 0, 0, 0, 21, 20, 86, 85, 434, 433, 440, 439, 446, 445, 834, 833,
418, 417, 424, 423, 430, 429, 106, 105, 58, 57, 0, 0, 0, 0, 0, 0, 0, 0, 23, 22, 88, 87, 436, 435, 442, 441, 448, 447, 835, 0,
420, 419, 426, 425, 432, 431, 108, 107, 60, 59, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 90, 89, 438, 437, 444, 443, 450, 449, 837, 836,
482, 481, 476, 475, 470, 469, 49, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 54, 53, 464, 463, 458, 457, 452, 451, 838, 0,
484, 483, 478, 477, 472, 471, 50, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 466, 465, 460, 459, 454, 453, 840, 839,
486, 485, 480, 479, 474, 473, 52, 51, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 43, 468, 467, 462, 461, 456, 455, 841, 0,
488, 487, 494, 493, 500, 499, 98, 97, 62, 61, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 92, 91, 506, 505, 512, 511, 518, 517, 843, 842,
490, 489, 496, 495, 502, 501, 100, 99, 64, 63, 0, 0, 0, 0, 0, 0, 0, 0, 29, 28, 94, 93, 508, 507, 514, 513, 520, 519, 844, 0,
492, 491, 498, 497, 504, 503, 102, 101, 66, 65, 18, 0, 0, 0, 0, 0, 0, 0, 19, 30, 96, 95, 510, 509, 516, 515, 522, 521, 846, 845,
560, 559, 554, 553, 548, 547, 542, 541, 74, 73, 33, 0, 0, 0, 0, 0, 0, 11, 68, 67, 116, 115, 536, 535, 530, 529, 524, 523, 847, 0,
562, 561, 556, 555, 550, 549, 544, 543, 76, 75, 0, 0, 8, 7, 36, 35, 12, 0, 70, 69, 118, 117, 538, 537, 532, 531, 526, 525, 849, 848,
564, 563, 558, 557, 552, 551, 546, 545, 78, 77, 0, 34, 10, 9, 26, 25, 0, 0, 72, 71, 120, 119, 540, 539, 534, 533, 528, 527, 850, 0,
566, 565, 572, 571, 578, 577, 584, 583, 590, 589, 596, 595, 602, 601, 608, 607, 614, 613, 620, 619, 626, 625, 632, 631, 638, 637, 644, 643, 852, 851,
568, 567, 574, 573, 580, 579, 586, 585, 592, 591, 598, 597, 604, 603, 610, 609, 616, 615, 622, 621, 628, 627, 634, 633, 640, 639, 646, 645, 853, 0,
570, 569, 576, 575, 582, 581, 588, 587, 594, 593, 600, 599, 606, 605, 612, 611, 618, 617, 624, 623, 630, 629, 636, 635, 642, 641, 648, 647, 855, 854,
728, 727, 722, 721, 716, 715, 710, 709, 704, 703, 698, 697, 692, 691, 686, 685, 680, 679, 674, 673, 668, 667, 662, 661, 656, 655, 650, 649, 856, 0,
730, 729, 724, 723, 718, 717, 712, 711, 706, 705, 700, 699, 694, 693, 688, 687, 682, 681, 676, 675, 670, 669, 664, 663, 658, 657, 652, 651, 858, 857,
732, 731, 726, 725, 720, 719, 714, 713, 708, 707, 702, 701, 696, 695, 690, 689, 684, 683, 678, 677, 673, 671, 666, 665, 660, 659, 654, 653, 859, 0,
734, 733, 740, 739, 746, 745, 752, 751, 758, 757, 764, 763, 770, 769, 776, 775, 782, 781, 788, 787, 794, 793, 800, 799, 806, 805, 812, 811, 861, 860,
736, 735, 742, 741, 748, 747, 754, 753, 760, 759, 766, 765, 772, 771, 778, 777, 784, 783, 790, 789, 796, 795, 802, 801, 808, 807, 814, 813, 862, 0,
738, 737, 744, 743, 750, 749, 756, 755, 762, 761, 768, 767, 774, 773, 780, 779, 786, 785, 792, 791, 798, 797, 804, 803, 810, 809, 816, 815, 864, 863
};
int maxiCodeSet[256] = { /* from Appendix A - ASCII character to Code Set (e.g. 2 = Set B) */
/* set 0 refers to special characters that fit into more than one set (e.g. GS) */
5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 0, 5, 5, 5, 5, 5, 5,
5, 5, 5, 5, 5, 5, 5, 5, 0, 0, 0, 5, 0, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2,
2, 2, 2, 2, 2, 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, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
5, 4, 5, 5, 5, 5, 5, 5, 4, 5, 3, 4, 3, 5, 5, 4, 4, 3, 3, 3,
4, 3, 5, 4, 4, 3, 3, 4, 3, 3, 3, 4, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
};
int maxiSymbolChar[256] = { /* from Appendix A - ASCII character to symbol value */
0, 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, 30, 28, 29, 30, 35, 32, 53, 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, 37,
38, 39, 40, 41, 52, 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, 42, 43, 44, 45, 46, 0, 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, 32, 54, 34, 35, 36, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 47, 48,
49, 50, 51, 52, 53, 54, 55, 56, 57, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 36,
37, 37, 38, 39, 40, 41, 42, 43, 38, 44, 37, 39, 38, 45, 46, 40, 41, 39, 40, 41,
42, 42, 47, 43, 44, 43, 44, 45, 45, 46, 47, 46, 0, 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, 32,
33, 34, 35, 36, 0, 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, 32, 33, 34, 35, 36
};
+588
View File
@@ -0,0 +1,588 @@
/* maxipng.h - Shapes for Maxicode output to PNG file */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* This file contains the pixel-by-pixel representation of maxicode glyphs
at a resolution of 12 pixels per millimeter. hexagon[] is taken directly
from ISO 16023 Annex J. bullseye[] was calculated by the Gimp */
#define SSET "0123456789ABCDEF"
static int hexagon[120] = {
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 1, 1, 1, 1, 1, 1, 1, 1, 1,
0, 0, 1, 1, 1, 1, 1, 1, 1, 0,
0, 0, 0, 1, 1, 1, 1, 1, 0, 0,
0, 0, 0, 0, 1, 1, 1, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};
static char bullseye[34532] =
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````````````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````````"
"````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````"
"````````````````````````````````````````````````````````````````"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````"
"````````````````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
"!!!!````````````````````````````````````````````````````````````"
"````````````````````````````````````````````````````````````````"
"````````````````````````````````````";
+237
View File
@@ -0,0 +1,237 @@
/* medical.c - Handles 1 track and 2 track pharmacode and Codabar */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
/* Codabar table checked against EN 798:1995 */
#define CASET "0123456789-$:/.+ABCD"
static char *CodaTable[20] = {"11111221", "11112211", "11121121", "22111111", "11211211", "21111211",
"12111121", "12112111", "12211111", "21121111", "11122111", "11221111", "21112121", "21211121",
"21212111", "11212121", "11221211", "12121121", "11121221", "11122211"};
int pharma_one(struct zint_symbol *symbol, unsigned char source[])
{
/* "Pharmacode can represent only a single integer from 3 to 131070. Unlike other
commonly used one-dimensional barcode schemes, pharmacode does not store the data in a
form corresponding to the human-readable digits; the number is encoded in binary, rather
than decimal. Pharmacode is read from right to left: with n as the bar position starting
at 0 on the right, each narrow bar adds 2n to the value and each wide bar adds 2(2^n).
The minimum barcode is 2 bars and the maximum 16, so the smallest number that could
be encoded is 3 (2 narrow bars) and the biggest is 131070 (16 wide bars)."
- http://en.wikipedia.org/wiki/Pharmacode */
/* This code uses the One Track Pharamacode calculating algorithm as recommended by
the specification at http://www.laetus.com/laetus.php?request=file&id=69 */
unsigned long int tester;
int counter;
char inter[17];
int errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 6) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
strcpy(inter, "");
tester = atoi(source);
if((tester < 3) || (tester > 131070)) {
strcpy(symbol->errtxt, "error: data out of range");
return ERROR_INVALID_DATA;
}
do
{
if(tester%2 == 0) {
concat(inter, "W");
tester = (tester - 2) / 2;
} else {
concat(inter, "N");
tester = (tester - 1) / 2;
}
}
while(tester != 0);
for(counter = (strlen(inter) - 1); counter >= 0; counter--) {
if(inter[counter] == 'W') {
concat(dest, "32");
} else {
concat(dest, "12");
}
}
expand(symbol, dest);
strcpy(symbol->text, "");
return errno;
}
int pharma_two_calc(struct zint_symbol *symbol, unsigned char source[], char dest[])
{
/* This code uses the Two Track Pharamacode defined in the document at
http://www.laetus.com/laetus.php?request=file&id=69 and using a modified
algorithm from the One Track system. This standard accepts integet values
from 4 to 64570080. */
unsigned long int tester;
int counter;
char inter[17];
int errno;
errno = 0;
strcpy(dest, "");
strcpy(inter, "");
tester = atoi(source);
if((tester < 4) || (tester > 64570080))
{
strcpy(symbol->errtxt, "error: data out of range");
return ERROR_INVALID_DATA;
}
do
{
switch(tester%3) {
case 0:
concat(inter, "3");
tester = (tester - 3) / 3;
break;
case 1:
concat(inter, "1");
tester = (tester - 1) / 3;
break;
case 2:
concat(inter, "2");
tester = (tester - 2) / 3;
break;
}
}
while(tester != 0);
for(counter = (strlen(inter) - 1); counter >= 0; counter--)
{
dest[(strlen(inter) - 1) - counter] = inter[counter];
}
dest[strlen(inter)] = '\0';
return errno;
}
int pharma_two(struct zint_symbol *symbol, unsigned char source[])
{
/* Draws the patterns for two track pharmacode */
char height_pattern[200];
unsigned int loopey;
int writer;
int errno = 0;
strcpy(height_pattern, "");
if(strlen(source) > 8) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
errno = pharma_two_calc(symbol, source, height_pattern);
if(errno != 0) {
return errno;
}
writer = 0;
for(loopey = 0; loopey < strlen(height_pattern); loopey++)
{
if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '3'))
{
symbol->encoded_data[0][writer] = '1';
}
if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '3'))
{
symbol->encoded_data[1][writer] = '1';
}
writer += 2;
}
symbol->rows = 2;
symbol->width = writer - 1;
strcpy(symbol->text, "");
return errno;
}
int codabar(struct zint_symbol *symbol, unsigned char source[])
{ /* The Codabar system consisting of simple substitution */
int i, errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 60) { /* No stack smashing please */
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
to_upper(source);
errno = is_sane(CASET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* Codabar must begin and end with the characters A, B, C or D */
if(((source[0] != 'A') && (source[0] != 'B')) &&
((source[0] != 'C') && (source[0] != 'D')))
{
strcpy(symbol->errtxt, "error: invalid characters in data");
return 6;
}
if(((source[strlen(source) - 1] != 'A') && (source[strlen(source) - 1] != 'B')) &&
((source[strlen(source) - 1] != 'C') && (source[strlen(source) - 1] != 'D')))
{
strcpy(symbol->errtxt, "error: invalid characters in data");
return 6;
}
for(i = 0; i <= strlen(source); i++)
{
lookup(CASET, CodaTable, source[i], dest);
}
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
+29
View File
@@ -0,0 +1,29 @@
/* no_qr.c Handlier if no QR Encode library is available */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include "common.h"
int qr_code(struct zint_symbol *symbol, unsigned char source[])
{
strcpy(symbol->errtxt, "error: QR Code library <qrencode> not available");
return ERROR_INVALID_OPTION;
}
+1039
View File
File diff suppressed because it is too large Load Diff
+454
View File
@@ -0,0 +1,454 @@
/* pdf417.h - PDF417 tables and coefficients */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart (zint@hotmail.co.uk)
Portions Copyright (C) 2004 Grandzebu
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* this file contains the character table, the pre-calculated coefficients and the
codeword patterns taken from lines 416 to 454 of pdf417.frm */
#define TRUE 1
#define FALSE 0
#define TEX 900
#define BYT 901
#define NUM 902
#define PDF_MAX 928
#define BRSET "ABCDEFabcdefghijklmnopqrstuvwxyz*+-"
/* text mode processing tables */
static int asciix[95] = { 7, 8, 8, 4, 12, 4, 4, 8, 8, 8, 12, 4, 12, 12, 12, 12, 4, 4, 4, 4, 4, 4, 4, 4,
4, 4, 12, 8, 8, 4, 8, 8, 8, 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, 8, 8, 8, 4, 8, 8, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
2, 2, 2, 2, 8, 8, 8, 8 };
static int asciiy[95] = { 26, 10, 20, 15, 18, 21, 10, 28, 23, 24, 22, 20, 13, 16, 17, 19, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 14, 0, 1, 23, 2, 25, 3, 0, 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, 4, 5, 6, 24, 7, 8, 0, 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, 21, 27, 9 };
/* PDF417 error correction coefficients from Grand Zebu */
static int coefrs[1022] = {
/* k = 2 */
27, 917,
/* k = 4 */
522, 568, 723, 809,
/* k = 8 */
237, 308, 436, 284, 646, 653, 428, 379,
/* k = 16 */
274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
/* k = 32 */
361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517,
273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
/* k = 64 */
539, 422, 6, 93, 862, 771, 453, 106, 610, 287, 107, 505, 733, 877, 381, 612,
723, 476, 462, 172, 430, 609, 858, 822, 543, 376, 511, 400, 672, 762, 283, 184,
440, 35, 519, 31, 460, 594, 225, 535, 517, 352, 605, 158, 651, 201, 488, 502,
648, 733, 717, 83, 404, 97, 280, 771, 840, 629, 4, 381, 843, 623, 264, 543,
/* k = 128 */
521, 310, 864, 547, 858, 580, 296, 379, 53, 779, 897, 444, 400, 925, 749, 415,
822, 93, 217, 208, 928, 244, 583, 620, 246, 148, 447, 631, 292, 908, 490, 704,
516, 258, 457, 907, 594, 723, 674, 292, 272, 96, 684, 432, 686, 606, 860, 569,
193, 219, 129, 186, 236, 287, 192, 775, 278, 173, 40, 379, 712, 463, 646, 776,
171, 491, 297, 763, 156, 732, 95, 270, 447, 90, 507, 48, 228, 821, 808, 898,
784, 663, 627, 378, 382, 262, 380, 602, 754, 336, 89, 614, 87, 432, 670, 616,
157, 374, 242, 726, 600, 269, 375, 898, 845, 454, 354, 130, 814, 587, 804, 34,
211, 330, 539, 297, 827, 865, 37, 517, 834, 315, 550, 86, 801, 4, 108, 539,
/* k = 256 */
524, 894, 75, 766, 882, 857, 74, 204, 82, 586, 708, 250, 905, 786, 138, 720,
858, 194, 311, 913, 275, 190, 375, 850, 438, 733, 194, 280, 201, 280, 828, 757,
710, 814, 919, 89, 68, 569, 11, 204, 796, 605, 540, 913, 801, 700, 799, 137,
439, 418, 592, 668, 353, 859, 370, 694, 325, 240, 216, 257, 284, 549, 209, 884,
315, 70, 329, 793, 490, 274, 877, 162, 749, 812, 684, 461, 334, 376, 849, 521,
307, 291, 803, 712, 19, 358, 399, 908, 103, 511, 51, 8, 517, 225, 289, 470,
637, 731, 66, 255, 917, 269, 463, 830, 730, 433, 848, 585, 136, 538, 906, 90,
2, 290, 743, 199, 655, 903, 329, 49, 802, 580, 355, 588, 188, 462, 10, 134,
628, 320, 479, 130, 739, 71, 263, 318, 374, 601, 192, 605, 142, 673, 687, 234,
722, 384, 177, 752, 607, 640, 455, 193, 689, 707, 805, 641, 48, 60, 732, 621,
895, 544, 261, 852, 655, 309, 697, 755, 756, 60, 231, 773, 434, 421, 726, 528,
503, 118, 49, 795, 32, 144, 500, 238, 836, 394, 280, 566, 319, 9, 647, 550,
73, 914, 342, 126, 32, 681, 331, 792, 620, 60, 609, 441, 180, 791, 893, 754,
605, 383, 228, 749, 760, 213, 54, 297, 134, 54, 834, 299, 922, 191, 910, 532,
609, 829, 189, 20, 167, 29, 872, 449, 83, 402, 41, 656, 505, 579, 481, 173,
404, 251, 688, 95, 497, 555, 642, 543, 307, 159, 924, 558, 648, 55, 497, 10,
/* k = 512 */
352, 77, 373, 504, 35, 599, 428, 207, 409, 574, 118, 498, 285, 380, 350, 492,
197, 265, 920, 155, 914, 299, 229, 643, 294, 871, 306, 88, 87, 193, 352, 781,
846, 75, 327, 520, 435, 543, 203, 666, 249, 346, 781, 621, 640, 268, 794, 534,
539, 781, 408, 390, 644, 102, 476, 499, 290, 632, 545, 37, 858, 916, 552, 41,
542, 289, 122, 272, 383, 800, 485, 98, 752, 472, 761, 107, 784, 860, 658, 741,
290, 204, 681, 407, 855, 85, 99, 62, 482, 180, 20, 297, 451, 593, 913, 142,
808, 684, 287, 536, 561, 76, 653, 899, 729, 567, 744, 390, 513, 192, 516, 258,
240, 518, 794, 395, 768, 848, 51, 610, 384, 168, 190, 826, 328, 596, 786, 303,
570, 381, 415, 641, 156, 237, 151, 429, 531, 207, 676, 710, 89, 168, 304, 402,
40, 708, 575, 162, 864, 229, 65, 861, 841, 512, 164, 477, 221, 92, 358, 785,
288, 357, 850, 836, 827, 736, 707, 94, 8, 494, 114, 521, 2, 499, 851, 543,
152, 729, 771, 95, 248, 361, 578, 323, 856, 797, 289, 51, 684, 466, 533, 820,
669, 45, 902, 452, 167, 342, 244, 173, 35, 463, 651, 51, 699, 591, 452, 578,
37, 124, 298, 332, 552, 43, 427, 119, 662, 777, 475, 850, 764, 364, 578, 911,
283, 711, 472, 420, 245, 288, 594, 394, 511, 327, 589, 777, 699, 688, 43, 408,
842, 383, 721, 521, 560, 644, 714, 559, 62, 145, 873, 663, 713, 159, 672, 729,
624, 59, 193, 417, 158, 209, 563, 564, 343, 693, 109, 608, 563, 365, 181, 772,
677, 310, 248, 353, 708, 410, 579, 870, 617, 841, 632, 860, 289, 536, 35, 777,
618, 586, 424, 833, 77, 597, 346, 269, 757, 632, 695, 751, 331, 247, 184, 45,
787, 680, 18, 66, 407, 369, 54, 492, 228, 613, 830, 922, 437, 519, 644, 905,
789, 420, 305, 441, 207, 300, 892, 827, 141, 537, 381, 662, 513, 56, 252, 341,
242, 797, 838, 837, 720, 224, 307, 631, 61, 87, 560, 310, 756, 665, 397, 808,
851, 309, 473, 795, 378, 31, 647, 915, 459, 806, 590, 731, 425, 216, 548, 249,
321, 881, 699, 535, 673, 782, 210, 815, 905, 303, 843, 922, 281, 73, 469, 791,
660, 162, 498, 308, 155, 422, 907, 817, 187, 62, 16, 425, 535, 336, 286, 437,
375, 273, 610, 296, 183, 923, 116, 667, 751, 353, 62, 366, 691, 379, 687, 842,
37, 357, 720, 742, 330, 5, 39, 923, 311, 424, 242, 749, 321, 54, 669, 316,
342, 299, 534, 105, 667, 488, 640, 672, 576, 540, 316, 486, 721, 610, 46, 656,
447, 171, 616, 464, 190, 531, 297, 321, 762, 752, 533, 175, 134, 14, 381, 433,
717, 45, 111, 20, 596, 284, 736, 138, 646, 411, 877, 669, 141, 919, 45, 780,
407, 164, 332, 899, 165, 726, 600, 325, 498, 655, 357, 752, 768, 223, 849, 647,
63, 310, 863, 251, 366, 304, 282, 738, 675, 410, 389, 244, 31, 121, 303, 263 };
static char *codagemc[2787] = { "urA", "xfs", "ypy", "unk", "xdw", "yoz", "pDA", "uls", "pBk", "eBA",
"pAs", "eAk", "prA", "uvs", "xhy", "pnk", "utw", "xgz", "fDA", "pls", "fBk", "frA", "pvs",
"uxy", "fnk", "ptw", "uwz", "fls", "psy", "fvs", "pxy", "ftw", "pwz", "fxy", "yrx", "ufk",
"xFw", "ymz", "onA", "uds", "xEy", "olk", "ucw", "dBA", "oks", "uci", "dAk", "okg", "dAc",
"ovk", "uhw", "xaz", "dnA", "ots", "ugy", "dlk", "osw", "ugj", "dks", "osi", "dvk", "oxw",
"uiz", "dts", "owy", "dsw", "owj", "dxw", "oyz", "dwy", "dwj", "ofA", "uFs", "xCy", "odk",
"uEw", "xCj", "clA", "ocs", "uEi", "ckk", "ocg", "ckc", "ckE", "cvA", "ohs", "uay", "ctk",
"ogw", "uaj", "css", "ogi", "csg", "csa", "cxs", "oiy", "cww", "oij", "cwi", "cyy", "oFk",
"uCw", "xBj", "cdA", "oEs", "uCi", "cck", "oEg", "uCb", "ccc", "oEa", "ccE", "oED", "chk",
"oaw", "uDj", "cgs", "oai", "cgg", "oab", "cga", "cgD", "obj", "cib", "cFA", "oCs", "uBi",
"cEk", "oCg", "uBb", "cEc", "oCa", "cEE", "oCD", "cEC", "cas", "cag", "caa", "cCk", "uAr",
"oBa", "oBD", "cCB", "tfk", "wpw", "yez", "mnA", "tds", "woy", "mlk", "tcw", "woj", "FBA",
"mks", "FAk", "mvk", "thw", "wqz", "FnA", "mts", "tgy", "Flk", "msw", "Fks", "Fkg", "Fvk",
"mxw", "tiz", "Fts", "mwy", "Fsw", "Fsi", "Fxw", "myz", "Fwy", "Fyz", "vfA", "xps", "yuy",
"vdk", "xow", "yuj", "qlA", "vcs", "xoi", "qkk", "vcg", "xob", "qkc", "vca", "mfA", "tFs",
"wmy", "qvA", "mdk", "tEw", "wmj", "qtk", "vgw", "xqj", "hlA", "Ekk", "mcg", "tEb", "hkk",
"qsg", "hkc", "EvA", "mhs", "tay", "hvA", "Etk", "mgw", "taj", "htk", "qww", "vij", "hss",
"Esg", "hsg", "Exs", "miy", "hxs", "Eww", "mij", "hww", "qyj", "hwi", "Eyy", "hyy", "Eyj",
"hyj", "vFk", "xmw", "ytj", "qdA", "vEs", "xmi", "qck", "vEg", "xmb", "qcc", "vEa", "qcE",
"qcC", "mFk", "tCw", "wlj", "qhk", "mEs", "tCi", "gtA", "Eck", "vai", "tCb", "gsk", "Ecc",
"mEa", "gsc", "qga", "mED", "EcC", "Ehk", "maw", "tDj", "gxk", "Egs", "mai", "gws", "qii",
"mab", "gwg", "Ega", "EgD", "Eiw", "mbj", "gyw", "Eii", "gyi", "Eib", "gyb", "gzj", "qFA",
"vCs", "xli", "qEk", "vCg", "xlb", "qEc", "vCa", "qEE", "vCD", "qEC", "qEB", "EFA", "mCs",
"tBi", "ghA", "EEk", "mCg", "tBb", "ggk", "qag", "vDb", "ggc", "EEE", "mCD", "ggE", "qaD",
"ggC", "Eas", "mDi", "gis", "Eag", "mDb", "gig", "qbb", "gia", "EaD", "giD", "gji", "gjb",
"qCk", "vBg", "xkr", "qCc", "vBa", "qCE", "vBD", "qCC", "qCB", "ECk", "mBg", "tAr", "gak",
"ECc", "mBa", "gac", "qDa", "mBD", "gaE", "ECC", "gaC", "ECB", "EDg", "gbg", "gba", "gbD",
"vAq", "vAn", "qBB", "mAq", "EBE", "gDE", "gDC", "gDB", "lfA", "sps", "wey", "ldk", "sow",
"ClA", "lcs", "soi", "Ckk", "lcg", "Ckc", "CkE", "CvA", "lhs", "sqy", "Ctk", "lgw", "sqj",
"Css", "lgi", "Csg", "Csa", "Cxs", "liy", "Cww", "lij", "Cwi", "Cyy", "Cyj", "tpk", "wuw",
"yhj", "ndA", "tos", "wui", "nck", "tog", "wub", "ncc", "toa", "ncE", "toD", "lFk", "smw",
"wdj", "nhk", "lEs", "smi", "atA", "Cck", "tqi", "smb", "ask", "ngg", "lEa", "asc", "CcE",
"asE", "Chk", "law", "snj", "axk", "Cgs", "trj", "aws", "nii", "lab", "awg", "Cga", "awa",
"Ciw", "lbj", "ayw", "Cii", "ayi", "Cib", "Cjj", "azj", "vpA", "xus", "yxi", "vok", "xug",
"yxb", "voc", "xua", "voE", "xuD", "voC", "nFA", "tms", "wti", "rhA", "nEk", "xvi", "wtb",
"rgk", "vqg", "xvb", "rgc", "nEE", "tmD", "rgE", "vqD", "nEB", "CFA", "lCs", "sli", "ahA",
"CEk", "lCg", "slb", "ixA", "agk", "nag", "tnb", "iwk", "rig", "vrb", "lCD", "iwc", "agE",
"naD", "iwE", "CEB", "Cas", "lDi", "ais", "Cag", "lDb", "iys", "aig", "nbb", "iyg", "rjb",
"CaD", "aiD", "Cbi", "aji", "Cbb", "izi", "ajb", "vmk", "xtg", "ywr", "vmc", "xta", "vmE",
"xtD", "vmC", "vmB", "nCk", "tlg", "wsr", "rak", "nCc", "xtr", "rac", "vna", "tlD", "raE",
"nCC", "raC", "nCB", "raB", "CCk", "lBg", "skr", "aak", "CCc", "lBa", "iik", "aac", "nDa",
"lBD", "iic", "rba", "CCC", "iiE", "aaC", "CCB", "aaB", "CDg", "lBr", "abg", "CDa", "ijg",
"aba", "CDD", "ija", "abD", "CDr", "ijr", "vlc", "xsq", "vlE", "xsn", "vlC", "vlB", "nBc",
"tkq", "rDc", "nBE", "tkn", "rDE", "vln", "rDC", "nBB", "rDB", "CBc", "lAq", "aDc", "CBE",
"lAn", "ibc", "aDE", "nBn", "ibE", "rDn", "CBB", "ibC", "aDB", "ibB", "aDq", "ibq", "ibn",
"xsf", "vkl", "tkf", "nAm", "nAl", "CAo", "aBo", "iDo", "CAl", "aBl", "kpk", "BdA", "kos",
"Bck", "kog", "seb", "Bcc", "koa", "BcE", "koD", "Bhk", "kqw", "sfj", "Bgs", "kqi", "Bgg",
"kqb", "Bga", "BgD", "Biw", "krj", "Bii", "Bib", "Bjj", "lpA", "sus", "whi", "lok", "sug",
"loc", "sua", "loE", "suD", "loC", "BFA", "kms", "sdi", "DhA", "BEk", "svi", "sdb", "Dgk",
"lqg", "svb", "Dgc", "BEE", "kmD", "DgE", "lqD", "BEB", "Bas", "kni", "Dis", "Bag", "knb",
"Dig", "lrb", "Dia", "BaD", "Bbi", "Dji", "Bbb", "Djb", "tuk", "wxg", "yir", "tuc", "wxa",
"tuE", "wxD", "tuC", "tuB", "lmk", "stg", "nqk", "lmc", "sta", "nqc", "tva", "stD", "nqE",
"lmC", "nqC", "lmB", "nqB", "BCk", "klg", "Dak", "BCc", "str", "bik", "Dac", "lna", "klD",
"bic", "nra", "BCC", "biE", "DaC", "BCB", "DaB", "BDg", "klr", "Dbg", "BDa", "bjg", "Dba",
"BDD", "bja", "DbD", "BDr", "Dbr", "bjr", "xxc", "yyq", "xxE", "yyn", "xxC", "xxB", "ttc",
"wwq", "vvc", "xxq", "wwn", "vvE", "xxn", "vvC", "ttB", "vvB", "llc", "ssq", "nnc", "llE",
"ssn", "rrc", "nnE", "ttn", "rrE", "vvn", "llB", "rrC", "nnB", "rrB", "BBc", "kkq", "DDc",
"BBE", "kkn", "bbc", "DDE", "lln", "jjc", "bbE", "nnn", "BBB", "jjE", "rrn", "DDB", "jjC",
"BBq", "DDq", "BBn", "bbq", "DDn", "jjq", "bbn", "jjn", "xwo", "yyf", "xwm", "xwl", "tso",
"wwf", "vto", "xwv", "vtm", "tsl", "vtl", "lko", "ssf", "nlo", "lkm", "rno", "nlm", "lkl",
"rnm", "nll", "rnl", "BAo", "kkf", "DBo", "lkv", "bDo", "DBm", "BAl", "jbo", "bDm", "DBl",
"jbm", "bDl", "jbl", "DBv", "jbv", "xwd", "vsu", "vst", "nku", "rlu", "rlt", "DAu", "bBu",
"jDu", "jDt", "ApA", "Aok", "keg", "Aoc", "AoE", "AoC", "Aqs", "Aqg", "Aqa", "AqD", "Ari",
"Arb", "kuk", "kuc", "sha", "kuE", "shD", "kuC", "kuB", "Amk", "kdg", "Bqk", "kvg", "kda",
"Bqc", "kva", "BqE", "kvD", "BqC", "AmB", "BqB", "Ang", "kdr", "Brg", "kvr", "Bra", "AnD",
"BrD", "Anr", "Brr", "sxc", "sxE", "sxC", "sxB", "ktc", "lvc", "sxq", "sgn", "lvE", "sxn",
"lvC", "ktB", "lvB", "Alc", "Bnc", "AlE", "kcn", "Drc", "BnE", "AlC", "DrE", "BnC", "AlB",
"DrC", "BnB", "Alq", "Bnq", "Aln", "Drq", "Bnn", "Drn", "wyo", "wym", "wyl", "swo", "txo",
"wyv", "txm", "swl", "txl", "kso", "sgf", "lto", "swv", "nvo", "ltm", "ksl", "nvm", "ltl",
"nvl", "Ako", "kcf", "Blo", "ksv", "Dno", "Blm", "Akl", "bro", "Dnm", "Bll", "brm", "Dnl",
"Akv", "Blv", "Dnv", "brv", "yze", "yzd", "wye", "xyu", "wyd", "xyt", "swe", "twu", "swd",
"vxu", "twt", "vxt", "kse", "lsu", "ksd", "ntu", "lst", "rvu", "ypk", "zew", "xdA", "yos",
"zei", "xck", "yog", "zeb", "xcc", "yoa", "xcE", "yoD", "xcC", "xhk", "yqw", "zfj", "utA",
"xgs", "yqi", "usk", "xgg", "yqb", "usc", "xga", "usE", "xgD", "usC", "uxk", "xiw", "yrj",
"ptA", "uws", "xii", "psk", "uwg", "xib", "psc", "uwa", "psE", "uwD", "psC", "pxk", "uyw",
"xjj", "ftA", "pws", "uyi", "fsk", "pwg", "uyb", "fsc", "pwa", "fsE", "pwD", "fxk", "pyw",
"uzj", "fws", "pyi", "fwg", "pyb", "fwa", "fyw", "pzj", "fyi", "fyb", "xFA", "yms", "zdi",
"xEk", "ymg", "zdb", "xEc", "yma", "xEE", "ymD", "xEC", "xEB", "uhA", "xas", "yni", "ugk",
"xag", "ynb", "ugc", "xaa", "ugE", "xaD", "ugC", "ugB", "oxA", "uis", "xbi", "owk", "uig",
"xbb", "owc", "uia", "owE", "uiD", "owC", "owB", "dxA", "oys", "uji", "dwk", "oyg", "ujb",
"dwc", "oya", "dwE", "oyD", "dwC", "dys", "ozi", "dyg", "ozb", "dya", "dyD", "dzi", "dzb",
"xCk", "ylg", "zcr", "xCc", "yla", "xCE", "ylD", "xCC", "xCB", "uak", "xDg", "ylr", "uac",
"xDa", "uaE", "xDD", "uaC", "uaB", "oik", "ubg", "xDr", "oic", "uba", "oiE", "ubD", "oiC",
"oiB", "cyk", "ojg", "ubr", "cyc", "oja", "cyE", "ojD", "cyC", "cyB", "czg", "ojr", "cza",
"czD", "czr", "xBc", "ykq", "xBE", "ykn", "xBC", "xBB", "uDc", "xBq", "uDE", "xBn", "uDC",
"uDB", "obc", "uDq", "obE", "uDn", "obC", "obB", "cjc", "obq", "cjE", "obn", "cjC", "cjB",
"cjq", "cjn", "xAo", "ykf", "xAm", "xAl", "uBo", "xAv", "uBm", "uBl", "oDo", "uBv", "oDm",
"oDl", "cbo", "oDv", "cbm", "cbl", "xAe", "xAd", "uAu", "uAt", "oBu", "oBt", "wpA", "yes",
"zFi", "wok", "yeg", "zFb", "woc", "yea", "woE", "yeD", "woC", "woB", "thA", "wqs", "yfi",
"tgk", "wqg", "yfb", "tgc", "wqa", "tgE", "wqD", "tgC", "tgB", "mxA", "tis", "wri", "mwk",
"tig", "wrb", "mwc", "tia", "mwE", "tiD", "mwC", "mwB", "FxA", "mys", "tji", "Fwk", "myg",
"tjb", "Fwc", "mya", "FwE", "myD", "FwC", "Fys", "mzi", "Fyg", "mzb", "Fya", "FyD", "Fzi",
"Fzb", "yuk", "zhg", "hjs", "yuc", "zha", "hbw", "yuE", "zhD", "hDy", "yuC", "yuB", "wmk",
"ydg", "zEr", "xqk", "wmc", "zhr", "xqc", "yva", "ydD", "xqE", "wmC", "xqC", "wmB", "xqB",
"tak", "wng", "ydr", "vik", "tac", "wna", "vic", "xra", "wnD", "viE", "taC", "viC", "taB",
"viB", "mik", "tbg", "wnr", "qyk", "mic", "tba", "qyc", "vja", "tbD", "qyE", "miC", "qyC",
"miB", "qyB", "Eyk", "mjg", "tbr", "hyk", "Eyc", "mja", "hyc", "qza", "mjD", "hyE", "EyC",
"hyC", "EyB", "Ezg", "mjr", "hzg", "Eza", "hza", "EzD", "hzD", "Ezr", "ytc", "zgq", "grw",
"ytE", "zgn", "gny", "ytC", "glz", "ytB", "wlc", "ycq", "xnc", "wlE", "ycn", "xnE", "ytn",
"xnC", "wlB", "xnB", "tDc", "wlq", "vbc", "tDE", "wln", "vbE", "xnn", "vbC", "tDB", "vbB",
"mbc", "tDq", "qjc", "mbE", "tDn", "qjE", "vbn", "qjC", "mbB", "qjB", "Ejc", "mbq", "gzc",
"EjE", "mbn", "gzE", "qjn", "gzC", "EjB", "gzB", "Ejq", "gzq", "Ejn", "gzn", "yso", "zgf",
"gfy", "ysm", "gdz", "ysl", "wko", "ycf", "xlo", "ysv", "xlm", "wkl", "xll", "tBo", "wkv",
"vDo", "tBm", "vDm", "tBl", "vDl", "mDo", "tBv", "qbo", "vDv", "qbm", "mDl", "qbl", "Ebo",
"mDv", "gjo", "Ebm", "gjm", "Ebl", "gjl", "Ebv", "gjv", "yse", "gFz", "ysd", "wke", "xku",
"wkd", "xkt", "tAu", "vBu", "tAt", "vBt", "mBu", "qDu", "mBt", "qDt", "EDu", "gbu", "EDt",
"gbt", "ysF", "wkF", "xkh", "tAh", "vAx", "mAx", "qBx", "wek", "yFg", "zCr", "wec", "yFa",
"weE", "yFD", "weC", "weB", "sqk", "wfg", "yFr", "sqc", "wfa", "sqE", "wfD", "sqC", "sqB",
"lik", "srg", "wfr", "lic", "sra", "liE", "srD", "liC", "liB", "Cyk", "ljg", "srr", "Cyc",
"lja", "CyE", "ljD", "CyC", "CyB", "Czg", "ljr", "Cza", "CzD", "Czr", "yhc", "zaq", "arw",
"yhE", "zan", "any", "yhC", "alz", "yhB", "wdc", "yEq", "wvc", "wdE", "yEn", "wvE", "yhn",
"wvC", "wdB", "wvB", "snc", "wdq", "trc", "snE", "wdn", "trE", "wvn", "trC", "snB", "trB",
"lbc", "snq", "njc", "lbE", "snn", "njE", "trn", "njC", "lbB", "njB", "Cjc", "lbq", "azc",
"CjE", "lbn", "azE", "njn", "azC", "CjB", "azB", "Cjq", "azq", "Cjn", "azn", "zio", "irs",
"rfy", "zim", "inw", "rdz", "zil", "ily", "ikz", "ygo", "zaf", "afy", "yxo", "ziv", "ivy",
"adz", "yxm", "ygl", "itz", "yxl", "wco", "yEf", "wto", "wcm", "xvo", "yxv", "wcl", "xvm",
"wtl", "xvl", "slo", "wcv", "tno", "slm", "vro", "tnm", "sll", "vrm", "tnl", "vrl", "lDo",
"slv", "nbo", "lDm", "rjo", "nbm", "lDl", "rjm", "nbl", "rjl", "Cbo", "lDv", "ajo", "Cbm",
"izo", "ajm", "Cbl", "izm", "ajl", "izl", "Cbv", "ajv", "zie", "ifw", "rFz", "zid", "idy",
"icz", "yge", "aFz", "ywu", "ygd", "ihz", "ywt", "wce", "wsu", "wcd", "xtu", "wst", "xtt",
"sku", "tlu", "skt", "vnu", "tlt", "vnt", "lBu", "nDu", "lBt", "rbu", "nDt", "rbt", "CDu",
"abu", "CDt", "iju", "abt", "ijt", "ziF", "iFy", "iEz", "ygF", "ywh", "wcF", "wsh", "xsx",
"skh", "tkx", "vlx", "lAx", "nBx", "rDx", "CBx", "aDx", "ibx", "iCz", "wFc", "yCq", "wFE",
"yCn", "wFC", "wFB", "sfc", "wFq", "sfE", "wFn", "sfC", "sfB", "krc", "sfq", "krE", "sfn",
"krC", "krB", "Bjc", "krq", "BjE", "krn", "BjC", "BjB", "Bjq", "Bjn", "yao", "zDf", "Dfy",
"yam", "Ddz", "yal", "wEo", "yCf", "who", "wEm", "whm", "wEl", "whl", "sdo", "wEv", "svo",
"sdm", "svm", "sdl", "svl", "kno", "sdv", "lro", "knm", "lrm", "knl", "lrl", "Bbo", "knv",
"Djo", "Bbm", "Djm", "Bbl", "Djl", "Bbv", "Djv", "zbe", "bfw", "npz", "zbd", "bdy", "bcz",
"yae", "DFz", "yiu", "yad", "bhz", "yit", "wEe", "wgu", "wEd", "wxu", "wgt", "wxt", "scu",
"stu", "sct", "tvu", "stt", "tvt", "klu", "lnu", "klt", "nru", "lnt", "nrt", "BDu", "Dbu",
"BDt", "bju", "Dbt", "bjt", "jfs", "rpy", "jdw", "roz", "jcy", "jcj", "zbF", "bFy", "zjh",
"jhy", "bEz", "jgz", "yaF", "yih", "yyx", "wEF", "wgh", "wwx", "xxx", "sch", "ssx", "ttx",
"vvx", "kkx", "llx", "nnx", "rrx", "BBx", "DDx", "bbx", "jFw", "rmz", "jEy", "jEj", "bCz",
"jaz", "jCy", "jCj", "jBj", "wCo", "wCm", "wCl", "sFo", "wCv", "sFm", "sFl", "kfo", "sFv",
"kfm", "kfl", "Aro", "kfv", "Arm", "Arl", "Arv", "yDe", "Bpz", "yDd", "wCe", "wau", "wCd",
"wat", "sEu", "shu", "sEt", "sht", "kdu", "kvu", "kdt", "kvt", "Anu", "Bru", "Ant", "Brt",
"zDp", "Dpy", "Doz", "yDF", "ybh", "wCF", "wah", "wix", "sEh", "sgx", "sxx", "kcx", "ktx",
"lvx", "Alx", "Bnx", "Drx", "bpw", "nuz", "boy", "boj", "Dmz", "bqz", "jps", "ruy", "jow",
"ruj", "joi", "job", "bmy", "jqy", "bmj", "jqj", "jmw", "rtj", "jmi", "jmb", "blj", "jnj",
"jli", "jlb", "jkr", "sCu", "sCt", "kFu", "kFt", "Afu", "Aft", "wDh", "sCh", "sax", "kEx",
"khx", "Adx", "Avx", "Buz", "Duy", "Duj", "buw", "nxj", "bui", "bub", "Dtj", "bvj", "jus",
"rxi", "jug", "rxb", "jua", "juD", "bti", "jvi", "btb", "jvb", "jtg", "rwr", "jta", "jtD",
"bsr", "jtr", "jsq", "jsn", "Bxj", "Dxi", "Dxb", "bxg", "nyr", "bxa", "bxD", "Dwr", "bxr",
"bwq", "bwn", "pjk", "urw", "ejA", "pbs", "uny", "ebk", "pDw", "ulz", "eDs", "pBy", "eBw",
"zfc", "fjk", "prw", "zfE", "fbs", "pny", "zfC", "fDw", "plz", "zfB", "fBy", "yrc", "zfq",
"frw", "yrE", "zfn", "fny", "yrC", "flz", "yrB", "xjc", "yrq", "xjE", "yrn", "xjC", "xjB",
"uzc", "xjq", "uzE", "xjn", "uzC", "uzB", "pzc", "uzq", "pzE", "uzn", "pzC", "djA", "ors",
"ufy", "dbk", "onw", "udz", "dDs", "oly", "dBw", "okz", "dAy", "zdo", "drs", "ovy", "zdm",
"dnw", "otz", "zdl", "dly", "dkz", "yno", "zdv", "dvy", "ynm", "dtz", "ynl", "xbo", "ynv",
"xbm", "xbl", "ujo", "xbv", "ujm", "ujl", "ozo", "ujv", "ozm", "ozl", "crk", "ofw", "uFz",
"cns", "ody", "clw", "ocz", "cky", "ckj", "zcu", "cvw", "ohz", "zct", "cty", "csz", "ylu",
"cxz", "ylt", "xDu", "xDt", "ubu", "ubt", "oju", "ojt", "cfs", "oFy", "cdw", "oEz", "ccy",
"ccj", "zch", "chy", "cgz", "ykx", "xBx", "uDx", "cFw", "oCz", "cEy", "cEj", "caz", "cCy",
"cCj", "FjA", "mrs", "tfy", "Fbk", "mnw", "tdz", "FDs", "mly", "FBw", "mkz", "FAy", "zFo",
"Frs", "mvy", "zFm", "Fnw", "mtz", "zFl", "Fly", "Fkz", "yfo", "zFv", "Fvy", "yfm", "Ftz",
"yfl", "wro", "yfv", "wrm", "wrl", "tjo", "wrv", "tjm", "tjl", "mzo", "tjv", "mzm", "mzl",
"qrk", "vfw", "xpz", "hbA", "qns", "vdy", "hDk", "qlw", "vcz", "hBs", "qky", "hAw", "qkj",
"hAi", "Erk", "mfw", "tFz", "hrk", "Ens", "mdy", "hns", "qty", "mcz", "hlw", "Eky", "hky",
"Ekj", "hkj", "zEu", "Evw", "mhz", "zhu", "zEt", "hvw", "Ety", "zht", "hty", "Esz", "hsz",
"ydu", "Exz", "yvu", "ydt", "hxz", "yvt", "wnu", "xru", "wnt", "xrt", "tbu", "vju", "tbt",
"vjt", "mju", "mjt", "grA", "qfs", "vFy", "gnk", "qdw", "vEz", "gls", "qcy", "gkw", "qcj",
"gki", "gkb", "Efs", "mFy", "gvs", "Edw", "mEz", "gtw", "qgz", "gsy", "Ecj", "gsj", "zEh",
"Ehy", "zgx", "gxy", "Egz", "gwz", "ycx", "ytx", "wlx", "xnx", "tDx", "vbx", "mbx", "gfk",
"qFw", "vCz", "gds", "qEy", "gcw", "qEj", "gci", "gcb", "EFw", "mCz", "ghw", "EEy", "ggy",
"EEj", "ggj", "Eaz", "giz", "gFs", "qCy", "gEw", "qCj", "gEi", "gEb", "ECy", "gay", "ECj",
"gaj", "gCw", "qBj", "gCi", "gCb", "EBj", "gDj", "gBi", "gBb", "Crk", "lfw", "spz", "Cns",
"ldy", "Clw", "lcz", "Cky", "Ckj", "zCu", "Cvw", "lhz", "zCt", "Cty", "Csz", "yFu", "Cxz",
"yFt", "wfu", "wft", "sru", "srt", "lju", "ljt", "arA", "nfs", "tpy", "ank", "ndw", "toz",
"als", "ncy", "akw", "ncj", "aki", "akb", "Cfs", "lFy", "avs", "Cdw", "lEz", "atw", "ngz",
"asy", "Ccj", "asj", "zCh", "Chy", "zax", "axy", "Cgz", "awz", "yEx", "yhx", "wdx", "wvx",
"snx", "trx", "lbx", "rfk", "vpw", "xuz", "inA", "rds", "voy", "ilk", "rcw", "voj", "iks",
"rci", "ikg", "rcb", "ika", "afk", "nFw", "tmz", "ivk", "ads", "nEy", "its", "rgy", "nEj",
"isw", "aci", "isi", "acb", "isb", "CFw", "lCz", "ahw", "CEy", "ixw", "agy", "CEj", "iwy",
"agj", "iwj", "Caz", "aiz", "iyz", "ifA", "rFs", "vmy", "idk", "rEw", "vmj", "ics", "rEi",
"icg", "rEb", "ica", "icD", "aFs", "nCy", "ihs", "aEw", "nCj", "igw", "raj", "igi", "aEb",
"igb", "CCy", "aay", "CCj", "iiy", "aaj", "iij", "iFk", "rCw", "vlj", "iEs", "rCi", "iEg",
"rCb", "iEa", "iED", "aCw", "nBj", "iaw", "aCi", "iai", "aCb", "iab", "CBj", "aDj", "ibj",
"iCs", "rBi", "iCg", "rBb", "iCa", "iCD", "aBi", "iDi", "aBb", "iDb", "iBg", "rAr", "iBa",
"iBD", "aAr", "iBr", "iAq", "iAn", "Bfs", "kpy", "Bdw", "koz", "Bcy", "Bcj", "Bhy", "Bgz",
"yCx", "wFx", "sfx", "krx", "Dfk", "lpw", "suz", "Dds", "loy", "Dcw", "loj", "Dci", "Dcb",
"BFw", "kmz", "Dhw", "BEy", "Dgy", "BEj", "Dgj", "Baz", "Diz", "bfA", "nps", "tuy", "bdk",
"now", "tuj", "bcs", "noi", "bcg", "nob", "bca", "bcD", "DFs", "lmy", "bhs", "DEw", "lmj",
"bgw", "DEi", "bgi", "DEb", "bgb", "BCy", "Day", "BCj", "biy", "Daj", "bij", "rpk", "vuw",
"xxj", "jdA", "ros", "vui", "jck", "rog", "vub", "jcc", "roa", "jcE", "roD", "jcC", "bFk",
"nmw", "ttj", "jhk", "bEs", "nmi", "jgs", "rqi", "nmb", "jgg", "bEa", "jga", "bED", "jgD",
"DCw", "llj", "baw", "DCi", "jiw", "bai", "DCb", "jii", "bab", "jib", "BBj", "DDj", "bbj",
"jjj", "jFA", "rms", "vti", "jEk", "rmg", "vtb", "jEc", "rma", "jEE", "rmD", "jEC", "jEB",
"bCs", "nli", "jas", "bCg", "nlb", "jag", "rnb", "jaa", "bCD", "jaD", "DBi", "bDi", "DBb",
"jbi", "bDb", "jbb", "jCk", "rlg", "vsr", "jCc", "rla", "jCE", "rlD", "jCC", "jCB", "bBg",
"nkr", "jDg", "bBa", "jDa", "bBD", "jDD", "DAr", "bBr", "jDr", "jBc", "rkq", "jBE", "rkn",
"jBC", "jBB", "bAq", "jBq", "bAn", "jBn", "jAo", "rkf", "jAm", "jAl", "bAf", "jAv", "Apw",
"kez", "Aoy", "Aoj", "Aqz", "Bps", "kuy", "Bow", "kuj", "Boi", "Bob", "Amy", "Bqy", "Amj",
"Bqj", "Dpk", "luw", "sxj", "Dos", "lui", "Dog", "lub", "Doa", "DoD", "Bmw", "ktj", "Dqw",
"Bmi", "Dqi", "Bmb", "Dqb", "Alj", "Bnj", "Drj", "bpA", "nus", "txi", "bok", "nug", "txb",
"boc", "nua", "boE", "nuD", "boC", "boB", "Dms", "lti", "bqs", "Dmg", "ltb", "bqg", "nvb",
"bqa", "DmD", "bqD", "Bli", "Dni", "Blb", "bri", "Dnb", "brb", "ruk", "vxg", "xyr", "ruc",
"vxa", "ruE", "vxD", "ruC", "ruB", "bmk", "ntg", "twr", "jqk", "bmc", "nta", "jqc", "rva",
"ntD", "jqE", "bmC", "jqC", "bmB", "jqB", "Dlg", "lsr", "bng", "Dla", "jrg", "bna", "DlD",
"jra", "bnD", "jrD", "Bkr", "Dlr", "bnr", "jrr", "rtc", "vwq", "rtE", "vwn", "rtC", "rtB",
"blc", "nsq", "jnc", "blE", "nsn", "jnE", "rtn", "jnC", "blB", "jnB", "Dkq", "blq", "Dkn",
"jnq", "bln", "jnn", "rso", "vwf", "rsm", "rsl", "bko", "nsf", "jlo", "bkm", "jlm", "bkl",
"jll", "Dkf", "bkv", "jlv", "rse", "rsd", "bke", "jku", "bkd", "jkt", "Aey", "Aej", "Auw",
"khj", "Aui", "Aub", "Adj", "Avj", "Bus", "kxi", "Bug", "kxb", "Bua", "BuD", "Ati", "Bvi",
"Atb", "Bvb", "Duk", "lxg", "syr", "Duc", "lxa", "DuE", "lxD", "DuC", "DuB", "Btg", "kwr",
"Dvg", "lxr", "Dva", "BtD", "DvD", "Asr", "Btr", "Dvr", "nxc", "tyq", "nxE", "tyn", "nxC",
"nxB", "Dtc", "lwq", "bvc", "nxq", "lwn", "bvE", "DtC", "bvC", "DtB", "bvB", "Bsq", "Dtq",
"Bsn", "bvq", "Dtn", "bvn", "vyo", "xzf", "vym", "vyl", "nwo", "tyf", "rxo", "nwm", "rxm",
"nwl", "rxl", "Dso", "lwf", "bto", "Dsm", "jvo", "btm", "Dsl", "jvm", "btl", "jvl", "Bsf",
"Dsv", "btv", "jvv", "vye", "vyd", "nwe", "rwu", "nwd", "rwt", "Dse", "bsu", "Dsd", "jtu",
"bst", "jtt", "vyF", "nwF", "rwh", "DsF", "bsh", "jsx", "Ahi", "Ahb", "Axg", "kir", "Axa",
"AxD", "Agr", "Axr", "Bxc", "kyq", "BxE", "kyn", "BxC", "BxB", "Awq", "Bxq", "Awn", "Bxn",
"lyo", "szf", "lym", "lyl", "Bwo", "kyf", "Dxo", "lyv", "Dxm", "Bwl", "Dxl", "Awf", "Bwv",
"Dxv", "tze", "tzd", "lye", "nyu", "lyd", "nyt", "Bwe", "Dwu", "Bwd", "bxu", "Dwt", "bxt",
"tzF", "lyF", "nyh", "BwF", "Dwh", "bwx", "Aiq", "Ain", "Ayo", "kjf", "Aym", "Ayl", "Aif",
"Ayv", "kze", "kzd", "Aye", "Byu", "Ayd", "Byt", "szp" };
/* converts values into bar patterns - replacing Grand Zebu's true type font */
static char *PDFttf[35] = { "00000", "00001", "00010", "00011", "00100", "00101", "00110", "00111",
"01000", "01001", "01010", "01011", "01100", "01101", "01110", "01111", "10000", "10001",
"10010", "10011", "10100", "10101", "10110", "10111", "11000", "11001", "11010",
"11011", "11100", "11101", "11110", "11111", "01", "1111111101010100", "11111101000101001"};
/* MicroPDF417 coefficients from ISO/IEC 24728:2006 Annex F */
static int Microcoeffs[344] = {
/* k = 7 */
76, 925, 537, 597, 784, 691, 437,
/* k = 8 */
237, 308, 436, 284, 646, 653, 428, 379,
/* k = 9 */
567, 527, 622, 257, 289, 362, 501, 441, 205,
/* k = 10 */
377, 457, 64, 244, 826, 841, 818, 691, 266, 612,
/* k = 11 */
462, 45, 565, 708, 825, 213, 15, 68, 327, 602, 904,
/* k = 12 */
597, 864, 757, 201, 646, 684, 347, 127, 388, 7, 69, 851,
/* k = 13 */
764, 713, 342, 384, 606, 583, 322, 592, 678, 204, 184, 394, 692,
/* k = 14 */
669, 677, 154, 187, 241, 286, 274, 354, 478, 915, 691, 833, 105, 215,
/* k = 15 */
460, 829, 476, 109, 904, 664, 230, 5, 80, 74, 550, 575, 147, 868, 642,
/* k = 16 */
274, 562, 232, 755, 599, 524, 801, 132, 295, 116, 442, 428, 295, 42, 176, 65,
/* k = 18 */
279, 577, 315, 624, 37, 855, 275, 739, 120, 297, 312, 202, 560, 321, 233, 756,
760, 573,
/* k = 21 */
108, 519, 781, 534, 129, 425, 681, 553, 422, 716, 763, 693, 624, 610, 310, 691,
347, 165, 193, 259, 568,
/* k = 26 */
443, 284, 887, 544, 788, 93, 477, 760, 331, 608, 269, 121, 159, 830, 446, 893,
699, 245, 441, 454, 325, 858, 131, 847, 764, 169,
/* k = 32 */
361, 575, 922, 525, 176, 586, 640, 321, 536, 742, 677, 742, 687, 284, 193, 517,
273, 494, 263, 147, 593, 800, 571, 320, 803, 133, 231, 390, 685, 330, 63, 410,
/* k = 38 */
234, 228, 438, 848, 133, 703, 529, 721, 788, 322, 280, 159, 738, 586, 388, 684,
445, 680, 245, 595, 614, 233, 812, 32, 284, 658, 745, 229, 95, 689, 920, 771,
554, 289, 231, 125, 117, 518,
/* k = 44 */
476, 36, 659, 848, 678, 64, 764, 840, 157, 915, 470, 876, 109, 25, 632, 405,
417, 436, 714, 60, 376, 97, 413, 706, 446, 21, 3, 773, 569, 267, 272, 213,
31, 560, 231, 758, 103, 271, 572, 436, 339, 730, 82, 285,
/* k = 50 */
923, 797, 576, 875, 156, 706, 63, 81, 257, 874, 411, 416, 778, 50, 205, 303,
188, 535, 909, 155, 637, 230, 534, 96, 575, 102, 264, 233, 919, 593, 865, 26,
579, 623, 766, 146, 10, 739, 246, 127, 71, 244, 211, 477, 920, 876, 427, 820,
718, 435 };
/* rows, columns, error codewords, k-offset of valid MicroPDF417 sizes from ISO/IEC 24728:2006 */
static int MicroVariants[170] =
{ 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
11, 14, 17, 20, 24, 28, 8, 11, 14, 17, 20, 23, 26, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44, 4, 6, 8, 10, 12, 15, 20, 26, 32, 38, 44,
7, 7, 7, 8, 8, 8, 8, 9, 9, 10, 11, 13, 15, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50, 8, 12, 14, 16, 18, 21, 26, 32, 38, 44, 50,
0, 0, 0, 7, 7, 7, 7, 15, 15, 24, 34, 57, 84, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294, 7, 45, 70, 99, 115, 133, 154, 180, 212, 250, 294 };
/* rows, columns, error codewords, k-offset */
/* Automatic sizing table */
static int MicroAutosize[56] =
{ 4, 6, 7, 8, 10, 12, 13, 14, 16, 18, 19, 20, 24, 29, 30, 33, 34, 37, 39, 46, 54, 58, 70, 72, 82, 90, 108, 126,
1, 14, 2, 7, 3, 25, 8, 16, 5, 17, 9, 6, 10, 11, 28, 12, 19, 13, 29, 20, 30, 21, 22, 31, 23, 32, 33, 34
};
/* following is Left RAP, Centre RAP, Right RAP and Start Cluster from ISO/IEC 24728:2006 tables 10, 11 and 12 */
static int RAPTable[136] =
{ 1, 8, 36, 19, 9, 25, 1, 1, 8, 36, 19, 9, 27, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1, 47, 1, 7, 15, 25, 37, 1, 1, 21, 15, 1,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25, 19, 1, 7, 15, 25, 37, 17, 9, 29, 31, 25,
9, 8, 36, 19, 17, 33, 1, 9, 8, 36, 19, 17, 35, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49, 43, 1, 7, 15, 25, 37, 33, 17, 37, 47, 49,
0, 3, 6, 0, 6, 0, 0, 0, 3, 6, 0, 6, 6, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0, 3, 0, 0, 6, 0, 0, 0, 0, 6, 6, 0 };
/* Left and Right Row Address Pattern from Table 2 */
static char *RAPLR[53] = {"", "221311", "311311", "312211", "222211", "213211", "214111", "223111",
"313111", "322111", "412111", "421111", "331111", "241111", "232111", "231211", "321211",
"411211", "411121", "411112", "321112", "312112", "311212", "311221", "311131", "311122",
"311113", "221113", "221122", "221131", "221221", "222121", "312121", "321121", "231121",
"231112", "222112", "213112", "212212", "212221", "212131", "212122", "212113", "211213",
"211123", "211132", "211141", "211231", "211222", "211312", "211321", "211411", "212311" };
/* Centre Row Address Pattern from Table 2 */
static char *RAPC[53] = {"", "112231", "121231", "122131", "131131", "131221", "132121", "141121",
"141211", "142111", "133111", "132211", "131311", "122311", "123211", "124111", "115111",
"114211", "114121", "123121", "123112", "122212", "122221", "121321", "121411", "112411",
"113311", "113221", "113212", "113122", "122122", "131122", "131113", "122113", "113113",
"112213", "112222", "112312", "112321", "111421", "111331", "111322", "111232", "111223",
"111133", "111124", "111214", "112114", "121114", "121123", "121132", "112132", "112141" };
+583
View File
@@ -0,0 +1,583 @@
/* plessey.c - Handles Plessey and MSI Plessey */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common.h"
#define SSET "0123456789ABCDEF"
static char *PlessTable[16] = {"13131313", "31131313", "13311313", "31311313", "13133113", "31133113",
"13313113", "31313113", "13131331", "31131331", "13311331", "31311331", "13133131",
"31133131", "13313131", "31313131"};
static char *MSITable[10] = {"12121212", "12121221", "12122112", "12122121", "12211212", "12211221",
"12212112", "12212121", "21121212", "21121221"};
int plessey(struct zint_symbol *symbol, unsigned char source[])
{ /* Not MSI/Plessey but the older Plessey standard */
unsigned int i, check;
unsigned char *checkptr;
static char grid[9] = {1,1,1,1,0,1,0,0,1};
char dest[1000];
int errno;
errno = 0;
strcpy(dest, "");
if(strlen(source) > 65) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(SSET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
checkptr = calloc (1, strlen(source) * 4 + 8);
/* Start character */
concat(dest, "31311331");
/* Data area */
for(i = 0; i <= strlen(source); i++)
{
check = posn(SSET, source[i]);
lookup(SSET, PlessTable, source[i], dest);
checkptr[4*i] = check & 1;
checkptr[4*i+1] = (check >> 1) & 1;
checkptr[4*i+2] = (check >> 2) & 1;
checkptr[4*i+3] = (check >> 3) & 1;
}
/* CRC check digit code adapted from code by Leonid A. Broukhis
used in GNU Barcode */
for (i=0; i < 4*strlen(source); i++) {
int j;
if (checkptr[i])
for (j = 0; j < 9; j++)
checkptr[i+j] ^= grid[j];
}
for (i = 0; i < 8; i++) {
switch(checkptr[strlen(source) * 4 + i])
{
case 0: concat(dest, "13"); break;
case 1: concat(dest, "31"); break;
}
}
/* Stop character */
concat(dest, "331311313");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int msi_plessey(struct zint_symbol *symbol, unsigned char source[])
{ /* Plain MSI Plessey - does not calculate any check character */
unsigned int i;
int errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 55) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start character */
concat (dest, "21");
for(i = 0; i <= strlen(source); i++)
{
lookup(NESET, MSITable, source[i], dest);
}
/* Stop character */
concat (dest, "121");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int msi_plessey_mod10(struct zint_symbol *symbol, unsigned char source[])
{ /* MSI Plessey with Modulo 10 check digit - algorithm from Barcode Island
http://www.barcodeisland.com/ */
unsigned int i, wright, dau, pedwar, pump;
char un[200], tri[200];
int errno, h;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 55) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start character */
concat (dest, "21");
/* draw data section */
for(i = 0; i < strlen(source); i++)
{
lookup(NESET, MSITable, source[i], dest);
}
/* caluculate check digit */
wright = 0;
if((strlen(source)%2) == 0)
{
for(i = 1; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
else
{
for(i = 0; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
un[wright] = '\0';
dau = atoi(un);
dau *= 2;
sprintf(tri,"%d",dau);
pedwar = 0;
for(i = 0; i < strlen(tri); i++)
{
pedwar += ctoi(tri[i]);
}
if((strlen(source)%2) == 0)
{
for(i = 0; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
else
{
for(i = 1; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
pump = (10 - pedwar%10);
if(pump == 10)
{
pump = 0;
}
/* draw check digit */
lookup(NESET, MSITable, itoc(pump), dest);
/* Stop character */
concat (dest, "121");
h = strlen(source);
source[h] = itoc(pump);
source[h + 1] = '\0';
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int msi_plessey_mod1010(struct zint_symbol *symbol, unsigned char source[])
{ /* MSI Plessey with two Modulo 10 check digits - algorithm from
Barcode Island http://www.barcodeisland.com/ */
unsigned int i, wright, dau, pedwar, pump, chwech;
char un[200], tri[200];
int errno, h;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 55) { /* No Entry Stack Smashers! */
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start character */
concat (dest, "21");
/* draw data section */
for(i = 0; i < strlen(source); i++)
{
lookup(NESET, MSITable, source[i], dest);
}
/* calculate first check digit */
wright = 0;
if((strlen(source)%2) == 0)
{
for(i = 1; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
else
{
for(i = 0; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
un[wright] = '\0';
dau = atoi(un);
dau *= 2;
sprintf(tri,"%d",dau);
pedwar = 0;
for(i = 0; i < strlen(tri); i++)
{
pedwar += ctoi(tri[i]);
}
if((strlen(source)%2) == 0)
{
for(i = 0; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
else
{
for(i = 1; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
pump = (10 - pedwar%10);
if(pump == 10)
{
pump = 0;
}
/* calculate second check digit */
wright = 0;
if((strlen(source)%2) == 0)
{
for(i = 0; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
else
{
for(i = 1; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
un[wright] = itoc(pump);
wright++;
un[wright] = '\0';
dau = atoi(un);
dau *= 2;
sprintf(tri,"%d",dau);
pedwar = 0;
for(i = 0; i < strlen(tri); i++)
{
pedwar += ctoi(tri[i]);
}
if((strlen(source)%2) == 0)
{
for(i = 1; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
else
{
for(i = 0; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
chwech = (10 - pedwar%10);
if(chwech == 10)
{
chwech = 0;
}
/* Draw check digits */
lookup(NESET, MSITable, itoc(pump), dest);
lookup(NESET, MSITable, itoc(chwech), dest);
/* Stop character */
concat (dest, "121");
h = strlen(source);
source[h] = itoc(pump);
source[h + 1] = itoc(chwech);
source[h + 2] = '\0';
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int msi_plessey_mod11(struct zint_symbol *symbol, unsigned char source[])
{
/* Calculate a Modulo 11 check digit using the system discussed on Wikipedia -
see http://en.wikipedia.org/wiki/Talk:MSI_Barcode */
/* uses the IBM weight system */
int i, weight, x, check, h;
int errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 55) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start character */
concat (dest, "21");
/* draw data section */
for(i = 0; i < strlen(source); i++)
{
lookup(NESET, MSITable, source[i], dest);
}
/* calculate check digit */
x = 0;
weight = 2;
for(i = (strlen(source) - 1); i >= 0; i--) {
x += weight * ctoi(source[i]);
weight++;
if(weight > 7) {
weight = 2;
}
}
check = (11 - (x % 11)) % 11;
if(check == 10) {
lookup(NESET, MSITable, '1', dest);
lookup(NESET, MSITable, '0', dest);
} else {
lookup(NESET, MSITable, itoc(check), dest);
}
h = strlen(source);
if(check == 10) {
source[h] = '1';
source[h + 1] = '0';
source[h + 2] = '\0';
} else {
source[h] = itoc(check);
source[h + 1] = '\0';
}
/* stop character */
concat (dest, "121");
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int msi_plessey_mod1110(struct zint_symbol *symbol, unsigned char source[])
{
/* Combining the Barcode Island and Wikipedia code */
/* Verified against http://www.bokai.com/BarcodeJSP/applet/BarcodeSampleApplet.htm */
/* Weighted using the IBM system */
int i, weight, x, check, wright, dau, pedwar, pump, h;
char un[200], tri[200];
int errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 55) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* start character */
concat (dest, "21");
/* draw data section */
for(i = 0; i < strlen(source); i++)
{
lookup(NESET, MSITable, source[i], dest);
}
/* calculate first (mod 11) digit */
wright = strlen(source);
x = 0;
weight = 2;
for(i = (strlen(source) - 1); i >= 0; i--) {
x += weight * ctoi(source[i]);
weight++;
if(weight > 7) {
weight = 2;
}
}
check = (11 - (x % 11)) % 11;
if(check == 10) {
lookup(NESET, MSITable, '1', dest);
lookup(NESET, MSITable, '0', dest);
source[wright] = '1';
source[wright + 1] = '0';
source[wright + 2] = '\0';
} else {
lookup(NESET, MSITable, itoc(check), dest);
source[wright] = itoc(check);
source[wright + 1] = '\0';
}
/* caluculate second (mod 10) check digit */
wright = 0;
if((strlen(source)%2) == 0)
{
for(i = 1; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
else
{
for(i = 0; i < strlen(source); i+=2)
{
un[wright] = source[i];
wright ++;
}
}
un[wright] = '\0';
dau = atoi(un);
dau *= 2;
sprintf(tri,"%d",dau);
pedwar = 0;
for(i = 0; i < strlen(tri); i++)
{
pedwar += ctoi(tri[i]);
}
if((strlen(source)%2) == 0)
{
for(i = 0; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
else
{
for(i = 1; i < strlen(source); i+=2)
{
pedwar += ctoi(source[i]);
}
}
pump = (10 - pedwar%10);
if(pump == 10)
{
pump = 0;
}
/* draw check digit */
lookup(NESET, MSITable, itoc(pump), dest);
/* stop character */
concat (dest, "121");
h = strlen(source);
source[h] = itoc(pump);
source[h + 1] = '\0';
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
+556
View File
@@ -0,0 +1,556 @@
/* png.c - Handles output to PNG file */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
/* Any resemblance to the code used by Greg Reolofs' wpng code examples is not
coincidental. Rather odd use of mainprog_info in this file is due to gradual adaption
from that code. Read his excellent book "PNG: The Definitive Guide" online at
http://www.libpng.org/pub/png/book/ */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "png.h" /* libpng header; includes zlib.h and setjmp.h */
#include "common.h"
#include "maxipng.h" /* Maxicode shapes */
#define SSET "0123456789ABCDEF"
struct mainprog_info_type {
long width;
long height;
FILE *outfile;
jmp_buf jmpbuf;
};
static void writepng_error_handler(png_structp png_ptr, png_const_charp msg)
{
struct mainprog_info_type *graphic;
fprintf(stderr, "writepng libpng error: %s\n", msg);
fflush(stderr);
graphic = png_get_error_ptr(png_ptr);
if (graphic == NULL) { /* we are completely hosed now */
fprintf(stderr,
"writepng severe error: jmpbuf not recoverable; terminating.\n");
fflush(stderr);
exit(99);
}
longjmp(graphic->jmpbuf, 1);
}
int png_plot(struct zint_symbol *symbol)
{
struct mainprog_info_type wpng_info;
struct mainprog_info_type *graphic;
unsigned char outdata[6000];
png_structp png_ptr;
png_infop info_ptr;
graphic = &wpng_info;
long j;
unsigned long rowbytes;
unsigned char *image_data;
int i, k, offset, row, row_binding, errno;
int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
float large_bar_height, preset_height;
int large_bar_count;
/* sort out colour options */
to_upper(symbol->fgcolour);
to_upper(symbol->bgcolour);
if(strlen(symbol->fgcolour) != 6) {
strcpy(symbol->errtxt, "error: malformed foreground colour target");
return ERROR_INVALID_OPTION;
}
if(strlen(symbol->bgcolour) != 6) {
strcpy(symbol->errtxt, "error: malformed background colour target");
return ERROR_INVALID_OPTION;
}
errno = is_sane(SSET, symbol->fgcolour);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: malformed foreground colour target");
return ERROR_INVALID_OPTION;
}
errno = is_sane(SSET, symbol->bgcolour);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: malformed background colour target");
return ERROR_INVALID_OPTION;
}
fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
/* x-dimension is equivalent to 2 pixels so multiply everything by 2 */
/* calculate graphic width and height */
graphic->width = 2 * (symbol->width + (symbol->border_width * 2) + (symbol->whitespace_width * 2));
row_binding = 0;
if (symbol->height == 0) {
symbol->height = 50;
}
large_bar_count = 0;
preset_height = 0.0;
for(i = 0; i < symbol->rows; i++) {
preset_height += symbol->row_height[i];
if(symbol->row_height[i] == 0) {
large_bar_count++;
}
}
large_bar_height = (symbol->height - preset_height) / large_bar_count;
if (large_bar_count == 0) {
symbol->height = preset_height;
}
graphic->height = (2 * symbol->height) + (symbol->border_width * 4);
if((symbol->rows > 1) && ((symbol->output_options == BARCODE_BIND) || (symbol->output_options == BARCODE_BOX))) {
row_binding = 1;
}
if(symbol->symbology == BARCODE_CODE16K) {
row_binding = 1;
}
/* Open output file in binary mode */
if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) {
strcpy(symbol->errtxt, "error: can't open output file");
return ERROR_FILE_ACCESS;
}
/* Set up error handling routine as proc() above */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, graphic,
writepng_error_handler, NULL);
if (!png_ptr) {
strcpy(symbol->errtxt, "error: out of memory");
return ERROR_MEMORY;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, NULL);
strcpy(symbol->errtxt, "error: out of memory");
return ERROR_MEMORY;
}
/* catch jumping here */
if (setjmp(graphic->jmpbuf)) {
png_destroy_write_struct(&png_ptr, &info_ptr);
strcpy(symbol->errtxt, "error: libpng error occurred");
return ERROR_MEMORY;
}
/* open output file with libpng */
png_init_io(png_ptr, graphic->outfile);
/* set compression */
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
/* set Header block */
png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
/* write all chunks up to (but not including) first IDAT */
png_write_info(png_ptr, info_ptr);
/* set up the transformations: for now, just pack low-bit-depth pixels
into bytes (one, two or four pixels per byte) */
png_set_packing(png_ptr);
/* set rowbytes - depends on picture depth */
rowbytes = wpng_info.width * 3;
/* Pixel Plotting */
offset = (2 * symbol->border_width) + (2 * symbol->whitespace_width);
for (j = 0; j < graphic->height; j++) {
/* top border */
if (j < (2 * symbol->border_width)) {
if ((symbol->output_options == BARCODE_BOX) || (symbol->output_options == BARCODE_BIND)) {
for(i = 0; i < (graphic->width * 3); i+=3) {
outdata[i] = fgred;
outdata[i + 1] = fggrn;
outdata[i + 2] = fgblu;
}
} else {
for(i = 0; i < (graphic->width * 3); i+=3) {
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
}
}
}
/* middle section */
if ((j >= (2 * symbol->border_width)) && (j < (graphic->height - (2 * symbol->border_width)))) {
for(i = 0; i < (graphic->width * 3); i+= 3) {
k = (i / 3);
/* left hand border */
if(k < (2 * symbol->border_width)) {
if(symbol->output_options == BARCODE_BOX) {
outdata[i] = fgred;
outdata[i + 1] = fggrn;
outdata[i + 2] = fgblu;
} else {
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
}
}
/* left whitespace */
if((k >= (2 * symbol->border_width)) && (k < ((2 * symbol->border_width) + (2 * symbol->whitespace_width)))) {
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
}
/* the symbol area */
if((k >= ((2 * symbol->border_width) + (2 * symbol->whitespace_width))) && (k < (graphic->width - ((2 * symbol->border_width) + (2 * symbol->whitespace_width))))) {
float y_position, cumul;
y_position = ((j / 2) - symbol->border_width);
y_position += 1.0;
row = 0;
if(symbol->row_height[row] == 0) {
cumul = large_bar_height;
} else {
cumul = symbol->row_height[row];
}
while(cumul < y_position) {
row++;
if(symbol->row_height[row] == 0) {
cumul += large_bar_height;
} else {
cumul += symbol->row_height[row];
}
}
switch(symbol->encoded_data[row][(k - offset) / 2])
{
case '1':
outdata[i] = fgred;
outdata[i + 1] = fggrn;
outdata[i + 2] = fgblu;
break;
/* NOTE: Other preset colours will go here */
case 'R':
outdata[i] = 0xff;
outdata[i + 1] = 0x00;
outdata[i + 2] = 0x00;
break;
case 'G':
outdata[i] = 0x00;
outdata[i + 1] = 0xff;
outdata[i + 2] = 0x00;
break;
case 'B':
outdata[i] = 0x00;
outdata[i + 1] = 0x00;
outdata[i + 2] = 0xff;
break;
case 'C':
outdata[i] = 0x00;
outdata[i + 1] = 0xff;
outdata[i + 2] = 0xff;
break;
case 'M':
outdata[i] = 0xff;
outdata[i + 1] = 0x00;
outdata[i + 2] = 0xff;
break;
case 'Y':
outdata[i] = 0xff;
outdata[i + 1] = 0xff;
outdata[i + 2] = 0x00;
break;
default:
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
break;
}
/* row binding */
if(row_binding) {
/* Only valid if all rows are the same height */
float total_height, equal_height;
total_height = (graphic->height / 2) - symbol->border_width;
equal_height = total_height / symbol->rows;
if((y_position > ((equal_height * row) - 1.0)) && (y_position < ((equal_height * row) + 1.0))) {
outdata[i] = fgred;
outdata[i + 1] = fggrn;
outdata[i + 2] = fgblu;
}
if((y_position > ((equal_height * (row + 1)) - 1.0)) && (y_position < ((equal_height * (row + 1)) + 1.0))) {
outdata[i] = fgred;
outdata[i + 1] = fggrn;
outdata[i + 2] = fgblu;
}
}
}
/* right whitespace */
if((k >= (graphic->width - ((2 *symbol->border_width) + (2 * symbol->whitespace_width)))) && (k < (graphic->width - (2 * symbol->border_width)))) {
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
}
/* right hand border */
if(k >= (graphic->width - (2 * symbol->border_width))) {
if(symbol->output_options == BARCODE_BOX) {
outdata[i] = fgred;
outdata[i + 1] = fggrn;
outdata[i + 2] = fgblu;
} else {
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
}
}
}
}
/* bottom border */
if (j >= (graphic->height - (2 * symbol->border_width))) {
if ((symbol->output_options == BARCODE_BOX) || (symbol->output_options == BARCODE_BIND)) {
for(i = 0; i < (graphic->width * 3); i+=3) {
outdata[i] = fgred;
outdata[i + 1] = fggrn;
outdata[i + 2] = fgblu;
}
} else {
for(i = 0; i < (graphic->width * 3); i+=3) {
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
}
}
}
/* write row contents to file */
image_data = outdata;
png_write_row(png_ptr, image_data);
}
/* End the file */
png_write_end(png_ptr, NULL);
/* make sure we have disengaged */
if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(wpng_info.outfile);
return 0;
}
int maxi_png_plot(struct zint_symbol *symbol)
{
struct mainprog_info_type wpng_info;
struct mainprog_info_type *graphic;
unsigned char outdata[6000];
png_structp png_ptr;
png_infop info_ptr;
graphic = &wpng_info;
long j;
unsigned long rowbytes;
unsigned char *image_data;
int i, k, row, row_binding, errno;
int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
int x_posn, y_posn, w_posn, h_posn;
/* sort out colour options */
to_upper(symbol->fgcolour);
to_upper(symbol->bgcolour);
if(strlen(symbol->fgcolour) != 6) {
strcpy(symbol->errtxt, "error: malformed foreground colour target");
return ERROR_INVALID_OPTION;
}
if(strlen(symbol->bgcolour) != 6) {
strcpy(symbol->errtxt, "error: malformed background colour target");
return ERROR_INVALID_OPTION;
}
errno = is_sane(SSET, symbol->fgcolour);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: malformed foreground colour target");
return ERROR_INVALID_OPTION;
}
errno = is_sane(SSET, symbol->bgcolour);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: malformed background colour target");
return ERROR_INVALID_OPTION;
}
fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
graphic->width = 300;
graphic->height = 300;
/* Open output file in binary mode */
if (!(graphic->outfile = fopen(symbol->outfile, "wb"))) {
strcpy(symbol->errtxt, "error: can't open output file");
return ERROR_FILE_ACCESS;
}
/* Set up error handling routine as proc() above */
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, graphic,
writepng_error_handler, NULL);
if (!png_ptr) {
strcpy(symbol->errtxt, "error: out of memory");
return ERROR_MEMORY;
}
info_ptr = png_create_info_struct(png_ptr);
if (!info_ptr) {
png_destroy_write_struct(&png_ptr, NULL);
strcpy(symbol->errtxt, "error: out of memory");
return ERROR_MEMORY;
}
/* catch jumping here */
if (setjmp(graphic->jmpbuf)) {
png_destroy_write_struct(&png_ptr, &info_ptr);
strcpy(symbol->errtxt, "error: libpng error occurred");
return ERROR_MEMORY;
}
/* open output file with libpng */
png_init_io(png_ptr, graphic->outfile);
/* set compression */
png_set_compression_level(png_ptr, Z_BEST_COMPRESSION);
/* set Header block */
png_set_IHDR(png_ptr, info_ptr, graphic->width, graphic->height,
8, PNG_COLOR_TYPE_RGB, PNG_INTERLACE_NONE,
PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT);
/* write all chunks up to (but not including) first IDAT */
png_write_info(png_ptr, info_ptr);
/* set up the transformations: for now, just pack low-bit-depth pixels
into bytes (one, two or four pixels per byte) */
png_set_packing(png_ptr);
/* set rowbytes - depends on picture depth */
rowbytes = wpng_info.width * 3;
/* Pixel Plotting */
for (j = 0; j < graphic->height; j++) {
for(i = 0; i < (graphic->width * 3); i += 3) {
outdata[i] = bgred;
outdata[i + 1] = bggrn;
outdata[i + 2] = bgblu;
}
if((j % 18) < 12) {
/* We are in a 'full' row of hexagons */
for(i = 0; i < graphic->width; i++) {
x_posn = i / 10;
y_posn = j / 18;
y_posn *= 2;
if(symbol->encoded_data[y_posn][x_posn] == '1') {
/* A hexagon needs plotting here */
w_posn = i % 10;
h_posn = j % 18;
if(hexagon[(h_posn * 10) + w_posn] == 1) {
outdata[i * 3] = fgred;
outdata[(i * 3) + 1] = fggrn;
outdata[(i * 3) + 2] = fgblu;
}
}
}
}
if(((j + 9) % 18) < 12) {
int ia, ja;
ja = j - 9;
/* We are in a 'reduced' row of hexagons */
for(i = 5; i < (graphic->width - 5); i++) {
ia = i - 5;
x_posn = ia / 10;
y_posn = ja / 18;
y_posn *= 2;
y_posn++;
if(symbol->encoded_data[y_posn][x_posn] == '1') {
/* A hexagon needs plotting here */
w_posn = ia % 10;
h_posn = ja % 18;
if(hexagon[(h_posn * 10) + w_posn] == 1) {
outdata[i * 3] = fgred;
outdata[(i * 3) + 1] = fggrn;
outdata[(i * 3) + 2] = fgblu;
}
}
}
}
if((j >= 103) && (j < 196)) {
/* Central bullseye */
for(i = 0; i < 93; i++) {
if(bullseye[(((j - 103) * 93) + i) * 4] == '!') {
outdata[i * 3 + 297] = fgred;
outdata[(i * 3) + 1 + 297] = fggrn;
outdata[(i * 3) + 2 + 297] = fgblu;
}
}
}
/* write row contents to file */
image_data = outdata;
png_write_row(png_ptr, image_data);
}
/* End the file */
png_write_end(png_ptr, NULL);
/* make sure we have disengaged */
if (png_ptr && info_ptr) png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(wpng_info.outfile);
return 0;
}
+341
View File
@@ -0,0 +1,341 @@
/* postal.c - Handles PostNet, PLANET, FIM. RM4SCC and Flattermarken */
/* Zint - A barcode generating program using libpng
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "common.h"
#define BESET "ABCD"
#define KRSET "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"
/* PostNet number encoding table - In this table L is long as S is short */
static char *PNTable[10] = {"LLSSS", "SSSLL", "SSLSL", "SSLLS", "SLSSL", "SLSLS", "SLLSS", "LSSSL",
"LSSLS", "LSLSS"};
static char *PLTable[10] = {"SSLLL", "LLLSS", "LLSLS", "LLSSL", "LSLLS", "LSLSL", "LSSLL", "SLLLS",
"SLLSL", "SLSLL"};
static char *FIMTable[4] = {"12121112121", "111112111211111", "121111111111121", "13111111131"};
static char *RoyalValues[36] = {"11", "12", "13", "14", "15", "10", "21", "22", "23", "24", "25",
"20", "31", "32", "33", "34", "35", "30", "41", "42", "43", "44", "45", "40", "51", "52",
"53", "54", "55", "50", "01", "02", "03", "04", "05", "00"};
static char *RoyalTable[36] = {"3300", "3210", "3201", "2310", "2301", "2211", "3120", "3030", "3021",
"2130", "2121", "2031", "3102", "3012", "3003", "2112", "2103", "2013", "1320", "1230",
"1221", "0330", "0321", "0231", "1302", "1212", "1203", "0312", "0303", "0213", "1122",
"1032", "1023", "0132", "0123", "0033"};
static char *FlatTable[10] = {"0504", "18", "0117", "0216", "0315", "0414", "0513", "0612", "0711",
"0810"};
int postnet(struct zint_symbol *symbol, unsigned char source[], char dest[])
{
/* Handles the PostNet system used for Zip codes in the US */
unsigned int i, sum, check_digit;
int errno, h;
errno = 0;
if(strlen(source) > 90) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
sum = 0;
/* start character */
concat (dest, "L");
for (i=0; i < strlen(source); i++)
{
lookup(NESET, PNTable, source[i], dest);
sum += ctoi(source[i]);
}
check_digit = 10 - (sum%10);
concat(dest, PNTable[check_digit]);
/* stop character */
concat (dest, "L");
h = strlen(source);
source[h] = itoc(check_digit);
source[h + 1] = '\0';
strcpy(symbol->text, "");
return errno;
}
int post_plot(struct zint_symbol *symbol, unsigned char source[])
{
/* Puts PostNet barcodes into the pattern matrix */
char height_pattern[200];
unsigned int loopey;
int writer;
strcpy(height_pattern, "");
int errno;
errno = 0;
errno = postnet(symbol, source, height_pattern);
if(errno != 0) {
return errno;
}
writer = 0;
for(loopey = 0; loopey < strlen(height_pattern); loopey++)
{
if(height_pattern[loopey] == 'L')
{
symbol->encoded_data[0][writer] = '1';
}
symbol->encoded_data[1][writer] = '1';
writer += 2;
}
symbol->row_height[0] = 6;
symbol->row_height[1] = 6;
symbol->rows = 2;
symbol->width = writer - 1;
return errno;
}
int planet(struct zint_symbol *symbol, unsigned char source[], char dest[])
{
/* Handles the PLANET system used for item tracking in the US */
unsigned int i, sum, check_digit;
int errno, h;
errno = 0;
if(strlen(source) > 90) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
sum = 0;
/* start character */
concat (dest, "L");
for (i=0; i < strlen(source); i++)
{
lookup(NESET, PLTable, source[i], dest);
sum += ctoi(source[i]);
}
check_digit = 10 - (sum%10);
concat(dest, PLTable[check_digit]);
/* stop character */
concat (dest, "L");
h = strlen(source);
source[h] = itoc(check_digit);
source[h + 1] = '\0';
strcpy(symbol->text, "");
return errno;
}
int planet_plot(struct zint_symbol *symbol, unsigned char source[])
{
/* Puts PLANET barcodes into the pattern matrix */
char height_pattern[200];
unsigned int loopey;
int writer;
int errno;
strcpy(height_pattern, "");
errno = 0;
errno = planet(symbol, source, height_pattern);
if(errno != 0) {
return errno;
}
writer = 0;
for(loopey = 0; loopey < strlen(height_pattern); loopey++)
{
if(height_pattern[loopey] == 'L')
{
symbol->encoded_data[0][writer] = '1';
}
symbol->encoded_data[1][writer] = '1';
writer += 2;
}
symbol->row_height[0] = 6;
symbol->row_height[1] = 6;
symbol->rows = 2;
symbol->width = writer - 1;
return errno;
}
int fim(struct zint_symbol *symbol, unsigned char source[])
{
/* The simplest barcode symbology ever! Supported by MS Word, so here it is! */
/* glyphs from http://en.wikipedia.org/wiki/Facing_Identification_Mark */
int errno;
char dest[17];
errno = 0;
strcpy(dest, "");
to_upper(source);
if(strlen(source) > 1) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(BESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
lookup(BESET, FIMTable, source[0], dest);
expand(symbol, dest);
strcpy(symbol->text, "");
return errno;
}
char rm4scc(char source[], unsigned char dest[])
{
/* Handles the 4 State barcodes used in the UK by Royal Mail */
unsigned int i;
int top, bottom, row, column, check_digit;
char values[3], set_copy[38];
strcpy(set_copy, KRSET);
top = 0;
bottom = 0;
/* start character */
concat (dest, "1");
for (i=0; i < strlen(source); i++) {
lookup(KRSET, RoyalTable, source[i], dest);
strcpy(values, RoyalValues[posn(KRSET, source[i])]);
top += ctoi(values[0]);
bottom += ctoi(values[1]);
}
/* Calculate the check digit */
row = (top % 6) - 1;
column = (bottom % 6) - 1;
if(row == -1) { row = 5; }
if(column == -1) { column = 5; }
check_digit = (6 * row) + column;
concat(dest, RoyalTable[check_digit]);
/* stop character */
concat (dest, "0");
return set_copy[check_digit];
}
int royal_plot(struct zint_symbol *symbol, unsigned char source[])
{
/* Puts RM4SCC into the data matrix */
char height_pattern[200], check;
unsigned int loopey;
int writer;
int errno, h;
strcpy(height_pattern, "");
errno = 0;
to_upper(source);
if(strlen(source) > 120) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(KRSET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
check = rm4scc(source, height_pattern);
writer = 0;
for(loopey = 0; loopey < strlen(height_pattern); loopey++)
{
if((height_pattern[loopey] == '1') || (height_pattern[loopey] == '0'))
{
symbol->encoded_data[0][writer] = '1';
}
symbol->encoded_data[1][writer] = '1';
if((height_pattern[loopey] == '2') || (height_pattern[loopey] == '0'))
{
symbol->encoded_data[2][writer] = '1';
}
writer += 2;
}
symbol->row_height[0] = 4;
symbol->row_height[1] = 2;
symbol->row_height[2] = 4;
symbol->rows = 3;
symbol->width = writer - 1;
h = strlen(source);
source[h] = check;
source[h + 1] = '\0';
strcpy(symbol->text, "");
return errno;
}
int flattermarken(struct zint_symbol *symbol, unsigned char source[])
{ /* Flattermarken - Not really a barcode symbology and (in my opinion) probably not much use
but it's supported by TBarCode so it's supported by Zint! */
int loop, errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
if(strlen(source) > 90) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
for(loop = 0; loop < strlen(source); loop++) {
lookup(NESET, FlatTable, source[loop], dest);
}
expand(symbol, dest);
strcpy(symbol->text, "");
return errno;
}
+790
View File
@@ -0,0 +1,790 @@
/* ps.c - Post Script output */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include "common.h"
#define SSET "0123456789ABCDEF"
/* This file has expanded quite a bit since version 1.5 in order to accomodate
the formatting rules for EAN and UPC symbols as set out in EN 797:1995 - the
down side of this support is that the code is now vertually unreadable! */
int ps_plot(struct zint_symbol *symbol)
{
int i, block_width, latch, r, this_row;
float textpos, large_bar_height, preset_height, row_height, row_posn;
FILE *feps;
int fgred, fggrn, fgblu, bgred, bggrn, bgblu;
float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper;
int errno = 0;
int textoffset, xoffset, yoffset, textdone, main_width;
char textpart[10], addon[6];
int large_bar_count, comp_offset;
float addon_text_posn;
textdone = 0;
main_width = symbol->width;
strcpy(addon, "");
comp_offset = 0;
addon_text_posn = 0.0;
feps = fopen(symbol->outfile, "w");
if(feps == NULL) {
strcpy(symbol->errtxt, "error: could not open output file");
return ERROR_FILE_ACCESS;
}
/* sort out colour options */
to_upper(symbol->fgcolour);
to_upper(symbol->bgcolour);
if(strlen(symbol->fgcolour) != 6) {
strcpy(symbol->errtxt, "error: malformed foreground colour target");
return ERROR_INVALID_OPTION;
}
if(strlen(symbol->bgcolour) != 6) {
strcpy(symbol->errtxt, "error: malformed background colour target");
return ERROR_INVALID_OPTION;
}
errno = is_sane(SSET, symbol->fgcolour);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: malformed foreground colour target");
return ERROR_INVALID_OPTION;
}
errno = is_sane(SSET, symbol->bgcolour);
if (errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: malformed background colour target");
return ERROR_INVALID_OPTION;
}
fgred = (16 * ctoi(symbol->fgcolour[0])) + ctoi(symbol->fgcolour[1]);
fggrn = (16 * ctoi(symbol->fgcolour[2])) + ctoi(symbol->fgcolour[3]);
fgblu = (16 * ctoi(symbol->fgcolour[4])) + ctoi(symbol->fgcolour[5]);
bgred = (16 * ctoi(symbol->bgcolour[0])) + ctoi(symbol->bgcolour[1]);
bggrn = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
bgblu = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
red_ink = fgred / 256.0;
green_ink = fggrn / 256.0;
blue_ink = fgblu / 256.0;
red_paper = bgred / 256.0;
green_paper = bggrn / 256.0;
blue_paper = bgblu / 256.0;
if (symbol->height == 0) {
symbol->height = 50;
}
large_bar_count = 0;
preset_height = 0.0;
for(i = 0; i < symbol->rows; i++) {
preset_height += symbol->row_height[i];
if(symbol->row_height[i] == 0) {
large_bar_count++;
}
}
large_bar_height = (symbol->height - preset_height) / large_bar_count;
if (large_bar_count == 0) {
symbol->height = preset_height;
}
while(symbol->encoded_data[symbol->rows - 1][comp_offset] != '1') {
comp_offset++;
}
/* Certain symbols need whitespace otherwise characters get chopped off the sides */
if (((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) {
switch(strlen(symbol->text)) {
case 13: /* EAN 13 */
case 16:
case 19:
if(symbol->whitespace_width == 0) {
symbol->whitespace_width = 10;
}
main_width = 96 + comp_offset;
break;
default:
main_width = 68 + comp_offset;
}
}
if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
if(symbol->whitespace_width == 0) {
symbol->whitespace_width = 10;
main_width = 96 + comp_offset;
}
}
if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
if(symbol->whitespace_width == 0) {
symbol->whitespace_width = 10;
main_width = 51 + comp_offset;
}
}
latch = 0;
r = 0;
/* Isolate add-on text */
for(i = 0; i < strlen(symbol->text); i++) {
if (latch == 1) {
addon[r] = symbol->text[i];
r++;
}
if (symbol->text[i] == '+') {
latch = 1;
}
}
addon[r] = '\0';
if(strcmp(symbol->text, "")) {
textoffset = 9;
} else {
textoffset = 0;
}
xoffset = symbol->border_width + symbol->whitespace_width;
yoffset = symbol->border_width;
/* Start writing the header */
fprintf(feps, "%!PS-Adobe-3.0 EPSF-3.0\n");
fprintf(feps, "%%%%Creator: Zint %s\n", VERSION);
if(strlen(symbol->text) != 0) {
fprintf(feps, "%%%%Title: %s\n",symbol->text);
} else {
fprintf(feps, "%%%%Title: Zint Generated Symbol\n");
}
fprintf(feps, "%%%%Pages: 0\n");
if(symbol->symbology != BARCODE_MAXICODE) {
fprintf(feps, "%%%%BoundingBox: 0 0 %d %d\n", (symbol->width + xoffset + xoffset), (symbol->height + textoffset + yoffset + yoffset));
} else {
fprintf(feps, "%%%%BoundingBox: 0 0 74 72\n");
}
fprintf(feps, "%%%%EndComments\n");
/* Definitions */
fprintf(feps, "/TL { setlinewidth moveto lineto stroke } bind def\n");
fprintf(feps, "/TC { moveto 0 360 arc 360 0 arcn fill } bind def\n");
fprintf(feps, "/TH { 0 setlinewidth moveto lineto lineto lineto lineto lineto closepath fill } bind def\n");
fprintf(feps, "/TB { 2 copy } bind def\n");
fprintf(feps, "/TR { newpath 4 1 roll exch moveto 1 index 0 rlineto 0 exch rlineto neg 0 rlineto closepath fill } bind def\n");
fprintf(feps, "/TE { pop pop } bind def\n");
fprintf(feps, "newpath\n");
/* Now the actual representation */
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_paper, green_paper, blue_paper);
fprintf(feps, "%d.00 0.00 TB 0.00 %d.00 TR\n", (symbol->height + textoffset + yoffset + yoffset), symbol->width + xoffset + xoffset);
if(symbol->symbology == BARCODE_MAXICODE) {
/* Maxicode uses hexagons */
float ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy, mx, my;
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "35.76 35.60 10.85 35.76 35.60 8.97 44.73 35.60 TC\n");
fprintf(feps, "35.76 35.60 7.10 35.76 35.60 5.22 40.98 35.60 TC\n");
fprintf(feps, "35.76 35.60 3.31 35.76 35.60 1.43 37.19 35.60 TC\n");
for(r = 0; r < symbol->rows; r++) {
for(i = 0; i < symbol->width; i++) {
if(symbol->encoded_data[r][i] == '1') {
/* Dump a hexagon */
my = ((symbol->rows - r - 1)) * 2.135 + 1.43;
ay = my + 1.0;
by = my + 0.5;
cy = my - 0.5;
dy = my - 1.0;
ey = my - 0.5;
fy = my + 0.5;
if(r % 2 == 1) {
mx = (2.46 * i) + 1.23 + 1.23;
} else {
mx = (2.46 * i) + 1.23;
}
ax = mx;
bx = mx + 0.86;
cx = mx + 0.86;
dx = mx;
ex = mx - 0.86;
fx = mx - 0.86;
fprintf(feps, "%.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f %.2f TH\n", ax, ay, bx, by, cx, cy, dx, dy, ex, ey, fx, fy);
}
}
}
}
if(symbol->symbology == BARCODE_ULTRA) {
/* Ultracode uses a colour scheme all of its own! */
int addon_latch = 0;
for(r = 0; r < symbol->rows; r++) {
this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */
if(symbol->row_height[this_row] == 0) {
row_height = large_bar_height;
} else {
row_height = symbol->row_height[this_row];
}
row_posn = 0;
for(i = 0; i < r; i++) {
if(symbol->row_height[symbol->rows - i - 1] == 0) {
row_posn += large_bar_height;
} else {
row_posn += symbol->row_height[symbol->rows - i - 1];
}
}
row_posn += (textoffset + yoffset);
for(i = 0; i < symbol->width; i++) {
switch(symbol->encoded_data[this_row][i]) {
case '1':
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, 1);
break;
case 'R':
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", 1.00, 0.00, 0.00);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, 1);
break;
case 'G':
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", 0.00, 1.00, 0.00);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, 1);
break;
case 'B':
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", 0.00, 0.00, 1.00);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, 1);
break;
case 'C':
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", 0.00, 1.00, 1.00);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, 1);
break;
case 'M':
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", 1.00, 0.00, 1.00);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, 1);
break;
case 'Y':
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", 1.00, 1.00, 0.00);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, 1);
break;
}
}
}
}
if((symbol->symbology != BARCODE_MAXICODE) && (symbol->symbology != BARCODE_ULTRA)) {
/* everything else uses rectangles (or squares) */
/* Works from the bottom of the symbol up */
int addon_latch = 0;
for(r = 0; r < symbol->rows; r++) {
this_row = symbol->rows - r - 1; /* invert r otherwise plots upside down */
if(symbol->row_height[this_row] == 0) {
row_height = large_bar_height;
} else {
row_height = symbol->row_height[this_row];
}
row_posn = 0;
for(i = 0; i < r; i++) {
if(symbol->row_height[symbol->rows - i - 1] == 0) {
row_posn += large_bar_height;
} else {
row_posn += symbol->row_height[symbol->rows - i - 1];
}
}
row_posn += (textoffset + yoffset);
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f ", row_height, row_posn);
i = 0;
if(symbol->encoded_data[this_row][0] == '1') {
latch = 1;
} else {
latch = 0;
}
do {
block_width = 0;
do {
block_width++;
} while (symbol->encoded_data[this_row][i + block_width] == symbol->encoded_data[this_row][i]);
if((addon_latch == 0) && (r == 0) && (i > main_width)) {
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f ", (row_height - 5.0), (row_posn - 5.0));
addon_text_posn = row_posn + row_height - 8.0;
addon_latch = 1;
}
if(latch == 1) {
/* a bar */
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset, block_width);
latch = 0;
} else {
/* a space */
latch = 1;
}
i += block_width;
} while (i < symbol->width);
}
}
/* That's done the actual data area, everything else is human-friendly */
xoffset += comp_offset;
if (((symbol->symbology == BARCODE_EANX) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_EANX_CC)) {
/* guard bar extensions and text formatting for EAN8 and EAN13 */
switch(strlen(symbol->text)) {
case 8: /* EAN-8 */
case 11:
case 14:
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f ", 5.0, 4.0 + yoffset);
fprintf(feps, "TB %d.00 %d.00 TR\n", 0 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 2 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 32 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 34 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 64 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 66 + xoffset, 1);
for(i = 0; i < 4; i++) {
textpart[i] = symbol->text[i];
}
textpart[4] = '\0';
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = 17;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
for(i = 0; i < 4; i++) {
textpart[i] = symbol->text[i + 4];
}
textpart[4] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = 50;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
textdone = 1;
switch(strlen(addon)) {
case 2:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 10;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
case 5:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 23;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
}
break;
case 13: /* EAN 13 */
case 16:
case 19:
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f ", 5.0, 4.0 + yoffset);
fprintf(feps, "TB %d.00 %d.00 TR\n", 0 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 2 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 46 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 48 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 92 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 94 + xoffset, 1);
textpart[0] = symbol->text[0];
textpart[1] = '\0';
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = -7;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
for(i = 0; i < 6; i++) {
textpart[i] = symbol->text[i + 1];
}
textpart[6] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = 24;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
for(i = 0; i < 6; i++) {
textpart[i] = symbol->text[i + 7];
}
textpart[6] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = 71;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
textdone = 1;
switch(strlen(addon)) {
case 2:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 10;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
case 5:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 23;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
}
break;
}
}
if (((symbol->symbology == BARCODE_UPCA) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCA_CC)) {
/* guard bar extensions and text formatting for UPCA */
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f ", 5.0, 4.0 + yoffset);
latch = 1;
i = 0 + comp_offset;
do {
block_width = 0;
do {
block_width++;
} while (symbol->encoded_data[symbol->rows - 1][i + block_width] == symbol->encoded_data[symbol->rows - 1][i]);
if(latch == 1) {
/* a bar */
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset - comp_offset, block_width);
latch = 0;
} else {
/* a space */
latch = 1;
}
i += block_width;
} while (i < 11 + comp_offset);
fprintf(feps, "TB %d.00 %d.00 TR\n", 46 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 48 + xoffset, 1);
latch = 1;
i = 85 + comp_offset;
do {
block_width = 0;
do {
block_width++;
} while (symbol->encoded_data[symbol->rows - 1][i + block_width] == symbol->encoded_data[symbol->rows - 1][i]);
if(latch == 1) {
/* a bar */
fprintf(feps, "TB %d.00 %d.00 TR\n", i + xoffset - comp_offset, block_width);
latch = 0;
} else {
/* a space */
latch = 1;
}
i += block_width;
} while (i < 96 + comp_offset);
textpart[0] = symbol->text[0];
textpart[1] = '\0';
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "8.00 scalefont setfont\n");
textpos = -5;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
for(i = 0; i < 5; i++) {
textpart[i] = symbol->text[i + 1];
}
textpart[5] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = 27;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
for(i = 0; i < 5; i++) {
textpart[i] = symbol->text[i + 6];
}
textpart[6] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = 68;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
textpart[0] = symbol->text[11];
textpart[1] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "8.00 scalefont setfont\n");
textpos = 100;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
textdone = 1;
switch(strlen(addon)) {
case 2:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 10;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
case 5:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 23;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
}
}
if (((symbol->symbology == BARCODE_UPCE) && (symbol->rows == 1)) || (symbol->symbology == BARCODE_UPCE_CC)) {
/* guard bar extensions and text formatting for UPCE */
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%.2f %.2f ", 5.0, 4.0 + yoffset);
fprintf(feps, "TB %d.00 %d.00 TR\n", 0 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 2 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 46 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 48 + xoffset, 1);
fprintf(feps, "TB %d.00 %d.00 TR\n", 50 + xoffset, 1);
textpart[0] = symbol->text[0];
textpart[1] = '\0';
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "8.00 scalefont setfont\n");
textpos = -5;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
for(i = 0; i < 6; i++) {
textpart[i] = symbol->text[i + 1];
}
textpart[6] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = 24;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
textpart[0] = symbol->text[7];
textpart[1] = '\0';
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "8.00 scalefont setfont\n");
textpos = 55;
fprintf(feps, " 0 0 moveto %.2f 0.50 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", textpart);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", textpart);
fprintf(feps, "setmatrix\n");
textdone = 1;
switch(strlen(addon)) {
case 2:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 10;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
case 5:
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "11.00 scalefont setfont\n");
textpos = symbol->width + xoffset - 23;
fprintf(feps, " 0 0 moveto %.2f %.2f translate 0.00 rotate 0 0 moveto\n", textpos, addon_text_posn);
fprintf(feps, " (%s) stringwidth\n", addon);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", addon);
fprintf(feps, "setmatrix\n");
break;
}
}
xoffset -= comp_offset;
/* Put boundary bars or box around symbol */
if ((symbol->output_options == BARCODE_BOX) || (symbol->output_options == BARCODE_BIND)) {
/* boundary bars */
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%d.00 %d.00 TB %d.00 %d.00 TR\n", symbol->border_width, textoffset, 0, (symbol->width + xoffset + xoffset));
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%d.00 %d.00 TB %d.00 %d.00 TR\n", symbol->border_width, textoffset + symbol->height + symbol->border_width, 0, (symbol->width + xoffset + xoffset));
if(symbol->rows > 1) {
/* row binding */
for(r = 1; r < symbol->rows; r++) {
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%d.00 %.2f TB %d.00 %d.00 TR\n", 2, ((r * row_height) + textoffset + yoffset - 1), xoffset, symbol->width);
}
}
}
if (symbol->output_options == BARCODE_BOX) {
/* side bars */
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%d.00 %d.00 TB %d.00 %d.00 TR\n", symbol->height + (2 * symbol->border_width), textoffset, 0, symbol->border_width);
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "%d.00 %d.00 TB %d.00 %d.00 TR\n", symbol->height + (2 * symbol->border_width), textoffset, (symbol->width + xoffset + xoffset - symbol->border_width), symbol->border_width);
}
/* Put the human readable text at the bottom */
if((textdone == 0) && (strlen(symbol->text) != 0)) {
fprintf(feps, "TE\n");
fprintf(feps, "%.2f %.2f %.2f setrgbcolor\n", red_ink, green_ink, blue_ink);
fprintf(feps, "matrix currentmatrix\n");
fprintf(feps, "/Helvetica findfont\n");
fprintf(feps, "8.00 scalefont setfont\n");
textpos = symbol->width / 2.0;
fprintf(feps, " 0 0 moveto %.2f 1.67 translate 0.00 rotate 0 0 moveto\n", textpos + xoffset);
fprintf(feps, " (%s) stringwidth\n", symbol->text);
fprintf(feps, "pop\n");
fprintf(feps, "-2 div 0 rmoveto\n");
fprintf(feps, " (%s) show\n", symbol->text);
fprintf(feps, "setmatrix\n");
}
fprintf(feps, "\nshowpage\n");
fclose(feps);
return errno;
}
+94
View File
@@ -0,0 +1,94 @@
/* qr.c Handles QR Code by utilising libqrencode */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
Copyright (C) 2006 Kentaro Fukuchi <fukuchi@megaui.net>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <qrencode.h> /* The assumption is that this is already installed */
#include "common.h"
static int kanji = 0;
static QRecLevel level = QR_ECLEVEL_L;
QRcode *encode(int security, int size, const unsigned char *intext)
{
int version;
QRecLevel level;
QRencodeMode hint;
QRcode *code;
if(kanji) {
hint = QR_MODE_KANJI;
} else {
hint = QR_MODE_8;
}
if((security >= 1) && (security <= 4)) {
switch (security) {
case 1: level = QR_ECLEVEL_L; break;
case 2: level = QR_ECLEVEL_M; break;
case 3: level = QR_ECLEVEL_Q; break;
case 4: level = QR_ECLEVEL_H; break;
}
} else {
level = QR_ECLEVEL_L;
}
if((size >= 1) && (size <= 40)) {
version = size;
} else {
version = 0;
}
code = QRcode_encodeString(intext, version, level, hint, 1);
return code;
}
int qr_code(struct zint_symbol *symbol, unsigned char source[])
{
QRcode *code;
int errno = 0;
int i, j;
code = encode(symbol->option_1, symbol->option_2, source);
if(code == NULL) {
strcpy(symbol->errtxt, "error: libqrencode failed to encode the input data");
return ERROR_ENCODING_PROBLEM;
}
symbol->width = code->width;
symbol->rows = code->width;
for(i = 0; i < code->width; i++) {
for(j = 0; j < code->width; j++) {
if((*(code->data + (i * code->width) + j) & 0x01) == 0) {
symbol->encoded_data[i][j] = '0';
} else {
symbol->encoded_data[i][j] = '1';
}
}
symbol->row_height[i] = 1;
}
QRcode_free(code);
return errno;
}
+170
View File
@@ -0,0 +1,170 @@
/**
*
* This is a simple Reed-Solomon encoder
* (C) Cliff Hones 2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
// It is not written with high efficiency in mind, so is probably
// not suitable for real-time encoding. The aim was to keep it
// simple, general and clear.
//
// <Some notes on the theory and implementation need to be added here>
// Usage:
// First call rs_init_gf(poly) to set up the Galois Field parameters.
// Then call rs_init_code(size, index) to set the encoding size
// Then call rs_encode(datasize, data, out) to encode the data.
//
// These can be called repeatedly as required - but note that
// rs_init_code must be called following any rs_init_gf call.
//
// If the parameters are fixed, some of the statics below can be
// replaced with constants in the obvious way, and additionally
// malloc/free can be avoided by using static arrays of a suitable
// size.
#include <stdio.h> // only needed for debug (main)
#include <stdlib.h> // only needed for malloc/free
static int gfpoly;
static int symsize; // in bits
static int logmod; // 2**symsize - 1
static int rlen;
static int *log = NULL, *alog = NULL, *rspoly = NULL;
// rs_init_gf(poly) initialises the parameters for the Galois Field.
// The symbol size is determined from the highest bit set in poly
// This implementation will support sizes up to 30 bits (though that
// will result in very large log/antilog tables) - bit sizes of
// 8 or 4 are typical
//
// The poly is the bit pattern representing the GF characteristic
// polynomial. e.g. for ECC200 (8-bit symbols) the polynomial is
// a**8 + a**5 + a**3 + a**2 + 1, which translates to 0x12d.
void rs_init_gf(int poly)
{
int m, b, p, v;
// Return storage from previous setup
if (log) {
free(log);
free(alog);
free(rspoly);
rspoly = NULL;
}
// Find the top bit, and hence the symbol size
for (b = 1, m = 0; b <= poly; b <<= 1)
m++;
b >>= 1;
m--;
gfpoly = poly;
symsize = m;
// Calculate the log/alog tables
logmod = (1 << m) - 1;
log = (int *)malloc(sizeof(int) * (logmod + 1));
alog = (int *)malloc(sizeof(int) * logmod);
for (p = 1, v = 0; v < logmod; v++) {
alog[v] = p;
log[p] = v;
p <<= 1;
if (p & b)
p ^= poly;
}
}
// rs_init_code(nsym, index) initialises the Reed-Solomon encoder
// nsym is the number of symbols to be generated (to be appended
// to the input data). index is usually 1 - it is the index of
// the constant in the first term (i) of the RS generator polynomial:
// (x + 2**i)*(x + 2**(i+1))*... [nsym terms]
// For ECC200, index is 1.
void rs_init_code(int nsym, int index)
{
int i, k;
if (rspoly)
free(rspoly);
rspoly = (int *)malloc(sizeof(int) * (nsym + 1));
rlen = nsym;
rspoly[0] = 1;
for (i = 1; i <= nsym; i++) {
rspoly[i] = 1;
for (k = i - 1; k > 0; k--) {
if (rspoly[k])
rspoly[k] =
alog[(log[rspoly[k]] + index) % logmod];
rspoly[k] ^= rspoly[k - 1];
}
rspoly[0] = alog[(log[rspoly[0]] + index) % logmod];
index++;
}
}
void rs_encode(int len, unsigned char *data, unsigned char *res)
{
int i, k, m;
for (i = 0; i < rlen; i++)
res[i] = 0;
for (i = 0; i < len; i++) {
m = res[rlen - 1] ^ data[i];
for (k = rlen - 1; k > 0; k--) {
if (m && rspoly[k])
res[k] =
res[k -
1] ^ alog[(log[m] +
log[rspoly[k]]) % logmod];
else
res[k] = res[k - 1];
}
if (m && rspoly[0])
res[0] = alog[(log[m] + log[rspoly[0]]) % logmod];
else
res[0] = 0;
}
}
void rs_encode_long(int len, unsigned int *data, unsigned int *res)
{ /* The same as above but for larger bitlengths - Aztec code compatible */
int i, k, m;
for (i = 0; i < rlen; i++)
res[i] = 0;
for (i = 0; i < len; i++) {
m = res[rlen - 1] ^ data[i];
for (k = rlen - 1; k > 0; k--) {
if (m && rspoly[k])
res[k] =
res[k -
1] ^ alog[(log[m] +
log[rspoly[k]]) % logmod];
else
res[k] = res[k - 1];
}
if (m && rspoly[0])
res[0] = alog[(log[m] + log[rspoly[0]]) % logmod];
else
res[0] = 0;
}
}
+30
View File
@@ -0,0 +1,30 @@
/**
*
* This is a simple Reed-Solomon encoder
* (C) Cliff Hones 2004
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#ifndef __REEDSOL_H
#define __REEDSOL_H
void rs_init_gf(int poly);
void rs_init_code(int nsym, int index);
void rs_encode(int len, unsigned char *data, unsigned char *res);
void rs_encode_long(int len, unsigned int *data, unsigned int *res);
#endif /* __REEDSOL_H */
+2293
View File
File diff suppressed because it is too large Load Diff
+225
View File
@@ -0,0 +1,225 @@
/* rss.h - Data tables for Reduced Space Symbology */
/*
libzint - the open source barcode library
Copyright (C) 2007 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define NUMERIC 110
#define ALPHA 97
#define ISOIEC 105
#define INVALID_CHAR 100
#define ANY_ENC 120
#define ALPHA_OR_ISO 121
/* RSS-14 Tables */
static int g_sum_table[9] = { 0, 161, 961, 2015, 2715, 0, 336, 1036, 1516};
static int t_table[9] = { 1, 10, 34, 70, 126, 4, 20, 48, 81};
static int modules_odd[9] = { 12, 10, 8, 6, 4, 5, 7, 9, 11 };
static int modules_even[9] = { 4, 6, 8, 10, 12, 10, 8, 6, 4 };
static int widest_odd[9] = { 8, 6, 4, 3, 1, 2, 4, 6, 8 };
static int widest_even[9] = { 1, 3, 5, 6, 8, 7, 5, 3, 1 };
static int widths[8];
static int finder_pattern[45] = {
3, 8, 2, 1, 1,
3, 5, 5, 1, 1,
3, 3, 7, 1, 1,
3, 1, 9, 1, 1,
2, 7, 4, 1, 1,
2, 5, 6, 1, 1,
2, 3, 8, 1, 1,
1, 5, 7, 1, 1,
1, 3, 9, 1, 1
};
static int checksum_weight[32] = { /* Table 5 */
1, 3, 9, 27, 2, 6, 18, 54,
4, 12, 36, 29, 8, 24, 72, 58,
16, 48, 65, 37, 32, 17, 51, 74,
64, 34, 23, 69, 49, 68, 46, 59
};
/* RSS Limited Tables */
static int t_even_ltd[7] = { 28, 728, 6454, 203, 2408, 1, 16632 };
static int modules_odd_ltd[7] = { 17, 13, 9, 15, 11, 19, 7 };
static int modules_even_ltd[7] = { 9, 13, 17, 11, 15, 7, 19 };
static int widest_odd_ltd[7] = { 6, 5, 3, 5, 4, 8, 1 };
static int widest_even_ltd[7] = { 3, 4, 6, 4, 5, 1, 8 };
static int checksum_weight_ltd[28] = { /* Table 7 */
1, 3, 9, 27, 81, 65, 17, 51, 64, 14, 42, 37, 22, 66,
20, 60, 2, 6, 18, 54, 73, 41, 34, 13, 39, 28, 84, 74
};
static int finder_pattern_ltd[1232] = {
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1, 1,
1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1,
1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1, 1,
1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 3, 1, 1, 1,
1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 3, 1, 1, 1,
1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1,
1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1,
1, 1, 1, 2, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1,
1, 1, 1, 2, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1,
1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 3, 1, 1, 1,
1, 2, 1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 1,
1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1,
1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1,
1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1, 1,
1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 2, 1, 1, 1,
1, 1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1,
1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1,
1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1,
1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1,
1, 1, 1, 3, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 1, 1,
1, 2, 1, 1, 1, 2, 1, 1, 2, 1, 2, 1, 1, 1,
1, 2, 1, 2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1,
1, 3, 1, 1, 1, 1, 1, 1, 2, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 3, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1, 2, 1, 1,
1, 1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 2, 3, 1, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 2, 1, 1,
1, 1, 1, 1, 1, 1, 2, 1, 1, 3, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 1, 1,
1, 1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1,
1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1,
1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 2, 1, 1, 1,
1, 1, 1, 2, 1, 2, 2, 1, 1, 1, 2, 1, 1, 1,
1, 1, 1, 3, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1,
1, 2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1,
1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1, 1,
1, 2, 1, 2, 1, 1, 2, 1, 1, 1, 2, 1, 1, 1,
1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3, 1, 1,
1, 1, 1, 1, 2, 1, 1, 1, 1, 2, 2, 2, 1, 1,
1, 1, 1, 1, 2, 1, 1, 1, 1, 3, 2, 1, 1, 1,
1, 1, 1, 1, 2, 1, 1, 2, 1, 1, 2, 2, 1, 1,
1, 1, 1, 1, 2, 1, 1, 2, 1, 2, 2, 1, 1, 1,
1, 1, 1, 1, 2, 2, 1, 1, 1, 1, 2, 2, 1, 1,
1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1,
1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1, 1,
1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 2, 1, 1, 1,
1, 2, 1, 1, 2, 2, 1, 1, 1, 1, 2, 1, 1, 1,
1, 2, 1, 2, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1,
1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 1, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 2, 3, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1,
1, 1, 2, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1,
1, 1, 2, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1,
1, 1, 2, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1,
1, 1, 2, 1, 1, 2, 1, 1, 1, 1, 2, 2, 1, 1,
1, 1, 2, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1,
1, 1, 2, 2, 1, 1, 1, 1, 1, 1, 2, 2, 1, 1,
2, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 1, 1,
2, 1, 1, 1, 1, 1, 1, 1, 1, 3, 2, 1, 1, 1,
2, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2, 2, 1, 1,
2, 1, 1, 1, 1, 1, 1, 2, 1, 2, 2, 1, 1, 1,
2, 1, 1, 1, 1, 1, 1, 3, 1, 1, 2, 1, 1, 1,
2, 1, 1, 1, 1, 2, 1, 1, 1, 2, 2, 1, 1, 1,
2, 1, 1, 1, 1, 2, 1, 2, 1, 1, 2, 1, 1, 1,
2, 1, 1, 2, 1, 1, 1, 1, 1, 2, 2, 1, 1, 1
};
/* RSS Expanded Tables */
static int g_sum_exp[5] = { 0, 348, 1388, 2948, 3988 };
static int t_even_exp[5] = { 4, 20, 52, 104, 204 };
static int modules_odd_exp[5] = { 12, 10, 8, 6, 4 };
static int modules_even_exp[5] = { 5, 7, 9, 11, 13 };
static int widest_odd_exp[5] = { 7, 5, 4, 3, 1 };
static int widest_even_exp[5] = { 2, 4, 5, 6, 8 };
static int checksum_weight_exp[184] = { /* Table 14 */
1, 3, 9, 27, 81, 32, 96, 77,
20, 60, 180, 118, 143, 7, 21, 63,
189, 145, 13, 39, 117, 140, 209, 205,
193, 157, 49, 147, 19, 57, 171, 91,
62, 186, 136, 197, 169, 85, 44, 132,
185, 133, 188, 142, 4, 12, 36, 108,
113, 128, 173, 97, 80, 29, 87, 50,
150, 28, 84, 41, 123, 158, 52, 156,
46, 138, 203, 187, 139, 206, 196, 166,
76, 17, 51, 153, 37, 111, 122, 155,
43, 129, 176, 106, 107, 110, 119, 146,
16, 48, 144, 10, 30, 90, 59, 177,
109, 166, 137, 200, 178, 112, 125, 164,
70, 210, 208, 202, 184, 130, 179, 115,
134, 191, 151, 31, 93, 68, 204, 190,
148, 22, 66, 198, 172, 94, 71, 2,
6, 18, 54, 162, 64, 192, 154, 40,
120, 149, 25, 75, 14, 42, 126, 167,
79, 26, 78, 23, 69, 207, 199, 175,
103, 98, 83, 38, 114, 131, 182, 124,
161, 61, 183, 127, 170, 88, 53, 159,
55, 165, 73, 8, 24, 72, 5, 15,
45, 135, 194, 160, 58, 174, 100, 89
};
static int finder_pattern_exp[60] = { /* Table 15 */
1, 8, 4, 1, 1,
1, 1, 4, 8, 1,
3, 6, 4, 1, 1,
1, 1, 4, 6, 3,
3, 4, 6, 1, 1,
1, 1, 6, 4, 3,
3, 2, 8, 1, 1,
1, 1, 8, 2, 3,
2, 6, 5, 1, 1,
1, 1, 5, 6, 2,
2, 2, 9, 1, 1,
1, 1, 9, 2, 2
};
static int finder_sequence[198] = { /* Table 16 */
1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0,
1, 4, 3, 0, 0, 0, 0, 0, 0, 0, 0,
1, 6, 3, 8, 0, 0, 0, 0, 0, 0, 0,
1, 10, 3, 8, 5, 0, 0, 0, 0, 0, 0,
1, 10, 3, 8, 7, 12, 0, 0, 0, 0, 0,
1, 10, 3, 8, 9, 12, 11, 0, 0, 0, 0,
1, 2, 3, 4, 5, 6, 7, 8, 0, 0, 0,
1, 2, 3, 4, 5, 6, 7, 10, 9, 0, 0,
1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 0,
1, 2, 3, 4, 5, 8, 7, 10, 9, 12, 11
};
static int weight_rows[210] = {
0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 5, 6, 3, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 9, 10, 3, 4, 13, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 17, 18, 3, 4, 13, 14, 7, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 17, 18, 3, 4, 13, 14, 11, 12, 21, 22, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 17, 18, 3, 4, 13, 14, 15, 16, 21, 22, 19, 20, 0, 0, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 0, 0, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 15, 16, 0, 0, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 17, 18, 19, 20, 21, 22, 0, 0,
0, 1, 2, 3, 4, 5, 6, 7, 8, 13, 14, 11, 12, 17, 18, 15, 16, 21, 22, 19, 20
};
+155
View File
@@ -0,0 +1,155 @@
/* telepen.c - Handles Telepen and Telepen numeric */
/*
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include "common.h"
static char *TeleTable[128] = { "1111111111111111", "1131313111", "33313111", "1111313131",
"3111313111", "11333131", "13133131", "111111313111", "31333111", "1131113131", "33113131",
"1111333111", "3111113131", "1113133111", "1311133111", "111111113131", "3131113111",
"11313331", "333331", "111131113111", "31113331", "1133113111", "1313113111", "1111113331",
"31131331", "113111113111", "3311113111", "1111131331", "311111113111", "1113111331",
"1311111331", "11111111113111", "31313311", "1131311131", "33311131", "1111313311",
"3111311131", "11333311", "13133311", "111111311131", "31331131", "1131113311", "33113311",
"1111331131", "3111113311", "1113131131", "1311131131", "111111113311", "3131111131",
"1131131311", "33131311", "111131111131", "3111131311", "1133111131", "1313111131",
"111111131311", "3113111311", "113111111131", "3311111131", "111113111311", "311111111131",
"111311111311", "131111111311", "11111111111131", "3131311111", "11313133", "333133",
"111131311111", "31113133", "1133311111", "1313311111", "1111113133", "313333",
"113111311111", "3311311111", "11113333", "311111311111", "11131333", "13111333",
"11111111311111", "31311133", "1131331111", "33331111", "1111311133", "3111331111",
"11331133", "13131133", "111111331111", "3113131111", "1131111133", "33111133",
"111113131111", "3111111133", "111311131111", "131111131111", "111111111133", "31311313",
"113131111111", "3331111111", "1111311313", "311131111111", "11331313", "13131313",
"11111131111111", "3133111111", "1131111313", "33111313", "111133111111", "3111111313",
"111313111111", "131113111111", "111111111313", "313111111111", "1131131113", "33131113",
"11113111111111", "3111131113", "113311111111", "131311111111", "111111131113", "3113111113",
"11311111111111", "331111111111", "111113111113", "31111111111111", "111311111113",
"131111111113"};
int telepen(struct zint_symbol *symbol, unsigned char source[])
{
unsigned int i, count, check_digit;
int ascii_value;
int errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
count = 0;
if(strlen(source) > 30) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
for(i = 0; i < strlen(source); i++) {
if(source[i] > 127) {
/* Cannot encode extended ASCII */
strcpy(symbol->errtxt, "error: invalid characters in input data");
return ERROR_INVALID_DATA;
}
}
/* Start character */
concat(dest, TeleTable['_']);
for (i=0; i < strlen(source); i++)
{
ascii_value = source[i];
concat(dest, TeleTable[ascii_value]);
count += source[i];
}
check_digit = 127 - (count % 127);
concat(dest, TeleTable[check_digit]);
/* Stop character */
concat(dest, TeleTable['z']);
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
int telepen_num(struct zint_symbol *symbol, unsigned char source[])
{
unsigned int i, count, check_digit, glyph;
int errno;
char dest[1000];
errno = 0;
strcpy(dest, "");
count = 0;
if(strlen(source) > 60) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
errno = is_sane(NESET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
/* Add a leading zero if required */
if ((strlen(source)%2) != 0)
{
unsigned int length;
char temp[200];
length = strlen(source);
strcpy(temp, source);
source[0] = '0';
for(i = 0; i <= length; i++)
{
source[i + 1] = temp[i];
}
}
/* Start character */
concat(dest, TeleTable['_']);
for (i=0; i < strlen(source); i+=2)
{
glyph = (10 * ctoi(source[i])) + ctoi(source[i + 1]);
glyph += 27;
concat(dest, TeleTable[glyph]);
count += glyph;
}
check_digit = 127 - (count % 127);
concat(dest, TeleTable[check_digit]);
/* Stop character */
concat(dest, TeleTable['z']);
expand(symbol, dest);
strcpy(symbol->text, source);
return errno;
}
+691
View File
@@ -0,0 +1,691 @@
/* upcean.c - Handles UPC, EAN and ISBN
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define NASET "0123456789+"
#define EAN2 102
#define EAN5 105
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "common.h"
/* UPC and EAN tables checked against EN 797:1996 */
static char *UPCParity0[10] = {"BBBAAA", "BBABAA", "BBAABA", "BBAAAB", "BABBAA", "BAABBA", "BAAABB",
"BABABA", "BABAAB", "BAABAB"}; /* Number set for UPC-E symbol (EN Table 4) */
static char *UPCParity1[10] = {"AAABBB", "AABABB", "AABBAB", "AABBBA", "ABAABB", "ABBAAB", "ABBBAA",
"ABABAB", "ABABBA", "ABBABA"}; /* Not covered by BS EN 797:1995 */
static char *EAN2Parity[4] = {"AA", "AB", "BA", "BB"}; /* Number sets for 2-digit add-on (EN Table 6) */
static char *EAN5Parity[10] = {"BBAAA", "BABAA", "BAABA", "BAAAB", "ABBAA", "AABBA", "AAABB", "ABABA",
"ABAAB", "AABAB"}; /* Number set for 5-digit add-on (EN Table 7) */
static char *EAN13Parity[10] = {"AAAAA", "ABABB", "ABBAB", "ABBBA", "BAABB", "BBAAB", "BBBAA", "BABAB",
"BABBA", "BBABA"}; /* Left hand of the EAN-13 symbol (EN Table 3) */
static char *EANsetA[10] = {"3211", "2221", "2122", "1411", "1132", "1231", "1114", "1312", "1213",
"3112"}; /* Representation set A and C (EN Table 1) */
static char *EANsetB[10] = {"1123", "1222", "2212", "1141", "2311", "1321", "4111", "2131", "3121",
"2113"}; /* Representation set B (EN Table 1) */
char upc_check(unsigned char source[])
{ /* Calculate the correct check digit for a UPC barcode */
unsigned int i, count, check_digit;
count = 0;
for (i = 0; i < strlen(source); i++)
{
count += ctoi(source[i]);
if ((i%2) == 0)
{
count += 2 * (ctoi(source[i]));
}
}
check_digit = 10 - (count%10);
if (check_digit == 10) { check_digit = 0; }
return itoc(check_digit);
}
void upca_draw(unsigned char source[], char dest[])
{ /* UPC A is usually used for 12 digit numbers, but this function takes a source of any length */
unsigned int i, half_way;
half_way = strlen(source) / 2;
/* start character */
concat (dest, "111");
for(i = 0; i <= strlen(source); i++)
{
if (i == half_way)
{
/* middle character - separates manufacturer no. from product no. */
/* also inverts right hand characters */
concat(dest, "11111");
}
lookup(NESET, EANsetA, source[i], dest);
}
/* stop character */
concat (dest, "111");
}
void upca(struct zint_symbol *symbol, unsigned char source[], char dest[])
{ /* Make a UPC A barcode when we haven't been given the check digit */
int length;
length = strlen(source);
source[length] = upc_check(source);
source[length + 1] = '\0';
upca_draw(source, dest);
strcpy(symbol->text, source);
}
void upce(struct zint_symbol *symbol, unsigned char source[], char dest[])
{ /* UPC E is a zero-compressed version of UPC A */
unsigned int i, num_system;
char emode, equivalent[12], check_digit, parity[8], temp[8];
char hrt[8];
/* Two number systems can be used - system 0 and system 1 */
if(strlen(source) == 7) {
switch(source[0]) {
case '0': num_system = 0; break;
case '1': num_system = 1; break;
default: num_system = 0; source[0] = '0'; break;
}
strcpy(temp, source);
strcpy(hrt, source);
for(i = 1; i <= 7; i++) {
source[i - 1] = temp[i];
}
}
else {
num_system = 0;
hrt[0] = '0';
hrt[1] = '\0';
concat(hrt, source);
}
/* Expand the zero-compressed UPCE code to make a UPCA equivalent (EN Table 5) */
emode = source[5];
for(i = 0; i < 11; i++) {
equivalent[i] = '0';
}
equivalent[1] = source[0];
equivalent[2] = source[1];
equivalent[11] = '\0';
switch(emode)
{
case '0':
case '1':
case '2':
equivalent[3] = emode;
equivalent[8] = source[2];
equivalent[9] = source[3];
equivalent[10] = source[4];
break;
case '3':
equivalent[3] = source[2];
equivalent[9] = source[3];
equivalent[10] = source[4];
if(((source[2] == '0') || (source[2] == '1')) || (source[2] == '2')) {
/* Note 1 - "X3 shall not be equal to 0, 1 or 2" */
strcpy(symbol->errtxt, "warning: invalid UPC-E data");
}
break;
case '4':
equivalent[3] = source[2];
equivalent[4] = source[3];
equivalent[10] = source[4];
if(source[3] == '0') {
/* Note 2 - "X4 shall not be equal to 0" */
strcpy(symbol->errtxt, "warning: invalid UPC-E data");
}
break;
case '5':
case '6':
case '7':
case '8':
case '9':
equivalent[3] = source[2];
equivalent[4] = source[3];
equivalent[5] = source[4];
equivalent[10] = emode;
if(source[4] == '0') {
/* Note 3 - "X5 shall not be equal to 0" */
strcpy(symbol->errtxt, "warning: invalid UPC-E data");
}
break;
}
/* Get the check digit from the expanded UPCA code */
check_digit = upc_check(equivalent);
/* Use the number system and check digit information to choose a parity scheme */
if(num_system == 1) {
strcpy(parity, UPCParity1[ctoi(check_digit)]);
} else {
strcpy(parity, UPCParity0[ctoi(check_digit)]);
}
/* Take all this information and make the barcode pattern */
/* start character */
concat (dest, "111");
for(i = 0; i <= strlen(source); i++) {
switch(parity[i]) {
case 'A': lookup(NESET, EANsetA, source[i], dest); break;
case 'B': lookup(NESET, EANsetB, source[i], dest); break;
}
}
/* stop character */
concat (dest, "111111");
hrt[7] = check_digit;
hrt[8] = '\0';
strcpy(symbol->text, hrt);
}
void add_on(unsigned char source[], char dest[], int mode)
{ /* EAN-2 and EAN-5 add-on codes */
char parity[6];
unsigned int i, code_type;
/* If an add-on then append with space */
if (mode != 0)
{
concat(dest, "9");
}
/* Start character */
concat (dest, "112");
/* Determine EAN2 or EAN5 add-on */
if(strlen(source) == 2)
{
code_type = EAN2;
}
else
{
code_type = EAN5;
}
/* Calculate parity for EAN2 */
if(code_type == EAN2)
{
int code_value, parity_bit;
code_value = (10 * ctoi(source[0])) + ctoi(source[1]);
parity_bit = code_value%4;
strcpy(parity, EAN2Parity[parity_bit]);
}
if(code_type == EAN5)
{
int values[6], parity_sum, parity_bit;
for(i = 0; i < 6; i++)
{
values[i] = ctoi(source[i]);
}
parity_sum = (3 * (values[0] + values[2] + values[4]));
parity_sum += (9 * (values[1] + values[3]));
parity_bit = parity_sum%10;
strcpy(parity, EAN5Parity[parity_bit]);
}
for(i = 0; i < strlen(source); i++)
{
switch(parity[i]) {
case 'A': lookup(NESET, EANsetA, source[i], dest); break;
case 'B': lookup(NESET, EANsetB, source[i], dest); break;
}
/* Glyph separator */
if(i != (strlen(source) - 1))
{
concat (dest, "11");
}
}
}
/* ************************ EAN-13 ****************** */
char ean_check(unsigned char source[])
{ /* Calculate the correct check digit for a EAN-13 barcode */
int i;
unsigned int h, count, check_digit;
count = 0;
h = strlen(source);
for (i = h - 1; i >= 0; i--)
{
count += ctoi(source[i]);
if (!((i%2) == 0))
{
count += 2 * ctoi(source[i]);
}
}
check_digit = 10 - (count%10);
if (check_digit == 10) { check_digit = 0; }
return itoc(check_digit);
}
void ean13(struct zint_symbol *symbol, unsigned char source[], char dest[])
{
unsigned int length, i, half_way;
char parity[6];
strcpy(parity, "");
/* Add the appropriate check digit */
length = strlen(source);
source[length] = ean_check(source);
source[length + 1] = '\0';
/* Get parity for first half of the symbol */
lookup(NASET, EAN13Parity, source[0], parity);
/* Now get on with the cipher */
half_way = 7;
/* start character */
concat (dest, "111");
for(i = 1; i <= strlen(source); i++)
{
if (i == half_way)
{
/* middle character - separates manufacturer no. from product no. */
/* also inverses right hand characters */
concat (dest, "11111");
}
if(((i > 1) && (i < 7)) && (parity[i - 2] == 'B'))
{
lookup(NESET, EANsetB, source[i], dest);
}
else
{
lookup(NESET, EANsetA, source[i], dest);
}
}
/* stop character */
concat (dest, "111");
strcpy(symbol->text, source);
}
void ean8(struct zint_symbol *symbol, unsigned char source[], char dest[])
{ /* Make an EAN-8 barcode when we haven't been given the check digit */
/* EAN-8 is basically the same as UPC-A but with fewer digits */
int length;
length = strlen(source);
source[length] = upc_check(source);
source[length + 1] = '\0';
upca_draw(source, dest);
strcpy(symbol->text, source);
}
char isbn13_check(unsigned char source[]) /* For ISBN(13) only */
{
unsigned int i, weight, sum, check;
sum = 0;
weight = 1;
for(i = 0; i < (strlen(source) - 1); i++)
{
sum += ctoi(source[i]) * weight;
if(weight == 1) weight = 3; else weight = 1;
}
check = sum % 10;
check = 10 - check;
return itoc(check);
}
char isbn_check(unsigned char source[]) /* For ISBN(10) and SBN only */
{
unsigned int i, weight, sum, check;
sum = 0;
weight = 1;
for(i = 0; i < (strlen(source) - 1); i++)
{
sum += ctoi(source[i]) * weight;
weight++;
}
check = sum % 11;
return itoc(check);
}
int isbn(struct zint_symbol *symbol, unsigned char source[], char dest[]) /* Make an EAN-13 barcode from an SBN or ISBN */
{
int i, errno;
char check_digit;
errno = 0;
to_upper(source);
errno = is_sane("0123456789X", source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in input");
return errno;
}
/* Input must be 9, 10 or 13 characters */
if(((strlen(source) < 9) || (strlen(source) > 13)) || ((strlen(source) > 10) && (strlen(source) < 13)))
{
strcpy(symbol->errtxt, "error: input wrong length");
return ERROR_TOO_LONG;
}
if(strlen(source) == 13) /* Using 13 character ISBN */
{
if(!(((source[0] == '9') && (source[1] == '7')) &&
((source[2] == '8') || (source[2] == '9'))))
{
strcpy(symbol->errtxt, "error: invalid ISBN");
return ERROR_INVALID_DATA;
}
check_digit = isbn13_check(source);
if (source[strlen(source) - 1] != check_digit)
{
strcpy(symbol->errtxt, "error: incorrect ISBN check");
return ERROR_INVALID_CHECK;
}
source[12] = '\0';
ean13(symbol, source, dest);
}
if(strlen(source) == 10) /* Using 10 digit ISBN */
{
check_digit = isbn_check(source);
if(check_digit != source[strlen(source) - 1])
{
strcpy(symbol->errtxt, "error: incorrect ISBN check");
return ERROR_INVALID_CHECK;
}
for(i = 13; i > 0; i--)
{
source[i] = source[i - 3];
}
source[0] = '9';
source[1] = '7';
source[2] = '8';
source[12] = '\0';
ean13(symbol, source, dest);
}
if(strlen(source) == 9) /* Using 9 digit SBN */
{
/* Add leading zero */
for(i = 10; i > 0; i--)
{
source[i] = source[i - 1];
}
source[0] = '0';
/* Verify check digit */
check_digit = isbn_check(source);
if(check_digit != source[strlen(source) - 1])
{
strcpy(symbol->errtxt, "error: incorrect SBN check");
return ERROR_INVALID_CHECK;
}
/* Convert to EAN-13 number */
for(i = 13; i > 0; i--)
{
source[i] = source[i - 3];
}
source[0] = '9';
source[1] = '7';
source[2] = '8';
source[12] = '\0';
ean13(symbol, source, dest);
}
return errno;
}
int eanx(struct zint_symbol *symbol, unsigned char source[])
{
/* splits string to parts before and after '+' parts */
char first_part[20], second_part[20], dest[1000];
unsigned int latch, reader, writer, with_addon;
strcpy(first_part, "");
strcpy(second_part, "");
int errno, i;
errno = 0;
strcpy(dest, "");
with_addon = FALSE;
latch = FALSE;
writer = 0;
if(strlen(source) > 19) {
strcpy(symbol->errtxt, "error: input too long");
return ERROR_TOO_LONG;
}
if(symbol->symbology != BARCODE_ISBNX) {
/* ISBN has it's own checking routine */
errno = is_sane(NASET, source);
if(errno == ERROR_INVALID_DATA) {
strcpy(symbol->errtxt, "error: invalid characters in data");
return errno;
}
}
for(reader = 0; reader <= strlen(source); reader++)
{
if(source[reader] == '+') { with_addon = TRUE; }
}
reader = 0;
if(with_addon) {
do {
if(source[reader] == '+') {
first_part[writer] = '\0';
latch = TRUE;
reader++;
writer = 0;
}
if(latch) {
second_part[writer] = source[reader];
reader++;
writer++;
} else {
first_part[writer] = source[reader];
reader++;
writer++;
}
} while (reader <= strlen(source));
} else {
strcpy(first_part, source);
}
switch(symbol->symbology)
{
case BARCODE_EANX:
switch(strlen(first_part))
{
case 2: add_on(first_part, dest, 0); strcpy(symbol->text, first_part); break;
case 5: add_on(first_part, dest, 0); strcpy(symbol->text, first_part); break;
case 7: ean8(symbol, first_part, dest); break;
case 12: ean13(symbol, first_part, dest); break;
default: strcpy(symbol->errtxt, "error: invalid length input"); return ERROR_TOO_LONG; break;
}
break;
case BARCODE_EANX_CC:
switch(strlen(first_part))
{ /* Adds vertical separator bars according to ISO/IEC 24723 section 11.4 */
case 7: symbol->encoded_data[symbol->rows][1] = '1';
symbol->encoded_data[symbol->rows][67] = '1';
symbol->encoded_data[symbol->rows + 1][0] = '1';
symbol->encoded_data[symbol->rows + 1][68] = '1';
symbol->encoded_data[symbol->rows + 2][1] = '1';
symbol->encoded_data[symbol->rows + 2][67] = '1';
symbol->row_height[symbol->rows] = 2;
symbol->row_height[symbol->rows + 1] = 2;
symbol->row_height[symbol->rows + 2] = 2;
symbol->rows += 3;
ean8(symbol, first_part, dest); break;
case 12:symbol->encoded_data[symbol->rows][1] = '1';
symbol->encoded_data[symbol->rows][95] = '1';
symbol->encoded_data[symbol->rows + 1][0] = '1';
symbol->encoded_data[symbol->rows + 1][96] = '1';
symbol->encoded_data[symbol->rows + 2][1] = '1';
symbol->encoded_data[symbol->rows + 2][95] = '1';
symbol->row_height[symbol->rows] = 2;
symbol->row_height[symbol->rows + 1] = 2;
symbol->row_height[symbol->rows + 2] = 2;
symbol->rows += 3;
ean13(symbol, first_part, dest); break;
default: strcpy(symbol->errtxt, "error: invalid length EAN input"); return ERROR_TOO_LONG; break;
}
break;
case BARCODE_UPCA:
if(strlen(first_part) == 11) {
upca(symbol, first_part, dest);
} else {
strcpy(symbol->errtxt, "error: input wrong length");
return ERROR_TOO_LONG;
}
break;
case BARCODE_UPCA_CC:
if(strlen(first_part) == 11) {
symbol->encoded_data[symbol->rows][1] = '1';
symbol->encoded_data[symbol->rows][95] = '1';
symbol->encoded_data[symbol->rows + 1][0] = '1';
symbol->encoded_data[symbol->rows + 1][96] = '1';
symbol->encoded_data[symbol->rows + 2][1] = '1';
symbol->encoded_data[symbol->rows + 2][95] = '1';
symbol->row_height[symbol->rows] = 2;
symbol->row_height[symbol->rows + 1] = 2;
symbol->row_height[symbol->rows + 2] = 2;
symbol->rows += 3;
upca(symbol, first_part, dest);
} else {
strcpy(symbol->errtxt, "error: UPCA input wrong length");
return ERROR_TOO_LONG;
}
break;
case BARCODE_UPCE:
if((strlen(first_part) >= 6) && (strlen(first_part) <= 7)) {
upce(symbol, first_part, dest);
} else {
strcpy(symbol->errtxt, "error: input wrong length");
return ERROR_TOO_LONG;
}
break;
case BARCODE_UPCE_CC:
if((strlen(first_part) >= 6) && (strlen(first_part) <= 7)) {
symbol->encoded_data[symbol->rows][1] = '1';
symbol->encoded_data[symbol->rows][51] = '1';
symbol->encoded_data[symbol->rows + 1][0] = '1';
symbol->encoded_data[symbol->rows + 1][52] = '1';
symbol->encoded_data[symbol->rows + 2][1] = '1';
symbol->encoded_data[symbol->rows + 2][51] = '1';
symbol->row_height[symbol->rows] = 2;
symbol->row_height[symbol->rows + 1] = 2;
symbol->row_height[symbol->rows + 2] = 2;
symbol->rows += 3;
upce(symbol, first_part, dest);
} else {
strcpy(symbol->errtxt, "error: UPCE input wrong length");
return ERROR_TOO_LONG;
}
break;
case BARCODE_ISBNX:
errno = isbn(symbol, first_part, dest);
if(errno > 4) {
return errno;
}
break;
}
switch(strlen(second_part))
{
case 0: break;
case 2:
add_on(second_part, dest, 1);
concat(symbol->text, "+");
concat(symbol->text, second_part);
break;
case 5:
add_on(second_part, dest, 1);
concat(symbol->text, "+");
concat(symbol->text, second_part);
break;
default:
strcpy(symbol->errtxt, "error: invalid length input");
return ERROR_TOO_LONG;
break;
}
expand(symbol, dest);
switch(symbol->symbology) {
case BARCODE_EANX_CC:
case BARCODE_UPCA_CC:
case BARCODE_UPCE_CC:
/* shift the symbol to the right one space to allow for separator bars */
for(i = (symbol->width + 1); i >= 1; i--) {
symbol->encoded_data[symbol->rows - 1][i] = symbol->encoded_data[symbol->rows - 1][i - 1];
}
symbol->encoded_data[symbol->rows - 1][0] = '0';
symbol->width += 2;
break;
}
if((symbol->errtxt[0] == 'w') && (errno == 0)) {
errno = 1; /* flag UPC-E warnings */
}
return errno;
}
+133
View File
@@ -0,0 +1,133 @@
/* zint.h - definitions for libzint
libzint - the open source barcode library
Copyright (C) 2008 Robin Stuart <zint@hotmail.co.uk>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#define VERSION "1.6.0"
struct zint_symbol {
int symbology;
int height;
int whitespace_width;
int border_width;
int output_options;
char fgcolour[10];
char bgcolour[10];
char outfile[256];
int option_1;
int option_2;
char text[100];
int rows;
int width;
char primary[100];
char encoded_data[155][1000];
int row_height[155];
char errtxt[100];
};
#define BARCODE_CODE11 1
#define BARCODE_C25MATRIX 2
#define BARCODE_C25INTER 3
#define BARCODE_C25IATA 4
#define BARCODE_C25LOGIC 6
#define BARCODE_C25IND 7
#define BARCODE_CODE39 8
#define BARCODE_EXCODE39 9
#define BARCODE_EANX 13
#define BARCODE_EAN128 16
#define BARCODE_CODABAR 18
#define BARCODE_CODE128 20
#define BARCODE_DPLEIT 21
#define BARCODE_DPIDENT 22
#define BARCODE_CODE16K 23
#define BARCODE_CODE93 25
#define BARCODE_FLAT 28
#define BARCODE_RSS14 29
#define BARCODE_RSS_LTD 30
#define BARCODE_RSS_EXP 31
#define BARCODE_TELEPEN 32
#define BARCODE_UPCA 34
#define BARCODE_UPCE 37
#define BARCODE_POSTNET 40
#define BARCODE_MSI_PLESSEY 47
#define BARCODE_FIM 49
#define BARCODE_LOGMARS 50
#define BARCODE_PHARMA 51
#define BARCODE_PZN 52
#define BARCODE_PHARMA_TWO 53
#define BARCODE_PDF417 55
#define BARCODE_PDF417TRUNC 56
#define BARCODE_MAXICODE 57
#define BARCODE_QRCODE 58
#define BARCODE_CODE128B 60
#define BARCODE_AUSPOST 63
#define BARCODE_AUSREPLY 66
#define BARCODE_AUSROUTE 67
#define BARCODE_AUSREDIRECT 68
#define BARCODE_ISBNX 69
#define BARCODE_RM4SCC 70
#define BARCODE_DATAMATRIX 71
#define BARCODE_ITF14 72
#define BARCODE_NVE18 75
#define BARCODE_KOREAPOST 77
#define BARCODE_RSS14STACK 79
#define BARCODE_RSS14STACK_OMNI 80
#define BARCODE_RSS_EXPSTACK 81
#define BARCODE_PLANET 82
#define BARCODE_MICROPDF417 84
#define BARCODE_ONECODE 85
#define BARCODE_PLESSEY 86
#define BARCODE_TELEPEN_NUM 100
#define BARCODE_MSI_10 101
#define BARCODE_MSI_10_10 102
#define BARCODE_MSI_11 103
#define BARCODE_MSI_11_10 104
#define BARCODE_CODE39_43 105
#define BARCODE_EXCODE39_43 106
#define BARCODE_AZTEC 107
#define BARCODE_SUPER 108
#define BARCODE_ULTRA 109
#define BARCODE_EANX_CC 110
#define BARCODE_EAN128_CC 111
#define BARCODE_RSS14_CC 112
#define BARCODE_RSS_LTD_CC 113
#define BARCODE_RSS_EXP_CC 114
#define BARCODE_UPCA_CC 115
#define BARCODE_UPCE_CC 116
#define BARCODE_RSS14STACK_CC 117
#define BARCODE_RSS14_OMNI_CC 118
#define BARCODE_RSS_EXPSTACK_CC 119
#define BARCODE_NO_ASCII 1
#define BARCODE_BIND 2
#define BARCODE_BOX 4
#define WARN_INVALID_OPTION 2
#define ERROR_TOO_LONG 5
#define ERROR_INVALID_DATA 6
#define ERROR_INVALID_CHECK 7
#define ERROR_INVALID_OPTION 8
#define ERROR_ENCODING_PROBLEM 9
#define ERROR_FILE_ACCESS 10
#define ERROR_MEMORY 11
extern struct zint_symbol *ZBarcode_Create();
extern int ZBarcode_Delete(struct zint_symbol *symbol);
extern int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *input);
extern int ZBarcode_Print(struct zint_symbol *symbol);
extern int ZBarcode_Encode_and_Print(struct zint_symbol *symbol, unsigned char *input);