Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e181aadac5 | ||
|
|
082b360122 | ||
|
|
8d37a81f83 | ||
|
|
49459df4b8 | ||
|
|
a0162813fd | ||
|
|
7c4634ce64 | ||
|
|
1383491c9b | ||
|
|
a4a6113ac5 | ||
|
|
4c36a07d1d | ||
|
|
4da1679757 | ||
|
|
7f6861505b | ||
|
|
8e1c7701d0 | ||
|
|
0246a1bc8b | ||
|
|
436ab6eff2 | ||
|
|
fd8e64a660 | ||
|
|
b008158500 | ||
|
|
554dd02134 | ||
|
|
83c885309c | ||
|
|
b445bc64a4 | ||
|
|
a5c7a0c942 | ||
|
|
38aed29bb0 | ||
|
|
afe81598ca | ||
|
|
cdc82185f1 | ||
|
|
56c734a675 | ||
|
|
8f423c9975 | ||
|
|
0fca55569d | ||
|
|
9909b4b109 | ||
|
|
629b205da4 | ||
|
|
15750af31a | ||
|
|
c7f8169d73 | ||
|
|
e3f666500b | ||
|
|
81a1c221bb | ||
|
|
1bb1ca591a | ||
|
|
9e42bd1228 | ||
|
|
6e603475a8 | ||
|
|
353e0222d5 | ||
|
|
81cb1a433c | ||
|
|
004cbb0238 | ||
|
|
c97826c144 | ||
|
|
3dd4951fe2 | ||
|
|
d65eb6597b | ||
|
|
88c10a91cb | ||
|
|
712a73818f | ||
|
|
b205899131 | ||
|
|
d757bffca5 | ||
|
|
9fd9fbfdc2 | ||
|
|
88d354e068 | ||
|
|
e297a3ba0d | ||
|
|
e203bd6d27 | ||
|
|
780fe682c9 | ||
|
|
b1f5265642 | ||
|
|
b257b8e6a0 | ||
|
|
3c86a882cd | ||
|
|
a27b55a867 | ||
|
|
0aee3bb863 | ||
|
|
944c2034c8 | ||
|
|
3e1a6d5540 | ||
|
|
eda748ef0e | ||
|
|
42c629ffef | ||
|
|
692b7899d7 | ||
|
|
f3eaebc8b8 | ||
|
|
3fd70cfd35 | ||
|
|
d18c7e27f2 | ||
|
|
77975c6ae2 | ||
|
|
a8291872c7 | ||
|
|
87a1e49b2d | ||
|
|
20d2927224 | ||
|
|
150af5a36e | ||
|
|
ca4a245aec | ||
|
|
612bbbd0d0 | ||
|
|
bdf31de0c3 | ||
|
|
a3d9900bab | ||
|
|
fd33ab67c1 | ||
|
|
7d9a19b5d9 | ||
|
|
577f10858a | ||
|
|
2abd946ea5 | ||
|
|
c9f0c93f73 | ||
|
|
407e14ec3f | ||
|
|
f95ff86e43 | ||
|
|
8da473e254 | ||
|
|
aad99bad9a | ||
|
|
1cd0d0a9df | ||
|
|
e56eab4b36 | ||
|
|
109f0bdba0 | ||
|
|
116a1f1a25 | ||
|
|
cfaccc1609 | ||
|
|
f40f9800c8 | ||
|
|
ee3dc556b8 | ||
|
|
13e1e802c0 | ||
|
|
cb6475c0dd | ||
|
|
eaa2c2ae37 | ||
|
|
e47e501eb0 | ||
|
|
cf2b7d7995 | ||
|
|
b3d9c8c4ed | ||
|
|
6f7db0775e | ||
|
|
5ca9ffea7a | ||
|
|
1f6d137434 | ||
|
|
e5733a0607 | ||
|
|
23b0e2beae | ||
|
|
c8c8ea5cac | ||
|
|
dce61b3c5b | ||
|
|
f27a974c34 | ||
|
|
81e4bd2fa7 | ||
|
|
4250d71093 | ||
|
|
5152be9a57 | ||
|
|
0a39c2c993 | ||
|
|
a02327df53 | ||
|
|
e1dcef1453 | ||
|
|
617eeed554 | ||
|
|
32a361ab3e | ||
|
|
4917cd2fc8 | ||
|
|
a1d8dbcecd | ||
|
|
23819a86d8 | ||
|
|
9e7e040a37 | ||
|
|
b64356b3af | ||
|
|
c231dfb70a | ||
|
|
571a16717f | ||
|
|
4b6f54dc16 | ||
|
|
e88e4e4b93 | ||
|
|
bd4bbaf9cc | ||
|
|
54badeeb7c | ||
|
|
eb2ceba5ed | ||
|
|
21ee2d225e | ||
|
|
22a8196c8f | ||
|
|
efe2fe07c9 | ||
|
|
b2c11c33a4 | ||
|
|
f5f6d692cf | ||
|
|
3332c78f5e | ||
|
|
a77e36250f | ||
|
|
1db505e28e | ||
|
|
0a9f055edb | ||
|
|
1a6bfd0716 | ||
|
|
72bdba80b1 | ||
|
|
78eff533c6 | ||
|
|
3287b8e46a | ||
|
|
541f87b249 | ||
|
|
e3929659dc | ||
|
|
d1a11a9316 | ||
|
|
cb0db7c276 | ||
|
|
67065cbcef | ||
|
|
f25ff39537 | ||
|
|
34f01aa793 | ||
|
|
412a1e16db | ||
|
|
4ce7365212 | ||
|
|
14995e39dd | ||
|
|
f1fa0537fb | ||
|
|
44a17dcdfa | ||
|
|
8e9b334a25 | ||
|
|
15965ad8ad | ||
|
|
1c5b4f40d7 | ||
|
|
0e2374e0bd | ||
|
|
2ac5797422 | ||
|
|
a58e145e09 | ||
|
|
f8db9f38d1 | ||
|
|
fa9dadea72 | ||
|
|
9cb000f178 | ||
|
|
86aea43007 | ||
|
|
759fcd392d | ||
|
|
2a6f2c84b3 | ||
|
|
9325069dd4 | ||
|
|
271f911984 | ||
|
|
f2a10108b3 | ||
|
|
a8b93f0ccc | ||
|
|
3b34231a3a | ||
|
|
e2e5eba95d | ||
|
|
963b46a3d9 | ||
|
|
e59397ad7c | ||
|
|
91a2bc4814 | ||
|
|
4f180d13f8 | ||
|
|
b311d51e3d | ||
|
|
3fc4293a42 | ||
|
|
59f54c80b2 | ||
|
|
0a8311b885 | ||
|
|
7e0ed37e97 | ||
|
|
fd05534d44 | ||
|
|
c2781d7a8d | ||
|
|
b6b6230a1b | ||
|
|
dfb086e130 | ||
|
|
496b374e9c | ||
|
|
1f2e6b9990 | ||
|
|
1026d7b18d | ||
|
|
b4dad279a9 | ||
|
|
8cfa5f90b5 | ||
|
|
6acaac4d08 | ||
|
|
ff1f577c08 | ||
|
|
43c13ae9c8 | ||
|
|
da51cd9167 | ||
|
|
89c5802990 | ||
|
|
a3843e2597 | ||
|
|
16948f64a2 | ||
|
|
1b9ce86821 | ||
|
|
d5be2d16cb | ||
|
|
dad63699ed | ||
|
|
c023ec6004 | ||
|
|
d5670ff858 | ||
|
|
3b8807df85 | ||
|
|
c3a15ed84e | ||
|
|
0b9e9d7ed7 | ||
|
|
f70834521c | ||
|
|
edaa7a2ac1 | ||
|
|
9aabd4366d | ||
|
|
ec2fb0005a | ||
|
|
e1db762b58 | ||
|
|
93727ff83b | ||
|
|
46f31d5a53 | ||
|
|
070790ef73 | ||
|
|
003a1f15ae | ||
|
|
5c43dfebe4 | ||
|
|
8f6de9b512 | ||
|
|
5518be34c0 | ||
|
|
188efa55af | ||
|
|
726c51181a | ||
|
|
48f2b1bf92 | ||
|
|
2317a6b681 | ||
|
|
109164e012 | ||
|
|
9c910144aa | ||
|
|
82a4b089c7 | ||
|
|
c59529a9a1 | ||
|
|
55fa36062d | ||
|
|
8efd666c21 | ||
|
|
1449b46500 | ||
|
|
ed3dc51c55 | ||
|
|
494236c1fc | ||
|
|
327eb03790 | ||
|
|
4001c95ac7 | ||
|
|
99b0f37ac6 | ||
|
|
78ee5e05ea | ||
|
|
dc5bffcf3f | ||
|
|
3641834a11 | ||
|
|
92e488a3b7 | ||
|
|
fabce2ac33 | ||
|
|
a707c2a534 | ||
|
|
ecb807262e | ||
|
|
8b5ace53a9 | ||
|
|
4037671a31 | ||
|
|
1aa2cf6edf | ||
|
|
6aac5b182a | ||
|
|
44ff29deb7 | ||
|
|
f782db69e3 | ||
|
|
c0bbf873f2 | ||
|
|
e4b5fa4ea7 | ||
|
|
ce03d56d8e | ||
|
|
209c1bfd46 | ||
|
|
9ccbc43f38 | ||
|
|
ae1031044f | ||
|
|
4b22cf4452 | ||
|
|
32946e54e5 | ||
|
|
1605a4a961 | ||
|
|
f7c4023487 | ||
|
|
d5d9146f32 | ||
|
|
aba8470c91 | ||
|
|
b48f0650a4 | ||
|
|
d7ecbbb100 | ||
|
|
04fc83edeb | ||
|
|
c31b10007b | ||
|
|
30ea4ebdfa | ||
|
|
72bc675885 | ||
|
|
6da2b6ef48 | ||
|
|
d9f326f18e | ||
|
|
1278f60e7a | ||
|
|
e03b7b38b4 | ||
|
|
8b8952d964 | ||
|
|
989bf367ec | ||
|
|
ab93bfa6c0 | ||
|
|
404015ef26 | ||
|
|
efd27a9dfb | ||
|
|
78aaf34d3a | ||
|
|
f099e19d94 | ||
|
|
7d53464069 | ||
|
|
9c706409f1 | ||
|
|
88152a6a10 | ||
|
|
1beeb27dae | ||
|
|
52846a5253 | ||
|
|
76610138e9 | ||
|
|
ab694d0322 | ||
|
|
0674f8de7b | ||
|
|
53d2e5db1d | ||
|
|
af4b6f1da6 | ||
|
|
c5ef0f2e50 | ||
|
|
78441fa29a | ||
|
|
92db3f5d35 | ||
|
|
acfb6a9e28 | ||
|
|
e44400feac | ||
|
|
884dfd6b7c | ||
|
|
a37aa72f93 | ||
|
|
737b317394 | ||
|
|
51705b7fba | ||
|
|
19121dc4f0 | ||
|
|
5fa8d996bd | ||
|
|
f6b2a13473 | ||
|
|
1196815fd1 | ||
|
|
3a9d3faab5 | ||
|
|
4be5ca093d | ||
|
|
c51349a0d6 | ||
|
|
90dfdb1720 | ||
|
|
71b4cffcaa | ||
|
|
7f28d3f3f1 | ||
|
|
2e663455ee | ||
|
|
a7d0346cb0 | ||
|
|
c5cd76a395 | ||
|
|
575fcb3c13 | ||
|
|
c653ab0052 | ||
|
|
5532d49387 | ||
|
|
1875a9b884 | ||
|
|
a432a35e34 | ||
|
|
7a510254c6 | ||
|
|
e471c7ea49 | ||
|
|
5320f79968 | ||
|
|
bbd48ca172 | ||
|
|
c721423cdd | ||
|
|
babbd98081 | ||
|
|
afaaf6d10d | ||
|
|
3e3fba67c0 | ||
|
|
f60205ab50 | ||
|
|
4a4f50eda8 | ||
|
|
a285a5d1ed | ||
|
|
3c32812296 | ||
|
|
b89fa9d0d6 | ||
|
|
60800746bf | ||
|
|
fe48013d04 | ||
|
|
4ee35351f1 | ||
|
|
caf15b6b73 | ||
|
|
e64b2cb425 | ||
|
|
33c0181843 | ||
|
|
5dd9feeade | ||
|
|
490d51bc96 | ||
|
|
3ffb4ae7e8 | ||
|
|
53aa8a1674 | ||
|
|
09d3464c9d | ||
|
|
fcc45717fa | ||
|
|
893eead5a8 | ||
|
|
9c6c9192f1 | ||
|
|
03ee387c05 | ||
|
|
d5973882d8 | ||
|
|
ebea33b0c2 | ||
|
|
b085899021 | ||
|
|
9c45ba9cf1 | ||
|
|
9b41418941 | ||
|
|
b22260bd19 | ||
|
|
d779a32814 | ||
|
|
80374c0128 | ||
|
|
96f420b26d | ||
|
|
a2e7ec714f | ||
|
|
acbd1f3c9f | ||
|
|
9aeece7a53 | ||
|
|
71a329672e | ||
|
|
a22ed46940 | ||
|
|
0d9f098dbb | ||
|
|
0ff1bf34f9 | ||
|
|
a028a11a0b | ||
|
|
99adfb43a8 | ||
|
|
cd4ca3bae4 | ||
|
|
73f958341e | ||
|
|
23235c9851 | ||
|
|
c85b5d7768 | ||
|
|
c23cda28a5 |
@@ -40,7 +40,7 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- desc: sonar gcc9/C++14 py39 boost1.76 exr3.1 ocio2.1
|
||||
- desc: sonar gcc9/C++14 py39 boost1.76 exr3.1 ocio2.2
|
||||
nametag: static-analysis-sonar
|
||||
os: ubuntu-latest
|
||||
vfxyear: 2022
|
||||
@@ -62,6 +62,7 @@ jobs:
|
||||
CODECOV=1
|
||||
CTEST_TEST_TIMEOUT=1200
|
||||
OIIO_CMAKE_FLAGS="-DOIIO_TEX_IMPLEMENT_VARYINGREF=OFF"
|
||||
OPENCOLORIO_VERSION=v2.2.0
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
container:
|
||||
|
||||
+54
-16
@@ -30,17 +30,18 @@ jobs:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- desc: gcc6/C++14 py2.7 boost1.66 exr2.3 ocio1.1
|
||||
- desc: gcc6/C++14 py2.7 boost1.66 exr2.4 ocio1.1
|
||||
nametag: linux-vfx2019
|
||||
os: ubuntu-latest
|
||||
container: aswf/ci-osl:2019
|
||||
vfxyear: 2019
|
||||
cxx_std: 14
|
||||
openexr_ver: v2.4.3
|
||||
python_ver: 2.7
|
||||
simd: sse4.2
|
||||
fmt_ver: 6.1.2
|
||||
fmt_ver: 7.0.1
|
||||
pybind11_ver: v2.4.2
|
||||
setenvs: export PUGIXML_VERSION=v1.9
|
||||
setenvs: export PUGIXML_VERSION=v1.9 CMAKE_VERSION=3.15.5
|
||||
- desc: gcc6/C++14 py3.7 boost1.70 exr2.4 ocio1.1
|
||||
nametag: linux-vfx2020
|
||||
os: ubuntu-latest
|
||||
@@ -95,7 +96,7 @@ jobs:
|
||||
cxx_std: 17
|
||||
python_ver: 3.9
|
||||
simd: "avx2,f16c"
|
||||
fmt_ver: 8.1.1
|
||||
fmt_ver: 9.1.0
|
||||
pybind11_ver: v2.8.1
|
||||
- desc: icc/C++17 py3.9 boost1.76 exr3.1 ocio2.1 qt5.15
|
||||
nametag: linux-vfx2022-icc
|
||||
@@ -137,7 +138,7 @@ jobs:
|
||||
OIIO_CMAKE_FLAGS="-DSANITIZE=address,undefined -DUSE_PYTHON=0"
|
||||
CMAKE_BUILD_TYPE=Debug
|
||||
CTEST_TEST_TIMEOUT=1200
|
||||
CTEST_EXCLUSIONS="broken|cmake-consumer|png-damaged"
|
||||
CTEST_EXCLUSIONS="broken|png-damaged"
|
||||
- desc: gcc11/C++17 py3.10 boost1.80 exr3.1 ocio2.2
|
||||
nametag: linux-vfx2023
|
||||
os: ubuntu-latest
|
||||
@@ -146,9 +147,9 @@ jobs:
|
||||
cxx_std: 17
|
||||
python_ver: "3.10"
|
||||
simd: "avx2,f16c"
|
||||
fmt_ver: 9.1.0
|
||||
fmt_ver: 10.1.1
|
||||
pybind11_ver: v2.10.0
|
||||
- desc: oldest/hobbled gcc6.3/C++14 py2.7 boost-1.66 exr-2.3 no-sse no-ocio
|
||||
- desc: oldest/hobbled gcc6.3/C++14 py2.7 boost-1.66 exr-2.4 no-sse no-ocio
|
||||
# Oldest versions of the dependencies that we can muster, and various
|
||||
# things disabled (no SSE, OCIO, or OpenCV, don't embed plugins).
|
||||
nametag: linux-oldest
|
||||
@@ -156,17 +157,18 @@ jobs:
|
||||
container: aswf/ci-osl:2019
|
||||
vfxyear: 2019
|
||||
cxx_std: 14
|
||||
fmt_ver: 6.1.2
|
||||
openexr_ver: v2.3.0
|
||||
fmt_ver: 7.0.1
|
||||
openexr_ver: v2.4.0
|
||||
pybind11_ver: v2.4.2
|
||||
python_ver: 2.7
|
||||
simd: 0
|
||||
setenvs: export EMBEDPLUGINS=0
|
||||
PTEX_VERSION=v2.3.1
|
||||
CMAKE_VERSION=3.15.5
|
||||
PTEX_VERSION=v2.3.2
|
||||
WEBP_VERSION=v1.0.0
|
||||
USE_JPEGTURBO=0
|
||||
USE_OPENCOLORIO=0
|
||||
USE_OPENCV=0
|
||||
WEBP_VERSION=v1.0.0
|
||||
depcmds: sudo rm -rf /usr/local/include/OpenEXR
|
||||
|
||||
# Test formatting. This test entry doesn't do a full build, it
|
||||
@@ -184,6 +186,26 @@ jobs:
|
||||
setenvs: export BUILDTARGET=clang-format
|
||||
OIIO_CMAKE_FLAGS=-DUSE_PYTHON=0
|
||||
|
||||
# Test ABI stability. `abi_check` is the version or commit that we
|
||||
# believe is the current standard against which we don't want to
|
||||
# break the ABI. Basically, we will build that version as well as
|
||||
# the current one, and compare the resulting libraries.
|
||||
- desc: abi check
|
||||
nametag: linux-vfx2023
|
||||
os: ubuntu-latest
|
||||
container: aswftesting/ci-osl:2023-clang15
|
||||
vfxyear: 2023
|
||||
cxx_std: 17
|
||||
python_ver: "3.10"
|
||||
simd: "avx2,f16c"
|
||||
fmt_ver: 10.1.1
|
||||
pybind11_ver: v2.10.0
|
||||
skip_tests: 1
|
||||
abi_check: v2.5.3.0-beta1
|
||||
setenvs: export OIIO_CMAKE_FLAGS="-DOIIO_BUILD_TOOLS=0 -DOIIO_BUILD_TESTS=0 -DUSE_PYTHON=0"
|
||||
USE_OPENCV=0 USE_FFMPEG=0 USE_PYTHON=0
|
||||
CMAKE_BUILD_TYPE=RelWithDebInfo
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
container:
|
||||
image: ${{ matrix.container }}
|
||||
@@ -196,6 +218,7 @@ jobs:
|
||||
OPENEXR_VERSION: ${{matrix.openexr_ver}}
|
||||
PYBIND11_VERSION: ${{matrix.pybind11_ver}}
|
||||
PYTHON_VERSION: ${{matrix.python_ver}}
|
||||
ABI_CHECK: ${{matrix.abi_check}}
|
||||
steps:
|
||||
# We would like to use harden-runner, but it flags too many false
|
||||
# positives, every time we download a dependency. We should use it only
|
||||
@@ -228,12 +251,30 @@ jobs:
|
||||
- name: Testsuite
|
||||
if: matrix.skip_tests != '1'
|
||||
run: src/build-scripts/ci-test.bash
|
||||
- name: Check out ABI standard
|
||||
if: matrix.abi_check != ''
|
||||
uses: actions/checkout@3df4ab11eba7bda6032a0b82a6bb43b11571feac # v4.0.0
|
||||
with:
|
||||
ref: ${{matrix.abi_check}}
|
||||
path: abi_standard
|
||||
- name: Build ABI standard
|
||||
if: matrix.abi_check != ''
|
||||
run: |
|
||||
mkdir -p abi_standard/build
|
||||
pushd abi_standard
|
||||
src/build-scripts/ci-build.bash
|
||||
popd
|
||||
- name: Check ABI
|
||||
if: matrix.abi_check != ''
|
||||
run: |
|
||||
src/build-scripts/ci-abicheck.bash ./build abi_standard/build libOpenImageIO libOpenImageIO_Util
|
||||
- uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
|
||||
if: failure()
|
||||
with:
|
||||
name: oiio-${{github.job}}-${{matrix.nametag}}
|
||||
path: |
|
||||
build/cmake-save
|
||||
build/compat_reports
|
||||
build/testsuite/*/*.*
|
||||
!build/testsuite/oiio-images
|
||||
!build/testsuite/openexr-images
|
||||
@@ -261,7 +302,6 @@ jobs:
|
||||
setenvs: export LIBRAW_VERSION=0.20.2
|
||||
LIBTIFF_VERSION=v4.5.0
|
||||
OPENCOLORIO_VERSION=v2.3.0
|
||||
OPENIMAGEIO_OPTIONS="openexr:core=1"
|
||||
OPENJPEG_VERSION=v2.4.0
|
||||
PTEX_VERSION=v2.4.0
|
||||
PUGIXML_VERSION=v1.13
|
||||
@@ -282,7 +322,6 @@ jobs:
|
||||
setenvs: export LIBRAW_VERSION=master
|
||||
LIBTIFF_VERSION=master
|
||||
OPENCOLORIO_VERSION=main
|
||||
OPENIMAGEIO_OPTIONS="openexr:core=1"
|
||||
OPENJPEG_VERSION=master
|
||||
PTEX_VERSION=main
|
||||
PUGIXML_VERSION=master
|
||||
@@ -296,14 +335,13 @@ jobs:
|
||||
cxx_compiler: clang++
|
||||
cc_compiler: clang
|
||||
cxx_std: 20
|
||||
fmt_ver: 9.0.0
|
||||
openexr_ver: v3.1.5
|
||||
fmt_ver: 10.1.1
|
||||
openexr_ver: v3.1.11
|
||||
pybind11_ver: v2.9.2
|
||||
python_ver: 3.8
|
||||
simd: avx2,f16c
|
||||
setenvs: export LLVM_VERSION=14.0.0
|
||||
OPENCOLORIO_VERSION=v2.1.2
|
||||
OPENIMAGEIO_OPTIONS="openexr:core=1"
|
||||
USE_OPENVDB=0
|
||||
# The installed OpenVDB has a TLS conflict with Python 3.8
|
||||
- desc: debug gcc7/C++14, sse4.2, exr2.4
|
||||
|
||||
@@ -14,7 +14,7 @@ This is a checklist for TSC's to review as part of the intake process. The TSC s
|
||||
- [ ] A [SUPPORT.md](../SUPPORT.md) file to let users and developers know about ways to get help with your project.
|
||||
- Infrastructure/Assets
|
||||
- [X] Technical Charter Approved
|
||||
- [ ] **(Awaiting scan from LF)** License scan completed and no issues found
|
||||
- [X] License scan completed and no issues found
|
||||
- [ ] Code repository imported to ASWF GitHub organization or ownership of current GitHub organization given to `thelinuxfoundation` user
|
||||
- [X] Developer Certificate of Origin past commit signoff done and DCO Probot enabled.
|
||||
- [X] Issue/feature tracker established (JIRA, GitHub issues)
|
||||
@@ -36,7 +36,7 @@ This is a checklist for TSC's to review as part of the intake process. The TSC s
|
||||
- [X] CLA Approved ( if used ) ( [CCLA](CLA-corporate.md) and [ICLA](CLA-individual.md) )
|
||||
- Project charter ( [Technical-Charter.md](Technical-Charter.md) )
|
||||
- [X] Approved by TSC
|
||||
- [ ] Filed ( create pull request against [foundation repo](https://github.com/AcademySoftwareFoundation/foundation) )
|
||||
- [X] Filed ( create pull request against [foundation repo](https://github.com/AcademySoftwareFoundation/foundation) )
|
||||
- [X] [Core Infrastructure Initiative Best Practices Badge](https://bestpractices.coreinfrastructure.org/) achieved as the 'Passing' level.
|
||||
- Outreach
|
||||
- [ ] New project announcement done ( create [issue on foundation repo](https://github.com/AcademySoftwareFoundation/foundation/issues/new) to trigger )
|
||||
|
||||
+648
-45
@@ -1,5 +1,622 @@
|
||||
Release 2.4.16.0 (1 Oct? 2023) -- compared to 2.4.15.0
|
||||
-------------------------------------------------------
|
||||
Release 2.5 (Fall 2023) -- compared to 2.4
|
||||
-------------------------------------------------
|
||||
|
||||
Beta 1: 2023-09-04
|
||||
|
||||
### New minimum dependencies and compatibility changes:
|
||||
* CMake: minimum needed to build OpenImageIO has been raised from 3.12 to
|
||||
3.15. [#3924](https://github.com/OpenImageIO/oiio/pull/3924) (2.5.2.1)
|
||||
* LibRaw: minimum has ben raised from 0.15 to 0.18.
|
||||
[#3921](https://github.com/OpenImageIO/oiio/pull/3921) (2.5.2.1)
|
||||
* The new OpenEXR minimum is 2.4 (raised from 2.3).
|
||||
[#3928](https://github.com/OpenImageIO/oiio/pull/3928) (2.5.2.1)
|
||||
* The new `fmt` library minimum is 7.0 (raised from 6.1)
|
||||
[#3973](https://github.com/OpenImageIO/oiio/pull/3973) (2.5.3.0)
|
||||
|
||||
### ⛰️ New features and public API changes:
|
||||
|
||||
* TextureSystem color management: [#3761](https://github.com/OpenImageIO/oiio/pull/3761) (2.5.1.0)
|
||||
- TextureOpt and TextureOptBatch have a new field, `colortransformid`,
|
||||
which supplies an integer ID for a requested color space transformation
|
||||
to be applied as texture tiles are read. The default value 0 means no
|
||||
transformation because the texture is presumed to be in the working
|
||||
color space (this is the old behavior, and most performant). Tiles from
|
||||
the same texture file but using different color transformations are
|
||||
allowed and will not interfere with each other in the cache.
|
||||
- New `TextureSystem::get_colortransform_id(from, to)` maps from/to named
|
||||
color spaces to a color transform ID that can be passed to texture
|
||||
lookup calls.
|
||||
- `ImageCache::get_image_handle` and `TextureSystem::get_texture_handle`
|
||||
now take an optional `TextureOpt*` parameter that can supply additional
|
||||
constraints (such as color transformation) that TS/IC implementations
|
||||
may wish to split into separate handles. This is currently not used, but
|
||||
is reserved so that the API doesn't need to be changed if we use it in
|
||||
the future.
|
||||
- texture.h defines symbol `OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE` that
|
||||
can be tested for existence to know if the new fields are in the
|
||||
TextureOpt structure.
|
||||
* Extensive support for OpenColorIO 2.2 functionality and improved color
|
||||
management:
|
||||
- When building against OCIO 2.2, you can specify/use the new "built-in"
|
||||
configs, including using `ocio://default`, which will automatically be
|
||||
usd if no config is specified and the `$OCIO` variable is not set #3662
|
||||
#3707 (2.5.0.0)
|
||||
- OIIO tries to find and honor the common color space aliases
|
||||
"scene_linear", "srgb", "lin_srgb", and "ACEScg". When building against
|
||||
OCIO 2.2+, it will know which of any config's color spaces are
|
||||
equivalent to these, even if they are named something totally different,
|
||||
thanks to the magic of OCIO 2.2 built-in configs. For older OCIO (2.1 or
|
||||
older), it is less robust and may have to make best guesses based on the
|
||||
name of the color spaces it finds. #3707 (2.5.0.0)
|
||||
- New ColorConfig methods: `getAliases()` #3662; `isColorSpaceLinear()`
|
||||
#3662; `resolve(name)` turns any color space name, alias, role, or OIIO
|
||||
name (like "sRGB") into a canonical color space name;
|
||||
`equivalent(n1,n2)` returns true if it can tell that the two names
|
||||
refer, ultimately, to equivalent color spaces #3707 (2.5.0.0)
|
||||
- New `ImageSpec::set_colorspace()` method is a more thorough way to set
|
||||
the color space data than simply setting the "oiio:ColorSpace" metadata
|
||||
(though it also does that). #3734 (2.5.0.1)
|
||||
- Improve OIIO's ability to guess which of the config's color space names
|
||||
are aliases for common spaces such as srgb, lin_srgb, and acescg (quite
|
||||
robustly if using OCIO >= 2.2, even for totally nonstandard names in the
|
||||
config). #3755 (2.5.0.1)
|
||||
- New `ColorConfig::getColorSpaceIndex()` looks up a color space index by
|
||||
its name, alias, or role. #3758 (2.5.0.1)
|
||||
* oiiotool new commands and features:
|
||||
- New `--iccread` and `--iccwrite` add an ICC profile from an external
|
||||
file to the metadata of an image, or extract the ICC profile metadata
|
||||
and save it as a separate file. #3550 (2.5.0.0)
|
||||
- New `--parallel-frames` parallelizes execution over a frame range rather
|
||||
than over regions within each image operation. This should be used with
|
||||
caution, as it will give incorrect results for an oiiotool command line
|
||||
involving a frame range where the iterations have a data dependency on
|
||||
each other and must be executed in order. But in cases where the order
|
||||
of frame processing doesn't matter and there are many more frames in the
|
||||
sequence than cores, you can get a substantial performance improvement
|
||||
using this flag. [#3849](https://github.com/OpenImageIO/oiio/pull/3849) (2.5.2.0)
|
||||
- New `--no-error-exit` causes an error to not exit immediately, but
|
||||
rather to try to execute the remaining command line operations. This is
|
||||
intended primarily for unit tests and debugging. #3643 (2.5.0.0)
|
||||
- New `--colorconfiginfo` prints the full inventory of color management
|
||||
information, including color space aliases, roles, and with improved
|
||||
readability of output for larger configs. #3707 (2.5.0.0)
|
||||
- The `--resize` command takes new optional `:from=`, `:to=`, and
|
||||
`:edgeclamp=` modifiers to give more general and fine control over the
|
||||
specific correspondence between display windows in the input image and
|
||||
resized destination image (including allowing partial pixel offsets).
|
||||
#3751 #3752 (2.5.0.1)
|
||||
- New expression substitution additions:
|
||||
- New syntax for retrieving metadata `{TOP[foo]}` is similar to the
|
||||
existing `{TOP.foo}`, if there is no `foo` metadata found, the
|
||||
former evaluates to an empty string, whereas the latter is an error.
|
||||
#3619 (2.4.5/2.5.0.0)
|
||||
- `{NIMAGES}` gives current stack depth
|
||||
[#3822](https://github.com/OpenImageIO/oiio/pull/3822) (2.5.2.0)
|
||||
- `{nativeformat}` is the pixel data format of the file, whereas the
|
||||
existing `format` has always returned the data type used in memory.
|
||||
Also, `METANATIVE` and `METANATIVEBRIEF` are the full metadata
|
||||
keywords for native file metadata, comapred to the previously
|
||||
existing `META` and `METABRIEF` which we now clarify reflect the
|
||||
in-memory representation. #3639 (2.5.0.0)
|
||||
- `--ociodisplay` now takes an optional `:inverse=1` modifier. #3650
|
||||
(2.5.0.0)
|
||||
- New `-otex` optional modifier `forcefloat=0` can improve memory use for
|
||||
enormous texture conversion.
|
||||
[#3829](https://github.com/OpenImageIO/oiio/pull/3829) (2.5.2.0)
|
||||
- `--printinfo` now takes new optional modifiers: `:native=1` ensures
|
||||
that the metadata printed is of the file, not changed by the way the
|
||||
image is stored in memory (for example, it may have been converted to
|
||||
a more convenient in-memory data type); `:verbose=1` prints verbose
|
||||
stats even if `-v` is not used; `:stats=1` prints full pixel stats,
|
||||
even if `--stats` is not used. #3639 (2.5.0.0)
|
||||
- New `--normalize` mormalizes image that represent 3D vectors (i.e.,
|
||||
divide by their length) textures. This is helpful for normal maps.
|
||||
[#3945](https://github.com/OpenImageIO/oiio/pull/3945) (by Vlad (Kuzmin) Erium) (2.5.3.0)
|
||||
* ImageBufAlgo additions:
|
||||
- A new flavor of `ociodisplay()` now contains an inverse parameter.
|
||||
#3650 (2.5.0.0)
|
||||
- New `normalize()` normalizes image that represent 3D vectors (i.e.,
|
||||
divide by their length) textures. This is helpful for normal maps.
|
||||
[#3945](https://github.com/OpenImageIO/oiio/pull/3945) (by Vlad (Kuzmin)
|
||||
Erium) [#3963](https://github.com/OpenImageIO/oiio/pull/3963) (2.5.3.0)
|
||||
* ImageInput / ImageOutput
|
||||
- New `ImageOutput::check_open()` method can be used by format writers
|
||||
authors to centralize certain validity tests so they don't need to be
|
||||
implemented separately for each file type. This is not meant to be
|
||||
called by client application code, only by format writer authors. #3686
|
||||
(2.5.0.0)
|
||||
- Add an `ImageInput::valid_file(IOProxy)` overload
|
||||
[#3826](https://github.com/OpenImageIO/oiio/pull/3826) (by Jesse Y)
|
||||
(2.5.2.0) and implement its overloads for DDS, PSD, and WEBP
|
||||
[#3831](https://github.com/OpenImageIO/oiio/pull/3831) (by Jesse Y)
|
||||
(2.5.2.0)
|
||||
- New `ImageOutput::check_open()` and `ImageInput::open_check()` can be
|
||||
used by format reader/writer authors to centralize certain validity
|
||||
tests so they don't need to be implemented separately for each file
|
||||
type. This is not meant to be called by client application code, only by
|
||||
format reader/writer authors.
|
||||
[#3686](https://github.com/OpenImageIO/oiio/pull/3686) (2.5.0.0)
|
||||
[#3967](https://github.com/OpenImageIO/oiio/pull/3967) (2.5.3.0)
|
||||
- *ImageInput*: Add an ImageInput::valid_file(IOProxy) overload
|
||||
[#3826](https://github.com/OpenImageIO/oiio/pull/3826) (by Jesse Y) (2.5.2.0)
|
||||
- *ImageInput*: Implement valid_file(IOProxy) overloads for DDS, PSD, and
|
||||
WEBP [#3831](https://github.com/OpenImageIO/oiio/pull/3831) (by Jesse
|
||||
Y) (2.5.2.0)
|
||||
* New top-level `namespace OIIO` functions:
|
||||
- `OIIO::shutdown()` method [#3882](https://github.com/OpenImageIO/oiio/pull/3882) (by Ray Molenkamp)
|
||||
- `OIIO::default_thread_pool_shutdown()` [#2382](https://github.com/OpenImageIO/oiio/pull/2382)
|
||||
- `OIIO::print()` exposes `Strutil::print()` in the main OIIO namespace.
|
||||
#3667 (2.4.6/2.5.0.0)
|
||||
* OIIO::getattribute() new queries:
|
||||
- `font_list`, `font_file_list`, `font_dir_list` return, respectively, the
|
||||
list of fonts that OIIO found, the list of full paths to font files, and
|
||||
the list of directories searched for fonts. All return a single string
|
||||
that is a semicolon-separated list of the items. #3633 (2.5.0.0)
|
||||
- `opencolorio_version` returns the human-readable (e.g. "2.2.0") version
|
||||
of OpenColorIO that is being used. #3662 (2.5.0.0)
|
||||
* IOProxy support for additional file formats: SGI #3641, RLA #3642, IFF #3647
|
||||
(2.5.0.0), ICO input [#3919](https://github.com/OpenImageIO/oiio/pull/3919)
|
||||
(by jasonbaumeister) (2.5.2.0)
|
||||
* Remove long deprecated/nonfunctional C API headers [#3567](https://github.com/OpenImageIO/oiio/pull/3567)
|
||||
|
||||
### 🚀 Performance improvements:
|
||||
|
||||
- Fixed some ImageBuf and IBA internals to avoid unnecessary/redundant zeroing
|
||||
out of newly allocated buffer memory. #3754 (2.5.0.1)
|
||||
- *oiiotool*: `--parallel-frames` parallelizes execution over a frame
|
||||
range rather than over regions within each image operation.
|
||||
[#3849](https://github.com/OpenImageIO/oiio/pull/3849) (2.5.2.0)
|
||||
- *psd*: Improve memory efficiency of PSD read
|
||||
[#3807](https://github.com/OpenImageIO/oiio/pull/3807) (2.5.2.0)
|
||||
- Improvements to performance and memory when making very large textures
|
||||
[#3829](https://github.com/OpenImageIO/oiio/pull/3829) (2.5.2.0)
|
||||
- OpenEXR: Change to using exr-core for reading by default [#3788](https://github.com/OpenImageIO/oiio/pull/3788)
|
||||
- TextureSystem: Improve texture lookup performance by remove redundant
|
||||
instructions from tile hash [#3898](https://github.com/OpenImageIO/oiio/pull/3898) (by Curtis Black) (2.5.2.0)
|
||||
|
||||
### 🐛 Fixes and feature enhancements:
|
||||
|
||||
* ImageInput: fix typo in debug output [#3956](https://github.com/OpenImageIO/oiio/pull/3956) (by Jesse Yurkovich)
|
||||
* Python bindings:
|
||||
- Add ability to `getattribute()` of int64 and uint64 data [#3555](https://github.com/OpenImageIO/oiio/pull/3555) (2.5.0.0)
|
||||
- Fixed ability to add and retrieve `uint8[]` metadata, which on the
|
||||
python side will be numpy arrays of type uint8 (dtype='B'). This is
|
||||
important for being able to set and retrieve "ICCProfile" metadata.
|
||||
#3556 (2.5.0.0)
|
||||
- Eliminate redundant code in Python IBA bindings [#3615](https://github.com/OpenImageIO/oiio/pull/3615)
|
||||
- Improve error messages for when passing incorrect python array sizes.
|
||||
#3801 (2.5.1.0)
|
||||
- Fix arithmetic overflow in oiio_bufinfo (Python interop) [#3931](https://github.com/OpenImageIO/oiio/pull/3931) (by Jesse Yurkovich) (2.5.2.0)
|
||||
* ImageBuf improvements:
|
||||
- Fixes to subtle bugs when ImageBuf is used with IOProxy. #3666
|
||||
(2.4.6/2.5.0.0)
|
||||
- Auto print uncaught ImageBuf errors. When an IB is destroyed, any errors
|
||||
that were never retrieved via `geterror()` will be printed, to aid users
|
||||
who would not notice the errors otherwise.
|
||||
[#3949](https://github.com/OpenImageIO/oiio/pull/3949) (2.5.3.0)
|
||||
* ImageBufAlgo improvements:
|
||||
- IBAPrep should not zero out deep images when creating a new destination
|
||||
image. #3724 (2.5.0.0/2.4.8.0)
|
||||
- Improve error message for IBA::ocio functions [#3887](https://github.com/OpenImageIO/oiio/pull/3887)
|
||||
- UTF-8 text rendering fixes [#3935](https://github.com/OpenImageIO/oiio/pull/3935)
|
||||
(by Nicolas) (2.5.3.0)
|
||||
* make_texture() / maketx / TextureSystem / ImageCache:
|
||||
- Ensure proper setting of certain metadata when using a texture as a
|
||||
source to build another texture. #3634 (2.4.5/2.5.0.0)
|
||||
- Minor improvements in statistics printing for IC. #3654 (2.5.0.0)
|
||||
- When creating a texture, don't overwrite an existing DateTime metadata
|
||||
in the source file. #3692 (2.5.0.0)
|
||||
- Fix environment mapping in batch mode when >4 channels are requested in
|
||||
a lookup. #3694 (2.5.0.0)
|
||||
- Fixed `maketx --lightprobe`, which never worked properly for images
|
||||
that weren't `float` pixel data type. #3732 (2.5.0.0/2.4.7.0)
|
||||
- Fix bad handling of `maketx --cdf`, which was trying to take an extra
|
||||
command line argument that it didn't need. #3748 (2.5.0.1)
|
||||
- Improve IC statistics appearance by omitting certain meaningless stats
|
||||
when no files were read by the IC/TS. #3765 (2.4.9.0/2.5.0.1)
|
||||
- Fixes that avoid deadlock situations on the file handle cache in certain
|
||||
scenarios with very high thread contention. #3784 (2.4.10.0/2.5.0.3)
|
||||
- maketx and oiiotool --otex: Add support for CDFs of bumpslopes channels.
|
||||
Previously, if you used both --bumpslopes and --cdf at the same time,
|
||||
the CDFs were not produced for all channels. #3793 (by Tom Knowles) (2.4.10.0/2.5.1.0)
|
||||
* oiiotool improvements:
|
||||
- When `-q` (quiet mode) is used, and when an error occurs, only print the
|
||||
error message and not the full help message. #3649 (2.5.0.0)
|
||||
- Fix problems with `--point` when there is no alpha channel. #3684
|
||||
(2.4.6/2.5.0.0)
|
||||
- `--dumpdata` fix channel name output. #3687 (2.4.6/2.5.0.0)
|
||||
- `--help` now prints a much abbreviated color management section (just the
|
||||
OCIO version and config file). Use the new `--colorconfiginfo` argument
|
||||
to print the full color management information, which is both more
|
||||
readable and more detailed than what `--help` used to print. #3707
|
||||
(2.5.0.0)
|
||||
- Don't propagate unsupported channels
|
||||
[#3838](https://github.com/OpenImageIO/oiio/pull/3838) (2.5.2.0)
|
||||
- *refactor*: Get rid of the global Oiiotool singleton.
|
||||
[#3848](https://github.com/OpenImageIO/oiio/pull/3848) (2.5.2.0)
|
||||
- *oiiotool*: Work around static destruction order issue #3295 [#3591](https://github.com/OpenImageIO/oiio/pull/3591) (by Aras Pranckevičius)
|
||||
* ICC Profiles found in JPEG, JPEG-2000, PSN, PSD, and TIFF files are now
|
||||
examined and several key fields are extracted as separate metadata. #3554
|
||||
(2.5.0.0)
|
||||
* Various protections against corrupted files [#3954](https://github.com/OpenImageIO/oiio/pull/3954) (2.5.3.0)
|
||||
* BMP:
|
||||
- Fix reading 16bpp images. [#3592](https://github.com/OpenImageIO/oiio/pull/3592) (by Aras Pranckevičius) (2.4.5/2.5.0.0)
|
||||
- Protect against corrupt pixel coordinates. (TALOS-2022-1630,
|
||||
CVE-2022-38143) [#3620](https://github.com/OpenImageIO/oiio/pull/3620) (2.4.5/2.5.0.0)
|
||||
- Fix possible write errors, fixes TALOS-2022-1653 / CVE-2022-43594,
|
||||
CVE-2022-43595. #3673 (2.4.6/2.5.0.0)
|
||||
- Mark color space as sRGB, which seems likely to be true of any BMP
|
||||
files anybody encounters. #3701 (2.5.0.0)
|
||||
- Fix signed integer overflow when computing total number of pixels
|
||||
[#3948](https://github.com/OpenImageIO/oiio/pull/3948) (by xiaoxiaoafeifei) (2.5.3.0)
|
||||
* DDS:
|
||||
- Fix heap overflow in DDS input. #3542 (2.5.0.0)
|
||||
- Improved support for DTX5, ATI2/BC5 normal maps, R10G10B10A2
|
||||
format, RXGB, BC4U, BC5U, A8, improved low bit expansion to 8 bits.
|
||||
[#3573](https://github.com/OpenImageIO/oiio/pull/3573)
|
||||
(by Aras Pranckevičius)(2.4.4.2/2.5.0.0)
|
||||
- Fix alpha/luminance files, better testing. [#3581](https://github.com/OpenImageIO/oiio/pull/3581) (by Aras Pranckevičius) (2.4.5/2.5.0.0)
|
||||
- Optimize loading of compressed images, improves 3-5x. [#3583](https://github.com/OpenImageIO/oiio/pull/3583) (by Aras Pranckevičius) #3584
|
||||
(2.4.5/2.5.0.0)
|
||||
- Honor ImageInput thread policy [#3584](https://github.com/OpenImageIO/oiio/pull/3584)
|
||||
- Fix crashes for cubemap files when a cube face was not present, and
|
||||
check for invalid bits per pixel. (TALOS-2022-1634, CVE-2022-41838)
|
||||
(TALOS-2022-1635, CVE-2022-41999) [#3625](https://github.com/OpenImageIO/oiio/pull/3625) (2.4.5/2.5.0.0)
|
||||
(TALOS-2022-1635, CVE-2022-41999) #3625 (2.4.5/2.5.0.0)
|
||||
- Fix divide-by-0 during DXT4 DDS load [#3959](https://github.com/OpenImageIO/oiio/pull/3959) (by Jesse Yurkovich) (2.5.3.0)
|
||||
* DPX:
|
||||
- Fix possible write errors, fixes TALOS-2022-1651 / CVE-2022-43592 and
|
||||
TALOS-2022-1652 / CVE-2022-43593. #3672 (2.4.6/2.5.0.0)
|
||||
* FITS:
|
||||
- Ensure that the file is closed if open fails to find the right magic
|
||||
number. #3771 (2.5.1.0)
|
||||
* GIF:
|
||||
- Fix potential array overrun when writing GIF files. #3789
|
||||
(2.4.10.0/2.5.1.0)
|
||||
- Prevent heap-buffer-overflow
|
||||
[#3841](https://github.com/OpenImageIO/oiio/pull/3841) (2.5.2.0) (by
|
||||
xiaoxiaoafeifei)
|
||||
* HEIC:
|
||||
- Support the ".hif" extension, which seems to be used by some Canon
|
||||
cameras instead of .heif.
|
||||
[#3813](https://github.com/OpenImageIO/oiio/pull/3813)(by AdamMainsTL)
|
||||
* HDR:
|
||||
- Fix a 8x (!) read performance regression for HDR files that was
|
||||
introduced in OIIO in 2.4. On top of that, speed up by another 4x beyond
|
||||
what we ever did before by speeding up the RGBE->float conversion.
|
||||
[#3588](https://github.com/OpenImageIO/oiio/pull/3588) [#3590](https://github.com/OpenImageIO/oiio/pull/3590)
|
||||
(by Aras Pranckevičius) (2.4.5/2.5.0.0)
|
||||
* ICO:
|
||||
- Heap-buffer-overflow [#3872](https://github.com/OpenImageIO/oiio/pull/3872) (by xiaoxiaoafeifei) Fixes CVE-2023-36183.
|
||||
* IFF:
|
||||
- Protect against 0-sized allocations. #3603 (2.5.0.0)
|
||||
- IOProxy support. #3647 (2.4.6/2.5.0.0)
|
||||
FIXME Temporarily disable IOProxy support to avoid bugs in #3760
|
||||
(2.5.0.1)
|
||||
- Fix possible write errors, fixes TALOS-2022-1654 / CVE-2022-43596,
|
||||
TALOS-2022-1655 / CVE-2022-43597 CVE-2022-43598, TALOS-2022-1656 /
|
||||
CVE-2022-43599 CVE-2022-43600 CVE-2022-43601 CVE-2022-43602 #3676
|
||||
(2.4.6/2.5.0.0)
|
||||
- Catch possible exception, identified by static analysis [#3681](https://github.com/OpenImageIO/oiio/pull/3681)
|
||||
* JPEG
|
||||
- *jpeg*: Fix density calculation for jpeg output
|
||||
[#3861](https://github.com/OpenImageIO/oiio/pull/3861) (2.5.2.0) (by
|
||||
Loïc Vital)
|
||||
* JPEG2000:
|
||||
- Better pixel type promotion logic [#3878](https://github.com/OpenImageIO/oiio/pull/3878) (2.5.2.0)
|
||||
* OpenEXR:
|
||||
- Fix potential use of uninitialized value when closing. #3764 (2.5.0.1)
|
||||
- Try to improve exr thread pool weirdness
|
||||
[#3864](https://github.com/OpenImageIO/oiio/pull/3864) (2.5.2.0)
|
||||
- Controlled shutdown of IlmThread pool in all apps in which we use it.
|
||||
[#3805](https://github.com/OpenImageIO/oiio/pull/3805) (2.5.2.0)
|
||||
- Correction to dwa vs zip logic when outputting OpenEXR [#3884](https://github.com/OpenImageIO/oiio/pull/3884) (2.5.2.0)
|
||||
- Enable openexr core library by default when recent enough
|
||||
[#3942](https://github.com/OpenImageIO/oiio/pull/3942) (2.5.3.0)
|
||||
* PBM:
|
||||
- Fix accidental inversion for 1-bit bitmap pbm files. [#3731](https://github.com/OpenImageIO/oiio/pull/3731)
|
||||
(2.5.0.0/2.4.8.0)
|
||||
* PNG:
|
||||
- Fix memory leaks for error conditions. #3543 #3544 (2.5.0.0)
|
||||
- Add EXIF write support to PNG output. [#3736](https://github.com/OpenImageIO/oiio/pull/3736) (by Joris Nijs) (2.5.0.1)
|
||||
* PSD:
|
||||
- Fix a PSD read error on ARM architecture. #3589 (2.4.5/2.5.0.0)
|
||||
- Protect against corrupted embedded thumbnails. (TALOS-2022-1626,
|
||||
CVE-2022-41794) #3629 (2.4.5/2.5.0.0)
|
||||
- Fix thumbnail extraction. #3668 (2.4.6/2.5.0.0)
|
||||
- When reading, don't reject padded thumbnails. #3677 (2.4.6/2.5.0.0)
|
||||
- Fix wrong "oiio:UnassociatedAlpha" metadata. #3750 (2.5.0.1)
|
||||
- Handle very wide images with more than 64k resolution in either
|
||||
direction. #3806 (2.5.1.0/2.4.11)
|
||||
- Improve memory efficiency of PSD read [#3807](https://github.com/OpenImageIO/oiio/pull/3807) (2.5.2.0)
|
||||
- Prevent simultaneous psd thumbnail reads from clashing [#3877](https://github.com/OpenImageIO/oiio/pull/3877)
|
||||
- CMYK PSD files now copy alpha correctly [#3918](https://github.com/OpenImageIO/oiio/pull/3918) (by jasonbaumeister) (2.5.2.0)
|
||||
* RAW:
|
||||
- Add color metadata: pre_mul, cam_mul, cam_xyz, rgb_cam. #3561 #3569
|
||||
#3572 (2.5.0.0)
|
||||
- Update Exif orientation if user flip is set. #3669 (2.4.6/2.5.0.0)
|
||||
- Correctly handle 1-channel raw images. #3798 (2.5.1.0/2.4.11.0)
|
||||
- Fix LibRaw flip to Exif orientation conversion
|
||||
[#3847](https://github.com/OpenImageIO/oiio/pull/3847)
|
||||
[#3858](https://github.com/OpenImageIO/oiio/pull/3858) (2.5.2.0) (by
|
||||
Loïc Vital)
|
||||
* RLA:
|
||||
- Fix potential buffer overrun. (TALOS-2022-1629, CVE-2022-36354) #3624
|
||||
(2.4.5/2.5.0.0)
|
||||
- IOProxy support. #3642 (2.5.0.0)
|
||||
- Fix possible invalid read from an empty vector during RLA load
|
||||
[#3960](https://github.com/OpenImageIO/oiio/pull/3960) (by Jesse Yurkovich) (2.5.3.0)
|
||||
* SGI:
|
||||
- IOProxy support. #3641 (2.5.0.0)
|
||||
* Targa:
|
||||
- Fix incorrect unique_ptr allocation. #3541 (2.5.0.0)
|
||||
- Fix string overflow safety. (TALOS-2022-1628, CVE-2022-41981)
|
||||
[#3622](https://github.com/OpenImageIO/oiio/pull/3622) (2.4.5/2.5.0.0)
|
||||
- Guard against corrupted tga files Fixes TALOS-2023-1707 /
|
||||
CVE-2023-24473, TALOS-2023-1708 / CVE-2023-22845. #3768 (2.5.1.0/2.4.8.1)
|
||||
* TIFF:
|
||||
- Guard against corrupt files with buffer overflows. (TALOS-2022-1627,
|
||||
CVE-2022-41977) [#3628](https://github.com/OpenImageIO/oiio/pull/3628) (2.4.5/2.5.0.0)
|
||||
- Guard against buffer overflow for certain CMYK files. (TALOS-2022-1633,
|
||||
CVE-2022-41639) (TALOS-2022-1643, CVE-2022-41988)
|
||||
[#3632](https://github.com/OpenImageIO/oiio/pull/3632) (2.4.5/2.5.0.0)
|
||||
- While building against the new libtiff 4.5, use its new per-tiff error
|
||||
handlers to ensure better thread safety. #3719 (2.5.0.0/2.4.8.0)
|
||||
- Better logic for making TIFF PhotometricInterpretation tag and
|
||||
oiio:ColorSpace metadata correspond to each other correctly for TIFF
|
||||
files. [#3746](https://github.com/OpenImageIO/oiio/pull/3746) (2.5.0.1)
|
||||
- Fix: race condition in TIFF reader, fixes TALOS-2023-1709 /
|
||||
CVE-2023-24472. #3772 (2.5.1.0/2.4.8.1)
|
||||
- Disable writing TIFF files with JPEG compression -- it never worked
|
||||
properly and we can't seem to fix it. The fact that nobody noticed that
|
||||
it never worked is taken as evidence that nobody needs it. If asked for,
|
||||
it just uses the default ZIP compression instead. The TIFF reader can
|
||||
still read JPEG-compressed TIFF files just fine, it's only writing that
|
||||
appears problematic. #3791 (2.5.0.4)
|
||||
* Zfile:
|
||||
- Zfile write safety, fixes TALOS-2022-1657 / CVE-2022-43603. #3670
|
||||
(2.4.6/2.5.0.0)
|
||||
* Exif (all formats that support it, TIFF/JPEG/PSD):
|
||||
- Fix EXIF bugs where corrupted exif blocks could overrun memory.
|
||||
(TALOS-2022-1626, CVE-2022-41794) (TALOS-2022-1632, CVE-2022-41684)
|
||||
(TALOS-2022-1636 CVE-2022-41837) #3627 (2.4.5/2.5.0.0)
|
||||
- Fix typo that prevented us from correctly naming Exif
|
||||
"CameraElevationAngle" metadata.
|
||||
[#3783](https://github.com/OpenImageIO/oiio/pull/3783) (by Fabien
|
||||
Castan) (2.4.10.0/2.5.1.0)
|
||||
- Convert paramvalue string to integer when needed [#3886](https://github.com/OpenImageIO/oiio/pull/3886) (by Fabien Servant @ TCS) (2.5.2.0)
|
||||
- Squash some alignment problems caught by ubsan [#3646](https://github.com/OpenImageIO/oiio/pull/3646)
|
||||
* Fix missing OIIO::getattribute support for `limits:channels` and
|
||||
`limits:imagesize_MB`. #3617 (2.4.5/2.5.0.0)
|
||||
* IBA::render_text and `oiiotool --text` now can find ".ttc" font files. #3633
|
||||
(2.5.0.0)
|
||||
* Fix ImageOutput::check_open error conditions. #3769 (2.5.1.0)
|
||||
* Fix thread safety issue when reading ICC profiles from multiple files
|
||||
simultaneously. This could affect any files with ICC profiles. #3767
|
||||
(2.5.1.0)
|
||||
* Improve searching for fonts for the text rendering functionality. #3802
|
||||
#3803 (2.5.1.0)
|
||||
* Improve OpenCV support -- errors, version, half
|
||||
[#3853](https://github.com/OpenImageIO/oiio/pull/3853) (2.5.2.0)
|
||||
* Prevent possible deadlock when reading files with wrong extensions
|
||||
[#3845](https://github.com/OpenImageIO/oiio/pull/3845)
|
||||
* Wait for terminated threads to join in thread_pool::Impl::resize [#3879](https://github.com/OpenImageIO/oiio/pull/3879) (by Ray Molenkamp)
|
||||
|
||||
### 🔧 Internals and developer goodies
|
||||
|
||||
* filesystem.h:
|
||||
- Add an optional size parameter to `read_text_file()` to limit the
|
||||
maximum size that will be allocated and read (default to a limit of
|
||||
16MB). New `read_text_from_command()` is similar to `read_text_file`,
|
||||
but reads from the console output of a shell command. #3635 (2.5.0.0)
|
||||
- New `Filesystem::is_executable()` and `find_program()`. #3638
|
||||
(2.4.6/2.5.0.0)
|
||||
- Change IOMemReader constructor to take a const buffer pointer. #3665
|
||||
(2.4.6/2.5.0.0)
|
||||
- IOMemReader::pread now detects and correctly handles out-of-range
|
||||
read positions. #3712 (2.4.7/2.5.0.0)
|
||||
* fmath.h:
|
||||
- Fix a wrong result with `fast_exp2()` with MSVS and sse4.2.
|
||||
[#3804](https://github.com/OpenImageIO/oiio/pull/3804) (by Eric Mehl)
|
||||
(2.5.1.0/2.4.11)
|
||||
* platform.h:
|
||||
- New macros for detecting MSVS 2019 and 2022. #3727 (2.5.0.0/2.4.8.0)
|
||||
* simd.h:
|
||||
- Fixes to ensure safe compilation for Cuda. #3810 (2.5.1.0/2.4.11)
|
||||
- Fix sense of hiding deprecated type names [#3870](https://github.com/OpenImageIO/oiio/pull/3870) (2.5.2.0)
|
||||
- Fix broken OIIO_NO_NEON definition [#3911](https://github.com/OpenImageIO/oiio/pull/3911)
|
||||
* span.h:
|
||||
- `cspan<>` template now allows for Extent template argument (as `span<>`
|
||||
already did). #3685 (2.5.0.0)
|
||||
- New custom fmt formatter can print spans. #3685 (2.5.0.0)
|
||||
* string_view.h:
|
||||
- Avoid sanitizer warning unsigned integer overflow [#3678](https://github.com/OpenImageIO/oiio/pull/3678)(by wayne-arnold-adsk)
|
||||
* strutil.h:
|
||||
- Add a new flavor of `utf16_to_utf8()` to convert between std::u16string
|
||||
and std::string (UTF-8 encoded). Note the contrast between this and the
|
||||
existing flavor that takes a `std::wstring` with UTF-16 encoding
|
||||
(`std::wchar/wstring` is not guaranteed to 16 bits on all platforms, but
|
||||
`u16char/u16string` is). #3553 (2.5.0.0)
|
||||
- New `trimmed_whitspace()`. [#3636](https://github.com/OpenImageIO/oiio/pull/3636) (2.4.5/2.5.0.0)
|
||||
- Use std::forward properly for sync::print().
|
||||
[#3825](https://github.com/OpenImageIO/oiio/pull/3825) (2.5.2.0)
|
||||
- Ensure proper constexpr of string hashing [#3901](https://github.com/OpenImageIO/oiio/pull/3901)
|
||||
* timer.h:
|
||||
- Minor improvements to Timer and LoggedTimer classes. #3753 (2.5.0.1)
|
||||
* tiffutils.h:
|
||||
- `decode_icc_profile` extracts several fields from an ICC profile binary
|
||||
blob and adds them as metadata to an ImageSpec. #3554 (2.5.0.0)
|
||||
* typedesc.h:
|
||||
- Extend TypeDescFromC template to the full set of pixel types. #3726
|
||||
(2.5.0.0/2.4.8.0)
|
||||
* ustring.h:
|
||||
- Make `std::hash` work for ustring, add `operator<` for ustringhash, add
|
||||
`from_hash()` to ustringhash, make ustringhash `==` and `!=` be
|
||||
constexpr for C++17 and beyond. #3577 (2.4.5/2.5.0.0)
|
||||
- Custom fmt formatter for ustringhash that prints the string rather than
|
||||
the hash. #3614 (2.4.5/2.5.0.0)
|
||||
- Ensure that ustring hashes are always 64 bits, even on 32-bit
|
||||
architectures. #3606 (2.5.0.0)
|
||||
- Ensure safe use of this header from Cuda. #3718 (2.4.7/2.5.0.0)
|
||||
- ustringhash: Make an explicit constructor from a hash value.
|
||||
[#3778](https://github.com/OpenImageIO/oiio/pull/3778) (2.4.9.0/2.5.1.0)
|
||||
- String literal operator for ustring and ustringhash
|
||||
[#3939](https://github.com/OpenImageIO/oiio/pull/3939) (2.5.3.0)
|
||||
* Safety: excise the last instances of unsafe sprintf. #3705 (2.5.0.0)
|
||||
* Root out stray uses of deprecated simd type names; `OIIO_DISABLE_DEPRECATED`
|
||||
[#3830](https://github.com/OpenImageIO/oiio/pull/3830) (2.5.2.0)
|
||||
* Convert iconvert.cpp stream io and sprintf to modern [#3925](https://github.com/OpenImageIO/oiio/pull/3925)
|
||||
|
||||
### 🏗 Build/test/CI and platform ports:
|
||||
|
||||
* CMake build system and scripts:
|
||||
- It is now possible to `-DOpenImageIO_VERSION` to override the version
|
||||
number being built (use with extreme caution). #3549 #3653 (2.5.0.0)
|
||||
- Perform parallel builds with MSVS. #3571 (2.5.0.0)
|
||||
- New CMake cache variable `FORTIFY_SOURCE`, if enabled, builds with the
|
||||
specified gcc `_FORTIFY_SOURCE` option defined. This may be desirable
|
||||
for people deploying OIIO in security-sensitive environments. #3575
|
||||
(2.4.5/2.5.0.0)
|
||||
- CMake config should not include a find of fmt if it's internalized.
|
||||
#3739 (2.4.7.1/2.5.0.0)
|
||||
- New CMake cache variable `OIIO_DISABLE_BOOST_STACKTRACE` to disable the
|
||||
stacktrace functionality for users who want to avoid the Boost
|
||||
stacktrace library. #3777 (by jreichel-nvidia) (2.4.9.0/2.5.1.0)
|
||||
- Check need for libatomic with check_cxx_source_compiles instead of the
|
||||
more expensive check_cxx_source_runs. #3774 (2.4.9.0/2.5.1.0)
|
||||
- Fix incorrect CMake variable name to control symbol visibility
|
||||
[#3834](https://github.com/OpenImageIO/oiio/pull/3834) (2.5.2.0)
|
||||
- Make sure use of `${PROJECT_NAME}` doesn't occur before the call to
|
||||
`project()`. [#3651](https://github.com/OpenImageIO/oiio/pull/3651)
|
||||
- Fix use of OIIO_LOCAL_DEPS_PATH [#3865](https://github.com/OpenImageIO/oiio/pull/3865)
|
||||
- Added check for Boost_NO_BOOST_CMAKE, ignore if already set
|
||||
[#3961](https://github.com/OpenImageIO/oiio/pull/3961) (by Mikael Sundell) (2.5.3.0)
|
||||
* Dependency version support:
|
||||
- Support for OpenColorIO 2.2. #3644 (2.5.0.0)
|
||||
- New CMake option `INTERNALIZE_FMT` (default ON), if set to OFF, will
|
||||
force OIIO clients to use the system fmt library and will not copy the
|
||||
necessary fmt headers into the OIIO include area. #3598 (2.4.7/2.5.0.0)
|
||||
- build_libtiff.bash changed to build shared library by default. #3586
|
||||
(2.5.0.0)
|
||||
- build_openexr.bash changed to build v3.1.5 by default. #3703 (by Michael Oliver) (2.5.0.0)
|
||||
- Qt6 support for iv. #3779 (2.4.9.0/2.5.1.0)
|
||||
- Fmt 10.0 support [#3836](https://github.com/OpenImageIO/oiio/pull/3836) (2.5.2.0)
|
||||
- FFmpeg 6.0 support [#3812](https://github.com/OpenImageIO/oiio/pull/3812) (2.5.2.0)
|
||||
- Disable new warning for fmt headers in gcc13
|
||||
[#3827](https://github.com/OpenImageIO/oiio/pull/3827) (2.5.2.0)
|
||||
- Raise minimum CMake dependency from 3.12 to 3.15 [#3924](https://github.com/OpenImageIO/oiio/pull/3924) (2.5.2.0)
|
||||
- Raise minimum libraw to 0.18 [#3921](https://github.com/OpenImageIO/oiio/pull/3921) (2.5.2.0)
|
||||
- Raise OpenEXR minimum from 2.3 to 2.4 [#3928](https://github.com/OpenImageIO/oiio/pull/3928) (2.5.2.0)
|
||||
- Fix WebP linking if CMAKE_FIND_PACKAGE_PREFER_CONFIG is ON [#3863](https://github.com/OpenImageIO/oiio/pull/3863) (by Benjamin Buch)
|
||||
- Find OpenEXR equally well with our FindOpenEXR and exr's exported config
|
||||
file [#3862](https://github.com/OpenImageIO/oiio/pull/3862) (by Benjamin
|
||||
Buch)
|
||||
- Fix fmt vs gcc warning that had version typo [#3874](https://github.com/OpenImageIO/oiio/pull/3874)
|
||||
- Fix broken libheif < 1.13 [#3970](https://github.com/OpenImageIO/oiio/pull/3970) (2.5.3.0)
|
||||
* Testing and Continuous integration (CI) systems:
|
||||
- Restored sanitizer tests which had been inadvertently disabled. #3545
|
||||
(2.5.0.0)
|
||||
- Added tests for undefined behavior sanitizer. #3565 (2.5.0.0)
|
||||
- Added tests or improved test coverage for Cineon files #3607, iinfo
|
||||
#3605 #3613 #3688 #3706, texture statistics #3612, oiiotool unit tests
|
||||
#3616, oiiotool expression substitution #3636, various oiiotool #3626
|
||||
#3637 #3643 #3649, oiiotool control flow #3643, oiiotool sequence errors
|
||||
and selecting out of range subimages or mip levels #3649, Strutil
|
||||
functionality #3655, ImageCache #3654, environment mapping #3694,
|
||||
texture3d #3699, term output #3714, igrep #3715, oiiotool --pdiff #3723,
|
||||
zover, fixnan for deep images, 2D filters #3730, pbm files #3731, maketx
|
||||
--lightprobe #3732 (2.5.0.0), TypeDesc::tostring, python ImageCache and
|
||||
ImageBuf #3745, maketx #3748 (2.5.0.1), ImageBufAlgo python functions
|
||||
#3766 (2.5.1.0), etc. #3745
|
||||
- Make testsuite/oiiotool-control run much faster by combining commands
|
||||
into fewer oiiotool invocations (speeds up testsuite) #3618 (2.5.0.0)
|
||||
- CI color related tests use the OCIO buit-in configs, when OCIO 2.2+ is
|
||||
available. #3662 (2.5.0.0)
|
||||
- Fix compiler warnings [#3833](https://github.com/OpenImageIO/oiio/pull/3833) (2.5.2.0)
|
||||
- Fix package name for icc [#3860](https://github.com/OpenImageIO/oiio/pull/3860) (2.5.2.0)
|
||||
- Change the few symbolic links to copies to help Windows
|
||||
[#3818](https://github.com/OpenImageIO/oiio/pull/3818) (2.5.2.0)
|
||||
- Fix incorrect branch name when cloning openexr-images for the tests
|
||||
[#3814](https://github.com/OpenImageIO/oiio/pull/3814) (2.5.2.0) (by
|
||||
Jesse Y)
|
||||
- Sonar analysis should exclude stb_sprintf.h [#3609](https://github.com/OpenImageIO/oiio/pull/3609)
|
||||
- Eliminate xxhash and farmhash code from coverage analysis [#3621](https://github.com/OpenImageIO/oiio/pull/3621)
|
||||
- No longer add the ppa:ubuntu-toolchain-r/test repository [#3671](https://github.com/OpenImageIO/oiio/pull/3671)
|
||||
- Test against latest webp, and deal with its master->main repo change [#3695](https://github.com/OpenImageIO/oiio/pull/3695)
|
||||
- Fix broken Mac CI with proper numpy install [#3702](https://github.com/OpenImageIO/oiio/pull/3702)
|
||||
- Lock down to older icc so it's not broken [#3744](https://github.com/OpenImageIO/oiio/pull/3744)
|
||||
- Updates to runners, dependencies [#3786](https://github.com/OpenImageIO/oiio/pull/3786)
|
||||
- Bump 'latest versions' test to the newest openexr release [#3796](https://github.com/OpenImageIO/oiio/pull/3796)
|
||||
- Fix broken heif dependency and test [#3894](https://github.com/OpenImageIO/oiio/pull/3894)
|
||||
- Add test with new aswf containers for VFX Platform 2023 [#3875](https://github.com/OpenImageIO/oiio/pull/3875)
|
||||
- Simplify build_llvm.bash script [#3892](https://github.com/OpenImageIO/oiio/pull/3892)
|
||||
- Get rid of long-unused install_test_images.bash [#3895](https://github.com/OpenImageIO/oiio/pull/3895)
|
||||
- Test against pybind11 v2.11 [#3912](https://github.com/OpenImageIO/oiio/pull/3912)
|
||||
- Lock down icx version [#3929](https://github.com/OpenImageIO/oiio/pull/3929)
|
||||
- Fix missing simd test due to copy paste typo [#3896](https://github.com/OpenImageIO/oiio/pull/3896)
|
||||
- Bump build_openexr and build_opencolorio defaults to latest versions [#3920](https://github.com/OpenImageIO/oiio/pull/3920)
|
||||
- Test both openexr old and core versions [#3604](https://github.com/OpenImageIO/oiio/pull/3604)
|
||||
- Add benchmarking of strutil.h ways to concatenate strings. [#3787](https://github.com/OpenImageIO/oiio/pull/3787)
|
||||
- Make timer_test more robust [#3953](https://github.com/OpenImageIO/oiio/pull/3953) (2.5.3.0)
|
||||
* Platform support:
|
||||
- Windows: protect against OpenEXR thread deadlock on shutdown. #3582
|
||||
(2.4.5/2.5.0.0)
|
||||
- Windows: Work around a static destruction order issue. #3591
|
||||
(2.4.5/2.5.0.0)
|
||||
- Windows: define `NOGDI` to keep the inclusion of windows.h from adding
|
||||
as many unneeded symbols. [#3596](https://github.com/OpenImageIO/oiio/pull/3596) (by Aras Pranckevičius) (2.4.5/2.5.0.0)
|
||||
- Windows: Stop including Windows.h from public OIIO headers. [#3597](https://github.com/OpenImageIO/oiio/pull/3597) (by Aras Pranckevičius) (2.5.0.0)
|
||||
- Windows: Fix windows.h pre-definitions
|
||||
[#3965](https://github.com/OpenImageIO/oiio/pull/3965) (2.5.3.0)
|
||||
- Windows on ARM64 build fixes. #3690 (2.4.6/2.5.0.0)
|
||||
- Windows: Fix unresolved external symbol for MSVS 2017.
|
||||
[#3763](https://github.com/OpenImageIO/oiio/pull/3763) (by Latios96) (2.5.0.1)
|
||||
- Windows: Fix build error with MSVC [#3832](https://github.com/OpenImageIO/oiio/pull/3832) (by Ray Molenkamp) (2.5.2.0)
|
||||
- MinGW: fix incorrect symbol visibility issue for ImageBuf iterators. #3578
|
||||
- Mac: Suppress warnings about deprecated std::codecvt on newest Apple
|
||||
clang. #3709 #3710 (2.4.7/2.5.0.0)
|
||||
- Mac: Fixes to make a clean build using Apple Clang 11.0.
|
||||
[#3795](https://github.com/OpenImageIO/oiio/pull/3795) (by johnfea) (2.4.10.0/2.5.1.0)
|
||||
- Mac: Fixes for latest xcode on MacOS 13.3 Ventura [#3854](https://github.com/OpenImageIO/oiio/pull/3854) (2.5.2.0)
|
||||
- Mac: Suppress Xcode warnings [#3940](https://github.com/OpenImageIO/oiio/pull/3940) (by Anton Dukhovnikov) (2.5.3.0)
|
||||
#3722 (2.4.7/2.5.0.0)
|
||||
- Mac: Fixes for latest xcode on MacOS 13.3 Ventura [#3854](https://github.com/OpenImageIO/oiio/pull/3854) (2.5.2.0)
|
||||
- Fixes to make a clean build on Mac using Apple Clang 11.0.
|
||||
- ARM: Fix signed/unsigned mismatch compiler errors in vbool4 methods.
|
||||
- ARM: improve SIMD operations for ARM NEON. #3599 (2.4.5/2.5.0.0)
|
||||
- ARM: Fix signed/unsigned mismatch compiler errors in vbool4 methods.
|
||||
- ARM Mac: Fix build break. #3735 (2.5.0.0/2.4.7.1)
|
||||
- Fixes to build properly on OpenBSD. [#3808](https://github.com/OpenImageIO/oiio/pull/3808) (by Brad Smith) (2.5.1.0/2.4.11)
|
||||
- Squash warning in gcc 12.1 + C++20 [#3679](https://github.com/OpenImageIO/oiio/pull/3679)
|
||||
- Work around problems with fmt library + NVPTX relating to unknown
|
||||
float128 type. [#3823](https://github.com/OpenImageIO/oiio/pull/3823)
|
||||
(by Edoardo Dominici)
|
||||
- Silence gcc new/delete warnings for texturesys [#3944](https://github.com/OpenImageIO/oiio/pull/3944) (by Shootfast) (2.5.3.0)
|
||||
|
||||
### 📚 Notable documentation changes:
|
||||
|
||||
- Docs: Better Windows build instructions in INSTALL.md. [#3602](https://github.com/OpenImageIO/oiio/pull/3602) (by Aras Pranckevičius) (2.4.5/2.5.0.0)
|
||||
- ImageInput and ImageOutput docs updated to Python 3. [#3866](https://github.com/OpenImageIO/oiio/pull/3866) (by Ziggy Cross)
|
||||
- Fix explanation of raw:Exposure config hint [#3889](https://github.com/OpenImageIO/oiio/pull/3889)
|
||||
- Many fixes to python code examples [#3869](https://github.com/OpenImageIO/oiio/pull/3869) (by Jesse Y)
|
||||
- Update ImageInput docs to not use deprecated APIs [#3907](https://github.com/OpenImageIO/oiio/pull/3907) (by Jesse Y)
|
||||
|
||||
### 🏢 Project Administration
|
||||
|
||||
- Added RELEASING.md documenting our versioning and release procedures #3564
|
||||
#3580
|
||||
- Update CONTRIBUTING and SECURITY [#3852](https://github.com/OpenImageIO/oiio/pull/3852) (2.5.2.0)
|
||||
- Update mail list to https://lists.aswf.io/g/oiio-dev [#3880](https://github.com/OpenImageIO/oiio/pull/3880)
|
||||
- Add charter and other ASWF documents to the repo [#3850](https://github.com/OpenImageIO/oiio/pull/3850)
|
||||
- Document use of the DCO which is now required for all PRs [#3897](https://github.com/OpenImageIO/oiio/pull/3897)
|
||||
- Put logo on the main readme [#3927](https://github.com/OpenImageIO/oiio/pull/3927)
|
||||
- Remove old CLAs that are no longer in effect
|
||||
- Change open source license to Apache 2.0. #3899, #3903, #3904, #3906,
|
||||
#3914, #3922, #3926, #3938, #3966.
|
||||
- Make sure README has links for slack and meetings [#3936](https://github.com/OpenImageIO/oiio/pull/3936)
|
||||
- Update pull request and issue templates [#3946](https://github.com/OpenImageIO/oiio/pull/3946)
|
||||
- Add Jesse Yurkovich to the TSC [#3937](https://github.com/OpenImageIO/oiio/pull/3937)
|
||||
|
||||
|
||||
|
||||
Release 2.4.15.0 (1 Sep 2023) -- compared to 2.4.14.0
|
||||
@@ -44,29 +661,27 @@ Release 2.4.14.0 (1 Aug 2023) -- compared to 2.4.13.0
|
||||
|
||||
Release 2.4.13.0 (1 July 2023) -- compared to 2.4.12.0
|
||||
-------------------------------------------------------
|
||||
- *OpenCV*: Improve OpenCV support -- errors, version, half [#3853](https://github.com/OpenImageIO/oiio/pull/3853)
|
||||
- *IBA*: Improve error message for IBA::ocio functions [#3887](https://github.com/OpenImageIO/oiio/pull/3887)
|
||||
- *exif*: Convert paramvalue string to integer when needed [#3886](https://github.com/OpenImageIO/oiio/pull/3886) (by Fabien Servant @ TCS)
|
||||
- *exr*: Correction to dwa vs zip logic when outputting OpenEXR [#3884](https://github.com/OpenImageIO/oiio/pull/3884)
|
||||
- *OpenCV*: Improve OpenCV support -- errors, version, half [#3853](https://github.com/OpenImageIO/oiio/pull/3853)
|
||||
- *IBA*: Improve error message for IBA::ocio functions [#3887](https://github.com/OpenImageIO/oiio/pull/3887)
|
||||
- *exif*: Convert paramvalue string to integer when needed [#3886](https://github.com/OpenImageIO/oiio/pull/3886) (by Fabien Servant @ TCS)
|
||||
- *exr*: Correction to dwa vs zip logic when outputting OpenEXR [#3884](https://github.com/OpenImageIO/oiio/pull/3884)
|
||||
- *ico*: Heap-buffer-overflow [#3872](https://github.com/OpenImageIO/oiio/pull/3872) (by xiaoxiaoafeifei) Fixes CVE-2023-36183.
|
||||
- *jpeg*: Fix density calculation for jpeg output [#3861](https://github.com/OpenImageIO/oiio/pull/3861) (by Loïc Vital)
|
||||
- *jpeg2000*: Better pixel type promotion logic [#3878](https://github.com/OpenImageIO/oiio/pull/3878)
|
||||
- *psd*: Prevent simultaneous psd thumbnail reads from clashing [#3877](https://github.com/OpenImageIO/oiio/pull/3877)
|
||||
- *strutil.h*: Ensure proper constexpr of string hashing [#3901](https://github.com/OpenImageIO/oiio/pull/3901)
|
||||
- *jpeg*: Fix density calculation for jpeg output [#3861](https://github.com/OpenImageIO/oiio/pull/3861) (by Loïc Vital)
|
||||
- *jpeg2000*: Better pixel type promotion logic [#3878](https://github.com/OpenImageIO/oiio/pull/3878)
|
||||
- *psd*: Prevent simultaneous psd thumbnail reads from clashing [#3877](https://github.com/OpenImageIO/oiio/pull/3877)
|
||||
- *strutil.h*: Ensure proper constexpr of string hashing [#3901](https://github.com/OpenImageIO/oiio/pull/3901)
|
||||
- *build* Fix use of OIIO_LOCAL_DEPS_PATH [#3865](https://github.com/OpenImageIO/oiio/pull/3865)
|
||||
- *build* Fix fmt vs gcc warning that had version typo [#3874](https://github.com/OpenImageIO/oiio/pull/3874)
|
||||
- *ci*: Add test with new aswf containers for VFX Platform 2023 [#3875](https://github.com/OpenImageIO/oiio/pull/3875)
|
||||
- *ci*: Fix broken heif dependency and test [#3894](https://github.com/OpenImageIO/oiio/pull/3894)
|
||||
- *ci*: Simplify build_llvm.bash script [#3892](https://github.com/OpenImageIO/oiio/pull/3892)
|
||||
- *build* Fix fmt vs gcc warning that had version typo [#3874](https://github.com/OpenImageIO/oiio/pull/3874)
|
||||
- *ci*: Add test with new aswf containers for VFX Platform 2023 [#3875](https://github.com/OpenImageIO/oiio/pull/3875)
|
||||
- *ci*: Fix broken heif dependency and test [#3894](https://github.com/OpenImageIO/oiio/pull/3894)
|
||||
- *ci*: Simplify build_llvm.bash script [#3892](https://github.com/OpenImageIO/oiio/pull/3892)
|
||||
- *tests*: Fix missing simd test due to copy paste typo [#3896](https://github.com/OpenImageIO/oiio/pull/3896)
|
||||
- *docs*: Update CONTRIBUTING and SECURITY [#3852](https://github.com/OpenImageIO/oiio/pull/3852)
|
||||
- *docs*: Update CONTRIBUTING and SECURITY [#3852](https://github.com/OpenImageIO/oiio/pull/3852)
|
||||
- *docs*: ImageInput and ImageOutput docs updated to Python 3. [#3866](https://github.com/OpenImageIO/oiio/pull/3866) (by Ziggy Cross)
|
||||
- *docs*: Many fixes to python code examples [#3869](https://github.com/OpenImageIO/oiio/pull/3869) (by Jesse Y)
|
||||
- *docs*: Update mail list URL [#3880](https://github.com/OpenImageIO/oiio/pull/3880)
|
||||
- *docs*: Fix explanation of raw:Exposure config hint [#3889](https://github.com/OpenImageIO/oiio/pull/3889)
|
||||
- *docs*: Document use of the DCO which is now required for all PRs [#3897](https://github.com/OpenImageIO/oiio/pull/3897)
|
||||
|
||||
|
||||
- *docs*: Many fixes to python code examples [#3869](https://github.com/OpenImageIO/oiio/pull/3869) (by Jesse Y)
|
||||
- *docs*: Update mail list URL [#3880](https://github.com/OpenImageIO/oiio/pull/3880)
|
||||
- *docs*: Fix explanation of raw:Exposure config hint [#3889](https://github.com/OpenImageIO/oiio/pull/3889)
|
||||
- *docs*: Document use of the DCO which is now required for all PRs [#3897](https://github.com/OpenImageIO/oiio/pull/3897)
|
||||
|
||||
Release 2.4.12.0 (1 June 2023) -- compared to 2.4.11.1
|
||||
------------------------------------------------------
|
||||
@@ -83,7 +698,6 @@ Release 2.4.12.0 (1 June 2023) -- compared to 2.4.11.1
|
||||
- *ci*: Fix warnings [#3833](https://github.com/OpenImageIO/oiio/pull/3833)
|
||||
- *ci*: Fix package name for icc [#3860](https://github.com/OpenImageIO/oiio/pull/3860)
|
||||
|
||||
|
||||
Release 2.4.11.1 (14 May 2023) -- compared to 2.4.11.0
|
||||
------------------------------------------------------
|
||||
- *build*: Fmt 10.0 support [#3836](https://github.com/OpenImageIO/oiio/pull/3836)
|
||||
@@ -95,7 +709,7 @@ Release 2.4.11.0 (1 May 2023) -- compared to 2.4.10.0
|
||||
* Python: Improve error messages when passing wrong python array sizes. #3801
|
||||
* Raw: handle 1-channel raw images. #3798
|
||||
* HEIC: Support the ".hif" extension, which seems to be used by some Canon
|
||||
cameras instead of .heif. #3813
|
||||
cameras instead of .heif. [#3813](https://github.com/OpenImageIO/oiio/pull/3813)(by AdamMainsTL)
|
||||
* PSD: Fix problems reading images with width > 64k pixels. #3806
|
||||
* Windows/fmath: Work around MSVS bug(?) that generated wrong code for
|
||||
fast_exp2. #3804
|
||||
@@ -104,7 +718,7 @@ Release 2.4.11.0 (1 May 2023) -- compared to 2.4.10.0
|
||||
(including Cuda compiles). #3814
|
||||
* Build: Fix building against new ffmpeg 6.0. #3812
|
||||
* Build: Work around problems with fmt library + NVPTX relating to unknown
|
||||
float128 type. #3823
|
||||
float128 type. [#3823](https://github.com/OpenImageIO/oiio/pull/3823) (by Edoardo Dominici)
|
||||
* CI/test: Fix incorrect branch name when cloning openexr-images for the
|
||||
testsuite. #3814
|
||||
* Test: Use copies instead of symlinks in a couple spots to help on Windows.
|
||||
@@ -172,7 +786,6 @@ Release 2.4.8.0 (1 Feb 2023) -- compared to 2.4.7.1
|
||||
* Docs: Fix old release notes to document all CVEs addressed in certain
|
||||
prior releases.
|
||||
|
||||
|
||||
Release 2.4.7.1 (3 Jan 2023) -- compared to 2.4.7.0
|
||||
----------------------------------------------------
|
||||
* Fix build break for Mac ARM. #3735
|
||||
@@ -216,9 +829,10 @@ Release 2.4.6 (1 Dec 2022) -- compared to 2.4.5.0
|
||||
* IFF files: Add IOProxy support. #3647
|
||||
* IFF: Fix possible write errors, fixes TALOS-2022-1654 / CVE-2022-43596,
|
||||
TALOS-2022-1655 / CVE-2022-43597 CVE-2022-43598, TALOS-2022-1656 /
|
||||
CVE-2022-43599 CVE-2022-43600 CVE-2022-43601 CVE-2022-43602 #3676
|
||||
CVE-2022-43599 CVE-2022-43600 CVE-2022-43601 CVE-2022-43602
|
||||
[#3676](https://github.com/OpenImageIO/oiio/pull/3676)
|
||||
* PSD: Fix thumbnail extraction. #3668
|
||||
* PSD: when reading, don't reject padded thumbnails. #3677
|
||||
* PSD: when reading, don't reject padded thumbnails. [#3677](https://github.com/OpenImageIO/oiio/pull/3677)
|
||||
* Raw: Update Exif orientation if user flip is set. #3669
|
||||
* Zfile write safety, fixes TALOS-2022-1657 / CVE-2022-43603. #3670
|
||||
* filesystem.h: new `Filesystem::is_executable()` and `find_program()`. #3638
|
||||
@@ -321,7 +935,7 @@ New major features and public API changes:
|
||||
headers (relying on the accidental fact of other OIIO headers
|
||||
transitively including them), you may need to adjust your includes.
|
||||
#3301 #3332 (2.4.0.2) #3406 #3474 (2.4.2)
|
||||
- New `V3fParam`, `M33fParam`, and `M44Param` (defined in vecparam.h) are
|
||||
- New `V3fParam`, `M33fParam`, and `M44fParam` (defined in vecparam.h) are
|
||||
used just for parameter passing in public APIs, instead of Imath::V3f,
|
||||
M33f, or M44f, in order to more fully hide Imath types from our public
|
||||
interfaces. These are only parameter-passing classes, and are not useful
|
||||
@@ -460,7 +1074,7 @@ New major features and public API changes:
|
||||
"GammaCorrectedX.Y"). #3202 (2.4.0)
|
||||
* `oiioversion.h` now defines symbols `OIIO_USING_IMATH_VERSION_MAJOR` and
|
||||
`OIIO_USING_IMATH_VERSION_MINOR` that reveal which Imath version was used
|
||||
internally to OIIO when it was build (which may be different than the
|
||||
internally to OIIO when it was built (which may be different than the
|
||||
version found when the downstream app is being compiled). #3305 (2.4.0.1)
|
||||
* Most of the major APIs (including ImageInput, ImageOutput, and ImageBuf)
|
||||
that took a std::string or string_view to indicate a filename (assumed to
|
||||
@@ -864,7 +1478,7 @@ Developer goodies / internals:
|
||||
representation is the hash, rather than the unique string pointer. #3436
|
||||
(2.4.2)
|
||||
* vecparam.h:
|
||||
- New `V3fParam`, `M33fParam`, and `M44Param` (defined in vecparam.h) are
|
||||
- New `V3fParam`, `M33fParam`, and `M44fParam` (defined in vecparam.h) are
|
||||
used just for parameter passing in public APIs, instead of Imath::V3f,
|
||||
M33f, or M44f, in order to more fully hide Imath types from our public
|
||||
interfaces. These are only parameter-passing classes, and are not useful
|
||||
@@ -936,7 +1550,7 @@ Build/test system improvements and platform ports:
|
||||
components to the path. #3487 (2.4.2.1)
|
||||
- On MacOS, do not force MACOS_RPATH on. #3523 (2.4.2.2)
|
||||
- Improvements to the generated cmake config files when building static
|
||||
libraries. #3552 #3557 (2.4.4.0)
|
||||
libraries. #3552 #3557 (by Povilas Kanapickas) (2.4.4.0)
|
||||
* Dependency version support:
|
||||
- When using C++17, use std::gcd instead of boost. #3076 (2.4.0)
|
||||
- When using C++17, use `inline constexpr` instead of certain statics.
|
||||
@@ -961,6 +1575,7 @@ Build/test system improvements and platform ports:
|
||||
- Fixes for ffmpeg 5.1 detection. #3516 (2.3.19.0/2.4.2.2)
|
||||
- Support for gcc 12.1. #3480 (2.4.2.1) #3551 (2.4.4.0)
|
||||
- Support building with clang 15.0. #3563 (2.4.4.0)
|
||||
- Try FORTIFY_SOURCE [#3575](https://github.com/OpenImageIO/oiio/pull/3575)
|
||||
* Testing and Continuous integration (CI) systems:
|
||||
- Properly test against all the versions of VFX Platform 2022. #3074
|
||||
(2.4.0)
|
||||
@@ -1000,8 +1615,8 @@ Build/test system improvements and platform ports:
|
||||
- Improved simd.h support for armv7 and aarch32. #3361 (2.4.1.0/2.3.14)
|
||||
- Suppress MacOS wasnings about OpenGL deprecation. #3380 (2.4.1.0/2.3.14)
|
||||
- Fix MSVS/Windows errors. #3382 (2.4.1.1)
|
||||
- Fix cross-compiling on Android failing due to `-latomic` check. #3560
|
||||
(2.4.4.0)
|
||||
- Fix cross-compiling on Android failing due to `-latomic` check.
|
||||
[#3560](https://github.com/OpenImageIO/oiio/pull/3560) (by Povilas Kanapickas) (2.4.4.0)
|
||||
- Fix building on iOS. #3562 (2.4.4.0)
|
||||
|
||||
Notable documentation changes:
|
||||
@@ -1023,18 +1638,6 @@ Notable documentation changes:
|
||||
|
||||
|
||||
|
||||
Release 2.3.21 (1 Nov 2022) -- compared to 2.3.20
|
||||
--------------------------------------------------
|
||||
* oiiotool: protect against OpenEXR thread deadlock on Windows. #3582
|
||||
* oiiotool: work around static destruction order issue. #3591
|
||||
* Fix PSD import on ARM. #3589
|
||||
* Docs: write Windows build instructions in INSTALL.md. #3602
|
||||
* RLA: fix potential buffer overrun. (TALOS-2022-1629, CVE-2022-36354) #3624
|
||||
* TIFF: guard against corrupt files with buffer overflows. (TALOS-2022-1627,
|
||||
CVE-2022-41977) #3628
|
||||
* TIFF: guard against buffer overflow for certain CMYK files.
|
||||
(TALOS-2022-1633, CVE-2022-41639) (TALOS-2022-1643, CVE-2022-41988) #3632
|
||||
|
||||
Release 2.3.20 (1 Oct 2022) -- compared to 2.3.19
|
||||
-------------------------------------------------
|
||||
* Fixes to compile with gcc 12. #3551
|
||||
|
||||
+4
-4
@@ -2,9 +2,9 @@
|
||||
# SPDX-License-Identifier: BSD-3-Clause and Apache-2.0
|
||||
# https://github.com/OpenImageIO/oiio
|
||||
|
||||
cmake_minimum_required (VERSION 3.12)
|
||||
cmake_minimum_required (VERSION 3.15)
|
||||
|
||||
set (OpenImageIO_VERSION "2.4.16.0")
|
||||
set (OpenImageIO_VERSION "2.5.3.0")
|
||||
set (OpenImageIO_VERSION_OVERRIDE "" CACHE STRING
|
||||
"Version override (use with caution)!")
|
||||
mark_as_advanced (OpenImageIO_VERSION_OVERRIDE)
|
||||
@@ -19,7 +19,7 @@ project (OpenImageIO VERSION ${OpenImageIO_VERSION}
|
||||
set (PROJ_NAME OIIO) # short name, caps
|
||||
string (TOLOWER ${PROJ_NAME} PROJ_NAME_LOWER) # short name lower case
|
||||
string (TOUPPER ${PROJ_NAME} PROJ_NAME_UPPER) # short name upper case
|
||||
set (PROJECT_VERSION_RELEASE_TYPE "" CACHE STRING
|
||||
set (PROJECT_VERSION_RELEASE_TYPE "beta" CACHE STRING
|
||||
"Build type, for example: dev, beta2, RC1 (empty string for normal release)")
|
||||
set (${PROJECT_NAME}_VERSION_RELEASE_TYPE ${PROJECT_VERSION_RELEASE_TYPE})
|
||||
set (PROJECT_AUTHORS "Contributors to the OpenImageIO project")
|
||||
@@ -305,7 +305,7 @@ install (EXPORT OIIO_EXPORTED_TARGETS
|
||||
NAMESPACE ${PROJECT_NAME}::)
|
||||
|
||||
|
||||
if (PROJECT_IS_TOP_LEVEL AND BUILD_TESTING)
|
||||
if (PROJECT_IS_TOP_LEVEL AND BUILD_TESTING AND ${PROJ_NAME}_BUILD_TESTS)
|
||||
oiio_setup_test_data()
|
||||
oiio_add_all_tests()
|
||||
endif ()
|
||||
|
||||
@@ -90,7 +90,6 @@ lg@openimageio.org
|
||||
* Jeremy Rose
|
||||
* Jeremy Selan
|
||||
* Jim Hourihan
|
||||
* Joachim Reichel
|
||||
* Johannes Unterguggenberger
|
||||
* John Burnett
|
||||
* John Fea
|
||||
|
||||
+30
-31
@@ -14,20 +14,22 @@ NEW or CHANGED MINIMUM dependencies since the last major release are **bold**.
|
||||
|
||||
### Required dependencies -- OIIO will not build at all without these
|
||||
|
||||
* C++14 (also builds with C++17, and C++20)
|
||||
* C++14 or higher (also builds with C++17, and C++20)
|
||||
* The default build mode is C++14. This can be controlled by via the
|
||||
CMake configuration flag: `-DCMAKE_CXX_STANDARD=17`, etc.
|
||||
* ADVISORY: We expect that OIIO 2.6 in 2024 will require C++17 or higher.
|
||||
* Compilers: gcc 6.1 - 12.1, clang 3.4 - 16, MSVS 2017 - 2019,
|
||||
Intel icc 17+, **Intel OneAPI C++ compiler 2022+**.
|
||||
* CMake >= 3.12 (tested through 3.26)
|
||||
* **OpenEXR/Imath >= 2.3** (recommended: 2.4 or higher; tested through 3.2 and main)
|
||||
Intel icc 17+, Intel OneAPI C++ compiler 2022+.
|
||||
* **CMake >= 3.15** (tested through 3.27)
|
||||
* **OpenEXR/Imath >= 2.4** (recommended: 3.1 or higher; tested through 3.2
|
||||
and main) (ADVISORY: We expect that OIIO 2.6 in 2024 will require OpenEXR >= 3.1)
|
||||
* libTIFF >= 3.9 (recommended: 4.0+; tested through 4.5)
|
||||
* libjpeg >= 8, or libjpeg-turbo >= 1.1 (tested through jpeg9d and jpeg-turbo
|
||||
2.1)
|
||||
* Boost >= 1.53 (recommended: at least 1.66; tested through 1.81)
|
||||
* [fmtlib](https://github.com/fmtlib/fmt) >= 6.1.2 (tested through 10.0). If
|
||||
not found at build time, this will be automatically downloaded unless the
|
||||
build sets `-DBUILD_MISSING_FMT=OFF`.
|
||||
* **[fmtlib](https://github.com/fmtlib/fmt) >= 7.0** (tested through 10.1).
|
||||
If not found at build time, this will be automatically downloaded unless
|
||||
the build sets `-DBUILD_MISSING_FMT=OFF`.
|
||||
|
||||
### Optional dependencies -- features may be disabled if not found
|
||||
* If you are building the `iv` viewer (which will be disabled if any of
|
||||
@@ -40,8 +42,7 @@ NEW or CHANGED MINIMUM dependencies since the last major release are **bold**.
|
||||
not support Python < 3.6.)
|
||||
* NumPy
|
||||
* If you want support for camera "RAW" formats:
|
||||
* LibRaw >= 0.15 (tested 0.15 - 0.21.1; LibRaw >= 0.18 is necessary for
|
||||
ACES support and much better recognition of camera metadata; if
|
||||
* LibRaw >= 0.18 (tested though 0.21.1; if
|
||||
building with C++17 or higher, LibRaw >= 0.20 is necessary)
|
||||
* If you want support for a wide variety of video formats:
|
||||
* ffmpeg >= 3.0 (tested through 6.0)
|
||||
@@ -123,6 +124,9 @@ build options), maybe one of these packages managers will do it for you:
|
||||
|
||||
If these work for you and it's all you need, bingo! You are done.
|
||||
|
||||
You may find this guide to versions carried by distributions helpful:
|
||||
|
||||
[](https://repology.org/project/openimageio/versions)
|
||||
|
||||
|
||||
Building from source
|
||||
@@ -248,9 +252,8 @@ The command 'make help' will list all possible options.
|
||||
You can also ignore the top level Makefile wrapper, and instead use
|
||||
CMake directly:
|
||||
|
||||
mkdir build
|
||||
cd build
|
||||
cmake ..
|
||||
cmake -B build -S .
|
||||
cmake --build build --target install
|
||||
|
||||
If the compile stops because of warnings, try again with
|
||||
|
||||
@@ -259,8 +262,9 @@ If the compile stops because of warnings, try again with
|
||||
|
||||
or, if you are using CMake directly,
|
||||
|
||||
cd build
|
||||
cmake -DSTOP_ON_WARNING=0 ..
|
||||
rm -rf build
|
||||
cmake -B build -S . -DSTOP_ON_WARNING=0
|
||||
cmake --build build --target install
|
||||
|
||||
|
||||
|
||||
@@ -285,19 +289,16 @@ the section below, and will only have to point OIIO build process so their locat
|
||||
```
|
||||
cd {ZLIB_ROOT}
|
||||
git clone https://github.com/madler/zlib .
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=. ..
|
||||
cmake --build . --config Release --target install
|
||||
del lib\zlib.lib
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=.
|
||||
cmake --build build --config Release --target install
|
||||
del build\lib\zlib.lib
|
||||
```
|
||||
* libTIFF:
|
||||
```
|
||||
cd {TIFF_ROOT}
|
||||
git clone https://gitlab.com/libtiff/libtiff.git .
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=. ..
|
||||
cmake --build . --target install
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DCMAKE_INSTALL_PREFIX=.
|
||||
cmake --build build --target install
|
||||
```
|
||||
* libjpeg-turbo:
|
||||
```
|
||||
@@ -305,19 +306,19 @@ the section below, and will only have to point OIIO build process so their locat
|
||||
git clone https://github.com/libjpeg-turbo/libjpeg-turbo .
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=. ..
|
||||
cmake --build . --config Release --target install
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DENABLE_SHARED=OFF -DCMAKE_INSTALL_PREFIX=.
|
||||
cmake --build build --config Release --target install
|
||||
```
|
||||
* OpenEXR: you'll have to point it to your `{ZLIB_ROOT}` location from the above. If copy-pasting the multi-line command (with lines ending in `^`) into
|
||||
cmd.exe prompt, make sure to copy all the lines at once.
|
||||
```
|
||||
cd {EXR_ROOT}
|
||||
git clone https://github.com/AcademySoftwareFoundation/openexr .
|
||||
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=dist ^
|
||||
cmake -S . -B build -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=dist ^
|
||||
-DBUILD_TESTING=OFF -DBUILD_SHARED_LIBS=OFF -DOPENEXR_BUILD_TOOLS=OFF ^
|
||||
-DOPENEXR_INSTALL_TOOLS=OFF -DOPENEXR_INSTALL_EXAMPLES=OFF ^
|
||||
-DZLIB_ROOT={ZLIB_ROOT}\build ..
|
||||
cmake --build . --target install --config Release
|
||||
-DZLIB_ROOT={ZLIB_ROOT}\build
|
||||
cmake --build build --target install --config Release
|
||||
```
|
||||
|
||||
Now get the OIIO source and do one-time CMake configuration step. Replace `{*_ROOT}` below with folders where you have put the 3rd party
|
||||
@@ -325,16 +326,14 @@ dependencies.
|
||||
```
|
||||
cd {OIIO_ROOT}
|
||||
git clone https://github.com/OpenImageIO/oiio .
|
||||
mkdir build
|
||||
cd build
|
||||
cmake -DVERBOSE=ON -DCMAKE_BUILD_TYPE=Release ^
|
||||
cmake -S . -B build -DVERBOSE=ON -DCMAKE_BUILD_TYPE=Release ^
|
||||
-DBoost_USE_STATIC_LIBS=ON -DBoost_NO_WARN_NEW_VERSIONS=ON -DBoost_ROOT={BOOST_ROOT} ^
|
||||
-DZLIB_ROOT={ZLIB_ROOT}\build ^
|
||||
-DTIFF_ROOT={TIFF_ROOT}\build ^
|
||||
-DOpenEXR_ROOT={EXR_ROOT}\build\dist ^
|
||||
-DImath_DIR={EXR_ROOT}\build\dist\lib\cmake\Imath ^
|
||||
-DJPEG_ROOT={JPEG_ROOT}\build ^
|
||||
-DUSE_PYTHON=0 -DUSE_QT=0 -DBUILD_SHARED_LIBS=0 -DLINKSTATIC=1 ..
|
||||
-DUSE_PYTHON=0 -DUSE_QT=0 -DBUILD_SHARED_LIBS=0 -DLINKSTATIC=1
|
||||
```
|
||||
|
||||
This will produce `{OIIO_ROOT}/build/OpenImageIO.sln` that can be opened in Visual Studio IDE. Note that the solution will be
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
[](https://github.com/OpenImageIO/oiio/blob/master/LICENSE.md)
|
||||
[](https://github.com/OpenImageIO/oiio/actions/workflows/ci.yml)
|
||||
[](https://bestpractices.coreinfrastructure.org/projects/2694)
|
||||
[](https://repology.org/project/openimageio/versions)
|
||||
|
||||
|
||||
Introduction
|
||||
|
||||
@@ -222,6 +222,10 @@ else ifeq (${platform}, macosx)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=gcc-11 -DCMAKE_CXX_COMPILER=g++-11
|
||||
USE_LIBCPLUSPLUS := 0
|
||||
else ifeq (${COMPILER}, gcc13)
|
||||
MY_CMAKE_FLAGS += \
|
||||
-DCMAKE_C_COMPILER=gcc-13 -DCMAKE_CXX_COMPILER=g++-13
|
||||
USE_LIBCPLUSPLUS := 0
|
||||
else ifeq (${COMPILER},clang13)
|
||||
MY_CMAKE_FLAGS += -DCMAKE_C_COMPILER=/usr/local/opt/llvm@13/bin/clang \
|
||||
-DCMAKE_CXX_COMPILER=/usr/local/opt/llvm@13/bin/clang++
|
||||
|
||||
@@ -19,7 +19,4 @@ sonar.cfamily.build-wrapper-output=build/bw_output
|
||||
sonar.cfamily.gcov.reportsPath=_coverage
|
||||
sonar.coverage.exclusions=src/iv/**,src/include/OpenImageIO/detail/pugixml/**,src/include/OpenImageIO/detail/fmt/**,src/libOpenImageIO/kissfft.hh
|
||||
|
||||
sonar.cfamily.cache.enabled=true
|
||||
sonar.cfamily.cache.path=/tmp/sonarcache
|
||||
|
||||
sonar.verbose=false
|
||||
|
||||
@@ -23,7 +23,7 @@ public:
|
||||
{
|
||||
return feature == "ioproxy";
|
||||
}
|
||||
bool valid_file(const std::string& filename) const override;
|
||||
bool valid_file(Filesystem::IOProxy* ioproxy) const override;
|
||||
bool open(const std::string& name, ImageSpec& newspec) override;
|
||||
bool open(const std::string& name, ImageSpec& newspec,
|
||||
const ImageSpec& config) override;
|
||||
@@ -94,11 +94,13 @@ OIIO_PLUGIN_EXPORTS_END
|
||||
|
||||
|
||||
bool
|
||||
BmpInput::valid_file(const std::string& filename) const
|
||||
BmpInput::valid_file(Filesystem::IOProxy* ioproxy) const
|
||||
{
|
||||
if (!ioproxy || ioproxy->mode() != Filesystem::IOProxy::Mode::Read)
|
||||
return false;
|
||||
|
||||
bmp_pvt::BmpFileHeader header;
|
||||
Filesystem::IOFile file(filename, Filesystem::IOProxy::Read);
|
||||
return file.opened() && header.read_header(&file) && header.isBmp();
|
||||
return header.read_header(ioproxy) && header.isBmp();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -81,27 +81,11 @@ BmpOutput::supports(string_view feature) const
|
||||
bool
|
||||
BmpOutput::open(const std::string& name, const ImageSpec& spec, OpenMode mode)
|
||||
{
|
||||
if (mode != Create) {
|
||||
errorfmt("{} does not support subimages or MIP levels", format_name());
|
||||
if (!check_open(mode, spec, { 0, 65535, 0, 65535, 0, 1, 0, 4 },
|
||||
uint64_t(OpenChecks::Disallow2Channel)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// saving 'name' and 'spec' for later use
|
||||
m_filename = name;
|
||||
m_spec = spec;
|
||||
|
||||
if (m_spec.nchannels != 1 && m_spec.nchannels != 3
|
||||
&& m_spec.nchannels != 4) {
|
||||
errorfmt("{} does not support {}-channel images\n", format_name(),
|
||||
m_spec.nchannels);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_spec.x || m_spec.y || m_spec.z) {
|
||||
errorfmt("{} does not support images with non-zero image origin offset",
|
||||
format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Only support 8 bit channels for now.
|
||||
m_spec.set_format(TypeDesc::UINT8);
|
||||
|
||||
@@ -36,15 +36,13 @@ cd ${OPENJPEG_SRC_DIR}
|
||||
echo "git checkout ${OPENJPEG_VERSION} --force"
|
||||
git checkout ${OPENJPEG_VERSION} --force
|
||||
|
||||
mkdir -p ${OPENJPEG_BUILD_DIR} && true
|
||||
cd ${OPENJPEG_BUILD_DIR}
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${OPENJPEG_BUILD_DIR} \
|
||||
-DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${OPENJPEG_INSTALL_DIR} \
|
||||
-DBUILD_CODEC=OFF \
|
||||
${OPENJPEG_CONFIG_OPTS} ..
|
||||
time cmake --build . --config Release --target install
|
||||
${OPENJPEG_CONFIG_OPTS}
|
||||
time cmake --build ${OPENJPEG_BUILD_DIR} --config Release --target install
|
||||
fi
|
||||
|
||||
# ls -R ${OPENJPEG_INSTALL_DIR}
|
||||
|
||||
@@ -31,12 +31,10 @@ cd ${PTEX_SRC_DIR}
|
||||
echo "git checkout ${PTEX_VERSION} --force"
|
||||
git checkout ${PTEX_VERSION} --force
|
||||
|
||||
mkdir -p ${PTEX_BUILD_DIR}
|
||||
cd ${PTEX_BUILD_DIR}
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${PTEX_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${PTEX_INSTALL_DIR} \
|
||||
${PTEX_CONFIG_OPTS} ..
|
||||
time cmake --build . --config Release --target install
|
||||
${PTEX_CONFIG_OPTS}
|
||||
time cmake --build ${PTEX_BUILD_DIR} --config Release --target install
|
||||
|
||||
# ls -R ${PTEX_INSTALL_DIR}
|
||||
popd
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Utility script to download and build abi checking tools
|
||||
#
|
||||
# Copyright Contributors to the OpenImageIO project.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# https://github.com/OpenImageIO/oiio
|
||||
|
||||
# Exit the whole script if any command fails.
|
||||
set -ex
|
||||
|
||||
# Where to install the final results
|
||||
: ${LOCAL_DEPS_DIR:=${PWD}/ext}
|
||||
: ${ABITOOLS_INSTALL_DIR:=${LOCAL_DEPS_DIR}/dist}
|
||||
|
||||
mkdir -p ${LOCAL_DEPS_DIR}
|
||||
pushd ${LOCAL_DEPS_DIR}
|
||||
|
||||
git clone https://github.com/lvc/vtable-dumper
|
||||
pushd vtable-dumper ; make install prefix=${ABITOOLS_INSTALL_DIR} ; popd
|
||||
|
||||
git clone https://github.com/lvc/abi-dumper
|
||||
pushd abi-dumper ; make install prefix=${ABITOOLS_INSTALL_DIR} ; popd
|
||||
|
||||
git clone https://github.com/lvc/abi-compliance-checker
|
||||
pushd abi-compliance-checker ; make install prefix=${ABITOOLS_INSTALL_DIR} ; popd
|
||||
|
||||
popd
|
||||
|
||||
# ls -R ${LOCAL_DEPS_DIR}
|
||||
export PATH=${PATH}:${ABITOOLS_INSTALL_DIR}/bin
|
||||
@@ -12,7 +12,7 @@ set -ex
|
||||
echo "Building cmake"
|
||||
uname
|
||||
|
||||
CMAKE_VERSION=${CMAKE_VERSION:=3.12.4}
|
||||
CMAKE_VERSION=${CMAKE_VERSION:=3.18.5}
|
||||
LOCAL_DEPS_DIR=${LOCAL_DEPS_DIR:=${PWD}/ext}
|
||||
CMAKE_INSTALL_DIR=${CMAKE_INSTALL_DIR:=${LOCAL_DEPS_DIR}/cmake}
|
||||
|
||||
|
||||
@@ -36,14 +36,11 @@ cd ${LIBJPEGTURBO_SRC_DIR}
|
||||
echo "git checkout ${LIBJPEGTURBO_VERSION} --force"
|
||||
git checkout ${LIBJPEGTURBO_VERSION} --force
|
||||
|
||||
mkdir -p ${LIBJPEGTURBO_BUILD_DIR}
|
||||
cd ${LIBJPEGTURBO_BUILD_DIR}
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${LIBJPEGTURBO_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${LIBJPEGTURBO_INSTALL_DIR} \
|
||||
${LIBJPEGTURBO_CONFIG_OPTS} ..
|
||||
time cmake --build . --config Release --target install
|
||||
${LIBJPEGTURBO_CONFIG_OPTS}
|
||||
time cmake --build ${LIBJPEGTURBO_BUILD_DIR} --config Release --target install
|
||||
fi
|
||||
|
||||
# ls -R ${LIBJPEGTURBO_INSTALL_DIR}
|
||||
|
||||
@@ -38,16 +38,13 @@ cd ${LIBPNG_SRC_DIR}
|
||||
echo "git checkout ${LIBPNG_VERSION} --force"
|
||||
git checkout ${LIBPNG_VERSION} --force
|
||||
|
||||
mkdir -p ${LIBPNG_BUILD_DIR}
|
||||
cd ${LIBPNG_BUILD_DIR}
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${LIBPNG_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${LIBPNG_INSTALL_DIR} \
|
||||
-DPNG_EXECUTABLES=OFF \
|
||||
-DPNG_TESTS=OFF \
|
||||
${LIBPNG_CONFIG_OPTS} ..
|
||||
time cmake --build . --config Release --target install
|
||||
${LIBPNG_CONFIG_OPTS}
|
||||
time cmake --build ${LIBPNG_BUILD_DIR} --config Release --target install
|
||||
fi
|
||||
|
||||
# ls -R ${LIBPNG_INSTALL_DIR}
|
||||
|
||||
@@ -36,16 +36,17 @@ cd libtiff
|
||||
echo "git checkout ${LIBTIFF_VERSION} --force"
|
||||
git checkout ${LIBTIFF_VERSION} --force
|
||||
|
||||
mkdir -p build
|
||||
cd build
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=${LIBTIFF_BUILD_TYPE} \
|
||||
time cmake -S . -B build \
|
||||
-DCMAKE_BUILD_TYPE=${LIBTIFF_BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX=${LIBTIFF_INSTALL_DIR} \
|
||||
-DCMAKE_CXX_FLAGS="${LIBTIFF_CXX_FLAGS}" \
|
||||
-DBUILD_SHARED_LIBS=${LIBTIFF_BUILD_SHARED_LIBS:-ON} \
|
||||
${LIBTIFF_BUILDOPTS} ..
|
||||
time cmake --build . --target install
|
||||
-Dtiff-tests=${LIBTIFF_BUILD_TESTS:-OFF} \
|
||||
-Dtiff-docs=${LIBTIFF_BUILD_TESTS:-OFF} \
|
||||
-Dlibdeflate=ON \
|
||||
${LIBTIFF_BUILDOPTS}
|
||||
time cmake --build build --target install
|
||||
fi
|
||||
|
||||
popd
|
||||
|
||||
@@ -18,6 +18,7 @@ LOCAL_DEPS_DIR=${LOCAL_DEPS_DIR:=${PWD}/ext}
|
||||
OPENCOLORIO_SOURCE_DIR=${OPENCOLORIO_SOURCE_DIR:=${LOCAL_DEPS_DIR}/OpenColorIO}
|
||||
OPENCOLORIO_BUILD_DIR=${OPENCOLORIO_BUILD_DIR:=${LOCAL_DEPS_DIR}/OpenColorIO-build}
|
||||
OPENCOLORIO_INSTALL_DIR=${OPENCOLORIO_INSTALL_DIR:=${LOCAL_DEPS_DIR}/dist}
|
||||
OPENCOLORIO_BUILD_TYPE=${OPENCOLORIO_BUILD_TYPE:=Release}
|
||||
OPENCOLORIO_CXX_FLAGS=${OPENCOLORIO_CXX_FLAGS:="-Wno-unused-function -Wno-deprecated-declarations -Wno-cast-qual -Wno-write-strings"}
|
||||
# Just need libs:
|
||||
OPENCOLORIO_BUILDOPTS="-DOCIO_BUILD_APPS=OFF -DOCIO_BUILD_NUKE=OFF \
|
||||
@@ -42,13 +43,12 @@ cd ${OPENCOLORIO_SOURCE_DIR}
|
||||
|
||||
echo "git checkout ${OPENCOLORIO_VERSION} --force"
|
||||
git checkout ${OPENCOLORIO_VERSION} --force
|
||||
mkdir -p ${OPENCOLORIO_BUILD_DIR}
|
||||
cd ${OPENCOLORIO_BUILD_DIR}
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${OPENCOLORIO_BUILD_DIR} \
|
||||
-DCMAKE_BUILD_TYPE=${OPENCOLORIO_BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX=${OPENCOLORIO_INSTALL_DIR} \
|
||||
-DCMAKE_CXX_FLAGS="${OPENCOLORIO_CXX_FLAGS}" \
|
||||
${OPENCOLORIO_BUILDOPTS} ${OPENCOLORIO_SOURCE_DIR}
|
||||
time cmake --build . --config Release --target install
|
||||
${OPENCOLORIO_BUILDOPTS}
|
||||
time cmake --build ${OPENCOLORIO_BUILD_DIR} --config Release --target install
|
||||
popd
|
||||
|
||||
# ls -R ${OPENCOLORIO_INSTALL_DIR}
|
||||
|
||||
@@ -36,42 +36,25 @@ if [[ ! -e ${OPENEXR_SOURCE_DIR} ]] ; then
|
||||
git clone ${OPENEXR_REPO} ${OPENEXR_SOURCE_DIR}
|
||||
fi
|
||||
mkdir -p ${OPENEXR_INSTALL_DIR} && true
|
||||
mkdir -p ${OPENEXR_BUILD_DIR} && true
|
||||
|
||||
pushd ${OPENEXR_SOURCE_DIR}
|
||||
git checkout ${OPENEXR_VERSION} --force
|
||||
|
||||
if [[ ${OPENEXR_VERSION} == "v2.3.0" ]] ; then
|
||||
# Simplified setup for 2.3+
|
||||
cd ${OPENEXR_BUILD_DIR}
|
||||
cmake -DCMAKE_BUILD_TYPE=${OPENEXR_BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX="${OPENEXR_INSTALL_DIR}" \
|
||||
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \
|
||||
-DILMBASE_PACKAGE_PREFIX="${OPENEXR_INSTALL_DIR}" \
|
||||
-DOPENEXR_BUILD_UTILS=0 \
|
||||
-DOPENEXR_BUILD_TESTS=0 \
|
||||
-DOPENEXR_BUILD_PYTHON_LIBS=0 \
|
||||
-DCMAKE_CXX_FLAGS="${OPENEXR_CXX_FLAGS}" \
|
||||
${OPENEXR_CMAKE_FLAGS} ${OPENEXR_SOURCE_DIR}
|
||||
time cmake --build . --target install --config ${OPENEXR_BUILD_TYPE}
|
||||
else
|
||||
# Simplified setup for 2.4+
|
||||
cd ${OPENEXR_BUILD_DIR}
|
||||
cmake -DCMAKE_BUILD_TYPE=${OPENEXR_BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX="${OPENEXR_INSTALL_DIR}" \
|
||||
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \
|
||||
-DILMBASE_PACKAGE_PREFIX="${OPENEXR_INSTALL_DIR}" \
|
||||
-DOPENEXR_BUILD_UTILS=0 \
|
||||
-DBUILD_TESTING=0 \
|
||||
-DPYILMBASE_ENABLE=0 \
|
||||
-DOPENEXR_VIEWERS_ENABLE=0 \
|
||||
-DINSTALL_OPENEXR_EXAMPLES=0 \
|
||||
-DOPENEXR_INSTALL_EXAMPLES=0 \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DCMAKE_CXX_FLAGS="${OPENEXR_CXX_FLAGS}" \
|
||||
${OPENEXR_CMAKE_FLAGS} ${OPENEXR_SOURCE_DIR}
|
||||
time cmake --build . --target install --config ${OPENEXR_BUILD_TYPE}
|
||||
fi
|
||||
cmake -S . -B ${OPENEXR_BUILD_DIR} \
|
||||
-DCMAKE_BUILD_TYPE=${OPENEXR_BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX="${OPENEXR_INSTALL_DIR}" \
|
||||
-DCMAKE_PREFIX_PATH="${CMAKE_PREFIX_PATH}" \
|
||||
-DILMBASE_PACKAGE_PREFIX="${OPENEXR_INSTALL_DIR}" \
|
||||
-DOPENEXR_BUILD_UTILS=0 \
|
||||
-DBUILD_TESTING=0 \
|
||||
-DPYILMBASE_ENABLE=0 \
|
||||
-DOPENEXR_VIEWERS_ENABLE=0 \
|
||||
-DINSTALL_OPENEXR_EXAMPLES=0 \
|
||||
-DOPENEXR_INSTALL_EXAMPLES=0 \
|
||||
-DCMAKE_INSTALL_LIBDIR=lib \
|
||||
-DCMAKE_CXX_FLAGS="${OPENEXR_CXX_FLAGS}" \
|
||||
${OPENEXR_CMAKE_FLAGS}
|
||||
time cmake --build ${OPENEXR_BUILD_DIR} --target install --config ${OPENEXR_BUILD_TYPE}
|
||||
|
||||
popd
|
||||
|
||||
|
||||
@@ -38,16 +38,13 @@ cd ${PUGIXML_SRC_DIR}
|
||||
echo "git checkout ${PUGIXML_VERSION} --force"
|
||||
git checkout ${PUGIXML_VERSION} --force
|
||||
|
||||
mkdir -p ${PUGIXML_BUILD_DIR}
|
||||
cd ${PUGIXML_BUILD_DIR}
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${PUGIXML_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${PUGIXML_INSTALL_DIR} \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
-DBUILD_TESTS=OFF \
|
||||
${PUGIXML_BUILD_OPTS} ..
|
||||
time cmake --build . --config Release --target install
|
||||
time cmake --build ${PUGIXML_BUILD_DIR} --config Release --target install
|
||||
fi
|
||||
|
||||
# ls -R ${PUGIXML_INSTALL_DIR}
|
||||
|
||||
@@ -42,15 +42,12 @@ cd ${PYBIND11_SRC_DIR}
|
||||
echo "git checkout ${PYBIND11_VERSION} --force"
|
||||
git checkout ${PYBIND11_VERSION} --force
|
||||
|
||||
mkdir -p ${PYBIND11_BUILD_DIR}
|
||||
cd ${PYBIND11_BUILD_DIR}
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${PYBIND11_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${PYBIND11_INSTALL_DIR} \
|
||||
-DPYBIND11_TEST=OFF \
|
||||
${PYBIND11_BUILD_OPTS} ..
|
||||
time cmake --build . --config Release --target install
|
||||
${PYBIND11_BUILD_OPTS}
|
||||
time cmake --build ${PYBIND11_BUILD_DIR} --config Release --target install
|
||||
fi
|
||||
|
||||
# ls -R ${PYBIND11_INSTALL_DIR}
|
||||
|
||||
@@ -37,11 +37,8 @@ cd ${WEBP_SRC_DIR}
|
||||
echo "git checkout ${WEBP_VERSION} --force"
|
||||
git checkout ${WEBP_VERSION} --force
|
||||
|
||||
mkdir -p ${WEBP_BUILD_DIR}
|
||||
cd ${WEBP_BUILD_DIR}
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=${WEBP_BUILD_TYPE} \
|
||||
time cmake -S . -B ${WEBP_BUILD_DIR} -DCMAKE_BUILD_TYPE=${WEBP_BUILD_TYPE} \
|
||||
-DCMAKE_INSTALL_PREFIX=${WEBP_INSTALL_DIR} \
|
||||
-DWEBP_BUILD_ANIM_UTILS=OFF \
|
||||
-DWEBP_BUILD_CWEBP=OFF \
|
||||
@@ -51,8 +48,8 @@ if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
-DWEBP_BUILD_IMG2WEBP=OFF \
|
||||
-DWEBP_BUILD_EXTRAS=OFF \
|
||||
-DBUILD_SHARED_LIBS=ON \
|
||||
${WEBP_CONFIG_OPTS} ..
|
||||
time cmake --build . --target install
|
||||
${WEBP_CONFIG_OPTS}
|
||||
time cmake --build ${WEBP_BUILD_DIR} --target install
|
||||
fi
|
||||
|
||||
|
||||
|
||||
@@ -37,15 +37,11 @@ cd ${ZLIB_SRC_DIR}
|
||||
echo "git checkout ${ZLIB_VERSION} --force"
|
||||
git checkout ${ZLIB_VERSION} --force
|
||||
|
||||
mkdir -p ${ZLIB_BUILD_DIR} && true
|
||||
cd ${ZLIB_BUILD_DIR}
|
||||
|
||||
|
||||
if [[ -z $DEP_DOWNLOAD_ONLY ]]; then
|
||||
time cmake -DCMAKE_BUILD_TYPE=Release \
|
||||
time cmake -S . -B ${ZLIB_BUILD_DIR} -DCMAKE_BUILD_TYPE=Release \
|
||||
-DCMAKE_INSTALL_PREFIX=${ZLIB_INSTALL_DIR} \
|
||||
${ZLIB_CONFIG_OPTS} ..
|
||||
time cmake --build . --config Release --target install
|
||||
${ZLIB_CONFIG_OPTS}
|
||||
time cmake --build ${ZLIB_BUILD_DIR} --config Release --target install
|
||||
fi
|
||||
|
||||
# ls -R ${ZLIB_INSTALL_DIR}
|
||||
|
||||
Executable
+54
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# Copyright Contributors to the OpenImageIO project.
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# https://github.com/OpenImageIO/oiio
|
||||
|
||||
# Important: set -ex causes this whole script to terminate with error if
|
||||
# any command in it fails. This is crucial for CI tests.
|
||||
set -e
|
||||
|
||||
# Arguments to this script are:
|
||||
# BUILDDIR_NEW BUILDDIR_OLD LIBRARIES...
|
||||
|
||||
BUILDDIR_NEW=$1
|
||||
shift
|
||||
BUILDDIR_OLD=$1
|
||||
shift
|
||||
LIBS=$*
|
||||
|
||||
#
|
||||
# First, create ABI dumps from both builds
|
||||
#
|
||||
ABI_ARGS="-bin-only -skip-cxx -public-headers $PWD/dist/include/OpenImageIO "
|
||||
echo "ABI_CHECK: PWD=${PWD} "
|
||||
ls -l $BUILDDIR_NEW
|
||||
ls -l $BUILDDIR_OLD
|
||||
for dir in $BUILDDIR_NEW $BUILDDIR_OLD ; do
|
||||
for lib in $LIBS ; do
|
||||
abi-dumper $ABI_ARGS ${dir}/lib/${lib}.so -o ${dir}/abi-${lib}.dump
|
||||
done
|
||||
done
|
||||
echo "Saved ABI dumps"
|
||||
|
||||
#
|
||||
# Run the ABI compliance checker, saving the outputs to files
|
||||
#
|
||||
for lib in $LIBS ; do
|
||||
abi-compliance-checker -l $lib -old $BUILDDIR_OLD/abi-$lib.dump -new $BUILDDIR_NEW/abi-$lib.dump | tee ${lib}-abi-results.txt || true
|
||||
echo -e "\x1b[33;1m"
|
||||
echo -e "$lib"
|
||||
fgrep "Binary compatibility:" ${lib}-abi-results.txt
|
||||
echo -e "\x1b[33;0m"
|
||||
done
|
||||
|
||||
#
|
||||
# If the "Binary compatibility" summary results say anything other than 100%,
|
||||
# we fail!
|
||||
#
|
||||
for lib in $LIBS ; do
|
||||
if [[ `fgrep "Binary compatibility:" ${lib}-abi-results.txt | grep -v 100\%` != "" ]] ; then
|
||||
cp -r compat_reports ${BUILDDIR_NEW}/compat_reports
|
||||
exit 1
|
||||
fi
|
||||
done
|
||||
@@ -27,8 +27,7 @@ if [[ ${GITHUB_ACTIONS} == true ]] ; then
|
||||
OIIO_CMAKE_FLAGS+=" -DCMAKE_UNITY_BUILD=${CMAKE_UNITY_BUILD:=ON} -DCMAKE_UNITY_BUILD_MODE=${CMAKE_UNITY_BUILD_MODE:=BATCH}"
|
||||
fi
|
||||
|
||||
pushd build
|
||||
cmake .. -G "$CMAKE_GENERATOR" \
|
||||
cmake -S . -B build -G "$CMAKE_GENERATOR" \
|
||||
-DCMAKE_BUILD_TYPE="${CMAKE_BUILD_TYPE}" \
|
||||
-DCMAKE_PREFIX_PATH="$CMAKE_PREFIX_PATH" \
|
||||
-DCMAKE_INSTALL_PREFIX="$OpenImageIO_ROOT" \
|
||||
@@ -40,15 +39,14 @@ cmake .. -G "$CMAKE_GENERATOR" \
|
||||
$OIIO_CMAKE_FLAGS -DVERBOSE=1
|
||||
|
||||
# Save a copy of the generated files for debugging broken CI builds.
|
||||
mkdir cmake-save || /bin/true
|
||||
cp -r CMake* *.cmake cmake-save
|
||||
mkdir build/cmake-save || /bin/true
|
||||
cp -r build/CMake* build/*.cmake build/cmake-save
|
||||
|
||||
: ${BUILDTARGET:=install}
|
||||
if [[ "$BUILDTARGET" != "none" ]] ; then
|
||||
echo "Parallel build ${CMAKE_BUILD_PARALLEL_LEVEL} of target ${BUILDTARGET}"
|
||||
time ${OIIO_CMAKE_BUILD_WRAPPER} cmake --build . --target ${BUILDTARGET} --config ${CMAKE_BUILD_TYPE}
|
||||
time ${OIIO_CMAKE_BUILD_WRAPPER} cmake --build build --target ${BUILDTARGET} --config ${CMAKE_BUILD_TYPE}
|
||||
fi
|
||||
popd
|
||||
|
||||
if [[ "${DEBUG_CI:=0}" != "0" ]] ; then
|
||||
echo "PATH=$PATH"
|
||||
|
||||
@@ -50,7 +50,7 @@ export LD_LIBRARY_PATH=${LOCAL_DEPS_DIR}/dist/lib:$LD_LIBRARY_PATH
|
||||
export LD_LIBRARY_PATH=${LOCAL_DEPS_DIR}/dist/lib64:$LD_LIBRARY_PATH
|
||||
export DYLD_LIBRARY_PATH=${LOCAL_DEPS_DIR}/dist/lib:$DYLD_LIBRARY_PATH
|
||||
|
||||
export OCIO="$PWD/testsuite/common/OpenColorIO/nuke-default/config.ocio"
|
||||
# export OCIO="$PWD/testsuite/common/OpenColorIO/nuke-default/config.ocio"
|
||||
export TESTSUITE_CLEANUP_ON_SUCCESS=${TESTSUITE_CLEANUP_ON_SUCCESS:=1}
|
||||
|
||||
mkdir -p build dist
|
||||
|
||||
@@ -24,6 +24,8 @@ echo ; echo "Results of oiiotool brief help:"
|
||||
$OpenImageIO_ROOT/bin/oiiotool || true
|
||||
echo ; echo "Results of oiiotool full --help:"
|
||||
$OpenImageIO_ROOT/bin/oiiotool --help || true
|
||||
echo ; echo "Results of oiiotool --colorconfiginfo:"
|
||||
$OpenImageIO_ROOT/bin/oiiotool --colorconfiginfo
|
||||
echo ; echo "Results of oiiotool with no args (should get short help message):"
|
||||
$OpenImageIO_ROOT/bin/oiiotool || true
|
||||
echo ; echo "Run unit tests and simple stats:"
|
||||
|
||||
@@ -18,8 +18,12 @@ if [[ "$ASWF_ORG" != "" ]] ; then
|
||||
#ls /etc/yum.repos.d
|
||||
|
||||
sudo yum install -y giflib giflib-devel && true
|
||||
sudo yum install -y opencv opencv-devel && true
|
||||
sudo yum install -y ffmpeg ffmpeg-devel && true
|
||||
if [[ "${USE_OPENCV}" != "0" ]] ; then
|
||||
sudo yum install -y opencv opencv-devel && true
|
||||
fi
|
||||
if [[ "${USE_FFMPEG}" != "0" ]] ; then
|
||||
sudo yum install -y ffmpeg ffmpeg-devel && true
|
||||
fi
|
||||
if [[ "${EXTRA_DEP_PACKAGES}" != "" ]] ; then
|
||||
time sudo yum install -y ${EXTRA_DEP_PACKAGES}
|
||||
fi
|
||||
@@ -138,6 +142,9 @@ else
|
||||
|
||||
fi
|
||||
|
||||
if [[ "$CMAKE_VERSION" != "" ]] ; then
|
||||
source src/build-scripts/build_cmake.bash
|
||||
fi
|
||||
cmake --version
|
||||
|
||||
|
||||
@@ -190,6 +197,10 @@ if [[ "$PTEX_VERSION" != "" ]] ; then
|
||||
source src/build-scripts/build_Ptex.bash
|
||||
fi
|
||||
|
||||
if [[ "$ABI_CHECK" != "" ]] ; then
|
||||
source src/build-scripts/build_abi_tools.bash
|
||||
fi
|
||||
|
||||
if [[ "$USE_ICC" != "" ]] ; then
|
||||
# We used gcc for the prior dependency builds, but use icc for OIIO itself
|
||||
echo "which icpc:" $(which icpc)
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
if [[ ! -e ../oiio-images ]] ; then
|
||||
git clone https://github.com/OpenImageIO/oiio-images.git -b RB-2.4 --depth 1 ../oiio-images
|
||||
# NOTE: on release branches, this should include `-b RB-x.y`` so that
|
||||
# updates to the master oiio-images don't break tests in release branches.
|
||||
fi
|
||||
|
||||
# if [[ ! -e ../libtiffpic ]] ; then
|
||||
# curl -o pics-3.8.0.tar.gz https://download.osgeo.org/libtiff/pics-3.8.0.tar.gz
|
||||
# tar xf pics-3.8.0.tar.gz -C ..
|
||||
# fi
|
||||
|
||||
if [[ ! -e ../openexr-images ]] ; then
|
||||
git clone https://github.com/openexr/openexr-images.git --depth 1 ../openexr-images
|
||||
fi
|
||||
|
||||
# if [[ ! -e ../bmpsuite ]] ; then
|
||||
# mkdir ../bmpsuite
|
||||
# curl -o bmpsuite.zip http://entropymine.com/jason/bmpsuite/bmpsuite.zip
|
||||
# unzip bmpsuite.zip -d ../bmpsuite
|
||||
# fi
|
||||
+20
-41
@@ -15,13 +15,11 @@
|
||||
###########################################################################
|
||||
# Print some basic status about the system and compiler
|
||||
#
|
||||
if (VERBOSE)
|
||||
message (STATUS "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
|
||||
message (STATUS "CMAKE_SYSTEM_VERSION = ${CMAKE_SYSTEM_VERSION}")
|
||||
message (STATUS "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
endif ()
|
||||
message (STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
|
||||
message (STATUS "CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
|
||||
message (VERBOSE "CMAKE_SYSTEM_NAME = ${CMAKE_SYSTEM_NAME}")
|
||||
message (VERBOSE "CMAKE_SYSTEM_VERSION = ${CMAKE_SYSTEM_VERSION}")
|
||||
message (VERBOSE "CMAKE_SYSTEM_PROCESSOR = ${CMAKE_SYSTEM_PROCESSOR}")
|
||||
message (STATUS "CMAKE_CXX_COMPILER = ${CMAKE_CXX_COMPILER}")
|
||||
message (STATUS "CMAKE_CXX_COMPILER_ID = ${CMAKE_CXX_COMPILER_ID}")
|
||||
|
||||
|
||||
###########################################################################
|
||||
@@ -44,9 +42,7 @@ if (CMAKE_COMPILER_IS_GNUCC)
|
||||
execute_process (COMMAND ${CMAKE_CXX_COMPILER} -dumpversion
|
||||
OUTPUT_VARIABLE GCC_VERSION
|
||||
OUTPUT_STRIP_TRAILING_WHITESPACE)
|
||||
if (VERBOSE)
|
||||
message (STATUS "Using gcc ${GCC_VERSION} as the compiler")
|
||||
endif ()
|
||||
message (VERBOSE "Using gcc ${GCC_VERSION} as the compiler")
|
||||
else ()
|
||||
set (GCC_VERSION 0)
|
||||
endif ()
|
||||
@@ -63,26 +59,18 @@ if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER MATCHES "[Cc]lan
|
||||
set (CMAKE_CXX_COMPILER_ID "AppleClang")
|
||||
set (CMAKE_COMPILER_IS_APPLECLANG 1)
|
||||
string (REGEX REPLACE ".* version ([0-9]+\\.[0-9]+).*" "\\1" APPLECLANG_VERSION_STRING ${clang_full_version_string})
|
||||
if (VERBOSE)
|
||||
message (STATUS "The compiler is Clang: ${CMAKE_CXX_COMPILER_ID} version ${APPLECLANG_VERSION_STRING}")
|
||||
endif ()
|
||||
message (VERBOSE "The compiler is Clang: ${CMAKE_CXX_COMPILER_ID} version ${APPLECLANG_VERSION_STRING}")
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "IntelLLVM")
|
||||
set (CMAKE_COMPILER_IS_INTELCLANG 1)
|
||||
string (REGEX MATCH "[0-9]+(\\.[0-9]+)+" INTELCLANG_VERSION_STRING ${clang_full_version_string})
|
||||
if (VERBOSE)
|
||||
message (STATUS "The compiler is Intel Clang: ${CMAKE_CXX_COMPILER_ID} version ${INTELCLANG_VERSION_STRING}")
|
||||
endif ()
|
||||
message (VERBOSE "The compiler is Intel Clang: ${CMAKE_CXX_COMPILER_ID} version ${INTELCLANG_VERSION_STRING}")
|
||||
else ()
|
||||
string (REGEX REPLACE ".* version ([0-9]+\\.[0-9]+).*" "\\1" CLANG_VERSION_STRING ${clang_full_version_string})
|
||||
if (VERBOSE)
|
||||
message (STATUS "The compiler is Clang: ${CMAKE_CXX_COMPILER_ID} version ${CLANG_VERSION_STRING}")
|
||||
endif ()
|
||||
message (VERBOSE "The compiler is Clang: ${CMAKE_CXX_COMPILER_ID} version ${CLANG_VERSION_STRING}")
|
||||
endif ()
|
||||
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Intel")
|
||||
set (CMAKE_COMPILER_IS_INTEL 1)
|
||||
if (VERBOSE)
|
||||
message (STATUS "Using Intel as the compiler")
|
||||
endif ()
|
||||
message (VERBOSE "Using Intel as the compiler")
|
||||
endif ()
|
||||
|
||||
|
||||
@@ -121,11 +109,11 @@ endif ()
|
||||
# give more fine-grained control for hiding symbols, because sometimes
|
||||
# dependent libraries may not be well behaved and need extra hiding.
|
||||
#
|
||||
set (CXX_VISIBILITY_PRESET "hidden" CACHE STRING "Symbol visibility (hidden or default")
|
||||
set (CMAKE_CXX_VISIBILITY_PRESET "hidden" CACHE STRING "Symbol visibility (hidden or default")
|
||||
option (VISIBILITY_INLINES_HIDDEN "Hide symbol visibility of inline functions" ON)
|
||||
set (VISIBILITY_MAP_FILE "${PROJECT_SOURCE_DIR}/src/build-scripts/hidesymbols.map" CACHE FILEPATH "Visibility map file")
|
||||
set (C_VISIBILITY_PRESET ${CXX_VISIBILITY_PRESET})
|
||||
if (${CXX_VISIBILITY_PRESET} STREQUAL "hidden" AND VISIBILITY_MAP_FILE AND
|
||||
set (CMAKE_C_VISIBILITY_PRESET ${CMAKE_CXX_VISIBILITY_PRESET})
|
||||
if (${CMAKE_CXX_VISIBILITY_PRESET} STREQUAL "hidden" AND VISIBILITY_MAP_FILE AND
|
||||
(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_CLANG) AND
|
||||
(CMAKE_SYSTEM_NAME MATCHES "Linux|kFreeBSD" OR CMAKE_SYSTEM_NAME STREQUAL "GNU"))
|
||||
# Linux/FreeBSD/Hurd: also hide all the symbols of dependent libraries
|
||||
@@ -191,6 +179,7 @@ endif ()
|
||||
if (MSVC)
|
||||
# Microsoft specific options
|
||||
add_compile_options (/W1)
|
||||
add_compile_options (/MP)
|
||||
add_definitions (-D_CRT_SECURE_NO_DEPRECATE)
|
||||
add_definitions (-D_CRT_SECURE_NO_WARNINGS)
|
||||
add_definitions (-D_CRT_NONSTDC_NO_WARNINGS)
|
||||
@@ -314,9 +303,7 @@ if (NOT USE_SIMD STREQUAL "")
|
||||
else ()
|
||||
string (REPLACE "," ";" SIMD_FEATURE_LIST ${USE_SIMD})
|
||||
foreach (feature ${SIMD_FEATURE_LIST})
|
||||
if (VERBOSE)
|
||||
message (STATUS "SIMD feature: ${feature}")
|
||||
endif ()
|
||||
message (VERBOSE "SIMD feature: ${feature}")
|
||||
if (MSVC OR CMAKE_COMPILER_IS_INTEL)
|
||||
set (SIMD_COMPILE_FLAGS ${SIMD_COMPILE_FLAGS} "/arch:${feature}")
|
||||
else ()
|
||||
@@ -371,9 +358,7 @@ if (NOT MSVC AND NOT APPLE AND NOT ANDROID)
|
||||
message (FATAL_ERROR "Compiler needs libatomic, but not found")
|
||||
endif ()
|
||||
else ()
|
||||
if (VERBOSE)
|
||||
message (STATUS "Compiler supports std::atomic, no libatomic necessary")
|
||||
endif ()
|
||||
message (VERBOSE "Compiler supports std::atomic, no libatomic necessary")
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
@@ -476,10 +461,8 @@ if (CLANG_TIDY)
|
||||
find_program(CLANG_TIDY_EXE NAMES "clang-tidy"
|
||||
DOC "Path to clang-tidy executable")
|
||||
message (STATUS "CLANG_TIDY_EXE ${CLANG_TIDY_EXE}")
|
||||
if (CLANG_TIDY_EXE AND NOT ${CMAKE_VERSION} VERSION_LESS 3.6)
|
||||
set (CMAKE_CXX_CLANG_TIDY
|
||||
"${CLANG_TIDY_EXE}"
|
||||
)
|
||||
if (CLANG_TIDY_EXE)
|
||||
set (CMAKE_CXX_CLANG_TIDY "${CLANG_TIDY_EXE}")
|
||||
if (CLANG_TIDY_ARGS)
|
||||
list (APPEND CMAKE_CXX_CLANG_TIDY ${CLANG_TIDY_ARGS})
|
||||
endif ()
|
||||
@@ -573,9 +556,7 @@ else ()
|
||||
set (SOVERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH}
|
||||
CACHE STRING "Set the SO version for dynamic libraries")
|
||||
endif ()
|
||||
if (VERBOSE)
|
||||
message(STATUS "Setting SOVERSION to: ${SOVERSION}")
|
||||
endif ()
|
||||
message(VERBOSE "Setting SOVERSION to: ${SOVERSION}")
|
||||
|
||||
|
||||
###########################################################################
|
||||
@@ -637,9 +618,7 @@ else ()
|
||||
# add the automatically determined parts of the RPATH that
|
||||
# point to directories outside the build tree to the install RPATH
|
||||
set (CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
|
||||
if (VERBOSE)
|
||||
message (STATUS "CMAKE_INSTALL_RPATH = ${CMAKE_INSTALL_RPATH}")
|
||||
endif ()
|
||||
message (VERBOSE "CMAKE_INSTALL_RPATH = ${CMAKE_INSTALL_RPATH}")
|
||||
endif ()
|
||||
|
||||
|
||||
|
||||
@@ -99,8 +99,8 @@ checked_find_package (TIFF REQUIRED
|
||||
|
||||
# IlmBase & OpenEXR
|
||||
checked_find_package (OpenEXR REQUIRED
|
||||
VERSION_MIN 2.3
|
||||
RECOMMEND_MIN 2.4
|
||||
VERSION_MIN 2.4
|
||||
RECOMMEND_MIN 3.1
|
||||
PRINT IMATH_INCLUDES OPENEXR_INCLUDES)
|
||||
# Force Imath includes to be before everything else to ensure that we have
|
||||
# the right Imath/OpenEXR version, not some older version in the system
|
||||
@@ -123,18 +123,14 @@ set (OPENIMAGEIO_IMATH_TARGETS
|
||||
# For OpenEXR >= 2.4/2.5 with reliable exported targets
|
||||
$<TARGET_NAME_IF_EXISTS:IlmBase::Imath>
|
||||
$<TARGET_NAME_IF_EXISTS:IlmBase::Half>
|
||||
$<TARGET_NAME_IF_EXISTS:IlmBase::Iex>
|
||||
# For OpenEXR <= 2.3:
|
||||
${ILMBASE_LIBRARIES} )
|
||||
$<TARGET_NAME_IF_EXISTS:IlmBase::Iex> )
|
||||
set (OPENIMAGEIO_OPENEXR_TARGETS
|
||||
# For OpenEXR/Imath 3.x:
|
||||
$<TARGET_NAME_IF_EXISTS:OpenEXR::OpenEXR>
|
||||
# For OpenEXR >= 2.4/2.5 with reliable exported targets
|
||||
$<TARGET_NAME_IF_EXISTS:OpenEXR::IlmImf>
|
||||
$<TARGET_NAME_IF_EXISTS:IlmBase::IlmThread>
|
||||
$<TARGET_NAME_IF_EXISTS:IlmBase::Iex>
|
||||
# For OpenEXR <= 2.3:
|
||||
${OPENEXR_LIBRARIES} )
|
||||
$<TARGET_NAME_IF_EXISTS:IlmBase::Iex> )
|
||||
set (OPENIMAGEIO_IMATH_DEPENDENCY_VISIBILITY "PUBLIC" CACHE STRING
|
||||
"Should we expose Imath library dependency as PUBLIC or PRIVATE")
|
||||
set (OPENIMAGEIO_CONFIG_DO_NOT_FIND_IMATH OFF CACHE BOOL
|
||||
@@ -183,9 +179,16 @@ checked_find_package (OpenColorIO
|
||||
DEFINITIONS -DUSE_OCIO=1 -DUSE_OPENCOLORIO=1
|
||||
# PREFER_CONFIG
|
||||
)
|
||||
if (NOT OpenColorIO_FOUND)
|
||||
if (OpenColorIO_FOUND)
|
||||
option (OIIO_DISABLE_BUILTIN_OCIO_CONFIGS
|
||||
"For deveoper debugging/testing ONLY! Disable OCIO 2.2 builtin configs." OFF)
|
||||
if (OIIO_DISABLE_BUILTIN_OCIO_CONFIGS OR "$ENV{OIIO_DISABLE_BUILTIN_OCIO_CONFIGS}")
|
||||
add_compile_definitions(OIIO_DISABLE_BUILTIN_OCIO_CONFIGS)
|
||||
endif ()
|
||||
else ()
|
||||
set (OpenColorIO_FOUND 0)
|
||||
endif ()
|
||||
|
||||
checked_find_package (OpenCV 3.0
|
||||
DEFINITIONS -DUSE_OPENCV=1)
|
||||
|
||||
@@ -212,8 +215,7 @@ if (APPLE AND LIBHEIF_VERSION VERSION_GREATER_EQUAL 1.10 AND LIBHEIF_VERSION VER
|
||||
endif ()
|
||||
|
||||
checked_find_package (LibRaw
|
||||
RECOMMEND_MIN 0.18
|
||||
RECOMMEND_MIN_REASON "for ACES support and better camera metadata"
|
||||
VERSION_MIN 0.18
|
||||
PRINT LibRaw_r_LIBRARIES)
|
||||
if (LibRaw_FOUND AND LibRaw_VERSION VERSION_LESS 0.20 AND CMAKE_CXX_STANDARD VERSION_GREATER_EQUAL 17)
|
||||
message (STATUS "${ColorYellow}WARNING When building for C++17, LibRaw should be 0.20 or higher (found ${LibRaw_VERSION}). You may get errors, depending on the compiler.${ColorReset}")
|
||||
@@ -315,7 +317,7 @@ endmacro()
|
||||
option (BUILD_FMT_FORCE "Force local download/build of fmt even if installed" OFF)
|
||||
option (BUILD_MISSING_FMT "Local download/build of fmt if not installed" ON)
|
||||
option (INTERNALIZE_FMT "Copy fmt headers into <install>/include/OpenImageIO/detail/fmt" ON)
|
||||
set (BUILD_FMT_VERSION "9.0.0" CACHE STRING "Preferred fmtlib/fmt version, when downloading/building our own")
|
||||
set (BUILD_FMT_VERSION "10.0.0" CACHE STRING "Preferred fmtlib/fmt version, when downloading/building our own")
|
||||
|
||||
macro (find_or_download_fmt)
|
||||
# If we weren't told to force our own download/build of fmt, look
|
||||
@@ -348,7 +350,8 @@ macro (find_or_download_fmt)
|
||||
else ()
|
||||
set (OIIO_USING_FMT_LOCAL FALSE)
|
||||
endif ()
|
||||
checked_find_package (fmt REQUIRED)
|
||||
checked_find_package (fmt REQUIRED
|
||||
VERSION_MIN 7.0)
|
||||
endmacro()
|
||||
|
||||
find_or_download_fmt()
|
||||
|
||||
@@ -55,9 +55,7 @@ macro (fancy_add_executable)
|
||||
if (CMAKE_UNITY_BUILD AND UNITY_BUILD_MODE STREQUAL GROUP)
|
||||
set_source_files_properties(${_target_SRC} PROPERTIES
|
||||
UNITY_GROUP ${_target_NAME})
|
||||
if (VERBOSE)
|
||||
message (STATUS "Unity group ${_target_NAME} = ${_target_SRC}")
|
||||
endif ()
|
||||
message (VERBOSE "Unity group ${_target_NAME} = ${_target_SRC}")
|
||||
endif ()
|
||||
if (_target_NAME_INSTALL_enabled)
|
||||
install_targets (${_target_NAME})
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# Copyright Contributors to the OpenImageIO project.
|
||||
# SPDX-License-Identifier: BSD-3-Clause and Apache-2.0
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# https://github.com/OpenImageIO/oiio
|
||||
|
||||
# Module to find OpenEXR and Imath.
|
||||
@@ -7,7 +7,7 @@
|
||||
# I'm afraid this is a mess, due to needing to support a wide range of
|
||||
# OpenEXR versions.
|
||||
#
|
||||
# For OpenEXR & Imath 3.0, this will establish the following imported
|
||||
# For OpenEXR & Imath 3.x, this will establish the following imported
|
||||
# targets:
|
||||
#
|
||||
# Imath::Imath
|
||||
@@ -24,14 +24,12 @@
|
||||
# IlmBase::IlmThread
|
||||
# OpenEXR::IlmImf
|
||||
#
|
||||
# For all versions -- but for OpenEXR < 2.4 the only thing this sets --
|
||||
# are the following CMake variables:
|
||||
# For all version, the following CMake variables:
|
||||
#
|
||||
# OPENEXR_FOUND true, if found
|
||||
# OPENEXR_INCLUDES directory where OpenEXR headers are found
|
||||
# OPENEXR_LIBRARIES libraries for OpenEXR + IlmBase
|
||||
# OPENEXR_VERSION OpenEXR version (accurate for >= 2.0.0,
|
||||
# otherwise will just guess 1.6.1)
|
||||
# OPENEXR_VERSION OpenEXR version
|
||||
# IMATH_INCLUDES directory where Imath headers are found
|
||||
# ILMBASE_INCLUDES directory where IlmBase headers are found
|
||||
# ILMBASE_LIBRARIES libraries just IlmBase
|
||||
@@ -111,162 +109,4 @@ elseif (TARGET OpenEXR::IlmImf AND TARGET IlmBase::Imath AND
|
||||
string(REGEX REPLACE "include/OpenEXR$" "include" IMATH_INCLUDES "${IMATH_INCLUDES}")
|
||||
string(REGEX REPLACE "include/OpenEXR$" "include" OPENEXR_INCLUDES "${OPENEXR_INCLUDES}")
|
||||
|
||||
else ()
|
||||
# OpenEXR 2.x older versions without a config or whose configs we don't
|
||||
# trust.
|
||||
|
||||
set (FOUND_OPENEXR_WITH_CONFIG 0)
|
||||
|
||||
# Other standard issue macros
|
||||
include (FindPackageHandleStandardArgs)
|
||||
include (SelectLibraryConfigurations)
|
||||
|
||||
find_package (ZLIB REQUIRED)
|
||||
|
||||
# Link with pthreads if required
|
||||
find_package (Threads)
|
||||
if (CMAKE_USE_PTHREADS_INIT)
|
||||
set (ILMBASE_PTHREADS ${CMAKE_THREAD_LIBS_INIT})
|
||||
endif ()
|
||||
|
||||
# Attempt to find OpenEXR with pkgconfig
|
||||
find_package(PkgConfig)
|
||||
if (PKG_CONFIG_FOUND)
|
||||
if (NOT Ilmbase_ROOT AND NOT ILMBASE_ROOT
|
||||
AND NOT DEFINED ENV{Ilmbase_ROOT} AND NOT DEFINED ENV{ILMBASE_ROOT})
|
||||
pkg_check_modules(_ILMBASE QUIET IlmBase>=2.0.0)
|
||||
endif ()
|
||||
if (NOT OpenEXR_ROOT AND NOT OPENEXR_ROOT
|
||||
AND NOT DEFINED ENV{OpenEXR_ROOT} AND NOT DEFINED ENV{OPENEXR_ROOT})
|
||||
pkg_check_modules(_OPENEXR QUIET OpenEXR>=2.0.0)
|
||||
endif ()
|
||||
endif (PKG_CONFIG_FOUND)
|
||||
|
||||
# List of likely places to find the headers -- note priority override of
|
||||
# ${OPENEXR_ROOT}/include.
|
||||
# ILMBASE is needed in case ilmbase an openexr are installed in separate
|
||||
# directories, like NixOS does
|
||||
set (GENERIC_INCLUDE_PATHS
|
||||
${OPENEXR_ROOT}/include
|
||||
$ENV{OPENEXR_ROOT}/include
|
||||
${ILMBASE_ROOT}/include
|
||||
$ENV{ILMBASE_ROOT}/include
|
||||
${_ILMBASE_INCLUDEDIR}
|
||||
${_OPENEXR_INCLUDEDIR}
|
||||
/usr/local/include
|
||||
/usr/include
|
||||
/usr/include/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||
/sw/include
|
||||
/opt/local/include )
|
||||
|
||||
# Find the include file locations.
|
||||
find_path (ILMBASE_INCLUDE_PATH OpenEXR/IlmBaseConfig.h
|
||||
HINTS ${ILMBASE_INCLUDE_DIR} ${OPENEXR_INCLUDE_DIR}
|
||||
${GENERIC_INCLUDE_PATHS} )
|
||||
find_path (OPENEXR_INCLUDE_PATH OpenEXR/OpenEXRConfig.h
|
||||
HINTS ${OPENEXR_INCLUDE_DIR}
|
||||
${GENERIC_INCLUDE_PATHS} )
|
||||
|
||||
# Try to figure out version number
|
||||
if (DEFINED _OPENEXR_VERSION AND NOT "${_OPENEXR_VERSION}" STREQUAL "")
|
||||
set (OPENEXR_VERSION "${_OPENEXR_VERSION}")
|
||||
set (OpenEXR_VERSION "${_OPENEXR_VERSION}")
|
||||
string (REGEX REPLACE "([0-9]+)\\.[0-9\\.]+" "\\1" OpenEXR_VERSION_MAJOR "${_OPENEXR_VERSION}")
|
||||
string (REGEX REPLACE "[0-9]+\\.([0-9]+)(\\.[0-9]+)?" "\\1" OpenEXR_VERSION_MINOR "${_OPENEXR_VERSION}")
|
||||
elseif (EXISTS "${OPENEXR_INCLUDE_PATH}/OpenEXR/ImfMultiPartInputFile.h")
|
||||
# Must be at least 2.0
|
||||
file(STRINGS "${OPENEXR_INCLUDE_PATH}/OpenEXR/OpenEXRConfig.h" TMP REGEX "^#define OPENEXR_VERSION_STRING .*$")
|
||||
string (REGEX MATCHALL "[0-9]+[.0-9]+" OpenEXR_VERSION ${TMP})
|
||||
file(STRINGS "${OPENEXR_INCLUDE_PATH}/OpenEXR/OpenEXRConfig.h" TMP REGEX "^#define OPENEXR_VERSION_MAJOR .*$")
|
||||
string (REGEX MATCHALL "[0-9]+" OpenEXR_VERSION_MAJOR ${TMP})
|
||||
file(STRINGS "${OPENEXR_INCLUDE_PATH}/OpenEXR/OpenEXRConfig.h" TMP REGEX "^#define OPENEXR_VERSION_MINOR .*$")
|
||||
string (REGEX MATCHALL "[0-9]+" OpenEXR_VERSION_MINOR ${TMP})
|
||||
else ()
|
||||
# Assume an old one, predates 2.x that had versions
|
||||
set (OPENEXR_VERSION 1.6.1)
|
||||
set (OpenEXR_VERSION 1.6.1)
|
||||
set (OpenEXR_VERSION_MAJOR 1)
|
||||
set (OpenEXR_VERSION_MINOR 6)
|
||||
endif ()
|
||||
|
||||
|
||||
# List of likely places to find the libraries -- note priority override of
|
||||
# ${OPENEXR_ROOT}/lib.
|
||||
set (GENERIC_LIBRARY_PATHS
|
||||
${OPENEXR_ROOT}/lib
|
||||
${ILMBASE_ROOT}/lib
|
||||
${OPENEXR_INCLUDE_PATH}/../lib
|
||||
${ILMBASE_INCLUDE_PATH}/../lib
|
||||
${_ILMBASE_LIBDIR}
|
||||
${_OPENEXR_LIBDIR}
|
||||
/usr/local/lib
|
||||
/usr/local/lib/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||
/usr/lib
|
||||
/usr/lib/${CMAKE_LIBRARY_ARCHITECTURE}
|
||||
/sw/lib
|
||||
/opt/local/lib
|
||||
$ENV{PROGRAM_FILES}/OpenEXR/lib/static )
|
||||
|
||||
# message (STATUS "Generic lib paths: ${GENERIC_LIBRARY_PATHS}")
|
||||
|
||||
# Handle request for static libs by altering CMAKE_FIND_LIBRARY_SUFFIXES.
|
||||
# We will restore it at the end of this file.
|
||||
set (_openexr_orig_suffixes ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
if (OpenEXR_USE_STATIC_LIBS)
|
||||
if (WIN32)
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES})
|
||||
else ()
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES .a)
|
||||
endif ()
|
||||
endif ()
|
||||
|
||||
# Look for the libraries themselves, for all the components.
|
||||
# This is complicated because the OpenEXR libraries may or may not be
|
||||
# built with version numbers embedded.
|
||||
set (_openexr_components IlmThread IlmImf Imath Iex Half)
|
||||
foreach (COMPONENT ${_openexr_components})
|
||||
string (TOUPPER ${COMPONENT} UPPERCOMPONENT)
|
||||
# First try with the version embedded
|
||||
find_library (OPENEXR_${UPPERCOMPONENT}_LIBRARY
|
||||
NAMES ${COMPONENT}-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}
|
||||
${COMPONENT}
|
||||
${COMPONENT}-${OpenEXR_VERSION_MAJOR}_${OpenEXR_VERSION_MINOR}_d
|
||||
${COMPONENT}_d
|
||||
HINTS ${OPENEXR_LIBRARY_DIR} $ENV{OPENEXR_LIBRARY_DIR}
|
||||
${GENERIC_LIBRARY_PATHS} )
|
||||
endforeach ()
|
||||
|
||||
find_package_handle_standard_args (OpenEXR
|
||||
REQUIRED_VARS ILMBASE_INCLUDE_PATH OPENEXR_INCLUDE_PATH
|
||||
OPENEXR_IMATH_LIBRARY OPENEXR_ILMIMF_LIBRARY
|
||||
OPENEXR_IEX_LIBRARY OPENEXR_HALF_LIBRARY
|
||||
)
|
||||
|
||||
if (OPENEXR_FOUND)
|
||||
set (OPENEXR_VERSION_MAJOR ${OpenEXR_VERSION_MAJOR})
|
||||
set (OPENEXR_VERSION_MINOR ${OpenEXR_VERSION_MINOR})
|
||||
set (Imath_VERSION_MAJOR ${OpenEXR_VERSION_MAJOR})
|
||||
set (Imath_VERSION_MINOR ${OpenEXR_VERSION_MINOR})
|
||||
set (ILMBASE_FOUND TRUE)
|
||||
set (ILMBASE_INCLUDES ${ILMBASE_INCLUDE_PATH})
|
||||
set (IMATH_INCLUDES ${ILMBASE_INCLUDE_PATH})
|
||||
set (OPENEXR_INCLUDES ${OPENEXR_INCLUDE_PATH})
|
||||
set (ILMBASE_INCLUDE_DIR ${ILMBASE_INCLUDE_PATH})
|
||||
set (IMATH_INCLUDE_DIR ${ILMBASE_INCLUDE_PATH})
|
||||
set (OPENEXR_INCLUDE_DIR ${OPENEXR_INCLUDE_PATH})
|
||||
set (ILMBASE_LIBRARIES ${OPENEXR_IMATH_LIBRARY} ${OPENEXR_IEX_LIBRARY} ${OPENEXR_HALF_LIBRARY} ${OPENEXR_ILMTHREAD_LIBRARY} ${ILMBASE_PTHREADS} CACHE STRING "The libraries needed to use IlmBase")
|
||||
set (OPENEXR_LIBRARIES ${OPENEXR_ILMIMF_LIBRARY} ${ILMBASE_LIBRARIES} ${ZLIB_LIBRARIES} CACHE STRING "The libraries needed to use OpenEXR")
|
||||
set (FINDOPENEXR_FALLBACK TRUE)
|
||||
endif ()
|
||||
|
||||
mark_as_advanced(
|
||||
OPENEXR_ILMIMF_LIBRARY
|
||||
OPENEXR_IMATH_LIBRARY
|
||||
OPENEXR_IEX_LIBRARY
|
||||
OPENEXR_HALF_LIBRARY
|
||||
OPENEXR_VERSION)
|
||||
|
||||
# Restore the original CMAKE_FIND_LIBRARY_SUFFIXES
|
||||
set (CMAKE_FIND_LIBRARY_SUFFIXES ${_openexr_orig_suffixes})
|
||||
|
||||
endif ()
|
||||
|
||||
@@ -16,9 +16,7 @@ find_package (pugixml CONFIG)
|
||||
if (TARGET pugixml::pugixml)
|
||||
# New pugixml (>= 1.11) has nice config files we can rely on and makes a
|
||||
# pugixml::pugixml target.
|
||||
if (VERBOSE)
|
||||
message (STATUS "Found CONFIG for pugixml (>=1.11)")
|
||||
endif ()
|
||||
message (VERBOSE "Found CONFIG for pugixml (>=1.11)")
|
||||
|
||||
set (PUGIXML_FOUND true)
|
||||
set (pugixml_FOUND true)
|
||||
|
||||
@@ -52,11 +52,9 @@ macro (find_python)
|
||||
if (NOT DEFINED PYTHON_SITE_DIR)
|
||||
set (PYTHON_SITE_DIR "${CMAKE_INSTALL_LIBDIR}/python${PYTHON_VERSION_FOUND}/site-packages/OpenImageIO")
|
||||
endif ()
|
||||
if (VERBOSE)
|
||||
message (STATUS " Python site packages dir ${PYTHON_SITE_DIR}")
|
||||
message (STATUS " Python to include 'lib' prefix: ${PYLIB_LIB_PREFIX}")
|
||||
message (STATUS " Python to include SO version: ${PYLIB_INCLUDE_SONAME}")
|
||||
endif ()
|
||||
message (VERBOSE " Python site packages dir ${PYTHON_SITE_DIR}")
|
||||
message (VERBOSE " Python to include 'lib' prefix: ${PYLIB_LIB_PREFIX}")
|
||||
message (VERBOSE " Python to include SO version: ${PYLIB_INCLUDE_SONAME}")
|
||||
endmacro()
|
||||
|
||||
|
||||
@@ -114,9 +112,7 @@ macro (setup_python_module)
|
||||
|
||||
# This is only needed for SpComp2
|
||||
if (PYLIB_INCLUDE_SONAME)
|
||||
if (VERBOSE)
|
||||
message(STATUS "Setting Py${lib_MODULE} SOVERSION to: ${SOVERSION}")
|
||||
endif ()
|
||||
message(VERBOSE "Setting Py${lib_MODULE} SOVERSION to: ${SOVERSION}")
|
||||
set_target_properties(${target_name} PROPERTIES
|
||||
VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
|
||||
SOVERSION ${SOVERSION} )
|
||||
|
||||
+22
-17
@@ -69,7 +69,8 @@ macro (oiio_add_tests)
|
||||
set (_test_disabled 1)
|
||||
endif ()
|
||||
endforeach ()
|
||||
if (0 AND OpenColorIO_VERSION VERSION_GREATER_EQUAL 2.2)
|
||||
if (OpenColorIO_VERSION VERSION_GREATER_EQUAL 2.2
|
||||
AND NOT (OIIO_DISABLE_BUILTIN_OCIO_CONFIGS OR "$ENV{OIIO_DISABLE_BUILTIN_OCIO_CONFIGS}"))
|
||||
# For OCIO 2.2+, have the testsuite use the default built-in config
|
||||
list (APPEND _ats_ENVIRONMENT "OCIO=ocio://default"
|
||||
"OIIO_TESTSUITE_OCIOCONFIG=ocio://default")
|
||||
@@ -124,9 +125,7 @@ macro (oiio_add_tests)
|
||||
endif()
|
||||
|
||||
endforeach ()
|
||||
if (VERBOSE)
|
||||
message (STATUS "TESTS: ${_ats_UNPARSED_ARGUMENTS}")
|
||||
endif ()
|
||||
message (VERBOSE "TESTS: ${_ats_UNPARSED_ARGUMENTS}")
|
||||
endif ()
|
||||
endmacro ()
|
||||
|
||||
@@ -140,6 +139,7 @@ macro (oiio_add_all_tests)
|
||||
# Freestanding tests:
|
||||
oiio_add_tests (
|
||||
cmake-consumer
|
||||
docs-examples-cpp
|
||||
iinfo igrep
|
||||
nonwhole-tiles
|
||||
oiiotool
|
||||
@@ -185,6 +185,7 @@ macro (oiio_add_all_tests)
|
||||
texture-stats
|
||||
texture-threadtimes
|
||||
texture-env
|
||||
texture-colorspace
|
||||
)
|
||||
oiio_add_tests (${all_texture_tests})
|
||||
# Duplicate texture tests with batch mode
|
||||
@@ -208,6 +209,7 @@ macro (oiio_add_all_tests)
|
||||
# libraries to run correctly.
|
||||
if (USE_PYTHON AND NOT BUILD_OIIOUTIL_ONLY AND NOT SANITIZE)
|
||||
oiio_add_tests (
|
||||
docs-examples-python
|
||||
python-colorconfig
|
||||
python-deep
|
||||
python-imagebuf
|
||||
@@ -274,12 +276,18 @@ macro (oiio_add_all_tests)
|
||||
set (all_openexr_tests
|
||||
openexr-suite openexr-multires openexr-chroma
|
||||
openexr-v2 openexr-window perchannel oiiotool-deep)
|
||||
if (OpenEXR_VERSION VERSION_GREATER_EQUAL 3.1.10)
|
||||
# OpenEXR 3.1.10 is the first release where the exr core library
|
||||
# properly supported all compression types (DWA in particular).
|
||||
list (APPEND all_openexr_tests openexr-compression)
|
||||
endif ()
|
||||
# Run all OpenEXR tests without core library
|
||||
oiio_add_tests (${all_openexr_tests}
|
||||
ENVIRONMENT OPENIMAGEIO_OPTIONS=openexr:core=0
|
||||
IMAGEDIR openexr-images
|
||||
URL http://github.com/AcademySoftwareFoundation/openexr-images)
|
||||
# For OpenEXR >= 3.1, be sure to test with the core option on
|
||||
if (OpenEXR_VERSION VERSION_GREATER_EQUAL 3.1)
|
||||
# For OpenEXR >= 3.1, be sure to test with the core option on
|
||||
oiio_add_tests (${all_openexr_tests}
|
||||
SUFFIX ".core"
|
||||
ENVIRONMENT OPENIMAGEIO_OPTIONS=openexr:core=1
|
||||
@@ -360,18 +368,15 @@ function (oiio_get_test_data name)
|
||||
if (IS_DIRECTORY "${OIIO_LOCAL_TESTDATA_ROOT}/${name}"
|
||||
AND NOT EXISTS "${CMAKE_BINARY_DIR}/testsuite/${name}")
|
||||
set (_ogtd_LINK_RESULT "")
|
||||
if (CMAKE_VERSION VERSION_GREATER_EQUAL 3.14)
|
||||
# Just make a link if we can
|
||||
message (STATUS "Linking ${name} from ${OIIO_LOCAL_TESTDATA_ROOT}/${name}")
|
||||
file (CREATE_LINK "${OIIO_LOCAL_TESTDATA_ROOT}/${name}"
|
||||
"${CMAKE_BINARY_DIR}/testsuite/${name}"
|
||||
SYMBOLIC RESULT _ogtd_LINK_RESULT)
|
||||
# Note: Using 'COPY_ON_ERROR' in the above command should have prevented the need to
|
||||
# have the manual fall-back below. However, there's been at least one case where a user
|
||||
# noticed that copying did not happen if creating the link failed (CMake 3.24). We can
|
||||
# adjust this in the future if CMake behavior improves.
|
||||
message (STATUS "Link result ${_ogtd_LINK_RESULT}")
|
||||
endif ()
|
||||
message (STATUS "Linking ${name} from ${OIIO_LOCAL_TESTDATA_ROOT}/${name}")
|
||||
file (CREATE_LINK "${OIIO_LOCAL_TESTDATA_ROOT}/${name}"
|
||||
"${CMAKE_BINARY_DIR}/testsuite/${name}"
|
||||
SYMBOLIC RESULT _ogtd_LINK_RESULT)
|
||||
# Note: Using 'COPY_ON_ERROR' in the above command should have prevented the need to
|
||||
# have the manual fall-back below. However, there's been at least one case where a user
|
||||
# noticed that copying did not happen if creating the link failed (CMake 3.24). We can
|
||||
# adjust this in the future if CMake behavior improves.
|
||||
message (VERBOSE "Link result ${_ogtd_LINK_RESULT}")
|
||||
if (NOT _ogtd_LINK_RESULT EQUAL 0)
|
||||
# Older cmake or failure to link -- copy
|
||||
message (STATUS "Copying ${name} from ${OIIO_LOCAL_TESTDATA_ROOT}/${name}")
|
||||
|
||||
@@ -5,6 +5,10 @@
|
||||
#pragma once
|
||||
|
||||
|
||||
// Some documentation for the DDS format:
|
||||
// https://learn.microsoft.com/en-us/windows/win32/direct3ddds/dx-graphics-dds-pguide
|
||||
// https://learn.microsoft.com/en-us/windows/win32/direct3ddds/dx-graphics-dds-reference
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ public:
|
||||
{
|
||||
return feature == "ioproxy";
|
||||
}
|
||||
bool valid_file(Filesystem::IOProxy* ioproxy) const override;
|
||||
bool open(const std::string& name, ImageSpec& newspec) override;
|
||||
bool open(const std::string& name, ImageSpec& spec,
|
||||
const ImageSpec& config) override;
|
||||
@@ -101,6 +102,8 @@ private:
|
||||
|
||||
/// Helper function: performs the actual pixel decoding.
|
||||
bool internal_readimg(unsigned char* dst, int w, int h, int d);
|
||||
|
||||
static bool validate_signature(uint32_t signature);
|
||||
};
|
||||
|
||||
static TypeDesc::BASETYPE
|
||||
@@ -316,6 +319,27 @@ OIIO_PLUGIN_EXPORTS_END
|
||||
|
||||
|
||||
|
||||
bool
|
||||
DDSInput::validate_signature(uint32_t signature)
|
||||
{
|
||||
return signature == DDS_MAKE4CC('D', 'D', 'S', ' ');
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
DDSInput::valid_file(Filesystem::IOProxy* ioproxy) const
|
||||
{
|
||||
if (!ioproxy || ioproxy->mode() != Filesystem::IOProxy::Mode::Read)
|
||||
return false;
|
||||
|
||||
uint32_t magic {};
|
||||
const size_t numRead = ioproxy->pread(&magic, sizeof(magic), 0);
|
||||
return numRead == sizeof(magic) && validate_signature(magic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
DDSInput::open(const std::string& name, ImageSpec& newspec,
|
||||
const ImageSpec& config)
|
||||
@@ -379,7 +403,7 @@ DDSInput::open(const std::string& name, ImageSpec& newspec)
|
||||
// sanity checks - valid 4CC, correct struct sizes and flags which should
|
||||
// be always present, regardless of the image type, size etc., also check
|
||||
// for impossible flag combinations
|
||||
if (m_dds.fourCC != DDS_MAKE4CC('D', 'D', 'S', ' ') || m_dds.size != 124
|
||||
if (!validate_signature(m_dds.fourCC) || m_dds.size != 124
|
||||
|| m_dds.fmt.size != 32 || !(m_dds.caps.flags1 & DDS_CAPS1_TEXTURE)
|
||||
|| !(m_dds.flags & DDS_CAPS) || !(m_dds.flags & DDS_PIXELFORMAT)
|
||||
|| (m_dds.caps.flags2 & DDS_CAPS2_VOLUME
|
||||
|
||||
+98
-40
@@ -168,6 +168,8 @@ Z component of a normal map. This applies to images using DXT5 compression
|
||||
and images using BC5/ATI2 compression (normal X & Y components are in
|
||||
red & green channels).
|
||||
|
||||
**Attributes**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
:header-rows: 1
|
||||
@@ -215,27 +217,9 @@ When the attribute value is set to non-zero (default is zero), any input
|
||||
image using BC5/ATI2 compression format is assumed to be a normal map,
|
||||
even if pixel format "normal map" flag is not set.
|
||||
|
||||
|
||||
**Configuration settings for DDS output**
|
||||
|
||||
When opening an DDS ImageOutput, the following special metadata tokens
|
||||
control aspects of the writing itself:
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
:header-rows: 1
|
||||
|
||||
* - Output Configuration Attribute
|
||||
- Type
|
||||
- Meaning
|
||||
* - ``oiio:ioproxy``
|
||||
- ptr
|
||||
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
|
||||
example by writing to a memory buffer.
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
DDS supports the "custom I/O" feature via the
|
||||
DDS input supports the "custom I/O" feature via the
|
||||
special ``"oiio:ioproxy"`` attributes (see Sections
|
||||
:ref:`sec-imageoutput-ioproxy` and :ref:`sec-imageinput-ioproxy`) as well as
|
||||
the `set_ioproxy()` methods.
|
||||
@@ -326,15 +310,15 @@ control aspects of the writing itself:
|
||||
will keep unaltered pixel values (versus the default OIIO behavior
|
||||
of automatically converting from RGB to the designated color space
|
||||
as the pixels are written).
|
||||
* - ``oiio:ioproxy``
|
||||
- ptr
|
||||
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
|
||||
example by writing to memory rather than the file system.
|
||||
* - ``oiio:dither``
|
||||
- int
|
||||
- If nonzero and outputting UINT8 values in the file from a source of
|
||||
higher bit depth, will add a small amount of random dither to combat
|
||||
the appearance of banding.
|
||||
* - ``oiio:ioproxy``
|
||||
- ptr
|
||||
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
|
||||
example by writing to memory rather than the file system.
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
@@ -647,7 +631,7 @@ control aspects of the writing itself:
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
GIF supports the "custom I/O" feature via the
|
||||
GIF input and output support the "custom I/O" feature via the
|
||||
special ``"oiio:ioproxy"`` attributes (see Sections
|
||||
:ref:`sec-imageoutput-ioproxy` and :ref:`sec-imageinput-ioproxy`) as well as
|
||||
the `set_ioproxy()` methods.
|
||||
@@ -682,6 +666,7 @@ applications and to distribute HDR environment maps. But newer formats with
|
||||
native HDR support, such as OpenEXR, are vastly superior and should be
|
||||
preferred except when legacy file access is required.
|
||||
|
||||
**Attributes**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
@@ -695,7 +680,8 @@ preferred except when legacy file access is required.
|
||||
- encodes the orientation (see Section :ref:`sec-metadata-orientation`)
|
||||
* - ``oiio:ColorSpace``
|
||||
- string
|
||||
- Color space (see Section :ref:`sec-metadata-color`).
|
||||
- Color space (see Section :ref:`sec-metadata-color`). We currently
|
||||
assume that any RGBE files encountered are linear with sRGB primaries.
|
||||
* - ``oiio:Gamma``
|
||||
- float
|
||||
- the gamma correction specified in the RGBE header (if it's gamma corrected).
|
||||
@@ -738,7 +724,7 @@ control aspects of the writing itself:
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
HDR supports the "custom I/O" feature via the
|
||||
HDR input and output support the "custom I/O" feature via the
|
||||
special ``"oiio:ioproxy"`` attributes (see Sections
|
||||
:ref:`sec-imageoutput-ioproxy` and :ref:`sec-imageinput-ioproxy`) as well as
|
||||
the `set_ioproxy()` methods.
|
||||
@@ -884,6 +870,8 @@ IFF
|
||||
|
||||
IFF files are used by Autodesk Maya and use the file extension :file:`.iff`.
|
||||
|
||||
**Attributes**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
:header-rows: 1
|
||||
@@ -1062,7 +1050,7 @@ control aspects of the writing itself:
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
JPEG supports the "custom I/O" feature
|
||||
JPEG input and output support the "custom I/O" feature
|
||||
via the `ImageInput::set_ioproxy()` method and the special
|
||||
``"oiio:ioproxy"`` attributes (see Section :ref:`sec-imageinput-ioproxy`).
|
||||
|
||||
@@ -1478,6 +1466,8 @@ coordinate mapping. Layers may be scalar (1 channel) or vector (3 channel)
|
||||
fields, and the voxel data are always `float`. OpenVDB files always
|
||||
report as tiled, using the leaf dimension size.
|
||||
|
||||
**Attributes**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
:header-rows: 1
|
||||
@@ -1785,7 +1775,7 @@ Lab or duotone modes.
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
PSD supports the "custom I/O" feature via the special ``"oiio:ioproxy"``
|
||||
PSD output supports the "custom I/O" feature via the special ``"oiio:ioproxy"``
|
||||
attributes (see Sections :ref:`sec-imageoutput-ioproxy` and
|
||||
:ref:`sec-imageinput-ioproxy`) as well as the `set_ioproxy()` methods.
|
||||
|
||||
@@ -1806,6 +1796,7 @@ Ptex files, but the TextureSystem doesn't properly filter across face
|
||||
boundaries when using it as a texture. OpenImageIO currently does not write
|
||||
Ptex files at all.
|
||||
|
||||
**Attributes**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
@@ -2024,6 +2015,24 @@ software developed at Wavefront. RLA files commonly use the file extension
|
||||
- float
|
||||
- the gamma correction value (if specified).
|
||||
|
||||
**Configuration settings for RLA input**
|
||||
|
||||
When opening a RLA ImageInput with a *configuration* (see
|
||||
Section :ref:`sec-input-with-config`), the following special configuration
|
||||
options are supported:
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
:header-rows: 1
|
||||
|
||||
* - Input Configuration Attribute
|
||||
- Type
|
||||
- Meaning
|
||||
* - ``oiio:ioproxy``
|
||||
- ptr
|
||||
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
|
||||
example by reading from memory rather than the file system.
|
||||
|
||||
**Configuration settings for RLA output**
|
||||
|
||||
When opening a RLA ImageOutput, the following special metadata tokens
|
||||
@@ -2041,6 +2050,17 @@ control aspects of the writing itself:
|
||||
- If nonzero and outputting UINT8 values in the file from a source of
|
||||
higher bit depth, will add a small amount of random dither to combat
|
||||
the appearance of banding.
|
||||
* - ``oiio:ioproxy``
|
||||
- ptr
|
||||
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
|
||||
example by reading from memory rather than the file system.
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
RLA input and output support the "custom I/O" feature via the
|
||||
special ``"oiio:ioproxy"`` attributes (see Sections
|
||||
:ref:`sec-imageoutput-ioproxy` and :ref:`sec-imageinput-ioproxy`) as well as
|
||||
the `set_ioproxy()` methods.
|
||||
|
||||
**Limitations**
|
||||
|
||||
@@ -2081,6 +2101,24 @@ otherwise: no support for tiles, no MIPmaps, no multi-subimage, only 8- and
|
||||
- string
|
||||
- Image name.
|
||||
|
||||
**Configuration settings for SGI input**
|
||||
|
||||
When opening a SGI ImageInput with a *configuration* (see
|
||||
Section :ref:`sec-input-with-config`), the following special configuration
|
||||
options are supported:
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
:header-rows: 1
|
||||
|
||||
* - Input Configuration Attribute
|
||||
- Type
|
||||
- Meaning
|
||||
* - ``oiio:ioproxy``
|
||||
- ptr
|
||||
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
|
||||
example by reading from memory rather than the file system.
|
||||
|
||||
**Configuration settings for SGI output**
|
||||
|
||||
When opening an SGI ImageOutput, the following special metadata tokens
|
||||
@@ -2098,8 +2136,19 @@ control aspects of the writing itself:
|
||||
- If nonzero and outputting UINT8 values in the file from a source of
|
||||
higher bit depth, will add a small amount of random dither to combat
|
||||
the appearance of banding.
|
||||
* - ``oiio:ioproxy``
|
||||
- ptr
|
||||
- Pointer to a ``Filesystem::IOProxy`` that will handle the I/O, for
|
||||
example by reading from memory rather than the file system.
|
||||
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
SGI input and output support the "custom I/O" feature via the
|
||||
special ``"oiio:ioproxy"`` attributes (see Sections
|
||||
:ref:`sec-imageoutput-ioproxy` and :ref:`sec-imageinput-ioproxy`) as well as
|
||||
the `set_ioproxy()` methods.
|
||||
|
||||
|
|
||||
|
||||
.. _sec-bundledplugins-pic:
|
||||
@@ -2115,6 +2164,8 @@ The Softimage PIC format is sometimes used for legacy apps, but has little
|
||||
merit otherwise, so currently OpenImageIO only reads Softimage files and is
|
||||
unable to write them.
|
||||
|
||||
**Attributes**
|
||||
|
||||
.. list-table::
|
||||
:widths: 30 10 65
|
||||
:header-rows: 1
|
||||
@@ -2259,7 +2310,7 @@ control aspects of the writing itself:
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
DDS supports the "custom I/O" feature via the
|
||||
Targa input and output support the "custom I/O" feature via the
|
||||
special ``"oiio:ioproxy"`` attributes (see Sections
|
||||
:ref:`sec-imageoutput-ioproxy` and :ref:`sec-imageinput-ioproxy`) as well as
|
||||
the `set_ioproxy()` methods.
|
||||
@@ -2445,9 +2496,13 @@ aspects of the writing itself:
|
||||
TIFF files despite their being legal.
|
||||
* - ``tiff:ColorSpace``
|
||||
- string
|
||||
- Requests that the file be saved with a non-RGB color spaces. Choices
|
||||
are ``RGB``, ``CMYK``. (``YCbCr``, ``CIELAB``, ``ICCLAB``,
|
||||
``ITULAB`` are not yet supported.)
|
||||
- Requests that the RGB image be converted and saved in the TIFF file in
|
||||
a non-RGB color space. Choices are ``RGB``, ``CMYK``. (Note that
|
||||
``YCbCr``, ``CIELAB``, ``ICCLAB``, ``ITULAB`` are not yet supported
|
||||
for convertion. However, if the `oiio:ColorSpace` is one of those,
|
||||
meaning that the image data is presumed to already be in that
|
||||
space, the TIFF PhotometricInterpretation tag will be set to convey
|
||||
this information.)
|
||||
* - ``tiff:zipquality``
|
||||
- int
|
||||
- A time-vs-space knob for ``zip`` compression, ranging from 1-9
|
||||
@@ -2475,18 +2530,17 @@ aspects of the writing itself:
|
||||
**TIFF compression modes**
|
||||
|
||||
The full list of possible TIFF compression mode values are as
|
||||
follows ($ ^*$ indicates that OpenImageIO can write that format, and is not
|
||||
part of the format name):
|
||||
follows.
|
||||
|
||||
``none`` $ ^*$
|
||||
``lzw`` $ ^*$
|
||||
``zip`` $ ^*$
|
||||
``none`` :sup:`*`
|
||||
``lzw`` :sup:`*`
|
||||
``zip`` :sup:`*`
|
||||
``ccitt_t4``
|
||||
``ccitt_t6``
|
||||
``ccittfax3``
|
||||
``ccittfax4``
|
||||
``ccittrle2``
|
||||
``ccittrle`` $ ^*$
|
||||
``ccittrle`` :sup:`*`
|
||||
``dcs``
|
||||
``isojbig``
|
||||
``IT8BL``
|
||||
@@ -2494,11 +2548,11 @@ part of the format name):
|
||||
``IT8LW``
|
||||
``IT8MP``
|
||||
``jp2000``
|
||||
``jpeg`` $ ^*$
|
||||
``jpeg`` :sup:`*`
|
||||
``lzma``
|
||||
``next``
|
||||
``ojpeg``
|
||||
``packbits`` $ ^*$
|
||||
``packbits`` :sup:`*`
|
||||
``pixarfilm``
|
||||
``pixarlog``
|
||||
``sgilog24``
|
||||
@@ -2507,6 +2561,10 @@ part of the format name):
|
||||
``T85``
|
||||
``thunderscan``
|
||||
|
||||
:sup:`*` indicates that OpenImageIO can write that format, and is not
|
||||
part of the format name. The compression types without the asterisk are
|
||||
supported for reading but not for writing.
|
||||
|
||||
**Custom I/O Overrides**
|
||||
|
||||
TIFF input and output support the "custom I/O" feature
|
||||
|
||||
@@ -286,6 +286,13 @@ just exist in the OIIO namespace as general utilities. (See
|
||||
|
||||
.. doxygenfunction:: get_extension_map
|
||||
|
||||
.. _sec-startupshutdown:
|
||||
|
||||
Startup and Shutdown
|
||||
==========================================
|
||||
|
||||
.. doxygenfunction:: shutdown
|
||||
|
||||
|
|
||||
|
||||
|
||||
|
||||
+46
-75
@@ -18,42 +18,19 @@ to a file:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: c++
|
||||
.. tab:: C++
|
||||
.. literalinclude:: ../../testsuite/docs-examples-cpp/src/docs-examples-imageoutput.cpp
|
||||
:language: c++
|
||||
:start-after: BEGIN-imageoutput-simple
|
||||
:end-before: END-imageoutput-simple
|
||||
|
||||
#include <OpenImageIO/imageio.h>
|
||||
using namespace OIIO;
|
||||
...
|
||||
.. tab:: Python
|
||||
|
||||
const char *filename = "foo.jpg";
|
||||
const int xres = 640, yres = 480;
|
||||
const int channels = 3; // RGB
|
||||
unsigned char pixels[xres * yres * channels];
|
||||
.. literalinclude:: ../../testsuite/docs-examples-python/src/docs-examples-imageoutput.py
|
||||
:language: py
|
||||
:start-after: BEGIN-imageoutput-simple
|
||||
:end-before: END-imageoutput-simple
|
||||
|
||||
std::unique_ptr<ImageOutput> out = ImageOutput::create (filename);
|
||||
if (! out)
|
||||
return;
|
||||
ImageSpec spec (xres, yres, channels, TypeDesc::UINT8);
|
||||
out->open (filename, spec);
|
||||
out->write_image (TypeDesc::UINT8, pixels);
|
||||
out->close ();
|
||||
|
||||
.. code-tab:: py
|
||||
|
||||
import OpenImageIO as oiio
|
||||
import numpy as np
|
||||
|
||||
filename = "foo.jpg"
|
||||
xres = 640
|
||||
yres = 480
|
||||
channels = 3 # RGB
|
||||
pixels = np.zeros((yres, xres, channels), dtype=np.uint8)
|
||||
|
||||
out = oiio.ImageOutput.create (filename)
|
||||
if out:
|
||||
spec = oiio.ImageSpec(xres, yres, channels, 'uint8')
|
||||
out.open (filename, spec)
|
||||
out.write_image (pixels)
|
||||
out.close ()
|
||||
|
||||
This little bit of code does a surprising amount of useful work:
|
||||
|
||||
@@ -73,7 +50,7 @@ This little bit of code does a surprising amount of useful work:
|
||||
out = ImageOutput.create (filename)
|
||||
|
||||
* Open the file, write the correct headers, and in all other important ways
|
||||
prepare a file with the given dimensions (640 x 480), number of color
|
||||
prepare a file with the given dimensions (320 x 240), number of color
|
||||
channels (3), and data format (unsigned 8-bit integer).
|
||||
|
||||
.. tabs::
|
||||
@@ -172,33 +149,26 @@ time, one tile at a time, or by individual rectangles.
|
||||
Writing individual scanlines
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Individual scanlines may be written using the ``writescanline()`` API call:
|
||||
Individual scanlines may be written using the ``write_scanline()`` API call:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: c++
|
||||
.. tab:: C++
|
||||
.. literalinclude:: ../../testsuite/docs-examples-cpp/src/docs-examples-imageoutput.cpp
|
||||
:language: c++
|
||||
:start-after: BEGIN-imageoutput-scanlines
|
||||
:end-before: END-imageoutput-scanlines
|
||||
:dedent: 4
|
||||
|
||||
unsigned char scanline[xres*channels];
|
||||
out->open (filename, spec);
|
||||
int z = 0; // Always zero for 2D images
|
||||
for (int y = 0; y < yres; ++y) {
|
||||
... generate data in scanline[0..xres*channels-1] ...
|
||||
out->write_scanline (y, z, TypeDesc::UINT8, scanline);
|
||||
}
|
||||
out->close ();
|
||||
.. tab:: Python
|
||||
|
||||
.. code-tab:: py
|
||||
.. literalinclude:: ../../testsuite/docs-examples-python/src/docs-examples-imageoutput.py
|
||||
:language: py
|
||||
:start-after: BEGIN-imageoutput-scanlines
|
||||
:end-before: END-imageoutput-scanlines
|
||||
:dedent: 8
|
||||
|
||||
out.open (filename, spec)
|
||||
z = 0 # Always zero for 2D images
|
||||
for y in range(yres) :
|
||||
# generate data in scanline[0..xres*channels-1] ...
|
||||
scanline = ...
|
||||
out.write_scanline (y, z, scanline)
|
||||
}
|
||||
out.close ()
|
||||
|
||||
The first two arguments to ``writescanline()`` specify which scanline is
|
||||
The first two arguments to ``write_scanline()`` specify which scanline is
|
||||
being written by its vertical (*y*) scanline number (beginning with 0)
|
||||
and, for volume images, its slice (*z*) number (the slice number should
|
||||
be 0 for 2D non-volume images). This is followed by a `TypeDesc`
|
||||
@@ -212,7 +182,7 @@ All ``ImageOutput`` implementations will accept scanlines in strict order
|
||||
any). See Section :ref:`sec-imageoutput-random-access-pixels` for details
|
||||
on out-of-order or repeated scanlines.
|
||||
|
||||
The full description of the ``writescanline()`` function may be found
|
||||
The full description of the ``write_scanline()`` function may be found
|
||||
in Section :ref:`sec-imageoutput-class-reference`.
|
||||
|
||||
Writing individual tiles
|
||||
@@ -220,7 +190,7 @@ Writing individual tiles
|
||||
|
||||
Not all image formats (and therefore not all ``ImageOutput``
|
||||
implementations) support tiled images. If the format does not support
|
||||
tiles, then ``writetile()`` will fail. An application using OpenImageIO
|
||||
tiles, then ``write_tile()`` will fail. An application using OpenImageIO
|
||||
should gracefully handle the case that tiled output is not available for
|
||||
the chosen format.
|
||||
|
||||
@@ -297,7 +267,7 @@ individual plugin.
|
||||
out.write_tile (x, y, z, tile)
|
||||
out.close ()
|
||||
|
||||
The first three arguments to ``writetile()`` specify which tile is being
|
||||
The first three arguments to ``write_tile()`` specify which tile is being
|
||||
written by the pixel coordinates of any pixel contained in the tile: *x*
|
||||
(column), *y* (scanline), and *z* (slice, which should always be 0 for 2D
|
||||
non-volume images). This is followed by a `TypeDesc` describing the data
|
||||
@@ -311,7 +281,7 @@ All ``ImageOutput`` implementations that support tiles will accept tiles in
|
||||
strict order of increasing *y* rows, and within each row, increasing *x*
|
||||
column, without missing any tiles. See
|
||||
|
||||
The full description of the ``writetile()`` function may be found
|
||||
The full description of the ``write_tile()`` function may be found
|
||||
in Section :ref:`sec-imageoutput-class-reference`.
|
||||
|
||||
Writing arbitrary rectangles
|
||||
@@ -451,15 +421,15 @@ do not attempt to remap values, and do not clamp (except to their full
|
||||
floating-point range).
|
||||
|
||||
|
||||
It is not required that the pixel data passed to ``writeimage()``,
|
||||
``writescanline()``, ``writetile()``, or ``write_rectangle()`` actually be
|
||||
It is not required that the pixel data passed to ``write_image()``,
|
||||
``write_scanline()``, ``write_tile()``, or ``write_rectangle()`` actually be
|
||||
in the same data type as that requested as the native pixel data type of the
|
||||
file. You can fully mix and match data you pass to the various "write"
|
||||
routines and OpenImageIO will automatically convert from the internal format
|
||||
to the native file format. For example, the following code will open a TIFF
|
||||
file that stores pixel data as 16-bit unsigned integers (values ranging from
|
||||
0 to 65535), compute internal pixel values as floating-point values, with
|
||||
``writeimage()`` performing the conversion automatically:
|
||||
``write_image()`` performing the conversion automatically:
|
||||
|
||||
.. tabs::
|
||||
|
||||
@@ -484,7 +454,7 @@ file that stores pixel data as 16-bit unsigned integers (values ranging from
|
||||
out.write_image (pixels)
|
||||
|
||||
|
||||
Note that ``writescanline()``, ``writetile()``, and ``write_rectangle()``
|
||||
Note that ``write_scanline()``, ``write_tile()``, and ``write_rectangle()``
|
||||
have a parameter that works in a corresponding manner.
|
||||
|
||||
|
||||
@@ -507,13 +477,13 @@ passed to the "write" functions are *contiguous*, that is:
|
||||
* for 3D volumetric images, the first pixel of slice *z* immediately
|
||||
follows the last pixel of of slice ``z-1``.
|
||||
|
||||
Please note that this implies that data passed to ``writetile()`` be
|
||||
Please note that this implies that data passed to ``write_tile()`` be
|
||||
contiguous in the shape of a single tile (not just an offset into a whole
|
||||
image worth of pixels), and that data passed to ``write_rectangle()`` be
|
||||
contiguous in the dimensions of the rectangle.
|
||||
|
||||
The ``writescanline()`` function takes an optional ``xstride`` argument, and
|
||||
the ``writeimage()``, ``writetile()``, and ``write_rectangle()`` functions
|
||||
The ``write_scanline()`` function takes an optional ``xstride`` argument, and
|
||||
the ``write_image()``, ``write_tile()``, and ``write_rectangle()`` functions
|
||||
take optional ``xstride``, ``ystride``, and ``zstride`` values that describe
|
||||
the distance, in *bytes*, between successive pixel columns, rows, and
|
||||
slices, respectively, of the data you are passing. For any of these values
|
||||
@@ -910,25 +880,26 @@ The color space hints only describe color channels. You should always pass
|
||||
alpha, depth, or other non-color channels with linear values.
|
||||
|
||||
Here is a simple example of setting up the ``ImageSpec`` when you know that
|
||||
the pixel values you are writing are linear:
|
||||
the pixel values you are writing are in your default linear scene-referred
|
||||
color space:
|
||||
|
||||
.. tabs::
|
||||
|
||||
.. code-tab:: c++
|
||||
|
||||
ImageSpec spec (width, length, channels, format);
|
||||
spec.attribute ("oiio:ColorSpace", "Linear");
|
||||
spec.attribute ("oiio:ColorSpace", "scene_linear");
|
||||
|
||||
.. code-tab:: py
|
||||
|
||||
spec = ImageSpec(width, length, channels, format)
|
||||
spec.attribute ("oiio:ColorSpace", "Linear")
|
||||
spec.attribute ("oiio:ColorSpace", "scene_linear")
|
||||
|
||||
If a particular ``ImageOutput`` implementation is required (by the rules of
|
||||
the file format it writes) to have pixels in a particular color space,
|
||||
the file format it writes) to have pixels in a fixed color space,
|
||||
then it should try to convert the color values of your image to the right color
|
||||
space if it is not already in that space. For example, JPEG images
|
||||
must be in sRGB space, so if you declare your pixels to be ``"Linear"``,
|
||||
must be in sRGB space, so if you declare your pixels to be ``"scene_linear"``,
|
||||
the JPEG ``ImageOutput`` will convert to sRGB.
|
||||
|
||||
If you leave the ``"oiio:ColorSpace"`` unset, the values will not be
|
||||
@@ -1151,8 +1122,8 @@ specification of the subimages at the time you first open the file.
|
||||
out.write_image (pixels[s])
|
||||
out.close ()
|
||||
|
||||
In both of these examples, we have used ``writeimage()``, but of course
|
||||
``writescanline()``, ``writetile()``, and ``write_rectangle()`` work as you
|
||||
In both of these examples, we have used ``write_image()``, but of course
|
||||
``write_scanline()``, ``write_tile()``, and ``write_rectangle()`` work as you
|
||||
would expect, on the current subimage.
|
||||
|
||||
|
||||
@@ -1277,8 +1248,8 @@ used for texture mapping):
|
||||
out.close ()
|
||||
|
||||
|
||||
In this example, we have used ``writeimage()``, but of course
|
||||
``writescanline()``, ``writetile()``, and ``write_rectangle()`` work as you
|
||||
In this example, we have used ``write_image()``, but of course
|
||||
``write_scanline()``, ``write_tile()``, and ``write_rectangle()`` work as you
|
||||
would expect, on the current MIP level.
|
||||
|
||||
|
||||
|
||||
+155
-19
@@ -136,18 +136,23 @@ contents of an expression may be any of:
|
||||
`ImageDescription`, or `width`)
|
||||
* `filename` : the name of the file (e.g., `foo.tif`)
|
||||
* `file_extension` : the extension of the file (e.g., `tif`)
|
||||
* `geom` : the pixel data size in the form `640x480+0+0`)
|
||||
* `full_geom` : the "full" or "display" size)
|
||||
* `geom` : the pixel data size in the form `640x480+0+0`)
|
||||
* `nativeformat` : the pixel data type from the file.
|
||||
* `MINCOLOR` : the minimum value of each channel over the entire image
|
||||
(channels are comma-separated)
|
||||
* `MAXCOLOR` : the maximum value of each channel over the entire image
|
||||
(channels are comma-separated)
|
||||
* `AVGCOLOR` : the average pixel value of the image (channels are
|
||||
comma-separated)
|
||||
* `METABRIEF` : a string containing the brief one-line description that
|
||||
would be printed with `oiiotool -info`.
|
||||
* `META` : a multi-line string containing the full metadata that would
|
||||
be printed with `oiiotool -info -v`.
|
||||
* `META` : a multi-line string containing the full metadata of the image,
|
||||
similar to what would be printed with `oiiotool -info -v`.
|
||||
* `METABRIEF` : a string containing the brief one-line description,
|
||||
similar to what would be printed that with `oiiotool -info`.
|
||||
* `METANATIVE` : like `META`, but for the "native" original information from
|
||||
when the file was read from disk.
|
||||
* `METANATIVEBRIEF` : like `METABRIEF`, but for the "native" original
|
||||
information from when the file was read from disk.
|
||||
* `STATS` : a multi-line string containing the image statistics that would
|
||||
be printed with `oiiotool -stats`.
|
||||
|
||||
@@ -1068,6 +1073,30 @@ output each one to a different file, with names `sub0001.tif`,
|
||||
frame (rather than the default behavior of exiting immediately and not
|
||||
even attempting the other frames in the range).
|
||||
|
||||
.. option:: --parallel-frames
|
||||
|
||||
When iterating over a frame range or views, if this option is used, the
|
||||
frames will run *concurrently* and not necessarily in any deterministic
|
||||
order.
|
||||
|
||||
Running the range of frames in parallel is helpful in cases where (a)
|
||||
there are enough frames in the range to make it be better to parallelize
|
||||
over the range rather than within each operation (rule of thumb: you
|
||||
should probably have at least as many frames to process as cores
|
||||
available); (b) it doesn't matter what order the frames are processed in
|
||||
(e.g., no frames have a dependency on the computed results of earlier
|
||||
frames); and (c) you have enough memory and I/O bandwidth to handle all
|
||||
the parallel jobs (probably equal to the number of cores).
|
||||
|
||||
Without the `--parallel-frames` option, the frame range will be executed
|
||||
in increasing numerical order and each frame in the range will run to
|
||||
completion before the next one starts. Multithreading will be used for the
|
||||
individual operations done to each frame. This mode is less efficient if
|
||||
you have more frames than cores available, but it is guaranteed to be safe
|
||||
even if there are order or data dependencies between your frames, and it
|
||||
|
||||
This feature was added to OpenImageIO 2.5.1.
|
||||
|
||||
.. option:: --wildcardoff, --wildcardon
|
||||
|
||||
These *positional* options turn off (or on) numeric wildcard expansion
|
||||
@@ -1376,7 +1405,7 @@ Writing images
|
||||
|
||||
`:type=` *name*
|
||||
Set the pixel data type (like `-d`) for this output image (e.g.,
|
||||
`:uint8`, `uint16`, `half`, `float`, etc.).
|
||||
`uint8`, `uint16`, `half`, `float`, etc.).
|
||||
`:bits=` *int*
|
||||
Set the bits per pixel (if nonstandard for the datatype) for this
|
||||
output image.
|
||||
@@ -1666,11 +1695,40 @@ Writing images
|
||||
|
||||
.. option:: --printinfo
|
||||
|
||||
Prints information and all metadata about the current image.
|
||||
Prints information and all metadata about the current (top) image. This
|
||||
behavior is similar to invoking oiiotool with :option:`--info -v`, but it
|
||||
applies immediately to the current top image, even if it is a "computed"
|
||||
image (whereas :option:`--info` only applies to images as they are read
|
||||
from disk).
|
||||
|
||||
Optional appended modifiers include:
|
||||
|
||||
- `:allsubimages=` *int*
|
||||
If nonzero, stats will be printed about all subimages of the current
|
||||
image. (The default is given by whether or not the `-a` option was
|
||||
used.)
|
||||
|
||||
- `:native=1`
|
||||
Print metadata reflecting the "native" image as it was originally
|
||||
read from disk. This may have a data type, tile size, or other
|
||||
items that differ from the current in-memory representation of
|
||||
the image.
|
||||
|
||||
- `:stats=1`
|
||||
Print statistics about the image (much like the :option:`--stats`
|
||||
command).
|
||||
|
||||
- `:verbose=0`
|
||||
Overrides the default verbosity (1, on) with a less verbose output.
|
||||
|
||||
|
||||
.. option:: --printstats
|
||||
|
||||
Prints detailed statistical information about the current image.
|
||||
Prints detailed statistical information about the current image. This
|
||||
behavior is similar to invoking oiiotool with :option:`--stats`, but it
|
||||
applies immediately to the current top image, even if it is a "computed"
|
||||
image (whereas :option:`--stats` only applies to images as they are read
|
||||
from disk).
|
||||
|
||||
Optional appended modifiers include:
|
||||
|
||||
@@ -1686,8 +1744,8 @@ Writing images
|
||||
|
||||
- `:allsubimages=` *int*
|
||||
If nonzero, stats will be printed about all subimages of the current
|
||||
image. (The default is zero, meaning that stats will only be printed for
|
||||
the first subimage of the current image.)
|
||||
image. (The default is given by whether or not the `-a` option was
|
||||
used.)
|
||||
|
||||
.. option:: --colorcount r1,g1,b1,...:r2,g2,b2,...:...
|
||||
|
||||
@@ -2499,6 +2557,38 @@ current top image.
|
||||
Include/exclude subimages (see :ref:`sec-oiiotool-subimage-modifier`).
|
||||
|
||||
|
||||
.. option:: --normalize
|
||||
|
||||
Normalize the top image. Assuming the first three channels represent a 3D
|
||||
vector, divide each pixel by its length to make it unit length. This
|
||||
function assumes a 3-channel image that represents a 3-vector, or a
|
||||
4-channel image that represents a 3-vector plus an alpha value. If an
|
||||
alpha channel is present, its value is merely copied, and is not part of
|
||||
the normalization computation.
|
||||
|
||||
Optional appended modifiers include:
|
||||
|
||||
`:incenter=` *float*
|
||||
The pixel value that corresponds to a 0.0 vector value for the input.
|
||||
(default: 0.0)
|
||||
|
||||
`:outcenter=` *float*
|
||||
The pixel value that corresponds to a 0.0 vector value for the output.
|
||||
(default: 0.0)
|
||||
|
||||
`:scale=` *float*
|
||||
The desired length of the output vectors. (default: 1.0)
|
||||
|
||||
Example::
|
||||
|
||||
# Normalize a floating point image containing vector values:
|
||||
oiiotool xyzvectors.exr --normalize -o normalized.exr
|
||||
|
||||
# Normalize an unsigned integer image where [-1,1] vector values
|
||||
# are encoded on [0,1] for both input and output:
|
||||
oiiotool xyzvectors.tif --normalize:incenter=0.5:outcenter=0.5:scale=0.5 -o normalized.tif
|
||||
|
||||
|
||||
.. option:: --noise
|
||||
|
||||
Alter the top image to introduce noise, with the option `:type=`
|
||||
@@ -3140,11 +3230,29 @@ current top image.
|
||||
|
||||
*wscale% x hscale%*
|
||||
|
||||
if `width` or `height` is 0, that dimension will be
|
||||
automatically computed so as to preserve the original aspect ratio.
|
||||
If `width` or `height` is 0, that dimension will be automatically computed
|
||||
so as to preserve the original aspect ratio.
|
||||
|
||||
By default, the scaling that occurs is to map the *full/display* window
|
||||
area of the input image to the full/display window of the output image
|
||||
(determined by the `size` argument). However, a more general warping
|
||||
can be specified using any of the `:from=`, `:to=`, or `:offset=`
|
||||
optional modifiers. (These modifiers were added in OpenmageIO 2.5.)
|
||||
|
||||
Optional appended modifiers include:
|
||||
|
||||
`:from=` *size*
|
||||
The region (specified in any of the same forms as the *size* argument,
|
||||
with decimal / partial pixel sizes and offsets allowed) of the source
|
||||
image that defines the transformational mapping. This defaults to the
|
||||
full/display window of the source image.
|
||||
|
||||
`:to=` *size*
|
||||
The region (specified in any of the same forms as the *size* argument,
|
||||
with decimal / partial pixel sizes and offsets allowed) of the
|
||||
destination image that defines the transformational mapping. This
|
||||
defaults to the full/display window of the destination image.
|
||||
|
||||
`:filter=` *name*
|
||||
Filter name. The default is `blackman-harris` when increasing
|
||||
resolution, `lanczos3` when decreasing resolution.
|
||||
@@ -3155,6 +3263,11 @@ current top image.
|
||||
`--rangeexpand`, which can reduce visible ringing artifacts when a
|
||||
filter with negative lobes is used on a very high-contrast HDR image.
|
||||
|
||||
`:edgeclamp=` *bool*
|
||||
If nonzero, clamp the image to the edge pixels before filtering.
|
||||
This might help with certain edge ringing situations. The default is
|
||||
0 (off).
|
||||
|
||||
`:subimages=` *indices-or-names*
|
||||
Include/exclude subimages (see :ref:`sec-oiiotool-subimage-modifier`).
|
||||
|
||||
@@ -3165,6 +3278,15 @@ current top image.
|
||||
--resize 300% # increase resolution to 1920x1440
|
||||
--resize 400x0 # new resolution will be 400x300
|
||||
|
||||
# Create a 1024x768 image that is a resized and shifted version
|
||||
# of the original, where the upper left 100x100 section of the
|
||||
# original maps to a 200x200 region starting at the 50,50
|
||||
# coordinates of the new image.
|
||||
--resize:from=100x100:to=200x200+50+50 1024x768
|
||||
|
||||
# Resize to 320x240, but with an additional 1/2 pixel shift in
|
||||
# each direction.
|
||||
--resize:offset=+0.5+0.5 320x240
|
||||
|
||||
.. option:: --fit <size>
|
||||
|
||||
@@ -3976,7 +4098,23 @@ versa).
|
||||
|
||||
If you ask for :program:`oiiotool` help (`oiiotool --help`), at the very
|
||||
bottom you will see the list of all color spaces, looks, and displays that
|
||||
:program:`oiiotool` knows about.
|
||||
:program:`oiiotool` knows about. That information (including even more detail)
|
||||
will be printed with the command `oiiotool --colorconfiginfo`.
|
||||
|
||||
.. option:: --colorconfiginfo
|
||||
|
||||
Print to the console extensive information about the color management
|
||||
configuration, including the list of all known color spaces (and their
|
||||
aliases), looks, displays (and their views), as well as which version
|
||||
of OpenColorIO is being used, and the path to the configuration file.
|
||||
|
||||
This command was added in OIIO 2.4.6.
|
||||
|
||||
.. option:: --colorconfig <filename>
|
||||
|
||||
Instruct :program:`oiiotool` to read an OCIO configuration from a custom
|
||||
location. Without this, the default is to use the `$OCIO` environment
|
||||
variable as a guide for the location of the configuration file.
|
||||
|
||||
.. option:: --iscolorspace <colorspace>
|
||||
|
||||
@@ -3985,12 +4123,6 @@ bottom you will see the list of all color spaces, looks, and displays that
|
||||
it only changes :program:`oiiotool`'s understanding of what color space
|
||||
those those pixels are in.
|
||||
|
||||
.. option:: --colorconfig <filename>
|
||||
|
||||
Instruct :program:`oiiotool` to read an OCIO configuration from a custom
|
||||
location. Without this, the default is to use the `$OCIO` environment
|
||||
variable as a guide for the location of the configuration file.
|
||||
|
||||
.. option:: --colorconvert <fromspace> <tospace>
|
||||
|
||||
Replace the current image with a new image whose pixels are transformed
|
||||
@@ -4160,6 +4292,10 @@ bottom you will see the list of all color spaces, looks, and displays that
|
||||
is 0, meaning the color transformation not will be automatically
|
||||
bracketed by divide-by-alpha / mult-by-alpha operations.
|
||||
|
||||
`inverse=` *val* :
|
||||
|
||||
If *val* is nonzero, inverts the color transformation.
|
||||
|
||||
`:subimages=` *indices-or-names*
|
||||
Include/exclude subimages (see :ref:`sec-oiiotool-subimage-modifier`).
|
||||
|
||||
|
||||
@@ -3552,7 +3552,7 @@ Color manipulation
|
||||
.. code-block:: python
|
||||
|
||||
Src = ImageBuf ("tahoe.jpg")
|
||||
Dst = ImageBufAlgo.colorconvert (Src, "sRGB", "linear")
|
||||
Dst = ImageBufAlgo.colorconvert (Src, "sRGB", "scene_linear")
|
||||
|
||||
|
||||
|
||||
@@ -3592,8 +3592,8 @@ Color manipulation
|
||||
|
||||
|
||||
|
||||
.. py:method:: ImageBuf ImageBufAlgo.ociodisplay (src, display, view, fromspace="", looks="", unpremult=True, context_key="", context_value="", colorconfig="", roi=ROI.All, nthreads=0)
|
||||
bool ImageBufAlgo.ociodisplay (dst, src, display, view, fromspace="", looks="", unpremult=True, context_key="", context_value="", colorconfig="", roi=ROI.All, nthreads=0)
|
||||
.. py:method:: ImageBuf ImageBufAlgo.ociodisplay (src, display, view, fromspace="", looks="", unpremult=True, inverse=False, context_key="", context_value="", colorconfig="", roi=ROI.All, nthreads=0)
|
||||
bool ImageBufAlgo.ociodisplay (dst, src, display, view, fromspace="", looks="", unpremult=True, inverse=False, context_key="", context_value="", colorconfig="", roi=ROI.All, nthreads=0)
|
||||
|
||||
Apply an OpenColorIO "display" transform to the pixel values.
|
||||
|
||||
|
||||
+10
-4
@@ -141,12 +141,18 @@ Color information
|
||||
|
||||
The name of the color space of the color channels. Values include:
|
||||
|
||||
- `"Linear"` : Color pixel values are known to be scene-linear and
|
||||
using facility-default color primaries (presumed sRGB/Rec709 color
|
||||
primaries if otherwise unknown.
|
||||
- `"scene_linear"` : Color pixel values are known to be scene-linear and
|
||||
using facility-default color primaries as defined by the OpenColorIO
|
||||
configuration. Note that `"linear"` is treated as a synonym. (Note: when
|
||||
no color config is found, this are presumed to use sRGB/Rec709 color
|
||||
primaries when built against OpenColorIO 2.1 or earlier, or when no OCIO
|
||||
support is available, but is presumed to be ACEScg when built against
|
||||
OCIO 2.2 or higher and using its built-in config.)
|
||||
- `"lin_srgb"` : Color pixel values are known to be linear and
|
||||
using sRGB/Rec709 color primaries.
|
||||
- `"sRGB"` : Using standard sRGB response and primaries.
|
||||
- `"Rec709"` : Using standard Rec709 response and primaries.
|
||||
- `"ACES"` : ACES color space encoding.
|
||||
- `"ACEScg"` : ACEScg color space encoding.
|
||||
- `"AdobeRGB"` : Adobe RGB color space.
|
||||
- `"KodakLog"` : Kodak logarithmic color space.
|
||||
- `"GammaX.Y"` : Color values have been gamma corrected
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// But that seems not to be actively maintained.
|
||||
#include "libdpx/DPX.h"
|
||||
#include "libdpx/DPXColorConverter.h"
|
||||
#include "libdpx/DPXHeader.h"
|
||||
|
||||
#include <OpenImageIO/imageio.h>
|
||||
#include <OpenImageIO/strutil.h>
|
||||
@@ -29,7 +30,7 @@ public:
|
||||
{
|
||||
return (feature == "ioproxy");
|
||||
}
|
||||
bool valid_file(const std::string& filename) const override;
|
||||
bool valid_file(Filesystem::IOProxy* ioproxy) const override;
|
||||
bool open(const std::string& name, ImageSpec& newspec) override;
|
||||
bool open(const std::string& name, ImageSpec& newspec,
|
||||
const ImageSpec& config) override;
|
||||
@@ -107,21 +108,14 @@ OIIO_PLUGIN_EXPORTS_END
|
||||
|
||||
|
||||
bool
|
||||
DPXInput::valid_file(const std::string& filename) const
|
||||
DPXInput::valid_file(Filesystem::IOProxy* ioproxy) const
|
||||
{
|
||||
Filesystem::IOProxy* io
|
||||
= new Filesystem::IOFile(filename, Filesystem::IOProxy::Mode::Read);
|
||||
std::unique_ptr<Filesystem::IOProxy> io_uptr(io);
|
||||
if (!io || io->mode() != Filesystem::IOProxy::Mode::Read)
|
||||
if (!ioproxy || ioproxy->mode() != Filesystem::IOProxy::Mode::Read)
|
||||
return false;
|
||||
|
||||
std::unique_ptr<InStream> stream_uptr(new InStream(io));
|
||||
if (!stream_uptr)
|
||||
return false;
|
||||
|
||||
dpx::Reader dpx;
|
||||
dpx.SetInStream(stream_uptr.get());
|
||||
return dpx.ReadHeader(); // IOFile is automatically closed when destructed
|
||||
dpx::U32 magic {};
|
||||
const size_t numRead = ioproxy->pread(&magic, sizeof(magic), 0);
|
||||
return numRead == sizeof(magic) && dpx::Header::ValidMagicCookie(magic);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -142,8 +142,8 @@ bool
|
||||
DPXOutput::open(const std::string& name, int subimages, const ImageSpec* specs)
|
||||
{
|
||||
if (subimages > MAX_DPX_IMAGE_ELEMENTS) {
|
||||
errorf("DPX does not support more than %d subimages",
|
||||
MAX_DPX_IMAGE_ELEMENTS);
|
||||
errorfmt("DPX does not support more than {} subimages",
|
||||
MAX_DPX_IMAGE_ELEMENTS);
|
||||
return false;
|
||||
};
|
||||
m_subimages_to_write = subimages;
|
||||
@@ -158,14 +158,7 @@ bool
|
||||
DPXOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
OpenMode mode)
|
||||
{
|
||||
if (mode == Create) {
|
||||
m_subimage = 0;
|
||||
if (m_subimage_specs.size() < 1) {
|
||||
m_subimage_specs.resize(1);
|
||||
m_subimage_specs[0] = userspec;
|
||||
m_subimages_to_write = 1;
|
||||
}
|
||||
} else if (mode == AppendSubimage) {
|
||||
if (mode == AppendSubimage) {
|
||||
if (!is_opened()) {
|
||||
errorfmt("open() with AppendSubimage called but file is not open.");
|
||||
return false;
|
||||
@@ -174,28 +167,35 @@ DPXOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
write_buffer();
|
||||
++m_subimage;
|
||||
if (m_subimage >= m_subimages_to_write) {
|
||||
errorf("Exceeded the pre-declared number of subimages (%d)",
|
||||
m_subimages_to_write);
|
||||
errorfmt("Exceeded the pre-declared number of subimages ({})",
|
||||
m_subimages_to_write);
|
||||
return false;
|
||||
}
|
||||
return prep_subimage(m_subimage, true);
|
||||
// Nothing else to do, the header taken care of when we opened with
|
||||
// Create.
|
||||
} else if (mode == AppendMIPLevel) {
|
||||
errorf("DPX does not support MIP-maps");
|
||||
return false;
|
||||
}
|
||||
|
||||
// From here out, all the heavy lifting is done for Create
|
||||
OIIO_DASSERT(mode == Create);
|
||||
|
||||
if (is_opened())
|
||||
close(); // Close any already-opened file
|
||||
|
||||
ioproxy_retrieve_from_config(userspec);
|
||||
if (!check_open(mode, userspec, { 0, 1 << 20, 0, 1 << 20, 0, 1, 0, 256 }))
|
||||
return false;
|
||||
|
||||
// From here out, all the heavy lifting is done for Create
|
||||
OIIO_DASSERT(mode == Create);
|
||||
|
||||
ioproxy_retrieve_from_config(m_spec);
|
||||
if (!ioproxy_use_or_open(name))
|
||||
return false;
|
||||
|
||||
m_subimage = 0;
|
||||
if (m_subimage_specs.empty()) {
|
||||
m_subimage_specs.resize(1);
|
||||
m_subimage_specs[0] = m_spec;
|
||||
m_subimages_to_write = 1;
|
||||
}
|
||||
|
||||
m_stream = new OutStream(ioproxy());
|
||||
m_dpx.SetOutStream(m_stream);
|
||||
m_dpx.Start();
|
||||
@@ -203,20 +203,6 @@ DPXOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
|
||||
ImageSpec& spec0(m_subimage_specs[m_subimage]); // alias the spec
|
||||
|
||||
// Check for things this format doesn't support
|
||||
if (spec0.width < 1 || spec0.height < 1) {
|
||||
errorf("Image resolution must be at least 1x1, you asked for %d x %d",
|
||||
spec0.width, spec0.height);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (spec0.depth < 1)
|
||||
spec0.depth = 1;
|
||||
else if (spec0.depth > 1) {
|
||||
errorf("DPX does not support volume images (depth > 1)");
|
||||
return false;
|
||||
}
|
||||
|
||||
// some metadata
|
||||
std::string software = spec0.get_string_attribute("Software", "");
|
||||
std::string project = spec0.get_string_attribute("DocumentName", "");
|
||||
|
||||
@@ -44,8 +44,10 @@ public:
|
||||
int supports(string_view feature) const override
|
||||
{
|
||||
return (feature == "arbitrary_metadata"
|
||||
|| feature == "exif" // Because of arbitrary_metadata
|
||||
|| feature == "iptc"); // Because of arbitrary_metadata
|
||||
|| feature == "exif" // Because of arbitrary_metadata
|
||||
|| feature == "iptc" // Because of arbitrary_metadata
|
||||
|| feature == "noimage" // allow metadata only, no pixels
|
||||
);
|
||||
}
|
||||
bool valid_file(const std::string& filename) const override;
|
||||
bool open(const std::string& name, ImageSpec& spec) override;
|
||||
|
||||
@@ -31,7 +31,7 @@ FitsOutput::supports(string_view feature) const
|
||||
{
|
||||
return (feature == "multiimage" || feature == "alpha"
|
||||
|| feature == "nchannels" || feature == "random_access"
|
||||
|| feature == "arbitrary_metadata"
|
||||
|| feature == "noimage" || feature == "arbitrary_metadata"
|
||||
|| feature == "exif" // Because of arbitrary_metadata
|
||||
|| feature == "iptc"); // Because of arbitrary_metadata
|
||||
}
|
||||
@@ -41,14 +41,12 @@ FitsOutput::supports(string_view feature) const
|
||||
bool
|
||||
FitsOutput::open(const std::string& name, const ImageSpec& spec, OpenMode mode)
|
||||
{
|
||||
if (mode == AppendMIPLevel) {
|
||||
errorf("%s does not support MIP levels", format_name());
|
||||
close();
|
||||
if (!check_open(mode, spec, { 0, 1 << 30, 0, 1 << 30, 0, 1, 0, 1 << 10 }))
|
||||
return false;
|
||||
}
|
||||
|
||||
// saving 'name' and 'spec' for later use
|
||||
m_filename = name;
|
||||
m_spec = spec;
|
||||
|
||||
if (m_spec.format == TypeDesc::UNKNOWN) // if unknown, default to float
|
||||
m_spec.set_format(TypeDesc::FLOAT);
|
||||
// FITS only supports signed short and int pixels
|
||||
@@ -60,12 +58,7 @@ FitsOutput::open(const std::string& name, const ImageSpec& spec, OpenMode mode)
|
||||
// checking if the file exists and can be opened in WRITE mode
|
||||
m_fd = Filesystem::fopen(m_filename, mode == AppendSubimage ? "r+b" : "wb");
|
||||
if (!m_fd) {
|
||||
errorf("Could not open \"%s\"", m_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_spec.depth != 1) {
|
||||
errorf("Volume FITS files not supported");
|
||||
errorfmt("Could not open \"{}\"", m_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -92,7 +85,7 @@ FitsOutput::write_scanline(int y, int /*z*/, TypeDesc format, const void* data,
|
||||
if (m_spec.width == 0 && m_spec.height == 0)
|
||||
return true;
|
||||
if (y > m_spec.height) {
|
||||
errorf("Attempt to write too many scanlines to %s", m_filename);
|
||||
errorfmt("Attempt to write too many scanlines to {}", m_filename);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
@@ -224,7 +217,7 @@ FitsOutput::create_fits_header(void)
|
||||
size_t byte_count = fwrite(&header[0], 1, header.size(), m_fd);
|
||||
if (byte_count != header.size()) {
|
||||
// FIXME Bad Write
|
||||
errorf("Bad header write (err %d)", byte_count);
|
||||
errorfmt("Bad header write (err {})", byte_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
|
||||
if (GIF_FOUND)
|
||||
add_oiio_plugin (gifinput.cpp gifoutput.cpp
|
||||
INCLUDE_DIRS ${GIF_INCLUDE_DIRS}
|
||||
LINK_LIBRARIES ${GIF_LIBRARIES}
|
||||
LINK_LIBRARIES GIF::GIF
|
||||
DEFINITIONS "-DUSE_GIF")
|
||||
else()
|
||||
message (WARNING "GIF plugin will not be built")
|
||||
|
||||
@@ -97,7 +97,7 @@ private:
|
||||
ioproxy_clear();
|
||||
}
|
||||
|
||||
bool start_subimage();
|
||||
bool start_subimage(const ImageSpec& spec);
|
||||
bool finish_subimage();
|
||||
};
|
||||
|
||||
@@ -126,7 +126,7 @@ GIFOutput::open(const std::string& name, const ImageSpec& newspec,
|
||||
}
|
||||
|
||||
if (mode == AppendMIPLevel) {
|
||||
errorf("%s does not support MIP levels", format_name());
|
||||
errorfmt("{} does not support MIP levels", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -134,8 +134,7 @@ GIFOutput::open(const std::string& name, const ImageSpec& newspec,
|
||||
if (m_pending_write)
|
||||
finish_subimage();
|
||||
++m_subimage;
|
||||
m_spec = newspec;
|
||||
return start_subimage();
|
||||
return start_subimage(newspec);
|
||||
}
|
||||
|
||||
OIIO_ASSERT_MSG(0, "Unknown open mode %d", int(mode));
|
||||
@@ -148,7 +147,7 @@ bool
|
||||
GIFOutput::open(const std::string& name, int subimages, const ImageSpec* specs)
|
||||
{
|
||||
if (subimages < 1) {
|
||||
errorf("%s does not support %d subimages.", format_name(), subimages);
|
||||
errorfmt("{} does not support {} subimages.", format_name(), subimages);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -156,7 +155,6 @@ GIFOutput::open(const std::string& name, int subimages, const ImageSpec* specs)
|
||||
m_subimage = 0;
|
||||
m_nsubimages = subimages;
|
||||
m_subimagespecs.assign(specs, specs + subimages);
|
||||
m_spec = specs[0];
|
||||
float fps = m_spec.get_float_attribute("FramesPerSecond", 1.0f);
|
||||
m_delay = (fps == 0.0f ? 0 : (int)(100.0f / fps));
|
||||
|
||||
@@ -164,7 +162,7 @@ GIFOutput::open(const std::string& name, int subimages, const ImageSpec* specs)
|
||||
if (!ioproxy_use_or_open(name))
|
||||
return false;
|
||||
|
||||
return start_subimage();
|
||||
return start_subimage(specs[0]);
|
||||
}
|
||||
|
||||
|
||||
@@ -184,25 +182,11 @@ GIFOutput::close()
|
||||
|
||||
|
||||
bool
|
||||
GIFOutput::start_subimage()
|
||||
GIFOutput::start_subimage(const ImageSpec& spec)
|
||||
{
|
||||
// Check for things this format doesn't support
|
||||
if (m_spec.width < 1 || m_spec.height < 1) {
|
||||
errorf("Image resolution must be at least 1x1, you asked for %d x %d",
|
||||
m_spec.width, m_spec.height);
|
||||
if (!check_open(Create, spec, { 0, 65535, 0, 65535, 0, 1, 0, 4 },
|
||||
uint64_t(OpenChecks::Disallow1or2Channel)))
|
||||
return false;
|
||||
}
|
||||
if (m_spec.depth < 1)
|
||||
m_spec.depth = 1;
|
||||
if (m_spec.depth > 1) {
|
||||
errorf("%s does not support volume images (depth > 1)", format_name());
|
||||
return false;
|
||||
}
|
||||
if (m_spec.nchannels != 3 && m_spec.nchannels != 4) {
|
||||
errorf("%s does not support %d-channel images", format_name(),
|
||||
m_spec.nchannels);
|
||||
return false;
|
||||
}
|
||||
|
||||
m_spec.set_format(TypeDesc::UINT8); // GIF is only 8 bit
|
||||
|
||||
@@ -212,7 +196,7 @@ GIFOutput::start_subimage()
|
||||
m_spec.height, m_delay, 8 /*bit depth*/,
|
||||
true /*dither*/);
|
||||
if (!ok) {
|
||||
errorf("Could not open \"%s\"", m_filename);
|
||||
errorfmt("Could not open \"{}\"", m_filename);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,6 +41,7 @@ public:
|
||||
{
|
||||
return feature == "ioproxy";
|
||||
}
|
||||
bool valid_file(Filesystem::IOProxy* ioproxy) const override;
|
||||
bool open(const std::string& name, ImageSpec& spec) override;
|
||||
bool open(const std::string& name, ImageSpec& newspec,
|
||||
const ImageSpec& config) override;
|
||||
@@ -202,6 +203,19 @@ rgbe2float(float& red, float& green, float& blue, unsigned char rgbe[4])
|
||||
|
||||
|
||||
|
||||
bool
|
||||
HdrInput::valid_file(Filesystem::IOProxy* ioproxy) const
|
||||
{
|
||||
if (!ioproxy || ioproxy->mode() != Filesystem::IOProxy::Mode::Read)
|
||||
return false;
|
||||
|
||||
char magic[2] {};
|
||||
const size_t numRead = ioproxy->pread(magic, sizeof(magic), 0);
|
||||
return numRead == sizeof(magic) && memcmp(magic, "#?", sizeof(magic)) == 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
HdrInput::open(const std::string& name, ImageSpec& newspec,
|
||||
const ImageSpec& config)
|
||||
@@ -277,7 +291,10 @@ HdrInput::RGBE_ReadHeader()
|
||||
if (!line.size())
|
||||
return false;
|
||||
|
||||
m_spec.attribute("oiio:ColorSpace", "linear"); // presume linear
|
||||
m_spec.attribute("oiio:ColorSpace", "lin_srgb");
|
||||
// presume linear w/ srgb primaries -- seems like the safest assumption
|
||||
// for this old file format.
|
||||
|
||||
bool found_FORMAT_line = false;
|
||||
for (int nlines = 0; nlines < 100 /* safety */; ++nlines) {
|
||||
if (line.size() == 0 || line[0] == '\n') // stop at blank line
|
||||
@@ -493,11 +510,6 @@ HdrInput::read_native_scanline(int subimage, int miplevel, int y, int /*z*/,
|
||||
bool
|
||||
HdrInput::close()
|
||||
{
|
||||
// if (m_io_local) {
|
||||
// // If we allocated our own ioproxy, close it.
|
||||
// ioproxy_clear();
|
||||
// }
|
||||
|
||||
init(); // Reset to initial state
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -204,33 +204,11 @@ bool
|
||||
HdrOutput::open(const std::string& name, const ImageSpec& newspec,
|
||||
OpenMode mode)
|
||||
{
|
||||
if (mode != Create) {
|
||||
errorf("%s does not support subimages or MIP levels", format_name());
|
||||
if (!check_open(mode, newspec, { 0, 1 << 20, 0, 1 << 20, 0, 1, 0, 3 },
|
||||
uint64_t(OpenChecks::Disallow1or2Channel)))
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save spec for later use
|
||||
m_spec = newspec;
|
||||
// HDR always behaves like floating point
|
||||
m_spec.set_format(TypeDesc::FLOAT);
|
||||
|
||||
// Check for things HDR can't support
|
||||
if (m_spec.nchannels != 3) {
|
||||
errorf("HDR can only support 3-channel images");
|
||||
return false;
|
||||
}
|
||||
if (m_spec.width < 1 || m_spec.height < 1) {
|
||||
errorf("Image resolution must be at least 1x1, you asked for %d x %d",
|
||||
m_spec.width, m_spec.height);
|
||||
return false;
|
||||
}
|
||||
if (m_spec.depth < 1)
|
||||
m_spec.depth = 1;
|
||||
if (m_spec.depth > 1) {
|
||||
errorf("%s does not support volume images (depth > 1)", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_spec.set_format(TypeDesc::FLOAT); // Native rgbe is float32 only
|
||||
|
||||
ioproxy_retrieve_from_config(m_spec);
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
const char* format_name(void) const override { return "heif"; }
|
||||
int supports(string_view feature) const override
|
||||
{
|
||||
return feature == "alpha" || feature == "exif";
|
||||
return feature == "alpha" || feature == "exif" || feature == "tiles";
|
||||
}
|
||||
bool open(const std::string& name, const ImageSpec& spec,
|
||||
OpenMode mode) override;
|
||||
@@ -95,34 +95,11 @@ bool
|
||||
HeifOutput::open(const std::string& name, const ImageSpec& newspec,
|
||||
OpenMode mode)
|
||||
{
|
||||
if (mode != Create) {
|
||||
errorf("%s does not support subimages or MIP levels", format_name());
|
||||
if (!check_open(mode, newspec, { 0, 1 << 20, 0, 1 << 20, 0, 1, 0, 4 },
|
||||
uint64_t(OpenChecks::Disallow2Channel)))
|
||||
return false;
|
||||
}
|
||||
|
||||
m_filename = name;
|
||||
// Save spec for later used
|
||||
m_spec = newspec;
|
||||
// heif always behaves like floating point
|
||||
m_spec.set_format(TypeDesc::FLOAT);
|
||||
|
||||
// Check for things heif can't support
|
||||
if (m_spec.nchannels != 1 && m_spec.nchannels != 3
|
||||
&& m_spec.nchannels != 4) {
|
||||
errorf("heif can only support 1-, 3- or 4-channel images");
|
||||
return false;
|
||||
}
|
||||
if (m_spec.width < 1 || m_spec.height < 1) {
|
||||
errorf("Image resolution must be at least 1x1, you asked for %d x %d",
|
||||
m_spec.width, m_spec.height);
|
||||
return false;
|
||||
}
|
||||
if (m_spec.depth < 1)
|
||||
m_spec.depth = 1;
|
||||
if (m_spec.depth > 1) {
|
||||
errorf("%s does not support volume images (depth > 1)", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_spec.set_format(TypeUInt8); // Only uint8 for now
|
||||
|
||||
@@ -149,11 +126,11 @@ HeifOutput::open(const std::string& name, const ImageSpec& newspec,
|
||||
#endif
|
||||
} catch (const heif::Error& err) {
|
||||
std::string e = err.get_message();
|
||||
errorf("%s", e.empty() ? "unknown exception" : e.c_str());
|
||||
errorfmt("{}", e.empty() ? "unknown exception" : e.c_str());
|
||||
return false;
|
||||
} catch (const std::exception& err) {
|
||||
std::string e = err.what();
|
||||
errorf("%s", e.empty() ? "unknown exception" : e.c_str());
|
||||
errorfmt("{}", e.empty() ? "unknown exception" : e.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -231,13 +208,13 @@ HeifOutput::close()
|
||||
} catch (const heif::Error& err) {
|
||||
#ifdef DEBUG
|
||||
std::string e = err.get_message();
|
||||
Strutil::printf("%s", e.empty() ? "unknown exception" : e.c_str());
|
||||
Strutil::print("{}", e.empty() ? "unknown exception" : e.c_str());
|
||||
#endif
|
||||
}
|
||||
m_ctx->set_primary_image(m_ihandle);
|
||||
Filesystem::IOFile ioproxy(m_filename, Filesystem::IOProxy::Write);
|
||||
if (ioproxy.mode() != Filesystem::IOProxy::Write) {
|
||||
errorf("Could not open \"%s\"", m_filename);
|
||||
errorfmt("Could not open \"{}\"", m_filename);
|
||||
ok = false;
|
||||
} else {
|
||||
MyHeifWriter writer(&ioproxy);
|
||||
@@ -245,11 +222,11 @@ HeifOutput::close()
|
||||
}
|
||||
} catch (const heif::Error& err) {
|
||||
std::string e = err.get_message();
|
||||
errorf("%s", e.empty() ? "unknown exception" : e.c_str());
|
||||
errorfmt("{}", e.empty() ? "unknown exception" : e.c_str());
|
||||
return false;
|
||||
} catch (const std::exception& err) {
|
||||
std::string e = err.what();
|
||||
errorf("%s", e.empty() ? "unknown exception" : e.c_str());
|
||||
errorfmt("{}", e.empty() ? "unknown exception" : e.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -76,7 +76,7 @@ private:
|
||||
{
|
||||
size_t n = ::fwrite(buf, itemsize, nitems, m_file);
|
||||
if (n != nitems)
|
||||
errorf("Write error");
|
||||
errorfmt("Write error");
|
||||
return n == nitems;
|
||||
}
|
||||
|
||||
@@ -87,7 +87,7 @@ private:
|
||||
{
|
||||
size_t n = ::fread(buf, itemsize, nitems, m_file);
|
||||
if (n != nitems)
|
||||
errorf("Read error");
|
||||
errorfmt("Read error");
|
||||
return n == nitems;
|
||||
}
|
||||
};
|
||||
@@ -127,33 +127,14 @@ bool
|
||||
ICOOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
OpenMode mode)
|
||||
{
|
||||
if (mode == AppendMIPLevel) {
|
||||
errorf("%s does not support MIP levels", format_name());
|
||||
close(); // Close any already-opened file
|
||||
|
||||
if (!check_open(mode, userspec, { 0, 256, 0, 256, 0, 1, 0, 4 }))
|
||||
return false;
|
||||
}
|
||||
|
||||
close(); // Close any already-opened file
|
||||
m_spec = userspec; // Stash the spec
|
||||
if (m_spec.format == TypeDesc::UNKNOWN) // if unknown, default to 8 bits
|
||||
m_spec.set_format(TypeDesc::UINT8);
|
||||
|
||||
// Check for things this format doesn't support
|
||||
if (m_spec.width < 1 || m_spec.height < 1) {
|
||||
errorf("Image resolution must be at least 1x1, you asked for %d x %d",
|
||||
m_spec.width, m_spec.height);
|
||||
return false;
|
||||
} else if (m_spec.width > 256 || m_spec.height > 256) {
|
||||
errorf("Image resolution must be at most 256x256, you asked for %d x %d",
|
||||
m_spec.width, m_spec.height);
|
||||
return false;
|
||||
}
|
||||
if (m_spec.depth < 1)
|
||||
m_spec.depth = 1;
|
||||
if (m_spec.depth > 1) {
|
||||
errorf("%s does not support volume images (depth > 1)", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if the client wants this subimage written as PNG
|
||||
// also force PNG if image size is 256 because ico_header->width and height
|
||||
// are 8-bit
|
||||
@@ -165,7 +146,7 @@ ICOOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
std::string s = PNG_pvt::create_write_struct(m_png, m_info,
|
||||
m_color_type, m_spec);
|
||||
if (s.length()) {
|
||||
errorf("%s", s);
|
||||
errorfmt("{}", s);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
@@ -176,7 +157,8 @@ ICOOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
case 3: m_color_type = PNG_COLOR_TYPE_RGB; break;
|
||||
case 4: m_color_type = PNG_COLOR_TYPE_RGB_ALPHA; break;
|
||||
default:
|
||||
errorf("ICO only supports 1-4 channels, not %d", m_spec.nchannels);
|
||||
errorfmt("ICO only supports 1-4 channels, not {}",
|
||||
m_spec.nchannels);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -203,7 +185,7 @@ ICOOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
|
||||
m_file = Filesystem::fopen(name, mode == AppendSubimage ? "r+b" : "wb");
|
||||
if (!m_file) {
|
||||
errorf("Could not open \"%s\"", name);
|
||||
errorfmt("Could not open \"{}\"", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -236,7 +218,7 @@ ICOOutput::open(const std::string& name, const ImageSpec& userspec,
|
||||
<< ico.type << " count = " << ico.count << "\n";*/
|
||||
|
||||
if (ico.reserved != 0 || ico.type != 1) {
|
||||
errorf("File failed ICO header check");
|
||||
errorfmt("File failed ICO header check");
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -448,7 +430,7 @@ ICOOutput::write_scanline(int y, int z, TypeDesc format, const void* data,
|
||||
|
||||
if (m_want_png) {
|
||||
if (!PNG_pvt::write_row(m_png, (png_byte*)data)) {
|
||||
errorf("PNG library error");
|
||||
errorfmt("PNG library error");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
|
||||
+50
-46
@@ -6,7 +6,6 @@
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
#include <iostream>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -16,11 +15,12 @@
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
#include <OpenImageIO/imagecache.h>
|
||||
#include <OpenImageIO/imageio.h>
|
||||
#include <OpenImageIO/strutil.h>
|
||||
#include <OpenImageIO/sysutil.h>
|
||||
|
||||
|
||||
using namespace OIIO;
|
||||
|
||||
using OIIO::Strutil::print;
|
||||
|
||||
static std::string uninitialized = "uninitialized \001 HHRU dfvAS: efjl";
|
||||
static std::string dataformatname = "";
|
||||
@@ -97,13 +97,13 @@ getargs(int argc, char* argv[])
|
||||
"--sRGB", &sRGB, "This file is in sRGB color space",
|
||||
"--separate", &separate, "Force planarconfig separate",
|
||||
"--contig", &contig, "Force planarconfig contig",
|
||||
"--no-clobber", &noclobber, "Do no overwrite existing files",
|
||||
"--no-clobber", &noclobber, "Do not overwrite existing files",
|
||||
//FIXME "-z", &zfile, "Treat input as a depth file",
|
||||
//FIXME "-c %s", &channellist, "Restrict/shuffle channels",
|
||||
nullptr);
|
||||
// clang-format on
|
||||
if (ap.parse(argc, (const char**)argv) < 0) {
|
||||
std::cerr << ap.geterror() << std::endl;
|
||||
print(stderr, "{}\n", ap.geterror());
|
||||
ap.usage();
|
||||
ap.abort();
|
||||
return_code = EXIT_FAILURE;
|
||||
@@ -117,23 +117,25 @@ getargs(int argc, char* argv[])
|
||||
}
|
||||
|
||||
if (filenames.size() != 2 && !inplace) {
|
||||
std::cerr
|
||||
<< "iconvert: Must have both an input and output filename specified.\n";
|
||||
print(
|
||||
stderr,
|
||||
"iconvert: Must have both an input and output filename specified.\n");
|
||||
ap.usage();
|
||||
ap.abort();
|
||||
return_code = EXIT_FAILURE;
|
||||
return;
|
||||
}
|
||||
if (filenames.size() == 0 && inplace) {
|
||||
std::cerr << "iconvert: Must have at least one filename\n";
|
||||
print(stderr, "iconvert: Must have at least one filename\n");
|
||||
ap.usage();
|
||||
ap.abort();
|
||||
return_code = EXIT_FAILURE;
|
||||
return;
|
||||
}
|
||||
if (((int)rotcw + (int)rotccw + (int)rot180 + (orientation > 0)) > 1) {
|
||||
std::cerr
|
||||
<< "iconvert: more than one of --rotcw, --rotccw, --rot180, --orientation\n";
|
||||
print(
|
||||
stderr,
|
||||
"iconvert: more than one of --rotcw, --rotccw, --rot180, --orientation\n");
|
||||
ap.usage();
|
||||
ap.abort();
|
||||
return_code = EXIT_FAILURE;
|
||||
@@ -312,14 +314,15 @@ static bool
|
||||
convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
{
|
||||
if (noclobber && Filesystem::exists(out_filename)) {
|
||||
std::cerr << "iconvert ERROR: Output file already exists \""
|
||||
<< out_filename << "\"\n";
|
||||
print(stderr, "iconvert ERROR: Output file already exists \"{}\"\n",
|
||||
out_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (verbose)
|
||||
std::cout << "Converting " << in_filename << " to " << out_filename
|
||||
<< "\n";
|
||||
if (verbose) {
|
||||
print("Converting {} to {}\n", in_filename, out_filename);
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
std::string tempname = out_filename;
|
||||
if (tempname == in_filename) {
|
||||
@@ -330,11 +333,10 @@ convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
auto in = ImageInput::open(in_filename);
|
||||
if (!in) {
|
||||
std::string err = geterror();
|
||||
std::cerr << "iconvert ERROR: "
|
||||
<< (err.length() ? err
|
||||
: Strutil::sprintf("Could not open \"%s\"",
|
||||
in_filename))
|
||||
<< "\n";
|
||||
print(stderr, "iconvert ERROR: {}\n",
|
||||
(err.length() ? err
|
||||
: Strutil::fmt::format("Could not open \"{}\"",
|
||||
in_filename)));
|
||||
return false;
|
||||
}
|
||||
ImageSpec inspec = in->spec();
|
||||
@@ -343,9 +345,10 @@ convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
// Find an ImageIO plugin that can open the output file, and open it
|
||||
auto out = ImageOutput::create(tempname);
|
||||
if (!out) {
|
||||
std::cerr
|
||||
<< "iconvert ERROR: Could not find an ImageIO plugin to write \""
|
||||
<< out_filename << "\" : " << geterror() << "\n";
|
||||
print(
|
||||
stderr,
|
||||
"iconvert ERROR: Could not find an ImageIO plugin to write \"{}\": {}\n",
|
||||
out_filename, geterror());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -375,9 +378,10 @@ convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
for (int subimage = 0; ok && in->seek_subimage(subimage, 0, inspec);
|
||||
++subimage) {
|
||||
if (subimage > 0 && !out->supports("multiimage")) {
|
||||
std::cerr << "iconvert WARNING: " << out->format_name()
|
||||
<< " does not support multiple subimages.\n";
|
||||
std::cerr << "\tOnly the first subimage has been copied.\n";
|
||||
print(stderr,
|
||||
"iconvert WARNING: {} does not support multiple subimages.\n"
|
||||
"\tOnly the first subimage has been copied.\n",
|
||||
out->format_name());
|
||||
break; // we're done
|
||||
}
|
||||
|
||||
@@ -396,16 +400,17 @@ convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
mode = ImageOutput::AppendSubimage; // use if we must
|
||||
if (!mip_to_subimage_warning
|
||||
&& strcmp(out->format_name(), "tiff")) {
|
||||
std::cerr << "iconvert WARNING: " << out->format_name()
|
||||
<< " does not support MIPmaps.\n";
|
||||
std::cerr
|
||||
<< "\tStoring the MIPmap levels in subimages.\n";
|
||||
print(stderr,
|
||||
"iconvert WARNING: {} does not support MIPmaps.\n"
|
||||
"\tStoring the MIPmap levels in subimages.\n",
|
||||
out->format_name());
|
||||
}
|
||||
mip_to_subimage_warning = true;
|
||||
} else {
|
||||
std::cerr << "iconvert WARNING: " << out->format_name()
|
||||
<< " does not support MIPmaps.\n";
|
||||
std::cerr << "\tOnly the first level has been copied.\n";
|
||||
print(stderr,
|
||||
"iconvert WARNING: {} does not support MIPmaps.\n"
|
||||
"\tOnly the first level has been copied.\n",
|
||||
out->format_name());
|
||||
break; // on to the next subimage
|
||||
}
|
||||
ok = out->open(tempname.c_str(), outspec, mode);
|
||||
@@ -424,12 +429,11 @@ convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
}
|
||||
if (!ok) {
|
||||
std::string err = out->geterror();
|
||||
std::cerr << "iconvert ERROR: "
|
||||
<< (err.length()
|
||||
? err
|
||||
: Strutil::sprintf("Could not open \"%s\"",
|
||||
out_filename))
|
||||
<< "\n";
|
||||
print(stderr, "iconvert ERROR: {}\n",
|
||||
(err.length()
|
||||
? err
|
||||
: Strutil::fmt::format("Could not open \"{}\"",
|
||||
out_filename)));
|
||||
ok = false;
|
||||
break;
|
||||
}
|
||||
@@ -448,9 +452,9 @@ convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
if (!nocopy) {
|
||||
ok = out->copy_image(in.get());
|
||||
if (!ok)
|
||||
std::cerr << "iconvert ERROR copying \"" << in_filename
|
||||
<< "\" to \"" << out_filename << "\" :\n\t"
|
||||
<< out->geterror() << "\n";
|
||||
print(stderr,
|
||||
"iconvert ERROR copying \"{}\" to \"{}\" :\n\t{}\n",
|
||||
in_filename, out_filename, out->geterror());
|
||||
} else {
|
||||
// Need to do it by hand for some reason. Future expansion in which
|
||||
// only a subset of channels are copied, or some such.
|
||||
@@ -458,13 +462,13 @@ convert_file(const std::string& in_filename, const std::string& out_filename)
|
||||
ok = in->read_image(subimage, miplevel, 0, outspec.nchannels,
|
||||
outspec.format, &pixels[0]);
|
||||
if (!ok) {
|
||||
std::cerr << "iconvert ERROR reading \"" << in_filename
|
||||
<< "\" : " << in->geterror() << "\n";
|
||||
print(stderr, "iconvert ERROR reading \"{}\": {}\n",
|
||||
in_filename, in->geterror());
|
||||
} else {
|
||||
ok = out->write_image(outspec.format, &pixels[0]);
|
||||
if (!ok)
|
||||
std::cerr << "iconvert ERROR writing \"" << out_filename
|
||||
<< "\" : " << out->geterror() << "\n";
|
||||
print(stderr, "iconvert ERROR writing \"{}\": {}\n",
|
||||
out_filename, out->geterror());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -522,6 +526,6 @@ main(int argc, char* argv[])
|
||||
} else {
|
||||
ok = convert_file(filenames[0], filenames[1]);
|
||||
}
|
||||
|
||||
shutdown();
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -399,5 +399,6 @@ main(int argc, char* argv[])
|
||||
|
||||
imagecache->invalidate_all(true);
|
||||
ImageCache::destroy(imagecache);
|
||||
shutdown();
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -2,4 +2,9 @@
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
# https://github.com/OpenImageIO/oiio
|
||||
|
||||
add_oiio_plugin (iffinput.cpp iffoutput.cpp)
|
||||
option (ENABLE_RLA_IOPROXY "(Temporarily) turn this off to switch back to the old pre-IOProxy RLA implementation to address a bug." ON)
|
||||
if (ENABLE_RLA_IOPROXY)
|
||||
add_oiio_plugin (iffinput.cpp iffoutput.cpp)
|
||||
else ()
|
||||
add_oiio_plugin (noproxy-iffinput.cpp noproxy-iffoutput.cpp noproxy-iff_pvt.cpp)
|
||||
endif ()
|
||||
|
||||
@@ -87,6 +87,9 @@ private:
|
||||
return read_type_len(name, len) && read_str(val, len);
|
||||
}
|
||||
|
||||
// Read a 4-byte type code (no endian swap), and if that succeeds (beware
|
||||
// of EOF or other errors), then also read a 32 bit size (subject to
|
||||
// endian swap).
|
||||
bool read_typesize(uint8_t type[4], uint32_t& size)
|
||||
{
|
||||
return ioread(type, 1, 4) && read(&size);
|
||||
@@ -181,7 +184,7 @@ IffInput::open(const std::string& name, ImageSpec& spec)
|
||||
m_spec.full_height = m_iff_header.height;
|
||||
|
||||
// tiles
|
||||
if (m_iff_header.tile_width > 0 || m_iff_header.tile_height > 0) {
|
||||
if (m_iff_header.tile_width > 0 && m_iff_header.tile_height > 0) {
|
||||
m_spec.tile_width = m_iff_header.tile_width;
|
||||
m_spec.tile_height = m_iff_header.tile_height;
|
||||
// only 1 subimage for IFF
|
||||
|
||||
@@ -143,33 +143,24 @@ IffOutput::open(const std::string& name, const ImageSpec& spec, OpenMode mode)
|
||||
// RGBA <size> tile pixels
|
||||
// ...
|
||||
|
||||
if (mode != Create) {
|
||||
errorfmt("{} does not support subimages or MIP levels", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
// saving 'name' and 'spec' for later use
|
||||
m_filename = name;
|
||||
m_spec = spec;
|
||||
|
||||
// Maya docs say 8k is the limit
|
||||
if (m_spec.width < 1 || m_spec.width > 8192 || m_spec.height < 1
|
||||
|| m_spec.height > 8192) {
|
||||
errorfmt("Image resolution {} x {} is not valid for an IFF file",
|
||||
m_spec.width, m_spec.height);
|
||||
if (!check_open(mode, spec, { 0, 8192, 0, 8192, 0, 1, 0, 4 }))
|
||||
return false;
|
||||
}
|
||||
// Maya docs say 8k is the limit
|
||||
|
||||
// tiles always
|
||||
m_spec.tile_width = tile_width();
|
||||
m_spec.tile_height = tile_height();
|
||||
m_spec.tile_depth = 1;
|
||||
|
||||
// This implementation only supports writing RGB and RGBA images as IFF
|
||||
if (m_spec.nchannels < 3 || m_spec.nchannels > 4) {
|
||||
errorfmt("Cannot write IFF file with {} channels", m_spec.nchannels);
|
||||
return false;
|
||||
}
|
||||
|
||||
// tiles
|
||||
m_spec.tile_width = tile_width();
|
||||
m_spec.tile_height = tile_height();
|
||||
m_spec.tile_depth = 1;
|
||||
|
||||
uint64_t xtiles = tile_width_size(m_spec.width);
|
||||
uint64_t ytiles = tile_height_size(m_spec.height);
|
||||
if (xtiles * ytiles >= (1 << 16)) { // The format can't store it!
|
||||
|
||||
@@ -0,0 +1,332 @@
|
||||
// Copyright Contributors to the OpenImageIO project.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// https://github.com/OpenImageIO/oiio
|
||||
#include "noproxy-iff_pvt.h"
|
||||
#include <OpenImageIO/dassert.h>
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_BEGIN
|
||||
|
||||
using namespace iff_pvt;
|
||||
|
||||
#define STRINGIZE2(a) #a
|
||||
#define STRINGIZE(a) STRINGIZE2(a)
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffFileHeader::read_header(FILE* fd, std::string& err)
|
||||
{
|
||||
uint8_t type[4];
|
||||
uint32_t size;
|
||||
uint32_t chunksize;
|
||||
uint32_t tbhdsize;
|
||||
uint32_t flags;
|
||||
uint16_t bytes;
|
||||
uint16_t prnum;
|
||||
uint16_t prden;
|
||||
|
||||
// read FOR4 <size> CIMG.
|
||||
err.clear();
|
||||
for (;;) {
|
||||
// get type and length
|
||||
if (!read_typesize(fd, type, size)) {
|
||||
err = "could not read type/size @ L" STRINGIZE(__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
chunksize = align_size(size, 4);
|
||||
|
||||
if (type[0] == 'F' && type[1] == 'O' && type[2] == 'R'
|
||||
&& type[3] == '4') {
|
||||
// get type
|
||||
if (!fread(&type, 1, sizeof(type), fd)) {
|
||||
err = "could not read FDR4 type @ L" STRINGIZE(__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if CIMG
|
||||
if (type[0] == 'C' && type[1] == 'I' && type[2] == 'M'
|
||||
&& type[3] == 'G') {
|
||||
// read TBHD.
|
||||
for (;;) {
|
||||
if (!read_typesize(fd, type, size)) {
|
||||
err = "could not read CIMG length @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
chunksize = align_size(size, 4);
|
||||
|
||||
if (type[0] == 'T' && type[1] == 'B' && type[2] == 'H'
|
||||
&& type[3] == 'D') {
|
||||
tbhdsize = size;
|
||||
|
||||
// test if table header size is correct
|
||||
if (tbhdsize != 24 && tbhdsize != 32) {
|
||||
err = "bad table header @ L" STRINGIZE(__LINE__);
|
||||
return false; // bad table header
|
||||
}
|
||||
|
||||
// get width and height
|
||||
if (!read(fd, width) || !read(fd, height)
|
||||
|| !read(fd, prnum) || !read(fd, prden)
|
||||
|| !read(fd, flags) || !read(fd, bytes)
|
||||
|| !read(fd, tiles) || !read(fd, compression)) {
|
||||
err = "@ L" STRINGIZE(__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// get xy
|
||||
if (tbhdsize == 32) {
|
||||
if (!read(fd, x) || !read(fd, y)) {
|
||||
err = "could not get xy @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
x = 0;
|
||||
y = 0;
|
||||
}
|
||||
|
||||
// tiles
|
||||
if (tiles == 0) {
|
||||
err = "non-tiles not supported @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
} // non-tiles not supported
|
||||
|
||||
// 0 no compression
|
||||
// 1 RLE compression
|
||||
// 2 QRL (not supported)
|
||||
// 3 QR4 (not supported)
|
||||
if (compression > 1) {
|
||||
err = "only RLE compression is supported @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// test format.
|
||||
if (flags & RGBA) {
|
||||
// test if black is set
|
||||
OIIO_DASSERT(!(flags & BLACK));
|
||||
|
||||
// test for RGB channels.
|
||||
if (flags & RGB)
|
||||
pixel_channels = 3;
|
||||
|
||||
// test for alpha channel
|
||||
if (flags & ALPHA)
|
||||
pixel_channels++;
|
||||
|
||||
// test pixel bits
|
||||
pixel_bits = bytes ? 16 : 8;
|
||||
}
|
||||
|
||||
// Z format.
|
||||
else if (flags & ZBUFFER) {
|
||||
pixel_channels = 1;
|
||||
pixel_bits = 32; // 32bit
|
||||
// NOTE: Z_F32 support - not supported
|
||||
OIIO_DASSERT(bytes == 0);
|
||||
}
|
||||
|
||||
// read AUTH, DATE or FOR4
|
||||
|
||||
for (;;) {
|
||||
// get type
|
||||
if (!read_typesize(fd, type, size)) {
|
||||
err = "could not read type/size @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
chunksize = align_size(size, 4);
|
||||
|
||||
if (type[0] == 'A' && type[1] == 'U'
|
||||
&& type[2] == 'T' && type[3] == 'H') {
|
||||
std::vector<char> str(chunksize);
|
||||
if (!fread(&str[0], 1, chunksize, fd)) {
|
||||
err = "could not read author @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
author = std::string(&str[0], size);
|
||||
} else if (type[0] == 'D' && type[1] == 'A'
|
||||
&& type[2] == 'T' && type[3] == 'E') {
|
||||
std::vector<char> str(chunksize);
|
||||
if (!fread(&str[0], 1, chunksize, fd)) {
|
||||
err = "could not read date @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
date = std::string(&str[0], size);
|
||||
} else if (type[0] == 'F' && type[1] == 'O'
|
||||
&& type[2] == 'R' && type[3] == '4') {
|
||||
if (!fread(&type, 1, sizeof(type), fd)) {
|
||||
err = "could not read FOR4 type @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check if CIMG
|
||||
if (type[0] == 'T' && type[1] == 'B'
|
||||
&& type[2] == 'M' && type[3] == 'P') {
|
||||
// tbmp position for later user in in
|
||||
// read_native_tile
|
||||
|
||||
tbmp_start = ftell(fd);
|
||||
|
||||
// read first RGBA block to detect tile size.
|
||||
|
||||
for (unsigned int t = 0; t < tiles; t++) {
|
||||
if (!read_typesize(fd, type, size)) {
|
||||
err = "xxx @ L" STRINGIZE(__LINE__);
|
||||
return false;
|
||||
}
|
||||
chunksize = align_size(size, 4);
|
||||
|
||||
// check if RGBA
|
||||
if (type[0] == 'R' && type[1] == 'G'
|
||||
&& type[2] == 'B'
|
||||
&& type[3] == 'A') {
|
||||
// get tile coordinates.
|
||||
uint16_t xmin, xmax, ymin, ymax;
|
||||
if (!read(fd, xmin)
|
||||
|| !read(fd, ymin)
|
||||
|| !read(fd, xmax)
|
||||
|| !read(fd, ymax)) {
|
||||
err = "xxx @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check tile
|
||||
if (xmin > xmax || ymin > ymax
|
||||
|| xmax >= width
|
||||
|| ymax >= height) {
|
||||
err = "tile min/max nonsensical @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
// set tile width and height
|
||||
tile_width = xmax - xmin + 1;
|
||||
tile_height = ymax - ymin + 1;
|
||||
|
||||
// done, return
|
||||
return true;
|
||||
}
|
||||
|
||||
// skip to the next block.
|
||||
if (fseek(fd, chunksize, SEEK_CUR)) {
|
||||
err = "could not fseek @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// skip to the next block.
|
||||
if (fseek(fd, chunksize, SEEK_CUR)) {
|
||||
err = "could not fseek @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// skip to the next block.
|
||||
if (fseek(fd, chunksize, SEEK_CUR)) {
|
||||
err = "could not fseek @ L" STRINGIZE(
|
||||
__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
// TBHD done, break
|
||||
break;
|
||||
}
|
||||
|
||||
// skip to the next block.
|
||||
if (fseek(fd, chunksize, SEEK_CUR)) {
|
||||
err = "could not fseek @ L" STRINGIZE(__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// skip to the next block.
|
||||
if (fseek(fd, chunksize, SEEK_CUR)) {
|
||||
err = "could not fseek @ L" STRINGIZE(__LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
err = "unknown error, ended early @ L" STRINGIZE(__LINE__);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffOutput::write_header(IffFileHeader& header)
|
||||
{
|
||||
// write 'FOR4' type, with 0 length for now (to reserve it)
|
||||
if (!(write_str("FOR4") && write_int(0)))
|
||||
return false;
|
||||
|
||||
// write 'CIMG' type
|
||||
if (!write_str("CIMG"))
|
||||
return false;
|
||||
|
||||
// write 'TBHD' type
|
||||
if (!write_str("TBHD"))
|
||||
return false;
|
||||
|
||||
// 'TBHD' length, 32 bytes
|
||||
if (!write_int(32))
|
||||
return false;
|
||||
|
||||
if (!write_int(header.width) || !write_int(header.height))
|
||||
return false;
|
||||
|
||||
// write prnum and prden (pixel aspect ratio? -- FIXME)
|
||||
if (!write_short(1) || !write_short(1)) //NOSONAR
|
||||
return false;
|
||||
|
||||
// write flags and channels
|
||||
if (!write_int(header.pixel_channels == 3 ? RGB : RGBA)
|
||||
|| !write_short(header.pixel_bits == 8 ? 0 : 1)
|
||||
|| !write_short(header.tiles))
|
||||
return false;
|
||||
|
||||
// write compression
|
||||
// 0 no compression
|
||||
// 1 RLE compression
|
||||
// 2 QRL (not supported)
|
||||
// 3 QR4 (not supported)
|
||||
if (!write_int(header.compression))
|
||||
return false;
|
||||
|
||||
// write x and y
|
||||
if (!write_int(header.x) || !write_int(header.y))
|
||||
return false;
|
||||
|
||||
// Write metadata
|
||||
write_meta_string("AUTH", header.author);
|
||||
write_meta_string("DATE", header.date);
|
||||
|
||||
// for4 position for later user in close
|
||||
header.for4_start = ftell(m_fd);
|
||||
|
||||
// write 'FOR4' type, with 0 length to reserve it for now
|
||||
if (!write_str("FOR4") || !write_int(0))
|
||||
return false;
|
||||
|
||||
// write 'TBMP' type
|
||||
if (!write_str("TBMP"))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_END
|
||||
@@ -0,0 +1,303 @@
|
||||
// Copyright Contributors to the OpenImageIO project.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// https://github.com/OpenImageIO/oiio
|
||||
|
||||
#pragma once
|
||||
|
||||
// Format reference: Affine Toolkit (Thomas E. Burge), riff.h and riff.c
|
||||
// Autodesk Maya documentation, ilib.h
|
||||
|
||||
#include <cstdio>
|
||||
|
||||
#include <OpenImageIO/filesystem.h>
|
||||
#include <OpenImageIO/fmath.h>
|
||||
#include <OpenImageIO/imageio.h>
|
||||
|
||||
#include "imageio_pvt.h"
|
||||
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_BEGIN
|
||||
|
||||
namespace iff_pvt {
|
||||
|
||||
// compression numbers
|
||||
const uint32_t NONE = 0;
|
||||
const uint32_t RLE = 1;
|
||||
const uint32_t QRL = 2;
|
||||
const uint32_t QR4 = 3;
|
||||
|
||||
const uint32_t RGB = 0x00000001;
|
||||
const uint32_t ALPHA = 0x00000002;
|
||||
const uint32_t RGBA = RGB | ALPHA;
|
||||
const uint32_t ZBUFFER = 0x00000004;
|
||||
const uint32_t BLACK = 0x00000010;
|
||||
|
||||
// store information about IFF file
|
||||
class IffFileHeader {
|
||||
public:
|
||||
// reads information about IFF file
|
||||
bool read_header(FILE* fd, std::string& err);
|
||||
|
||||
// header information
|
||||
uint32_t x;
|
||||
uint32_t y;
|
||||
uint32_t width;
|
||||
uint32_t height;
|
||||
uint32_t compression;
|
||||
uint8_t pixel_bits;
|
||||
uint8_t pixel_channels;
|
||||
uint16_t tiles;
|
||||
uint16_t tile_width;
|
||||
uint16_t tile_height;
|
||||
|
||||
// author string
|
||||
std::string author;
|
||||
|
||||
// date string
|
||||
std::string date;
|
||||
|
||||
// tbmp start
|
||||
uint32_t tbmp_start;
|
||||
|
||||
// for4 start
|
||||
uint32_t for4_start;
|
||||
|
||||
private:
|
||||
// Read a uint32_t, swap endian if necessary
|
||||
bool read(FILE* fd, uint32_t& data)
|
||||
{
|
||||
bool ok = (fread(&data, 1, sizeof(data), fd) == sizeof(data));
|
||||
if (littleendian())
|
||||
swap_endian(&data);
|
||||
return ok;
|
||||
}
|
||||
// Read a uint16_t, swap endian if necessary
|
||||
bool read(FILE* fd, uint16_t& data)
|
||||
{
|
||||
bool ok = (fread(&data, 1, sizeof(data), fd) == sizeof(data));
|
||||
if (littleendian())
|
||||
swap_endian(&data);
|
||||
return ok;
|
||||
}
|
||||
// Read a 4-byte code (no endian swap), and if that succeeds (beware of EOF or
|
||||
// other errors), then also read a 32 bit size (subject to endian swap).
|
||||
bool read_typesize(FILE* fd, uint8_t type[4], uint32_t& size)
|
||||
{
|
||||
return (fread(type, 1, 4, fd) == 4) && read(fd, size);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
// align size
|
||||
inline uint32_t
|
||||
align_size(uint32_t size, uint32_t alignment)
|
||||
{
|
||||
uint32_t mod = size % alignment;
|
||||
if (mod) {
|
||||
mod = alignment - mod;
|
||||
size += mod;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
// tile width
|
||||
inline const int&
|
||||
tile_width()
|
||||
{
|
||||
static int tile_w = 64;
|
||||
return tile_w;
|
||||
}
|
||||
|
||||
// tile height
|
||||
inline const int&
|
||||
tile_height()
|
||||
{
|
||||
static int tile_h = 64;
|
||||
return tile_h;
|
||||
}
|
||||
|
||||
// tile width size
|
||||
inline uint32_t
|
||||
tile_width_size(uint32_t width)
|
||||
{
|
||||
uint32_t tw = tile_width();
|
||||
return (width + tw - 1) / tw;
|
||||
}
|
||||
|
||||
// tile height size
|
||||
inline uint32_t
|
||||
tile_height_size(uint32_t height)
|
||||
{
|
||||
uint32_t th = tile_height();
|
||||
return (height + th - 1) / th;
|
||||
}
|
||||
|
||||
} // namespace iff_pvt
|
||||
|
||||
|
||||
|
||||
class IffInput final : public ImageInput {
|
||||
public:
|
||||
IffInput() { init(); }
|
||||
~IffInput() override
|
||||
{
|
||||
try {
|
||||
close();
|
||||
} catch (const std::exception& e) {
|
||||
OIIO::pvt::errorfmt("{}", e.what());
|
||||
}
|
||||
}
|
||||
const char* format_name(void) const override { return "iff"; }
|
||||
bool open(const std::string& name, ImageSpec& spec) override;
|
||||
bool close(void) override;
|
||||
bool read_native_scanline(int subimage, int miplevel, int y, int z,
|
||||
void* data) override;
|
||||
bool read_native_tile(int subimage, int miplevel, int x, int y, int z,
|
||||
void* data) override;
|
||||
|
||||
private:
|
||||
FILE* m_fd;
|
||||
std::string m_filename;
|
||||
iff_pvt::IffFileHeader m_iff_header;
|
||||
std::vector<uint8_t> m_buf;
|
||||
|
||||
uint32_t m_tbmp_start;
|
||||
|
||||
// init to initialize state
|
||||
void init(void)
|
||||
{
|
||||
m_fd = NULL;
|
||||
m_filename.clear();
|
||||
m_buf.clear();
|
||||
}
|
||||
|
||||
// helper to read an image
|
||||
bool readimg(void);
|
||||
|
||||
// helper to uncompress a rle channel
|
||||
size_t uncompress_rle_channel(const uint8_t* in, uint8_t* out, int size);
|
||||
|
||||
bool read_short(uint16_t& val)
|
||||
{
|
||||
bool ok = fread(&val, sizeof(val), 1, m_fd);
|
||||
if (littleendian())
|
||||
swap_endian(&val);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool read_int(uint32_t& val)
|
||||
{
|
||||
bool ok = fread(&val, sizeof(val), 1, m_fd);
|
||||
if (littleendian())
|
||||
swap_endian(&val);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool read_str(std::string& val, uint32_t len, uint32_t round = 4)
|
||||
{
|
||||
const uint32_t big = 1024;
|
||||
char strbuf[big];
|
||||
len = std::min(len, big);
|
||||
bool ok = fread(strbuf, len, 1, m_fd);
|
||||
val.assign(strbuf, len);
|
||||
for (uint32_t pad = len % round; pad; --pad)
|
||||
fgetc(m_fd);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool read_type_len(std::string& type, uint32_t& len)
|
||||
{
|
||||
return read_str(type, 4) && read_int(len);
|
||||
}
|
||||
|
||||
bool read_meta_string(std::string& name, std::string& val)
|
||||
{
|
||||
uint32_t len = 0;
|
||||
return read_type_len(name, len) && read_str(val, len);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
class IffOutput final : public ImageOutput {
|
||||
public:
|
||||
IffOutput() { init(); }
|
||||
~IffOutput() override
|
||||
{
|
||||
try {
|
||||
close();
|
||||
} catch (const std::exception& e) {
|
||||
OIIO::pvt::errorfmt("{}", e.what());
|
||||
}
|
||||
}
|
||||
const char* format_name(void) const override { return "iff"; }
|
||||
int supports(string_view feature) const override;
|
||||
bool open(const std::string& name, const ImageSpec& spec,
|
||||
OpenMode mode) override;
|
||||
bool close(void) override;
|
||||
bool write_scanline(int y, int z, TypeDesc format, const void* data,
|
||||
stride_t xstride) override;
|
||||
bool write_tile(int x, int y, int z, TypeDesc format, const void* data,
|
||||
stride_t xstride, stride_t ystride,
|
||||
stride_t zstride) override;
|
||||
|
||||
private:
|
||||
FILE* m_fd;
|
||||
std::string m_filename;
|
||||
iff_pvt::IffFileHeader m_iff_header;
|
||||
std::vector<uint8_t> m_buf;
|
||||
unsigned int m_dither;
|
||||
std::vector<uint8_t> scratch;
|
||||
|
||||
void init(void)
|
||||
{
|
||||
m_fd = NULL;
|
||||
m_filename.clear();
|
||||
}
|
||||
|
||||
// writes information about iff file to give file
|
||||
bool write_header(iff_pvt::IffFileHeader& header);
|
||||
|
||||
bool write_short(uint16_t val)
|
||||
{
|
||||
if (littleendian())
|
||||
swap_endian(&val);
|
||||
return fwrite(&val, sizeof(val), 1, m_fd);
|
||||
}
|
||||
bool write_int(uint32_t val)
|
||||
{
|
||||
if (littleendian())
|
||||
swap_endian(&val);
|
||||
return fwrite(&val, sizeof(val), 1, m_fd);
|
||||
}
|
||||
|
||||
bool write_str(string_view val, size_t round = 4)
|
||||
{
|
||||
bool ok = fwrite(val.data(), val.size(), 1, m_fd);
|
||||
for (size_t i = val.size(); i < round_to_multiple(val.size(), round);
|
||||
++i)
|
||||
ok &= (fputc(' ', m_fd) != EOF);
|
||||
return ok;
|
||||
}
|
||||
|
||||
bool write_meta_string(string_view name, string_view val,
|
||||
bool write_if_empty = false)
|
||||
{
|
||||
if (val.empty() && !write_if_empty)
|
||||
return true;
|
||||
return write_str(name) && write_int(int(val.size()))
|
||||
&& (val.size() == 0 || write_str(val));
|
||||
}
|
||||
|
||||
// helper to compress verbatim
|
||||
void compress_verbatim(const uint8_t*& in, uint8_t*& out, int size);
|
||||
|
||||
// helper to compress duplicate
|
||||
void compress_duplicate(const uint8_t*& in, uint8_t*& out, int size);
|
||||
|
||||
// helper to compress a rle channel
|
||||
size_t compress_rle_channel(const uint8_t* in, uint8_t* out, int size);
|
||||
};
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_END
|
||||
@@ -0,0 +1,488 @@
|
||||
// Copyright Contributors to the OpenImageIO project.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// https://github.com/OpenImageIO/oiio
|
||||
#include "noproxy-iff_pvt.h"
|
||||
|
||||
#include <cmath>
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_BEGIN
|
||||
|
||||
using namespace iff_pvt;
|
||||
|
||||
// Obligatory material to make this a recognizable imageio plugin
|
||||
OIIO_PLUGIN_EXPORTS_BEGIN
|
||||
|
||||
OIIO_EXPORT int iff_imageio_version = OIIO_PLUGIN_VERSION;
|
||||
|
||||
OIIO_EXPORT const char*
|
||||
iff_imageio_library_version()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
OIIO_EXPORT ImageInput*
|
||||
iff_input_imageio_create()
|
||||
{
|
||||
return new IffInput;
|
||||
}
|
||||
|
||||
OIIO_EXPORT const char* iff_input_extensions[] = { "iff", "z", nullptr };
|
||||
|
||||
OIIO_PLUGIN_EXPORTS_END
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffInput::open(const std::string& name, ImageSpec& spec)
|
||||
{
|
||||
// Autodesk Maya documentation:
|
||||
// "Maya Image File Format - IFF
|
||||
//
|
||||
// Maya supports images in the Interchange File Format (IFF).
|
||||
// IFF is a generic structured file access mechanism, and is not only
|
||||
// limited to images.
|
||||
//
|
||||
// The openimageio IFF implementation deals specifically with Maya IFF
|
||||
// images with it's data blocks structured as follows:
|
||||
//
|
||||
// Header:
|
||||
// FOR4 <size> CIMG
|
||||
// TBHD <size> flags, width, height, compression ...
|
||||
// AUTH <size> attribute ...
|
||||
// DATE <size> attribute ...
|
||||
// FOR4 <size> TBMP
|
||||
// Tiles:
|
||||
// RGBA <size> tile pixels
|
||||
// RGBA <size> tile pixels
|
||||
// RGBA <size> tile pixels
|
||||
// ...
|
||||
|
||||
// saving 'name' for later use
|
||||
m_filename = name;
|
||||
|
||||
m_fd = Filesystem::fopen(m_filename, "rb");
|
||||
if (!m_fd) {
|
||||
errorf("Could not open file \"%s\"", name);
|
||||
return false;
|
||||
}
|
||||
|
||||
// we read header of the file that we think is IFF file
|
||||
std::string err;
|
||||
if (!m_iff_header.read_header(m_fd, err)) {
|
||||
errorf("\"%s\": could not read iff header (%s)", m_filename,
|
||||
err.size() ? err : std::string("unknown"));
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// image specification
|
||||
m_spec = ImageSpec(m_iff_header.width, m_iff_header.height,
|
||||
m_iff_header.pixel_channels,
|
||||
m_iff_header.pixel_bits == 8 ? TypeDesc::UINT8
|
||||
: TypeDesc::UINT16);
|
||||
// set x, y
|
||||
m_spec.x = m_iff_header.x;
|
||||
m_spec.y = m_iff_header.y;
|
||||
|
||||
// set full width, height
|
||||
m_spec.full_width = m_iff_header.width;
|
||||
m_spec.full_height = m_iff_header.height;
|
||||
|
||||
// tiles
|
||||
if (m_iff_header.tile_width > 0 || m_iff_header.tile_height > 0) {
|
||||
m_spec.tile_width = m_iff_header.tile_width;
|
||||
m_spec.tile_height = m_iff_header.tile_height;
|
||||
// only 1 subimage for IFF
|
||||
m_spec.tile_depth = 1;
|
||||
} else {
|
||||
errorf("\"%s\": wrong tile size", m_filename);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// attributes
|
||||
|
||||
// compression
|
||||
if (m_iff_header.compression == iff_pvt::RLE) {
|
||||
m_spec.attribute("compression", "rle");
|
||||
}
|
||||
|
||||
// author
|
||||
if (m_iff_header.author.size()) {
|
||||
m_spec.attribute("Artist", m_iff_header.author);
|
||||
}
|
||||
|
||||
// date
|
||||
if (m_iff_header.date.size()) {
|
||||
m_spec.attribute("DateTime", m_iff_header.date);
|
||||
}
|
||||
|
||||
// file pointer is set to the beginning of tbmp data
|
||||
// we save this position - it will be helpful in read_native_tile
|
||||
m_tbmp_start = m_iff_header.tbmp_start;
|
||||
|
||||
spec = m_spec;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffInput::read_native_scanline(int /*subimage*/, int /*miplevel*/, int /*y*/,
|
||||
int /*z*/, void* /*data*/)
|
||||
{
|
||||
// scanline not used for Maya IFF, uses tiles instead.
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffInput::read_native_tile(int subimage, int miplevel, int x, int y, int /*z*/,
|
||||
void* data)
|
||||
{
|
||||
lock_guard lock(*this);
|
||||
if (!seek_subimage(subimage, miplevel))
|
||||
return false;
|
||||
|
||||
if (m_buf.empty())
|
||||
readimg();
|
||||
|
||||
// tile size
|
||||
int w = m_spec.width;
|
||||
int tw = std::min(x + m_spec.tile_width, m_spec.width) - x;
|
||||
int th = std::min(y + m_spec.tile_height, m_spec.height) - y;
|
||||
|
||||
// tile data
|
||||
int oy = 0;
|
||||
for (int iy = y; iy < y + th; iy++) {
|
||||
// in
|
||||
uint8_t* in_p = &m_buf[0] + (iy * w + x) * m_spec.pixel_bytes();
|
||||
// out
|
||||
uint8_t* out_p = (uint8_t*)data
|
||||
+ (oy * m_spec.tile_width) * m_spec.pixel_bytes();
|
||||
// copy
|
||||
memcpy(out_p, in_p, tw * m_spec.pixel_bytes());
|
||||
oy++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool inline IffInput::close(void)
|
||||
{
|
||||
if (m_fd) {
|
||||
fclose(m_fd);
|
||||
m_fd = NULL;
|
||||
}
|
||||
init();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffInput::readimg()
|
||||
{
|
||||
uint8_t type[4];
|
||||
uint32_t size;
|
||||
uint32_t chunksize;
|
||||
|
||||
// seek pos
|
||||
// set position tile may be called randomly
|
||||
fseek(m_fd, m_tbmp_start, SEEK_SET);
|
||||
|
||||
// resize buffer
|
||||
m_buf.resize(m_spec.image_bytes());
|
||||
|
||||
for (unsigned int t = 0; t < m_iff_header.tiles;) {
|
||||
// get type
|
||||
if (!fread(&type, 1, sizeof(type), m_fd) ||
|
||||
// get length
|
||||
!fread(&size, 1, sizeof(size), m_fd))
|
||||
return false;
|
||||
|
||||
if (littleendian())
|
||||
swap_endian(&size);
|
||||
|
||||
chunksize = align_size(size, 4);
|
||||
|
||||
// check if RGBA
|
||||
if (type[0] == 'R' && type[1] == 'G' && type[2] == 'B'
|
||||
&& type[3] == 'A') {
|
||||
// get tile coordinates.
|
||||
uint16_t xmin, xmax, ymin, ymax;
|
||||
if (!fread(&xmin, 1, sizeof(xmin), m_fd)
|
||||
|| !fread(&ymin, 1, sizeof(ymin), m_fd)
|
||||
|| !fread(&xmax, 1, sizeof(xmax), m_fd)
|
||||
|| !fread(&ymax, 1, sizeof(ymax), m_fd))
|
||||
return false;
|
||||
|
||||
// swap endianness
|
||||
if (littleendian()) {
|
||||
swap_endian(&xmin);
|
||||
swap_endian(&ymin);
|
||||
swap_endian(&xmax);
|
||||
swap_endian(&ymax);
|
||||
}
|
||||
|
||||
// get tile width/height
|
||||
uint32_t tw = xmax - xmin + 1;
|
||||
uint32_t th = ymax - ymin + 1;
|
||||
|
||||
// get image size
|
||||
// skip coordinates, uint16_t (2) * 4 = 8
|
||||
uint32_t image_size = chunksize - 8;
|
||||
|
||||
// check tile
|
||||
if (xmin > xmax || ymin > ymax || xmax >= m_spec.width
|
||||
|| ymax >= m_spec.height || !tw || !th) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// tile compress
|
||||
bool tile_compress = false;
|
||||
|
||||
// if tile compression fails to be less than image data stored
|
||||
// uncompressed the tile is written uncompressed
|
||||
|
||||
// set channels
|
||||
uint8_t channels = m_iff_header.pixel_channels;
|
||||
|
||||
// set tile size
|
||||
uint32_t tile_size = tw * th * channels * m_spec.channel_bytes()
|
||||
+ 8;
|
||||
|
||||
// test if compressed
|
||||
// we use the non aligned size
|
||||
if (tile_size > size) {
|
||||
tile_compress = true;
|
||||
}
|
||||
|
||||
// handle 8-bit data.
|
||||
if (m_iff_header.pixel_bits == 8) {
|
||||
std::vector<uint8_t> scratch;
|
||||
|
||||
// set bytes.
|
||||
scratch.resize(image_size);
|
||||
|
||||
if (!fread(&scratch[0], 1, scratch.size(), m_fd))
|
||||
return false;
|
||||
|
||||
// set tile data
|
||||
uint8_t* p = static_cast<uint8_t*>(&scratch[0]);
|
||||
|
||||
// tile compress.
|
||||
if (tile_compress) {
|
||||
// map BGR(A) to RGB(A)
|
||||
for (int c = (channels * m_spec.channel_bytes()) - 1;
|
||||
c >= 0; --c) {
|
||||
std::vector<uint8_t> in(tw * th);
|
||||
uint8_t* in_p = &in[0];
|
||||
|
||||
// uncompress and increment
|
||||
p += uncompress_rle_channel(p, in_p, tw * th);
|
||||
|
||||
// set tile
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
uint8_t* out_dy = static_cast<uint8_t*>(&m_buf[0])
|
||||
+ (py * m_spec.width)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
uint8_t* out_p
|
||||
= out_dy + px * m_spec.pixel_bytes() + c;
|
||||
*out_p++ = *in_p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int sy = 0;
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
uint8_t* out_dy = static_cast<uint8_t*>(&m_buf[0])
|
||||
+ (py * m_spec.width + xmin)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
// set tile
|
||||
int sx = 0;
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
uint8_t* in_p
|
||||
= p + (sy * tw + sx) * m_spec.pixel_bytes();
|
||||
|
||||
// map BGR(A) to RGB(A)
|
||||
for (int c = channels - 1; c >= 0; --c) {
|
||||
uint8_t* out_p = in_p
|
||||
+ (c * m_spec.channel_bytes());
|
||||
*out_dy++ = *out_p;
|
||||
}
|
||||
sx++;
|
||||
}
|
||||
sy++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle 16-bit data.
|
||||
else if (m_iff_header.pixel_bits == 16) {
|
||||
std::vector<uint8_t> scratch;
|
||||
|
||||
// set bytes.
|
||||
scratch.resize(image_size);
|
||||
|
||||
if (!fread(&scratch[0], 1, scratch.size(), m_fd))
|
||||
return false;
|
||||
|
||||
// set tile data
|
||||
uint8_t* p = static_cast<uint8_t*>(&scratch[0]);
|
||||
|
||||
if (tile_compress) {
|
||||
// set map
|
||||
std::vector<uint8_t> map;
|
||||
if (littleendian()) {
|
||||
int rgb16[] = { 0, 2, 4, 1, 3, 5 };
|
||||
int rgba16[] = { 0, 2, 4, 6, 1, 3, 5, 7 };
|
||||
if (m_iff_header.pixel_channels == 3) {
|
||||
map = std::vector<uint8_t>(rgb16, &rgb16[6]);
|
||||
} else {
|
||||
map = std::vector<uint8_t>(rgba16, &rgba16[8]);
|
||||
}
|
||||
|
||||
} else {
|
||||
int rgb16[] = { 1, 3, 5, 0, 2, 4 };
|
||||
int rgba16[] = { 1, 3, 5, 7, 0, 2, 4, 6 };
|
||||
if (m_iff_header.pixel_channels == 3) {
|
||||
map = std::vector<uint8_t>(rgb16, &rgb16[6]);
|
||||
} else {
|
||||
map = std::vector<uint8_t>(rgba16, &rgba16[8]);
|
||||
}
|
||||
}
|
||||
|
||||
// map BGR(A)BGR(A) to RRGGBB(AA)
|
||||
for (int c = (channels * m_spec.channel_bytes()) - 1;
|
||||
c >= 0; --c) {
|
||||
int mc = map[c];
|
||||
|
||||
std::vector<uint8_t> in(tw * th);
|
||||
uint8_t* in_p = &in[0];
|
||||
|
||||
// uncompress and increment
|
||||
p += uncompress_rle_channel(p, in_p, tw * th);
|
||||
|
||||
// set tile
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
uint8_t* out_dy = static_cast<uint8_t*>(&m_buf[0])
|
||||
+ (py * m_spec.width)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
uint8_t* out_p
|
||||
= out_dy + px * m_spec.pixel_bytes() + mc;
|
||||
*out_p++ = *in_p++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int sy = 0;
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
uint8_t* out_dy = static_cast<uint8_t*>(&m_buf[0])
|
||||
+ (py * m_spec.width + xmin)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
// set scanline, make copy easier
|
||||
std::vector<uint16_t> scanline(tw
|
||||
* m_spec.pixel_bytes());
|
||||
uint16_t* sl_p = &scanline[0];
|
||||
|
||||
// set tile
|
||||
int sx = 0;
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
uint8_t* in_p
|
||||
= p + (sy * tw + sx) * m_spec.pixel_bytes();
|
||||
|
||||
// map BGR(A) to RGB(A)
|
||||
for (int c = channels - 1; c >= 0; --c) {
|
||||
uint16_t pixel;
|
||||
uint8_t* out_p = in_p
|
||||
+ (c * m_spec.channel_bytes());
|
||||
memcpy(&pixel, out_p, 2);
|
||||
// swap endianness
|
||||
if (littleendian()) {
|
||||
swap_endian(&pixel);
|
||||
}
|
||||
*sl_p++ = pixel;
|
||||
}
|
||||
sx++;
|
||||
}
|
||||
// copy data
|
||||
memcpy(out_dy, &scanline[0], tw * m_spec.pixel_bytes());
|
||||
sy++;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
errorf("\"%s\": unsupported number of bits per pixel for tile",
|
||||
m_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
// tile
|
||||
t++;
|
||||
|
||||
} else {
|
||||
// skip to the next block
|
||||
if (fseek(m_fd, chunksize, SEEK_CUR))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// flip buffer to make read_native_tile easier,
|
||||
// from tga.imageio:
|
||||
|
||||
int bytespp = m_spec.pixel_bytes();
|
||||
|
||||
std::vector<unsigned char> flip(m_spec.width * bytespp);
|
||||
unsigned char *src, *dst, *tmp = &flip[0];
|
||||
for (int y = 0; y < m_spec.height / 2; y++) {
|
||||
src = &m_buf[(m_spec.height - y - 1) * m_spec.width * bytespp];
|
||||
dst = &m_buf[y * m_spec.width * bytespp];
|
||||
|
||||
memcpy(tmp, src, m_spec.width * bytespp);
|
||||
memcpy(src, dst, m_spec.width * bytespp);
|
||||
memcpy(dst, tmp, m_spec.width * bytespp);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t
|
||||
IffInput::uncompress_rle_channel(const uint8_t* in, uint8_t* out, int size)
|
||||
{
|
||||
const uint8_t* const _in = in;
|
||||
const uint8_t* const end = out + size;
|
||||
|
||||
while (out < end) {
|
||||
// information.
|
||||
const uint8_t count = (*in & 0x7f) + 1;
|
||||
const bool run = (*in & 0x80) ? true : false;
|
||||
++in;
|
||||
|
||||
// find runs
|
||||
if (!run) {
|
||||
// verbatim
|
||||
for (int i = 0; i < count; i++)
|
||||
*out++ = *in++;
|
||||
} else {
|
||||
// duplicate
|
||||
const uint8_t p = *in++;
|
||||
for (int i = 0; i < count; i++)
|
||||
*out++ = p;
|
||||
}
|
||||
}
|
||||
const size_t r = in - _in;
|
||||
return r;
|
||||
}
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_END
|
||||
@@ -0,0 +1,600 @@
|
||||
// Copyright Contributors to the OpenImageIO project.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// https://github.com/OpenImageIO/oiio
|
||||
|
||||
#include "noproxy-iff_pvt.h"
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_BEGIN
|
||||
|
||||
using namespace iff_pvt;
|
||||
|
||||
|
||||
// Obligatory material to make this a recognizable imageio plugin
|
||||
OIIO_PLUGIN_EXPORTS_BEGIN
|
||||
|
||||
OIIO_EXPORT ImageOutput*
|
||||
iff_output_imageio_create()
|
||||
{
|
||||
return new IffOutput;
|
||||
}
|
||||
|
||||
OIIO_EXPORT const char* iff_output_extensions[] = { "iff", "z", nullptr };
|
||||
|
||||
OIIO_PLUGIN_EXPORTS_END
|
||||
|
||||
|
||||
|
||||
int
|
||||
IffOutput::supports(string_view feature) const
|
||||
{
|
||||
return (feature == "tiles" || feature == "alpha" || feature == "nchannels");
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffOutput::open(const std::string& name, const ImageSpec& spec, OpenMode mode)
|
||||
{
|
||||
// Autodesk Maya documentation:
|
||||
// "Maya Image File Format - IFF
|
||||
//
|
||||
// Maya supports images in the Interchange File Format (IFF).
|
||||
// IFF is a generic structured file access mechanism, and is not only
|
||||
// limited to images.
|
||||
//
|
||||
// The openimageio IFF implementation deals specifically with Maya IFF
|
||||
// images with it's data blocks structured as follows:
|
||||
//
|
||||
// Header:
|
||||
// FOR4 <size> CIMG
|
||||
// TBHD <size> flags, width, height, compression ...
|
||||
// AUTH <size> attribute ...
|
||||
// DATE <size> attribute ...
|
||||
// FOR4 <size> TBMP
|
||||
// Tiles:
|
||||
// RGBA <size> tile pixels
|
||||
// RGBA <size> tile pixels
|
||||
// RGBA <size> tile pixels
|
||||
// ...
|
||||
|
||||
if (mode != Create) {
|
||||
errorf("%s does not support subimages or MIP levels", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
close(); // Close any already-opened file
|
||||
// saving 'name' and 'spec' for later use
|
||||
m_filename = name;
|
||||
m_spec = spec;
|
||||
|
||||
// tiles
|
||||
m_spec.tile_width = tile_width();
|
||||
m_spec.tile_height = tile_height();
|
||||
m_spec.tile_depth = 1;
|
||||
|
||||
m_fd = Filesystem::fopen(m_filename, "wb");
|
||||
if (!m_fd) {
|
||||
errorf("Could not open \"%s\"", m_filename);
|
||||
return false;
|
||||
}
|
||||
|
||||
// IFF image files only supports UINT8 and UINT16. If something
|
||||
// else was requested, revert to the one most likely to be readable
|
||||
// by any IFF reader: UINT8
|
||||
if (m_spec.format != TypeDesc::UINT8 && m_spec.format != TypeDesc::UINT16)
|
||||
m_spec.set_format(TypeDesc::UINT8);
|
||||
|
||||
m_dither = (m_spec.format == TypeDesc::UINT8)
|
||||
? m_spec.get_int_attribute("oiio:dither", 0)
|
||||
: 0;
|
||||
|
||||
// check if the client wants the image to be run length encoded
|
||||
// currently only RGB RLE compression is supported, we default to RLE
|
||||
// as Maya does not handle non-compressed IFF's very well.
|
||||
m_iff_header.compression
|
||||
= (m_spec.get_string_attribute("compression") == "none") ? NONE : RLE;
|
||||
|
||||
uint64_t xtiles = tile_width_size(m_spec.width);
|
||||
uint64_t ytiles = tile_height_size(m_spec.height);
|
||||
if (xtiles * ytiles >= (1 << 16)) { // The format can't store it!
|
||||
errorf(
|
||||
"Too high a resolution (%dx%d), exceeds maximum of 64k tiles in the image\n",
|
||||
m_spec.width, m_spec.height);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
// we write the header of the file
|
||||
m_iff_header.x = m_spec.x;
|
||||
m_iff_header.y = m_spec.y;
|
||||
m_iff_header.width = m_spec.width;
|
||||
m_iff_header.height = m_spec.height;
|
||||
m_iff_header.tiles = xtiles * ytiles;
|
||||
m_iff_header.pixel_bits = m_spec.format == TypeDesc::UINT8 ? 8 : 16;
|
||||
m_iff_header.pixel_channels = m_spec.nchannels;
|
||||
m_iff_header.author = m_spec.get_string_attribute("Artist");
|
||||
m_iff_header.date = m_spec.get_string_attribute("DateTime");
|
||||
|
||||
if (!write_header(m_iff_header)) {
|
||||
errorf("\"%s\": could not write iff header", m_filename);
|
||||
close();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_buf.resize(m_spec.image_bytes());
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffOutput::write_scanline(int y, int z, TypeDesc format, const void* data,
|
||||
stride_t xstride)
|
||||
{
|
||||
// scanline not used for Maya IFF, uses tiles instead.
|
||||
// Emulate by copying the scanline to the buffer we're accumulating.
|
||||
std::vector<unsigned char> scratch;
|
||||
data = to_native_scanline(format, data, xstride, scratch, m_dither, y, z);
|
||||
size_t scanlinesize = spec().scanline_bytes(true);
|
||||
size_t offset = scanlinesize * (y - spec().y)
|
||||
+ scanlinesize * spec().height * (z - spec().z);
|
||||
memcpy(&m_buf[offset], data, scanlinesize);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
bool
|
||||
IffOutput::write_tile(int x, int y, int z, TypeDesc format, const void* data,
|
||||
stride_t xstride, stride_t ystride, stride_t zstride)
|
||||
{
|
||||
// auto stride
|
||||
m_spec.auto_stride(xstride, ystride, zstride, format, spec().nchannels,
|
||||
spec().tile_width, spec().tile_height);
|
||||
|
||||
// native tile
|
||||
data = to_native_tile(format, data, xstride, ystride, zstride, scratch,
|
||||
m_dither, x, y, z);
|
||||
|
||||
x -= m_spec.x; // Account for offset, so x,y are file relative, not
|
||||
y -= m_spec.y; // image relative
|
||||
|
||||
// tile size
|
||||
int w = m_spec.width;
|
||||
int tw = std::min(x + m_spec.tile_width, m_spec.width) - x;
|
||||
int th = std::min(y + m_spec.tile_height, m_spec.height) - y;
|
||||
|
||||
// tile data
|
||||
int iy = 0;
|
||||
for (int oy = y; oy < y + th; oy++) {
|
||||
// in
|
||||
uint8_t* in_p = (uint8_t*)data
|
||||
+ (iy * m_spec.tile_width) * m_spec.pixel_bytes();
|
||||
// out
|
||||
uint8_t* out_p = &m_buf[0] + (oy * w + x) * m_spec.pixel_bytes();
|
||||
// copy
|
||||
memcpy(out_p, in_p, tw * m_spec.pixel_bytes());
|
||||
iy++;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
inline bool
|
||||
IffOutput::close(void)
|
||||
{
|
||||
if (m_fd && m_buf.size()) {
|
||||
// flip buffer to make write tile easier,
|
||||
// from tga.imageio:
|
||||
|
||||
int bytespp = m_spec.pixel_bytes();
|
||||
|
||||
std::vector<unsigned char> flip(m_spec.width * bytespp);
|
||||
unsigned char *src, *dst, *tmp = &flip[0];
|
||||
for (int y = 0; y < m_spec.height / 2; y++) {
|
||||
src = &m_buf[(m_spec.height - y - 1) * m_spec.width * bytespp];
|
||||
dst = &m_buf[y * m_spec.width * bytespp];
|
||||
|
||||
memcpy(tmp, src, m_spec.width * bytespp);
|
||||
memcpy(src, dst, m_spec.width * bytespp);
|
||||
memcpy(dst, tmp, m_spec.width * bytespp);
|
||||
}
|
||||
|
||||
// write y-tiles
|
||||
for (uint32_t ty = 0; ty < tile_height_size(m_spec.height); ty++) {
|
||||
// write x-tiles
|
||||
for (uint32_t tx = 0; tx < tile_width_size(m_spec.width); tx++) {
|
||||
// channels
|
||||
uint8_t channels = m_iff_header.pixel_channels;
|
||||
|
||||
// set tile coordinates
|
||||
uint16_t xmin, xmax, ymin, ymax;
|
||||
|
||||
// set xmin and xmax
|
||||
xmin = tx * tile_width();
|
||||
xmax = std::min(xmin + tile_width(), m_spec.width) - 1;
|
||||
|
||||
// set ymin and ymax
|
||||
ymin = ty * tile_height();
|
||||
ymax = std::min(ymin + tile_height(), m_spec.height) - 1;
|
||||
|
||||
// set width and height
|
||||
uint32_t tw = xmax - xmin + 1;
|
||||
uint32_t th = ymax - ymin + 1;
|
||||
|
||||
// write 'RGBA' type
|
||||
std::string tmpstr = "RGBA";
|
||||
if (!fwrite(tmpstr.c_str(), tmpstr.length(), 1, m_fd))
|
||||
return false;
|
||||
|
||||
// length.
|
||||
uint32_t length = tw * th * m_spec.pixel_bytes();
|
||||
|
||||
// tile length.
|
||||
uint32_t tile_length = length;
|
||||
|
||||
// align.
|
||||
length = align_size(length, 4);
|
||||
|
||||
// append xmin, xmax, ymin and ymax.
|
||||
length += 8;
|
||||
|
||||
// tile compression.
|
||||
bool tile_compress = (m_iff_header.compression == RLE);
|
||||
|
||||
// set bytes.
|
||||
std::vector<uint8_t> scratch;
|
||||
scratch.resize(tile_length);
|
||||
|
||||
uint8_t* out_p = static_cast<uint8_t*>(&scratch[0]);
|
||||
|
||||
// handle 8-bit data
|
||||
if (m_spec.format == TypeDesc::UINT8) {
|
||||
if (tile_compress) {
|
||||
uint32_t index = 0, size = 0;
|
||||
std::vector<uint8_t> tmp;
|
||||
|
||||
// set bytes.
|
||||
tmp.resize(tile_length * 2);
|
||||
|
||||
// map: RGB(A) to BGRA
|
||||
for (int c = (channels * m_spec.channel_bytes()) - 1;
|
||||
c >= 0; --c) {
|
||||
std::vector<uint8_t> in(tw * th);
|
||||
uint8_t* in_p = &in[0];
|
||||
|
||||
// set tile
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
const uint8_t* in_dy
|
||||
= &m_buf[0]
|
||||
+ (py * m_spec.width)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
// get pixel
|
||||
uint8_t pixel;
|
||||
const uint8_t* in_dx
|
||||
= in_dy + px * m_spec.pixel_bytes() + c;
|
||||
memcpy(&pixel, in_dx, 1);
|
||||
// set pixel
|
||||
*in_p++ = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
// compress rle channel
|
||||
size = compress_rle_channel(&in[0], &tmp[0] + index,
|
||||
tw * th);
|
||||
index += size;
|
||||
}
|
||||
|
||||
// if size exceeds tile length write uncompressed
|
||||
|
||||
if (index < tile_length) {
|
||||
memcpy(&scratch[0], &tmp[0], index);
|
||||
|
||||
// set tile length
|
||||
tile_length = index;
|
||||
|
||||
// append xmin, xmax, ymin and ymax
|
||||
length = index + 8;
|
||||
|
||||
// set length
|
||||
uint32_t align = align_size(length, 4);
|
||||
if (align > length) {
|
||||
out_p = &scratch[0] + index;
|
||||
// Pad.
|
||||
for (uint32_t i = 0; i < align - length; i++) {
|
||||
*out_p++ = '\0';
|
||||
tile_length++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tile_compress = false;
|
||||
}
|
||||
}
|
||||
if (!tile_compress) {
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
const uint8_t* in_dy = &m_buf[0]
|
||||
+ (py * m_spec.width)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
// Map: RGB(A)8 RGBA to BGRA
|
||||
for (int c = channels - 1; c >= 0; --c) {
|
||||
// get pixel
|
||||
uint8_t pixel;
|
||||
const uint8_t* in_dx
|
||||
= in_dy + px * m_spec.pixel_bytes()
|
||||
+ c * m_spec.channel_bytes();
|
||||
memcpy(&pixel, in_dx, 1);
|
||||
// set pixel
|
||||
*out_p++ = pixel;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// handle 16-bit data
|
||||
else if (m_spec.format == TypeDesc::UINT16) {
|
||||
if (tile_compress) {
|
||||
uint32_t index = 0, size = 0;
|
||||
std::vector<uint8_t> tmp;
|
||||
|
||||
// set bytes.
|
||||
tmp.resize(tile_length * 2);
|
||||
|
||||
// set map
|
||||
std::vector<uint8_t> map;
|
||||
if (littleendian()) {
|
||||
int rgb16[] = { 0, 2, 4, 1, 3, 5 };
|
||||
int rgba16[] = { 0, 2, 4, 7, 1, 3, 5, 6 };
|
||||
if (m_iff_header.pixel_channels == 3) {
|
||||
map = std::vector<uint8_t>(rgb16, &rgb16[6]);
|
||||
} else {
|
||||
map = std::vector<uint8_t>(rgba16, &rgba16[8]);
|
||||
}
|
||||
|
||||
} else {
|
||||
int rgb16[] = { 1, 3, 5, 0, 2, 4 };
|
||||
int rgba16[] = { 1, 3, 5, 7, 0, 2, 4, 6 };
|
||||
if (m_iff_header.pixel_channels == 3) {
|
||||
map = std::vector<uint8_t>(rgb16, &rgb16[6]);
|
||||
} else {
|
||||
map = std::vector<uint8_t>(rgba16, &rgba16[8]);
|
||||
}
|
||||
}
|
||||
|
||||
// map: RRGGBB(AA) to BGR(A)BGR(A)
|
||||
for (int c = (channels * m_spec.channel_bytes()) - 1;
|
||||
c >= 0; --c) {
|
||||
int mc = map[c];
|
||||
|
||||
std::vector<uint8_t> in(tw * th);
|
||||
uint8_t* in_p = &in[0];
|
||||
|
||||
// set tile
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
const uint8_t* in_dy
|
||||
= &m_buf[0]
|
||||
+ (py * m_spec.width)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
// get pixel
|
||||
uint8_t pixel;
|
||||
const uint8_t* in_dx
|
||||
= in_dy + px * m_spec.pixel_bytes()
|
||||
+ mc;
|
||||
memcpy(&pixel, in_dx, 1);
|
||||
// set pixel.
|
||||
*in_p++ = pixel;
|
||||
}
|
||||
}
|
||||
|
||||
// compress rle channel
|
||||
size = compress_rle_channel(&in[0], &tmp[0] + index,
|
||||
tw * th);
|
||||
index += size;
|
||||
}
|
||||
|
||||
// if size exceeds tile length write uncompressed
|
||||
|
||||
if (index < tile_length) {
|
||||
memcpy(&scratch[0], &tmp[0], index);
|
||||
|
||||
// set tile length
|
||||
tile_length = index;
|
||||
|
||||
// append xmin, xmax, ymin and ymax
|
||||
length = index + 8;
|
||||
|
||||
// set length
|
||||
uint32_t align = align_size(length, 4);
|
||||
if (align > length) {
|
||||
out_p = &scratch[0] + index;
|
||||
// Pad.
|
||||
for (uint32_t i = 0; i < align - length; i++) {
|
||||
*out_p++ = '\0';
|
||||
tile_length++;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
tile_compress = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!tile_compress) {
|
||||
for (uint16_t py = ymin; py <= ymax; py++) {
|
||||
const uint8_t* in_dy = &m_buf[0]
|
||||
+ (py * m_spec.width)
|
||||
* m_spec.pixel_bytes();
|
||||
|
||||
for (uint16_t px = xmin; px <= xmax; px++) {
|
||||
// map: RGB(A) to BGRA
|
||||
for (int c = channels - 1; c >= 0; --c) {
|
||||
uint16_t pixel;
|
||||
const uint8_t* in_dx
|
||||
= in_dy + px * m_spec.pixel_bytes()
|
||||
+ c * m_spec.channel_bytes();
|
||||
memcpy(&pixel, in_dx, 2);
|
||||
if (littleendian()) {
|
||||
swap_endian(&pixel);
|
||||
}
|
||||
// set pixel
|
||||
*out_p++ = pixel & 0xff;
|
||||
*out_p++ = pixel >> 8;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write 'RGBA' length
|
||||
if (littleendian())
|
||||
swap_endian(&length);
|
||||
|
||||
if (!fwrite(&length, sizeof(length), 1, m_fd))
|
||||
return false;
|
||||
|
||||
// write xmin, xmax, ymin and ymax
|
||||
if (littleendian()) {
|
||||
swap_endian(&xmin);
|
||||
swap_endian(&ymin);
|
||||
swap_endian(&xmax);
|
||||
swap_endian(&ymax);
|
||||
}
|
||||
|
||||
if (!fwrite(&xmin, sizeof(xmin), 1, m_fd)
|
||||
|| !fwrite(&ymin, sizeof(ymin), 1, m_fd)
|
||||
|| !fwrite(&xmax, sizeof(xmax), 1, m_fd)
|
||||
|| !fwrite(&ymax, sizeof(ymax), 1, m_fd))
|
||||
return false;
|
||||
|
||||
// write tile
|
||||
if (!fwrite(&scratch[0], tile_length, 1, m_fd))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// set sizes
|
||||
uint32_t pos, tmppos;
|
||||
pos = ftell(m_fd);
|
||||
|
||||
uint32_t p0 = pos - 8;
|
||||
uint32_t p1 = p0 - m_iff_header.for4_start;
|
||||
|
||||
// set pos
|
||||
tmppos = 4;
|
||||
fseek(m_fd, tmppos, SEEK_SET);
|
||||
|
||||
// write FOR4 <size> CIMG
|
||||
if (littleendian()) {
|
||||
swap_endian(&p0);
|
||||
}
|
||||
|
||||
if (!fwrite(&p0, sizeof(p0), 1, m_fd))
|
||||
return false;
|
||||
|
||||
// set pos
|
||||
tmppos = m_iff_header.for4_start + 4;
|
||||
fseek(m_fd, tmppos, SEEK_SET);
|
||||
|
||||
// write FOR4 <size> TBMP
|
||||
if (littleendian()) {
|
||||
swap_endian(&p1);
|
||||
}
|
||||
|
||||
if (!fwrite(&p1, sizeof(p1), 1, m_fd))
|
||||
return false;
|
||||
|
||||
m_buf.resize(0);
|
||||
m_buf.shrink_to_fit();
|
||||
}
|
||||
if (m_fd) {
|
||||
// close the stream
|
||||
fclose(m_fd);
|
||||
m_fd = NULL;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
IffOutput::compress_verbatim(const uint8_t*& in, uint8_t*& out, int size)
|
||||
{
|
||||
int count = 1;
|
||||
unsigned char byte = 0;
|
||||
|
||||
// two in a row or count
|
||||
for (; count < size; ++count) {
|
||||
if (in[count - 1] == in[count]) {
|
||||
if (byte == in[count - 1]) {
|
||||
count -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
byte = in[count - 1];
|
||||
}
|
||||
|
||||
// copy
|
||||
*out++ = count - 1;
|
||||
memcpy(out, in, count);
|
||||
|
||||
out += count;
|
||||
in += count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void
|
||||
IffOutput::compress_duplicate(const uint8_t*& in, uint8_t*& out, int size)
|
||||
{
|
||||
int count = 1;
|
||||
for (; count < size; ++count) {
|
||||
if (in[count - 1] != in[count])
|
||||
break;
|
||||
}
|
||||
|
||||
const bool run = count > 1;
|
||||
const int length = run ? 1 : count;
|
||||
|
||||
// copy
|
||||
*out++ = ((count - 1) & 0x7f) | (run << 7);
|
||||
*out = *in;
|
||||
|
||||
out += length;
|
||||
in += count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
size_t
|
||||
IffOutput::compress_rle_channel(const uint8_t* in, uint8_t* out, int size)
|
||||
{
|
||||
const uint8_t* const _out = out;
|
||||
const uint8_t* const end = in + size;
|
||||
|
||||
while (in < end) {
|
||||
// find runs
|
||||
const int max = std::min(0x7f + 1, static_cast<int>(end - in));
|
||||
if (max > 0) {
|
||||
if (in < (end - 1) && in[0] == in[1]) {
|
||||
// compress duplicate
|
||||
compress_duplicate(in, out, max);
|
||||
} else {
|
||||
// compress verbatim
|
||||
compress_verbatim(in, out, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
const size_t r = out - _out;
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
|
||||
OIIO_PLUGIN_NAMESPACE_END
|
||||
+6
-2
@@ -181,13 +181,17 @@ main(int argc, const char* argv[])
|
||||
flag = std::regex_constants::extended;
|
||||
if (ap["i"].get<int>())
|
||||
flag |= std::regex_constants::icase;
|
||||
|
||||
bool ok = true;
|
||||
|
||||
try {
|
||||
std::regex re(pattern, flag);
|
||||
for (auto&& s : filenames)
|
||||
grep_file(s, re);
|
||||
} catch (const std::regex_error& e) {
|
||||
std::cerr << "igrep: " << e.what() << "\n";
|
||||
return EXIT_FAILURE;
|
||||
ok = false;
|
||||
}
|
||||
return 0;
|
||||
shutdown();
|
||||
return ok ? EXIT_SUCCESS : EXIT_FAILURE;
|
||||
}
|
||||
|
||||
@@ -487,5 +487,6 @@ main(int argc, const char* argv[])
|
||||
if (sum)
|
||||
print("Total size: {}\n", Strutil::memformat(totalsize));
|
||||
|
||||
shutdown();
|
||||
return returncode;
|
||||
}
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
/// This routine will return the error string (and by default, clear any
|
||||
/// error flags). If no error has occurred since the last time
|
||||
/// geterror() was called, it will return an empty string.
|
||||
std::string geterror(bool clear = true);
|
||||
std::string geterror(bool clear = true) const;
|
||||
|
||||
/// Get the number of ColorSpace(s) defined in this configuration
|
||||
int getNumColorSpaces() const;
|
||||
@@ -102,6 +102,12 @@ public:
|
||||
/// Query the name of the specified ColorSpace.
|
||||
const char* getColorSpaceNameByIndex(int index) const;
|
||||
|
||||
/// Given a color space name, return the index of an equivalent color
|
||||
/// space, or -1 if not found. It will first look for an exact match of
|
||||
/// the name, but if not found, will match a color space that is
|
||||
/// "equivalent" to the named color space.
|
||||
int getColorSpaceIndex(string_view name) const;
|
||||
|
||||
/// Get the name of the color space representing the named role,
|
||||
/// or NULL if none could be identified.
|
||||
const char* getColorSpaceNameByRole(string_view role) const;
|
||||
@@ -168,7 +174,7 @@ public:
|
||||
/// inverse==true, request the inverse transformation. The
|
||||
/// context_key and context_value can optionally be used to establish
|
||||
/// extra key/value pairs in the OCIO context if they are comma-
|
||||
/// separated lists of ontext keys and values, respectively.
|
||||
/// separated lists of context keys and values, respectively.
|
||||
///
|
||||
/// The handle is actually a shared_ptr, so when you're done with a
|
||||
/// ColorProcess, just discard it. ColorProcessor(s) remain valid even
|
||||
@@ -252,14 +258,26 @@ public:
|
||||
ColorProcessorHandle
|
||||
createDisplayTransform(string_view display, string_view view,
|
||||
string_view inputColorSpace, string_view looks = "",
|
||||
string_view context_key = "",
|
||||
bool inverse = false, string_view context_key = "",
|
||||
string_view context_value = "") const;
|
||||
ColorProcessorHandle
|
||||
createDisplayTransform(ustring display, ustring view,
|
||||
ustring inputColorSpace, ustring looks = ustring(),
|
||||
bool inverse = false,
|
||||
ustring context_key = ustring(),
|
||||
ustring context_value = ustring()) const;
|
||||
|
||||
// OIIO_DEPRECATED("prefer the kind that takes an `inverse` parameter (2.5)")
|
||||
ColorProcessorHandle
|
||||
createDisplayTransform(string_view display, string_view view,
|
||||
string_view inputColorSpace, string_view looks,
|
||||
string_view context_key,
|
||||
string_view context_value = "") const;
|
||||
// OIIO_DEPRECATED("prefer the kind that takes an `inverse` parameter (2.5)")
|
||||
ColorProcessorHandle createDisplayTransform(
|
||||
ustring display, ustring view, ustring inputColorSpace, ustring looks,
|
||||
ustring context_key, ustring context_value = ustring()) const;
|
||||
|
||||
/// Construct a processor to perform color transforms determined by an
|
||||
/// OpenColorIO FileTransform. It is possible that this will return an
|
||||
/// empty handle if the FileTransform doesn't exist or is not allowed.
|
||||
@@ -297,6 +315,15 @@ public:
|
||||
/// is found.
|
||||
string_view parseColorSpaceFromString(string_view str) const;
|
||||
|
||||
/// Turn the name, which could be a color space, an alias, a role, or
|
||||
/// an OIIO-understood universal name (like "sRGB") into a canonical
|
||||
/// color space name. If the name is not recognized, return "".
|
||||
string_view resolve(string_view name) const;
|
||||
|
||||
/// Are the two color space names/aliases/roles equivalent?
|
||||
bool equivalent(string_view color_space,
|
||||
string_view other_color_space) const;
|
||||
|
||||
/// Return a filename or other identifier for the config we're using.
|
||||
std::string configname() const;
|
||||
|
||||
@@ -313,6 +340,13 @@ public:
|
||||
/// OCIO support is available.
|
||||
static int OpenColorIO_version_hex();
|
||||
|
||||
/// Return a default ColorConfig, which is a singleton that will be
|
||||
/// created the first time it is needed. It will be initialized with the
|
||||
/// OCIO environment variable, if it exists, or the OCIO built-in config
|
||||
/// (for OCIO >= 2.2). If neither of those is possible, it will be
|
||||
/// initialized with a built-in minimal config.
|
||||
static const ColorConfig& default_colorconfig();
|
||||
|
||||
private:
|
||||
ColorConfig(const ColorConfig&) = delete;
|
||||
ColorConfig& operator=(const ColorConfig&) = delete;
|
||||
@@ -324,7 +358,8 @@ private:
|
||||
|
||||
|
||||
|
||||
/// Utility -- convert sRGB value to linear
|
||||
/// Utility -- convert sRGB value to linear transfer function, without
|
||||
/// any change in color primaries.
|
||||
/// http://en.wikipedia.org/wiki/SRGB
|
||||
inline float
|
||||
sRGB_to_linear(float x)
|
||||
@@ -344,7 +379,8 @@ sRGB_to_linear(const simd::vfloat4& x)
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Utility -- convert linear value to sRGB
|
||||
/// Utility -- convert linear value to sRGB transfer function, without
|
||||
/// any change in color primaries.
|
||||
inline float
|
||||
linear_to_sRGB(float x)
|
||||
{
|
||||
@@ -354,7 +390,8 @@ linear_to_sRGB(float x)
|
||||
|
||||
|
||||
#ifndef __CUDA_ARCH__
|
||||
/// Utility -- convert linear value to sRGB
|
||||
/// Utility -- convert linear value to sRGB transfer function, without
|
||||
/// any change in color primaries.
|
||||
inline simd::vfloat4
|
||||
linear_to_sRGB(const simd::vfloat4& x)
|
||||
{
|
||||
@@ -365,7 +402,8 @@ linear_to_sRGB(const simd::vfloat4& x)
|
||||
#endif
|
||||
|
||||
|
||||
/// Utility -- convert Rec709 value to linear
|
||||
/// Utility -- convert Rec709 value to linear transfer function, without
|
||||
/// any change in color primaries.
|
||||
/// http://en.wikipedia.org/wiki/Rec._709
|
||||
inline float
|
||||
Rec709_to_linear(float x)
|
||||
@@ -376,7 +414,8 @@ Rec709_to_linear(float x)
|
||||
return powf((x + 0.099f) * (1.0f / 1.099f), (1.0f / 0.45f));
|
||||
}
|
||||
|
||||
/// Utility -- convert linear value to Rec709
|
||||
/// Utility -- convert linear value to Rec709 transfer function, without
|
||||
/// any change in color primaries.
|
||||
inline float
|
||||
linear_to_Rec709(float x)
|
||||
{
|
||||
|
||||
@@ -51,6 +51,9 @@ OIIO_PRAGMA_WARNING_PUSH
|
||||
#if OIIO_GNUC_VERSION >= 70000
|
||||
# pragma GCC diagnostic ignored "-Wmaybe-uninitialized"
|
||||
#endif
|
||||
#if OIIO_GNUC_VERSION >= 130000
|
||||
# pragma GCC diagnostic ignored "-Wdangling-reference"
|
||||
#endif
|
||||
#if OIIO_INTEL_LLVM_COMPILER
|
||||
# pragma GCC diagnostic ignored "-Wtautological-constant-compare"
|
||||
#endif
|
||||
|
||||
@@ -247,8 +247,19 @@ OIIO_UTIL_API int open (string_view path, int flags);
|
||||
|
||||
/// Read the entire contents of the named text file (as a UTF-8 encoded
|
||||
/// filename) and place it in str, returning true on success, false on
|
||||
/// failure.
|
||||
OIIO_UTIL_API bool read_text_file (string_view filename, std::string &str);
|
||||
/// failure. The optional size parameter gives the maximum amount to read
|
||||
/// (for memory safety) and defaults to 16MB. Set size to 0 for no limit
|
||||
/// (use at your own risk).
|
||||
OIIO_UTIL_API bool read_text_file(string_view filename, std::string &str,
|
||||
size_t size = (1UL << 24));
|
||||
|
||||
/// Run a command line process and capture its console output in `str`,
|
||||
/// returning true on success, false on failure. The optional size parameter
|
||||
/// gives the maximum amount to read (for memory safety) and defaults to 16MB.
|
||||
/// Set size to 0 for no limit (use at your own risk).
|
||||
OIIO_UTIL_API bool read_text_from_command(string_view command,
|
||||
std::string &str,
|
||||
size_t size = (1UL << 24));
|
||||
|
||||
/// Write the entire contents of the string `str` to the named file (UTF-8
|
||||
/// encoded), overwriting any prior contents of the file (if it existed),
|
||||
|
||||
@@ -789,8 +789,7 @@ OIIO_FORCEINLINE OIIO_HOSTDEVICE OUT_TYPE bit_cast (const IN_TYPE& in) {
|
||||
|
||||
#if defined(__x86_64__) && !defined(__CUDA_ARCH__) && \
|
||||
(defined(__INTEL_COMPILER) || defined(__INTEL_LLVM_COMPILER) \
|
||||
|| OIIO_CLANG_VERSION >= 100000 || OIIO_APPLE_CLANG_VERSION >= 130000 \
|
||||
|| OIIO_GCC_VERSION >= 90300)
|
||||
|| OIIO_CLANG_VERSION >= 100000 || OIIO_APPLE_CLANG_VERSION >= 130000)
|
||||
// On x86/x86_64 for certain compilers we can use Intel CPU intrinsics for
|
||||
// some common bitcast cases that might be even more understandable to the
|
||||
// compiler and generate better code without its getting confused about the
|
||||
|
||||
@@ -80,7 +80,12 @@ inline uint64_t fasthash64(const void *buf, size_t len, uint64_t seed=1771)
|
||||
uint64_t v;
|
||||
|
||||
while (pos != end) {
|
||||
// This appears to be a false positive which only affects GCC.
|
||||
// https://godbolt.org/z/5q7Y7ndfb
|
||||
OIIO_PRAGMA_WARNING_PUSH
|
||||
OIIO_GCC_ONLY_PRAGMA(GCC diagnostic ignored "-Wmaybe-uninitialized")
|
||||
v = *pos++;
|
||||
OIIO_PRAGMA_WARNING_PUSH
|
||||
h ^= mix(v);
|
||||
h *= m;
|
||||
}
|
||||
|
||||
@@ -679,6 +679,9 @@ bool OIIO_API resize (ImageBuf &dst, const ImageBuf &src, Filter2D *filter,
|
||||
/// For "deep" images, this function returns copies the closest source pixel
|
||||
/// needed, rather than attempting to interpolate deep pixels (regardless of
|
||||
/// the value of `interpolate`).
|
||||
///
|
||||
/// @see ImageBufAlgo::resize()
|
||||
|
||||
ImageBuf OIIO_API resample (const ImageBuf &src, bool interpolate = true,
|
||||
ROI roi={}, int nthreads=0);
|
||||
/// Write to an existing image `dst` (allocating if it is uninitialized).
|
||||
@@ -790,6 +793,27 @@ bool OIIO_API warp (ImageBuf &dst, const ImageBuf &src, M33fParam M,
|
||||
const Filter2D *filter, bool recompute_roi = false,
|
||||
ImageBuf::WrapMode wrap = ImageBuf::WrapDefault,
|
||||
ROI roi = {}, int nthreads=0);
|
||||
|
||||
#ifdef OIIO_INTERNAL /* experimental -- not part of public API yet */
|
||||
ImageBuf OIIO_API warp (const ImageBuf &src, M33fParam M,
|
||||
string_view filtername,
|
||||
float filterwidth, bool recompute_roi,
|
||||
ImageBuf::WrapMode wrap, bool edgeclamp,
|
||||
ROI roi={}, int nthreads=0);
|
||||
ImageBuf OIIO_API warp (const ImageBuf &src, M33fParam M,
|
||||
const Filter2D *filter, bool recompute_roi,
|
||||
ImageBuf::WrapMode wrap, bool edgeclamp,
|
||||
ROI roi = {}, int nthreads=0);
|
||||
bool OIIO_API warp (ImageBuf &dst, const ImageBuf &src, M33fParam M,
|
||||
string_view filtername,
|
||||
float filterwidth, bool recompute_roi,
|
||||
ImageBuf::WrapMode wrap, bool edgeclamp,
|
||||
ROI roi={}, int nthreads=0);
|
||||
bool OIIO_API warp (ImageBuf &dst, const ImageBuf &src, M33fParam M,
|
||||
const Filter2D *filter, bool recompute_roi,
|
||||
ImageBuf::WrapMode wrap, bool edgeclamp,
|
||||
ROI roi = {}, int nthreads=0);
|
||||
#endif // OIIO_INTERNAL
|
||||
/// @}
|
||||
|
||||
|
||||
@@ -1004,6 +1028,38 @@ ImageBuf OIIO_API pow (const ImageBuf &A, cspan<float> B,
|
||||
bool OIIO_API pow (ImageBuf &dst, const ImageBuf &A, cspan<float> B,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
/// Normalize a 3D vector texture (i.e., divide each pixel by its length).
|
||||
/// This function assumes a 3-channel image that represents a 3-vector, or a
|
||||
/// 4-channel image that represents a 3-vector plus an alpha value. If an
|
||||
/// alpha channel is present, its value is merely copied, and is not part of
|
||||
/// the normalization computation. If the destination has no alpha channel but
|
||||
/// the sources do, the alpha channel will be dropped.
|
||||
///
|
||||
/// `inCenter` and `outCenter` define the pixel value that corresponds to a
|
||||
/// 0.0 vector value for input and output, respectively. `scale` defines the
|
||||
/// scale factor to apply to the normalized vectors.
|
||||
///
|
||||
/// Thus, if the input image encodes vector components into [0,1] range pixel
|
||||
/// values so that a pixel value 0.5 indicates a 0-length vector, then you
|
||||
/// should use `inCenter=0.5`, whereas if they are already using the full
|
||||
/// range (0.0 is encoded as 0.0), then you want `inCenter=0.0`. Similarly, if
|
||||
/// you want the output normalized vectors to be in the range [0,1], use
|
||||
/// `outCenter=0.5` and `scale=0.5`, but if you want them to be in the range
|
||||
/// [-1,1], use `outCenter=0.0` and `scale=1.0` (this probably will only work
|
||||
/// if you intend to write the results in `float` or `half` format).
|
||||
///
|
||||
/// Expressed another way, the computation is conceptually:
|
||||
///
|
||||
/// out = outCenter + scale * (in - inCenter) / length(in - inCenter)
|
||||
///
|
||||
bool OIIO_API normalize(ImageBuf& dst, const ImageBuf& A, float inCenter=0.0f,
|
||||
float outCenter=0.0f, float scale=1.0f,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
ImageBuf OIIO_API normalize(const ImageBuf& A, float inCenter=0.0f,
|
||||
float outCenter=0.0, float scale=1.0f,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
|
||||
/// Converts a multi-channel image into a one-channel image via a weighted
|
||||
/// sum of channels:
|
||||
@@ -1827,7 +1883,7 @@ bool OIIO_API erode (ImageBuf &dst, const ImageBuf &src,
|
||||
ImageBuf OIIO_API colorconvert (const ImageBuf &src,
|
||||
string_view fromspace, string_view tospace, bool unpremult=true,
|
||||
string_view context_key="", string_view context_value="",
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
/// Transform using a ColorProcessor, returning an ImageBuf result.
|
||||
@@ -1838,7 +1894,7 @@ ImageBuf OIIO_API colorconvert (const ImageBuf &src,
|
||||
bool OIIO_API colorconvert (ImageBuf &dst, const ImageBuf &src,
|
||||
string_view fromspace, string_view tospace, bool unpremult=true,
|
||||
string_view context_key="", string_view context_value="",
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
/// Transform using a ColorProcessor, storing reults into an existing ImageBuf.
|
||||
@@ -1928,14 +1984,14 @@ ImageBuf OIIO_API ociolook (const ImageBuf &src, string_view looks,
|
||||
string_view fromspace, string_view tospace,
|
||||
bool unpremult=true, bool inverse=false,
|
||||
string_view context_key="", string_view context_value="",
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
/// Write to an existing image `dst` (allocating if it is uninitialized).
|
||||
bool OIIO_API ociolook (ImageBuf &dst, const ImageBuf &src, string_view looks,
|
||||
string_view fromspace, string_view tospace,
|
||||
bool unpremult=true, bool inverse=false,
|
||||
string_view context_key="", string_view context_value="",
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
|
||||
@@ -1983,19 +2039,38 @@ bool OIIO_API ociolook (ImageBuf &dst, const ImageBuf &src, string_view looks,
|
||||
ImageBuf OIIO_API ociodisplay (const ImageBuf &src,
|
||||
string_view display, string_view view,
|
||||
string_view fromspace="", string_view looks="",
|
||||
bool unpremult=true,
|
||||
bool unpremult=true, bool inverse=false,
|
||||
string_view context_key="", string_view context_value="",
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
/// Write to an existing image `dst` (allocating if it is uninitialized).
|
||||
bool OIIO_API ociodisplay (ImageBuf &dst, const ImageBuf &src,
|
||||
string_view display, string_view view,
|
||||
string_view fromspace="", string_view looks="",
|
||||
bool unpremult=true,
|
||||
bool unpremult=true, bool inverse=false,
|
||||
string_view context_key="", string_view context_value="",
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
#ifndef OIIO_DOXYGEN
|
||||
// OIIO_DEPRECATED("prefer the kind that takes an `inverse` parameter (2.5)")
|
||||
ImageBuf OIIO_API ociodisplay (const ImageBuf &src,
|
||||
string_view display, string_view view,
|
||||
string_view fromspace, string_view looks,
|
||||
bool unpremult,
|
||||
string_view context_key, string_view context_value="",
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
// OIIO_DEPRECATED("prefer the kind that takes an `inverse` parameter (2.5)")
|
||||
bool OIIO_API ociodisplay (ImageBuf &dst, const ImageBuf &src,
|
||||
string_view display, string_view view,
|
||||
string_view fromspace, string_view looks,
|
||||
bool unpremult,
|
||||
string_view context_key, string_view context_value="",
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
#endif
|
||||
|
||||
|
||||
/// Return the pixels of `src` within the ROI, applying an OpenColorIO
|
||||
/// "file" transform. In-place operations (`dst` == `src`) are supported.
|
||||
@@ -2023,13 +2098,13 @@ bool OIIO_API ociodisplay (ImageBuf &dst, const ImageBuf &src,
|
||||
ImageBuf OIIO_API ociofiletransform (const ImageBuf &src,
|
||||
string_view name,
|
||||
bool unpremult=true, bool inverse=false,
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
/// Write to an existing image `dst` (allocating if it is uninitialized).
|
||||
bool OIIO_API ociofiletransform (ImageBuf &dst, const ImageBuf &src,
|
||||
string_view name,
|
||||
bool unpremult=true, bool inverse=false,
|
||||
ColorConfig *colorconfig=nullptr,
|
||||
const ColorConfig* colorconfig = nullptr,
|
||||
ROI roi={}, int nthreads=0);
|
||||
|
||||
|
||||
|
||||
@@ -134,6 +134,11 @@ IBAprep(ROI& roi, ImageBuf* dst, const ImageBuf* A, int prepflags)
|
||||
{
|
||||
return IBAprep(roi, dst, A, NULL, NULL, NULL, prepflags);
|
||||
}
|
||||
inline bool
|
||||
IBAprep(ROI& roi, ImageBuf* dst, int prepflags)
|
||||
{
|
||||
return IBAprep(roi, dst, nullptr, nullptr, nullptr, nullptr, prepflags);
|
||||
}
|
||||
|
||||
|
||||
// clang-format off
|
||||
@@ -155,6 +160,7 @@ enum IBAprep_flags {
|
||||
IBAprep_MINIMIZE_NCHANNELS = 1<<14, // Multi-inputs get min(nchannels)
|
||||
IBAprep_REQUIRE_MATCHING_CHANNELS = 1<<15, // Channel names must match
|
||||
IBAprep_MERGE_METADATA = 1 << 16, // Merge all inputs' metadata
|
||||
IBAprep_FILL_ZERO_ALLOC = 1 << 17, // Fill with 0 if we alloc space
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
|
||||
OIIO_NAMESPACE_BEGIN
|
||||
|
||||
// Forward declaration
|
||||
class TextureOpt;
|
||||
|
||||
namespace pvt {
|
||||
// Forward declaration
|
||||
class ImageCacheImpl;
|
||||
@@ -222,6 +225,11 @@ public:
|
||||
/// enabled, this reduces the number of file opens, at the
|
||||
/// expense of not being able to open files if their format do
|
||||
/// not actually match their filename extension). Default: 0
|
||||
/// - `string colorspace` :
|
||||
/// The working colorspace of the texture system. Default: none.
|
||||
/// - `string colorconfig` :
|
||||
/// Name of the OCIO config to use. Default: "" (meaning to use
|
||||
/// the default color config).
|
||||
///
|
||||
/// - `string options`
|
||||
/// This catch-all is simply a comma-separated list of
|
||||
@@ -473,18 +481,22 @@ public:
|
||||
/// internals.
|
||||
typedef pvt::ImageCacheFile ImageHandle;
|
||||
|
||||
/// Retrieve an opaque handle for fast image lookups. The filename is
|
||||
/// presumed to be UTF-8 encoded. The opaque `pointer thread_info` is
|
||||
/// thread-specific information returned by `get_perthread_info()`.
|
||||
/// Return NULL if something has gone horribly wrong.
|
||||
virtual ImageHandle* get_image_handle (ustring filename,
|
||||
Perthread *thread_info=NULL) = 0;
|
||||
/// Retrieve an opaque handle for fast texture lookups, or nullptr upon
|
||||
/// failure. The filename is presumed to be UTF-8 encoded. The `options`,
|
||||
/// if not null, may be used to create a separate handle for certain
|
||||
/// texture option choices. (Currently unused, but reserved for the future
|
||||
/// or for alternate IC implementations.) The opaque pointer `thread_info`
|
||||
/// is thread-specific information returned by `get_perthread_info()`.
|
||||
virtual ImageHandle* get_image_handle(ustring filename,
|
||||
Perthread* thread_info = nullptr,
|
||||
const TextureOpt* options = nullptr) = 0;
|
||||
|
||||
/// Get an ImageHandle using a UTF-16 encoded wstring filename.
|
||||
ImageHandle* get_image_handle (const std::wstring& filename,
|
||||
Perthread *thread_info=NULL) {
|
||||
return get_image_handle (ustring(Strutil::utf16_to_utf8(filename)),
|
||||
thread_info);
|
||||
ImageHandle* get_image_handle(const std::wstring& filename,
|
||||
Perthread* thread_info = nullptr,
|
||||
const TextureOpt* options = nullptr) {
|
||||
return get_image_handle(ustring(Strutil::utf16_to_utf8(filename)),
|
||||
thread_info, options);
|
||||
}
|
||||
|
||||
/// Return true if the image handle (previously returned by
|
||||
|
||||
@@ -1003,6 +1003,10 @@ public:
|
||||
/// Does this format reader support retrieving a reduced
|
||||
/// resolution copy of the image via the `thumbnail()` method?
|
||||
///
|
||||
/// - `"noimage"` :
|
||||
/// Does this format allow 0x0 sized images, i.e. an image file
|
||||
/// with metadata only and no pixels?
|
||||
///
|
||||
/// This list of queries may be extended in future releases. Since this
|
||||
/// can be done simply by recognizing new query strings, and does not
|
||||
/// require any new API entry points, addition of support for new
|
||||
@@ -1025,11 +1029,24 @@ public:
|
||||
/// `true` upon success, or `false` upon failure.
|
||||
virtual bool valid_file (const std::string& filename) const;
|
||||
|
||||
/// Check valid vile using a UTF-16 encoded wstring filename.
|
||||
/// Check valid file using a UTF-16 encoded wstring filename.
|
||||
bool valid_file (const std::wstring& filename) const {
|
||||
return valid_file(Strutil::utf16_to_utf8(filename));
|
||||
}
|
||||
|
||||
/// Return true if the `ioproxy` represents a file of the type for this
|
||||
/// ImageInput. The implementation will try to determine this as
|
||||
/// efficiently as possible, in most cases much less expensively than
|
||||
/// doing a full `open()`. Note that there can be false positives: a
|
||||
/// file can appear to be of the right type (i.e., `valid_file()`
|
||||
/// returning `true`) but still fail a subsequent call to `open()`, such
|
||||
/// as if the contents of the file are truncated, nonsensical, or
|
||||
/// otherwise corrupted.
|
||||
///
|
||||
/// @returns
|
||||
/// `true` upon success, or `false` upon failure.
|
||||
virtual bool valid_file (Filesystem::IOProxy* ioproxy) const;
|
||||
|
||||
/// Opens the file with given name and seek to the first subimage in the
|
||||
/// file. Various file attributes are put in `newspec` and a copy
|
||||
/// is also saved internally to the `ImageInput` (retrievable via
|
||||
@@ -1805,6 +1822,53 @@ protected:
|
||||
/// Helper: retrieve the current position of the proxy, akin to ftell.
|
||||
int64_t iotell() const;
|
||||
|
||||
/// Helper: convenience boilerplate for several checks and operations that
|
||||
/// every implementation of ImageInput::open() will need to do. Failure is
|
||||
/// presumed to indicate a file that is corrupt (or perhaps maliciously
|
||||
/// crafted) and no further reading should be attempted.
|
||||
///
|
||||
/// @param spec
|
||||
/// The ImageSpec that we are validating.
|
||||
///
|
||||
/// @param range
|
||||
/// An ROI that describes the allowable pixel coordinates and channel
|
||||
/// indices as half-open intervals. For example, the default value
|
||||
/// `{0, 65535, 0, 65535, 0, 1, 0, 4}` means that pixel coordinates
|
||||
/// must be non-negative and the width and height be representable by
|
||||
/// a uint16 value, up to 4 channels are allowed, and volumes are not
|
||||
/// permitted (z coordinate may only be 0). File formats that can
|
||||
/// handle larger resolutions, or volumes, or >4 channels must
|
||||
/// override these limits!
|
||||
///
|
||||
/// @param flags
|
||||
/// A bitfield flag (bits defined by `enum OpenChecks`) that can
|
||||
/// indicate additional checks to perform, or checks that should be
|
||||
/// skipped.
|
||||
///
|
||||
/// @returns
|
||||
/// Return `true` if the spec is valid and passes all checks,
|
||||
/// otherwise return `false` and make appropriate calls to
|
||||
/// this->errorfmt() to record the errors.
|
||||
///
|
||||
/// Checks performed include:
|
||||
///
|
||||
/// * Whether the resolution and channel count are within the range
|
||||
/// implied by `range`.
|
||||
/// * Whether the channel count is within the `"limit:channels"` OIIO
|
||||
/// attribute.
|
||||
/// * The total uncompressed pixel data size is expected to be within the
|
||||
/// `"limit:imagesize_MB"` OIIO attribute.
|
||||
///
|
||||
bool check_open (const ImageSpec &spec,
|
||||
ROI range = {0, 65535, 0, 65535, 0, 1, 0, 4},
|
||||
uint64_t flags = 0);
|
||||
|
||||
/// Bit field definitions for the `flags` argument to `check_open()`.
|
||||
enum class OpenChecks : uint64_t {
|
||||
Defaults = 0,
|
||||
// Reserved for future use
|
||||
};
|
||||
|
||||
/// @}
|
||||
|
||||
private:
|
||||
@@ -2019,6 +2083,10 @@ public:
|
||||
/// thumbnail must be supplied immediately after `open()`, prior
|
||||
/// to any of the `write_*()` calls.)
|
||||
///
|
||||
/// - `"noimage"` :
|
||||
/// Does this format allow 0x0 sized images, i.e. an image file
|
||||
/// with metadata only and no pixels?
|
||||
///
|
||||
/// This list of queries may be extended in future releases. Since this
|
||||
/// can be done simply by recognizing new query strings, and does not
|
||||
/// require any new API entry points, addition of support for new
|
||||
@@ -2490,6 +2558,102 @@ public:
|
||||
typedef ImageOutput* (*Creator)();
|
||||
|
||||
protected:
|
||||
/// @{
|
||||
/// @name Helper functions for ImageOutput implementations.
|
||||
///
|
||||
/// This set of utility functions are not meant to be called by user code.
|
||||
/// They are protected methods of ImageOutput, and are used internally by
|
||||
/// the ImageOutput implementation to help it properly implement support
|
||||
/// of IOProxy.
|
||||
///
|
||||
|
||||
/// Helper: convenience boilerplate for several checks and operations that
|
||||
/// every implementation of ImageOutput::open() will need to do.
|
||||
///
|
||||
/// 1. Check if the open `mode` is one allowed by `supports("multiimage")`
|
||||
/// and `supports("mipmap")`.
|
||||
/// 2. Copy the passed spec to the internal m_spec.
|
||||
/// 3. Do all possible validity checks based on `supports()` (for example,
|
||||
/// is the request to write volumetric data but the format writer
|
||||
/// doesn't support it).
|
||||
///
|
||||
/// Returns true if ok, false if the open request can't be satisfied (and
|
||||
/// makes appropriate calls to this->errorfmt() to record the errors).
|
||||
///
|
||||
/// Having a central helper method for this is beneficial:
|
||||
///
|
||||
/// * Less repeated code in the many open() implementations, which also
|
||||
/// means less opportunity for bugs.
|
||||
/// * Ensures that all image writers perform the full set of possible
|
||||
/// validity checks.
|
||||
/// * Ensures that error messages are consistent across all writers and
|
||||
/// can be improved in a single location.
|
||||
/// * Better code coverage for testing, because the error handling that is
|
||||
/// done centrally means we don't need to separately test every possible
|
||||
/// error condition in every writer.
|
||||
///
|
||||
/// @param mode
|
||||
/// The mode in which the file is to be opened (`Create`,
|
||||
/// `AppendSubimage`, or `AppendMIPLevel`).
|
||||
///
|
||||
/// @param spec
|
||||
/// The ImageSpec that we are validating.
|
||||
///
|
||||
/// @param range
|
||||
/// An ROI that describes the allowable pixel coordinates and channel
|
||||
/// indices as half-open intervals. For example, the default value
|
||||
/// `{0, 65535, 0, 65535, 0, 1, 0, 4}` means that pixel coordinates
|
||||
/// must be non-negative and the width and height be representable by
|
||||
/// a uint16 value, up to 4 channels are allowed, and volumes are not
|
||||
/// permitted (z coordinate may only be 0). File formats that can
|
||||
/// handle larger resolutions, or volumes, or >4 channels must
|
||||
/// override these limits!
|
||||
///
|
||||
/// @param flags
|
||||
/// A bitfield flag (bits defined by `enum OpenChecks`) that can
|
||||
/// indicate additional checks to perform, or checks that should be
|
||||
/// skipped.
|
||||
///
|
||||
/// @returns
|
||||
/// Return `true` if the spec is valid and passes all checks,
|
||||
/// otherwise return `false` and make appropriate calls to
|
||||
/// this->errorfmt() to record the errors.
|
||||
///
|
||||
/// Checks performed include:
|
||||
///
|
||||
/// * Whether the open `mode` is one allowed by `supports("multiimage")`
|
||||
/// and `supports("mipmap")`.
|
||||
/// * Whether the resolution and channel count is within the range
|
||||
/// implied by `range`. If `spec.depth < 1`, it will be set to 1.
|
||||
/// * Whether the request for volumes or deep images can be accommodated
|
||||
/// by the format (according to its `supports()` queries).
|
||||
/// * If per-channel data types are supplied (and not all the same), but
|
||||
/// but the file format does not not `supports("channelformats")`. If
|
||||
/// `spec.channelformats` is used but all formats are equal, then
|
||||
/// the `channelformats` vector will be cleared and only `spec.format`
|
||||
/// will be used.
|
||||
/// * If any of the "full" size fields are negative or zero, they will be
|
||||
/// set to the corresponding pixel data size fields.
|
||||
/// * Whether the pixel origin offset (`spec.x`, `spec.y`, `spec.z`) is
|
||||
/// allowed to be non-zero (according to `supports("origin")` or
|
||||
/// negative (`supports("negativeorigin")`) -- if it is not allowed,
|
||||
/// it is an error if flags includes `Strict`, otherwise it will simply
|
||||
/// be adjusted to 0.
|
||||
/// * Whether the `extra_attribs` contains a request to use an IOProxy,
|
||||
/// but the format writer does not report `supports("ioproxy")`.
|
||||
bool check_open(OpenMode mode, const ImageSpec &spec,
|
||||
ROI range = {0, 65535, 0, 65535, 0, 1, 0, 4},
|
||||
uint64_t flags = 0);
|
||||
|
||||
/// Bit field definitions for the `flags` argument to `check_open()`.
|
||||
enum class OpenChecks : uint64_t {
|
||||
Defaults = 0,
|
||||
Disallow1Channel = 1,
|
||||
Disallow2Channel = 2,
|
||||
Disallow1or2Channel = Disallow1Channel | Disallow2Channel,
|
||||
Strict = (uint64_t(1) << 32)
|
||||
};
|
||||
|
||||
/// Helper routines used by write_* implementations: convert data (in
|
||||
/// the given format and stride) to the "native" format of the file
|
||||
/// (described by the 'spec' member variable), in contiguous order. This
|
||||
@@ -2545,13 +2709,15 @@ protected:
|
||||
void *image_buffer,
|
||||
TypeDesc buf_format = TypeDesc::UNKNOWN);
|
||||
|
||||
/// @}
|
||||
|
||||
/// @{
|
||||
/// @name IOProxy aids for ImageInput implementations.
|
||||
/// @name IOProxy aids for ImageOutput implementations.
|
||||
///
|
||||
/// This set of utility functions are not meant to be called by user code.
|
||||
/// They are protected methods of ImageInput, and are used internally by
|
||||
/// the ImageInput implementation to help it properly implement support of
|
||||
/// IOProxy.
|
||||
/// They are protected methods of ImageOutput, and are used internally by
|
||||
/// the ImageOutput implementation to help it properly implement support
|
||||
/// of IOProxy.
|
||||
///
|
||||
|
||||
/// Get the IOProxy being used underneath.
|
||||
@@ -2590,8 +2756,8 @@ protected:
|
||||
/// Helper: retrieve the current position of the proxy, akin to ftell.
|
||||
int64_t iotell() const;
|
||||
|
||||
// Write a formatted string to the output proxy. Return true on success,
|
||||
// false upon failure and issue an error message.
|
||||
/// Write a formatted string to the output proxy. Return true on success,
|
||||
/// false upon failure and issue an error message.
|
||||
template<typename Str, typename... Args>
|
||||
inline bool iowritefmt(const Str& fmt, Args&&... args)
|
||||
{
|
||||
@@ -2619,6 +2785,13 @@ private:
|
||||
|
||||
// Utility functions
|
||||
|
||||
/// `OIIO::shutdown` prepares OpenImageIO for shutdown. Before exiting an
|
||||
/// application that utilizes OpenImageIO the `OIIO::shutdown` function must be
|
||||
/// called, which will perform shutdown of any running thread-pools. Failing
|
||||
/// to call `OIIO::shutdown` could lead to a sporadic dead-lock during
|
||||
/// application shutdown on certain platforms such as Windows.
|
||||
OIIO_API void shutdown ();
|
||||
|
||||
/// Returns a numeric value for the version of OpenImageIO, 10000 for each
|
||||
/// major version, 100 for each minor version, 1 for each patch. For
|
||||
/// example, OpenImageIO 1.2.3 would return a value of 10203. One example of
|
||||
@@ -2789,7 +2962,7 @@ OIIO_API std::string geterror(bool clear = true);
|
||||
/// you should raise this limit. Setting the limit to 0 means having no
|
||||
/// limit.
|
||||
///
|
||||
/// - `int log_times`
|
||||
/// - `int log_times` (0)
|
||||
///
|
||||
/// When the `"log_times"` attribute is nonzero, `ImageBufAlgo` functions
|
||||
/// are instrumented to record the number of times they were called and
|
||||
@@ -2807,6 +2980,20 @@ OIIO_API std::string geterror(bool clear = true);
|
||||
/// the log information. When the `log_times` attribute is disabled,
|
||||
/// there is no additional performance cost.
|
||||
///
|
||||
/// - `imagebuf:print_uncaught_errors` (1)
|
||||
///
|
||||
/// If nonzero, an `ImageBuf` upon destruction will print any error messages
|
||||
/// that were never retrieved by its `geterror()` method. While this may
|
||||
/// seem chaotic, we are presuming that any well-written library or
|
||||
/// application will proactively check error codes and retrieve errors, so
|
||||
/// will never print anything upon destruction. But for less sophisticated
|
||||
/// applications (or users), this is very useful for forcing display of
|
||||
/// error messages so that users can see relevant errors even if they never
|
||||
/// check them explicitly, thus self-diagnose their troubles before asking
|
||||
/// the project dev deam for help. Advanced users who for some reason desire
|
||||
/// to neither retrieve errors themselves nor have them printed in this
|
||||
/// manner can disable the behavior by setting this attribute to 0.
|
||||
///
|
||||
OIIO_API bool attribute(string_view name, TypeDesc type, const void* val);
|
||||
|
||||
/// Shortcut attribute() for setting a single integer.
|
||||
@@ -2863,8 +3050,14 @@ inline bool attribute (string_view name, string_view val) {
|
||||
///
|
||||
/// "tiff:LIBTIFF 4.0.4;gif:gif_lib 4.2.3;openexr:OpenEXR 2.2.0"
|
||||
///
|
||||
/// - string "timing_report"
|
||||
/// A string containing the report of all the log_times.
|
||||
/// - `string font_list`
|
||||
/// - `string font_file_list`
|
||||
/// - `string font_dir_list`
|
||||
///
|
||||
/// A semicolon-separated list of, respectively, all the fonts that
|
||||
/// OpenImageIO can find, all the font files that OpenImageIO can find (with
|
||||
/// full paths), and all the directories that OpenImageIO will search for
|
||||
/// fonts. (Added in OpenImageIO 2.5)
|
||||
///
|
||||
/// - `string opencolorio_version`
|
||||
///
|
||||
|
||||
@@ -88,6 +88,29 @@
|
||||
OIIO_VERSION_MINOR, OIIO_VERSION_PATCH, \
|
||||
OIIO_VERSION_TWEAK, "")
|
||||
|
||||
// OIIO_DISABLE_DEPRECATED encodes the version for which any declarations that
|
||||
// were deprecated as of that version may be hidden from view of software
|
||||
// including the OIIO headers. For example, if a downstream project says
|
||||
//
|
||||
// #define OIIO_DISABLE_DEPRECATED OIIO_MAKE_VERSION(2,2,0)
|
||||
//
|
||||
// before including any OpenImageIO header, then we will do our best to make
|
||||
// it a compile-time error if they try to use anything that was deprecated
|
||||
// in or before version 2.2.0. This is viewed as equivalent to the downstream
|
||||
// package considering their minimum OIIO to be 2.2 and they want to be sure
|
||||
// they aren't using any features that are slated for deprecation. The
|
||||
// default, 0, will not try to hide any deprecated features.
|
||||
//
|
||||
// To clarify, if version 2.2 is the first to deprecate a certain definition,
|
||||
// then it is considered good practice to guard it like this:
|
||||
//
|
||||
// #if OIIO_DISABLE_DEPRECATED < OIIO_MAKE_VERSION(2,2,0)
|
||||
// ... deprecated definition here ...
|
||||
// #endif
|
||||
//
|
||||
#ifndef OIIO_DISABLE_DEPRECATED
|
||||
# define OIIO_DISABLE_DEPRECATED 0
|
||||
#endif
|
||||
|
||||
// Establish the name spaces
|
||||
namespace @PROJ_NAMESPACE_V@ { }
|
||||
|
||||
@@ -110,6 +110,11 @@ public:
|
||||
: ParamValue(_name, ustring(value))
|
||||
{
|
||||
}
|
||||
ParamValue(string_view _name, ustringhash value) noexcept
|
||||
{
|
||||
init_noclear(ustring(_name), TypeDesc::USTRINGHASH, 1, &value,
|
||||
Copy(true));
|
||||
}
|
||||
|
||||
// Set from string -- parse
|
||||
ParamValue(string_view _name, TypeDesc type, string_view value);
|
||||
|
||||
@@ -38,29 +38,15 @@
|
||||
# include <malloc.h> // for alloca
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# ifndef VC_EXTRALEAN
|
||||
# define VC_EXTRALEAN
|
||||
# endif
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
# ifndef NOGDI
|
||||
# define NOGDI
|
||||
# endif
|
||||
# include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifdef _MSC_VER
|
||||
# include <intrin.h>
|
||||
#endif
|
||||
|
||||
//Avoid min and max being defined
|
||||
#if defined(_WIN32)
|
||||
#define NOMINMAX
|
||||
// Avoid min and max being defined for any subsequent include of windows.h
|
||||
#ifdef _WIN32
|
||||
# ifndef NOMINMAX
|
||||
# define NOMINMAX
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#include <OpenImageIO/oiioversion.h>
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
/// Additional web resources:
|
||||
/// http://www.codersnotes.com/notes/maths-lib-2016/
|
||||
/// https://www.agner.org/optimize/
|
||||
/// https://www.corsix.org/content/converting-fp32-to-fp16
|
||||
|
||||
// clang-format off
|
||||
|
||||
@@ -292,7 +293,11 @@ class vbool16;
|
||||
class vint16;
|
||||
class vfloat16;
|
||||
|
||||
#if OIIO_DISABLE_DEPRECATED < OIIO_MAKE_VERSION(1,9,0) && !defined(OIIO_INTERNAL)
|
||||
// Deprecated names -- remove these in 1.9
|
||||
// These are removed from visibility for the OIIO codebase itself, or for any
|
||||
// downstream project that defines OIIO_DISABLE_DEPRECATED to exclude
|
||||
// declarations deprecated as of version 1.9 or later.
|
||||
typedef vbool4 mask4; // old name
|
||||
typedef vbool4 bool4;
|
||||
typedef vbool8 bool8;
|
||||
@@ -301,6 +306,7 @@ typedef vint8 int8;
|
||||
typedef vfloat3 float3;
|
||||
typedef vfloat4 float4;
|
||||
typedef vfloat8 float8;
|
||||
#endif
|
||||
|
||||
} // namespace simd
|
||||
|
||||
|
||||
@@ -127,11 +127,7 @@ template<typename Str, typename... Args>
|
||||
OIIO_NODISCARD
|
||||
inline std::string format(const Str& fmt, Args&&... args)
|
||||
{
|
||||
#if FMT_VERSION >= 70000
|
||||
return ::fmt::vformat(fmt, ::fmt::make_format_args(args...));
|
||||
#else
|
||||
return ::fmt::format(fmt, args...);
|
||||
#endif
|
||||
}
|
||||
} // namespace fmt
|
||||
|
||||
@@ -371,26 +367,46 @@ std::string OIIO_UTIL_API wordwrap (string_view src, int columns = 80,
|
||||
|
||||
/// Our favorite "string" hash of a length of bytes. Currently, it is just
|
||||
/// a wrapper for an inlined, constexpr (if C++ >= 14), Cuda-safe farmhash.
|
||||
/// It returns a size_t, so will be a 64 bit hash on 64-bit platforms, but
|
||||
/// a 32 bit hash on 32-bit platforms.
|
||||
inline constexpr size_t
|
||||
strhash (size_t len, const char *s)
|
||||
strhash(size_t len, const char *s)
|
||||
{
|
||||
return OIIO::farmhash::inlined::Hash(s, len);
|
||||
}
|
||||
|
||||
|
||||
/// A guaranteed 64-bit string hash on all platforms.
|
||||
inline constexpr uint64_t
|
||||
strhash64(size_t len, const char *s)
|
||||
{
|
||||
return OIIO::farmhash::inlined::Hash64(s, len);
|
||||
}
|
||||
|
||||
|
||||
/// Hash a string_view. This is OIIO's default favorite string hasher.
|
||||
/// Currently, it uses farmhash, is constexpr (for C++14), and works in
|
||||
/// Cuda. This is rigged, though, so that empty strings hash always hash to
|
||||
/// 0 (that isn't what a raw farmhash would give you, but it's a useful
|
||||
/// property, especially for trivial initialization).
|
||||
/// Currently, it uses farmhash, is constexpr (for C++14), and works in Cuda.
|
||||
/// This is rigged, though, so that empty strings hash always hash to 0 (that
|
||||
/// isn't what a raw farmhash would give you, but it's a useful property,
|
||||
/// especially for trivial initialization). It returns a size_t, so will be a
|
||||
/// 64 bit hash on 64-bit platforms, but a 32 bit hash on 32-bit platforms.
|
||||
inline constexpr size_t
|
||||
strhash (string_view s)
|
||||
strhash(string_view s)
|
||||
{
|
||||
return s.length() ? strhash(s.length(), s.data()) : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Hash a string_view, guaranteed 64 bits (even on 32 bit platforms).
|
||||
inline constexpr uint64_t
|
||||
strhash64(string_view s)
|
||||
{
|
||||
return s.length() ? strhash64(s.length(), s.data()) : 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Case-insensitive comparison of strings. For speed, this always uses a
|
||||
/// static locale that doesn't require a mutex. Caveat: the case-sensivive
|
||||
/// `==` of string_view's is about 20x faster than this case-insensitive
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
// Define symbols that let client applications determine if newly added
|
||||
// features are supported.
|
||||
#define OIIO_TEXTURESYSTEM_SUPPORTS_CLOSE 1
|
||||
#define OIIO_TEXTURESYSTEM_SUPPORTS_COLORSPACE 1
|
||||
|
||||
// Is the getattributetype() method present? (Added in 2.5)
|
||||
#define OIIO_TEXTURESYSTEM_SUPPORTS_GETATTRIBUTETYPE 1
|
||||
@@ -232,6 +233,7 @@ public:
|
||||
fill(0.0f), missingcolor(nullptr),
|
||||
time(0.0f), rnd(-1.0f), samples(1),
|
||||
rwrap(WrapDefault), rblur(0.0f), rwidth(1.0f),
|
||||
colortransformid(0),
|
||||
envlayout(0)
|
||||
{ }
|
||||
|
||||
@@ -264,6 +266,8 @@ public:
|
||||
float rblur; ///< Blur amount in the r direction
|
||||
float rwidth; ///< Multiplier for derivatives in r direction
|
||||
|
||||
int colortransformid; ///< Color space id of the texture
|
||||
|
||||
/// Utility: Return the Wrap enum corresponding to a wrap name:
|
||||
/// "default", "black", "clamp", "periodic", "mirror".
|
||||
static Wrap decode_wrapmode(const char* name)
|
||||
@@ -313,9 +317,7 @@ public:
|
||||
alignas(Tex::BatchAlign) float twidth[Tex::BatchWidth];
|
||||
alignas(Tex::BatchAlign) float rwidth[Tex::BatchWidth];
|
||||
// Note: rblur,rwidth only used for volumetric lookups
|
||||
#if OIIO_VERSION_GREATER_EQUAL(2,4,0)
|
||||
alignas(Tex::BatchAlign) float rnd[Tex::BatchWidth];
|
||||
#endif
|
||||
|
||||
// Options that must be the same for all points we're texturing at once
|
||||
int firstchannel = 0; ///< First channel of the lookup
|
||||
@@ -330,6 +332,7 @@ public:
|
||||
int conservative_filter = 1; ///< True: over-blur rather than alias
|
||||
float fill = 0.0f; ///< Fill value for missing channels
|
||||
const float *missingcolor = nullptr; ///< Color for missing texture
|
||||
int colortransformid = 0; ///< Color space id of the texture
|
||||
|
||||
private:
|
||||
// Options set INTERNALLY by libtexture after the options are passed
|
||||
@@ -554,6 +557,10 @@ public:
|
||||
/// - `int max_errors_per_file` :
|
||||
/// Limits how many errors to issue for each file. (default:
|
||||
/// 100)
|
||||
/// - `string colorspace` :
|
||||
/// The working colorspace of the texture system.
|
||||
/// - `string colorconfig` :
|
||||
/// Name of the OCIO config to use (default: "").
|
||||
///
|
||||
/// Texture-specific settings:
|
||||
/// - `matrix44 worldtocommon` / `matrix44 commontoworld` :
|
||||
@@ -791,16 +798,20 @@ public:
|
||||
class TextureHandle;
|
||||
|
||||
/// Retrieve an opaque handle for fast texture lookups. The filename is
|
||||
/// presumed to be UTF-8 encoded. The opaque pointer `thread_info` is
|
||||
/// thread-specific information returned by `get_perthread_info()`.
|
||||
/// Return nullptr if something has gone horribly wrong.
|
||||
virtual TextureHandle* get_texture_handle (ustring filename,
|
||||
Perthread *thread_info=nullptr) = 0;
|
||||
/// presumed to be UTF-8 encoded. The `options`, if not null, may be used
|
||||
/// to create a separate handle for certain texture option choices
|
||||
/// (currently: the colorspace). The opaque pointer `thread_info` is
|
||||
/// thread-specific information returned by `get_perthread_info()`. Return
|
||||
/// nullptr if something has gone horribly wrong.
|
||||
virtual TextureHandle* get_texture_handle(ustring filename,
|
||||
Perthread* thread_info = nullptr,
|
||||
const TextureOpt* options = nullptr) = 0;
|
||||
/// Get a TextureHandle using a UTF-16 encoded wstring filename.
|
||||
TextureHandle* get_texture_handle (const std::wstring& filename,
|
||||
Perthread *thread_info=nullptr) {
|
||||
return get_texture_handle (ustring(Strutil::utf16_to_utf8(filename)),
|
||||
thread_info);
|
||||
TextureHandle* get_texture_handle(const std::wstring& filename,
|
||||
Perthread* thread_info = nullptr,
|
||||
const TextureOpt* options = nullptr) {
|
||||
return get_texture_handle(ustring(Strutil::utf16_to_utf8(filename)),
|
||||
thread_info, options);
|
||||
}
|
||||
|
||||
/// Return true if the texture handle (previously returned by
|
||||
@@ -813,6 +824,14 @@ public:
|
||||
/// This method was added in OpenImageIO 2.3.
|
||||
virtual ustring filename_from_handle(TextureHandle* handle) = 0;
|
||||
|
||||
/// Retrieve an id for a color transformation by name. This ID can be used
|
||||
/// as the value for TextureOpt::colortransformid. The returned value will
|
||||
/// be -1 if either color space is unknown, and 0 for a null
|
||||
/// transformation.
|
||||
virtual int get_colortransform_id(ustring fromspace,
|
||||
ustring tospace) const = 0;
|
||||
virtual int get_colortransform_id(ustringhash fromspace,
|
||||
ustringhash tospace) const = 0;
|
||||
/// @}
|
||||
|
||||
/// @{
|
||||
@@ -1750,8 +1769,8 @@ public:
|
||||
/// `filenames` will be sized to `ntiles * nvtiles` and filled with the
|
||||
/// the names of the concrete files comprising the atlas, with an empty
|
||||
/// ustring corresponding to any unpopulated tiles (the UDIM set is
|
||||
/// allowed to be sparse). The filename list is indexed as `utile + vtile
|
||||
/// * nvtiles`.
|
||||
/// allowed to be sparse). The filename list is indexed as
|
||||
/// `utile + vtile * nvtiles`.
|
||||
///
|
||||
/// This method was added in OpenImageIO 2.3.
|
||||
virtual void inventory_udim(ustring udimpattern,
|
||||
@@ -1833,6 +1852,9 @@ public:
|
||||
|
||||
virtual ~TextureSystem () { }
|
||||
|
||||
// For testing -- do not use
|
||||
static void unit_test_hash();
|
||||
|
||||
protected:
|
||||
// User code should never directly construct or destruct a TextureSystem.
|
||||
// Always use TextureSystem::create() and TextureSystem::destroy().
|
||||
|
||||
@@ -112,11 +112,19 @@ pause(int delay) noexcept
|
||||
|
||||
#elif defined(_MSC_VER)
|
||||
for (int i = 0; i < delay; ++i) {
|
||||
# if defined(_WIN64)
|
||||
YieldProcessor();
|
||||
# else
|
||||
// A reimplementation of winnt.h YieldProcessor,
|
||||
// to avoid including windows headers.
|
||||
#if defined(_M_AMD64)
|
||||
_mm_pause();
|
||||
#elif defined(_M_ARM64) || defined(_M_HYBRID_X86_ARM64)
|
||||
__dmb(_ARM64_BARRIER_ISHST);
|
||||
__yield();
|
||||
#elif defined(_M_ARM)
|
||||
__dmb(_ARM_BARRIER_ISHST);
|
||||
__yield();
|
||||
#else
|
||||
_asm pause
|
||||
# endif /* _WIN64 */
|
||||
#endif
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -762,10 +770,18 @@ private:
|
||||
|
||||
|
||||
/// Return a reference to the "default" shared thread pool. In almost all
|
||||
/// ordinary circumstances, you should use this exclusively to get a
|
||||
/// single shared thread pool, since creating multiple thread pools
|
||||
/// could result in hilariously over-threading your application.
|
||||
OIIO_UTIL_API thread_pool* default_thread_pool ();
|
||||
/// ordinary circumstances, you should use this exclusively to get a single
|
||||
/// shared thread pool, since creating multiple thread pools could result in
|
||||
/// hilariously over-threading your application. Note that this call may
|
||||
/// (safely, and only once) trigger creation of the thread pool and its
|
||||
/// worker threads if it has not yet been created.
|
||||
OIIO_UTIL_API thread_pool* default_thread_pool();
|
||||
|
||||
/// If a thread pool has been created, this call will safely terminate its
|
||||
/// worker threads. This should presumably be called by an application
|
||||
/// immediately before it exists, when it is confident the thread pool will
|
||||
/// no longer be needed.
|
||||
OIIO_UTIL_API void default_thread_pool_shutdown();
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,6 @@
|
||||
#include <OpenImageIO/strutil.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
//# include <windows.h> // Already done by platform.h
|
||||
#elif defined(__APPLE__)
|
||||
# include <mach/mach_time.h>
|
||||
#else
|
||||
@@ -64,27 +63,32 @@ class OIIO_UTIL_API Timer {
|
||||
public:
|
||||
typedef int64_t ticks_t;
|
||||
enum StartNowVal { DontStartNow, StartNow };
|
||||
enum PrintDtrVal { DontPrintDtr, PrintDtr };
|
||||
enum PrintDtrVal { DontPrintDtr, PrintDtr, PrintCtrDtr };
|
||||
|
||||
/// Constructor -- reset at zero, and start timing unless optional
|
||||
/// 'startnow' argument is false.
|
||||
Timer(StartNowVal startnow = StartNow, PrintDtrVal printdtr = DontPrintDtr,
|
||||
Timer(StartNowVal startnow, PrintDtrVal printdtr = DontPrintDtr,
|
||||
const char* name = NULL)
|
||||
: m_ticking(false)
|
||||
, m_printdtr(printdtr == PrintDtr)
|
||||
, m_printdtr(printdtr == PrintDtr || printdtr == PrintCtrDtr)
|
||||
, m_starttime(0)
|
||||
, m_elapsed_ticks(0)
|
||||
, m_name(name)
|
||||
{
|
||||
if (startnow == StartNow)
|
||||
if (startnow == StartNow) {
|
||||
start();
|
||||
if (printdtr == PrintCtrDtr) {
|
||||
Strutil::print("Starting timer {}\n", (m_name ? m_name : ""),
|
||||
seconds(ticks()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Constructor -- reset at zero, and start timing unless optional
|
||||
/// 'startnow' argument is false.
|
||||
Timer(bool startnow)
|
||||
Timer(bool startnow = true)
|
||||
: m_ticking(false)
|
||||
, m_printdtr(DontPrintDtr)
|
||||
, m_printdtr(false)
|
||||
, m_starttime(0)
|
||||
, m_elapsed_ticks(0)
|
||||
, m_name(NULL)
|
||||
@@ -96,9 +100,9 @@ public:
|
||||
/// Destructor.
|
||||
~Timer()
|
||||
{
|
||||
if (m_printdtr == PrintDtr)
|
||||
Strutil::printf("Timer %s: %gs\n", (m_name ? m_name : ""),
|
||||
seconds(ticks()));
|
||||
if (m_printdtr)
|
||||
Strutil::print("Timer {}: {:g}s\n", (m_name ? m_name : ""),
|
||||
seconds(ticks()));
|
||||
}
|
||||
|
||||
/// Start (or restart) ticking, if we are not currently.
|
||||
@@ -199,23 +203,23 @@ private:
|
||||
/// Platform-dependent grab of current time, expressed as ticks_t.
|
||||
///
|
||||
ticks_t now(void) const
|
||||
{
|
||||
#ifdef _WIN32
|
||||
LARGE_INTEGER n;
|
||||
QueryPerformanceCounter(&n); // From MSDN web site
|
||||
return n.QuadPart;
|
||||
#elif defined(__APPLE__)
|
||||
; // a non-inline function on Windows
|
||||
#else
|
||||
{
|
||||
# if defined(__APPLE__)
|
||||
return mach_absolute_time();
|
||||
#elif OIIO_TIMER_LINUX_USE_clock_gettime
|
||||
# elif OIIO_TIMER_LINUX_USE_clock_gettime
|
||||
struct timespec t;
|
||||
clock_gettime(CLOCK_MONOTONIC, &t);
|
||||
return int64_t(t.tv_sec) * int64_t(1000000000) + t.tv_nsec;
|
||||
#else
|
||||
# else
|
||||
struct timeval t;
|
||||
gettimeofday(&t, NULL);
|
||||
return int64_t(t.tv_sec) * int64_t(1000000) + t.tv_usec;
|
||||
#endif
|
||||
# endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/// Difference between two times, expressed in (platform-dependent)
|
||||
/// ticks.
|
||||
|
||||
@@ -83,6 +83,7 @@ struct OIIO_UTIL_API TypeDesc {
|
||||
DOUBLE, ///< 64-bit IEEE floating point values, (C/C++ `double`).
|
||||
STRING, ///< Character string.
|
||||
PTR, ///< A pointer value.
|
||||
USTRINGHASH, ///< The hash of a ustring
|
||||
LASTBASE
|
||||
};
|
||||
|
||||
@@ -404,6 +405,7 @@ OIIO_INLINE_CONSTEXPR TypeDesc TypeTimeCode (TypeDesc::UINT, TypeDesc::SCALAR, T
|
||||
OIIO_INLINE_CONSTEXPR TypeDesc TypeKeyCode (TypeDesc::INT, TypeDesc::SCALAR, TypeDesc::KEYCODE, 7);
|
||||
OIIO_INLINE_CONSTEXPR TypeDesc TypeRational(TypeDesc::INT, TypeDesc::VEC2, TypeDesc::RATIONAL);
|
||||
OIIO_INLINE_CONSTEXPR TypeDesc TypePointer(TypeDesc::PTR);
|
||||
OIIO_INLINE_CONSTEXPR TypeDesc TypeUstringhash(TypeDesc::USTRINGHASH);
|
||||
|
||||
|
||||
|
||||
@@ -485,6 +487,10 @@ template<> struct TypeDescFromC<Imath::Box3i> { static const constexpr TypeDesc
|
||||
#endif
|
||||
|
||||
|
||||
class ustringhash; // forward declaration
|
||||
|
||||
|
||||
|
||||
/// A template mechanism for getting C type of TypeDesc::BASETYPE.
|
||||
///
|
||||
template<int b> struct CType {};
|
||||
@@ -501,6 +507,7 @@ template<> struct CType<(int)TypeDesc::HALF> { typedef half type; };
|
||||
#endif
|
||||
template<> struct CType<(int)TypeDesc::FLOAT> { typedef float type; };
|
||||
template<> struct CType<(int)TypeDesc::DOUBLE> { typedef double type; };
|
||||
template<> struct CType<(int)TypeDesc::USTRINGHASH> { typedef ustringhash type; };
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -127,6 +127,7 @@ class OIIO_UTIL_API ustring {
|
||||
public:
|
||||
using rep_t = const char*; ///< The underlying representation type
|
||||
using value_type = char;
|
||||
using hash_t = uint64_t; ///< The hash type
|
||||
using pointer = value_type*;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
@@ -314,7 +315,7 @@ public:
|
||||
}
|
||||
|
||||
/// Return a hashed version of the string
|
||||
size_t hash() const noexcept
|
||||
hash_t hash() const noexcept
|
||||
{
|
||||
if (!m_chars)
|
||||
return 0;
|
||||
@@ -741,7 +742,7 @@ public:
|
||||
/// ustring() if there is no registered ustring with that hash. Note that
|
||||
/// if there are multiple ustrings with the same hash, this will return
|
||||
/// the first one it finds in the table.
|
||||
OIIO_NODISCARD static ustring from_hash(size_t hash);
|
||||
OIIO_NODISCARD static ustring from_hash(hash_t hash);
|
||||
|
||||
private:
|
||||
// Individual ustring internal representation -- the unique characters.
|
||||
@@ -755,12 +756,12 @@ public:
|
||||
// if you know the rep, the chars are at (char *)(rep+1), and if you
|
||||
// know the chars, the rep is at ((TableRep *)chars - 1).
|
||||
struct TableRep {
|
||||
size_t hashed; // precomputed Hash value
|
||||
hash_t hashed; // precomputed Hash value
|
||||
std::string str; // String representation
|
||||
size_t length; // Length of the string; must be right before cap
|
||||
size_t dummy_capacity; // Dummy field! must be right before refcount
|
||||
int dummy_refcount; // Dummy field! must be right before chars
|
||||
TableRep(string_view strref, size_t hash);
|
||||
TableRep(string_view strref, hash_t hash);
|
||||
~TableRep();
|
||||
const char* c_str() const noexcept { return (const char*)(this + 1); }
|
||||
};
|
||||
@@ -789,7 +790,8 @@ private:
|
||||
///
|
||||
class OIIO_UTIL_API ustringhash {
|
||||
public:
|
||||
using rep_t = size_t; ///< The underlying representation type
|
||||
using rep_t = ustring::hash_t; ///< The underlying representation type
|
||||
using hash_t = ustring::hash_t; ///< The hash type
|
||||
|
||||
// Default constructor
|
||||
OIIO_HOSTDEVICE constexpr ustringhash() noexcept
|
||||
@@ -853,7 +855,7 @@ public:
|
||||
|
||||
/// Construct from a raw hash value. Beware: results are undefined if it's
|
||||
/// not the valid hash of a ustring.
|
||||
OIIO_HOSTDEVICE explicit constexpr ustringhash(size_t hash) noexcept
|
||||
OIIO_HOSTDEVICE explicit constexpr ustringhash(hash_t hash) noexcept
|
||||
: m_hash(hash)
|
||||
{
|
||||
}
|
||||
@@ -909,7 +911,7 @@ public:
|
||||
#endif
|
||||
|
||||
/// Return a hashed version of the string
|
||||
OIIO_HOSTDEVICE constexpr size_t hash() const noexcept { return m_hash; }
|
||||
OIIO_HOSTDEVICE constexpr hash_t hash() const noexcept { return m_hash; }
|
||||
|
||||
#ifndef __CUDA_ARCH__
|
||||
/// Return the number of characters in the string.
|
||||
@@ -986,8 +988,8 @@ public:
|
||||
#endif
|
||||
|
||||
/// Return the ustringhash corresponding to the given hash. Caveat emptor:
|
||||
/// results are undefined if it's not the hash value of a ustring.
|
||||
OIIO_NODISCARD static constexpr ustringhash from_hash(size_t hash)
|
||||
/// results are undefined if it's not the valid hash of a ustring.
|
||||
OIIO_NODISCARD static constexpr ustringhash from_hash(hash_t hash)
|
||||
{
|
||||
ustringhash u;
|
||||
u.m_hash = hash;
|
||||
@@ -1003,8 +1005,8 @@ private:
|
||||
|
||||
|
||||
|
||||
static_assert(sizeof(ustringhash) == sizeof(size_t),
|
||||
"ustringhash should be the same size as a size_t");
|
||||
static_assert(sizeof(ustringhash) == sizeof(uint64_t),
|
||||
"ustringhash should be the same size as a uint64_t");
|
||||
static_assert(sizeof(ustring) == sizeof(const char*),
|
||||
"ustring should be the same size as a const char*");
|
||||
|
||||
@@ -1049,10 +1051,6 @@ OIIO_DEVICE_CONSTEXPR ustringhash operator""_ush(const char* str,
|
||||
/// Deprecated -- This is too easy to confuse with the ustringhash class. And
|
||||
/// also it is unnecessary if you use std::hash<ustring>. This will be removed
|
||||
/// in OIIO 3.0.
|
||||
# if OIIO_VERSION_GREATER_EQUAL(2, 6, 0)
|
||||
OIIO_DEPRECATED("Use std::hash<ustring> instead of ustringHash")
|
||||
# endif
|
||||
|
||||
using ustringHash = std::hash<ustring>;
|
||||
#endif
|
||||
|
||||
@@ -1138,7 +1136,10 @@ OIIO_NAMESPACE_END
|
||||
namespace std { // not necessary in C++17, then we can just say std::hash
|
||||
// std::hash specialization for ustring
|
||||
template<> struct hash<OIIO::ustring> {
|
||||
std::size_t operator()(OIIO::ustring u) const noexcept { return u.hash(); }
|
||||
std::size_t operator()(OIIO::ustring u) const noexcept
|
||||
{
|
||||
return static_cast<std::size_t>(u.hash());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1147,7 +1148,7 @@ template<> struct hash<OIIO::ustringhash> {
|
||||
OIIO_HOSTDEVICE constexpr std::size_t
|
||||
operator()(OIIO::ustringhash u) const noexcept
|
||||
{
|
||||
return u.hash();
|
||||
return static_cast<std::size_t>(u.hash());
|
||||
}
|
||||
};
|
||||
} // namespace std
|
||||
|
||||
+1
-1
@@ -127,6 +127,6 @@ main(int argc, char* argv[])
|
||||
std::cout << "\n";
|
||||
std::cout << imagecache->getstats(1 + verbose) << "\n";
|
||||
}
|
||||
|
||||
shutdown();
|
||||
return r;
|
||||
}
|
||||
|
||||
@@ -62,10 +62,8 @@ public:
|
||||
{
|
||||
return (feature == "exif" || feature == "iptc" || feature == "ioproxy");
|
||||
}
|
||||
bool valid_file(const std::string& filename) const override
|
||||
{
|
||||
return valid_file(filename, nullptr);
|
||||
}
|
||||
bool valid_file(Filesystem::IOProxy* ioproxy) const override;
|
||||
|
||||
bool open(const std::string& name, ImageSpec& spec) override;
|
||||
bool open(const std::string& name, ImageSpec& spec,
|
||||
const ImageSpec& config) override;
|
||||
@@ -119,8 +117,6 @@ private:
|
||||
|
||||
bool read_icc_profile(j_decompress_ptr cinfo, ImageSpec& spec);
|
||||
|
||||
bool valid_file(const std::string& filename, Filesystem::IOProxy* io) const;
|
||||
|
||||
void close_file() { init(); }
|
||||
|
||||
friend class JpgOutput;
|
||||
|
||||
@@ -138,26 +138,16 @@ JpgInput::jpegerror(my_error_ptr /*myerr*/, bool fatal)
|
||||
|
||||
|
||||
bool
|
||||
JpgInput::valid_file(const std::string& filename, Filesystem::IOProxy* io) const
|
||||
JpgInput::valid_file(Filesystem::IOProxy* ioproxy) const
|
||||
{
|
||||
// Check magic number to assure this is a JPEG file
|
||||
uint8_t magic[2] = { 0, 0 };
|
||||
bool ok = true;
|
||||
if (!ioproxy || ioproxy->mode() != Filesystem::IOProxy::Read)
|
||||
return false;
|
||||
|
||||
if (io) {
|
||||
ok = (io->pread(magic, sizeof(magic), 0) == sizeof(magic));
|
||||
} else {
|
||||
FILE* fd = Filesystem::fopen(filename, "rb");
|
||||
if (!fd)
|
||||
return false;
|
||||
ok = (::fread(magic, sizeof(magic), 1, fd) == 1);
|
||||
fclose(fd);
|
||||
}
|
||||
|
||||
if (magic[0] != JPEG_MAGIC1 || magic[1] != JPEG_MAGIC2) {
|
||||
ok = false;
|
||||
}
|
||||
return ok;
|
||||
uint8_t magic[2] {};
|
||||
const size_t numRead = ioproxy->pread(magic, sizeof(magic), 0);
|
||||
return numRead == sizeof(magic) && magic[0] == JPEG_MAGIC1
|
||||
&& magic[1] == JPEG_MAGIC2;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -121,27 +121,16 @@ bool
|
||||
JpgOutput::open(const std::string& name, const ImageSpec& newspec,
|
||||
OpenMode mode)
|
||||
{
|
||||
if (mode != Create) {
|
||||
errorf("%s does not support subimages or MIP levels", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
// Save name and spec for later use
|
||||
m_filename = name;
|
||||
m_spec = newspec;
|
||||
|
||||
// Check for things this format doesn't support
|
||||
if (m_spec.width < 1 || m_spec.height < 1) {
|
||||
errorf("Image resolution must be at least 1x1, you asked for %d x %d",
|
||||
m_spec.width, m_spec.height);
|
||||
if (!check_open(mode, newspec,
|
||||
{ 0, JPEG_MAX_DIMENSION, 0, JPEG_MAX_DIMENSION, 0, 1, 0,
|
||||
256 }))
|
||||
return false;
|
||||
}
|
||||
if (m_spec.depth < 1)
|
||||
m_spec.depth = 1;
|
||||
if (m_spec.depth > 1) {
|
||||
errorf("%s does not support volume images (depth > 1)", format_name());
|
||||
return false;
|
||||
}
|
||||
// NOTE: we appear to let a large number of channels be allowed, but
|
||||
// that's only because we robustly truncate to only RGB no matter what we
|
||||
// are handed.
|
||||
|
||||
ioproxy_retrieve_from_config(m_spec);
|
||||
if (!ioproxy_use_or_open(name))
|
||||
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
const char* format_name(void) const override { return "jpeg2000"; }
|
||||
int supports(string_view feature) const override
|
||||
{
|
||||
return feature == "alpha" || feature == "ioproxy";
|
||||
return feature == "alpha" || feature == "ioproxy" || feature == "tiles";
|
||||
// FIXME: we should support Exif/IPTC, but currently don't.
|
||||
}
|
||||
bool open(const std::string& name, const ImageSpec& spec,
|
||||
@@ -150,33 +150,11 @@ bool
|
||||
Jpeg2000Output::open(const std::string& name, const ImageSpec& spec,
|
||||
OpenMode mode)
|
||||
{
|
||||
if (mode != Create) {
|
||||
errorf("%s does not support subimages or MIP levels", format_name());
|
||||
if (!check_open(mode, spec, { 0, 1 << 20, 0, 1 << 20, 0, 1, 0, 4 },
|
||||
uint64_t(OpenChecks::Disallow2Channel)))
|
||||
return false;
|
||||
}
|
||||
|
||||
m_filename = name;
|
||||
m_spec = spec;
|
||||
|
||||
// Check for things this format doesn't support
|
||||
if (m_spec.width < 1 || m_spec.height < 1) {
|
||||
errorf("Image resolution must be at least 1x1, you asked for %d x %d",
|
||||
m_spec.width, m_spec.height);
|
||||
return false;
|
||||
}
|
||||
if (m_spec.depth < 1)
|
||||
m_spec.depth = 1;
|
||||
if (m_spec.depth > 1) {
|
||||
errorf("%s does not support volume images (depth > 1)", format_name());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_spec.nchannels != 1 && m_spec.nchannels != 3
|
||||
&& m_spec.nchannels != 4) {
|
||||
errorf("%s does not support %d-channel images\n", format_name(),
|
||||
m_spec.nchannels);
|
||||
return false;
|
||||
}
|
||||
|
||||
// If not uint8 or uint16, default to uint16
|
||||
if (m_spec.format != TypeDesc::UINT8 && m_spec.format != TypeDesc::UINT16)
|
||||
|
||||
@@ -103,6 +103,18 @@ if (EMBEDPLUGINS)
|
||||
endforeach ()
|
||||
endif ()
|
||||
|
||||
# Enable default use of OpenEXR core library for versions of the library
|
||||
# new enough to support DWA compression in exrcore.
|
||||
if (OPENEXR_VERSION VERSION_GREATER_EQUAL 3.1.10)
|
||||
target_compile_definitions(OpenImageIO
|
||||
PRIVATE OIIO_OPENEXR_CORE_DEFAULT=1)
|
||||
message (STATUS "OpenEXR core library will be used by default")
|
||||
else ()
|
||||
target_compile_definitions(OpenImageIO
|
||||
PRIVATE OIIO_OPENEXR_CORE_DEFAULT=0)
|
||||
message (STATUS "OpenEXR core library will not be used by default")
|
||||
endif ()
|
||||
|
||||
# Source groups for libutil and libtexture
|
||||
source_group ("libutil" REGULAR_EXPRESSION ".+/libutil/.+")
|
||||
source_group ("libtexture" REGULAR_EXPRESSION ".+/libtexture/.+")
|
||||
@@ -216,7 +228,7 @@ install_targets (OpenImageIO)
|
||||
|
||||
# Testing
|
||||
|
||||
if (OIIO_BUILD_TESTS)
|
||||
if (OIIO_BUILD_TESTS AND BUILD_TESTING)
|
||||
|
||||
add_executable (color_test color_test.cpp)
|
||||
target_link_libraries (color_test PRIVATE OpenImageIO)
|
||||
@@ -260,4 +272,4 @@ if (OIIO_BUILD_TESTS)
|
||||
set_target_properties (compute_test PROPERTIES FOLDER "Unit Tests")
|
||||
add_test (unit_compute ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/compute_test)
|
||||
|
||||
endif (OIIO_BUILD_TESTS)
|
||||
endif ()
|
||||
|
||||
+659
-159
File diff suppressed because it is too large
Load Diff
@@ -1302,6 +1302,8 @@ encode_exif(const ImageSpec& spec, std::vector<char>& blob,
|
||||
TIFFHeader head;
|
||||
head.tiff_magic = (endianreq == endian::little) ? 0x4949 : 0x4d4d;
|
||||
head.tiff_version = 42;
|
||||
if (endianreq != endian::native)
|
||||
swap_endian(&head.tiff_version);
|
||||
// N.B. need to swap_endian head.tiff_diroff below, once we know the sizes
|
||||
append(blob, head);
|
||||
|
||||
|
||||
@@ -485,6 +485,16 @@ ImageBufImpl::~ImageBufImpl()
|
||||
// else init_spec requested the system-wide shared cache, which
|
||||
// does not need to be destroyed.
|
||||
clear();
|
||||
|
||||
// Upon destruction, print uncaught errors to help users who don't know
|
||||
// how to properly check for errors.
|
||||
if (!m_err.empty() /* Note: safe becausethis is the dtr */
|
||||
&& pvt::imagebuf_print_uncaught_errors) {
|
||||
OIIO::print(
|
||||
"An ImageBuf was destroyed with a pending error message that was never\n"
|
||||
"retrieved via ImageBuf::geterror(). This was the error message:\n{}\n",
|
||||
m_err);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -501,6 +501,16 @@ test_write_over()
|
||||
|
||||
|
||||
|
||||
static void
|
||||
test_uncaught_error()
|
||||
{
|
||||
ImageBuf buf;
|
||||
buf.error("Boo!");
|
||||
// buf exists scope and is destroyed without anybody retrieving the error.
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main(int /*argc*/, char* /*argv*/[])
|
||||
{
|
||||
@@ -534,6 +544,8 @@ main(int /*argc*/, char* /*argv*/[])
|
||||
|
||||
test_write_over();
|
||||
|
||||
test_uncaught_error();
|
||||
|
||||
Filesystem::remove("A_imagebuf_test.tif");
|
||||
return unit_test_failures;
|
||||
}
|
||||
|
||||
@@ -254,7 +254,9 @@ ImageBufAlgo::IBAprep(ROI& roi, ImageBuf* dst, const ImageBuf* A,
|
||||
}
|
||||
}
|
||||
|
||||
dst->reset(spec);
|
||||
dst->reset(spec, (prepflags & IBAprep_FILL_ZERO_ALLOC)
|
||||
? InitializePixels::Yes
|
||||
: InitializePixels::No);
|
||||
|
||||
// If we just allocated more channels than the caller will write,
|
||||
// clear the extra channels.
|
||||
|
||||
@@ -5,6 +5,8 @@
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
#include <limits>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <OpenImageIO/half.h>
|
||||
|
||||
@@ -185,6 +187,22 @@ ImageBufAlgo::zero(ImageBuf& dst, ROI roi, int nthreads)
|
||||
pvt::LoggedTimer logtime("IBA::zero");
|
||||
if (!IBAprep(roi, &dst))
|
||||
return false;
|
||||
OIIO_ASSERT(dst.localpixels());
|
||||
if (dst.contiguous() && roi == dst.roi() && !dst.deep()) {
|
||||
// Special case: we're zeroing out an entire contiguous buffer -- safe
|
||||
// to use use memset.
|
||||
ImageBufAlgo::parallel_image(roi, nthreads, [=, &dst](ROI roi) {
|
||||
auto size = dst.spec().pixel_bytes() * imagesize_t(roi.width());
|
||||
for (int z = roi.zbegin; z < roi.zend; ++z) {
|
||||
for (int y = roi.ybegin; y < roi.yend; ++y) {
|
||||
memset(dst.pixeladdr(roi.xbegin, y, z), 0, size);
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
// More general case -- fall back on fill_const
|
||||
float* zero = OIIO_ALLOCA(float, roi.chend);
|
||||
memset(zero, 0, roi.chend * sizeof(float));
|
||||
bool ok;
|
||||
@@ -707,14 +725,165 @@ ImageBufAlgo::bluenoise_image()
|
||||
|
||||
|
||||
|
||||
static std::vector<std::string> font_search_dirs;
|
||||
static std::vector<std::string> all_font_files;
|
||||
static std::vector<std::string> all_fonts;
|
||||
static std::unordered_map<std::string, std::string> font_file_map;
|
||||
static std::mutex font_search_mutex;
|
||||
static bool fonts_are_enumerated = false;
|
||||
static const char* font_dir_prefix_envvars[]
|
||||
= { "OPENIMAGEIO_FONTS", "HOME", "SystemRoot", "OpenImageIO_ROOT" };
|
||||
static const char* font_dir_prefixes[]
|
||||
= { "/Library/Fonts", "/System/Library/Fonts",
|
||||
"C:/Windows", "/usr",
|
||||
"/usr/local", "/opt/local" };
|
||||
static const char* font_dir_suffixes[]
|
||||
= { "fonts", "Fonts", "Library/Fonts",
|
||||
"share/fonts", "share/Fonts", "share/fonts/OpenImageIO" };
|
||||
static const char* default_font_name[] = { "DroidSans", "cour", "Courier New",
|
||||
"FreeMono", nullptr };
|
||||
// static const char* font_extensions[] = { "", ".ttf", ".ttc", ".pfa", ".pfb" };
|
||||
|
||||
|
||||
|
||||
// Add one dir to font_search_dirs, if the dir exists.
|
||||
static void
|
||||
fontpath_add_one_dir(string_view dir, int recursion = 0)
|
||||
{
|
||||
if (dir.size() && Filesystem::is_directory(dir)) {
|
||||
font_search_dirs.emplace_back(dir);
|
||||
if (recursion) {
|
||||
std::vector<std::string> files;
|
||||
if (Filesystem::get_directory_entries(dir, files, false)) {
|
||||
for (auto&& subdir : files)
|
||||
fontpath_add_one_dir(subdir, recursion - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add all the dirs in a searchpath to font_search_dirs.
|
||||
static void
|
||||
fontpath_add_from_searchpath(string_view searchpath)
|
||||
{
|
||||
if (searchpath.size()) {
|
||||
for (auto& dir : Filesystem::searchpath_split(searchpath, true)) {
|
||||
fontpath_add_one_dir(dir);
|
||||
for (auto s : font_dir_suffixes)
|
||||
fontpath_add_one_dir(Strutil::fmt::format("{}/{}", dir, s));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add dir/{common_font_subdirs} to font_search_dirs.
|
||||
static void
|
||||
fontpath_add_from_dir(const std::string& dir)
|
||||
{
|
||||
if (dir.size() && Filesystem::is_directory(dir)) {
|
||||
fontpath_add_one_dir(dir);
|
||||
for (auto s : font_dir_suffixes)
|
||||
fontpath_add_one_dir(Strutil::fmt::format("{}/{}", dir, s));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
enumerate_fonts()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(font_search_mutex);
|
||||
if (fonts_are_enumerated)
|
||||
return; // already done
|
||||
|
||||
// Find all the existing dirs from the font search path to populate
|
||||
// font_search_dirs.
|
||||
fontpath_add_from_searchpath(pvt::font_searchpath);
|
||||
for (auto s : font_dir_prefix_envvars)
|
||||
fontpath_add_from_searchpath(Sysutil::getenv(s));
|
||||
for (auto s : font_dir_prefixes)
|
||||
fontpath_add_from_dir(s);
|
||||
std::string this_program = OIIO::Sysutil::this_program_path();
|
||||
if (this_program.size()) {
|
||||
std::string path = Filesystem::parent_path(this_program);
|
||||
path = Filesystem::parent_path(path);
|
||||
fontpath_add_from_dir(path);
|
||||
}
|
||||
|
||||
// Get list of directories one level deeper than the font_search_dirs
|
||||
auto dirs = font_search_dirs;
|
||||
for (auto& dir : font_search_dirs) {
|
||||
std::vector<std::string> filenames;
|
||||
Filesystem::get_directory_entries(dir, filenames, false);
|
||||
for (auto& f : filenames)
|
||||
if (f.size() && Filesystem::is_directory(f))
|
||||
dirs.push_back(f);
|
||||
}
|
||||
|
||||
// Look for all the font files in dirs, populate font_file_set and font_set
|
||||
std::set<std::string> font_set;
|
||||
std::set<std::string> font_file_set;
|
||||
for (auto& dir : dirs) {
|
||||
std::vector<std::string> filenames;
|
||||
Filesystem::get_directory_entries(dir, filenames, false);
|
||||
for (auto& f : filenames) {
|
||||
if (Strutil::iends_with(f, ".ttf") || Strutil::iends_with(f, ".ttc")
|
||||
|| Strutil::iends_with(f, ".pfa")
|
||||
|| Strutil::iends_with(f, ".pfb")) {
|
||||
std::string fontname
|
||||
= Filesystem::replace_extension(Filesystem::filename(f),
|
||||
"");
|
||||
font_file_set.insert(f);
|
||||
font_set.insert(fontname);
|
||||
if (font_file_map.find(fontname) == font_file_map.end())
|
||||
font_file_map[fontname] = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (auto& f : font_file_set)
|
||||
all_font_files.push_back(f);
|
||||
for (auto& f : font_set)
|
||||
all_fonts.push_back(f);
|
||||
|
||||
// Don't need to do that again
|
||||
fonts_are_enumerated = true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::vector<std::string>&
|
||||
pvt::font_dirs()
|
||||
{
|
||||
enumerate_fonts();
|
||||
return font_search_dirs;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::vector<std::string>&
|
||||
pvt::font_file_list()
|
||||
{
|
||||
enumerate_fonts();
|
||||
return all_font_files;
|
||||
}
|
||||
|
||||
|
||||
|
||||
const std::vector<std::string>&
|
||||
pvt::font_list()
|
||||
{
|
||||
enumerate_fonts();
|
||||
return all_fonts;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#ifdef USE_FREETYPE
|
||||
namespace { // anon
|
||||
static mutex ft_mutex;
|
||||
static FT_Library ft_library = NULL;
|
||||
static bool ft_broken = false;
|
||||
static std::vector<std::string> font_search_dirs;
|
||||
static const char* default_font_name[] = { "DroidSans", "cour", "Courier New",
|
||||
"FreeMono", nullptr };
|
||||
|
||||
|
||||
// Helper: given unicode and a font face, compute its size
|
||||
static ROI
|
||||
@@ -748,43 +917,6 @@ text_size_from_unicode(cspan<uint32_t> utext, FT_Face face, int fontsize)
|
||||
}
|
||||
|
||||
|
||||
// Add one dir to font_search_dirs, if the dir exists.
|
||||
static void
|
||||
fontpath_add_one_dir(string_view dir)
|
||||
{
|
||||
if (dir.size() && Filesystem::is_directory(dir))
|
||||
font_search_dirs.emplace_back(dir);
|
||||
}
|
||||
|
||||
|
||||
// Add all the dirs in a searchpath to font_search_dirs.
|
||||
static void
|
||||
fontpath_add_from_searchpath(string_view searchpath)
|
||||
{
|
||||
if (searchpath.size()) {
|
||||
std::vector<std::string> user_font_dirs;
|
||||
Filesystem::searchpath_split(searchpath, user_font_dirs, true);
|
||||
for (auto& dir : user_font_dirs)
|
||||
fontpath_add_one_dir(dir);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Add dir/{common_font_subdirs} to font_search_dirs.
|
||||
static void
|
||||
fontpath_add_from_dir(const std::string& dir)
|
||||
{
|
||||
if (dir.size() && Filesystem::is_directory(dir)) {
|
||||
fontpath_add_one_dir(dir + "/fonts");
|
||||
fontpath_add_one_dir(dir + "/Fonts");
|
||||
fontpath_add_one_dir(dir + "/Library/Fonts");
|
||||
fontpath_add_one_dir(dir + "/share/fonts");
|
||||
fontpath_add_one_dir(dir + "/share/Fonts");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Given font name, resolve it to an existing font filename.
|
||||
// If found, return true and put the resolved filename in result.
|
||||
// If not found, return false and put an error message in result.
|
||||
@@ -807,66 +939,34 @@ resolve_font(string_view font_, std::string& result)
|
||||
}
|
||||
}
|
||||
|
||||
// A set of likely directories for fonts to live, across several systems.
|
||||
// Fill out the list of search dirs if not yet done.
|
||||
if (font_search_dirs.size() == 0) {
|
||||
fontpath_add_from_searchpath(pvt::font_searchpath);
|
||||
fontpath_add_from_searchpath(Sysutil::getenv("OPENIMAGEIO_FONTS"));
|
||||
fontpath_add_from_dir(Sysutil::getenv("HOME"));
|
||||
fontpath_add_from_dir(Sysutil::getenv("SystemRoot"));
|
||||
fontpath_add_from_dir(Sysutil::getenv("OpenImageIO_ROOT"));
|
||||
fontpath_add_from_dir(
|
||||
Sysutil::getenv("OPENIMAGEIO_ROOT_DIR")); // DEPRECATED(1.9)
|
||||
fontpath_add_from_dir(
|
||||
Sysutil::getenv("OPENIMAGEIOHOME")); // DEPRECATED(1.9)
|
||||
fontpath_add_from_dir("/Library");
|
||||
fontpath_add_from_dir("C:/Windows");
|
||||
fontpath_add_from_dir("/usr");
|
||||
fontpath_add_from_dir("/usr/local");
|
||||
fontpath_add_from_dir("/opt/local");
|
||||
std::string this_program = OIIO::Sysutil::this_program_path();
|
||||
if (this_program.size()) {
|
||||
std::string path = Filesystem::parent_path(this_program);
|
||||
path = Filesystem::parent_path(path);
|
||||
fontpath_add_from_dir(path);
|
||||
}
|
||||
}
|
||||
|
||||
// Try to find the font. Experiment with several extensions
|
||||
// Try to find the font.
|
||||
enumerate_fonts();
|
||||
std::string font = font_;
|
||||
if (font.empty()) {
|
||||
// nothing specified -- look for something to use as a default.
|
||||
for (int j = 0; default_font_name[j] && font.empty(); ++j) {
|
||||
static const char* extensions[] = { "", ".ttf", ".pfa", ".pfb",
|
||||
NULL };
|
||||
for (int i = 0; font.empty() && extensions[i]; ++i)
|
||||
font = Filesystem::searchpath_find(
|
||||
std::string(default_font_name[j]) + extensions[i],
|
||||
font_search_dirs, true, true);
|
||||
for (auto fontname : default_font_name) {
|
||||
auto f = font_file_map.find(fontname);
|
||||
if (f != font_file_map.end()) {
|
||||
font = f->second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (font.empty()) {
|
||||
result = "Could not set default font face";
|
||||
return false;
|
||||
}
|
||||
} else if (Filesystem::is_regular(font)) {
|
||||
// directly specified a filename -- use it
|
||||
} else {
|
||||
}
|
||||
if (!Filesystem::is_regular(font)) {
|
||||
// A font name was specified but it's not a full path, look for it
|
||||
std::string f;
|
||||
static const char* extensions[] = { "", ".ttf", ".pfa", ".pfb", NULL };
|
||||
for (int i = 0; f.empty() && extensions[i]; ++i)
|
||||
f = Filesystem::searchpath_find(font + extensions[i],
|
||||
font_search_dirs, true, true);
|
||||
if (f.empty()) {
|
||||
result = Strutil::sprintf("Could not set font face to \"%s\"",
|
||||
font);
|
||||
return false;
|
||||
}
|
||||
font = f;
|
||||
auto f = font_file_map.find(font);
|
||||
if (f != font_file_map.end())
|
||||
font = f->second;
|
||||
else
|
||||
font = std::string();
|
||||
}
|
||||
|
||||
if (!Filesystem::is_regular(font)) {
|
||||
result = Strutil::sprintf("Could not find font \"%s\"", font);
|
||||
result = Strutil::fmt::format("Could not find font \"{}\"", font);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@@ -433,6 +433,71 @@ ImageBufAlgo::pow(const ImageBuf& A, cspan<float> b, ROI roi, int nthreads)
|
||||
return result;
|
||||
}
|
||||
|
||||
template<class Rtype>
|
||||
static bool
|
||||
normalize_impl(ImageBuf& R, const ImageBuf& A, float inCenter, float outCenter,
|
||||
float scale, ROI roi, int nthreads)
|
||||
{
|
||||
ImageBufAlgo::parallel_image(roi, nthreads, [&](ROI roi) {
|
||||
ImageBuf::ConstIterator<Rtype> a(A, roi);
|
||||
for (ImageBuf::Iterator<Rtype> r(R, roi); !r.done(); ++r, ++a) {
|
||||
float x = a[0] - inCenter;
|
||||
float y = a[1] - inCenter;
|
||||
float z = a[2] - inCenter;
|
||||
|
||||
float length = std::sqrt(x * x + y * y + z * z);
|
||||
|
||||
float s = (length > 0.0f) ? scale / length : 0.0f;
|
||||
|
||||
r[0] = x * s + outCenter;
|
||||
r[1] = y * s + outCenter;
|
||||
r[2] = z * s + outCenter;
|
||||
|
||||
if (R.spec().nchannels == 4) {
|
||||
r[3] = a[3];
|
||||
}
|
||||
}
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
ImageBufAlgo::normalize(ImageBuf& dst, const ImageBuf& src, float inCenter,
|
||||
float outCenter, float scale, ROI roi, int nthreads)
|
||||
{
|
||||
if (!ImageBufAlgo::IBAprep(roi, &dst, &src))
|
||||
return false;
|
||||
|
||||
if (src.spec().nchannels != 3 && src.spec().nchannels != 4) {
|
||||
src.errorfmt("normalize can only handle 3- or 4-channel images");
|
||||
return false;
|
||||
}
|
||||
if (src.spec().nchannels < dst.spec().nchannels) {
|
||||
dst.errorfmt(
|
||||
"destination buffer can`t have more channels than the source");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ok;
|
||||
OIIO_DISPATCH_COMMON_TYPES(ok, "normalize", normalize_impl,
|
||||
dst.spec().format, dst, src, inCenter, outCenter,
|
||||
scale, roi, nthreads);
|
||||
|
||||
return ok;
|
||||
}
|
||||
|
||||
ImageBuf
|
||||
ImageBufAlgo::normalize(const ImageBuf& A, float inCenter, float outCenter,
|
||||
float scale, ROI roi, int nthreads)
|
||||
{
|
||||
ImageBuf result;
|
||||
bool ok = ImageBufAlgo::normalize(result, A, inCenter, outCenter, scale,
|
||||
roi, nthreads);
|
||||
if (!ok && !result.has_error())
|
||||
result.errorfmt("normalize error");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
template<class D, class S>
|
||||
|
||||
@@ -20,6 +20,7 @@
|
||||
|
||||
#include <OpenImageIO/argparse.h>
|
||||
#include <OpenImageIO/benchmark.h>
|
||||
#include <OpenImageIO/color.h>
|
||||
#include <OpenImageIO/imagebuf.h>
|
||||
#include <OpenImageIO/imagebufalgo.h>
|
||||
#include <OpenImageIO/imagebufalgo_util.h>
|
||||
@@ -1112,6 +1113,28 @@ test_opencv()
|
||||
|
||||
|
||||
|
||||
void
|
||||
test_color_management()
|
||||
{
|
||||
ColorConfig config;
|
||||
|
||||
// Test the IBA::colorconvert version that works on a color at a time
|
||||
{
|
||||
auto processor = config.createColorProcessor("lin_srgb", "srgb");
|
||||
float rgb[3] = { 0.5f, 0.5f, 0.5f };
|
||||
ImageBufAlgo::colorconvert(rgb, processor.get(), false);
|
||||
OIIO_CHECK_EQUAL_THRESH(rgb[1], 0.735356983052449f, 1.0e-5);
|
||||
}
|
||||
{
|
||||
auto processor = config.createColorProcessor("lin_srgb", "srgb");
|
||||
float rgb[4] = { 0.5f, 0.5f, 0.5f, 1.0f };
|
||||
ImageBufAlgo::colorconvert(rgb, processor.get(), true);
|
||||
OIIO_CHECK_EQUAL_THRESH(rgb[1], 0.735356983052449f, 1.0e-5);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
static void
|
||||
test_yee()
|
||||
{
|
||||
@@ -1168,6 +1191,7 @@ main(int argc, char** argv)
|
||||
test_IBAprep();
|
||||
test_validate_st_warp_checks();
|
||||
test_opencv();
|
||||
test_color_management();
|
||||
test_yee();
|
||||
|
||||
benchmark_parallel_image(64, iterations * 64);
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user