Skip to content

Commit 7589369

Browse files
committed
Merge remote-tracking branch 'JuliaImages/jc/ct' into ah/cartesian-ed
2 parents debfb58 + fb22593 commit 7589369

File tree

7 files changed

+58
-42
lines changed

7 files changed

+58
-42
lines changed

src/DitherPunk.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ include("ordered_imagemagick.jl")
1919
include("error_diffusion.jl")
2020
include("closest_color.jl")
2121
include("eval.jl")
22+
include("deprecations.jl")
2223

2324
export dither, dither!
2425
# Threshold dithering

src/deprecations.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# v2
2+
@deprecate ErrorDiffusion(filter; color_space=XYZ, kwargs...) ErrorDiffusion{color_space}(filter; kwargs...)

src/error_diffusion.jl

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,17 @@ julia> cs = ColorSchemes.PuOr_7.colors; # using ColorSchemes.jl for color palett
1515
1616
julia> dither(img, alg, cs);
1717
```
18+
19+
!!! note "Color Image"
20+
For color image, two color spaces are used when applying the algorithm: 1) the luminance
21+
channel in the Lab space is used to find the closest color in `cs`, and 2) the `CT`
22+
diffusion color space is used to propagate the error. `CT` is typically a linear
23+
colorspace, and the default value is `XYZ`. Another common choice is `RGB`, but strictly
24+
speaking, RGB is not a linear space.
1825
"""
1926

20-
_error_diffusion_kwargs = """
27+
const _error_diffusion_kwargs = """
2128
# Keyword arguments
22-
- `color_space`: Color space in which the error is diffused.
23-
Only used when dithering with a color palette. Defaults to `XYZ`.
24-
To replicate the output of other dithering libraries, set this to `RGB`.
2529
- `clamp_error::Bool`: Clamp accumulated error on each pixel within limits of colorant
2630
type `color_space` before looking up the closest color. Defaults to `true`.
2731
"""
@@ -81,11 +85,11 @@ function diffuse_error!(img, err, I, filter)
8185
end
8286

8387
function colordither(
84-
alg::ErrorDiffusion{F,C},
88+
alg::ErrorDiffusion{C},
8589
img::GenericImage,
8690
cs::AbstractVector{<:Pixel},
8791
metric::DifferenceMetric,
88-
) where {F,C}
92+
) where {C}
8993
# this function does not yet support OffsetArray
9094
require_one_based_indexing(img)
9195
index = Matrix{UInt8}(undef, size(img)...) # allocate matrix of color indices
@@ -116,7 +120,7 @@ function colordither(
116120
end
117121

118122
"""
119-
SimpleErrorDiffusion()
123+
SimpleErrorDiffusion(color_space=XYZ)
120124
121125
Error diffusion algorithm using the filter
122126
```
@@ -135,7 +139,7 @@ SimpleErrorDiffusion(; kwargs...) = ErrorDiffusion(SIMPLE_ERROR_DIFFUSION, 1; kw
135139
const SIMPLE_ERROR_DIFFUSION = [0 1; 1 0]//2
136140

137141
"""
138-
FloydSteinberg()
142+
FloydSteinberg(color_space=XYZ; kwargs...)
139143
140144
Error diffusion algorithm using the filter
141145
```
@@ -154,7 +158,7 @@ FloydSteinberg(; kwargs...) = ErrorDiffusion(FLOYD_STEINBERG, 2; kwargs...)
154158
const FLOYD_STEINBERG = [0 0 7; 3 5 1]//16
155159

156160
"""
157-
JarvisJudice()
161+
JarvisJudice(color_space=XYZ; kwargs...)
158162
159163
Error diffusion algorithm using the filter
160164
```
@@ -175,7 +179,7 @@ JarvisJudice(; kwargs...) = ErrorDiffusion(JARVIS_JUDICE, 3; kwargs...)
175179
const JARVIS_JUDICE = [0 0 0 7 5; 3 5 7 5 3; 1 3 5 3 1]//48
176180

177181
"""
178-
Stucki()
182+
Stucki(color_space=XYZ; kwargs...)
179183
180184
Error diffusion algorithm using the filter
181185
```
@@ -195,7 +199,7 @@ Stucki(; kwargs...) = ErrorDiffusion(STUCKI, 3; kwargs...)
195199
const STUCKI = [0 0 0 8 4; 2 4 8 4 2; 1 2 4 2 1]//42
196200

197201
"""
198-
Burkes()
202+
Burkes(color_space=XYZ; kwargs...)
199203
200204
Error diffusion algorithm using the filter
201205
```
@@ -214,7 +218,7 @@ Burkes(; kwargs...) = ErrorDiffusion(BURKES, 3; kwargs...)
214218
const BURKES = [0 0 0 8 4; 2 4 8 4 2]//32
215219

216220
"""
217-
Sierra()
221+
Sierra(color_space=XYZ; kwargs...)
218222
219223
Error diffusion algorithm using the filter
220224
```
@@ -231,7 +235,7 @@ Sierra(; kwargs...) = ErrorDiffusion(SIERRA, 3; kwargs...)
231235
const SIERRA = [0 0 0 5 3; 2 4 5 4 2; 0 2 3 2 0]//32
232236

233237
"""
234-
TwoRowSierra()
238+
TwoRowSierra(color_space=XYZ; kwargs...)
235239
236240
Error diffusion algorithm using the filter
237241
```
@@ -246,7 +250,7 @@ TwoRowSierra(; kwargs...) = ErrorDiffusion(TWO_ROW_SIERRA, 3; kwargs...)
246250
const TWO_ROW_SIERRA = [0 0 0 4 3; 1 2 3 2 1]//16
247251

248252
"""
249-
SierraLite()
253+
SierraLite(color_space=XYZ; kwargs...)
250254
251255
Error diffusion algorithm using the filter
252256
```
@@ -261,7 +265,7 @@ SierraLite(; kwargs...) = ErrorDiffusion(SIERRA_LITE, 2; kwargs...)
261265
const SIERRA_LITE = [0 0 2; 1 1 0]//4
262266

263267
"""
264-
Atkinson()
268+
Atkinson(color_space=XYZ; kwargs...)
265269
266270
Error diffusion algorithm using the filter
267271
```
@@ -276,7 +280,7 @@ Atkinson(; kwargs...) = ErrorDiffusion(ATKINSON, 2; kwargs...)
276280
const ATKINSON = [0 0 1 1; 1 1 1 0; 0 1 0 0]//8
277281

278282
"""
279-
Fan93()
283+
Fan93(color_space=XYZ; kwargs...)
280284
281285
Error diffusion algorithm using the filter
282286
```
@@ -296,7 +300,7 @@ Fan93(; kwargs...) = ErrorDiffusion(FAN_93, 3; kwargs...)
296300
const FAN_93 = [0 0 0 7; 1 3 5 0]//16
297301

298302
"""
299-
ShiauFan()
303+
ShiauFan(color_space=XYZ; kwargs...)
300304
301305
Error diffusion algorithm using the filter
302306
```
@@ -314,7 +318,7 @@ ShiauFan(; kwargs...) = ErrorDiffusion(SHIAU_FAN, 3; kwargs...)
314318
const SHIAU_FAN = [0 0 0 4; 1 1 2 0]//8
315319

316320
"""
317-
ShiauFan2()
321+
ShiauFan2(color_space=XYZ; kwargs...)
318322
319323
Error diffusion algorithm using the filter
320324
```
@@ -335,7 +339,7 @@ ShiauFan2(; kwargs...) = ErrorDiffusion(SHIAU_FAN_2, 4; kwargs...)
335339
const SHIAU_FAN_2 = [0 0 0 0 8; 1 1 2 4 0]//16
336340

337341
"""
338-
FalseFloydSteinberg()
342+
FalseFloydSteinberg(color_space=XYZ; kwargs...)
339343
340344
Error diffusion algorithm using the filter
341345
```

test/deprecations.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
@testset "test deprecated usage" begin
2+
alg = FloydSteinberg()
3+
@test alg == ErrorDiffusion(DitherPunk._floydsteinberg_filter; color_space=XYZ)
4+
end

test/runtests.jl

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,30 @@ using Test
33

44
@testset "DitherPunk.jl" begin
55
@testset "Utilities" begin
6-
println("Testing utilities...")
6+
@info "Testing utilities..."
77
include("test_utils.jl")
88
end
99
@testset "Bayer matrices" begin
10-
println("Testing Bayer matrices...")
10+
@info "Testing Bayer matrices..."
1111
include("test_bayer.jl")
1212
end
1313
@testset "Binary dithering" begin
14-
println("Testing binary dithering...")
14+
@info "Testing binary dithering..."
1515
include("test_gradient.jl")
1616
end
1717
@testset "Color image" begin
1818
@testset "Fixed palette" begin
19-
println("Testing per-channel dithering...")
19+
@info "Testing per-channel dithering..."
2020
include("test_fixed_color.jl")
2121
end
2222
@testset "Custom palette" begin
23-
println("Testing color palette dithering...")
23+
@info "Testing color palette dithering..."
2424
include("test_color.jl")
2525
end
2626
end
27+
# test deprecations at the end
28+
@testset "deprecations" begin
29+
@info "Testing deprecated usage, depwarns are expected..."
30+
include("deprecations.jl")
31+
end
2732
end

test/test_color.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ img_gray = testimage("fabio_gray_256")
2121

2222
# Run & test custom color palette dithering methods
2323
algs = Dict(
24-
"FloydSteinberg_XYZ" => FloydSteinberg(; color_space=XYZ),
25-
"FloydSteinberg_RGB" => FloydSteinberg(; color_space=RGB),
26-
"ClosestColor" => ClosestColor(),
27-
"Bayer" => Bayer(),
24+
"FloydSteinberg_XYZ" => @inferred(FloydSteinberg(XYZ)),
25+
"FloydSteinberg_RGB" => @inferred(FloydSteinberg(RGB)),
26+
"ClosestColor" => @inferred(ClosestColor()),
27+
"Bayer" => @inferred(Bayer()),
2828
)
2929

3030
for (name, alg) in algs

test/test_gradient.jl

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -37,21 +37,21 @@ algs_deterministic = Dict(
3737
"IM_c6x6" => IM_c6x6(),
3838
"IM_c7x7" => IM_c7x7(),
3939
# error error_diffusion
40-
"SimpleErrorDiffusion" => SimpleErrorDiffusion(),
41-
"FloydSteinberg" => FloydSteinberg(),
42-
"JarvisJudice" => JarvisJudice(),
43-
"Stucki" => Stucki(),
44-
"Burkes" => Burkes(),
45-
"Atkinson" => Atkinson(),
46-
"Sierra" => Sierra(),
47-
"TwoRowSierra" => TwoRowSierra(),
48-
"SierraLite" => SierraLite(),
49-
"Fan" => Fan93(),
50-
"ShiauFan" => ShiauFan(),
51-
"ShiauFan2" => ShiauFan2(),
52-
"FalseFloydSteinberg" => DitherPunk.FalseFloydSteinberg(),
40+
"SimpleErrorDiffusion" => @inferred(SimpleErrorDiffusion()),
41+
"FloydSteinberg" => @inferred(FloydSteinberg()),
42+
"JarvisJudice" => @inferred(JarvisJudice()),
43+
"Stucki" => @inferred(Stucki()),
44+
"Burkes" => @inferred(Burkes()),
45+
"Atkinson" => @inferred(Atkinson()),
46+
"Sierra" => @inferred(Sierra()),
47+
"TwoRowSierra" => @inferred(TwoRowSierra()),
48+
"SierraLite" => @inferred(SierraLite()),
49+
"Fan" => @inferred(Fan93()),
50+
"ShiauFan" => @inferred(ShiauFan()),
51+
"ShiauFan2" => @inferred(ShiauFan2()),
52+
"FalseFloydSteinberg" => @inferred(DitherPunk.FalseFloydSteinberg()),
5353
# Keyword arguments
54-
"FloydSteinberg_clamp_error" => FloydSteinberg(; clamp_error=false),
54+
"FloydSteinberg_clamp_error" => @inferred(FloydSteinberg(; clamp_error=false)),
5555
"Bayer_invert_map" => Bayer(; invert_map=true),
5656
)
5757

0 commit comments

Comments
 (0)