ColourMapping of deep sprites
=============================

Deep sprites - those of 16bpp or 24bpp depths - cannot be operated on using
standard pixel translation tables. The tables necessary to operate on such
sprites would be 2<<16 bytes (128k), or 4<<24 bytes (64M). Since such tables
would be impractical at best, and the range of operations that are possible
possible on such images is large, a manner in which these images can be
manipulated has been implemented.

For non-deep sprites, pixel translation tables are generated using
ColourTrans (q.v. ColourTrans_SelectTable, ColourTrans_GenerateTable) or
manually. This initial scheme was suitable for paletted images. It was later
extended to encompass more accurate plotting of paletted images in deep
modes, and to allow the translation tables to be transformed through a
transfer function. The transfer function allows arbitrary translation of
an RGB value to another RGB value before that value is used in calculations.

For deep sprites a similar method has been adopted. As before, a transfer
function provides a conversion between one source RGB value and a
destination RGB value. This allows any deep sprite to be colour transformed.
Since this transformation must be performed on every pixel plotted, the
additional processing required for the colour transformation (henceforth
called 'colour mapping', or more simply 'mapping' to distinguish it from
a spacial transformations) may be much greater than a plain plot of the
same graphic.


API changes
-----------
The interface for rendering colour mapped sprites is an extension of that
used for plain plotting. Sprite operations PutSpriteScaled and
PutSpriteTransformed, and JPEG operations JPEG_PlotScaled,
JPEG_PlotFileScaled, JPEG_PlotTransformed and JPEG_PlotFileTransformed have
updated APIs to handle the new form of colour mapping.

Colour mapping functions only apply to deep sprites. Using the functions on
non-deep sprites will generate an error. Such sprites should use pixel
translation tables if they wish to be colour mapped.


OS_SpriteOp 52 (PutSpriteScaled)
=> R0 = 52 + operation type (refer to documentation)
   R1 = pointer to sprite area
   R2 = pointer to sprite name, or sprite pointer.
   R3 = x coordinate
   R4 = y coordinate
   R5 = plot action; valid bits :
             3 use mask
             6 dithering on
             7 use colour mapping (must be set)
        all other values will be ignored, and may be explicitly faulted.
   R6 = pointer to scale factors (refer to documentation)
   R7 = pointer to colour mapping descriptor

This operation will plot a deep sprite using the colour mapping supplied.


OS_SpriteOp 56 (PutSpriteTransformed)
=> R0 = 56 + operation type (refer to documentation)
   R1 = pointer to sprite area
   R2 = pointer to sprite name, or sprite pointer.
   R3 = flags (refer to documentation)
   R4 = pointer to source rectangle within sprite
   R5 = plot action; valid bits :
             3 use mask
             7 use colour mapping (must be set)
        all other values will be ignored, and may be explicitly faulted.
   R6 = pointer to transformation matrix, or destination coords
        (refer to documentation)
   R7 = pointer to colour mapping descriptor

This operation will plot a deep sprite using the colour mapping supplied.


JPEG_PlotScaled
=> R0 = pointer to JPEG
   R1 = x coordinate
   R2 = y coordinate
   R3 = pointer to scale factors (refer to documentation)
   R4 = length of image
   R5 = plot flag bits :
           0 dither output when plotting 24bit JPEG at 16bpp or below
           1 invalid
           3 use colourmap (must be set)
   R6 = pointer to colour mapping descriptor

This operation plots a JPEG using the colour mapping supplied.


JPEG_PlotFileScaled
=> R0 = pointer to filename of JPEG file
   R1 = x coordinate
   R2 = y coordinate
   R3 = pointer to scale factors (refer to documentation)
   R4 = plot flag bits :
           0 dither output when plotting 24bit JPEG at 16bpp or below
           1 invalid
           3 use colourmap (must be set)
   R5 = pointer to colour mapping descriptor

This operation plots a JPEG using the colour mapping supplied.


JPEG_PlotTransformed
=> R0 = pointer to JPEG
   R1 = transformation flag bits :
           0 R2 = pointer to destination coordinate block, rather than
                  matrix
           1 dither output when plotting 24bit JPEG at 16bpp or below
           2 invalid
           4 use colourmap (must be set)
   R2 = pointer to transformation matrix, or destination coords
        (refer to documentation)
   R3 = length of image
   R4 = pointer to colour mapping descriptor

This operation plots a JPEG using the colour mapping supplied.


JPEG_PlotFileTransformed
=> R0 = pointer to filename of JPEG file
   R1 = transformation flag bits :
           0 R2 = pointer to destination coordinate block, rather than
                  matrix
           1 dither output when plotting 24bit JPEG at 16bpp or below
           2 invalid
           4 use colourmap (must be set)
   R2 = pointer to transformation matrix, or destination coords
        (refer to documentation)
   R3 = pointer to colour mapping descriptor

This operation plots a JPEG using the colour mapping supplied.



Colour mapping descriptor and transfer function
-----------------------------------------------
The colour mapping descriptor is a small structure containing the workspace
and transfer function pointer. The structure has the following layout :
  +0 workspace to pass in R12 to transfer function
  +4 pointer to transfer function

The transfer function used by these operations is exactly the same as
that used by the ColourTrans_SelectTable calls (PRM 3-346). The function
will be called in SVC mode with the usual supervisor stack limits.

=> R0 = palette entry (&BBGGRR00)
   R12 = workspace value passed when call made
   R13 = supervisor stack
   R14 = return address
<= R0 = palette entry (&BBGGRR00)
   R12 may be corrupt
   R14 may be corrupt

The transfer function should perform whatever processing is required on the
palette entry passed to it. The routine may not change mode, perform any
operation which might cause SpriteExtend to be threaded out of (eg VDU
output) or cause the machine to block. You should return with MOV pc,lr.
The transfer function will not be called for masked pixels.
