|
CUPS rastertoql filter
1.0.4
Filter for the Brother QL family of label printers
|
Creating the printer's wire data for bi-coloured print. More...
Data Structures | |
| struct | colour_line_start |
Macros | |
| #define | HIGH_ENERGY 0x01 |
| #define | LOW_ENERGY 0x02 |
Functions | |
| static void | remove_overlapping_dots (size_t cnt, unsigned char black_block[cnt], const unsigned char red_block[cnt]) |
| static void | colour_line_convert (struct line_command *cmd, size_t input_cnt, const signed short inputb[input_cnt], const signed short inputr[input_cnt]) |
| static struct line_command * | colour_command_get (size_t bytes_per_line) |
| static void | colour_command_put (void *cmd) |
| static int | cups_ql_colour_line_process (struct qldriver *ql, struct halftone_converter *cnv_black, struct halftone_converter *cnv_red) |
| static double | fraction (double no) |
| static void | rgb2hsv (struct qlhsv *hsv, const struct qlrgb *rgb_pixel) |
| static void | red_dot_mark (signed int val, signed short *black_pixel, signed short *red_pixel) |
| static void | black_dot_mark (signed int val, signed short *black_pixel, signed short *red_pixel) |
| static signed int | to_grey (const struct qlrgb *pixel) |
| static signed int | is_red (struct qldriver *ql, const struct qlrgb *pixel) |
| static int | cups_ql_next_colour_line_read (struct qldriver *ql, struct halftone_converter *cnv_black, struct halftone_converter *cnv_red) |
| int | cups_ql_colour_page_print (struct qldriver *ql, int first_time) |
Variables | |
| int | terminate |
Creating the printer's wire data for bi-coloured print.
The QL8xx familiy of printers is capable of printing red and black dots on a special medium (e.g. DK2251).
"Colour" here means: black and red on white labels.
In this mode every line must be sent twice. First for low energie to print red dots and second for high energie to print black dots.
The result isn't perfect, since low energy creates red dots, the high energy black dots all have red shadows around them (because the high energy cools down beside the main dot area, the medium tends to red colour). Refer Limitations in bi-colour print for details.
| #define HIGH_ENERGY 0x01 |
Value to force a black dot. Used in the printer's command to print the black dots, refer colour_line_start for details
| #define LOW_ENERGY 0x02 |
Value to force a red dot. Used in the printer's command to print the red dots, refer colour_line_start for details
|
static |
Mark a black dot value into both line bufffers
| [in] | val | The brightness of the dot (-255 = full brightness … 0 = black) (negative value!) |
| [out] | black_pixel | Where to store the corresponding black value for no black dot at this position |
| [out] | red_pixel | Where to store the corresponding red value |
The black dots scale from 0x00 (black dot!) to 0xff (paper colour!) Red settings depends on red_dot_mark() and its inversion, e.g. both colours scale from 0x00 (dot!) to 0xff (no dot!)
|
static |
Allocate the buffer for the colour print command
| [in] | bytes_per_line | Expected bytes per line to be sent to the printer |
|
static |
Free the buffer for the monochrome print command
| [in] | cmd | The command buffer to be freed |
|
static |
Create the command to print one dual colour line
| [out] | cmd | Command data structure where to store the line data |
| [in] | input_cnt | Count of signed shorts in inputb and inputr (max. 2040 elements, usual 720 elements) |
| [in] | inputb | Black data to convert |
| [in] | inputr | Red data to convert |
The printer wire colour data format is:
| command | <bytes_per_line> | command | <bytes_per_line> |
e.g. according to the QL800 datasheet 186 bytes over all (90 bytes per line each).
|
static |
Process one line and send it to the printer
| [in] | ql | Full job description |
| [in] | cnv_black | Black data half-tone converter |
| [in] | cnv_red | Red data half-tone converter |
| 0 | On success |
| int cups_ql_colour_page_print | ( | struct qldriver * | ql, |
| int | first_time | ||
| ) |
Convert the current page into the printer's wire data format
| [in] | ql | Full job description |
| [in] | first_time | '1' if called the first time of this job, '0' else |
| 0 | On success |
| -EINVAL | Unsupported raster input format |
| -ECANCELED | Termination request from outerspace |
The routine loops through all or the remaining lines of the current page and converts them into the printer's colour wire format
|
static |
Read in the next line from a CUPS RGB raster right border aligned and separate black (e.g. shades of grey) and red (shades of)
| [in] | ql | Full job description |
| [in,out] | cnv_black | The black part of the line |
| [in,out] | cnv_red | The red part of the line |
|
static |
Return the fractional part of a floating point
| [in] | no | The full number |
Check, if the given pixel in RGB colour space defines a red pixel
| [in] | ql | Full job description |
| [in] | pixel | The RGB pixel to check |
| Positive | Black pixel brightness (grey scale value) |
| Negative | Red pixel brightness (hsv's value) |
This is a simple and ugly red dot detection. Since we have an RGB colour space, a red colour is hard to detect. Converting it into an HSV colour space makes it simpler to detect red.
If the hue is below 30° or above 350° it is more or less a red. It then depends on its saturation and value if it is a visible red - or still a black.
All checked values are user defined and part of the qldriver structure.
|
static |
Mark a red dot value into both line bufffers
| [in] | val | The brightness of the dot (-255 = full red brightness … 0 = no colour) (negative value!) |
| [out] | black_pixel | Where to store the corresponding black value for no black dot at this position |
| [out] | red_pixel | Where to store the corresponding red value |
The input values for the red dots get inverted. A 0x00 input means "no red", so a 255 is stored to keep the paper colour. And a -255 input means a "full red", so a 0 is stored to print a red dot. At the same position, the black pixel is setup to keep the paper colour and to not disturb the red dot printing.
|
static |
Remove dots in the black block, if they are already set in the red block
| [in] | cnt | Element count in black_block and red_block |
| [in,out] | black_block | Monochrome data for black dots |
| [in] | red_block | Monochrome data for red dots |
We should not send the command for low energy and high energy at the same dot position. So, remove the black dots (high energy) in favour of the red dots (low energy) if they overlap.
Convert one pixel from RGB colour space to HSV colour space
| [out] | hsv | The target HSV colour space |
| [in] | rgb_pixel | The RGB pixel to convert |
https://github.com/iamh2o/rgbw_colorspace_converter/
https://www.neltnerlabs.com/saikoled/how-to-convert-from-hsi-to-rgb-white
|
static |
Convert an RGB pixel to grey scale
| [in] | pixel | The pixel in RGB to convert (scale is 0…255 in each channel) |
| int terminate |
Change to '1' to signal the program should stop
1.8.17