changeset 28535:09b60b423e6f

Re-do fix for reading images with non-ASCII filenames on Windows (bug #58493). * __magick_read__.cc (read_file): Remove function overload that reads a blob, which can be very memory inefficient. Try using ASCII filename to work around issue with non-ASCII characters in file names on Windows instead of using inefficient blob. (F__magick_ping__): Try using ASCII filename to work around issue with non-ASCII characters in file names on Windows instead of using inefficient blob.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 04 Jul 2020 15:43:59 +0200
parents 548598760b66
children a32409899ad6
files libinterp/corefcn/__magick_read__.cc
diffstat 1 files changed, 12 insertions(+), 59 deletions(-) [+]
line wrap: on
line diff
--- a/libinterp/corefcn/__magick_read__.cc	Sat Jul 04 12:14:21 2020 +0200
+++ b/libinterp/corefcn/__magick_read__.cc	Sat Jul 04 15:43:59 2020 +0200
@@ -751,58 +751,19 @@
   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);
+  // FIXME: We need this on Windows because GraphicsMagick uses the ANSI API
+  // to open files on disc.  In contrast, the API of ImageMagick uses UTF-8
+  // encoded strings.  Should we somehow detect which is used on runtime and
+  // pass the file names accordingly? (See also bug #58493.)
+  std::string ascii_fname = octave::sys::get_ASCII_filename (filename, true);
 
   try
     {
-      // Create images from blob
-      Magick::readImages (&imvec, blob);
+      Magick::readImages (&imvec, ascii_fname);
     }
   catch (Magick::Warning& w)
     {
@@ -1734,24 +1695,16 @@
   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);
+  // FIXME: We need this on Windows because GraphicsMagick uses the ANSI API
+  // to open files on disc.  In contrast, the API of ImageMagick uses UTF-8
+  // encoded strings.  Should we somehow detect which is used on runtime and
+  // pass the file names accordingly? (See also bug #58493.)
+  std::string ascii_fname = octave::sys::get_ASCII_filename (filename, true);
 
   try
     {
-      img.ping (blob);
+      img.ping (ascii_fname);
     }
-#  else
-  try
-    {
-      img.ping (filename);
-    }
-#  endif
   catch (Magick::Warning& w)
     {
       warning ("Magick++ warning: %s", w.what ());