Harlequin RIP SDK

A primitive non-monotonic screening module example. More...

#include "std.h"
#include "htm4x4.h"
#include <string.h>

Data Structures

struct  HTI
 The structure this example uses internally for its halftone instances. More...
 

Macros

#define RERANGE16(x)   ( ((x) >> 12) + ((x) >> 15) )
 Re-range a uint16 value to lie between 0 and 16. We do this by taking the top 4 bits and then adding one if the value was over half, i.e., top bit was set. More...
 
#define RERANGE8(x)   ( ((x) >> 4) + ((x) >> 7) )
 Re-range a uint8 value to lie between 0 and 16. We do this by taking the top 4 bits and then adding one if the value was over half, i.e., top bit was set. More...
 
#define BASECELLUNIT(pCells, inval, cellY)    ( *((pCells) + ( (inval) << 2 ) + (cellY)) )
 Get the basic cell unit (bcu) for a value. More...
 
#define BCUREPL(bcu)   ( bcu )
 Replicates a uint32 basic cell unit to fill a sw_htm_raster_unit. More...
 
#define NEWPEL16(dst, pelmsk, pCells, pSrc16, ixSrc, cellY)
 Set a pixel bit for the given 16-bit input value. More...
 
#define NEWPEL8(dst, pelmsk, pCells, pSrc8, ixSrc, cellY)
 Set a pixel bit for the given 8-bit input value. More...
 
#define INVERT_SCREEN_CELLS(norm, invs)
 Create an inverse cell array from the original. More...
 

Typedefs

typedef struct HTI HTI
 The structure this example uses internally for its halftone instances. More...
 

Functions

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...
 
static void makeInverses ()
 Initialize all four sets of inverse screen cells.
 
sw_htm_apihtm4x4_getInstance (void)
 Return the singleton instance of the sw_htm_api object containing details of the example '4x4' screening module. More...
 

Variables

static sw_htm_api htmApi
 The sw_htm_api used to register the module with the RIP. More...
 
static const uint32 g_rasterTonesBase [17][4]
 Halftone cell tables. More...
 
static const uint32 g_rasterTones90R [17][4]
 These are the base cells in g_rasterTonesBase rotated 90-degrees clockwise.
 
static const uint32 g_rasterTones90L [17][4]
 These are the base cells in g_rasterTonesBase rotated 90-degrees counter-clockwise.
 
static const uint32 g_rasterTones180 [17][4]
 These are the base cells in g_rasterTonesBase rotated 180-degrees.
 
static uint32 g_inverseTonesBase [17][4]
 Inverse screen cells. More...
 
static uint32 g_inverseTones90R [17][4]
 Inverse screen cells. More...
 
static uint32 g_inverseTones90L [17][4]
 Inverse screen cells. More...
 
static uint32 g_inverseTones180 [17][4]
 Inverse screen cells. More...
 
static HqBool g_inversesInited = 0
 Whether the inverse screen cells have been initialized.
 
static HTI g_HTI_C = { ((void*)0) , *g_rasterTonesBase }
 The individual static halftone instances. More...
 
static HTI g_HTI_M = { ((void*)0) , *g_rasterTones180 }
 The individual static halftone instances. More...
 
static HTI g_HTI_Y = { ((void*)0) , *g_rasterTones90R }
 The individual static halftone instances. More...
 
static HTI g_HTI_K = { ((void*)0) , *g_rasterTones90L }
 The individual static halftone instances. More...
 
static HTI g_HTI_Ci = { ((void*)0) , *g_inverseTonesBase }
 The individual static halftone instances. More...
 
static HTI g_HTI_Mi = { ((void*)0) , *g_inverseTones180 }
 The individual static halftone instances. More...
 
static HTI g_HTI_Yi = { ((void*)0) , *g_inverseTones90R }
 The individual static halftone instances. More...
 
static HTI g_HTI_Ki = { ((void*)0) , *g_inverseTones90L }
 The individual static halftone instances. More...
 
static HTIg_HTIs [8]
 Our table of halftone instances. More...
 

Detailed Description

A primitive non-monotonic screening module example.

Macro Definition Documentation

◆ BASECELLUNIT

#define BASECELLUNIT (   pCells,
  inval,
  cellY 
)     ( *((pCells) + ( (inval) << 2 ) + (cellY)) )

Get the basic cell unit (bcu) for a value.

The basic cell unit is the uint32 value of the cell for the appropriate input level and line offset. It comprises 8 side-by-side copies of the 4-bit row in the 4x4 grid.

Parameters
[in]pCellsPointer to the start of the overall cell array.
[in]invalThe cell index of the desired cell, 0 to 16.
[in]cellYThe line/row offset within the cell, 0 to 3.
Returns
The 32-bit basic cell unit.

◆ BCUREPL

#define BCUREPL (   bcu)    ( bcu )

Replicates a uint32 basic cell unit to fill a sw_htm_raster_unit.

When SW_HTM_RASTER_UNIT_BITS is 32, it just returns the basic cell unit unchanged. When SW_HTM_RASTER_UNIT_BITS is 64, it extends the basic cell unit to 64 bits.

