Unpremultiplication (source code)

= Unpremultiplication

\b[Unpremultiplication] converts <premultiplied alpha> colour samples back to <straight alpha> by dividing out a nonzero <alpha channel>. If $c=\alpha C$ is the stored premultiplied colour triple, then
$$
C=\frac c\alpha,\qquad \alpha>0.
$$
The alpha value is retained. PNG's encoder guidance specifies this division when converting associated input samples to its unassociated representation, followed by scaling to the output sample range and rounding.<Portable Network Graphics (PNG) Specification (Third Edition) by Mark Adler and others>[§12.3, Alpha channel creation]{ref}

For an original exact-arithmetic example in <Linear-light RGB>, let $c=(0.12,0.06,0.03)$ and $\alpha=0.2$. The recovered colour is $C=(0.6,0.3,0.15)$. Multiplying that triple by the retained alpha restores $c$. Dividing the alpha itself would instead destroy the transparency information.

At $\alpha=0$, all exact premultiplied colour triples arising from finite $C$ equal zero. The original colour cannot be recovered from that result: many inputs mapped to the same stored value. PNG's conversion guidance chooses black for this case; that is a defined output convention, not recovered hidden colour.<Portable Network Graphics (PNG) Specification (Third Edition) by Mark Adler and others>[§12.3, zero-alpha case]{ref}

Finite precision adds another limitation. Suppose $C=(0.4,0.6,0.9)$, $\alpha=1/255$, and the premultiplied channels are rounded to eight-bit normalized codes. Their integer codes become $(0,1,1)$, while the alpha code is one. Unpremultiplication then yields normalized straight colour $(0,1,1)$, far from the original triple. For fixed exact alpha, a stored component error $\delta$ becomes $\delta/\alpha$ after division. Near-zero alpha can therefore magnify <rounding error> even when the conversion formula is correct.