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

📄 iec16022ecc200.c

📁 IEC16022 bar code generation library and RS encode
💻 C
📖 第 1 页 / 共 3 页
字号:
               }
               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
   {
      short s;                  // number of bytes of source that can be encoded in a row at this point using this encoding mode
      short t;                  // number of bytes of target generated encoding from this point to end if already in this encoding mode
   } 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;
      }

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -