From 1c0066baa92157a350db9be6d37c26133f823f65 Mon Sep 17 00:00:00 2001 From: Harald Oehlmann Date: Tue, 18 Aug 2015 13:53:55 +0200 Subject: [PATCH] DMRE: Datamatrix with extended rectangular formats --- backend/dmatrix.c | 60 ++++++++++++++------- backend/dmatrix.h | 132 ++++++++++++++++++++++++++++++++++++++++------ frontend/main.c | 2 +- 3 files changed, 158 insertions(+), 36 deletions(-) diff --git a/backend/dmatrix.c b/backend/dmatrix.c index 8ec6598f..f4c88dae 100755 --- a/backend/dmatrix.c +++ b/backend/dmatrix.c @@ -42,6 +42,7 @@ #include #include #include +#include #ifdef _MSC_VER #include #endif @@ -60,6 +61,28 @@ static void ecc200placementbit(int *array, int NR, int NC, int r, int c, int p, c += NC; r += 4 - ((NC + 4) % 8); } + // Necessary for 36x120,36x144,72x120,72x144 + if (r >= NR) { + #ifdef DEBUG + fprintf(stderr,"r >= NR:%i,%i at r=%i->",p,b,r); + #endif + r = r - NR; + #ifdef DEBUG + fprintf(stderr,"%i,c=%i\n",r,c); + #endif + } + #ifdef DEBUG + if(0 != array[r * NC + c] ){ + int a = array[r * NC + c]; + fprintf(stderr,"Double:%i,%i->%i,%i at r=%i,c=%i\n",a >> 3, a & 7, p,b,r,c); + return; + } + #endif + // Check index limits + assert( r < NR ); + assert( c < NC ); + // Check double-assignment + assert( 0 == array[r * NC + c] ); array[r * NC + c] = (p << 3) + b; } @@ -802,32 +825,21 @@ int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int leng return ERROR_TOO_LONG; } - if((symbol->option_2 >= 1) && (symbol->option_2 <= 30)) { + if((symbol->option_2 >= 1) && (symbol->option_2 <= DM_SYMBOL_OPTION_MAX)) { optionsize = intsymbol[symbol->option_2 - 1]; } else { optionsize = -1; } - calcsize = 29; - for(i = 29; i > -1; i--) { - if(matrixbytes[i] >= binlen) { + calcsize = DM_SYMBOL_OPTION_MAX-1; + for(i = DM_SYMBOL_OPTION_MAX-1; i > -1; i--) { + if(matrixbytes[i] >= binlen + && ( symbol->option_3 != DM_SQUARE + || matrixH[i] == matrixW[i] ) ) { calcsize = i; } } - if(symbol->option_3 == DM_SQUARE) { - /* Force to use square symbol */ - switch(calcsize) { - case 2: - case 4: - case 6: - case 9: - case 11: - case 14: - calcsize++; - } - } - symbolsize = optionsize; if(calcsize > optionsize) { symbolsize = calcsize; @@ -875,14 +887,24 @@ int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], int leng for (y = 0; y < H; y += 2) grid[y * W + x + FW - 1] = 1; } + #ifdef DEBUG + // Print position matrix as in standard + for (y = NR-1; y >= 0; y--) { + for (x = 0; x < NC; x++) { + if (x != 0) + fprintf (stderr, "|"); + int v = places[(NR - y - 1) * NC + x]; + fprintf(stderr,"%3d.%2d",(v>>3),8-(v&7)); + } + fprintf (stderr, "\n"); + } + #endif for (y = 0; y < NR; y++) { for (x = 0; x < NC; x++) { int v = places[(NR - y - 1) * NC + x]; - //fprintf (stderr, "%4d", v); if (v == 1 || (v > 7 && (binary[(v >> 3) - 1] & (1 << (v & 7))))) grid[(1 + y + 2 * (y / (FH - 2))) * W + 1 + x + 2 * (x / (FW - 2))] = 1; } - //fprintf (stderr, "\n"); } for(y = H - 1; y >= 0; y--) { int x; diff --git a/backend/dmatrix.h b/backend/dmatrix.h index 8068d7af..1844757e 100644 --- a/backend/dmatrix.h +++ b/backend/dmatrix.h @@ -54,6 +54,8 @@ extern int data_matrix_200(struct zint_symbol *symbol, unsigned char source[], i #define DM_EDIFACT 5 #define DM_BASE256 6 +#define DM_SYMBOL_OPTION_MAX 43 + static const int c40_shift[] = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -77,36 +79,134 @@ static const int text_value[] = { 3,0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,4,5,6,7,8,9,10,11,12,13, 15,16,17,18,19,20,21,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26, 22,23,24,25,26,0,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,27,28,29,30,31 }; + +// Position in option array [symbol option value - 1] +// The position in the option array is by increasing total data codewords with square first static const int intsymbol[] = { - 0,1,3,5,7,8,10,12,13,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,2,4,6,9,11,14 }; + 0, /* 1: 10x10 */ 1, /* 2: 12x12 */ 3, /* 3: 14x14 */ 5, // 4: 16x16 + 7, /* 5: 18x18 */ 9, /* 6: 24x24 */ 12, /* 7: 22x22 */ 15, // 8: 24x24 + 17, /* 9: 26x26 */ 22, /* 10: 32x32 */ 26, /* 11: 36x36 */ 29, // 12: 40x40 + 31, /* 13: 44x44 */ 32, /* 14: 48x48 */ 33, /* 15: 52x52 */ 34, // 16: 64x64 + 37, /* 17: 72x72 */ 38, /* 18: 80x80 */ 39, /* 19: 88x88 */ 41, // 20: 96x96 + 42, /* 21:104x104*/ 43, /* 22:120x120*/ 44, /* 23:132x132*/ 45, // 24:144x144 + 2, /* 25: 8x18 */ 4, /* 26: 8x32 */ 6, /* 27: 12x26 */ 10, // 28: 12x36 + 13, /* 29: 16x36 */ 18, /* 30: 16x48 */ 8, /* 31: 8x48 */ 11, /* 32: 8x64 */ + 14, /* 33: 12x48 */ 16, /* 34: 12x64 */ 23, /* 35: 16x64 */ 19, /* 36: 24x32 */ + 21, /* 37: 24x36 */ 25, /* 38: 24x48 */ 28, /* 39: 24x64 */ 20, /* 40: 26x32 */ + 24, /* 41: 26x40 */ 27, /* 42: 26x48 */ 30, /* 43: 26x64 */ + 0 }; + +// Horizontal matrix size static const int matrixH[] = { - 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 32, 36, 40, 44, 48, - 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 }; +/*0*/ 10, /* 10x10 ,3 */ 12, /* 12x12 ,5 */ 8, /* 8x18 ,5 */ 14, /* 14x14 , 8 */ +/*4*/ 8, /* 8x32 ,10 */ 16, /* 16x16 ,12 */ 12, /* 12x26 ,16 */ 18, /* 18x18 ,18 */ +/*8*/ 8, /* 8x48 ,18 */ 20, /* 20x20 ,22 */ 12, /* 12x36 ,22 */ 8, /* 8x64 ,24 */ +/*12*/ 22, /* 22x22 ,30 */ 16, /* 16x32 ,32 */ 12, /* 12x48 ,32 */ 24, /* 24x24 ,36 */ +/*16*/ 12, /* 12x64 ,43 */ 26, /* 26x26 ,44 */ 16, /* 16x48 ,49 */ 24, /* 24x32 ,49 */ +/*20*/ 26, /* 26x32 ,52 */ 24, /* 24x36 ,55 */ 32, /* 32x32 ,62 */ 16, /* 16x64 ,62 */ +/*24*/ 26, /* 26x40 ,70 */ 24, /* 24x48 ,80 */ 36, /* 36x36 ,86 */ 26, /* 26x48 ,90 */ +/*28*/ 24, /* 24x64 ,108*/ 40, /* 40x40 ,114*/ 26, /* 26x64 ,118*/ 44, /* 44x44 ,144*/ +/*32*/ 48, /* 48x48,174 */ 52, /* 62x52,204 */ 64, /* 64x64,280 */ 72, /* 72x72,368 */ +/*36*/ 80, /* 80x80,456 */ 88, /* 88x88,576 */ 96, /* 96x96,696 */ 104,/*104x104,816*/ +/*40*/ 120,/*120x120,1050*/132,/*132x132,1304*/144/*144x144,1558*/ + }; + +// Vertical matrix sizes static const int matrixW[] = { - 10, 12, 18, 14, 32, 16, 26, 18, 20, 36, 22, 36, 24, 26, 48, 32, 36, 40, 44, - 48, 52, 64, 72, 80, 88, 96, 104, 120, 132, 144 }; +/*0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */ +/*4*/ 32, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */ +/*8*/ 48, /* 8x48 */ 20, /* 20x20 */ 36, /* 12x36 */ 64, /* 8x64 */ +/*12*/ 22, /* 22x22 */ 32, /* 16x32 */ 48, /* 12x48 */ 24, /* 24x24 */ +/*16*/ 64, /* 12x64 */ 26, /* 26x26 */ 48, /* 16x48 */ 32, /* 24x32 */ +/*20*/ 32, /* 26x32 */ 36, /* 24x36 */ 32, /* 32x32 */ 64, /* 16x64 */ +/*24*/ 40, /* 26x40 */ 48, /* 24x48 */ 36, /* 36x36 */ 48, /* 26x48 */ +/*28*/ 64, /* 24x64 */ 40, /* 40x40 */ 64, /* 26x64 */ 44, /* 44x44 */ +/*32*/ 48, /* 48x48 */ 52, /* 52x52 */ 64, /* 64x64 */ 72, /* 72x72 */ +/*36*/ 80, /* 80x80 */ 88, /* 88x88 */ 96, /* 96x96 */ 104,/* 104x104 */ +/*40*/ 120,/*120x120*/ 132,/*132x132*/ 144 /*144x144*/ + }; + +// Horizontal submodule size (including subfinder) static const int matrixFH[] = { - 10, 12, 8, 14, 8, 16, 12, 18, 20, 12, 22, 16, 24, 26, 16, 16, 18, 20, 22, 24, - 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 }; +/*0*/ 10, /* 10x10 */ 12, /* 12x12 */ 8, /* 8x18 */ 14, /* 14x14 */ +/*4*/ 8, /* 8x32 */ 16, /* 16x16 */ 12, /* 12x26 */ 18, /* 18x18 */ +/*8*/ 8, /* 8x48 */ 20, /* 20x20 */ 12, /* 12x36 */ 8, /* 8x64 */ +/*12*/ 22, /* 22x22 */ 16, /* 16x32 */ 12, /* 12x48 */ 24, /* 24x24 */ +/*16*/ 12, /* 12x64 */ 26, /* 26x26 */ 16, /* 16x48 */ 24, /* 24x32 */ +/*20*/ 26, /* 26x32 */ 24, /* 24x36 */ 16, /* 32x32 */ 16, /* 16x64 */ +/*24*/ 26, /* 26x40 */ 24, /* 24x48 */ 18, /* 36x36 */ 26, /* 26x48 */ +/*28*/ 24, /* 24x64 */ 20, /* 40x40 */ 26, /* 26x64 */ 22, /* 44x44 */ +/*32*/ 24, /* 48x48 */ 26, /* 52x52 */ 16, /* 64x64 */ 18, /* 72x72 */ +/*36*/ 20, /* 80x80 */ 22, /* 88x88 */ 24, /* 96x96 */ 26, /*104x104*/ +/*40*/ 20, /*120x120*/ 22, /*132x132*/ 24 /*144x144*/ + }; + +// Vertical submodule size (including subfinder) static const int matrixFW[] = { - 10, 12, 18, 14, 16, 16, 26, 18, 20, 18, 22, 18, 24, 26, 24, 16, 18, 20, 22, - 24, 26, 16, 18, 20, 22, 24, 26, 20, 22, 24 }; +/*0*/ 10, /* 10x10 */ 12, /* 12x12 */ 18, /* 8x18 */ 14, /* 14x14 */ +/*4*/ 16, /* 8x32 */ 16, /* 16x16 */ 26, /* 12x26 */ 18, /* 18x18 */ +/*8*/ 24, /* 8x48 */ 20, /* 20x20 */ 18, /* 12x36 */ 16, /* 8x64 */ +/*12*/ 22, /* 22x22 */ 18, /* 16x32 */ 24, /* 12x48 */ 24, /* 24x24 */ +/*16*/ 16, /* 12x64 */ 26, /* 26x26 */ 24, /* 16x48 */ 16, /* 24x32 */ +/*20*/ 16, /* 26x32 */ 18, /* 24x36 */ 16, /* 32x32 */ 16, /* 16x64 */ +/*24*/ 20, /* 26x40 */ 24, /* 24x48 */ 18, /* 36x36 */ 24, /* 26x48 */ +/*28*/ 16, /* 24x64 */ 20, /* 40x40 */ 16, /* 26x64 */ 22, /* 44x44 */ +/*32*/ 24, /* 48x48 */ 26, /* 52x52 */ 16, /* 64x64 */ 18, /* 72x72 */ +/*36*/ 20, /* 80x80 */ 22, /* 88x88 */ 24, /* 96x96 */ 26, /*104x104*/ +/*40*/ 20, /*120x120*/ 22, /*132x132*/ 24 /*144x144*/ + }; + +// Total Data Codewords static const int matrixbytes[] = { - 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, - 174, 204, 280, 368, 456, 576, 696, 816, 1050, 1304, 1558 }; +/*0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */ +/*4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */ +/*8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */ +/*12*/ 30, /* 22x22 */ 32, /* 16x32 */ 32, /* 12x48 */ 36, /* 24x24 */ +/*16*/ 43, /* 12x64 */ 44, /* 26x26 */ 49, /* 16x48 */ 49, /* 24x32 */ +/*20*/ 52, /* 26x32 */ 55, /* 24x36 */ 62, /* 32x32 */ 62, /* 16x64 */ +/*24*/ 70, /* 26x40 */ 80, /* 24x48 */ 86, /* 36x36 */ 90, /* 26x48 */ +/*28*/ 108, /* 24x64 */ 114, /* 40x40 */ 118, /* 26x64 */ 144, /* 44x44 */ +/*32*/ 174, /* 48x48 */ 204, /* 52x52 */ 280, /* 64x64 */ 368, /* 72x72 */ +/*36*/ 456, /* 80x80 */ 576, /* 88x88 */ 696, /* 96x96 */ 816, /*104x104*/ +/*40*/ 1050, /*120x120*/ 1304, /*132x132*/ 1558 /*144x144*/ + }; + +// Data Codewords per RS-Block static const int matrixdatablock[] = { - 3, 5, 5, 8, 10, 12, 16, 18, 22, 22, 30, 32, 36, 44, 49, 62, 86, 114, 144, - 174, 102, 140, 92, 114, 144, 174, 136, 175, 163, 156 }; - +/*0*/ 3, /* 10x10 */ 5, /* 12x12 */ 5, /* 8x18 */ 8, /* 14x14 */ +/*4*/ 10, /* 8x32 */ 12, /* 16x16 */ 16, /* 12x26 */ 18, /* 18x18 */ +/*8*/ 18, /* 8x48 */ 22, /* 20x20 */ 22, /* 12x36 */ 24, /* 8x64 */ +/*12*/ 30, /* 22x22 */ 32, /* 16x32 */ 32, /* 12x48 */ 36, /* 24x24 */ +/*16*/ 43, /* 12x64 */ 44, /* 26x26 */ 49, /* 16x48 */ 49, /* 24x32 */ +/*20*/ 52, /* 26x32 */ 55, /* 24x36 */ 62, /* 32x32 */ 62, /* 16x64 */ +/*24*/ 70, /* 26x40 */ 80, /* 24x48 */ 86, /* 36x36 */ 90, /* 26x48 */ +/*28*/ 108,/* 24x64 */ 114,/* 40x40 */ 118,/* 26x64 */ 144,/* 44x44 */ +/*32*/ 174,/* 48x48 */ 102,/* 52x52 */ 140,/* 64x64 */ 92, /* 72x72 */ +/*36*/ 114,/* 80x80 */ 144,/* 88x88 */ 174,/* 96x96 */ 136,/*104x104*/ +/*40*/ 175,/*120x120*/ 163,/*132x132*/ 156 /*144x144*/ + }; + +// ECC Codewords per RS-Block + static const int matrixrsblock[] = { - 5, 7, 7, 10, 11, 12, 14, 14, 18, 18, 20, 24, 24, 28, 28, 36, 42, 48, 56, 68, - 42, 56, 36, 48, 56, 68, 56, 68, 62, 62 }; +/*0*/ 5, /* 10x10 */ 7, /* 12x12 */ 7, /* 8x18 */ 10, /* 14x14 */ +/*4*/ 11, /* 8x32 */ 12, /* 16x16 */ 14, /* 12x26 */ 14, /* 18x18 */ +/*8*/ 15, /* 8x48 */ 18, /* 20x20 */ 18, /* 12x36 */ 18, /* 8x64 */ +/*12*/ 20, /* 22x22 */ 24, /* 16x32 */ 23, /* 12x48 */ 24, /* 24x24 */ +/*16*/ 27, /* 12x64 */ 28, /* 26x26 */ 28, /* 16x48 */ 28, /* 24x32 */ +/*20*/ 32, /* 26x32 */ 33, /* 24x36 */ 36, /* 32x32 */ 36, /* 16x64 */ +/*24*/ 38, /* 26x40 */ 41, /* 24x48 */ 42, /* 36x36 */ 42, /* 26x48 */ +/*28*/ 46, /* 24x64 */ 48, /* 40x40 */ 50, /* 26x64 */ 56, /* 44x44 */ +/*32*/ 68, /* 48x48 */ 42, /* 52x52 */ 56, /* 64x64 */ 36, /* 72x72 */ +/*36*/ 48, /* 80x80 */ 56, /* 88x88 */ 68, /* 96x96 */ 56, /*104x104*/ +/*40*/ 68, /*120x120*/ 62, /*132x132*/ 62 /*144x144*/ + }; #endif /* __IEC16022ECC200_H */ diff --git a/frontend/main.c b/frontend/main.c index c23399a6..afdd3426 100644 --- a/frontend/main.c +++ b/frontend/main.c @@ -481,7 +481,7 @@ int main(int argc, char **argv) } } if(!strcmp(long_options[option_index].name, "vers")) { - if((atoi(optarg) >= 1) && (atoi(optarg) <= 40)) { + if((atoi(optarg) >= 1) && (atoi(optarg) <= 47)) { my_symbol->option_2 = atoi(optarg); } else { fprintf(stderr, "Invalid QR Code version\n");