29.1 Non ICC-based Colorspaces

The first and most basic colorspace creation method is for creating a non-ICC based colorspace, by calling:

fz_colorspace *fz_new_colorspace( 
                     fz_context *ctx, 
                     const char *name, 
                     enum fz_colorspace_type type, 
                     int flags, 
                     int n, 
                     fz_colorspace_convert_fn *to_ccs, 
                     fz_colorspace_convert_fn *from_ccs, 
                     fz_colorspace_base_fn *base, 
                     fz_colorspace_clamp_fn *clamp, 
                     fz_colorspace_destruct_fn *destruct, 
                     void *data, 
                     size_t size);

The name parameter is a pointer to a (short) ASCII string describing the colorspace, and n is the number of colorants in the space.

The type of the colorspace should be chosen as one of the following types (which should be consistent with the value of n chosen):

enum fz_colorspace_type 
{ 
   FZ_COLORSPACE_NONE, 
   FZ_COLORSPACE_GRAY, 
   FZ_COLORSPACE_RGB, 
   FZ_COLORSPACE_BGR, 
   FZ_COLORSPACE_CMYK, 
   FZ_COLORSPACE_LAB, 
   FZ_COLORSPACE_INDEXED, 
   FZ_COLORSPACE_SEPARATION, 
};

The flags value for is the logical or of a selection of values from the following enum:

enum 
{ 
   FZ_COLORSPACE_IS_DEVICE = 1, 
   FZ_COLORSPACE_IS_ICC = 2, 
   FZ_COLORSPACE_IS_CAL = 4, 
   FZ_COLORSPACE_LAST_PUBLIC_FLAG = 4, 
};

MuPDF uses some extra bits internally, so unknown bits should be considered private.

If the colorspace requires any private data (perhaps a palette for an indexed space), then an opaque pointer can be passed as data. A function to destroy this data when the colorspace reference count reaches zero should be passed as destruct.

Colorspaces are placed into the Store, so some measure of the size of their data is required - the size in bytes of the colorspaces extra data should be passed as size.

If this colorspace is based on another one then a function to return a borrowed reference to the underlying space should be supplied as base. For instance, an indexed space with an RGB palette would pass a function that returns fz_device_rgb.

This leaves the 3 functions that do the heavy lifting.

The to_ccs parameter should be a function that takes n colorant values in the colorspace, and returns them as RGB values.

The from_ccs parameter should be a function that takes RGB colorant values, and returns them as n colorant values in the colorspace.

Finally, the clamp field should be a function that takes n colorant values in the colorspace, and clamps them into the appropriate range.