📄 iec16022ecc200.c
字号:
// IEC16022 bar code generation library
// This software is provided under the terms of the GPL v2 or later.
// This software is provided free of charge with a full "Money back" guarantee.
// Use entirely at your own risk. We accept no liability. If you don't like that - don't use it.
// Adrian Kennard, Andrews & Arnold Ltd
// with help from Cliff Hones on the RS coding
//
// $Log: iec16022ecc200.c,v $
// Revision 1.8 2004/09/12 10:35:25 cvs
// Minor fixes to auto encoding, and more precise placement of text on stamp output.
//
// Revision 1.7 2004/09/11 11:16:20 cvs
// Fixed binary format encoding, and added output file to indicia
//
// Revision 1.6 2004/09/10 16:10:30 cvs
// Correction of declaration ordering
//
// Revision 1.5 2004/09/09 12:35:48 cvs
// Interleaved (large) codes now working as well.
// Fixed bugs in the auto encoding (was selecting EDIFACT wrongly)
//
// Revision 1.4 2004/09/09 07:45:09 cvs
// Added change history to source files
// Added "info" type to IEC16022
// Added exact size checking shortcodes on encoding generation for iec16022
//
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <time.h>
#include <popt.h>
#include <malloc.h>
#include "reedsol.h"
#include "iec16022ecc200.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;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -