CAPS Universe documentation
1.0.4
All you need to know to be successful
|
Collection of halftone routines. More...
Data Structures | |
union | ht_dot_vector |
Union to convert eight grey scale dots into monochrome. More... | |
struct | monochrome_converter |
Halftone processing buffer. More... | |
struct | drv_halftone_converter |
Monochrome halftone processing. More... | |
Macros | |
#define | WHITE_DOT 255 |
Typedefs | |
typedef unsigned char | htpix8 |
Vector to define eight dots in the halftone buffer. | |
Functions | |
struct drv_halftone_converter * | ht_get (enum halftone_type t, unsigned cnt) |
void | ht_put (struct drv_halftone_converter *ht) |
static signed int | ht_quantize_grey_dot (const struct drv_halftone_converter *ht, signed int v) |
static signed int | ht_quant_error_calc (signed int orig, signed int final) |
static unsigned char | diffuse (signed int raw, signed int err, signed int numerator, signed int denominator) |
static void | lp_average (struct drv_halftone_converter *ht) |
static void | lp_ordered (struct drv_halftone_converter *ht) |
static void | lp_flsdiffusion_lr (struct drv_halftone_converter *ht) |
static void | lp_flsdiffusion_rl (struct drv_halftone_converter *ht) |
static void | lp_jjndiffusion_lr (struct drv_halftone_converter *ht) |
static void | lp_jjndiffusion_rl (struct drv_halftone_converter *ht) |
static void | dither_line (struct drv_halftone_converter *ht) |
int | ht_grey_line_add (struct drv_halftone_converter *ht, unsigned cnt, const struct caps_dot_grey raw[cnt]) |
int | ht_emptyline_add (struct drv_halftone_converter *ht) |
int | ht_drain (struct drv_halftone_converter *ht) |
unsigned | ht_monochrome_line_get (struct drv_halftone_converter *ht, enum caps_colour_format cf, unsigned cnt, struct caps_dot_monochrome ln[cnt]) |
Variables | |
static const signed char | bayer_8x8_pattern [8][8] |
8x8 Bayer ordered dithering pattern | |
Halftone routines for monochrome rasters.
Halftoning is done according to halftone_type and processing is done on unsigned char values, one per dot.
After processing a single dot in the top monochrome_converter::sliding_line buffer has a '0' for a black dot or a '255' (WHITE_DOT) for no dot (e.g. keep medium's colour).
Converting into monochrome data is done via ht_monochrome_line_get().
According to a famous paper about halftone algorithms:
It is critical with all of these algorithms that when error values are added to neighboring pixels, the resultant summed values must be truncated to fit- within the limits of hardware. Otherwise, an area of very intense color may cause streaks into an adjacent area of less intense color.
This truncation is known as "clipping," and is analogous to the audio world's concept of the same name. As in the case of an audio amplifier, clipping adds undesired noise to the data. Unlike the audio world, however, the visual clipping performed in error-diffusion halftoning is acceptable since it is not nearly so offensive as the color streaking that would occur otherwise. It is mainly for this reason that the larger filters work better – they split the errors up more finely and produce less clipping noise.
With all of these filters, it is also important to ensure that the sum of the distributed error values is equal to the original error value. This is most easily accomplished by subtracting each fraction, as it is calculated, from the whole error value, and using the final remainder as the last fraction.
Cited from "DHALF.txt".
#define WHITE_DOT 255 |
Defines the signed short value for a white dot (e.g. no dot)
typedef unsigned char htpix8 |
struct drv_halftone_converter * ht_get | ( | enum halftone_type | t, |
unsigned | cnt | ||
) |
Create and configure a halftone converter
[in] | t | Type of the halftone algorithm to configure |
[in] | cnt | Pixel count in each line |
Depending on the selected halftone algorithm, memory to process the input grey scale lines later on will be allocated.
void ht_put | ( | struct drv_halftone_converter * | ht | ) |
Destroy a halftone converter configuration and free resources
[in] | ht | The halftone converter configuration |
|
static |
|
static |
Calculate the quantization error for a dot value
[in] | orig | The original value (0 … 255) |
[in] | final | The quantized value (0 or 255) |
Positive | The final value was too dark compared to orig |
Negative | The final value was too light compared to orig |
Returns: orig
- final
|
static |
Diffuse a quantization error according to a fraction number
[in] | raw | The raw value (0 … 255) |
[in] | err | The quantization error (-128 … 0 … +127) |
[in] | numerator | The numerator of the fraction |
[in] | denominator | The denominator of the fraction |
Calculation done here is: result = raw
+ ((err
* numerator
) / denominator
)
The multiplication is done first, to keep the error as small as possible.
And the result is clipped to be in the range of 0 … 255
|
static |
Process a line according to the average method
[in] | ht | The halftone converter configuration |
For this method, there is no left/right serpentine processing.
|
static |
Process a line according to the Bayer ordered dither.
[in] | ht | The halftone converter configuration |
For this method, there is no left/right serpentine processing.
|
static |
Process a line according to the Floyd and Steinberg method, left to right processing direction
[in] | ht | The halftone converter configuration |
Processing description:
------------------> processing direction | * 7/16 | <-- cnf->sliding_line[0] | 3/16 5/16 1/16 | <-- cnf->sliding_line[1]
|
static |
Process a line according to the Floyd and Steinberg method, right to left processing direction
[in] | ht | The halftone converter configuration |
Processing description:
<------------------ processing direction | 7/16 * | <-- sliding_line[0] | 1/16 5/16 3/16 | <-- sliding_line[1]
|
static |
Process a line according to the Jarvis, Judice, and Ninke method, left to right processing direction
[in] | ht | The halftone converter configuration |
Processing description:
-------------------------------> processing direction | * 7/48 5/48 | <-- cnf->sliding_line[0] | 3/48 5/48 7/48 5/48 3/48 | <-- cnf->sliding_line[1] | 1/48 3/48 5/48 3/48 1/48 | <-- cnf->sliding_line[2]
|
static |
Process a line according to the Jarvis, Judice, and Ninke method, right to left processing direction
[in] | ht | The halftone converter configuration |
Processing description:
<--------------------------------- processing direction | 5/48 7/48 * | <-- cnf->sliding_line[0] | 3/48 5/48 7/48 5/48 3/48 | <-- cnf->sliding_line[1] | 1/48 3/48 5/48 3/48 1/48 | <-- cnf->sliding_line[2]
|
static |
Run the halftone algorithm on buffer's top line
[in] | ht | The halftone converter configuration |
int ht_grey_line_add | ( | struct drv_halftone_converter * | ht, |
unsigned | cnt, | ||
const struct caps_dot_grey | raw[cnt] | ||
) |
Add a line with grey scale content to the halftone algorithm's processing buffer
[in] | ht | The halftone converter configuration |
[in] | cnt | Count of grey scale dots in raw (can be '0') |
[in] | raw | A raw line of grey scale dots (caps_dot_grey), can be NULL if cnt is '0' as well |
-EAGAIN | Add another line first to pre-load the halftone algorithm |
0 | A dithered line awaits its read via ht_monochrome_line_get() |
If the call returns with a 0, a line can be read with ht_monochrome_line_get()
cnt
is '0', an empty line (e.g. all dot are white) is added to the halftone converter.Silently:
int ht_emptyline_add | ( | struct drv_halftone_converter * | ht | ) |
Add an empty line (e.g. all dots are white) to the halftone algorithm's processing buffer
[in] | ht | The halftone converter configuration |
-EAGAIN | Add another line first to pre-load the halftone algorithm |
0 | A dithered line awaits its read via ht_monochrome_line_get() |
When the call returns with a 0, a line can be read with ht_monochrome_line_get()
int ht_drain | ( | struct drv_halftone_converter * | ht | ) |
Drain the halftone algorithm's processing buffer by padding an empty line
[in] | ht | The halftone converter configuration |
0 | Finished |
-EAGAIN | Read a dithered line via ht_monochrome_line_get() and call again |
Let process the halftone algorithm the next line with a new empty line. Intended to be called at the bottom of the input raster to finish the halftone algorithm. Some algorithm needs more than one line in its buffer to process the current line. Call this routine as often as it returns -EAGAIN. After each call (and -EAGAIN) you can read the next processed line. If it returns 0
, you are done.
If the call returns with a -EAGAIN, another line can be read with ht_monochrome_line_get()
unsigned ht_monochrome_line_get | ( | struct drv_halftone_converter * | ht, |
enum caps_colour_format | cf, | ||
unsigned | cnt, | ||
struct caps_dot_monochrome | ln[cnt] | ||
) |
Extract the monochrome data line from the halftone processing buffer
[in] | ht | The halftone converter configuration |
[in] | cf | The target monochrome colour format (one of CAPS_CF_MONOCHROME0 or CAPS_CF_MONOCHROME1) |
[in] | cnt | The amount of bytes in ln |
[out] | ln | The buffer for the monochrome data |
ln
(not bytes!)Converts the top line from the halftone converter into a line of monochrome bits in ln
. In order to make this work, this top line must already be processed, e.g. the last call to ht_grey_line_add() and ht_emptyline_add() returned with '0' or a call to ht_drain() returned with -EAGAIN.
If the count of grey scale dots in the halftone converter's line isn't a multiple of eight, the remaining resulting monochrome bits are white, e.g. set to "no dot".
ln
must be equal or greater than DOTS_TO_BYTES(drv_halftone_converter::cnt) bytes
|
static |
Used by the lp_ordered() halftone funtion.