Page 1 of 1
Formalizing ModulusAdd and ModulusSubtract
Posted: 2019-07-22T00:38:23-07:00
by gubach
I am trying to formalize ModulusAdd and ModulusSubtract (see
http://www.imagemagick.org/Usage/compose/#modulus_add and the discussion
https://www.imagemagick.org/discourse-s ... dd#p124698) with the known image symbols Sca, Dca, Sa, Da (from
http://www.w3.org/TR/2014/CR-compositing-1-20140220/) which represents here 1-channel arrays (gray scale images respective alphas) all as double. Are the following hypothesis correct and what about transforming the corresponding alpha?
ModulusAdd:
Code: Select all
if (Sca + Dca) <= 1
Dca = Sca + Dca;
else
Dca = (Sca + Dca) - 1;
end
Alpha channel:
Da = Sa + Da or the same procedure:
if (Sa + Da) <= 1; Da = Sa + Da; else; Da = (Sa + Da) - 1; end
ModulusSubtract:
Code: Select all
if (Sca - Dca) >= 0
Dca = Sca - Dca;
else
Dca = (Sca - Dca) + 1;
end
Alpha channel:
Da = Sa - Da or the same procedure:
if (Sa - Da) >= 0; Da = Sa - Da; else; Da = (Sa - Da) + 1; end
Re: Formalizing ModulusAdd and ModulusSubtract
Posted: 2019-07-22T04:25:18-07:00
by magick
Let's go to the authoritative source, IMv7:
Alpha:
Gray:
Code: Select all
case ModulusAddCompositeOp:
{
pixel=Sc+Dc;
while (pixel > QuantumRange)
pixel-=QuantumRange;
while (pixel < 0.0)
pixel+=QuantumRange;
pixel=(Sa*Da*pixel+Sa*Sc*(1.0-Da)+Da*Dc*(1.0-Sa));
break;
}
case ModulusSubtractCompositeOp:
{
pixel=Sc-Dc;
while (pixel > QuantumRange)
pixel-=QuantumRange;
while (pixel < 0.0)
pixel+=QuantumRange;
pixel=(Sa*Da*pixel+Sa*Sc*(1.0-Da)+Da*Dc*(1.0-Sa));
break;
}
Re: Formalizing ModulusAdd and ModulusSubtract
Posted: 2019-07-22T05:49:46-07:00
by snibgo
As magick says.
Also note that with HDRI, input values can be outside the range 0.0 to 1.0 (as a fraction of QuantumRange).
Formalisations (and the source code) can be verified, eg (Windows CMD syntax):
Code: Select all
magick xc:srgba(10%,20%,30%,0.3) xc:srgba(60%,70%,380%,0.4) ^
-define compose:clamp=off ^
-compose ModulusSubtract -composite ^
txt:
# ImageMagick pixel enumeration: 1,1,65535,srgba
0,0: (16121.6,19136.2,77200.2,38010.3) #3EFA4AC0FFFF947A srgba(24.6%,29.2%,117.8%,0.58)
And:
Code: Select all
result.a = 1 - ((1 - dest.a) * (1 - src.a)) = 1 - (1 - src.a - dest.a + src.a * dest.a) = scr.a + dest.a - src.a * dest.a
Re: Formalizing ModulusAdd and ModulusSubtract
Posted: 2019-07-25T23:55:32-07:00
by gubach
Is the interpretion of the code in "case ModulusAddCompositeOp" correct, that if pixel (= Sc + Dc; why not Sca + Dca like in the SVG specification?) is larger than QuantumRange (= 1) or smaller than 0 (which is equivalent to pixel is in the interval [0 1]) the equation
Code: Select all
pixel=(Sa*Da*pixel+Sa*Sc*(1.0-Da)+Da*Dc*(1.0-Sa))
holds?
Correct me if I am wrong but
Code: Select all
pixel=(Sa*Da*pixel+Sa*Sc*(1.0-Da)+Da*Dc*(1.0-Sa))
<=> Sc + Dc = Sa * Da * (Sc+Dc) + Sa * Sc * (1.0-Da) + Da * Dc * (1.0-Sa)
<=> Sc + Dc = Sa * Da * (Sc+Dc) + Sca * (1.0-Da) + Dca * (1.0-Sa)
<=> Sc + Dc = Sa * Da * Sc + Sa * Da * Dc + Sca - Sca * Da + Dca - Dca * Sa
<=> Sc + Dc = Sca * Da + Sa * Dca + Sca - Sca * Da + Dca - Dca * Sa
<=> Sc + Dc = Sca + Dca #which holds only in the special case that Sa = Da = 1
<=> Dca = Sc + Dc - Sca
which looks different from the expected plus-equation Dca = Sca + Dca that should be applied within [0 1]; according to the SVG specification for plus:
Code: Select all
Dca' = Sca × Da + Dca × Sa + Sca × (1 - Da) + Dca × (1 - Sa) = Sca + Dca.
Re: Formalizing ModulusAdd and ModulusSubtract
Posted: 2019-07-26T04:17:48-07:00
by magick
We will review/confirm/correct the ModulusAdd computation within a few days. Thanks for your analysis.