◆ INVERT_SCREEN_CELLS

#define INVERT_SCREEN_CELLS (   norm,
  invs 
)
Value:
MACRO_START \
for (i = 0 ; i < 17 ; i++) { \
for (j = 0 ; j < 4 ; j++) { \
(invs)[16 - i][j] = ~(norm)[i][j]; \
} } \
MACRO_END

Create an inverse cell array from the original.

Parameters
[in]normThe name of the original, normal cell array.
[out]invsThe name of the inverse cell array.

◆ NEWPEL16

#define NEWPEL16 (   dst,
  pelmsk,
  pCells,
  pSrc16,
  ixSrc,
  cellY 
)
Value:
MACRO_START { \
sw_htm_raster_unit bcu_ = BASECELLUNIT( pCells, RERANGE16((pSrc16)[ixSrc]), cellY ); \
dst = ((dst) & ~(pelmsk)) | ((dst) & (pelmsk) & BCUREPL ( bcu_ )); \
pelmsk >>= 1 ; ixSrc++ ; \
} MACRO_END
#define BASECELLUNIT(pCells, inval, cellY)
Get the basic cell unit (bcu) for a value.
Definition: htm4x4.c:279
#define BCUREPL(bcu)
Replicates a uint32 basic cell unit to fill a sw_htm_raster_unit.
Definition: htm4x4.c:294
#define RERANGE16(x)
Re-range a uint16 value to lie between 0 and 16. We do this by taking the top 4 bits and then adding ...
Definition: htm4x4.c:255

Set a pixel bit for the given 16-bit input value.

Parameters
[in,out]dstThe sw_htm_raster_unit where the pixels are being collected. The appropriate bit for the pixel should initially be set on or off according to whether the original mask bitmap bit was set. Afterwards, if the pixel bit was on initially, it will have been replaced with the corresponding bit from the halftone cell.
[in,out]pelmskA mask with a single bit set isolating the pixel. The pelmsk value gets shifted one position to the right afterwards.
[in]pCellsPointer to the start of the overall cell array.
[in]pSrc16Pointer to the 16-bit source raster line.
[in,out]ixSrcIndex of the current pixel in the source line. The index gets incremented afterwards.
[in]cellYThe line/row offset within the cell, 0 to 3.

◆ NEWPEL8

#define NEWPEL8 (   dst,
  pelmsk,
  pCells,
  pSrc8,
  ixSrc,
  cellY 
)
Value:
MACRO_START { \
sw_htm_raster_unit bcu_ = BASECELLUNIT( pCells, RERANGE8(pSrc8[ixSrc]), cellY ); \
dst = ((dst) & ~(pelmsk)) | ((dst) & (pelmsk) & BCUREPL ( bcu_ )); \
pelmsk >>= 1 ; ixSrc++ ; \
} MACRO_END
#define RERANGE8(x)
Re-range a uint8 value to lie between 0 and 16. We do this by taking the top 4 bits and then adding o...
Definition: htm4x4.c:265

Set a pixel bit for the given 8-bit input value.

Parameters
[in,out]dstThe sw_htm_raster_unit where the pixels are being collected. The appropriate bit for the pixel should initially be set on or off according to whether the original mask bitmap bit was set. Afterwards, if the pixel bit was on initially, it will have been replaced with the corresponding bit from the halftone cell.
[in,out]pelmskA mask with a single bit set isolating the pixel. The pelmsk value gets shifted one position to the right afterwards.
[in]pCellsPointer to the start of the overall cell array.
[in]pSrc8Pointer to the 8-bit source raster line.
[in,out]ixSrcIndex of the current pixel in the source line. The index gets incremented afterwards.
[in]cellYThe line/row offset within the cell, 0 to 3.

◆ RERANGE16

#define RERANGE16 (   x)    ( ((x) >> 12) + ((x) >> 15) )

Re-range a uint16 value to lie between 0 and 16. We do this by taking the top 4 bits and then adding one if the value was over half, i.e., top bit was set.

Parameters
[in]xThe 16-bit value to re-range.
Returns
A value in the range 0 to 16.

◆ RERANGE8

#define RERANGE8 (   x)    ( ((x) >> 4) + ((x) >> 7) )

Re-range a uint8 value to lie between 0 and 16. We do this by taking the top 4 bits and then adding one if the value was over half, i.e., top bit was set.

Parameters
[in]xThe 8-bit value to re-range.
Returns
A value in the range 0 to 16.

Typedef Documentation

◆ HTI

typedef struct HTI HTI

The structure this example uses internally for its halftone instances.

This simple example module needs nothing more than a reference count and a pointer to the start of the appropriate cell table array.

Variable Documentation

◆ g_HTI_C

HTI g_HTI_C = { ((void*)0) , *g_rasterTonesBase }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTI_Ci

HTI g_HTI_Ci = { ((void*)0) , *g_inverseTonesBase }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTI_K

HTI g_HTI_K = { ((void*)0) , *g_rasterTones90L }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTI_Ki

HTI g_HTI_Ki = { ((void*)0) , *g_inverseTones90L }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTI_M

HTI g_HTI_M = { ((void*)0) , *g_rasterTones180 }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTI_Mi

