From dd6dfba51e31a65bc8e84363ed88cea5fccb486a Mon Sep 17 00:00:00 2001 From: Jesper Stemann Andersen Date: Mon, 15 Apr 2024 10:43:55 +0200 Subject: [PATCH] Added support for WebP --- Project.toml | 2 ++ README.md | 2 +- src/ImageIO.jl | 20 +++++++++++++++++++- test/runtests.jl | 18 ++++++++++++++++++ 4 files changed, 40 insertions(+), 2 deletions(-) diff --git a/Project.toml b/Project.toml index 5fffea4..0d77b20 100644 --- a/Project.toml +++ b/Project.toml @@ -15,6 +15,7 @@ QOI = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" Sixel = "45858cf5-a6b0-47a3-bbea-62219f50df47" TiffImages = "731e570b-9d59-4bfa-96dc-6df516fadf69" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" +WebP = "e3aaa7dc-3e4b-44e0-be63-ffb868ccd7c1" [compat] FileIO = "1.2" @@ -28,6 +29,7 @@ PNGFiles = "0.3, 0.4" QOI = "1" Sixel = "0.1.2" TiffImages = "0.3, 0.4, 0.5, 0.6, 0.7, 0.8" +WebP = "0.1.2" julia = "1.6" [extras] diff --git a/README.md b/README.md index 2381283..b35e047 100644 --- a/README.md +++ b/README.md @@ -15,7 +15,7 @@ FileIO.jl integration for image files | [QOI (Quite Okay Image)](https://qoiformat.org/) format | `.qoi` | [QOI.jl](https://github.com/KristofferC/QOI.jl) | pure Julia | | | DEC SIXEL (six-pixels) graphics | `.six`, `.sixel` | [Sixel.jl](https://github.com/johnnychen94/Sixel.jl) | Julia wrapper of [libsixel](https://github.com/libsixel/libsixel) | | | TIFF (Tag Image File Format) | `.tiff`, `.tif` | [TiffImages.jl](https://github.com/tlnagy/TiffImages.jl) | pure Julia | check [OMETIFF.jl](https://github.com/tlnagy/OMETIFF.jl) for OMETIFF support | - +| WebP | `.webp` | [WebP.jl](https://github.com/stemann/WebP.jl) | Julia wrapper of [libwebp](https://developers.google.com/speed/webp/docs/api) | | ## Installation diff --git a/src/ImageIO.jl b/src/ImageIO.jl index 3f9c0df..aeeead1 100644 --- a/src/ImageIO.jl +++ b/src/ImageIO.jl @@ -14,6 +14,7 @@ using LazyModules # @lazy macro is used to delay the package loading to its firs @lazy import OpenEXR = "52e1d378-f018-4a11-a4be-720524705ac7" @lazy import QOI = "4b34888f-f399-49d4-9bb3-47ed5cae4e65" @lazy import JpegTurbo = "b835a17e-a41a-41e7-81f0-2f016b05efe0" +@lazy import WebP = "e3aaa7dc-3e4b-44e0-be63-ffb868ccd7c1" # Enforce a type conversion to be backend independent (issue #25) # Note: If the backend does not provide efficient `convert` implementation, @@ -24,7 +25,8 @@ for FMT in ( :EXR, :QOI, :SIXEL, - :JPEG + :JPEG, + :WebP, ) @eval canonical_type(::DataFormat{$(Expr(:quote, FMT))}, ::AbstractArray{T, N}) where {T,N} = Array{T,N} @@ -186,6 +188,22 @@ function save(s::Stream{DataFormat{:JPEG}}, image::AbstractArray; kwargs...) JpegTurbo.fileio_save(s, image; kwargs...) end +## WebP +function load(f::File{DataFormat{:WebP}}; kwargs...) + data = WebP.fileio_load(f, kwargs...) + return enforce_canonical_type(f, data) +end +function load(s::Stream{DataFormat{:WebP}}; kwargs...) + data = WebP.fileio_load(s, kwargs...) + return enforce_canonical_type(s, data) +end +function save(f::File{DataFormat{:WebP}}, image::AbstractArray; kwargs...) + WebP.fileio_save(f, image; kwargs...) +end +function save(s::Stream{DataFormat{:WebP}}, image::AbstractArray; kwargs...) + WebP.fileio_save(s, image; kwargs...) +end + ## Function names labelled for FileIO. Makes FileIO lookup quicker const fileio_save = save const fileio_load = load diff --git a/test/runtests.jl b/test/runtests.jl index 313f76a..4e2a669 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -210,4 +210,22 @@ Threads.nthreads() <= 1 && @info "Threads.nthreads() = $(Threads.nthreads()), mu end end end + + @testset "WebP" begin + for typ in [RGBA{N0f8}, RGB{N0f8}] + @testset "$typ JPEG" begin + img = rand(typ, 10, 10) + f = File{format"WebP"}(joinpath(tmpdir, "test_fpath.webp")) + ImageIO.save(f, img) + img_saveload = ImageIO.load(f) + @test eltype(img_saveload) == n0f8(typ) # WebP uses 8bit + @test typeof(img_saveload) == ImageIO.canonical_type(f, img_saveload) + + open(io->ImageIO.save(Stream{format"WebP"}(io), img), joinpath(tmpdir, "test_io.webp"), "w") + img_saveload = open(io->ImageIO.load(Stream{format"WebP"}(io)), joinpath(tmpdir, "test_io.webp")) + @test eltype(img_saveload) == n0f8(typ) # WebP uses 8bit + @test typeof(img_saveload) == ImageIO.canonical_type(f, img_saveload) + end + end + end end