From 0e560805b420d467cb14803cc843d6662a7d4238 Mon Sep 17 00:00:00 2001 From: hooper114 Date: Sat, 16 May 2009 14:19:43 +0000 Subject: [PATCH] Add Channel Code --- backend/code.c | 144 +++++++++++++++++++++++++++++++++--- backend/dm200.c | 6 +- backend/library.c | 4 +- backend/svg.c | 2 +- backend/zint.h | 1 + frontend_qt4/mainWindow.ui | 71 ++++++++++++++++++ frontend_qt4/mainwindow.cpp | 20 ++++- frontend_qt4/mainwindow.h | 1 + 8 files changed, 232 insertions(+), 17 deletions(-) diff --git a/backend/code.c b/backend/code.c index 368f830f..2aa63709 100644 --- a/backend/code.c +++ b/backend/code.c @@ -73,6 +73,16 @@ static char *C93Table[47] = {"131112", "111213", "111312", "111411", "121113", " "122121", "123111", "121131", "311112", "311211", "321111", "112131", "113121", "211131", "121221", "312111", "311121", "122211"}; +/* Global Variables for Channel Code */ +int S[11], B[11]; +long value; +long target_value; +char pattern[30]; + +/* Function Prototypes */ +void NextS(int Chan, int i, int MaxS, int MaxB); +void NextB(int Chan, int i, int MaxB, int MaxS); + /* *********************** CODE 11 ******************** */ int code_11(struct zint_symbol *symbol, unsigned char source[]) @@ -88,12 +98,12 @@ int code_11(struct zint_symbol *symbol, unsigned char source[]) strcpy(dest, ""); if(ustrlen(source) > 80) { - strcpy(symbol->errtxt, "Input too long [011]"); + strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } error_number = is_sane(NASET, source); if(error_number == ERROR_INVALID_DATA) { - strcpy(symbol->errtxt, "Invalid characters in data [012]"); + strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } c_weight = 1; @@ -170,12 +180,12 @@ int c39(struct zint_symbol *symbol, unsigned char source[]) to_upper(source); if(ustrlen(source) > 45) { - strcpy(symbol->errtxt, "Input too long [081]"); + strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } error_number = is_sane(TCSET , source); if(error_number == ERROR_INVALID_DATA) { - strcpy(symbol->errtxt, "Invalid characters in data [082]"); + strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } @@ -257,12 +267,12 @@ int pharmazentral(struct zint_symbol *symbol, unsigned char source[]) count = 0; h = ustrlen(source); if(h > 6) { - strcpy(symbol->errtxt, "Input wrong length [521]"); + strcpy(symbol->errtxt, "Input wrong length"); return ERROR_TOO_LONG; } error_number = is_sane(NESET, source); if(error_number == ERROR_INVALID_DATA) { - strcpy(symbol->errtxt, "Invalid characters in data [522]"); + strcpy(symbol->errtxt, "Invalid characters in data"); return error_number; } @@ -310,7 +320,7 @@ int ec39(struct zint_symbol *symbol, unsigned char source[]) /* only stops strings which are far too long - actual length of the barcode depends on the type of data being encoded - if it's too long it's picked up by c39() */ - strcpy(symbol->errtxt, "Input too long [091]"); + strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } @@ -318,7 +328,7 @@ int ec39(struct zint_symbol *symbol, unsigned char source[]) for(i = 0; i < ustrlen(source); i++) { if(source[i] > 127) { /* Cannot encode extended ASCII */ - strcpy(symbol->errtxt, "Invalid characters in input data [092]"); + strcpy(symbol->errtxt, "Invalid characters in input data"); return ERROR_INVALID_DATA; } } @@ -368,14 +378,14 @@ int c93(struct zint_symbol *symbol, unsigned char source[]) if(ustrlen(source) > 45) { /* This stops rediculously long input - the actual length of the barcode depends on the type of data */ - strcpy(symbol->errtxt, "Input too long [251]"); + strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } for(i = 0; i < ustrlen(source); i++) { if(source[i] > 127) { /* Cannot encode extended ASCII */ - strcpy(symbol->errtxt, "Invalid characters in input data [252]"); + strcpy(symbol->errtxt, "Invalid characters in input data"); return ERROR_INVALID_DATA; } } @@ -395,7 +405,7 @@ int c93(struct zint_symbol *symbol, unsigned char source[]) /* Now we can check the true length of the barcode */ if(strlen(buffer) > 45) { - strcpy(symbol->errtxt, "Input too long [253]"); + strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } @@ -466,3 +476,115 @@ int c93(struct zint_symbol *symbol, unsigned char source[]) } return error_number; } + +/* NextS() and NextB() are from ANSI/AIM BC12-1998 and are Copyright (c) AIM 1997 */ +/* Their are used here on the understanding that they form part of the specification + for Channel Code and therefore their use is permitted under the following terms + set out in that document: + + "It is the intent and understanding of AIM [t]hat the symbology presented in this + specification is entirely in the public domain and free of all use restrictions, + licenses and fees. AIM USA, its memer companies, or individual officers + assume no liability for the use of this document." */ + +void CheckCharacter() { + int i; + char part[3]; + + if(value == target_value) { + /* Target reached - save the generated pattern */ + strcpy(pattern, "11110"); + for(i = 0; i < 11; i++) { + part[0] = itoc(S[i]); + part[1] = itoc(B[i]); + part[2] = '\0'; + concat(pattern, part); + } + } +} + +void NextB(int Chan, int i, int MaxB, int MaxS) { + int b; + + b = (S[i]+B[i-1]+S[i-1]+B[i-2] > 4)? 1:2; + if (i < Chan+2) { + for (; b <= MaxB; b++) { + B[i] = b; + NextS(Chan,i+1,MaxS,MaxB+1-b); + } + } else if (b <= MaxB) { + B[i] = MaxB; + CheckCharacter(); + value++; + } +} + +void NextS(int Chan, int i, int MaxS, int MaxB) { + int s; + + for (s = (i 7) { + strcpy(symbol->errtxt, "Input too long"); + return ERROR_TOO_LONG; + } + error_number = is_sane(NESET, source); + if(error_number == ERROR_INVALID_DATA) { + strcpy(symbol->errtxt, "Invalid characters in data"); + return error_number; + } + + if((symbol->option_2 < 3) || (symbol->option_2 > 8)) { channels = 0; } else { channels = symbol->option_2; } + if(channels == 0) { channels = input_length + 1; } + if(channels == 2) { channels = 3; } + + for(i = 0; i < input_length; i++) { + target_value *= 10; + target_value += ctoi((char) source[i]); + } + + switch(channels) { + case 3: if(target_value > 26) { range = 1; } break; + case 4: if(target_value > 292) { range = 1; } break; + case 5: if(target_value > 3493) { range = 1; } break; + case 6: if(target_value > 44072) { range = 1; } break; + case 7: if(target_value > 576688) { range = 1; } break; + case 8: if(target_value > 7742862) { range = 1; } break; + } + if(range) { + strcpy(symbol->errtxt, "Value out of range"); + return ERROR_INVALID_DATA; + } + + for(i = 0; i < 11; i++) { B[i] = 0; S[i] = 0; } + + B[0] = S[1] = B[1] = S[2] = B[2] = 1; + value = 0; + NextS(channels,3,channels,channels); + + strcpy(hrt, ""); + zeroes = channels - 1 - input_length; + for(i = 0; i < zeroes; i++) { + concat(hrt, "0"); + } + concat(hrt, (char *)source); + ustrcpy(symbol->text, (unsigned char *)hrt); + + expand(symbol, pattern); + + return error_number; +} \ No newline at end of file diff --git a/backend/dm200.c b/backend/dm200.c index 888ed9b0..9f77b7cb 100644 --- a/backend/dm200.c +++ b/backend/dm200.c @@ -194,7 +194,7 @@ float dmroundup(float input) float fraction, output; fraction = input - (int)input; - if(fraction > 0.01) { output = (input - fraction) + 1.0; } + if(fraction > 0.01) { output = (input - fraction) + 1.0; } else { output = input; } return output; } @@ -538,7 +538,7 @@ int dm200encode(struct zint_symbol *symbol, unsigned char source[], unsigned cha /* step (e) X12 encodation */ if(current_mode == DM_X12) { - int value; + int value = 0; next_mode = DM_X12; if(text_p == 0) { @@ -579,7 +579,7 @@ int dm200encode(struct zint_symbol *symbol, unsigned char source[], unsigned cha /* step (f) EDIFACT encodation */ if(current_mode == DM_EDIFACT) { - int value; + int value = 0; next_mode = DM_EDIFACT; if(edifact_p == 3) { diff --git a/backend/library.c b/backend/library.c index accb7b79..4e45ad21 100644 --- a/backend/library.c +++ b/backend/library.c @@ -121,6 +121,7 @@ extern int aztec_runes(struct zint_symbol *symbol, unsigned char source[]); /* A extern int korea_post(struct zint_symbol *symbol, unsigned char source[]); /* Korea Post */ extern int japan_post(struct zint_symbol *symbol, unsigned char source[]); /* Japanese Post */ extern int code_49(struct zint_symbol *symbol, unsigned char source[]); /* Code 49 */ +extern int channel_code(struct zint_symbol *symbol, unsigned char source[]); /* Channel Code */ #ifndef NO_PNG int png_handle(struct zint_symbol *symbol, int rotate_angle); @@ -429,7 +430,7 @@ int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source) if(symbol->symbology == 111) { symbol->symbology = BARCODE_HIBC_BLOCKF; } if((symbol->symbology >= 112) && (symbol->symbology <= 127)) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } /* Everything from 128 up is Zint-specific */ - if(symbol->symbology >= 140) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } + if(symbol->symbology >= 141) { strcpy(symbol->errtxt, "Symbology out of range, using Code 128"); symbol->symbology = BARCODE_CODE128; error_number = WARN_INVALID_OPTION; } if(error_number > 4) { error_tag(symbol->errtxt, error_number); @@ -565,6 +566,7 @@ int ZBarcode_Encode(struct zint_symbol *symbol, unsigned char *source) case BARCODE_HIBC_BLOCKF: error_number = hibc(symbol, preprocessed); break; case BARCODE_JAPANPOST: error_number = japan_post(symbol, preprocessed); break; case BARCODE_CODE49: error_number = code_49(symbol, preprocessed); break; + case BARCODE_CHANNEL: error_number = channel_code(symbol, preprocessed); break; } if((symbol->symbology == BARCODE_CODE128) || (symbol->symbology == BARCODE_CODE128B)) { diff --git a/backend/svg.c b/backend/svg.c index 2991a06b..ef37724b 100644 --- a/backend/svg.c +++ b/backend/svg.c @@ -29,7 +29,7 @@ int svg_plot(struct zint_symbol *symbol) { int i, block_width, latch, r, this_row; - float textpos, large_bar_height, preset_height, row_height, row_posn; + float textpos, large_bar_height, preset_height, row_height, row_posn = 0; FILE *fsvg; int fgred, fggrn, fgblu, bgred, bggrn, bgblu; float red_ink, green_ink, blue_ink, red_paper, green_paper, blue_paper; diff --git a/backend/zint.h b/backend/zint.h index 7aa96926..27f7a307 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -137,6 +137,7 @@ struct zint_symbol { #define BARCODE_RSS14STACK_CC 137 #define BARCODE_RSS14_OMNI_CC 138 #define BARCODE_RSS_EXPSTACK_CC 139 +#define BARCODE_CHANNEL 140 #define BARCODE_NO_ASCII 1 #define BARCODE_BIND 2 diff --git a/frontend_qt4/mainWindow.ui b/frontend_qt4/mainWindow.ui index 30bedf4d..624946c1 100644 --- a/frontend_qt4/mainWindow.ui +++ b/frontend_qt4/mainWindow.ui @@ -2227,6 +2227,77 @@ p, li { white-space: pre-wrap; } + + + + 160 + 70 + 235 + 44 + + + + Channel Code + + + + + 134 + 15 + 87 + 22 + + + + + Automatic + + + + + 3 + + + + + 4 + + + + + 5 + + + + + 6 + + + + + 7 + + + + + 8 + + + + + + + 7 + 20 + 118 + 16 + + + + Number of Channels: + + + diff --git a/frontend_qt4/mainwindow.cpp b/frontend_qt4/mainwindow.cpp index 8c5ea73f..9e64e2d5 100644 --- a/frontend_qt4/mainwindow.cpp +++ b/frontend_qt4/mainwindow.cpp @@ -33,6 +33,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags fl) "Australia Post Redirect Code", "Aztec Code", "Aztec Runes", + "Channel Code", "Code 11", "Code 128", "Code 16k", @@ -95,7 +96,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags fl) bstyle->addItem(metaObject()->enumerator(0).key(i)); bstyle->setItemText(i,bstyle_text[i]); } - bstyle->setCurrentIndex(7); + bstyle->setCurrentIndex(8); change_options(); update_preview(); view->scene()->addItem(&m_bc); @@ -164,6 +165,7 @@ MainWindow::MainWindow(QWidget* parent, Qt::WFlags fl) connect(cmbMaxiMode, SIGNAL(currentIndexChanged( int )), SLOT(maxi_primary())); connect(txtMaxiPrimary, SIGNAL(textChanged( const QString& )), SLOT(update_preview())); connect(spnWhitespace, SIGNAL(valueChanged( int )), SLOT(update_preview())); + connect(cmbChannel, SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); } MainWindow::~MainWindow() @@ -296,6 +298,14 @@ void MainWindow::change_options() } else { grpMaxiCode->hide(); } + + if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CHANNEL) + { + options = true; + grpChannel->show(); + } else { + grpChannel->hide(); + } if(options == true) { @@ -644,6 +654,14 @@ void MainWindow::update_preview() m_bc.bc.setSecurityLevel(cmbMaxiMode->currentIndex() + 3); } break; + case BARCODE_CHANNEL: + m_bc.bc.setSymbol(BARCODE_CHANNEL); + if(cmbChannel->currentIndex() == 0) { + m_bc.bc.setWidth(0); + } else { + m_bc.bc.setWidth(cmbChannel->currentIndex() + 2); + } + break; default: m_bc.bc.setSymbol(metaObject()->enumerator(0).value(bstyle->currentIndex())); break; diff --git a/frontend_qt4/mainwindow.h b/frontend_qt4/mainwindow.h index e879fbb6..63d30b18 100644 --- a/frontend_qt4/mainwindow.h +++ b/frontend_qt4/mainwindow.h @@ -38,6 +38,7 @@ public: AUSREDIRECT =68, AZTEC =92, AZRUNE =128, + CHANNEL =140, CODE11 =1, CODE128 =20, CODE16K =23,