-
-
Notifications
You must be signed in to change notification settings - Fork 386
Add image(buffer, size) API #2961
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should not be commited, also do not configure in source to avoid this. |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| #include "config.h" | ||
|
|
||
| namespace f3d::detail | ||
| { | ||
| const std::string LibVersion = ""; // Version is synchronized with F3D | ||
| const std::string LibVersionFull = ""; // Version is synchronized with F3D | ||
| const std::string LibBuildSystem = "Darwin "; | ||
| const std::string LibBuildDate = ""; | ||
| const std::string LibCompiler = "AppleClang 17.0.0.17000604"; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ | |
| #include <vtkImageReader2Collection.h> | ||
| #include <vtkImageReader2Factory.h> | ||
| #include <vtkJPEGWriter.h> | ||
| #include <vtkMemoryResourceStream.h> | ||
| #include <vtkPNGReader.h> | ||
| #include <vtkPNGWriter.h> | ||
| #include <vtkPointData.h> | ||
|
|
@@ -33,6 +34,7 @@ | |
| #include <sstream> | ||
| #include <string> | ||
| #include <unordered_map> | ||
| #include <iostream> //debug | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. to remove |
||
|
|
||
| namespace fs = std::filesystem; | ||
|
|
||
|
|
@@ -258,6 +260,72 @@ image& image::operator=(image&& img) noexcept | |
| return *this; | ||
| } | ||
|
|
||
| image::image(std::byte* buffer, std::size_t size) | ||
| : Internals(new image::internals()) | ||
| { | ||
| detail::init::initialize(); | ||
|
|
||
| try | ||
| { | ||
| if (buffer == nullptr) | ||
| { | ||
| delete this->Internals; | ||
| throw read_exception("Cannot read image from buffer: Buffer is empty"); | ||
| } | ||
|
|
||
| vtkNew<vtkMemoryResourceStream> stream; | ||
| stream->SetBuffer(buffer, size); | ||
|
|
||
| vtkNew<vtkImageReader2Collection> collection; | ||
| vtkImageReader2Factory::GetRegisteredReaders(collection); | ||
| collection->InitTraversal(); | ||
| vtkImageReader2* reader = collection->GetNextItem(); | ||
|
|
||
| int bestScore = -1; | ||
| vtkImageReader2* bestReader = nullptr; | ||
|
|
||
| while (reader != nullptr) | ||
| { | ||
| int score = reader->CanReadFile(stream); | ||
| if (score > bestScore) | ||
| { | ||
| bestReader = reader; | ||
| bestScore = score; | ||
| } | ||
|
|
||
| reader = collection->GetNextItem(); | ||
| } | ||
|
Comment on lines
+287
to
+297
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is no API to do this for you in VTK ?
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I'm looking at vtkImageReader2 docs, and I don't see an API that does this I'm also looking at the relevant commits in vtk and there is
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think I forgot to add it, ill take a look, but lets of course keep it here for now. |
||
|
|
||
| if (bestScore <= 0) | ||
| { | ||
| delete this->Internals; | ||
| throw read_exception("Cannot read image from buffer"); | ||
| } | ||
|
|
||
| bestReader->SetStream(stream); | ||
| bestReader->Update(); | ||
| this->Internals->Image = bestReader->GetOutput(); | ||
|
|
||
| vtkPNGReader* pngReader = vtkPNGReader::SafeDownCast(bestReader); | ||
| if (pngReader != nullptr) | ||
| { | ||
| this->Internals->ReadPngMetadata(pngReader); | ||
| } | ||
|
|
||
| if (!this->Internals->Image) | ||
| { | ||
| delete this->Internals; | ||
| throw read_exception("Cannot read image from buffer"); | ||
| } | ||
| } | ||
|
|
||
| catch (const fs::filesystem_error& ex) | ||
| { | ||
| delete this->Internals; | ||
| throw read_exception(std::string("Cannot read image from buffer: ") + ex.what()); | ||
| } | ||
| } | ||
|
|
||
| //---------------------------------------------------------------------------- | ||
| std::vector<std::string> image::getSupportedFormats() | ||
| { | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -121,6 +121,11 @@ PYBIND11_MODULE(pyf3d, module) | |||||
| .def(py::init<>()) | ||||||
| .def(py::init<const std::filesystem::path&>()) | ||||||
| .def(py::init<unsigned int, unsigned int, unsigned int, f3d::image::ChannelType>()) | ||||||
| .def(py::init([](py::bytes buffer, size_t size){ | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
Unlike in C which uses a raw pointer, the length can and should be retrieved from the Python buffer object, see I believe this also applies to Java and WebAssembly
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Would there ever be a situation where the user wants to read only part of the buffer?
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think so, in python I'd slice the buffer with From what I can tell this whole extra
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's right, let's drop the size argument, otherwise it will look odd from Python |
||||||
| std::string bufferStr = buffer; | ||||||
| std::byte* byte = reinterpret_cast<std::byte*>(bufferStr.data()); | ||||||
| return f3d::image(byte, size); | ||||||
| })) | ||||||
| .def(py::self == py::self) | ||||||
| .def(py::self != py::self) | ||||||
| .def_static("supported_formats", &f3d::image::getSupportedFormats) | ||||||
|
|
||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
document separately and add doc about the behavior, espacially the exceptions