The htm4x4 example of the modular screening API implements a primitive bi-level halftone that could not be produced using conventional PostScript/PDF thresholds, because pixels can be extinguished as well as lit when moving from one shade to a darker shade. More...
Files | |
file | htm4x4.h |
HTM Interface to a simple example screening module which implements primitive non-monotonic halftones. | |
file | htm4x4.c |
A primitive non-monotonic screening module example. | |
Functions | |
sw_htm_api * | htm4x4_getInstance (void) |
Return the singleton instance of the sw_htm_api object containing details of the example '4x4' screening module. More... | |
static sw_htm_result | h4x4HalftoneSelect (sw_htm_instance *instance, const sw_htm_select_info *info, sw_htm_instance **matches) |
Implementation of sw_htm_api::HalftoneSelect(). More... | |
static void | h4x4HalftoneRelease (sw_htm_instance *instance) |
Implementation of sw_htm_api::HalftoneRelease(). More... | |
static sw_htm_result | h4x4RenderInit (sw_htm_api *implementation, const sw_htm_render_info *render_info) |
Implementation of sw_htm_api::RenderInitiation(). More... | |
static HqBool | h4x4DoHalftone (sw_htm_instance *instance, const sw_htm_dohalftone_request *request) |
Implementation of sw_htm_api::DoHalftone(). More... | |
static void | h4x4AbortHalftone (sw_htm_instance *instance, const sw_htm_dohalftone_request *request) |
Implementation of sw_htm_api::AbortHalftone(). More... | |
The htm4x4 example of the modular screening API implements a primitive bi-level halftone that could not be produced using conventional PostScript/PDF thresholds, because pixels can be extinguished as well as lit when moving from one shade to a darker shade.
It uses simple hand-crafted 4x4 grids as the basis for its halftones.
These are not intended to produce screening of anything but a very poor quality - the objective being only to demonstrate the mechanisms used. The halftones are limited to producing a mere 16 tonal shades, apart from white/blank, and consequently exhibit significant quantization. They also suffer from patterning.
To demonstrate the htm4x4 screen in action, you can use the configuration in SW/TestConfig/HTM/CMYKCompHtmEgBand300dpi
with the "clrip" application.
This example module is registered by calling SwRegisterHTM() with the singleton API instance returned by htm4x4_getInstance(). The module implements the modular screening API methods h4x4HalftoneSelect(), h4x4HalftoneRelease(), h4x4RenderInit(), h4x4DoHalftone(), and h4x4AbortHalftone().
|
static |
Implementation of sw_htm_api::AbortHalftone().
The RIP calls h4x4AbortHalftone() when it wants the module to stop rendering an outstanding request issued by h4x4DoHalftone() with the same arguments.
The module must stop writing to its output buffers and then invoke sw_htm_dohalftone_request::DoneHalftone() before returning (it is permissible to invoke it from another thread). Because the calls can't be synchronized, it may happen that the module has already called sw_htm_dohalftone_request::DoneHalftone() between the RIP deciding to abort and actually invoking AbortHalftone(). This is acceptable, but the module must be so constructed that any such sw_htm_dohalftone_request::DoneHalftone() has, in fact, returned before AbortHalftone() returns. The RIP will check if the request has, in fact, terminated, and it is an error if it hasn't.
[in] | instance | Pointer to a halftone instance selected by HalftoneSelect(). |
[in] | request | Pointer to a structure holding details of the RIP's halftone request. |
|
static |
Implementation of sw_htm_api::DoHalftone().
This is the most important function in the module.
The RIP calls h4x4DoHalftone() when it wants the module to render a halftone instance into a channel within the RIP's band buffers.
In the case of this example, the halftoning is so simple that even though the RIP is capable of asynchronous calls, we still opt to complete ours synchronously.
[in] | instance | Pointer to a halftone instance selected by HalftoneSelect(). |
[in] | request | Pointer to a structure holding details of the RIP's halftone request. |
FALSE | The module is unable to accept the request. In this case, the module must not touch any arguments passed to it, and the RIP will deem this an unrecoverable failure. |
TRUE | The module accepts the request and will call sw_htm_dohalftone_request::DoneHalftone() when done. The success or failure of the overall request is indicated by the result parameter of sw_htm_dohalftone_request::DoneHalftone(). |
The module must not block on something that depends on another DoHalftone() invocation being made. Even if sw_htm_render_info::max_render_threads > 1, there's no guarantee that another invocation can be made concurrently.
The module must call sw_htm_dohalftone_request::DoneHalftone() using exactly the same request pointer passed in to it.
|
static |
Implementation of sw_htm_api::HalftoneRelease().
h4x4HalftoneRelease() will be called once for each previously successful h4x4HalftoneSelect() when the RIP no longer needs the halftone instance.
Because this example uses statically declared halftone instances, we don't need to free any memory or do anything very complex at all.
All we do, therefore, is check that the halftone instance value matches one of our instances, and that its reference count hasn't gone awry.
HalftoneRelease() will be called once for each previously successful HalftoneSelect(), with the instance pointer that is not required. The implementation should clean up any resources associated with the instance.
[in] | instance | The halftone instance value originally constructed by HalftoneSelect(). |
|
static |
Implementation of sw_htm_api::HalftoneSelect().
h4x4HalftoneSelect() is called when the page description language (PDL) does the equivalent of a PostScript sethalftone
.
The RIP calls us individually for each halftone needed, so in the case of multi-colorants, such as a PostScript/PDF type 5 halftone dictionary, the RIP will call us for each colorant sub-dictionary therein.
We only have to worry, therefore, about a single halftone instance in any one call.
The key names this module understands from the halftone dictionary are:
false
.This example is so simple that we can declare our instance structures statically, so all that's really involved here is validating our parameters, initializing the inverse screen cells if needed, determine our appropriate halftone instance, increment its reference count, and fill in the details for the RIP.
In the case of the bit depth of the source raster, we can handle both 8 and 16 bits, so if the RIP hasn't already decided upon a bit depth, we opt for 8 bits on the premise that the extra depth won't benefit our very primitive screens, and 8 bits will RIP faster than 16.
[in,out] | instance | An incomplete instance of the sw_htm_instance structure to complete. The RIP will allocate a structure of the size presented in the implementation's sw_htm_api::info.instance_size field, fill in the implementation and callback API instance pointers, and then pass it to this routine. The HalftoneSelect() method is expected to fill in the remaining fields. The implementation may sub-class the instance to allocate private workspace by initialising the sw_htm_api::info.instance_size larger than the size of the sw_htm_instance structure, then downcasting the instance pointer in method calls. |
[in] | info | Halftone selection information from the RIP. This contains things like the halftone phase and a pointer to an information structure describing the destination raster and colorants etc. It also contains a data access API, a datum representing the colorant name for which this halftone is being selected and a datum representing the halftone dictionary. Any data accessed through this pointer MUST be copied if the halftone instance wished to refer to it after the HalftoneSelect() method has returned. |
[out] | matches | If the halftone module currently has an instance selected that maps onto the same screen, it should store the existing instance in this pointer and return SW_HTM_SUCCESS. In this case, the instance under construction will be destroyed immediately, and there will be no call to HalftoneRelease(). This will ensure that equivalent screen definitions share the same DoHalftone() calls, and will improve rendering efficiency. It is an error to store the instance under construction through this pointer. |
|
static |
Implementation of sw_htm_api::RenderInitiation().
The RIP calls h4x4RenderInit() when it prepares to render a page.
This primitive example doesn't really have much to do in this function. We just check that the source (contone) and destination (halftone) raster bit depths are appropriate, and let the RIP know our rendering needs.
RenderInitiation() is a class function. It will be called once for each halftone module that may have halftones used on a page.
In the case of color-separated output, RenderInitiation() takes place once, before the RIP renders all the separations of a page.
Note that when the RenderInitiation() is for a partial paint, very little memory will be available, so any mandatory buffers should be preallocated during HalftoneSelect().
This method is optional.
[in] | implementation | A pointer to the implementation registered with the RIP. |
[in] | render_info | Pointer to a structure containing general information about the upcoming render as a whole. |
sw_htm_api* htm4x4_getInstance | ( | void | ) |
Return the singleton instance of the sw_htm_api object containing details of the example '4x4' screening module.
If compiled normally, the "clrip" application layer registers this module during RIP startup. Halftone module examples may be excluded from "clrip" by building with NO_HTMEG
defined.