Compare commits

...
7 Commits
Author SHA1 Message Date
Larry Gritz e181aadac5 build: Test ABI compliance (#3983, #3988)
This patch adds a new test to the CI matrix: verifying that we do not
break the ABI during releases.

Basically, in addition to building the current checkout, it also builds
a checkout of the designated "ABI standard" (generally, the first
non-beta release of a major version), then generates ABI dumps of both
versions and runs the ABI compliance checker using the tools from
https://github.com/lvc

Making two builds sounds expensive, but both builds are rigged to be
minimal, since only the main two libraries are needed for ABI checks (we
can turn off the binary tools, unit tests, python bindings, and support
for many formats), and of course the test suite need not run. So
actually, it's less expensive than most of the test matrix entries, and
it helps ensure that we don't accidentally break ABI when we don't mean
to.

I'm not sure how many false positives we'll have. We might need to
adjust the methodology slightly as we gain experience with this.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
2023-09-16 21:58:34 -07:00
Jesse Yurkovich 082b360122 fix(png): Write out proper tiff header version in png EXIF blobs (#3984)
When writing out EXIF headers in PNG files, the `tiff_version` field
wasn't handling endianness properly.

This lead to some tools like `exiv2` refusing to process the file at
all[1]

[1] https://github.com/Exiv2/exiv2/issues/2745

---------

Signed-off-by: Jesse Yurkovich <jesse.y@gmail.com>
2023-09-16 16:32:48 -07:00
Larry Gritz 8d37a81f83 feat(python): Implement ImageCache.get_imagespec() (#3982)
This C++ method of ImageCache was never exposed previously.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
2023-09-16 16:31:39 -07:00
Larry Gritz 49459df4b8 docs: Prototype docs examples doubling as tests (#3977)
New theory of code examples in the docs: every one should live in the
testsuite somewhere, and merely be included by reference in the docs.
This ensures that every code example works, stays current with the
evolution of the APIs, and never breaks. It also beefs up our test cases
for more thorough code overage in the testsuite.

I've done this with just two examples here, but hopefully it serves as
an example for others to -- bit by bit -- convert all the other code
examples in the docs into tests in a similar manner.

Doing this for any one example is a perfect "good first issue," since
it's bite sized and can easily be done in a day, it doesn't require any
knowledge of deep OIIO internals, and in the process it also teaches you
something about how both the docs and the testsuite are set up.

A few notes:

* I'm structuring it (for now?) as two testsuite entry for each chapter
of the documentation (one for C++ and one for Python).

* Note how I can have many code snippets in a test source file, and use
the Sphinx `:start-after:` and `:end-before:` modifiers of
`literalinclude` to clip particular subsections of the file, using
special comment markers in the code.

While I was there, I also fixed some typos I noticed in the text of the
chapter, oops.

---------

Signed-off-by: Larry Gritz <lg@larrygritz.com>
2023-09-16 16:31:24 -07:00
Larry Gritz a0162813fd fix(ustring): fix Cuda warnings (#3978)
To my eyes, these two constructors look like they should be treated as
doing exactly the same thing:

    MyType()
        : mymember(...)
    { }

and

    MyType()
    {
       mymember = ...;
    }

But nvcc in Cuda mode says no, if the constructor is constexpr, the
former is okey dokey, but latter gives a warning. Fine, Cuda, whatver
you say.

Signed-off-by: Larry Gritz <lg@larrygritz.com>
2023-09-08 13:41:02 -07:00
Jesse Yurkovich 7c4634ce64 Remove unnecessary headers from strutil.cpp causing build trouble (#3976)
While testing out the 2.5 beta for use in Blender, I hit an odd build
error[1] apparently related to include order. Apparently `windows.h`
should be included before `shellapi.h`[2]. Swapping the order does fix
things, however, it turns out neither is used in this particular file so
just remove them both. Unsure why we didn't see it until now.

[1]
```
20>[9/146] Building CXX object src\libutil\CMakeFiles\OpenImageIO_Util.dir\strutil.cpp.obj
20>FAILED: src/libutil/CMakeFiles/OpenImageIO_Util.dir/strutil.cpp.obj

20>cl : Command line warning D9002: ignoring unknown option '/arch:sse2'
20>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\shellapi.h(68): error C2146: syntax error: missing ';' before identifier 'DECLSPEC_IMPORT'
20>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\shellapi.h(79): error C2065: 'HDROP': undeclared identifier
20>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\shellapi.h(82): error C2086: 'int EXTERN_C': redefinition
20>C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\um\shellapi.h(68): note: see declaration of 'EXTERN_C'
```
[2] 

https://stackoverflow.com/questions/2953704/vs2010-lots-of-errors-when-including-standard-libraries

https://social.msdn.microsoft.com/forums/vstudio/en-us/ed93ae48-969a-4280-8fd5-ef57a332022b/problems-with-shellexecute-and-shellapih?forum=vcgeneral

## Checklist:

<!-- Put an 'x' in the boxes as you complete the checklist items -->

- [X] I have read the [contribution
guidelines](https://github.com/OpenImageIO/oiio/blob/master/CONTRIBUTING.md).
- [ ] I have updated the documentation, if applicable.
- [ ] I have ensured that the change is tested somewhere in the
testsuite
  (adding new test cases if necessary).
- [ ] If I added or modified a C++ API call, I have also amended the
corresponding Python bindings (and if altering ImageBufAlgo functions,
also
  exposed the new functionality as oiiotool options).
- [X] My code follows the prevailing code style of this project. If I
haven't
already run clang-format before submitting, I definitely will look at
the CI
test that runs clang-format and fix anything that it highlights as being
  nonconforming.

Signed-off-by: Jesse Yurkovich <jesse.y@gmail.com>
2023-09-08 12:42:31 -07:00
Larry Gritz 1383491c9b Stage for 2.5.3.0-beta1
Signed-off-by: Larry Gritz <lg@larrygritz.com>
2023-09-04 19:58:10 -07:00
31 changed files with 419 additions and 107 deletions
+40 -1
View File
@@ -138,7 +138,7 @@ jobs:
OIIO_CMAKE_FLAGS="-DSANITIZE=address,undefined -DUSE_PYTHON=0"
CMAKE_BUILD_TYPE=Debug
CTEST_TEST_TIMEOUT=1200
CTEST_EXCLUSIONS="broken|cmake-consumer|png-damaged"
CTEST_EXCLUSIONS="broken|png-damaged"
- desc: gcc11/C++17 py3.10 boost1.80 exr3.1 ocio2.2
nametag: linux-vfx2023
os: ubuntu-latest
@@ -186,6 +186,26 @@ jobs:
setenvs: export BUILDTARGET=clang-format
OIIO_CMAKE_FLAGS=-DUSE_PYTHON=0
# Test ABI stability. `abi_check` is the version or commit that we
# believe is the current standard against which we don't want to
# break the ABI. Basically, we will build that version as well as
# the current one, and compare the resulting libraries.
- desc: abi check
nametag: linux-vfx2023
os: ubuntu-latest
container: aswftesting/ci-osl:2023-clang15
vfxyear: 2023
cxx_std: 17
python_ver: "3.10"
simd: "avx2,f16c"
fmt_ver: 10.1.1
pybind11_ver: v2.10.0
skip_tests: 1
abi_check: v2.5.3.0-beta1
setenvs: export OIIO_CMAKE_FLAGS="-DOIIO_BUILD_TOOLS=0 -DOIIO_BUILD_TESTS=0 -DUSE_PYTHON=0"
USE_OPENCV=0 USE_FFMPEG=0 USE_PYTHON=0
CMAKE_BUILD_TYPE=RelWithDebInfo
runs-on: ${{ matrix.os }}
container:
image: ${{ matrix.container }}
@@ -198,6 +218,7 @@ jobs:
OPENEXR_VERSION: ${{matrix.openexr_ver}}
PYBIND11_VERSION: ${{matrix.pybind11_ver}}
PYTHON_VERSION: ${{matrix.python_ver}}
ABI_CHECK: ${{matrix.abi_check}}
steps:
# We would like to use harden-runner, but it flags too many false
# positives, every time we download a dependency. We should use it only
@@ -230,12 +251,30 @@ jobs:
- name: Testsuite
if: matrix.skip_tests != '1'
run: src/build-scripts/ci-test.bash
- name: Check out ABI standard
if: matrix.abi_check != ''
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
with:
ref: ${{matrix.abi_check}}
path: abi_standard
- name: Build ABI standard
if: matrix.abi_check != ''
run: |
mkdir -p abi_standard/build
pushd abi_standard
src/build-scripts/ci-build.bash
popd
- name: Check ABI
if: matrix.abi_check != ''
run: |
src/build-scripts/ci-abicheck.bash ./build abi_standard/build libOpenImageIO libOpenImageIO_Util
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
if: failure()
with:
name: oiio-${{github.job}}-${{matrix.nametag}}
path: |
build/cmake-save
build/compat_reports
build/testsuite/*/*.*
!build/testsuite/oiio-images
!build/testsuite/openexr-images
+3 -3
View File
@@ -19,12 +19,12 @@ project (OpenImageIO VERSION ${OpenImageIO_VERSION}
set (PROJ_NAME OIIO) # short name, caps
string (TOLOWER ${PROJ_NAME} PROJ_NAME_LOWER) # short name lower case
string (TOUPPER ${PROJ_NAME} PROJ_NAME_UPPER) # short name upper case
set (PROJECT_VERSION_RELEASE_TYPE "dev" CACHE STRING
set (PROJECT_VERSION_RELEASE_TYPE "beta" CACHE STRING
"Build type, for example: dev, beta2, RC1 (empty string for normal release)")
set (${PROJECT_NAME}_VERSION_RELEASE_TYPE ${PROJECT_VERSION_RELEASE_TYPE})
set (PROJECT_AUTHORS "Contributors to the OpenImageIO project")
option (${PROJECT_NAME}_SUPPORTED_RELEASE
"Set ON for supported release branch, OFF for master" OFF)
"Set ON for supported release branch, OFF for master" ON)
if (${PROJECT_NAME}_SUPPORTED_RELEASE)
set (${PROJECT_NAME}_DEV_RELEASE OFF)
else ()
@@ -305,7 +305,7 @@ install (EXPORT OIIO_EXPORTED_TARGETS
NAMESPACE ${PROJECT_NAME}::)
if (PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
if (PROJECT_IS_TOP_LEVEL AND BUILD_TESTING AND ${PROJ_NAME}_BUILD_TESTS)
oiio_setup_test_data()
oiio_add_all_tests()
endif ()
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env bash
# Utility script to download and build abi checking tools
#
# Copyright Contributors to the OpenImageIO project.
# SPDX-License-Identifier: Apache-2.0
# https://github.com/OpenImageIO/oiio
# Exit the whole script if any command fails.
set -ex
# Where to install the final results
: ${LOCAL_DEPS_DIR:=${PWD}/ext}
: ${ABITOOLS_INSTALL_DIR:=${LOCAL_DEPS_DIR}/dist}
mkdir -p ${LOCAL_DEPS_DIR}
pushd ${LOCAL_DEPS_DIR}
git clone https://github.com/lvc/vtable-dumper
pushd vtable-dumper ; make install prefix=${ABITOOLS_INSTALL_DIR} ; popd
git clone https://github.com/lvc/abi-dumper
pushd abi-dumper ; make install prefix=${ABITOOLS_INSTALL_DIR} ; popd
git clone https://github.com/lvc/abi-compliance-checker
pushd abi-compliance-checker ; make install prefix=${ABITOOLS_INSTALL_DIR} ; popd
popd
# ls -R ${LOCAL_DEPS_DIR}
export PATH=${PATH}:${ABITOOLS_INSTALL_DIR}/bin
+54
View File
@@ -0,0 +1,54 @@
#!/usr/bin/env bash
# Copyright Contributors to the OpenImageIO project.
# SPDX-License-Identifier: Apache-2.0
# https://github.com/OpenImageIO/oiio
# Important: set -ex causes this whole script to terminate with error if
# any command in it fails. This is crucial for CI tests.
set -e
# Arguments to this script are:
# BUILDDIR_NEW BUILDDIR_OLD LIBRARIES...
BUILDDIR_NEW=$1
shift
BUILDDIR_OLD=$1
shift
LIBS=$*
#
# First, create ABI dumps from both builds
#
ABI_ARGS="-bin-only -skip-cxx -public-headers $PWD/dist/include/OpenImageIO "
echo "ABI_CHECK: PWD=${PWD} "
ls -l $BUILDDIR_NEW
ls -l $BUILDDIR_OLD
for dir in $BUILDDIR_NEW $BUILDDIR_OLD ; do
for lib in $LIBS ; do
abi-dumper $ABI_ARGS ${dir}/lib/${lib}.so -o ${dir}/abi-${lib}.dump
done
done
echo "Saved ABI dumps"
#
# Run the ABI compliance checker, saving the outputs to files
#
for lib in $LIBS ; do
abi-compliance-checker -l $lib -old $BUILDDIR_OLD/abi-$lib.dump -new $BUILDDIR_NEW/abi-$lib.dump | tee ${lib}-abi-results.txt || true
echo -e "\x1b[33;1m"
echo -e "$lib"
fgrep "Binary compatibility:" ${lib}-abi-results.txt
echo -e "\x1b[33;0m"
done
#
# If the "Binary compatibility" summary results say anything other than 100%,
# we fail!
#
for lib in $LIBS ; do
if [[ `fgrep "Binary compatibility:" ${lib}-abi-results.txt | grep -v 100\%` != "" ]] ; then
cp -r compat_reports ${BUILDDIR_NEW}/compat_reports
exit 1
fi
done
+10 -2
View File
@@ -18,8 +18,12 @@ if [[ "$ASWF_ORG" != "" ]] ; then
#ls /etc/yum.repos.d
sudo yum install -y giflib giflib-devel && true
sudo yum install -y opencv opencv-devel && true
sudo yum install -y ffmpeg ffmpeg-devel && true
if [[ "${USE_OPENCV}" != "0" ]] ; then
sudo yum install -y opencv opencv-devel && true
fi
if [[ "${USE_FFMPEG}" != "0" ]] ; then
sudo yum install -y ffmpeg ffmpeg-devel && true
fi
if [[ "${EXTRA_DEP_PACKAGES}" != "" ]] ; then
time sudo yum install -y ${EXTRA_DEP_PACKAGES}
fi
@@ -193,6 +197,10 @@ if [[ "$PTEX_VERSION" != "" ]] ; then
source src/build-scripts/build_Ptex.bash
fi
if [[ "$ABI_CHECK" != "" ]] ; then
source src/build-scripts/build_abi_tools.bash
fi
if [[ "$USE_ICC" != "" ]] ; then
# We used gcc for the prior dependency builds, but use icc for OIIO itself
echo "which icpc:" $(which icpc)
+2
View File
@@ -139,6 +139,7 @@ macro (oiio_add_all_tests)
# Freestanding tests:
oiio_add_tests (
cmake-consumer
docs-examples-cpp
iinfo igrep
nonwhole-tiles
oiiotool
@@ -208,6 +209,7 @@ macro (oiio_add_all_tests)
# libraries to run correctly.
if (USE_PYTHON AND NOT BUILD_OIIOUTIL_ONLY AND NOT SANITIZE)
oiio_add_tests (
docs-examples-python
python-colorconfig
python-deep
python-imagebuf
+40 -70
View File
@@ -18,42 +18,19 @@ to a file:
.. tabs::
.. code-tab:: c++
.. tab:: C++
.. literalinclude:: ../../testsuite/docs-examples-cpp/src/docs-examples-imageoutput.cpp
:language: c++
:start-after: BEGIN-imageoutput-simple
:end-before: END-imageoutput-simple
#include <OpenImageIO/imageio.h>
using namespace OIIO;
...
.. tab:: Python
const char *filename = "foo.jpg";
const int xres = 640, yres = 480;
const int channels = 3; // RGB
unsigned char pixels[xres * yres * channels];
.. literalinclude:: ../../testsuite/docs-examples-python/src/docs-examples-imageoutput.py
:language: py
:start-after: BEGIN-imageoutput-simple
:end-before: END-imageoutput-simple
std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
if (! out)
return;
ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);
out->open (filename, spec);
out->write_image (TypeDesc::UINT8, pixels);
out->close ();
.. code-tab:: py
import OpenImageIO as oiio
import numpy as np
filename = "foo.jpg"
xres = 640
yres = 480
channels = 3 # RGB
pixels = np.zeros((yres, xres, channels), dtype=np.uint8)
out = oiio.ImageOutput.create (filename)
if out:
spec = oiio.ImageSpec(xres, yres, channels, 'uint8')
out.open (filename, spec)
out.write_image (pixels)
out.close ()
This little bit of code does a surprising amount of useful work:
@@ -73,7 +50,7 @@ This little bit of code does a surprising amount of useful work:
out = ImageOutput.create (filename)
* Open the file, write the correct headers, and in all other important ways
prepare a file with the given dimensions (640 x 480), number of color
prepare a file with the given dimensions (320 x 240), number of color
channels (3), and data format (unsigned 8-bit integer).
.. tabs::
@@ -172,33 +149,26 @@ time, one tile at a time, or by individual rectangles.
Writing individual scanlines
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Individual scanlines may be written using the ``writescanline()`` API call:
Individual scanlines may be written using the ``write_scanline()`` API call:
.. tabs::
.. code-tab:: c++
.. tab:: C++
.. literalinclude:: ../../testsuite/docs-examples-cpp/src/docs-examples-imageoutput.cpp
:language: c++
:start-after: BEGIN-imageoutput-scanlines
:end-before: END-imageoutput-scanlines
:dedent: 4
unsigned char scanline[xres*channels];
out->open (filename, spec);
int z = 0; // Always zero for 2D images
for (int y = 0; y < yres; ++y) {
... generate data in scanline[0..xres*channels-1] ...
out->write_scanline (y, z, TypeDesc::UINT8, scanline);
}
out->close ();
.. tab:: Python
.. code-tab:: py
.. literalinclude:: ../../testsuite/docs-examples-python/src/docs-examples-imageoutput.py
:language: py
:start-after: BEGIN-imageoutput-scanlines
:end-before: END-imageoutput-scanlines
:dedent: 8
out.open (filename, spec)
z = 0 # Always zero for 2D images
for y in range(yres) :
# generate data in scanline[0..xres*channels-1] ...
scanline = ...
out.write_scanline (y, z, scanline)
}
out.close ()
The first two arguments to ``writescanline()`` specify which scanline is
The first two arguments to ``write_scanline()`` specify which scanline is
being written by its vertical (*y*) scanline number (beginning with 0)
and, for volume images, its slice (*z*) number (the slice number should
be 0 for 2D non-volume images). This is followed by a `TypeDesc`
@@ -212,7 +182,7 @@ All ``ImageOutput`` implementations will accept scanlines in strict order
any). See Section :ref:`sec-imageoutput-random-access-pixels` for details
on out-of-order or repeated scanlines.
The full description of the ``writescanline()`` function may be found
The full description of the ``write_scanline()`` function may be found
in Section :ref:`sec-imageoutput-class-reference`.
Writing individual tiles
@@ -220,7 +190,7 @@ Writing individual tiles
Not all image formats (and therefore not all ``ImageOutput``
implementations) support tiled images. If the format does not support
tiles, then ``writetile()`` will fail. An application using OpenImageIO
tiles, then ``write_tile()`` will fail. An application using OpenImageIO
should gracefully handle the case that tiled output is not available for
the chosen format.
@@ -297,7 +267,7 @@ individual plugin.
out.write_tile (x, y, z, tile)
out.close ()
The first three arguments to ``writetile()`` specify which tile is being
The first three arguments to ``write_tile()`` specify which tile is being
written by the pixel coordinates of any pixel contained in the tile: *x*
(column), *y* (scanline), and *z* (slice, which should always be 0 for 2D
non-volume images). This is followed by a `TypeDesc` describing the data
@@ -311,7 +281,7 @@ All ``ImageOutput`` implementations that support tiles will accept tiles in
strict order of increasing *y* rows, and within each row, increasing *x*
column, without missing any tiles. See
The full description of the ``writetile()`` function may be found
The full description of the ``write_tile()`` function may be found
in Section :ref:`sec-imageoutput-class-reference`.
Writing arbitrary rectangles
@@ -451,15 +421,15 @@ do not attempt to remap values, and do not clamp (except to their full
floating-point range).
It is not required that the pixel data passed to ``writeimage()``,
``writescanline()``, ``writetile()``, or ``write_rectangle()`` actually be
It is not required that the pixel data passed to ``write_image()``,
``write_scanline()``, ``write_tile()``, or ``write_rectangle()`` actually be
in the same data type as that requested as the native pixel data type of the
file. You can fully mix and match data you pass to the various "write"
routines and OpenImageIO will automatically convert from the internal format
to the native file format. For example, the following code will open a TIFF
file that stores pixel data as 16-bit unsigned integers (values ranging from
0 to 65535), compute internal pixel values as floating-point values, with
``writeimage()`` performing the conversion automatically:
``write_image()`` performing the conversion automatically:
.. tabs::
@@ -484,7 +454,7 @@ file that stores pixel data as 16-bit unsigned integers (values ranging from
out.write_image (pixels)
Note that ``writescanline()``, ``writetile()``, and ``write_rectangle()``
Note that ``write_scanline()``, ``write_tile()``, and ``write_rectangle()``
have a parameter that works in a corresponding manner.
@@ -507,13 +477,13 @@ passed to the "write" functions are *contiguous*, that is:
* for 3D volumetric images, the first pixel of slice *z* immediately
follows the last pixel of of slice ``z-1``.
Please note that this implies that data passed to ``writetile()`` be
Please note that this implies that data passed to ``write_tile()`` be
contiguous in the shape of a single tile (not just an offset into a whole
image worth of pixels), and that data passed to ``write_rectangle()`` be
contiguous in the dimensions of the rectangle.
The ``writescanline()`` function takes an optional ``xstride`` argument, and
the ``writeimage()``, ``writetile()``, and ``write_rectangle()`` functions
The ``write_scanline()`` function takes an optional ``xstride`` argument, and
the ``write_image()``, ``write_tile()``, and ``write_rectangle()`` functions
take optional ``xstride``, ``ystride``, and ``zstride`` values that describe
the distance, in *bytes*, between successive pixel columns, rows, and
slices, respectively, of the data you are passing. For any of these values
@@ -1152,8 +1122,8 @@ specification of the subimages at the time you first open the file.
out.write_image (pixels[s])
out.close ()
In both of these examples, we have used ``writeimage()``, but of course
``writescanline()``, ``writetile()``, and ``write_rectangle()`` work as you
In both of these examples, we have used ``write_image()``, but of course
``write_scanline()``, ``write_tile()``, and ``write_rectangle()`` work as you
would expect, on the current subimage.
@@ -1278,8 +1248,8 @@ used for texture mapping):
out.close ()
In this example, we have used ``writeimage()``, but of course
``writescanline()``, ``writetile()``, and ``write_rectangle()`` work as you
In this example, we have used ``write_image()``, but of course
``write_scanline()``, ``write_tile()``, and ``write_rectangle()`` work as you
would expect, on the current MIP level.
+2 -2
View File
@@ -1769,8 +1769,8 @@ public:
/// `filenames` will be sized to `ntiles * nvtiles` and filled with the
/// the names of the concrete files comprising the atlas, with an empty
/// ustring corresponding to any unpopulated tiles (the UDIM set is
/// allowed to be sparse). The filename list is indexed as `utile + vtile
/// * nvtiles`.
/// allowed to be sparse). The filename list is indexed as
/// `utile + vtile * nvtiles`.
///
/// This method was added in OpenImageIO 2.3.
virtual void inventory_udim(ustring udimpattern,
+9 -13
View File
@@ -816,41 +816,41 @@ public:
/// Construct a ustringhash from a null-terminated C string (char *).
OIIO_DEVICE_CONSTEXPR explicit ustringhash(const char* str)
{
#ifdef __CUDA_ARCH__
// GPU: just compute the hash. This can be constexpr!
m_hash = Strutil::strhash(str);
: m_hash(Strutil::strhash(str))
#else
// CPU: make ustring, get its hash. Note that ustring ctr can't be
// constexpr because it has to modify the internal ustring table.
m_hash = ustring(str).hash();
: m_hash(ustring(str).hash())
#endif
{
}
OIIO_DEVICE_CONSTEXPR explicit ustringhash(const char* str, size_t len)
{
#ifdef __CUDA_ARCH__
// GPU: just compute the hash. This can be constexpr!
m_hash = Strutil::strhash(len, str);
: m_hash(Strutil::strhash(len, str))
#else
// CPU: make ustring, get its hash. Note that ustring ctr can't be
// constexpr because it has to modify the internal ustring table.
m_hash = ustring(str, len).hash();
: m_hash(ustring(str, len).hash())
#endif
{
}
/// Construct a ustringhash from a string_view, which can be
/// auto-converted from either a std::string.
OIIO_DEVICE_CONSTEXPR explicit ustringhash(string_view str)
{
#ifdef __CUDA_ARCH__
// GPU: just compute the hash. This can be constexpr!
m_hash = Strutil::strhash(str);
: m_hash(Strutil::strhash(str))
#else
// CPU: make ustring, get its hash. Note that ustring ctr can't be
// constexpr because it has to modify the internal ustring table.
m_hash = ustring(str).hash();
: m_hash(ustring(str).hash())
#endif
{
}
/// Construct from a raw hash value. Beware: results are undefined if it's
@@ -1051,10 +1051,6 @@ OIIO_DEVICE_CONSTEXPR ustringhash operator""_ush(const char* str,
/// Deprecated -- This is too easy to confuse with the ustringhash class. And
/// also it is unnecessary if you use std::hash<ustring>. This will be removed
/// in OIIO 3.0.
# if OIIO_VERSION_GREATER_EQUAL(2, 6, 0)
OIIO_DEPRECATED("Use std::hash<ustring> instead of ustringHash")
# endif
using ustringHash = std::hash<ustring>;
#endif
+2 -2
View File
@@ -228,7 +228,7 @@ install_targets (OpenImageIO)
# Testing
if (OIIO_BUILD_TESTS)
if (OIIO_BUILD_TESTS AND BUILD_TESTING)
add_executable (color_test color_test.cpp)
target_link_libraries (color_test PRIVATE OpenImageIO)
@@ -272,4 +272,4 @@ if (OIIO_BUILD_TESTS)
set_target_properties (compute_test PROPERTIES FOLDER "Unit Tests")
add_test (unit_compute ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/compute_test)
endif (OIIO_BUILD_TESTS)
endif ()
+2
View File
@@ -1302,6 +1302,8 @@ encode_exif(const ImageSpec& spec, std::vector<char>& blob,
TIFFHeader head;
head.tiff_magic = (endianreq == endian::little) ? 0x4949 : 0x4d4d;
head.tiff_version = 42;
if (endianreq != endian::native)
swap_endian(&head.tiff_version);
// N.B. need to swap_endian head.tiff_diroff below, once we know the sizes
append(blob, head);
+1 -1
View File
@@ -84,7 +84,7 @@ install_targets (OpenImageIO_Util)
if (OIIO_BUILD_TESTS)
if (OIIO_BUILD_TESTS AND BUILD_TESTING)
add_executable (argparse_test argparse_test.cpp)
target_link_libraries (argparse_test PRIVATE OpenImageIO_Util)
-5
View File
@@ -31,11 +31,6 @@
#include <OpenImageIO/thread.h>
#include <OpenImageIO/ustring.h>
#ifdef _WIN32
# include <shellapi.h>
# include <windows.h>
#endif
// We use the public domain stb implementation of vsnprintf because
// not all platforms support a locale-independent version of vsnprintf.
+11 -2
View File
@@ -120,8 +120,17 @@ declare_imagecache(py::module& m)
return PY_STR(ic.m_cache->resolve_filename(filename));
})
// .def("get_image_info", &ImageCacheWrap::get_image_info)
// .def("get_imagespec", &ImageCacheWrap::get_imagespec,
// "subimage"_a=0),
.def(
"get_imagespec",
[](const ImageCacheWrap& ic, const std::string& filename,
int subimage, int miplevel, bool native) {
ImageSpec spec;
ic.m_cache->get_imagespec(ustring(filename), spec, subimage,
miplevel, native);
return spec;
},
"filename"_a, "subimage"_a = 0, "miplevel"_a = 0,
"native"_a = false)
// .def("get_thumbnail", &ImageCacheWrap::get_thumbnail,
// "subimage"_a=0)
.def("get_pixels", &ImageCacheWrap::get_pixels, "filename"_a,
+8 -2
View File
@@ -2,7 +2,7 @@
# SPDX-License-Identifier: Apache-2.0
# https://github.com/OpenImageIO/oiio
cmake_minimum_required (VERSION 3.12)
cmake_minimum_required (VERSION 3.15)
project (consumer
LANGUAGES CXX)
@@ -12,7 +12,7 @@ endif ()
message (STATUS "Building ${PROJECT_NAME} ${PROJECT_VERSION} - ${CMAKE_BUILD_TYPE}")
# Use C++11
# Use C++14
set (CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to prefer (14, 17, etc.)")
set (CMAKE_CXX_STANDARD_REQUIRED ON)
set (CMAKE_CXX_EXTENSIONS OFF)
@@ -21,6 +21,12 @@ set (CMAKE_CXX_EXTENSIONS OFF)
# Make sure we have dependencies we need
find_package (OpenImageIO CONFIG REQUIRED)
# Special for OIIO testsuite when running in sanitize mode
if (DEFINED ENV{SANITIZE})
add_compile_options (-fsanitize=$ENV{SANITIZE})
add_link_options (-fsanitize=$ENV{SANITIZE})
endif()
add_executable(consumer consumer.cpp)
target_link_libraries (consumer
@@ -0,0 +1,45 @@
# Copyright Contributors to the OpenImageIO project.
# SPDX-License-Identifier: Apache-2.0
# https://github.com/OpenImageIO/oiio
cmake_minimum_required (VERSION 3.15)
project (oiio-docs-examples
LANGUAGES CXX)
if (NOT CMAKE_BUILD_TYPE)
set (CMAKE_BUILD_TYPE "Release")
endif ()
message (STATUS "Building ${PROJECT_NAME} ${PROJECT_VERSION} - ${CMAKE_BUILD_TYPE}")
# Use C++14
set (CMAKE_CXX_STANDARD 14 CACHE STRING "C++ standard to prefer (14, 17, etc.)")
set (CMAKE_CXX_STANDARD_REQUIRED ON)
set (CMAKE_CXX_EXTENSIONS OFF)
# Make sure we have dependencies we need
find_package (OpenImageIO CONFIG REQUIRED)
# Special for OIIO testsuite when running in sanitize mode
if (DEFINED ENV{SANITIZE})
add_compile_options (-fsanitize=$ENV{SANITIZE})
add_link_options (-fsanitize=$ENV{SANITIZE})
endif()
add_executable(docs-examples-imageoutput src/docs-examples-imageoutput.cpp)
target_link_libraries (docs-examples-imageoutput
PRIVATE OpenImageIO::OpenImageIO)
# Chapters we haven't done yet:
# add_executable(docs-imageinput src/docs-examples-imageinput.cpp)
# target_link_libraries (docs-examples-imageinput
# PRIVATE OpenImageIO::OpenImageIO)
#
# add_executable(docs-imagebuf src/docs-examples-imagebuf.cpp)
# target_link_libraries (docs-examples-imagebuf
# PRIVATE OpenImageIO::OpenImageIO)
#
# add_executable(docs-imagebufalgo src/docs-examples-imagebufalgo.cpp)
# target_link_libraries (docs-examples-imagebufalgo
# PRIVATE OpenImageIO::OpenImageIO)
+4
View File
@@ -0,0 +1,4 @@
Comparing "simple.tif" and "ref/simple.tif"
PASS
Comparing "scanlines.tif" and "ref/scanlines.tif"
PASS
Binary file not shown.
Binary file not shown.
+17
View File
@@ -0,0 +1,17 @@
#!/usr/bin/env python
# Copyright Contributors to the OpenImageIO project.
# SPDX-License-Identifier: Apache-2.0
# https://github.com/OpenImageIO/oiio
# command += "echo test_source_dir=" + test_source_dir + " >> build.txt ;"
command += run_app("cmake " + test_source_dir + " -DCMAKE_BUILD_TYPE=Release >> build.txt 2>&1", silent=True)
command += run_app("cmake --build . --config Release >> build.txt 2>&1", silent=True)
if platform.system() == 'Windows' :
command += run_app("Release\\docs-examples-imageoutput")
else :
command += run_app("./docs-examples-imageoutput")
outputs = [ "simple.tif", "scanlines.tif",
"out.txt" ]
@@ -0,0 +1,52 @@
// BEGIN-imageoutput-simple
#include <OpenImageIO/imageio.h>
using namespace OIIO;
void simple_write()
{
const char* filename = "simple.tif";
const int xres = 320, yres = 240, channels = 3;
unsigned char pixels[xres * yres * channels] = { 0 };
std::unique_ptr<ImageOutput> out = ImageOutput::create(filename);
if (!out)
return; // error
ImageSpec spec(xres, yres, channels, TypeDesc::UINT8);
out->open(filename, spec);
out->write_image(TypeDesc::UINT8, pixels);
out->close();
}
// END-imageoutput-simple
void scanlines_write()
{
const char* filename = "scanlines.tif";
const int xres = 320, yres = 240, channels = 3;
std::unique_ptr<ImageOutput> out = ImageOutput::create(filename);
if (!out)
return; // error
ImageSpec spec(xres, yres, channels, TypeDesc::UINT8);
// BEGIN-imageoutput-scanlines
unsigned char scanline[xres * channels] = { 0 };
out->open (filename, spec);
int z = 0; // Always zero for 2D images
for (int y = 0; y < yres; ++y) {
// ... generate data in scanline[0..xres*channels-1] ...
out->write_scanline (y, z, TypeDesc::UINT8, scanline);
}
out->close();
// END-imageoutput-scanlines
}
int main(int /*argc*/, char** /*argv*/)
{
simple_write();
scanlines_write();
return 0;
}
@@ -0,0 +1,4 @@
Comparing "simple.tif" and "ref/simple.tif"
PASS
Comparing "scanlines.tif" and "ref/scanlines.tif"
PASS
Binary file not shown.
Binary file not shown.
+12
View File
@@ -0,0 +1,12 @@
#!/usr/bin/env python
# Copyright Contributors to the OpenImageIO project.
# SPDX-License-Identifier: Apache-2.0
# https://github.com/OpenImageIO/oiio
# Run the script
command += pythonbin + " src/docs-examples-imageoutput.py >> out.txt ;"
outputs = [ "simple.tif", "scanlines.tif", "out.txt" ]
@@ -0,0 +1,58 @@
#!/usr/bin/env python
# Copyright Contributors to the OpenImageIO project.
# SPDX-License-Identifier: Apache-2.0
# https://github.com/OpenImageIO/oiio
from __future__ import print_function
from __future__ import absolute_import
# BEGIN-imageoutput-simple
import OpenImageIO as oiio
import numpy as np
def simple_write() :
filename = "simple.tif"
xres = 320
yres = 240
channels = 3 # RGB
pixels = np.zeros((yres, xres, channels), dtype=np.uint8)
out = oiio.ImageOutput.create (filename)
if out:
spec = oiio.ImageSpec(xres, yres, channels, 'uint8')
out.open (filename, spec)
out.write_image (pixels)
out.close ()
# END-imageoutput-simple
import OpenImageIO as oiio
import numpy as np
def scanlines_write() :
filename = "scanlines.tif"
xres = 320
yres = 240
channels = 3 # RGB
spec = oiio.ImageSpec(xres, yres, channels, 'uint8')
out = oiio.ImageOutput.create (filename)
if out:
# BEGIN-imageoutput-scanlines
z = 0 # Always zero for 2D images
out.open (filename, spec)
for y in range(yres) :
# Generate pixel array for one scanline.
# As an example, we are just making a zero-filled scanline
scanline = np.zeros((xres, channels), dtype=np.uint8)
out.write_scanline (y, z, scanline)
out.close ()
# END-imageoutput-scanlines
if __name__ == '__main__':
simple_write()
scanlines_write()
@@ -1,6 +1,8 @@
getattribute("max_open_files") 90
getattribute("max_memory_MB") 900.0
getattribute("searchpath") ../common
tahoe_tiny is 128 x 96
grid is 1000 x 1000
full getattribute stat:cache_memory_used 0
full getattribute stat:image_size 4036864
full getattribute total_files 2
@@ -1,6 +1,8 @@
getattribute("max_open_files") 90
getattribute("max_memory_MB") 900.0
getattribute("searchpath") ../common
tahoe_tiny is 128 x 96
grid is 1000 x 1000
full getattribute stat:cache_memory_used 0
full getattribute stat:image_size 4036864
full getattribute total_files 2
+2
View File
@@ -1,6 +1,8 @@
getattribute("max_open_files") 90
getattribute("max_memory_MB") 900.0
getattribute("searchpath") ../common
tahoe_tiny is 128 x 96
grid is 1000 x 1000
full getattribute stat:cache_memory_used 0
full getattribute stat:image_size 4036864
full getattribute total_files 2
@@ -27,9 +27,11 @@ try:
print ("getattribute(\"max_memory_MB\")", ic.getattribute("max_memory_MB"))
print ("getattribute(\"searchpath\")", ic.getattribute("searchpath"))
# Force a file to be touched by the IC
ib = oiio.ImageBuf("../common/tahoe-tiny.tif")
ib = oiio.ImageBuf("../common/grid.tif")
# Force a file to be touched by the IC and test get_imagespec
spec = ic.get_imagespec("../common/tahoe-tiny.tif")
print ("tahoe_tiny is", spec.width, "x", spec.height)
spec = ic.get_imagespec("../common/grid.tif")
print ("grid is", spec.width, "x", spec.height)
# Test getattribute(name, type) with the full type specified
print ("full getattribute stat:cache_memory_used", ic.getattribute("stat:cache_memory_used", 'int64'))
+1 -1
View File
@@ -10,7 +10,7 @@ command += oiio_app("iconvert") + "../common/grid.tif --scanline scanline.tif >
command += oiio_app("iconvert") + "../common/grid.tif --tile 64 64 tiled.tif > out.txt ;"
# Run the script
command += pythonbin + " src/test_imageoutput.py > out.txt ;"
command += pythonbin + " src/test_imageoutput.py >> out.txt ;"
# compare the outputs -- these are custom because they compare to grid.tif
files = [ "grid-image.tif", "grid-scanline.tif", "grid-scanlines.tif",