Linear light composition

MyPaint is considering moving to a linear light workflow internally: this has artistic and aesthetic benefits for users, and technical benefits which allow more complex layer blend modes to be implemented correctly. We'll attempt to retain backwards compatibility for older images to reduce the impact of this change as much as possible.

Benefits of linear light
For artists, linear light composition affects the way mid-range alpha pixels combine with the layers below them. You might see less fringing at the edges of brushstokes, and should see fewer artefacts around the edges of strokes when scaling. More difficult to spot are the effects when compositing one layer over another and altering the opacity of the top layer: changes to the opacity slider should result in brightness changes in a way that's proportional to the way the human eye responds. The results of a 'crossfade' done in such a way are said to be "more cinematic", grey highlights out less, reduce halo artefacts; but more generally they should be closer to the colours resulting from combinations of coloured filters or backlit transparencies.

For developers, we can implement fancy compositing modes more correctly, allowing us to develop fancier colour and lightness modes in a way that can be as consistent as possible with other OpenRaster-aware apps.

Sample images

 * Source images:
 * Lin-light samples src cityscape.png + Lin-light samples src trumpeter.png


 * Non-linear compositing results:
 * This is what MyPaint currently does. Trumpeter image composited at 50% src-over the cityscape image.
 * Lin-light samples nonlin comp.png


 * Linear compositing results:
 * Results of the new code, using the same source images exactly the same compositing parameters. The layers are composited in "linear light", i.e. with numerical red, green and blue values proportional to the human eye's perception of brightness.
 * Lin-light samples lin comp.png


 * The effect on scaling:
 * This image shows effect linear light has when zooming lineart. At the top is the original size, at the bottom the zoomed-out image, before and after implementing linear light. (View at full size for best comparision).
 * Linear_light_scaling.png
 * You can also watch the linear_light_scaling.ogv screencast to see the difference.

Consequences
Brush designers may need to update particularly low-alpha brushsets (i.e. particularly soft or loose-edged brushes) because this change affects the way alpha-blended stuff is laid down on the canvas.

Old files will not look the same as they did in linear-light versions unless we have a backwards-compatibility mode.

Status
Work is in progress in git, just a general speed test right now. It should work like so when complete:


 * The encoding of the PNG images in ORA files stays as it is (assumed sRGB, with an encoding gamma of approximately 1/2.2)
 * What content artists will put in there to get a particular effect will vary for new images created after the change, but that should be fine :)
 * When images are loaded from PNG, ORA or JPEG, convert to linear light in the internal tiles with the appropriate gamma expansion.
 * Composite layers before display in linear light.
 * Gamma-compress the results of compositing for display.
 * When saving or exporting images, also gamma-compress images so they'll look right in viewers.
 * When pasting an image from the clipboard into a layer, gamma expand as if it were loaded from a file.
 * When copying a layer to the clipboard, apply gamma compression.
 * When colours are chosen using on-screen colour chooser tools on the basis of it "looking right" in the chooser as compared to the working image, apply gamma expansion there too.

The transition from nonlinear to linear is not managed properly yet; we'll need some agreement on the CREATE list and a note in the OpenRaster draft spec regarding how we encode legacy and new-style files, and what the default should be.