3232
3333OIIO_PLUGIN_NAMESPACE_BEGIN
3434
35+
36+ class HeifReader final : public heif::Context::Reader {
37+ public:
38+ HeifReader (Filesystem::IOProxy* ioproxy)
39+ : m_ioproxy(ioproxy)
40+ {
41+ m_ioproxy->seek (0 );
42+ }
43+ int64_t get_position () const override { return m_ioproxy->tell (); }
44+ int read (void * data, size_t size) override
45+ {
46+ return m_ioproxy->read (data, size) == size ? 0 : -1 ;
47+ }
48+ int seek (int64_t position) override
49+ {
50+ return m_ioproxy->seek (position) ? 0 : -1 ;
51+ }
52+ heif_reader_grow_status wait_for_file_size (int64_t target_size) override
53+ {
54+ return target_size <= int64_t (m_ioproxy->size ())
55+ ? heif_reader_grow_status_size_reached
56+ : heif_reader_grow_status_size_beyond_eof;
57+ }
58+
59+ private:
60+ Filesystem::IOProxy* m_ioproxy;
61+ };
62+
63+
3564class HeifInput final : public ImageInput {
3665public:
3766 HeifInput () {}
3867 ~HeifInput () override { close (); }
3968 const char * format_name (void ) const override { return " heif" ; }
4069 int supports (string_view feature) const override
4170 {
42- return feature == " exif"
71+ return feature == " exif" || feature == " ioproxy "
4372#if LIBHEIF_HAVE_VERSION(1, 9, 0)
4473 || feature == " cicp"
4574#endif
4675 ;
4776 }
48- bool valid_file (const std::string& filename ) const override ;
77+ bool valid_file (Filesystem::IOProxy* ioproxy ) const override ;
4978 bool open (const std::string& name, ImageSpec& newspec) override ;
5079 bool open (const std::string& name, ImageSpec& newspec,
5180 const ImageSpec& config) override ;
@@ -67,14 +96,14 @@ class HeifInput final : public ImageInput {
6796 bool m_do_associate = false ;
6897 bool m_reorient = true ;
6998 std::unique_ptr<heif::Context> m_ctx;
99+ std::unique_ptr<HeifReader> m_reader;
70100 heif_item_id m_primary_id; // id of primary image
71101 std::vector<heif_item_id> m_item_ids; // ids of all other images
72102 heif::ImageHandle m_ihandle;
73103 heif::Image m_himage;
74104};
75105
76106
77-
78107void
79108oiio_heif_init ()
80109{
@@ -111,10 +140,12 @@ OIIO_PLUGIN_EXPORTS_END
111140
112141
113142bool
114- HeifInput::valid_file (const std::string& filename ) const
143+ HeifInput::valid_file (Filesystem::IOProxy* ioproxy ) const
115144{
145+ if (!ioproxy || ioproxy->mode () != Filesystem::IOProxy::Mode::Read)
146+ return false ;
116147 uint8_t magic[12 ];
117- if (Filesystem::read_bytes (filename, magic, sizeof (magic)) != sizeof (magic))
148+ if (ioproxy-> pread ( magic, sizeof (magic), 0 ) != sizeof (magic))
118149 return false ;
119150 heif_filetype_result filetype_check = heif_check_filetype (magic,
120151 sizeof (magic));
@@ -141,7 +172,12 @@ HeifInput::open(const std::string& name, ImageSpec& newspec,
141172 m_filename = name;
142173 m_subimage = -1 ;
143174
175+ ioproxy_retrieve_from_config (config);
176+ if (!ioproxy_use_or_open (name))
177+ return false ;
178+
144179 m_ctx.reset (new heif::Context);
180+ m_reader.reset (new HeifReader (ioproxy ()));
145181 m_himage = heif::Image ();
146182 m_ihandle = heif::ImageHandle ();
147183
@@ -150,8 +186,7 @@ HeifInput::open(const std::string& name, ImageSpec& newspec,
150186 m_reorient = config.get_int_attribute (" oiio:reorient" , 1 );
151187
152188 try {
153- m_ctx->read_from_file (name);
154- // FIXME: should someday be read_from_reader to give full flexibility
189+ m_ctx->read_from_reader (*m_reader);
155190
156191 m_item_ids = m_ctx->get_list_of_top_level_image_IDs ();
157192 m_primary_id = m_ctx->get_primary_image_ID ();
@@ -187,6 +222,7 @@ HeifInput::close()
187222 m_himage = heif::Image ();
188223 m_ihandle = heif::ImageHandle ();
189224 m_ctx.reset ();
225+ m_reader.reset ();
190226 m_subimage = -1 ;
191227 m_num_subimages = 0 ;
192228 m_associated_alpha = true ;
0 commit comments