Compare commits

..
178 Commits
Author SHA1 Message Date
Cary Phillips a1a00ffeec Add PR 1674 to notes
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-25 11:27:30 -07:00
Peter StenetegandCary Phillips edc86ed415 CMake packaging fix. (#1674)
* CMake packaging fix.

Add find_dependency for the new dependency libdeflate, and remove the REQUIRED flag. find_dependency will pickup the correct flag from the calling find_package call.

Signed-off-by: Peter Steneteg <peter@steneteg.se>

* find_dependency only if libdeflate_FOUND

Signed-off-by: Cary Phillips <cary@ilm.com>

* Need to expand the libdeflate_FOUND variable at configure_file time

Signed-off-by: Peter Steneteg <peter@steneteg.se>

---------

Signed-off-by: Peter Steneteg <peter@steneteg.se>
Signed-off-by: Cary Phillips <cary@ilm.com>
Co-authored-by: Cary Phillips <cary@ilm.com>
2024-03-25 11:20:18 -07:00
Cary Phillips 7239a2652f Fix merge of website_workflow.yml
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:48:55 -07:00
Cary Phillips 53786883ac Add additional PRs to to release notes
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:35:49 -07:00
Cary Phillips a830413002 Improve workflow filters (#1668)
Run the ci_workflow and website_workflow only on changes to the
appropriate source files and workflow files.

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:31:32 -07:00
Aliaksei UrbanskiandCary Phillips c8b731abf5 🐛 Remove the OPENEXR_INSTALL_EXAMPLES CMake option (#1666)
The OPENEXR_INSTALL_EXAMPLES option is misleading and doesn't have any effect.
It might be safely removed in favor of the OPENEXR_BUILD_EXAMPLES option.

Signed-off-by: Aliaksei Urbanski <aliaksei.urbanski@gmail.com>
Co-authored-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:29:54 -07:00
Cary Phillips cbb0ca61cd Initialize _ySampling to 0 (#1662)
Caught by the santizer as potential use-before-initialization

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:29:45 -07:00
Cary Phillips 454cd4d62a Use size_t as iterator instead of int (#1659)
Caught by the sanitizer

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:29:37 -07:00
Cary Phillips 1969623dd4 Bump version for v3.2.4
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:06:59 -07:00
Cary Phillips afb5b6fc02 Release notes for v3.2.4
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:06:24 -07:00
Kimball Thurston 8d25bedd83 Fix typo causing prefix len to be wrong (#1684)
When constructing the decompress side of dwaa/b compression support,
simple typo when computing the prefix length as distance between
pointers causing the length to be wrong, triggering csc decompression
values to be wrong when decompressed.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-03-23 12:04:45 -07:00
Cary Phillips 1a59a1a7f6 Release notes for v3.1.13
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-23 12:03:16 -07:00
Cary Phillips e4b8d0226a Remove debugging CIBW_BUILD: cp312
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-06 16:38:54 -08:00
Cary Phillips d5c8b71dbe Update release notes
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 09:02:33 -08:00
Cary Phillips cca5eb44a0 Bump Imath to 3.1.11
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 09:02:16 -08:00
Cary Phillips f627f72dae Add recent releases to website news (#1651)
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 08:54:19 -08:00
Cary Phillips 0ef34bbc6e Run release-sign workflow on published instead of created (#1650)
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 08:54:10 -08:00
Kimball Thurston 58f2ab0fbb Allow partial chunk tables (#1653)
* fix sporadic UB in dwa

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Allow partial chunk tables

This will fix #1642, re-enabling partial chunk tables during
reconstruction (at least for the last part read). Correctly handles
reconstructing tables where discovered tiles are shifted from expected
indices

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Avoid OOB write

When reconstructing chunk table with corrupt chunks, avoid writing out
of bounds

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* avoid undefined behavior

unaligned reads are UB, use (__builtin_) memcpy

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

---------

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-03-04 08:53:48 -08:00
Kimball Thurston efdfcff21a Fix 0 samples in deep data (#1652)
Add some additional safety checks, but properly handle when there are 0
samples in a deep scanline / tile (chunk)

Should fix #1639 and OSS-Fuzz 66612

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-03-04 08:53:41 -08:00
Cary Phillips 09914784e2 Remove -Dsonar.login from sonar-scanner command line (#1647)
Addresses #1646

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 08:53:34 -08:00
Cary Phillips d9f606e484 Fix memory leaks in exrstdattr and example code (#1649)
Caught by the address sanitizer, worth addressing in the example code
as good programming practice.

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 08:53:27 -08:00
Cary Phillips 9c3e18aade Add instructions for creating signed releases/tags (#1637)
* Add instructions for creating signed releases/tags

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add openexr.keyring

Signed-off-by: Cary Phillips <cary@ilm.com>

* Sign & upload release artifacts via sigstore

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add release-sign.yml

Signed-off-by: Cary Phillips <cary@ilm.com>

* Use gh-action-sigstore-python

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 08:53:22 -08:00
Jean-Christophe Morin 27fb7abe70 Use component for python (#1643)
* Add "COMPONENT python" to install() the python bindings and tell scikit-build-core to only install the python component

Signed-off-by: Jean-Christophe Morin <jean_christophe_morin@hotmail.com>

* Update scikit-build-core to 0.8.1

Signed-off-by: Jean-Christophe Morin <jean_christophe_morin@hotmail.com>

* Fix typo

Signed-off-by: Jean-Christophe Morin <jean_christophe_morin@hotmail.com>

---------

Signed-off-by: Jean-Christophe Morin <jean_christophe_morin@hotmail.com>
2024-03-04 08:53:16 -08:00
Cary Phillips 690ee3edf7 Fix version tag for python wheel sdist (#1640)
* Fix version tag for sdist

Signed-off-by: Cary Phillips <cary@ilm.com>

* Don't set OPENEXR_RELEASE_CANDIDATE_TAG for the non-test publish

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-03-04 08:53:08 -08:00
17811af04e Build python wheels via scikit-build-core (#1629)
* Build python wheels via scikit-build-core

This converts the setuptools configuration for building python wheels
to use scikit-build-core, which has better support for CMake. There is
no more setup.py; the configuration is entirely in `pyproject.toml`
and the compile/link is done exclusively via cmake.

The build/publish policy is:

* A PR that changes any of the python wheel source/configuration
  (src/wrappers/python/* or .github/workflows/python-wheels.yml)
  triggers a build as a check.

* PRs that change other library source do *not* trigger a build of the
  python wheels. Note that the primary CI workflow does build and test
  the bindings, although only for a single python version on a single
  arch for Linux/macOS/Windows. The wheel building validates multiple
  python versions and architectures, but involves signifant
  computation/time.  Currently, the python wheels are a thin wrapper
  about basic read/write functions that don't add significant
  additional functionality to the library. Any potential problem will
  almost certainly get caught by the primary CI.

* A tag of the form `v3.[0-9]+.[0-9]+-rc*` (e.g. `v3.2.4-rc`) triggers
  a full build of the wheels followed by a publish to
  `test.pypi.org`. This validates release candidates.

* Publishing a release triggers a full build of the wheels followed by
  a publish to `pypi.org`.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add custom README.md for pypi.org

Signed-off-by: Cary Phillips <cary@ilm.com>

* fix typo

Signed-off-by: Cary Phillips <cary@ilm.com>

* reference src/wrappers/python/README.md in pyproject.toml

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add copyright notice

Signed-off-by: Cary Phillips <cary@ilm.com>

* Update pyproject.toml

Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

* Update pyproject.toml

Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

* Update src/wrappers/python/CMakeLists.txt

Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

* Add uninstall target (#1624)

* Add uninstall target

Satisfy the OpenSSF Best Practices Badge requirement for an
insta/uninstall process:
https://www.bestpractices.dev/en/criteria/1#1.installation_common

CMake does not support a standard "uninstall" target, but the
community recommends implementing an "uninstal" target that remove files named in the
`install_manifest.txt`:
https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

However, our existing process of installing the symlink to the "bare"
library, i.e. the symlink from libImath-3_2.so to libImath.so, fails
to add the symlink to the manifest, so "make uninstall" misses the
symlink. The existing mechanism use "install(CODE execute_process(cmake -E create_symlink))".

This changes that to use a simpler "file(CREATE_LINK)" and
"install(FILES)" to accomplish the same thing while also registering
the symlink the the manifest.

Also, this fixes an issue where `OpenEXRConfig.h` was passed to
`install()` twice, producing two entries in `install_manifest.txt`.

Signed-off-by: Cary Phillips <cary@ilm.com>

* mention uninstall in install instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

* poke

Signed-off-by: Cary Phillips <cary@ilm.com>

* COPY_ON_ERROR

Signed-off-by: Cary Phillips <cary@ilm.com>

* clarify the uninstall instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add cmake.targets and OPENEXR_INSTALL=OFF

Signed-off-by: Cary Phillips <cary@ilm.com>

* INSTALL_TOOLS=OFF

Signed-off-by: Cary Phillips <cary@ilm.com>

* propogate OPENEXR_INSTALL to Imath

Signed-off-by: Cary Phillips <cary@ilm.com>

* test1

Signed-off-by: Cary Phillips <cary@ilm.com>

* OPENEXR_INSTALL_PKG_CONFIG

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix CVE 2023 5841 (#1627)

* enable deep file checks for core

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* fix possible int overflow

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* fix validation of deep sample counts

Addresses CVE-2023-5841, fixing sample count check to not only check
against 0 but previous sample as well.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* add clarifying comment

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

---------

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Bazel support: Bump Imath to 3.1.10 (#1626)

Signed-off-by: Vertexwahn <julian.amann@tum.de>

* Document security expectations (#1623)

* Document security expectations

Signed-off-by: Cary Phillips <cary@ilm.com>

* Menion Imath as a dependency

Signed-off-by: Cary Phillips <cary@ilm.com>

* Update SECURITY.md

Co-authored-by: Nick Porcino <meshula@hotmail.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

* change 'Threat Model' to 'Potential Vulnerabilties'

Signed-off-by: Cary Phillips <cary@ilm.com>

* Mention GitHub issue as fallback security contact

Signed-off-by: Cary Phillips <cary@ilm.com>

* github security advisory

Signed-off-by: Cary Phillips <cary@ilm.com>

* mention exrcheck

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
Co-authored-by: Nick Porcino <meshula@hotmail.com>

* Add uninstall target (#1624)

* Add uninstall target

Satisfy the OpenSSF Best Practices Badge requirement for an
insta/uninstall process:
https://www.bestpractices.dev/en/criteria/1#1.installation_common

CMake does not support a standard "uninstall" target, but the
community recommends implementing an "uninstal" target that remove files named in the
`install_manifest.txt`:
https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

However, our existing process of installing the symlink to the "bare"
library, i.e. the symlink from libImath-3_2.so to libImath.so, fails
to add the symlink to the manifest, so "make uninstall" misses the
symlink. The existing mechanism use "install(CODE execute_process(cmake -E create_symlink))".

This changes that to use a simpler "file(CREATE_LINK)" and
"install(FILES)" to accomplish the same thing while also registering
the symlink the the manifest.

Also, this fixes an issue where `OpenEXRConfig.h` was passed to
`install()` twice, producing two entries in `install_manifest.txt`.

Signed-off-by: Cary Phillips <cary@ilm.com>

* mention uninstall in install instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

* poke

Signed-off-by: Cary Phillips <cary@ilm.com>

* COPY_ON_ERROR

Signed-off-by: Cary Phillips <cary@ilm.com>

* clarify the uninstall instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Remove snyk-scan-pr.yml (#1631)

This workflow is causing errors on each PR:

  Snyk is missing auth token in order to run inside CI. You must include your API token as an environment value: `SNYK_TOKEN=12345678`
  Error: Process completed with exit code 2.

As discussed on #1608, the preferred workflow will run weekly, not on PR.

Signed-off-by: Cary Phillips <cary@ilm.com>

* fix issue with unpacking sample counts (#1630)

When unpacking sample counts as "individual" counts (no longer
monotonic), it writes the total sample count to a value 1 past the
individual sample counts, but this is not in the packed data, so do not
expect to unpack that many values. The buffer just needs to be allocated
one value larger to avoid write past end of buffer which is taken care
of in the update_pack_unpack_ptrs function

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* adjust checks for core to better match c++ checks (#1632)

The core checks were not setting the same image / tile size limits and
not disabling reads at quite the same level.

Note: the core check does not read the entire image into a contiguous
slice, so does not replicate the maximum deep sample checks in the same
way, this is a source of potential false-negative failures

This should address OSS-Fuzz 66491 and 66489 (different forms of the
same failure where a large sample size allocation was happening), and
are only constrained memory (2.5Gb) issues.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Fix install of symlink (#1633)

PR #1624 caused the .so symlink without the `OPENEXR_LIB_SUFFIX`
(e.g. libOpenEXR.so which links to libOpenEXR-3_2.so) to get created
in the wrong directory. This caused certain invocations of cmake to
fail, even though the invocation in the CI succeeded. It's not at all
clear why.

This also changes the CI to invoke cmake in the way that previously
failed (e.g. from the top-level directory with `-B` and `-S`), as an additional check.

Signed-off-by: Cary Phillips <cary@ilm.com>

* adds a shortcut to avoid reconstructing every call (#1634)

When there is a loop trying to get scan / tile info that is ignoring
return values, add a shortcut to avoid trying to reconstruct the chunk
table every time. This will still respect the strict header flag, either
returning an error immediately (strict), or (non-strict) enabling a
multi-part file with only partially corrupt parts to work.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* check and control reduceMemory and reduceTime in stream mode (#1635)

exrcheck by default uses file mode, but the fuzzer and exrcheck -s use
stream mode, need to respect the memory and time flags consistently on
that path as well.

Will address OSS-Fuzz 66612, although real fix underlying is in #1634

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Update .github/workflows/python-wheels-publish-test.yml

Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

* Add sdist

Signed-off-by: Cary Phillips <cary@ilm.com>

* Update .github/workflows/python-wheels-publish-test.yml

Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

* fix sdist; remove debugging

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
Signed-off-by: Vertexwahn <julian.amann@tum.de>
Co-authored-by: Jean-Christophe Morin <38703886+JeanChristopheMorinPerso@users.noreply.github.com>
Co-authored-by: Kimball Thurston <kdt3rd@gmail.com>
Co-authored-by: Vertexwahn <julian.amann@tum.de>
Co-authored-by: Nick Porcino <meshula@hotmail.com>
2024-02-15 17:19:01 -08:00
John Mertic 2d3fce400b Do synk scans weekly on Sunday mornings (#1636)
Signed-off-by: John Mertic <jmertic@linuxfoundation.org>
2024-02-15 17:19:01 -08:00
Cary Phillips c3804276bb Release notes for v3.2.3
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary Phillips 6a0a5c0143 Bump version for v3.2.3
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Kimball Thurston 0e46554b2a adds a shortcut to avoid reconstructing every call (#1634)
When there is a loop trying to get scan / tile info that is ignoring
return values, add a shortcut to avoid trying to reconstruct the chunk
table every time. This will still respect the strict header flag, either
returning an error immediately (strict), or (non-strict) enabling a
multi-part file with only partially corrupt parts to work.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-02-15 17:19:01 -08:00
Cary Phillips 441cf460a9 Fix install of symlink (#1633)
PR #1624 caused the .so symlink without the `OPENEXR_LIB_SUFFIX`
(e.g. libOpenEXR.so which links to libOpenEXR-3_2.so) to get created
in the wrong directory. This caused certain invocations of cmake to
fail, even though the invocation in the CI succeeded. It's not at all
clear why.

This also changes the CI to invoke cmake in the way that previously
failed (e.g. from the top-level directory with `-B` and `-S`), as an additional check.

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary Phillips 4ae29178d3 Remove snyk-scan-pr.yml (#1631)
This workflow is causing errors on each PR:

  Snyk is missing auth token in order to run inside CI. You must include your API token as an environment value: `SNYK_TOKEN=12345678`
  Error: Process completed with exit code 2.

As discussed on #1608, the preferred workflow will run weekly, not on PR.

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary Phillips daa66664e3 Add uninstall target (#1624)
* Add uninstall target

Satisfy the OpenSSF Best Practices Badge requirement for an
insta/uninstall process:
https://www.bestpractices.dev/en/criteria/1#1.installation_common

CMake does not support a standard "uninstall" target, but the
community recommends implementing an "uninstal" target that remove files named in the
`install_manifest.txt`:
https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake

However, our existing process of installing the symlink to the "bare"
library, i.e. the symlink from libImath-3_2.so to libImath.so, fails
to add the symlink to the manifest, so "make uninstall" misses the
symlink. The existing mechanism use "install(CODE execute_process(cmake -E create_symlink))".

This changes that to use a simpler "file(CREATE_LINK)" and
"install(FILES)" to accomplish the same thing while also registering
the symlink the the manifest.

Also, this fixes an issue where `OpenEXRConfig.h` was passed to
`install()` twice, producing two entries in `install_manifest.txt`.

Signed-off-by: Cary Phillips <cary@ilm.com>

* mention uninstall in install instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

* poke

Signed-off-by: Cary Phillips <cary@ilm.com>

* COPY_ON_ERROR

Signed-off-by: Cary Phillips <cary@ilm.com>

* clarify the uninstall instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary PhillipsandNick Porcino b765658cfb Document security expectations (#1623)
* Document security expectations

Signed-off-by: Cary Phillips <cary@ilm.com>

* Menion Imath as a dependency

Signed-off-by: Cary Phillips <cary@ilm.com>

* Update SECURITY.md

Co-authored-by: Nick Porcino <meshula@hotmail.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

* change 'Threat Model' to 'Potential Vulnerabilties'

Signed-off-by: Cary Phillips <cary@ilm.com>

* Mention GitHub issue as fallback security contact

Signed-off-by: Cary Phillips <cary@ilm.com>

* github security advisory

Signed-off-by: Cary Phillips <cary@ilm.com>

* mention exrcheck

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
Co-authored-by: Nick Porcino <meshula@hotmail.com>
2024-02-15 17:19:01 -08:00
Vertexwahn 74f3a2d191 Bazel support: Bump Imath to 3.1.10 (#1626)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2024-02-15 17:19:01 -08:00
Cary Phillips c825a08bec Make 'Hello, World' example reader/writer downloadable (#1620)
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary Phillips 4198d004ed Add a reference to building tools from source to the tools webpage. (#1622)
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary PhillipsandNick Porcino e29a6dafe1 Add explanation of distinction between OpenEXR/OpenEXRCore to API section (#1621)
* Add explanation of the distinction between OpenEXR/OpenEXRCore to API section

This was described in the release notes but was never addressed in the
actual online documentation, where it was not, in fact, obvious.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Update website/API.rst

Co-authored-by: Nick Porcino <meshula@hotmail.com>
Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
Co-authored-by: Nick Porcino <meshula@hotmail.com>
2024-02-15 17:19:01 -08:00
Brecht Van Lommel 2641f8b341 Support cmake config for libdeflate (#1613)
* Support cmake config and shared library for libdeflate

When not using the internal deflate, the only option was pkgconfig which
is not well supported on Windows. This adds support for using the
libdeflate cmake config files when available.

This change also affects the generated OpenEXR cmake config files. For
a static OpenEXR library, INTERFACE_LINK_LIBRARIES now appropriately
includes libdeflate along with the existing dependencies like Imath.

It also turns the internal libdeflate into a target for consistency.

Resolves #1588

Signed-off-by: Brecht Van Lommel <brecht@blender.org>

* Back out of adding a target for internal libdeflate

Signed-off-by: Brecht Van Lommel <brecht@blender.org>

* Use Requires.private for generated pkgconfig file

Signed-off-by: Brecht Van Lommel <brecht@blender.org>

---------

Signed-off-by: Brecht Van Lommel <brecht@blender.org>
2024-02-15 17:19:01 -08:00
Cary Phillips b6caee5b8b Update MacPorts install instructions (#1611)
* Update MacPorts install instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

* remove sudo

Signed-off-by: Cary Phillips <cary@ilm.com>

* mention vcpkg for Windows

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary Phillips 6925579b36 Fix bswap on NetBSD (#1612)
The #includes were incorrect.

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Vertexwahn d6c7eed7e7 Fix spelling of GitHub (#1615)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2024-02-15 17:19:01 -08:00
David Deal f37f7d1c43 CI/CD - Added Snyk C/C++ Scanning Job (#1608)
- added example C/C++ Code scanner using the Snyk GitHub Action.
  The `--unmanaged` flag indicates this is for a C/C++ codebase. In this
  example, it currently scans on a new pull request to the 'main'
  branch. The repository administrator should set both the SNYK_ORG and
  SNYK_TOKEN environment variables before merging this PR. The
  environment variables can be obtained from the LFX Security team.
- added *.h, *.c, *.cpp filter to only run the scan when source files
  are changed

Signed-off-by: David Deal <ddeal@linuxfoundation.org>
2024-02-15 17:19:01 -08:00
Vertexwahn e7a34c5e04 Bump skylib in workspace approach (#1605)
Default behavior enable_bzlmod was switch (https://github.com/bazelbuild/bazel/issues/18958)

Bump Bazel version to 7.0.0

Update Bazel modules

Apply buildifier on MODULE.bazel

Signed-off-by: Vertexwahn <julian.amann@tum.de>
2024-02-15 17:19:01 -08:00
Cary Phillips 93336dae74 Release notes and news for v2.5.10 (#1600)
* Release notes for v2.5.10

Signed-off-by: Cary Phillips <cary@ilm.com>

* News for v2.5.10

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Cary Phillips 162abaa322 Account for duplicate emails with .mailmap (#1597)
The .mailmap file maps author/committer names and emails to canonical
real names and email addresses.

This also updates the CONTRIBUTORS.md file with missing names from the
git logs.

This information is to the best of our knowledge, but please submit
any corrections if you prefer.

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-15 17:19:01 -08:00
Megha S 5261e5ef19 Converting code-blocks to literalincludes in ReadingAndWritingImageFiles.rst (#1583)
* Converting code-blocks to literalincludes in ReadingAndWritingImageFiles.rst

Signed-off-by: Megha S <megha199501@gmail.com>

* Addressed review comments

Signed-off-by: Megha S <megha199501@gmail.com>

* Changing from std::clamp to Imath::clamp

Signed-off-by: Megha S <megha199501@gmail.com>

---------

Signed-off-by: Megha S <megha199501@gmail.com>
2024-02-15 17:19:01 -08:00
annguyen-ilm 467e7e58ff #1545 Fix formatting of sample exr file in OpenEXRFileLayout.rst - 3rd attempt (#1587)
* Replaced the sample exr file code blocks with a grid table formatted with bytes of the sample file in one column. The value in the second column and the third column being the description of the bytes and value.

Signed-off-by: An Nguyen <annguyen@ilm.com>

* * Updated so the ascii values for the bytes are aligned to each byte.
* Gave the table a title and reduce the width to 50%

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Added missing 4 bytes missing from the dataWindow value and displayWindow value

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Added the sample.exr file

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Annotated the attribute values more for the header. Should be a bit clearer.

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Adding the sample.exr file was documented.

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Added download link to the sample.exr file.

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Move the download link above the table. Updated the paragraph before the table to describe the table

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Move the sample.exr image into the downloads directory to match the target destination naming scheme to avoid confusion where the files go when built

Signed-off-by: An Nguyen <annguyen@ilm.com>

* Updated the table to annotate the type and literal as type.

Signed-off-by: An Nguyen <annguyen@ilm.com>

---------

Signed-off-by: An Nguyen <annguyen@ilm.com>
2024-02-15 17:19:01 -08:00
peterhillman 55b199c13e add deep id/manifest tools and doc (#1595)
* add deep id/manifest tools and docs

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* fix const-ness in deepidexample

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* fix link on doc, better variable name

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* add discussion of cryptomatte and deep compositing

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* fix names of cryptomatte ID channels

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

---------

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
2024-02-15 17:19:01 -08:00
Dave Sawyer 8061f57626 Remove some dead code when writing (#1592)
The file version is set to 2 above for writing files (it is impossible write version 1 data). Please refer to the history of history of ImfDwaCompressor.cpp or look at the reading code for details on the version 1 format.

Signed-off-by: Dave Sawyer <kingsawyer@gmail.com>
2024-02-15 17:19:01 -08:00
Anton Dukhovnikov 88cd3c713b Fix issue with decompressing fp32 dwa files (#1591)
There was an issue with the data type not passed to the DCT decompressor in the DWA decoder. That caused 32 bit DWA images to look squashed, as the decompressed 16 bit values were not getting expanded back to 32 bit.

Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
2024-02-15 17:19:01 -08:00
Ben Grimes 0414107b3f Add tests for the Header class. (#1577)
These are intended to exercise methods that are currently not covered by
other tests according to the coverage report.

Signed-off-by: Ben Grimes <bgrimes@ilm.com>
2024-02-15 17:19:01 -08:00
cdleu430 38c4b59e08 adding better error reporting for bin tests (#1578)
forgot a few things

Signed-off-by: cdleu430 <cleu@ilm.com>
2024-02-15 17:19:01 -08:00
Barnaby Robson 74776cbaf8 python-wheels.yml - add arm64 builds for macOS (#1579)
The CI platform that builds the wheels is Intel based and
by default only builds Intel wheels.

Modern Macs are all based on Apple Silicon so to support them
we need to also build arm64. This is done via cross compiling.

It is not possible to test when cross compiling according to:

https://cibuildwheel.readthedocs.io/en/stable/faq/#how-to-cross-compile

Signed-off-by: Barnaby Robson <brobson@ilm.com>
2024-02-15 17:19:01 -08:00
Barnaby Robson 00ee0fb31b python-wheels.yml - bumps cibuildwheel version (#1576) 2024-02-15 17:19:01 -08:00
Barnaby Robson d9360a608b fix typo in README.md (#1575)
* fix typo in README.md

change make -> cmake

Signed-off-by: Barnaby Robson <brobson@ilm.com>

* removes mkdir.

Suggested by Milos in review. I tested it and it works.

Signed-off-by: Barnaby Robson <brobson@ilm.com>

---------

Signed-off-by: Barnaby Robson <brobson@ilm.com>
2024-02-15 17:19:01 -08:00
ianianda 9a999c95b6 install.rst - update $ to % in the example shell prompts (#1570)
Signed-off-by: ianianda <wyking1030@gmail.com>
2024-02-15 17:19:01 -08:00
Kimball Thurston 0b3f83fde6 check and control reduceMemory and reduceTime in stream mode (#1635)
exrcheck by default uses file mode, but the fuzzer and exrcheck -s use
stream mode, need to respect the memory and time flags consistently on
that path as well.

Will address OSS-Fuzz 66612, although real fix underlying is in #1634

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-02-15 17:19:01 -08:00
Cary Phillips 7adf2c8f6f Remove duplicate line in release-notice.yml
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-11 20:14:08 -08:00
Cary Phillips c0208feee9 Add PR 1630 and 1632 to release notes
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-10 11:17:34 -08:00
Kimball Thurston d5cc7b7ebe adjust checks for core to better match c++ checks (#1632)
The core checks were not setting the same image / tile size limits and
not disabling reads at quite the same level.

Note: the core check does not read the entire image into a contiguous
slice, so does not replicate the maximum deep sample checks in the same
way, this is a source of potential false-negative failures

This should address OSS-Fuzz 66491 and 66489 (different forms of the
same failure where a large sample size allocation was happening), and
are only constrained memory (2.5Gb) issues.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-02-10 11:11:59 -08:00
Kimball Thurston d8cb68dfd6 fix issue with unpacking sample counts (#1630)
When unpacking sample counts as "individual" counts (no longer
monotonic), it writes the total sample count to a value 1 past the
individual sample counts, but this is not in the packed data, so do not
expect to unpack that many values. The buffer just needs to be allocated
one value larger to avoid write past end of buffer which is taken care
of in the update_pack_unpack_ptrs function

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-02-10 11:11:33 -08:00
Cary Phillips 280606593f Add CVE-2023-5841
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-04 12:34:04 -08:00
Cary Phillips 561969efe2 Bump version for v3.2.2
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-04 12:27:07 -08:00
Cary Phillips e0cb398300 Release notes for v3.2.2
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-04 12:26:24 -08:00
Cary Phillips 5c0381835d Add slack release notifier workflow
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-04 12:23:16 -08:00
Cary Phillips 8902ae6e71 Require sphinx 5.0 (#1617)
Apparently now required by other dependencies

Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-04 12:23:04 -08:00
Cary Phillips f996a5f076 Release notes for v3.1.12
Signed-off-by: Cary Phillips <cary@ilm.com>
2024-02-04 12:22:27 -08:00
Kimball Thurston 8bedf106ef Fix CVE 2023 5841 (#1627)
* enable deep file checks for core

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* fix possible int overflow

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* fix validation of deep sample counts

Addresses CVE-2023-5841, fixing sample count check to not only check
against 0 but previous sample as well.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* add clarifying comment

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

---------

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2024-02-04 12:18:24 -08:00
737b2707a0 v3.2.1 commits and release notes (#1569)
* Propagate OPENEXR_INSTALL_PKG_CONFIG to internal Imath (#1531)

* Propagate OPENEXR_INSTALL_PKG_CONFIG to internal Imath

If OpenEXR is installing a pkg-config file, then the internal Imath
build (if there is one) should install it, too.

Also, add an explicit release version variable to the .pc file.

This is in preparation for the python wheel build to pick up the
version settings from the pkg-config files.

Signed-off-by: Cary Phillips <cary@ilm.com>

* remove version= from OpenEXR.pc

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Remove check for _MSC_VER in internal_cpuid.h (#1528)

As noted in #1445, _MSC_VER should only be used to detect msvc, not
for Windows. The _WIN32 check should be sufficient. The extra check
for _MSC_VER fails when cross-compiling from Linux to Windows.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix warnings in multipartExamples.cpp (#1533)

* Fix warnings in multipartExamples.cpp

Signed-off-by: Cary Phillips <cary@ilm.com>

* fix indentation

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix warnings from cross-compiling with x86_64-w64-mingw32-gcc-posix (#1534)

* Fix compiler warnings from x86_64-w64-mingw32-g++-posix

* MSVCRT doesn't recognize printf("%l") so PRIu64 doesn't work, it
  expects "%I64u".

* Add to the cases that disable a strncpy warning

Signed-off-by: Cary Phillips <cary@ilm.com>

* %zu for size_t

Signed-off-by: Cary Phillips <cary@ilm.com>

* revert attempt to fix PRIu64 warnings

Signed-off-by: Cary Phillips <cary@ilm.com>

* revert blank line

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix OPENEXR_VERSION_HEX (#1539)

* Fix OPENEXR_VERSION_HEX

* fix syntax error
* remove unnecessary uint32_t cast
* add validation test

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add #if statement with OPENEXR_VERSION_HEX

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* OPENEXR_INSTALL_PKG_CONFIG is on by default, even on Windows (#1541)

There seems to be no downside to generating the OpenEXR.pc file even
on Windows, so for consistency, apply the setting to all platforms.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Remove SPDX license identifier in LICENSE.md

Signed-off-by: Cary Phillips <cary@ilm.com>

* Python wheel setup gets version from OpenEXR.pc/Imath.pc (#1536)

* Python wheel setup gets version from OpenEXR.pc/Imath.pc

OpenEXR and Imath have indepdenent versions that may not match. The
.pc files appear to be the simplest way to extract the versions and
library suffixes.

Running pkg-config itself doesn't work on Windows, hence the manual
file parsing.

Signed-off-by: Cary Phillips <cary@ilm.com>

* =

Signed-off-by: Cary Phillips <cary@ilm.com>

* Remove -DOPENEXR_INSTALL_PKG_CONFIG=ON since it's now on by default

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Default value for chromaticities attribute constructor in exrstdattr (#1540)

Signed-off-by: Cary Phillips <cary@ilm.com>

* Update openexr_deps.bzl (#1565)

Signed-off-by: Vertexwahn <julian.amann@tum.de>

* Bazel: Improve module (#1562)

Signed-off-by: Vertexwahn <julian.amann@tum.de>

* Set build-shared:OFF for Static build (#1557)

Looks like this somehow we've been building shared when we meant to be
building static.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Omit OPENEXR_IMAGES_TAG from test image url if empty (#1560)

This allows the url for the test images to reference a local file:

  cmake -DOPENEXR_IMAGES_REPO=file:///my/clone/of/openexr-images -DOPENEXR_IMAGES_TAG=""

which avoids the remote downloading of the test images at cmake time.

Also, mention the test images in the install docs.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Clean up handling of libdeflate when linking static  (#1561)

* Set EXR_DEFLATE_LIB properly for static linking

This leads OpenEXRCore/CMakeLists.txt to do:

    target_link_libraries(OpenEXRCore PUBLIC libdeflate)

instead of:

    target_link_libraries(OpenEXRCore PUBLIC PkgConfig::deflate)

which is not recognized. With a target link library of
`PkgConfig::deflate`, the static build of the OpenEXR libraries builds
successfully, but configuring an application against those static
libraries fails, saying it can't find `PkgConfig::deflate`.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add -ldeflate to pkgconfig for static builds

When static linking and referencing an external libdeflate (i.e. not
fetching and building internally), OpenEXR.pc needs -ldeflate.

This also adds a test for this condition to the CI's validation script.

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Don't trigger ci/bazel/ossfuzz builds on pushes/PRs to src/wrappers (#1532)

No need to rebuild/test OpenEXR on changes to the python wheels.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Set minimal permissions for workflow python-wheels.yml (#1530)

The exact same changes done on other workflows through the PR #1417

Signed-off-by: Diogo Teles Sant'Anna <diogoteles@google.com>

* Release notes for 3.2.1

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix Imf/Iex/IlmThread namespaces in python bindings and website code (#1568)

* Fix Imf/Iex/IlmThread namespaces in python bindings and website code

Use OPENEXR_NAMESPACE, IEX_NAMESPACE, ILMTHREAD_NAMESPACE instead of
Imf, Iex, IlmThread, to support custom settings.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Use Iex:: namespace in example code instead of IEX_NAMESPACE

Requires this in all.cpp:

  namespace Iex = IEX_NAMESPACE;

Signed-off-by: Cary Phillips <cary@ilm.com>

* use #define Iex

Signed-off-by: Cary Phillips <cary@ilm.com>

* remove explicit Iex namespace

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>

* Bump version to 3.2.1

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
Signed-off-by: Vertexwahn <julian.amann@tum.de>
Signed-off-by: Diogo Teles Sant'Anna <diogoteles@google.com>
Co-authored-by: Vertexwahn <julian.amann@tum.de>
Co-authored-by: Diogo Teles Sant'Anna <diogoteles@google.com>
2023-09-24 22:46:06 -04:00
Cary Phillips 456bf42dc2 Pin IMATH_TAG to v3.1.9
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-28 10:56:26 -07:00
Cary Phillips fdaee4bd27 Remove -dev setting from release type
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-28 10:50:44 -07:00
Cary Phillips 4713cf0da6 OpenEXRConfig.h.in uses version extracted from openexr_version.h (#1527)
* OpenEXRConfig.h.in uses version extracted from openexr_version.h

The logic was already in place to extract the version from
`openexr_version.h`, so the `.in` file just needed to reference the
proper CMake variables. This also duplicates the `OpenEXR_VERSION_*`
settings to `OPENEXR_VERSION_*`.

Signed-off-by: Cary Phillips <cary@ilm.com>

* bazel

Signed-off-by: Cary Phillips <cary@ilm.com>

* comment

Signed-off-by: Cary Phillips <cary@ilm.com>

* fix formatting of core version test error message

Signed-off-by: Cary Phillips <cary@ilm.com>

* fix extra comparison test

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-28 10:45:58 -07:00
Cary Phillips b2cfe364db Add 1523, 1525, 1527 to notes
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-28 09:32:39 -07:00
Vertexwahn a8609d9252 Add bzlmod support (#1525)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-08-28 09:29:05 -07:00
Cary Phillips 311c6e691e Add DEPENDENCIES Imath::Imath for OpenEXRCore (#1523)
This frees exrinfo and any other external application from any special
settings to pick up the necessary Imath #includes.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-28 09:28:57 -07:00
Cary Phillips 22b99053b9 Release notes and news for v3.2.0 (#1515)
* release notes for v3.1.10

Signed-off-by: Cary Phillips <cary@ilm.com>

* fix typos in CHANGES.md

Signed-off-by: Cary Phillips <cary@ilm.com>

* update release date

Signed-off-by: Cary Phillips <cary@ilm.com>

* release notes for v3.1.11

Signed-off-by: Cary Phillips <cary@ilm.com>

* Release notes and news for 3.2.0

Signed-off-by: Cary Phillips <cary@ilm.com>

* add 1520,1519,1518,1517,1516

Signed-off-by: Cary Phillips <cary@ilm.com>

* push release date; fix news links/formatting

Signed-off-by: Cary Phillips <cary@ilm.com>

* add 1473, 1522; fix formatting

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-17 14:14:08 -07:00
Nick Porcino 15aa9a726c consolidate project configurations to one place (#1473)
* Consolidate external project includes to openexr_conf.h

Signed-off-by: Nick Porcino <meshula@hotmail.com>

* Add path for ImathConfig.h

Signed-off-by: Nick Porcino <meshula@hotmail.com>

* Add missing dependency on OpenEXR::Config to exrinfo

Signed-off-by: Nick Porcino <meshula@hotmail.com>

* Rename openexr_conf.h to openexr_config.h

Signed-off-by: Nick Porcino <meshula@hotmail.com>

* Add Imath dependency to OpenEXRCore

Signed-off-by: Nick Porcino <meshula@hotmail.com>

---------

Signed-off-by: Nick Porcino <meshula@hotmail.com>
2023-08-17 14:06:36 -07:00
Cary Phillips ce7d8606d1 Rename cifuzz workflow to OSS-Fuzz, and filter out unnecessary triggers (#1522)
This name is more consistent with the others. And the workflow does
not need to run on changes to the website or website source.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-17 14:03:35 -07:00
Cary Phillips 318536c09e Streamline Python wheel workflow, and add tests and a CMake setup for bindings (#1517)
- Remove the libdeflate patch, not actually necessary
- Add a CMake build setup, controlled ``OPENEXR_BUILD_PYTHON``, off by default
- Update the doc strings
- Add ``#define PY_SSIZE_T_CLEAN``, apparently required in Python 3.10
  for ``Py_BuildValue("s#")``. PreviewImage attributes crash
  otherwise.
- Add a more extensive unit test
- Disable building PyPy wheels, since the bindings don't work properly
  (the ``channels()`` method fails in ``test_unittests.py`` when built
  against PyPy)

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-15 16:18:52 -07:00
Cary Phillips aed455ff67 Separate workflow for the website (#1513)
The website does not need to be built on changes to source code, only
on changes in the "website" directory. And the main CI builds/tests
don't need to be triggered by website changes.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-15 16:01:53 -07:00
Anton Dukhovnikov faceebdfa1 fix memory leaks in exrmultipart (#1520)
* fix memory leaks in exrmultipart

Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>

* remove unneeded change

Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>

---------

Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
2023-08-15 16:00:34 -07:00
Vertexwahn e8809d45e3 Bazel support: Simplify use of libdeflate dependency (#1518)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-08-14 17:22:35 -07:00
Vertexwahn e1a8ce0831 Remove .bazelrc file (#1519)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-08-14 15:53:12 -07:00
Cary Phillips 69b1297563 Website "Attributes" page now describes all attributes (#1511)
* Website "Attributes" page now describes all attributes

This gathers all the attribute definitions onto a single page, both
required and optional, and organizes them into logical groups. It also
documents each attribute's type.

Signed-off-by: Cary Phillips <cary@ilm.com>

* update display/data window definitions

Signed-off-by: Cary Phillips <cary@ilm.com>

* clarify some definitions

Signed-off-by: Cary Phillips <cary@ilm.com>

* lose the status column

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-14 09:13:59 -07:00
Vertexwahn 9852be60a5 Bazel support: Remove Bazel specific example and use same examples as CMake build (#1516)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-08-13 16:41:45 -07:00
Cary Phillips 0dba5e3663 Deprecate renderingTransform and lookModTransform (#1510)
As discussed in #1379, these are obsolete. This leaves them in place
but marks them as deprecated.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-13 16:41:29 -07:00
Cary Phillips d688d05d99 Initialize regs[] to 0 in check_for_x86_simd (#1509)
gcc warns of a potentially uninitialized memory reference, in the case
where ``__get_cpuid()`` fails to assign values to all its parameters.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-09 10:12:34 -07:00
Cary Phillips 5bd66ff6ea Rename "docs" to "website" (#1504)
* Rename "docs" to "website"

"website" is a more accurate term for the majority of the content that
has been under ``docs``, with the exception of the tool manpages, so:

- The website source now lives in the ``website`` subdirectory (was ``docs``)
- The CMake option is now ``BUILD_WEBSITE`` (was ``BUILD_DOCS``)
- The new CMake target ``website`` now builds the website source (via doxygen, sphinx, etc)
- The CI job is called "Website" (was ``Docs``)
- The CMake target ``docs`` now installs just the tool manpages
- The CMake option ``OPENEXR_INSTALL_DOCS`` controls whether to install the manpages, and defaults to OFF
- [website/install.rst](website/install.rst) explains the process and dependencies

Signed-off-by: Cary Phillips <cary@ilm.com>

* remove src subdir

Signed-off-by: Cary Phillips <cary@ilm.com>

* build website/src; mention posix

Signed-off-by: Cary Phillips <cary@ilm.com>

* max

Signed-off-by: Cary Phillips <cary@ilm.com>

* clamp

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-07 09:09:48 -07:00
Cary Phillips 772208b45d Reorganize share/util and remove unnecessary files (#1503)
- Move util under share
- Move the scripts under share into share/util
- The . files in src/bin appear to have been committed unncessarily long ago

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-07 09:08:37 -07:00
Anton Dukhovnikov 09f8aeae66 multipart code examples (#1502)
Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
2023-08-06 16:37:38 -07:00
Yaakov Selkowitz ebeb5676cb Fix CPUID detection with -march=x86-64-v3 (#1507)
When compiling for x86-64-v3 (or with -mavx -mf16c), bypass the CPUID
detection entirely, as osxsave is not (nor need be) defined in that
case.

Fixes: #1459

Signed-off-by: Yaakov Selkowitz <yselkowi@redhat.com>
2023-08-06 16:36:59 -07:00
Cary Phillips 8f6849f6a8 Add missing copyright/license specifiers (#1505)
* Add missing copyright/license specifiers

Signed-off-by: Cary Phillips <cary@ilm.com>

* revert CODEOWNERS

Signed-off-by: Cary Phillips <cary@ilm.com>

* revert .bazelversion

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-03 17:09:34 -07:00
Kimball Thurston 726fde32bc Add simple abi checker util (#1428)
* Add copyright clause

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Add abi_check folder to git ignore

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Add initial version of abi check wrapper script

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

---------

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-08-03 08:17:02 -07:00
Cary Phillips ce8f39a23a Add website example source files to the CMake build for validation (#1501)
- Include all .cpp files in `docs/src` in `docs/src/all.cpp` and add
  it as a build dependency. This validates that it compiles, although
  there's no execution so it still doesn't validate correct behavior.

- Move larger code-blocks from ReadingAndWritingImageFiles.rst into
  individual files in `docs/src`

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-03 08:08:29 -07:00
Cary Phillips f0c76e1bff Add 2023 Virtual Town Hall to news (#1500)
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-01 17:48:24 -07:00
Cary Phillips 8f8be506c9 Add detailed instructions for making both patch and major/minor release (#1471)
* Add detailed instructions for making both patch and major/minor release

This documents the way I've been doing it, I'm certainly open to
improvements. Certainly a lot of this could conceivably be automated.

The key element for a patch release is the SO version and ABI
compatibility, and our SO numbering scheme still needs simplification.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Update versioning process with the new policy and ``openexr_version.h``

Signed-off-by: Cary Phillips <cary@ilm.com>

* mention IMATH_TAG in the patch and major/minor release instructions

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-01 08:53:20 -07:00
Cary Phillips 649b25473b Update and simplify SO versioning policy (#1498)
* Update and simplify SO versioning policy

This change retires the "libtool" versioning scheme and adopts a
policy of appending the ``MAJOR.MINOR.PATCH`` software release name to
the SONAME to form the real name of the shared library.

The SOVERSION is specified via the ``OPENEXR_LIB_SOVERSION`` setting
in ``CMakeLists.txt`` and is the single number that increments
whenever, and only when, the ABI changes in non-backwards-compatible
ways. In practice, this corresponds to major and minor releases.

The resulting real shared library file names look like, for example,
``libOpenEXR.so.31.3.2.0``, where ``libOpenEXR.so.31`` is the SONAME
and ``.3.2.0`` identifies the corresponding software release.

This naming scheme helps reinforce the correspondence between the
shared library's real file name and the software release it
corresponds to, moreso than would be indicated by a single increasing
number.

By OpenEXR project policy and discussion of the technical steering
committee, the additional versioning information in the libtool
versioning scheme is too confusing and error-prone to follow, without
offering additional practical benefit.

Documentation is in ``CMakeLists.txt`` and in ``docs/install.rst``.

Signed-off-by: Cary Phillips <cary@ilm.com>

* remove reference to libtool

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-08-01 08:43:10 -07:00
Jose Luis Cercós Pita af87558c60 Python wheels (#1487)
* Let's see if the wheels are building

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Enable the building on the python branch to can test it

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Wrong path

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Windows...

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Copy the wrapper source files on the main folder

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Skip the OpenEXR examples

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Fixed the library names

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Install pytest to run the tests

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Let's try the cibuildwheel way

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Maybe this way...

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Use require instead of custom command

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Simplified the test

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Specifically instruct pytest to run the tests in the folder

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Fix the test

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Disable threading

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Reenable threading

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Link also OpenEXRCore

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* CIBW_BEFORE_BUILD is the same in all platforms

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Imath 3.1.9

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* List the exported symbols

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* List the exported symbols

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Link everything available

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Link everything available

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Link statically also libdeflate

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* tar.gz, not zip

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* libdeflate static lib name is not found by openexr on windows

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Syntax error

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Try to fix the deflate linking on windows

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* Remove the need of the wildcard while testing

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

* BSD license

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>

---------

Signed-off-by: Jose Luis Cercos-Pita <jlcercos@gmail.com>
2023-07-28 06:57:02 -07:00
Anton Dukhovnikov 881f4989ce adds deep examples, fixes the deep examples in docs (#1493)
Signed-off-by: Anton Dukhovnikov <antond@wetafx.co.nz>
2023-07-28 06:42:23 -07:00
Cary Phillips da9f785d6c Rename IMATH_REPO/TAG to OPENEXR_IMATH_REPO/TAG and update install docs (#1495)
For consistency with ``OPENEXR_DEFLATE_REPO`` and other config options.

Also, add docs section for the ``DEFLATE`` options.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-07-28 06:42:01 -07:00
Vertexwahn 34fd6433b9 Bazel update (#1496)
* Bazel: Update to Bazel 6.3.0

Signed-off-by: Vertexwahn <julian.amann@tum.de>

* Bazel: Use macOS Ventura in CI

Signed-off-by: Vertexwahn <julian.amann@tum.de>

---------

Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-07-28 06:41:33 -07:00
Joseph Goldstone cfd1c76eab Reorder attributes in doc to match order in header (#1494)
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-07-26 09:10:36 -07:00
Kimball Thurston 54dd0411dd Fix handling for corrupt number of DC components (#1484)
When the number of DC components has been incorrectly stored in the dwa
subheader, this causes a cascade of errors, resulting in out of bounds
access. Instead, track how many we've read and detect when we're out as
soon as possible

Fixes OSS-Fuzz #59457

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-07-23 14:55:27 -07:00
Kimball Thurston 83c57cb4b9 Revert pre-computed values (#1488)
It would appear the precomputed values cause differences from the
specific computed values on other architectures.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-07-23 14:55:07 -07:00
Joseph Goldstone ae32ed6c6e Add sensorCenterOffset, sensorOverallDimensions, sensorPhotositePitch… (#1489)
* Add sensorCenterOffset, sensorOverallDimensions, sensorPhotositePitch and sensorAcquisitionRectangle optional standard attributes

Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>

* Add descriptions of sensorCenterOffset, sensorOverallDimensions, sensorPhotositePitch, and sensorAcquisitionRectangle to doc page for standard optional attributes

Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>

* Fix typo in, and use correct inter-item spacing for Sphinx, in standard optional attributes doc

Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>

---------

Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-07-18 11:44:57 -07:00
peterhillman e452e5fd23 Readdress #1456: disallow NaNs in testOptimizedInterleavePatterns ... (#1490)
* Readdress #1456: disallow NaNs in testOptimizedInterleavePatterns unless both writing and reading as half

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* fix typos

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

---------

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
2023-07-17 15:27:27 -07:00
Cary Phillips 4d683ec76e Replace ILMBASE_THREADING_ENABLED with ILMTHREAD_THREADING_ENABLED (#1486)
A remnant vestage from v2.X

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-07-13 09:09:51 -07:00
Cary Phillips 2e27f41b79 Add ImfMisc.h and ImfCompressor.h as installed headers (#1483)
I tried compiling the source to ``exrheader`` against an installation
of OpenEXR and it failed because it includes ``ImfMisc.h`` and
``ImfCompressor.h``, which were not included in the list of installed
headers.

It seems that code should be buildable by the public API, so those
headers should, in fact, be distributed.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-07-10 08:30:58 -07:00
Cary Phillips c9b6b73e1f Add OPENEXR_MISSING_ARM_VLD1 workaround to internal_dwa_simd.h (#1482)
Addresses #1477

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-07-10 20:59:00 +12:00
Nick Porcino 811c941e42 Fix range check in dwa compressor (#1472)
Signed-off-by: Nick Porcino <meshula@hotmail.com>
2023-07-10 18:27:39 +12:00
Peter Urbanec 114cc6453b Fix Huffman performance regression on Linux/clang (#1480)
PR #1323 introduces a nested #ifdef check that results in a performance
regression on Linux systems that use the clang compiler. This is because
the check for __clang__ succeeds, but the nested check for __APPLE__
fails. As a result, the elif case is not taken on Linux.

Fixes issue #1479

Signed-off-by: Peter Urbanec <peterurbanec@users.noreply.github.com>
2023-07-09 11:52:00 -07:00
Christina Tempelaar-Lietz f3fc12b490 Update CI with vfx2023 Linux jobs. (#1475)
Signed-off-by: Christina Tempelaar-Lietz <xlietz@gmail.com>
2023-07-09 11:51:40 -07:00
Md Sadman Chowdhury a30498e76e fix dupe word typos (#1481)
Signed-off-by: sadman <61442059+SpicyCatGames@users.noreply.github.com>
2023-07-05 20:17:13 -04:00
Cary Phillips 2c9bf6f8a2 Fix gcc-11 warnings: signed/unsigned integer comparison, unused variables (#1463)
* Fix gcc-11 warnings: signed/unsigned integer comparision, unused variables

Signed-off-by: Cary Phillips <cary@ilm.com>

* declare loop variable i as unsigned int

Signed-off-by: Cary Phillips <cary@ilm.com>

* uncomment-out failable_free

Signed-off-by: Cary Phillips <cary@ilm.com>

* add commented-out assignment of failable_free as TODO

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-07-04 07:12:30 -07:00
Christoph Gohlke e4bb5997b9 Fix build error on win_arm64 (#1447)
* Fix build error on win_arm64

Signed-off-by: Christoph Gohlke <cgohlke@cgohlke.com>

* Simplify fix for build error on win_arm64

Signed-off-by: Christoph Gohlke <cgohlke@cgohlke.com>

---------

Signed-off-by: Christoph Gohlke <cgohlke@cgohlke.com>
2023-06-30 09:01:49 -07:00
Cristian Martínez fe463369d1 Fix build with i386 and musl libc (#1470)
The current code asumes glibc == linux. This patch extends support to all non-glibc Linux systems.

Signed-off-by: Cristian Othón Martínez Vera <cfuga@cfuga.mx>
2023-06-29 16:09:10 -07:00
zengwei2000 a5de20e817 Fix the code contains unhandled character (#1469)
It looks like there are some non-ASCII characters present in the code. Specifically, the character "–" in the line:

Signed-off-by: zengwei2000 <102871671+zengwei2000@users.noreply.github.com>
2023-06-27 14:07:37 -07:00
zengwei2000 0853c73bdf Fix the code contains unhandled character (#1466)
It looks like there are some non-ASCII characters present in the code. Specifically, the character "–" in the line:

Signed-off-by: zengwei2000 <102871671+zengwei2000@users.noreply.github.com>
2023-06-26 19:30:32 -07:00
Kimball Thurston 56ca398f36 Remove old zlib reference (#1468)
We have now switched to lib deflate, remove vestige of zlib usage

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-06-26 09:41:21 -07:00
Kimball Thurston f1d662064f Fix cpu detection of sse2 on non-64 x86 (#1467)
* Fix cpu detection of sse2 on non-64 x86

Previous code accidentally elided the i386 (i.e. non-64 bit versions of
x86 compiles). This refactors and simplifies the ifdef snarl to clarify
and fix that.

Fixes #1459

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Fix mismatch with windows and enable avx support check there

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Disable avx detection under msvc for now

We require gcc / clang style inline asm for avx support, detecting it
properly causes problems for the dwa support which uses that. Disable
again.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

---------

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-06-26 09:40:46 -07:00
Cary Phillips 1367e0a0da Fix link typos in news.rst (#1465)
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-06-26 09:27:48 -07:00
Cary Phillips 049eb3aa38 Fix macOS and Windows build failures when threading is disabled (#1462)
* Fix macOS and Windows build failures when threading is disabled

Addresses #1455

The logic around which implementation of the IlmThread::Semaphore
class to use is now consolidated into the block of code that deciphers
the platform and specifies the #includes, rather than spread across
multiple files.

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add macOS/Windows builds with threading disabled

Signed-off-by: Cary Phillips <cary@ilm.com>

* Fix typo with ILMTHREAD_SEMAPHORE_OTHER, and add missing macOS includes

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add threads-enabled='ON' so it shows up in the job name

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-06-26 09:26:43 -07:00
Cary Phillips 11a99dfd58 v3.1.9/v3.1.8 notes and news (#1464)
* v3.1.9 release notes

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add 1443, 1457, 1461 to release notes

Signed-off-by: Cary Phillips <cary@ilm.com>

* Add recent releases to news

Signed-off-by: Cary Phillips <cary@ilm.com>

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-06-25 20:53:56 -07:00
peterhillman fe2a8f5817 don't use NaNs/infs in testOptimizedInterleavePatterns (#1461)
* don't use NaNs/infs in testOptimizedInterleavePatterns

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

* allow NaN/inf halfs in testOptimizedInterleavePatterns if not casting to float

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>

---------

Signed-off-by: Peter Hillman <peterh@wetafx.co.nz>
2023-06-22 16:08:00 -07:00
Cary Phillips ff27eeb9e4 CIFuzz skips PRs that only modify markdown (#1453)
Similar to ci_workflow.yml

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-06-20 15:29:39 -07:00
Cary Phillips 7447f9930a Use security@openexr.com for consistency (#1452)
openexr.com forwards to openexr.org, but for consistency, let's refer
to all email addresses as @openexr.com, to match the website.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-06-19 16:31:36 -07:00
Cary Phillips 3147ffacdf Add OPENEXR_IMF_INTERNAL_NAMESPACE for WidenFilename (#1454)
Fixes #1446

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-06-18 16:08:38 -07:00
Vertexwahn e504fb2ec3 Bazel support: Switch back to VS2019 due to a toolchain issue in Bazel (#1457)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-06-16 12:21:16 -07:00
Vertexwahn 7a8ae78f8b Bazel bump imath (#1443)
* Bazel: Bump Imath to 3.1.9

Signed-off-by: Vertexwahn <julian.amann@tum.de>

* Bazel: Bump skylib version

Signed-off-by: Vertexwahn <julian.amann@tum.de>

---------

Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-06-14 17:36:10 -07:00
Sergey Fedorov 729f42648d compression.cpp: fix isnan (#1448)
Fixes: https://github.com/AcademySoftwareFoundation/openexr/issues/1412

Signed-off-by: Sergey Fedorov <vital.had@gmail.com>
2023-06-08 21:35:20 +12:00
Kimball Thurston 425d4b24e0 Fix scenario where malformed dwa file could read past end of buffer (#1439)
Fixes OSS-Fuzz 59382

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-29 19:19:02 +12:00
Vertexwahn 379a2884af Bazel update (#1438)
* Update Cache action in Bazel CI build

Signed-off-by: Vertexwahn <julian.amann@tum.de>

* Bazel support: Update #cmakedefines for Imath

Signed-off-by: Vertexwahn <julian.amann@tum.de>

---------

Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-05-26 14:54:27 -07:00
Vertexwahn 4d49374dc5 Fix macOS arm64 build (#1434)
Signed-off-by: Julian Amann <julian.amann@tum.de>
2023-05-26 11:15:39 -07:00
Vertexwahn af517234b3 Fix spelling mistakes (#1436)
Signed-off-by: Julian Amann <julian.amann@tum.de>
2023-05-26 11:07:49 -07:00
Vertexwahn 7fe4e3bfbc Bazel support: Update Imath to 3.1.8 (#1435)
Signed-off-by: Julian Amann <julian.amann@tum.de>
2023-05-26 11:05:50 -07:00
Kimball Thurston 6f235a803c fix out of bounds check with a full channel name vs. byte count (#1429)
Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-24 22:47:30 +12:00
Cary Phillips 200613925d Fix handling of builddir and cxxwarns in clang_coverage.sh (#1427)
Also, some ='s appeared to be missing on the -ignore-filename-regex lines

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-05-22 08:52:17 -07:00
Cary Phillips b4899a6788 Fix reference to the number of supported compression types (#1422)
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-05-21 12:24:55 -07:00
Kimball Thurston a5428248c1 Prevent re-download of images if already in place (#1426)
Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-21 21:13:09 +12:00
Kimball Thurston 9e47dfdfad prepare for new version of libdeflate with thread-safe alloc function mechanism (#1425)
Removes all other calls to internal_exr_alloc if there is a context,
allowing full memory allocator overload without setting global
functions.

Also cleanup code formatting

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-21 21:12:42 +12:00
Kimball Thurston a00bac506f Start working on improving test coverage (#1424)
* fix potential crash
* Add initial tests for half utility operations in core
* add dump of attr to support testing of debug code (coverage)
* Add simple script around running and generating coverage report locally using clang tools

---------

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-21 09:28:06 +12:00
Cary Phillips a91df5206e Document DWAA/DWAB compression in Technical Introduction (#1420)
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-05-19 13:57:53 -07:00
Kimball Thurston 447451f0a6 after other merges, need to fix include (#1421)
Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-19 22:46:15 +12:00
Kimball Thurston 62cf13cd69 ensure we are passing through valid function pointers (#1403)
libdeflate doesn't have the same fallback handling such that if
someone resets the pointers, allocations later will crash

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-19 20:41:49 +12:00
Diogo Teles Sant'Anna 39a77f22ae ci: set minimal permisisons on github workflows (#1417)
Signed-off-by: Diogo Teles Sant'Anna <diogoteles@google.com>
2023-05-18 13:29:55 -07:00
Sergey Fedorov 6773e77bad IlmThread: fix defines for older macOS: do not prefix with __ (#1416)
See: https://github.com/macports/macports-ports/pull/18711

Signed-off-by: Sergey Fedorov <vital.had@gmail.com>
2023-05-17 16:18:48 -07:00
Cary Phillips 2e4c5229e8 Add #include <cmath> for isnan (#1414)
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-05-17 08:55:02 -07:00
Kimball Thurston 7c40603eb2 Add dwa support to core (#1402)
* Fix nodiscard warning on gcc 13
* Add buffer range checks to huf code
* Refactor cpuid code for use in dwa
* Fix issue with big endian deep encoding of chunk table
* refactor to expose byte reordering zip compression uses for dwa
* expose option flag to enable headers to be more easily like old style headers
* fix potential issue with piz and not able to compress data small enough
* Restore piz tests
* Initial implementation of DWAA/B compression for Core
* write with legacy header during tests to make comparing bytes in files easier
* Initial support for validating exact match in file output between C / C++
* Enable DWAA/DWAB tests
* Older versions of MSVC have issues with specifying C11 for use of
stdalign.h and alignas macro. Work around this by targeting the lower
level macros / declspec instead of using C11 stdalign.h
* Add unit test for x86 cpu id checks
* Add alignment helper utility
* Add missing include guards
* Fix pedantic warnings
* Fix compile warnings. Core should now compile with
-Weverything
-Wno-reserved-identifier
-Wno-covered-switch-default
-Wno-cast-align
-Wno-overlength-strings

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-16 19:38:52 +12:00
Sergey Fedorov 7862c23a2b Use posix compat code for old macOS without libdispatch (#1409)
See: https://github.com/AcademySoftwareFoundation/openexr/issues/1405

Signed-off-by: Sergey Fedorov <vital.had@gmail.com>
2023-05-16 16:56:42 +12:00
Vertexwahn b7446c0ec5 Revert fix of spelling mistakes in PR messages (#1410)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-05-15 16:25:35 -07:00
Kimball Thurston 2dcc1b80e3 Shift MacOS versions in flight (#1411)
* Shift MacOS versions in flight

github has long deprecated version 10.15

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

* Fix versioning updates to match VFX platform with github supported o.s.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>

---------

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-05-15 16:20:34 -07:00
Sergey Fedorov 663708e53d internal_xdr.h: fix endian logic for Apple (#1408)
Fixes PPC builds as required for macports
See: https://github.com/AcademySoftwareFoundation/openexr/issues/1404

Signed-off-by: Sergey Fedorov <vital.had@gmail.com>
2023-05-13 23:23:48 -07:00
Cary Phillips cf19b5491b Deprecate exrbuild.cpp (#1381)
This code appears to have not made it through the v3.0 transition, the
associated CMakeList.txt has been lost. There isn't much in the git
history describing the program. It seems to do the same thing as
"exrmultipart --combine" so its benefit of maintaining it seems
minimal.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-05-12 10:23:18 -07:00
Vertexwahn 83210c7c7b Remove unused private member variable _maxScanLineSize (ABI break) (#1394)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-05-12 09:46:26 -07:00
Sergey Fedorov 9293eef977 internal_structs.h: __STDC_FORMAT_MACROS should be defined prior to inttypes.h (#1406)
Signed-off-by: Sergey Fedorov <vital.had@gmail.com>
2023-05-12 09:38:00 -07:00
Nick Porcino d2460f0192 Fix version h (#1399)
* More robust openexr_version.h handling
* hardcode versions for now until the vagaries of Bazel and linux install scripts can be sorted out

Signed-off-by: Nick Porcino <meshula@hotmail.com>
2023-04-29 00:26:02 -07:00
Nick Porcino 1f7de5aeef More robust openexr_version.h handling (#1398)
Signed-off-by: Nick Porcino <meshula@hotmail.com>
2023-04-29 00:04:43 -07:00
Vertexwahn 8c1fde8eca Fix spelling mistakes (#1396)
Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-04-27 13:22:33 -07:00
Vertexwahn 0d1d0c38f2 Bazel support update (#1395)
* Update Bazel version
* Apply buildifier on Bazel build files

Signed-off-by: Vertexwahn <julian.amann@tum.de>
2023-04-27 13:20:58 -07:00
Nick Porcino 9ef5625b19 Govern library version by OpenEXRVersion.h (#1386)
* Govern library version by openexr_version.h

Signed-off-by: Nick Porcino <meshula@hotmail.com>
2023-04-27 00:13:30 -07:00
Cary Phillips 80f798b0d7 remove debugging status message
Signed-off-by: Cary Phillips <cary@ilm.com>
2023-04-26 21:50:54 -07:00
Cary Phillips 6903f8a920 Tool manpages, doc page, and standardized --help messages
- Add manpages for the tool programs (exr2aces, exrenvmap, etc)
  - Pages are generated via help2man
  - Pages are installed into share/man

- Standardize the tool usage messages:
  * The output of --help goes to stdout, so that "exrheader --help | more" is easy
  * Usage output goes to stderr on mistakes like malformed arguments
  * Each program has a --version option
  * ImfMisc.h has a getLibraryVersion() that returns the
    CMAKE_OPENEXR_VERSION the library was compiled with (which might
    be mismatched with the headers currently being compiled.

- The website has a "Tools" page that describes the tools and usage,
  but also includes a pointer to oiiotool for any serious image
  processing utilities

- The website html output is no longer installed with the
  distribution. This was inadvertent and not helpful, a leftover from
  when "docs" referred to the .pdf technical documentation that now
  lives on the webpage.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-04-26 21:50:54 -07:00
Joseph Goldstone 2e24872d03 aperture and tStop have effectiveFocalLength as their numerator now, as per Cooke Optics
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-26 10:53:57 -07:00
Joseph Goldstone 714d90288b withdraw timecodeRate carryover from SMPTE ST 2065-4 in absence of compelling real-world use case
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-26 10:53:57 -07:00
Joseph Goldstone 9120defaf3 Move timecodeRate to be adjacent to framesPerSecond and add explanation of non-default rounding
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-26 10:53:57 -07:00
Joseph Goldstone eda96c308d framelines -> ascFramingDecisionList; UTF-8 clarification; improved descriptions of entrancePupilOffset and shutterAngle
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-26 10:53:57 -07:00
Joseph Goldstone d98a34bff4 Add missing ImfIntAttribute.h reference to ImfStandadAttributes.h; make the relationship between aperture and tStop less ambiguous.
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-26 10:53:57 -07:00
Joseph Goldstone 9ce8ef819a add framelines attribute to carry JSON-encoded frameline info; fix new unit test invocations to use same format as previous ones
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-26 10:53:57 -07:00
Joseph Goldstone 434a962771 Add selected SMPTE camdkit or camdkit-enabling standard optional attributes
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-26 10:53:57 -07:00
lilinjie 5aa18bca26 fix typo
Signed-off-by: lilinjie <lilinjie@uniontech.com>
2023-04-25 17:19:37 -07:00
Kimball Thurston ef4b710f73 Switch to embedding libdeflate into EXRCore (#1387)
Switches to embedding upstream (MIT license) libdeflate vs linking
against external library, functions should be private / hidden by
default.

Like Imath, enables one to use a system version or force using an
internally embedded version (OPENEXR_FORCE_INTERNAL_DEFLATE).
Further, the repository used can be controlled with
OPENEXR_DEFLATE_REPO and OPENEXR_DEFLATE_TAG cmake variables.

This centralizes all IETF RFC 1950 (zlib) compression into
the EXRCore library. This implies that the main C++ library
depends on EXRCore.

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-04-25 17:41:58 +12:00
Christina Tempelaar-Lietz faf1bc1e90 Updated Mac and Windows jobs for VFX platform 2023. (#1388)
Signed-off-by: Christina Tempelaar-Lietz <xlietz@gmail.com>
2023-04-25 17:40:26 +12:00
Kimball Thurston 358eec4516 Change setNumThreads to wait for thread start (#1291)
Fix Issue #890, issue with windows shutdown when exiting quickly prior to
threads actually starting. We do this by having a data block that is passed
by shared_ptr to the thread to avoid dereferencing a deleted object.

Further, greatly simplify the ThreadPool code by using atomic shared_ptr
functions instead of trying to manually implement something similar and
otherwise modernizing the thread code.

Fix a few potential null dereference locations and also fix an issue when
systems are overloaded enabling the TaskGroup destructor to destroy
the semaphore while code is still using it, causing undefined memory
corruption if some other thread immediately allocates that same block

Originally based on a proposed patch by Dieter De Baets @debaetsd

Signed-off-by: Kimball Thurston <kdt3rd@gmail.com>
2023-04-22 15:58:43 +12:00
Cary Phillips 67f7d05973 Update macOS installation instructions (#1382)
The recommendations for macOS were backwards. Homebrew is the
recommended installer. Macports is not recommended, as it's on v2.3.

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-04-14 06:22:14 -07:00
Joseph Goldstone 60611ccd5f Reorder attribute definitions in ImfStandardAttributes.h in functional groupings (#1379)
Signed-off-by: Joseph Goldstone <jgoldstone@arri.com>
2023-04-13 06:57:42 -07:00
Darby Johnston fc7f898ef0 Only install exrinfo when OPENEXR_INSTALL_TOOLS is on (#1377)
Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com>
2023-04-11 12:17:10 -07:00
Darby Johnston b6480cffe0 Fix typo in README.md (#1378)
Signed-off-by: Darby Johnston <darbyjohnston@yahoo.com>
2023-04-11 10:33:02 -07:00
Cary Phillips 71a7141556 Test Images page for website (#1372)
This adds a "Test Image" section to the website with a gallery of images from the test image repo https://github.com/AcademySoftwareFoundation/openexr-images, with a page for each image that shows the output of exrheader. Each image is a link to download the .exr file.

Preview it here: https://cary-ilm-openexr.readthedocs.io/en/docs-images/index.html

It's not perfect, but it's a decent start, feel free to suggest improvements to the layout or content. A few notes:

In lieu of setting up a way to view .exr images directly in a browser, I converted the .exr's in openexr-images to .jpg's. They are stored in the openexr-images repo and served to the website directly from github, so the OpenEXR distribution (which holds the website source) doesn't get bloated with extra image data. The download link downloads the source .exr image, not the .jpg.

This draft actually serves them from a branch of my fork of the openexr-images repo, but that can get fixed later.

The exr2rst.py script generates the rst (and embedded html) from the .exr's (by running exrheader) and the accompanying README's, so it's (relatively) easy to add new images.

---------

Major update to this, the .rst and the proxy .jpg’s are now generated automatically, so no need to maintain .jpg’s in the openexr-images repo.

The docs/test_images.txt file lists urls for .exr’s and README.rst files that define the contents of the “Test Images” page.

The docs/scripts/test_images.py script builds the index page and the per-image pages. It downloads the files via wget, then runs convert (ImageMagick) to generate the proxy .jpg’s, then runs exrheader to generate the tables of attribute values.

The script puts the auto-generated .rst files in the docs/_test_images subdirectory. Ideally, these would go in the build directory, but sphinx seems to want all .rst input under a single source root.

There's now a separate "Docs" CI job that builds the docs, so I removed all references to docs in the other jobs. It uses Ubuntu to mirror .readthedocs.yml. There's no need for the install_doxygen.sh and install_docs_env.sh scripts, the necessary installations are simple enough to do inline in the CI job.

---------

Signed-off-by: Cary Phillips <cary@ilm.com>
2023-04-07 15:42:56 -07:00
346 changed files with 25181 additions and 8162 deletions
-9
View File
@@ -1,9 +0,0 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
build --symlink_prefix=/ # Out of source build
# Uncomment this to treat C++ compile warnings as errors
#build --cxxopt=-Wall
#build --cxxopt=-Werror
#build --cxxopt=-Wextra
+1 -1
View File
@@ -1 +1 @@
6.0.0
7.0.2
+2
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
---
Language: Cpp
# BasedOnStyle: LLVM
+4 -1
View File
@@ -12,6 +12,9 @@ on:
- cron: "0 0 * * 0"
workflow_dispatch:
permissions:
contents: read
jobs:
# ---------------------------------------------------------------------------
@@ -83,7 +86,7 @@ jobs:
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
run: sonar-scanner -X -Dsonar.login=$SONAR_TOKEN
run: sonar-scanner -X
# ------------------------------------------------------------------------------
# Valgrind memcheck test
+65 -19
View File
@@ -6,74 +6,120 @@
name: Bazel
# Skip the run on *.md changes and on changes to the website, *except*
# for "website/src", since that code needs validation. There's a
# separate workflow for with website.
on:
push:
# Versioned branches and tags are ignored for OpenEXR <= 1.x.x
branches-ignore:
- RB-2.*
tags-ignore:
- v1.*
- v2.*
# Jobs are skipped when ONLY Markdown (*.md) files are changed
paths-ignore:
- '**.md'
paths:
- '**'
- '!**.md'
- '!website/**'
- 'website/src/**'
- '!src/wrappers/**'
pull_request:
branches-ignore:
- RB-2.*
tags-ignore:
- v1.*
- v2.*
paths-ignore:
- '**.md'
paths:
- '**'
- '!**.md'
- '!website/**'
- 'website/src/**'
- '!src/wrappers/**'
permissions:
contents: read
jobs:
build_and_test_ubuntu:
name: Linux Ubuntu 20.04 Bazel build <GCC 9.3.0>
runs-on: ubuntu-20.04
name: Linux Ubuntu 22.04 Bazel build <GCC 11.4.0>
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4.1.1
- name: Mount Bazel cache
uses: actions/cache@v2
uses: actions/cache@v4.0.0
with:
path: "/home/runner/.cache/bazel"
key: bazel-ubuntu
key: bazel-ubuntu-22
- name: Build
run: |
bazelisk build //...
bazelisk test //...
# Test without bzlmod
bazelisk build --noenable_bzlmod -- //...
bazelisk test --noenable_bzlmod -- //...
build_and_test_windows:
name: Windows Server 2022 build <Visual Studio 2022>
runs-on: windows-2022
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4.1.1
- name: Mount Bazel cache
uses: actions/cache@v2
uses: actions/cache@v4.0.0
with:
path: "/home/runner/.cache/bazel"
key: bazel-windows
key: bazel-windows-2022
- name: Build
run: |
bazelisk build //...
bazelisk test //...
# Test without bzlmod
bazelisk build --noenable_bzlmod -- //...
bazelisk test --noenable_bzlmod -- //...
build_and_test_macos:
name: macOS 12 Bazel build <Apple Clang14>
runs-on: macos-12
name: macOS 13 Bazel build <Apple Clang14>
runs-on: macos-13
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4.1.1
- name: Mount Bazel cache
uses: actions/cache@v2
uses: actions/cache@v4.0.0
with:
path: "/home/runner/.cache/bazel"
key: bazel-macos
key: bazel-macos-13
- name: Build
run: |
bazelisk build //...
bazelisk test //...
# Test without bzlmod
bazelisk build --noenable_bzlmod -- //...
bazelisk test --noenable_bzlmod -- //...
build_and_test_macos_M1:
name: macOS 14 Bazel build <Apple Clang14>
runs-on: macos-14
steps:
- uses: actions/checkout@v4.1.1
- name: Mount Bazel cache
uses: actions/cache@v4.0.0
with:
path: "/home/runner/.cache/bazel"
key: bazel-macos-14
- name: Build
run: |
bazelisk build //...
bazelisk test //...
# Test without bzlmod
bazelisk build --noenable_bzlmod -- //...
bazelisk test --noenable_bzlmod -- //...
+178 -178
View File
@@ -6,25 +6,38 @@
name: CI
# Run on all changes except:
# - doc file changes
# - changes to the website, *except* for "website/src", since that
# code needs validation. The website has a separate workflow
# - changes to the bazel config, since it has its own workflow
# - changes to the python bindings
# - changes to workflows other than this one
on:
push:
# Versioned branches and tags are ignored for OpenEXR <= 1.x.x
branches-ignore:
- RB-2.*
tags-ignore:
- v1.*
- v2.*
# Jobs are skipped when ONLY Markdown (*.md) files are changed
paths-ignore:
- '**.md'
paths:
- '**'
- '!**.md'
- '!website/**'
- 'website/src/**'
- '!bazel/**'
- '!src/wrappers/**'
- '!.github/workflows/**'
- '.github/workflows/ci_workflow.yml'
pull_request:
branches-ignore:
- RB-2.*
tags-ignore:
- v1.*
- v2.*
paths-ignore:
- '**.md'
paths:
- '**'
- '!**.md'
- '!website/**'
- 'website/src/**'
- '!bazel/**'
- '!src/wrappers/**'
- '!.github/workflows/**'
- '.github/workflows/ci_workflow.yml'
permissions:
contents: read
jobs:
# Linux jobs run in Docker containers, so the latest OS version is OK. macOS
@@ -47,8 +60,7 @@ jobs:
C++${{ matrix.cxx-standard }},
config=${{ matrix.build-type }},
shared=${{ matrix.build-shared }},
threads=${{ matrix.threads-enabled }},
docs=${{ matrix.build-docs }}>'
threads=${{ matrix.threads-enabled }}>'
# GH-hosted VM. The build runs in CentOS 7 'container' defined below.
runs-on: ubuntu-latest
container:
@@ -57,11 +69,11 @@ jobs:
image: aswf/ci-openexr:${{ matrix.vfx-cy }}
strategy:
matrix:
build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
build: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
include:
# -------------------------------------------------------------------
# VFX CY2022 - GCC
# VFX CY2023 - GCC
# -------------------------------------------------------------------
# Shared, Release
- build: 1
@@ -70,11 +82,10 @@ jobs:
cxx-standard: 17
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc9.3.1
compiler-desc: gcc11.2.1
label:
threads-enabled: 'ON'
vfx-cy: 2022
build-docs: 'ON'
vfx-cy: 2023
exclude-tests:
# Shared, Release, Threads OFF
@@ -84,11 +95,10 @@ jobs:
cxx-standard: 17
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc9.3.1
compiler-desc: gcc11.2.1
label:
threads-enabled: 'OFF'
vfx-cy: 2022
build-docs: 'OFF'
vfx-cy: 2023
exclude-tests:
# Shared, Debug
@@ -98,43 +108,40 @@ jobs:
cxx-standard: 17
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc9.3.1
compiler-desc: gcc11.2.1
label:
threads-enabled: 'ON'
vfx-cy: 2022
build-docs: 'OFF'
vfx-cy: 2023
exclude-tests:
# Static, Release
- build: 4
build-type: Release
build-shared: 'ON'
cxx-standard: 17
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc9.3.1
label:
threads-enabled: 'ON'
vfx-cy: 2022
build-docs: 'OFF'
exclude-tests:
# Static, Debug
- build: 5
build-type: Debug
build-shared: 'OFF'
cxx-standard: 17
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc9.3.1
compiler-desc: gcc11.2.1
label:
threads-enabled: 'ON'
vfx-cy: 2022
build-docs: 'OFF'
vfx-cy: 2023
exclude-tests:
# Shared, Release, C++14
- build: 5
build-type: Release
build-shared: 'ON'
cxx-standard: 14
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc11.2.1
label:
threads-enabled: 'ON'
vfx-cy: 2023
exclude-tests:
# -------------------------------------------------------------------
# VFX CY2021 - Clang
# VFX CY2023 - Clang 15.0
# -------------------------------------------------------------------
# Release
- build: 6
@@ -143,60 +150,49 @@ jobs:
cxx-standard: 17
cxx-compiler: clang++
cc-compiler: clang
compiler-desc: clang10
compiler-desc: clang15.0
label:
threads-enabled: 'ON'
vfx-cy: 2022
build-docs: 'OFF'
vfx-cy: 2023
exclude-tests:
# Debug
# -------------------------------------------------------------------
# VFX CY2023 - Clang 14.0
# -------------------------------------------------------------------
# Release
- build: 7
build-type: Debug
build-shared: 'ON'
cxx-standard: 17
cxx-compiler: clang++
cc-compiler: clang
compiler-desc: clang10
label:
threads-enabled: 'ON'
vfx-cy: 2022
build-docs: 'OFF'
exclude-tests:
# Static, Release
- build: 8
build-type: Release
build-shared: 'ON'
cxx-standard: 17
cxx-compiler: clang++
cc-compiler: clang
compiler-desc: clang10
compiler-desc: clang14.0
label:
threads-enabled: 'ON'
vfx-cy: 2022
build-docs: 'OFF'
exclude-tests:
# Static, Debug
- build: 9
build-type: Debug
build-shared: 'OFF'
cxx-standard: 17
cxx-compiler: clang++
cc-compiler: clang
compiler-desc: clang10
label:
threads-enabled: 'ON'
build-docs: 'OFF'
vfx-cy: 2022
vfx-cy: 2023
exclude-tests:
# -------------------------------------------------------------------
# VFX CY2021 - GCC, Release
# VFX CY2022 - GCC, Release
# -------------------------------------------------------------------
# Shared, Release
- build: 10
- build: 8
build-type: Release
build-shared: 'ON'
cxx-standard: 17
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc9.3.1
label:
threads-enabled: 'ON'
vfx-cy: 2022
exclude-tests:
# -------------------------------------------------------------------
# VFX CY2021 - GCC, Release
# -------------------------------------------------------------------
# Shared, Release
- build: 9
build-type: Release
build-shared: 'ON'
cxx-standard: 17
@@ -205,7 +201,6 @@ jobs:
compiler-desc: gcc9.3.1
label:
threads-enabled: 'ON'
build-docs: 'OFF'
vfx-cy: 2021
exclude-tests:
@@ -213,7 +208,7 @@ jobs:
# VFX CY2020 - GCC, Release
# -------------------------------------------------------------------
# Shared, Release
- build: 11
- build: 10
build-type: Release
build-shared: 'ON'
cxx-standard: 14
@@ -222,44 +217,9 @@ jobs:
compiler-desc: gcc6.3.1
label:
threads-enabled: 'ON'
build-docs: 'OFF'
vfx-cy: 2020
exclude-tests:
# -------------------------------------------------------------------
# VFX CY2019 - GCC, Release
# -------------------------------------------------------------------
# Shared, Release
- build: 12
build-type: Release
build-shared: 'ON'
cxx-standard: 14
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc6.3.1
label:
threads-enabled: 'ON'
build-docs: 'OFF'
vfx-cy: 2019
exclude-tests:
# -------------------------------------------------------------------
# Legacy - VFX CY2019 - C++11
# -------------------------------------------------------------------
# Shared, Release
- build: 13
build-type: Release
build-shared: 'ON'
cxx-standard: 11
cxx-compiler: g++
cc-compiler: gcc
compiler-desc: gcc6.3.1
label: 'Legacy '
threads-enabled: 'ON'
build-docs: 'OFF'
vfx-cy: 2019
exclude-tests:
env:
CXX: ${{ matrix.cxx-compiler }}
CC: ${{ matrix.cc-compiler }}
@@ -271,29 +231,26 @@ jobs:
mkdir _install
mkdir _build
mkdir _examples
- name: Install docs env
run: share/ci/scripts/linux/yum/install_docs_env.sh
if: matrix.build-docs == 'ON'
- name: Install help2man
run: yum install -y help2man
- name: Configure
run: |
cmake .. \
-DCMAKE_INSTALL_PREFIX=../_install \
cmake -B _build -S . \
-DCMAKE_INSTALL_PREFIX=_install \
-DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \
-DCMAKE_CXX_STANDARD=${{ matrix.cxx-standard }} \
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
-DBUILD_DOCS=${{ matrix.build-docs }} \
-DOPENEXR_BUILD_TOOLS='ON' \
-DOPENEXR_INSTALL_TOOLS='ON' \
-DOPENEXR_INSTALL_DOCS='ON' \
-DOPENEXR_RUN_FUZZ_TESTS='OFF' \
-DOPENEXR_ENABLE_THREADING=${{ matrix.threads-enabled }}
working-directory: _build
- name: Build
run: |
cmake --build . \
cmake --build _build \
--target install \
--config ${{ matrix.build-type }}
working-directory: _build
- name: Validate
run: |
share/ci/scripts/linux/validate_openexr_libs.sh _install
@@ -327,50 +284,79 @@ jobs:
# TODO: Add ARM64/x86_64 (universal 2) build
macos:
name: 'Mac VFXP-2022 macos-${{ matrix.osver }}
name: 'Mac VFXP-${{ matrix.vfx-cy }} macos-${{ matrix.osver }}
<${{ matrix.compiler-desc }},
C++${{ matrix.cxx-standard }},
config=${{ matrix.build-type }},
shared=${{ matrix.build-shared }},
cxx=${{ matrix.cxx-standard }},
docs=${{ matrix.build-docs }}>'
threads=${{ matrix.threads-enabled }}>'
runs-on: macos-${{ matrix.osver }}
strategy:
matrix:
build: [1, 2, 3]
build: [1, 2, 3, 4, 5]
include:
# -------------------------------------------------------------------
# VFX CY2022 - C++17
# VFX CY2023 - C++17 - MacOS 11.0
# -------------------------------------------------------------------
# Shared, Release
- build: 1
build-type: Release
build-shared: 'ON'
build-docs: 'OFF'
threads-enabled: 'ON'
compiler-desc: AppleClang11.0
cxx-standard: 17
osver: 10.15
osver: 11.0
exclude-tests:
vfx-cy: 23
# Static, Release
# Shared, Release, Threads OFF
- build: 2
build-type: Release
build-shared: 'OFF'
build-docs: 'OFF'
build-shared: 'ON'
threads-enabled: 'OFF'
compiler-desc: AppleClang11.0
cxx-standard: 17
osver: 10.15
osver: 11.0
exclude-tests:
vfx-cy: 23
# Static, Release
- build: 3
build-type: Release
build-shared: 'OFF'
threads-enabled: 'ON'
compiler-desc: AppleClang11.0
cxx-standard: 17
osver: 11.0
exclude-tests:
vfx-cy: 23
# Shared, Debug
- build: 3
- build: 4
build-type: Debug
build-shared: 'ON'
build-docs: 'OFF'
threads-enabled: 'ON'
compiler-desc: AppleClang11.0
cxx-standard: 17
osver: 10.15
osver: 11.0
exclude-tests:
vfx-cy: 23
# -------------------------------------------------------------------
# VFX CY2023 - C++17 - MacOS 12
# -------------------------------------------------------------------
# Shared, Release
- build: 5
build-type: Release
build-shared: 'ON'
threads-enabled: 'ON'
compiler-desc: AppleClang11.0
cxx-standard: 17
osver: 12.0
exclude-tests:
vfx-cy: 23
steps:
- name: Checkout
uses: actions/checkout@v3
@@ -388,7 +374,8 @@ jobs:
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
-DOPENEXR_BUILD_TOOLS='ON' \
-DOPENEXR_INSTALL_TOOLS='ON' \
-DOPENEXR_INSTALL_DOCS='OFF' \
-DOPENEXR_RUN_FUZZ_TESTS='OFF'
working-directory: _build
- name: Build
@@ -398,7 +385,7 @@ jobs:
--config ${{ matrix.build-type }}
working-directory: _build
- name: Examples
run: |
run: |
# Make sure we can build the examples when configured as a
# standalone application linking against the just-installed
# OpenEXR library.
@@ -426,67 +413,78 @@ jobs:
# ---------------------------------------------------------------------------
# TODO: Debug mode is catatonically slow under windows
windows:
name: 'Windows VFXP-2022
name: 'Windows VFXP-${{ matrix.vfx-cy }}
<${{ matrix.compiler-desc }},
config=${{ matrix.build-type }},
shared=${{ matrix.build-shared }},
cxx=${{ matrix.cxx-standard }},
docs=${{ matrix.build-docs }}>'
cxx=${{ matrix.cxx-standard }},
threads=${{ matrix.threads-enabled }}>'
runs-on: windows-${{ matrix.osver }}
strategy:
matrix:
build: [1, 2, 3, 4]
build: [1, 2, 3, 4, 5]
include:
# -------------------------------------------------------------------
# VFX CY2022 - C++17 - Windows 2019
# VFX CY2023 - C++17 - Windows 2022 runner - MSVC 2022 (17.5)
# -------------------------------------------------------------------
# Shared, Release
- build: 1
build-type: Release
build-shared: 'ON'
build-docs: 'OFF'
compiler-desc: msvc16.11
threads-enabled: 'ON'
compiler-desc: msvc17.5
cxx-standard: 17
vfx-cy: 2021
vfx-cy: 2023
exclude-tests: ''
osver: 2019
osver: 2022
# Static, Release
# Shared, Release, Threads OFF
- build: 2
build-type: Release
build-shared: 'OFF'
build-docs: 'OFF'
compiler-desc: msvc16.11
cxx-standard: 17
vfx-cy: 2021
exclude-tests: ''
osver: 2019
# -------------------------------------------------------------------
# VFX CY2022 - C++17 - Windows 2022
# -------------------------------------------------------------------
# Shared, Release
- build: 3
build-type: Release
build-shared: 'ON'
build-docs: 'OFF'
compiler-desc: msvc17.1
threads-enabled: 'OFF'
compiler-desc: msvc17.5
cxx-standard: 17
vfx-cy: 2021
vfx-cy: 2023
exclude-tests: ''
osver: 2022
# Static, Release
- build: 4
- build: 3
build-type: Release
build-shared: 'OFF'
build-docs: 'OFF'
compiler-desc: msvc17.1
threads-enabled: 'ON'
compiler-desc: msvc17.5
cxx-standard: 17
vfx-cy: 2021
vfx-cy: 2023
exclude-tests: ''
osver: 2022
# -------------------------------------------------------------------
# VFX CY2022 - C++17 - Windows 2019 runner - MSVC 2019 (16.11)
# -------------------------------------------------------------------
# Shared, Release
- build: 4
build-type: Release
build-shared: 'ON'
threads-enabled: 'ON'
compiler-desc: msvc16.11
cxx-standard: 17
vfx-cy: 2022
exclude-tests: ''
osver: 2019
# Static, Release
- build: 5
build-type: Release
build-shared: 'OFF'
threads-enabled: 'ON'
compiler-desc: msvc16.11
cxx-standard: 17
vfx-cy: 2022
exclude-tests: ''
osver: 2019
steps:
- name: Checkout
uses: actions/checkout@v3
@@ -511,7 +509,8 @@ jobs:
-DCMAKE_CXX_FLAGS=${{ matrix.cxx-flags }} \
-DCMAKE_VERBOSE_MAKEFILE:BOOL='OFF' \
-DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \
-DOPENEXR_BUILD_TOOLS='ON' \
-DOPENEXR_INSTALL_TOOLS='ON' \
-DOPENEXR_INSTALL_DOCS='OFF' \
-DOPENEXR_RUN_FUZZ_TESTS='OFF'
shell: bash
working-directory: _build
@@ -547,3 +546,4 @@ jobs:
-VV
shell: bash
working-directory: _build
@@ -1,5 +1,40 @@
name: CIFuzz
on: [pull_request]
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
name: OSS-Fuzz
# Skip the run on *.md changes and on changes to the website.
# Also, no need to run on changes to the bazel setup.
on:
push:
branches-ignore:
- RB-2.*
tags-ignore:
- v1.*
- v2.*
paths:
- '**'
- '!**.md'
- '!website/**'
- '!bazel/**'
- '!src/wrappers/**'
pull_request:
branches-ignore:
- RB-2.*
tags-ignore:
- v1.*
- v2.*
paths:
- '**'
- '!**.md'
- '!website/**'
- '!bazel/**'
- '!src/wrappers/**'
permissions:
contents: read
jobs:
Fuzzing:
runs-on: ubuntu-latest
@@ -0,0 +1,104 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
name: Publish python distribution 📦 to TestPyPI
on:
# Publish python wheels to test.pypi when a release candidate is tagged,
# e.g. v3.4.5-rc, v3.4.5-rc6, etc.
push:
tags:
- v3.[0-9]+.[0-9]+-rc*
workflow_dispatch:
permissions:
contents: read
jobs:
build:
name: Python Wheels - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
environment:
name: testpypi
url: https://test.pypi.org/p/openexr
permissions:
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Create sdist
# Only create it once.
if: ${{ matrix.os == 'ubuntu-latest' }}
env:
OPENEXR_RELEASE_CANDIDATE_TAG: ${{ github.ref_name }}
run: pipx run build --sdist . --outdir wheelhouse
- name: Build wheel
uses: pypa/cibuildwheel@v2.16
with:
output-dir: wheelhouse
env:
CIBW_ARCHS_LINUX: x86_64
CIBW_ARCHS_MACOS: x86_64 arm64 universal2
# Skip python 3.6 since scikit-build-core requires 3.7+
# Skip 32-bit wheels builds on Windows
# Also skip the PyPy builds, since they fail the unit tests
CIBW_SKIP: cp36-* *-win32 *_i686 pp*
CIBW_TEST_SKIP: "*-macosx_universal2:arm64"
CIBW_ENVIRONMENT: OPENEXR_RELEASE_CANDIDATE_TAG="${{ github.ref_name }}"
- name: Upload artifact
uses: actions/upload-artifact@v4.0.0
with:
name: wheels-${{ matrix.os }}
path: |
./wheelhouse/*.whl
./wheelhouse/*.tar.gz
publish-to-testpypi:
name: Publish Python 🐍 distribution 📦 to TestPyPI
needs:
- build
runs-on: ubuntu-latest
environment:
name: testpypi
url: https://test.pypi.org/p/openexr
permissions:
id-token: write
steps:
- name: Download Linux artifacts
uses: actions/download-artifact@v4.0.0
with:
name: wheels-ubuntu-latest
path: dist
- name: Download macOS artifacts
uses: actions/download-artifact@v4.0.0
with:
name: wheels-macos-latest
path: dist
- name: Download Windows artifacts
uses: actions/download-artifact@v4.0.0
with:
name: wheels-windows-latest
path: dist
- name: Publish distribution 📦 to TestPyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,95 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
name: Publish python distribution 📦 to PyPI
on:
# Publish wheels to pypi on release
release:
types: [published]
workflow_dispatch:
permissions:
contents: read
jobs:
build:
name: Python Wheels - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
environment:
name: pypi
url: https://pypi.org/p/openexr
permissions:
id-token: write
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Create sdist
# Only create it once.
if: ${{ matrix.os == 'ubuntu-latest' }}
run: pipx run build --sdist . --outdir wheelhouse
- name: Build wheel
uses: pypa/cibuildwheel@v2.16
with:
output-dir: wheelhouse
env:
CIBW_ARCHS_LINUX: x86_64
CIBW_ARCHS_MACOS: x86_64 arm64 universal2
# Skip python 3.6 since scikit-build-core requires 3.7+
# Skip 32-bit wheels builds on Windows
# Also skip the PyPy builds, since they fail the unit tests
CIBW_SKIP: cp36-* *-win32 *_i686 pp*
CIBW_TEST_SKIP: "*arm64"
- name: Upload artifact
uses: actions/upload-artifact@v4.0.0
with:
name: wheels-${{ matrix.os }}
path: |
./wheelhouse/*.whl
./wheelhouse/*.tar.gz
publish-to-pypi:
name: Publish Python 🐍 distribution 📦 to PyPI
needs:
- build
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/p/openexr
permissions:
id-token: write
steps:
- name: Download Linux artifacts
uses: actions/download-artifact@v4.0.0
with:
name: wheels-ubuntu-latest
path: dist
- name: Download macOS artifacts
uses: actions/download-artifact@v4.0.0
with:
name: wheels-macos-latest
path: dist
- name: Download Windows artifacts
uses: actions/download-artifact@v4.0.0
with:
name: wheels-windows-latest
path: dist
- name: Publish distribution 📦 to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
+74
View File
@@ -0,0 +1,74 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
name: Python Wheels
on:
# Run on all changes (PR and push) to the python binding
# source/configuration files, except on the release branches, which
# have their own workflow, which also publish to pypi/test.pypi.
# Note that changes to the core libraries will *not*
# trigger building the wheels. However, the main ci workflow does
# build and test the bindings (for a single python version on a
# single arch)
push:
branches-ignore:
- RB-*
paths:
- 'src/wrappers/python/**'
- 'pyproject.toml'
- '.github/workflows/python-wheels.yml'
pull_request:
branches-ignore:
- RB-*
paths:
- 'src/wrappers/python/**'
- 'pyproject.toml'
- '.github/workflows/python-wheels.yml'
permissions:
contents: read
jobs:
build_wheels:
name: Python Wheels - ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Python
uses: actions/setup-python@v5
with:
python-version: '3.x'
- name: Create sdist
# Only create it once.
if: ${{ matrix.os == 'ubuntu-latest' }}
run: pipx run build --sdist . --outdir wheelhouse
- name: Build wheel
uses: pypa/cibuildwheel@v2.16
env:
CIBW_ARCHS_MACOS: x86_64 arm64 universal2
# Skip python 3.6 since scikit-build-core requires 3.7+
# Skip 32-bit wheels builds on Windows
# Also skip the PyPy builds, since they fail the unit tests
CIBW_SKIP: cp36-* *-win32 *_i686 pp*
CIBW_TEST_SKIP: "*-macosx*arm64"
- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: wheels-${{ matrix.os }}
path: |
./wheelhouse/*.whl
./wheelhouse/*.tar.gz
+35
View File
@@ -0,0 +1,35 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
name: Publish Release Notice to ASWF Slack
on:
release:
types:
- published
# published should cover both 'released' and 'prereleased'
jobs:
publish:
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: 'Notify Slack #release-announcements'
id: slack1
with:
project_name: "OpenEXR"
slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }}
slack_channel: "#release-announcements"
project_logo: "https://artwork.aswf.io/projects/openexr/icon/color/openexr-icon-color.png"
uses: jmertic/slack-release-notifier@main
- name: 'Notify Slack #openexr'
id: slack2
with:
project_name: "OpenEXR"
slack_bot_token: ${{ secrets.SLACK_BOT_TOKEN }}
slack_channel: "#openexr"
project_logo: "https://artwork.aswf.io/projects/openexr/icon/color/openexr-icon-color.png"
uses: jmertic/slack-release-notifier@main
+54
View File
@@ -0,0 +1,54 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
#
# Releases are signed via https://github.com/sigstore/sigstore-python.
# See https://docs.sigstore.dev for information about sigstore.
#
# This action creates a .tar.gz of the complete OpenEXR source tree at
# the given release tag, signs it via sigstore, and uploads the
# .tar.gz and the associated .tar.gz.sigstore credential bundle.
#
# To verify a downloaded release at a given tag:
#
# % pip install sigstore
# % sigstore verify github --cert-identity https://github.com/AcademySoftwareFoundation/openexr/.github/workflows/release-sign.yml@refs/tags/<tag> openexr-<tag>.tar.gz
#
name: Sign Release
on:
release:
types: [published]
permissions:
contents: write
id-token: write
repository-projects: write
jobs:
release:
name: Sign & upload release artifacts
runs-on: ubuntu-latest
env:
tarball: openexr-${{ github.ref_name }}.tar.gz
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Create archive
run: git archive --format=tar.gz -o ${{ env.tarball }} ${{ github.ref_name }}
- name: Sign archive with Sigstore
uses: sigstore/gh-action-sigstore-python@v2.1.1
with:
inputs: ${{ env.tarball }}
- name: Upload release archive
env:
GH_TOKEN: ${{ github.token }}
run: gh release upload ${{ github.ref_name }} ${{ env.tarball }} ${{ env.tarball }}.sigstore
+40
View File
@@ -0,0 +1,40 @@
---
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
name: Snyk Scan Code
on:
# https://docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions
schedule:
- cron: "0 4 * * 0"
jobs:
snyk-scan-pr:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: snyk/actions/setup@master
id: snyk
- name: Snyk version
run: echo "${{ steps.snyk.outputs.version }}"
- name: Snyk Auth
run: snyk auth ${{ secrets.SNYK_TOKEN }}
- name: Snyk Scan Code
# Scan the C/C++ code for vulnerabilities using the Snyk CLI with the unmanaged flag
# https://docs.snyk.io/scan-using-snyk/supported-languages-and-frameworks/c-c++ for options
run: snyk test --unmanaged --print-dep-paths --org=${{ secrets.SNYK_ORG }}
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
continue-on-error: true # optional
- name: Monitor for Vulnerabilities
# To import the test results (issues and dependencies) in the Snyk CLI, run the snyk monitor --unmanaged command:
run: snyk monitor --unmanaged --org=${{ secrets.SNYK_ORG }}
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
continue-on-error: true # optional
+65
View File
@@ -0,0 +1,65 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
#
# GitHub Actions workflow file
# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions
name: Website
# Run only on changes in the "website" directory or workflow file.
# Skip the release branches, since the website is built from main.
on:
push:
branches:-ignore:
- RB-*
paths:
- 'website/**'
- '.github/workflows/website_workflow.yml'
pull_request:
branches:-ignore:
- RB-*
paths:
- 'website/**'
- '.github/workflows/website_workflow.yml'
permissions:
contents: read
jobs:
Website:
# Build the website, using a process that mimics the readthedoc build.
#
# Note that this job does not actually build OpenEXR libraries or
# programs, it just runs doxygen, sphinx, and the
# website/script/test_images.py script to generate the "Test Images"
# page.
name: 'Website'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Create build directory
run: mkdir _build
- name: Install doxygen & imagemagick
# Need imagemagick for convert, to convert "Test Image" exrs to jpgs
# Need openexr for exrheader
run: sudo apt-get install -y doxygen imagemagick openexr
- name: Install sphinx requirements
run: pip3 install -r website/requirements.txt
- name: Configure
run: cmake .. -DBUILD_WEBSITE='ON'
working-directory: _build
- name: Build
run: |
cmake --build . \
--target website \
--config Release
working-directory: _build
+9 -1
View File
@@ -1,3 +1,5 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
Makefile
Makefile.in
autom4te.cache
@@ -45,8 +47,14 @@ Contrib/DtexToExr/DtexToExr
*.project
*.cproject
.DS_Store
abi_check
build/
build-win/
build-nuget/
*~
.vscode
.vscode
docs/_test_images/
# Ignore Bazel generated files
bazel-*
MODULE.bazel.lock
+163
View File
@@ -0,0 +1,163 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
#
# This file establishes email equivalences so we can resolve what look like
# multiple authors, but actually are the same author who has used multiple
# emails over the course of their involvement with the project.
#
# The format is any of the following:
# <CANONICAL-EMAIL> <alternate-email>
# CANONICAL-NAME <CANONICAL-EMAIL> <alternate-email>
# CANONICAL-NAME <CANONICAL-EMAIL> alternate-name <alternate-email>
#
# You can check for duplicates with this command:
# git shortlog -sne --all
# That command (and others) will use this file to collapse the duplicates.
#
# If you see any duplicates we don't account for here, or if you look at your
# own entry here and want a different name or email to be your canonical one
# (we may not have guessed correctly and matched your preferences), please
# file a PR with the edits to this file.
Aaron Demolder <aaron.demolder@gmail.com>
Abe Fettig <abe@fettig.net>
Aloys Baillet <aloys.baillet+github@gmail.com> aloysb <aloysb@al.com.au>
Andrew Kunz <akunz@ilm.com>
Anton Dukhovnikov <antond@wetafx.co.nz> Anton Dukhovnikov <131838425+antond-weta@users.noreply.github.com>
Antonio Rojas <arojas@archlinux.org>
Aras Pranckevičius <nearaz@gmail.com> Aras Pranckevičius <aras@nesnausk.org>
Aras Pranckevičius <nearaz@gmail.com> Aras Pranckevičius <aras@unity3d.com>
Arkady Shapkin <arkady.shapkin@gmail.com>
Arkell Rasiah <arkellrasiah@gmail.com> Arkell Rasiah <arasiah@ilm.com>
Arkell Rasiah <arkellrasiah@gmail.com> Arkell Rasiah <arasiah@pixsystem.com>
Axel Waggershauser <awagger@gmail.com>
axxel <awagger@gmail.com>
Balázs Oroszi <ignus2@users.noreply.github.com>
Barnaby Robson <brobson@ilm.com> Barnaby Robson <mail@barnaby.org>
Ben Grimes <72311676+MrGlobby@users.noreply.github.com>
Bernd <waebbl-gentoo@posteo.net>
Brendan Bolles <brendan@fnordware.com>
CAHEK7 <ghosts.in.a.box@gmail.com>
Cary Phillips <cary@ilm.com> cary-ilm <cary@ilm.com>
Cary Phillips <cary@ilm.com> Cary Phillips <cary@rnd-build7-sf-38.lucasfilm.com>
Cary Phillips <cary@ilm.com> seabeepea <seabeepea@gmail.com>
Catherine <catyeo18@users.noreply.github.com>
Chris Leu <cdleu430@gmail.com> cdleu430 <cdleu430@gmail.com>
Christina Tempelaar-Lietz <xlietz@gmail.com> ¨Christina Tempelaar-Lietz¨ <xlietz@gmail.com>
Christina Tempelaar-Lietz <xlietz@gmail.com> xlietz <31363633+xlietz@users.noreply.github.com>
Christopher Horvath <blackencino+git@gmail.com>
Christopher Kulla <fpsunflower@users.noreply.github.com>
Christoph Gohlke <cgohlke@cgohlke.com>
cia-rana <kiwamura0314@gmail.com>
Cristian Martínez <cfuga@cfuga.mx>
Dan Horák <dan@danny.cz>
Daniel Kaneider <danielkaneider@users.sf.net>
Darby Johnston <darbyjohnston@yahoo.com>
Dave Sawyer <kingsawyer@gmail.com>
David Korczynski <david@adalogics.com>
Developer-Ecosystem-Engineering <65677710+Developer-Ecosystem-Engineering@users.noreply.github.com>
dgmzc <dorian.gmz@hotmail.com>
Diogo Teles Sant'Anna <diogoteles@google.com>
Dirk Lemstra <dirk@lemstra.org> dirk <dirk@git.imagemagick.org>
dracwyrm <j.scruggs@gmail.com>
Drew Hess <dhess@ilm.com>
Ed Hanway <ehanway@ilm.com> Ed Hanway <ehanway-ilm@users.noreply.github.com>
Edward Kmett <ekmett@gmail.com>
Eric Sommerlade <es0m@users.noreply.github.com>
Eric Wimmer <ewimmer@ilm.com>
E Sommerlade <es0m@users.noreply.github.com>
fgc <fgc>
Florian Kainz <kainz@ilm.com>
Grant Kim <6302240+enpinion@users.noreply.github.com>
Gregorio Litenstein <g.litenstein@gmail.com>
Gyula Gubacsi <gyula.gubacsi@foundry.com>
Halfdan Ingvarsson <halfdan@sidefx.com>
Harry Mallon <hjmallon@gmail.com>
Huibean Luo <huibean.luo@gmail.com>
ianianda <wyking1030@gmail.com>
Ibraheem Alhashim <ibraheem.alhashim@gmail.com>
Jack Kingsman <jack.kingsman@gmail.com>
Jamie Kenyon <jamie.kenyon@thefoundry.co.uk>
Jan Tojnar <jtojnar@gmail.com>
jbradley <jbradley@dreamworks.com>
Jean-Francois Panisset <32653482+jfpanisset@users.noreply.github.com>
Jens Lindgren <lindgren_jens@hotmail.com>
Ji Hun Yu <jihun@ilm.com>
Johannes Vollmer <32042925+johannesvollmer@users.noreply.github.com>
John Loy <jloy@pixar.com>
John Mertic <jmertic@linuxfoundation.org>
Jonathan Stone <stonej@github.com>
Jose Luis Cercos-Pita <jlcercos@gmail.com> Jose Luis Cercós Pita <lacigarracomunista@gmail.com>
Joseph Goldstone <joseph.goldstone@mac.com> Joseph Goldstone <jgoldstone@arri.com>
Juha Reunanen <juha.reunanen@tomaattinen.com>
Julian Amann <julian.amann@tum.de>
Juri Abramov <openexr@dr-abramov.de> Juri Abramov <gabramov@nvidia.com>
Juri Abramov <openexr@dr-abramov.de> JuriAbramov <openexr@dr-abramov.de>
Karl Hendrikse <karlhendrikse@gmail.com> karlhendrikse <karlhendrikse@gmail.com>
Karl Rasche <karl.rasche@dreamworks.com> Karl Rasche <karlrasche@users.noreply.github.com>
Kevin Wheatley <kevin.wheatley@framestore.com>
Kimball Thurston <kdt3rd@gmail.com>
kwizart <kwizart@gmail.com>
Larry Gritz <lg@larrygritz.com>
Laurens Voerman <l.voerman@rug.nl>
L. E. Segovia <amy@amyspark.me>
Liam Fernandez <liam@utexas.edu>
lilinjie <lilinjie@uniontech.com>
Lucy Wilkes <lucywilkes@users.noreply.github.com>
luzpaz <luzpaz@users.noreply.github.com>
mancoast <RobertPancoast77@gmail.com>
mandree <mandree@users.noreply.github.com>
Mark Reid <mindmark@gmail.com>
Mark Sisson <5761292+marksisson@users.noreply.github.com>
Martin Aumüller <aumuell@reserv.at>
Martin Husemann <martin@NetBSD.org>
Matthäus G. Chajdas <Anteru@users.noreply.github.com>
Matthias C. M. Troffaes <matthias.troffaes@gmail.com>
Matt Pharr <matt@pharr.org>
Md Sadman Chowdhury <61442059+SpicyCatGames@users.noreply.github.com>
Michael Thomas (malinka) <malinka@entropy-development.com>
Nicholas Yue <yue.nicholas@gmail.com>
Nick Porcino <meshula@hotmail.com> meshula <nick.porcino@gmail.com>
Nick Porcino <meshula@hotmail.com> Nick Porcino <nick.porcino@oculus.com>
Nick Porcino <meshula@hotmail.com> Nick Porcino <nporcino@pixar.com>
Nick Porcino <meshula@hotmail.com> nporcino-pixar <78001580+nporcino-pixar@users.noreply.github.com>
Nick Rasmussen <nick@ilm.com> Nick Rasmussen <nick@jive.org>
Nick Rasmussen <nick@ilm.com> Nick Rasmussen <nick.rasmussen@gmail.com>
Nicolas Chauvet <kwizart@gmail.com>
Niklas Hambüchen <mail@nh2.me>
OgreTransporter <OgreTransporter@users.noreply.github.com>
oleksii.vorobiov <oleksii.vorobiov@globallogic.com>
Owen Thompson <oxt3479@rit.edu>
patlefort <northon_patrick3@yahoo.ca>
Paul Schneider <pauls@ilm.com>
Peter Hillman <peterh@wetafx.co.nz> peterhillman <peterh@wetafx.co.nz>
Peter Hillman <peterh@wetafx.co.nz> peterhillman <peter@peterhillman.org.uk>
Peter Steneteg <peter@steneteg.se>
Peter Urbanec <peterurbanec@users.noreply.github.com>
Phyrexian <jarko.paska@gmail.com>
Piotr Stanczyk <piotr.stanczyk@gmail.com> Piotr <pstanczyk@ilm.com>
Piotr Stanczyk <piotr.stanczyk@gmail.com> Piotr Stanczyk <pstanczyk@ilm.com>
Piotr Stanczyk <piotr.stanczyk@gmail.com> pstanczyk <pstanczyk@ilm.com>
Ralph Potter <r.potter@bath.ac.uk>
r-a-sattarov <r.a.sattarov@yandex.ru>
Rémi Achard <remiachard@gmail.com>
Reto Kromer <retokromer@users.noreply.github.com>
Richard Goedeken <Richard@fascinationsoftware.com>
Sergey Fedorov <vital.had@gmail.com>
Shawn Walker-Salas <shawn.walker@oracle.com>
Simon Boorer <sboorer@ilm.com>
Simon Otter <skurmedel@gmail.com>
Srinath Ravichandran <srinath.pop@gmail.com>
Thanh Ha <thanh.ha@linuxfoundation.org>
Thomas Debesse <dev@illwieckz.net>
Thorsten Kaufmann <thorsten.kaufmann@mackevision.de>
Timothy Lyanguzov <theta682@gmail.com>
Transporter <ogre.transporter@gmail.com>
Vertexwahn <julian.amann@tum.de>
Wenzel Jakob <wenzel@inf.ethz.ch>
Wojciech Jarosz <wkjarosz@users.noreply.github.com> wjarosz <wjarosz>
Xo Wang <xow@google.com>
Yaakov Selkowitz <yselkowi@redhat.com>
Yining Karl Li <betajippity@gmail.com>
Yujie Shu <yshu@ilm.com> Yujie Shu (Intern) <yshu@ilm.com>
zengwei2000 <102871671+zengwei2000@users.noreply.github.com>
+28
View File
@@ -0,0 +1,28 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
# .readthedocs.yml
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
build:
os: "ubuntu-22.04"
tools:
python: "3.9"
apt_packages:
- wget # for test images
- imagemagick # for convert, for test images
- openexr # for exrheader, for test images
jobs:
pre_build:
- python website/scripts/test_images.py
sphinx:
configuration: website/conf.py
python:
install:
- requirements: website/requirements.txt
+124 -3
View File
@@ -53,10 +53,10 @@ expand_template(
"@OPENEXR_NAMESPACE_CUSTOM@": "3.2.0",
"@OPENEXR_PACKAGE_NAME@": "OpenEXR 3.2.0",
"@OPENEXR_VERSION_EXTRA@": "",
"@OPENEXR_VERSION@": "3.2.0",
"@OPENEXR_VERSION_MAJOR@": "3",
"@OPENEXR_VERSION_MINOR@": "2",
"@OPENEXR_VERSION_PATCH@": "0",
"@OPENEXR_VERSION@": "3.2.0",
"#cmakedefine OPENEXR_ENABLE_API_VISIBILITY": "#define OPENEXR_ENABLE_API_VISIBILITY",
"#cmakedefine OPENEXR_HAVE_LARGE_STACK 1": "/* #undef OPENEXR_HAVE_LARGE_STACK */",
},
@@ -84,6 +84,7 @@ cc_library(
"src/lib/Iex/IexMathFloatExc.cpp",
"src/lib/Iex/IexMathFpu.cpp",
"src/lib/Iex/IexThrowErrnoExc.cpp",
"src/lib/OpenEXRCore/openexr_version.h",
],
hdrs = [
"src/lib/Iex/Iex.h",
@@ -109,6 +110,7 @@ cc_library(
includes = [
"src/lib/Iex",
"src/lib/OpenEXR",
"src/lib/OpenEXRCore",
],
)
@@ -122,6 +124,7 @@ cc_library(
"src/lib/IlmThread/IlmThreadSemaphorePosix.cpp",
"src/lib/IlmThread/IlmThreadSemaphorePosixCompat.cpp",
"src/lib/IlmThread/IlmThreadSemaphoreWin32.cpp",
"src/lib/OpenEXRCore/openexr_version.h",
],
hdrs = [
"src/lib/IlmThread/IlmThread.h",
@@ -137,10 +140,128 @@ cc_library(
":windows": ["windows_export_all_symbols"],
"//conditions:default": [],
}),
includes = ["src/lib/IlmThread"],
includes = [
"src/lib/IlmThread",
"src/lib/OpenEXRCore",
],
deps = [":Iex"],
)
cc_library(
name = "OpenEXRCore",
srcs = [
"src/lib/IlmThread/IlmThreadConfig.h",
"src/lib/OpenEXR/OpenEXRConfig.h",
"src/lib/OpenEXR/OpenEXRConfigInternal.h",
"src/lib/OpenEXR/dwaLookups.h",
"src/lib/OpenEXRCore/attributes.c",
"src/lib/OpenEXRCore/backward_compatibility.h",
"src/lib/OpenEXRCore/base.c",
"src/lib/OpenEXRCore/channel_list.c",
"src/lib/OpenEXRCore/chunk.c",
"src/lib/OpenEXRCore/coding.c",
"src/lib/OpenEXRCore/compression.c",
"src/lib/OpenEXRCore/context.c",
"src/lib/OpenEXRCore/debug.c",
"src/lib/OpenEXRCore/decoding.c",
"src/lib/OpenEXRCore/encoding.c",
"src/lib/OpenEXRCore/float_vector.c",
"src/lib/OpenEXRCore/internal_attr.h",
"src/lib/OpenEXRCore/internal_b44.c",
"src/lib/OpenEXRCore/internal_b44_table.c",
"src/lib/OpenEXRCore/internal_channel_list.h",
"src/lib/OpenEXRCore/internal_coding.h",
"src/lib/OpenEXRCore/internal_compress.h",
"src/lib/OpenEXRCore/internal_constants.h",
"src/lib/OpenEXRCore/internal_cpuid.h",
"src/lib/OpenEXRCore/internal_decompress.h",
"src/lib/OpenEXRCore/internal_dwa.c",
"src/lib/OpenEXRCore/internal_dwa_channeldata.h",
"src/lib/OpenEXRCore/internal_dwa_classifier.h",
"src/lib/OpenEXRCore/internal_dwa_compressor.h",
"src/lib/OpenEXRCore/internal_dwa_decoder.h",
"src/lib/OpenEXRCore/internal_dwa_encoder.h",
"src/lib/OpenEXRCore/internal_dwa_helpers.h",
"src/lib/OpenEXRCore/internal_dwa_simd.h",
"src/lib/OpenEXRCore/internal_file.h",
"src/lib/OpenEXRCore/internal_float_vector.h",
"src/lib/OpenEXRCore/internal_huf.c",
"src/lib/OpenEXRCore/internal_huf.h",
"src/lib/OpenEXRCore/internal_memory.h",
"src/lib/OpenEXRCore/internal_opaque.h",
"src/lib/OpenEXRCore/internal_piz.c",
"src/lib/OpenEXRCore/internal_posix_file_impl.h",
"src/lib/OpenEXRCore/internal_preview.h",
"src/lib/OpenEXRCore/internal_pxr24.c",
"src/lib/OpenEXRCore/internal_rle.c",
"src/lib/OpenEXRCore/internal_string.h",
"src/lib/OpenEXRCore/internal_string_vector.h",
"src/lib/OpenEXRCore/internal_structs.c",
"src/lib/OpenEXRCore/internal_structs.h",
"src/lib/OpenEXRCore/internal_util.h",
"src/lib/OpenEXRCore/internal_win32_file_impl.h",
"src/lib/OpenEXRCore/internal_xdr.h",
"src/lib/OpenEXRCore/internal_zip.c",
"src/lib/OpenEXRCore/memory.c",
"src/lib/OpenEXRCore/opaque.c",
"src/lib/OpenEXRCore/openexr_version.h",
"src/lib/OpenEXRCore/pack.c",
"src/lib/OpenEXRCore/parse_header.c",
"src/lib/OpenEXRCore/part.c",
"src/lib/OpenEXRCore/part_attr.c",
"src/lib/OpenEXRCore/preview.c",
"src/lib/OpenEXRCore/std_attr.c",
"src/lib/OpenEXRCore/string.c",
"src/lib/OpenEXRCore/string_vector.c",
"src/lib/OpenEXRCore/unpack.c",
"src/lib/OpenEXRCore/validation.c",
"src/lib/OpenEXRCore/write_header.c",
],
hdrs = [
"src/lib/OpenEXRCore/openexr.h",
"src/lib/OpenEXRCore/openexr_attr.h",
"src/lib/OpenEXRCore/openexr_base.h",
"src/lib/OpenEXRCore/openexr_chunkio.h",
"src/lib/OpenEXRCore/openexr_coding.h",
"src/lib/OpenEXRCore/openexr_compression.h",
"src/lib/OpenEXRCore/openexr_config.h",
"src/lib/OpenEXRCore/openexr_context.h",
"src/lib/OpenEXRCore/openexr_debug.h",
"src/lib/OpenEXRCore/openexr_decode.h",
"src/lib/OpenEXRCore/openexr_encode.h",
"src/lib/OpenEXRCore/openexr_errors.h",
"src/lib/OpenEXRCore/openexr_part.h",
"src/lib/OpenEXRCore/openexr_std_attr.h",
],
copts = select({
":windows": [],
"//conditions:default": [
"-Wno-error",
],
}),
features = select({
":windows": ["windows_export_all_symbols"],
"//conditions:default": [],
}),
includes = [
"src/lib/IlmThread",
"src/lib/OpenEXR",
"src/lib/OpenEXRCore",
],
linkopts =
select({
":windows": [],
"//conditions:default": [
"-pthread",
],
}),
visibility = ["//visibility:public"],
deps = [
"@Imath",
"@libdeflate//:deflate",
],
)
cc_library(
name = "OpenEXR",
srcs = [
@@ -378,8 +499,8 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
":IlmThread",
":OpenEXRCore",
"@Imath",
"@net_zlib_zlib//:zlib",
],
)
+1266 -579
View File
File diff suppressed because it is too large Load Diff
+73 -34
View File
@@ -19,46 +19,69 @@ endif()
# configuration files
#######################################
project(OpenEXR VERSION 3.2.0 LANGUAGES C CXX)
file(READ "src/lib/OpenEXRCore/openexr_version.h" VERSION_H)
string(REGEX MATCH "VERSION_MAJOR ([0-9]*)" _ ${VERSION_H})
set(OPENEXR_VERSION_MAJOR ${CMAKE_MATCH_1})
string(REGEX MATCH "VERSION_MINOR ([0-9]*)" _ ${VERSION_H})
set(OPENEXR_VERSION_MINOR ${CMAKE_MATCH_1})
string(REGEX MATCH "VERSION_PATCH ([0-9]*)" _ ${VERSION_H})
set(OPENEXR_VERSION_PATCH ${CMAKE_MATCH_1})
set(OPENEXR_VERSION_RELEASE_TYPE "-dev" CACHE STRING "Extra version tag string for OpenEXR build, such as -dev, -beta1, etc.")
project(OpenEXR VERSION ${OPENEXR_VERSION_MAJOR}.${OPENEXR_VERSION_MINOR}.${OPENEXR_VERSION_PATCH} LANGUAGES C CXX)
set(OPENEXR_VERSION_RELEASE_TYPE "" CACHE STRING "Extra version tag string for OpenEXR build, such as -dev, -beta1, etc.")
set(OPENEXR_VERSION ${OpenEXR_VERSION})
set(OPENEXR_VERSION_API "${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}")
# Library/shared-object version using libtool versioning policy.
# See https://www.gnu.org/software/libtool/manual/html_node/Updating-version-info.html
# The SOVERSION (i.e. numerical component of SONAME) tracks the ABI
# version. Increment this number whenever, and only when, the ABI changes in
# non-backwards-compatible ways.
#
# Library API version (CMake's library VERSION attribute) is of the
# form CURRENT.REVISION.AGE; the CMake SOVERSION attribute corresponds
# to just CURRENT. These produce a .so and a symlink symlink, e.g.:
# libOpenEXR-3_1.so.29 -> libOpenEXR-3_1.so.29.0.0
# ^ ^ ^ ^
# | | | |
# CURRENT | | AGE
# | REVISION
# CURRENT
# When updating:
# 1. no API change: CURRENT.REVISION+1.AGE
# 2. API added: CURRENT+1.0.AGE+1
# 3. API changed: CURRENT+1.0.0
#
set(OPENEXR_LIBTOOL_CURRENT 29)
set(OPENEXR_LIBTOOL_REVISION 0)
set(OPENEXR_LIBTOOL_AGE 0)
set(OPENEXR_LIB_VERSION "${OPENEXR_LIBTOOL_CURRENT}.${OPENEXR_LIBTOOL_REVISION}.${OPENEXR_LIBTOOL_AGE}")
set(OPENEXR_LIB_SOVERSION ${OPENEXR_LIBTOOL_CURRENT})
# The OpenEXR project policy is to append the library version
# "major.minor.patch" to the SONAME to form the real shared library name.
# For example, in "libOpenEXR.so.31.3.2.0", "libOpenEXR.so.31" is the SONAME
# and ".3.2.0" identifies the corresponding library release.
set(OPENEXR_LIB_SOVERSION 31)
set(OPENEXR_LIB_VERSION "${OPENEXR_LIB_SOVERSION}.${OPENEXR_VERSION}") # e.g. "31.3.2.0"
option(OPENEXR_INSTALL "Install OpenEXR libraries" ON)
option(OPENEXR_INSTALL_TOOLS "Install OpenEXR tools" ON)
if(OPENEXR_INSTALL_TOOLS AND NOT OPENEXR_INSTALL)
message(SEND_ERROR "OPENEXR_INSTALL_TOOLS requires OPENEXR_INSTALL")
# uninstall target
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
# uninstall target
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
# uninstall target
if(NOT TARGET uninstall)
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/cmake_uninstall.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake"
IMMEDIATE @ONLY)
add_custom_target(uninstall
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_BINARY_DIR}/cmake_uninstall.cmake)
endif()
include(cmake/LibraryDefine.cmake)
include(cmake/OpenEXRSetup.cmake)
add_subdirectory(cmake)
message(STATUS "Configure ${OPENEXR_PACKAGE_NAME}, library API version: ${OPENEXR_LIB_VERSION}")
# Hint: This can be set to enable custom find_package
@@ -77,8 +100,13 @@ if(BUILD_TESTING AND NOT OPENEXR_IS_SUBPROJECT)
endif()
# Include these two modules without enable/disable options
add_subdirectory(src/lib)
add_subdirectory(src/bin)
if (OPENEXR_BUILD_LIBS)
add_subdirectory(src/lib)
endif()
if(OPENEXR_BUILD_TOOLS AND OPENEXR_BUILD_LIBS)
add_subdirectory(src/bin)
endif()
# Tell CMake where to find the OpenEXRConfig.cmake file. Makes it possible to call
# find_package(OpenEXR) in downstream projects
@@ -87,8 +115,7 @@ set(OpenEXR_DIR "${CMAKE_CURRENT_BINARY_DIR}/cmake" CACHE PATH "" FORCE)
# Can be empty since we already defined the targets in add_subdirectory
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/cmake/OpenEXRTargets.cmake" "# Dummy file")
option(OPENEXR_INSTALL_EXAMPLES "Install OpenEXR examples" ON)
if(OPENEXR_INSTALL_EXAMPLES)
if(OPENEXR_BUILD_EXAMPLES AND OPENEXR_BUILD_LIBS)
add_subdirectory( src/examples )
endif()
@@ -116,7 +143,7 @@ endif()
#set(CTEST_DROP_SITE_CDASH TRUE)
include(CTest)
if(BUILD_TESTING AND NOT OPENEXR_IS_SUBPROJECT)
if(BUILD_TESTING AND OPENEXR_BUILD_LIBS AND NOT OPENEXR_IS_SUBPROJECT)
add_subdirectory(src/test)
endif()
@@ -126,9 +153,21 @@ if(NOT OPENEXR_IS_SUBPROJECT)
include(cmake/clang-format.cmake)
endif()
option(BUILD_DOCS "Set ON to build html documentation")
if (BUILD_DOCS AND NOT OPENEXR_IS_SUBPROJECT)
option(INSTALL_DOCS "Set ON to install html documentation" ON)
option(OPENEXR_INSTALL_DOCS "Set ON to install tool manpages")
if (OPENEXR_INSTALL_DOCS AND NOT OPENEXR_IS_SUBPROJECT)
add_subdirectory(docs)
endif()
option(BUILD_WEBSITE "Set ON to build website source")
if (BUILD_WEBSITE AND NOT OPENEXR_IS_SUBPROJECT)
add_subdirectory(website)
endif()
if (OPENEXR_BUILD_LIBS AND NOT OPENEXR_IS_SUBPROJECT)
# Even if not building the website, still make sure the website example code compiles.
add_subdirectory(website/src)
endif()
if (OPENEXR_BUILD_PYTHON AND OPENEXR_BUILD_LIBS AND NOT OPENEXR_IS_SUBPROJECT)
add_subdirectory(src/wrappers/python)
endif()
+305 -12
View File
@@ -11,7 +11,8 @@ explains our contribution process and procedures:
* [Development Workflow](#Development-Workflow)
* [Coding Style](#Coding-Style)
* [Versioning Policy](#Versioning-Policy)
* [Creating a Release](#Creating-a-Release)
* [Creating a Patch Release](#Creating-a-Patch-Release)
* [Creating a Major/Minor Release](#Creating-a-Major/Minor-Release)
For a description of the roles and responsibilities of the various
members of the OpenEXR community, see [GOVERNANCE](GOVERNANCE.md), and
@@ -210,7 +211,7 @@ openexr-dev@lists.aswf.io mail list.
### Pull Requests
Contributions should be submitted as Github pull requests. See
Contributions should be submitted as GitHub pull requests. See
[Creating a pull request](https://help.github.com/articles/creating-a-pull-request/)
if you're unfamiliar with this concept.
@@ -226,7 +227,7 @@ with a separate pull request.
3. Push commits to your fork.
4. Create a Github pull request from your topic branch.
4. Create a GitHub pull request from your topic branch.
5. Pull requests will be reviewed by project committers and contributors,
who may discuss, offer constructive feedback, request changes, or approve
@@ -258,7 +259,7 @@ submitted, in order to solicit feedback, try to get as much consensus
as possible, and alert all the stakeholders to be on the lookout for
the eventual PR when it appears.
* Trivial changes that don't affect functionality (typos, docs, tests)
* Trivial changes that don't affect functionality (typos, tests, website)
can be approved by the committer without review, after waiting at
least 48 hours.
@@ -452,19 +453,311 @@ each version with three numbers: ``major.minor.patch``, where:
* ``minor`` - indicates functionality added in a backwards-compatible manner
* ``patch`` - indicates backwards-compatible bug fixes
## Creating a Release
## Creating a Patch Release
Making a patch release typically involves merging changes from the
main branch into the release branch, since all development generally
takes place on the main branch. The usual workflow is to group these
changes together and merge them all just prior to a release, rather
than merging one-by-one as the changes go into main, although merging
along the way is acceptable as well. For OpenEXR and Imath, a patch
release typically involves under a dozen commits, so it's not a huge
amount of work to organize them all at once.
A patch release *must* be ABI-compatible with preceding minor releases
and should be validated with an ABI-checker tool such as
[``abipkgdiff``](https://manpages.ubuntu.com/manpages/lunar/en/man1/abipkgdiff.1.html).
These instructions are for project administrators who have "push"
access on the GitHub repo.
The preferred workflow is:
1. Make a PR that merges appropriate changes from the main branch to
the release branch:
a. In a forked clone, create a branch to hold the patch commits,
e.g. ``v3.1.9-fixes``.
b. Cherry-pick the appropriate commits from ``main``, resolving any
merge conflicts.
c. Increment ``OPENEXR_VERSION_PATCH`` in
[src/lib/OpenEXRCore/openexr_version.h](src/lib/OpenEXRCore/openexr_version.h)
d. Update the ``IMATH_TAG`` setting in
[cmake/OpenEXRSetup.cmake](cmake/OpenEXRSetup.cmake) to
correspond to the proper Imath release.
e. Add release notes to [CHANGES.md](CHANGES.md):
- Generate a list of links to merged pull requests.
Use ``git log`` to identify the merged commits, and for each
commit, and add a link in the notes to the corresponding PR
that merged it to ``main``. Citing PR's in the release notes
is preferable to citing raw commits because the PR's often
have helpful information and discussion missing from the
commit descriptions, and the commit history is readily
accessible via ``git log`` anyway.
The typical OpenEXR project workflow uses "squash and merge"
to merge PR's into ``main``, so the changes involved in each
PR end up on ``main`` as a single commit. This is preferable
because a raw PR often includes numerous commits that address
comments and feedback or fix typos or mistakes, intermediate
steps not helpful to the preserved history of the main
development thread. Note that GitHub's "squash and merge"
helpfully appends the PR number to the commit subject line.
Note that when this PR is merged to the release branch, it
should go in via "rebase and merge" that the release branch
retains the granular changes, described below.
- Generate a list of OSS-Fuzz issues addressed.
These are security concerns, so they deserve special
attention. Provide a link in the notes to the issue at
https://bugs.chromium.org/p/oss-fuzz, including the issue id
number and description.
- If there are any public CVE's, mention them explicitly with a
link to the CVE registry item.
- Provide an executive summary of the patch changes, in a few
sentences as well as bullet points if appropriate.
- Choose a proposed release date at least several days in
advance.
f. If there are any public CVE's, reference them in
[SECURITY.md](SECURITY.md).
g. Submit the PR for others to review. The PR should go *to the
release branch, not ``main``*, obviously.
h. After others have had a chance to sanity-check the changes,
merge the PR *with "rebase and merge"*. Unlike with the usual
PR's merged to main, it is essential to retain the individual
commits on the release branch. That way, the release branch
commit history retains the details of the changes.
i. If further fixes come in that need to go into the release, push
them to the PR branch. It's not absolutely essential that all
changes to the release branch go in via a PR. The PR is simply a
convient forum for publicly discussing and reviewing the
composition of the release.
2. Tag the release with a ``-rc`` "release candidate" tag,
e.g. ``v3.1.9-rc``.
3. Validate ABI compatibility. Build at the release candidate tag and
run
[abipkgdiff](https://manpages.ubuntu.com/manpages/lunar/en/man1/abipkgdiff.1.html)
against a build of the previous patch release to confirm that no
ABI changes have leaked in. Additions to the ABI are acceptable for
a patch release, but there should be no symbol changes and no
symbols removed. If there are, back up and fix them before proceeding.
4. Send mail to ``openexr-dev@lists.aswf.io`` announcing the staging
of the release with link to the release candidate tag. Include the
release notes from [CHANGES.md](CHANGES.md) for review.
5. Draft the release on the GitHub
[Releases](https://github.com/AcademySoftwareFoundation/openexr/releases)
page. Include the summary from the notes in
[CHANGES.md](CHANGES.md), but don't include the list of PR's.
Create the release from the latest ``--rc`` tag, and give it a name
that begins with ``v``, i.e. ``v3.1.9``.
Save the release as a "draft".
6. Wait at least 48 hours, to give the community time to discover and
report any obvious problems. Avoid the temptation to rush changes
into a release and publish it immediately, as that is uncomfortably
error prone.
If additional fixes need to go in before release:
a. Merge commits to the release branch. Push them directly, no need
for a pull request.
b. Update the release notes in a separate commit.
c. Re-tag with a incremented "release candidate" number,
e.g. ``v3.1.9-rc2``.
d. Send an email update to ``openexr-dev@lists.aswf.io`` notifying
the community of the addition and the new tag.
7. Create a signed release tag
a. Make sure you have a [GPG
key](https://docs.github.com/en/authentication/managing-commit-signature-verification/generating-a-new-gpg-key)
and it is
[registered](https://docs.github.com/en/authentication/managing-commit-signature-verification/telling-git-about-your-signing-key)
with your GitHub account and git config.
b. Create a signed tag with the release name via `git tag -s v3.1.9`.
c. Push the tag via `git push --tags`
8. Publish the release
a. Click the "Publish release" button on the GitHub release draft
b. Send an email to ``openexr-dev@lists.aswf.io`` officially
annoucing the release.
9. Update the ``release`` branch, which should always point to the
most recent patch of the most recent minor release, i.e. the most
preferred release.
From a clone of the main repo:
% git checkout release
% git merge RB-3.1
% git push
10. Submit a PR that adds the release notes to [CHANGES.md](CHANGES.md)
on the main branch. Cherry-pick the release notes commit from
the release branch.
- If any changes have gone into [SECURITY.md](SECURITY), cherry-pick
the associated commit as well.
- Also include in this PR edits to [``docs/news.rst``](docs/news.rst)
that add an announcment of the release.
11. After review/merge of the updates to ``docs/news.rst``, build the
website at https://readthedocs.org/projects/openexr.
12. If the release has resolved any OSS-Fuzz issues, update the
associated pages at https://bugs.chromium.org/p/oss-fuzz with a
reference to the release.
13. If the release has resolved any public CVE's, request an update
from the registry service providing the release and a link to the
release notes.
## Creating a Major/Minor Release
A major/minor release is created from the main branch, assuming there
are no changes on ``main`` that should *not* go into the release. We
don't generally allow experimental changes onto ``main``. Anything
accepted onto ``main`` should be intended for the next release.
The overall workflow is similar to a patch release, as described
above, but it's simpler because there is no cherry-picking and merging
of commits. The major/minor release is simply a snapshot of ``main``.
To create a new release from the ``main`` branch:
1. Update the release notes in ``CHANGES.md``.
1. Confirm that the ``OPENEXR_VERSION_MAJOR``,
``OPENEXR_VERSION_MINOR``, and ``OPENEXR_VERSION_PATCH`` value in
[src/lib/OpenEXRCore/openexr_version.h](src/lib/OpenEXRCore/openexr_version.h)
are correct. The OpenEXR project policy is that the values on the
main branch, which is the bleeding edge of development, correspond
to the next minor release, with the patch set to 0.
Write a high-level summary of the features and
improvements. Include the summary in ``CHANGES.md`` and also in the
Release comments.
2. Update the release notes in [CHANGES.md](CHANGES.md):
Include the log of all PR's included beyond the previous release.
- Write a high-level summary of the features and improvements.
2. Create a new release on the GitHub Releases page.
- Include the log of all PR's that have *not* been merged into the
previous minor release.
3. Tag the release with name beginning with ``v``', e.g. ``v2.3.0``.
- Mention any OSS-Fuzz issues. Provide a link in the notes to the issue at
https://bugs.chromium.org/p/oss-fuzz, including the issue id
number and description.
- If there are any public CVE's, mention them explicitly with a
link to the CVE registry item.
- Submit this change as a separate PR.
3. Add a mention of the release to [``docs/news.rst``](docs/news.rst)
- Submit this change as a separate PR.
4. Increment the ``OPENEXR_LIB_SOVERSION`` setting in [CMakeLists.txt](CMakeLists.txt).
- The SO version increases whenever, and only when, the ABI changes
in non-backwards-compatible ways. Consistent with the semantic
versioning policy, this usually happens at major and minor
releases, but never on a patch release.
- Submit this change as a separate PR for review.
5. Once the above PR's are merged, create the release branch with the
``RB`` prefix, e.g. ``RB-3.2``.
6. Update the ``IMATH_TAG`` setting in
[cmake/OpenEXRSetup.cmake](cmake/OpenEXRSetup.cmake) to correspond
to the proper Imath release.
7. Tag the release with a ``-rc`` "release candidate" tag,
e.g. ``v3.2.0-rc``.
8. Send mail to ``openexr-dev@lists.aswf.io`` announcing the staging
of the release with link to the release candidate tag. Include the
release notes from [CHANGES.md](CHANGES.md) for review.
9. If additonal fixes need to go in before release:
a. Merge commits to the release branch. Push them directly, no need
for a pull request.
b. Update the release notes in a separate commit.
c. Re-tag with a incremented "release candidate" number,
e.g. ``v3.2.0-rc2``.
d. Send a email update to ``openexr-dev@lists.aswf.io`` notifying
the community of the addition.
10. Draft the release on the GitHub
[Releases](https://github.com/AcademySoftwareFoundation/openexr/releases)
page. Include the summary from the notes in
[CHANGES.md](CHANGES.md), but don't include the list of PR's.
- Create the release from the latest ``--rc`` tag, and give it a name
that begins with ``v`` and ends in ``0``, e.g. ``v3.2.0``.
- Save the release as a "draft".
11. Wait at least 48 hours after the email announcement.
12. Publish the release
a. Click the "Publish release" button on the GitHub release draft
b. Send an email to ``openexr-dev@lists.aswf.io`` officially
annoucing the release.
13. Update the ``release`` branch, which should always point to the
most recent release.
From a clone of the main repo:
% git checkout release
% git merge RB-3.1
% git push
14. Increment ``OPENEXR_VERSION_MINOR`` in
[src/lib/OpenEXRCore/openexr_version.h](src/lib/OpenEXRCore/openexr_version.h) on the main branch
- Submit a PR for this. This leaves the release version on the
main branch pointing to the next minor release, as described in
Step #1.
15. Build the website at https://readthedocs.org/projects/openexr.
16. If the release has resolved any OSS-Fuzz issues, update the
associated pages at https://bugs.chromium.org/p/oss-fuzz with a
reference to the release.
17. If the release has resolved any public CVE's, request an update
from the registry service providing the release and a link to the
release notes.
+47 -2
View File
@@ -4,20 +4,37 @@
This is a list of contributors to the OpenEXR project, sorted
alphabetically by first name.
If you know of missing, please email: info@openexr.com.
If you know of missing, please email info@openexr.com or submit a PR.
* Aaron Demolder
* Abe Fettig
* Aloys Baillet
* Andre Mazzone
* Andrew Kunz
* Anton Dukhovnikov
* Antonio Rojas
* Aras Pranckevičius
* Arkady Shapkin
* Arkell Rasiah
* Axel Waggershauser
* Balázs Oroszi
* Barnaby Robson
* Ben Grimes
* Brendan Bolles
* Cary Phillips
* Chris Leu
* Christina Tempelaar-Lietz
* Christopher Horvath
* Christopher Kulla
* Christoph Gohlke
* Cristian Martínez
* Dan Horák
* Daniel Kaneider
* Darby Johnston
* Dave Sawyer
* David Korczynski
* Diogo Teles Sant'Anna
* Dirk Lemstra
* Drew Hess
* Ed Hanway
* Edward Kmett
@@ -25,47 +42,75 @@ If you know of missing, please email: info@openexr.com.
* Eric Wimmer
* E Sommerlade
* Florian Kainz
* Grant Kim
* Gregorio Litenstein
* Gyula Gubacsi
* Halfdan Ingvarsson
* Harry Mallon
* Huibean Luo
* Ibraheem Alhashim
* Jack Kingsman
* Jamie Kenyon
* Jan Tojnar
* Jean-Francois Panisset
* Jens Lindgren
* Ji Hun Yu
* Johannes Vollmer
* John Loy
* John Mertic
* Jonathan Stone
* Jose Luis Cercos-Pita
* Joseph Goldstone
* Juha Reunanen
* Julian Amann
* Juri Abramov
* Karl Hendrikse
* Karl Rasche
* Kevin Wheatley
* Kimball Thurston
* Larry Gritz
* Laurens Voerman
* L. E. Segovia
* Liam Fernandez
* Lucy Wilkes
* Mark Reid
* Mark Sisson
* Martin Aumüller
* Martin Husemann
* Matthäus G. Chajdas
* Matthias C. M. Troffaes
* Matt Pharr
* Md Sadman Chowdhury
* Michael Thomas
* Nicholas Yue
* Nick Porcino
* Nick Rasmussen
* Nicolas Chauvet
* Niklas Hambüchen
* OgreTransporter
* Owen Thompson
* Paul Schneider
* Peter Hillman
* Peter Steneteg
* Peter Urbanec
* Phil Barrett
* Piotr Stanczyk
* Ralph Potter
* Rémi Achard
* Reto Kromer
* Richard Goedeken
* Sergey Fedorov
* Shawn Walker-Salas
* Simon Boorer
* Simon Otter
* Srinath Ravichandran
* Thanh Ha
* Thomas Debesse
* Thorsten Kaufmann
* Timothy Lyanguzov
* Wenzel Jakob
* Wojciech Jarosz
* Xo Wang
* Yaakov Selkowitz
* Yining Karl Li
* Yujie Shu
+1 -1
View File
@@ -51,7 +51,7 @@ namespace PxDeep
//-*****************************************************************************
// DENSITY
//-*****************************************************************************
// "Density" refers to the the optical density which, when integrated
// "Density" refers to the optical density which, when integrated
// through a line, produces an alpha. The relationship between alpha, density,
// and line segment of a given length "dz" is as follows:
//
-3
View File
@@ -1,6 +1,3 @@
<!-- SPDX-License-Identifier: BSD-3-Clause -->
<!-- Copyright (c) Contributors to the OpenEXR Project -->
Copyright (c) Contributors to the OpenEXR Project. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+12
View File
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
module(
name = "openexr",
compatibility_level = 1,
)
bazel_dep(name = "bazel_skylib", version = "1.5.0")
bazel_dep(name = "imath", version = "3.1.10", repo_name = "Imath")
bazel_dep(name = "libdeflate", version = "1.19")
bazel_dep(name = "platforms", version = "0.0.8")
+7 -8
View File
@@ -52,13 +52,13 @@ package.
OpenEXR is a project of the [Academy Software
Foundation](https://www.aswf.io). See the project's [governance
policies](GOVERNANCE.md), [contribution guidelines](CONTRIBzuTING.md), and [code of conduct](CODE_OF_CONDUCT)
policies](GOVERNANCE.md), [contribution guidelines](CONTRIBUTING.md), and [code of conduct](CODE_OF_CONDUCT)
for more information.
# Quick Start
See the [technical documentation](https://openexr.readthedocs.io) for
complete details, but to get started, the "hello, world" `.exr` writer program is:
complete details, but to get started, the "Hello, world" [`exrwriter.cpp`](https://raw.githubusercontent.com/AcademySoftwareFoundation/openexr/main/website/src/exrwriter/exrwriter.cpp) writer program is:
#include <ImfRgbaFile.h>
#include <ImfArray.h>
@@ -86,20 +86,19 @@ complete details, but to get started, the "hello, world" `.exr` writer program i
return 0;
}
The `CMakeLists.txt` to build:
The [`CMakeLists.txt`](https://raw.githubusercontent.com/AcademySoftwareFoundation/openexr/main/website/src/exrwriter/CMakeLists.txt) to build:
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.12)
project(exrwriter)
find_package(OpenEXR REQUIRED)
add_executable(${PROJECT_NAME} writer.cpp)
add_executable(${PROJECT_NAME} exrwriter.cpp)
target_link_libraries(${PROJECT_NAME} OpenEXR::OpenEXR)
To build:
$ mkdir _build
$ cmake -S . -B _build
$ make --build _build
$ cmake -S . -B _build -DCMAKE_PREFIX_PATH=<path to OpenEXR libraries/includes>
$ cmake --build _build
For more details, see [The OpenEXR
API](https://openexr.readthedocs.io/en/latest/API.html#the-openexr-api).
+125 -7
View File
@@ -6,19 +6,21 @@
## Reporting a Vulnerability
If you think you've found a potential vulnerability in OpenEXR, please
report it by emailing security@openexr.org. Only Technical Steering
Committee members and Academy Software Foundation project management
have access to these messages. Include detailed steps to reproduce the
issue, and any other information that could aid an investigation. Our
policy is to respond to vulnerability reports within 14 days.
report it by filing a GitHub [security
advisory](https://github.com/AcademySoftwareFoundation/openexr/security/advisories/new). Alternatively,
email security@openexr.com and provide your contact info for further
private/secure discussion. If your email does not receive a prompt
acknowledgement, your address may be blocked.
Our policy is to address critical security vulnerabilities rapidly and
post patches as quickly as possible.
Our policy is to acknowledge the receipt of vulnerability reports
within 48 hours. Our policy is to address critical security vulnerabilities
rapidly and post patches within 14 days if possible.
## Known Vulnerabilities
These vulnerabilities are present in the given versions:
* [CVE-2023-5841](https://takeonme.org/cves/CVE-2023-5841.html) 3.1.0, 3.1.1, 3.1.2, 3.1.3 3.1.4 3.1.5 3.1.6 3.1.7 3.1.8 3.1.9 3.1.10 3.1.11 3.2.0 3.2.1
* [CVE-2021-45942](https://nvd.nist.gov/vuln/detail/CVE-2021-45942) 3.1.0, 3.1.1, 3.1.2, 3.1.3
* [CVE-2021-20296](https://nvd.nist.gov/vuln/detail/CVE-2021-20296) 2.4.0, 2.4.1, 2.4.2, 2.5.0, 2.5.1, 2.5.2, 2.5.3
* [CVE-2021-3479](https://nvd.nist.gov/vuln/detail/CVE-2021-3479) 2.4.0, 2.4.1, 2.4.2, 2.5.0, 2.5.1, 2.5.2, 2.5.3
@@ -57,3 +59,119 @@ These vulnerabilities are present in the given versions:
See the [release notes](CHANGES.md) for more information.
## Supported Versions
This gives guidance about which branches are supported with patches to
security vulnerabilities.
| Version / branch | Supported |
| --------- | ---------------------------------------------------- |
| main | :white_check_mark: :construction: ALL fixes immediately, but this is a branch under development with a frequently unstable ABI and occasionally unstable API. |
| 3.2.x | :white_check_mark: All fixes that can be backported without breaking ABI compatibility. |
| 3.1.x | :warning: Only the most critical fixes, only if they can be easily backported. |
| 3.0.x | :warning: Only the most critical fixes, only if they can be easily backported. |
| 2.5.x | :warning: Only the most critical fixes, only if they can be easily backported. |
| <= 1.x | :x: No longer receiving patches of any kind. |
## Signed Releases
Releases artifacts are signed via
[sigstore](https://www.sigstore.dev). See
[release-sign.yml](.github/workflows/release-sign.yml) for details.
To verify a downloaded release at a given tag:
% pip install sigstore
% sigstore verify github --cert-identity https://github.com/AcademySoftwareFoundation/openexr/.github/workflows/release-sign.yml@refs/tags/<tag> openexr-<tag>.tar.gz
## Security Expectations
### Software Features
- The OpenEXR project implements the EXR image file format, used
throughout the motion picture industry and beyond, on Linux, macOS,
and Windows.
- The project consists of a software run-time library, implemented in
C/C++ and built via cmake, that reads and writes image data
files. The project also distributes python wrappings for the C/C++
I/O API.
- The library reads and writes binary image data and text-based
metadata, treated as blind data, none of which is executable code.
- Other than the website and online technical documentation, the
project implements no web/online services or network communication
protocols. The library never requests any security or
authentication credentials or login information from users.
The website implements no interactive features and requires no login
credentials.
- The library reads and writes only to file paths specificly requested
via the C/C++ API. The runtime library uses no system configuration
files or sidecar data files. Access to data files uses only standard
file I/O system calls.
- The library compresses/decompresses data via standard compression
algorithms but uses no cryptographic or confidentiality protocols.
### Software Dependencies
OpenEXR depends on
[Imath](https://github.com/AcademySoftwareFoundation/Imath), a library
of basic math operations also maintained and distributed by the
OpenEXR project. Imath follows the same security conventions
documented here for OpenEXR itself. The core Imath library has no
external dependencies. The Imath python bindings depend on python and
boost.
The only
external library dependency of OpenEXR is
[libdeflate](https://github.com/ebiggers/libdeflate), which implements
standard deflate/zlib/gzip compression and decompression.
The project uses
[Snyk](https://github.com/AcademySoftwareFoundation/openexr/blob/main/.github/workflows/snyk-scan-pr.yml)
to scan for dependency vulnerability.
### Potential Vulnerabilities
Potential entry points are images being loaded using the
library. Malformed images could caused issues such as heap buffer
overflows, out-of-memory faults, or segmentation faults that could be
exploitable as denial-of-service attacks.
### Hardening
#### Testing
The OpenEXR project implements a comprehensive suite of validation
tests, including fuzz testing to harden against malicious input
data. Note that fuzz testing hardens only against *small* input data
files and is not a comprehensive test against all potential input.
Note that the
[exrcheck](https://github.com/AcademySoftwareFoundation/openexr/tree/main/src/bin/exrcheck)
utility is intended to be used by testers to demonstrate a particular
proof-of-concept input file exposes a vulnerability, and it is very
helpful to let us know if a vulnerability can be reproduced using that
tool.
The project also uses the [OSS
Fuzz](https://bugs.chromium.org/p/oss-fuzz) service for continuous
fuzz testing.
#### Development Cycle and Distribution
OpenEXR is downloadable and buildable by C/C++ source via GitHub. Only
members of the project's Technical Steering Committee, all veteran
software engineers at major motion picture studios or vendors, have
write permissions on the source code repository. All critical software
changes are reviewed by multiple TSC members.
The library is distributed in binary form via many common package
managers across all platforms.
+3
View File
@@ -1,3 +1,6 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
workspace(name = "com_openexr")
load("//:bazel/third_party/openexr_deps.bzl", "openexr_deps")
-8
View File
@@ -1,8 +0,0 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
cc_binary(
name = "Demo",
srcs = ["main.cpp"],
deps = ["//:OpenEXR"],
)
-61
View File
@@ -1,61 +0,0 @@
#include <ImfRgba.h>
#include <ImfRgbaFile.h>
#include <string>
// Function copied (with minor modifications) from pbrt-v3 (https://github.com/mmp/pbrt-v3) which is under BSD-2-Clause License
static void
WriteImageEXR (
const std::string& name,
const float* pixels,
int xRes,
int yRes,
int totalXRes,
int totalYRes,
int xOffset,
int yOffset)
{
using namespace Imf;
using namespace Imath;
Rgba* hrgba = new Rgba[xRes * yRes];
for (int i = 0; i < xRes * yRes; ++i)
hrgba[i] = Rgba (pixels[3 * i], pixels[3 * i + 1], pixels[3 * i + 2]);
// OpenEXR uses inclusive pixel bounds.
Box2i displayWindow (V2i (0, 0), V2i (totalXRes - 1, totalYRes - 1));
Box2i dataWindow (
V2i (xOffset, yOffset), V2i (xOffset + xRes - 1, yOffset + yRes - 1));
try
{
RgbaOutputFile file (
name.c_str (), displayWindow, dataWindow, WRITE_RGB);
file.setFrameBuffer (hrgba - xOffset - yOffset * xRes, 1, xRes);
file.writePixels (yRes);
}
catch (const std::exception& exc)
{
throw std::runtime_error ("Error writing");
}
delete[] hrgba;
}
int
main ()
{
float data[3 * 100 * 100];
for (int y = 0; y < 100; ++y)
for (int x = 0; x < 100; ++x)
{
data[(y * 100 + x) * 3 + 0] = 0.f;
data[(y * 100 + x) * 3 + 1] = 1.f;
data[(y * 100 + x) * 3 + 2] = 0.f;
}
WriteImageEXR ("test.exr", data, 100, 100, 100, 100, 0, 0);
return 0;
}
+6 -6
View File
@@ -8,14 +8,14 @@ expand_template(
out = "src/Imath/ImathConfig.h",
substitutions = {
"@IMATH_INTERNAL_NAMESPACE@": "Imath_3_1",
"@IMATH_LIB_VERSION@": "3.1.7",
"@IMATH_LIB_VERSION@": "3.1.9",
"@IMATH_NAMESPACE_CUSTOM@": "0",
"@IMATH_NAMESPACE@": "Imath",
"@IMATH_PACKAGE_NAME@": "Imath 3.1.7",
"@IMATH_VERSION_MAJOR@": "3",
"@IMATH_VERSION_MINOR@": "1",
"@IMATH_VERSION_PATCH@": "7",
"@IMATH_VERSION@": "3.1.7",
"@IMATH_PACKAGE_NAME@": "Imath 3.1.9",
"@Imath_VERSION_MAJOR@": "3",
"@Imath_VERSION_MINOR@": "1",
"@Imath_VERSION_PATCH@": "9",
"@IMATH_VERSION@": "3.1.9",
"#cmakedefine IMATH_HALF_USE_LOOKUP_TABLE": "#define IMATH_HALF_USE_LOOKUP_TABLE",
"#cmakedefine IMATH_ENABLE_API_VISIBILITY": "#define IMATH_ENABLE_API_VISIBILITY",
"#cmakedefine IMATH_HAVE_LARGE_STACK": "/* #undef IMATH_HAVE_LARGE_STACK */",
+55
View File
@@ -0,0 +1,55 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
cc_library(
name = "deflate",
srcs = [
"common_defs.h",
"lib/adler32.c",
"lib/adler32_vec_template.h",
"lib/arm/adler32_impl.h",
"lib/arm/cpu_features.c",
"lib/arm/cpu_features.h",
"lib/arm/crc32_impl.h",
"lib/arm/crc32_pmull_helpers.h",
"lib/arm/crc32_pmull_wide.h",
"lib/arm/matchfinder_impl.h",
"lib/bt_matchfinder.h",
"lib/cpu_features_common.h",
"lib/crc32.c",
"lib/crc32_multipliers.h",
"lib/crc32_tables.h",
"lib/decompress_template.h",
"lib/deflate_compress.c",
"lib/deflate_compress.h",
"lib/deflate_constants.h",
"lib/deflate_decompress.c",
"lib/gzip_compress.c",
"lib/gzip_constants.h",
"lib/gzip_decompress.c",
"lib/hc_matchfinder.h",
"lib/ht_matchfinder.h",
"lib/lib_common.h",
"lib/matchfinder_common.h",
"lib/utils.c",
"lib/x86/adler32_impl.h",
"lib/x86/cpu_features.c",
"lib/x86/cpu_features.h",
"lib/x86/crc32_impl.h",
"lib/x86/crc32_pclmul_template.h",
"lib/x86/decompress_impl.h",
"lib/x86/matchfinder_impl.h",
"lib/zlib_compress.c",
"lib/zlib_constants.h",
"lib/zlib_decompress.c",
],
hdrs = ["libdeflate.h"],
includes = ["."],
visibility = ["//visibility:public"],
)
alias(
name = "libdeflate",
actual = ":deflate",
visibility = ["//visibility:public"],
)
+14 -16
View File
@@ -7,34 +7,32 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
load("@bazel_tools//tools/build_defs/repo:utils.bzl", "maybe")
def openexr_deps():
"""Fetches dependencies (zlib and Imath) of OpenEXR and Skylib for header generation."""
"""Fetches dependencies (libdeflate and Imath) of OpenEXR and Skylib for header generation."""
maybe(
http_archive,
name = "net_zlib_zlib",
build_file = "@com_openexr//:bazel/third_party/zlib.BUILD",
sha256 = "b3a24de97a8fdbc835b9833169501030b8977031bcb54b3b3ac13740f846ab30",
strip_prefix = "zlib-1.2.13",
urls = [
"https://mirror.bazel.build/zlib.net/zlib-1.2.13.tar.gz",
"https://zlib.net/zlib-1.2.13.tar.gz",
],
name = "libdeflate",
build_file = "@com_openexr//:bazel/third_party/libdeflate.BUILD",
sha256 = "27bf62d71cd64728ff43a9feb92f2ac2f2bf748986d856133cc1e51992428c25",
strip_prefix = "libdeflate-1.19",
urls = ["https://github.com/ebiggers/libdeflate/archive/refs/tags/v1.19.tar.gz"],
)
maybe(
http_archive,
name = "Imath",
build_file = "@com_openexr//:bazel/third_party/Imath.BUILD",
strip_prefix = "Imath-3.1.7",
sha256 = "bff1fa140f4af0e7f02c6cb78d41b9a7d5508e6bcdfda3a583e35460eb6d4b47",
urls = ["https://github.com/AcademySoftwareFoundation/Imath/archive/refs/tags/v3.1.7.tar.gz"],
strip_prefix = "Imath-3.1.10",
sha256 = "f2943e86bfb694e216c60b9a169e5356f8a90f18fbd34d7b6e3450be14f60b10",
urls = ["https://github.com/AcademySoftwareFoundation/Imath/archive/refs/tags/v3.1.10.tar.gz"],
)
http_archive(
maybe(
http_archive,
name = "bazel_skylib",
sha256 = "b8a1527901774180afc798aeb28c4634bdccf19c4d98e7bdd1ce79d1fe9aaad7",
sha256 = "cd55a062e763b9349921f0f5db8c3933288dc8ba4f76dd9416aac68acee3cb94",
urls = [
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.1/bazel-skylib-1.4.1.tar.gz",
"https://mirror.bazel.build/github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz",
"https://github.com/bazelbuild/bazel-skylib/releases/download/1.5.0/bazel-skylib-1.5.0.tar.gz",
],
)
-98
View File
@@ -1,98 +0,0 @@
# Copied from https://github.com/protocolbuffers/protobuf/blob/master/third_party/zlib.BUILD
# Copyright 2008 Google Inc. All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
# Code generated by the Protocol Buffer compiler is owned by the owner
# of the input file used when generating it. This code is not
# standalone and requires a support library to be linked with it. This
# support library is itself covered by the above license.
load("@rules_cc//cc:defs.bzl", "cc_library")
licenses(["notice"]) # BSD/MIT-like license (for zlib)
_ZLIB_HEADERS = [
"crc32.h",
"deflate.h",
"gzguts.h",
"inffast.h",
"inffixed.h",
"inflate.h",
"inftrees.h",
"trees.h",
"zconf.h",
"zlib.h",
"zutil.h",
]
_ZLIB_PREFIXED_HEADERS = ["zlib/include/" + hdr for hdr in _ZLIB_HEADERS]
# In order to limit the damage from the `includes` propagation
# via `:zlib`, copy the public headers to a subdirectory and
# expose those.
genrule(
name = "copy_public_headers",
srcs = _ZLIB_HEADERS,
outs = _ZLIB_PREFIXED_HEADERS,
cmd = "cp $(SRCS) $(@D)/zlib/include/",
)
cc_library(
name = "zlib",
srcs = [
"adler32.c",
"compress.c",
"crc32.c",
"deflate.c",
"gzclose.c",
"gzlib.c",
"gzread.c",
"gzwrite.c",
"infback.c",
"inffast.c",
"inflate.c",
"inftrees.c",
"trees.c",
"uncompr.c",
"zutil.c",
# Include the un-prefixed headers in srcs to work
# around the fact that zlib isn't consistent in its
# choice of <> or "" delimiter when including itself.
] + _ZLIB_HEADERS,
hdrs = _ZLIB_PREFIXED_HEADERS,
copts = select({
"@bazel_tools//src/conditions:windows": [],
"//conditions:default": [
"-Wno-unused-variable",
"-Wno-implicit-function-declaration",
],
}),
includes = ["zlib/include/"],
visibility = ["//visibility:public"],
)
+4 -13
View File
@@ -71,15 +71,8 @@ endif()
configure_file(OpenEXRConfig.h.in ${CMAKE_CURRENT_BINARY_DIR}/OpenEXRConfig.h)
configure_file(OpenEXRConfigInternal.h.in ${CMAKE_CURRENT_BINARY_DIR}/OpenEXRConfigInternal.h)
if(OPENEXR_INSTALL)
install(
FILES
${CMAKE_CURRENT_BINARY_DIR}/OpenEXRConfig.h
DESTINATION
${CMAKE_INSTALL_INCLUDEDIR}/${OPENEXR_OUTPUT_SUBDIR}
)
endif()
# make a temp copy in the binary dir for OpenEXRConfig.h to include
configure_file(../src/lib/OpenEXRCore/openexr_version.h ${CMAKE_CURRENT_BINARY_DIR}/OpenEXRCore/openexr_version.h COPYONLY)
###################################################
####### IexConfig.h and IexConfigInternal.h
@@ -209,9 +202,6 @@ if(OPENEXR_INSTALL_PKG_CONFIG)
endif()
set(exr_pthread_libs ${CMAKE_THREAD_LIBS_INIT})
endif()
if(NOT zlib_INTERNAL_DIR)
set(zlib_link "-lz")
endif()
string(REPLACE ".in" "" pcout ${pcinfile})
configure_file(${pcinfile} ${CMAKE_CURRENT_BINARY_DIR}/${pcout} @ONLY)
install(
@@ -220,8 +210,9 @@ if(OPENEXR_INSTALL_PKG_CONFIG)
)
endfunction()
openexr_pkg_config_help(OpenEXR.pc.in)
message(STATUS "OpenEXR pkg-config generation enabled")
else()
message(STATUS "-- pkg-config generation disabled")
message(STATUS "OpenEXR pkg-config generation disabled")
endif()
###################################################
+5 -1
View File
@@ -27,6 +27,9 @@ function(OPENEXR_DEFINE_LIBRARY libname)
PRIVATE cxx_std_${OPENEXR_CXX_STANDARD}
INTERFACE cxx_std_11 )
# we are embedding libdeflate
target_include_directories(${objlib} PRIVATE ${EXR_DEFLATE_INCLUDE_DIR})
if(OPENEXR_CURLIB_PRIV_EXPORT AND BUILD_SHARED_LIBS)
target_compile_definitions(${objlib} PRIVATE ${OPENEXR_CURLIB_PRIV_EXPORT})
if(WIN32)
@@ -90,7 +93,8 @@ function(OPENEXR_DEFINE_LIBRARY libname)
string(TOUPPER "${CMAKE_BUILD_TYPE}" uppercase_CMAKE_BUILD_TYPE)
set(verlibname ${CMAKE_SHARED_LIBRARY_PREFIX}${libname}${OPENEXR_LIB_SUFFIX}${CMAKE_${uppercase_CMAKE_BUILD_TYPE}_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
set(baselibname ${CMAKE_SHARED_LIBRARY_PREFIX}${libname}${CMAKE_${uppercase_CMAKE_BUILD_TYPE}_POSTFIX}${CMAKE_SHARED_LIBRARY_SUFFIX})
install(CODE "execute_process(COMMAND ${CMAKE_COMMAND} -E chdir \"\$ENV\{DESTDIR\}${CMAKE_INSTALL_FULL_LIBDIR}\" ${CMAKE_COMMAND} -E create_symlink ${verlibname} ${baselibname})")
file(CREATE_LINK ${verlibname} ${CMAKE_CURRENT_BINARY_DIR}/${baselibname} SYMBOLIC)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${baselibname} DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR})
install(CODE "message(STATUS \"Creating symlink ${CMAKE_INSTALL_FULL_LIBDIR}/${baselibname} -> ${verlibname}\")")
set(verlibname)
set(baselibname)
+2 -1
View File
@@ -17,4 +17,5 @@ Version: @OPENEXR_VERSION@
Libs: @exr_pthread_libs@ -L${libdir} -lOpenEXR${libsuffix} -lOpenEXRUtil${libsuffix} -lOpenEXRCore${libsuffix} -lIex${libsuffix} -lIlmThread${libsuffix}
Cflags: -I${includedir} -I${OpenEXR_includedir} @exr_pthread_cflags@
Requires: Imath
Libs.private: @zlib_link@
Requires.private: @EXR_DEFLATE_PKGCONFIG_REQUIRES@
+6 -3
View File
@@ -8,12 +8,15 @@ include(CMakeFindDependencyMacro)
set(openexr_needthreads @OPENEXR_ENABLE_THREADING@)
if (openexr_needthreads)
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_dependency(Threads REQUIRED)
find_dependency(Threads)
endif()
unset(openexr_needthreads)
find_dependency(ZLIB REQUIRED)
find_dependency(Imath REQUIRED)
find_dependency(Imath)
if (@libdeflate_FOUND@)
find_dependency(libdeflate)
endif()
include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
check_required_components("@PROJECT_NAME@")
+19 -8
View File
@@ -8,6 +8,20 @@
#pragma once
//
// The OpenEXR release version is defined officially in
// src/lib/OpenEXRCore/openexr_version.h, but CMake doesn't readily allow
// that to be included here, so duplicate the settings for
// backwards-compatibility with applications that may expect to get the
// defines from this include.
//
#ifndef INCLUDED_OPENEXR_VERSION_H
#define OPENEXR_VERSION_MAJOR @OpenEXR_VERSION_MAJOR@
#define OPENEXR_VERSION_MINOR @OpenEXR_VERSION_MINOR@
#define OPENEXR_VERSION_PATCH @OpenEXR_VERSION_PATCH@
#endif
//
// Options / configuration based on O.S. / compiler
/////////////////////
@@ -45,9 +59,6 @@
#define OPENEXR_VERSION_STRING "@OPENEXR_VERSION@"
#define OPENEXR_PACKAGE_STRING "@OPENEXR_PACKAGE_NAME@"
#define OPENEXR_VERSION_MAJOR @OpenEXR_VERSION_MAJOR@
#define OPENEXR_VERSION_MINOR @OpenEXR_VERSION_MINOR@
#define OPENEXR_VERSION_PATCH @OpenEXR_VERSION_PATCH@
#define OPENEXR_VERSION_RELEASE_TYPE "@OPENEXR_VERSION_RELEASE_TYPE@"
// Deprecated, for back compatibility:
#define OPENEXR_VERSION_EXTRA "@OPENEXR_VERSION_RELEASE_TYPE@"
@@ -57,10 +68,10 @@
// clang-format on
// Version as a single hex number, e.g. 0x01000300 == 1.0.3
#define OPENEXR_VERSION_HEX \
((uint32_t (OPENEXR_VERSION_MAJOR) << 24) | \
(uint32_t (OPENEXR_VERSION_MINOR) << 16) | \
(uint32_t (OPENEXR_VERSION_PATCH) << 8))
#define OPENEXR_VERSION_HEX \
(((OPENEXR_VERSION_MAJOR) << 24) | \
((OPENEXR_VERSION_MINOR) << 16) | \
((OPENEXR_VERSION_PATCH) << 8))
// On modern versions of gcc & clang, __has_attribute can test support for
// __attribute__((attr)). Make sure it's safe for other compilers.
@@ -74,7 +85,7 @@
/// \defgroup ExportMacros Macros to manage symbol visibility
///
/// See docs/SymbolVisibility.md for more discussion about the
/// See website/SymbolVisibility.rst for more discussion about the
/// motivation for these macros
///
/// If we are compiling a DLL for Windows, there needs to be custom
+109 -98
View File
@@ -36,11 +36,7 @@ set(IEX_INTERNAL_NAMESPACE "Iex_${OPENEXR_VERSION_API}" CACHE STRING "Real names
set(IEX_NAMESPACE "Iex" CACHE STRING "Public namespace alias for Iex")
# Whether to generate and install a pkg-config file OpenEXR.pc
if (WIN32)
option(OPENEXR_INSTALL_PKG_CONFIG "Install OpenEXR.pc file" OFF)
else()
option(OPENEXR_INSTALL_PKG_CONFIG "Install OpenEXR.pc file" ON)
endif()
# Whether to enable threading. This can be disabled, although thread pool and tasks
# are still used, just processed immediately
@@ -55,8 +51,22 @@ option(OPENEXR_ENABLE_LARGE_STACK "Enables code to take advantage of large stack
########################
## Build related options
# Whether to build & install the various command line utility programs
option(OPENEXR_INSTALL "Install OpenEXR libraries/binaries/bindings" ON)
# Whether to build & install the main libraries
option(OPENEXR_BUILD_LIBS "Enables building of main libraries" ON)
# Whether to build the various command line utility programs
option(OPENEXR_BUILD_TOOLS "Enables building of utility programs" ON)
option(OPENEXR_INSTALL_TOOLS "Install OpenEXR tools" ON)
option(OPENEXR_BUILD_EXAMPLES "Build and install OpenEXR examples" ON)
option(OPENEXR_BUILD_PYTHON "Build python bindings" OFF)
option(OPENEXR_TEST_LIBRARIES "Run library tests" ON)
option(OPENEXR_TEST_TOOLS "Run tool tests" ON)
option(OPENEXR_TEST_PYTHON "Run python binding tests" ON)
# This is a variable here for use in controlling where include files are
# installed. Care must be taken when changing this, as many things
@@ -142,6 +152,10 @@ if(OPENEXR_USE_CLANG_TIDY)
)
endif()
if (NOT OPENEXR_BUILD_LIBS)
return()
endif()
###############################
# Dependent libraries
@@ -157,100 +171,91 @@ if(OPENEXR_ENABLE_THREADING)
endif()
endif()
option(OPENEXR_FORCE_INTERNAL_ZLIB "Force using an internal zlib" OFF)
if (NOT OPENEXR_FORCE_INTERNAL_ZLIB)
if(NOT TARGET ZLIB::ZLIB)
find_package(ZLIB QUIET)
option(OPENEXR_FORCE_INTERNAL_DEFLATE "Force using an internal libdeflate" OFF)
set(OPENEXR_DEFLATE_REPO "https://github.com/ebiggers/libdeflate.git" CACHE STRING "Repo path for libdeflate source")
set(OPENEXR_DEFLATE_TAG "v1.18" CACHE STRING "Tag to use for libdeflate source repo (defaults to primary if empty)")
if(NOT OPENEXR_FORCE_INTERNAL_DEFLATE)
#TODO: ^^ Release should not clone from main, this is a place holder
set(CMAKE_IGNORE_PATH "${CMAKE_CURRENT_BINARY_DIR}/_deps/deflate-src/config;${CMAKE_CURRENT_BINARY_DIR}/_deps/deflate-build/config")
# First try cmake config
find_package(libdeflate CONFIG QUIET)
if(libdeflate_FOUND)
if(TARGET libdeflate::libdeflate_shared)
set(EXR_DEFLATE_LIB libdeflate::libdeflate_shared)
else()
set(EXR_DEFLATE_LIB libdeflate::libdeflate_static)
endif()
set(EXR_DEFLATE_VERSION ${libdeflate_VERSION})
message(STATUS "Using libdeflate from ${libdeflate_DIR}")
else()
# If not found, try pkgconfig
find_package(PkgConfig)
if(PKG_CONFIG_FOUND)
include(FindPkgConfig)
pkg_check_modules(deflate IMPORTED_TARGET GLOBAL libdeflate)
if(deflate_FOUND)
set(EXR_DEFLATE_LIB PkgConfig::deflate)
set(EXR_DEFLATE_VERSION ${deflate_VERSION})
message(STATUS "Using libdeflate from ${deflate_LINK_LIBRARIES}")
endif()
endif()
endif()
set(CMAKE_IGNORE_PATH)
endif()
if(OPENEXR_FORCE_INTERNAL_ZLIB OR NOT TARGET ZLIB::ZLIB)
set(zlib_VER "1.2.11")
if(OPENEXR_FORCE_INTERNAL_ZLIB)
message(STATUS "Compiling internal copy of zlib version ${zlib_VER}")
if(EXR_DEFLATE_LIB)
# Using external library
set(EXR_DEFLATE_SOURCES)
set(EXR_DEFLATE_INCLUDE_DIR)
# For OpenEXR.pc.in for static build
set(EXR_DEFLATE_PKGCONFIG_REQUIRES "libdeflate >= ${EXR_DEFLATE_VERSION}")
else()
# Using internal deflate
if(OPENEXR_FORCE_INTERNAL_DEFLATE)
message(STATUS "libdeflate forced internal, installing from ${OPENEXR_DEFLATE_REPO} (${OPENEXR_DEFLATE_TAG})")
else()
message(STATUS "zlib library not found, compiling ${zlib_VER}")
message(STATUS "libdeflate was not found, installing from ${OPENEXR_DEFLATE_REPO} (${OPENEXR_DEFLATE_TAG})")
endif()
# Unfortunately, zlib has an ancient cmake setup which does not include
# modern cmake exports, so we can't use the faster / more integrated
# FetchContent as we do for Imath below. There may be a way, but
# external project is just as easy
include(ExternalProject)
set(cmake_cc_arg)
if (CMAKE_CROSSCOMPILING)
set(cmake_cc_arg -DCMAKE_TOOLCHAIN_FILE=${CMAKE_TOOLCHAIN_FILE})
endif ()
if(NOT (APPLE OR WIN32) AND NOT OPENEXR_FORCE_INTERNAL_ZLIB)
set(zlib_INTERNAL_DIR "${CMAKE_INSTALL_PREFIX}" CACHE PATH "zlib install dir")
else()
set(zlib_INTERNAL_DIR "${CMAKE_BINARY_DIR}/zlib-install" CACHE PATH "zlib install dir")
endif()
# Need to set byproducts so ninja generator knows where the targets come from
ExternalProject_Add(zlib_external
GIT_REPOSITORY "https://github.com/madler/zlib.git"
include(FetchContent)
FetchContent_Declare(Deflate
GIT_REPOSITORY "${OPENEXR_DEFLATE_REPO}"
GIT_TAG "${OPENEXR_DEFLATE_TAG}"
GIT_SHALLOW ON
GIT_TAG "v${zlib_VER}"
UPDATE_COMMAND ""
SOURCE_DIR zlib-src
BINARY_DIR zlib-build
INSTALL_DIR ${zlib_INTERNAL_DIR}
BUILD_BYPRODUCTS
"${zlib_INTERNAL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}z${CMAKE_SHARED_LIBRARY_SUFFIX}"
"${zlib_INTERNAL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}z${CMAKE_STATIC_LIBRARY_SUFFIX}"
CMAKE_ARGS
-D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE}
-D CMAKE_POSITION_INDEPENDENT_CODE=ON
-D CMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
-D CMAKE_GENERATOR:STRING=${CMAKE_GENERATOR}
${cmake_cc_arg}
)
file(MAKE_DIRECTORY "${zlib_INTERNAL_DIR}")
file(MAKE_DIRECTORY "${zlib_INTERNAL_DIR}/include")
file(MAKE_DIRECTORY "${zlib_INTERNAL_DIR}/lib")
if(WIN32)
set(zliblibname "zlib")
set(zlibstaticlibname "zlibstatic")
else()
set(zliblibname "z")
set(zlibstaticlibname "z")
endif()
if(MSVC)
set(zlibpostfix "d")
endif()
add_library(zlib_static STATIC IMPORTED GLOBAL)
add_dependencies(zlib_static zlib_external)
set_property(TARGET zlib_static PROPERTY
IMPORTED_LOCATION "${zlib_INTERNAL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${zlibstaticlibname}${CMAKE_STATIC_LIBRARY_SUFFIX}"
)
set_property(TARGET zlib_static PROPERTY
IMPORTED_LOCATION_DEBUG "${zlib_INTERNAL_DIR}/lib/${CMAKE_STATIC_LIBRARY_PREFIX}${zlibstaticlibname}${zlibpostfix}${CMAKE_STATIC_LIBRARY_SUFFIX}"
)
target_include_directories(zlib_static INTERFACE "${zlib_INTERNAL_DIR}/include")
if(NOT (APPLE OR WIN32) AND BUILD_SHARED_LIBS AND NOT OPENEXR_FORCE_INTERNAL_ZLIB)
add_library(zlib_shared SHARED IMPORTED GLOBAL)
add_dependencies(zlib_shared zlib_external)
set_property(TARGET zlib_shared PROPERTY
IMPORTED_LOCATION "${zlib_INTERNAL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}${zliblibname}${CMAKE_SHARED_LIBRARY_SUFFIX}"
)
set_property(TARGET zlib_static PROPERTY
IMPORTED_LOCATION_DEBUG "${zlib_INTERNAL_DIR}/lib/${CMAKE_SHARED_LIBRARY_PREFIX}${zliblibname}${zlibpostfix}${CMAKE_SHARED_LIBRARY_SUFFIX}"
)
target_include_directories(zlib_shared INTERFACE "${zlib_INTERNAL_DIR}/include")
FetchContent_GetProperties(Deflate)
if(NOT Deflate_POPULATED)
FetchContent_Populate(Deflate)
endif()
if(NOT (APPLE OR WIN32) AND BUILD_SHARED_LIBS AND NOT OPENEXR_FORCE_INTERNAL_ZLIB)
add_library(ZLIB::ZLIB ALIAS zlib_shared)
else()
add_library(ZLIB::ZLIB ALIAS zlib_static)
endif()
# Rather than actually compile something, just embed the sources
# into exrcore. This could in theory cause issues when compiling as
# a static library into another application which also uses
# libdeflate but we switch the export symbol to hidden which should
# hide the symbols when linking...
set(EXR_DEFLATE_SOURCES
lib/arm/cpu_features.c
lib/x86/cpu_features.c
lib/utils.c
lib/deflate_compress.c
lib/deflate_decompress.c
lib/adler32.c
lib/zlib_compress.c
lib/zlib_decompress.c)
# don't need these
# lib/crc32.c
# lib/gzip_compress.c
# lib/gzip_decompress.c
file(READ ${deflate_SOURCE_DIR}/lib/lib_common.h DEFLATE_HIDE)
string(REPLACE "visibility(\"default\")" "visibility(\"hidden\")" DEFLATE_HIDE "${DEFLATE_HIDE}")
string(REPLACE "__declspec(dllexport)" "/**/" DEFLATE_HIDE "${DEFLATE_HIDE}")
file(WRITE ${deflate_SOURCE_DIR}/lib/lib_common.h "${DEFLATE_HIDE}")
# cmake makes fetch content name lowercase for the properties (to deflate)
list(TRANSFORM EXR_DEFLATE_SOURCES PREPEND ${deflate_SOURCE_DIR}/)
set(EXR_DEFLATE_INCLUDE_DIR ${deflate_SOURCE_DIR})
set(EXR_DEFLATE_LIB)
endif()
#######################################
@@ -259,10 +264,8 @@ endif()
option(OPENEXR_FORCE_INTERNAL_IMATH "Force using an internal imath" OFF)
# Check to see if Imath is installed outside of the current build directory.
set(IMATH_REPO "https://github.com/AcademySoftwareFoundation/Imath.git" CACHE STRING
"Repo for auto-build of Imath")
set(IMATH_TAG "main" CACHE STRING
"Tag for auto-build of Imath (branch, tag, or SHA)")
set(OPENEXR_IMATH_REPO "https://github.com/AcademySoftwareFoundation/Imath.git" CACHE STRING "Repo for auto-build of Imath")
set(OPENEXR_IMATH_TAG "v3.1.11" CACHE STRING "Tag for auto-build of Imath (branch, tag, or SHA)")
if(NOT OPENEXR_FORCE_INTERNAL_IMATH)
#TODO: ^^ Release should not clone from main, this is a place holder
set(CMAKE_IGNORE_PATH "${CMAKE_CURRENT_BINARY_DIR}/_deps/imath-src/config;${CMAKE_CURRENT_BINARY_DIR}/_deps/imath-build/config")
@@ -272,20 +275,28 @@ endif()
if(NOT TARGET Imath::Imath AND NOT Imath_FOUND)
if(OPENEXR_FORCE_INTERNAL_IMATH)
message(STATUS "Imath forced internal, installing from ${IMATH_REPO} (${IMATH_TAG})")
message(STATUS "Imath forced internal, installing from ${OPENEXR_IMATH_REPO} (${OPENEXR_IMATH_TAG})")
else()
message(STATUS "Imath was not found, installing from ${IMATH_REPO} (${IMATH_TAG})")
message(STATUS "Imath was not found, installing from ${OPENEXR_IMATH_REPO} (${OPENEXR_IMATH_TAG})")
endif()
include(FetchContent)
FetchContent_Declare(Imath
GIT_REPOSITORY ${IMATH_REPO}
GIT_TAG ${IMATH_TAG}
GIT_REPOSITORY "${OPENEXR_IMATH_REPO}"
GIT_TAG "${OPENEXR_IMATH_TAG}"
GIT_SHALLOW ON
)
FetchContent_GetProperties(Imath)
if(NOT Imath_POPULATED)
FetchContent_Populate(Imath)
# Propagate OpenEXR's install setting to Imath
set(IMATH_INSTALL ${OPENEXR_INSTALL})
# Propagate OpenEXR's setting for pkg-config generation to Imath:
# If OpenEXR is generating it, the internal Imath should, too.
set(IMATH_INSTALL_PKG_CONFIG ${OPENEXR_INSTALL_PKG_CONFIG})
# hrm, cmake makes Imath lowercase for the properties (to imath)
add_subdirectory(${imath_SOURCE_DIR} ${imath_BINARY_DIR})
endif()
+23
View File
@@ -0,0 +1,23 @@
# Source: https://gitlab.kitware.com/cmake/community/-/wikis/FAQ#can-i-do-make-uninstall-with-cmake
if(NOT EXISTS "@CMAKE_BINARY_DIR@/install_manifest.txt")
message(FATAL_ERROR "Cannot find install manifest: @CMAKE_BINARY_DIR@/install_manifest.txt")
endif()
file(READ "@CMAKE_BINARY_DIR@/install_manifest.txt" files)
string(REGEX REPLACE "\n" ";" files "${files}")
foreach(file ${files})
message(STATUS "Uninstalling $ENV{DESTDIR}${file}")
if(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
exec_program(
"@CMAKE_COMMAND@" ARGS
"-E remove \"$ENV{DESTDIR}${file}\""
OUTPUT_VARIABLE rm_out
RETURN_VALUE rm_retval)
if(NOT "${rm_retval}" STREQUAL 0)
message(FATAL_ERROR "Problem when removing $ENV{DESTDIR}${file}")
endif()
else(IS_SYMLINK "$ENV{DESTDIR}${file}" OR EXISTS "$ENV{DESTDIR}${file}")
message(STATUS "File $ENV{DESTDIR}${file} does not exist.")
endif()
endforeach()
-19
View File
@@ -1,19 +0,0 @@
..
SPDX-License-Identifier: BSD-3-Clause
Copyright Contributors to the OpenEXR Project.
.. _The OpenEXR API:
The OpenEXR API
###############
.. toctree::
:caption: API
:maxdepth: 2
HelloWorld
ReadingAndWritingImageFiles
OpenEXRCoreAPI
* :ref:`genindex`
+42 -34
View File
@@ -3,50 +3,58 @@
set(CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
find_package(Doxygen REQUIRED)
find_package(Sphinx REQUIRED)
# man pages for the bin programs
include(FindPythonPackage)
find_python_package(sphinx-press-theme REQUIRED)
find_program(HELP2MAN help2man)
set(DOXYGEN_INPUT_DIR ${PROJECT_SOURCE_DIR}/src/lib/OpenEXRCore)
set(DOXYGEN_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/doxygen)
set(DOXYGEN_INDEX_FILE ${DOXYGEN_OUTPUT_DIR}/html/index.html)
set(DOXYFILE_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
set(DOXYFILE_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
set(MANPAGE_OUTPUT_DIR ${CMAKE_CURRENT_BINARY_DIR}/man)
file(MAKE_DIRECTORY ${MANPAGE_OUTPUT_DIR}/man1)
set(SPHINX_SOURCE ${CMAKE_CURRENT_SOURCE_DIR})
set(SPHINX_BUILD ${CMAKE_CURRENT_BINARY_DIR}/sphinx)
set(SPHINX_INDEX_FILE ${SPHINX_BUILD}/index.html)
message(STATUS "MANPAGE_OUTPUT_DIR=${MANPAGE_OUTPUT_DIR}")
message(STATUS "CMAKE_INSTALL_MANDIR=${CMAKE_INSTALL_MANDIR}")
set(SPHINX_OPTS "-W" CACHE STRING "Sphinx build options")
set(manpage_files "")
configure_file(${DOXYFILE_IN} ${DOXYFILE_OUT} @ONLY)
function(DEFINE_MANPAGE tool description)
file(MAKE_DIRECTORY ${DOXYGEN_OUTPUT_DIR})
set(manpage_file ${MANPAGE_OUTPUT_DIR}/man1/${tool}.1)
set(manpage_files "${manpage_files};${manpage_file}" PARENT_SCOPE)
add_custom_command(OUTPUT ${DOXYGEN_INDEX_FILE}
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYFILE_OUT}
MAIN_DEPENDENCY ${DOXYFILE_OUT} ${DOXYFILE_IN}
COMMENT "Running doxygen"
VERBATIM)
add_custom_command(OUTPUT ${SPHINX_INDEX_FILE}
COMMAND
${SPHINX_EXECUTABLE} -b html ${SPHINX_OPTS}
# Tell Breathe where to find the Doxygen output
-Dbreathe_projects.OpenEXR=${DOXYGEN_OUTPUT_DIR}/xml
${SPHINX_SOURCE} ${SPHINX_BUILD}
add_custom_command(OUTPUT ${manpage_file}
COMMAND
${HELP2MAN} -n ${description} --output=${manpage_file} -N
${CMAKE_CURRENT_BINARY_DIR}/../bin/${tool}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${DOXYGEN_INDEX_FILE}
MAIN_DEPENDENCY conf.py
COMMENT "Generating documentation with Sphinx")
DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/../bin/${tool}
COMMENT "Generating man page for ${tool}"
VERBATIM)
endfunction()
add_custom_target(docs ALL DEPENDS ${SPHINX_INDEX_FILE} ${DOXYGEN_INDEX_FILE})
# Provide help2man a useful single-line program description. There's
# no especially good way to embed this in the program's --help text so
# that help2man can detect it.
define_manpage(exr2aces "convert exr images to ACES format")
define_manpage(exrcheck "validate exr files")
define_manpage(exrenvmap "convert exr image environment maps")
define_manpage(exrheader "print exr image header metadata")
define_manpage(exrinfo "print exr image header metadata")
define_manpage(exrmakepreview "generate exr preview thumbnail images")
define_manpage(exrmaketiled "convert exr images to tiled format")
define_manpage(exrmultipart "combine or split multipart exr images")
define_manpage(exrmultiview "convert between single/multi-view exr images")
define_manpage(exrstdattr "set exr image metadata")
add_custom_target(docs ALL DEPENDS
${manpage_files})
# Add a target to install the manpages
# Add an install target to install the docs
if(INSTALL_DOCS)
include(GNUInstallDirs)
install(DIRECTORY ${SPHINX_BUILD}
DESTINATION ${CMAKE_INSTALL_DOCDIR})
install(DIRECTORY ${MANPAGE_OUTPUT_DIR}/man1 DESTINATION ${CMAKE_INSTALL_MANDIR})
endif()
# build the example code to verify that it compiles
-43
View File
@@ -1,43 +0,0 @@
..
SPDX-License-Identifier: BSD-3-Clause
Copyright Contributors to the OpenEXR Project.
.. _Hello:
Hello, World
############
.. toctree::
:caption: Hello, World
:maxdepth: 1
A simple program to write a simple ``.exr`` file of an image of 10x10
pixels with values that are a ramp in green and blue:
.. literalinclude:: src/writer/writer.cpp
And the ``CMakeLists.txt`` file to build:
.. literalinclude:: src/writer/CMakeLists.txt
To build:
.. literalinclude:: src/writer/build.sh
For more details, see :ref:`The OpenEXR API`.
And a simple program to read an ``.exr`` file:
.. literalinclude:: src/reader/reader.cpp
And the ``CMakeLists.txt`` file to build:
.. literalinclude:: src/reader/CMakeLists.txt
To build:
.. literalinclude:: src/reader/build.sh
-199
View File
@@ -1,199 +0,0 @@
..
SPDX-License-Identifier: BSD-3-Clause
Copyright Contributors to the OpenEXR Project.
Standard Optional Attributes
############################
.. toctree::
:caption: Standard Optional Attributes
By default, OpenEXR files have the following attributes:
**chromaticities**
For RGB images, specifies the CIE (x,y) chromaticities of the
primaries and the white point.
**whiteLuminance**
For RGB images, defines the luminance, in Nits (candelas per square
meter) of the RGB value (1.0, 1.0, 1.0).
If the chromaticities and the whiteLuminance of an RGB image are
known, then it is possible to convert the image's pixels from RGB to
CIE XYZ tristimulus values.
**adoptedNeutral**
Specifies the CIE (x,y) coordinates that should be considered
neutral during color rendering. Pixels in the image file whose
(x,y) coordinates match the adoptedNeutral value should be mapped to
neutral values on the display.
**renderingTransform**, lookModTransform
Specify the names of the CTL functions that implements the intended
color rendering and look modification transforms for this image.
**xDensity**
Horizontal output density, in pixels per inch. The image's vertical
output density is xDensity * pixelAspectRatio.
**owner**
Name of the owner of the image.
**comments**
Additional image information in human-readable form, for example a
verbal description of the image.
**capDate**
The date when the image was created or captured, in local time, and
formatted as ``YYYY:MM:DD hh:mm:ss``, where ``YYYY`` is the year (4
digits, e.g. 2003), ``MM`` is the month (2 digits, 01, 02, ... 12),
``DD`` is the day of the month (2 digits, 01, 02, ... 31), hh is the
hour (2 digits, 00, 01, ... 23), mm is the minute, and ss is the
second (2 digits, 00, 01, ... 59).
**utcOffset**
Universal Coordinated Time (UTC), in seconds: UTC == local time +
utcOffset
**longitude**, **latitude**, **altitude**
For images of real objects, the location where the image was
recorded. Longitude and latitude are in degrees east of Greenwich
and north of the equator. Altitude is in meters above sea level.
For example, Kathmandu, Nepal is at longitude 85.317, latitude
27.717, altitude 1305.
**focus**
The camera's focus distance, in meters.
**exposure**
Exposure time, in seconds.
**aperture**
The camera's lens aperture, in f-stops (focal length of the lens
divided by the diameter of the iris opening).
**isoSpeed**
The ISO speed of the film or image sensor that was used to record
the image.
**envmap**
If this attribute is present, the image represents an environment
map. The attribute's value defines how 3D directions are mapped to
2D pixel locations.
**keyCode**
For motion picture film frames. Identifies film manufacturer, film
type, film roll and frame position within the roll.
**timeCode**
Time and control code
**wrapmodes**
Determines how texture map images are extrapolated. If an OpenEXR
file is used as a texture map for 3D rendering, texture coordinates
(0.0, 0.0) and (1.0, 1.0) correspond to the upper left and lower
right corners of the data window. If the image is mapped onto a
surface with texture coordinates outside the zero-to-one range, then
the image must be extrapolated. This attribute tells the renderer
how to do this extrapolation. The attribute contains either a pair
of comma-separated keywords, to specify separate extrapolation modes
for the horizontal and vertical directions; or a single keyword, to
specify extrapolation in both directions (e.g. "clamp,periodic" or
"clamp"). Extra white space surrounding the keywords is allowed,
but should be ignored by the renderer ("clamp, black " is equivalent
to "clamp,black"). The keywords listed below are predefined; some
renderers may support additional extrapolation modes:
**black**
pixels outside the zero-to-one range are black
**clamp**
texture coordinates less than 0.0 and greater than 1.0 are clamped
to 0.0 and 1.0 respectively.
**periodic**
the texture image repeats periodically
**mirror**
the texture image repeats periodically, but every other instance
is mirrored
**framesPerSecond**
Defines the nominal playback frame rate for image sequences, in
frames per second. Every image in a sequence should have a
framesPerSecond attribute, and the attribute value should be the
same for all images in the sequence. If an image sequence has no
framesPerSecond attribute, playback software should assume that the
frame rate for the sequence is 24 frames per second.
In order to allow exact representation of NTSC frame and field
rates, framesPerSecond is stored as a rational number. A rational
number is a pair of integers, n and d, that represents the value
n/d.
**multiView**
Defines the view names for multi-view image files. A multi-view
image contains two or more views of the same scene, as seen from
different viewpoints, for example a left-eye and a right-eye view
for stereo displays. The multiView attribute lists the names of the
views in an image, and a naming convention identifies the channels
that belong to each view.
**worldToCamera**
For images generated by 3D computer graphics rendering, a matrix
that transforms 3D points from the world to the camera coordinate
space of the renderer.
The camera coordinate space is left-handed. Its origin indicates
the location of the camera. The positive x and y axes correspond to
the "right" and "up" directions in the rendered image. The positive
z axis indicates the camera's viewing direction. (Objects in front
of the camera have positive z coordinates.)
Camera coordinate space in OpenEXR is the same as in Pixar's
Renderman.
**worldToNDC**
For images generated by 3D computer graphics rendering, a matrix
that transforms 3D points from the world to the Normalized Device
Coordinate (NDC) space of the renderer.
NDC is a 2D coordinate space that corresponds to the image plane,
with positive x and pointing to the right and y positive pointing
down. The coordinates (0, 0) and (1, 1) correspond to the upper
left and lower right corners of the OpenEXR display window.
To transform a 3D point in word space into a 2D point in NDC space,
multiply the 3D point by the worldToNDC matrix and discard the z
coordinate.
NDC space in OpenEXR is the same as in Pixar's Renderman.
**deepImageState**
Specifies whether the pixels in a deep image are sorted and
non-overlapping.
Note: this attribute can be set by application code that writes a
file in order to tell applications that read the file whether the
pixel data must be cleaned up prior to image processing operations
such as flattening. The OpenEXR library does not verify that the
attribute is consistent with the actual state of the pixels.
Application software may assume that the attribute is valid, as long
as the software will not crash or lock up if any pixels are
inconsistent with the deepImageState attribute.
**originalDataWindow**
If application software crops an image, then it should save the data
window of the original, un-cropped image in the originalDataWindow
attribute.
**dwaCompressionLevel**
Sets the quality level for images compressed with the DWAA or DWAB
method.
**ID Manifest**
ID manifest.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 158 KiB

-154
View File
@@ -1,154 +0,0 @@
#FIG 3.2
Landscape
Center
Metric
A4
60.00
Single
-2
1200 2
0 32 #d3d3d3
6 11025 900 17775 12150
6 13275 900 16650 12150
2 2 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 5
13500 1125 15300 1125 15300 2925 13500 2925 13500 1125
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
13950 2025 14850 2025
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
14400 1575 14400 2475
2 2 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 5
13500 2925 15300 2925 15300 4725 13500 4725 13500 2925
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
13950 3825 14850 3825
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
14400 3375 14400 4275
2 2 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 5
13500 4725 15300 4725 15300 6525 13500 6525 13500 4725
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
13950 5625 14850 5625
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
14400 5175 14400 6075
2 2 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 5
13500 6525 15300 6525 15300 8325 13500 8325 13500 6525
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
13950 7425 14850 7425
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
14400 6975 14400 7875
2 2 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 5
13500 8325 15300 8325 15300 10125 13500 10125 13500 8325
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
13950 9225 14850 9225
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
14400 8775 14400 9675
2 2 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 5
13500 10125 15300 10125 15300 11925 13500 11925 13500 10125
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
13950 11025 14850 11025
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
14400 10575 14400 11475
4 1 0 48 -1 22 18 0.0000 4 195 135 15075 2115 Z\001
4 1 0 48 -1 22 18 0.0000 4 195 150 14400 1440 Y\001
4 0 0 48 -1 22 18 0.0000 4 195 780 15750 2115 +X face\001
4 1 0 48 -1 22 18 0.0000 4 195 150 14400 3240 Y\001
4 1 0 48 -1 22 18 0.0000 4 195 135 13770 3915 Z\001
4 1 0 48 -1 22 18 0.0000 4 195 150 14400 8640 Y\001
4 1 0 48 -1 22 18 0.0000 4 195 150 14400 10440 Y\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 1440 3\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 1440 7\001
4 1 0 48 -1 22 18 0.0000 4 195 120 13725 2790 1\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 2790 5\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 3240 6\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 3240 2\001
4 1 0 48 -1 22 18 0.0000 4 195 120 13725 4590 4\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 4590 0\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 5040 6\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 5040 7\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 6390 2\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 6390 3\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 6840 0\001
4 1 0 48 -1 22 18 0.0000 4 195 120 15075 6840 1\001
4 1 0 48 -1 22 18 0.0000 4 195 120 13725 8190 4\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 8190 5\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 8640 7\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 8640 6\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 9990 5\001
4 1 0 48 -1 22 18 0.0000 4 195 120 15075 9990 4\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 10440 2\001
4 1 0 48 -1 22 18 0.0000 4 180 120 15075 10440 3\001
4 1 0 48 -1 22 18 0.0000 4 180 120 13725 11790 0\001
4 1 0 48 -1 22 18 0.0000 4 195 120 15075 11790 1\001
4 0 0 48 -1 22 18 0.0000 4 195 720 15750 3915 -X face\001
4 0 0 48 -1 22 18 0.0000 4 195 780 15750 5715 +Y face\001
4 0 0 48 -1 22 18 0.0000 4 195 720 15750 7515 -Y face\001
4 0 0 48 -1 22 18 0.0000 4 195 765 15750 9315 +Z face\001
4 0 0 48 -1 22 18 0.0000 4 195 705 15750 11115 -Z face\001
4 1 0 48 -1 22 18 0.0000 4 195 135 14400 5040 Z\001
4 1 0 48 -1 22 18 0.0000 4 195 150 15075 5715 X\001
4 1 0 48 -1 22 18 0.0000 4 195 150 15075 7515 X\001
4 1 0 48 -1 22 18 0.0000 4 195 135 14400 8190 Z\001
4 1 0 48 -1 22 18 0.0000 4 195 150 13770 9315 X\001
4 1 0 48 -1 22 18 0.0000 4 195 150 15075 11115 X\001
-6
2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
15750 11925 15390 11925
4 0 0 48 -1 22 18 0.0000 4 195 1785 15885 12015 dataWindow.max\001
4 2 0 48 -1 22 18 0.0000 4 195 1740 12915 1215 dataWindow.min\001
-6
2 1 0 3 32 7 49 -1 -1 0.000 0 0 -1 0 0 2
8329 6919 10269 6919
2 1 0 3 32 7 49 -1 -1 0.000 0 0 -1 0 0 2
8323 6905 8323 4972
2 2 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 5
5403 5406 9443 5406 9443 9446 5403 9446 5403 5406
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
5409 5406 7335 4618
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
9449 9452 11029 8319
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 3
7329 4619 11023 4619 11023 8319
2 1 0 3 0 7 48 -1 -1 0.000 0 0 -1 0 0 2
9449 5406 11029 4612
2 1 0 3 0 7 46 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 180.00 360.00
7428 7417 6515 7924
2 1 0 3 0 7 46 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 180.00 360.00
8323 4992 8323 3059
2 1 0 3 0 7 46 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 180.00 360.00
10262 6919 12202 6919
2 1 0 3 32 7 52 -1 -1 0.000 0 0 -1 0 0 3
7323 4619 7323 8326 11029 8326
2 1 0 3 32 7 52 -1 -1 0.000 0 0 -1 0 0 2
5403 9452 7316 8326
2 1 0 9 7 7 47 -1 -1 0.000 0 0 -1 0 0 2
7139 7578 7629 7328
2 1 0 3 32 7 46 -1 -1 0.000 0 0 -1 0 0 2
8345 6917 7432 7424
2 1 0 9 7 7 47 -1 -1 0.000 0 0 -1 0 0 2
10800 6930 11250 6930
2 1 0 9 7 7 47 -1 -1 0.000 0 0 -1 0 0 2
8325 4815 8325 4410
2 1 0 9 7 7 49 -1 -1 0.000 0 0 -1 0 0 2
7065 5400 7515 5400
2 1 0 9 7 7 49 -1 -1 0.000 0 0 -1 0 0 2
9450 8145 9450 8595
2 1 0 9 7 7 49 -1 -1 0.000 0 0 -1 0 0 2
8100 5400 8550 5400
2 1 0 9 7 7 49 -1 -1 0.000 0 0 -1 0 0 2
9450 6750 9450 7200
2 1 0 1 0 7 48 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
13050 1125 13410 1125
4 1 0 48 -1 22 18 0.0000 4 195 150 8325 2817 Y\001
4 1 0 48 -1 22 18 0.0000 4 195 120 5400 9810 4\001
4 1 0 48 -1 22 18 0.0000 4 180 120 9450 9810 5\001
4 1 0 48 -1 22 18 0.0000 4 180 120 7335 4410 2\001
4 1 0 48 -1 22 18 0.0000 4 180 120 11025 4410 3\001
4 1 0 48 -1 22 18 0.0000 4 180 120 9450 5220 7\001
4 1 0 48 -1 22 18 0.0000 4 180 120 5400 5220 6\001
4 1 0 48 -1 22 18 0.0000 4 180 120 7335 8685 0\001
4 1 0 48 -1 22 18 0.0000 4 195 120 11025 8685 1\001
4 1 0 48 -1 22 18 0.0000 4 195 135 6255 8190 Z\001
4 1 0 48 -1 22 18 0.0000 4 195 150 12510 7020 X\001
-973
View File
@@ -1,973 +0,0 @@
#FIG 3.2
Landscape
Center
Metric
A4
80.00
Single
-2
1200 2
0 32 #d0d0d0
6 3330 6480 4140 7020
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 6525 45 45 3375 6525 3375 6570
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 6750 45 45 3375 6750 3375 6795
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 6975 45 45 3375 6975 3375 7020
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 6525 45 45 3600 6525 3600 6570
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 6750 45 45 3600 6750 3600 6795
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 6975 45 45 3600 6975 3600 7020
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 6525 45 45 3825 6525 3825 6570
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 6750 45 45 3825 6750 3825 6795
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 6975 45 45 3825 6975 3825 7020
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 6525 45 45 4050 6525 4050 6570
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 6750 45 45 4050 6750 4050 6795
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 6975 45 45 4050 6975 4050 7020
-6
6 3330 8460 4140 9090
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 8550 45 45 3375 8550 3375 8595
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 8775 45 45 3375 8775 3375 8820
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 9000 45 45 3375 9000 3375 9045
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 8550 45 45 3600 8550 3600 8595
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 8775 45 45 3600 8775 3600 8820
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 9000 45 45 3600 9000 3600 9045
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 8550 45 45 3825 8550 3825 8595
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 8775 45 45 3825 8775 3825 8820
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 9000 45 45 3825 9000 3825 9045
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4050 8550 45 45 4050 8550 4050 8595
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4050 8775 45 45 4050 8775 4050 8820
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4050 9000 45 45 4050 9000 4050 9045
-6
6 3240 9090 4140 9810
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3375 9225 45 45 3375 9225 3375 9270
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3375 9450 45 45 3375 9450 3375 9495
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3375 9675 45 45 3375 9675 3375 9720
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3600 9225 45 45 3600 9225 3600 9270
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3600 9450 45 45 3600 9450 3600 9495
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3600 9675 45 45 3600 9675 3600 9720
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3825 9225 45 45 3825 9225 3825 9270
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3825 9450 45 45 3825 9450 3825 9495
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 3825 9675 45 45 3825 9675 3825 9720
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4050 9225 45 45 4050 9225 4050 9270
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4050 9450 45 45 4050 9450 4050 9495
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4050 9675 45 45 4050 9675 4050 9720
-6
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 450 45 45 1575 450 1575 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 675 45 45 1575 675 1575 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 900 45 45 1575 900 1575 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 1125 45 45 1575 1125 1575 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 1350 45 45 1575 1350 1575 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 1575 45 45 1575 1575 1575 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 1800 45 45 1575 1800 1575 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 2025 45 45 1575 2025 1575 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 2250 45 45 1575 2250 1575 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 2475 45 45 1575 2475 1575 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 2700 45 45 1575 2700 1575 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 2925 45 45 1575 2925 1575 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 3150 45 45 1575 3150 1575 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 3375 45 45 1575 3375 1575 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 3600 45 45 1575 3600 1575 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 3825 45 45 1575 3825 1575 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 4050 45 45 1575 4050 1575 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 4275 45 45 1575 4275 1575 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 4500 45 45 1575 4500 1575 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 4725 45 45 1575 4725 1575 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 4950 45 45 1575 4950 1575 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 5175 45 45 1575 5175 1575 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 5400 45 45 1575 5400 1575 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 5625 45 45 1575 5625 1575 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1575 5850 45 45 1575 5850 1575 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 450 45 45 1800 450 1800 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 675 45 45 1800 675 1800 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 900 45 45 1800 900 1800 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 1125 45 45 1800 1125 1800 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 1350 45 45 1800 1350 1800 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 1575 45 45 1800 1575 1800 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 1800 45 45 1800 1800 1800 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 2025 45 45 1800 2025 1800 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 2250 45 45 1800 2250 1800 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 2475 45 45 1800 2475 1800 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 2700 45 45 1800 2700 1800 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 2925 45 45 1800 2925 1800 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 3150 45 45 1800 3150 1800 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 3375 45 45 1800 3375 1800 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 3600 45 45 1800 3600 1800 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 3825 45 45 1800 3825 1800 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 4050 45 45 1800 4050 1800 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 4275 45 45 1800 4275 1800 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 4500 45 45 1800 4500 1800 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 4725 45 45 1800 4725 1800 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 4950 45 45 1800 4950 1800 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 5175 45 45 1800 5175 1800 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 5400 45 45 1800 5400 1800 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 5625 45 45 1800 5625 1800 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 1800 5850 45 45 1800 5850 1800 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 450 45 45 2025 450 2025 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 675 45 45 2025 675 2025 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 900 45 45 2025 900 2025 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 1125 45 45 2025 1125 2025 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 1350 45 45 2025 1350 2025 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 1575 45 45 2025 1575 2025 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 1800 45 45 2025 1800 2025 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 2025 45 45 2025 2025 2025 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 2250 45 45 2025 2250 2025 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 2475 45 45 2025 2475 2025 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 2700 45 45 2025 2700 2025 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 2925 45 45 2025 2925 2025 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 3150 45 45 2025 3150 2025 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 3375 45 45 2025 3375 2025 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 3600 45 45 2025 3600 2025 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 3825 45 45 2025 3825 2025 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 4050 45 45 2025 4050 2025 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 4275 45 45 2025 4275 2025 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 4500 45 45 2025 4500 2025 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 4725 45 45 2025 4725 2025 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 4950 45 45 2025 4950 2025 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 5175 45 45 2025 5175 2025 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 5400 45 45 2025 5400 2025 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 5625 45 45 2025 5625 2025 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2025 5850 45 45 2025 5850 2025 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 450 45 45 2250 450 2250 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 675 45 45 2250 675 2250 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 900 45 45 2250 900 2250 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 1125 45 45 2250 1125 2250 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 1350 45 45 2250 1350 2250 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 1575 45 45 2250 1575 2250 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 1800 45 45 2250 1800 2250 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 2025 45 45 2250 2025 2250 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 2250 45 45 2250 2250 2250 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 2475 45 45 2250 2475 2250 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 2700 45 45 2250 2700 2250 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 2925 45 45 2250 2925 2250 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 3150 45 45 2250 3150 2250 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 3375 45 45 2250 3375 2250 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 3600 45 45 2250 3600 2250 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 3825 45 45 2250 3825 2250 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 4050 45 45 2250 4050 2250 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 4275 45 45 2250 4275 2250 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 4500 45 45 2250 4500 2250 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 4725 45 45 2250 4725 2250 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 4950 45 45 2250 4950 2250 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 5175 45 45 2250 5175 2250 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 5400 45 45 2250 5400 2250 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 5625 45 45 2250 5625 2250 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2250 5850 45 45 2250 5850 2250 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 450 45 45 2475 450 2475 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 675 45 45 2475 675 2475 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 900 45 45 2475 900 2475 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 1125 45 45 2475 1125 2475 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 1350 45 45 2475 1350 2475 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 1575 45 45 2475 1575 2475 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 1800 45 45 2475 1800 2475 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 5400 45 45 2475 5400 2475 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 5625 45 45 2475 5625 2475 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2475 5850 45 45 2475 5850 2475 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 450 45 45 2700 450 2700 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 675 45 45 2700 675 2700 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 900 45 45 2700 900 2700 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 1125 45 45 2700 1125 2700 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 1350 45 45 2700 1350 2700 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 1575 45 45 2700 1575 2700 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 1800 45 45 2700 1800 2700 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 5400 45 45 2700 5400 2700 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 5625 45 45 2700 5625 2700 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2700 5850 45 45 2700 5850 2700 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 450 45 45 2925 450 2925 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 675 45 45 2925 675 2925 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 900 45 45 2925 900 2925 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 1125 45 45 2925 1125 2925 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 1350 45 45 2925 1350 2925 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 1575 45 45 2925 1575 2925 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 1800 45 45 2925 1800 2925 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 5400 45 45 2925 5400 2925 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 5625 45 45 2925 5625 2925 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 2925 5850 45 45 2925 5850 2925 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 450 45 45 3150 450 3150 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 675 45 45 3150 675 3150 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 900 45 45 3150 900 3150 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 1125 45 45 3150 1125 3150 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 1350 45 45 3150 1350 3150 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 1575 45 45 3150 1575 3150 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 1800 45 45 3150 1800 3150 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 5400 45 45 3150 5400 3150 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 5625 45 45 3150 5625 3150 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3150 5850 45 45 3150 5850 3150 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 450 45 45 3375 450 3375 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 675 45 45 3375 675 3375 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 900 45 45 3375 900 3375 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 1125 45 45 3375 1125 3375 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 1350 45 45 3375 1350 3375 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 1575 45 45 3375 1575 3375 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 1800 45 45 3375 1800 3375 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 5400 45 45 3375 5400 3375 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 5625 45 45 3375 5625 3375 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3375 5850 45 45 3375 5850 3375 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 450 45 45 3600 450 3600 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 675 45 45 3600 675 3600 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 900 45 45 3600 900 3600 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 1125 45 45 3600 1125 3600 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 1350 45 45 3600 1350 3600 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 1575 45 45 3600 1575 3600 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 1800 45 45 3600 1800 3600 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 5400 45 45 3600 5400 3600 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 5625 45 45 3600 5625 3600 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3600 5850 45 45 3600 5850 3600 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 450 45 45 3825 450 3825 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 675 45 45 3825 675 3825 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 1125 45 45 3825 1125 3825 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 1350 45 45 3825 1350 3825 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 1575 45 45 3825 1575 3825 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 1800 45 45 3825 1800 3825 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 5400 45 45 3825 5400 3825 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 5625 45 45 3825 5625 3825 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 5850 45 45 3825 5850 3825 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 450 45 45 4050 450 4050 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 675 45 45 4050 675 4050 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 900 45 45 4050 900 4050 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 5400 45 45 4050 5400 4050 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 5625 45 45 4050 5625 4050 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4050 5850 45 45 4050 5850 4050 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4275 450 45 45 4275 450 4275 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4275 675 45 45 4275 675 4275 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4275 900 45 45 4275 900 4275 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4275 5400 45 45 4275 5400 4275 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4275 5625 45 45 4275 5625 4275 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4275 5850 45 45 4275 5850 4275 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4500 450 45 45 4500 450 4500 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4500 675 45 45 4500 675 4500 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4500 900 45 45 4500 900 4500 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4500 5400 45 45 4500 5400 4500 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4500 5625 45 45 4500 5625 4500 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4500 5850 45 45 4500 5850 4500 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4725 450 45 45 4725 450 4725 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4725 675 45 45 4725 675 4725 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4725 900 45 45 4725 900 4725 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4725 5400 45 45 4725 5400 4725 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4725 5625 45 45 4725 5625 4725 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4725 5850 45 45 4725 5850 4725 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4950 450 45 45 4950 450 4950 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4950 675 45 45 4950 675 4950 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4950 900 45 45 4950 900 4950 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5175 450 45 45 5175 450 5175 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5175 675 45 45 5175 675 5175 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5175 900 45 45 5175 900 5175 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5175 5400 45 45 5175 5400 5175 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5400 450 45 45 5400 450 5400 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5400 675 45 45 5400 675 5400 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5400 900 45 45 5400 900 5400 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5400 5400 45 45 5400 5400 5400 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5625 450 45 45 5625 450 5625 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5625 675 45 45 5625 675 5625 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5625 900 45 45 5625 900 5625 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5625 5400 45 45 5625 5400 5625 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5850 450 45 45 5850 450 5850 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5850 675 45 45 5850 675 5850 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5850 900 45 45 5850 900 5850 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5850 5400 45 45 5850 5400 5850 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5850 5625 45 45 5850 5625 5850 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5850 5850 45 45 5850 5850 5850 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6075 450 45 45 6075 450 6075 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6075 675 45 45 6075 675 6075 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6075 900 45 45 6075 900 6075 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6075 5400 45 45 6075 5400 6075 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6075 5625 45 45 6075 5625 6075 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6075 5850 45 45 6075 5850 6075 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6300 450 45 45 6300 450 6300 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6300 675 45 45 6300 675 6300 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6300 900 45 45 6300 900 6300 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6300 5400 45 45 6300 5400 6300 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6300 5625 45 45 6300 5625 6300 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6300 5850 45 45 6300 5850 6300 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6525 450 45 45 6525 450 6525 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6525 675 45 45 6525 675 6525 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6525 900 45 45 6525 900 6525 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6525 5400 45 45 6525 5400 6525 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6525 5625 45 45 6525 5625 6525 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6525 5850 45 45 6525 5850 6525 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6750 450 45 45 6750 450 6750 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6750 675 45 45 6750 675 6750 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6750 900 45 45 6750 900 6750 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6750 5400 45 45 6750 5400 6750 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6750 5625 45 45 6750 5625 6750 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6750 5850 45 45 6750 5850 6750 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6975 450 45 45 6975 450 6975 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6975 675 45 45 6975 675 6975 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6975 900 45 45 6975 900 6975 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6975 5400 45 45 6975 5400 6975 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6975 5625 45 45 6975 5625 6975 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 6975 5850 45 45 6975 5850 6975 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7200 450 45 45 7200 450 7200 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7200 675 45 45 7200 675 7200 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7200 900 45 45 7200 900 7200 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7200 5400 45 45 7200 5400 7200 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7200 5625 45 45 7200 5625 7200 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7200 5850 45 45 7200 5850 7200 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7425 450 45 45 7425 450 7425 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7425 675 45 45 7425 675 7425 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7425 900 45 45 7425 900 7425 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7425 5400 45 45 7425 5400 7425 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7425 5625 45 45 7425 5625 7425 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7425 5850 45 45 7425 5850 7425 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7650 450 45 45 7650 450 7650 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7650 675 45 45 7650 675 7650 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7650 900 45 45 7650 900 7650 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7650 5400 45 45 7650 5400 7650 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7650 5625 45 45 7650 5625 7650 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7650 5850 45 45 7650 5850 7650 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 450 45 45 7875 450 7875 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 675 45 45 7875 675 7875 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 900 45 45 7875 900 7875 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 4725 45 45 7875 4725 7875 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 4950 45 45 7875 4950 7875 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 5175 45 45 7875 5175 7875 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 5400 45 45 7875 5400 7875 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 5625 45 45 7875 5625 7875 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 7875 5850 45 45 7875 5850 7875 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 450 45 45 8100 450 8100 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 675 45 45 8100 675 8100 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 900 45 45 8100 900 8100 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 4725 45 45 8100 4725 8100 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 4950 45 45 8100 4950 8100 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 5175 45 45 8100 5175 8100 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 5400 45 45 8100 5400 8100 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 5625 45 45 8100 5625 8100 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8100 5850 45 45 8100 5850 8100 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 450 45 45 8325 450 8325 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 675 45 45 8325 675 8325 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 900 45 45 8325 900 8325 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 4725 45 45 8325 4725 8325 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 4950 45 45 8325 4950 8325 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 5175 45 45 8325 5175 8325 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 5400 45 45 8325 5400 8325 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 5625 45 45 8325 5625 8325 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8325 5850 45 45 8325 5850 8325 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 450 45 45 8550 450 8550 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 675 45 45 8550 675 8550 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 900 45 45 8550 900 8550 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 4725 45 45 8550 4725 8550 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 4950 45 45 8550 4950 8550 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 5175 45 45 8550 5175 8550 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 5400 45 45 8550 5400 8550 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 5625 45 45 8550 5625 8550 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8550 5850 45 45 8550 5850 8550 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 450 45 45 8775 450 8775 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 675 45 45 8775 675 8775 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 900 45 45 8775 900 8775 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 1125 45 45 8775 1125 8775 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 1350 45 45 8775 1350 8775 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 1575 45 45 8775 1575 8775 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 1800 45 45 8775 1800 8775 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 2025 45 45 8775 2025 8775 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 2250 45 45 8775 2250 8775 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 2475 45 45 8775 2475 8775 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 2700 45 45 8775 2700 8775 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 2925 45 45 8775 2925 8775 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 3150 45 45 8775 3150 8775 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 3375 45 45 8775 3375 8775 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 3600 45 45 8775 3600 8775 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 3825 45 45 8775 3825 8775 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 4050 45 45 8775 4050 8775 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 4275 45 45 8775 4275 8775 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 4500 45 45 8775 4500 8775 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 4725 45 45 8775 4725 8775 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 4950 45 45 8775 4950 8775 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 5175 45 45 8775 5175 8775 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 450 45 45 9000 450 9000 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 675 45 45 9000 675 9000 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 900 45 45 9000 900 9000 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 1125 45 45 9000 1125 9000 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 1350 45 45 9000 1350 9000 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 1575 45 45 9000 1575 9000 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 1800 45 45 9000 1800 9000 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 2025 45 45 9000 2025 9000 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 2250 45 45 9000 2250 9000 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 2475 45 45 9000 2475 9000 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 2700 45 45 9000 2700 9000 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 2925 45 45 9000 2925 9000 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 3150 45 45 9000 3150 9000 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 3375 45 45 9000 3375 9000 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 3600 45 45 9000 3600 9000 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 3825 45 45 9000 3825 9000 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 4050 45 45 9000 4050 9000 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 4275 45 45 9000 4275 9000 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 4500 45 45 9000 4500 9000 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 4725 45 45 9000 4725 9000 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 4950 45 45 9000 4950 9000 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 5175 45 45 9000 5175 9000 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 450 45 45 9225 450 9225 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 675 45 45 9225 675 9225 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 900 45 45 9225 900 9225 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 1125 45 45 9225 1125 9225 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 1350 45 45 9225 1350 9225 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 1575 45 45 9225 1575 9225 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 1800 45 45 9225 1800 9225 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 2025 45 45 9225 2025 9225 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 2250 45 45 9225 2250 9225 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 2475 45 45 9225 2475 9225 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 2700 45 45 9225 2700 9225 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 2925 45 45 9225 2925 9225 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 3150 45 45 9225 3150 9225 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 3375 45 45 9225 3375 9225 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 3600 45 45 9225 3600 9225 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 3825 45 45 9225 3825 9225 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 4050 45 45 9225 4050 9225 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 4275 45 45 9225 4275 9225 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 4500 45 45 9225 4500 9225 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 4725 45 45 9225 4725 9225 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 4950 45 45 9225 4950 9225 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 5175 45 45 9225 5175 9225 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 450 45 45 9450 450 9450 495
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 675 45 45 9450 675 9450 720
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 900 45 45 9450 900 9450 945
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 1125 45 45 9450 1125 9450 1170
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 1350 45 45 9450 1350 9450 1395
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 1575 45 45 9450 1575 9450 1620
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 1800 45 45 9450 1800 9450 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 2025 45 45 9450 2025 9450 2070
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 2250 45 45 9450 2250 9450 2295
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 2475 45 45 9450 2475 9450 2520
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 2700 45 45 9450 2700 9450 2745
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 2925 45 45 9450 2925 9450 2970
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 3150 45 45 9450 3150 9450 3195
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 3375 45 45 9450 3375 9450 3420
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 3600 45 45 9450 3600 9450 3645
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 3825 45 45 9450 3825 9450 3870
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 4050 45 45 9450 4050 9450 4095
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 4275 45 45 9450 4275 9450 4320
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 4500 45 45 9450 4500 9450 4545
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 4725 45 45 9450 4725 9450 4770
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 4950 45 45 9450 4950 9450 4995
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 5175 45 45 9450 5175 9450 5220
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 3825 900 45 45 3825 900 3825 945
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 2025 45 45 2475 2025 2475 2070
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 2250 45 45 2475 2250 2475 2295
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 2475 45 45 2475 2475 2475 2520
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 2700 45 45 2475 2700 2475 2745
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 2925 45 45 2475 2925 2475 2970
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 3150 45 45 2475 3150 2475 3195
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 3375 45 45 2475 3375 2475 3420
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 3600 45 45 2475 3600 2475 3645
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 3825 45 45 2475 3825 2475 3870
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 4050 45 45 2475 4050 2475 4095
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 4275 45 45 2475 4275 2475 4320
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 4500 45 45 2475 4500 2475 4545
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 4725 45 45 2475 4725 2475 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 4950 45 45 2475 4950 2475 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2475 5175 45 45 2475 5175 2475 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 2025 45 45 2700 2025 2700 2070
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 2250 45 45 2700 2250 2700 2295
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 2475 45 45 2700 2475 2700 2520
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 2700 45 45 2700 2700 2700 2745
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 2925 45 45 2700 2925 2700 2970
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 3150 45 45 2700 3150 2700 3195
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 3375 45 45 2700 3375 2700 3420
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 3600 45 45 2700 3600 2700 3645
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 3825 45 45 2700 3825 2700 3870
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 4050 45 45 2700 4050 2700 4095
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 4275 45 45 2700 4275 2700 4320
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 4500 45 45 2700 4500 2700 4545
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 4725 45 45 2700 4725 2700 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 4950 45 45 2700 4950 2700 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2700 5175 45 45 2700 5175 2700 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 2025 45 45 2925 2025 2925 2070
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 2250 45 45 2925 2250 2925 2295
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 2475 45 45 2925 2475 2925 2520
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 2700 45 45 2925 2700 2925 2745
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 2925 45 45 2925 2925 2925 2970
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 3150 45 45 2925 3150 2925 3195
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 3375 45 45 2925 3375 2925 3420
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 3600 45 45 2925 3600 2925 3645
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 3825 45 45 2925 3825 2925 3870
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 4050 45 45 2925 4050 2925 4095
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 4275 45 45 2925 4275 2925 4320
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 4500 45 45 2925 4500 2925 4545
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 4725 45 45 2925 4725 2925 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 4950 45 45 2925 4950 2925 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 2925 5175 45 45 2925 5175 2925 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 2025 45 45 3150 2025 3150 2070
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 2250 45 45 3150 2250 3150 2295
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 2475 45 45 3150 2475 3150 2520
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 2700 45 45 3150 2700 3150 2745
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 2925 45 45 3150 2925 3150 2970
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 3150 45 45 3150 3150 3150 3195
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 3375 45 45 3150 3375 3150 3420
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 3600 45 45 3150 3600 3150 3645
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 3825 45 45 3150 3825 3150 3870
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 4050 45 45 3150 4050 3150 4095
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 4275 45 45 3150 4275 3150 4320
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 4500 45 45 3150 4500 3150 4545
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 4725 45 45 3150 4725 3150 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 4950 45 45 3150 4950 3150 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3150 5175 45 45 3150 5175 3150 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 2025 45 45 3375 2025 3375 2070
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 2250 45 45 3375 2250 3375 2295
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 2475 45 45 3375 2475 3375 2520
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 2700 45 45 3375 2700 3375 2745
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 2925 45 45 3375 2925 3375 2970
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 3150 45 45 3375 3150 3375 3195
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 3375 45 45 3375 3375 3375 3420
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 3600 45 45 3375 3600 3375 3645
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 3825 45 45 3375 3825 3375 3870
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 4050 45 45 3375 4050 3375 4095
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 4275 45 45 3375 4275 3375 4320
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 4500 45 45 3375 4500 3375 4545
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 4725 45 45 3375 4725 3375 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 4950 45 45 3375 4950 3375 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3375 5175 45 45 3375 5175 3375 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 2025 45 45 3600 2025 3600 2070
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 2250 45 45 3600 2250 3600 2295
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 2475 45 45 3600 2475 3600 2520
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 2700 45 45 3600 2700 3600 2745
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 2925 45 45 3600 2925 3600 2970
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 3150 45 45 3600 3150 3600 3195
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 3375 45 45 3600 3375 3600 3420
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 3600 45 45 3600 3600 3600 3645
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 3825 45 45 3600 3825 3600 3870
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 4050 45 45 3600 4050 3600 4095
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 4275 45 45 3600 4275 3600 4320
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 4500 45 45 3600 4500 3600 4545
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 4725 45 45 3600 4725 3600 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 4950 45 45 3600 4950 3600 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3600 5175 45 45 3600 5175 3600 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 2025 45 45 3825 2025 3825 2070
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 2250 45 45 3825 2250 3825 2295
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 2475 45 45 3825 2475 3825 2520
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 2700 45 45 3825 2700 3825 2745
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 2925 45 45 3825 2925 3825 2970
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 3150 45 45 3825 3150 3825 3195
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 3375 45 45 3825 3375 3825 3420
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 3600 45 45 3825 3600 3825 3645
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 3825 45 45 3825 3825 3825 3870
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 4050 45 45 3825 4050 3825 4095
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 4275 45 45 3825 4275 3825 4320
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 4950 45 45 3825 4950 3825 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 5175 45 45 3825 5175 3825 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4050 4950 45 45 4050 4950 4050 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4050 5175 45 45 4050 5175 4050 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4275 4725 45 45 4275 4725 4275 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4275 4950 45 45 4275 4950 4275 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4275 5175 45 45 4275 5175 4275 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4500 4725 45 45 4500 4725 4500 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4500 4950 45 45 4500 4950 4500 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4500 5175 45 45 4500 5175 4500 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4725 4725 45 45 4725 4725 4725 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4725 4950 45 45 4725 4950 4725 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4725 5175 45 45 4725 5175 4725 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4950 4725 45 45 4950 4725 4950 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4950 4950 45 45 4950 4950 4950 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4950 5175 45 45 4950 5175 4950 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5175 4725 45 45 5175 4725 5175 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5175 4950 45 45 5175 4950 5175 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5175 5175 45 45 5175 5175 5175 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5400 4725 45 45 5400 4725 5400 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5400 4950 45 45 5400 4950 5400 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5400 5175 45 45 5400 5175 5400 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5625 4725 45 45 5625 4725 5625 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5625 4950 45 45 5625 4950 5625 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5625 5175 45 45 5625 5175 5625 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5850 4725 45 45 5850 4725 5850 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5850 4950 45 45 5850 4950 5850 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 5850 5175 45 45 5850 5175 5850 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6075 4725 45 45 6075 4725 6075 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6075 4950 45 45 6075 4950 6075 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6075 5175 45 45 6075 5175 6075 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6300 4725 45 45 6300 4725 6300 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6300 4950 45 45 6300 4950 6300 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6300 5175 45 45 6300 5175 6300 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6525 4725 45 45 6525 4725 6525 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6525 4950 45 45 6525 4950 6525 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6525 5175 45 45 6525 5175 6525 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6750 4725 45 45 6750 4725 6750 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6750 4950 45 45 6750 4950 6750 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6750 5175 45 45 6750 5175 6750 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6975 4725 45 45 6975 4725 6975 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6975 4950 45 45 6975 4950 6975 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 6975 5175 45 45 6975 5175 6975 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7200 4725 45 45 7200 4725 7200 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7200 4950 45 45 7200 4950 7200 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7200 5175 45 45 7200 5175 7200 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7425 4725 45 45 7425 4725 7425 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7425 4950 45 45 7425 4950 7425 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7425 5175 45 45 7425 5175 7425 5220
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7650 4725 45 45 7650 4725 7650 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7650 4950 45 45 7650 4950 7650 4995
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 4500 45 45 3825 4500 3825 4545
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 3825 4725 45 45 3825 4725 3825 4770
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 4050 4725 45 45 4050 4725 4050 4770
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4500 1125 45 45 4500 1125 4500 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4725 1125 45 45 4725 1125 4725 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4950 1125 45 45 4950 1125 4950 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5175 1125 45 45 5175 1125 5175 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5400 1125 45 45 5400 1125 5400 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5625 1125 45 45 5625 1125 5625 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5850 1125 45 45 5850 1125 5850 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6075 1125 45 45 6075 1125 6075 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6300 1125 45 45 6300 1125 6300 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6525 1125 45 45 6525 1125 6525 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6750 1125 45 45 6750 1125 6750 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6975 1125 45 45 6975 1125 6975 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7200 1125 45 45 7200 1125 7200 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7425 1125 45 45 7425 1125 7425 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7650 1125 45 45 7650 1125 7650 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 1125 45 45 7875 1125 7875 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 1125 45 45 8100 1125 8100 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 1125 45 45 8325 1125 8325 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 1125 45 45 8550 1125 8550 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 1350 45 45 8550 1350 8550 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 1575 45 45 8550 1575 8550 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 1800 45 45 8550 1800 8550 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 2025 45 45 8550 2025 8550 2070
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 2250 45 45 8550 2250 8550 2295
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 2475 45 45 8550 2475 8550 2520
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 2700 45 45 8550 2700 8550 2745
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 2925 45 45 8550 2925 8550 2970
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 3150 45 45 8550 3150 8550 3195
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 3375 45 45 8550 3375 8550 3420
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 3600 45 45 8550 3600 8550 3645
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 3825 45 45 8550 3825 8550 3870
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 4050 45 45 8550 4050 8550 4095
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 4275 45 45 8550 4275 8550 4320
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8550 4500 45 45 8550 4500 8550 4545
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5400 1350 45 45 5400 1350 5400 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5400 1575 45 45 5400 1575 5400 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5400 1800 45 45 5400 1800 5400 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5625 1350 45 45 5625 1350 5625 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5625 1575 45 45 5625 1575 5625 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5625 1800 45 45 5625 1800 5625 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5850 1350 45 45 5850 1350 5850 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5850 1575 45 45 5850 1575 5850 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5850 1800 45 45 5850 1800 5850 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6075 1350 45 45 6075 1350 6075 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6075 1575 45 45 6075 1575 6075 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6075 1800 45 45 6075 1800 6075 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6300 1350 45 45 6300 1350 6300 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6300 1575 45 45 6300 1575 6300 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6300 1800 45 45 6300 1800 6300 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6525 1350 45 45 6525 1350 6525 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6525 1575 45 45 6525 1575 6525 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6525 1800 45 45 6525 1800 6525 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6750 1350 45 45 6750 1350 6750 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6750 1575 45 45 6750 1575 6750 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6750 1800 45 45 6750 1800 6750 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6975 1350 45 45 6975 1350 6975 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6975 1575 45 45 6975 1575 6975 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 6975 1800 45 45 6975 1800 6975 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7200 1350 45 45 7200 1350 7200 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7200 1575 45 45 7200 1575 7200 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7200 1800 45 45 7200 1800 7200 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7425 1350 45 45 7425 1350 7425 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7425 1575 45 45 7425 1575 7425 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7425 1800 45 45 7425 1800 7425 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7650 1350 45 45 7650 1350 7650 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7650 1575 45 45 7650 1575 7650 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7650 1800 45 45 7650 1800 7650 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 1350 45 45 7875 1350 7875 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 1575 45 45 7875 1575 7875 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 1800 45 45 7875 1800 7875 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 2025 45 45 7875 2025 7875 2070
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 2250 45 45 7875 2250 7875 2295
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 2475 45 45 7875 2475 7875 2520
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 2700 45 45 7875 2700 7875 2745
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 2925 45 45 7875 2925 7875 2970
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 3150 45 45 7875 3150 7875 3195
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 3375 45 45 7875 3375 7875 3420
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 3600 45 45 7875 3600 7875 3645
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 3825 45 45 7875 3825 7875 3870
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 4050 45 45 7875 4050 7875 4095
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 4275 45 45 7875 4275 7875 4320
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 7875 4500 45 45 7875 4500 7875 4545
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 1350 45 45 8100 1350 8100 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 1575 45 45 8100 1575 8100 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 1800 45 45 8100 1800 8100 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 2025 45 45 8100 2025 8100 2070
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 2250 45 45 8100 2250 8100 2295
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 2475 45 45 8100 2475 8100 2520
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 2700 45 45 8100 2700 8100 2745
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 2925 45 45 8100 2925 8100 2970
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 3150 45 45 8100 3150 8100 3195
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 3375 45 45 8100 3375 8100 3420
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 3600 45 45 8100 3600 8100 3645
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 3825 45 45 8100 3825 8100 3870
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 4050 45 45 8100 4050 8100 4095
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 4275 45 45 8100 4275 8100 4320
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8100 4500 45 45 8100 4500 8100 4545
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 1350 45 45 8325 1350 8325 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 1575 45 45 8325 1575 8325 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 1800 45 45 8325 1800 8325 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 2025 45 45 8325 2025 8325 2070
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 2250 45 45 8325 2250 8325 2295
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 2475 45 45 8325 2475 8325 2520
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 2700 45 45 8325 2700 8325 2745
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 2925 45 45 8325 2925 8325 2970
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 3150 45 45 8325 3150 8325 3195
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 3375 45 45 8325 3375 8325 3420
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 3600 45 45 8325 3600 8325 3645
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 3825 45 45 8325 3825 8325 3870
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 4050 45 45 8325 4050 8325 4095
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 4275 45 45 8325 4275 8325 4320
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 8325 4500 45 45 8325 4500 8325 4545
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4050 1350 45 45 4050 1350 4050 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4050 1575 45 45 4050 1575 4050 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4050 1800 45 45 4050 1800 4050 1845
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 3150 45 45 4050 3150 4050 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 3375 45 45 4050 3375 4050 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 3600 45 45 4050 3600 4050 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 3825 45 45 4050 3825 4050 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 4050 45 45 4050 4050 4050 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 4275 45 45 4050 4275 4050 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 4500 45 45 4050 4500 4050 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 2025 45 45 4275 2025 4275 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 2250 45 45 4275 2250 4275 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 2475 45 45 4275 2475 4275 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 2700 45 45 4275 2700 4275 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 2925 45 45 4275 2925 4275 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 3150 45 45 4275 3150 4275 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 3375 45 45 4275 3375 4275 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 3600 45 45 4275 3600 4275 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 3825 45 45 4275 3825 4275 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 4050 45 45 4275 4050 4275 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 4275 45 45 4275 4275 4275 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4275 4500 45 45 4275 4500 4275 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 2025 45 45 4500 2025 4500 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 2250 45 45 4500 2250 4500 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 2475 45 45 4500 2475 4500 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 2700 45 45 4500 2700 4500 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 2925 45 45 4500 2925 4500 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 3150 45 45 4500 3150 4500 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 3375 45 45 4500 3375 4500 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 3600 45 45 4500 3600 4500 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 3825 45 45 4500 3825 4500 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 4050 45 45 4500 4050 4500 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 4275 45 45 4500 4275 4500 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4500 4500 45 45 4500 4500 4500 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 2025 45 45 4725 2025 4725 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 2250 45 45 4725 2250 4725 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 2475 45 45 4725 2475 4725 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 2700 45 45 4725 2700 4725 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 2925 45 45 4725 2925 4725 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 3150 45 45 4725 3150 4725 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 3375 45 45 4725 3375 4725 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 3600 45 45 4725 3600 4725 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 3825 45 45 4725 3825 4725 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 4050 45 45 4725 4050 4725 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 4275 45 45 4725 4275 4725 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4725 4500 45 45 4725 4500 4725 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 2025 45 45 4950 2025 4950 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 2250 45 45 4950 2250 4950 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 2475 45 45 4950 2475 4950 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 2700 45 45 4950 2700 4950 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 2925 45 45 4950 2925 4950 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 3150 45 45 4950 3150 4950 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 3375 45 45 4950 3375 4950 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 3600 45 45 4950 3600 4950 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 3825 45 45 4950 3825 4950 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 4050 45 45 4950 4050 4950 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 4275 45 45 4950 4275 4950 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4950 4500 45 45 4950 4500 4950 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 2025 45 45 5175 2025 5175 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 2250 45 45 5175 2250 5175 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 2475 45 45 5175 2475 5175 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 2700 45 45 5175 2700 5175 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 2925 45 45 5175 2925 5175 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 3150 45 45 5175 3150 5175 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 3375 45 45 5175 3375 5175 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 3600 45 45 5175 3600 5175 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 3825 45 45 5175 3825 5175 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 4050 45 45 5175 4050 5175 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 4275 45 45 5175 4275 5175 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5175 4500 45 45 5175 4500 5175 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 2025 45 45 5400 2025 5400 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 2250 45 45 5400 2250 5400 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 2475 45 45 5400 2475 5400 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 2700 45 45 5400 2700 5400 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 2925 45 45 5400 2925 5400 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 3150 45 45 5400 3150 5400 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 3375 45 45 5400 3375 5400 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 3600 45 45 5400 3600 5400 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 3825 45 45 5400 3825 5400 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 4050 45 45 5400 4050 5400 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 4275 45 45 5400 4275 5400 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5400 4500 45 45 5400 4500 5400 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 2025 45 45 5625 2025 5625 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 2250 45 45 5625 2250 5625 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 2475 45 45 5625 2475 5625 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 2700 45 45 5625 2700 5625 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 2925 45 45 5625 2925 5625 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 3150 45 45 5625 3150 5625 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 3375 45 45 5625 3375 5625 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 3600 45 45 5625 3600 5625 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 3825 45 45 5625 3825 5625 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 4050 45 45 5625 4050 5625 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 4275 45 45 5625 4275 5625 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5625 4500 45 45 5625 4500 5625 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 2025 45 45 5850 2025 5850 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 2250 45 45 5850 2250 5850 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 2475 45 45 5850 2475 5850 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 2700 45 45 5850 2700 5850 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 2925 45 45 5850 2925 5850 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 3150 45 45 5850 3150 5850 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 3375 45 45 5850 3375 5850 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 3600 45 45 5850 3600 5850 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 3825 45 45 5850 3825 5850 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 4050 45 45 5850 4050 5850 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 4275 45 45 5850 4275 5850 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 5850 4500 45 45 5850 4500 5850 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 2025 45 45 6075 2025 6075 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 2250 45 45 6075 2250 6075 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 2475 45 45 6075 2475 6075 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 2700 45 45 6075 2700 6075 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 2925 45 45 6075 2925 6075 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 3150 45 45 6075 3150 6075 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 3375 45 45 6075 3375 6075 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 3600 45 45 6075 3600 6075 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 3825 45 45 6075 3825 6075 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 4050 45 45 6075 4050 6075 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 4275 45 45 6075 4275 6075 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6075 4500 45 45 6075 4500 6075 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 2025 45 45 6300 2025 6300 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 2250 45 45 6300 2250 6300 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 2475 45 45 6300 2475 6300 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 2700 45 45 6300 2700 6300 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 2925 45 45 6300 2925 6300 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 3150 45 45 6300 3150 6300 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 3375 45 45 6300 3375 6300 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 3600 45 45 6300 3600 6300 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 3825 45 45 6300 3825 6300 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 4050 45 45 6300 4050 6300 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 4275 45 45 6300 4275 6300 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6300 4500 45 45 6300 4500 6300 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 2025 45 45 6525 2025 6525 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 2250 45 45 6525 2250 6525 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 2475 45 45 6525 2475 6525 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 2700 45 45 6525 2700 6525 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 2925 45 45 6525 2925 6525 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 3150 45 45 6525 3150 6525 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 3375 45 45 6525 3375 6525 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 3600 45 45 6525 3600 6525 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 3825 45 45 6525 3825 6525 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 4050 45 45 6525 4050 6525 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 4275 45 45 6525 4275 6525 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6525 4500 45 45 6525 4500 6525 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 2025 45 45 6750 2025 6750 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 2250 45 45 6750 2250 6750 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 2475 45 45 6750 2475 6750 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 2700 45 45 6750 2700 6750 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 2925 45 45 6750 2925 6750 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 3150 45 45 6750 3150 6750 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 3375 45 45 6750 3375 6750 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 3600 45 45 6750 3600 6750 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 3825 45 45 6750 3825 6750 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 4050 45 45 6750 4050 6750 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 4275 45 45 6750 4275 6750 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6750 4500 45 45 6750 4500 6750 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 2025 45 45 6975 2025 6975 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 2250 45 45 6975 2250 6975 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 2475 45 45 6975 2475 6975 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 2700 45 45 6975 2700 6975 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 2925 45 45 6975 2925 6975 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 3150 45 45 6975 3150 6975 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 3375 45 45 6975 3375 6975 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 3600 45 45 6975 3600 6975 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 3825 45 45 6975 3825 6975 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 4050 45 45 6975 4050 6975 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 4275 45 45 6975 4275 6975 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 6975 4500 45 45 6975 4500 6975 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 2025 45 45 7200 2025 7200 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 2250 45 45 7200 2250 7200 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 2475 45 45 7200 2475 7200 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 2700 45 45 7200 2700 7200 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 2925 45 45 7200 2925 7200 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 3150 45 45 7200 3150 7200 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 3375 45 45 7200 3375 7200 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 3600 45 45 7200 3600 7200 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 3825 45 45 7200 3825 7200 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 4050 45 45 7200 4050 7200 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 4275 45 45 7200 4275 7200 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7200 4500 45 45 7200 4500 7200 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 2025 45 45 7425 2025 7425 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 2250 45 45 7425 2250 7425 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 2475 45 45 7425 2475 7425 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 2700 45 45 7425 2700 7425 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 2925 45 45 7425 2925 7425 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 3150 45 45 7425 3150 7425 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 3375 45 45 7425 3375 7425 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 3600 45 45 7425 3600 7425 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 3825 45 45 7425 3825 7425 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 4050 45 45 7425 4050 7425 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 4275 45 45 7425 4275 7425 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7425 4500 45 45 7425 4500 7425 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 2025 45 45 7650 2025 7650 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 2250 45 45 7650 2250 7650 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 2475 45 45 7650 2475 7650 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 2700 45 45 7650 2700 7650 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 2925 45 45 7650 2925 7650 2970
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 3150 45 45 7650 3150 7650 3195
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 3375 45 45 7650 3375 7650 3420
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 3600 45 45 7650 3600 7650 3645
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 3825 45 45 7650 3825 7650 3870
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 4050 45 45 7650 4050 7650 4095
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 4275 45 45 7650 4275 7650 4320
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 7650 4500 45 45 7650 4500 7650 4545
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 2025 45 45 4050 2025 4050 2070
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 2250 45 45 4050 2250 4050 2295
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 2475 45 45 4050 2475 4050 2520
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 2700 45 45 4050 2700 4050 2745
1 3 0 2 4 1 50 0 20 0.000 1 0.0000 4050 2925 45 45 4050 2925 4050 2970
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4275 1125 45 45 4275 1125 4275 1170
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5175 1350 45 45 5175 1350 5175 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5175 1575 45 45 5175 1575 5175 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 5175 1800 45 45 5175 1800 5175 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4275 1350 45 45 4275 1350 4275 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4275 1575 45 45 4275 1575 4275 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4275 1800 45 45 4275 1800 4275 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4500 1350 45 45 4500 1350 4500 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4500 1575 45 45 4500 1575 4500 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4500 1800 45 45 4500 1800 4500 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4725 1350 45 45 4725 1350 4725 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4725 1575 45 45 4725 1575 4725 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4725 1800 45 45 4725 1800 4725 1845
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4950 1350 45 45 4950 1350 4950 1395
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4950 1575 45 45 4950 1575 4950 1620
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4950 1800 45 45 4950 1800 4950 1845
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4950 5400 45 45 4950 5400 4950 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4950 5625 45 45 4950 5625 4950 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 4950 5850 45 45 4950 5850 4950 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5175 5625 45 45 5175 5625 5175 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5175 5850 45 45 5175 5850 5175 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5400 5625 45 45 5400 5625 5400 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5400 5850 45 45 5400 5850 5400 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5625 5625 45 45 5625 5625 5625 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 5625 5850 45 45 5625 5850 5625 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 5400 45 45 8775 5400 8775 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 5625 45 45 8775 5625 8775 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 8775 5850 45 45 8775 5850 8775 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 5400 45 45 9000 5400 9000 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 5625 45 45 9000 5625 9000 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9000 5850 45 45 9000 5850 9000 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 5400 45 45 9225 5400 9225 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 5625 45 45 9225 5625 9225 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9225 5850 45 45 9225 5850 9225 5895
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 5400 45 45 9450 5400 9450 5445
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 5625 45 45 9450 5625 9450 5670
1 3 0 1 32 7 50 0 -1 0.000 1 0.0000 9450 5850 45 45 9450 5850 9450 5895
1 3 0 2 4 7 50 0 -1 0.000 1 0.0000 4050 1125 45 45 4050 1125 4050 1170
1 3 0 1 32 1 50 0 20 0.000 1 0.0000 7650 5175 45 45 7650 5175 7650 5220
2 1 0 2 0 7 52 0 -1 0.000 0 0 -1 1 0 2
1 1 2.00 120.00 240.00
2475 0 2475 6525
2 1 0 2 0 7 52 0 -1 0.000 0 0 -1 1 0 2
1 1 2.00 120.00 240.00
1125 2025 10125 2025
2 2 0 4 28 1 51 0 -1 0.000 0 0 -1 0 0 5
3375 7875 4050 7875 4050 8325 3375 8325 3375 7875
2 2 0 4 11 1 51 0 -1 0.000 0 0 -1 0 0 5
3375 7200 4050 7200 4050 7650 3375 7650 3375 7200
2 2 0 4 11 1 51 0 -1 0.000 0 0 -1 0 0 5
2475 2025 7650 2025 7650 5175 2475 5175 2475 2025
2 2 0 4 28 1 51 0 -1 0.000 0 0 -1 0 0 5
4050 1125 8550 1125 8550 4500 4050 4500 4050 1125
4 0 0 50 0 16 18 0.0000 4 210 210 2700 6525 Y\001
4 0 0 50 0 16 18 0.0000 4 210 195 9900 2475 X\001
4 0 0 50 0 16 18 0.0000 4 270 1785 4365 6840 pixel positions\001
4 0 0 50 0 16 18 0.0000 4 270 1905 4365 7515 display window\001
4 0 0 50 0 16 18 0.0000 4 210 1560 4365 8190 data window\001
4 0 0 50 0 16 18 0.0000 4 270 3855 4365 8865 pixels that are part of the image\001
4 0 0 50 0 16 18 0.0000 4 270 4545 4365 9540 pixels for which the file contains data\001
Binary file not shown.

Before

Width:  |  Height:  |  Size: 613 KiB

-116
View File
@@ -1,116 +0,0 @@
#FIG 3.2
Landscape
Center
Metric
A4
60.00
Single
-2
1200 2
0 32 #d2d2d2
6 11025 2250 11925 2700
4 2 0 50 -1 22 18 0.0000 4 195 315 11340 2565 lat.\001
4 0 0 50 -1 32 20 0.0000 4 195 510 11385 2565 +p/2\001
-6
6 10800 2475 11925 2925
4 0 0 50 -1 32 20 0.0000 4 135 300 11565 2835 +p\001
4 2 0 50 -1 22 18 0.0000 4 255 525 11520 2835 long.\001
-6
6 8010 3060 9135 3375
6 8010 3060 9135 3375
4 0 0 50 -1 32 20 0.0000 4 195 510 8595 3285 +p/2\001
4 2 0 50 -1 22 18 0.0000 4 255 525 8550 3285 long.\001
-6
-6
1 1 0 3 0 7 48 -1 -1 0.000 1 0.0000 5595 2437 62 43 5595 2437 5657 2480
1 3 0 3 0 7 50 -1 -1 0.000 1 0.0000 5602 4453 2269 2269 5602 4453 7871 4453
2 2 0 3 0 7 50 -1 -1 0.000 0 0 -1 0 0 5
10800 2250 15300 2250 15300 4500 10800 4500 10800 2250
2 1 0 1 0 7 47 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
7965 3285 7110 3825
2 1 0 1 0 7 47 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
3420 3060 4275 3510
2 1 0 1 0 7 47 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
4950 1710 5490 2340
2 1 0 9 7 7 48 -1 -1 0.000 0 0 -1 0 0 2
3420 3060 4275 3510
2 1 0 9 7 7 48 -1 -1 0.000 0 0 -1 0 0 2
4950 1710 5450 2290
2 1 0 9 7 7 48 -1 -1 0.000 0 0 -1 0 0 2
7965 3285 7110 3825
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
10800 1755 10800 2160
2 1 0 1 0 7 50 -1 -1 0.000 0 0 -1 1 0 2
1 1 1.00 60.00 120.00
15300 4995 15300 4590
2 1 0 3 32 7 51 -1 -1 0.000 0 0 -1 0 0 2
5604 4454 3867 5459
2 1 0 3 32 7 51 -1 -1 0.000 0 0 -1 0 0 2
5607 4452 7336 5456
2 1 0 3 32 7 51 -1 -1 0.000 0 0 -1 0 0 2
5604 4455 5604 2448
2 1 0 9 7 7 52 -1 -1 0.000 0 0 -1 0 0 2
4498 3292 4951 2808
2 1 0 9 7 7 52 -1 -1 0.000 0 0 -1 0 0 2
6246 2822 6686 3248
2 1 0 9 7 7 52 -1 -1 0.000 0 0 -1 0 0 2
5594 2689 5594 3177
2 1 0 3 0 7 47 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 113.44 226.88
3866 5462 2910 6016
2 1 0 3 0 7 47 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 113.44 226.88
7341 5461 8300 6021
2 1 0 3 0 7 47 -1 -1 0.000 0 0 -1 1 0 2
1 1 3.00 113.44 226.88
5601 2449 5601 1339
2 1 0 9 7 7 48 -1 -1 0.000 0 0 -1 0 0 2
5598 2292 5598 2022
2 1 0 9 7 7 48 -1 -1 0.000 0 0 -1 0 0 2
3712 5554 3565 5638
2 1 0 9 7 7 48 -1 -1 0.000 0 0 -1 0 0 2
7497 5549 7679 5656
3 0 0 3 0 7 50 -1 -1 0.000 0 0 0 17
4520 6452 4387 6381 4207 6230 4033 5989 3926 5754 3851 5468
3818 5041 3905 4454 4104 3903 4494 3274 4943 2817 5401 2514
5771 2376 6138 2322 6431 2366 6574 2405 6726 2482
0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
0.000
3 0 0 3 0 7 50 -1 -1 0.000 0 0 0 17
7871 4389 7876 4539 7835 4771 7713 5043 7563 5253 7353 5461
7000 5703 6448 5920 5871 6023 5132 6000 4512 5839 4020 5594
3715 5343 3486 5053 3377 4777 3339 4634 3330 4464
0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
0.000
3 0 0 3 0 7 50 -1 -1 0.000 0 0 0 17
4411 2520 4539 2441 4760 2360 5056 2329 5313 2354 5599 2432
5984 2617 6449 2986 6826 3434 7176 4086 7347 4704 7380 5252
7316 5641 7179 5986 6995 6217 6889 6322 6746 6415
0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
0.000
3 0 0 3 32 7 53 -1 -1 0.000 0 0 0 17
7871 4535 7876 4385 7835 4153 7713 3881 7563 3671 7353 3463
7000 3221 6448 3003 5871 2901 5132 2923 4512 3084 4020 3329
3715 3580 3486 3871 3377 4146 3339 4290 3330 4460
0.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
1.000 1.000 1.000 1.000 1.000 1.000 1.000 1.000
0.000
4 1 0 50 -1 22 18 0.0000 4 195 150 5625 1170 Y\001
4 1 0 50 -1 22 18 0.0000 4 195 135 2700 6255 Z\001
4 1 0 50 -1 22 18 0.0000 4 195 150 8550 6255 X\001
4 2 0 50 -1 22 18 0.0000 4 255 525 14760 4365 long.\001
4 2 0 50 -1 22 18 0.0000 4 195 315 14580 4095 lat.\001
4 0 0 50 -1 32 20 0.0000 4 195 495 14625 4095 -p/2\001
4 0 0 50 -1 32 20 0.0000 4 135 285 14805 4365 -p\001
4 2 0 50 -1 22 18 0.0000 4 195 315 4365 1665 lat.\001
4 0 0 50 -1 32 20 0.0000 4 195 510 4410 1665 +p/2\001
4 2 0 50 -1 22 18 0.0000 4 195 1740 10845 1665 dataWindow.min\001
4 0 0 50 -1 22 18 0.0000 4 195 1785 15255 5265 dataWindow.max\001
4 2 0 50 -1 22 18 0.0000 4 255 705 3375 3060 long. 0\001
-164
View File
@@ -1,164 +0,0 @@
#FIG 3.2
Landscape
Center
Metric
A4
70.00
Single
-2
1200 2
0 32 #afafaf
6 11250 7875 11700 8325
2 3 0 0 0 0 52 -1 20 4.000 0 0 -1 0 0 4
11250 7983 11538 7955 11250 8213 11250 7983
-6
6 9675 9675 10125 10350
2 3 0 0 0 0 52 -1 20 4.000 0 0 -1 0 0 4
9787 9959 9899 10240 10011 9846 9787 9959
-6
6 10800 6525 11250 6975
2 3 0 0 0 0 52 -1 20 4.000 0 0 -1 0 0 4
10800 6633 11088 6605 10800 6863 10800 6633
-6
6 2925 4275 3150 4725
2 3 0 0 0 0 52 -1 20 4.000 0 0 -1 0 0 4
3150 4613 2942 4378 3150 4404 3150 4613
-6
6 8325 3600 8775 4275
2 3 0 0 0 0 52 -1 20 4.000 0 0 -1 0 0 4
8663 3992 8551 3711 8439 4104 8663 3992
-6
6 7425 3375 7875 3600
2 3 0 0 0 0 38 -1 20 4.000 0 0 -1 0 0 4
7516 3389 7660 3375 7516 3504 7516 3389
-6
6 4950 4500 5175 4725
2 3 0 0 0 0 38 -1 20 4.000 0 0 -1 0 0 4
5104 4711 4960 4725 5104 4596 5104 4711
-6
1 3 0 1 0 0 42 -1 20 4.000 1 0.0000 6750 6750 41 41 6750 6750 6761 6789
1 3 0 1 0 0 33 -1 20 4.000 1 0.0000 8550 7875 41 41 8550 7875 8561 7914
1 3 0 1 0 0 42 -1 20 4.000 1 0.0000 6300 6075 41 41 6300 6075 6311 6114
2 1 0 2 0 0 42 -1 -1 6.000 1 1 -1 0 0 2
9900 8775 9900 9900
2 1 0 2 0 0 42 -1 -1 6.000 1 1 -1 0 0 2
9900 8775 11250 8100
2 3 0 0 0 7 43 -1 20 2.000 1 1 -1 0 0 5
7287 6845 7429 6934 7500 6894 7366 6814 7287 6845
2 3 0 0 0 7 41 -1 20 2.000 1 1 -1 0 0 5
6914 6611 7012 6668 7065 6637 6963 6584 6914 6611
2 3 0 0 0 7 41 -1 20 2.000 1 1 -1 0 0 5
6781 6691 6879 6748 6932 6717 6830 6664 6781 6691
2 3 0 0 0 7 43 -1 20 2.000 1 1 -1 0 0 5
7014 6982 7170 7073 7256 7023 7122 6943 7014 6982
2 3 0 0 0 7 43 -1 20 2.000 1 1 -1 0 0 5
7123 6925 7265 7014 7340 6978 7194 6899 7123 6925
2 3 0 0 0 7 39 -1 20 2.000 1 1 -1 0 0 5
6231 6309 6329 6366 6382 6335 6280 6282 6231 6309
2 3 0 0 0 7 39 -1 20 2.000 1 1 -1 0 0 5
6240 6194 6338 6251 6391 6220 6289 6167 6240 6194
2 3 0 0 0 7 41 -1 20 2.000 1 1 -1 0 0 5
6675 6620 6773 6677 6826 6646 6724 6593 6675 6620
2 3 0 0 0 7 41 -1 20 2.000 1 1 -1 0 0 5
6683 6469 6781 6526 6834 6495 6732 6442 6683 6469
2 3 0 0 0 7 41 -1 20 2.000 1 1 -1 0 0 5
6342 6565 6342 6437 6256 6384 6259 6514 6342 6565
2 3 0 0 0 7 41 -1 20 2.000 1 1 -1 0 0 5
4911 5536 4911 5678 5000 5736 5004 5589 4911 5536
2 3 0 0 0 7 39 -1 20 2.000 1 1 -1 0 0 5
8422 7507 8617 7626 8617 7564 8417 7449 8422 7507
2 3 0 0 0 7 39 -1 20 2.000 1 1 -1 0 0 5
7907 7147 8164 7293 8195 7382 7929 7227 7907 7147
2 3 0 0 0 7 39 -1 20 2.000 1 1 -1 0 0 5
8727 7698 8922 7817 8922 7755 8722 7640 8727 7698
2 3 0 0 0 7 49 -1 20 2.000 1 1 -1 0 0 5
8345 7134 8376 7245 8443 7267 8403 7143 8345 7134
2 3 0 0 0 7 49 -1 20 2.000 1 1 -1 0 0 5
8514 7209 8514 7338 8585 7373 8580 7254 8514 7209
2 3 0 0 0 7 49 -1 20 2.000 1 1 -1 0 0 5
8989 7609 9104 7551 9188 7604 9073 7657 8989 7609
2 3 0 0 0 7 43 -1 20 2.000 1 1 -1 0 0 5
8518 4506 8518 4622 8589 4671 8589 4542 8518 4506
2 3 0 0 0 7 43 -1 20 2.000 1 1 -1 0 0 5
10394 8454 10521 8392 10640 8468 10506 8540 10394 8454
2 3 0 0 0 7 43 -1 20 2.000 1 1 -1 0 0 5
9571 7968 9722 7900 9835 7980 9684 8045 9571 7968
2 1 0 3 11 0 40 -1 -1 6.000 1 1 -1 0 0 3
9450 10800 9450 8100 12150 6750
2 1 0 3 11 0 44 -1 -1 6.000 1 1 -1 0 0 3
9450 10800 12150 9450 12150 6750
2 3 0 0 32 7 41 -1 20 0.000 1 1 -1 0 0 5
6020 6160 6118 6226 6167 6204 6060 6133 6020 6160
2 3 0 0 32 7 41 -1 20 2.000 1 1 -1 0 0 5
6100 6115 6211 6178 6247 6151 6153 6093 6100 6115
2 3 0 0 32 7 43 -1 20 2.000 1 1 -1 0 0 5
5845 6245 5972 6186 6061 6245 5916 6313 5845 6245
2 1 2 1 32 0 38 -1 -1 1.500 1 1 -1 0 0 2
4950 5400 9450 8100
2 1 2 1 32 0 38 -1 -1 1.500 1 1 -1 0 0 2
8550 7875 4950 5400
2 1 2 1 32 0 42 -1 -1 1.500 1 1 -1 0 0 2
8550 7875 4950 8100
2 1 2 1 32 0 42 -1 -1 1.500 1 1 -1 0 0 2
4950 8100 1350 8325
2 1 2 1 32 0 42 -1 -1 1.500 1 1 -1 0 0 2
4950 5400 1350 2925
2 1 2 1 32 0 42 -1 -1 1.500 1 1 -1 0 0 2
8550 7875 7650 4050
2 1 2 1 32 0 44 -1 -1 1.500 1 1 -1 0 0 2
7650 4050 12150 6750
2 1 2 1 32 0 50 -1 -1 1.500 1 1 -1 0 0 2
7650 6750 12150 9450
2 1 2 1 32 0 42 -1 -1 1.500 1 1 -1 0 0 2
4950 8100 9450 10800
2 1 2 1 32 0 42 -1 -1 1.500 1 1 -1 0 0 2
8550 7875 7650 6750
2 1 0 3 0 7 42 -1 -1 6.000 1 1 -1 0 0 2
8550 7875 6750 6750
2 1 0 3 0 7 42 -1 -1 6.000 1 1 -1 0 0 2
4950 5625 3150 4500
2 1 0 3 0 0 42 -1 -1 6.000 1 1 -1 0 0 2
8550 7875 8550 4050
2 1 0 3 0 0 42 -1 -1 6.000 1 1 -1 0 0 2
8550 7875 10800 6750
2 1 0 1 0 7 38 -1 20 4.000 1 1 -1 0 0 2
4950 5310 4950 4500
2 1 0 1 0 7 38 -1 20 4.000 1 1 -1 0 0 2
7650 3960 7650 3150
2 1 2 1 32 0 42 -1 -1 1.500 1 1 -1 0 0 2
7650 4050 6750 225
2 3 0 0 0 7 40 -1 20 2.000 1 1 -1 0 0 7
7552 3354 7495 3354 7468 3402 7481 3513 7503 3544 7570 3518
7552 3354
2 2 0 0 0 7 37 -1 20 2.000 1 1 -1 0 0 5
6075 3825 6525 3825 6525 4275 6075 4275 6075 3825
2 1 0 1 0 7 38 -1 20 4.000 1 1 -1 0 0 2
4950 4725 7650 3375
2 1 0 3 12 0 40 -1 -1 6.000 1 1 -1 0 0 3
4950 8100 4950 5400 7650 4050
2 1 0 3 12 0 44 -1 -1 6.000 1 1 -1 0 0 3
4950 8100 7650 6750 7650 4050
2 3 0 0 0 7 33 -1 20 2.000 1 1 -1 0 0 5
10759 8471 10539 8591 10749 8801 10989 8661 10759 8471
2 1 0 2 0 0 42 -1 -1 0.000 1 1 -1 0 0 2
4950 6750 7650 5400
2 1 0 2 0 0 40 -1 -1 0.000 1 1 -1 0 0 2
6300 7425 6300 4725
2 1 0 2 0 0 40 -1 -1 4.000 1 1 -1 0 0 2
6300 6975 6750 6750
2 1 0 2 0 0 42 -1 -1 0.000 1 1 -1 0 0 2
6750 6750 6750 5850
2 1 0 2 32 7 44 -1 -1 6.000 1 1 -1 0 0 2
6750 6750 4950 5625
4 0 0 30 -1 22 18 0.0000 4 195 150 10125 9900 Y\001
4 0 0 30 -1 22 18 0.0000 4 195 150 8775 4410 Y\001
4 0 0 30 -1 22 18 0.0000 4 195 135 3375 5130 Z\001
4 0 0 30 -1 22 18 0.0000 4 195 150 10440 6705 X\001
4 0 0 30 -1 22 18 0.0000 4 195 150 11700 7965 X\001
4 1 0 36 -1 22 18 0.0000 4 195 210 6300 4140 W\001
4 1 0 36 -1 22 18 0.0000 4 195 120 6705 7070 1\001
4 0 0 43 -1 22 18 0.0000 4 195 165 6048 5957 C\001
4 0 0 36 -1 22 18 0.0000 4 195 165 8679 8111 O\001
4 0 0 36 -1 23 18 0.4461 4 195 1560 5775 8015 screen window\001
4 0 0 30 -1 23 18 0.4461 4 255 1170 10115 9000 pixel space\001
4 0 0 30 -1 23 18 0.4461 4 255 1605 10155 10845 display window\001
Binary file not shown.

Before

Width:  |  Height:  |  Size: 943 KiB

-120
View File
@@ -1,120 +0,0 @@
#FIG 3.2
Landscape
Center
Metric
A4
60.00
Single
-2
1200 2
0 32 #cdcdcd
6 1575 1575 3150 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
1800 1800 2925 1800 2925 3375 1800 3375 1800 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
1800 3375 2925 3375 2925 4950 1800 4950 1800 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
1800 4950 2925 4950 2925 6525 1800 6525 1800 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
1800 6525 2925 6525 2925 8100 1800 8100 1800 6525
-6
6 2700 1575 4275 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
2925 1800 4050 1800 4050 3375 2925 3375 2925 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
2925 3375 4050 3375 4050 4950 2925 4950 2925 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
2925 4950 4050 4950 4050 6525 2925 6525 2925 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
2925 6525 4050 6525 4050 8100 2925 8100 2925 6525
-6
6 3825 1575 5400 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
4050 1800 5175 1800 5175 3375 4050 3375 4050 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
4050 3375 5175 3375 5175 4950 4050 4950 4050 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
4050 4950 5175 4950 5175 6525 4050 6525 4050 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
4050 6525 5175 6525 5175 8100 4050 8100 4050 6525
-6
6 4950 1575 6525 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
5175 1800 6300 1800 6300 3375 5175 3375 5175 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
5175 3375 6300 3375 6300 4950 5175 4950 5175 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
5175 4950 6300 4950 6300 6525 5175 6525 5175 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
5175 6525 6300 6525 6300 8100 5175 8100 5175 6525
-6
6 6075 1575 7650 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
6300 1800 7425 1800 7425 3375 6300 3375 6300 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
6300 3375 7425 3375 7425 4950 6300 4950 6300 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
6300 4950 7425 4950 7425 6525 6300 6525 6300 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
6300 6525 7425 6525 7425 8100 6300 8100 6300 6525
-6
6 7200 1575 8775 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
7425 1800 8550 1800 8550 3375 7425 3375 7425 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
7425 3375 8550 3375 8550 4950 7425 4950 7425 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
7425 4950 8550 4950 8550 6525 7425 6525 7425 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
7425 6525 8550 6525 8550 8100 7425 8100 7425 6525
-6
6 8325 1575 9900 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
8550 1800 9675 1800 9675 3375 8550 3375 8550 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
8550 3375 9675 3375 9675 4950 8550 4950 8550 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
8550 4950 9675 4950 9675 6525 8550 6525 8550 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
8550 6525 9675 6525 9675 8100 8550 8100 8550 6525
-6
6 9450 1575 11025 8325
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
9675 1800 10800 1800 10800 3375 9675 3375 9675 1800
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
9675 3375 10800 3375 10800 4950 9675 4950 9675 3375
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
9675 4950 10800 4950 10800 6525 9675 6525 9675 4950
2 2 0 2 10 7 47 -1 -1 0.000 0 0 -1 0 0 5
9675 6525 10800 6525 10800 8100 9675 8100 9675 6525
-6
2 5 0 1 0 -1 50 0 -1 0.000 0 0 -1 0 0 5
0 kapaa.png
1800 1800 10260 1800 10260 7560 1800 7560 1800 1800
2 2 1 4 20 7 46 0 -1 10.000 0 0 -1 0 0 5
1800 1800 10260 1800 10260 7560 1800 7560 1800 1800
2 2 0 4 28 7 48 0 -1 0.000 0 0 -1 0 0 5
1800 1800 10260 1800 10260 7560 1800 7560 1800 1800
2 2 0 0 0 32 55 -1 20 0.000 0 0 -1 0 0 5
1800 1800 10800 1800 10800 8100 1800 8100 1800 1800
2 2 0 0 10 32 51 0 20 0.000 0 0 -1 0 0 5
5400 8775 6075 8775 6075 9225 5400 9225 5400 8775
2 2 0 4 28 1 51 0 -1 0.000 0 0 -1 0 0 5
1800 9450 2475 9450 2475 9900 1800 9900 1800 9450
2 2 1 4 20 7 47 0 -1 10.000 0 0 -1 0 0 5
1800 9450 2475 9450 2475 9900 1800 9900 1800 9450
2 2 0 2 10 13 51 0 -1 0.000 0 0 -1 0 0 5
1800 8775 2475 8775 2475 9225 1800 9225 1800 8775
4 0 0 50 0 18 24 0.0000 4 285 750 2790 9090 tiles\001
4 0 0 50 0 18 24 0.0000 4 285 2205 2790 9765 data window\001
4 0 0 50 0 18 24 0.0000 4 360 4635 6390 9090 pixels not stored in the file\001
4 0 10 50 -1 18 20 0.0000 4 270 585 2025 2700 (0,0)\001
4 0 10 50 -1 18 20 0.0000 4 270 585 3150 2700 (1,0)\001
4 0 10 50 -1 18 20 0.0000 4 270 585 4275 2700 (2,0)\001
4 0 10 50 -1 18 20 0.0000 4 270 585 5400 2700 (3,0)\001
4 0 10 50 -1 18 20 0.0000 4 270 585 2025 4275 (0,1)\001
4 0 10 50 -1 18 20 0.0000 4 270 585 3150 4275 (1,1)\001
4 0 10 50 -1 18 20 0.0000 4 270 585 4275 4275 (2,1)\001
4 0 10 50 -1 18 20 0.0000 4 270 585 6525 2700 (4,0)\001
4 0 10 50 -1 18 20 0.0000 4 270 660 2025 5850 (0, 2)\001
4 0 10 50 -1 18 20 0.0000 4 270 660 3150 5850 (1, 2)\001
-55
View File
@@ -1,55 +0,0 @@
#FIG 3.2
Landscape
Center
Metric
A4
60.00
Single
-2
1200 2
0 32 #d0d0d0
2 5 0 1 0 -1 50 0 -1 0.000 0 0 -1 0 0 5
0 still.png
1800 1800 11340 1800 11340 7560 1800 7560 1800 1800
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 2.00 120.00 240.00
2250 1350 2250 8325
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 2.00 120.00 240.00
1350 2250 11925 2250
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
1800 1350 1800 1800
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
1350 1800 1800 1800
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
1350 7560 1800 7560
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
1350 7110 1800 7110
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
10890 1350 10890 1800
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
11340 1350 11340 1800
2 2 0 4 28 1 51 0 -1 0.000 0 0 -1 0 0 5
5175 9000 5850 9000 5850 9450 5175 9450 5175 9000
2 2 0 4 11 1 51 0 -1 0.000 0 0 -1 0 0 5
5175 8325 5850 8325 5850 8775 5175 8775 5175 8325
2 2 0 4 11 7 49 0 -1 0.000 0 0 -1 0 0 5
2250 2250 10890 2250 10890 7110 2250 7110 2250 2250
2 2 0 4 28 7 49 0 -1 0.000 0 0 -1 0 0 5
1800 1800 11340 1800 11340 7560 1800 7560 1800 1800
2 2 1 4 20 7 47 0 -1 10.000 0 0 -1 0 0 5
1800 1800 11340 1800 11340 7560 1800 7560 1800 1800
2 2 1 4 20 7 47 0 -1 10.000 0 0 -1 0 0 5
5175 9000 5850 9000 5850 9450 5175 9450 5175 9000
4 2 0 50 0 18 24 0.0000 4 270 780 1260 7650 1179\001
4 2 0 50 0 18 24 0.0000 4 270 780 1260 7200 1079\001
4 0 0 50 0 18 24 0.0000 4 285 255 2475 8100 Y\001
4 2 0 50 0 18 24 0.0000 4 270 195 1260 2340 0\001
4 2 0 50 0 18 24 0.0000 4 270 705 1260 1890 -100\001
4 2 0 50 0 18 24 0.0000 4 270 705 1800 1260 -100\001
4 0 0 50 0 18 24 0.0000 4 270 195 2250 1260 0\001
4 2 0 50 0 18 24 0.0000 4 270 780 10890 1260 1919\001
4 0 0 50 0 18 24 0.0000 4 270 780 11340 1260 2019\001
4 0 0 50 0 18 24 0.0000 4 285 270 11700 2700 X\001
4 0 0 50 0 18 24 0.0000 4 360 2715 6165 8640 display window\001
4 0 0 50 0 18 24 0.0000 4 285 2205 6165 9315 data window\001
-57
View File
@@ -1,57 +0,0 @@
#FIG 3.2
Landscape
Center
Metric
A4
60.00
Single
-2
1200 2
0 32 #d0d0d0
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 2.00 120.00 240.00
2250 1800 2250 8325
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 1 0 2
1 1 2.00 120.00 240.00
1800 2250 11925 2250
2 5 0 1 0 -1 50 0 -1 0.000 0 0 -1 0 0 5
0 blobs.png
6750 4050 8550 4050 8550 5850 6750 5850 6750 4050
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
10890 1800 10890 2250
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
1800 7110 2250 7110
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
6300 4050 6750 4050
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
6750 3600 6750 4050
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
8550 3600 8550 4050
2 1 0 2 0 7 50 0 -1 0.000 0 0 -1 0 0 2
6300 5850 6750 5850
2 2 0 4 11 1 51 0 -1 0.000 0 0 -1 0 0 5
5175 7875 5850 7875 5850 8325 5175 8325 5175 7875
2 2 0 4 28 1 51 0 -1 0.000 0 0 -1 0 0 5
5175 8550 5850 8550 5850 9000 5175 9000 5175 8550
2 2 0 4 28 1 49 0 -1 0.000 0 0 -1 0 0 5
6750 4050 8550 4050 8550 5850 6750 5850 6750 4050
2 2 0 4 11 7 49 0 -1 0.000 0 0 -1 0 0 5
2250 2250 10890 2250 10890 7110 2250 7110 2250 2250
2 2 0 0 0 32 52 0 20 0.000 0 0 -1 0 0 5
2250 2250 10890 2250 10890 7110 2250 7110 2250 2250
2 2 1 4 20 7 47 0 -1 10.000 0 0 -1 0 0 5
6750 4050 8550 4050 8550 5850 6750 5850 6750 4050
2 2 1 4 20 7 47 0 -1 10.000 0 0 -1 0 0 5
5175 8550 5850 8550 5850 9000 5175 9000 5175 8550
4 0 0 50 0 18 24 0.0000 4 285 2205 6165 8865 data window\001
4 0 0 50 0 18 24 0.0000 4 360 2715 6165 8190 display window\001
4 2 0 50 0 18 24 0.0000 4 270 780 1710 7200 1079\001
4 0 0 50 0 18 24 0.0000 4 285 255 2475 8100 Y\001
4 0 0 50 0 18 24 0.0000 4 285 270 11700 2700 X\001
4 1 0 50 0 18 24 0.0000 4 270 780 10890 1710 1919\001
4 2 0 50 0 18 24 0.0000 4 270 195 1710 2340 0\001
4 1 0 50 0 18 24 0.0000 4 270 195 2250 1710 0\001
4 2 0 50 0 18 24 0.0000 4 270 585 6210 5940 800\001
4 2 0 50 0 18 24 0.0000 4 270 585 6210 4140 400\001
4 1 0 50 0 18 24 0.0000 4 270 780 6750 3510 1000\001
4 1 0 50 0 18 24 0.0000 4 270 780 8550 3510 1400\001
-55
View File
@@ -1,55 +0,0 @@
void
readGZ1 (
const char fileName[],
Array2D<half>& rPixels,
Array2D<half>& gPixels,
Array2D<float>& zPixels,
int& width,
int& height)
{
InputFile file (fileName);
Box2i dw = file.header ().dataWindow ();
width = dw.max.x - dw.min.x + 1;
height = dw.max.y - dw.min.y + 1;
rPixels.resizeErase (height, width);
gPixels.resizeErase (height, width);
zPixels.resizeErase (height, width);
FrameBuffer frameBuffer;
frameBuffer.insert ("R", // name
Slice (HALF, // type
(char *) (&rPixels[0][0] - // base
dw.min.x -
dw.min.y * width),
sizeof (rPixels[0][0]) * 1, // xStride
sizeof (rPixels[0][0]) * width, // yStride
1, 1, // x/y sampling
0.0)); // fillValue
frameBuffer.insert ("G", // name
Slice (HALF, // type
(char *) (&gPixels[0][0] - // base
dw.min.x -
dw.min.y * width),
sizeof (gPixels[0][0]) * 1, // xStride
sizeof (gPixels[0][0]) * width, // yStride
1, 1, // x/y sampling
0.0)); // fillValue
frameBuffer.insert ("Z", // name
Slice (FLOAT, // type
(char *) (&zPixels[0][0] - // base
dw.min.x -
dw.min.y * width),
sizeof (zPixels[0][0]) * 1, // xStride
sizeof (zPixels[0][0]) * width, // yStride
1, 1, // x/y sampling
FLT_MAX)); // fillValue
file.setFrameBuffer (frameBuffer);
file.readPixels (dw.min.y, dw.max.y);
}
-31
View File
@@ -1,31 +0,0 @@
void
makePreviewImage (
const Array2D<Rgba>& pixels,
int width,
int height,
Array2D<PreviewRgba>& previewPixels,
int& previewWidth,
int& previewHeight)
{
const int N = 8;
previewWidth = width / N;
previewHeight = height / N;
previewPixels.resizeErase (previewHeight, previewWidth);
for (int y = 0; y < previewHeight; ++y)
{
for (int x = 0; x < previewWidth; ++x)
{
const Rgba& inPixel = pixels[y * N][x * N];
PreviewRgba& outPixel = previewPixels[y][x];
outPixel.r = gamma (inPixel.r);
outPixel.g = gamma (inPixel.g);
outPixel.b = gamma (inPixel.b);
outPixel.a = int (clamp (inPixel.a * 255.f, 0.f, 255.f) + 0.5f);
}
}
}
-16
View File
@@ -1,16 +0,0 @@
void
readHeader (const char fileName[])
{
RgbaInputFile file (fileName);
const StringAttribute* comments =
file.header ().findTypedAttribute<StringAttribute> ("comments");
const M44fAttribute* cameraTransform =
file.header ().findTypedAttribute<M44fAttribute> ("cameraTransform");
if (comments) cout << "commentsn " << comments->value () << endl;
if (cameraTransform)
cout << "cameraTransformn" << cameraTransform->value () << flush;
}
-3
View File
@@ -1,3 +0,0 @@
$ mkdir _build
$ cmake -S . -B _build
$ cmake --build _build
-7
View File
@@ -1,7 +0,0 @@
void
writeRgba1 (const char fileName[], const Rgba* pixels, int width, int height)
{
RgbaOutputFile file (fileName, width, height, WRITE_RGBA); // 1
file.setFrameBuffer (pixels, 1, width); // 2
file.writePixels (height); // 3
}
-13
View File
@@ -1,13 +0,0 @@
void
writeRgba2 (
const char fileName[],
const Rgba* pixels,
int width,
int height,
const Box2i& dataWindow)
{
Box2i displayWindow (V2i (0, 0), V2i (width - 1, height - 1));
RgbaOutputFile file (fileName, displayWindow, dataWindow, WRITE_RGBA);
file.setFrameBuffer (pixels, 1, width);
file.writePixels (dataWindow.max.y - dataWindow.min.y + 1);
}
-3
View File
@@ -1,3 +0,0 @@
$ mkdir _build
$ cmake -S . -B _build
$ cmake --build _build
+66
View File
@@ -0,0 +1,66 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
[build-system]
requires = ["scikit-build-core==0.8.1"]
build-backend = "scikit_build_core.build"
[project]
name = "OpenEXR"
dynamic = ["version"]
description="Python bindings for the OpenEXR image file format"
readme = "src/wrappers/python/README.md"
authors = [
{ name="Contributors to the OpenEXR project", email="info@openexr.com" },
]
requires-python = ">=3.7"
[project.urls]
"Homepage" = "https://openexr.com"
"Source" = "https://github.com/AcademySoftwareFoundation/OpenEXR"
"Bug Tracker" = "https://github.com/AcademySoftwareFoundation/OpenEXR/issues"
[project.optional-dependencies]
test = ["pytest"]
[tool.scikit-build]
wheel.expand-macos-universal-tags = true
sdist.exclude = [".github", "src/test", "src/examples", "website", "ASWF", "bazel", "share"]
# Only build the PyOpenEXR (cmake --build --target PyOpenEXR).
cmake.targets = ["PyOpenEXR"]
# Only install the "python" component (cmake --install --component python).
# This makes sure that only files marked as "python" component are installed.
install.components = ["python"]
# Enable experimental features if any are available
# In this case we need custom local plugin to get
# the project version from cmake.
experimental = true
metadata.version.provider = "openexr_skbuild_plugin"
metadata.version.provider-path = "./src/wrappers/python"
[tool.scikit-build.cmake.define]
OPENEXR_INSTALL = 'OFF'
OPENEXR_BUILD_PYTHON = 'ON'
OPENEXR_BUILD_EXAMPLES = 'OFF'
OPENEXR_BUILD_TOOLS = 'OFF'
OPENEXR_INSTALL_TOOLS = 'OFF'
OPENEXR_INSTALL_PKG_CONFIG = 'OFF'
OPENEXR_FORCE_INTERNAL_DEFLATE = 'ON'
OPENEXR_FORCE_INTERNAL_IMATH = 'ON'
OPENEXR_TEST_LIBRARIES = 'OFF'
BUILD_SHARED_LIBS = 'OFF'
CMAKE_POSITION_INDEPENDENT_CODE = 'ON'
[tool.cibuildwheel]
test-command = "ctest -R PyOpenEXR"
test-extras = ["test"]
test-skip = ["*universal2:arm64"]
build-verbosity = 1
manylinux-x86_64-image = "manylinux2014"
manylinux-i686-image = "manylinux2014"
manylinux-aarch64-image = "manylinux2014"
@@ -1,5 +1,8 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
set -ex
VALGRIND_VERSION="3.15.0"
+3
View File
@@ -1,5 +1,8 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
set -ex
LOGDIR="$1"
+31 -11
View File
@@ -1,5 +1,8 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
#
# Validate the library symlinks:
# * The actual elf binary is, e.g. libIlmThread-3_1.so.29.0.0
@@ -18,26 +21,34 @@ if [[ $# == "0" ]]; then
exit -1
fi
set -x
BUILD_ROOT=$1
SRC_ROOT=$2
# Locate OpenEXR.pc and set PKG_CONFIG_PATH accordingly
pkgconfig=$(find $BUILD_ROOT -name OpenEXR.pc)
pkgconfig=$(find $BUILD_ROOT -name OpenEXR.pc | head -1)
if [[ "$pkgconfig" == "" ]]; then
echo "Can't find OpenEXR.pc"
exit -1
fi
cat $pkgconfig
export PKG_CONFIG_PATH=$(dirname $pkgconfig)
# Build the validation program
CXX_FLAGS=$(pkg-config OpenEXR --cflags)
LD_FLAGS=$(pkg-config OpenEXR --libs --static)
CXX_FLAGS=$(env PKG_CONFIG_PATH=$PKG_CONFIG_PATH pkg-config OpenEXR --cflags)
LD_FLAGS=$(env PKG_CONFIG_PATH=$PKG_CONFIG_PATH pkg-config OpenEXR --libs --static)
VALIDATE_CPP=$(mktemp --tmpdir "validate_XXX.cpp")
VALIDATE_BIN=$(mktemp --tmpdir "validate_XXX")
trap "rm -rf $VALIDATE_CPP $VALIDATE_BIN" exit
VALIDATE_CPP=$(mktemp --tmpdir "validate_cpp_XXX.cpp")
VALIDATE_BIN=$(mktemp --tmpdir "validate_bin_XXX")
VALIDATE_BUILD=$(mktemp -d --tmpdir "validate_build_XXX")
trap "rm -rf $VALIDATE_CPP $VALIDATE_BIN $VALIDATE_BUILD" exit
echo -e '#include <ImfHeader.h>\n#include <OpenEXRConfig.h>\n#include <stdio.h>\nint main() { puts(OPENEXR_PACKAGE_STRING); Imf::Header h; return 0; }' > $VALIDATE_CPP
@@ -45,7 +56,7 @@ g++ $CXX_FLAGS $VALIDATE_CPP -o $VALIDATE_BIN $LD_FLAGS
# Execute the program
LIB_DIR=$(pkg-config OpenEXR --variable=libdir)
LIB_DIR=$(env PKG_CONFIG_PATH=$PKG_CONFIG_PATH pkg-config OpenEXR --variable=libdir)
export LD_LIBRARY_PATH=$LIB_DIR
validate=`$VALIDATE_BIN`
@@ -59,7 +70,7 @@ if [[ "$status" != "0" ]]; then
fi
# Get the suffix, e.g. -2_5_d, and determine if there's also a _d
libsuffix=$(pkg-config OpenEXR --variable=libsuffix)
libsuffix=$(env PKG_CONFIG_PATH=$PKG_CONFIG_PATH pkg-config OpenEXR --variable=libsuffix)
if [[ $libsuffix != $(basename ./$libsuffix _d) ]]; then
_d="_d"
else
@@ -67,7 +78,7 @@ else
fi
# Validate each of the libs
libs=$(pkg-config OpenEXR --libs-only-l | sed -e s/-l//g)
libs=$(env PKG_CONFIG_PATH=$PKG_CONFIG_PATH pkg-config OpenEXR --libs-only-l | sed -e s/-l//g)
for lib in $libs; do
base=$(echo $lib | cut -d- -f1)
@@ -102,7 +113,7 @@ if [[ "$?" == "0" ]]; then
fi
if [[ "$SRC_ROOT" != "" ]]; then
version=$(pkg-config OpenEXR --modversion)
version=$(env PKG_CONFIG_PATH=$PKG_CONFIG_PATH pkg-config OpenEXR --modversion)
notes=$(grep "\* \[Version $version\]" $SRC_ROOT/CHANGES.md | head -1)
if [[ "$notes" == "" ]]; then
echo "No release notes."
@@ -110,5 +121,14 @@ if [[ "$SRC_ROOT" != "" ]]; then
echo "Release notes: $notes"
fi
fi
# Confirm that the example programs build, link, and run
cd $VALIDATE_BUILD
cmake -DCMAKE_PREFIX_PATH=$BUILD_ROOT $SRC_ROOT/src/examples
cmake --build .
./bin/OpenEXRExamples
echo "ok."
@@ -1,10 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenColorIO Project.
set -ex
HERE=$(dirname $0)
bash $HERE/install_doxygen.sh latest
pip3 install -r $HERE/../../../../../docs/requirements.txt
@@ -1,13 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenColorIO Project.
set -ex
DOXYGEN_VERSION="$1"
if [ "$DOXYGEN_VERSION" == "latest" ]; then
yum install -y doxygen
else
yum install -y doxygen-${DOXYGEN_VERSION}
fi
+109
View File
@@ -0,0 +1,109 @@
#! /bin/bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
buildtype=Debug
cflags="-ggdb3 -Og"
lib_names=(Iex IlmThread OpenEXRCore OpenEXR OpenEXRUtil)
libver_old=v3.1.7
sonames_old=(libIex-3_1_d.so.30.7.1 libIlmThread-3_1_d.so.30.7.1 libOpenEXRCore-3_1_d.so.30.7.1 libOpenEXRUtil-3_1_d.so.30.7.1 libOpenEXR-3_1_d.so.30.7.1)
libver_new=RB-3.1
sonames_new=(libIex-3_1_d.so.30.8.1 libIlmThread-3_1_d.so.30.8.1 libOpenEXRCore-3_1_d.so.30.8.1 libOpenEXRUtil-3_1_d.so.30.8.1 libOpenEXR-3_1_d.so.30.8.1)
srcdir=`pwd`
if [[ "$1" == distclean ]]; then
rm -rf abi_check
fi
mkdir -p abi_check
export PATH=${srcdir}/abi_check/bin:${PATH}
cd abi_check
if [[ ! -e bin/vtable-dumper ]]; then
mkdir -p src
cd src
git clone https://github.com/lvc/vtable-dumper
cd vtable-dumper
make
make install prefix=${srcdir}/abi_check
cd ${srcdir}/abi_check
fi
if [[ ! -e bin/abi-dumper ]]; then
mkdir -p src
cd src
git clone https://github.com/lvc/abi-dumper
cd abi-dumper
perl Makefile.pl -install --prefix=${srcdir}/abi_check
cd ${srcdir}/abi_check
fi
if [[ ! -e bin/abi-compliance-checker ]]; then
mkdir -p src
cd src
git clone https://github.com/lvc/abi-compliance-checker
cd abi-compliance-checker
perl Makefile.pl -install --prefix=${srcdir}/abi_check
cd ${srcdir}/abi_check
fi
builddir_v1=build.${libver_old}
builddir_v2=build.${libver_new}
instdir_v1=inst.${libver_old}
instdir_v2=inst.${libver_new}
if [[ "$1" == clean ]]; then
rm -rf ${builddir_v1}
rm -rf ${builddir_v2}
rm -rf ${instdir_v1}
rm -rf ${instdir_v2}
rm -rf abidumps
fi
curhash=`git branch --show-current`
if [[ "${curhash}" == "" ]]; then
curhash=`git rev-parse HEAD`
fi
if [[ ! -e ${instdir_v1} ]]; then
rm -rf ${builddir_v1}
git checkout ${libver_old} || exit 1
cmake -B ${builddir_v1} -S ${srcdir} -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=OFF -DCMAKE_C_FLAGS="${cflags}" -DCMAKE_CXX_FLAGS="${cflags}" -DCMAKE_INSTALL_PREFIX=${srcdir}/abi_check/${instdir_v1} || exit 1
ninja -C ${builddir_v1} install || exit 1
git checkout ${curhash}
fi
if [[ ! -e ${instdir_v2} ]]; then
rm -rf ${builddir_v2}
git checkout ${libver_new} || exit 1
cmake -B ${builddir_v2} -S ${srcdir} -G Ninja -DCMAKE_BUILD_TYPE=Debug -DBUILD_TESTING=OFF -DCMAKE_C_FLAGS="${cflags}" -DCMAKE_CXX_FLAGS="${cflags}" -DCMAKE_INSTALL_PREFIX=${srcdir}/abi_check/${instdir_v2} || exit 1
ninja -C ${builddir_v2} install || exit 1
git checkout ${curhash}
fi
len=${#lib_names[@]}
mkdir -p abidumps/${libver_old}
mkdir -p abidumps/${libver_new}
for (( i=0; i<$len; i++ ));
do
name=${lib_names[$i]}
echo "Processing ${name}"
abi-dumper ${instdir_v1}/lib/${sonames_old[$i]} -o abidumps/${libver_old}/ABI-${name}.dump -vnum ${libver_old} -skip-cxx -all-symbols
abi-dumper ${instdir_v2}/lib/${sonames_new[$i]} -o abidumps/${libver_new}/ABI-${name}.dump -vnum ${libver_new} -skip-cxx -all-symbols
abi-compliance-checker -l ${name} -d1 abidumps/${libver_old}/ABI-${name}.dump -v1 ${libver_old} -d2 abidumps/${libver_new}/ABI-${name}.dump -v2 ${libver_new}
done
echo "Reports should be at:"
for (( i=0; i<$len; i++ ));
do
name=${lib_names[$i]}
echo "${name}: file://${srcdir}/abi_check/compat_reports/${name}/${libver_old}_to_${libver_new}/compat_report.html"
done
+100
View File
@@ -0,0 +1,100 @@
#! /bin/bash
# SPDX-License-Identifier: BSD-3-Clause
# Copyright Contributors to the OpenEXR Project.
# This script can be used to generate a local test coverage report
# using the clang / llvm toolset for doing so
# It should hopefully be obvious how to adjust, but should work
# on most linux distros
buildtype=Debug
builddir=build.coverage
haveninja=`which ninja`
#imathoverride="-DOPENEXR_FORCE_INTERNAL_IMATH=ON -DIMATH_REPO=/home/user/Development/Imath"
# also turn on most of the warnings because we should look at that
# as well...
cwarns="-fstack-protector-all -Weverything -Wno-reserved-identifier -Wno-covered-switch-default -Wno-cast-align -Wno-overlength-strings -fprofile-arcs -fprofile-instr-generate -fcoverage-mapping"
cxxwarns="-fstack-protector-all -Wno-sign-conversion -Wno-float-equal -Wno-padded -Wno-zero-as-null-pointer-constant -Wno-old-style-cast -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-missing-braces -fprofile-instr-generate -fcoverage-mapping"
genargs=""
if [[ "$haveninja" != "" ]]; then
genargs="-G Ninja"
fi
if [[ ! -e "${builddir}" ]]; then
export CC=/usr/bin/clang
export CXX=/usr/bin/clang++
cmake -B ${builddir} -S . ${genargs} ${imathoverride} -DCMAKE_C_FLAGS="${cwarns}" -DCMAKE_CXX_FLAGS="${cxxwarns}" -DCMAKE_BUILD_TYPE=${buildtype} || exit 1
fi
if [[ "$haveninja" != "" ]]; then
ninja -C ${builddir} || exit 1
else
nproc=`cat /proc/cpuinfo|grep processor|wc -l`
make -j${nproc} -C ${builddir} || exit 1
fi
# archive previous runs????
rm -rf coverage
/usr/bin/env LLVM_PROFILE_FILE=coverage/core.profraw build.coverage/bin/OpenEXRCoreTest || exit 1
/usr/bin/env LLVM_PROFILE_FILE=coverage/exr.profraw build.coverage/bin/OpenEXRTest || exit 1
/usr/bin/env LLVM_PROFILE_FILE=coverage/util.profraw build.coverage/bin/OpenEXRUtilTest || exit 1
llvm-profdata merge -sparse -o coverage/exr.profdata coverage/core.profraw coverage/exr.profraw coverage/util.profraw
llvm-cov show \
build.coverage/bin/OpenEXRCoreTest \
-object build.coverage/src/lib/OpenEXRCore/libOpenEXRCore-3_2_d.so \
-instr-profile=coverage/exr.profdata \
-show-regions \
-show-expansions \
--output-dir=coverage/core_only \
--format="html" \
-ignore-filename-regex='src/test/.*' \
-ignore-filename-regex='build.coverage/.*' \
-ignore-filename-regex='src/lib/OpenEXR/Imf*'
llvm-cov show \
build.coverage/bin/OpenEXRTest \
-object build.coverage/src/lib/OpenEXR/libOpenEXR-3_2_d.so \
-instr-profile=coverage/exr.profdata \
-show-regions \
-show-expansions \
--output-dir=coverage/exr_only \
--format="html" \
-ignore-filename-regex='src/test/.*' \
-ignore-filename-regex='build.coverage/.*' \
-ignore-filename-regex='src/lib/OpenEXRCore/*'
llvm-cov show \
build.coverage/bin/OpenEXRUtilTest \
-object build.coverage/src/lib/OpenEXRUtil/libOpenEXRUtil-3_2_d.so \
-instr-profile=coverage/exr.profdata \
-show-regions \
-show-expansions \
--output-dir=coverage/util_only \
--format="html" \
-ignore-filename-regex='src/test/.*' \
-ignore-filename-regex='build.coverage/.*' \
-ignore-filename-regex='src/lib/OpenEXR/Imf*' \
-ignore-filename-regex='src/lib/OpenEXRCore/*'
llvm-cov show \
build.coverage/bin/OpenEXRCoreTest \
-object build.coverage/bin/OpenEXRTest \
-object build.coverage/bin/OpenEXRUtilTest \
-object build.coverage/src/lib/OpenEXRCore/libOpenEXRCore-3_2_d.so \
-object build.coverage/src/lib/OpenEXR/libOpenEXR-3_2_d.so \
-object build.coverage/src/lib/OpenEXRUtil/libOpenEXRUtil-3_2_d.so \
-instr-profile=coverage/exr.profdata \
-show-regions \
-show-expansions \
--output-dir=coverage/combined \
--format="html" \
-ignore-filename-regex='src/test/.*' \
-ignore-filename-regex='build.coverage/.*'
-224
View File
@@ -1,224 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?fileVersion 4.0.0?>
<cproject storage_type_id="org.eclipse.cdt.core.XmlProjectDescriptionStorage">
<storageModule moduleId="org.eclipse.cdt.core.settings">
<cconfiguration id="0.1157538972">
<storageModule buildSystemId="org.eclipse.cdt.managedbuilder.core.configurationDataProvider" id="0.1157538972" moduleId="org.eclipse.cdt.core.settings" name="Default">
<externalSettings/>
<extensions>
<extension id="org.eclipse.cdt.core.VCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GmakeErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.CWDLocator" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GCCErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GASErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
<extension id="org.eclipse.cdt.core.GLDErrorParser" point="org.eclipse.cdt.core.ErrorParser"/>
</extensions>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<configuration artifactName="${ProjName}" buildProperties="" description="" id="0.1157538972" name="Default" parent="org.eclipse.cdt.build.core.prefbase.cfg">
<folderInfo id="0.1157538972." name="/" resourcePath="">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1097826404" name="No ToolChain" resourceTypeBasedDiscovery="false" superClass="org.eclipse.cdt.build.core.prefbase.toolchain">
<targetPlatform id="org.eclipse.cdt.build.core.prefbase.toolchain.1097826404.578956434" name=""/>
<builder id="org.eclipse.cdt.build.core.settings.default.builder.1380660793" keepEnvironmentInBuildfile="false" managedBuildOn="false" name="Gnu Make Builder" parallelBuildOn="true" parallelizationNumber="3" superClass="org.eclipse.cdt.build.core.settings.default.builder"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.140385122" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.1295772254" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1142602772" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.902892435" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.515112128" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1755992095" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1394057810" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
</configuration>
</storageModule>
<storageModule moduleId="scannerConfiguration">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<scannerConfigBuildInfo instanceId="0.1157538972">
<autodiscovery enabled="true" problemReportingEnabled="true" selectedProfileId=""/>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.make.core.GCCStandardMakePerFileProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="makefileGenerator">
<runAction arguments="-E -P -v -dD" command="" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/${specs_file}" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.cpp" command="g++" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-E -P -v -dD ${plugin_state_location}/specs.c" command="gcc" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfile">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/${specs_file}&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileCPP">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'g++ -E -P -v -dD &quot;${plugin_state_location}/specs.cpp&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
<profile id="org.eclipse.cdt.managedbuilder.core.GCCWinManagedMakePerProjectProfileC">
<buildOutputProvider>
<openAction enabled="true" filePath=""/>
<parser enabled="true"/>
</buildOutputProvider>
<scannerInfoProvider id="specsFile">
<runAction arguments="-c 'gcc -E -P -v -dD &quot;${plugin_state_location}/specs.c&quot;'" command="sh" useDefault="true"/>
<parser enabled="true"/>
</scannerInfoProvider>
</profile>
</scannerConfigBuildInfo>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.core.externalSettings"/>
<storageModule moduleId="org.eclipse.cdt.core.language.mapping"/>
<storageModule moduleId="org.eclipse.cdt.make.core.buildtargets">
<buildTargets>
<target name="IlmImfTest" path="IlmImfTest" targetID="org.eclipse.cdt.build.MakeTargetBuilder">
<buildCommand>make</buildCommand>
<buildArguments/>
<buildTarget>IlmImfTest</buildTarget>
<stopOnError>true</stopOnError>
<useDefaultCommand>true</useDefaultCommand>
<runAllBuilders>true</runAllBuilders>
</target>
</buildTargets>
</storageModule>
<storageModule moduleId="org.eclipse.cdt.internal.ui.text.commentOwnerProjectMappings"/>
</cconfiguration>
</storageModule>
<storageModule moduleId="cdtBuildSystem" version="4.0.0">
<project id="openexr.null.1533970790" name="openexr"/>
</storageModule>
</cproject>
-28
View File
@@ -1,28 +0,0 @@
IlmImf/b44ExpLogTable
IlmImf/dwaLookups
OpenEXR.pc
autom4te.cache/
config.guess
config.log
config.status
config.sub
config/OpenEXRConfig.h
config/stamp-h1
configure
depcomp
exr2aces/exr2aces
exrbuild/exrbuild
exrenvmap/exrenvmap
exrbuild/exrbuild
exrheader/exrheader
exrmakepreview/exrmakepreview
exrmaketiled/exrmaketiled
exrmultipart/exrmultipart
exrmultiview/exrmultiview
exrstdattr/exrstdattr
install-sh
libtool
ltmain.sh
missing
.metadata/
-79
View File
@@ -1,79 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>openexr</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.genmakebuilder</name>
<triggers>clean,full,incremental,</triggers>
<arguments>
<dictionary>
<key>?name?</key>
<value></value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.append_environment</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.autoBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildArguments</key>
<value>-j3</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.buildCommand</key>
<value>make</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.cleanBuildTarget</key>
<value>clean</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.contents</key>
<value>org.eclipse.cdt.make.core.activeConfigSettings</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableAutoBuild</key>
<value>false</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableCleanBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.enableFullBuild</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.fullBuildTarget</key>
<value>all</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.stopOnError</key>
<value>true</value>
</dictionary>
<dictionary>
<key>org.eclipse.cdt.make.core.useDefaultBuildCmd</key>
<value>true</value>
</dictionary>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.cdt.managedbuilder.core.ScannerConfigBuilder</name>
<triggers>full,incremental,</triggers>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.cdt.core.cnature</nature>
<nature>org.eclipse.cdt.core.ccnature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.managedBuildNature</nature>
<nature>org.eclipse.cdt.managedbuilder.core.ScannerConfigNature</nature>
</natures>
</projectDescription>
+17 -15
View File
@@ -1,18 +1,20 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
##########################
# Binaries / Utilities
##########################
if(OPENEXR_BUILD_TOOLS)
add_subdirectory( exr2aces )
add_subdirectory( exrheader )
add_subdirectory( exrinfo )
add_subdirectory( exrmaketiled )
add_subdirectory( exrstdattr )
add_subdirectory( exrmakepreview )
add_subdirectory( exrenvmap )
add_subdirectory( exrmultiview )
add_subdirectory( exrmultipart )
add_subdirectory( exrcheck )
endif()
##################
# Binaries / Tools
##################
message(STATUS "Building OpenEXR tools")
add_subdirectory( exr2aces )
add_subdirectory( exrheader )
add_subdirectory( exrinfo )
add_subdirectory( exrmaketiled )
add_subdirectory( exrstdattr )
add_subdirectory( exrmakepreview )
add_subdirectory( exrenvmap )
add_subdirectory( exrmultiview )
add_subdirectory( exrmultipart )
add_subdirectory( exrcheck )
add_subdirectory( exrmanifest )
+60 -44
View File
@@ -13,6 +13,8 @@
#include <ImfAcesFile.h>
#include <ImfArray.h>
#include <ImfRgbaFile.h>
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <exception>
#include <iostream>
#include <stdlib.h>
@@ -28,44 +30,38 @@ namespace
{
void
usageMessage (const char argv0[], bool verbose = false)
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: " << argv0 << " [options] infile outfile" << endl;
stream << "Usage: " << program_name << " [options] infile outfile" << endl;
if (verbose)
{
cerr << "\n"
"Reads an OpenEXR file from infile and saves the contents\n"
"in ACES image file outfile.\n"
"\n"
"The ACES image file format is a subset of the OpenEXR file\n"
"format. ACES image files are restricted as follows:\n"
"\n"
"* Images are stored as scanlines; tiles are not allowed.\n"
"\n"
"* Images contain three color channels, either\n"
" R, G, B (red, green, blue) or\n"
" Y, RY, BY (luminance, sub-sampled chroma)\n"
"\n"
"* Images may optionally contain an alpha channel.\n"
"\n"
"* Only three compression types are allowed:\n"
" NO_COMPRESSION (file is not compressed)\n"
" PIZ_COMPRESSION (lossless)\n"
" B44A_COMPRESSION (lossy)\n"
"* The \"chromaticities\" header attribute must specify\n"
" the ACES RGB primaries and white point.\n"
"\n"
"Options:\n"
"\n"
"-v verbose mode\n"
"\n"
"-h prints this message\n";
cerr << endl;
}
exit (1);
stream << "\n"
"Read an OpenEXR file from infile and save the contents\n"
"in ACES image file outfile.\n"
"\n"
"The ACES image file format is a subset of the OpenEXR file\n"
"format. ACES image files are restricted as follows:\n"
"\n"
" * Images are stored as scanlines; tiles are not allowed.\n"
" * Images contain three color channels, either:\n"
" R, G, B (red, green, blue)\n"
" or:\n"
" Y, RY, BY (luminance, sub-sampled chroma)\n"
" * Images may optionally contain an alpha channel.\n"
" * Only three compression types are allowed:\n"
" NO_COMPRESSION (file is not compressed)\n"
" PIZ_COMPRESSION (lossless)\n"
" B44A_COMPRESSION (lossy)\n"
" * The \"chromaticities\" header attribute must specify\n"
" the ACES RGB primaries and white point.\n"
"\n"
"Options:\n"
" -v, --verbose verbose mode\n"
" -h, --help print this message\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
void
@@ -128,7 +124,11 @@ main (int argc, char** argv)
// Parse the command line.
//
if (argc < 2) usageMessage (argv[0], true);
if (argc < 2)
{
usageMessage (cerr, argv[0], false);
return -1;
}
int i = 1;
@@ -143,13 +143,27 @@ main (int argc, char** argv)
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h"))
else if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
//
// Print help message
//
usageMessage (argv[0], true);
usageMessage (cout, "exr2aces", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exr2aces (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
else
{
@@ -166,23 +180,25 @@ main (int argc, char** argv)
}
}
if (inFile == 0 || outFile == 0) usageMessage (argv[0]);
if (inFile == 0 || outFile == 0)
{
usageMessage (cerr, argv[0], false);
return -1;
}
//
// Load inFile, and save a tiled version in outFile.
//
int exitStatus = 0;
try
{
exr2aces (inFile, outFile, verbose);
}
catch (const exception& e)
{
cerr << e.what () << endl;
exitStatus = 1;
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
return exitStatus;
return 0;
}
-524
View File
@@ -1,524 +0,0 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Weta Digital, Ltd and Contributors to the OpenEXR Project.
//
#include <ImfChannelList.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfDeepScanLineInputPart.h>
#include <ImfDeepScanLineOutputPart.h>
#include <ImfInputPart.h>
#include <ImfMultiPartInputFile.h>
#include <ImfMultiPartOutputFile.h>
#include <ImfMultiView.h>
#include <ImfOutputPart.h>
#include <ImfPartType.h>
#include <ImfStandardAttributes.h>
#include <ImfStringAttribute.h>
#include <ImfTiledInputPart.h>
#include <ImfTiledOutputPart.h>
#include <iostream>
#include <stdlib.h>
#include <vector>
#include <OpenEXRConfig.h>
using namespace OPENEXR_IMF_NAMESPACE;
//
// constructs new EXRs from parts of others
// this code is deliberately inefficient - it decompresses
// and recompresses the file
//
//
using std::cerr;
using std::endl;
using std::max;
using std::min;
using std::ostringstream;
using std::set;
using std::string;
using std::vector;
void
copy_tiledimage (
MultiPartInputFile& input,
MultiPartOutputFile& output,
int inPart,
int outPart,
const std::string& inview = std::string (""))
{
int buffer_size;
FrameBuffer inFrameBuffer;
FrameBuffer outFrameBuffer;
TiledInputPart in (input, inPart);
TiledOutputPart out (output, outPart);
const Header& inhdr = input.header (inPart);
int channels = 0;
for (ChannelList::ConstIterator i = inhdr.channels ().begin ();
i != inhdr.channels ().end ();
++i)
++channels;
int x_levels = 0;
int y_levels = 0;
TileDescription t = inhdr.tileDescription ();
StringVector views;
if (hasMultiView (inhdr)) { views = multiView (inhdr); }
switch (t.mode)
{
case ONE_LEVEL:
x_levels = 1;
y_levels = 1;
break;
case MIPMAP_LEVELS:
x_levels = t.xSize;
y_levels = 1;
break;
case RIPMAP_LEVELS: x_levels = t.xSize; y_levels = t.ySize;
}
for (int x_level = 0; x_level < x_levels; x_level++)
{
for (int y_level = 0; y_level < y_levels; y_level++)
{
int actual_y_level = t.mode == RIPMAP_LEVELS ? y_level : x_level;
IMATH_NAMESPACE::Box2i dw =
in.dataWindowForLevel (x_level, actual_y_level);
int width = dw.max.x - dw.min.x + 1;
int height = dw.max.y - dw.min.y + 1;
int y = dw.min.y;
int x = dw.min.x;
// allocate at least enough memory to handle the data
// (biggest data is four bytes)
// we store the channels separately, one after the other
buffer_size = 4 * width * height * channels;
char* channelbuf = new char[buffer_size];
// pointer to where we put the first byte
char* bufptr = channelbuf;
for (ChannelList::ConstIterator i = inhdr.channels ().begin ();
i != inhdr.channels ().end ();
++i)
{
if (inview == "" || views.size () == 0 ||
viewFromChannelName (i.name (), views) == inview)
{
inFrameBuffer.insert (
i.name (),
Slice (
i.channel ().type,
bufptr - (y * width + x) * 4,
4,
width * 4));
outFrameBuffer.insert (
removeViewName (i.name (), inview),
Slice (
i.channel ().type,
bufptr - (y * width + x) * 4,
4,
width * 4));
bufptr += width * height * 4;
}
}
in.setFrameBuffer (inFrameBuffer);
out.setFrameBuffer (outFrameBuffer);
//
// copy tiles for level
//
for (int tileY = 0; tileY < out.numYTiles (actual_y_level); ++tileY)
for (int tileX = 0; tileX < out.numXTiles (x_level); ++tileX)
{
memset (channelbuf, 20, width * height * channels * 4);
in.readTile (tileX, tileY, x_level, actual_y_level);
out.writeTile (tileX, tileY, x_level, actual_y_level);
}
delete[] channelbuf;
}
}
}
void
copy_scanlineimage (
MultiPartInputFile& input,
MultiPartOutputFile& output,
int inPart,
int outPart,
const std::string& inview = std::string (""))
{
int buffer_size;
FrameBuffer inFrameBuffer;
FrameBuffer outFrameBuffer;
InputPart in (input, inPart);
OutputPart out (output, outPart);
const Header& inhdr = input.header (inPart);
int channels = 0;
for (ChannelList::ConstIterator i = inhdr.channels ().begin ();
i != inhdr.channels ().end ();
++i)
++channels;
int width = inhdr.dataWindow ().max.x - inhdr.dataWindow ().min.x + 1;
int height = inhdr.dataWindow ().max.y - inhdr.dataWindow ().min.y + 1;
int y = inhdr.dataWindow ().min.y;
int x = inhdr.dataWindow ().min.x;
//allocate at least enough memory to handle the data
//(biggest data is four bytes)
// we store the channels separately, one after the other
buffer_size = 4 * width * height * channels;
char* channelbuf = new char[buffer_size];
// now iterate over each channel and hook it all up
// pointer to where we put the first byte
char* bufptr = channelbuf;
StringVector views;
if (hasMultiView (inhdr)) { views = multiView (inhdr); }
for (ChannelList::ConstIterator i = inhdr.channels ().begin ();
i != inhdr.channels ().end ();
++i)
{
if (inview == "" || views.size () == 0 ||
viewFromChannelName (i.name (), views) == inview)
{
inFrameBuffer.insert (
i.name (),
Slice (
i.channel ().type,
bufptr - (y * width + x) * 4,
4,
width * 4));
outFrameBuffer.insert (
removeViewName (i.name (), inview),
Slice (
i.channel ().type,
bufptr - (y * width + x) * 4,
4,
width * 4));
}
bufptr += width * height * 4;
}
in.setFrameBuffer (inFrameBuffer);
out.setFrameBuffer (outFrameBuffer);
for (int row = inhdr.dataWindow ().min.y; row <= inhdr.dataWindow ().max.y;
row++)
{
in.readPixels (row);
out.writePixels (1);
}
delete[] channelbuf;
}
void
copy_scanlinedeep (
MultiPartInputFile& input,
MultiPartOutputFile& output,
int inPart,
int outPart)
{
DeepFrameBuffer inFrameBuffer;
DeepFrameBuffer outFrameBuffer;
DeepScanLineInputPart in (input, inPart);
DeepScanLineOutputPart out (output, outPart);
const Header& header = input.header (inPart);
int channels = 0;
for (ChannelList::ConstIterator i = header.channels ().begin ();
i != header.channels ().end ();
++i)
++channels;
int width = header.dataWindow ().max.x - header.dataWindow ().min.x + 1;
int height = header.dataWindow ().max.y - header.dataWindow ().min.y + 1;
int y = header.dataWindow ().min.y;
int x = header.dataWindow ().min.x;
//allocate enough memory to handle the sample counts for every pixel in the image
int counter_size = width * height;
int* countbuf = new int[counter_size];
//
//allocate enough memory to handle the pointers for every channel of every pixel in the image
//
int pointer_size = width * height * channels;
char** pointerbuf = new char*[pointer_size];
inFrameBuffer.insertSampleCountSlice (Slice (
UINT,
(char*) (countbuf - (y * width + x)),
sizeof (unsigned int) * 1, // xStride
sizeof (unsigned int) * width)); // yStride
outFrameBuffer.insertSampleCountSlice (Slice (
UINT,
(char*) (countbuf - (y * width + x)),
sizeof (unsigned int) * 1, // xStride
sizeof (unsigned int) * width)); // yStride
// for simplicity, allocate 4 bytes per channel per sample (even though halfs only take two)
// pointers are interleaved -pointers for all channels of pixel 0 go first, then pixel 1 etc
// within the data vector, samples will be stored contiguously (i.e. channels are interleaved)
int channel = 0;
for (ChannelList::ConstIterator i = header.channels ().begin ();
i != header.channels ().end ();
++i)
{
inFrameBuffer.insert (
i.name (),
DeepSlice (
i.channel ().type,
((char*) pointerbuf) -
((y * width + x) * channels + channel) * 4,
4 * channels,
width * 4 * channels,
4 * channels));
outFrameBuffer.insert (
i.name (),
DeepSlice (
i.channel ().type,
((char*) pointerbuf) -
((y * width + x) * channels + channel) * 4,
4 * channels,
width * 4 * channels,
4 * channels));
channel++;
}
in.setFrameBuffer (inFrameBuffer);
out.setFrameBuffer (outFrameBuffer);
//
// read the entire sample count array
//
in.readPixelSampleCounts (
header.dataWindow ().min.y, header.dataWindow ().max.y);
vector<char> samples;
int* count_start = countbuf; // pointer to first sample count in the image
char** pointer_start = pointerbuf;
//
// loop over each row of the image - at each row, allocate storage for this row only
// within the sample array
// we can reuse the array every row, so we only need as much memory as is required for the largest row
//
for (int row = header.dataWindow ().min.y;
row <= header.dataWindow ().max.y;
row++)
{
// count samples on the row
int count = 0;
for (int x = header.dataWindow ().min.x;
x <= header.dataWindow ().max.x;
x++)
count += count_start[x];
// allocate enough data for that row
samples.resize (count * channels);
// set pointers for row
count = 0;
for (int x = header.dataWindow ().min.x;
x <= header.dataWindow ().max.x;
x++)
{
for (int i = 0; i < channels; i++)
{
pointer_start[x * channels + i] =
&samples[count * channels + i];
}
count += count_start[x];
}
//
// set pointers for row z
//
in.readPixels (row);
out.writePixels (1);
// bump pointers to next row
count_start += width;
pointer_start += width * channels;
}
delete[] countbuf;
delete[] pointerbuf;
}
void
make_unique_names (vector<Header>& headers)
{
set<string> names;
for (size_t i = 0; i < headers.size (); i++)
{
std::string base_name;
// if no name at all, set it to <type><partnum> (first part is part 1)
if (!headers[i].hasName ())
{
ostringstream s;
s << headers[i].type () << (i + 1);
base_name = s.str ();
headers[i].setName (base_name);
}
else
{
base_name = headers[i].name ();
}
// check name hasn't already been used, if so add a _<number> to it
if (names.find (base_name) != names.end ())
{
ostringstream s;
size_t backup = 1;
do
{
s.clear ();
s << headers[i].type () << i << "_" << backup;
backup++;
} while (names.find (s.str ()) != names.end ());
headers[i].setName (s.str ());
}
}
}
int
main (int argc, char* argv[])
{
if (argc < 3)
{
cerr
<< argv[0]
<< " takes a collection of EXR images and outputs them as a single multipart EXR\n";
cerr
<< std::string (strlen (argv[0]), ' ') << " syntax: " << argv[0]
<< " [input.exr[:partnum[.view]]] [input2.exr[:partnum[.view]]] ... output.exr\n";
exit (1);
}
int numInputs = argc - 2;
vector<int> partnums (numInputs);
vector<MultiPartInputFile*> inputs (numInputs);
vector<Header> headers (numInputs);
vector<string> views (numInputs);
//
// parse all inputs
//
//
for (int i = 0; i < numInputs; i++)
{
// if input is <file>:<partnum>[.view] then extract part number (and also view if preset), else get part 0
string filename (argv[i + 1]);
size_t colon = filename.rfind (':');
if (colon == string::npos) { partnums[i] = 0; }
else
{
string num = filename.substr (colon + 1);
partnums[i] = atoi (num.c_str ());
filename = filename.substr (0, colon);
size_t dot = num.rfind ('.');
if (dot != string::npos) { views[i] = num.substr (dot + 1); }
}
// open and check
inputs[i] = new MultiPartInputFile (filename.c_str ());
if (partnums[i] >= inputs[i]->parts ())
{
std::cerr << "oops: you asked for part " << partnums[i] << " in "
<< argv[1 + i] << ", which only has "
<< inputs[i]->parts () << " parts\n";
exit (1);
}
//copy header from required part of input to our header array
headers[i] = inputs[i]->header (partnums[i]);
if (views[i] != "")
{
if (hasMultiView (headers[i]))
{
StringVector multiview = multiView (headers[i]);
ChannelList newList;
//
// also clean up channel names
//
for (ChannelList::Iterator c = headers[i].channels ().begin ();
c != headers[i].channels ().end ();
++c)
{
if (viewFromChannelName (c.name (), multiview) == views[i])
{
newList.insert (
removeViewName (c.name (), views[i]), c.channel ());
}
}
headers[i].channels () = newList;
headers[i].erase ("multiView");
}
headers[i].setView (views[i]);
}
}
// sort out names - make unique
if (numInputs > 1) { make_unique_names (headers); }
MultiPartOutputFile out (
argv[argc - 1], &headers[0], headers.size (), false, 4);
for (int p = 0; p < numInputs; p++)
{
//todo - this only works for regular images - make one of these
//for every type of data
Header header = headers[p];
std::string type = header.type ();
if (type == SCANLINEIMAGE)
{
copy_scanlineimage (*inputs[p], out, partnums[p], p, views[p]);
}
else if (type == TILEDIMAGE)
{
copy_tiledimage (*inputs[p], out, partnums[p], p, views[p]);
}
else if (type == DEEPSCANLINE)
{
copy_scanlinedeep (*inputs[p], out, partnums[p], p);
}
} //next part
}
+37 -30
View File
@@ -3,10 +3,13 @@
#include <ImathConfig.h>
#include <ImfCheckFile.h>
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <cstdint>
#include <fstream>
#include <iostream>
#include <ostream>
#include <string.h>
#if defined _WIN32 || defined _WIN64
# include <io.h>
@@ -16,25 +19,27 @@
#include <vector>
using namespace OPENEXR_IMF_NAMESPACE;
using std::cerr;
using std::cout;
using std::endl;
using std::ifstream;
using std::streampos;
using std::vector;
using namespace std;
void
usageMessage (const char argv0[])
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: " << argv0 << " [options] imagefile [imagefile ...]\n";
cerr << "options: \n";
cerr
<< " -m : avoid excessive memory allocation (some files will not be fully checked)\n";
cerr
<< " -t : avoid spending excessive time (some files will not be fully checked)\n";
cerr << " -s : use stream API instead of file API\n";
cerr << " -c : add core library checks\n";
cerr << " -v : print OpenEXR and Imath software library version info\n";
stream << "Usage: " << program_name << " [options] imagefile [imagefile ...]\n";
if (verbose)
stream << "\n"
"Read exr files to validate their contents and the correct behavior of the software.\n"
"\n"
"Options:\n"
" -m avoid excessive memory allocation (some files will not be fully checked)\n"
" -t avoid spending excessive time (some files will not be fully checked)\n"
" -s use stream API instead of file API\n"
" -c add core library checks\n"
" -h, --help print this message\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
bool
@@ -96,7 +101,7 @@ main (int argc, char** argv)
{
if (argc < 2)
{
usageMessage (argv[0]);
usageMessage (cerr, argv[0], false);
return 1;
}
@@ -107,10 +112,10 @@ main (int argc, char** argv)
bool useStream = false;
for (int i = 1; i < argc; ++i)
{
if (!strcmp (argv[i], "-h"))
if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
usageMessage (argv[0]);
return 1;
usageMessage (cout, "exrcheck", true);
return 0;
}
else if (!strcmp (argv[i], "-m"))
{
@@ -135,16 +140,18 @@ main (int argc, char** argv)
{
enableCoreCheck = true;
}
else if (!strcmp (argv[i], "-v"))
else if (!strcmp (argv[i], "--version"))
{
std::cout << OPENEXR_PACKAGE_STRING
<< " Lib API: " << OPENEXR_LIB_VERSION_STRING << ", "
<< IMATH_PACKAGE_STRING
#if defined(IMATH_LIB_VERSION_STRING)
<< " Lib API: " << IMATH_LIB_VERSION_STRING
#endif
<< std::endl;
exit (0);
const char* libraryVersion = getLibraryVersion();
cout << "exrcheck (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
else
{
@@ -156,7 +163,7 @@ main (int argc, char** argv)
#endif
{
cerr << "No such file: " << argv[i] << endl;
exit (-1);
return -1;
}
cout << " file " << argv[i] << ' ';
+328 -313
View File
@@ -12,12 +12,16 @@
#include <EnvmapImage.h>
#include <ImfEnvmap.h>
#include <ImfHeader.h>
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <blurImage.h>
#include <makeCubeMap.h>
#include <makeLatLongMap.h>
#include <exception>
#include <stdexcept>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <string>
@@ -30,102 +34,103 @@ namespace
{
void
usageMessage (const char argv0[], bool verbose = false)
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: " << argv0 << " [options] infile outfile" << endl;
stream << "Usage: " << program_name << " [options] infile outfile" << endl;
if (verbose)
{
cerr << "\n"
"Converts OpenEXR latitude-longitude environment maps\n"
"into cube-face environment maps or vice versa.\n"
"Reads an environment map image from infile, converts\n"
"it, and stores the result in outfile.\n"
"\n"
"If the input file name contains a '%' character, then an\n"
"input cube-face environment map is assembled from six\n"
"square sub-images that represent the six faces of the cube.\n"
"The names of the six image files are generated by replacing\n"
"the % with +X, -X, +Y, -Y, +Z and -Z respectively.\n"
"\n"
"If the output file name contains a '%' character and\n"
"the program has been instructed to produce a cube-face\n"
"environment map, then the output image is split into six\n"
"square sub-images that are saved in six separate output\n"
"files. The names of the files are generated by replacing\n"
"the % with +X, -X, +Y, -Y, +Z and -Z respectively.\n"
"\n"
"Options:\n"
"\n"
"-o produces a ONE_LEVEL output file (default)\n"
"\n"
"-m produces a MIPMAP_LEVELS output file (-m has\n"
" no effect if the output image is split into\n"
" multiple files)\n"
"\n"
"-c the output file will be a cube-face environment\n"
" map (default)\n"
"\n"
"-l the output file will be a latitude-longitude\n"
" environment map\n"
"\n"
"-ci the input file is interpreted as a cube-face\n"
" environment map, regardless of its envmap\n"
" attribute\n"
"\n"
"-li the input file is interpreted as a latitude-\n"
" longitude environment map, regardless of its\n"
" envmap attribute (-li has no effect if the\n"
" input image is assembled from multiple files)\n"
"\n"
"-w x sets the width of the output image to x pixels\n"
" (default is 256). The height of the output image\n"
" will be x*6 pixels for a cube-face map, or x/2\n"
" pixels for a latitude-longitude map.\n"
"\n"
"-f r n sets the antialiasing filter radius to r\n"
" (default is 1.0) and the sampling rate to\n"
" n by n (default is 5 by 5). Increasing r\n"
" makes the output image blurrier; decreasing r\n"
" makes the image sharper but may cause aliasing.\n"
" Increasing n improves antialiasing, but\n"
" generating the output image takes longer.\n"
"\n"
"-b blurs the environment map image by applying a\n"
" 180-degree-wide filter kernel such that point-\n"
" sampling the blurred image at a location that\n"
" corresponds to 3D direction N returns the color\n"
" that a white diffuse reflector with surface\n"
" normal N would have if it was illuminated using\n"
" the original non-blurred image.\n"
" Generating the blurred image can be fairly slow.\n"
"\n"
"-t x y sets the output file's tile size to x by y pixels\n"
" (default is 64 by 64)\n"
"\n"
"-p t b if the input image is a latitude-longitude map,\n"
" pad the image at the top and bottom with t*h\n"
" and b*h extra scan lines, where h is the height\n"
" of the input image. This is useful for images\n"
" from 360-degree panoramic scans that cover\n"
" less than 180 degrees vertically.\n"
"\n"
"-d sets level size rounding to ROUND_DOWN (default)\n"
"\n"
"-u sets level size rounding to ROUND_UP\n"
"\n"
"-z x sets the data compression method to x\n"
" (none/rle/zip/piz/pxr24/b44/b44a/dwaa/dwab,\n"
" default is zip)\n"
"\n"
"-v verbose mode\n"
"\n"
"-h prints this message\n";
cerr << endl;
stream << "\n"
"Convert an OpenEXR latitude-longitude environment map\n"
"into a cube-face environment map or vice versa.\n"
"Reads an environment map image from infile, converts\n"
"it, and stores the result in outfile.\n"
"\n"
"If the input file name contains a '%' character, then an\n"
"input cube-face environment map is assembled from six\n"
"square sub-images that represent the six faces of the cube.\n"
"The names of the six image files are generated by replacing\n"
"the % with +X, -X, +Y, -Y, +Z and -Z respectively.\n"
"\n"
"If the output file name contains a '%' character and\n"
"the program has been instructed to produce a cube-face\n"
"environment map, then the output image is split into six\n"
"square sub-images that are saved in six separate output\n"
"files. The names of the files are generated by replacing\n"
"the % with +X, -X, +Y, -Y, +Z and -Z respectively.\n"
"\n"
"Options:\n"
"\n"
" -o produces a ONE_LEVEL output file (default)\n"
"\n"
" -m produces a MIPMAP_LEVELS output file (-m has\n"
" no effect if the output image is split into\n"
" multiple files)\n"
"\n"
" -c the output file will be a cube-face environment\n"
" map (default)\n"
"\n"
" -l the output file will be a latitude-longitude\n"
" environment map\n"
"\n"
" -ci the input file is interpreted as a cube-face\n"
" environment map, regardless of its envmap\n"
" attribute\n"
"\n"
" -li the input file is interpreted as a latitude-\n"
" longitude environment map, regardless of its\n"
" envmap attribute (-li has no effect if the\n"
" input image is assembled from multiple files)\n"
"\n"
" -w x sets the width of the output image to x pixels\n"
" (default is 256). The height of the output image\n"
" will be x*6 pixels for a cube-face map, or x/2\n"
" pixels for a latitude-longitude map.\n"
"\n"
" -f r n sets the antialiasing filter radius to r\n"
" (default is 1.0) and the sampling rate to\n"
" n by n (default is 5 by 5). Increasing r\n"
" makes the output image blurrier; decreasing r\n"
" makes the image sharper but may cause aliasing.\n"
" Increasing n improves antialiasing, but\n"
" generating the output image takes longer.\n"
"\n"
" -b blurs the environment map image by applying a\n"
" 180-degree-wide filter kernel such that point-\n"
" sampling the blurred image at a location that\n"
" corresponds to 3D direction N returns the color\n"
" that a white diffuse reflector with surface\n"
" normal N would have if it was illuminated using\n"
" the original non-blurred image.\n"
" Generating the blurred image can be fairly slow.\n"
"\n"
" -t x y sets the output file's tile size to x by y pixels\n"
" (default is 64 by 64)\n"
"\n"
" -p t b if the input image is a latitude-longitude map,\n"
" pad the image at the top and bottom with t*h\n"
" and b*h extra scan lines, where h is the height\n"
" of the input image. This is useful for images\n"
" from 360-degree panoramic scans that cover\n"
" less than 180 degrees vertically.\n"
"\n"
" -d sets level size rounding to ROUND_DOWN (default)\n"
"\n"
" -u sets level size rounding to ROUND_UP\n"
"\n"
" -z x sets the data compression method to x\n"
" (none/rle/zip/piz/pxr24/b44/b44a/dwaa/dwab,\n"
" default is zip)\n"
"\n"
" -v verbose mode\n"
"\n"
" -h, --help print this message\n"
"\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
exit (1);
}
Compression
@@ -171,8 +176,9 @@ getCompression (const string& str)
}
else
{
cerr << "Unknown compression method \"" << str << "\"." << endl;
exit (1);
std::stringstream e;
e << "Unknown compression method \"" << str << "\"";
throw invalid_argument(e.str().c_str());
}
return c;
@@ -204,227 +210,236 @@ main (int argc, char** argv)
// Parse the command line.
//
if (argc < 2) usageMessage (argv[0], true);
int i = 1;
while (i < argc)
if (argc < 2)
{
if (!strcmp (argv[i], "-o"))
{
//
// generate a ONE_LEVEL image
//
levelMode = ONE_LEVEL;
i += 1;
}
else if (!strcmp (argv[i], "-m"))
{
//
// Generate a MIPMAP_LEVELS image
//
levelMode = MIPMAP_LEVELS;
i += 1;
}
else if (!strcmp (argv[i], "-c"))
{
//
// Generate a cube-face map
//
type = ENVMAP_CUBE;
i += 1;
}
else if (!strcmp (argv[i], "-l"))
{
//
// Generate a latitude-longitude map
//
type = ENVMAP_LATLONG;
i += 1;
}
else if (!strcmp (argv[i], "-ci"))
{
//
// Assume input is a cube-face map
//
overrideInputType = ENVMAP_CUBE;
i += 1;
}
else if (!strcmp (argv[i], "-li"))
{
//
// Assume input is a latitude-longitude map
//
overrideInputType = ENVMAP_LATLONG;
i += 1;
}
else if (!strcmp (argv[i], "-w"))
{
//
// Set output image width
//
if (i > argc - 2) usageMessage (argv[0]);
mapWidth = strtol (argv[i + 1], 0, 0);
if (mapWidth <= 0)
{
cerr << "Output image width must be greater than zero." << endl;
return 1;
}
i += 2;
}
else if (!strcmp (argv[i], "-f"))
{
//
// Set filter radius and supersampling rate
//
if (i > argc - 3) usageMessage (argv[0]);
filterRadius = strtod (argv[i + 1], 0);
numSamples = strtol (argv[i + 2], 0, 0);
if (filterRadius < 0)
{
cerr << "Filter radius must not be less than zero." << endl;
return 1;
}
if (numSamples <= 0)
{
cerr << "Sampling rate must be greater than zero." << endl;
return 1;
}
i += 3;
}
else if (!strcmp (argv[i], "-b"))
{
//
// Diffuse blur
//
diffuseBlur = true;
i += 1;
}
else if (!strcmp (argv[i], "-t"))
{
//
// Set tile size
//
if (i > argc - 3) usageMessage (argv[0]);
tileWidth = strtol (argv[i + 1], 0, 0);
tileHeight = strtol (argv[i + 2], 0, 0);
if (tileWidth <= 0 || tileHeight <= 0)
{
cerr << "Tile size must be greater than zero." << endl;
return 1;
}
i += 3;
}
else if (!strcmp (argv[i], "-p"))
{
//
// Set top and bottom padding
//
if (i > argc - 3) usageMessage (argv[0]);
padTop = strtod (argv[i + 1], 0);
padBottom = strtod (argv[i + 2], 0);
if (padTop < 0 || padBottom < 0)
{
cerr << "Padding must not be less than zero." << endl;
return 1;
}
i += 3;
}
else if (!strcmp (argv[i], "-d"))
{
//
// Round down
//
roundingMode = ROUND_DOWN;
i += 1;
}
else if (!strcmp (argv[i], "-u"))
{
//
// Round down
//
roundingMode = ROUND_UP;
i += 1;
}
else if (!strcmp (argv[i], "-z"))
{
//
// Set compression method
//
if (i > argc - 2) usageMessage (argv[0]);
compression = getCompression (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h"))
{
//
// Print help message
//
usageMessage (argv[0], true);
}
else
{
//
// Image file name
//
if (inFile == 0)
inFile = argv[i];
else
outFile = argv[i];
i += 1;
}
usageMessage (cerr, argv[0], false);
return -1;
}
if (inFile == 0 || outFile == 0) usageMessage (argv[0]);
//
// Load inFile, convert it, and save the result in outFile.
//
int exitStatus = 0;
try
{
int i = 1;
while (i < argc)
{
if (!strcmp (argv[i], "-o"))
{
//
// generate a ONE_LEVEL image
//
levelMode = ONE_LEVEL;
i += 1;
}
else if (!strcmp (argv[i], "-m"))
{
//
// Generate a MIPMAP_LEVELS image
//
levelMode = MIPMAP_LEVELS;
i += 1;
}
else if (!strcmp (argv[i], "-c"))
{
//
// Generate a cube-face map
//
type = ENVMAP_CUBE;
i += 1;
}
else if (!strcmp (argv[i], "-l"))
{
//
// Generate a latitude-longitude map
//
type = ENVMAP_LATLONG;
i += 1;
}
else if (!strcmp (argv[i], "-ci"))
{
//
// Assume input is a cube-face map
//
overrideInputType = ENVMAP_CUBE;
i += 1;
}
else if (!strcmp (argv[i], "-li"))
{
//
// Assume input is a latitude-longitude map
//
overrideInputType = ENVMAP_LATLONG;
i += 1;
}
else if (!strcmp (argv[i], "-w"))
{
//
// Set output image width
//
if (i > argc - 2)
throw invalid_argument("Missing width for -w argument");
mapWidth = strtol (argv[i + 1], 0, 0);
if (mapWidth <= 0)
throw invalid_argument("Output image width must be greater than zero");
i += 2;
}
else if (!strcmp (argv[i], "-f"))
{
//
// Set filter radius and supersampling rate
//
if (i > argc - 3)
throw invalid_argument("Missing filter radius with -f option");
filterRadius = strtod (argv[i + 1], 0);
numSamples = strtol (argv[i + 2], 0, 0);
if (filterRadius < 0)
throw invalid_argument("Filter radius must not be less than zero");
if (numSamples <= 0)
throw invalid_argument("Sampling rate must be greater than zero");
i += 3;
}
else if (!strcmp (argv[i], "-b"))
{
//
// Diffuse blur
//
diffuseBlur = true;
i += 1;
}
else if (!strcmp (argv[i], "-t"))
{
//
// Set tile size
//
if (i > argc - 3)
throw invalid_argument("missing tile size with -t option");
tileWidth = strtol (argv[i + 1], 0, 0);
tileHeight = strtol (argv[i + 2], 0, 0);
if (tileWidth <= 0 || tileHeight <= 0)
throw invalid_argument("Tile size must be greater than zero");
i += 3;
}
else if (!strcmp (argv[i], "-p"))
{
//
// Set top and bottom padding
//
if (i > argc - 3)
throw invalid_argument("missing padding value with -p option");
padTop = strtod (argv[i + 1], 0);
padBottom = strtod (argv[i + 2], 0);
if (padTop < 0 || padBottom < 0)
throw invalid_argument("Padding must not be less than zero");
i += 3;
}
else if (!strcmp (argv[i], "-d"))
{
//
// Round down
//
roundingMode = ROUND_DOWN;
i += 1;
}
else if (!strcmp (argv[i], "-u"))
{
//
// Round down
//
roundingMode = ROUND_UP;
i += 1;
}
else if (!strcmp (argv[i], "-z"))
{
//
// Set compression method
//
if (i > argc - 2)
throw invalid_argument("Missing compression method with -z option");
compression = getCompression (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
//
// Print help message
//
usageMessage (cout, "exrenvmap", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exrenvmap (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
else
{
//
// Image file name
//
if (inFile == 0)
inFile = argv[i];
else
outFile = argv[i];
i += 1;
}
}
if (inFile == 0 || outFile == 0)
{
usageMessage (cerr, argv[0], false);
return -1;
}
//
// Load inFile, convert it, and save the result in outFile.
//
EnvmapImage image;
Header header;
RgbaChannels channels;
@@ -478,9 +493,9 @@ main (int argc, char** argv)
}
catch (const exception& e)
{
cerr << e.what () << endl;
exitStatus = 1;
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
return exitStatus;
return 0;
}
+36 -11
View File
@@ -31,6 +31,8 @@
#include <ImfTimeCodeAttribute.h>
#include <ImfVecAttribute.h>
#include <ImfVersion.h>
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <iomanip>
#include <iostream>
@@ -456,9 +458,20 @@ printInfo (const char fileName[])
}
void
usageMessage (const char argv0[])
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
std::cerr << "Usage: " << argv0 << " imagefile [imagefile ...]\n";
stream << "Usage: " << program_name << " imagefile [imagefile ...]\n";
if (verbose)
stream << "\n"
"Read exr files and print the values of header attributes.\n"
"\n"
"Options:\n"
" -h, --help print this message\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
int
@@ -466,16 +479,28 @@ main (int argc, char** argv)
{
if (argc < 2)
{
usageMessage (argv[0]);
return 1;
usageMessage (cerr, argv[0], false);
return -1;
}
for (int i = 1; i < argc; ++i)
{
if (!strcmp (argv[i], "-h"))
if (!strcmp (argv[i], "-h") || !strcmp(argv[1], "--help"))
{
usageMessage (argv[0]);
return 1;
usageMessage (cout, "exrheader", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exrheader (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
}
@@ -483,12 +508,12 @@ main (int argc, char** argv)
{
for (int i = 1; i < argc; ++i)
printInfo (argv[i]);
return 0;
}
catch (const std::exception& e)
catch (const exception& e)
{
std::cerr << e.what () << std::endl;
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
return 0;
}
+4 -1
View File
@@ -6,7 +6,10 @@ target_link_libraries(exrinfo OpenEXR::OpenEXRCore)
set_target_properties(exrinfo PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
install(TARGETS exrinfo DESTINATION ${CMAKE_INSTALL_BINDIR})
if(OPENEXR_INSTALL_TOOLS)
install(TARGETS exrinfo DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WIN32 AND (BUILD_SHARED_LIBS OR OPENEXR_BUILD_BOTH_STATIC_SHARED))
target_compile_definitions(exrinfo PRIVATE OPENEXR_DLL)
endif()
+28 -10
View File
@@ -18,12 +18,25 @@
#include <stdlib.h>
static void
usage (const char* argv0)
usage (FILE* stream, const char* argv0, int verbose)
{
fprintf (
stderr,
"Usage: %s [-v|--verbose] [-a|--all-metadata] [-s|--strict] <filename> [<filename> ...]\n\n",
argv0);
fprintf (stream,
"Usage: %s [-v|--verbose] [-a|--all-metadata] [-s|--strict] <filename> [<filename> ...]\n\n",
argv0);
if (verbose)
fprintf(stream, "\n"
"Read exr files and print values of header attributes\n"
"\n"
"Options:\n"
" -s, --strict strict mode\n"
" -a, --all-metadata print all metadata\n"
" -v, --verbose verbose mode\n"
" -h, --help print this message\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"");
}
static void
@@ -129,14 +142,21 @@ process_file (const char* filename, int verbose, int allmeta, int strict)
int
main (int argc, const char* argv[])
{
int rv = 0, nfiles = 0, verbose = 0, allmeta = 0, strict = 0;
int rv = 0, verbose = 0, allmeta = 0, strict = 0;
for (int a = 1; a < argc; ++a)
{
if (!strcmp (argv[a], "-h") || !strcmp (argv[a], "-?") ||
!strcmp (argv[a], "--help"))
{
usage (argv[0]);
usage (stdout, "exrinfo", 1);
return 0;
}
else if (!strcmp (argv[a], "--version"))
{
printf("exrinfo (OpenEXR) %s https://openexr.com\n", OPENEXR_VERSION_STRING);
printf("Copyright (c) Contributors to the OpenEXR Project\n");
printf("License BSD-3-Clause\n");
return 0;
}
else if (!strcmp (argv[a], "-v") || !strcmp (argv[a], "--verbose"))
@@ -153,17 +173,15 @@ main (int argc, const char* argv[])
}
else if (!strcmp (argv[a], "-"))
{
++nfiles;
rv += process_stdin (verbose, allmeta, strict);
}
else if (argv[a][0] == '-')
{
usage (argv[0]);
usage (stderr, argv[0], 0);
return 1;
}
else
{
++nfiles;
rv += process_file (argv[a], verbose, allmeta, strict);
}
}
+129 -106
View File
@@ -12,43 +12,46 @@
#include "makePreview.h"
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <exception>
#include <iostream>
#include <stdlib.h>
#include <string.h>
using namespace OPENEXR_IMF_NAMESPACE;
using namespace std;
void
usageMessage (const char argv0[], bool verbose = false)
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: " << argv0 << " [options] infile outfile" << endl;
stream << "Usage: " << program_name << " [options] infile outfile" << endl;
if (verbose)
{
cerr << "\n"
"Reads an OpenEXR image from infile, generates a preview\n"
"image, adds it to the image's header, and saves the result\n"
"in outfile. Infile and outfile must not refer to the same\n"
"file (the program cannot edit an image file \"in place\").\n"
"\n"
"Options:\n"
"\n"
"-w x sets the width of the preview image to x pixels\n"
" (default is 100)\n"
"\n"
"-e s adjusts the preview image's exposure by s f-stops\n"
" (default is 0). Positive values make the image\n"
" brighter, negative values make it darker.\n"
"\n"
"-v verbose mode\n"
"\n"
"-h prints this message\n";
cerr << endl;
}
exit (1);
stream << "\n"
"Read an OpenEXR image from infile, generate a preview\n"
"image, add it to the image's header, and save the result\n"
"in outfile. Infile and outfile must not refer to the same\n"
"file (the program cannot edit an image file \"in place\").\n"
"\n"
"Options:\n"
"\n"
" -w x sets the width of the preview image to x pixels\n"
" (default is 100)\n"
"\n"
" -e s adjusts the preview image's exposure by s f-stops\n"
" (default is 0). Positive values make the image\n"
" brighter, negative values make it darker.\n"
"\n"
" -v verbose mode\n"
"\n"
" -h, --help print this message\n"
"\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
int
@@ -64,95 +67,115 @@ main (int argc, char** argv)
// Parse the command line.
//
if (argc < 2) usageMessage (argv[0], true);
int i = 1;
while (i < argc)
if (argc < 2)
{
if (!strcmp (argv[i], "-w"))
{
//
// Set preview image width
//
if (i > argc - 2) usageMessage (argv[0]);
previewWidth = strtol (argv[i + 1], 0, 0);
i += 2;
}
else if (!strcmp (argv[i], "-e"))
{
//
// Set preview image width
//
if (i > argc - 2) usageMessage (argv[0]);
exposure = strtod (argv[i + 1], 0);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h"))
{
//
// Print help message
//
usageMessage (argv[0], true);
}
else
{
//
// Image file name
//
if (inFile == 0)
inFile = argv[i];
else
outFile = argv[i];
i += 1;
}
usageMessage (cerr, argv[0], false);
return -1;
}
if (inFile == 0 || outFile == 0) usageMessage (argv[0]);
if (!strcmp (inFile, outFile))
{
cerr << "Input and output cannot be the same file." << endl;
return 1;
}
if (previewWidth <= 0)
{
cerr << "Preview image width must be greater than zero." << endl;
return 1;
}
//
// Load inFile, add a preview image, and save the result in outFile.
//
int exitStatus = 0;
try
{
int i = 1;
while (i < argc)
{
if (!strcmp (argv[i], "-w"))
{
//
// Set preview image width
//
if (i > argc - 2)
throw invalid_argument("Missing width for -w argument");
previewWidth = strtol (argv[i + 1], 0, 0);
if (previewWidth <= 0)
throw invalid_argument("preview width must be greater than zero");
i += 2;
}
else if (!strcmp (argv[i], "-e"))
{
//
// Set exposure
//
if (i > argc - 2)
throw invalid_argument("missing exposure for -e argument");
exposure = strtod (argv[i + 1], 0);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
//
// Print help message
//
usageMessage (cout, "exrmakepreview", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exrmakepreview (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
else
{
//
// Image file name
//
if (inFile == 0)
inFile = argv[i];
else
outFile = argv[i];
i += 1;
}
}
if (inFile == 0 || outFile == 0)
{
usageMessage (cerr, argv[0], false);
return -1;
}
if (!strcmp (inFile, outFile))
throw invalid_argument("Input and output cannot be the same file");
if (previewWidth <= 0)
throw invalid_argument("Preview image width must be greater than zero");
//
// Load inFile, add a preview image, and save the result in outFile.
//
makePreview (inFile, outFile, previewWidth, exposure, verbose);
}
catch (const exception& e)
{
cerr << e.what () << endl;
exitStatus = 1;
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
return exitStatus;
return 0;
}
+240 -218
View File
@@ -13,9 +13,12 @@
#include "makeTiled.h"
#include <ImfHeader.h>
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <exception>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <string>
@@ -28,61 +31,62 @@ namespace
{
void
usageMessage (const char argv0[], bool verbose = false)
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: " << argv0 << " [options] infile outfile" << endl;
stream << "Usage: " << program_name << " [options] infile outfile" << endl;
if (verbose)
{
cerr << "\n"
"Reads an OpenEXR image from infile, produces a tiled\n"
"version of the image, and saves the result in outfile.\n"
"\n"
"Options:\n"
"\n"
"-o produces a ONE_LEVEL image (default)\n"
"\n"
"-m produces a MIPMAP_LEVELS multiresolution image\n"
"\n"
"-r produces a RIPMAP_LEVELS multiresolution image\n"
"\n"
"-f c when a MIPMAP_LEVELS or RIPMAP_LEVELS image\n"
" is produced, image channel c will be resampled\n"
" without low-pass filtering. This option can\n"
" be specified multiple times to disable low-pass\n"
" filtering for multiple channels.\n"
"\n"
"-e x y when a MIPMAP_LEVELS or RIPMAP_LEVELS image\n"
" is produced, low-pass filtering takes samples\n"
" outside the image's data window. This requires\n"
" extrapolating the image. Option -e specifies\n"
" how the image is extrapolated horizontally and\n"
" vertically (black/clamp/periodic/mirror, default\n"
" is clamp).\n"
"\n"
"-t x y sets the tile size in the output image to\n"
" x by y pixels (default is 64 by 64)\n"
"\n"
"-d sets level size rounding to ROUND_DOWN (default)\n"
"\n"
"-u sets level size rounding to ROUND_UP\n"
"\n"
"-z x sets the data compression method to x\n"
" (none/rle/zip/piz/pxr24/b44/b44a/dwaa/dwab,\n"
" default is zip)\n"
"\n"
"-v verbose mode\n"
"\n"
"-h prints this message\n"
"\n"
"Multipart Options:\n"
"\n"
"-p i part number, default is 0\n";
cerr << endl;
stream << "\n"
"Read an OpenEXR image from infile, produce a tiled\n"
"version of the image, and save the result in outfile.\n"
"\n"
"Options:\n"
"\n"
" -o produces a ONE_LEVEL image (default)\n"
"\n"
" -m produces a MIPMAP_LEVELS multiresolution image\n"
"\n"
" -r produces a RIPMAP_LEVELS multiresolution image\n"
"\n"
" -f c when a MIPMAP_LEVELS or RIPMAP_LEVELS image\n"
" is produced, image channel c will be resampled\n"
" without low-pass filtering. This option can\n"
" be specified multiple times to disable low-pass\n"
" filtering for multiple channels.\n"
"\n"
" -e x y when a MIPMAP_LEVELS or RIPMAP_LEVELS image\n"
" is produced, low-pass filtering takes samples\n"
" outside the image's data window. This requires\n"
" extrapolating the image. Option -e specifies\n"
" how the image is extrapolated horizontally and\n"
" vertically (black/clamp/periodic/mirror, default\n"
" is clamp).\n"
"\n"
" -t x y sets the tile size in the output image to\n"
" x by y pixels (default is 64 by 64)\n"
"\n"
" -d sets level size rounding to ROUND_DOWN (default)\n"
"\n"
" -u sets level size rounding to ROUND_UP\n"
"\n"
" -z x sets the data compression method to x\n"
" (none/rle/zip/piz/pxr24/b44/b44a/dwaa/dwab,\n"
" default is zip)\n"
"\n"
" -v verbose mode\n"
"\n"
" -h, --help print this message\n"
"\n"
" --version print version information\n"
"\n"
"Multipart Options:\n"
"\n"
" -p i part number, default is 0\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
exit (1);
}
Compression
@@ -128,8 +132,9 @@ getCompression (const string& str)
}
else
{
cerr << "Unknown compression method \"" << str << "\"." << endl;
exit (1);
std::stringstream e;
e << "Unknown compression method \"" << str << "\"";
throw invalid_argument(e.str());
}
return c;
@@ -155,8 +160,9 @@ getExtrapolation (const string& str)
}
else
{
cerr << "Unknown extrapolation method \"" << str << "\"." << endl;
exit (1);
std::stringstream e;
e << "Unknown extrapolation method \"" << str << "\"";
throw invalid_argument(e.str());
}
return e;
@@ -165,7 +171,8 @@ getExtrapolation (const string& str)
void
getPartNum (int argc, char** argv, int& i, int* j)
{
if (i > argc - 2) usageMessage (argv[0]);
if (i > argc - 2)
throw invalid_argument("Missing part num with -p option");
*j = strtol (argv[i + 1], 0, 0);
cout << "part number: " << *j << endl;
@@ -193,163 +200,180 @@ main (int argc, char** argv)
// Parse the command line.
//
if (argc < 2) usageMessage (argv[0], true);
int i = 1;
int partnum = 0;
while (i < argc)
if (argc < 2)
{
if (!strcmp (argv[i], "-o"))
{
//
// generate a ONE_LEVEL image
//
mode = ONE_LEVEL;
i += 1;
}
else if (!strcmp (argv[i], "-m"))
{
//
// Generate a MIPMAP_LEVELS image
//
mode = MIPMAP_LEVELS;
i += 1;
}
else if (!strcmp (argv[i], "-r"))
{
//
// Generate a RIPMAP_LEVELS image
//
mode = RIPMAP_LEVELS;
i += 1;
}
else if (!strcmp (argv[i], "-f"))
{
//
// Don't low-pass filter the specified image channel
//
if (i > argc - 2) usageMessage (argv[0]);
doNotFilter.insert (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-e"))
{
//
// Set x and y extrapolation method
//
if (i > argc - 3) usageMessage (argv[0]);
extX = getExtrapolation (argv[i + 1]);
extY = getExtrapolation (argv[i + 2]);
i += 3;
}
else if (!strcmp (argv[i], "-t"))
{
//
// Set tile size
//
if (i > argc - 3) usageMessage (argv[0]);
tileSizeX = strtol (argv[i + 1], 0, 0);
tileSizeY = strtol (argv[i + 2], 0, 0);
if (tileSizeX <= 0 || tileSizeY <= 0)
{
cerr << "Tile size must be greater than zero." << endl;
return 1;
}
i += 3;
}
else if (!strcmp (argv[i], "-d"))
{
//
// Round down
//
roundingMode = ROUND_DOWN;
i += 1;
}
else if (!strcmp (argv[i], "-u"))
{
//
// Round down
//
roundingMode = ROUND_UP;
i += 1;
}
else if (!strcmp (argv[i], "-z"))
{
//
// Set compression method
//
if (i > argc - 2) usageMessage (argv[0]);
compression = getCompression (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h"))
{
//
// Print help message
//
usageMessage (argv[0], true);
}
else if (!strcmp (argv[i], "-p"))
{
getPartNum (argc, argv, i, &partnum);
}
else
{
//
// Image file name
//
if (inFile == 0)
inFile = argv[i];
else
outFile = argv[i];
i += 1;
}
usageMessage (cerr, argv[0], false);
return -1;
}
if (inFile == 0 || outFile == 0) usageMessage (argv[0]);
if (!strcmp (inFile, outFile))
{
cerr << "Input and output cannot be the same file." << endl;
return 1;
}
//
// Load inFile, and save a tiled version in outFile.
//
int exitStatus = 0;
try
{
int i = 1;
int partnum = 0;
while (i < argc)
{
if (!strcmp (argv[i], "-o"))
{
//
// generate a ONE_LEVEL image
//
mode = ONE_LEVEL;
i += 1;
}
else if (!strcmp (argv[i], "-m"))
{
//
// Generate a MIPMAP_LEVELS image
//
mode = MIPMAP_LEVELS;
i += 1;
}
else if (!strcmp (argv[i], "-r"))
{
//
// Generate a RIPMAP_LEVELS image
//
mode = RIPMAP_LEVELS;
i += 1;
}
else if (!strcmp (argv[i], "-f"))
{
//
// Don't low-pass filter the specified image channel
//
if (i > argc - 2)
throw invalid_argument("missing filter value with -f option");
doNotFilter.insert (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-e"))
{
//
// Set x and y extrapolation method
//
if (i > argc - 3)
throw invalid_argument("missing extrapolation values with -e option");
extX = getExtrapolation (argv[i + 1]);
extY = getExtrapolation (argv[i + 2]);
i += 3;
}
else if (!strcmp (argv[i], "-t"))
{
//
// Set tile size
//
if (i > argc - 3)
throw invalid_argument("missing tile size with -t option");
tileSizeX = strtol (argv[i + 1], 0, 0);
tileSizeY = strtol (argv[i + 2], 0, 0);
if (tileSizeX <= 0 || tileSizeY <= 0)
throw invalid_argument("Tile size must be greater than zero");
i += 3;
}
else if (!strcmp (argv[i], "-d"))
{
//
// Round down
//
roundingMode = ROUND_DOWN;
i += 1;
}
else if (!strcmp (argv[i], "-u"))
{
//
// Round down
//
roundingMode = ROUND_UP;
i += 1;
}
else if (!strcmp (argv[i], "-z"))
{
//
// Set compression method
//
if (i > argc - 2)
throw invalid_argument("Missing compression value with -z option");
compression = getCompression (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-p"))
{
getPartNum (argc, argv, i, &partnum);
}
else if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
//
// Print help message
//
usageMessage (cout, "exrmaketiled", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exrmaketiled (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
else
{
//
// Image file name
//
if (inFile == 0)
inFile = argv[i];
else
outFile = argv[i];
i += 1;
}
}
if (inFile == 0 || outFile == 0)
{
usageMessage (cerr, argv[0], false);
return -1;
}
if (!strcmp (inFile, outFile))
throw invalid_argument("Input and output cannot be the same file");
//
// Load inFile, and save a tiled version in outFile.
//
//
// check input
//
@@ -359,18 +383,16 @@ main (int argc, char** argv)
if (partnum < 0 || partnum >= parts)
{
cerr << "ERROR: you asked for part " << partnum << " in "
<< inFile;
cerr << ", which only has " << parts << " parts\n";
exit (1);
std::stringstream e;
e << "You asked for part " << partnum << " in "
<< inFile
<< ", which only has " << parts << " parts";
throw invalid_argument(e.str());
}
Header h = input.header (partnum);
if (h.type () == DEEPTILE || h.type () == DEEPSCANLINE)
{
cerr << "Cannot make tile for deep data" << endl;
exit (1);
}
throw invalid_argument("Cannot make tile for deep data");
}
makeTiled (
@@ -389,9 +411,9 @@ main (int argc, char** argv)
}
catch (const exception& e)
{
cerr << e.what () << endl;
exitStatus = 1;
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
return exitStatus;
return 0;
}
+14
View File
@@ -0,0 +1,14 @@
# SPDX-License-Identifier: BSD-3-Clause
# Copyright (c) Contributors to the OpenEXR Project.
add_executable(exrmanifest main.cpp)
target_link_libraries(exrmanifest OpenEXR::OpenEXR)
set_target_properties(exrmanifest PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
if(OPENEXR_INSTALL_TOOLS)
install(TARGETS exrmanifest DESTINATION ${CMAKE_INSTALL_BINDIR})
endif()
if(WIN32 AND BUILD_SHARED_LIBS)
target_compile_definitions(exrmanifest PRIVATE OPENEXR_DLL)
endif()
+210
View File
@@ -0,0 +1,210 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
//
// output all the idmanifest information found in the file as plain text
//
#include <ImfMisc.h>
#include <ImfMultiPartInputFile.h>
#include <ImfIDManifestAttribute.h>
#include <ImfStandardAttributes.h>
#include <iostream>
#include <vector>
#include <string>
using namespace OPENEXR_IMF_NAMESPACE;
using std::cerr;
using std::cout;
using std::endl;
using std::exception;
using std::max;
using std::ostream;
using std::set;
using std::string;
using std::to_string;
using std::vector;
size_t
dumpManifest (const IDManifest& mfst)
{
size_t uncompressedSize = 0;
for (size_t i = 0; i < mfst.size (); ++i)
{
const IDManifest::ChannelGroupManifest& m = mfst[i];
bool first = true;
if (i > 0) { cout << "\n\n"; }
cout << " channels : ";
for (set<string>::const_iterator s = m.getChannels ().begin ();
s != m.getChannels ().end ();
++s)
{
if (!first) { cout << ','; }
else { first = false; }
cout << *s;
uncompressedSize += s->size () + 1;
}
cout << "\n hashScheme: " << m.getHashScheme () << endl;
cout << " encoding : " << m.getEncodingScheme () << endl;
switch (m.getLifetime ())
{
case IDManifest::LIFETIME_FRAME:
cout << " lifetime : frame\n";
break;
case IDManifest::LIFETIME_SHOT:
cout << " lifetime : shot\n";
break;
case IDManifest::LIFETIME_STABLE:
cout << " lifetime : stable\n";
break;
}
//
// compute max field sizes
//
size_t maxNumLen = 0;
vector<size_t> componentLength (m.getComponents ().size ());
for (size_t c = 0; c < m.getComponents ().size (); ++c)
{
size_t componentSize = m.getComponents ()[c].size ();
uncompressedSize += componentSize + 1;
componentLength[c] = max (componentLength[c], componentSize);
}
for (IDManifest::ChannelGroupManifest::ConstIterator q = m.begin ();
q != m.end ();
++q)
{
size_t stringLen = to_string (q.id ()).size ();
uncompressedSize += stringLen;
maxNumLen = max (maxNumLen, stringLen);
for (size_t i = 0; i < q.text ().size (); i++)
{
uncompressedSize += q.text ()[i].size () + 1;
componentLength[i] =
max (componentLength[i], q.text ()[i].size ());
}
}
cout << " " << string (maxNumLen + 1, ' ');
for (size_t c = 0; c < m.getComponents ().size (); ++c)
{
string s = m.getComponents ()[c];
cout << s << string (componentLength[c] + 1 - s.size (), ' ');
}
cout << endl;
for (IDManifest::ChannelGroupManifest::ConstIterator q = m.begin ();
q != m.end ();
++q)
{
string id = to_string (q.id ());
cout << " " << id << string (maxNumLen + 1 - id.size (), ' ');
for (size_t i = 0; i < q.text ().size (); i++)
{
string s = q.text ()[i];
cout << s << string (componentLength[i] + 1 - s.size (), ' ');
}
cout << '\n';
}
}
return uncompressedSize;
}
void
printManifest (const char fileName[])
{
MultiPartInputFile in (fileName);
//
// extract objectID attribute
//
for (int part = 0; part < in.parts (); part++)
{
if (in.parts () > 1) { cout << fileName << " part " << part << ":\n"; }
if (hasIDManifest (in.header (part)))
{
const Imf::CompressedIDManifest& mfst =
idManifest (in.header (part));
size_t size = dumpManifest (mfst);
cout << "raw text size : " << size << endl;
cout << "uncompressed size: " << mfst._uncompressedDataSize << endl;
cout << "compressed size : " << mfst._compressedDataSize << endl;
}
else { cout << "no manifest found\n"; }
}
}
void
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
stream << "Usage: " << program_name << " imagefile [imagefile ...]\n";
if (verbose)
stream
<< "\n"
"Read exr files and print the contents of the embedded manifest.\n"
"\n"
"Options:\n"
" -h, --help print this message\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
int
main (int argc, char* argv[])
{
if (argc < 2)
{
usageMessage (cerr, argv[0], false);
return -1;
}
for (int i = 1; i < argc; ++i)
{
if (!strcmp (argv[i], "-h") || !strcmp (argv[1], "--help"))
{
usageMessage (cout, "exrmanifest", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion ();
cout << "exrmanifest (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp (libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
}
try
{
for (int i = 1; i < argc; ++i)
printManifest (argv[i]);
}
catch (const exception& e)
{
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
for (int i = 1; i < argc; ++i) {}
}
+291 -361
View File
@@ -23,6 +23,8 @@
#include <ImfStringAttribute.h>
#include <ImfTiledInputPart.h>
#include <ImfTiledOutputPart.h>
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <Iex.h>
#include <OpenEXRConfig.h>
@@ -37,17 +39,7 @@
#include <vector>
using IMATH_NAMESPACE::Box2i;
using std::cerr;
using std::cout;
using std::endl;
using std::make_pair;
using std::max;
using std::min;
using std::ostringstream;
using std::pair;
using std::set;
using std::string;
using std::vector;
using namespace std;
using namespace OPENEXR_IMF_NAMESPACE;
@@ -182,10 +174,8 @@ parse_filename (
}
else
{
cerr << "\n"
<< "ERROR: part number must be a number" << endl;
exit (1);
}
throw invalid_argument("part number must be a number");
}
}
}
@@ -202,10 +192,7 @@ make_unique_names (vector<Header>& headers)
if (!h.hasName ())
{
// We should not be here, we have populated all headers with names.
cerr << "\n"
<< "Software Error: header does not have a valid name"
<< ":" << __LINE__ << endl;
exit (1);
throw invalid_argument("Software Error: header does not have a valid name");
}
else
{
@@ -235,16 +222,8 @@ filename_check (vector<string> names, const char* aname)
{
string bname (aname);
for (size_t i = 0; i < names.size (); i++)
{
if (bname.compare (names[i]) == 0)
{
cerr << "\n"
<< "ERROR: "
"input and output file names cannot be the same."
<< endl;
exit (1);
}
}
throw invalid_argument("input and output file names cannot be the same");
}
void
@@ -255,159 +234,133 @@ convert (
bool override)
{
if (in.size () != 1)
throw invalid_argument("can only convert one file at once - use 'combine' mode for multiple files");
MultiPartInputFile infile (in[0]);
if (infile.parts () != 1)
throw invalid_argument("can only convert single part EXRs to multipart EXR-2.0 files: use 'split' mode instead");
vector<MultiViewChannelName> input_channels;
string hero;
if (hasMultiView (infile.header (0)))
{
cerr
<< "\n"
<< "ERROR: "
"can only convert one file at once - use 'combine' mode for multiple files"
<< endl;
exit (1);
StringVector h = multiView (infile.header (0));
if (h.size () > 0) { hero = h[0]; }
}
try
// retrieve channel names from input file in view-friendly format
GetChannelsInMultiPartFile (infile, input_channels);
vector<MultiViewChannelName> output_channels = input_channels;
// remap channels to multiple output parts
int parts = SplitChannels (
output_channels.begin (), output_channels.end (), true, hero);
vector<Header> output_headers (parts);
vector<FrameBuffer> output_framebuffers (parts);
FrameBuffer input_framebuffer;
//
// make all output headers the same as the input header but
// with no channels
//
for (int i = 0; i < parts; i++)
{
MultiPartInputFile infile (in[0]);
Header& h = output_headers[i];
h = infile.header (0);
if (hasMultiView (h)) h.erase ("multiView");
if (infile.parts () != 1)
{
cerr
<< "\n"
<< "ERROR: "
"can only convert single part EXRs to multipart EXR-2.0 files: use 'split' mode instead"
<< endl;
exit (1);
}
string fn, pname;
int pnum;
bool pforce;
parse_filename (fn, pname, pforce, pnum);
if (!h.hasName () || pforce) h.setName (pname);
vector<MultiViewChannelName> input_channels;
string hero;
if (hasMultiView (infile.header (0)))
{
StringVector h = multiView (infile.header (0));
if (h.size () > 0) { hero = h[0]; }
}
// retrieve channel names from input file in view-friendly format
GetChannelsInMultiPartFile (infile, input_channels);
vector<MultiViewChannelName> output_channels = input_channels;
// remap channels to multiple output parts
int parts = SplitChannels (
output_channels.begin (), output_channels.end (), true, hero);
vector<Header> output_headers (parts);
vector<FrameBuffer> output_framebuffers (parts);
FrameBuffer input_framebuffer;
//
// make all output headers the same as the input header but
// with no channels
//
for (int i = 0; i < parts; i++)
{
Header& h = output_headers[i];
h = infile.header (0);
if (hasMultiView (h)) h.erase ("multiView");
string fn, pname;
int pnum;
bool pforce;
parse_filename (fn, pname, pforce, pnum);
if (!h.hasName () || pforce) h.setName (pname);
h.channels () = ChannelList ();
}
make_unique_names (output_headers);
const ChannelList& in_chanlist = infile.header (0).channels ();
int channel_count = 0;
for (ChannelList::ConstIterator i = in_chanlist.begin ();
i != in_chanlist.end ();
++i)
{
++channel_count;
}
Box2i dataWindow = infile.header (0).dataWindow ();
int pixel_count =
(dataWindow.size ().y + 1) * (dataWindow.size ().x + 1);
int pixel_width = dataWindow.size ().x + 1;
// offset in pixels between base of array and 0,0
int pixel_base = dataWindow.min.y * pixel_width + dataWindow.min.x;
vector<vector<char>> channelstore (channel_count);
//
// insert channels into correct header and framebuffers
//
for (size_t i = 0; i < input_channels.size (); i++)
{
// read the part we should be writing channel into, insert into header
int part = output_channels[i].part_number;
ChannelList::ConstIterator chan =
in_chanlist.find (input_channels[i].internal_name);
Header& h = output_headers[part];
h.channels ().insert (output_channels[i].name, chan.channel ());
if (output_channels[i].view != "")
{
h.setView (output_channels[i].view);
}
// compute size of channel
size_t samplesize = sizeof (float);
if (chan.channel ().type == HALF) { samplesize = sizeof (half); }
channelstore[i].resize (samplesize * pixel_count);
output_framebuffers[part].insert (
output_channels[i].name,
Slice (
chan.channel ().type,
&channelstore[i][0] - pixel_base * samplesize,
samplesize,
pixel_width * samplesize));
input_framebuffer.insert (
input_channels[i].internal_name,
Slice (
chan.channel ().type,
&channelstore[i][0] - pixel_base * samplesize,
samplesize,
pixel_width * samplesize));
}
//
// create output file
//
MultiPartOutputFile outfile (
outname, &output_headers[0], output_headers.size ());
InputPart inpart (infile, 0);
//
// read file
//
inpart.setFrameBuffer (input_framebuffer);
inpart.readPixels (dataWindow.min.y, dataWindow.max.y);
//
// write each part
//
for (size_t i = 0; i < output_framebuffers.size (); i++)
{
OutputPart outpart (outfile, i);
outpart.setFrameBuffer (output_framebuffers[i]);
outpart.writePixels (dataWindow.max.y + 1 - dataWindow.min.y);
}
h.channels () = ChannelList ();
}
catch (IEX_NAMESPACE::BaseExc& e)
make_unique_names (output_headers);
const ChannelList& in_chanlist = infile.header (0).channels ();
int channel_count = 0;
for (ChannelList::ConstIterator i = in_chanlist.begin ();
i != in_chanlist.end ();
++i)
{
cerr << "\n"
<< "ERROR:" << endl;
cerr << e.what () << endl;
exit (1);
++channel_count;
}
Box2i dataWindow = infile.header (0).dataWindow ();
int pixel_count =
(dataWindow.size ().y + 1) * (dataWindow.size ().x + 1);
int pixel_width = dataWindow.size ().x + 1;
// offset in pixels between base of array and 0,0
int pixel_base = dataWindow.min.y * pixel_width + dataWindow.min.x;
vector<vector<char>> channelstore (channel_count);
//
// insert channels into correct header and framebuffers
//
for (size_t i = 0; i < input_channels.size (); i++)
{
// read the part we should be writing channel into, insert into header
int part = output_channels[i].part_number;
ChannelList::ConstIterator chan =
in_chanlist.find (input_channels[i].internal_name);
Header& h = output_headers[part];
h.channels ().insert (output_channels[i].name, chan.channel ());
if (output_channels[i].view != "")
{
h.setView (output_channels[i].view);
}
// compute size of channel
size_t samplesize = sizeof (float);
if (chan.channel ().type == HALF) { samplesize = sizeof (half); }
channelstore[i].resize (samplesize * pixel_count);
output_framebuffers[part].insert (output_channels[i].name,
Slice (chan.channel ().type,
&channelstore[i][0] - pixel_base * samplesize,
samplesize,
pixel_width * samplesize));
input_framebuffer.insert (input_channels[i].internal_name,
Slice (chan.channel ().type,
&channelstore[i][0] - pixel_base * samplesize,
samplesize,
pixel_width * samplesize));
}
//
// create output file
//
MultiPartOutputFile outfile (outname, &output_headers[0], output_headers.size ());
InputPart inpart (infile, 0);
//
// read file
//
inpart.setFrameBuffer (input_framebuffer);
inpart.readPixels (dataWindow.min.y, dataWindow.max.y);
//
// write each part
//
for (size_t i = 0; i < output_framebuffers.size (); i++)
{
OutputPart outpart (outfile, i);
outpart.setFrameBuffer (output_framebuffers[i]);
outpart.writePixels (dataWindow.max.y + 1 - dataWindow.min.y);
}
}
@@ -447,57 +400,16 @@ combine (
{
fornamecheck.push_back (filename);
try
infile = new MultiPartInputFile (filename.c_str ());
fordelete.push_back (infile);
numparts = infile->parts ();
//copy header from all parts of input to our header array
for (int j = 0; j < numparts; j++)
{
infile = new MultiPartInputFile (filename.c_str ());
fordelete.push_back (infile);
numparts = infile->parts ();
//copy header from all parts of input to our header array
for (int j = 0; j < numparts; j++)
{
inputs.push_back (infile);
Header h = infile->header (j);
if (!h.hasName () || forcepartname) h.setName (partname);
headers.push_back (h);
if (views[i] != NULL)
headers[headers.size () - 1].setView (views[i]);
partnums.push_back (j);
}
}
catch (IEX_NAMESPACE::BaseExc& e)
{
cerr << "\n"
<< "ERROR:" << endl;
cerr << e.what () << endl;
exit (1);
}
} // no user parts specified
else
{
fornamecheck.push_back (filename);
try
{
infile = new MultiPartInputFile (filename.c_str ());
fordelete.push_back (infile);
if (partnum >= infile->parts ())
{
cerr << "ERROR: you asked for part " << partnum << " in "
<< in[i];
cerr << ", which only has " << infile->parts ()
<< " parts\n";
exit (1);
}
//copy header from required part of input to our header array
inputs.push_back (infile);
Header h = infile->header (partnum);
Header h = infile->header (j);
if (!h.hasName () || forcepartname) h.setName (partname);
headers.push_back (h);
@@ -505,15 +417,37 @@ combine (
if (views[i] != NULL)
headers[headers.size () - 1].setView (views[i]);
partnums.push_back (partnum);
partnums.push_back (j);
}
catch (IEX_NAMESPACE::BaseExc& e)
} // no user parts specified
else
{
fornamecheck.push_back (filename);
infile = new MultiPartInputFile (filename.c_str ());
fordelete.push_back (infile);
if (partnum >= infile->parts ())
{
cerr << "\n"
<< "ERROR:" << endl;
cerr << e.what () << endl;
exit (1);
std::stringstream e;
e << "You asked for part " << partnum << " in "
<< in[i]
<< ", which only has " << infile->parts ()
<< " parts";
throw invalid_argument(e.str());
}
//copy header from required part of input to our header array
inputs.push_back (infile);
Header h = infile->header (partnum);
if (!h.hasName () || forcepartname) h.setName (partname);
headers.push_back (h);
if (views[i] != NULL)
headers[headers.size () - 1].setView (views[i]);
partnums.push_back (partnum);
} // user parts specified
}
@@ -528,17 +462,8 @@ combine (
//
// early bail if need be
try
{
MultiPartOutputFile temp (
outname, &headers[0], headers.size (), override);
}
catch (IEX_NAMESPACE::BaseExc& e)
{
cerr << "\n"
<< "ERROR: " << e.what () << endl;
exit (1);
}
MultiPartOutputFile temp (outname, &headers[0], headers.size (), override);
MultiPartOutputFile out (outname, &headers[0], headers.size (), override);
for (size_t p = 0; p < partnums.size (); p++)
@@ -576,7 +501,6 @@ combine (
}
inputs.clear ();
fordelete.size ();
cout << "\n"
<< "Combine Success" << endl;
@@ -586,12 +510,7 @@ void
separate (vector<const char*> in, const char* out, bool override)
{
if (in.size () > 1)
{
cerr
<< "ERROR: -separate only take one input file\n"
"syntax: exrmultipart -separate -i infile.exr -o outfileBaseName\n";
exit (1);
}
throw invalid_argument("-separate only take one input file");
//
// parse the multipart input
@@ -602,16 +521,7 @@ separate (vector<const char*> in, const char* out, bool override)
vector<string> fornamecheck;
// add check for existence of the file
try
{
MultiPartInputFile temp (filename.c_str ());
}
catch (IEX_NAMESPACE::BaseExc& e)
{
cerr << "\n"
<< "ERROR: " << e.what () << endl;
exit (1);
}
MultiPartInputFile temp (filename.c_str ());
inputimage = new MultiPartInputFile (filename.c_str ());
numOutputs = inputimage->parts ();
@@ -674,129 +584,149 @@ separate (vector<const char*> in, const char* out, bool override)
}
void
usageMessage (const char argv[])
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: "
"exrmultipart -combine -i input.exr[:partnum][::partname] "
"[input2.exr[:partnum]][::partname] [...] -o outfile.exr [options]\n";
cerr << " or: exrmultipart -separate -i infile.exr -o outfileBaseName "
"[options]\n";
cerr << " or: exrmultipart -convert -i infile.exr -o outfile.exr "
"[options]\n";
cerr << "\n";
cerr << argv << " handles the combining and splitting of multipart data\n";
cerr << "\n";
cerr << "Options:\n";
cerr << "-override [0/1] 0-do not override conflicting shared "
"attributes [default]\n"
" 1-override conflicting shared attributes\n";
stream << "Usage: " << program_name << "-combine -i input.exr[:partnum][::partname] [input2.exr[:partnum]][::partname] [...] -o outfile.exr [options]\n";
stream << " or: exrmultipart -separate -i infile.exr -o outfileBaseName [options]\n";
stream << " or: exrmultipart -convert -i infile.exr -o outfile.exr [options]\n";
cout << "-view name (after specifying -i) "
"assign following inputs to view 'name'\n";
exit (1);
if (verbose)
stream << "\n"
"Combine or split multipart data\n"
"\n"
"Options:\n"
" -override [0/1] 0 = do not override conflicting shared "
" attributes [default]\n"
" 1 = override conflicting shared attributes\n"
" -view name (after specifying -i) assign following inputs to view 'name'\n"
" -h, --help print this message\n"
"\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
int
main (int argc, char* argv[])
{
if (argc < 6) { usageMessage (argv[0]); }
try {
vector<const char*> inFiles;
vector<const char*> views;
const char* view = 0;
const char* outFile = 0;
bool override = false;
vector<const char*> inFiles;
vector<const char*> views;
const char* view = 0;
const char* outFile = 0;
bool override = false;
int i = 1;
int mode = 0; // 0-do not read input, 1-infiles, 2-outfile, 3-override, 4-view
int i = 1;
int mode =
0; // 0-do not read input, 1-infiles, 2-outfile, 3-override, 4-view
while (i < argc)
{
if (!strcmp (argv[i], "-h")) { usageMessage (argv[0]); }
if (!strcmp (argv[i], "-i")) { mode = 1; }
else if (!strcmp (argv[i], "-o"))
while (i < argc)
{
mode = 2;
}
else if (!strcmp (argv[i], "-override"))
{
mode = 3;
}
else if (!strcmp (argv[i], "-view"))
{
if (mode != 1)
if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
usageMessage (argv[0]);
return 1;
usageMessage (cout, "exrmultipart", true);
return 0;
}
mode = 4;
if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exrmultipart (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
if (!strcmp (argv[i], "-i"))
{
mode = 1;
}
else if (!strcmp (argv[i], "-o"))
{
mode = 2;
}
else if (!strcmp (argv[i], "-override"))
{
mode = 3;
}
else if (!strcmp (argv[i], "-view"))
{
if (mode != 1)
throw invalid_argument("-view requires -i");
mode = 4;
}
else
{
switch (mode)
{
case 1:
inFiles.push_back (argv[i]);
views.push_back (view);
break;
case 2: outFile = argv[i]; break;
case 3: override = atoi (argv[i]); break;
case 4:
view = argv[i];
mode = 1;
break;
}
}
i++;
}
// check input and output files found or not
if (inFiles.size () == 0)
{
usageMessage(cerr, argv[0], false);
return 1;
}
cout << "input:" << endl;
for (size_t i = 0; i < inFiles.size (); i++)
{
cout << " " << inFiles[i];
if (views[i])
cout << " in view " << views[i];
cout << endl;
}
if (!outFile)
throw invalid_argument("No output file specified");
cout << "output:\n " << outFile << endl;
cout << "override:" << override << "\n" << endl;
if (!strcmp (argv[1], "-combine"))
{
cout << "-combine multipart input " << endl;
combine (inFiles, views, outFile, override);
}
else if (!strcmp (argv[1], "-separate"))
{
cout << "-separate multipart input " << endl;
separate (inFiles, outFile, override);
}
else if (!strcmp (argv[1], "-convert"))
{
cout << "-convert input to EXR2 multipart" << endl;
convert (inFiles, views, outFile, override);
}
else
{
switch (mode)
{
case 1:
inFiles.push_back (argv[i]);
views.push_back (view);
break;
case 2: outFile = argv[i]; break;
case 3: override = atoi (argv[i]); break;
case 4:
view = argv[i];
mode = 1;
break;
}
usageMessage (cerr, argv[0], false);
}
i++;
}
// check input and output files found or not
if (inFiles.size () == 0)
catch (const exception& e)
{
cerr << "\n"
<< "ERROR: found no input files" << endl;
exit (1);
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
cout << "input:" << endl;
for (size_t i = 0; i < inFiles.size (); i++)
{
cout << " " << inFiles[i];
if (views[i]) cout << " in view " << views[i];
cout << endl;
}
if (!outFile)
{
cerr << "\n"
<< "ERROR: found no output file" << endl;
exit (1);
}
cout << "output:\n " << outFile << endl;
cout << "override:" << override << "\n" << endl;
if (!strcmp (argv[1], "-combine"))
{
cout << "-combine multipart input " << endl;
combine (inFiles, views, outFile, override);
}
else if (!strcmp (argv[1], "-separate"))
{
cout << "-separate multipart input " << endl;
separate (inFiles, outFile, override);
}
else if (!strcmp (argv[1], "-convert"))
{
cout << "-convert input to EXR2 multipart" << endl;
convert (inFiles, views, outFile, override);
}
else
{
usageMessage (argv[0]);
}
return 0;
}
+114 -104
View File
@@ -11,10 +11,13 @@
//
//-----------------------------------------------------------------------------
#include <makeMultiView.h>
#include "makeMultiView.h"
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <exception>
#include <iostream>
#include <sstream>
#include <stdlib.h>
#include <string.h>
#include <string>
@@ -27,44 +30,38 @@ namespace
{
void
usageMessage (const char argv0[], bool verbose = false)
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: " << argv0
<< " "
"[options] viewname1 infile1 viewname2 infile2 ... outfile"
<< endl;
stream << "Usage: " << program_name << " [options] viewname1 infile1 viewname2 infile2 ... outfile" << endl;
if (verbose)
{
cerr << "\n"
"Combines two or more single-view OpenEXR image files into\n"
"a single multi-view image file. On the command line,\n"
"each single-view input image is specified together with\n"
"a corresponding view name. The first view on the command\n"
"line becomes the default view. Example:\n"
"\n"
" "
<< argv0
<< " left imgL.exr right imgR.exr imgLR.exr\n"
"\n"
"Here, imgL.exr and imgR.exr become the left and right\n"
"views in output file imgLR.exr. The left view becomes\n"
"the default view.\n"
"\n"
"Options:\n"
"\n"
"-z x sets the data compression method to x\n"
" (none/rle/zip/piz/pxr24/b44/b44a/dwaa/dwab,\n"
" default is piz)\n"
"\n"
"-v verbose mode\n"
"\n"
"-h prints this message\n";
cerr << endl;
}
exit (1);
stream << "\n"
"Combine two or more single-view OpenEXR image files into\n"
"a single multi-view image file. On the command line,\n"
"each single-view input image is specified together with\n"
"a corresponding view name. The first view on the command\n"
"line becomes the default view. Example:\n"
"\n"
" exrmultiview left imgL.exr right imgR.exr imgLR.exr\n"
"\n"
"Here, imgL.exr and imgR.exr become the left and right\n"
"views in output file imgLR.exr. The left view becomes\n"
"the default view.\n"
"\n"
"Options:\n"
"\n"
" -z x sets the data compression method to x\n"
" (none/rle/zip/piz/pxr24/b44/b44a/dwaa/dwab,\n"
" default is piz)\n"
"\n"
" -v verbose mode\n"
"\n"
" -h, --help print this message\n"
"\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
Compression
@@ -110,8 +107,9 @@ getCompression (const string& str)
}
else
{
cerr << "Unknown compression method \"" << str << "\"." << endl;
exit (1);
std::stringstream e;
e << "Unknown compression method \"" << str << "\"";
throw invalid_argument(e.str());
}
return c;
@@ -132,97 +130,109 @@ main (int argc, char** argv)
// Parse the command line.
//
if (argc < 2) usageMessage (argv[0], true);
int i = 1;
while (i < argc)
if (argc < 2)
{
if (!strcmp (argv[i], "-z"))
usageMessage (cerr, argv[0], false);
return -1;
}
try {
int i = 1;
while (i < argc)
{
//
// Set compression method
//
if (i > argc - 2) usageMessage (argv[0]);
compression = getCompression (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h"))
{
//
// Print help message
//
usageMessage (argv[0], true);
}
else
{
//
// View or image file name
//
if (i > argc - 2 || argv[i + 1][0] == '-')
if (!strcmp (argv[i], "-z"))
{
//
// Output file
// Set compression method
//
if (outFile) usageMessage (argv[0]);
if (i > argc - 2)
throw invalid_argument("Missing compression value with -z option");
outFile = argv[i];
compression = getCompression (argv[i + 1]);
i += 2;
}
else if (!strcmp (argv[i], "-v"))
{
//
// Verbose mode
//
verbose = true;
i += 1;
}
else if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
//
// Print help message
//
usageMessage (cout, "exrmultiview" , true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exrmultiview (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
else
{
//
// View plus input file
// View or image file name
//
views.push_back (argv[i]);
inFiles.push_back (argv[i + 1]);
i += 2;
if (i > argc - 2 || argv[i + 1][0] == '-')
{
//
// Output file
//
if (outFile)
throw invalid_argument("improper output file specified");
outFile = argv[i];
i += 1;
}
else
{
//
// View plus input file
//
views.push_back (argv[i]);
inFiles.push_back (argv[i + 1]);
i += 2;
}
}
}
}
if (views.size () < 2)
{
cerr << "Must specify at least two views." << endl;
return 1;
}
if (views.size () < 2)
throw invalid_argument ("Must specify at least two views");
if (outFile == 0)
{
cerr << "Must specify an output file." << endl;
return 1;
}
if (outFile == 0)
throw invalid_argument("Must specify an output file");
//
// Load inFiles, and save a combined multi-view image in outFile.
//
//
// Load inFiles, and save a combined multi-view image in outFile.
//
int exitStatus = 0;
try
{
makeMultiView (views, inFiles, outFile, compression, verbose);
}
catch (const exception& e)
{
cerr << e.what () << endl;
exitStatus = 1;
cerr << argv[0] << ": " << e.what () << endl;
return -1;
}
return exitStatus;
return 0;
}
+247 -219
View File
@@ -5,8 +5,8 @@
//-----------------------------------------------------------------------------
//
// exrstdattr -- a program that can set the values of most
// standard attributes in an OpenEXR image file's header.
// exrstdattr -- a program that can set the values of most
// standard attributes in an OpenEXR image file's header.
//
//-----------------------------------------------------------------------------
@@ -29,9 +29,12 @@
#include <ImfTiledOutputFile.h>
#include <ImfTiledOutputPart.h>
#include <ImfVecAttribute.h>
#include <ImfMisc.h>
#include <OpenEXRConfig.h>
#include <exception>
#include <iostream>
#include <sstream>
#include <map>
#include <stdlib.h>
#include <string.h>
@@ -42,173 +45,171 @@ using namespace OPENEXR_IMF_NAMESPACE;
using namespace IMATH_NAMESPACE;
void
usageMessage (const char argv0[], bool verbose = false)
usageMessage (ostream& stream, const char* program_name, bool verbose = false)
{
cerr << "Usage: " << argv0 << " [commands] infile outfile" << endl;
stream << "Usage: " << program_name << " [commands] infile outfile" << endl;
if (verbose)
{
cerr << "\n"
"Reads OpenEXR image file infile, sets the values of one\n"
"or more attributes in the headers of the file, and saves\n"
"the result in outfile. Infile and outfile must not refer\n"
"to the same file (the program cannot edit an image file "
"\"in place\").\n"
"\n"
"Command for selecting headers:\n"
"\n"
" -part i\n"
" If i is greater than or equal to zero, and less\n"
" than the number of parts in the input file, then\n"
" the header for part i becomes \"current.\" If i\n"
" is \"any\" or -1, then all headers become current.\n"
" Subsequent attribute setting commands affect only\n"
" the current header or headers. All headers are\n"
" current before the first -part command.\n"
"\n"
" For example, the command sequence\n"
"\n"
" -focus 3 -part 2 -aperture 8 -expTime 0.01 "
"-part any -owner luke\n"
"\n"
" sets the focus and owner attributes in all\n"
" headers, as well as the aperture and expTime\n"
" attributes in the header of part 2.\n"
"\n"
"Commands for setting attribute values:\n"
"\n"
" -chromaticities f f f f f f f f\n"
" CIE xy chromaticities for the red, green\n"
" and blue primaries, and for the white point\n"
" (8 floats)\n"
"\n"
" -whiteLuminance f\n"
" white luminance, in candelas per square meter\n"
" (float, >= 0.0)\n"
"\n"
" -adoptedNeutral f f\n"
" CIE xy coordinates that should be considered\n"
" \"neutral\" during color rendering. Pixels in\n"
" the image file whose xy coordinates match the\n"
" adoptedNeutral value should be mapped to neutral\n"
" values on the display. (2 floats)\n"
"\n"
" -renderingTransform s\n"
" name of the CTL rendering transform for this\n"
" image (string)\n"
"\n"
" -lookModTransform s\n"
" name of the CTL look modification transform for\n"
" this image (string)\n"
"\n"
" -xDensity f\n"
" horizontal output density, in pixels per inch\n"
" (float, >= 0.0)\n"
"\n"
" -owner s\n"
" name of the owner of the image (string)\n"
"\n"
" -comments s\n"
" additional information about the image (string)\n"
"\n"
" -capDate s\n"
" date when the image was created or\n"
" captured, in local time (string,\n"
" formatted as YYYY:MM:DD hh:mm:ss)\n"
"\n"
" -utcOffset f\n"
" offset of local time at capDate from UTC, in\n"
" seconds (float, UTC == local time + x)\n"
"\n"
" -longitude f\n"
" -latitude f\n"
" -altitude f\n"
" location where the image was recorded, in\n"
" degrees east of Greenwich and north of the\n"
" equator, and in meters above sea level\n"
" (float)\n"
"\n"
" -focus f\n"
" the camera's focus distance, in meters\n"
" (float, > 0, or \"infinity\")\n"
"\n"
" -expTime f\n"
" exposure time, in seconds (float, >= 0)\n"
"\n"
" -aperture f\n"
" lens apterture, in f-stops (float, >= 0)\n"
"\n"
" -isoSpeed f\n"
" effective speed of the film or image\n"
" sensor that was used to record the image\n"
" (float, >= 0)\n"
"\n"
" -envmap s\n"
" indicates that the image is an environment map\n"
" (string, LATLONG or CUBE)\n"
"\n"
" -framesPerSecond i i\n"
" playback frame rate expressed as a ratio of two\n"
" integers, n and d (the frame rate is n/d frames\n"
" per second)\n"
"\n"
" -keyCode i i i i i i i\n"
" key code that uniquely identifies a motion\n"
" picture film frame using 7 integers:\n"
" * film manufacturer code (0 - 99)\n"
" * film type code (0 - 99)\n"
" * prefix to identify film roll (0 - 999999)\n"
" * count, increments once every perfsPerCount\n"
" perforations (0 - 9999)\n"
" * offset of frame, in perforations from\n"
" zero-frame reference mark (0 - 119)\n"
" * number of perforations per frame (1 - 15)\n"
" * number of perforations per count (20 - 120)\n"
"\n"
" -timeCode i i\n"
" SMPTE time and control code, specified as a pair\n"
" of 8-digit base-16 integers. The first number\n"
" contains the time address and flags (drop frame,\n"
" color frame, field/phase, bgf0, bgf1, bgf2).\n"
" The second number contains the user data and\n"
" control codes.\n"
"\n"
" -wrapmodes s\n"
" if the image is used as a texture map, specifies\n"
" how the image should be extrapolated outside the\n"
" zero-to-one texture coordinate range\n"
" (string, e.g. \"clamp\" or \"periodic,clamp\")\n"
"\n"
" -pixelAspectRatio f\n"
" width divided by height of a pixel\n"
" (float, >= 0)\n"
"\n"
" -screenWindowWidth f\n"
" width of the screen window (float, >= 0)\n"
"\n"
" -screenWindowCenter f f\n"
" center of the screen window (2 floats)\n"
"\n"
" -string s s\n"
" custom string attribute\n"
" (2 strings, attribute name and value)\n"
"\n"
" -float s f\n"
" custom float attribute (string + float,\n"
" attribute name and value)\n"
"\n"
" -int s i\n"
" custom integer attribute (string + integer,\n"
" attribute name and value)\n"
"\n"
"Other Commands:\n"
"\n"
" -h prints this message\n";
cerr << endl;
}
exit (1);
stream << "\n"
"Read OpenEXR image file infile, set the values of one\n"
"or more attributes in the headers of the file, and save\n"
"the result in outfile. Infile and outfile must not refer\n"
"to the same file (the program cannot edit an image file "
"\"in place\").\n"
"\n"
"Command for selecting headers:\n"
"\n"
" -part i\n"
" If i is greater than or equal to zero, and less\n"
" than the number of parts in the input file, then\n"
" the header for part i becomes \"current.\" If i\n"
" is \"any\" or -1, then all headers become current.\n"
" Subsequent attribute setting commands affect only\n"
" the current header or headers. All headers are\n"
" current before the first -part command.\n"
"\n"
" For example, the command sequence\n"
"\n"
" -focus 3 -part 2 -aperture 8 -expTime 0.01 "
"-part any -owner luke\n"
"\n"
" sets the focus and owner attributes in all\n"
" headers, as well as the aperture and expTime\n"
" attributes in the header of part 2.\n"
"\n"
"Commands for setting attribute values:\n"
"\n"
" -chromaticities f f f f f f f f\n"
" CIE xy chromaticities for the red, green\n"
" and blue primaries, and for the white point\n"
" (8 floats)\n"
"\n"
" -whiteLuminance f\n"
" white luminance, in candelas per square meter\n"
" (float, >= 0.0)\n"
"\n"
" -adoptedNeutral f f\n"
" CIE xy coordinates that should be considered\n"
" \"neutral\" during color rendering. Pixels in\n"
" the image file whose xy coordinates match the\n"
" adoptedNeutral value should be mapped to neutral\n"
" values on the display. (2 floats)\n"
"\n"
" -renderingTransform s\n"
" name of the CTL rendering transform for this\n"
" image (string). This attribute is deprecated.\n"
"\n"
" -lookModTransform s\n"
" name of the CTL look modification transform for\n"
" this image (string). This attribute is deprecated.\n"
"\n"
" -xDensity f\n"
" horizontal output density, in pixels per inch\n"
" (float, >= 0.0)\n"
"\n"
" -owner s\n"
" name of the owner of the image (string)\n"
"\n"
" -comments s\n"
" additional information about the image (string)\n"
"\n"
" -capDate s\n"
" date when the image was created or\n"
" captured, in local time (string,\n"
" formatted as YYYY:MM:DD hh:mm:ss)\n"
"\n"
" -utcOffset f\n"
" offset of local time at capDate from UTC, in\n"
" seconds (float, UTC == local time + x)\n"
"\n"
" -longitude f\n"
" -latitude f\n"
" -altitude f\n"
" location where the image was recorded, in\n"
" degrees east of Greenwich and north of the\n"
" equator, and in meters above sea level\n"
" (float)\n"
"\n"
" -focus f\n"
" the camera's focus distance, in meters\n"
" (float, > 0, or \"infinity\")\n"
"\n"
" -expTime f\n"
" exposure time, in seconds (float, >= 0)\n"
"\n"
" -aperture f\n"
" lens apterture, in f-stops (float, >= 0)\n"
"\n"
" -isoSpeed f\n"
" effective speed of the film or image\n"
" sensor that was used to record the image\n"
" (float, >= 0)\n"
"\n"
" -envmap s\n"
" indicates that the image is an environment map\n"
" (string, LATLONG or CUBE)\n"
"\n"
" -framesPerSecond i i\n"
" playback frame rate expressed as a ratio of two\n"
" integers, n and d (the frame rate is n/d frames\n"
" per second)\n"
"\n"
" -keyCode i i i i i i i\n"
" key code that uniquely identifies a motion\n"
" picture film frame using 7 integers:\n"
" * film manufacturer code (0 - 99)\n"
" * film type code (0 - 99)\n"
" * prefix to identify film roll (0 - 999999)\n"
" * count, increments once every perfsPerCount\n"
" perforations (0 - 9999)\n"
" * offset of frame, in perforations from\n"
" zero-frame reference mark (0 - 119)\n"
" * number of perforations per frame (1 - 15)\n"
" * number of perforations per count (20 - 120)\n"
"\n"
" -timeCode i i\n"
" SMPTE time and control code, specified as a pair\n"
" of 8-digit base-16 integers. The first number\n"
" contains the time address and flags (drop frame,\n"
" color frame, field/phase, bgf0, bgf1, bgf2).\n"
" The second number contains the user data and\n"
" control codes.\n"
"\n"
" -wrapmodes s\n"
" if the image is used as a texture map, specifies\n"
" how the image should be extrapolated outside the\n"
" zero-to-one texture coordinate range\n"
" (string, e.g. \"clamp\" or \"periodic,clamp\")\n"
"\n"
" -pixelAspectRatio f\n"
" width divided by height of a pixel\n"
" (float, >= 0)\n"
"\n"
" -screenWindowWidth f\n"
" width of the screen window (float, >= 0)\n"
"\n"
" -screenWindowCenter f f\n"
" center of the screen window (2 floats)\n"
"\n"
" -string s s\n"
" custom string attribute\n"
" (2 strings, attribute name and value)\n"
"\n"
" -float s f\n"
" custom float attribute (string + float,\n"
" attribute name and value)\n"
"\n"
" -int s i\n"
" custom integer attribute (string + integer,\n"
" attribute name and value)\n"
"\n"
"Other options:\n"
"\n"
" -h, --help print this message\n"
" --version print version information\n"
"\n"
"Report bugs via https://github.com/AcademySoftwareFoundation/openexr/issues or email security@openexr.com\n"
"";
}
struct SetAttr
@@ -229,11 +230,10 @@ isNonNegative (const char attrName[], float f)
{
if (f < 0)
{
cerr << "The value for the " << attrName
<< " attribute "
"must not be less than zero."
<< endl;
exit (1);
std::stringstream e;
e << "The value for the " << attrName
<< " attribute must not be less than zero";
throw invalid_argument(e.str());
}
}
@@ -242,22 +242,20 @@ isPositive (const char attrName[], float f)
{
if (f <= 0)
{
cerr << "The value for the " << attrName
<< " attribute "
"must be greater than zero."
<< endl;
exit (1);
std::stringstream e;
e << "The value for the " << attrName
<< " attribute must be greater than zero";
throw invalid_argument(e.str());
}
}
void
notValidDate (const char attrName[])
{
cerr << "The value for the " << attrName
<< " attribute "
"is not a valid date of the form \"YYYY:MM:DD yy:mm:ss\"."
<< endl;
exit (1);
std::stringstream e;
e << "The value for the " << attrName
<< " attribute is not a valid date of the form \"YYYY:MM:DD yy:mm:ss\"";
throw invalid_argument(e.str());
}
int
@@ -328,7 +326,8 @@ getFloat (
SetAttrVector& attrs,
void (*check) (const char attrName[], float f) = 0)
{
if (i > argc - 2) usageMessage (argv[0]);
if (i > argc - 2)
throw invalid_argument("Expected a float");
float f = static_cast<float> (strtod (argv[i + 1], 0));
@@ -347,8 +346,9 @@ getPosFloatOrInf (
int part,
SetAttrVector& attrs)
{
if (i > argc - 2) usageMessage (argv[0]);
if (i > argc - 2)
throw invalid_argument("Expected a positive float (or \"infinity\")");
float f;
if (!strcmp (argv[i + 1], "inf") || !strcmp (argv[i + 1], "infinity"))
@@ -361,11 +361,10 @@ getPosFloatOrInf (
if (f <= 0)
{
cerr << "The value for the " << attrName
<< " attribute "
"must be greater than zero, or \"infinity\"."
<< endl;
exit (1);
std::stringstream e;
e << "The value for the " << attrName
<< " attribute must be greater than zero, or \"infinity\"";
throw invalid_argument(e.str());
}
}
@@ -383,7 +382,8 @@ getV2f (
SetAttrVector& attrs,
void (*check) (const char attrName[], const V2f& v) = 0)
{
if (i > argc - 3) usageMessage (argv[0]);
if (i > argc - 3)
throw invalid_argument ("Expected two floats");
V2f v (
static_cast<float> (strtod (argv[i + 1], 0)),
@@ -405,7 +405,8 @@ getRational (
SetAttrVector& attrs,
void (*check) (const char attrName[], const Rational& r) = 0)
{
if (i > argc - 3) usageMessage (argv[0]);
if (i > argc - 3)
throw invalid_argument("Expected a rational");
Rational r (strtol (argv[i + 1], 0, 0), strtol (argv[i + 2], 0, 0));
@@ -425,7 +426,8 @@ getString (
SetAttrVector& attrs,
void (*check) (const char attrName[], const char str[]) = 0)
{
if (i > argc - 2) usageMessage (argv[0]);
if (i > argc - 2)
throw invalid_argument("Expected a string");
const char* str = argv[i + 1];
@@ -438,7 +440,8 @@ getString (
void
getNameAndString (int argc, char** argv, int& i, int part, SetAttrVector& attrs)
{
if (i > argc - 3) usageMessage (argv[0]);
if (i > argc - 3)
throw invalid_argument("Expected a name and string");
const char* attrName = argv[i + 1];
const char* str = argv[i + 2];
@@ -449,7 +452,8 @@ getNameAndString (int argc, char** argv, int& i, int part, SetAttrVector& attrs)
void
getNameAndFloat (int argc, char** argv, int& i, int part, SetAttrVector& attrs)
{
if (i > argc - 3) usageMessage (argv[0]);
if (i > argc - 3)
throw invalid_argument("Expected a name and a float");
const char* attrName = argv[i + 1];
float f = static_cast<float> (strtod (argv[i + 2], 0));
@@ -460,7 +464,8 @@ getNameAndFloat (int argc, char** argv, int& i, int part, SetAttrVector& attrs)
void
getNameAndInt (int argc, char** argv, int& i, int part, SetAttrVector& attrs)
{
if (i > argc - 3) usageMessage (argv[0]);
if (i > argc - 3)
throw invalid_argument("Expected a name and an integer");
const char* attrName = argv[i + 1];
int j = strtol (argv[i + 2], 0, 0);
@@ -477,9 +482,10 @@ getChromaticities (
int part,
SetAttrVector& attrs)
{
if (i > argc - 9) usageMessage (argv[0]);
if (i > argc - 9)
throw invalid_argument("Expected 8 chromaticity values");
ChromaticitiesAttribute* a = new ChromaticitiesAttribute;
ChromaticitiesAttribute* a = new ChromaticitiesAttribute(Chromaticities());
attrs.push_back (SetAttr (attrName, part, a));
a->value ().red.x = static_cast<float> (strtod (argv[i + 1], 0));
@@ -502,7 +508,8 @@ getEnvmap (
int part,
SetAttrVector& attrs)
{
if (i > argc - 2) usageMessage (argv[0]);
if (i > argc - 2)
throw invalid_argument("Expected an env map");
char* str = argv[i + 1];
Envmap type;
@@ -517,11 +524,10 @@ getEnvmap (
}
else
{
cerr << "The value for the " << attrName
<< " attribute "
"must be either LATLONG or CUBE."
<< endl;
exit (1);
std::stringstream e;
e << "The value for the " << attrName
<< " attribute must be either LATLONG or CUBE";
throw invalid_argument(e.str());
}
attrs.push_back (SetAttr (attrName, part, new EnvmapAttribute (type)));
@@ -537,7 +543,8 @@ getKeyCode (
int part,
SetAttrVector& attrs)
{
if (i > argc - 8) usageMessage (argv[0]);
if (i > argc - 8)
throw invalid_argument("Expected a key code");
KeyCodeAttribute* a = new KeyCodeAttribute;
attrs.push_back (SetAttr (attrName, part, a));
@@ -561,7 +568,8 @@ getTimeCode (
int part,
SetAttrVector& attrs)
{
if (i > argc - 3) usageMessage (argv[0]);
if (i > argc - 3)
throw invalid_argument("Expected a time code");
TimeCodeAttribute* a = new TimeCodeAttribute;
attrs.push_back (SetAttr (attrName, part, a));
@@ -574,7 +582,8 @@ getTimeCode (
void
getPart (const char attrName[], int argc, char** argv, int& i, int& part)
{
if (i > argc - 2) usageMessage (argv[0]);
if (i > argc - 2)
throw invalid_argument("Expected a part number (or \"any\")");
if (!strcmp (argv[i + 1], "any"))
part = -1;
@@ -591,9 +600,11 @@ main (int argc, char** argv)
// Parse the command line.
//
if (argc < 2) usageMessage (argv[0], true);
int exitStatus = 0;
if (argc < 2)
{
usageMessage (cerr, argv[0], false);
return 1;
}
try
{
@@ -724,9 +735,23 @@ main (int argc, char** argv)
{
getNameAndInt (argc, argv, i, part, attrs);
}
else if (!strcmp (argv[i], "-h"))
else if (!strcmp (argv[i], "-h") || !strcmp (argv[i], "--help"))
{
usageMessage (argv[0], true);
usageMessage (cout, "exrstdattr", true);
return 0;
}
else if (!strcmp (argv[i], "--version"))
{
const char* libraryVersion = getLibraryVersion();
cout << "exrstdattr (OpenEXR) " << OPENEXR_VERSION_STRING;
if (strcmp(libraryVersion, OPENEXR_VERSION_STRING))
cout << "(OpenEXR version " << libraryVersion << ")";
cout << " https://openexr.com" << endl;
cout << "Copyright (c) Contributors to the OpenEXR Project" << endl;
cout << "License BSD-3-Clause" << endl;
return 0;
}
else
{
@@ -739,13 +764,13 @@ main (int argc, char** argv)
}
}
if (inFileName == 0 || outFileName == 0) usageMessage (argv[0]);
if (inFileName == 0)
throw invalid_argument("Missing input filename");
if (outFileName == 0)
throw invalid_argument("Missing input filename");
if (!strcmp (inFileName, outFileName))
{
cerr << "Input and output cannot be the same file." << endl;
return 1;
}
throw invalid_argument("Input and output cannot be the same file");
//
// Load the headers from the input file
@@ -823,12 +848,15 @@ main (int argc, char** argv)
outPart.copyPixels (inPart);
}
}
for (size_t i=0; i<attrs.size(); i++)
delete attrs[i].attr;
}
catch (const exception& e)
{
cerr << e.what () << endl;
exitStatus = 1;
cerr << argv[0] << ": " << e.what () << endl;
return 1;
}
return exitStatus;
return 0;
}
+28
View File
@@ -0,0 +1,28 @@
cc_test(
name = "OpenEXRExamples",
srcs = [
"deepExamples.cpp",
"deepExamples.h",
"deepTiledExamples.cpp",
"deepTiledExamples.h",
"drawImage.cpp",
"drawImage.h",
"generalInterfaceExamples.cpp",
"generalInterfaceExamples.h",
"generalInterfaceTiledExamples.cpp",
"generalInterfaceTiledExamples.h",
"lowLevelIoExamples.cpp",
"lowLevelIoExamples.h",
"main.cpp",
"multipartExamples.cpp",
"multipartExamples.h",
"namespaceAlias.h",
"previewImageExamples.cpp",
"previewImageExamples.h",
"rgbaInterfaceExamples.cpp",
"rgbaInterfaceExamples.h",
"rgbaInterfaceTiledExamples.cpp",
"rgbaInterfaceTiledExamples.h",
],
deps = ["//:OpenEXR"],
)
+24
View File
@@ -6,6 +6,8 @@
# standalone program linking against an already-installed OpenEXR
# library.
message(STATUS "Building OpenEXR examples")
if("${CMAKE_PROJECT_NAME}" STREQUAL "")
cmake_minimum_required(VERSION 3.12)
project(OpenEXRExamples)
@@ -29,12 +31,28 @@ add_executable(OpenEXRExamples
rgbaInterfaceExamples.h
rgbaInterfaceTiledExamples.cpp
rgbaInterfaceTiledExamples.h
deepExamples.cpp
deepExamples.h
deepTiledExamples.cpp
deepTiledExamples.h
multipartExamples.cpp
multipartExamples.h
)
target_link_libraries(OpenEXRExamples OpenEXR::OpenEXR)
set_target_properties(OpenEXRExamples PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"
)
add_executable(deepidexample deepidexample.cpp)
target_link_libraries(deepidexample OpenEXR::OpenEXR)
add_executable(deepidselect deepidselect.cpp)
target_link_libraries(deepidselect OpenEXR::OpenEXR)
if(WIN32 AND BUILD_SHARED_LIBS)
target_compile_definitions(OpenEXRExamples PRIVATE OPENEXR_DLL)
endif()
@@ -58,6 +76,12 @@ install(
rgbaInterfaceExamples.h
rgbaInterfaceTiledExamples.cpp
rgbaInterfaceTiledExamples.h
deepExamples.cpp
deepExamples.h
deepTiledExamples.cpp
deepTiledExamples.h
multipartExamples.cpp
multipartExamples.h
DESTINATION
${CMAKE_INSTALL_DOCDIR}/examples
)
+256
View File
@@ -0,0 +1,256 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
//-----------------------------------------------------------------------------
//
// Code examples that show how class DeepScanLineInputFile and
// class DeepScanLineOutputFile can be used to read and write
// OpenEXR image files with 16-bit floating-point green,
// and 32-bit floating point depth channels.
//
//-----------------------------------------------------------------------------
#include <ImfArray.h>
#include <ImfHeader.h>
#include <ImfPartType.h>
#include <ImfChannelList.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfDeepScanLineInputFile.h>
#include <ImfDeepScanLineOutputFile.h>
#include "drawImage.h"
#include "namespaceAlias.h"
using namespace IMF;
using namespace std;
using namespace IMATH_NAMESPACE;
void
readDeepScanlineFile (
const char filename[],
Box2i& displayWindow,
Box2i& dataWindow,
Array2D<float*>& dataZ,
Array2D<half*>& dataA,
Array2D<unsigned int>& sampleCount)
{
//
// Read a deep image using class DeepScanLineInputFile. Try to read one
// channel, A, of type HALF, and one channel, Z,
// of type FLOAT. Store the A, and Z pixels in two
// separate memory buffers.
//
// - open the file
// - allocate memory for the pixels
// - describe the layout of the A, and Z pixel buffers
// - read the sample counts from the file
// - allocate the memory requred to store the samples
// - read the pixels from the file
//
DeepScanLineInputFile file (filename);
const Header& header = file.header ();
dataWindow = header.dataWindow ();
displayWindow = header.displayWindow ();
int width = dataWindow.max.x - dataWindow.min.x + 1;
int height = dataWindow.max.y - dataWindow.min.y + 1;
sampleCount.resizeErase (height, width);
dataZ.resizeErase (height, width);
dataA.resizeErase (height, width);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice (Slice (
UINT,
(char*) (&sampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (unsigned int) * 1, // xStride
sizeof (unsigned int) * width)); // yStride
frameBuffer.insert (
"dataZ",
DeepSlice (
FLOAT,
(char*) (&dataZ[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (float*) * 1, // xStride for pointer array
sizeof (float*) * width, // yStride for pointer array
sizeof (float) * 1)); // stride for Z data sample
frameBuffer.insert (
"dataA",
DeepSlice (
HALF,
(char*) (&dataA[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (half*) * 1, // xStride for pointer array
sizeof (half*) * width, // yStride for pointer array
sizeof (half) * 1)); // stride for O data sample
file.setFrameBuffer (frameBuffer);
file.readPixelSampleCounts (dataWindow.min.y, dataWindow.max.y);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
dataZ[i][j] = new float[sampleCount[i][j]];
dataA[i][j] = new half[sampleCount[i][j]];
}
}
file.readPixels (dataWindow.min.y, dataWindow.max.y);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
delete[] dataZ[i][j];
delete[] dataA[i][j];
}
}
}
unsigned int getPixelSampleCount (int i, int j)
{
// Dummy code creating deep data from a flat image
return 1;
}
Array2D<float> testDataZ;
Array2D<half> testDataA;
void getPixelSampleData(
int i,
int j,
Array2D<float*>& dataZ,
Array2D<half*>& dataA)
{
// Dummy code creating deep data from a flat image
dataZ[i][j][0] = testDataZ[i][j];
dataA[i][j][0] = testDataA[i][j];
}
void
writeDeepScanlineFile (
const char filename[],
Box2i displayWindow,
Box2i dataWindow,
Array2D<float*>& dataZ,
Array2D<half*>& dataA,
Array2D<unsigned int>& sampleCount)
{
//
// Write a deep image with only a A (alpha) and a Z (depth) channel,
// using class DeepScanLineOutputFile.
//
// - create a file header
// - add A and Z channels to the header
// - open the file, and store the header in the file
// - describe the memory layout of the A and Z pixels
// - store the pixels in the file
//
int height = dataWindow.max.y - dataWindow.min.y + 1;
int width = dataWindow.max.x - dataWindow.min.x + 1;
Header header (displayWindow, dataWindow);
header.channels ().insert ("Z", Channel (FLOAT));
header.channels ().insert ("A", Channel (HALF));
header.setType (DEEPSCANLINE);
header.compression () = ZIPS_COMPRESSION;
DeepScanLineOutputFile file (filename, header);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice (Slice (
UINT,
(char*) (&sampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (unsigned int) * 1, // xS
sizeof (unsigned int) * width)); // yStride
frameBuffer.insert (
"Z",
DeepSlice (
FLOAT,
(char*) (&dataZ[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (float*) * 1, // xStride for pointer
sizeof (float*) * width, // yStride for pointer array
sizeof (float) * 1)); // stride for Z data sample
frameBuffer.insert (
"A",
DeepSlice (
HALF,
(char*) (&dataA[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (half*) * 1, // xStride for pointer array
sizeof (half*) * width, // yStride for pointer array
sizeof (half) * 1)); // stride for A data sample
file.setFrameBuffer (frameBuffer);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
sampleCount[i][j] = getPixelSampleCount (i, j);
dataZ[i][j] = new float[sampleCount[i][j]];
dataA[i][j] = new half[sampleCount[i][j]];
// Generate data for dataZ and dataA.
getPixelSampleData(i, j, dataZ, dataA);
}
file.writePixels (1);
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
delete[] dataZ[i][j];
delete[] dataA[i][j];
}
}
}
void deepExamples()
{
int w = 800;
int h = 600;
Box2i window;
window.min.setValue(0, 0);
window.max.setValue(w - 1, h - 1);
Array2D<float *> dataZ;
dataZ.resizeErase(h, w);
Array2D<half *> dataA;
dataA.resizeErase(h, w);
Array2D<unsigned int> sampleCount;
sampleCount.resizeErase(h, w);
// Create an image to be used as a source for deep data
testDataA.resizeErase(h, w);
testDataZ.resizeErase(h, w);
drawImage2(testDataA, testDataZ, w, h);
writeDeepScanlineFile("test.deep.exr", window, window, dataZ, dataA, sampleCount);
readDeepScanlineFile ("test.deep.exr", window, window, dataZ, dataA, sampleCount);
}
+6
View File
@@ -0,0 +1,6 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
void deepExamples ();
+278
View File
@@ -0,0 +1,278 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
//-----------------------------------------------------------------------------
//
// Code examples that show how class DeepTiledInputFile and
// class DeepTiledOutputFile can be used to read and write
// OpenEXR image files with 16-bit floating-point green,
// and 32-bit floating point depth channels.
//
//-----------------------------------------------------------------------------
#include <ImfArray.h>
#include <ImfHeader.h>
#include <ImfPartType.h>
#include <ImfChannelList.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfDeepTiledInputFile.h>
#include <ImfDeepTiledOutputFile.h>
#include "drawImage.h"
#include "namespaceAlias.h"
using namespace IMF;
using namespace std;
using namespace IMATH_NAMESPACE;
// defined in deepExamples.cpp
extern Array2D<float> testDataZ;
extern Array2D<half> testDataA;
extern unsigned int getPixelSampleCount (int i, int j);
extern void getPixelSampleData(
int i,
int j,
Array2D<float*>& dataZ,
Array2D<half*>& dataA);
void
readDeepTiledFile (
const char filename[],
Box2i& displayWindow,
Box2i& dataWindow,
Array2D<float*>& dataZ,
Array2D<half*>& dataA,
Array2D<unsigned int>& sampleCount)
{
//
// Read a deep image using class DeepTiledInputFile. Try to read one
// channel, A, of type HALF, and one channel, Z,
// of type FLOAT. Store the A, and Z pixels in two
// separate memory buffers.
//
// - open the file
// - allocate memory for the pixels
// - describe the layout of the A, and Z pixel buffers
// - read the sample counts from the file
// - allocate the memory requred to store the samples
// - read the pixels from the file
//
DeepTiledInputFile file (filename);
int width = dataWindow.max.x - dataWindow.min.x + 1;
int height = dataWindow.max.y - dataWindow.min.y + 1;
sampleCount.resizeErase (height, width);
dataZ.resizeErase (height, width);
dataA.resizeErase (height, width);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice (Slice (
UINT,
(char*) (&sampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (unsigned int) * 1, // xStride
sizeof (unsigned int) * width)); // yStride
frameBuffer.insert (
"Z",
DeepSlice (
FLOAT,
(char*) (&dataZ[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (float*) * 1, // xStride for pointer array
sizeof (float*) * width, // yStride for pointer array
sizeof (float) * 1)); // stride for samples
frameBuffer.insert (
"A",
DeepSlice (
HALF,
(char*) (&dataA[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (half*) * 1, // xStride for pointer array
sizeof (half*) * width, // yStride for pointer array
sizeof (half) * 1)); // stride for samples
file.setFrameBuffer (frameBuffer);
int numXTiles = file.numXTiles (0);
int numYTiles = file.numYTiles (0);
file.readPixelSampleCounts (0, numXTiles - 1, 0, numYTiles - 1);
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
dataZ[i][j] = new float[sampleCount[i][j]];
dataA[i][j] = new half[sampleCount[i][j]];
}
}
file.readTiles (0, numXTiles - 1, 0, numYTiles - 1);
// (after read data is processed, data must be freed:)
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
delete[] dataZ[i][j];
delete[] dataA[i][j];
}
}
}
void getSampleDataForTile (
int i,
int j,
int tileSizeX,
int tileSizeY,
Array2D<unsigned int>& sampleCount,
Array2D<float*>& dataZ,
Array2D<half*>& dataA)
{
for (int k = 0; k < tileSizeY; k++)
{
int y = j * tileSizeY + k;
if (y >= sampleCount.height()) break;
for (int l = 0; l < tileSizeX; l++)
{
int x = i * tileSizeX + l;
if (x >= sampleCount.width()) break;
sampleCount[y][x] = getPixelSampleCount(y, x);
dataZ[y][x] = new float[sampleCount[y][x]];
dataA[y][x] = new half [sampleCount[y][x]];
getPixelSampleData(y, x, dataZ, dataA);
}
}
}
void
writeDeepTiledFile (
const char filename[],
Box2i displayWindow,
Box2i dataWindow,
int tileSizeX,
int tileSizeY)
{
//
// Write a deep image with only a A (alpha) and a Z (depth) channel,
// using class DeepTiledOutputFile.
//
// - create a file header
// - add A and Z channels to the header
// - open the file, and store the header in the file
// - describe the memory layout of the A and Z pixels
// - store the pixels in the file
//
int height = dataWindow.max.y - dataWindow.min.y + 1;
int width = dataWindow.max.x - dataWindow.min.x + 1;
Header header (displayWindow, dataWindow);
header.channels ().insert ("Z", Channel (FLOAT));
header.channels ().insert ("A", Channel (HALF));
header.setType (DEEPTILE);
header.compression () = ZIPS_COMPRESSION;
header.setTileDescription (
TileDescription (tileSizeX, tileSizeY, ONE_LEVEL));
Array2D<float*> dataZ;
dataZ.resizeErase (height, width);
Array2D<half*> dataA;
dataA.resizeErase (height, width);
Array2D<unsigned int> sampleCount;
sampleCount.resizeErase (height, width);
DeepTiledOutputFile file (filename, header);
DeepFrameBuffer frameBuffer;
frameBuffer.insertSampleCountSlice (Slice (
UINT,
(char*) (&sampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (unsigned int) * 1, // xStride
sizeof (unsigned int) * width)); // yStride
frameBuffer.insert (
"Z",
DeepSlice (
FLOAT,
(char*) (&dataZ[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (float*) * 1, // xStride for pointer array
sizeof (float*) * width, // yStride for pointer array
sizeof (float) * 1)); // stride for samples
frameBuffer.insert (
"A",
DeepSlice (
HALF,
(char*) (&dataA[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (half*) * 1, // xStride for pointer array
sizeof (half*) * width, // yStride for pointer array
sizeof (half) * 1)); // stride for samples
file.setFrameBuffer (frameBuffer);
for (int j = 0; j < file.numYTiles (0); j++)
{
for (int i = 0; i < file.numXTiles (0); i++)
{
// Generate data for sampleCount, dataZ and dataA.
getSampleDataForTile (i, j, tileSizeX, tileSizeY, sampleCount, dataZ, dataA);
file.writeTile (i, j, 0);
}
}
for (int i = 0; i < height; i++)
{
for (int j = 0; j < width; j++)
{
delete[] dataZ[i][j];
delete[] dataA[i][j];
}
}
}
void deepTiledExamples()
{
int w = 800;
int h = 600;
int tileSizeX = 64;
int tileSizeY = 64;
Box2i window;
window.min.setValue(0, 0);
window.max.setValue(w - 1, h - 1);
Array2D<float *> dataZ;
dataZ.resizeErase(h, w);
Array2D<half *> dataA;
dataA.resizeErase(h, w);
Array2D<unsigned int> sampleCount;
sampleCount.resizeErase(h, w);
// Create an image to be used as a source for deep data
testDataA.resizeErase(h, w);
testDataZ.resizeErase(h, w);
drawImage2(testDataA, testDataZ, w, h);
writeDeepTiledFile("testTiled.deep.exr", window, window, tileSizeX, tileSizeY);
readDeepTiledFile ("testTiled.deep.exr", window, window, dataZ, dataA, sampleCount);
}
+6
View File
@@ -0,0 +1,6 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
void deepTiledExamples ();
+689
View File
@@ -0,0 +1,689 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
//
// example of writing a file with DeepIDs.
// Creates a deep file with a series of circles and 'blobs' (2D Guassian-like objects)
// of different colors and sizes, each with two or three ID channels, and an idmanifest
// to store the respective names.
//
//
#include <ImfChannelList.h>
#include <ImfDeepScanLineOutputFile.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfIDManifest.h>
#include <ImfStandardAttributes.h>
#include <string.h>
#include <algorithm>
#include <iostream>
#include <random>
#include <set>
#include <vector>
using namespace OPENEXR_IMF_NAMESPACE;
using std::cerr;
using std::set;
using std::sort;
using std::vector;
void
printHelp ()
{
cerr
<< "syntax: deepidexample options output.deep.exr\n\n";
cerr << "--multivariate : combine 'material' and 'model' name into a single ID channel, rather than separate channels\n";
cerr << "--64 : use 64 bit hashes in two channels, rather than a single channel 32 bit hash\n";
cerr << "--frame number : specify animation frame number. Animation cycles every 200 frames\n";
cerr << "--objectid : store object ids in a simple stringvector format rather than the idmanifest attribute\n";
cerr << "--size width height : specify image dimensions for output (default 256 256)\n";
cerr << "--count number : number of objects to write (default 100)\n";
}
//
// a 'sample' as written to the deep file, with RGBA, depth, and up to five ID channels
//
struct Rgbaz
{
half r, g, b, a, z;
uint32_t id0, id1, id2, id3, id4;
//
// depth sort (use ID to resolve ties)
//
bool operator<(const Rgbaz& other) const
{
if (z < other.z) { return true; }
if (z > other.z) { return false; }
return id4 < other.id4;
}
};
//
// object model names
//
static const char* shapeNames[] = {"blob", "circle"};
static const char* sizeNames[] = {"small", "medium", "big"};
//
// seven colors, names and RGB values of each
//
static const char* colorNames[] = {
"white", "red", "green", "blue", "cyan", "magenta", "yellow"};
struct Rgbaz colors[] = {
{0.9, 0.9, 0.9},
{0.9, 0.1, 0.1},
{0.1, 0.9, 0.1},
{0.1, 0.1, 0.9},
{0.1, 0.9, 0.9},
{0.9, 0.1, 0.9},
{0.9, 0.9, 0.1}};
int random (std::default_random_engine& generator, int max);
void drawBlob (
std::vector<std::vector<Rgbaz>>& image,
int width,
int height,
float x,
float y,
float z,
int size,
int color,
const uint32_t* ids);
void drawCircle (
std::vector<std::vector<Rgbaz>>& image,
int width,
int height,
float x,
float y,
float z,
int size,
int color,
const uint32_t* ids);
int
main (int argc, char* argv[])
{
char* outputFile = nullptr;
bool hash64 = false;
bool multivariate = false;
bool objectID = false;
int width = 256;
int height = 256;
int count = 100;
int frame = 0;
// parse options
for (int i = 1; i < argc; ++i)
{
if (strncmp (argv[i], "--64", 3) == 0) { hash64 = true; }
else if (strncmp (argv[i], "--multivariate", 3) == 0)
{
multivariate = true;
}
else if (strncmp (argv[i], "--help", 3) == 0)
{
printHelp ();
return 0;
}
else if (strncmp (argv[i], "--size", 3) == 0)
{
if (argc < i + 2)
{
printHelp ();
return 1;
}
width = atoi (argv[i + 1]);
height = atoi (argv[i + 2]);
i += 2;
}
else if (strncmp (argv[i], "--count", 3) == 0)
{
if (argc < i + 1)
{
printHelp ();
return 1;
}
count = atoi (argv[i + 1]);
i += 1;
}
else if (strncmp (argv[i], "--frame", 3) == 0)
{
if (argc < i + 1)
{
printHelp ();
return 1;
}
frame = atoi (argv[i + 1]);
i += 1;
}
else if (strncmp (argv[i], "--objectid", 3) == 0) { objectID = true; }
else if (outputFile == nullptr) { outputFile = argv[i]; }
else
{
printHelp ();
return 1;
}
}
if (outputFile == nullptr)
{
cerr << "error: need to specify output filename\n";
printHelp ();
return 1;
}
if (objectID)
{
if (!multivariate || hash64)
{
cerr
<< "error: --objectid mode only works with --multivariate on and --64 off\n";
return 1;
}
}
//
// initialize manifest object
//
IDManifest::ChannelGroupManifest modelOrMultiManifest;
IDManifest::ChannelGroupManifest materialManifest;
std::vector<std::string> oldObjectID;
if (multivariate)
{
if (hash64)
{
set<string> ids;
ids.insert ("id0");
ids.insert ("id1");
modelOrMultiManifest.setChannels (ids);
modelOrMultiManifest.setEncodingScheme (IDManifest::ID2_SCHEME);
modelOrMultiManifest.setHashScheme (IDManifest::MURMURHASH3_64);
}
else
{
modelOrMultiManifest.setChannel ("id");
modelOrMultiManifest.setEncodingScheme (IDManifest::ID_SCHEME);
modelOrMultiManifest.setHashScheme (IDManifest::MURMURHASH3_32);
}
vector<string> components (2);
components[0] = "model";
components[1] = "material";
modelOrMultiManifest.setComponents (components);
}
else
{
if (hash64)
{
set<string> model;
model.insert ("model.id0");
model.insert ("model.id1");
modelOrMultiManifest.setChannels (model);
modelOrMultiManifest.setEncodingScheme (IDManifest::ID2_SCHEME);
modelOrMultiManifest.setHashScheme (IDManifest::MURMURHASH3_64);
set<string> material;
material.insert ("material.id0");
material.insert ("material.id1");
materialManifest.setChannels (material);
materialManifest.setEncodingScheme (IDManifest::ID2_SCHEME);
materialManifest.setHashScheme (IDManifest::MURMURHASH3_64);
}
else
{
modelOrMultiManifest.setChannel ("modelid");
materialManifest.setChannel ("materialid");
modelOrMultiManifest.setEncodingScheme (IDManifest::ID_SCHEME);
modelOrMultiManifest.setHashScheme (IDManifest::MURMURHASH3_32);
materialManifest.setEncodingScheme (IDManifest::ID_SCHEME);
materialManifest.setHashScheme (IDManifest::MURMURHASH3_32);
}
modelOrMultiManifest.setComponent ("model");
materialManifest.setComponent ("material");
}
modelOrMultiManifest.setLifetime (IDManifest::LIFETIME_STABLE);
materialManifest.setLifetime (IDManifest::LIFETIME_STABLE);
//
// draw image
//
vector<vector<Rgbaz>> deepImage (width * height);
std::default_random_engine generator;
generator.seed (2);
uint32_t ids[5];
//
// animation oscillates between two random positions
// over 100 frames
//
float blend = 0.5 - cos (double (frame) * M_PI / 100.) / 2;
for (int object = 0; object < count; ++object)
{
int shape = random (generator, 1);
int size = random (generator, 2);
int color = random (generator, 6);
//
// generate ID
//
if (multivariate)
{
vector<string> s (2);
s[0] = string (shapeNames[shape]) + "/" + string (sizeNames[size]);
s[1] = colorNames[color];
uint64_t hash = modelOrMultiManifest.insert (s);
ids[0] = hash & 0xFFFFFFFF;
// only needed for 64 bit hash scheme: store most significant 32 bits in ids[1]
ids[1] = hash >> 32;
if (objectID)
{
oldObjectID.push_back (
s[0] + "," + s[1] + "," + std::to_string (ids[0]));
}
}
else
{
uint64_t hash = modelOrMultiManifest.insert (
string (shapeNames[shape]) + "/" + string (sizeNames[size]));
ids[0] = hash & 0xFFFFFFFF;
ids[1] = hash >> 32;
hash = materialManifest.insert (colorNames[color]);
ids[2] = hash & 0xFFFFFFFF;
ids[3] = hash >> 32;
}
ids[4] = object; // particle ID
//
// randomized position, velocity, depth
//
int x1 = random (generator, width);
int y1 = random (generator, height);
int x2 = random (generator, width);
int y2 = random (generator, height);
float z = random (generator, 4096) / 2.f;
float x = blend * x2 + (1.0 - blend) * x1;
float y = blend * y2 + (1.0 - blend) * y1;
if (shape == 0)
{
drawBlob (deepImage, width, height, x, y, z, size, color, ids);
}
else
{
drawCircle (deepImage, width, height, x, y, z, size, color, ids);
}
}
//
// initialize pointers required by OpenEXR API to indicate address of first sample of each channel of each pixel
//
vector<int> sampleCounts (width * height);
vector<char*> ptrR (width * height);
vector<char*> ptrG (width * height);
vector<char*> ptrB (width * height);
vector<char*> ptrA (width * height);
vector<char*> ptrZ (width * height);
vector<char*> ptrID0 (width * height);
vector<char*> ptrID1 (width * height);
vector<char*> ptrID2 (width * height);
vector<char*> ptrID3 (width * height);
vector<char*> ptrID4 (width * height);
for (int i = 0; i < width * height; ++i)
{
sampleCounts[i] = int (deepImage[i].size ());
if (sampleCounts[i] > 0)
{
//
// store samples depth sorted
//
sort (deepImage[i].begin (), deepImage[i].end ());
ptrR[i] = (char*) &deepImage[i][0].r;
ptrG[i] = (char*) &deepImage[i][0].g;
ptrB[i] = (char*) &deepImage[i][0].b;
ptrA[i] = (char*) &deepImage[i][0].a;
ptrZ[i] = (char*) &deepImage[i][0].z;
ptrID0[i] = (char*) &deepImage[i][0].id0;
ptrID1[i] = (char*) &deepImage[i][0].id1;
ptrID2[i] = (char*) &deepImage[i][0].id2;
ptrID3[i] = (char*) &deepImage[i][0].id3;
ptrID4[i] = (char*) &deepImage[i][0].id4;
}
}
// save file
Header h (width, height);
h.compression () = ZIPS_COMPRESSION;
DeepFrameBuffer buf;
buf.insertSampleCountSlice (Slice (
UINT,
(char*) sampleCounts.data (),
sizeof (int),
sizeof (int) * width));
h.channels ().insert ("R", Channel (HALF));
buf.insert (
"R",
DeepSlice (
HALF,
(char*) ptrR.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("G", Channel (HALF));
buf.insert (
"G",
DeepSlice (
HALF,
(char*) ptrG.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("B", Channel (HALF));
buf.insert (
"B",
DeepSlice (
HALF,
(char*) ptrB.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("A", Channel (HALF));
buf.insert (
"A",
DeepSlice (
HALF,
(char*) ptrA.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("Z", Channel (HALF));
buf.insert (
"Z",
DeepSlice (
HALF,
(char*) ptrZ.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
if (multivariate)
{
if (hash64)
{
h.channels ().insert ("id.id0", UINT);
buf.insert (
"id.id0",
DeepSlice (
UINT,
(char*) ptrID0.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("id.id1", UINT);
buf.insert (
"id.id1",
DeepSlice (
UINT,
(char*) ptrID1.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
}
else
{
h.channels ().insert ("id", UINT);
buf.insert (
"id",
DeepSlice (
UINT,
(char*) ptrID0.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
}
}
else
{
if (hash64)
{
h.channels ().insert ("model.id0", UINT);
buf.insert (
"model.id0",
DeepSlice (
UINT,
(char*) ptrID0.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("model.id1", UINT);
buf.insert (
"model.id1",
DeepSlice (
UINT,
(char*) ptrID1.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("material.id0", UINT);
buf.insert (
"material.id0",
DeepSlice (
UINT,
(char*) ptrID2.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("material.id1", UINT);
buf.insert (
"material.id1",
DeepSlice (
UINT,
(char*) ptrID3.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
}
else
{
h.channels ().insert ("modelid", UINT);
buf.insert (
"modelid",
DeepSlice (
UINT,
(char*) ptrID0.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
h.channels ().insert ("materialid", UINT);
buf.insert (
"materialid",
DeepSlice (
UINT,
(char*) ptrID2.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
}
}
h.channels ().insert ("particleid", UINT);
buf.insert (
"particleid",
DeepSlice (
UINT,
(char*) ptrID4.data (),
sizeof (char*),
sizeof (char*) * width,
sizeof (Rgbaz)));
if (objectID)
{
h.insert ("objectID", StringVectorAttribute (oldObjectID));
}
else
{
IDManifest manifest;
manifest.add (modelOrMultiManifest);
if (!multivariate) { manifest.add (materialManifest); }
IDManifest::ChannelGroupManifest particleManifest;
particleManifest.setChannel ("particleid");
particleManifest.setEncodingScheme (IDManifest::ID_SCHEME);
particleManifest.setHashScheme (IDManifest::NOTHASHED);
particleManifest.setLifetime (IDManifest::LIFETIME_SHOT);
manifest.add (particleManifest);
addIDManifest (h, manifest);
}
//
// samples are depth sorted, and do not overlap
//
addDeepImageState (h, DIS_TIDY);
DeepScanLineOutputFile file (outputFile, h);
file.setFrameBuffer (buf);
file.writePixels (height);
}
int
random (std::default_random_engine& generator, int max)
{
std::uniform_int_distribution<int> dist (0, max);
return dist (generator);
}
void
drawBlob (
std::vector<std::vector<Rgbaz>>& image,
int width,
int height,
float x,
float y,
float z,
int size,
int color,
const uint32_t* ids)
{
//
// draw windowed gaussian centered at (x,y)
//
float sigma = 5 + 40 * size;
int ptr = 0;
Rgbaz point;
point.z = z;
point.id0 = ids[0];
point.id1 = ids[1];
point.id2 = ids[2];
point.id3 = ids[3];
point.id4 = ids[4];
for (int j = 0; j < height; ++j)
{
for (int i = 0; i < width; ++i)
{
float dist_sq = (x - i) * (x - i) + (j - y) * (j - y);
float scale =
exp (-dist_sq / sigma) * (1.f - sqrt (dist_sq) / sigma);
if (scale > 0.001)
{
point.r = colors[color].r * scale;
point.g = colors[color].g * scale;
point.b = colors[color].b * scale;
point.a = scale;
image[ptr].push_back (point);
}
ptr++;
}
}
}
float
getAlpha (float xmin, float ymin, float xmax, float ymax, float size)
{
bool in1 = xmin * xmin + ymin * ymin < size * size;
bool in2 = xmax * xmax + ymin * ymin < size * size;
bool in3 = xmin * xmin + ymax * ymax < size * size;
bool in4 = xmin * xmin + ymax * ymax < size * size;
if (in1 && in2 && in3 && in4) { return (xmax - xmin) * (ymax - ymin); }
if (!in1 && !in2 && !in3 && !in4) { return 0.f; }
if (xmax - xmin < 0.001 && ymax - ymin < 0.001) { return 0.f; }
return getAlpha (xmin, ymin, (xmin + xmax) / 2, (ymin + ymax) / 2, size) +
getAlpha ((xmin + xmax) / 2, ymin, xmax, (ymin + ymax) / 2, size) +
getAlpha (xmin, (ymin + ymax) / 2, (xmin + xmax) / 2, ymax, size) +
getAlpha ((xmin + xmax) / 2, (ymin + ymax) / 2, xmax, ymax, size);
}
void
drawCircle (
std::vector<std::vector<Rgbaz>>& image,
int width,
int height,
float x,
float y,
float z,
int size,
int color,
const uint32_t* ids)
{
int ptr = 0;
float radius = 3 + 8 * size;
Rgbaz point;
point.z = z;
point.id0 = ids[0];
point.id1 = ids[1];
point.id2 = ids[2];
point.id3 = ids[3];
point.id4 = ids[4];
for (int j = 0; j < height; ++j)
{
for (int i = 0; i < width; ++i)
{
float alpha = getAlpha (
i - x - 0.5f, j - y - 0.5f, i - x + 0.5f, j - y + 0.5f, radius);
if (alpha > 0)
{
point.r = colors[color].r * alpha;
point.g = colors[color].g * alpha;
point.b = colors[color].b * alpha;
point.a = alpha;
image[ptr].push_back (point);
}
ptr++;
}
}
}
+540
View File
@@ -0,0 +1,540 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
//
// example of using an IDManifest to locate given objects in a deep image with IDs
// demonstrates how to use multivariate IDs, and 64 bit IDs spread across two channels
// deepidexample will create images that can be used as input
// (though this tool is intended to support images from other sources)
//
#include <ImfChannelList.h>
#include <ImfMultiPartInputFile.h>
#include <ImfDeepScanLineInputPart.h>
#include <ImfMultiPartOutputFile.h>
#include <ImfDeepScanLineOutputPart.h>
#include <ImfOutputPart.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfIDManifest.h>
#include <ImfStandardAttributes.h>
#include <ImfPartType.h>
#include <iomanip>
#include <list>
#include <map>
#include <vector>
using namespace OPENEXR_IMF_NAMESPACE;
using namespace IMATH_NAMESPACE;
using std::cerr;
using std::dec;
using std::endl;
using std::hex;
using std::list;
using std::map;
using std::set;
using std::stoi;
using std::vector;
struct match
{
int channel1; // index of first channel to look up ID in
uint32_t id1; // first ID
int channel2; // index of second channel, or -1 if only one channel
uint32_t id2; // second ID, ignored channel2==-1
};
//
// setIds parses the matches arguments, and populates lists of matching IDs. If there are '--and' statements in the matches
// ids are entered in a new list
//
void setIds (
const IDManifest& mfst,
list<list<match>>& ids,
const char* matches[],
int numMatches,
const map<string, int>& channelToPos);
int
main (int argc, const char* argv[])
{
if (argc < 4)
{
cerr
<< "syntax: [--mask] input.exr match [match...] [--and match [match...]] output.exr\n"
<< " if --mask specified, writes a shallow EXR with a mask of the selected object(s) in the 'A' channel\n"
<< " otherwise, writes a deep EXR only containing the selected object(s)\n"
<< '\n'
<< " matches can be:\n"
<< " searchstring - match any component of any channel\n"
<< " componentname:searchstring - only match given component\n"
<< " channelname:number - match specified numeric ID in given channel\n"
<< '\n'
<< "\"A B --and C D\" means \"(must match either A or B) and also (must match either C or D)\"\n"
<< " e.g:\n"
<< " input.deep.exr blue output.deep.exr\n"
<< " input.deep.exr material:blue --and model:blob output.deep.exr\n"
<< " input.deep.exr material:blue material:red --and model:blob output.deep.exr\n"
<< " input.deep.exr particleid:3 output.deep.exr\n";
return 1;
}
bool mask = false;
int numMatchArguments = argc - 2;
const char** matchArguments = argv + 2;
const char* inputFile = argv[1];
if (strcmp (argv[1], "--mask") == 0)
{
mask = true;
numMatchArguments--;
matchArguments++;
inputFile = argv[2];
}
MultiPartInputFile input (inputFile);
if (!hasIDManifest (input.header (0)))
{
cerr << "deepidselect requires an ID manifest in the EXR header\n";
return 1;
}
for (int i = 0; i < input.parts (); ++i)
{
if (input.header (i).type () != DEEPSCANLINE)
{
cerr
<< "deepidselect currently only supports files which are entirely deep scanline files\n";
return 1;
}
}
//
// build output headers. For deep output, this is easy: just copy them over
// for masks, build scanline images of the same dimensions, each with a single alpha channel
//
vector<Header> hdrs (input.parts ());
if (mask)
{
for (int h = 0; h < input.parts (); ++h)
{
const Header& inHdr = input.header (h);
hdrs[h].dataWindow () = inHdr.dataWindow ();
hdrs[h].setType (SCANLINEIMAGE);
hdrs[h].displayWindow () = inHdr.displayWindow ();
if (inHdr.hasView ()) { hdrs[h].setView (inHdr.view ()); }
if (inHdr.hasName ()) { hdrs[h].setName (inHdr.name ()); }
hdrs[h].channels ().insert ("A", Channel (HALF));
}
}
else
{
for (int h = 0; h < input.parts (); ++h)
{
hdrs[h] = input.header (h);
}
}
MultiPartOutputFile output (argv[argc - 1], hdrs.data (), input.parts ());
// process each part individually
for (int pt = 0; pt < input.parts (); ++pt)
{
const Header& inputHeader = input.header (pt);
const ChannelList& inputChans = inputHeader.channels ();
Box2i dataWindow = inputHeader.dataWindow ();
int width = dataWindow.max.x + 1 - dataWindow.min.x;
map<string, int>
channelToPos; // index of each channel as stored in scanLine object
int alphaChannel = -1;
PixelType alphaChannelType = HALF;
int channels = 0;
for (ChannelList::ConstIterator i = inputChans.begin ();
i != inputChans.end ();
++i)
{
channelToPos[i.name ()] = channels;
if (strcmp (i.name (), "A") == 0)
{
alphaChannel = channels;
alphaChannelType = i.channel ().type;
}
channels++;
}
// if the part has a manifest, use this part's manifest
// otherwise use part 0's manifest.
// (but reparse the manifest for every part in case the channel list has changed)
//
int manifestPart = hasIDManifest (inputHeader) ? pt : 0;
list<list<match>> ids;
IDManifest mfst = idManifest (input.header (manifestPart));
setIds (mfst, ids, matchArguments, numMatchArguments, channelToPos);
// store for an individual deep scanline. Accessed using scanLine[channelIndex][pixelIndex][sampleIndex]
// where pixelIndex is 0 for the leftmost pixel (even if the dataWindow doesn't start at 0)
vector<vector<vector<uint32_t>>> scanLine (channels);
// pointers to the data in each channel for FrameBuffer
vector<vector<uint32_t*>> scanPointers (channels);
for (int i = 0; i < channels; ++i)
{
scanLine[i].resize (width);
scanPointers[i].resize (width);
}
vector<int> pixelCounts (width);
vector<half> outputAlpha (
width); // only required for --mask mode: stores output
DeepFrameBuffer buf;
buf.insertSampleCountSlice (Slice (
UINT,
(char*) pixelCounts.data () - dataWindow.min.x,
sizeof (int),
0));
int c = 0;
//
// read all channels as their native type, so they round trip when writing deep
//
for (ChannelList::ConstIterator i = inputChans.begin ();
i != inputChans.end ();
++i, ++c)
{
buf.insert (
i.name (),
DeepSlice (
i.channel ().type,
(char*) scanPointers[c].data () - dataWindow.min.x,
sizeof (char*),
0,
sizeof (int32_t)));
}
DeepScanLineInputPart inPart (input, pt);
inPart.setFrameBuffer (buf);
//
// for mask, create an alpha channel and initialize a FrameBuffer with that data
// otherwise, can use the deep frame buffer for both input and output, since the data is processed in-place
//
if (mask)
{
FrameBuffer outBuf;
outBuf.insert (
"A",
Slice (
HALF,
(char*) outputAlpha.data () - dataWindow.min.x,
sizeof (half),
0));
OutputPart outPart (output, pt);
outPart.setFrameBuffer (outBuf);
}
else
{
DeepScanLineOutputPart outPart (output, pt);
outPart.setFrameBuffer (buf);
}
for (int y = dataWindow.min.y; y <= dataWindow.max.y; ++y)
{
inPart.readPixelSampleCounts (y);
for (int c = 0; c < channels; ++c)
{
for (int x = 0; x < width; ++x)
{
scanLine[c][x].resize (pixelCounts[x]);
scanPointers[c][x] = scanLine[c][x].data ();
}
}
inPart.readPixels (y);
for (int x = 0; x < width; ++x)
{
int outputSample = 0;
float totalAlpha = 0.f;
float maskAlpha = 0.f;
for (int s = 0; s < pixelCounts[x]; ++s)
{
//
// should sample s be retained?
// look for an entry in each 'and group' where all the required channels match their
// corresponding values
//
bool good = true;
for (list<list<match>>::const_iterator idGroup =
ids.begin ();
idGroup != ids.end () && good;
++idGroup)
{
good = false;
for (list<match>::const_iterator i = idGroup->begin ();
i != idGroup->end () && !good;
++i)
{
if (scanLine[i->channel1][x][s] == i->id1 &&
(i->channel2 == -1 ||
scanLine[i->channel2][x][s] == i->id2))
{
good = true;
}
}
}
//
// deep output mode:
// delete unwanted samples
// mask output node:
// composite together wanted sample's alpha
//
if (mask)
{
//cast alpha to float, and composite
float alpha = 0.f;
switch (alphaChannelType)
{
case FLOAT:
alpha = *(float*) (&scanLine[alphaChannel][x]
.data ()[s]);
break;
case HALF:
alpha = *(half*) (&scanLine[alphaChannel][x]
.data ()[s]);
break;
case UINT:
alpha = scanLine[alphaChannel][x][s];
break; //wat! this is a weird thing to do,but whatever...
case NUM_PIXELTYPES: break;
}
if (good) { maskAlpha += (1.0 - totalAlpha) * alpha; }
totalAlpha += (1.0 - totalAlpha) * alpha;
}
else if (good)
{
// keep Sample: copy from original position into output position
// (so overwrite any samples that are to be deleted)
for (int c = 0; c < channels; ++c)
{
scanLine[c][x][outputSample] = scanLine[c][x][s];
}
outputSample++;
}
}
if (mask)
{
if (totalAlpha > 0.f) { maskAlpha /= totalAlpha; }
outputAlpha[x] = maskAlpha;
}
else
{
// update total count of samples
pixelCounts[x] = outputSample;
}
}
//
// write data out
//
if (mask)
{
OutputPart outPart (output, pt);
outPart.writePixels (1);
}
else
{
DeepScanLineOutputPart outPart (output, pt);
outPart.writePixels (1);
}
}
}
}
void
setIds (
const IDManifest& mfst,
list<list<match>>& ids,
const char* matches[],
int numMatches,
const map<string, int>& channelToPos)
{
//
// initially one single list
//
ids.clear ();
ids.push_back (list<match> ());
//
// check each manifest, each entry, against each matching expression
//
for (int c = 0; c < numMatches; ++c)
{
//
// an 'and' argument means proceed to the next group of ids
// must find a match in every such group
//
if (strcmp (matches[c], "--and") == 0)
{
ids.push_back (list<match> ());
continue;
}
string matchString (matches[c]);
//
// handle strings of the form component:searchstring
// and channel:idnumber
//
string componentName;
string::size_type pos = matchString.find (':');
if (pos != string::npos)
{
componentName = matchString.substr (0, pos);
matchString = matchString.substr (pos + 1);
}
if (matchString.find_first_not_of ("0123456789") == string::npos)
{
map<string, int>::const_iterator chan =
channelToPos.find (componentName);
if (chan != channelToPos.end ())
{
match m;
m.channel1 = chan->second;
m.id1 = stoi (matchString);
m.channel2 = -1;
ids.back ().push_back (m);
}
continue; // skip parsing the manifests for this string
}
// check the manifest for each group of channels
for (size_t i = 0; i < mfst.size (); ++i)
{
for (IDManifest::ChannelGroupManifest::ConstIterator it =
mfst[i].begin ();
it != mfst[i].end ();
++it)
{
for (size_t stringIndex = 0; stringIndex < it.text ().size ();
++stringIndex)
{
if (componentName == "" ||
mfst[i].getComponents ()[stringIndex] == componentName)
{
// simple substring matching only: could do wildcards or regexes here instead
if (it.text ()[stringIndex].find (matchString) !=
string::npos)
{
// a match is found - add it to the corresponding channels
if (mfst[i].getEncodingScheme () ==
IDManifest::ID_SCHEME)
{
// simple scheme: the ID channel has to match
for (const string& s: mfst[i].getChannels ())
{
map<string, int>::const_iterator chan =
channelToPos.find (s);
if (chan != channelToPos.end ())
{
//could support matching the ID against a specific channel
//that check would happen here
match m;
m.channel1 = chan->second;
m.id1 = uint32_t (it.id ());
m.channel2 = -1;
ids.back ().push_back (m);
cerr << "adding match " << hex
<< it.id () << dec
<< " for string "
<< it.text ()[stringIndex]
<< " in channel " << chan->second
<< '(' << chan->first << ")\n";
}
}
}
else if (
mfst[i].getEncodingScheme () ==
IDManifest::ID2_SCHEME)
{
// 64 bit IDs are spread across two channels, with the least significant bits
// in the first channel (alphabetically) and the most significant bits in the second
// so process the channel set in pairs
set<string>::const_iterator chanLow =
mfst[i].getChannels ().begin ();
set<string>::const_iterator end =
mfst[i].getChannels ().end ();
while (chanLow != end)
{
set<string>::const_iterator chanHigh =
chanLow;
++chanHigh;
if (chanHigh != end)
{
map<string, int>::const_iterator
chanIdxLow =
channelToPos.find (*chanLow);
map<string, int>::const_iterator
chanIdxHigh =
channelToPos.find (*chanHigh);
if (chanIdxLow != channelToPos.end () &&
chanIdxHigh != channelToPos.end ())
{
// to match against specific channels, check at least one channel matches here
match m;
m.channel1 = chanIdxLow->second;
m.id1 = it.id () & 0xFFFFFFFF;
m.channel2 = chanIdxHigh->second;
m.id2 = it.id () >> 32;
ids.back ().push_back (m);
cerr << "adding match " << hex
<< it.id () << dec
<< " for string "
<< it.text ()[stringIndex]
<< ": " << hex << m.id1
<< " in channel " << m.channel1
<< '(' << chanIdxLow->first
<< "), " << hex << m.id2
<< " in channel " << m.channel2
<< '(' << chanIdxHigh->first
<< ")\n";
}
++chanLow;
if (chanLow != end) { ++chanLow; }
}
}
}
}
}
}
}
}
}
}
+1 -1
View File
@@ -44,7 +44,7 @@ writeGZ1 (
// - create a file header
// - add G and Z channels to the header
// - open the file, and store the header in the file
// - describe the memory layout of the G anx Z pixels
// - describe the memory layout of the G and Z pixels
// - store the pixels in the file
//
+13
View File
@@ -9,6 +9,9 @@
#include "previewImageExamples.h"
#include "rgbaInterfaceExamples.h"
#include "rgbaInterfaceTiledExamples.h"
#include "deepExamples.h"
#include "deepTiledExamples.h"
#include "multipartExamples.h"
#include <iostream>
#include <stdexcept>
@@ -24,9 +27,19 @@ main (int argc, char* argv[])
rgbaInterfaceTiledExamples ();
generalInterfaceTiledExamples ();
deepExamples ();
deepTiledExamples ();
lowLevelIoExamples ();
previewImageExamples ();
// This example uses the files created by
// generalInterfaceExamples,
// generalInterfaceTiledExamples,
// deepExamples,
// deepTiledExamples
multipartExamples ();
}
catch (const std::exception& exc)
{
+507
View File
@@ -0,0 +1,507 @@
//
// SPDX-License-Identifier: BSD-3-Clause
// Copyright (c) Contributors to the OpenEXR Project.
//
//-----------------------------------------------------------------------------
//
// Code examples that show how class MultiPartInputFile and
// class MultiPartOutputFile can be used to read and write
// OpenEXR image files containing multiple images.
//
//-----------------------------------------------------------------------------
#include <ImfHeader.h>
#include <ImfPartType.h>
#include <ImfChannelList.h>
#include <ImfArray.h>
#include <ImfFrameBuffer.h>
#include <ImfDeepFrameBuffer.h>
#include <ImfMultiPartInputFile.h>
#include <ImfMultiPartOutputFile.h>
#include <ImfInputPart.h>
#include <ImfTiledInputPart.h>
#include <ImfDeepScanLineInputPart.h>
#include <ImfDeepTiledInputPart.h>
#include <ImfOutputPart.h>
#include <ImfTiledOutputPart.h>
#include <ImfDeepScanLineOutputPart.h>
#include <ImfDeepTiledOutputPart.h>
#include <vector>
#include <list>
#include "namespaceAlias.h"
using namespace IMF;
using namespace std;
using namespace IMATH_NAMESPACE;
template <class InputPartType, class OutputPartType>
void copyPixels (
MultiPartInputFile & inputFile,
MultiPartOutputFile & outputFile,
int inputPartNumber,
int outputPartNumber)
{
InputPartType inPart (inputFile, inputPartNumber);
OutputPartType outPart (outputFile, outputPartNumber);
outPart.copyPixels (inPart);
}
void copyPixels(
const std::string & type,
MultiPartInputFile & inputFile,
MultiPartOutputFile & outputFile,
int inputPartNumber,
int outputPartNumber)
{
//
// Copy pixels from a given part of a multipart input file
// to a given part of a multipart output file.
//
if (type == SCANLINEIMAGE)
{
copyPixels<InputPart, OutputPart> (inputFile, outputFile, inputPartNumber, outputPartNumber);
}
else if (type == TILEDIMAGE)
{
copyPixels<TiledInputPart, TiledOutputPart> (inputFile, outputFile, inputPartNumber, outputPartNumber);
}
else if (type == DEEPSCANLINE)
{
copyPixels<DeepScanLineInputPart, DeepScanLineOutputPart> (inputFile, outputFile, inputPartNumber, outputPartNumber);
}
else if (type == DEEPTILE)
{
copyPixels<DeepTiledInputPart, DeepTiledOutputPart> (inputFile, outputFile, inputPartNumber, outputPartNumber);
}
}
void combineFiles ()
{
//
// Read multiple single-part input files and write them as a multi-part file.
// If an input file is multi-part, only one part is copied.
// All input files dimentions must be the same.
//
std::vector<MultiPartInputFile *> inputFiles;
std::vector<Header> headers;
const char * filenames[] = {"gz1.exr", "tiledgz1.exr", "test.deep.exr", "testTiled.deep.exr"};
for (size_t i = 0; i < sizeof (filenames) / sizeof (filenames[0]); i++)
{
MultiPartInputFile * in_file = new MultiPartInputFile (filenames[i]);
Header header = in_file->header (0);
if (!header.hasName ())
{
header.setName (filenames[i]);
}
inputFiles.push_back (in_file);
headers.push_back (header);
}
MultiPartOutputFile outputFile ("multipart.exr", headers.data (), (int)headers.size ());
for (size_t i = 0; i < sizeof (filenames) / sizeof (filenames[0]); i++)
{
Header & header = headers[i];
const string& type = header.type ();
copyPixels (type, *inputFiles[i], outputFile, 0, i);
delete inputFiles[i];
}
}
void splitFiles ()
{
//
// Read a multi-part input file and write all parts as separate files.
//
MultiPartInputFile inputFile ("modified.exr");
for (int i = 0; i < inputFile.parts (); i++)
{
Header header = inputFile.header (i);
string out_path = string ("split_part_") + to_string (i) + string (".exr");
const string& type = header.type ();
MultiPartOutputFile outputFile (out_path.c_str (), &header, 1);
copyPixels (type, inputFile, outputFile, i, 0);
}
}
template <typename ValueType>
void insertSlice(
Box2i & dataWindow,
FrameBuffer & frameBuffer,
const char name[],
PixelType pixelType,
list<Array2D<ValueType>> & channels)
{
//
// Allocate a pixel buffer and describe the layout of
// the buffer in the FrameBuffer object.
//
size_t width = dataWindow.max.x - dataWindow.min.x + 1;
size_t height = dataWindow.max.y - dataWindow.min.y + 1;
channels.emplace_back ();
Array2D<ValueType> & buffer = channels.back ();
buffer.resizeErase (height, width);
char * base = (char *)(&buffer[0][0] - dataWindow.min.x - dataWindow.min.y * width);
frameBuffer.insert (
name, // name
Slice (
pixelType, // type
base, // base
sizeof (ValueType) * 1, // xStride
sizeof (ValueType) * width // yStride
)
);
}
template <typename ValueType>
void insertDeepSlice(
Box2i & dataWindow,
DeepFrameBuffer & frameBuffer,
const char name[],
PixelType pixelType,
list<Array2D<ValueType *>> & channels)
{
//
// Allocate a pixel buffer and describe the layout of
// the buffer in the DeepFrameBuffer object.
//
size_t width = dataWindow.max.x - dataWindow.min.x + 1;
size_t height = dataWindow.max.y - dataWindow.min.y + 1;
channels.emplace_back ();
Array2D<ValueType *> & buffer = channels.back ();
buffer.resizeErase (height, width);
char * base = (char *)(&buffer[0][0] - dataWindow.min.x - dataWindow.min.y * width);
frameBuffer.insert (
name, // name
DeepSlice (
pixelType, // type
base, // base
sizeof (ValueType *) * 1, // xStride
sizeof (ValueType *) * width, // yStride
sizeof (ValueType) * width // sample stride
)
);
}
FrameBuffer setupFramebuffer (
const Header & header,
list<Array2D<uint32_t>> & intChannels,
list<Array2D<half>> & halfChannels,
list<Array2D<float>> & floatChannels
)
{
//
// Allocate pixel buffers for all channels specified in the header, describe the layout of
// the buffers in the FrameBuffer object.
//
FrameBuffer frameBuffer;
Box2i dataWindow = header.dataWindow ();
for (auto i = header.channels ().begin (); i != header.channels ().end (); i++)
{
if (i.channel ().type == UINT)
{
insertSlice<uint32_t> (dataWindow, frameBuffer, i.name (), i.channel ().type, intChannels);
}
else if (i.channel ().type == HALF)
{
insertSlice<half> (dataWindow, frameBuffer, i.name (), i.channel ().type, halfChannels);
}
else if (i.channel ().type == FLOAT)
{
insertSlice<float> (dataWindow, frameBuffer, i.name (), i.channel ().type, floatChannels);
}
}
return frameBuffer;
}
DeepFrameBuffer setupDeepFramebuffer (
const Header & header,
Array2D<uint32_t> & sampleCount,
list<Array2D<uint32_t *>> & intChannels,
list<Array2D<half *>> & halfChannels,
list<Array2D<float *>> & floatChannels
)
{
//
// Allocate pixel buffers for all channels specified in the header, describe the layout of
// the buffers in the DeepFrameBuffer object.
//
DeepFrameBuffer frameBuffer;
Box2i dataWindow = header.dataWindow ();
size_t width = dataWindow.max.x - dataWindow.min.x + 1;
size_t height = dataWindow.max.y - dataWindow.min.y + 1;
sampleCount.resizeErase (height, width);
frameBuffer.insertSampleCountSlice (
Slice (
UINT,
(char*) (&sampleCount[0][0] - dataWindow.min.x - dataWindow.min.y * width),
sizeof (unsigned int) * 1, // xStride
sizeof (unsigned int) * width // yStride
)
);
for (auto i = header.channels ().begin (); i != header.channels ().end (); i++)
{
if (i.channel ().type == UINT)
{
insertDeepSlice<uint32_t> (dataWindow, frameBuffer, i.name (), i.channel ().type, intChannels);
}
else if (i.channel ().type == HALF)
{
insertDeepSlice<half> (dataWindow, frameBuffer, i.name (), i.channel ().type, halfChannels);
}
else if (i.channel ().type == FLOAT)
{
insertDeepSlice<float> (dataWindow, frameBuffer, i.name (), i.channel ().type, floatChannels);
}
}
return frameBuffer;
}
template <typename T>
void resizeDeepBuffers (
Array2D<uint32_t> & sampleCount,
list<Array2D<T *>> & channels
)
{
//
// Allocate memory for samples in all pixel buffers according to the data in sampleCount buffer.
//
for (auto i = channels.begin (); i != channels.end (); i++)
{
Array2D<T *> & channel = *i;
for (int y = 0; y < channel.height (); y++)
{
for (int x = 0; x < channel.width (); x++)
{
uint32_t count = sampleCount[y][x];
channel[y][x] = new T [count];
}
}
}
}
template <typename T>
void freeDeepBuffers (list<Array2D<T *>> & channels)
{
for (auto i = channels.begin (); i != channels.end (); i++)
{
Array2D<T*> & channel = *i;
for (int y = 0; y < channel.height (); y++)
for (int x = 0; x < channel.width (); x++)
delete[] channel[y][x];
}
}
template <typename T>
void modifyChannels(list<Array2D<T>> & channels, T delta)
{
//
// Dummy code modifying each pixel by incrementing every channel by a given delta.
//
for (auto i = channels.begin (); i != channels.end (); i++)
{
Array2D<T> & channel = *i;
for (int y = 0; y < channel.height (); y++)
{
for (int x = 0; x < channel.width (); x++)
{
channel[y][x] += delta;
}
}
}
}
template <typename T>
void modifyDeepChannels(Array2D<uint32_t> & sampleCount, list<Array2D<T *>> & channels, T delta)
{
//
// Dummy code modifying each deep pixel by incrementing every sample of each channel by a given delta.
//
for (auto i = channels.begin (); i != channels.end (); i++)
{
Array2D<T *> & channel = *i;
for (int y = 0; y < channel.height (); y++)
{
for (int x = 0; x < channel.width (); x++)
{
uint32_t count = sampleCount[y][x];
for (uint32_t j = 0; j < count; j++)
channel[y][x][j] += delta;
}
}
}
}
void modifyMultipart ()
{
//
// Read all channels from a multi-part file, modify each pixel value, write the modified data as a multi-part file.
// The parts in the file can be scanline- or tile-based, either flat or deep.
// Every channel of the input file gets modified.
//
MultiPartInputFile inputFile ("multipart.exr");
std::vector<Header> headers (inputFile.parts ());
for (int i = 0; i < inputFile.parts (); i++)
{
headers[i] = inputFile.header (i);
}
MultiPartOutputFile outputFile("modified.exr", headers.data (), (int)headers.size ());
for (int i = 0; i < inputFile.parts (); i++)
{
Header & header = headers[i];
const string& type = header.type ();
if (type == SCANLINEIMAGE ||
type == TILEDIMAGE)
{
list<Array2D<uint32_t>> intChannels;
list<Array2D<half>> halfChannels;
list<Array2D<float>> floatChannels;
FrameBuffer frameBuffer = setupFramebuffer (header, intChannels, halfChannels, floatChannels);
if (type == SCANLINEIMAGE)
{
InputPart inputPart (inputFile, i);
inputPart.setFrameBuffer (frameBuffer);
inputPart.readPixels (header.dataWindow ().min.y, header.dataWindow ().max.y);
}
else
{
TiledInputPart inputPart (inputFile, i);
inputPart.setFrameBuffer (frameBuffer);
inputPart.readTiles (0, inputPart.numXTiles () - 1, 0, inputPart.numYTiles () - 1);
}
modifyChannels<uint32_t> (intChannels, 1);
modifyChannels<half> (halfChannels, 0.3);
modifyChannels<float> (floatChannels, 0.5);
if (type == SCANLINEIMAGE)
{
Box2i dataWindow = header.dataWindow ();
OutputPart outputPart (outputFile, i);
outputPart.setFrameBuffer (frameBuffer);
outputPart.writePixels (dataWindow.max.y - dataWindow.min.y + 1);
}
else
{
TiledOutputPart outputPart (outputFile, i);
outputPart.setFrameBuffer (frameBuffer);
outputPart.writeTiles (0, outputPart.numXTiles () - 1, 0, outputPart.numYTiles () - 1);
}
}
else if (type == DEEPSCANLINE || type == DEEPTILE)
{
Array2D<uint32_t> sampleCount;
list<Array2D<uint32_t *>> intChannels;
list<Array2D<half *>> halfChannels;
list<Array2D<float *>> floatChannels;
DeepFrameBuffer frameBuffer = setupDeepFramebuffer (header, sampleCount, intChannels, halfChannels, floatChannels);
if (type == DEEPSCANLINE)
{
DeepScanLineInputPart inputPart (inputFile, i);
inputPart.setFrameBuffer (frameBuffer);
inputPart.readPixelSampleCounts (header.dataWindow ().min.y, header.dataWindow ().max.y);
resizeDeepBuffers<uint32_t> (sampleCount, intChannels);
resizeDeepBuffers<half> (sampleCount, halfChannels);
resizeDeepBuffers<float> (sampleCount, floatChannels);
inputPart.readPixels (header.dataWindow ().min.y, header.dataWindow ().max.y);
}
else
{
DeepTiledInputPart inputPart (inputFile, i);
inputPart.setFrameBuffer (frameBuffer);
inputPart.readPixelSampleCounts (0, inputPart.numXTiles () - 1, 0, inputPart.numYTiles () - 1);
resizeDeepBuffers<uint32_t> (sampleCount, intChannels);
resizeDeepBuffers<half> (sampleCount, halfChannels);
resizeDeepBuffers<float> (sampleCount, floatChannels);
inputPart.readTiles (0, inputPart.numXTiles () - 1, 0, inputPart.numYTiles () - 1);
}
modifyDeepChannels<uint32_t> (sampleCount, intChannels, 1);
modifyDeepChannels<half> (sampleCount, halfChannels, 0.3);
modifyDeepChannels<float> (sampleCount, floatChannels, 0.5);
if (type == DEEPSCANLINE)
{
Box2i dataWindow = header.dataWindow ();
DeepScanLineOutputPart outputPart (outputFile, i);
outputPart.setFrameBuffer (frameBuffer);
outputPart.writePixels (dataWindow.max.y - dataWindow.min.y + 1);
}
else
{
DeepTiledOutputPart outputPart (outputFile, i);
outputPart.setFrameBuffer (frameBuffer);
outputPart.writeTiles (0, outputPart.numXTiles () - 1, 0, outputPart.numYTiles () - 1);
}
freeDeepBuffers(intChannels);
freeDeepBuffers(halfChannels);
freeDeepBuffers(floatChannels);
}
}
}
void multipartExamples()
{
// Read multiple single-part files and write them out as a single multi-part file.
combineFiles ();
// Read all parts from a multi-part file, modify each channel of every pixel by incrementing its value, write out as a multi-part file.
modifyMultipart ();
// Read a multi-part file and write out as multiple single-part files.
splitFiles ();
}

Some files were not shown because too many files have changed in this diff Show More