Introduction
------------
The ColourMap module provides an interface for constructing combinations of
colour mapping functions (as used by SpriteExtend, DrawFile and others).
These functions allow colours within images to be manipulated to affect
their rendering. Typical examples of colour mapping functions are to
highlight or to fade elements (as used within the WindowManager). The colour
mapping is performed through a colour mapping descriptor - a function
pointer and workspace pair which are used to translate colours the colours.
The ColourMap module can provide descriptors for commonly used colour
operations allowing clients to perform mappings without recourse to
repeatedly providing their own implementations.


Technical details
-----------------
In order to provide a colour mapping descriptor, the ColourMap module must
be given a block of workspace for its own use and informed of the mappings
which the users wishes to be applied. The workspace block is provided by the
client and its size can be determined through calls to the module. Should
more space be required within the workspace block, this will be indicated
through errors from the ColourMap module in a similar manner to other RISC
OS interfaces (returning the size field as negative to indicate the size).

The normal sequence of operations to create and use the ColourMap module
would be :

  1. Call ColourMap_Start, requesting the initial size of the workspace
     This will return the size of the workspace necessary to hold the
     standard information about the mappings requested and to hold at least
     one of the more common mapping functions (blend to colour).
  2. Allocate workspace of size requested.
  3. Call ColourMap_Start, passing the workspace pointer and the size of
     the workspace.
  4. Call ColourMap_ApplyMapping, passing details of the workspace and the
     mapping required.
  5. If an error occurred, and the size returned is negative resize the
     workspace appropriately and call ColourMap_ApplyMapping again.
     If the size was positive still, report an error in the mapping.
  6. Repeat applying additional mappings as necessary.
  7. Call ColourMap_End to obtain a colourmap descriptor which may be used
     with DrawFile, SpriteExtend or other clients.
  8. Release workspace if colourmapping is no longer required.


Workspace properties
--------------------
The workspace provided by the client may be freely relocated during the
construction of the mappings. The workspace contents should be considered
private and should not be modified by the client. The ColourMap module will
not provide direct references during the construction of the mapping. Once
ColourMap_End has been called, the workspace should remain static. The
descriptor returned will contain references to the current location of the
workspace and relocating the workspace will make this invalid.

If the workspace must be moved in memory, the ColourMap_End call should be
made once more to obtain a new colourmap descriptor. Clients may release the
memory used by the workspace once the colour mappings it provides are no
longer required. No references are made from the ColourMap module to the
workspace. Multiple clients may use the ColourMap module.

Clients should be aware that if the ColourMap module is killed, or
reinitialised, the colourmap descriptor may be invalid.

Although the workspace may be relocated in memory by the client during
construction of the mappings and between calls to ColourMap_End, it should
not be assumed that the format of the workspace will remain constant
between updates of the module. Because of this, workspace blocks should not
be stored in persistent storage (eg in data files, or embedded in
applications). The workspace requirement for any given mapping will remain
constant regardless of the parameters provided. This allows clients to reuse
workspace blocks for similar mappings without any relocation requirements.

Code will never be placed within the workspace, therefore it may be located
outside the 26bit executable range.


ColourMap_Start
=> R0 = flags (reserved, must be 0)
   R1 = pointer to workspace, or 0 to read initial size of workspace
   R2 = size of workspace
<= R2 = size of workspace used, for information

This SWI is used to initialise a block of memory as use as a ColourMap
module mapping workspace, or to request the minimum size of the workspace.
Larger workspaces than the minimum may be provided and will prevent
reallocation requests on subsequent ColourMap_ApplyMapping calls.


ColourMap_ApplyMapping
=> R0 = flag bits :
         b0-7  Type of mapping to apply
         other reserved, must be 0
   R1 = pointer to workspace
   R2 = size of workspace
   R3... parameters for mapping
<= R2 = -ve size of workspace required if an out of memory error occurred

This SWI is used to apply a new colour mapping to those already held in the
workspace. The new mapping will be applied after those already held in the
workspace.

Mapping types currently known to the ColourMap module are :
  0 - User
      R3 = pointer to colourmap descriptor to use (a copy will be taken)
      A standard colourmap function will be invoked, allowing a number
      of mapping functions to be chained together.

  1 - Identity
      No parameters
      The identity mapping does not affect the colour.

  2 - Invert
      No parameters
      The colour value is inverted.

  3 - Monochrome
      No parameters
      The colour is converted to a greyscale.

  4 - Monochrome and scale
      R3 = &BBGGRR00 'black' colour
      R4 = &BBGGRR00 'white' colour
      The colour is converted to a greyscale and then scaled to cover the
      range between the colours specified.
  
  5 - Gamma
      R3 = 256 * gamma level (0-4)
      The colour has gamma correction applied to it. This takes the form
      of a mapping from the linear space to a logarithmic curve whose
      depth is determined by the gamma level.
  
  6 - Contrast
      R3 = 256 * factor (0-4)
      The colour has its contrast increased or decreased according to the
      factor. Values for factor above 1 will increase the range of the
      colours, effectively increasing the contrast; conversely, values of
      less than 1 will decrease the range.
  
  7 - Brightness
      R3 = value to add (-256 - 256)
      The colour will have the value supplied added to each of the R, G
      and B components, effectively brightening or darkening the image.
  
  8 - Blend
      R3 = &BBGGRR00 colour
      R4 = factor (0 for solid source colour, &FF for solid blend colour)
      The colour will be blended toward the colour supplied by a given
      factor.

ColourMap_End
=> R0 = flag bits
   R1 = pointer to workspace
   R2 = size of workspace
<= R0 = pointer to colourmap descriptor, or 0 if no descriptor is necessary

This SWI is used to read the colourmap descriptor which applies the mappings
requested. If no mappings are held in the workspace, this will be indicated
by returning a 0 value for the descriptor. Once this call has been made, the
workspace should remain static. If changes are made to the workspace, or
it is moved in memory, the descriptor returned by this call will be invalid.
Calling ColourMap_End once more will return a valid descriptor.


Workspace format:
 +0 MAGIC
 +4 Size of workspace used
 +8 Colour mapping descriptor to use this (or 0 values if not currently
    valid)
 +16 List of mapping data...
Mapping data:
 +0 mapping type, or -1 for end of list
 +4 workspace size
 +8 function pointer
 +12... workspace data

Colour mapping types :
 0 - user function
     User: colour descriptor
 1 - identity
     User: No params
 2 - invert
     User: No params
 3 - monochrome
     User: No params
 4 - monochrome and scale to range (make the image blue-scale, for example)
     User: low colour
           high colour
 5 - gamma
     User: Gamma (256*level)
 6 - contrast (increase or decrease range of values)
     User: Scaling (256*factor)
 7 - brightness (change 0 base)
     User: change
 8 - blend to alternate colour
     User: colour
           factor (0 for solid colour, &FF for solid background)
