mirror of
https://github.com/zint/zint
synced 2024-11-16 20:57:25 +13:00
Better compression for Ultracode in BMP
Also corrects colour shifting bug File size is still bigger than it needs to be for Ultracode, but now uses 4bpp
This commit is contained in:
parent
20f767c4b6
commit
b5e27d3e0b
@ -52,10 +52,11 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
bitmap_info_header_t info_header;
|
||||
color_ref_t bg_color_ref;
|
||||
color_ref_t fg_color_ref;
|
||||
color_ref_t ultra_color_ref[8];
|
||||
|
||||
if (symbol->symbology == BARCODE_ULTRA) {
|
||||
bits_per_pixel = 24;
|
||||
colour_count = 0;
|
||||
bits_per_pixel = 4;
|
||||
colour_count = 9;
|
||||
} else {
|
||||
bits_per_pixel = 1;
|
||||
colour_count = 2;
|
||||
@ -63,9 +64,7 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
row_size = 4 * ((bits_per_pixel * symbol->bitmap_width + 31) / 32);
|
||||
data_size = symbol->bitmap_height * row_size;
|
||||
data_offset = sizeof (bitmap_file_header_t) + sizeof (bitmap_info_header_t);
|
||||
if (symbol->symbology != BARCODE_ULTRA) {
|
||||
data_offset += (2 * (sizeof(color_ref_t)));
|
||||
}
|
||||
data_offset += (colour_count * (sizeof(color_ref_t)));
|
||||
file_size = data_offset + data_size;
|
||||
|
||||
bitmap_file_start = (unsigned char *) malloc(file_size);
|
||||
@ -85,64 +84,44 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
bg_color_ref.green = (16 * ctoi(symbol->bgcolour[2])) + ctoi(symbol->bgcolour[3]);
|
||||
bg_color_ref.blue = (16 * ctoi(symbol->bgcolour[4])) + ctoi(symbol->bgcolour[5]);
|
||||
bg_color_ref.reserved = 0x00;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
ultra_color_ref[i].red = colour_to_red(i + 1);
|
||||
ultra_color_ref[i].green = colour_to_green(i + 1);
|
||||
ultra_color_ref[i].blue = colour_to_blue(i + 1);
|
||||
ultra_color_ref[i].reserved = 0x00;
|
||||
}
|
||||
|
||||
/* Pixel Plotting */
|
||||
if (symbol->symbology == BARCODE_ULTRA) {
|
||||
for (row = 0; row < symbol->bitmap_height; row++) {
|
||||
for (column = 0; column < symbol->bitmap_width; column++) {
|
||||
i = (3 * column) + (row * row_size);
|
||||
i = (column / 2) + (row * row_size);
|
||||
switch (*(pixelbuf + (symbol->bitmap_width * (symbol->bitmap_height - row - 1)) + column)) {
|
||||
case 'W': // White
|
||||
bitmap[i] = 255;
|
||||
bitmap[i + 1] = 255;
|
||||
bitmap[i + 2] = 255;
|
||||
break;
|
||||
case 'C': // Cyan
|
||||
bitmap[i] = 255;
|
||||
bitmap[i + 1] = 255;
|
||||
bitmap[i + 2] = 0;
|
||||
bitmap[i] += 1 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
case 'B': // Blue
|
||||
bitmap[i] = 255;
|
||||
bitmap[i + 1] = 0;
|
||||
bitmap[i + 2] = 0;
|
||||
bitmap[i] += 2 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
case 'M': // Magenta
|
||||
bitmap[i] = 255;
|
||||
bitmap[i + 1] = 0;
|
||||
bitmap[i + 2] = 255;
|
||||
bitmap[i] += 3 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
case 'R': // Red
|
||||
bitmap[i] = 0;
|
||||
bitmap[i + 1] = 0;
|
||||
bitmap[i + 2] = 255;
|
||||
bitmap[i] += 4 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
case 'Y': // Yellow
|
||||
bitmap[i] = 0;
|
||||
bitmap[i + 1] = 255;
|
||||
bitmap[i + 2] = 255;
|
||||
bitmap[i] += 5 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
case 'G': // Green
|
||||
bitmap[i] = 0;
|
||||
bitmap[i + 1] = 255;
|
||||
bitmap[i + 2] = 0;
|
||||
bitmap[i] += 6 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
case 'K': // Black
|
||||
bitmap[i] = 0;
|
||||
bitmap[i + 1] = 0;
|
||||
bitmap[i + 2] = 0;
|
||||
bitmap[i] += 7 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
case '1':
|
||||
bitmap[i] = fg_color_ref.blue;
|
||||
bitmap[i + 1] = fg_color_ref.green;
|
||||
bitmap[i + 2] = fg_color_ref.red;
|
||||
case 'W': // White
|
||||
bitmap[i] += 8 << (4 * (1 - (column % 2)));
|
||||
break;
|
||||
default:
|
||||
bitmap[i] = bg_color_ref.blue;
|
||||
bitmap[i + 1] = bg_color_ref.green;
|
||||
bitmap[i + 2] = bg_color_ref.red;
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -181,9 +160,14 @@ INTERNAL int bmp_pixel_plot(struct zint_symbol *symbol, char *pixelbuf) {
|
||||
bmp_posn += sizeof (bitmap_file_header_t);
|
||||
memcpy(bmp_posn, &info_header, sizeof (bitmap_info_header_t));
|
||||
|
||||
if (symbol->symbology != BARCODE_ULTRA) {
|
||||
bmp_posn += sizeof(bitmap_info_header_t);
|
||||
memcpy(bmp_posn, &bg_color_ref, sizeof(color_ref_t));
|
||||
bmp_posn += sizeof(bitmap_info_header_t);
|
||||
memcpy(bmp_posn, &bg_color_ref, sizeof(color_ref_t));
|
||||
if (symbol->symbology == BARCODE_ULTRA) {
|
||||
for (i = 0; i < 8; i++) {
|
||||
bmp_posn += sizeof(color_ref_t);
|
||||
memcpy(bmp_posn, &ultra_color_ref[i], sizeof(color_ref_t));
|
||||
}
|
||||
} else {
|
||||
bmp_posn += sizeof(color_ref_t);
|
||||
memcpy(bmp_posn, &fg_color_ref, sizeof(color_ref_t));
|
||||
}
|
||||
|
@ -67,9 +67,9 @@ extern "C" {
|
||||
} bitmap_info_header_t;
|
||||
|
||||
typedef struct color_ref {
|
||||
uint8_t red;
|
||||
uint8_t green;
|
||||
uint8_t blue;
|
||||
uint8_t green;
|
||||
uint8_t red;
|
||||
uint8_t reserved;
|
||||
} color_ref_t;
|
||||
|
||||
|
@ -449,6 +449,51 @@ INTERNAL void pn_define_mode(char *mode, const unsigned int data[], const size_t
|
||||
}
|
||||
}
|
||||
|
||||
INTERNAL int colour_to_red(int colour) {
|
||||
int return_val = 0;
|
||||
|
||||
switch(colour) {
|
||||
case 8: // White
|
||||
case 3: // Magenta
|
||||
case 4: // Red
|
||||
case 5: // Yellow
|
||||
return_val = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
INTERNAL int colour_to_green(int colour) {
|
||||
int return_val = 0;
|
||||
|
||||
switch(colour) {
|
||||
case 8: // White
|
||||
case 1: // Cyan
|
||||
case 5: // Yellow
|
||||
case 6: // Green
|
||||
return_val = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
INTERNAL int colour_to_blue(int colour) {
|
||||
int return_val = 0;
|
||||
|
||||
switch(colour) {
|
||||
case 8: // White
|
||||
case 1: // Cyan
|
||||
case 2: // Blue
|
||||
case 3: // Magenta
|
||||
return_val = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
#ifdef ZINT_TEST
|
||||
/* Dumps hex-formatted codewords in symbol->errtxt (for use in testing) */
|
||||
void debug_test_codeword_dump(struct zint_symbol *symbol, unsigned char *codewords, int length) {
|
||||
|
@ -100,6 +100,10 @@ extern "C" {
|
||||
INTERNAL void pn_define_mode(char *mode, const unsigned int data[], const size_t length, const int debug,
|
||||
unsigned int state[], const char mode_types[], const int num_modes,
|
||||
pn_head_costs head_costs, pn_switch_cost switch_cost, pn_eod_cost eod_cost, pn_cur_cost cur_cost);
|
||||
|
||||
INTERNAL int colour_to_red(int colour);
|
||||
INTERNAL int colour_to_green(int colour);
|
||||
INTERNAL int colour_to_blue(int colour);
|
||||
|
||||
#ifdef ZINT_TEST
|
||||
void debug_test_codeword_dump(struct zint_symbol *symbol, unsigned char *codewords, int length);
|
||||
|
@ -42,51 +42,6 @@
|
||||
#include "common.h"
|
||||
#include "emf.h"
|
||||
|
||||
int colour_to_red(int colour) {
|
||||
int return_val = 0;
|
||||
|
||||
switch(colour) {
|
||||
case 8: // White
|
||||
case 3: // Magenta
|
||||
case 4: // Red
|
||||
case 5: // Yellow
|
||||
return_val = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
int colour_to_green(int colour) {
|
||||
int return_val = 0;
|
||||
|
||||
switch(colour) {
|
||||
case 8: // White
|
||||
case 1: // Cyan
|
||||
case 5: // Yellow
|
||||
case 6: // Green
|
||||
return_val = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
int colour_to_blue(int colour) {
|
||||
int return_val = 0;
|
||||
|
||||
switch(colour) {
|
||||
case 8: // White
|
||||
case 1: // Cyan
|
||||
case 2: // Blue
|
||||
case 3: // Magenta
|
||||
return_val = 255;
|
||||
break;
|
||||
}
|
||||
|
||||
return return_val;
|
||||
}
|
||||
|
||||
static int count_rectangles(struct zint_symbol *symbol) {
|
||||
int rectangles = 0;
|
||||
struct zint_vector_rect *rect;
|
||||
@ -617,18 +572,15 @@ INTERNAL int emf_plot(struct zint_symbol *symbol) {
|
||||
}
|
||||
|
||||
if (symbol->symbology == BARCODE_ULTRA) {
|
||||
printf("Using Ultra draw\n");
|
||||
for(i = 0; i < 8; i++) {
|
||||
if (rectangle_count_bycolour[i]) {
|
||||
fwrite(&emr_selectobject_colour[i], sizeof (emr_selectobject_t), 1, emf_file);
|
||||
|
||||
printf("colour %d\n", i);
|
||||
rect = symbol->vector->rectangles;
|
||||
this_rectangle = 0;
|
||||
while (rect) {
|
||||
if (rect->colour == i) {
|
||||
fwrite(&rectangle[this_rectangle], sizeof (emr_rectangle_t), 1, emf_file);
|
||||
printf("rect\n");
|
||||
}
|
||||
this_rectangle++;
|
||||
rect = rect->next;
|
||||
|
Loading…
Reference in New Issue
Block a user