diff --git a/backend/raster.c b/backend/raster.c index 08ca5704..98781d29 100644 --- a/backend/raster.c +++ b/backend/raster.c @@ -89,7 +89,7 @@ static int buffer_plot(struct zint_symbol *symbol, char *pixelbuf) { free(symbol->alphamap); symbol->alphamap = NULL; } - + symbol->bitmap = (unsigned char *) malloc(symbol->bitmap_width * symbol->bitmap_height * 3); if (symbol->bitmap == NULL) { strcpy(symbol->errtxt, "661: Insufficient memory for bitmap buffer"); @@ -181,7 +181,7 @@ static int buffer_plot(struct zint_symbol *symbol, char *pixelbuf) { return 0; } -static int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) { +static int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int file_type) { int error_number; int row, column; @@ -238,9 +238,23 @@ static int save_raster_image_to_file(struct zint_symbol *symbol, int image_heigh break; } - switch (image_type) { + switch (file_type) { case OUT_BUFFER: - error_number = buffer_plot(symbol, rotated_pixbuf); + if (symbol->output_options & OUT_BUFFER_INTERMEDIATE) { + if (symbol->bitmap != NULL) { + free(symbol->bitmap); + symbol->bitmap = NULL; + } + if (symbol->alphamap != NULL) { + free(symbol->alphamap); + symbol->alphamap = NULL; + } + symbol->bitmap = (unsigned char *) rotated_pixbuf; + rotate_angle = 0; /* Suppress freeing buffer if rotated */ + error_number = 0; + } else { + error_number = buffer_plot(symbol, rotated_pixbuf); + } break; case OUT_PNG_FILE: #ifndef NO_PNG @@ -550,7 +564,7 @@ static void plot_hexagon(char *scaled_hexagon, int hexagon_size) { } } -static int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int data_type) { +static int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int file_type) { /* Plot a MaxiCode symbol with hexagons and bullseye */ int row, column, xposn; int image_height, image_width; @@ -624,13 +638,15 @@ static int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, in } } - error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); + error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, file_type); free(scaled_hexagon); - free(pixelbuf); + if (rotate_angle || file_type != OUT_BUFFER || !(symbol->output_options & OUT_BUFFER_INTERMEDIATE)) { + free(pixelbuf); + } return error_number; } -static int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int data_type) { +static int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int file_type) { float scaler = 2 * symbol->scale; float half_scaler, dot_size_scaled; char *scaled_pixelbuf; @@ -676,8 +692,10 @@ static int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int d } } - error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type); - free(scaled_pixelbuf); + error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, file_type); + if (rotate_angle || file_type != OUT_BUFFER || !(symbol->output_options & OUT_BUFFER_INTERMEDIATE)) { + free(scaled_pixelbuf); + } return error_number; } @@ -723,7 +741,7 @@ static void to_iso8859_1(const unsigned char source[], unsigned char preprocesse return; } -static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_type) { +static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int file_type) { int error_number; float large_bar_height; int textdone; @@ -1085,12 +1103,14 @@ static int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int } } - error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type); + error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, file_type); free(scaled_pixelbuf); } else { - error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type); + error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, file_type); + } + if (rotate_angle || file_type != OUT_BUFFER || !(symbol->output_options & OUT_BUFFER_INTERMEDIATE)) { + free(pixelbuf); } - free(pixelbuf); return error_number; } diff --git a/backend/tests/test_raster.c b/backend/tests/test_raster.c index 579cb238..5b7630de 100644 --- a/backend/tests/test_raster.c +++ b/backend/tests/test_raster.c @@ -32,7 +32,12 @@ #include "testcommon.h" static int is_row_column_black(struct zint_symbol *symbol, int row, int column) { - int i = (row * symbol->bitmap_width + column) * 3; + int i; + if (symbol->output_options & OUT_BUFFER_INTERMEDIATE) { + i = row * symbol->bitmap_width + column; + return symbol->bitmap[i] == '1'; // Black + } + i = (row * symbol->bitmap_width + column) * 3; return symbol->bitmap[i] == 0 && symbol->bitmap[i + 1] == 0 && symbol->bitmap[i + 2] == 0; // Black } @@ -594,6 +599,7 @@ static void test_output_options(int index, int debug) { int whitespace_width; int border_width; int output_options; + int rotate_angle; unsigned char *data; int ret; @@ -608,49 +614,65 @@ static void test_output_options(int index, int debug) { }; // s/\/\*[ 0-9]*\*\//\=printf("\/*%3d*\/", line(".") - line("'<")) struct item data[] = { - /* 0*/ { BARCODE_CODE128, -1, -1, -1, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 4 }, - /* 1*/ { BARCODE_CODE128, -1, 2, -1, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 4 }, - /* 2*/ { BARCODE_CODE128, -1, 2, BARCODE_BIND, "A123", 0, 50, 1, 79, 158, 126, 1, 0, 4 }, - /* 3*/ { BARCODE_CODE128, -1, 2, BARCODE_BIND, "A123", 0, 50, 1, 79, 158, 126, 0, 4, 4 }, - /* 4*/ { BARCODE_CODE128, -1, 2, BARCODE_BOX, "A123", 0, 50, 1, 79, 166, 126, 1, 4, 4 }, - /* 5*/ { BARCODE_CODE128, -1, 0, BARCODE_BIND, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 4 }, - /* 6*/ { BARCODE_CODE128, -1, 0, BARCODE_BOX, "A123", 0, 50, 1, 79, 158, 118, 0, 4, 4 }, - /* 7*/ { BARCODE_CODE128, -1, -1, -1, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 8 }, - /* 8*/ { BARCODE_CODE128, 3, -1, -1, "A123", 0, 50, 1, 79, 170, 118, 1, 0, 8 }, - /* 9*/ { BARCODE_CODE128, 3, 4, -1, "A123", 0, 50, 1, 79, 170, 118, 1, 0, 8 }, - /* 10*/ { BARCODE_CODE128, 3, 4, BARCODE_BIND, "A123", 0, 50, 1, 79, 170, 134, 1, 0, 0 }, - /* 11*/ { BARCODE_CODE128, 3, 4, BARCODE_BIND, "A123", 0, 50, 1, 79, 170, 134, 0, 8, 0 }, - /* 12*/ { BARCODE_CODE128, 3, 4, BARCODE_BOX, "A123", 0, 50, 1, 79, 186, 134, 1, 8, 0 }, - /* 13*/ { BARCODE_CODE128, -1, -1, BARCODE_DOTTY_MODE, "A123", ZINT_ERROR_INVALID_OPTION, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* 14*/ { BARCODE_QRCODE, -1, -1, -1, "A123", 0, 21, 21, 21, 42, 42, 0, 2, 2 }, - /* 15*/ { BARCODE_QRCODE, -1, 3, -1, "A123", 0, 21, 21, 21, 42, 42, 0, 2, 2 }, - /* 16*/ { BARCODE_QRCODE, -1, 3, BARCODE_BIND, "A123", 0, 21, 21, 21, 42, 54, 1, 2, 2 }, - /* 17*/ { BARCODE_QRCODE, -1, 3, BARCODE_BIND, "A123", 0, 21, 21, 21, 42, 54, 0, 20, 0 }, - /* 18*/ { BARCODE_QRCODE, -1, 3, BARCODE_BOX, "A123", 0, 21, 21, 21, 54, 54, 1, 20, 0 }, - /* 19*/ { BARCODE_QRCODE, -1, -1, -1, "A123", 0, 21, 21, 21, 42, 42, 1, 0, 0 }, - /* 20*/ { BARCODE_QRCODE, 5, -1, -1, "A123", 0, 21, 21, 21, 62, 42, 0, 0, 0 }, - /* 21*/ { BARCODE_QRCODE, 5, 6, -1, "A123", 0, 21, 21, 21, 62, 42, 0, 0, 0 }, - /* 22*/ { BARCODE_QRCODE, 5, 6, BARCODE_BIND, "A123", 0, 21, 21, 21, 62, 66, 1, 0, 0 }, - /* 23*/ { BARCODE_QRCODE, 5, 6, BARCODE_BIND, "A123", 0, 21, 21, 21, 62, 66, 0, 12, 0 }, - /* 24*/ { BARCODE_QRCODE, 5, 6, BARCODE_BOX, "A123", 0, 21, 21, 21, 86, 66, 1, 12, 0 }, - /* 25*/ { BARCODE_QRCODE, -1, -1, BARCODE_DOTTY_MODE, "A123", 0, 21, 21, 21, 43, 43, -1, -1, -1 }, // TODO: investigate +1 size - /* 26*/ { BARCODE_QRCODE, -1, 4, BARCODE_DOTTY_MODE, "A123", 0, 21, 21, 21, 43, 43, -1, -1, -1 }, - /* 27*/ { BARCODE_QRCODE, -1, 4, BARCODE_BIND | BARCODE_DOTTY_MODE, "A123", 0, 21, 21, 21, 43, 59, -1, -1, -1 }, // TODO: fix (bind/box in dotty mode) - /* 28*/ { BARCODE_QRCODE, 1, 4, BARCODE_BOX | BARCODE_DOTTY_MODE, "A123", 0, 21, 21, 21, 63, 59, -1, -1, -1 }, // TODO: fix (bind/box in dotty mode) - /* 29*/ { BARCODE_MAXICODE, -1, -1, -1, "A123", 0, 165, 33, 30, 300, 300, 0, 0, 0 }, - /* 30*/ { BARCODE_MAXICODE, -1, 5, -1, "A123", 0, 165, 33, 30, 300, 300, 0, 0, 0 }, - /* 31*/ { BARCODE_MAXICODE, -1, 5, BARCODE_BIND, "A123", 0, 165, 33, 30, 300, 320, 1, 0, 0 }, - /* 32*/ { BARCODE_MAXICODE, -1, 5, BARCODE_BIND, "A123", 0, 165, 33, 30, 300, 320, 0, 10, 0 }, - /* 33*/ { BARCODE_MAXICODE, -1, 5, BARCODE_BOX, "A123", 0, 165, 33, 30, 320, 320, 1, 10, 0 }, - /* 34*/ { BARCODE_MAXICODE, -1, -1, -1, "A123", 0, 165, 33, 30, 300, 300, 1, 0, 14 }, - /* 35*/ { BARCODE_MAXICODE, 6, -1, -1, "A123", 0, 165, 33, 30, 324, 300, 0, 0, 14 }, - /* 36*/ { BARCODE_MAXICODE, 6, 5, BARCODE_BIND, "A123", 0, 165, 33, 30, 324, 320, 1, 10, 25 }, - /* 37*/ { BARCODE_MAXICODE, 6, 5, BARCODE_BIND, "A123", 0, 165, 33, 30, 324, 320, 0, 10, 9 }, - /* 38*/ { BARCODE_MAXICODE, 6, 5, BARCODE_BOX, "A123", 0, 165, 33, 30, 344, 320, 1, 10, 9 }, - /* 39*/ { BARCODE_MAXICODE, -1, -1, BARCODE_DOTTY_MODE, "A123", ZINT_ERROR_INVALID_OPTION, -1, -1, -1, -1, -1, -1, -1, -1 }, - /* 40*/ { BARCODE_ITF14, -1, -1, -1, "123", 0, 50, 1, 135, 330, 138, 1, 110, 0 }, - /* 41*/ { BARCODE_ITF14, -1, 0, -1, "123", 0, 50, 1, 135, 330, 138, 1, 110, 0 }, - /* 42*/ { BARCODE_ITF14, -1, 0, BARCODE_BOX, "123", 0, 50, 1, 135, 310, 118, 0, 100, 0 }, + /* 0*/ { BARCODE_CODE128, -1, -1, -1, 0, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 4 }, + /* 1*/ { BARCODE_CODE128, -1, -1, -1, 180, "A123", 0, 50, 1, 79, 158, 118, 0, 117, 4 }, + /* 2*/ { BARCODE_CODE128, -1, 2, -1, 0, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 4 }, + /* 3*/ { BARCODE_CODE128, -1, 2, BARCODE_BIND, 0, "A123", 0, 50, 1, 79, 158, 126, 1, 0, 4 }, + /* 4*/ { BARCODE_CODE128, -1, 2, BARCODE_BIND, 0, "A123", 0, 50, 1, 79, 158, 126, 0, 4, 4 }, + /* 5*/ { BARCODE_CODE128, -1, 2, BARCODE_BOX, 0, "A123", 0, 50, 1, 79, 166, 126, 1, 4, 4 }, + /* 6*/ { BARCODE_CODE128, -1, 0, BARCODE_BIND, 0, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 4 }, + /* 7*/ { BARCODE_CODE128, -1, 0, BARCODE_BOX, 0, "A123", 0, 50, 1, 79, 158, 118, 0, 4, 4 }, + /* 8*/ { BARCODE_CODE128, -1, -1, -1, 0, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 8 }, + /* 9*/ { BARCODE_CODE128, 3, -1, -1, 0, "A123", 0, 50, 1, 79, 170, 118, 1, 0, 8 }, + /* 10*/ { BARCODE_CODE128, 3, 4, -1, 0, "A123", 0, 50, 1, 79, 170, 118, 1, 0, 8 }, + /* 11*/ { BARCODE_CODE128, 3, 4, BARCODE_BIND, 0, "A123", 0, 50, 1, 79, 170, 134, 1, 0, 0 }, + /* 12*/ { BARCODE_CODE128, 3, 4, BARCODE_BIND, 0, "A123", 0, 50, 1, 79, 170, 134, 0, 8, 0 }, + /* 13*/ { BARCODE_CODE128, 3, 4, BARCODE_BOX, 0, "A123", 0, 50, 1, 79, 186, 134, 1, 8, 0 }, + /* 14*/ { BARCODE_CODE128, -1, -1, BARCODE_DOTTY_MODE, 0, "A123", ZINT_ERROR_INVALID_OPTION, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* 15*/ { BARCODE_CODE128, -1, -1, OUT_BUFFER_INTERMEDIATE, 0, "A123", 0, 50, 1, 79, 158, 118, 0, 0, 4 }, + /* 16*/ { BARCODE_CODE128, -1, -1, OUT_BUFFER_INTERMEDIATE, 180, "A123", 0, 50, 1, 79, 158, 118, 0, 117, 4 }, + /* 17*/ { BARCODE_CODE128, 3, 4, BARCODE_BOX | OUT_BUFFER_INTERMEDIATE, 0, "A123", 0, 50, 1, 79, 186, 134, 1, 8, 0 }, + /* 18*/ { BARCODE_QRCODE, -1, -1, -1, 0, "A123", 0, 21, 21, 21, 42, 42, 0, 2, 2 }, + /* 19*/ { BARCODE_QRCODE, -1, -1, -1, 180, "A123", 0, 21, 21, 21, 42, 42, 0, 39, 2 }, + /* 20*/ { BARCODE_QRCODE, -1, 3, -1, 0, "A123", 0, 21, 21, 21, 42, 42, 0, 2, 2 }, + /* 21*/ { BARCODE_QRCODE, -1, 3, BARCODE_BIND, 0, "A123", 0, 21, 21, 21, 42, 54, 1, 2, 2 }, + /* 22*/ { BARCODE_QRCODE, -1, 3, BARCODE_BIND, 0, "A123", 0, 21, 21, 21, 42, 54, 0, 20, 0 }, + /* 23*/ { BARCODE_QRCODE, -1, 3, BARCODE_BOX, 0, "A123", 0, 21, 21, 21, 54, 54, 1, 20, 0 }, + /* 24*/ { BARCODE_QRCODE, -1, -1, -1, 0, "A123", 0, 21, 21, 21, 42, 42, 1, 0, 0 }, + /* 25*/ { BARCODE_QRCODE, 5, -1, -1, 0, "A123", 0, 21, 21, 21, 62, 42, 0, 0, 0 }, + /* 26*/ { BARCODE_QRCODE, 5, 6, -1, 0, "A123", 0, 21, 21, 21, 62, 42, 0, 0, 0 }, + /* 27*/ { BARCODE_QRCODE, 5, 6, BARCODE_BIND, 0, "A123", 0, 21, 21, 21, 62, 66, 1, 0, 0 }, + /* 28*/ { BARCODE_QRCODE, 5, 6, BARCODE_BIND, 0, "A123", 0, 21, 21, 21, 62, 66, 0, 12, 0 }, + /* 29*/ { BARCODE_QRCODE, 5, 6, BARCODE_BOX, 0, "A123", 0, 21, 21, 21, 86, 66, 1, 12, 0 }, + /* 30*/ { BARCODE_QRCODE, -1, -1, BARCODE_DOTTY_MODE, 0, "A123", 0, 21, 21, 21, 43, 43, 1, 1, 1 }, // TODO: investigate +1 size + /* 31*/ { BARCODE_QRCODE, -1, -1, BARCODE_DOTTY_MODE, 0, "A123", 0, 21, 21, 21, 43, 43, 0, 0, 0 }, // TODO: investigate +1 size + /* 32*/ { BARCODE_QRCODE, -1, 4, BARCODE_DOTTY_MODE, 0, "A123", 0, 21, 21, 21, 43, 43, 1, 1, 1 }, + /* 33*/ { BARCODE_QRCODE, -1, 4, BARCODE_BIND | BARCODE_DOTTY_MODE, 0, "A123", 0, 21, 21, 21, 43, 59, -1, -1, -1 }, // TODO: fix (bind/box in dotty mode) + /* 34*/ { BARCODE_QRCODE, 1, 4, BARCODE_BOX | BARCODE_DOTTY_MODE, 0, "A123", 0, 21, 21, 21, 63, 59, -1, -1, -1 }, // TODO: fix (bind/box in dotty mode) + /* 35*/ { BARCODE_QRCODE, -1, -1, OUT_BUFFER_INTERMEDIATE, 0, "A123", 0, 21, 21, 21, 42, 42, 0, 2, 2 }, + /* 36*/ { BARCODE_QRCODE, -1, -1, BARCODE_DOTTY_MODE | OUT_BUFFER_INTERMEDIATE, 0, "A123", 0, 21, 21, 21, 43, 43, 1, 1, 1 }, // TODO: investigate +1 size + /* 37*/ { BARCODE_QRCODE, -1, -1, BARCODE_DOTTY_MODE | OUT_BUFFER_INTERMEDIATE, 180, "A123", 0, 21, 21, 21, 43, 43, 0, 39, 2 }, // TODO: investigate +1 size + /* 38*/ { BARCODE_MAXICODE, -1, -1, -1, 0, "A123", 0, 165, 33, 30, 300, 300, 0, 0, 0 }, + /* 39*/ { BARCODE_MAXICODE, -1, -1, -1, 270, "A123", 0, 165, 33, 30, 300, 300, 0, 0, 0 }, + /* 40*/ { BARCODE_MAXICODE, -1, 5, -1, 0, "A123", 0, 165, 33, 30, 300, 300, 0, 0, 0 }, + /* 41*/ { BARCODE_MAXICODE, -1, 5, BARCODE_BIND, 0, "A123", 0, 165, 33, 30, 300, 320, 1, 0, 0 }, + /* 42*/ { BARCODE_MAXICODE, -1, 5, BARCODE_BIND, 0, "A123", 0, 165, 33, 30, 300, 320, 0, 10, 0 }, + /* 43*/ { BARCODE_MAXICODE, -1, 5, BARCODE_BOX, 0, "A123", 0, 165, 33, 30, 320, 320, 1, 10, 0 }, + /* 44*/ { BARCODE_MAXICODE, -1, -1, -1, 0, "A123", 0, 165, 33, 30, 300, 300, 1, 0, 14 }, + /* 45*/ { BARCODE_MAXICODE, 6, -1, -1, 0, "A123", 0, 165, 33, 30, 324, 300, 0, 0, 14 }, + /* 46*/ { BARCODE_MAXICODE, 6, 5, BARCODE_BIND, 0, "A123", 0, 165, 33, 30, 324, 320, 1, 10, 25 }, + /* 47*/ { BARCODE_MAXICODE, 6, 5, BARCODE_BIND, 0, "A123", 0, 165, 33, 30, 324, 320, 0, 10, 9 }, + /* 48*/ { BARCODE_MAXICODE, 6, 5, BARCODE_BOX, 0, "A123", 0, 165, 33, 30, 344, 320, 1, 10, 9 }, + /* 49*/ { BARCODE_MAXICODE, -1, -1, BARCODE_DOTTY_MODE, 0, "A123", ZINT_ERROR_INVALID_OPTION, -1, -1, -1, -1, -1, -1, -1, -1 }, + /* 50*/ { BARCODE_MAXICODE, -1, -1, OUT_BUFFER_INTERMEDIATE, 0, "A123", 0, 165, 33, 30, 300, 300, 0, 0, 0 }, + /* 51*/ { BARCODE_MAXICODE, -1, -1, OUT_BUFFER_INTERMEDIATE, 0, "A123", 0, 165, 33, 30, 300, 300, 1, 0, 14 }, + /* 52*/ { BARCODE_MAXICODE, -1, -1, OUT_BUFFER_INTERMEDIATE, 270, "A123", 0, 165, 33, 30, 300, 300, 0, 0, 0 }, + /* 53*/ { BARCODE_ITF14, -1, -1, -1, 0, "123", 0, 50, 1, 135, 330, 138, 1, 110, 0 }, + /* 54*/ { BARCODE_ITF14, -1, -1, -1, 90, "123", 0, 50, 1, 135, 138, 330, 1, 0, 110 }, + /* 55*/ { BARCODE_ITF14, -1, 0, -1, 0, "123", 0, 50, 1, 135, 330, 138, 1, 110, 0 }, + /* 56*/ { BARCODE_ITF14, -1, 0, BARCODE_BOX, 0, "123", 0, 50, 1, 135, 310, 118, 0, 100, 0 }, + /* 57*/ { BARCODE_ITF14, -1, -1, OUT_BUFFER_INTERMEDIATE, 0, "123", 0, 50, 1, 135, 330, 138, 1, 110, 0 }, + /* 58*/ { BARCODE_ITF14, -1, -1, OUT_BUFFER_INTERMEDIATE, 90, "123", 0, 50, 1, 135, 138, 330, 1, 0, 110 }, }; int data_size = ARRAY_SIZE(data); @@ -674,7 +696,7 @@ static void test_output_options(int index, int debug) { ret = ZBarcode_Encode(symbol, data[i].data, length); assert_zero(ret, "i:%d ZBarcode_Encode(%d) ret %d != 0 %s\n", i, data[i].symbology, ret, symbol->errtxt); - ret = ZBarcode_Buffer(symbol, 0); + ret = ZBarcode_Buffer(symbol, data[i].rotate_angle); assert_equal(ret, data[i].ret, "i:%d ZBarcode_Buffer(%d) ret %d != %d\n", i, data[i].symbology, ret, data[i].ret); if (ret < 5) { diff --git a/backend/tests/testcommon.c b/backend/tests/testcommon.c index b8ae8e99..002c00a6 100644 --- a/backend/tests/testcommon.c +++ b/backend/tests/testcommon.c @@ -513,6 +513,7 @@ char *testUtilOutputOptionsName(int output_options) { { "CMYK_COLOUR", CMYK_COLOUR, 128 }, { "BARCODE_DOTTY_MODE", BARCODE_DOTTY_MODE, 256 }, { "GS1_GS_SEPARATOR", GS1_GS_SEPARATOR, 512 }, + { "OUT_BUFFER_INTERMEDIATE", OUT_BUFFER_INTERMEDIATE, 1024 }, }; int data_size = ARRAY_SIZE(data); int set = 0; @@ -1014,9 +1015,13 @@ void testUtilBitmapPrint(const struct zint_symbol *symbol) { for (row = 0; row < symbol->bitmap_height; row++) { printf("%3d: ", row); for (column = 0; column < symbol->bitmap_width; column++) { - i = ((row * symbol->bitmap_width) + column) * 3; - j = (symbol->bitmap[i] == 0) + (symbol->bitmap[i + 1] == 0) * 2 + (symbol->bitmap[i + 2] == 0) * 4; - putchar(colour[j]); + if (symbol->output_options & OUT_BUFFER_INTERMEDIATE) { + putchar(symbol->bitmap[(row * symbol->bitmap_width) + column]); + } else { + i = ((row * symbol->bitmap_width) + column) * 3; + j = (symbol->bitmap[i] == 0) + (symbol->bitmap[i + 1] == 0) * 2 + (symbol->bitmap[i + 2] == 0) * 4; + putchar(colour[j]); + } } putchar('\n'); } diff --git a/backend/zint.h b/backend/zint.h index b299a91c..7bb88ea1 100644 --- a/backend/zint.h +++ b/backend/zint.h @@ -105,7 +105,6 @@ extern "C" { unsigned int bitmap_byte_length; float dot_size; struct zint_vector *vector; - struct zint_render *rendered; int debug; }; @@ -248,6 +247,7 @@ extern "C" { #define CMYK_COLOUR 128 #define BARCODE_DOTTY_MODE 256 #define GS1_GS_SEPARATOR 512 +#define OUT_BUFFER_INTERMEDIATE 1024 // Input data types #define DATA_MODE 0 @@ -276,7 +276,7 @@ extern "C" { #define ZINT_ERROR_FILE_ACCESS 10 #define ZINT_ERROR_MEMORY 11 -// Raster file types +// File types #define OUT_BUFFER 0 #define OUT_SVG_FILE 10 #define OUT_EPS_FILE 20 diff --git a/docs/manual.txt b/docs/manual.txt index db2deb03..94d56d5e 100644 --- a/docs/manual.txt +++ b/docs/manual.txt @@ -198,7 +198,7 @@ characters are shown in the table below. -------------------------------------------------------------------- Escape Character | ASCII Equivalent | Interpretation -------------------------------------------------------------------- -\0 | 0x00 | Null +\0 | 0x00 | NUL character \E | 0x04 | End of Transmission \a | 0x07 | Bell \b | 0x08 | Backspace @@ -779,9 +779,9 @@ int ZBarcode_Encode_File_and_Print(struct zint_symbol *symbol, char *filename, int rotate_angle); In these definitions "length" can be used to set the length of the input -string. This allows the encoding of NULL (ASCII 0) characters in those +string. This allows the encoding of NUL (ASCII 0) characters in those symbologies which allow this. A value of 0 will disable this function and Zint -will encode data up to the first NULL character in the input string. +will encode data up to the first NUL character in the input string. The "rotate_angle" value can be used to rotate the image when outputting as a raster image. Valid values are 0, 90, 180 and 270. @@ -805,28 +805,44 @@ int ZBarcode_Encode_File_and_Buffer(struct zint_symbol *symbol, char *filename, int rotate_angle); The arguments here are the same as above. The difference is that instead of -saving the image to file it is placed in an unsigned integer array. The "bitmap" -pointer is set to the first memory location in the array and the values +saving the image to file it is placed in an unsigned character array. The +"bitmap" pointer is set to the first memory location in the array and the values "barcode_width" and "barcode_height" indicate the size of the resulting image in pixels. Rotation and colour options can be used at the same time as using the buffer functions in the same way as when saving to a raster image. The -pixel data can be extracted from the array by the method shown in -the example below where render_pixel() is assumed to be a function for drawing -a pixel on the screen implemented by the external application: +pixel data can be extracted from the array by the method shown in the example +below where render_pixel() is assumed to be a function for drawing a pixel on +the screen implemented by the external application: int row, col, i = 0; int red, blue, green; for (row = 0; row < my_symbol->bitmap_height; row++) { - for (column = 0; col < my_symbol->bitmap_width; column++) { + for (col = 0; col < my_symbol->bitmap_width; col++) { red = (int) my_symbol->bitmap[i]; green = (int) my_symbol->bitmap[i + 1]; blue = (int) my_symbol->bitmap[i + 2]; - render_pixel(row, column, red, green, blue); + render_pixel(row, col, red, green, blue); i += 3; } } +Where speed is important, the buffer can be returned instead in a more compact +intermediate form using the output option OUT_BUFFER_INTERMEDIATE. Here each +byte is an ASCII value: '1' for foreground colour and '0' for background colour, +except for Ultracode, which uses colour codes: 'W' for white, 'C' for cyan, 'B' +for blue, 'M' for magenta, 'R' for red, 'Y' for yellow, 'G' from green, and 'K' +for black. The loop for accessing the data is then: + +int row, col, i = 0; + +for (row = 0; row < my_symbol->bitmap_height; row++) { + for (col = 0; col < my_symbol->bitmap_width; col++) { + render_pixel(row, col, my_symbol->bitmap[i]); + i++; + } +} + 5.5 Setting Options ------------------- So far our application is not very useful unless we plan to only make Code 128 @@ -1143,21 +1159,23 @@ together when adjusting this value: my_symbol->output_options |= BARCODE_BIND | READER_INIT; -------------------------------------------------------------------------------- -Value | Effect +Value | Effect -------------------------------------------------------------------------------- -0 | No options selected. -BARCODE_BIND | Boundary bars above and below the symbol and between - | rows if stacking multiple symbols. [2] -BARCODE_BOX | Add a box surrounding the symbol and whitespace. [2] -BARCODE_STDOUT | Output the file to stdout. -READER_INIT | Add a reader initialisation symbol to the data before - | encoding. -SMALL_TEXT | Use a smaller font for the human readable text. -BOLD_TEXT | Embolden the human readable text. -CMYK_COLOUR | Select the CMYK colour space option for encapsulated - | PostScript files. -BARCODE_DOTTY_MODE | Plot a matrix symbol using dots rather than squares. -GS1_GS_SEPARATOR | Use GS instead FNC1 as GS1 separator (Data Matrix). +0 | No options selected. +BARCODE_BIND | Boundary bars above and below the symbol and between + | rows if stacking multiple symbols. [2] +BARCODE_BOX | Add a box surrounding the symbol and whitespace. [2] +BARCODE_STDOUT | Output the file to stdout. +READER_INIT | Add a reader initialisation symbol to the data before + | encoding. +SMALL_TEXT | Use a smaller font for the human readable text. +BOLD_TEXT | Embolden the human readable text. +CMYK_COLOUR | Select the CMYK colour space option for encapsulated + | PostScript files. +BARCODE_DOTTY_MODE | Plot a matrix symbol using dots rather than squares. +GS1_GS_SEPARATOR | Use GS instead FNC1 as GS1 separator (Data Matrix). +OUT_BUFFER_INTERMEDIATE | Return the bitmap buffer as ASCII values instead of + | separate colour channels (OUT_BUFFER only). -------------------------------------------------------------------------------- 5.9 Setting the Input Mode @@ -2950,7 +2968,7 @@ reproduced here for reference. ------------------------------------------------------------- Hex | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 ------------------------------------------------------------- -0 | NULL | DLE | SPACE | 0 | @ | P | ` | p +0 | NUL | DLE | SPACE | 0 | @ | P | ` | p 1 | SOH | DC1 | ! | 1 | A | Q | a | q 2 | STX | DC2 | " | 2 | B | R | b | r 3 | ETX | DC3 | # | 3 | C | S | c | s