@@ -50,79 +50,103 @@ gamutmax(::Type{T}) where {T<:HSL} = (360,1,1)
5050gamutmin (:: Type{T} ) where {T<: HSL } = (0 ,0 ,0 )
5151gamutmax (:: Type{T} ) where {T<: Lab } = (100 ,128 ,128 )
5252gamutmin (:: Type{T} ) where {T<: Lab } = (0 ,- 127 ,- 127 )
53- gamutmax (:: Type{T} ) where {T<: LCHab } = (100 ,1 ,360 )
53+ gamutmax (:: Type{T} ) where {T<: LCHab } = (100 ,1 ,360 ) # FIXME
5454gamutmin (:: Type{T} ) where {T<: LCHab } = (0 ,0 ,0 )
55- gamutmax (:: Type{T} ) where {T<: YIQ } = (1 ,0.5226 ,0.5226 )
56- gamutmin (:: Type{T} ) where {T<: YIQ } = (0 ,- 0.5957 ,- 0.5957 )
55+ gamutmax (:: Type{T} ) where {T<: YIQ } = (1 ,0.5226 ,0.5226 ) # FIXME
56+ gamutmin (:: Type{T} ) where {T<: YIQ } = (0 ,- 0.5957 ,- 0.5957 ) # FIXME
5757
5858gamutmax (:: Type{T} ) where {T<: AbstractGray } = (1 ,)
59- gamutmax (:: Type{T} ) where {T<: TransparentGray } = (1 ,1 )
60- gamutmax (:: Type{T} ) where {T<: AbstractRGB } = (1 ,1 ,1 )
61- gamutmax (:: Type{T} ) where {T<: TransparentRGB } = (1 ,1 ,1 ,1 )
6259gamutmin (:: Type{T} ) where {T<: AbstractGray } = (0 ,)
63- gamutmin (:: Type{T} ) where {T<: TransparentGray } = (0 , 0 )
60+ gamutmax (:: Type{T} ) where {T<: AbstractRGB } = (1 , 1 , 1 )
6461gamutmin (:: Type{T} ) where {T<: AbstractRGB } = (0 ,0 ,0 )
65- gamutmin (:: Type{T} ) where {T<: TransparentRGB } = (0 ,0 ,0 ,0 )
62+
63+ gamutmax (:: Type{C} ) where {C<: TransparentColor } = (gamutmax (color_type (C))... , 1 )
64+ gamutmin (:: Type{C} ) where {C<: TransparentColor } = (gamutmin (color_type (C))... , 0 )
6665
6766# rand
68- for t in [Float16,Float32,Float64,N0f8,N0f16,N0f32]
69- @eval _rand (:: Type{T} ) where {T<: Union{AbstractRGB{$t},AbstractGray{$t}} } =
70- mapc (x-> rand (eltype (T)), base_colorant_type (T)())
71- end
72-
73- function _rand (:: Type{T} ) where T<: Colorant
74- Gmax = gamutmax (T)
75- Gmin = gamutmin (T)
76- Mi = eltype (T) <: FixedPoint ? 1.0 / typemax (eltype (T)) : 1.0
77- A = rand (eltype (T), length (T))
78- for j in eachindex (Gmax)
79- A[j] = A[j] * (Mi * (Gmax[j]- Gmin[j])) + Gmin[j]
80- end
81- T (A... )
82- end
83-
84- if Base. VERSION < v " 1.6.0-DEV.1083"
85- reinterpretc (:: Type{T} , A:: Array{C} ) where {T<: Real ,C<: AbstractGray } = reinterpret (T, A)
86- reinterpretc (:: Type{T} , A:: Array{C} ) where {T<: Real ,C<: Colorant } = reshape (reinterpret (T, A), (sizeof (C)÷ sizeof (T), size (A)... ))
87- else
88- reinterpretc (:: Type{T} , A:: Array{C} ) where {T<: Real ,C<: Colorant } = reinterpret (reshape, T, A)
89- end
90-
91- function _rand (:: Type{T} , sz:: Dims ) where T<: Colorant
92- Mi = eltype (T) <: FixedPoint ? 1.0 / typemax (eltype (T)) : 1.0
93- A = Array {T} (undef, sz)
94- Tr = eltype (T) <: FixedPoint ? FixedPointNumbers. rawtype (eltype (T)) : eltype (T)
95- nchannels = sizeof (T)÷ sizeof (eltype (T))
96- Au = Random. UnsafeView (convert (Ptr{Tr}, pointer (A)), length (A)* nchannels)
97- rand! (Au)
98-
99- Gmax = gamutmax (T)
100- Gmin = gamutmin (T)
101- s = (Gmax .- Gmin) .* Mi
102- if ! all (iszero, Gmin) || ! all (== (1 ), s)
103- Ar = reinterpretc (eltype (T), A)
104- if T<: AbstractGray
105- s1, offset1 = s[1 ], Gmin[1 ]
106- for I in CartesianIndices (A)
107- Ar[I] = Ar[I] * s1 + offset1
108- end
109- else
110- for I in CartesianIndices (A)
111- for j in eachindex (s)
112- Ar[j,I] = Ar[j,I] * s[j] + Gmin[j]
113- end
114- end
115- end
67+ const Rand01Normd = Union{N0f8, N0f16, N0f32, N0f64}
68+ const Rand01Type = Union{AbstractFloat, Rand01Normd}
69+
70+ # TODO : Remove the following once it is guaranteed to be implemented in FixedPointNumbers.
71+ if which (rand, Tuple{AbstractRNG, SamplerType{<: FixedPoint }}). module === Random
72+ function rand (r:: AbstractRNG , :: SamplerType{X} ) where X <: FixedPoint
73+ reinterpret (X, rand (r, FixedPointNumbers. rawtype (X)))
11674 end
117- return A
11875end
11976
120- rand (:: Type{T} , sz:: Dims... ) where {T<: Colorant } = _rand (ccolor (T, base_colorant_type (T){Float64}), sz... )
77+ function rand (r:: AbstractRNG , :: SamplerType{C} ) where {C<: Colorant }
78+ rand (r, base_colorant_type (C){Float64})
79+ end
80+ function rand (r:: AbstractRNG , :: SamplerType{C} ) where {T, C<: Colorant{T} }
81+ Cmax = C (gamutmax (C)... )
82+ Cmin = C (gamutmin (C)... )
83+ mapc ((m, n) -> T ((m - n) * rand (r, floattype (T)) + n), Cmax, Cmin)
84+ end
85+ function rand (r:: AbstractRNG , :: SamplerType{C} ) where {T<: Rand01Type , C0<: AbstractGray{T} ,
86+ C<: Union{C0, TransparentGray{C0, T}} }
87+ mapc (_ -> rand (r, T), base_colorant_type (C)())
88+ end
89+ function rand (r:: AbstractRNG , :: SamplerType{C} ) where {T<: Rand01Type , C0<: AbstractRGB{T} ,
90+ C<: Union{C0, TransparentRGB{C0, T}} }
91+ mapc (_ -> rand (r, T), base_colorant_type (C)())
92+ end
93+ function rand (r:: AbstractRNG , :: SamplerType{AGray32} ) # Gray24 has little benefit of specialization.
94+ reinterpret (AGray32, (rand (r, UInt32) & 0xff0000ff ) * 0x010101 )
95+ end
96+ rand (r:: AbstractRNG , :: SamplerType{RGB24} ) = reinterpret (RGB24, rand (r, UInt32) & 0xffffff )
97+ rand (r:: AbstractRNG , :: SamplerType{ARGB32} ) = reinterpret (ARGB32, rand (r, UInt32))
98+
99+ function rand (r:: AbstractRNG , :: Type{C} , dims:: Dims ) where {C <: Colorant }
100+ CC = isconcretetype (C) ? C : base_colorant_type (C){Float64}
101+ rand! (r, Array {CC} (undef, dims), CC)
102+ end
121103
122- rand (:: Type{Gray24} ) = Gray24 (rand (N0f8))
123- rand (:: Type{Gray24} , sz:: Dims ) = Gray24 .(rand (N0f8,sz))
124- rand (:: Type{AGray32} ) = AGray32 (rand (N0f8),rand (N0f8))
125- rand (:: Type{AGray32} , sz:: Dims ) = AGray32 .(rand (N0f8,sz),rand (N0f8,sz))
104+ # rand!
105+ function rand! (r:: AbstractRNG , A:: Array{C} , :: SamplerType{C} ) where {C<: Colorant }
106+ rand! (r, A, SamplerType {base_colorant_type(C){Float64}} ())
107+ end
108+ function rand! (r:: AbstractRNG , A:: Array{C} , :: SamplerType{C} ) where {T, C<: Colorant{T} }
109+ A .= rand .((r,), C)
110+ end
111+ function _rand01! (r:: AbstractRNG , A:: Array{C} ,
112+ :: SamplerType{C} ) where {T<: Rand01Type , C<: Colorant{T} }
113+ N = sizeof (C) ÷ sizeof (T)
114+ T0 = T <: FixedPoint ? FixedPointNumbers. rawtype (T) : T
115+ At = unsafe_wrap (Array, reinterpret (Ptr{T0}, pointer (A)), (N, size (A)... ))
116+ rand! (r, At, T0)
117+ A
118+ end
119+ function rand! (r:: AbstractRNG , A:: Array{C} ,
120+ s:: SamplerType{C} ) where {T<: AbstractFloat , C<: Colorant{T} }
121+ _rand01! (r, A, s)
122+ Cmin = C (gamutmin (C)... )
123+ Cs = C ((gamutmax (C) .- gamutmin (C)). .. )
124+ f (c) = mapc ((a, b) -> T (a + b), mapc (* , c, Cs), Cmin)
125+ A .= f .(A)
126+ end
127+ function rand! (r:: AbstractRNG , A:: Array{C} ,
128+ s:: SamplerType{C} ) where {T<: Rand01Type , C<: Union{Gray{T}, AGray{T}, GrayA{T}} }
129+ _rand01! (r, A, s)
130+ end
131+ function rand! (r:: AbstractRNG , A:: Array{C} ,
132+ s:: SamplerType{C} ) where {T<: Rand01Type ,
133+ C<: Union {RGB{T}, ARGB{T}, RGBA{T}, XRGB{T}, RGBX{T},
134+ BGR{T}, ABGR{T}, BGRA{T}}}
135+ _rand01! (r, A, s)
136+ end
137+ function rand! (r:: AbstractRNG , A:: Array{C} ,
138+ :: SamplerType{C} ) where {C<: Union{Gray24, AGray32, RGB24, ARGB32} }
139+ At = unsafe_wrap (Array, reinterpret (Ptr{UInt32}, pointer (A)), size (A))
140+ rand! (r, At, UInt32)
141+ if C === Gray24
142+ At .= At .& 0xff .* 0x010101
143+ elseif C === AGray32
144+ At .= At .& 0xff0000ff .* 0x010101
145+ elseif C === RGB24
146+ At .&= 0xffffff
147+ end
148+ A
149+ end
126150
127151# broadcast
128152
0 commit comments