create new tag
view all tags

MuPDF Color Management

A short note outlining ideas/issues in bringing color management to MuPDF.

CMM interface:

Although we have not had a single customer want to connect another CMM to Ghostscript, I would advocate that we should do something similar. Essentially, we will want to have an API to the CMM allowing developers/customers to use other CMMs if desired. To me, it keeps things clear and easy if we ever to need/want to change. It is possible that iOS may eventually open up its CMM which we might want to look at using at that time. Question of naming the API methods. Perhaps something like fz_cmm_init(args), fz_cmm_create_link(args), fz_cmm_transform(args) etc? There might at most be a dozen methods.These would go in a new file perhaps color-cmm.c/h?


The output device fz_device structure should include an ICC profile associated with the target color space. Output formats that allow the embedding of ICC profiles (e.g. Tiff, JPEF, PNG) will embed this ICC profile into the format. Talking with Tor it sounds like that should not be an issue as the device will be available during the actual drawing operations which is where we would need to create the link transforms.

Link Based Approach:

Currently, the fz_colorspace structure defines mappings to go back and forth to RGB. Always mapping to RGB regardless of the output device color space is not ideal as it can result in loss in color fidelity. A better approach is to only map into the color space defined by the output device (hence the desire to associate a profile with the device).

At the same time, we want to maintain the existing simplicity/speed of the existing approach.To achieve this, we can create a link between color spaces.The link will contain function valued members, which may simply get us to the current mappings or to color managed mappings.The mappings to and from RGB would no longer be contained in the fz_colorspace structure.

Looking over the code, it appears that all the calls to apply the transforms occur in draw-device.c via fz_convert_color(args). We can likely keep this same call and have most of the rework occur in colorspace.c.

Currently the code calls fz_convert_color which looks up a color converter method (via fz_lookup_color_conveter) based upon the source and destination color space. With the proposed changes, given the particular source and destination color spaces, fz_convert_color would

  • Compute a hashtag based upon the color spaces and rendering conditions
  • Get a link from the store or create one if it was not found in the store
  • Apply transform
  • Release the link
The link structure would look something like this:

struct fz_colorlink_s


void *link;

fz_colorspace *src;

fz_colorspace *des;

fz_transform_color_fn *map_color;

fz_transform_buffer_fn *map_buffer;

fz_free_link_fn *free_link;

bool is_identity;

int num_input;

int num_output;


The *link member is the context supplied by the CMM when the link is created. The link is not created until needed and may be contained in the store code (see below). Right now, I believe I would like to have the source and destination color spaces in the link. It is possible these could go away but I won’t know until I get started.The method *map_color would be used to map individual colors.The method *map_buffer would be used to map large chunks of data such as those generated from images or transparency buffers. The method *free_link would be used to let the CMM know it should free up any allocations made for the link object.The member is_identity is there to make sure we are not converting to the same color space as our source color. The members num_input and num_output may be needed.

In the case where we are not doing color management, the link would be populated with the methods necessary to perform the current mapping methods (i.e. to or from RGB), link would be void, etc.

The structure fz_colorspace will need to be expanded to include ICC profile information.


We will want to include the following ICC profiles as resources:sGray, sRGB, SWOPCMYK, CIELAB.It looks like the font resources are created/stored in a separate library (libfonts) for mupdf.How do we want to handle the ICC resources?


Looking over the store code, it seems that this should be straight forward to use for caching of links and profiles and the fact that the store already handles all the locks etc. for threading is great. For a link, we would need to generate a hash tag from the source profile, destination profile, as well as the rendering conditions.

PDF color managed color spaces:

The PDF types of CalGray, and CalRGB should be mapped to equivalent ICC profiles.These profiles could be cached in the store with a hash tag related to the object reference code.


The PDF LAB color space will be implemented using the CIELAB ICC profile.

Display list:

Talking with Tor, as I understand it, the display list unlike Ghostscript’s C-list stores all colors in the original source color space.As such, the only thing we (or I) will need to make sure is that the ICC objects from the source document are embedded in the display list and associated with the colors.

Rendering Conditions:

Rendering intent, black point compensation will need to be incorporated into the creation of any links.Rendering intent is a current PDF attribute. Black point compensation will be part of PDF 2.0. This information would need to be included in the display list.

DeviceN color:

In the first run of this, we will punt on Device-N and Separation colors and use the base color space.However, since the fz_pixmap number of components could include spot colorants we plan to add support for these in the later part of this project.


Currently MuPDF does all its transparency blending work in RGB and ignores the blending color space. We will want to look at adapting the transparency code to follow the blending color space which can be Gray, RGB or CMYK as well as spot colors if the target device supports spot colors. Again, this can be a significant performance hit, so we will want to maintain the capability to just keep everything in RGB if desired. This will come in a later phase of this project. For now, we will maintain the RGB based blending approach.

-- Michael Vrhel - 2017-03-14


Topic revision: r1 - 2017-03-14 - MichaelVrhel
This site is powered by the TWiki collaboration platform Powered by PerlCopyright © 2014 Artifex Software Inc