Skip to content

Python internals: support int8[] metadata and ICCProfile, refactor #3556

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

Merged
merged 2 commits into from
Sep 19, 2022

Conversation

lgritz
Copy link
Collaborator

@lgritz lgritz commented Sep 17, 2022

This patch allows ParamValue, ParamValueList, and ImageSpec to support attribute/getattribute of metadata consisting of uint8[] arrays, which is how we store certain binary blobs or raw byte arrays. We translate this to Python as a numpy array of type uint8 (dtype='B').

This fixes a limitation where it was not possible to directly retrieve or set the "ICCProfile" metadata (which is stored as a uint8 array) from the Python APIs, as you could easily do from the C++ APIs.

In the process, I found similar bits of code in several different places, in various states of incompleteness. I refactored to make a single make_pyobject() utility and then used that call in place of several other redundant pieces of functionality.

This patch allows ParamValue, ParamValueList, and ImageSpec to support
attribute/getattribute of metadata consisting of uint8[] arrays, which
is how we store certain binary blobs or raw byte arrays.  We translate
this to Python as a numpy array of type uint8 (dtype='B').

This fixes a limitation where it was not possible to directly retrieve
or set the "ICCProfile" metadata (which is stored as a uint8 array)
from the Python APIs, as you could easily do from the C++ APIs.

In the process, I found similar bits of code in several different
places, in various states of incompleteness. I refactored to make a
single make_pyobject() utility and then used that call in place of
several other redundant pieces of functionality.
@lgritz
Copy link
Collaborator Author

lgritz commented Sep 17, 2022

@christopherdavies this is the fix necessary to allow get/set of ICCProfile metadata from python.

// Have to make a copy of the data, because make_numpy_array will
// take possession of it.
uint8_t* ucdata(new uint8_t[type.arraylen * nvalues]);
memcpy(ucdata, data, type.arraylen * nvalues);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe std::memcpy? Recent C++ standards are starting to diverge from C, e.g. functions from got constexpr specifiers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But these are dynamic memory and so can't possibly use a constexpr version here anyway.

I dunno, is it considered bad style to use the "non-std::" way to call a traditional C function that's also in C++? I've always just called the C function when they are identical.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it is considered bad style. Prior to C++23 these headers were actually deprecated. C++23 clarifies the status of the headers as "For compatibility with the C standard library" and also says that "Source files that are not intended to also be valid ISO C should not use any of the C headers."

If interesting, this paper contains rationale.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Interesting!

Ok, I will change this. I'm sure we have this kind of thing scattered all over the place. We'll clean up a bit here and there as we go.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated, thanks for the suggestion and the education.

@lgritz lgritz merged commit 80374c0 into AcademySoftwareFoundation:master Sep 19, 2022
@lgritz lgritz deleted the lg-pyuint8array branch September 20, 2022 01:44
lgritz added a commit to lgritz/OpenImageIO that referenced this pull request Sep 21, 2022
…cademySoftwareFoundation#3556)

This patch allows ParamValue, ParamValueList, and ImageSpec to support
attribute/getattribute of metadata consisting of uint8[] arrays, which
is how we store certain binary blobs or raw byte arrays.  We translate
this to Python as a numpy array of type uint8 (dtype='B').

This fixes a limitation where it was not possible to directly retrieve
or set the "ICCProfile" metadata (which is stored as a uint8 array)
from the Python APIs, as you could easily do from the C++ APIs.

In the process, I found similar bits of code in several different
places, in various states of incompleteness. I refactored to make a
single make_pyobject() utility and then used that call in place of
several other redundant pieces of functionality.
lgritz added a commit to lgritz/OpenImageIO that referenced this pull request Oct 6, 2022
…cademySoftwareFoundation#3556)

This patch allows ParamValue, ParamValueList, and ImageSpec to support
attribute/getattribute of metadata consisting of uint8[] arrays, which
is how we store certain binary blobs or raw byte arrays.  We translate
this to Python as a numpy array of type uint8 (dtype='B').

This fixes a limitation where it was not possible to directly retrieve
or set the "ICCProfile" metadata (which is stored as a uint8 array)
from the Python APIs, as you could easily do from the C++ APIs.

In the process, I found similar bits of code in several different
places, in various states of incompleteness. I refactored to make a
single make_pyobject() utility and then used that call in place of
several other redundant pieces of functionality.
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

Successfully merging this pull request may close these issues.

2 participants