mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Add Channel Code
This commit is contained in:
parent
cd614f42f7
commit
0e560805b4
144
backend/code.c
144
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<Chan+2)? 1: MaxS; s <= MaxS; s++) {
|
||||
S[i] = s;
|
||||
NextB(Chan,i,MaxB,MaxS+1-s);
|
||||
}
|
||||
}
|
||||
|
||||
int channel_code(struct zint_symbol *symbol, unsigned char source[]) {
|
||||
/* Channel Code - According to ANSI/AIM BC12-1998 */
|
||||
|
||||
int input_length, channels, i;
|
||||
int error_number = 0, range = 0, zeroes;
|
||||
char hrt[9];
|
||||
|
||||
input_length = ustrlen(source);
|
||||
target_value = 0;
|
||||
|
||||
if(input_length > 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;
|
||||
}
|
@ -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) {
|
||||
|
@ -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)) {
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -2227,6 +2227,77 @@ p, li { white-space: pre-wrap; }
|
||||
</item>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QGroupBox" name="grpChannel" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>160</x>
|
||||
<y>70</y>
|
||||
<width>235</width>
|
||||
<height>44</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="title" >
|
||||
<string>Channel Code</string>
|
||||
</property>
|
||||
<widget class="QComboBox" name="cmbChannel" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>134</x>
|
||||
<y>15</y>
|
||||
<width>87</width>
|
||||
<height>22</height>
|
||||
</rect>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>Automatic</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>3</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>4</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>5</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>6</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>7</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text" >
|
||||
<string>8</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
<widget class="QLabel" name="lblChannel" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>7</x>
|
||||
<y>20</y>
|
||||
<width>118</width>
|
||||
<height>16</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Number of Channels:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</widget>
|
||||
</widget>
|
||||
<widget class="QWidget" name="tabAppear" >
|
||||
<property name="geometry" >
|
||||
|
@ -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()
|
||||
@ -297,6 +299,14 @@ void MainWindow::change_options()
|
||||
grpMaxiCode->hide();
|
||||
}
|
||||
|
||||
if(metaObject()->enumerator(0).value(bstyle->currentIndex()) == BARCODE_CHANNEL)
|
||||
{
|
||||
options = true;
|
||||
grpChannel->show();
|
||||
} else {
|
||||
grpChannel->hide();
|
||||
}
|
||||
|
||||
|
||||
if(options == true) {
|
||||
lblNoOption->hide();
|
||||
@ -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;
|
||||
|
@ -38,6 +38,7 @@ public:
|
||||
AUSREDIRECT =68,
|
||||
AZTEC =92,
|
||||
AZRUNE =128,
|
||||
CHANNEL =140,
|
||||
CODE11 =1,
|
||||
CODE128 =20,
|
||||
CODE16K =23,
|
||||
|
Loading…
Reference in New Issue
Block a user