Skip to content

Commit

Permalink
Use WebP for CVD simulation demo in docs instead of indexed PNG
Browse files Browse the repository at this point in the history
  • Loading branch information
kimikage committed May 14, 2024
1 parent 0c59a5d commit f118d1e
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 80 deletions.
21 changes: 21 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
@@ -1,3 +1,21 @@
using Pkg
dependents = ["ImageCore"] # direct
idependents = ["WebP"] # indirect
devdir = get(ENV, "JULIA_PKG_DEVDIR", nothing) # backup
workdir = joinpath(@__DIR__, "work")
ENV["JULIA_PKG_DEVDIR"] = workdir
Pkg.activate(workdir)
Pkg.develop(dependents, preserve=PRESERVE_DIRECT)
ENV["JULIA_PKG_DEVDIR"] = devdir # restore
for dep in dependents
Pkg.activate(joinpath(workdir, dep))
Pkg.compat("Colors", "< 1")
end
Pkg.activate(@__DIR__) # this project
pkgspecs = [PackageSpec(path=joinpath(workdir, dep)) for dep in dependents]
Pkg.develop(pkgspecs, preserve=PRESERVE_DIRECT)
Pkg.add(idependents)

using Documenter, Colors

abstract type SVG end
Expand Down Expand Up @@ -39,3 +57,6 @@ makedocs(
deploydocs(
repo = "github.com/JuliaGraphics/Colors.jl.git",
target = "build")


Pkg.rm([idependents; dependents], io=IOBuffer())
87 changes: 19 additions & 68 deletions docs/sampleimages.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,91 +3,42 @@ module SampleImages

using Colors
using Base64
using WebP

struct BeadsImageSVG <: Main.SVG
buf::IOBuffer
end

const beads = WebP.read_webp(joinpath(@__DIR__, "src", "assets", "figures", "beads.webp"))

# The following code is ad-hoc and highly depends on "beads.svg".
# Be careful when modifying the svg file or its code.
function BeadsImageSVG(caption::String; filter=nothing, width="64mm", height="36mm")
io = IOBuffer()
id = string(hash(caption), base=16)

open(joinpath("assets", "figures", "beads.svg"), "r") do file
for line in eachline(file, keep=true)
occursin("<?xml", line) && continue
if occursin("<svg", line)
line = replace(line, ">"=>
""" width="$width" height="$height" style="display:inline; margin-left:1em; margin-bottom:1em">""")
elseif occursin("filter_beads_g", line)
line = replace(line, "filter_beads_g"=>"filter_"*id)
elseif occursin("</svg>", line)
text = """
<text x="16" y="1000" style="fill:black;opacity:0.9;font-size:80px;">$caption</text>
</svg>"""
line = replace(line, "</svg>"=>text)
end
write(io, """<svg version="1.1" viewBox="0 0 1920 1080" """)
write(io, """xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" """)
write(io, """width="$width" height="$height" image-rendering="optimizeQuality" """)
write(io, """style="display:inline; margin-left:1em; margin-bottom:1em">\n""")

m = match(r"data:image/png;base64,([^\"]+)", line)
if filter === nothing || m === nothing
write(io, line)
continue
end
img = filter === nothing ? beads : filter.(beads)
webp = WebP.encode(img, lossy=true, quality=85)

head = m.offsets[1]
write(io, SubString(line, 1, head - 1))
src = IOBuffer(m.captures[1])
b64dec = Base64DecodePipe(src) # decode all for simplicity
b64enc = Base64EncodePipe(io)
write(b64enc, read(b64dec, 33)) # before the length of "PLTE"
replace_palette(b64enc, b64dec, filter)
n = write(b64enc, read(b64dec))
close(b64enc)
close(b64dec)
write(io, SubString(line, head + length(m.captures[1]), length(line)))
end
end
BeadsImageSVG(io)
end
write(io, """<image width="1920" height="1080" xlink:href="data:image/webp;base64,""")

b64enc = Base64EncodePipe(io)
write(b64enc, webp)
close(b64enc)

function replace_palette(dest::IO, src::IO, filter)
buf = IOBuffer() # to calculate chunk CRCs
write(io, """" />\n""")

u8(x) = write(buf, UInt8(x & 0xFF))
u16(x) = (u8((x & 0xFFFF)>>8); u8(x))
u32(x) = (u16((x & 0xFFFFFFFF)>>16); u16(x))
function read_palette()
uint32 = (UInt32(read(src, UInt8)) << 16) |
(UInt32(read(src, UInt8)) << 8) | read(src, UInt8)
reinterpret(RGB24, uint32)
end
function write_palette(c::Color)
rgb24 = convert(RGB24,c)
u8(rgb24.color>>16); u8(rgb24.color>>8); u8(rgb24.color)
end
crct(x) = (for i = 1:8; x = x & 1==1 ? 0xEDB88320 (x>>1) : x>>1 end; x)
table = UInt32[crct(i) for i = 0x00:0xFF]
function crc32()
seekstart(buf)
crc = 0xFFFFFFFF
while !eof(buf)
crc = (crc>>8) table[(crc&0xFF) read(buf, UInt8) + 1]
end
u32(crc 0xFFFFFFFF)
for style in ("fill:white;stroke:white;stroke-width:20;opacity:0.2", "fill:black;opacity:0.9")
write(io,"""<text x="16" y="1000" style="$style;font-size:80px;">$caption</text>\n""")
end
lenbytes = read(src, 4)
len = (UInt32(lenbytes[3]) << 8) | lenbytes[4]
write(dest, lenbytes)
write(buf, read(src, 4)) # "PLTE"
for i = 1:(len÷3)
write_palette(filter(read_palette()))
end
read(src, 4) # CRC
crc32()
write(dest, take!(seekstart(buf)))

write(io, """</svg>\n""")

BeadsImageSVG(io)
end

end
Loading

0 comments on commit f118d1e

Please sign in to comment.