Skip to content

Commit fd37953

Browse files
committed
Merge remote-tracking branch 'upstream/main' into _imgui
2 parents b41ddd3 + 94ec2de commit fd37953

31 files changed

Lines changed: 519 additions & 322 deletions

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ else ()
112112
endif ()
113113
option (${PROJ_NAME}_BUILD_TOOLS "Build the command-line tools" ON)
114114
option (${PROJ_NAME}_BUILD_TESTS "Build the unit tests" ON)
115-
set_option (OIIO_USE_HWY "Enable experimental Google Highway SIMD optimizations (if Highway is available)" OFF)
115+
set_option (OIIO_USE_HWY "Enable experimental Google Highway SIMD optimizations (if Highway is available)" OFF VERBOSE)
116116
set (OIIO_LIBNAME_SUFFIX "" CACHE STRING
117117
"Optional name appended to ${PROJECT_NAME} libraries that are built")
118118
option (BUILD_OIIOUTIL_ONLY "If ON, will build *only* libOpenImageIO_Util" OFF)

src/cmake/dependency_utils.cmake

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ function (print_package_notfound_report)
154154
message (STATUS)
155155
message (STATUS "All build dependencies: ${_cfp_all_build_deps_found}")
156156
if (CFP_EXTERNAL_BUILD_DEPS_FOUND)
157-
message (STATUS "${ColorBoldWhite}The following dependencies found externally:${ColorReset}")
157+
message (STATUS "${ColorBoldWhite}The following dependencies were found externally:${ColorReset}")
158158
list (SORT CFP_EXTERNAL_BUILD_DEPS_FOUND CASE INSENSITIVE)
159159
list (REMOVE_DUPLICATES CFP_EXTERNAL_BUILD_DEPS_FOUND)
160160
foreach (_pkg IN LISTS CFP_EXTERNAL_BUILD_DEPS_FOUND)
@@ -233,8 +233,8 @@ function (handle_package_notfound pkgname required)
233233
message (STATUS "${ColorRed}${pkgname} library not found ${ColorReset}")
234234
if (${pkgname}_ROOT)
235235
message (STATUS " ${pkgname}_ROOT was: ${${pkgname}_ROOT}")
236-
elseif ($ENV{${pkgname}_ROOT})
237-
message (STATUS " ENV ${pkgname}_ROOT was: ${${pkgname}_ROOT}")
236+
elseif (DEFINED ENV{${pkgname}_ROOT})
237+
message (STATUS " ENV ${pkgname}_ROOT was: $ENV{${pkgname}_ROOT}")
238238
else ()
239239
message (STATUS " Try setting ${pkgname}_ROOT ?")
240240
endif ()
@@ -726,7 +726,7 @@ macro (build_dependency_with_cmake pkgname)
726726
${${pkgname}_GIT_CLONE_ARGS}
727727
${_pkg_exec_quiet})
728728
if (NOT IS_DIRECTORY ${${pkgname}_LOCAL_SOURCE_DIR})
729-
message (FATAL_ERROR "Could not download ${_pkg_GIT_REPOSITORY}")
729+
message (FATAL_ERROR "Could not download ${_pkg_GIT_REPOSITORY}: ${${pkgname}_clone_errors}")
730730
endif ()
731731
endif ()
732732
# Checkout and verify the source against the expected commit hash to

