@@ -77,9 +77,8 @@ correct_gamut(c::CV) where {CV<:TransparentRGB} =
77
77
CV (clamp01 (red (c)), clamp01 (green (c)), clamp01 (blue (c)), clamp01 (alpha (c))) # for `hex`
78
78
79
79
function srgb_compand (v:: Fractional )
80
- # the following is an optimization technique for `1.055v^(1/2.4) - 0.055`.
81
- # x^y ≈ exp(y*log(x)) ≈ exp2(y*log2(y)); the middle form is faster
82
- v <= 0.0031308 ? 12.92 v : 1.055 * exp (1 / 2.4 * log (v)) - 0.055
80
+ # `pow5_12` is an optimized function to get `v^(1/2.4)`
81
+ v <= 0.0031308 ? 12.92 v : 1.055 * pow5_12 (v) - 0.055
83
82
end
84
83
85
84
cnvt (:: Type{CV} , c:: AbstractRGB ) where {CV<: AbstractRGB } = CV (red (c), green (c), blue (c))
@@ -270,17 +269,30 @@ cnvt(::Type{HSI{T}}, c::Color3) where {T} = cnvt(HSI{T}, convert(RGB{T}, c))
270
269
# -----------------
271
270
272
271
function invert_srgb_compand (v:: Fractional )
273
- v <= 0.04045 && return v/ 12.92
274
- # the following is an optimization technique for `((v+0.055) /1.055)^2.4`.
275
- # see also: srgb_compand(v::Fractional)
276
- x = (v + 0.055 ) / 1.055
277
- return x^ 2 * exp (0.4 * log (x)) # 2.4 == 2 + 0.4
272
+ # `pow12_5` is an optimized function to get `x^2.4`
273
+ v <= 0.04045 ? 1 / 12.92 * v : pow12_5 (1 / 1.055 * (v + 0.055 ))
278
274
end
279
275
280
- const invert_srgb_compand_n0f8 = [invert_srgb_compand (v/ 255 ) for v = 0 : 255 ] # LUT
276
+ # lookup table for `N0f8` (the extra two elements are for `Float32` splines)
277
+ const invert_srgb_compand_n0f8 = [invert_srgb_compand (v/ 255.0 ) for v = 0 : 257 ]
281
278
282
279
function invert_srgb_compand (v:: N0f8 )
283
- invert_srgb_compand_n0f8[reinterpret (UInt8, v) + 1 ]
280
+ @inbounds invert_srgb_compand_n0f8[reinterpret (UInt8, v) + 1 ]
281
+ end
282
+
283
+ function invert_srgb_compand (v:: Float32 )
284
+ i = unsafe_trunc (Int32, v * 255 )
285
+ (i < 13 || i > 255 ) && return invert_srgb_compand (Float64 (v))
286
+ @inbounds y = view (invert_srgb_compand_n0f8, i: i+ 3 )
287
+ dv = v * 255.0 - i
288
+ dv == 0.0 && @inbounds return y[2 ]
289
+ if v < 0.38857287f0
290
+ return @fastmath (y[2 ]+ 0.5 * dv* ((- 2 / 3 * y[1 ]- y[2 ])+ (2 y[3 ]- 1 / 3 * y[4 ])+
291
+ dv* (( y[1 ]- 2 y[2 ])+ y[3 ]-
292
+ dv* (( 1 / 3 * y[1 ]- y[2 ])+ ( y[3 ]- 1 / 3 * y[4 ]) ))))
293
+ else
294
+ return @fastmath (y[2 ]+ 0.5 * dv* ((4 y[3 ]- 3 y[2 ])- y[4 ]+ dv* ((y[4 ]- y[3 ])+ (y[2 ]- y[3 ]))))
295
+ end
284
296
end
285
297
286
298
function cnvt (:: Type{XYZ{T}} , c:: AbstractRGB ) where T
0 commit comments