Add dot (circle) plotting for raster (PNG/GIF/PCX/BMP) images

This commit is contained in:
Robin Stuart 2016-08-08 23:18:55 +01:00
parent 30b8bebf82
commit 498fd4151d

View File

@ -55,54 +55,26 @@ extern int gif_pixel_plot(struct zint_symbol *symbol, int image_height, int imag
int save_raster_image_to_file(struct zint_symbol *symbol, int image_height, int image_width, char *pixelbuf, int rotate_angle, int image_type) {
int error_number;
float scaler = symbol->scale;
char *scaled_pixelbuf;
int horiz, vert, i;
int scale_width, scale_height;
if (scaler == 0) {
scaler = 0.5;
}
scale_width = image_width * scaler;
scale_height = image_height * scaler;
/* Apply scale options by creating another pixel buffer */
if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
printf("Insufficient memory for pixel buffer");
return ZINT_ERROR_ENCODING_PROBLEM;
} else {
for (i = 0; i < (scale_width * scale_height); i++) {
*(scaled_pixelbuf + i) = '0';
}
}
for (vert = 0; vert < scale_height; vert++) {
for (horiz = 0; horiz < scale_width; horiz++) {
*(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int) (vert / scaler) * image_width) + (int) (horiz / scaler));
}
}
switch (image_type) {
case OUT_PNG_FILE:
#ifndef NO_PNG
error_number = png_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle);
error_number = png_pixel_plot(symbol, image_height, image_width, pixelbuf, rotate_angle);
#else
return ZINT_ERROR_INVALID_OPTION;
#endif
break;
case OUT_PCX_FILE:
error_number = pcx_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle);
error_number = pcx_pixel_plot(symbol, image_height, image_width, pixelbuf, rotate_angle);
break;
case OUT_GIF_FILE:
error_number = gif_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle);
error_number = gif_pixel_plot(symbol, image_height, image_width, pixelbuf, rotate_angle);
break;
default:
error_number = bmp_pixel_plot(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle);
error_number = bmp_pixel_plot(symbol, image_height, image_width, pixelbuf, rotate_angle);
break;
}
free(scaled_pixelbuf);
return error_number;
}
@ -309,6 +281,10 @@ int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int data_
char *pixelbuf;
int error_number;
int xoffset, yoffset;
float scaler = symbol->scale;
char *scaled_pixelbuf;
int horiz, vert;
int scale_width, scale_height;
xoffset = symbol->border_width + symbol->whitespace_width;
yoffset = symbol->border_width;
@ -355,7 +331,31 @@ int plot_raster_maxicode(struct zint_symbol *symbol, int rotate_angle, int data_
draw_bar(pixelbuf, 300 + ((symbol->border_width + symbol->whitespace_width + symbol->whitespace_width) * 2), symbol->border_width * 2, 0, image_height, image_width, image_height);
}
error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
if (scaler == 0) {
scaler = 0.5;
}
scale_width = image_width * scaler;
scale_height = image_height * scaler;
/* Apply scale options by creating another pixel buffer */
if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
printf("Insufficient memory for pixel buffer");
return ZINT_ERROR_ENCODING_PROBLEM;
} else {
for (i = 0; i < (scale_width * scale_height); i++) {
*(scaled_pixelbuf + i) = '0';
}
}
for (vert = 0; vert < scale_height; vert++) {
for (horiz = 0; horiz < scale_width; horiz++) {
*(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int) (vert / scaler) * image_width) + (int) (horiz / scaler));
}
}
error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
free(scaled_pixelbuf);
free(pixelbuf);
return error_number;
}
@ -399,6 +399,70 @@ void to_latin1(unsigned char source[], unsigned char preprocessed[]) {
return;
}
void draw_circle(char *pixelbuf, int image_width, int image_height, int x0, int y0, int radius) {
int x, y;
for (y = -radius; y <= radius; y++) {
for (x = -radius; x <= radius; x++) {
if ((x * x) + (y * y) <= (radius * radius)) {
if ((y + y0 >= 0) && (y + y0 < image_height)
&& (x + x0 >= 0) && (x + x0 < image_width)) {
*(pixelbuf + ((y + y0) * image_width) + (x + x0)) = '1';
}
}
}
}
}
int plot_raster_dotty(struct zint_symbol *symbol, int rotate_angle, int data_type) {
float scaler = 2 * symbol->scale;
char *scaled_pixelbuf;
int r, i;
int scale_width, scale_height;
int error_number = 0;
int xoffset, yoffset, image_width, image_height;
symbol->height = symbol->rows; // This is true because only 2d matrix symbols are processed here
xoffset = symbol->border_width + symbol->whitespace_width;
yoffset = symbol->border_width;
image_width = symbol->width + xoffset + xoffset;
image_height = symbol->height + yoffset + yoffset;
if (scaler < 2.0) {
scaler = 2.0;
}
scale_width = (image_width * scaler) + 1;
scale_height = (image_height * scaler) + 1;
/* Apply scale options by creating another pixel buffer */
if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
printf("Insufficient memory for pixel buffer");
return ZINT_ERROR_ENCODING_PROBLEM;
} else {
for (i = 0; i < (scale_width * scale_height); i++) {
*(scaled_pixelbuf + i) = '0';
}
}
/* Plot the body of the symbol to the pixel buffer */
for (r = 0; r < symbol->rows; r++) {
for (i = 0; i < symbol->width; i++) {
if (module_is_set(symbol, r, i)) {
draw_circle(scaled_pixelbuf, scale_width, scale_height,
(int) ((i + xoffset) * scaler) + (scaler / 2.0),
(int) ((r + yoffset) * scaler) + (scaler / 2.0),
(int) (scaler / 2.0));
}
}
}
error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
free(scaled_pixelbuf);
return error_number;
}
int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_type) {
int textdone, main_width, comp_offset, large_bar_count;
char textpart[10], addon[6];
@ -411,6 +475,10 @@ int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_t
int error_number;
int default_text_posn;
int next_yposn;
float scaler = symbol->scale;
char *scaled_pixelbuf;
int horiz, vert;
int scale_width, scale_height;
#ifndef _MSC_VER
unsigned char local_text[ustrlen(symbol->text) + 1];
#else
@ -456,8 +524,7 @@ int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_t
row_height = 0;
if (symbol->output_options & SMALL_TEXT) {
textflags = 1;
}
else if (symbol->output_options & BOLD_TEXT) {
} else if (symbol->output_options & BOLD_TEXT) {
textflags = 2;
}
@ -826,7 +893,31 @@ int plot_raster_default(struct zint_symbol *symbol, int rotate_angle, int data_t
draw_string(pixelbuf, (char*) local_text, textpos, default_text_posn, textflags, image_width, image_height);
}
error_number = save_raster_image_to_file(symbol, image_height, image_width, pixelbuf, rotate_angle, data_type);
if (scaler == 0) {
scaler = 0.5;
}
scale_width = image_width * scaler;
scale_height = image_height * scaler;
/* Apply scale options by creating another pixel buffer */
if (!(scaled_pixelbuf = (char *) malloc(scale_width * scale_height))) {
printf("Insufficient memory for pixel buffer");
return ZINT_ERROR_ENCODING_PROBLEM;
} else {
for (i = 0; i < (scale_width * scale_height); i++) {
*(scaled_pixelbuf + i) = '0';
}
}
for (vert = 0; vert < scale_height; vert++) {
for (horiz = 0; horiz < scale_width; horiz++) {
*(scaled_pixelbuf + (vert * scale_width) + horiz) = *(pixelbuf + ((int) (vert / scaler) * image_width) + (int) (horiz / scaler));
}
}
error_number = save_raster_image_to_file(symbol, scale_height, scale_width, scaled_pixelbuf, rotate_angle, data_type);
free(scaled_pixelbuf);
free(pixelbuf);
return error_number;
}
@ -841,11 +932,15 @@ int plot_raster(struct zint_symbol *symbol, int rotate_angle, int file_type) {
}
#endif /* NO_PNG */
if (symbol->output_options &= BARCODE_DOTTY_MODE) {
error = plot_raster_dotty(symbol, rotate_angle, file_type);
} else {
if (symbol->symbology == BARCODE_MAXICODE) {
error = plot_raster_maxicode(symbol, rotate_angle, file_type);
} else {
error = plot_raster_default(symbol, rotate_angle, file_type);
}
}
return error;
}