HTI g_HTI_Mi = { ((void*)0) , *g_inverseTones180 }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTI_Y

HTI g_HTI_Y = { ((void*)0) , *g_rasterTones90R }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTI_Yi

HTI g_HTI_Yi = { ((void*)0) , *g_inverseTones90R }
static

The individual static halftone instances.

We only reference these from the static table g_HTIs, later.

Note
Of course, our use of the letters C, M, Y and K in these names are purely for our convenience - the Core's sethalftone really determines which screen will be used for which colorant.

◆ g_HTIs

HTI* g_HTIs[8]
static
Initial value:
static HTI g_HTI_Yi
The individual static halftone instances.
Definition: htm4x4.c:449
static HTI g_HTI_Ci
The individual static halftone instances.
Definition: htm4x4.c:445
static HTI g_HTI_M
The individual static halftone instances.
Definition: htm4x4.c:438
static HTI g_HTI_K
The individual static halftone instances.
Definition: htm4x4.c:442
static HTI g_HTI_Ki
The individual static halftone instances.
Definition: htm4x4.c:451
static HTI g_HTI_Y
The individual static halftone instances.
Definition: htm4x4.c:440
static HTI g_HTI_Mi
The individual static halftone instances.
Definition: htm4x4.c:447
static HTI g_HTI_C
The individual static halftone instances.
Definition: htm4x4.c:436

Our table of halftone instances.

So simple, in our case, that we can keep them static.

◆ g_inverseTones180

uint32 g_inverseTones180[17][4]
static

Inverse screen cells.

These are nothing more complicated than cells which light pixels in the opposite order to their counterparts. Inverses come in handy when using a cross-over between two shades of a colorant, such as light and dark Cyan. Using an inverse screen for the light ink and a normal screen for the dark (or vice-versa) means that the chances of light and dark dots coinciding are minimised.

Rather than hand code these inverse screens, we calculate them, from the originals, the first time an inverse is needed.

This is the inverse screen cells rotated 180 degrees.

◆ g_inverseTones90L

uint32 g_inverseTones90L[17][4]
static

Inverse screen cells.

These are nothing more complicated than cells which light pixels in the opposite order to their counterparts. Inverses come in handy when using a cross-over between two shades of a colorant, such as light and dark Cyan. Using an inverse screen for the light ink and a normal screen for the dark (or vice-versa) means that the chances of light and dark dots coinciding are minimised.

Rather than hand code these inverse screens, we calculate them, from the originals, the first time an inverse is needed.

This is the inverse screen cells rotated 90 degrees counter-clockwise.

◆ g_inverseTones90R

uint32 g_inverseTones90R[17][4]
static

Inverse screen cells.

These are nothing more complicated than cells which light pixels in the opposite order to their counterparts. Inverses come in handy when using a cross-over between two shades of a colorant, such as light and dark Cyan. Using an inverse screen for the light ink and a normal screen for the dark (or vice-versa) means that the chances of light and dark dots coinciding are minimised.

Rather than hand code these inverse screens, we calculate them, from the originals, the first time an inverse is needed.

This is the inverse screen cells rotated 90 degrees clockwise.

◆ g_inverseTonesBase

uint32 g_inverseTonesBase[17][4]
static

Inverse screen cells.

These are nothing more complicated than cells which light pixels in the opposite order to their counterparts. Inverses come in handy when using a cross-over between two shades of a colorant, such as light and dark Cyan. Using an inverse screen for the light ink and a normal screen for the dark (or vice-versa) means that the chances of light and dark dots coinciding are minimised.

Rather than hand code these inverse screens, we calculate them, from the originals, the first time an inverse is needed.

◆ g_rasterTonesBase

const uint32 g_rasterTonesBase[17][4]
static

Halftone cell tables.

The following tables are the halftone patterns for each of the possible tone levels/shades.

* The pixels lit for each shade in the basic grid are shown by hashes:
* Shade:  01     02     03     04     05     06     07     08
*        #---   -#--   #-#-   -#--   #-#-   -#-#   #-#-   -#-#
*        ----   #---   ----   #---   -#--   #-#-   _#_#   #-#-
*        ----   ----   #---   --#-   #-#-   ---#   #-#-   -#-#
*        ----   ----   ----   -#--   ----   ---#   -#--   #-#-
*
* Shade:  09     10     11     12     13     14     15     16
*        ##-#   ##--   --#-   ##-#   ###-   ####   ####   ####
*        #-#-   -###   -###   ###-   ####   ###-   ####   ####
*        -##-   ##--   ###-   ##-#   ###-   ####   ###-   ####
*        -##-   #-##   ####   ###-   ##-#   ###-   ####   ####
* 

This basic grid is then used in each of four rotations to make the halftones for four separations/colorants.

The major index into the tables is the shade (where blank is 0), which is also the number of pixels lit in that cell.

Each uint32 in the table holds eight copies, side by side horizontally, of one line of the basic 4x4 cell.

◆ htmApi

sw_htm_api htmApi
static

The sw_htm_api used to register the module with the RIP.

It is initialised in htm4x4_getInstance(), later.