/* Private types. */
/*========================================================*/
-typedef struct {
- gchar c;
- gchar *sym;
-} Code39Symbol;
-
/*===========================================*/
/* Private globals */
/*===========================================*/
-static Code39Symbol symbols[] = {
- /* BsBsBsBsB */
- { '0', "NnNwWnWnN" },
- { '1', "WnNwNnNnW" },
- { '2', "NnWwNnNnW" },
- { '3', "WnWwNnNnN" },
- { '4', "NnNwWnNnW" },
- { '5', "WnNwWnNnN" },
- { '6', "NnWwWnNnN" },
- { '7', "NnNwNnWnW" },
- { '8', "WnNwNnWnN" },
- { '9', "NnWwNnWnN" },
- { 'A', "WnNnNwNnW" },
- { 'B', "NnWnNwNnW" },
- { 'C', "WnWnNwNnN" },
- { 'D', "NnNnWwNnW" },
- { 'E', "WnNnWwNnN" },
- { 'F', "NnWnWwNnN" },
- { 'G', "NnNnNwWnW" },
- { 'H', "WnNnNwWnN" },
- { 'I', "NnWnNwWnN" },
- { 'J', "NnNnWwWnN" },
- { 'K', "WnNnNnNwW" },
- { 'L', "NnWnNnNwW" },
- { 'M', "WnWnNnNwN" },
- { 'N', "NnNnWnNwW" },
- { 'O', "WnNnWnNwN" },
- { 'P', "NnWnWnNwN" },
- { 'Q', "NnNnNnWwW" },
- { 'R', "WnNnNnWwN" },
- { 'S', "NnWnNnWwN" },
- { 'T', "NnNnWnWwN" },
- { 'U', "WwNnNnNnW" },
- { 'V', "NwWnNnNnW" },
- { 'W', "WwWnNnNnN" },
- { 'X', "NwNnWnNnW" },
- { 'Y', "WwNnWnNnN" },
- { 'Z', "NwWnWnNnN" },
- { '-', "NwNnNnWnW" },
- { '.', "WwNnNnWnN" },
- { ' ', "NwWnNnWnN" },
- { '$', "NwNwNwNnN" },
- { '/', "NwNwNnNwN" },
- { '+', "NwNnNwNwN" },
- { '%', "NnNwNwNwN" },
- { 0, NULL }
+/* Code 39 alphabet. Position indicates value. */
+static gchar *alphabet = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%";
+
+/* Code 39 symbols. Position must match position in alphabet. */
+static gchar* symbols[43] = {
+ /* BsBsBsBsB */
+ /* 0 */ "NnNwWnWnN",
+ /* 1 */ "WnNwNnNnW",
+ /* 2 */ "NnWwNnNnW",
+ /* 3 */ "WnWwNnNnN",
+ /* 4 */ "NnNwWnNnW",
+ /* 5 */ "WnNwWnNnN",
+ /* 6 */ "NnWwWnNnN",
+ /* 7 */ "NnNwNnWnW",
+ /* 8 */ "WnNwNnWnN",
+ /* 9 */ "NnWwNnWnN",
+ /* A */ "WnNnNwNnW",
+ /* B */ "NnWnNwNnW",
+ /* C */ "WnWnNwNnN",
+ /* D */ "NnNnWwNnW",
+ /* E */ "WnNnWwNnN",
+ /* F */ "NnWnWwNnN",
+ /* G */ "NnNnNwWnW",
+ /* H */ "WnNnNwWnN",
+ /* I */ "NnWnNwWnN",
+ /* J */ "NnNnWwWnN",
+ /* K */ "WnNnNnNwW",
+ /* L */ "NnWnNnNwW",
+ /* M */ "WnWnNnNwN",
+ /* N */ "NnNnWnNwW",
+ /* O */ "WnNnWnNwN",
+ /* P */ "NnWnWnNwN",
+ /* Q */ "NnNnNnWwW",
+ /* R */ "WnNnNnWwN",
+ /* S */ "NnWnNnWwN",
+ /* T */ "NnNnWnWwN",
+ /* U */ "WwNnNnNnW",
+ /* V */ "NwWnNnNnW",
+ /* W */ "WwWnNnNnN",
+ /* X */ "NwNnWnNnW",
+ /* Y */ "WwNnWnNnN",
+ /* Z */ "NwWnWnNnN",
+ /* - */ "NwNnNnWnW",
+ /* . */ "WwNnNnWnN",
+ /* */ "NwWnNnWnN",
+ /* $ */ "NwNwNwNnN",
+ /* / */ "NwNwNnNwN",
+ /* + */ "NwNnNwNwN",
+ /* % */ "NnNwNwNwN",
};
static gchar *frame_symbol = "NwNnWnWnN";
/* Local function prototypes */
/*===========================================*/
-static gchar *code39_encode (const gchar *data,
- gboolean checksum_flag);
+static gboolean code39_is_data_valid (const gchar *data);
+static gboolean code39_ext_is_data_valid (const gchar *data);
-static lglBarcode *code39_vectorize (const gchar *code,
- gdouble w,
- gdouble h,
- gboolean text_flag,
- gboolean checksum_flag,
- const gchar *data,
- const gchar *string);
+static gchar *code39_encode (const gchar *data,
+ gboolean checksum_flag);
+
+static lglBarcode *code39_vectorize (const gchar *code,
+ gdouble w,
+ gdouble h,
+ gboolean text_flag,
+ gboolean checksum_flag,
+ const gchar *data,
+ const gchar *string);
/****************************************************************************/
-/* Generate list of lines that form the barcode for the given digits. */
+/* Generate new Code 39 barcode structure from data. */
/****************************************************************************/
lglBarcode *
lgl_barcode_code39_new (lglBarcodeType type,
}
- /* Canonicalize data. */
- if ( data[0] == '\0' )
+ /* Validate data. */
+ if (type == LGL_BARCODE_TYPE_CODE39)
{
- return NULL;
+ if ( !code39_is_data_valid (data) )
+ {
+ return NULL;
+ }
+ canon_data = g_ascii_strup (data, -1);
+ display_data = g_strdup (canon_data);
}
- if (type == LGL_BARCODE_TYPE_CODE39_EXT)
+ else
{
GString *canon_data_str;
- GString *display_data_str;
+
+ if ( !code39_ext_is_data_valid (data) )
+ {
+ return NULL;
+ }
canon_data_str = g_string_new ("");
- display_data_str = g_string_new ("");
for ( p = (gchar *)data; *p != '\0'; p++ )
{
- canon_data_str = g_string_append (canon_data_str, ascii_map[(*p) & 0x7F]);
- display_data_str = g_string_append_c (display_data_str, (*p) & 0x7F);
+ canon_data_str = g_string_append (canon_data_str, ascii_map[(int)*p]);
}
-
canon_data = g_string_free (canon_data_str, FALSE);
- display_data = g_string_free (display_data_str, FALSE);
- }
- else
- {
- canon_data = g_ascii_strup (data, -1);
- g_strcanon (canon_data, "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-. $/+%", ' ');
- display_data = g_strdup (canon_data);
+
+ display_data = g_strdup (data);
}
/* First get code string */
code = code39_encode (canon_data, checksum_flag);
- if (code == NULL) {
+ if (code == NULL)
+ {
g_free (canon_data);
g_free (display_data);
return NULL;
}
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Validate data for Code 39. */
+/*--------------------------------------------------------------------------*/
+static gboolean
+code39_is_data_valid (const gchar *data)
+{
+ gchar *p;
+ gchar c;
+
+ if (!data || (*data == '\0'))
+ {
+ return FALSE;
+ }
+
+ for ( p = (gchar *)data; *p != 0; p++ )
+ {
+ c = g_ascii_toupper (*p);
+
+ if ( strchr(alphabet, c) == NULL )
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Validate data for Extended Code 39. */
+/*--------------------------------------------------------------------------*/
+static gboolean
+code39_ext_is_data_valid (const gchar *data)
+{
+ gchar *p;
+
+ if (!data || (*data == '\0'))
+ {
+ return FALSE;
+ }
+
+ for ( p = (gchar *)data; *p != 0; p++ )
+ {
+ if ( (*p < 0) || (*p > 0x7f) )
+ {
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
+
/*--------------------------------------------------------------------------*/
/* PRIVATE. Generate string of symbols, representing barcode. */
/*--------------------------------------------------------------------------*/
gboolean checksum_flag)
{
gchar *p, c;
- gint i, sum;
+ gint c_value, sum;
GString *code;
sum = 0;
for ( p=(gchar *)data; *p != 0; p++ )
{
- c = toupper( *p );
- for ( i = 0; symbols[i].c != 0; i++ )
- {
- if ( c == symbols[i].c )
- {
- sum += i;
- code = g_string_append (code, symbols[i].sym);
- break;
- }
- }
+ c = g_ascii_toupper( *p );
+ c_value = strchr(alphabet, c) - alphabet;
+ code = g_string_append (code, symbols[c_value]);
code = g_string_append (code, "i");
+
+ sum += c_value;
}
if ( checksum_flag )
{
- code = g_string_append (code, symbols[sum % 43].sym);
+ code = g_string_append (code, symbols[sum % 43]);
code = g_string_append (code, "i");
}
/*--------------------------------------------------------------------------*/
-/* Generate list of rectangles that form the barcode for the given digits. */
+/* PRIVATE. Vectorize encoded barcode. */
/*--------------------------------------------------------------------------*/
static lglBarcode *
code39_vectorize (const gchar *code,
};
-
-
/*===========================================*/
/* Local function prototypes */
/*===========================================*/
-static gboolean is_string_valid (const gchar *data);
-
-static gchar *onecode_encode (const gchar *data);
-
-static void int104_mult_uint (Int104 *x,
- guint y);
-static void int104_add_uint (Int104 *x,
- guint y);
-static void int104_add_uint64 (Int104 *x,
- guint64 y);
-static guint int104_div_uint (Int104 *x,
- guint y);
+static gboolean onecode_is_data_valid (const gchar *data);
+
+static gchar *onecode_encode (const gchar *data);
+
+static lglBarcode *onecode_vectorize (const gchar *code);
+
+static void int104_mult_uint (Int104 *x,
+ guint y);
+static void int104_add_uint (Int104 *x,
+ guint y);
+static void int104_add_uint64 (Int104 *x,
+ guint64 y);
+static guint int104_div_uint (Int104 *x,
+ guint y);
#ifdef DEBUG
-static void int104_print (Int104 *x);
+static void int104_print (Int104 *x);
#endif
static unsigned short USPS_MSB_Math_CRC11GenerateFrameCheckSequence( unsigned char *ByteArrayPtr );
-static lglBarcode *onecode_vectorize (const gchar *code);
-
/****************************************************************************/
-/* Generate list of lines that form the barcode for the given digits. */
+/* Generate new One Code barcode structure from data. */
/****************************************************************************/
lglBarcode *
lgl_barcode_onecode_new (lglBarcodeType type,
return NULL;
}
- /* First get code string */
+
+ /* Validate data */
+ if ( !onecode_is_data_valid (data) )
+ {
+ return NULL;
+ }
+
+ /* Now get code string */
code = onecode_encode (data);
if (code == NULL) {
return NULL;
}
+/*--------------------------------------------------------------------------*/
+/* Validate if string is of proper length & contains only valid characters. */
+/*--------------------------------------------------------------------------*/
+static gboolean
+onecode_is_data_valid (const gchar *data)
+{
+ gchar *p;
+ gint str_length;
+
+ if (!data)
+ {
+ return FALSE;
+ }
+
+ str_length = strlen (data);
+ if ( (str_length != 20) &&
+ (str_length != 25) &&
+ (str_length != 29) &&
+ (str_length != 31) )
+ {
+ return FALSE;
+ }
+
+ for ( p = (gchar *)data; *p != 0; p++ )
+ {
+ if (!g_ascii_isdigit (*p))
+ {
+ return FALSE;
+ }
+ }
+
+ if (data[1] > '4')
+ {
+ return FALSE; /* Invalid Barcode Identifier. */
+ }
+
+ return TRUE;
+}
+
+
/*--------------------------------------------------------------------------*/
/* PRIVATE. Generate string of symbols, representing barcode. */
/*--------------------------------------------------------------------------*/
gint d, a;
GString *code;
- if ( !is_string_valid (data) )
- {
- return NULL;
- }
-
-
/*-----------------------------------------------------------*/
/* Step 1 -- Conversion of Data Fields into Binary Data */
/*-----------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
-/* Validate if string is of proper length & contains only valid characters. */
+/* Vectorize encoded data. */
/*--------------------------------------------------------------------------*/
-static gboolean
-is_string_valid (const gchar *data)
+static lglBarcode *
+onecode_vectorize (const gchar *code)
{
- gchar *p;
- gint str_length;
-
- if (!data) {
- return FALSE;
- }
+ lglBarcode *bc;
+ gchar *p;
+ gdouble x, y, length, width;
- str_length = strlen (data);
- if ( (str_length != 20) &&
- (str_length != 25) &&
- (str_length != 29) &&
- (str_length != 31) )
- {
- return FALSE;
- }
+ bc = lgl_barcode_new ();
- for ( p = (gchar *)data; *p != 0; p++ )
+ /* Now traverse the code string and create a list of lines */
+ x = ONECODE_HORIZ_MARGIN;
+ for (p = (gchar *)code; *p != 0; p++)
{
- if (!g_ascii_isdigit (*p))
+ y = ONECODE_VERT_MARGIN;
+ switch ( *p )
{
- return FALSE;
+ case 'T':
+ y += ONECODE_TRACKER_OFFSET;
+ length = ONECODE_TRACKER_HEIGHT;
+ break;
+ case 'D':
+ y += ONECODE_DESCENDER_OFFSET;
+ length = ONECODE_DESCENDER_HEIGHT;
+ break;
+ case 'A':
+ y += ONECODE_ASCENDER_OFFSET;
+ length = ONECODE_ASCENDER_HEIGHT;
+ break;
+ case 'F':
+ y += ONECODE_FULL_OFFSET;
+ length = ONECODE_FULL_HEIGHT;
+ break;
+ default:
+ break;
}
- }
+ width = ONECODE_BAR_WIDTH;
- if (data[1] > '4')
- {
- return FALSE; /* Invalid Barcode Identifier. */
+ lgl_barcode_add_box (bc, x, y, width, length);
+
+ x += ONECODE_BAR_PITCH;
}
- return TRUE;
+ bc->width = x + ONECODE_HORIZ_MARGIN;
+ bc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
+
+ return bc;
}
}
-/*--------------------------------------------------------------------------*/
-/* Vectorize encoded data. */
-/*--------------------------------------------------------------------------*/
-static lglBarcode *
-onecode_vectorize (const gchar *code)
-{
- lglBarcode *bc;
- gchar *p;
- gdouble x, y, length, width;
-
- bc = lgl_barcode_new ();
-
- /* Now traverse the code string and create a list of lines */
- x = ONECODE_HORIZ_MARGIN;
- for (p = (gchar *)code; *p != 0; p++)
- {
- y = ONECODE_VERT_MARGIN;
- switch ( *p )
- {
- case 'T':
- y += ONECODE_TRACKER_OFFSET;
- length = ONECODE_TRACKER_HEIGHT;
- break;
- case 'D':
- y += ONECODE_DESCENDER_OFFSET;
- length = ONECODE_DESCENDER_HEIGHT;
- break;
- case 'A':
- y += ONECODE_ASCENDER_OFFSET;
- length = ONECODE_ASCENDER_HEIGHT;
- break;
- case 'F':
- y += ONECODE_FULL_OFFSET;
- length = ONECODE_FULL_HEIGHT;
- break;
- default:
- break;
- }
- width = ONECODE_BAR_WIDTH;
-
- lgl_barcode_add_box (bc, x, y, width, length);
-
- x += ONECODE_BAR_PITCH;
- }
-
- bc->width = x + ONECODE_HORIZ_MARGIN;
- bc->height = ONECODE_FULL_HEIGHT + 2 * ONECODE_VERT_MARGIN;
-
- return bc;
-}
-
-
/*
/*===========================================*/
/* Local function prototypes */
/*===========================================*/
-static gchar *postnet_encode (const gchar *digits);
+static gint postnet_validate_data (const gchar *data);
-static gboolean is_length_valid (const gchar *digits,
- gint n);
+static gchar *postnet_encode (const gchar *digits);
-static lglBarcode *postnet_vectorize (const gchar *code);
+static lglBarcode *postnet_vectorize (const gchar *code);
/****************************************************************************/
-/* Generate list of lines that form the barcode for the given digits. */
+/* Generate new Postnet barcode structure from data. */
/****************************************************************************/
lglBarcode *
lgl_barcode_postnet_new (lglBarcodeType type,
gdouble h,
const gchar *data)
{
+ gint n_digits;
gchar *code;
lglBarcode *bc;
- /* Validate code length for all subtypes. */
+ /* Validate data and length for all subtypes. */
+ n_digits = postnet_validate_data (data);
switch (type)
{
case LGL_BARCODE_TYPE_POSTNET:
- if (!is_length_valid (data, 5) &&
- !is_length_valid (data, 9) &&
- !is_length_valid (data, 11))
+ if ( (n_digits != 5) &&
+ (n_digits != 9) &&
+ (n_digits != 11) )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_POSTNET_5:
- if (!is_length_valid (data, 5))
+ if ( n_digits != 5 )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_POSTNET_9:
- if (!is_length_valid (data, 9))
+ if ( n_digits != 9 )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_POSTNET_11:
- if (!is_length_valid (data, 11))
+ if ( n_digits != 11 )
{
return NULL;
}
break;
case LGL_BARCODE_TYPE_CEPNET:
- if (!is_length_valid (data, 8))
+ if ( n_digits != 8 )
{
return NULL;
}
}
+/*--------------------------------------------------------------------------*/
+/* PRIVATE. Validate data, returning number of digits if valid. */
+/*--------------------------------------------------------------------------*/
+static gint
+postnet_validate_data (const gchar *data)
+{
+ gchar *p;
+ gint i;
+
+ if (!data)
+ {
+ return 0;
+ }
+
+ for ( p = (gchar *)data, i=0; *p != 0; p++ )
+ {
+ if (g_ascii_isdigit (*p))
+ {
+ i++;
+ }
+ else if ( (*p != '-') && (*p != ' ') )
+ {
+ /* Only allow digits, dashes, and spaces. */
+ return 0;
+ }
+ }
+
+ return i;
+}
+
+
/*--------------------------------------------------------------------------*/
/* PRIVATE. Generate string of symbols, representing barcode. */
/*--------------------------------------------------------------------------*/
code = g_string_new (frame_symbol);
sum = 0;
- for (p = (gchar *)data, len = 0; (*p != 0) && (len < 11); p++)
+ for ( p = (gchar *)data, len = 0; (*p != 0) && (len < 11); p++ )
{
if (g_ascii_isdigit (*p))
{
- /* Only translate valid characters (0-9) */
+ /* Only translate the digits (0-9) */
d = (*p) - '0';
sum += d;
code = g_string_append (code, symbols[d]);
}
-/*--------------------------------------------------------------------------*/
-/* PRIVATE. Validate specific length of string (for subtypes). */
-/*--------------------------------------------------------------------------*/
-static gboolean
-is_length_valid (const gchar *data,
- gint n)
-{
- gchar *p;
- gint i;
-
- if (!data)
- {
- return FALSE;
- }
-
- for (p = (gchar *)data, i=0; *p != 0; p++)
- {
- if (g_ascii_isdigit (*p))
- {
- i++;
- }
- }
-
- return (i == n);
-}
-
-
/*--------------------------------------------------------------------------*/
/* PRIVATE. Vectorize encoded barcode. */
/*--------------------------------------------------------------------------*/
/* Now traverse the code string and create a list of lines */
x = POSTNET_HORIZ_MARGIN;
- for (p = (gchar *)code; *p != 0; p++)
+ for ( p = (gchar *)code; *p != 0; p++ )
{
y = POSTNET_VERT_MARGIN;
switch (*p)