⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iec16022ecc200.c

📁 IEC16022 bar code generation library and RS encode
💻 C
📖 第 1 页 / 共 3 页
字号:
// 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 + -