diff --git a/backend/2of5.c b/backend/2of5.c index dd405986..07c17a25 100644 --- a/backend/2of5.c +++ b/backend/2of5.c @@ -171,12 +171,15 @@ int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], int i, j, k, error_number; char bars[7], spaces[7], mixed[14], dest[1000]; - unsigned char *temp = source; - unsigned int temp_len = length; +#ifndef _MSC_VER + unsigned char temp[length + 2]; +#else + unsigned char* temp = (unsigned char *)_alloca((length + 2) * sizeof(unsigned char)); +#endif error_number = 0; - if(length > 90) { + if(length > 89) { strcpy(symbol->errtxt, "Input too long"); return ERROR_TOO_LONG; } @@ -186,24 +189,20 @@ int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], return error_number; } + ustrcpy(temp, (unsigned char *) ""); /* Input must be an even number of characters for Interlaced 2 of 5 to work: if an odd number of characters has been entered then add a leading zero */ if ((length % 2) != 0) { - /* there are an odd number of input characters */ - if (NULL == (temp = (unsigned char*)malloc(++temp_len))) - { - strcpy(symbol->errtxt, "Memory allocation failed"); - return ERROR_MEMORY; - } - temp[0] = '0'; - ustrcpy(temp + 1, source); + ustrcpy(temp, (unsigned char *) "0"); + length++; } + uconcat(temp, source); /* start character */ strcpy(dest, "1111"); - for(i = 0; i < temp_len; i+=2 ) + for(i = 0; i < length; i+=2 ) { /* look up the bars and the spaces and put them in two strings */ strcpy(bars, ""); @@ -227,8 +226,6 @@ int interleaved_two_of_five(struct zint_symbol *symbol, unsigned char source[], expand(symbol, dest); ustrcpy(symbol->text, temp); - if (temp != source) - free(source); return error_number; } diff --git a/backend/dm200.c b/backend/dm200.c index df98d5a7..0d703906 100644 --- a/backend/dm200.c +++ b/backend/dm200.c @@ -786,35 +786,33 @@ int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int leng optionsize = -1; } - calcsize = 0; - for(i = 0; i < 30; i++) { - if(matrixbytes[i] < binlen) { + calcsize = 29; + for(i = 29; i > -1; i--) { + if(matrixbytes[i] > binlen) { calcsize = i; } } - calcsize++; - - if(calcsize <= optionsize) { - symbolsize = optionsize; - } else { - symbolsize = calcsize; - if(optionsize != -1) { - /* flag an error */ - error_number = WARN_INVALID_OPTION; - strcpy(symbol->errtxt, "Data does not fit in selected symbol size"); - } - } if(symbol->option_3 == DM_SQUARE) { /* Force to use square symbol */ - switch(symbolsize) { + switch(calcsize) { case 2: case 4: case 6: case 9: case 11: case 14: - symbolsize++; + calcsize++; + } + } + + symbolsize = optionsize; + if(calcsize > optionsize) { + symbolsize = calcsize; + if(optionsize != -1) { + /* flag an error */ + error_number = WARN_INVALID_OPTION; + strcpy(symbol->errtxt, "Data does not fit in selected symbol size"); } } diff --git a/backend/gridmtx.c b/backend/gridmtx.c index a6a11542..6cfd1db1 100644 --- a/backend/gridmtx.c +++ b/backend/gridmtx.c @@ -907,7 +907,7 @@ int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length) int auto_layers, min_layers, layers, auto_ecc_level, min_ecc_level, ecc_level; int x, y, i, j, glyph; char binary[9300]; - int data_cw; + int data_cw, input_latch = 0; int word[1460], data_max; #ifndef _MSC_VER @@ -972,9 +972,17 @@ int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length) for(i = 12; i > 0; i--) { if(gm_max_cw[(i - 1)] >= data_cw) { min_layers = i; } } - layers = auto_layers; + auto_ecc_level = 3; + if(layers == 1) { auto_ecc_level = 5; } + if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; } + min_ecc_level = 1; + if(layers == 1) { min_ecc_level = 4; } + if((layers == 2) || (layers == 3)) { min_ecc_level = 2; } + ecc_level = auto_ecc_level; + if((symbol->option_2 >= 1) && (symbol->option_2 <= 13)) { + input_latch = 1; if(symbol->option_2 > min_layers) { layers = symbol->option_2; } else { @@ -982,19 +990,28 @@ int grid_matrix(struct zint_symbol *symbol, unsigned char source[], int length) } } - auto_ecc_level = 3; - if(layers == 1) { auto_ecc_level = 5; } - if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; } - min_ecc_level = 1; - if(layers == 1) { min_ecc_level = 4; } - if((layers == 2) || (layers == 3)) { min_ecc_level = 2; } + if(input_latch == 1) { + auto_ecc_level = 3; + if(layers == 1) { auto_ecc_level = 5; } + if((layers == 2) || (layers == 3)) { auto_ecc_level = 4; } + ecc_level = auto_ecc_level; + if(data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { + layers++; + } + } - ecc_level = auto_ecc_level; - if((symbol->option_1 >= 1) && (symbol->option_1 <= 5)) { - if(symbol->option_1 > min_ecc_level) { - ecc_level = symbol->option_1; - } else { - ecc_level = min_ecc_level; + if(input_latch == 0) { + if((symbol->option_1 >= 1) && (symbol->option_1 <= 5)) { + if(symbol->option_1 > min_ecc_level) { + ecc_level = symbol->option_1; + } else { + ecc_level = min_ecc_level; + } + } + if(data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) { + do { + layers++; + } while ((data_cw > gm_data_codewords[(5 * (layers - 1)) + (ecc_level - 1)]) && (layers <= 13)); } } diff --git a/backend/qr.c b/backend/qr.c index 332cbc31..3e0672a4 100644 --- a/backend/qr.c +++ b/backend/qr.c @@ -57,7 +57,7 @@ int in_alpha(int glyph) { return retval; } -void define_mode(char mode[], int jisdata[], int length) +void define_mode(char mode[], int jisdata[], int length, int gs1) { /* Values placed into mode[] are: K = Kanji, B = Binary, A = Alphanumeric, N = Numeric */ int i, mlen, j; @@ -68,6 +68,7 @@ void define_mode(char mode[], int jisdata[], int length) } else { mode[i] = 'B'; if(in_alpha(jisdata[i])) { mode[i] = 'A'; } + if(gs1 && (jisdata[i] == '[')) { mode[i] = 'A'; } if((jisdata[i] >= '0') && (jisdata[i] <= '9')) { mode[i] = 'N'; } } } @@ -348,14 +349,65 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in int count; int first = 0, second = 0, prod; - first = posn(RHODIUM, (char) jisdata[position + i]); - count = 1; - prod = first; - - if(mode[position + i + 1] == 'A') { - second = posn(RHODIUM, (char) jisdata[position + i + 1]); - count = 2; - prod = (first * 45) + second; + if(percent == 0) { + if(gs1 && (jisdata[position + i] == '%')) { + first = posn(RHODIUM, '%'); + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + i++; + } else { + if(gs1 && (jisdata[position + i] == '[')) { + first = posn(RHODIUM, '%'); /* FNC1 */ + } else { + first = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 1; + i++; + prod = first; + + if(mode[position + i] == 'A') { + if(gs1 && (jisdata[position + i] == '%')) { + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + percent = 1; + } else { + if(gs1 && (jisdata[position + i] == '[')) { + second = posn(RHODIUM, '%'); /* FNC1 */ + } else { + second = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 2; + i++; + prod = (first * 45) + second; + } + } + } + } else { + first = posn(RHODIUM, '%'); + count = 1; + i++; + prod = first; + percent = 0; + + if(mode[position + i] == 'A') { + if(gs1 && (jisdata[position + i] == '%')) { + second = posn(RHODIUM, '%'); + count = 2; + prod = (first * 45) + second; + percent = 1; + } else { + if(gs1 && (jisdata[position + i] == '[')) { + second = posn(RHODIUM, '%'); /* FNC1 */ + } else { + second = posn(RHODIUM, (char) jisdata[position + i]); + } + count = 2; + i++; + prod = (first * 45) + second; + } + } } switch(count) { @@ -376,8 +428,6 @@ void qr_binary(int datastream[], int version, int target_binlen, char mode[], in } if(debug) { printf("0x%4X ", prod); } - - i += count; }; if(debug) { printf("\n"); } @@ -1116,7 +1166,7 @@ int qr_code(struct zint_symbol *symbol, unsigned char source[], int length) break; } - define_mode(mode, jisdata, length); + define_mode(mode, jisdata, length, gs1); est_binlen = estimate_binary_length(mode, length, gs1); ecc_level = LEVEL_L; @@ -1300,6 +1350,10 @@ int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, if(prod & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } if(debug) { printf("0x%4X ", prod); } + + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } } if(debug) { printf("\n"); } @@ -1332,6 +1386,10 @@ int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, if(byte & 0x01) { concat(binary, "1"); } else { concat(binary, "0"); } if(debug) { printf("0x%4X ", byte); } + + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } } if(debug) { printf("\n"); } @@ -1385,6 +1443,10 @@ int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, if(debug) { printf("0x%4X ", prod); } + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } + i += 2; }; @@ -1444,6 +1506,10 @@ int micro_qr_intermediate(char binary[], int jisdata[], char mode[], int length, if(debug) { printf("0x%4X (%d)", prod, prod); } + if(strlen(binary) > 128) { + return ERROR_TOO_LONG; + } + i += 3; }; @@ -2150,7 +2216,7 @@ int micro_apply_bitmask(unsigned char *grid, int size) int microqr(struct zint_symbol *symbol, unsigned char source[], int length) { int i, j, glyph, size; - char binary_stream[130]; + char binary_stream[200]; char full_stream[200]; int utfdata[40]; int jisdata[40]; @@ -2203,7 +2269,7 @@ int microqr(struct zint_symbol *symbol, unsigned char source[], int length) break; } - define_mode(mode, jisdata, length); + define_mode(mode, jisdata, length, 0); n_count = 0; a_count = 0; diff --git a/frontend_qt4/grpDM.ui b/frontend_qt4/grpDM.ui index 1424e380..c5203ccd 100644 --- a/frontend_qt4/grpDM.ui +++ b/frontend_qt4/grpDM.ui @@ -1,61 +1,62 @@ - + + grpDM - - + + 0 0 - 398 + 410 339 - + Form - + - - - + + + - - + + Encoding &Mode: - + cmbDMMode - + - + ECC 200 (Recommended) - + ECC 000 - + ECC 050 - + ECC 080 - + ECC 100 - + ECC 140 @@ -63,134 +64,134 @@ - - - + + + Non ECC 200 Options - - - - + + + + Si&ze: - + Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter - + cmbDMNon200Size - - + + - + Automatic - + 9 x 9 - + 11 x 11 - + 13 x 13 - + 15 x 15 - + 17 x 17 - + 19 x 19 - + 21 x 21 - + 23 x 23 - + 25 x 25 - + 27 x 27 - + 29 x 29 - + 31 x 31 - + 33 x 33 - + 35 x 35 - + 37 x 37 - + 39 x 39 - + 41 x 41 - + 43 x 43 - + 45 x 45 - + 47 x 47 - + 49 x 49 @@ -199,216 +200,226 @@ - - - + + + ECC 200 Options - - - - + + + + S&tandard - + true - - - + + + &HIBC Data Matrix - - - + + + &GS-1 Data Mode - - - + + + Si&ze: - + cmbDM200Size - - + + - + Automatic - + 10 x 10 - + 12 x 12 - + 14 x 14 - + 16 x 16 - + 18 x 18 - + 20 x 20 - + 22 x 22 - + 24 x 24 - + 26 x 26 - + 32 x 32 - + 36 x 36 - + 40 x 40 - + 44 x 44 - + 48 x 48 - + 52 x 52 - + 64 x 64 - + 72 x 72 - + 80 x 80 - + 88 x 88 - + 96 x 96 - + 104 x 104 - + 120 x 120 - + 132 x 132 - + 144 x 144 - + 8 x 18 - + 8 x 32 - + 12 x 26 - + 12 x 36 - + 16 x 36 - + 16 x 48 + + + + Suppress Rectangular Symbols in Automatic Mode + + + true + + + - - + + Qt::Vertical - + 20 71 diff --git a/frontend_qt4/mainwindow.cpp b/frontend_qt4/mainwindow.cpp index 28e20aeb..ebffbc90 100644 --- a/frontend_qt4/mainwindow.cpp +++ b/frontend_qt4/mainwindow.cpp @@ -374,6 +374,7 @@ void MainWindow::change_options() connect(m_optionWidget->findChild("radDM200HIBC"), SIGNAL(clicked( bool )), SLOT(update_preview())); connect(m_optionWidget->findChild("cmbDM200Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); connect(m_optionWidget->findChild("cmbDMNon200Size"), SIGNAL(currentIndexChanged( int )), SLOT(update_preview())); + connect(m_optionWidget->findChild("chkDMRectangle"), SIGNAL(stateChanged( int )), SLOT(update_preview())); datamatrix_options(); } @@ -738,6 +739,10 @@ void MainWindow::update_preview() m_bc.bc.setInputMode(GS1_MODE); m_bc.bc.setWidth(m_optionWidget->findChild("cmbDM200Size")->currentIndex()); + if(m_optionWidget->findChild("chkDMRectangle")->isChecked()) + m_bc.bc.setOption3(DM_SQUARE); + else + m_bc.bc.setOption3(0); } else { /* Not ECC 200 */