Code 128 barcode does not work properly

Bug #529114 reported by Horst Schottky
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
Inkscape
Fix Released
Medium
Unassigned

Bug Description

The changing Codes #99 - #100 - #101 are not correct calculated .
Barcodes with more than one code section (e.g. an odd count >5 of digits or letter and digits mixed) causes an error in inkscape and would otherwise not recognized by a scanner.
The code near the line 100 should be changed from

   num = num + (math.abs(num - 102) * 2)

to

  num = 204 - num

Furthermore a two digit Barcde is not optimized in Code 128C but its printed in Code 128A.
A simple change in the regex near line 55 could fix it:
Cange

  for datum in re.findall(r'(?:(?:\d\d){2,})|.', text):

to

  for datum in re.findall(r'(?:(?:\d\d){2,})|(?:^\d\d)|.', text):

here is the complete working Version:

'''
Copyright (C) 2007 Martin Owens

Debugged by Ralf Heinecke & Martin Siepmann 09/07/2007
Debugged by Horst Schottky Feb. 27. 2010

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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

'''

from Base import Barcode
import math
import re

map = [ '11011001100','11001101100','11001100110','10010011000','10010001100','10001001100','10011001000','10011000100','10001100100','11001001000','11001000100','11000100100','10110011100','10011011100','10011001110','10111001100','10011101100','10011100110','11001110010','11001011100','11001001110','11011100100','11001110100','11101101110','11101001100','11100101100','11100100110','11101100100','11100110100','11100110010','11011011000','11011000110','11000110110','10100011000','10001011000','10001000110','10110001000','10001101000','10001100010','11010001000','11000101000','11000100010','10110111000','10110001110','10001101110','10111011000','10111000110','10001110110','11101110110','11010001110','11000101110','11011101000','11011100010','11011101110','11101011000','11101000110','11100010110','11101101000','11101100010','11100011010','11101111010','11001000010','11110001010','10100110000','10100001100','10010110000','10010000110','10000101100','10000100110','10110010000','10110000100','10011010000','10011000010','10000110100','10000110010','11000010010','11001010000','11110111010','11000010100','10001111010','10100111100','10010111100','10010011110','10111100100','10011110100','10011110010','11110100100','11110010100','11110010010','11011011110','11011110110','11110110110','10101111000','10100011110','10001011110','10111101000','10111100010','11110101000','11110100010','10111011110','10111101110','11101011110','11110101110','11010000100','11010010000','11010011100','11000111010','11' ]

def mapExtra(sd, chars):
 result = list(sd)
 for char in chars:
  result.append(chr(char))
 result.append('FNC3')
 result.append('FNC2')
 result.append('SHIFT')
 return result

# The mapExtra method is used to slim down the amount
# of pre code and instead we generate the lists
charAB = list(' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_')
charA = mapExtra(charAB, range(0, 31)) # Offset 64
charB = mapExtra(charAB, range(96, 125)) # Offset -32

class Object(Barcode):
 def encode(self, text):
  result = ''
  blocks = []
  block = ''

  # Split up into sections of numbers, or charicters
  # This makes sure that all the charicters are encoded
  # In the best way posible for Code128
  for datum in re.findall(r'(?:(?:\d\d){2,})|(?:^\d\d)|.', text):
   if len(datum) == 1:
    block = block + datum
   else:
    if block:
     blocks.append(self.bestBlock(block))
     block = ''
    blocks.append( [ 'C', datum ] )

  if block:
   blocks.append(self.bestBlock(block))
   block = '';

  self.inclabel = text
  return self.encodeBlocks(blocks)

 def bestBlock(self, block):
  # If this has lower case then select B over A
  if block.upper() == block:
   return [ 'A', block ]
  return [ 'B', block ]

 def encodeBlocks(self, blocks):
  total = 0
  pos = 0
  encode = '';

  for block in blocks:
   set = block[0]
   datum = block[1]

   # POS : 0, 1
   # A : 101, 103
   # B : 100, 104
   # C : 99, 105
   num = 0;
   if set == 'A':
    num = 103
   elif set == 'B':
    num = 104
   elif set == 'C':
    num = 105

   i = pos
   if pos:
    num = 204 - num
   else:
    i = 1

   total = total + num * i
   encode = encode + map[num]
   pos = pos + 1

   if set == 'A' or set == 'B':
    chars = charB
    if set == 'A':
     chars = charA

    for char in datum:
     total = total + (chars.index(char) * pos)
     encode = encode + map[chars.index(char)]
     pos = pos + 1
   else:
    for char in (datum[i:i+2] for i in range(0, len(datum), 2)):
     total = total + (int(char) * pos)
     encode = encode + map[int(char)]
     pos = pos + 1

  checksum = total % 103
  encode = encode + map[checksum]
  encode = encode + map[106]
  encode = encode + map[107]

  return encode

Related branches

Revision history for this message
Horst Schottky (hog) wrote :
su_v (suv-lp)
tags: added: extensions-plugins
summary: - Code 128 does not work properly
+ Code 128 barcode does not work properly
Revision history for this message
Alvin Penner (apenner) wrote :

for testing purposes, could you provide a few examples of codes that work with the new version and previously did not work?

Revision history for this message
Horst Schottky (hog) wrote :

The input '12345' causes an error as shown in the attached screenshot '12345_in_old_Bacode128.png'.
The input 'abc1234' causes the same error - also shown in a screenshot 'abc1234_in_old_Barcode128.png'
The output with the fixed Code128.py is shown in the screenshots '12345_in_new_Barcode128.png' and 'abc1234_in_new_Barcode128.png'

The difference of the length in two-digits-input is shown in the screenshot '12_in_old_and_new_Barcode128'

Revision history for this message
Horst Schottky (hog) wrote :
Revision history for this message
Horst Schottky (hog) wrote :
Revision history for this message
Horst Schottky (hog) wrote :
Revision history for this message
Horst Schottky (hog) wrote :
Revision history for this message
Alvin Penner (apenner) wrote :

thanks, Horst, committed to bzr 9119.

Changed in inkscape:
status: New → Fix Committed
jazzynico (jazzynico)
Changed in inkscape:
milestone: none → 0.48
Changed in inkscape:
importance: Undecided → Medium
jazzynico (jazzynico)
Changed in inkscape:
status: Fix Committed → Fix Released
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.