Module: Cooltrainer::DistorteD::Technology::Vips::Load
- Included in:
- Cooltrainer::DistorteD::Technology::Vips
- Defined in:
- lib/distorted/modular_technology/vips/load.rb
Constant Summary collapse
- VIPS_LOADERS =
Returns a Set of MIME::Types based on libvips LipsForeignLoad capabilities. NOTE: libvips only declares support (via :get_suffixes) for the “saver” types,
but libvips can use additional external libraries for wider media-types support, e.g.:
-
SVG with librsvg2★ / libcairo. [*]
-
PDF with PDFium if available, otherwise with libpoppler-glib / libcairo.
-
OpenEXR/libIlmImf — ILM high dynamic range image format.
-
maybe more: github.com/libvips/libvips/blob/master/configure.ac
[FITS]: heasarc.gsfc.nasa.gov/docs/heasarc/fits.html
[RSVG2]: This is the normal SVG library for the GNOME/GLib world and is
probably fine for 95% of use-cases, but I'm pissed off at it because of: - https://gitlab.gnome.org/GNOME/librsvg/-/issues/56 - https://gitlab.gnome.org/GNOME/librsvg/-/issues/100 - https://gitlab.gnome.org/GNOME/librsvg/-/issues/183 - https://gitlab.gnome.org/GNOME/librsvg/-/issues/494 - https://bugzilla.gnome.org/show_bug.cgi?id=666477 - https://phabricator.wikimedia.org/T35245 TLDR: SVG <tspan> elements' [:x, :y, :dy, :dx] attributes can be a space-delimited list of position values for individual characters in the <tspan>, but librsvg2 only supported reading those attributes as a single one-shot numeric value. Documents using this totally-common and totally-in-spec feature rendered incorrectly with librsvg2. Effected <tspan> elements' subsequent children would hug one edge of the rendered output. And wouldn't you know it but the one (1) SVG on my website at the time I built this feature (IIDX-Turntable-parts.svg) used this feature for the double-digit parts diagram labels. I ended up having to edit my input document to just squash the offending <tspan>s down to a single child each. I guess that's semantically more correct in my document since they are numbers like Eleven and not two separate characters like '1 1' but still ugh lol This was finally fixed in 2019 as of librsvg2 version 2.45.91 :) https://gitlab.gnome.org/GNOME/librsvg/-/issues/494#note_579774
[MAGICK]: The Magick-based ‘.bmp’ loader is broken/missing in libvips <= 8.9.1,
but our automatic Loader detection will handle that. Just FYI :)
-
Cooltrainer::DistorteD::Technology::Vips::vips_get_types('VipsForeignLoad').keep_if { |t| Array[ t.media_type != 'application'.freeze, # e.g. application/pdf t.media_type != 'text'.freeze, # e.g. text/csv ].all? && Array[ t.sub_type.include?('zip'.freeze), # Skip declaring SVG here since I want to handle it in a Vector-only Molecule # and will re-declare this there. Prolly need to think up a better way to do this. t.sub_type.include?('svg'.freeze), ].none? }
- LOWER_WORLD =
Vips::vips_foreign_find_save is based on filename suffix (extension), but :vips_foreign_find_load seems to be based on file magic. That is, we can’t ‘vips_foreign_find_load` for a made-up filename or plain suffix like we can to to build ’vips/save’::OUTER_LIMITS. This caught me off guard but doesn’t entirely not-make-sense, considering Vips::Image::new_from_filename calls :vips_foreign_find_load and obviously expects a file to be present.
Example — works with real file and fails with only suffix: irb> Vips::vips_foreign_find_load ‘/home/okeeblow/cover.jpg’
> “VipsForeignLoadJpegFile”
irb> Vips::vips_foreign_find_load ‘cover.jpg’
> nil
Syscalls of successful real-file :vips_foreign_find_load call showing how it works:
- okeeblow@emi#okeeblow
-
strace ruby -e “require ‘vips’; Vips::vips_foreign_find_load ‘/home/okeeblow/cover.jpg’” 2>&1|grep cover.jpg
access(“/home/okeeblow/cover.jpg”, R_OK) = 0 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY) = 5 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY) = 5 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY) = 5 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY) = 5 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY|O_CLOEXEC) = 5 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY|O_CLOEXEC) = 5 lstat(“/home/okeeblow/cover.jpg”, st_size=6242228, …) = 0 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY|O_CLOEXEC) = 5 stat(“/home/okeeblow/cover.jpg”, st_size=6242228, …) = 0 stat(“/home/okeeblow/cover.jpg-journal”, 0x7fffa70f4df0) = -1 ENOENT (No such file or directory) stat(“/home/okeeblow/cover.jpg-wal”, 0x7fffa70f4df0) = -1 ENOENT (No such file or directory) stat(“/home/okeeblow/cover.jpg”, st_size=6242228, …) = 0 openat(AT_FDCWD, “/home/okeeblow/cover.jpg”, O_RDONLY) = 5
…and of a fake suffix-only filename to show how it doesn’t:
- okeeblow@emi#okeeblow
-
strace ruby -e “require ‘vips’; Vips::vips_foreign_find_load ‘fartbutt.jpg’” 2>&1|grep ‘.jpg’
read(5, “.write_to_target target, ".jpg[Q”…, 8192) = 8192 access(“fartbutt.jpg”, R_OK) = -1 ENOENT (No such file or directory)
Versus the corresponding Vips::vips_foreign_find_save which is only based on filename suffix and does not try to look at a file at all, perhaps (read: obviously) because that file wouldn’t exist yet to test until we save it :)
- okeeblow@emi#okeeblow
-
strace ruby -e “require ‘vips’; p Vips::vips_foreign_find_save ‘fartbutt.jpg’” 2>&1|grep -E ‘Save|.jpg’
read(5, “.write_to_target target, ".jpg[Q”…, 8192) = 8192 write(1, “"VipsForeignSaveJpegFile"n”, 26“VipsForeignSaveJpegFile”
For this reason I’m going to write my own shim Loader-finder and use it instead.
VIPS_LOADERS.reduce(Hash[]) { |types,type| types[type] = Cooltrainer::DistorteD::Technology::Vips::( Cooltrainer::DistorteD::Technology::Vips::vips_foreign_find_load_suffix(".#{type.preferred_extension}") ) types }
Instance Method Summary collapse
Instance Method Details
#to_vips_image ⇒ Object
123 124 125 126 127 128 129 130 |
# File 'lib/distorted/modular_technology/vips/load.rb', line 123 def to_vips_image # TODO: Learn more about what VipsAccess means for our use case, # if the default should be changed, and if it should be # a user-controllable attr or not. # https://libvips.github.io/libvips/API/current/VipsImage.html#VipsAccess # https://libvips.github.io/libvips/API/current/How-it-opens-files.md.html @vips_image ||= Vips::Image.new_from_file(path) end |