#34 Most of the missing Photoshop separable compositing operations

composite (2)
Brendan Lane

I've attached a patch implementing most of Photoshop's separable compositing operations, using the formulas in the final Adobe PDF specs and the text descriptions on Wikipedia's "Blend modes" article. In addition to the composite operation code itself, this required changing .psd file input/output, .xcf input/output, and the headers for PerlMagick and TclMagick. No test operations or examples were created.

These operations have been tested using command line and Magick++, comparing the output against the output of the same operations in Photoshop CS6 and (where implemented) ImageMagick 6.

Existing operations modfied:
Difference, Darken, Lighten, HardLight

New operations:
Overlay, Exclusion, ColorBurn, ColorDodge, SoftLight, LinearBurn, LinearDodge, LinearLight, VividLight, PinLight, HardMix

Comments on specific operations:
- There is no clear counterpart to PS "Normal"; "Over" does not give the same result, either here or in IM.
- I'm not sure how to implement Dissolve; which pixels are chosen is some kind of pseudorandom process.
- The current GM implementations of the Darken and Lighten operations are incorrect; they only take into account complete transparency, not alpha-blending. I have reimplemented them.
- ColorBurn and ColorDodge work differently in CS6 then the formula suggests, with a discontinuity in the filter for destination values of exactly MaxRGB (0 resp.). I have implemented these operations according to the formula, so they do not match PS exactly. IM matches PS for ColorBurn, and follows the formula for ColorDodge.
- The current GM implementation of HardLight does not consider alpha values at all; I have reimplemented it.
- HardMix takes the average pixel value then thresholds it at 0.5; Photoshop's implementation seems to include an asymmetry, where a white source over a black destination is black, while a black source over a white destination is white, though the average values are the same. IM has a symmetric filter. I have implemented a symmetric filter as well.
- The current GM Difference operation just does a per-channel difference, not an alpha blend. I've reimplemented it, but if you wanted the straight difference you could rename the operation. IM's Difference operation is the alpha-blending one.
- The formulas behind Subtract and Divide are unclear. IM's don't match Photoshop's, and the current GM implementations don't match either one.

1 Attachments


  • Brendan, I committed your changes as Mercurial changeset 14086:ec380aa902c8 but I can't consider this issue closed yet since I notice that the Difference composite results are different for the Q32 (QuantumDepth=32) build (seems ok for Q8 and Q16 builds). It looks like some sort of arithmetic overflow in the color channels. Perhaps there might be a similar issue with the new composition operators that I don't have a tests for yet.

    Are you able to help us ferret out these last issues?

    • assigned_to: Bob Friesenhahn
  • Brendan Lane
    Brendan Lane

    You're right, there was an overflow in the color channels. I've added the proper (double) casts in all of the cases I could find; interestingly, this fix also makes LinearBurn and LinearDodge match the PS versions (which I was almost certain were wrong).

    Last edit: Brendan Lane 2014-06-30
    • status: open --> closed-fixed
  • Your patch has solved the test suite issue with Q32. It is committed as Mercurial changeset changeset 14088:5e01a56d7874. Thank you very much for your valuable contribution.