From 03eca9df5082e97f3b157ce7d1d86ef76016e52b Mon Sep 17 00:00:00 2001 From: Jonathan Scruggs Date: Thu, 28 Sep 2017 16:00:16 +0100 Subject: [PATCH 3/3] oiio/RB-1.6: Repair breaks after boost python 1.65 changes (#1753) Alas, the new Boost 1.65 moves some boost python material from one namespace to another in a way that breaks compatibility related to support for numpy arrays. This breaks the build, including all of our MacOS-based TravisCI tests, which of course pick up the latest Boost via Homebrew. Backported from: https://github.com/OpenImageIO/oiio/commit/57f294df7430a860c60612c28235730fd429ea0d --- src/python/py_imagebuf.cpp | 22 +++++++++++++++------- src/python/py_imageoutput.cpp | 10 +++++----- src/python/py_oiio.cpp | 22 +++++++++++++++++++--- src/python/py_oiio.h | 23 +++++++---------------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/python/py_imagebuf.cpp b/src/python/py_imagebuf.cpp index 28a8c537..fa271fe2 100644 --- a/src/python/py_imagebuf.cpp +++ b/src/python/py_imagebuf.cpp @@ -329,7 +329,7 @@ BOOST_PYTHON_FUNCTION_OVERLOADS(ImageBuf_get_pixels_bt_overloads, bool -ImageBuf_set_pixels_tuple (ImageBuf &buf, ROI roi, tuple data) +ImageBuf_set_pixels_tuple (ImageBuf &buf, ROI roi, const tuple& data) { if (! roi.defined()) roi = buf.roi(); @@ -347,8 +347,13 @@ ImageBuf_set_pixels_tuple (ImageBuf &buf, ROI roi, tuple data) bool -ImageBuf_set_pixels_array (ImageBuf &buf, ROI roi, numeric::array data) +ImageBuf_set_pixels_array (ImageBuf &buf, ROI roi, const object& data) { + // If it's a tuple, we handle that with the other function + extract tup (data); + if (tup.check()) + return ImageBuf_set_pixels_tuple (buf, roi, tup()); + if (! roi.defined()) roi = buf.roi(); roi.chend = std::min (roi.chend, buf.nchannels()+1); @@ -356,13 +361,16 @@ ImageBuf_set_pixels_array (ImageBuf &buf, ROI roi, numeric::array data) if (size == 0) return true; // done - TypeDesc type; - size_t pylen = 0; - const void *addr = python_array_address (data, type, pylen); - if (!addr || size > pylen) + TypeDesc elementtype; + size_t numelements; + const void* addr = python_array_address (data, elementtype, numelements); + if (!addr || size > numelements) return false; // Not enough data to fill our ROI - buf.set_pixels (roi, type, addr); + std::vector vals (numelements); + convert_types (elementtype, addr, TypeDesc::TypeFloat, vals.data(), + int(numelements)); + buf.set_pixels (roi, TypeDesc::TypeFloat, &vals[0]); return true; } diff --git a/src/python/py_imageoutput.cpp b/src/python/py_imageoutput.cpp index 1c2e5f3c..2203aac4 100644 --- a/src/python/py_imageoutput.cpp +++ b/src/python/py_imageoutput.cpp @@ -112,7 +112,7 @@ ImageOutputWrap::make_read_buffer (object &buffer, imagesize_t size) bool -ImageOutputWrap::write_scanline_array (int y, int z, numeric::array &buffer) +ImageOutputWrap::write_scanline_array (int y, int z, object &buffer) { TypeDesc format; size_t numelements = 0; @@ -154,7 +154,7 @@ ImageOutputWrap::write_scanline_bt (int y, int z, TypeDesc::BASETYPE format, bool ImageOutputWrap::write_scanlines_array (int ybegin, int yend, int z, - numeric::array &buffer) + object &buffer) { TypeDesc format; size_t numelements = 0; @@ -199,7 +199,7 @@ ImageOutputWrap::write_scanlines_bt (int ybegin, int yend, int z, bool ImageOutputWrap::write_tile_array (int x, int y, int z, - numeric::array &buffer) + object &buffer) { TypeDesc format; size_t numelements = 0; @@ -243,7 +243,7 @@ ImageOutputWrap::write_tile_bt (int x, int y, int z, TypeDesc::BASETYPE format, bool ImageOutputWrap::write_tiles_array (int xbegin, int xend, int ybegin, int yend, int zbegin, int zend, - numeric::array &buffer) + object &buffer) { TypeDesc format; size_t numelements = 0; @@ -290,7 +290,7 @@ ImageOutputWrap::write_tiles_bt (int xbegin, int xend, int ybegin, int yend, bool -ImageOutputWrap::write_image_array (numeric::array &buffer) +ImageOutputWrap::write_image_array (object &buffer) { TypeDesc format; size_t numelements = 0; diff --git a/src/python/py_oiio.cpp b/src/python/py_oiio.cpp index bc10803c..5e965089 100644 --- a/src/python/py_oiio.cpp +++ b/src/python/py_oiio.cpp @@ -78,6 +78,13 @@ typedesc_from_python_array_code (char code) } +std::string +object_classname (const object& obj) +{ + return extract(obj.attr("__class__").attr("__name__")); +} + + object C_array_to_Python_array (const char *data, TypeDesc type, size_t size) @@ -313,11 +320,18 @@ oiio_get_string_attribute_d (const char *name, const char *defaultval) const void * -python_array_address (numeric::array &data, TypeDesc &elementtype, +python_array_address (const object &data, TypeDesc &elementtype, size_t &numelements) { // Figure out the type of the array - object tcobj = data.attr("typecode"); + object tcobj; + try { + tcobj = data.attr("typecode"); + } catch(...) { + return NULL; + } + if (! tcobj) + return NULL; extract tce (tcobj); char typecode = tce.check() ? (char)tce : 0; elementtype = typedesc_from_python_array_code (typecode); @@ -395,7 +409,9 @@ OIIO_DECLARE_PYMODULE(OIIO_PYMODULE_NAME) { scope().attr("VERSION_PATCH") = OIIO_VERSION_PATCH; scope().attr("INTRO_STRING") = OIIO_INTRO_STRING; - boost::python::numeric::array::set_module_and_type("array", "array"); + #if BOOST_VERSION < 106500 + boost::python::numeric::array::set_module_and_type("array", "array"); + #endif } } // namespace PyOpenImageIO diff --git a/src/python/py_oiio.h b/src/python/py_oiio.h index febe2f9e..9fc04d06 100644 --- a/src/python/py_oiio.h +++ b/src/python/py_oiio.h @@ -68,12 +68,13 @@ bool PyProgressCallback(void*, float); object C_array_to_Python_array (const char *data, TypeDesc type, size_t size); const char * python_array_code (TypeDesc format); TypeDesc typedesc_from_python_array_code (char code); +std::string object_classname (const object& obj); // Given python array 'data', figure out its element type and number of // elements, and return the memory address of its contents. Return NULL as // the address for an error. -const void * python_array_address (numeric::array &data, TypeDesc &elementtype, +const void * python_array_address (const object &data, TypeDesc &elementtype, size_t &numelements); @@ -105,16 +106,6 @@ void py_to_stdvector (std::vector &vals, const tuple &tup) -// Suck up a tuple of presumed T values into a vector -template -void py_to_stdvector (std::vector &vals, const numeric::array &arr) -{ - for (int i = 0, e = len(arr); i < e; ++i) - vals.push_back (extract(arr[i])); -} - - - // Convert an array of T values into either tuple. FUNC is a conversion // function such as PyInt_FromLong, PyFloat_FromDouble, or // PyString_FromString. @@ -312,12 +303,12 @@ public: stride_t xstride=AutoStride); bool write_scanline_bt (int, int, TypeDesc::BASETYPE, boost::python::object&, stride_t xstride=AutoStride); - bool write_scanline_array (int, int, numeric::array&); + bool write_scanline_array (int, int, object&); bool write_scanlines (int, int, int, TypeDesc, boost::python::object&, stride_t xstride=AutoStride); bool write_scanlines_bt (int, int, int, TypeDesc::BASETYPE, boost::python::object&, stride_t xstride=AutoStride); - bool write_scanlines_array (int, int, int, numeric::array&); + bool write_scanlines_array (int, int, int, object&); bool write_tile (int, int, int, TypeDesc, boost::python::object&, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); @@ -325,7 +316,7 @@ public: boost::python::object&, stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); - bool write_tile_array (int, int, int, numeric::array&); + bool write_tile_array (int, int, int, object&); bool write_tiles (int, int, int, int, int, int, TypeDesc, boost::python::object&, stride_t xstride=AutoStride, stride_t ystride=AutoStride, @@ -335,7 +326,7 @@ public: stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); - bool write_tiles_array (int, int, int, int, int, int, numeric::array&); + bool write_tiles_array (int, int, int, int, int, int, object&); bool write_image (TypeDesc format, object &buffer, stride_t xstride=AutoStride, stride_t ystride=AutoStride, @@ -344,7 +335,7 @@ public: stride_t xstride=AutoStride, stride_t ystride=AutoStride, stride_t zstride=AutoStride); - bool write_image_array (numeric::array &buffer); + bool write_image_array (object &buffer); bool write_deep_scanlines (int ybegin, int yend, int z, const DeepData &deepdata); bool write_deep_tiles (int xbegin, int xend, int ybegin, int yend, -- 2.14.2