@@ -140,6 +140,24 @@ channels(c::TransparentGray) = (gray(c), alpha(c))
140140channels (c:: AbstractRGB ) = (red (c), green (c), blue (c))
141141channels (c:: TransparentRGB ) = (red (c), green (c), blue (c), alpha (c))
142142
143+ if reinterpret (N0f16, 0xBADb )^ 2 === N0f16 (float (reinterpret (N0f16, 0xBADb ))^ 2 )
144+ function _mul (x:: N0f8 , y:: N0f8 )
145+ m = widemul (reinterpret (x), reinterpret (y))
146+ z = (((m + 0x80 ) >> 0x8 ) + m + 0x80 ) >> 0x8
147+ reinterpret (N0f8, z % UInt8)
148+ end
149+ function _mul (x:: N0f16 , y:: N0f16 )
150+ m = widemul (reinterpret (x), reinterpret (y))
151+ z = (((m + 0x8000 ) >> 0x10 ) + m + 0x8000 ) >> 0x10
152+ reinterpret (N0f16, z % UInt16)
153+ end
154+ end
155+ _mul (x:: T , y:: T ) where {T} = x * y
156+ _mul (x, y) = (T = multype (typeof (x), typeof (y)); _mul (T (x), T (y)))
157+
158+ _mapc (:: Type{C} , f, c) where {C<: MathTypes } = C (f .(channels (c))... )
159+ _mapc (:: Type{C} , f, a, b) where {C<: MathTypes } = C (f .(channels (a), channels (b))... )
160+
143161# # Generic algorithms
144162Base. add_sum (c1:: MathTypes ,c2:: MathTypes ) = mapc (Base. add_sum, c1, c2)
145163Base. reduce_first (:: typeof (Base. add_sum), c:: MathTypes ) = mapc (x-> Base. reduce_first (Base. add_sum, x), c)
@@ -182,6 +200,7 @@ complement(x::TransparentColor) = typeof(x)(complement(color(x)), alpha(x))
182200
183201# Common
184202copy (c:: MathTypes ) = c
203+ (* )(f:: Real , c:: MathTypes ) = _mapc (rettype (* , f, c), v -> _mul (f, v), c)
185204(* )(c:: MathTypes , f:: Real ) = (* )(f, c)
186205(+ )(c:: MathTypes ) = mapc (+ , c)
187206(+ )(c:: MathTypes{Bool} ) = c
@@ -191,7 +210,7 @@ copy(c::MathTypes) = c
191210(/ )(c:: MathTypes , f:: Integer ) = (one (eltype (c))/ f)* c
192211abs (c:: MathTypes ) = mapc (abs, c)
193212norm (c:: MathTypes , p:: Real = 2 ) = (cc = channels (c); norm (cc, p)/ (p == 0 ? length (cc) : length (cc)^ (1 / p)))
194- (⊙ )(a:: C , b:: C ) where {C<: MathTypes } = mapc ( * , a, b)
213+ (⊙ )(a:: C , b:: C ) where {C<: MathTypes } = _mapc ( rettype ( * , a, b), _mul , a, b)
195214(⋅ )(a:: C , b:: C ) where {C<: MathTypes } = throw (MethodError (dot, (a, b)))
196215(⊗ )(a:: C , b:: C ) where {C<: MathTypes } = throw (MethodError (tensor, (a, b)))
197216
@@ -204,16 +223,6 @@ norm(c::MathTypes, p::Real=2) = (cc = channels(c); norm(cc, p)/(p == 0 ? length(
204223
205224
206225# Scalar RGB
207- (* )(f:: Real , c:: AbstractRGB ) = rettype (* , f, c)(f* red (c), f* green (c), f* blue (c))
208- (* )(f:: Real , c:: TransparentRGB ) = rettype (* , f, c)(f* red (c), f* green (c), f* blue (c), f* alpha (c))
209- function (* )(f:: Real , c:: AbstractRGB{T} ) where T<: Normed
210- fs = f* (1 / reinterpret (oneunit (T)))
211- rettype (* , f, c)(fs* reinterpret (red (c)), fs* reinterpret (green (c)), fs* reinterpret (blue (c)))
212- end
213- function (* )(f:: Normed , c:: AbstractRGB{T} ) where T<: Normed
214- fs = reinterpret (f)* (1 / widen (reinterpret (oneunit (T)))^ 2 )
215- rettype (* , f, c)(fs* reinterpret (red (c)), fs* reinterpret (green (c)), fs* reinterpret (blue (c)))
216- end
217226function (/ )(c:: AbstractRGB{T} , f:: Real ) where T<: Normed
218227 fs = (one (f)/ reinterpret (oneunit (T)))/ f
219228 rettype (/ , c, f)(fs* reinterpret (red (c)), fs* reinterpret (green (c)), fs* reinterpret (blue (c)))
@@ -270,14 +279,12 @@ end
270279middle (c:: AbstractGray ) = arith_colorant_type (c)(middle (gray (c)))
271280middle (x:: C , y:: C ) where {C<: AbstractGray } = arith_colorant_type (C)(middle (gray (x), gray (y)))
272281
273- (* )(f:: Real , c:: AbstractGray ) = rettype (* , f, c)(f* gray (c))
274- (* )(f:: Real , c:: TransparentGray ) = rettype (* , f, c)(f* gray (c), f* alpha (c))
275282(/ )(n:: Number , c:: AbstractGray ) = base_color_type (c)(n/ gray (c))
276283(+ )(a:: AbstractGray , b:: AbstractGray ) = rettype (+ , a, b)(gray (a)+ gray (b))
277284(+ )(a:: TransparentGray , b:: TransparentGray ) = rettype (+ , a, b)(gray (a)+ gray (b), alpha (a)+ alpha (b))
278285(- )(a:: AbstractGray , b:: AbstractGray ) = rettype (- , a, b)(gray (a)- gray (b))
279286(- )(a:: TransparentGray , b:: TransparentGray ) = rettype (- , a, b)(gray (a)- gray (b), alpha (a)- alpha (b))
280- (* )(a:: AbstractGray , b:: AbstractGray ) = rettype ( * , a, b)( gray (a) * gray (b))
287+ (* )(a:: AbstractGray , b:: AbstractGray ) = a ⊙ b
281288(^ )(a:: AbstractGray , b:: Integer ) = rettype (^ , a, b)(gray (a)^ convert (Int,b))
282289(^ )(a:: AbstractGray , b:: Real ) = rettype (^ , a, b)(gray (a)^ b)
283290(/ )(a:: C , b:: C ) where C<: AbstractGray = base_color_type (C)(gray (a)/ gray (b))
@@ -287,7 +294,7 @@ middle(x::C, y::C) where {C<:AbstractGray} = arith_colorant_type(C)(middle(gray(
287294(- )(a:: AbstractGray , b:: Number ) = base_color_type (a)(gray (a)- b)
288295(- )(a:: Number , b:: AbstractGray ) = base_color_type (b)(a- gray (b))
289296
290- (⋅ )(x:: C , y:: C ) where {C<: AbstractGray } = gray (x)* gray (y)
297+ (⋅ )(x:: C , y:: C ) where {C<: AbstractGray } = _mul ( gray (x), gray (y) )
291298(⊗ )(x:: C , y:: C ) where {C<: AbstractGray } = x ⊙ y
292299
293300max (a:: T , b:: T ) where {T<: AbstractGray } = T (max (gray (a),gray (b)))
@@ -302,8 +309,7 @@ min(a::AbstractGray, b::Number) = min(promote(a,b)...)
302309atan (x:: AbstractGray , y:: AbstractGray ) = atan (gray (x), gray (y))
303310hypot (x:: AbstractGray , y:: AbstractGray ) = hypot (gray (x), gray (y))
304311
305- dotc (x:: C , y:: C ) where {C<: AbstractGray } = acc (gray (x))* acc (gray (y))
306- dotc (x:: AbstractGray , y:: AbstractGray ) = dotc (promote (x, y)... )
312+ dotc (x:: AbstractGray , y:: AbstractGray ) = _mul (acc (gray (x)), acc (gray (y)))
307313
308314typemin (:: Type{C} ) where {C<: AbstractGray } = C (typemin (eltype (C)))
309315typemax (:: Type{C} ) where {C<: AbstractGray } = C (typemax (eltype (C)))
0 commit comments