comparison libinterp/corefcn/__magick_read__.cc @ 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 04ee5e8694cb
children a3db48e66ef8
comparison
equal deleted inserted replaced
28534:548598760b66 28535:09b60b423e6f
749 retval(0) = img; 749 retval(0) = img;
750 750
751 return retval; 751 return retval;
752 } 752 }
753 753
754 // Read file content into blob.
755 static Magick::Blob
756 read_file (const std::string& filename)
757 {
758 octave::sys::file_stat fs (filename);
759
760 if (! fs)
761 error ("no such file, '%s'", filename.c_str ());
762
763 size_t sz = fs.size ();
764
765 std::ifstream file = octave::sys::ifstream (filename.c_str (),
766 std::ios::in | std::ios::binary);
767
768 std::string fstr (sz+1, 0);
769 if (file)
770 {
771 file.read (&fstr[0], sz+1);
772
773 if (! file.eof ())
774 error ("error reading file %s", filename.c_str ());
775 }
776
777 Magick::Blob blob;
778 try
779 {
780 // Convert to blob
781 blob = Magick::Blob (fstr.c_str (), fstr.size ());
782 }
783 catch (Magick::Warning& w)
784 {
785 warning ("Magick++ warning: %s", w.what ());
786 }
787 catch (Magick::Exception& e)
788 {
789 error ("Magick++ exception: %s", e.what ());
790 }
791
792 return blob;
793 }
794
795 // Read a file into vector of image objects. 754 // Read a file into vector of image objects.
796 void static 755 void static
797 read_file (const std::string& filename, std::vector<Magick::Image>& imvec) 756 read_file (const std::string& filename, std::vector<Magick::Image>& imvec)
798 { 757 {
799 // Read file content into blob 758 // FIXME: We need this on Windows because GraphicsMagick uses the ANSI API
800 Magick::Blob blob = read_file (filename); 759 // to open files on disc. In contrast, the API of ImageMagick uses UTF-8
760 // encoded strings. Should we somehow detect which is used on runtime and
761 // pass the file names accordingly? (See also bug #58493.)
762 std::string ascii_fname = octave::sys::get_ASCII_filename (filename, true);
801 763
802 try 764 try
803 { 765 {
804 // Create images from blob 766 Magick::readImages (&imvec, ascii_fname);
805 Magick::readImages (&imvec, blob);
806 } 767 }
807 catch (Magick::Warning& w) 768 catch (Magick::Warning& w)
808 { 769 {
809 warning ("Magick++ warning: %s", w.what ()); 770 warning ("Magick++ warning: %s", w.what ());
810 } 771 }
1732 1693
1733 Magick::Image img; 1694 Magick::Image img;
1734 img.subImage (idx); // start ping from this image (in case of multi-page) 1695 img.subImage (idx); // start ping from this image (in case of multi-page)
1735 img.subRange (1); // ping only one of them 1696 img.subRange (1); // ping only one of them
1736 1697
1737 # if (defined (OCTAVE_HAVE_WINDOWS_FILESYSTEM) && ! defined (OCTAVE_HAVE_POSIX_FILESYSTEM)) 1698 // FIXME: We need this on Windows because GraphicsMagick uses the ANSI API
1738 // Magick++ doesn't handle UTF-8 encoded file names on Windows. 1699 // to open files on disc. In contrast, the API of ImageMagick uses UTF-8
1739 // To prevent an error in this case, read the file content into a blob and 1700 // encoded strings. Should we somehow detect which is used on runtime and
1740 // pass the blob to Magick::Image::ping. This is less efficient than passing 1701 // pass the file names accordingly? (See also bug #58493.)
1741 // the file name to Magick::Image::ping because this requires to read the 1702 std::string ascii_fname = octave::sys::get_ASCII_filename (filename, true);
1742 // entire file from the disk. So, do this on affected file systems only.
1743 Magick::Blob blob = read_file (filename);
1744 1703
1745 try 1704 try
1746 { 1705 {
1747 img.ping (blob); 1706 img.ping (ascii_fname);
1748 } 1707 }
1749 # else
1750 try
1751 {
1752 img.ping (filename);
1753 }
1754 # endif
1755 catch (Magick::Warning& w) 1708 catch (Magick::Warning& w)
1756 { 1709 {
1757 warning ("Magick++ warning: %s", w.what ()); 1710 warning ("Magick++ warning: %s", w.what ());
1758 } 1711 }
1759 catch (Magick::Exception& e) 1712 catch (Magick::Exception& e)