Mercurial > octave
changeset 28473:04ee5e8694cb
__magick_read__.cc: Correctly read images from non-ASCII paths on Windows (bug #58493).
* libinterp/corefcn/__magick_read__.cc (read_file): Add new function overload to
read the image file content into a blob.
(F__magick_ping__): On Windows file systems, read image file into blob.
author | Markus Mützel <markus.muetzel@gmx.de> |
---|---|
date | Sun, 14 Jun 2020 13:02:59 +0200 |
parents | a40e3c3e17fa |
children | 4539c931734a |
files | libinterp/corefcn/__magick_read__.cc |
diffstat | 1 files changed, 62 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/libinterp/corefcn/__magick_read__.cc Sun Jun 14 12:17:10 2020 +0200 +++ b/libinterp/corefcn/__magick_read__.cc Sun Jun 14 13:02:59 2020 +0200 @@ -28,6 +28,7 @@ #endif #include "file-stat.h" +#include "lo-sysdep.h" #include "oct-env.h" #include "oct-time.h" @@ -750,13 +751,58 @@ return retval; } +// Read file content into blob. +static Magick::Blob +read_file (const std::string& filename) +{ + octave::sys::file_stat fs (filename); + + if (! fs) + error ("no such file, '%s'", filename.c_str ()); + + size_t sz = fs.size (); + + std::ifstream file = octave::sys::ifstream (filename.c_str (), + std::ios::in | std::ios::binary); + + std::string fstr (sz+1, 0); + if (file) + { + file.read (&fstr[0], sz+1); + + if (! file.eof ()) + error ("error reading file %s", filename.c_str ()); + } + + Magick::Blob blob; + try + { + // Convert to blob + blob = Magick::Blob (fstr.c_str (), fstr.size ()); + } + catch (Magick::Warning& w) + { + warning ("Magick++ warning: %s", w.what ()); + } + catch (Magick::Exception& e) + { + error ("Magick++ exception: %s", e.what ()); + } + + return blob; +} + // Read a file into vector of image objects. void static read_file (const std::string& filename, std::vector<Magick::Image>& imvec) { + // Read file content into blob + Magick::Blob blob = read_file (filename); + try { - Magick::readImages (&imvec, filename); + // Create images from blob + Magick::readImages (&imvec, blob); } catch (Magick::Warning& w) { @@ -1687,10 +1733,25 @@ Magick::Image img; img.subImage (idx); // start ping from this image (in case of multi-page) img.subRange (1); // ping only one of them + +# if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)) + // Magick++ doesn't handle UTF-8 encoded file names on Windows. + // To prevent an error in this case, read the file content into a blob and + // pass the blob to Magick::Image::ping. This is less efficient than passing + // the file name to Magick::Image::ping because this requires to read the + // entire file from the disk. So, do this on affected file systems only. + Magick::Blob blob = read_file (filename); + + try + { + img.ping (blob); + } +# else try { img.ping (filename); } +# endif catch (Magick::Warning& w) { warning ("Magick++ warning: %s", w.what ());