This is the output side of #147.
HotCell receives the destination as an open file descriptor, but it can't pass /dev/fd/N as destination:, because the savers pick the format from the path's extension. So HotCell saves to a scratch file named output.png and then copies that file into the descriptor (transforming.rb). That is an extra write and read of every output, plus tmpfs space for the scratch file.
ImageProcessing::Vips.source(src).convert("png").call(destination: "/dev/fd/5")
# Vips::Error: VipsForeignSave: "/dev/fd/5" is not a known file format
ImageProcessing::MiniMagick.source(src).loader(inherit_fds: [out]).convert("jpg").call(destination: "/dev/fd/5")
# writes a PNG
Proposal: when the destination has no extension, save in the #convert format.
- vips: pick the saver with
Vips.vips_foreign_find_save(".#{format}") and filter options as select_valid_saver_options does.
- MiniMagick: write to
"#{format}:#{destination}".
Destinations with an extension are unaffected. .saver(saver:) doesn't cover this, because it takes libvips operation names and skips option filtering.
Happy to open a PR, or to add a format: keyword to #call instead if you prefer.
I opened #150 with a concrete implementation, in case it helps.
This is the output side of #147.
HotCell receives the destination as an open file descriptor, but it can't pass
/dev/fd/Nasdestination:, because the savers pick the format from the path's extension. So HotCell saves to a scratch file namedoutput.pngand then copies that file into the descriptor (transforming.rb). That is an extra write and read of every output, plus tmpfs space for the scratch file.Proposal: when the destination has no extension, save in the
#convertformat.Vips.vips_foreign_find_save(".#{format}")and filter options asselect_valid_saver_optionsdoes."#{format}:#{destination}".Destinations with an extension are unaffected.
.saver(saver:)doesn't cover this, because it takes libvips operation names and skips option filtering.Happy to open a PR, or to add a
format:keyword to#callinstead if you prefer.I opened #150 with a concrete implementation, in case it helps.