src/cmake/testing.cmake

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ set(OIIO_TESTSUITE_IMAGEDIR "${PROJECT_BINARY_DIR}/testsuite" CACHE PATH
3030
# [ URL http://find.reference.cases.here.com ]
3131
# [ FOUNDVAR variable_name ... ]
3232
# [ ENABLEVAR variable_name ... ]
33+
# [ DISABLEVAR variable_name ... ]
3334
# [ SUFFIX suffix ]
3435
# [ ENVIRONMENT "VAR=value" ... ]
3536
# )
@@ -43,35 +44,48 @@ set(OIIO_TESTSUITE_IMAGEDIR "${PROJECT_BINARY_DIR}/testsuite" CACHE PATH
4344
# not existing and true, will skip the test.
4445
#
4546
# The optional ENABLEVAR introduces variables (typically ENABLE_Foo) that
46-
# if existing and yet false, will skip the test.
47+
# if existing and yet false/off/zero, will skip the test. (Not existing
48+
# does NOT disable the test.)
49+
#
50+
# The optional DISABLEVAR introduces variables that, if existing and
51+
# true/on/nonzero, will skip the test.
4752
#
4853
# The optional SUFFIX is appended to the test name.
4954
#
5055
# The optional ENVIRONMENT is a list of environment variables to set for the
5156
# test.
5257
#
5358
macro (oiio_add_tests)
54-
cmake_parse_arguments (_ats "" "SUFFIX;TESTNAME" "URL;IMAGEDIR;LABEL;FOUNDVAR;ENABLEVAR;ENVIRONMENT" ${ARGN})
59+
cmake_parse_arguments (_ats "" "SUFFIX;TESTNAME" "URL;IMAGEDIR;LABEL;FOUNDVAR;ENABLEVAR;DISABLEVAR;ENVIRONMENT" ${ARGN})
5560
# Arguments: <prefix> <options> <one_value_keywords> <multi_value_keywords> args...
5661
set (_ats_testdir "${OIIO_TESTSUITE_IMAGEDIR}/${_ats_IMAGEDIR}")
5762
# If there was a FOUNDVAR param specified and that variable name is
5863
# not defined, mark the test as broken.
5964
set (_test_disabled FALSE)
6065
set (_test_notfound FALSE)
6166
foreach (_var ${_ats_FOUNDVAR})
67+
# FOUNDVAR entires had better exist and be true
6268
if (NOT ${_var})
6369
set (_ats_LABEL "broken")
6470
set (_test_notfound TRUE)
6571
endif ()
6672
endforeach ()
6773
set (_test_disabled 0)
6874
foreach (_var ${_ats_ENABLEVAR})
75+
# ENABLEVAR, *if* it exists, must be true. But not existing is fine.
6976
if ((NOT "${${_var}}" STREQUAL "" AND NOT "${${_var}}") OR
7077
(NOT "$ENV{${_var}}" STREQUAL "" AND NOT "$ENV{${_var}}"))
7178
set (_ats_LABEL "broken")
7279
set (_test_disabled TRUE)
7380
endif ()
7481
endforeach ()
82+
foreach (_var ${_ats_DISABLEVAR})
83+
# DISABLEVAR, if true, disable the test. Not existing is fine.
84+
if (${_var})
85+
set (_ats_LABEL "broken")
86+
set (_test_disabled TRUE)
87+
endif ()
88+
endforeach ()
7589
# For OCIO 2.2+, have the testsuite use the default built-in config
7690
list (APPEND _ats_ENVIRONMENT "OCIO=ocio://default"
7791
"OIIO_TESTSUITE_OCIOCONFIG=ocio://default")
@@ -238,6 +252,27 @@ macro (oiio_add_all_tests)
238252
oiio_add_tests (oiiotool-color
239253
FOUNDVAR OpenColorIO_FOUND)
240254

255+
# Tests to run with HWY enabled.
256+
# Remember to add tests here as hwy enabled IBA functions are added
257+
oiio_add_tests ( oiiotool
258+
oiiotool-composite
259+
oiiotool-xform
260+
docs-examples-cpp
261+
FOUNDVAR hwy_FOUND
262+
ENABLEVAR OIIO_USE_HWY
263+
SUFFIX ".hwy"
264+
ENVIRONMENT "OPENIMAGEIO_ENABLE_HWY=1"
265+
)
266+
267+
oiio_add_tests ( python-imagebufalgo
268+
FOUNDVAR hwy_FOUND
269+
ENABLEVAR OIIO_USE_HWY USE_PYTHON
270+
DISABLEVAR BUILD_OIIOUTIL_ONLY SANITIZE
271+
SUFFIX ".hwy"
272+
ENVIRONMENT "OPENIMAGEIO_ENABLE_HWY=1"
273+
IMAGEDIR oiio-images
274+
)
275+
241276
# List testsuites for specific formats or features which might be not found
242277
# or be intentionally disabled, or which need special external reference
243278
# images from the web that if not found, should skip the tests:

src/dds.imageio/ddsinput.cpp

Lines changed: 58 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -97,11 +97,11 @@ class DDSInput final : public ImageInput {
9797

9898
/// Helper function: performs the actual file seeking.
9999
///
100-
void internal_seek_subimage(int cubeface, int miplevel, unsigned int& w,
101-
unsigned int& h, unsigned int& d);
100+
void internal_seek_subimage(int cubeface, int miplevel, size_t& w,
101+
size_t& h, size_t& d);
102102

103103
/// Helper function: performs the actual pixel decoding.
104-
bool internal_readimg(unsigned char* dst, int w, int h, int d);
104+
bool internal_readimg(unsigned char* dst, size_t w, size_t h, size_t d);
105105

106106
static bool validate_signature(uint32_t signature);
107107
};
@@ -671,8 +671,8 @@ DDSInput::calc_shifts(uint32_t mask, uint32_t& count, uint32_t& right)
671671
// NOTE: This function has no sanity checks! It's a private method and relies
672672
// on the input being correct and valid!
673673
void
674-
DDSInput::internal_seek_subimage(int cubeface, int miplevel, unsigned int& w,
675-
unsigned int& h, unsigned int& d)
674+
DDSInput::internal_seek_subimage(int cubeface, int miplevel, size_t& w,
675+
size_t& h, size_t& d)
676676
{
677677
// early out for cubemaps that don't contain the requested face
678678
if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP
@@ -683,10 +683,10 @@ DDSInput::internal_seek_subimage(int cubeface, int miplevel, unsigned int& w,
683683
// we can easily calculate the offsets because both compressed and
684684
// uncompressed images have predictable length
685685
// calculate the offset; start with after the header
686-
unsigned int ofs = sizeof(dds_header);
686+
size_t ofs = sizeof(dds_header);
687687
if (m_dds.fmt.fourCC == DDS_4CC_DX10)
688688
ofs += sizeof(dds_header_dx10);
689-
unsigned int len;
689+
size_t len;
690690
// this loop is used to iterate over cube map sides, or run once in the
691691
// case of ordinary 2D or 3D images
692692
for (int j = 0; j <= cubeface; j++) {
@@ -754,7 +754,7 @@ DDSInput::seek_subimage(int subimage, int miplevel)
754754
m_buf.clear();
755755

756756
// for cube maps, the seek will be performed when reading a tile instead
757-
unsigned int w = 0, h = 0, d = 0;
757+
size_t w = 0, h = 0, d = 0;
758758
TypeDesc::BASETYPE basetype = GetBaseType(m_compression);
759759
if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP) {
760760
// calc sizes separately for cube maps
@@ -903,13 +903,42 @@ DDSInput::seek_subimage(int subimage, int miplevel)
903903
m_spec.attribute("textureformat", "Plain Texture");
904904
}
905905

906+
// Check validity of resolutions.
907+
if (m_dds.caps.flags2 & DDS_CAPS2_CUBEMAP) {
908+
// cube maps must be square and each face can be up to 16384x16384
909+
// (currently). But remember that they are stored in a 3x2 or 1x6
910+
// layout.
911+
#ifdef DDS_3X2_CUBE_MAP_LAYOUT
912+
if (!check_open(m_spec, { 0, 16384 * 3, 0, 16384 * 2, 0, 1, 0, 4 }))
913+
return false;
914+
#else
915+
if (!check_open(m_spec, { 0, 16384, 0, 16384 * 6, 0, 1, 0, 4 }))
916+
return false;
917+
#endif
918+
if (m_spec.full_width != m_spec.full_height) {
919+
errorfmt(
920+
"Invalid cube map layout: width {} does not match height {}",
921+
m_spec.full_width, m_spec.full_height);
922+
return false;
923+
}
924+
} else if (m_dds.caps.flags2 & DDS_CAPS2_VOLUME) {
925+
// volume textures are limited to 4096x4096x4096 (currently)
926+
if (!check_open(m_spec, { 0, 4096, 0, 4096, 0, 4096, 0, 4 })) {
927+
return false;
928+
}
929+
} else {
930+
// 2D textures can be up to 32768x32768
931+
if (!check_open(m_spec, { 0, 32768, 0, 32768, 0, 1, 0, 4 }))
932+
return false;
933+
}
934+
906935
m_subimage = subimage;
907936
m_miplevel = miplevel;
908937
return true;
909938
}
910939

911940
bool
912-
DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
941+
DDSInput::internal_readimg(unsigned char* dst, size_t w, size_t h, size_t d)
913942
{
914943
if (m_compression != Compression::None) {
915944
// compressed image
@@ -920,15 +949,15 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
920949
if (!ioread(tmp.get(), bufsize, 1))
921950
return false;
922951
// decompress image
923-
DecompressImage(dst, w, h, tmp.get(), m_compression, m_dds.fmt,
924-
threads());
952+
DecompressImage(dst, int(w), int(h), tmp.get(), m_compression,
953+
m_dds.fmt, threads());
925954
tmp.reset();
926955
// correct pre-multiplied alpha, if necessary
927956
if (m_compression == Compression::DXT2
928957
|| m_compression == Compression::DXT4) {
929-
int k;
930-
for (int y = 0; y < h; y++) {
931-
for (int x = 0; x < w; x++) {
958+
size_t k;
959+
for (size_t y = 0; y < h; y++) {
960+
for (size_t x = 0; x < w; x++) {
932961
k = (y * w + x) * 4;
933962
if (dst[k + 3]) {
934963
dst[k + 0] = (unsigned char)((int)dst[k + 0] * 255
@@ -961,12 +990,12 @@ DDSInput::internal_readimg(unsigned char* dst, int w, int h, int d)
961990
}
962991

963992
std::unique_ptr<uint8_t[]> tmp(new uint8_t[w * m_Bpp]);
964-
for (int z = 0; z < d; z++) {
965-
for (int y = 0; y < h; y++) {
993+
for (size_t z = 0; z < d; z++) {
994+
for (size_t y = 0; y < h; y++) {
966995
if (!ioread(tmp.get(), w, m_Bpp))
967996
return false;
968997
size_t k = (z * h * w + y * w) * m_spec.nchannels;
969-
for (int x = 0; x < w; x++, k += m_spec.nchannels) {
998+
for (size_t x = 0; x < w; x++, k += m_spec.nchannels) {
970999
uint32_t pixel = 0;
9711000
memcpy(&pixel, tmp.get() + x * m_Bpp, m_Bpp);
9721001
for (int ch = 0; ch < m_spec.nchannels; ++ch) {
@@ -992,8 +1021,8 @@ DDSInput::readimg_scanlines()
9921021
m_buf.resize(m_spec.scanline_bytes() * m_spec.height * m_spec.depth
9931022
/*/ (1 << m_miplevel)*/);
9941023

995-
return internal_readimg(&m_buf[0], m_spec.width, m_spec.height,
996-
m_spec.depth);
1024+
return internal_readimg(&m_buf[0], size_t(m_spec.width),
1025+
size_t(m_spec.height), size_t(m_spec.depth));
9971026
}
9981027

9991028

@@ -1003,8 +1032,9 @@ DDSInput::readimg_tiles()
10031032
{
10041033
// resize destination buffer
10051034
OIIO_ASSERT(m_buf.size() >= m_spec.tile_bytes());
1006-
return internal_readimg(&m_buf[0], m_spec.tile_width, m_spec.tile_height,
1007-
m_spec.tile_depth);
1035+
return internal_readimg(&m_buf[0], size_t(m_spec.tile_width),
1036+
size_t(m_spec.tile_height),
1037+
size_t(m_spec.tile_depth));
10081038
}
10091039

10101040

@@ -1032,8 +1062,9 @@ DDSInput::read_native_scanline(int subimage, int miplevel, int y, int z,
10321062
if (m_buf.empty())
10331063
readimg_scanlines();
10341064

1035-
size_t size = spec().scanline_bytes();
1036-
memcpy(data, &m_buf[0] + z * m_spec.height * size + y * size, size);
1065+
size_t size = spec().scanline_bytes();
1066+
size_t offset = size_t(z) * m_spec.height * size + size_t(y) * size;
1067+
memcpy(data, &m_buf[0] + offset, size);
10371068
return true;
10381069
}
10391070

@@ -1075,10 +1106,10 @@ DDSInput::read_native_tile(int subimage, int miplevel, int x, int y, int z,
10751106
|| z % m_spec.tile_width)
10761107
return false;
10771108
if (m_buf.empty() || x != lastx || y != lasty || z != lastz) {
1078-
lastx = x;
1079-
lasty = y;
1080-
lastz = z;
1081-
unsigned int w = 0, h = 0, d = 0;
1109+
lastx = x;
1110+
lasty = y;
1111+
lastz = z;
1112+
size_t w = 0, h = 0, d = 0;
10821113
#ifdef DDS_3X2_CUBE_MAP_LAYOUT
10831114
internal_seek_subimage(((x / m_spec.tile_width) << 1)
10841115
+ y / m_spec.tile_height,

src/include/OpenImageIO/imagebuf.h

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1386,14 +1386,23 @@ class OIIO_API ImageBuf {
13861386
/// Z plane stride within the localpixels memory.
13871387
stride_t z_stride() const;
13881388

1389-
/// Is this an in-memory buffer with the data layout "contiguous", i.e.,
1389+
/// Is this an in-memory buffer with the data layout "fully contiguous",
1390+
/// i.e.,
13901391
/// ```
13911392
/// pixel_stride == nchannels * pixeltype().size()
13921393
/// scanline_stride == pixel_stride * spec().width
13931394
/// z_stride == scanline_stride * spec().height
13941395
/// ```
13951396
bool contiguous() const;
13961397

1398+
/// Is this an in-memory buffer with the data layout "contiguous" for
1399+
/// each scanline (but not considering whether adjacent scanlines or
1400+
/// image planes are fully contiguous), i.e.,
1401+
/// ```
1402+
/// pixel_stride == nchannels * pixeltype().size()
1403+
/// ```
1404+
bool contiguous_scanline() const;
1405+
13971406
/// Are the pixels backed by an ImageCache, rather than the whole
13981407
/// image being in RAM somewhere?
13991408
bool cachedpixels() const;

0 commit comments

Comments
 (0)