Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[FEATURE REQUEST] IOProxy read from memory without valid file #4547

Open
EmilDohne opened this issue Dec 1, 2024 · 2 comments
Open

[FEATURE REQUEST] IOProxy read from memory without valid file #4547

EmilDohne opened this issue Dec 1, 2024 · 2 comments

Comments

@EmilDohne
Copy link
Contributor

Is your feature request related to a problem? Please describe.
I'm currently implementing smart objects into my Photoshop reader/writer API and those (sometimes) store the raw file bytes directly in memory rather than having a file on disk it references. From what I can tell though OpenImageIO requires a valid filepath to read from an IOProxy. I've thrown together a hacky solution that works but it requires a temporary file to be created in order to actually read the file.

If there is a way to do this natively feel free to point me to it and I'll close this ticket :)

namespace _Impl
{
  struct TempImageFile
  {
  
    TempImageFile(std::filesystem::path file_path)
    {
      m_FilePath = file_path;
      std::unique_ptr<OIIO::ImageOutput> out = OIIO::ImageOutput::create(file_path);
      if (!out)
	      return;  // error
      
      std::vector<uint8_t> pixels(1);
      OIIO::ImageSpec spec(1, 1, 1, OIIO::TypeDesc::UINT8);
      out->open(file_path, spec);
      out->write_image(OIIO::TypeDesc::UINT8, pixels.data());
      out->close();
    }
    
    ~TempImageFile()
    {
      std::filesystem::remove(m_FilePath);
    }
  
  private:
	  std::filesystem::path m_FilePath;
  };
}

int main()
{
  std::filesystem::path file_path; // ....
  std::vector<std::byte> raw_data; // ...

  _Impl::TempImageFile tmp_file(file_path);
  auto _in = OIIO::ImageInput::create(file_path);
  if (_in && static_cast<bool>(_in->supports("ioproxy")))
  {
	  OIIO::Filesystem::IOMemReader memreader(raw_data.data(), raw_data.size());
	  auto oiio_in = OIIO::ImageInput::open(file_path.string(), nullptr, &memreader);
	  // keep processing.
  }
}

Describe the solution you'd like
A way to create an imageinput purely from memory.

Describe alternatives you've considered
I looked into using an OIIO::ImageBuf for this purpose but it looked like it only supported being backed from pixel buffers? Unsure about this.

@jessey-git
Copy link
Contributor

The ceremonial API dance I do for this case is the following:

  // During create(), provide _just_ the format extension (psd here) that OIIO will recognize
  // It will perform a stat/existence check on the "file" but no further filesystem access should occur.
  unique_ptr<ImageInput> in = ImageInput::create("psd");
  if (!in) {
    return nullptr;
  }

  // Set the ioproxy and use empty "" path during open()
  in->set_ioproxy(&mem_reader);
  bool ok = in->open("", newspec, config);
  ...

@EmilDohne
Copy link
Contributor Author

Ah thats smart! I wasnt aware you could do this, when I tried passing the filename or e.g. .exr in would be nullptr but I'll try what you suggested!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants