Mercurial > octave
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) |