Harlequin RIP SDK
A simple bilevel screen that cannot be written in PostScript

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_apihtm4x4_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...
 

Detailed Description

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().

Note
This code should be used for reference purposes only.

Function Documentation

◆ h4x4AbortHalftone()

static void h4x4AbortHalftone ( sw_htm_instance instance,
const sw_htm_dohalftone_request request 
)
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.

Note
This function is not implemented yet.

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.

Parameters
[in]instancePointer to a halftone instance selected by HalftoneSelect().
[in]requestPointer to a structure holding details of the RIP's halftone request.

◆ h4x4DoHalftone()

static HqBool h4x4DoHalftone ( sw_htm_instance instance,
const sw_htm_dohalftone_request 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.

Parameters
[in]instancePointer to a halftone instance selected by HalftoneSelect().
[in]requestPointer to a structure holding details of the RIP's halftone request.
Return values
FALSEThe 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.
TRUEThe 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.

◆ h4x4HalftoneRelease()

static void h4x4HalftoneRelease ( sw_htm_instance instance)
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.

Parameters
[in]instanceThe halftone instance value originally constructed by HalftoneSelect().

◆ h4x4HalftoneSelect()

static sw_htm_result h4x4HalftoneSelect ( sw_htm_instance instance,
const sw_htm_select_info info,
sw_htm_instance **  matches 
)
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:

Screen - Integer - Mandatory.
Which halftone pattern to use. Must be in the range 0 to 3.
Inverse - Boolean - Optional.
Whether to light pixels in inverse order. Default is 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.

Parameters
[in,out]instanceAn 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]infoHalftone 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]matchesIf 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.
Returns
SW_HTM_SUCCESS, or one of the sw_htm_error error constants.

◆ h4x4RenderInit()

static sw_htm_result h4x4RenderInit ( sw_htm_api implementation,
const sw_htm_render_info render_info 
)
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.

Note
In preparation for a partial paint, the RIP may choose to reduce the band size used for rendering. This may involve several repeated calls to RenderInitiation() until such time as the RIP reaches a good compromise. When two consecutive RenderInitiation() calls occur, without an intervening RenderCompletion(), the later RenderInitiation() supersedes the earlier one. In such cases RenderCompletion() will only be called once, because the superseded RenderInitiation() calls are deemed never to have taken place.
Parameters
[in]implementationA pointer to the implementation registered with the RIP.
[in]render_infoPointer to a structure containing general information about the upcoming render as a whole.
Returns
SW_HTM_SUCCESS, or one of the sw_htm_error error constants.

◆ htm4x4_getInstance()

sw_htm_api* htm4x4_getInstance ( void  )

Return the singleton instance of the sw_htm_api object containing details of the example '4x4' screening module.

Returns
A single instance of the screening module.
See also
SwRegisterHTM()

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.