Import Upstream version 2.3.0

This commit is contained in:
openKylinBot 2022-05-14 03:32:46 +08:00
commit c37484590d
192 changed files with 99077 additions and 0 deletions

21
AUTHORS Normal file
View File

@ -0,0 +1,21 @@
Developers:
-----------
Florian Kainz <kainz@ilm.com>
Rod Bogart <rgb@ilm.com>
Drew Hess <dhess@ilm.com>
Bill Anderson <wja@ilm.com>
Wojciech Jarosz <wjarosz@ucsd.edu>
Contributors:
-------------
Rito Trevino
Josh Pines
Christian Rouet
Win32 build system:
-------------------
Nick Porcino <NPorcino@lucasarts.com>
Kimball Thurston

195
CMakeLists.txt Normal file
View File

@ -0,0 +1,195 @@
IF (WIN32)
CMAKE_MINIMUM_REQUIRED(VERSION 3.11)
ELSE()
CMAKE_MINIMUM_REQUIRED(VERSION 3.2)
ENDIF()
PROJECT ( ilmbase )
set(ILMBASE_BASEVERSION ${OPENEXR_BASEVERSION})
set(ILMBASE_VERSION_MAJOR ${OPENEXR_VERSION_MAJOR})
set(ILMBASE_VERSION_MINOR ${OPENEXR_VERSION_MINOR})
set(ILMBASE_VERSION_PATCH ${OPENEXR_VERSION_PATCH})
set(ILMBASE_VERSION ${OPENEXR_VERSION})
set(ILMBASE_VERSION_API ${OPENEXR_VERSION_API})
INCLUDE_DIRECTORIES ( Iex IexMath Imath Half
IlmThread IexTest ImathTest HalfTest
${CMAKE_CURRENT_BINARY_DIR}/config )
IF(WIN32)
SET(CMAKE_DEBUG_POSTFIX "_d")
ENDIF()
# also add the current directory to pick up the autogenerated headers
SET(CMAKE_INCLUDE_CURRENT_DIR ON)
MACRO(GET_TARGET_PROPERTY_WITH_DEFAULT _variable _target _property _default_value)
GET_TARGET_PROPERTY (${_variable} ${_target} ${_property})
IF (${_variable} MATCHES NOTFOUND)
SET (${_variable} ${_default_value})
ENDIF (${_variable} MATCHES NOTFOUND)
ENDMACRO (GET_TARGET_PROPERTY_WITH_DEFAULT)
MACRO(CREATE_LIBTOOL_FILE _target _install_DIR)
SET(_target_location $<TARGET_FILE:${_target}>)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_static_lib ${_target} STATIC_LIB "")
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dependency_libs ${_target} LT_DEPENDENCY_LIBS "")
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_current ${_target} LT_VERSION_CURRENT 0)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_age ${_target} LT_VERSION_AGE 0)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_revision ${_target} LT_VERSION_REVISION 0)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_installed ${_target} LT_INSTALLED yes)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_shouldnotlink ${_target} LT_SHOULDNOTLINK yes)
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlopen ${_target} LT_DLOPEN "")
GET_TARGET_PROPERTY_WITH_DEFAULT(_target_dlpreopen ${_target} LT_DLPREOPEN "")
SET(_laname ${_target}${OPENEXR_LIBSUFFIX})
SET(_soname ${_laname})
SET(_laname ${PROJECT_BINARY_DIR}/${_laname}.la)
FILE(WRITE ${_laname} "# ${_laname} - a libtool library file\n")
FILE(APPEND ${_laname} "# Generated by CMake ${CMAKE_VERSION} (like GNU libtool)\n")
FILE(APPEND ${_laname} "\n# Please DO NOT delete this file!\n# It is necessary for linking the library with libtool.\n\n" )
FILE(APPEND ${_laname} "# The name that we can dlopen(3).\n")
FILE(APPEND ${_laname} "dlname='${_soname}'\n\n")
FILE(APPEND ${_laname} "# Names of this library.\n")
FILE(APPEND ${_laname} "library_names='${_soname}.${_target_current}.${_target_age}.${_target_revision} ${_soname}.${_target_current} ${_soname}'\n\n")
FILE(APPEND ${_laname} "# The name of the static archive.\n")
FILE(APPEND ${_laname} "old_library='${_target_static_lib}'\n\n")
FILE(APPEND ${_laname} "# Libraries that this one depends upon.\n")
FILE(APPEND ${_laname} "dependency_libs='${_target_dependency_libs}'\n\n")
FILE(APPEND ${_laname} "# Names of additional weak libraries provided by this library\n")
FILE(APPEND ${_laname} "weak_library_names=\n\n")
FILE(APPEND ${_laname} "# Version information for ${_laname}.\n")
FILE(APPEND ${_laname} "current=${_target_current}\n")
FILE(APPEND ${_laname} "age=${_target_age}\n")
FILE(APPEND ${_laname} "revision=${_target_revision}\n\n")
FILE(APPEND ${_laname} "# Is this an already installed library?\n")
FILE(APPEND ${_laname} "installed=${_target_installed}\n\n")
FILE(APPEND ${_laname} "# Should we warn about portability when linking against -modules?\n")
FILE(APPEND ${_laname} "shouldnotlink=${_target_shouldnotlink}\n\n")
FILE(APPEND ${_laname} "# Files to dlopen/dlpreopen\n")
FILE(APPEND ${_laname} "dlopen='${_target_dlopen}'\n")
FILE(APPEND ${_laname} "dlpreopen='${_target_dlpreopen}'\n\n")
FILE(APPEND ${_laname} "# Directory that this library needs to be installed in:\n")
FILE(APPEND ${_laname} "libdir='${CMAKE_INSTALL_PREFIX}${_install_DIR}'\n")
INSTALL( FILES ${_laname} DESTINATION ${CMAKE_INSTALL_PREFIX}${_install_DIR})
ENDMACRO(CREATE_LIBTOOL_FILE)
ADD_SUBDIRECTORY ( Half )
ADD_SUBDIRECTORY ( Iex )
ADD_SUBDIRECTORY ( IexMath )
ADD_SUBDIRECTORY ( Imath )
ADD_SUBDIRECTORY ( IlmThread )
##########################
# IlmBaseConfig.h generation
##########################
# By using a temp file then using configure_file below with copy, we
# avoid constantly updating it (unless a value has changed)
SET(ILMBASE_TMP_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h.in)
IF (WIN32)
FILE ( WRITE ${ILMBASE_TMP_CONFIG} "#ifdef HAVE_PTHREAD\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "# undef HAVE_PTHREAD\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#endif\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#ifdef HAVE_POSIX_SEMAPHORES\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "# undef HAVE_POSIX_SEMAPHORES\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#endif\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define PLATFORM_WINDOWS 1\n" )
ELSE ()
IF (APPLE)
FILE ( WRITE ${ILMBASE_TMP_CONFIG} "#define HAVE_PTHREAD 1\n" )
ELSE ()
FILE ( WRITE ${ILMBASE_TMP_CONFIG} "#define HAVE_PTHREAD 1\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_HAVE_LARGE_STACK 1\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define HAVE_POSIX_SEMAPHORES 1\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_HAVE_CONTROL_REGISTER_SUPPORT 1\n")
ENDIF ()
ENDIF ()
IF (OPENEXR_FORCE_CXX03)
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_FORCE_CXX03 1\n" )
ELSEIF (NOT WIN32)
# really only care about c++11 right now for the threading bits, but this can be changed to 14
# when needed...
# Note that the __cplusplus check is not valid under MSVC
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#if __cplusplus < 201103L\n# error \"Modern C++ 11/14 not enabled but force cxx03 not set\"\n#endif\n" )
ENDIF ()
IF (OPENEXR_NAMESPACE_VERSIONING)
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_INTERNAL_NAMESPACE_CUSTOM 1\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define IMATH_INTERNAL_NAMESPACE Imath_${ILMBASE_VERSION_API}\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define IEX_INTERNAL_NAMESPACE Iex_${ILMBASE_VERSION_API}\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMTHREAD_INTERNAL_NAMESPACE IlmThread_${ILMBASE_VERSION_API}\n")
ELSE ()
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_INTERNAL_NAMESPACE_CUSTOM 0\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define IMATH_INTERNAL_NAMESPACE Imath\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define IEX_INTERNAL_NAMESPACE Iex\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMTHREAD_INTERNAL_NAMESPACE IlmThread\n")
ENDIF ()
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define IMATH_NAMESPACE Imath\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define IEX_NAMESPACE Iex\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMTHREAD_NAMESPACE IlmThread\n")
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_VERSION_STRING \"${ILMBASE_VERSION}\"\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_PACKAGE_STRING \"IlmBase ${ILMBASE_VERSION}\"\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_VERSION_MAJOR ${ILMBASE_VERSION_MAJOR}\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_VERSION_MINOR ${ILMBASE_VERSION_MINOR}\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "#define ILMBASE_VERSION_PATCH ${ILMBASE_VERSION_PATCH}\n" )
FILE ( APPEND ${ILMBASE_TMP_CONFIG} "
// Version as a single hex number, e.g. 0x01000300 == 1.0.3
#define ILMBASE_VERSION_HEX ((ILMBASE_VERSION_MAJOR << 24) | \\
(ILMBASE_VERSION_MINOR << 16) | \\
(ILMBASE_VERSION_PATCH << 8))
")
CONFIGURE_FILE ( ${ILMBASE_TMP_CONFIG} ${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h COPYONLY )
FILE ( REMOVE ${ILMBASE_TMP_CONFIG} )
UNSET ( ILMBASE_TMP_CONFIG )
IF ( NOT WIN32 AND OPENEXR_BUILD_SHARED )
CREATE_LIBTOOL_FILE ( Half /lib )
CREATE_LIBTOOL_FILE ( Iex /lib )
CREATE_LIBTOOL_FILE ( IexMath /lib )
CREATE_LIBTOOL_FILE ( Imath /lib )
CREATE_LIBTOOL_FILE ( IlmThread /lib )
ENDIF ()
# Tests
IF ( ENABLE_TESTS )
ADD_SUBDIRECTORY ( HalfTest )
ADD_SUBDIRECTORY ( IexTest )
ADD_SUBDIRECTORY ( ImathTest )
ENDIF ()
# Installation
INSTALL ( FILES
${CMAKE_CURRENT_BINARY_DIR}/config/IlmBaseConfig.h
DESTINATION
include/OpenEXR
)
IF ( NOT WIN32 )
FILE ( WRITE ${CMAKE_BINARY_DIR}/IlmBase.pc "prefix=${CMAKE_INSTALL_PREFIX}\n" )
FILE ( APPEND ${CMAKE_BINARY_DIR}/IlmBase.pc "exec_prefix=\${prefix}
libdir=\${exec_prefix}/lib
includedir=\${prefix}/include
OpenEXR_includedir=\${prefix}/include/OpenEXR
Name: IlmBase
Description: Base math and exception libraries
Version: ${ILMBASE_VERSION}
Libs: -L\${libdir} -lImath${ILMBASE_LIBSUFFIX} -lIexMath${ILMBASE_LIBSUFFIX} -lHalf${ILMBASE_LIBSUFFIX} -lIex${ILMBASE_LIBSUFFIX} -lIlmThread${ILMBASE_LIBSUFFIX} -pthread
Cflags: -pthread -I\${OpenEXR_includedir}
")
INSTALL ( FILES
${CMAKE_BINARY_DIR}/IlmBase.pc
DESTINATION
lib/pkgconfig
)
ENDIF()

136
ChangeLog Normal file
View File

@ -0,0 +1,136 @@
Version 2.x.x
* Bumped version to track OpenEXR
(Piotr Stanczyk)
Version 2.0.1
* Bumped version to track OpenEXR
(Piotr Stanczyk)
Version 2.0.0
* Bumped version to track OpenEXR
(Piotr Stanczyk)
* Numerous minor fixes, missing includes etc
Version 1.1.0.beta.1
* Added new module PyIlmBase : python bindings for IlmBase
(Nick Rasmussen)
* Added git specific files
(Piotr Stanczyk)
* Minor fixes for newer gcc versions and OS X.
(misc)
* Preparation for OpenEXR v2 release { remove message for final release }
(Piotr Stanczyk)
* Updated the so verison to 10
(Piotr Stanczyk)
* Initial use of the CMake build system
(Nicholas Yue)
Version 1.0.3
* Added support for enabling/disabling large stack optimisations, used in
halfFunction.h.
(Piotr Stanczyk)
* Added ImathNoise.(h/cpp) files. Initializes Perlin noise to match the
Renderman implmenetation.
(Pixar Contribution)
* Fixed a number of missing includes to comply with stricter
enforcement by gnu compilers.
(Piotr Stanczyk)
* Depracated compiler flag: -Wno-long-double since it is no longer
supported under OS X.
(Piotr Stanczyk)
* A minor API change to Imath::Frustum has been made: the functions
'near' and 'far' have been renamed to 'nearPlane' and 'farPlane' due
to conflicts with certain windows headers. The former alternate
accessor names for these values on windows ('hither' and 'yon')
remain, though should be considered deprecated.
(David Lenihan)
* Added SVD, eigenvalue solver, and procrustes fit calculations
to ImathMatrixAlgo.
(Chris Twigg, Ji Hun Yu)
* Added Imath::FrustumTest for frustum visibility testing.
(Eric Johnston)
* Fixed a stack corruption in the matrix minorOf functions.
(Nick Rasmussen)
* Visual studio 2008 project files have been added to the vc/vc9
directory, and several minor visual studio compile fixes have
been applied.
(Nick Rasmussen)
* Updated the so verison to 7.
(Piotr Stanczyk)
* Depracated the MacCode_Warrior and Shake submodules.
(Piotr Stanczyk)
Version 1.0.2
* Added support for targetting builds on 64bit Windows and minimising
number of compiler warnings on Windows. Thanks to Ger Hobbelt for his
contributions to CreateDLL.
(Ji Hun Yu)
* Removed a spurious restrict qualifier in the matrix manipulation code
that was causing the 64-bit MS compiler to generate code in release
mode that caused incorrect results.
(Ji Hun Yu)
* Added patches for improving universal binaries on OS X. Thanks to
Paul Schneider for the contribution
(Piotr Stanczyk)
* Imath::Box optimization: remove loops from methods by partially
specializing the class, for boxes of two and three dimensions.
(Piotr Stanczyk)
* Added explicit copy constructors to Imath::Matrix33<T> and
ImathMatrix44<T> to make conversions between float and double
matrices more convenient.
(Florian Kainz)
* Added slerpShortestArc() and euclideanInnerProduct() functions
to Imath::Quat<T>.
(Nick Porcino)
* Added 4D vector class template Imath::Vec4<T>.
(Nick Porcino)
* Copy constructors and assignment operators for Matrix33<T>
and Matrix44<T> are up to 25% faster. Added matrix constructors
that do not initialize the matrix (this is faster in cases where
the initial value of the matrix is immediately overwritten anyway).
(Nick Porcino)
* Rewrote function closestPointOnBox(point,box). Shortened
the code, improved numerical accuracy, fixed a bug where
closestPointOnBox(box.center(),box) would return the center
of the +Z side of the box, even if the +/-X or +/-Y sides
were closer.
(Florian Kainz)
* Rewrote function findEntryAndExitPoints() in ImathBoxAlgo.h.
Results are now consistent with those from intersect(), also
in ImathBoxAlgo.h.
(Florian Kainz)
* Made Vec2<T>::length() and Vec3<T>::length() more accurate for
vectors whose length is less than sqrt(limits<T>::smallest());
(Florian Kainz)
* Made Quat<T>::angle() more accurate for small angles.
(Don Hatch)
Version 1.0.1:
* Removed Windows .suo files from distribution.
(Eric Wimmer)
Version 1.0.0:
* Bumped DSO version number to 6.0
(Florian Kainz)
* Rounding during float-to-half conversion now implements
"round to nearest even" mode: if the original float value
is exactly in the middle between the two closest half values
then rounding chooses the half value whose least significant
bit is zero.
(Florian Kainz)
* Installation Tuning:
- Corrected version number on dso's (libtool) - now 5.0
- Separated ILMBASE_LDFLAGS and ILMBASE_LIBS so that test programs
in configure scripts of packages dependent on IlmBase can link
with static libraries properly
- eliminated some warning messages during install
(Andrew Kunz)
Version 0.9.0:
* Initial release of this code as a separate library.
Previously the libraries contained were part of
version 1.4.0 of OpenEXR
* New build scripts for Linux/Unix
(Andrew Kunz)
* New Windows project files and build scripts
(Kimball Thurston)

94
Half/CMakeLists.txt Normal file
View File

@ -0,0 +1,94 @@
# yue.nicholas@gmail.com
ADD_EXECUTABLE ( eLut eLut.cpp )
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/eLut.h
COMMAND $<TARGET_FILE:eLut> ARGS > ${CMAKE_CURRENT_BINARY_DIR}/eLut.h
DEPENDS eLut)
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_CURRENT_BINARY_DIR}/eLut.h
PROPERTIES HEADER_FILE_ONLY TRUE)
ADD_EXECUTABLE ( toFloat toFloat.cpp )
ADD_CUSTOM_COMMAND(
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/toFloat.h
COMMAND $<TARGET_FILE:toFloat> ARGS > ${CMAKE_CURRENT_BINARY_DIR}/toFloat.h
DEPENDS toFloat)
SET_SOURCE_FILES_PROPERTIES(
${CMAKE_CURRENT_BINARY_DIR}/toFloat.h
PROPERTIES HEADER_FILE_ONLY TRUE)
SET_SOURCE_FILES_PROPERTIES(
half.cpp
PROPERTIES
OBJECT_DEPENDS
"${CMAKE_CURRENT_BINARY_DIR}/eLut.h;${CMAKE_CURRENT_BINARY_DIR}/toFloat.h"
)
SET (ILMBASE_LIB_TARGETS "")
IF (OPENEXR_BUILD_SHARED)
LIST ( APPEND ILMBASE_LIB_TARGETS Half )
ADD_LIBRARY ( Half SHARED
half.cpp
)
TARGET_COMPILE_DEFINITIONS ( Half PRIVATE HALF_EXPORTS )
IF (WIN32)
TARGET_COMPILE_DEFINITIONS ( Half PUBLIC OPENEXR_DLL )
ENDIF ()
SET_TARGET_PROPERTIES ( Half
PROPERTIES
VERSION ${OPENEXR_VERSION}
SOVERSION ${OPENEXR_SOVERSION}
OUTPUT_NAME "Half${ILMBASE_LIBSUFFIX}"
)
ADD_DEPENDENCIES ( Half toFloat eLut )
ENDIF ()
IF (BUILD_ILMBASE_STATIC)
LIST ( APPEND ILMBASE_LIB_TARGETS Half_static )
ADD_LIBRARY ( Half_static STATIC
half.cpp
)
SET_TARGET_PROPERTIES ( Half_static
PROPERTIES
VERSION ${ILMBASE_VERSION_MAJOR}.${ILMBASE_VERSION_MINOR}.${ILMBASE_VERSION_PATCH}
OUTPUT_NAME "Half${ILMBASE_LIBSUFFIX}_s"
)
ADD_DEPENDENCIES ( Half_static toFloat eLut )
ENDIF ()
IF (OPENEXR_BUILD_SHARED OR BUILD_ILMBASE_STATIC)
INSTALL ( TARGETS
${ILMBASE_LIB_TARGETS}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION ${RUNTIME_DIR}
)
ENDIF ()
INSTALL (
FILES
half.h
halfFunction.h
halfExport.h
halfLimits.h
DESTINATION
include/OpenEXR
)
if (OPENEXR_BUILD_SHARED)
add_library(IlmBase::Half ALIAS Half)
endif()
if (BUILD_ILMBASE_STATIC)
add_library(IlmBase::Half_static ALIAS Half_static)
endif()

32
Half/Makefile.am Normal file
View File

@ -0,0 +1,32 @@
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir)/config
lib_LTLIBRARIES = libHalf.la
libHalf_la_SOURCES = half.cpp half.h halfFunction.h halfLimits.h
libHalf_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
libHalfincludedir = $(includedir)/OpenEXR
libHalfinclude_HEADERS = half.h halfFunction.h halfLimits.h halfExport.h
# these are used to build eLut.h and toFloat.h dynamically
EXTRA_DIST = eLut.cpp toFloat.cpp CMakeLists.txt
CLEANFILES = eLut eLut.h toFloat toFloat.h
eLut_SOURCES = eLut.cpp
toFloat_SOURCES = toFloat.cpp
eLut.h: eLut
./eLut > eLut.h
toFloat.h: toFloat
./toFloat > toFloat.h
BUILT_SOURCES = eLut.h toFloat.h
noinst_PROGRAMS = eLut toFloat

745
Half/Makefile.in Normal file
View File

@ -0,0 +1,745 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
noinst_PROGRAMS = eLut$(EXEEXT) toFloat$(EXEEXT)
subdir = Half
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(libHalfinclude_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" \
"$(DESTDIR)$(libHalfincludedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libHalf_la_LIBADD =
am_libHalf_la_OBJECTS = half.lo
libHalf_la_OBJECTS = $(am_libHalf_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libHalf_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libHalf_la_LDFLAGS) $(LDFLAGS) -o $@
PROGRAMS = $(noinst_PROGRAMS)
am_eLut_OBJECTS = eLut.$(OBJEXT)
eLut_OBJECTS = $(am_eLut_OBJECTS)
eLut_LDADD = $(LDADD)
am_toFloat_OBJECTS = toFloat.$(OBJEXT)
toFloat_OBJECTS = $(am_toFloat_OBJECTS)
toFloat_LDADD = $(LDADD)
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libHalf_la_SOURCES) $(eLut_SOURCES) $(toFloat_SOURCES)
DIST_SOURCES = $(libHalf_la_SOURCES) $(eLut_SOURCES) \
$(toFloat_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(libHalfinclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
AM_CXXFLAGS = @AM_CXXFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
ILMBASE_VERSION = @ILMBASE_VERSION@
ILMBASE_VERSION_API = @ILMBASE_VERSION_API@
ILMBASE_VERSION_MAJOR = @ILMBASE_VERSION_MAJOR@
ILMBASE_VERSION_MINOR = @ILMBASE_VERSION_MINOR@
ILMBASE_VERSION_PATCH = @ILMBASE_VERSION_PATCH@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIB_SUFFIX = @LIB_SUFFIX@
LIB_SUFFIX_DASH = @LIB_SUFFIX_DASH@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
acx_pthread_config = @acx_pthread_config@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
INCLUDES = -I$(top_srcdir)/config
lib_LTLIBRARIES = libHalf.la
libHalf_la_SOURCES = half.cpp half.h halfFunction.h halfLimits.h
libHalf_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
libHalfincludedir = $(includedir)/OpenEXR
libHalfinclude_HEADERS = half.h halfFunction.h halfLimits.h halfExport.h
# these are used to build eLut.h and toFloat.h dynamically
EXTRA_DIST = eLut.cpp toFloat.cpp CMakeLists.txt
CLEANFILES = eLut eLut.h toFloat toFloat.h
eLut_SOURCES = eLut.cpp
toFloat_SOURCES = toFloat.cpp
BUILT_SOURCES = eLut.h toFloat.h
all: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Half/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Half/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libHalf.la: $(libHalf_la_OBJECTS) $(libHalf_la_DEPENDENCIES) $(EXTRA_libHalf_la_DEPENDENCIES)
$(AM_V_CXXLD)$(libHalf_la_LINK) -rpath $(libdir) $(libHalf_la_OBJECTS) $(libHalf_la_LIBADD) $(LIBS)
clean-noinstPROGRAMS:
@list='$(noinst_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
eLut$(EXEEXT): $(eLut_OBJECTS) $(eLut_DEPENDENCIES) $(EXTRA_eLut_DEPENDENCIES)
@rm -f eLut$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(eLut_OBJECTS) $(eLut_LDADD) $(LIBS)
toFloat$(EXEEXT): $(toFloat_OBJECTS) $(toFloat_DEPENDENCIES) $(EXTRA_toFloat_DEPENDENCIES)
@rm -f toFloat$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(toFloat_OBJECTS) $(toFloat_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eLut.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/half.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/toFloat.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-libHalfincludeHEADERS: $(libHalfinclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(libHalfinclude_HEADERS)'; test -n "$(libHalfincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(libHalfincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libHalfincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libHalfincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libHalfincludedir)" || exit $$?; \
done
uninstall-libHalfincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libHalfinclude_HEADERS)'; test -n "$(libHalfincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(libHalfincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) check-am
all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libHalfincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: $(BUILT_SOURCES)
$(MAKE) $(AM_MAKEFLAGS) install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
-test -z "$(CLEANFILES)" || rm -f $(CLEANFILES)
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
-test -z "$(BUILT_SOURCES)" || rm -f $(BUILT_SOURCES)
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
clean-noinstPROGRAMS mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-libHalfincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libHalfincludeHEADERS uninstall-libLTLIBRARIES
.MAKE: all check install install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool clean-noinstPROGRAMS \
cscopelist-am ctags ctags-am distclean distclean-compile \
distclean-generic distclean-libtool distclean-tags distdir dvi \
dvi-am html html-am info info-am install install-am \
install-data install-data-am install-dvi install-dvi-am \
install-exec install-exec-am install-html install-html-am \
install-info install-info-am install-libHalfincludeHEADERS \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am \
uninstall-libHalfincludeHEADERS uninstall-libLTLIBRARIES
eLut.h: eLut
./eLut > eLut.h
toFloat.h: toFloat
./toFloat > toFloat.h
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

114
Half/eLut.cpp Normal file
View File

@ -0,0 +1,114 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#include <iostream>
#include <iomanip>
using namespace std;
//-----------------------------------------------------
// Compute a lookup table for float-to-half conversion.
//
// When indexed with the combined sign and exponent of
// a float, the table either returns the combined sign
// and exponent of the corresponding half, or zero if
// the corresponding half may not be normalized (zero,
// denormalized, overflow).
//-----------------------------------------------------
void
initELut (unsigned short eLut[])
{
for (int i = 0; i < 0x100; i++)
{
int e = (i & 0x0ff) - (127 - 15);
if (e <= 0 || e >= 30)
{
//
// Special case
//
eLut[i] = 0;
eLut[i | 0x100] = 0;
}
else
{
//
// Common case - normalized half, no exponent overflow possible
//
eLut[i] = (e << 10);
eLut[i | 0x100] = ((e << 10) | 0x8000);
}
}
}
//------------------------------------------------------------
// Main - prints the sign-and-exponent conversion lookup table
//------------------------------------------------------------
int
main ()
{
const int tableSize = 1 << 9;
unsigned short eLut[tableSize];
initELut (eLut);
cout << "//\n"
"// This is an automatically generated file.\n"
"// Do not edit.\n"
"//\n\n";
cout << "{\n ";
for (int i = 0; i < tableSize; i++)
{
cout << setw (5) << eLut[i] << ", ";
if (i % 8 == 7)
{
cout << "\n";
if (i < tableSize - 1)
cout << " ";
}
}
cout << "};\n";
return 0;
}

310
Half/half.cpp Normal file
View File

@ -0,0 +1,310 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// class half --
// implementation of non-inline members
//
//---------------------------------------------------------------------------
#include <assert.h>
#include "half.h"
using namespace std;
//-------------------------------------------------------------
// Lookup tables for half-to-float and float-to-half conversion
//-------------------------------------------------------------
HALF_EXPORT const half::uif half::_toFloat[1 << 16] =
#include "toFloat.h"
HALF_EXPORT const unsigned short half::_eLut[1 << 9] =
#include "eLut.h"
//-----------------------------------------------
// Overflow handler for float-to-half conversion;
// generates a hardware floating-point overflow,
// which may be trapped by the operating system.
//-----------------------------------------------
HALF_EXPORT float
half::overflow ()
{
volatile float f = 1e10;
for (int i = 0; i < 10; i++)
f *= f; // this will overflow before
// the for­loop terminates
return f;
}
//-----------------------------------------------------
// Float-to-half conversion -- general case, including
// zeroes, denormalized numbers and exponent overflows.
//-----------------------------------------------------
HALF_EXPORT short
half::convert (int i)
{
//
// Our floating point number, f, is represented by the bit
// pattern in integer i. Disassemble that bit pattern into
// the sign, s, the exponent, e, and the significand, m.
// Shift s into the position where it will go in in the
// resulting half number.
// Adjust e, accounting for the different exponent bias
// of float and half (127 versus 15).
//
int s = (i >> 16) & 0x00008000;
int e = ((i >> 23) & 0x000000ff) - (127 - 15);
int m = i & 0x007fffff;
//
// Now reassemble s, e and m into a half:
//
if (e <= 0)
{
if (e < -10)
{
//
// E is less than -10. The absolute value of f is
// less than HALF_MIN (f may be a small normalized
// float, a denormalized float or a zero).
//
// We convert f to a half zero with the same sign as f.
//
return s;
}
//
// E is between -10 and 0. F is a normalized float
// whose magnitude is less than HALF_NRM_MIN.
//
// We convert f to a denormalized half.
//
//
// Add an explicit leading 1 to the significand.
//
m = m | 0x00800000;
//
// Round to m to the nearest (10+e)-bit value (with e between
// -10 and 0); in case of a tie, round to the nearest even value.
//
// Rounding may cause the significand to overflow and make
// our number normalized. Because of the way a half's bits
// are laid out, we don't have to treat this case separately;
// the code below will handle it correctly.
//
int t = 14 - e;
int a = (1 << (t - 1)) - 1;
int b = (m >> t) & 1;
m = (m + a + b) >> t;
//
// Assemble the half from s, e (zero) and m.
//
return s | m;
}
else if (e == 0xff - (127 - 15))
{
if (m == 0)
{
//
// F is an infinity; convert f to a half
// infinity with the same sign as f.
//
return s | 0x7c00;
}
else
{
//
// F is a NAN; we produce a half NAN that preserves
// the sign bit and the 10 leftmost bits of the
// significand of f, with one exception: If the 10
// leftmost bits are all zero, the NAN would turn
// into an infinity, so we have to set at least one
// bit in the significand.
//
m >>= 13;
return s | 0x7c00 | m | (m == 0);
}
}
else
{
//
// E is greater than zero. F is a normalized float.
// We try to convert f to a normalized half.
//
//
// Round to m to the nearest 10-bit value. In case of
// a tie, round to the nearest even value.
//
m = m + 0x00000fff + ((m >> 13) & 1);
if (m & 0x00800000)
{
m = 0; // overflow in significand,
e += 1; // adjust exponent
}
//
// Handle exponent overflow
//
if (e > 30)
{
overflow (); // Cause a hardware floating point overflow;
return s | 0x7c00; // if this returns, the half becomes an
} // infinity with the same sign as f.
//
// Assemble the half from s, e and m.
//
return s | (e << 10) | (m >> 13);
}
}
//---------------------
// Stream I/O operators
//---------------------
HALF_EXPORT ostream &
operator << (ostream &os, half h)
{
os << float (h);
return os;
}
HALF_EXPORT istream &
operator >> (istream &is, half &h)
{
float f;
is >> f;
h = half (f);
return is;
}
//---------------------------------------
// Functions to print the bit-layout of
// floats and halfs, mostly for debugging
//---------------------------------------
HALF_EXPORT void
printBits (ostream &os, half h)
{
unsigned short b = h.bits();
for (int i = 15; i >= 0; i--)
{
os << (((b >> i) & 1)? '1': '0');
if (i == 15 || i == 10)
os << ' ';
}
}
HALF_EXPORT void
printBits (ostream &os, float f)
{
half::uif x;
x.f = f;
for (int i = 31; i >= 0; i--)
{
os << (((x.i >> i) & 1)? '1': '0');
if (i == 31 || i == 23)
os << ' ';
}
}
HALF_EXPORT void
printBits (char c[19], half h)
{
unsigned short b = h.bits();
for (int i = 15, j = 0; i >= 0; i--, j++)
{
c[j] = (((b >> i) & 1)? '1': '0');
if (i == 15 || i == 10)
c[++j] = ' ';
}
c[18] = 0;
}
HALF_EXPORT void
printBits (char c[35], float f)
{
half::uif x;
x.f = f;
for (int i = 31, j = 0; i >= 0; i--, j++)
{
c[j] = (((x.i >> i) & 1)? '1': '0');
if (i == 31 || i == 23)
c[++j] = ' ';
}
c[34] = 0;
}

761
Half/half.h Normal file
View File

@ -0,0 +1,761 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// half -- a 16-bit floating point number class:
//
// Type half can represent positive and negative numbers whose
// magnitude is between roughly 6.1e-5 and 6.5e+4 with a relative
// error of 9.8e-4; numbers smaller than 6.1e-5 can be represented
// with an absolute error of 6.0e-8. All integers from -2048 to
// +2048 can be represented exactly.
//
// Type half behaves (almost) like the built-in C++ floating point
// types. In arithmetic expressions, half, float and double can be
// mixed freely. Here are a few examples:
//
// half a (3.5);
// float b (a + sqrt (a));
// a += b;
// b += a;
// b = a + 7;
//
// Conversions from half to float are lossless; all half numbers
// are exactly representable as floats.
//
// Conversions from float to half may not preserve a float's value
// exactly. If a float is not representable as a half, then the
// float value is rounded to the nearest representable half. If a
// float value is exactly in the middle between the two closest
// representable half values, then the float value is rounded to
// the closest half whose least significant bit is zero.
//
// Overflows during float-to-half conversions cause arithmetic
// exceptions. An overflow occurs when the float value to be
// converted is too large to be represented as a half, or if the
// float value is an infinity or a NAN.
//
// The implementation of type half makes the following assumptions
// about the implementation of the built-in C++ types:
//
// float is an IEEE 754 single-precision number
// sizeof (float) == 4
// sizeof (unsigned int) == sizeof (float)
// alignof (unsigned int) == alignof (float)
// sizeof (unsigned short) == 2
//
//---------------------------------------------------------------------------
#ifndef _HALF_H_
#define _HALF_H_
#include "halfExport.h" // for definition of HALF_EXPORT
#include <iostream>
class half
{
public:
//-------------
// Constructors
//-------------
half (); // no initialization
half (float f);
//--------------------
// Conversion to float
//--------------------
operator float () const;
//------------
// Unary minus
//------------
half operator - () const;
//-----------
// Assignment
//-----------
half & operator = (half h);
half & operator = (float f);
half & operator += (half h);
half & operator += (float f);
half & operator -= (half h);
half & operator -= (float f);
half & operator *= (half h);
half & operator *= (float f);
half & operator /= (half h);
half & operator /= (float f);
//---------------------------------------------------------
// Round to n-bit precision (n should be between 0 and 10).
// After rounding, the significand's 10-n least significant
// bits will be zero.
//---------------------------------------------------------
half round (unsigned int n) const;
//--------------------------------------------------------------------
// Classification:
//
// h.isFinite() returns true if h is a normalized number,
// a denormalized number or zero
//
// h.isNormalized() returns true if h is a normalized number
//
// h.isDenormalized() returns true if h is a denormalized number
//
// h.isZero() returns true if h is zero
//
// h.isNan() returns true if h is a NAN
//
// h.isInfinity() returns true if h is a positive
// or a negative infinity
//
// h.isNegative() returns true if the sign bit of h
// is set (negative)
//--------------------------------------------------------------------
bool isFinite () const;
bool isNormalized () const;
bool isDenormalized () const;
bool isZero () const;
bool isNan () const;
bool isInfinity () const;
bool isNegative () const;
//--------------------------------------------
// Special values
//
// posInf() returns +infinity
//
// negInf() returns -infinity
//
// qNan() returns a NAN with the bit
// pattern 0111111111111111
//
// sNan() returns a NAN with the bit
// pattern 0111110111111111
//--------------------------------------------
static half posInf ();
static half negInf ();
static half qNan ();
static half sNan ();
//--------------------------------------
// Access to the internal representation
//--------------------------------------
HALF_EXPORT unsigned short bits () const;
HALF_EXPORT void setBits (unsigned short bits);
public:
union uif
{
unsigned int i;
float f;
};
private:
HALF_EXPORT static short convert (int i);
HALF_EXPORT static float overflow ();
unsigned short _h;
HALF_EXPORT static const uif _toFloat[1 << 16];
HALF_EXPORT static const unsigned short _eLut[1 << 9];
};
//-----------
// Stream I/O
//-----------
HALF_EXPORT std::ostream & operator << (std::ostream &os, half h);
HALF_EXPORT std::istream & operator >> (std::istream &is, half &h);
//----------
// Debugging
//----------
HALF_EXPORT void printBits (std::ostream &os, half h);
HALF_EXPORT void printBits (std::ostream &os, float f);
HALF_EXPORT void printBits (char c[19], half h);
HALF_EXPORT void printBits (char c[35], float f);
//-------------------------------------------------------------------------
// Limits
//
// Visual C++ will complain if HALF_MIN, HALF_NRM_MIN etc. are not float
// constants, but at least one other compiler (gcc 2.96) produces incorrect
// results if they are.
//-------------------------------------------------------------------------
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#define HALF_MIN 5.96046448e-08f // Smallest positive half
#define HALF_NRM_MIN 6.10351562e-05f // Smallest positive normalized half
#define HALF_MAX 65504.0f // Largest positive half
#define HALF_EPSILON 0.00097656f // Smallest positive e for which
// half (1.0 + e) != half (1.0)
#else
#define HALF_MIN 5.96046448e-08 // Smallest positive half
#define HALF_NRM_MIN 6.10351562e-05 // Smallest positive normalized half
#define HALF_MAX 65504.0 // Largest positive half
#define HALF_EPSILON 0.00097656 // Smallest positive e for which
// half (1.0 + e) != half (1.0)
#endif
#define HALF_MANT_DIG 11 // Number of digits in mantissa
// (significand + hidden leading 1)
#define HALF_DIG 2 // Number of base 10 digits that
// can be represented without change
#define HALF_DECIMAL_DIG 5 // Number of base-10 digits that are
// necessary to uniquely represent all
// distinct values
#define HALF_RADIX 2 // Base of the exponent
#define HALF_MIN_EXP -13 // Minimum negative integer such that
// HALF_RADIX raised to the power of
// one less than that integer is a
// normalized half
#define HALF_MAX_EXP 16 // Maximum positive integer such that
// HALF_RADIX raised to the power of
// one less than that integer is a
// normalized half
#define HALF_MIN_10_EXP -4 // Minimum positive integer such
// that 10 raised to that power is
// a normalized half
#define HALF_MAX_10_EXP 4 // Maximum positive integer such
// that 10 raised to that power is
// a normalized half
//---------------------------------------------------------------------------
//
// Implementation --
//
// Representation of a float:
//
// We assume that a float, f, is an IEEE 754 single-precision
// floating point number, whose bits are arranged as follows:
//
// 31 (msb)
// |
// | 30 23
// | | |
// | | | 22 0 (lsb)
// | | | | |
// X XXXXXXXX XXXXXXXXXXXXXXXXXXXXXXX
//
// s e m
//
// S is the sign-bit, e is the exponent and m is the significand.
//
// If e is between 1 and 254, f is a normalized number:
//
// s e-127
// f = (-1) * 2 * 1.m
//
// If e is 0, and m is not zero, f is a denormalized number:
//
// s -126
// f = (-1) * 2 * 0.m
//
// If e and m are both zero, f is zero:
//
// f = 0.0
//
// If e is 255, f is an "infinity" or "not a number" (NAN),
// depending on whether m is zero or not.
//
// Examples:
//
// 0 00000000 00000000000000000000000 = 0.0
// 0 01111110 00000000000000000000000 = 0.5
// 0 01111111 00000000000000000000000 = 1.0
// 0 10000000 00000000000000000000000 = 2.0
// 0 10000000 10000000000000000000000 = 3.0
// 1 10000101 11110000010000000000000 = -124.0625
// 0 11111111 00000000000000000000000 = +infinity
// 1 11111111 00000000000000000000000 = -infinity
// 0 11111111 10000000000000000000000 = NAN
// 1 11111111 11111111111111111111111 = NAN
//
// Representation of a half:
//
// Here is the bit-layout for a half number, h:
//
// 15 (msb)
// |
// | 14 10
// | | |
// | | | 9 0 (lsb)
// | | | | |
// X XXXXX XXXXXXXXXX
//
// s e m
//
// S is the sign-bit, e is the exponent and m is the significand.
//
// If e is between 1 and 30, h is a normalized number:
//
// s e-15
// h = (-1) * 2 * 1.m
//
// If e is 0, and m is not zero, h is a denormalized number:
//
// S -14
// h = (-1) * 2 * 0.m
//
// If e and m are both zero, h is zero:
//
// h = 0.0
//
// If e is 31, h is an "infinity" or "not a number" (NAN),
// depending on whether m is zero or not.
//
// Examples:
//
// 0 00000 0000000000 = 0.0
// 0 01110 0000000000 = 0.5
// 0 01111 0000000000 = 1.0
// 0 10000 0000000000 = 2.0
// 0 10000 1000000000 = 3.0
// 1 10101 1111000001 = -124.0625
// 0 11111 0000000000 = +infinity
// 1 11111 0000000000 = -infinity
// 0 11111 1000000000 = NAN
// 1 11111 1111111111 = NAN
//
// Conversion:
//
// Converting from a float to a half requires some non-trivial bit
// manipulations. In some cases, this makes conversion relatively
// slow, but the most common case is accelerated via table lookups.
//
// Converting back from a half to a float is easier because we don't
// have to do any rounding. In addition, there are only 65536
// different half numbers; we can convert each of those numbers once
// and store the results in a table. Later, all conversions can be
// done using only simple table lookups.
//
//---------------------------------------------------------------------------
//--------------------
// Simple constructors
//--------------------
inline
half::half ()
{
// no initialization
}
//----------------------------
// Half-from-float constructor
//----------------------------
inline
half::half (float f)
{
uif x;
x.f = f;
if (f == 0)
{
//
// Common special case - zero.
// Preserve the zero's sign bit.
//
_h = (x.i >> 16);
}
else
{
//
// We extract the combined sign and exponent, e, from our
// floating-point number, f. Then we convert e to the sign
// and exponent of the half number via a table lookup.
//
// For the most common case, where a normalized half is produced,
// the table lookup returns a non-zero value; in this case, all
// we have to do is round f's significand to 10 bits and combine
// the result with e.
//
// For all other cases (overflow, zeroes, denormalized numbers
// resulting from underflow, infinities and NANs), the table
// lookup returns zero, and we call a longer, non-inline function
// to do the float-to-half conversion.
//
int e = (x.i >> 23) & 0x000001ff;
e = _eLut[e];
if (e)
{
//
// Simple case - round the significand, m, to 10
// bits and combine it with the sign and exponent.
//
int m = x.i & 0x007fffff;
_h = e + ((m + 0x00000fff + ((m >> 13) & 1)) >> 13);
}
else
{
//
// Difficult case - call a function.
//
_h = convert (x.i);
}
}
}
//------------------------------------------
// Half-to-float conversion via table lookup
//------------------------------------------
inline
half::operator float () const
{
return _toFloat[_h].f;
}
//-------------------------
// Round to n-bit precision
//-------------------------
inline half
half::round (unsigned int n) const
{
//
// Parameter check.
//
if (n >= 10)
return *this;
//
// Disassemble h into the sign, s,
// and the combined exponent and significand, e.
//
unsigned short s = _h & 0x8000;
unsigned short e = _h & 0x7fff;
//
// Round the exponent and significand to the nearest value
// where ones occur only in the (10-n) most significant bits.
// Note that the exponent adjusts automatically if rounding
// up causes the significand to overflow.
//
e >>= 9 - n;
e += e & 1;
e <<= 9 - n;
//
// Check for exponent overflow.
//
if (e >= 0x7c00)
{
//
// Overflow occurred -- truncate instead of rounding.
//
e = _h;
e >>= 10 - n;
e <<= 10 - n;
}
//
// Put the original sign bit back.
//
half h;
h._h = s | e;
return h;
}
//-----------------------
// Other inline functions
//-----------------------
inline half
half::operator - () const
{
half h;
h._h = _h ^ 0x8000;
return h;
}
inline half &
half::operator = (half h)
{
_h = h._h;
return *this;
}
inline half &
half::operator = (float f)
{
*this = half (f);
return *this;
}
inline half &
half::operator += (half h)
{
*this = half (float (*this) + float (h));
return *this;
}
inline half &
half::operator += (float f)
{
*this = half (float (*this) + f);
return *this;
}
inline half &
half::operator -= (half h)
{
*this = half (float (*this) - float (h));
return *this;
}
inline half &
half::operator -= (float f)
{
*this = half (float (*this) - f);
return *this;
}
inline half &
half::operator *= (half h)
{
*this = half (float (*this) * float (h));
return *this;
}
inline half &
half::operator *= (float f)
{
*this = half (float (*this) * f);
return *this;
}
inline half &
half::operator /= (half h)
{
*this = half (float (*this) / float (h));
return *this;
}
inline half &
half::operator /= (float f)
{
*this = half (float (*this) / f);
return *this;
}
inline bool
half::isFinite () const
{
unsigned short e = (_h >> 10) & 0x001f;
return e < 31;
}
inline bool
half::isNormalized () const
{
unsigned short e = (_h >> 10) & 0x001f;
return e > 0 && e < 31;
}
inline bool
half::isDenormalized () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 0 && m != 0;
}
inline bool
half::isZero () const
{
return (_h & 0x7fff) == 0;
}
inline bool
half::isNan () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 31 && m != 0;
}
inline bool
half::isInfinity () const
{
unsigned short e = (_h >> 10) & 0x001f;
unsigned short m = _h & 0x3ff;
return e == 31 && m == 0;
}
inline bool
half::isNegative () const
{
return (_h & 0x8000) != 0;
}
inline half
half::posInf ()
{
half h;
h._h = 0x7c00;
return h;
}
inline half
half::negInf ()
{
half h;
h._h = 0xfc00;
return h;
}
inline half
half::qNan ()
{
half h;
h._h = 0x7fff;
return h;
}
inline half
half::sNan ()
{
half h;
h._h = 0x7dff;
return h;
}
inline unsigned short
half::bits () const
{
return _h;
}
inline void
half::setBits (unsigned short bits)
{
_h = bits;
}
#endif

51
Half/halfExport.h Normal file
View File

@ -0,0 +1,51 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2008, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef HALFEXPORT_H
#define HALFEXPORT_H
#if defined(OPENEXR_DLL)
#if defined(HALF_EXPORTS)
#define HALF_EXPORT __declspec(dllexport)
#else
#define HALF_EXPORT __declspec(dllimport)
#endif
#define HALF_EXPORT_CONST
#else
#define HALF_EXPORT
#define HALF_EXPORT_CONST const
#endif
#endif // #ifndef HALFEXPORT_H

179
Half/halfFunction.h Normal file
View File

@ -0,0 +1,179 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
//---------------------------------------------------------------------------
//
// halfFunction<T> -- a class for fast evaluation
// of half --> T functions
//
// The constructor for a halfFunction object,
//
// halfFunction (function,
// domainMin, domainMax,
// defaultValue,
// posInfValue, negInfValue,
// nanValue);
//
// evaluates the function for all finite half values in the interval
// [domainMin, domainMax], and stores the results in a lookup table.
// For finite half values that are not in [domainMin, domainMax], the
// constructor stores defaultValue in the table. For positive infinity,
// negative infinity and NANs, posInfValue, negInfValue and nanValue
// are stored in the table.
//
// The tabulated function can then be evaluated quickly for arbitrary
// half values by calling the the halfFunction object's operator()
// method.
//
// Example:
//
// #include <math.h>
// #include <halfFunction.h>
//
// halfFunction<half> hsin (sin);
//
// halfFunction<half> hsqrt (sqrt, // function
// 0, HALF_MAX, // domain
// half::qNan(), // sqrt(x) for x < 0
// half::posInf(), // sqrt(+inf)
// half::qNan(), // sqrt(-inf)
// half::qNan()); // sqrt(nan)
//
// half x = hsin (1);
// half y = hsqrt (3.5);
//
//---------------------------------------------------------------------------
#ifndef _HALF_FUNCTION_H_
#define _HALF_FUNCTION_H_
#include "half.h"
#include "IlmBaseConfig.h"
#ifndef ILMBASE_HAVE_LARGE_STACK
#include <string.h> // need this for memset
#else
#endif
#include <float.h>
template <class T>
class halfFunction
{
public:
//------------
// Constructor
//------------
template <class Function>
halfFunction (Function f,
half domainMin = -HALF_MAX,
half domainMax = HALF_MAX,
T defaultValue = 0,
T posInfValue = 0,
T negInfValue = 0,
T nanValue = 0);
#ifndef ILMBASE_HAVE_LARGE_STACK
~halfFunction () { delete [] _lut; }
#endif
//-----------
// Evaluation
//-----------
T operator () (half x) const;
private:
#ifdef ILMBASE_HAVE_LARGE_STACK
T _lut[1 << 16];
#else
T * _lut;
#endif
};
//---------------
// Implementation
//---------------
template <class T>
template <class Function>
halfFunction<T>::halfFunction (Function f,
half domainMin,
half domainMax,
T defaultValue,
T posInfValue,
T negInfValue,
T nanValue)
{
#ifndef ILMBASE_HAVE_LARGE_STACK
_lut = new T[1<<16];
memset (_lut, 0 , (1<<16) * sizeof(T));
#endif
for (int i = 0; i < (1 << 16); i++)
{
half x;
x.setBits (i);
if (x.isNan())
_lut[i] = nanValue;
else if (x.isInfinity())
_lut[i] = x.isNegative()? negInfValue: posInfValue;
else if (x < domainMin || x > domainMax)
_lut[i] = defaultValue;
else
_lut[i] = f (x);
}
}
template <class T>
inline T
halfFunction<T>::operator () (half x) const
{
return _lut[x.bits()];
}
#endif

111
Half/halfLimits.h Normal file
View File

@ -0,0 +1,111 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
// Primary authors:
// Florian Kainz <kainz@ilm.com>
// Rod Bogart <rgb@ilm.com>
#ifndef INCLUDED_HALF_LIMITS_H
#define INCLUDED_HALF_LIMITS_H
//------------------------------------------------------------------------
//
// C++ standard library-style numeric_limits for class half
//
//------------------------------------------------------------------------
#include <limits>
#include "half.h"
namespace std {
template <>
class numeric_limits <half>
{
public:
static const bool is_specialized = true;
static half min () throw () {return HALF_NRM_MIN;}
static half max () throw () {return HALF_MAX;}
static const int digits = HALF_MANT_DIG;
static const int digits10 = HALF_DIG;
static const bool is_signed = true;
static const bool is_integer = false;
static const bool is_exact = false;
static const int radix = HALF_RADIX;
static half epsilon () throw () {return HALF_EPSILON;}
static half round_error () throw () {return HALF_EPSILON / 2;}
static const int min_exponent = HALF_MIN_EXP;
static const int min_exponent10 = HALF_MIN_10_EXP;
static const int max_exponent = HALF_MAX_EXP;
static const int max_exponent10 = HALF_MAX_10_EXP;
static const bool has_infinity = true;
static const bool has_quiet_NaN = true;
static const bool has_signaling_NaN = true;
static const float_denorm_style has_denorm = denorm_present;
static const bool has_denorm_loss = false;
static half infinity () throw () {return half::posInf();}
static half quiet_NaN () throw () {return half::qNan();}
static half signaling_NaN () throw () {return half::sNan();}
static half denorm_min () throw () {return HALF_MIN;}
static const bool is_iec559 = false;
static const bool is_bounded = false;
static const bool is_modulo = false;
static const bool traps = true;
static const bool tinyness_before = false;
static const float_round_style round_style = round_to_nearest;
#if __cplusplus >= 201103L
// C++11 additions.
static constexpr int max_digits10 = HALF_DECIMAL_DIG;
static half lowest () {return -HALF_MAX;}
#endif
};
} // namespace std
#endif

164
Half/toFloat.cpp Normal file
View File

@ -0,0 +1,164 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
//
// toFloat
//
// A program to generate the lookup table for half-to-float
// conversion needed by class half.
// The program loops over all 65536 possible half numbers,
// converts each of them to a float, and prints the result.
//
//---------------------------------------------------------------------------
#include <iostream>
#include <iomanip>
using namespace std;
//---------------------------------------------------
// Interpret an unsigned short bit pattern as a half,
// and convert that half to the corresponding float's
// bit pattern.
//---------------------------------------------------
unsigned int
halfToFloat (unsigned short y)
{
int s = (y >> 15) & 0x00000001;
int e = (y >> 10) & 0x0000001f;
int m = y & 0x000003ff;
if (e == 0)
{
if (m == 0)
{
//
// Plus or minus zero
//
return s << 31;
}
else
{
//
// Denormalized number -- renormalize it
//
while (!(m & 0x00000400))
{
m <<= 1;
e -= 1;
}
e += 1;
m &= ~0x00000400;
}
}
else if (e == 31)
{
if (m == 0)
{
//
// Positive or negative infinity
//
return (s << 31) | 0x7f800000;
}
else
{
//
// Nan -- preserve sign and significand bits
//
return (s << 31) | 0x7f800000 | (m << 13);
}
}
//
// Normalized number
//
e = e + (127 - 15);
m = m << 13;
//
// Assemble s, e and m.
//
return (s << 31) | (e << 23) | m;
}
//---------------------------------------------
// Main - prints the half-to-float lookup table
//---------------------------------------------
int
main ()
{
cout.precision (9);
cout.setf (ios_base::hex, ios_base::basefield);
cout << "//\n"
"// This is an automatically generated file.\n"
"// Do not edit.\n"
"//\n\n";
cout << "{\n ";
const int iMax = (1 << 16);
for (int i = 0; i < iMax; i++)
{
cout << "{0x" << setfill ('0') << setw (8) << halfToFloat (i) << "}, ";
if (i % 4 == 3)
{
cout << "\n";
if (i < iMax - 1)
cout << " ";
}
}
cout << "};\n";
return 0;
}

16
HalfTest/CMakeLists.txt Normal file
View File

@ -0,0 +1,16 @@
# yue.nicholas@gmail.com
ADD_EXECUTABLE ( HalfTest
main.cpp
testArithmetic.cpp
testBitPatterns.cpp
testClassification.cpp
testError.cpp
testFunction.cpp
testLimits.cpp
testSize.cpp
)
TARGET_LINK_LIBRARIES ( HalfTest IlmBase::Half${OPENEXR_TARGET_SUFFIX} )
ADD_TEST ( TestHalf HalfTest )

19
HalfTest/Makefile.am Normal file
View File

@ -0,0 +1,19 @@
## Process this file with automake to produce Makefile.in
check_PROGRAMS = HalfTest
HalfTest_SOURCES = main.cpp testArithmetic.cpp testArithmetic.h \
testBitPatterns.cpp testBitPatterns.h \
testClassification.cpp testClassification.h \
testError.cpp testError.h testFunction.cpp \
testFunction.h testLimits.cpp testLimits.h testSize.cpp \
testSize.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Half -I$(top_srcdir)/config
LDADD = -L$(top_builddir)/Half -lHalf
TESTS = HalfTest
EXTRA_DIST = CMakeLists.txt

1000
HalfTest/Makefile.in Normal file

File diff suppressed because it is too large Load Diff

32
HalfTest/main.cpp Normal file
View File

@ -0,0 +1,32 @@
#include <testSize.h>
#include <testArithmetic.h>
#include <testError.h>
#include <testBitPatterns.h>
#include <testClassification.h>
#include <testLimits.h>
#include <testFunction.h>
#include <iostream>
#include <string.h>
#define TEST(x) if (argc < 2 || !strcmp (argv[1], #x)) x();
int
main (int argc, char *argv[])
{
std::cout << "\ntesting type half:\n\n" << std::flush;
TEST (testSize);
TEST (testArithmetic);
TEST (testNormalizedConversionError);
TEST (testDenormalizedConversionError);
TEST (testRoundingError);
TEST (testBitPatterns);
TEST (testClassification);
TEST (testLimits);
TEST (testFunction);
return 0;
}

View File

@ -0,0 +1,55 @@
#include <testArithmetic.h>
#include "half.h"
#include <iostream>
#include <assert.h>
using namespace std;
void
testArithmetic ()
{
cout << "basic arithmetic operations:\n";
float f1 (1);
float f2 (2);
half h1 (3);
half h2 (4);
cout << "f1 = " << f1 << ", "
"f2 = " << f2 << ", "
"h1 = " << h1 << ", "
"h2 = " << h2 << endl;
h1 = f1 + f2;
assert (h1 == 3);
cout << "h1 = f1 + f2: " << h1 << endl;
h2 += f1;
assert (h2 == 5);
cout << "h2 += f1: " << h2 << endl;
h2 = h1 + h2;
assert (h2 == 8);
cout << "h2 = h1 + h2: " << h2 << endl;
h2 += h1;
assert (h2 == 11);
cout << "h2 += h1: " << h2 << endl;
h1 = h2;
assert (h1 == 11);
cout << "h1 = h2: " << h1 << endl;
h2 = -h1;
assert (h2 == -11);
cout << "h2 = -h1: " << h2 << endl;
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testArithmetic ();

View File

@ -0,0 +1,484 @@
#include <testBitPatterns.h>
#include "half.h"
#include <float.h>
#include <iostream>
#include <string.h>
#include <assert.h>
using namespace std;
namespace {
bool
equalBitPatterns (const char *b1, const char *b2)
{
//
// Returns true if the characters in zero-terminated string b1
// are the same as the charaters in string b2, except for places
// where b1 or b2 contains an 'X'. For example:
//
// equalBitPatterns ("100", "100") returns true
// equalBitPatterns ("100", "101") returns false
// equalBitPatterns ("10X", "101") returns true
// equalBitPatterns ("10X", "100") returns true
//
while (*b1 && *b2)
{
if (*b1 != *b2 && *b1 != 'X' && *b2 != 'X')
return false;
++b1;
++b2;
}
return !(*b1 || *b2);
}
void
testBits (float f, const char bh[19], const char bg[35])
{
half h (f);
float g (h);
cout.width (15);
cout.precision (8);
cout << f << " ";
printBits (cout, f);
cout << " ";
printBits (cout, h);
cout << '\n';
cout.width (15);
cout << g << " ";
printBits (cout, g);
cout << "\n\n";
if (bh || bg)
{
char ch[19], cg[35];
printBits (ch, h);
printBits (cg, g);
if (!equalBitPatterns (ch, bh))
{
cout << "error: expected " << bh << ", got " << ch << endl;
assert (false);
}
if (!equalBitPatterns (cg, bg))
{
cout << "error: expected " << bg << ", got " << cg << endl;
assert (false);
}
}
}
float
floatPosInfinity ()
{
half::uif x;
x.i = 0x7f800000;
return x.f;
}
float
floatNegInfinity ()
{
half::uif x;
x.i = 0xff800000;
return x.f;
}
float
floatPosQNan1 ()
{
half::uif x;
x.i = 0x7fffffff;
return x.f;
}
float
floatNegQNan1 ()
{
half::uif x;
x.i = 0xffffffff;
return x.f;
}
float
floatPosQNan2 ()
{
half::uif x;
x.i = 0x7fd55555;
return x.f;
}
float
floatNegQNan2 ()
{
half::uif x;
x.i = 0xffd55555;
return x.f;
}
} // namespace
void
testBitPatterns()
{
cout << "specific bit patterns\n\n";
//
// Numbers close to 1.0
//
testBits (1.0f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f + HALF_EPSILON,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON * 0.5f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f+ HALF_EPSILON * 0.4999f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f + HALF_EPSILON * 0.5001f,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.5f,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.4999f,
"0 01111 0000000001",
"0 01111111 00000000010000000000000");
testBits (1.0f + HALF_EPSILON + HALF_EPSILON * 0.5001f,
"0 01111 0000000010",
"0 01111111 00000000100000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.5f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.4999f,
"0 01111 0000000000",
"0 01111111 00000000000000000000000");
testBits (1.0f - HALF_EPSILON * 0.5f * 0.5001f,
"0 01110 1111111111",
"0 01111110 11111111110000000000000");
//
// Numbers close to HALF_MIN
//
testBits (HALF_MIN,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5f,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.4999f,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN + HALF_MIN * 0.5001f,
"0 00000 0000000010",
"0 01101000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5f,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.4999f,
"0 00000 0000000001",
"0 01100111 00000000000000000000000");
testBits (HALF_MIN - HALF_MIN * 0.5001f,
"0 00000 0000000000",
"0 00000000 00000000000000000000000");
//
// Numbers close to HALF_NRM_MIN
//
testBits (HALF_NRM_MIN,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.4999f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN + HALF_MIN * 0.5001f,
"0 00001 0000000001",
"0 01110001 00000000010000000000000");
testBits (HALF_NRM_MIN - HALF_MIN,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.5f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.49995f,
"0 00001 0000000000",
"0 01110001 00000000000000000000000");
testBits (HALF_NRM_MIN - HALF_MIN * 0.50005f,
"0 00000 1111111111",
"0 01110000 11111111100000000000000");
//
// Small positive integers and simple decimal fractions
//
testBits (2,
"0 10000 0000000000",
"0 10000000 00000000000000000000000");
testBits (3,
"0 10000 1000000000",
"0 10000000 10000000000000000000000");
testBits (10,
"0 10010 0100000000",
"0 10000010 01000000000000000000000");
testBits (0.1f,
"0 01011 1001100110",
"0 01111011 10011001100000000000000");
testBits (0.2f,
"0 01100 1001100110",
"0 01111100 10011001100000000000000");
testBits (0.3f,
"0 01101 0011001101",
"0 01111101 00110011010000000000000");
//
// Numbers close to HALF_MAX
//
testBits (HALF_MAX,
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * 1.0,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25f),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25005f),
"0 11110 1111111111",
"0 10001110 11111111110000000000000");
testBits ((1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.24995f),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
//
// Large positive numbers, positive infinity and NANs
//
testBits (HALF_MAX * HALF_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (FLT_MAX,
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosInfinity(),
"0 11111 0000000000", // +infinity
"0 11111111 00000000000000000000000"); // +infinity
testBits (floatPosQNan1(),
"0 11111 1111111111", // nan
"0 11111111 11111111110000000000000"); // nan
testBits (floatPosQNan2(),
"0 11111 1010101010", // nan
"0 11111111 10101010100000000000000"); // nan
//
// Numbers close to -1.0
//
testBits (-1.0,
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.5f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.4999f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f + HALF_EPSILON * 0.5001f),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.5f),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.4999f),
"1 01111 0000000001",
"1 01111111 00000000010000000000000");
testBits (-(1.0f + HALF_EPSILON + HALF_EPSILON * 0.5001f),
"1 01111 0000000010",
"1 01111111 00000000100000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.5f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.4999f),
"1 01111 0000000000",
"1 01111111 00000000000000000000000");
testBits (-(1.0f - HALF_EPSILON * 0.5f * 0.5001f),
"1 01110 1111111111",
"1 01111110 11111111110000000000000");
//
// Numbers close to -HALF_MIN
//
testBits (-HALF_MIN,
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5f),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.4999f),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN + HALF_MIN * 0.5001f),
"1 00000 0000000010",
"1 01101000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN),
"X 00000 0000000000",
"X 00000000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5f),
"1 00000 0000000000",
"1 00000000 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.4999f),
"1 00000 0000000001",
"1 01100111 00000000000000000000000");
testBits (-(HALF_MIN - HALF_MIN * 0.5001f),
"1 00000 0000000000",
"1 00000000 00000000000000000000000");
//
// Numbers close to -HALF_NRM_MIN
//
testBits (-HALF_NRM_MIN,
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.4999f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN + HALF_MIN * 0.5001f),
"1 00001 0000000001",
"1 01110001 00000000010000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.5f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.49995f),
"1 00001 0000000000",
"1 01110001 00000000000000000000000");
testBits (-(HALF_NRM_MIN - HALF_MIN * 0.50005f),
"1 00000 1111111111",
"1 01110000 11111111100000000000000");
//
// Small negative integers and simple decimal fractions
//
testBits (-2,
"1 10000 0000000000",
"1 10000000 00000000000000000000000");
testBits (-3,
"1 10000 1000000000",
"1 10000000 10000000000000000000000");
testBits (-10,
"1 10010 0100000000",
"1 10000010 01000000000000000000000");
testBits (-0.1f,
"1 01011 1001100110",
"1 01111011 10011001100000000000000");
testBits (-0.2f,
"1 01100 1001100110",
"1 01111100 10011001100000000000000");
testBits (-0.3f,
"1 01101 0011001101",
"1 01111101 00110011010000000000000");
//
// Numbers close to -HALF_MAX
//
testBits (-HALF_MAX,
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * 1.0f,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25f),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.25005f),
"1 11110 1111111111",
"1 10001110 11111111110000000000000");
testBits (-(1 << HALF_MAX_EXP) * (1.0f - HALF_EPSILON * 0.24995f),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
//
// Large negative numbers, negative infinity and NANs
//
testBits (-HALF_MAX * HALF_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (-FLT_MAX,
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegInfinity(),
"1 11111 0000000000", // +infinity
"1 11111111 00000000000000000000000"); // +infinity
testBits (floatNegQNan1(),
"1 11111 1111111111", // nan
"1 11111111 11111111110000000000000"); // nan
testBits (floatNegQNan2(),
"1 11111 1010101010", // nan
"1 11111111 10101010100000000000000"); // nan
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testBitPatterns ();

View File

@ -0,0 +1,170 @@
#include <testClassification.h>
#include "half.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
void
testClass (half h,
bool finite,
bool normalized,
bool denormalized,
bool zero,
bool nan,
bool infinity,
bool negative)
{
cout.width (15);
cout.precision (8);
cout << h << " ";
printBits (cout, h);
cout << " ";
if (h.isFinite())
cout << "finite ";
if (h.isNormalized())
cout << "normalized ";
if (h.isDenormalized())
cout << "denormalized ";
if (h.isZero())
cout << "zero ";
if (h.isNan())
cout << "nan ";
if (h.isInfinity())
cout << "infinity ";
if (h.isNegative())
cout << "negative ";
cout << endl;
assert (h.isFinite() == finite);
assert (h.isNormalized() == normalized);
assert (h.isDenormalized() == denormalized);
assert (h.isZero() == zero);
assert (h.isNan() == nan);
assert (h.isInfinity() == infinity);
assert (h.isNegative() == negative);
}
float
floatPosInfinity ()
{
half::uif x;
x.i = 0x7f800000;
return x.f;
}
float
floatNegInfinity ()
{
half::uif x;
x.i = 0xff800000;
return x.f;
}
float
floatPosQNan1 ()
{
half::uif x;
x.i = 0x7fffffff;
return x.f;
}
float
floatNegQNan1 ()
{
half::uif x;
x.i = 0xffffffff;
return x.f;
}
float
floatPosQNan2 ()
{
half::uif x;
x.i = 0x7fd55555;
return x.f;
}
float
floatNegQNan2 ()
{
half::uif x;
x.i = 0xffd55555;
return x.f;
}
} // namespace
void
testClassification()
{
cout << "classification of bit patterns\n\n";
//
// fini norm deno zero nan inf neg
//
testClass (0.0, 1, 0, 0, 1, 0, 0, 0);
testClass (1.0, 1, 1, 0, 0, 0, 0, 0);
testClass (1.0f + HALF_EPSILON, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (HALF_MIN + HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (HALF_NRM_MIN, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_NRM_MIN + HALF_MIN, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_NRM_MIN - HALF_MIN, 1, 0, 1, 0, 0, 0, 0);
testClass (2.0f, 1, 1, 0, 0, 0, 0, 0);
testClass (3.0f, 1, 1, 0, 0, 0, 0, 0);
testClass (0.1f, 1, 1, 0, 0, 0, 0, 0);
testClass (0.2f, 1, 1, 0, 0, 0, 0, 0);
testClass (0.3f, 1, 1, 0, 0, 0, 0, 0);
testClass (HALF_MAX, 1, 1, 0, 0, 0, 0, 0);
testClass (floatPosInfinity(), 0, 0, 0, 0, 0, 1, 0);
testClass (floatPosQNan1(), 0, 0, 0, 0, 1, 0, 0);
testClass (floatPosQNan2(), 0, 0, 0, 0, 1, 0, 0);
testClass (-1.0f, 1, 1, 0, 0, 0, 0, 1);
testClass (-1.0f - HALF_EPSILON, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_MIN, 1, 0, 1, 0, 0, 0, 1);
testClass (-HALF_MIN - HALF_MIN, 1, 0, 1, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN - HALF_MIN,1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_NRM_MIN + HALF_MIN,1, 0, 1, 0, 0, 0, 1);
testClass (-2.0f, 1, 1, 0, 0, 0, 0, 1);
testClass (-3.0f, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.1f, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.2f, 1, 1, 0, 0, 0, 0, 1);
testClass (-0.3f, 1, 1, 0, 0, 0, 0, 1);
testClass (-HALF_MAX, 1, 1, 0, 0, 0, 0, 1);
testClass (floatNegInfinity(), 0, 0, 0, 0, 0, 1, 1);
testClass (floatNegQNan1(), 0, 0, 0, 0, 1, 0, 1);
testClass (floatNegQNan2(), 0, 0, 0, 0, 1, 0, 1);
cout << "\n";
testClass (half::posInf(), 0, 0, 0, 0, 0, 1, 0);
testClass (half::negInf(), 0, 0, 0, 0, 0, 1, 1);
testClass (half::qNan(), 0, 0, 0, 0, 1, 0, 0);
testClass (half::sNan(), 0, 0, 0, 0, 1, 0, 0);
cout << "ok\n\n" << flush;
}

View File

@ -0,0 +1,3 @@
void testClassification ();

212
HalfTest/testError.cpp Normal file
View File

@ -0,0 +1,212 @@
#include <testError.h>
#include "half.h"
#include <iostream>
#include <stdlib.h>
#include <assert.h>
using namespace std;
namespace {
float
drand()
{
return static_cast<float> (rand()/(RAND_MAX+1.0f));
}
} // namespace
void
testNormalizedConversionError()
{
cout << "float-to-half conversion error for normalized half numbers\n";
float eMax = 0;
for (int i = 0; i < 20000000; i++)
{
float f (drand() * HALF_MAX);
if (f < HALF_NRM_MIN)
continue;
if (i & 1)
f = -f;
half h (f);
float e = 1.0f - h/f;
if (e < 0)
e = -e;
if (e > HALF_EPSILON * 0.5)
{
cout << "float = " << f <<
", half = " << h <<
", error = " << e << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << HALF_EPSILON * 0.5 << endl;
cout << "ok\n\n" << flush;
}
void
testDenormalizedConversionError()
{
cout << "float-to-half conversion error for denormalized half numbers\n";
float eMax = 0;
for (int i = 0; i < 20000000; i++)
{
float f (drand() * (HALF_NRM_MIN - HALF_MIN));
if (i & 1)
f = -f;
half h (f);
float e = h - f;
if (e < 0)
e = -e;
if (e > HALF_MIN * 0.5)
{
cout << "float = " << f <<
", half = " << h <<
", error = " << e << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << HALF_MIN * 0.5 << endl;
cout << "ok\n\n" << flush;
}
namespace {
void
testNormalizedRounding (int n)
{
cout << "rounding normalized numbers to " << n << "-bit precision\n";
float eExpected = (n < 10)? HALF_EPSILON * 0.5f * (1 << (10 - n)): 0;
float eMax = 0;
for (int i = 0; i < 200000; i++)
{
half h (drand() * HALF_MAX);
if (h < HALF_NRM_MIN)
continue;
if (i & 1)
h = -h;
half r (h.round(n));
float e = 1.0f - r/h;
if (e < 0)
e = -e;
if (e > eExpected)
{
cout << "half = " << h <<
", rounded = " << r <<
", error = " << e <<
", expected error = " << eExpected << endl;
printBits (cout, h);
cout << endl;
printBits (cout, r);
cout << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << eExpected << endl;
cout << "ok\n\n" << flush;
}
void
testDenormalizedRounding (int n)
{
cout << "rounding denormalized numbers to " << n << "-bit precision\n";
float eExpected = (n < 10)? HALF_MIN * 0.5f * (1 << (10 - n)): 0;
float eMax = 0;
for (int i = 0; i < 200000; i++)
{
half h (drand() * (HALF_NRM_MIN - HALF_MIN));
if (i & 1)
h = -h;
half r (h.round(n));
float e = r - h;
if (e < 0)
e = -e;
if (e > eExpected)
{
cout << "half = " << h <<
", rounded = " << r <<
", error = " << e <<
", expected error = " << eExpected << endl;
printBits (cout, h);
cout << endl;
printBits (cout, r);
cout << endl;
assert (false);
}
if (e > eMax)
eMax = e;
}
cout << "max error = " << eMax << endl;
cout << "max expected error = " << eExpected << endl;
cout << "ok\n\n" << flush;
}
} // namespace
void
testRoundingError ()
{
testNormalizedRounding (10);
testDenormalizedRounding (10);
testNormalizedRounding (9);
testDenormalizedRounding (9);
testNormalizedRounding (1);
testDenormalizedRounding (1);
testNormalizedRounding (0);
testDenormalizedRounding (0);
}

5
HalfTest/testError.h Normal file
View File

@ -0,0 +1,5 @@
void testNormalizedConversionError ();
void testDenormalizedConversionError ();
void testRoundingError ();

68
HalfTest/testFunction.cpp Normal file
View File

@ -0,0 +1,68 @@
#include <testFunction.h>
#include "halfFunction.h"
#include <iostream>
#include <assert.h>
using namespace std;
namespace {
float
divideByTwo (float x)
{
return x / 2;
}
struct timesN
{
timesN (float n): n (n) {}
float operator () (float x) {return x * n;}
float n;
};
} // namespace
void
testFunction ()
{
cout << "halfFunction<T>\n";
halfFunction <float> d2 (divideByTwo);
assert (d2 (0) == 0);
assert (d2 (2) == 1);
assert (d2 (-2) == -1);
assert (d2 (HALF_MAX) == HALF_MAX / 2);
assert (d2 (-HALF_MAX) == -HALF_MAX / 2);
assert (d2 (half::posInf()) == 0);
assert (d2 (half::negInf()) == 0);
assert (d2 (half::qNan()) == 0);
halfFunction <half> t5 (timesN (5), // function
0, HALF_MAX / 8, // domain
-1, // default value
half::posInf(), // posInfValue
half::negInf(), // negInfValue
half::qNan()); // nanValue
assert (t5 (0) == 0);
assert (t5 (2) == 10);
assert (t5 (-2) == -1);
assert (t5 (HALF_MAX) == -1);
assert (t5 (-HALF_MAX) == -1);
assert ( t5(half::posInf()).isInfinity());
assert (!t5(half::posInf()).isNegative());
assert (t5(half::negInf()).isInfinity());
assert (t5(half::negInf()).isNegative());
assert (t5(half::qNan()).isNan());
cout << "ok\n\n" << flush;
}

3
HalfTest/testFunction.h Normal file
View File

@ -0,0 +1,3 @@
void testFunction ();

105
HalfTest/testLimits.cpp Normal file
View File

@ -0,0 +1,105 @@
#include <testLimits.h>
#include "halfLimits.h"
#include <iostream>
#include <assert.h>
#include <cmath>
using namespace std;
namespace {
float
mypow (int x, int y)
{
bool negative = false;
if (y < 0)
{
negative = true;
y = -y;
}
float z = 1;
while (y > 0)
{
z *= x;
y -= 1;
}
if (negative)
z = 1 / z;
return z;
}
} // namespace
void
testLimits()
{
cout << "values in std::numeric_limits<half>\n";
cout << "min_exponent\n";
{
half h (mypow (2, numeric_limits<half>::min_exponent - 1));
assert (h.isNormalized());
}
{
half h (mypow (2, numeric_limits<half>::min_exponent - 2));
assert (h.isDenormalized());
}
cout << "max_exponent\n";
{
half h (mypow (2, numeric_limits<half>::max_exponent - 1));
assert (h.isNormalized());
}
{
half h (mypow (2, numeric_limits<half>::max_exponent));
assert (h.isInfinity());
}
cout << "min_exponent10\n";
{
half h (mypow (10, numeric_limits<half>::min_exponent10));
assert (h.isNormalized());
}
{
half h (mypow (10, numeric_limits<half>::min_exponent10 - 1));
assert (h.isDenormalized());
}
cout << "max_exponent10\n";
{
half h (mypow (10, numeric_limits<half>::max_exponent10));
assert (h.isNormalized());
}
{
half h (mypow (10, numeric_limits<half>::max_exponent10 + 1));
assert (h.isInfinity());
}
#if __cplusplus >= 201103L
cout << "max_digits10\n";
assert (numeric_limits<half>::max_digits10
== std::ceil(numeric_limits<half>::digits * std::log10(2) + 1));
cout << "lowest\n";
assert (numeric_limits<half>::lowest() == -HALF_MAX);
#endif
cout << "ok\n\n" << flush;
}

3
HalfTest/testLimits.h Normal file
View File

@ -0,0 +1,3 @@
void testLimits ();

27
HalfTest/testSize.cpp Normal file
View File

@ -0,0 +1,27 @@
#include <testSize.h>
#include "half.h"
#include <iostream>
#include <assert.h>
#include <stddef.h>
using namespace std;
void
testSize ()
{
cout << "size and alignment\n";
half h[2];
int size = sizeof (half);
ptrdiff_t algn = (char *)&h[1] - (char *)&h[0];
cout << "sizeof (half) = " << size << endl;
cout << "alignof (half) = " << (int) algn << endl;
assert (size == 2 && algn == 2);
cout << "ok\n\n" << flush;
}

3
HalfTest/testSize.h Normal file
View File

@ -0,0 +1,3 @@
void testSize ();

70
Iex/CMakeLists.txt Normal file
View File

@ -0,0 +1,70 @@
# yue.nicholas@gmail.com
SET (ILMBASE_LIB_TARGETS "")
IF(OPENEXR_BUILD_SHARED)
LIST ( APPEND ILMBASE_LIB_TARGETS Iex )
ADD_LIBRARY ( Iex SHARED
IexBaseExc.cpp
IexThrowErrnoExc.cpp
)
TARGET_COMPILE_DEFINITIONS ( Iex PRIVATE IEX_EXPORTS )
IF (WIN32)
TARGET_COMPILE_DEFINITIONS ( Iex PUBLIC OPENEXR_DLL )
ENDIF ()
SET_TARGET_PROPERTIES ( Iex
PROPERTIES
VERSION ${OPENEXR_VERSION}
SOVERSION ${OPENEXR_SOVERSION}
OUTPUT_NAME "Iex${ILMBASE_LIBSUFFIX}"
)
ENDIF()
IF (BUILD_ILMBASE_STATIC)
LIST ( APPEND ILMBASE_LIB_TARGETS Iex_static )
ADD_LIBRARY ( Iex_static STATIC
IexBaseExc.cpp
IexThrowErrnoExc.cpp
)
SET_TARGET_PROPERTIES ( Iex_static
PROPERTIES
VERSION ${ILMBASE_VERSION_MAJOR}.${ILMBASE_VERSION_MINOR}.${ILMBASE_VERSION_PATCH}
OUTPUT_NAME "Iex${ILMBASE_LIBSUFFIX}_s"
)
ENDIF()
IF (OPENEXR_BUILD_SHARED OR BUILD_ILMBASE_STATIC)
INSTALL ( TARGETS ${ILMBASE_LIB_TARGETS}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION ${RUNTIME_DIR}
)
ENDIF ()
INSTALL (
FILES
IexBaseExc.h
IexMathExc.h
IexThrowErrnoExc.h
IexErrnoExc.h
IexMacros.h
Iex.h
IexNamespace.h
IexExport.h
IexForward.h
DESTINATION
include/OpenEXR
)
if (OPENEXR_BUILD_SHARED)
add_library(IlmBase::Iex ALIAS Iex)
endif()
if (BUILD_ILMBASE_STATIC)
add_library(IlmBase::Iex_static ALIAS Iex_static)
endif()

60
Iex/Iex.h Normal file
View File

@ -0,0 +1,60 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEX_H
#define INCLUDED_IEX_H
//--------------------------------
//
// Exception handling
//
//--------------------------------
#include "IexMacros.h"
#include "IexBaseExc.h"
#include "IexMathExc.h"
#include "IexThrowErrnoExc.h"
// Note that we do not include file IexErrnoExc.h here. That file
// defines over 150 classes and significantly slows down compilation.
// If you throw ErrnoExc exceptions using the throwErrnoExc() function,
// you don't need IexErrnoExc.h. You have to include IexErrnoExc.h
// only if you want to catch specific subclasses of ErrnoExc.
#endif

213
Iex/IexBaseExc.cpp Normal file
View File

@ -0,0 +1,213 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------
//
// Constructors and destructors for our exception base class.
//
//---------------------------------------------------------------------
#include "IexExport.h"
#include "IexBaseExc.h"
#include "IexMacros.h"
#ifdef PLATFORM_WINDOWS
#include <windows.h>
#endif
#include <stdlib.h>
IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
namespace {
StackTracer currentStackTracer = 0;
} // namespace
void
setStackTracer (StackTracer stackTracer)
{
currentStackTracer = stackTracer;
}
StackTracer
stackTracer ()
{
return currentStackTracer;
}
BaseExc::BaseExc (const char* s) throw () :
_message (s? s: ""),
_stackTrace (currentStackTracer? currentStackTracer(): "")
{
// empty
}
BaseExc::BaseExc (const std::string &s) throw () :
_message (s),
_stackTrace (currentStackTracer? currentStackTracer(): "")
{
// empty
}
BaseExc::BaseExc (std::stringstream &s) throw () :
_message (s.str()),
_stackTrace (currentStackTracer? currentStackTracer(): "")
{
// empty
}
BaseExc::BaseExc (const BaseExc &be) throw () :
_message (be._message),
_stackTrace (be._stackTrace)
{
// empty
}
BaseExc::~BaseExc () throw ()
{
// empty
}
const char *
BaseExc::what () const throw ()
{
return _message.c_str();
}
BaseExc &
BaseExc::assign (std::stringstream &s)
{
_message.assign (s.str());
return *this;
}
BaseExc &
BaseExc::append (std::stringstream &s)
{
_message.append (s.str());
return *this;
}
const std::string &
BaseExc::message() const
{
return _message;
}
BaseExc &
BaseExc::operator = (std::stringstream &s)
{
return assign (s);
}
BaseExc &
BaseExc::operator += (std::stringstream &s)
{
return append (s);
}
BaseExc &
BaseExc::assign (const char *s)
{
_message.assign(s);
return *this;
}
BaseExc &
BaseExc::operator = (const char *s)
{
return assign(s);
}
BaseExc &
BaseExc::append (const char *s)
{
_message.append(s);
return *this;
}
BaseExc &
BaseExc::operator += (const char *s)
{
return append(s);
}
const std::string &
BaseExc::stackTrace () const
{
return _stackTrace;
}
IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
#ifdef PLATFORM_WINDOWS
#pragma optimize("", off)
void
iex_debugTrap()
{
if (0 != getenv("IEXDEBUGTHROW"))
::DebugBreak();
}
#else
void
iex_debugTrap()
{
// how to in Linux?
if (0 != ::getenv("IEXDEBUGTHROW"))
__builtin_trap();
}
#endif

215
Iex/IexBaseExc.h Normal file
View File

@ -0,0 +1,215 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXBASEEXC_H
#define INCLUDED_IEXBASEEXC_H
#include "IexNamespace.h"
#include "IexExport.h"
//----------------------------------------------------------
//
// A general exception base class, and a few
// useful exceptions derived from the base class.
//
//----------------------------------------------------------
#include <string>
#include <exception>
#include <sstream>
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
//-------------------------------
// Our most basic exception class
//-------------------------------
class BaseExc: public std::exception
{
public:
//----------------------------
// Constructors and destructor
//----------------------------
IEX_EXPORT BaseExc (const char *s = 0) throw(); // std::string (s)
IEX_EXPORT BaseExc (const std::string &s) throw(); // std::string (s)
IEX_EXPORT BaseExc (std::stringstream &s) throw(); // std::string (s.str())
IEX_EXPORT BaseExc (const BaseExc &be) throw();
IEX_EXPORT virtual ~BaseExc () throw ();
//---------------------------------------------------
// what() method -- e.what() returns _message.c_str()
//---------------------------------------------------
IEX_EXPORT virtual const char * what () const throw ();
//--------------------------------------------------
// Convenient methods to change the exception's text
//--------------------------------------------------
IEX_EXPORT BaseExc & assign (std::stringstream &s); // assign (s.str())
IEX_EXPORT BaseExc & operator = (std::stringstream &s);
IEX_EXPORT BaseExc & append (std::stringstream &s); // append (s.str())
IEX_EXPORT BaseExc & operator += (std::stringstream &s);
//--------------------------------------------------
// These methods from the base class get obscured by
// the definitions above.
//--------------------------------------------------
IEX_EXPORT BaseExc & assign (const char *s);
IEX_EXPORT BaseExc & operator = (const char *s);
IEX_EXPORT BaseExc & append (const char *s);
IEX_EXPORT BaseExc & operator += (const char *s);
//---------------------------------------------------
// Access to the string representation of the message
//---------------------------------------------------
IEX_EXPORT const std::string & message () const;
//--------------------------------------------------
// Stack trace for the point at which the exception
// was thrown. The stack trace will be an empty
// string unless a working stack-tracing routine
// has been installed (see below, setStackTracer()).
//--------------------------------------------------
IEX_EXPORT const std::string & stackTrace () const;
private:
std::string _message;
std::string _stackTrace;
};
//-----------------------------------------------------
// A macro to save typing when declararing an exception
// class derived directly or indirectly from BaseExc:
//-----------------------------------------------------
#define DEFINE_EXC_EXP(exp, name, base) \
class name: public base \
{ \
public: \
exp name() throw(): base (0) {} \
exp name (const char* text) throw(): base (text) {} \
exp name (const std::string &text) throw(): base (text) {} \
exp name (std::stringstream &text) throw(): base (text) {} \
exp ~name() throw() { } \
};
// For backward compatibility.
#define DEFINE_EXC(name, base) DEFINE_EXC_EXP(, name, base)
//--------------------------------------------------------
// Some exceptions which should be useful in most programs
//--------------------------------------------------------
DEFINE_EXC_EXP (IEX_EXPORT, ArgExc, BaseExc) // Invalid arguments to a function call
DEFINE_EXC_EXP (IEX_EXPORT, LogicExc, BaseExc) // General error in a program's logic,
// for example, a function was called
// in a context where the call does
// not make sense.
DEFINE_EXC_EXP (IEX_EXPORT, InputExc, BaseExc) // Invalid input data, e.g. from a file
DEFINE_EXC_EXP (IEX_EXPORT, IoExc, BaseExc) // Input or output operation failed
DEFINE_EXC_EXP (IEX_EXPORT, MathExc, BaseExc) // Arithmetic exception; more specific
// exceptions derived from this class
// are defined in ExcMath.h
DEFINE_EXC_EXP (IEX_EXPORT, ErrnoExc, BaseExc) // Base class for exceptions corresponding
// to errno values (see errno.h); more
// specific exceptions derived from this
// class are defined in ExcErrno.h
DEFINE_EXC_EXP (IEX_EXPORT, NoImplExc, BaseExc) // Missing method exception e.g. from a
// call to a method that is only partially
// or not at all implemented. A reminder
// to lazy software people to get back
// to work.
DEFINE_EXC_EXP (IEX_EXPORT, NullExc, BaseExc) // A pointer is inappropriately null.
DEFINE_EXC_EXP (IEX_EXPORT, TypeExc, BaseExc) // An object is an inappropriate type,
// i.e. a dynamnic_cast failed.
//----------------------------------------------------------------------
// Stack-tracing support:
//
// setStackTracer(st)
//
// installs a stack-tracing routine, st, which will be called from
// class BaseExc's constructor every time an exception derived from
// BaseExc is thrown. The stack-tracing routine should return a
// string that contains a printable representation of the program's
// current call stack. This string will be stored in the BaseExc
// object; the string is accesible via the BaseExc::stackTrace()
// method.
//
// setStackTracer(0)
//
// removes the current stack tracing routine. When an exception
// derived from BaseExc is thrown, the stack trace string stored
// in the BaseExc object will be empty.
//
// stackTracer()
//
// returns a pointer to the current stack-tracing routine, or 0
// if there is no current stack stack-tracing routine.
//
//----------------------------------------------------------------------
typedef std::string (* StackTracer) ();
IEX_EXPORT void setStackTracer (StackTracer stackTracer);
IEX_EXPORT StackTracer stackTracer ();
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IEXBASEEXC_H

208
Iex/IexErrnoExc.h Normal file
View File

@ -0,0 +1,208 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXERRNOEXC_H
#define INCLUDED_IEXERRNOEXC_H
//----------------------------------------------------------------
//
// Exceptions which correspond to "errno" error codes.
//
//----------------------------------------------------------------
#include "IexBaseExc.h"
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
DEFINE_EXC (EpermExc, ErrnoExc)
DEFINE_EXC (EnoentExc, ErrnoExc)
DEFINE_EXC (EsrchExc, ErrnoExc)
DEFINE_EXC (EintrExc, ErrnoExc)
DEFINE_EXC (EioExc, ErrnoExc)
DEFINE_EXC (EnxioExc, ErrnoExc)
DEFINE_EXC (E2bigExc, ErrnoExc)
DEFINE_EXC (EnoexecExc, ErrnoExc)
DEFINE_EXC (EbadfExc, ErrnoExc)
DEFINE_EXC (EchildExc, ErrnoExc)
DEFINE_EXC (EagainExc, ErrnoExc)
DEFINE_EXC (EnomemExc, ErrnoExc)
DEFINE_EXC (EaccesExc, ErrnoExc)
DEFINE_EXC (EfaultExc, ErrnoExc)
DEFINE_EXC (EnotblkExc, ErrnoExc)
DEFINE_EXC (EbusyExc, ErrnoExc)
DEFINE_EXC (EexistExc, ErrnoExc)
DEFINE_EXC (ExdevExc, ErrnoExc)
DEFINE_EXC (EnodevExc, ErrnoExc)
DEFINE_EXC (EnotdirExc, ErrnoExc)
DEFINE_EXC (EisdirExc, ErrnoExc)
DEFINE_EXC (EinvalExc, ErrnoExc)
DEFINE_EXC (EnfileExc, ErrnoExc)
DEFINE_EXC (EmfileExc, ErrnoExc)
DEFINE_EXC (EnottyExc, ErrnoExc)
DEFINE_EXC (EtxtbsyExc, ErrnoExc)
DEFINE_EXC (EfbigExc, ErrnoExc)
DEFINE_EXC (EnospcExc, ErrnoExc)
DEFINE_EXC (EspipeExc, ErrnoExc)
DEFINE_EXC (ErofsExc, ErrnoExc)
DEFINE_EXC (EmlinkExc, ErrnoExc)
DEFINE_EXC (EpipeExc, ErrnoExc)
DEFINE_EXC (EdomExc, ErrnoExc)
DEFINE_EXC (ErangeExc, ErrnoExc)
DEFINE_EXC (EnomsgExc, ErrnoExc)
DEFINE_EXC (EidrmExc, ErrnoExc)
DEFINE_EXC (EchrngExc, ErrnoExc)
DEFINE_EXC (El2nsyncExc, ErrnoExc)
DEFINE_EXC (El3hltExc, ErrnoExc)
DEFINE_EXC (El3rstExc, ErrnoExc)
DEFINE_EXC (ElnrngExc, ErrnoExc)
DEFINE_EXC (EunatchExc, ErrnoExc)
DEFINE_EXC (EnocsiExc, ErrnoExc)
DEFINE_EXC (El2hltExc, ErrnoExc)
DEFINE_EXC (EdeadlkExc, ErrnoExc)
DEFINE_EXC (EnolckExc, ErrnoExc)
DEFINE_EXC (EbadeExc, ErrnoExc)
DEFINE_EXC (EbadrExc, ErrnoExc)
DEFINE_EXC (ExfullExc, ErrnoExc)
DEFINE_EXC (EnoanoExc, ErrnoExc)
DEFINE_EXC (EbadrqcExc, ErrnoExc)
DEFINE_EXC (EbadsltExc, ErrnoExc)
DEFINE_EXC (EdeadlockExc, ErrnoExc)
DEFINE_EXC (EbfontExc, ErrnoExc)
DEFINE_EXC (EnostrExc, ErrnoExc)
DEFINE_EXC (EnodataExc, ErrnoExc)
DEFINE_EXC (EtimeExc, ErrnoExc)
DEFINE_EXC (EnosrExc, ErrnoExc)
DEFINE_EXC (EnonetExc, ErrnoExc)
DEFINE_EXC (EnopkgExc, ErrnoExc)
DEFINE_EXC (EremoteExc, ErrnoExc)
DEFINE_EXC (EnolinkExc, ErrnoExc)
DEFINE_EXC (EadvExc, ErrnoExc)
DEFINE_EXC (EsrmntExc, ErrnoExc)
DEFINE_EXC (EcommExc, ErrnoExc)
DEFINE_EXC (EprotoExc, ErrnoExc)
DEFINE_EXC (EmultihopExc, ErrnoExc)
DEFINE_EXC (EbadmsgExc, ErrnoExc)
DEFINE_EXC (EnametoolongExc, ErrnoExc)
DEFINE_EXC (EoverflowExc, ErrnoExc)
DEFINE_EXC (EnotuniqExc, ErrnoExc)
DEFINE_EXC (EbadfdExc, ErrnoExc)
DEFINE_EXC (EremchgExc, ErrnoExc)
DEFINE_EXC (ElibaccExc, ErrnoExc)
DEFINE_EXC (ElibbadExc, ErrnoExc)
DEFINE_EXC (ElibscnExc, ErrnoExc)
DEFINE_EXC (ElibmaxExc, ErrnoExc)
DEFINE_EXC (ElibexecExc, ErrnoExc)
DEFINE_EXC (EilseqExc, ErrnoExc)
DEFINE_EXC (EnosysExc, ErrnoExc)
DEFINE_EXC (EloopExc, ErrnoExc)
DEFINE_EXC (ErestartExc, ErrnoExc)
DEFINE_EXC (EstrpipeExc, ErrnoExc)
DEFINE_EXC (EnotemptyExc, ErrnoExc)
DEFINE_EXC (EusersExc, ErrnoExc)
DEFINE_EXC (EnotsockExc, ErrnoExc)
DEFINE_EXC (EdestaddrreqExc, ErrnoExc)
DEFINE_EXC (EmsgsizeExc, ErrnoExc)
DEFINE_EXC (EprototypeExc, ErrnoExc)
DEFINE_EXC (EnoprotooptExc, ErrnoExc)
DEFINE_EXC (EprotonosupportExc, ErrnoExc)
DEFINE_EXC (EsocktnosupportExc, ErrnoExc)
DEFINE_EXC (EopnotsuppExc, ErrnoExc)
DEFINE_EXC (EpfnosupportExc, ErrnoExc)
DEFINE_EXC (EafnosupportExc, ErrnoExc)
DEFINE_EXC (EaddrinuseExc, ErrnoExc)
DEFINE_EXC (EaddrnotavailExc, ErrnoExc)
DEFINE_EXC (EnetdownExc, ErrnoExc)
DEFINE_EXC (EnetunreachExc, ErrnoExc)
DEFINE_EXC (EnetresetExc, ErrnoExc)
DEFINE_EXC (EconnabortedExc, ErrnoExc)
DEFINE_EXC (EconnresetExc, ErrnoExc)
DEFINE_EXC (EnobufsExc, ErrnoExc)
DEFINE_EXC (EisconnExc, ErrnoExc)
DEFINE_EXC (EnotconnExc, ErrnoExc)
DEFINE_EXC (EshutdownExc, ErrnoExc)
DEFINE_EXC (EtoomanyrefsExc, ErrnoExc)
DEFINE_EXC (EtimedoutExc, ErrnoExc)
DEFINE_EXC (EconnrefusedExc, ErrnoExc)
DEFINE_EXC (EhostdownExc, ErrnoExc)
DEFINE_EXC (EhostunreachExc, ErrnoExc)
DEFINE_EXC (EalreadyExc, ErrnoExc)
DEFINE_EXC (EinprogressExc, ErrnoExc)
DEFINE_EXC (EstaleExc, ErrnoExc)
DEFINE_EXC (EioresidExc, ErrnoExc)
DEFINE_EXC (EucleanExc, ErrnoExc)
DEFINE_EXC (EnotnamExc, ErrnoExc)
DEFINE_EXC (EnavailExc, ErrnoExc)
DEFINE_EXC (EisnamExc, ErrnoExc)
DEFINE_EXC (EremoteioExc, ErrnoExc)
DEFINE_EXC (EinitExc, ErrnoExc)
DEFINE_EXC (EremdevExc, ErrnoExc)
DEFINE_EXC (EcanceledExc, ErrnoExc)
DEFINE_EXC (EnolimfileExc, ErrnoExc)
DEFINE_EXC (EproclimExc, ErrnoExc)
DEFINE_EXC (EdisjointExc, ErrnoExc)
DEFINE_EXC (EnologinExc, ErrnoExc)
DEFINE_EXC (EloginlimExc, ErrnoExc)
DEFINE_EXC (EgrouploopExc, ErrnoExc)
DEFINE_EXC (EnoattachExc, ErrnoExc)
DEFINE_EXC (EnotsupExc, ErrnoExc)
DEFINE_EXC (EnoattrExc, ErrnoExc)
DEFINE_EXC (EdircorruptedExc, ErrnoExc)
DEFINE_EXC (EdquotExc, ErrnoExc)
DEFINE_EXC (EnfsremoteExc, ErrnoExc)
DEFINE_EXC (EcontrollerExc, ErrnoExc)
DEFINE_EXC (EnotcontrollerExc, ErrnoExc)
DEFINE_EXC (EenqueuedExc, ErrnoExc)
DEFINE_EXC (EnotenqueuedExc, ErrnoExc)
DEFINE_EXC (EjoinedExc, ErrnoExc)
DEFINE_EXC (EnotjoinedExc, ErrnoExc)
DEFINE_EXC (EnoprocExc, ErrnoExc)
DEFINE_EXC (EmustrunExc, ErrnoExc)
DEFINE_EXC (EnotstoppedExc, ErrnoExc)
DEFINE_EXC (EclockcpuExc, ErrnoExc)
DEFINE_EXC (EinvalstateExc, ErrnoExc)
DEFINE_EXC (EnoexistExc, ErrnoExc)
DEFINE_EXC (EendofminorExc, ErrnoExc)
DEFINE_EXC (EbufsizeExc, ErrnoExc)
DEFINE_EXC (EemptyExc, ErrnoExc)
DEFINE_EXC (EnointrgroupExc, ErrnoExc)
DEFINE_EXC (EinvalmodeExc, ErrnoExc)
DEFINE_EXC (EcantextentExc, ErrnoExc)
DEFINE_EXC (EinvaltimeExc, ErrnoExc)
DEFINE_EXC (EdestroyedExc, ErrnoExc)
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif

51
Iex/IexExport.h Normal file
View File

@ -0,0 +1,51 @@
#ifndef IEXEXPORT_H
#define IEXEXPORT_H
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#if defined(OPENEXR_DLL)
#if defined(IEX_EXPORTS)
#define IEX_EXPORT __declspec(dllexport)
#else
#define IEX_EXPORT __declspec(dllimport)
#endif
#define IEX_EXPORT_CONST
#else
#define IEX_EXPORT
#define IEX_EXPORT_CONST const
#endif
#endif // #ifndef IEXEXPORT_H

229
Iex/IexForward.h Normal file
View File

@ -0,0 +1,229 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXFORWARD_H
#define INCLUDED_IEXFORWARD_H
#include "IexNamespace.h"
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Base exceptions.
//
class BaseExc;
class ArgExc;
class LogicExc;
class InputExc;
class IoExc;
class MathExc;
class ErrnoExc;
class NoImplExc;
class NullExc;
class TypeExc;
//
// Math exceptions.
//
class OverflowExc;
class UnderflowExc;
class DivzeroExc;
class InexactExc;
class InvalidFpOpExc;
//
// Errno exceptions.
//
class EpermExc;
class EnoentExc;
class EsrchExc;
class EintrExc;
class EioExc;
class EnxioExc;
class E2bigExc;
class EnoexecExc;
class EbadfExc;
class EchildExc;
class EagainExc;
class EnomemExc;
class EaccesExc;
class EfaultExc;
class EnotblkExc;
class EbusyExc;
class EexistExc;
class ExdevExc;
class EnodevExc;
class EnotdirExc;
class EisdirExc;
class EinvalExc;
class EnfileExc;
class EmfileExc;
class EnottyExc;
class EtxtbsyExc;
class EfbigExc;
class EnospcExc;
class EspipeExc;
class ErofsExc;
class EmlinkExc;
class EpipeExc;
class EdomExc;
class ErangeExc;
class EnomsgExc;
class EidrmExc;
class EchrngExc;
class El2nsyncExc;
class El3hltExc;
class El3rstExc;
class ElnrngExc;
class EunatchExc;
class EnocsiExc;
class El2hltExc;
class EdeadlkExc;
class EnolckExc;
class EbadeExc;
class EbadrExc;
class ExfullExc;
class EnoanoExc;
class EbadrqcExc;
class EbadsltExc;
class EdeadlockExc;
class EbfontExc;
class EnostrExc;
class EnodataExc;
class EtimeExc;
class EnosrExc;
class EnonetExc;
class EnopkgExc;
class EremoteExc;
class EnolinkExc;
class EadvExc;
class EsrmntExc;
class EcommExc;
class EprotoExc;
class EmultihopExc;
class EbadmsgExc;
class EnametoolongExc;
class EoverflowExc;
class EnotuniqExc;
class EbadfdExc;
class EremchgExc;
class ElibaccExc;
class ElibbadExc;
class ElibscnExc;
class ElibmaxExc;
class ElibexecExc;
class EilseqExc;
class EnosysExc;
class EloopExc;
class ErestartExc;
class EstrpipeExc;
class EnotemptyExc;
class EusersExc;
class EnotsockExc;
class EdestaddrreqExc;
class EmsgsizeExc;
class EprototypeExc;
class EnoprotooptExc;
class EprotonosupportExc;
class EsocktnosupportExc;
class EopnotsuppExc;
class EpfnosupportExc;
class EafnosupportExc;
class EaddrinuseExc;
class EaddrnotavailExc;
class EnetdownExc;
class EnetunreachExc;
class EnetresetExc;
class EconnabortedExc;
class EconnresetExc;
class EnobufsExc;
class EisconnExc;
class EnotconnExc;
class EshutdownExc;
class EtoomanyrefsExc;
class EtimedoutExc;
class EconnrefusedExc;
class EhostdownExc;
class EhostunreachExc;
class EalreadyExc;
class EinprogressExc;
class EstaleExc;
class EioresidExc;
class EucleanExc;
class EnotnamExc;
class EnavailExc;
class EisnamExc;
class EremoteioExc;
class EinitExc;
class EremdevExc;
class EcanceledExc;
class EnolimfileExc;
class EproclimExc;
class EdisjointExc;
class EnologinExc;
class EloginlimExc;
class EgrouploopExc;
class EnoattachExc;
class EnotsupExc;
class EnoattrExc;
class EdircorruptedExc;
class EdquotExc;
class EnfsremoteExc;
class EcontrollerExc;
class EnotcontrollerExc;
class EenqueuedExc;
class EnotenqueuedExc;
class EjoinedExc;
class EnotjoinedExc;
class EnoprocExc;
class EmustrunExc;
class EnotstoppedExc;
class EclockcpuExc;
class EinvalstateExc;
class EnoexistExc;
class EendofminorExc;
class EbufsizeExc;
class EemptyExc;
class EnointrgroupExc;
class EinvalmodeExc;
class EcantextentExc;
class EinvaltimeExc;
class EdestroyedExc;
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IEXFORWARD_H

170
Iex/IexMacros.h Normal file
View File

@ -0,0 +1,170 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2018, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXMACROS_H
#define INCLUDED_IEXMACROS_H
//--------------------------------------------------------------------
//
// Macros which make throwing exceptions more convenient
//
//--------------------------------------------------------------------
#include <sstream>
//----------------------------------------------------------------------------
// A macro to throw exceptions whose text is assembled using stringstreams.
//
// Example:
//
// THROW (InputExc, "Syntax error in line " << line ", " << file << ".");
//
//----------------------------------------------------------------------------
#include "IexExport.h"
#include "IexForward.h"
IEX_EXPORT void iex_debugTrap();
#define THROW(type, text) \
do \
{ \
iex_debugTrap(); \
std::stringstream _iex_throw_s; \
_iex_throw_s << text; \
throw type (_iex_throw_s); \
} \
while (0)
//----------------------------------------------------------------------------
// Macros to add to or to replace the text of an exception.
// The new text is assembled using stringstreams.
//
// Examples:
//
// Append to end of an exception's text:
//
// catch (BaseExc &e)
// {
// APPEND_EXC (e, " Directory " << name << " does not exist.");
// throw;
// }
//
// Replace an exception's text:
//
// catch (BaseExc &e)
// {
// REPLACE_EXC (e, "Directory " << name << " does not exist. " << e);
// throw;
// }
//----------------------------------------------------------------------------
#define APPEND_EXC(exc, text) \
do \
{ \
std::stringstream _iex_append_s; \
_iex_append_s << text; \
exc.append (_iex_append_s); \
} \
while (0)
#define REPLACE_EXC(exc, text) \
do \
{ \
std::stringstream _iex_replace_s; \
_iex_replace_s << text; \
exc.assign (_iex_replace_s); \
} \
while (0)
//-------------------------------------------------------------
// A macro to throw ErrnoExc exceptions whose text is assembled
// using stringstreams:
//
// Example:
//
// THROW_ERRNO ("Cannot open file " << name << " (%T).");
//
//-------------------------------------------------------------
#define THROW_ERRNO(text) \
do \
{ \
std::stringstream _iex_throw_errno_s; \
_iex_throw_errno_s << text; \
::IEX_NAMESPACE::throwErrnoExc (_iex_throw_errno_s.str()); \
} \
while (0)
//-------------------------------------------------------------
// A macro to throw exceptions if an assertion is false.
//
// Example:
//
// ASSERT (ptr != 0, NullExc, "Null pointer" );
//
//-------------------------------------------------------------
#define ASSERT(assertion, type, text) \
do \
{ \
if( bool(assertion) == false ) \
{ \
THROW( type, text ); \
} \
} \
while (0)
//-------------------------------------------------------------
// A macro to throw an IEX_NAMESPACE::LogicExc if an assertion is false,
// with the text composed from the source code file, line number,
// and assertion argument text.
//
// Example:
//
// LOGIC_ASSERT (i < n);
//
//-------------------------------------------------------------
#define LOGIC_ASSERT(assertion) \
ASSERT(assertion, \
IEX_NAMESPACE::LogicExc, \
__FILE__ << "(" << __LINE__ << "): logical assertion failed: " << #assertion )
#endif

57
Iex/IexMathExc.h Normal file
View File

@ -0,0 +1,57 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXMATHEXC_H
#define INCLUDED_IEXMATHEXC_H
#include "IexBaseExc.h"
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
//---------------------------------------------------------
// Exception classess which correspond to specific floating
// point exceptions.
//---------------------------------------------------------
DEFINE_EXC (OverflowExc, MathExc) // Overflow
DEFINE_EXC (UnderflowExc, MathExc) // Underflow
DEFINE_EXC (DivzeroExc, MathExc) // Division by zero
DEFINE_EXC (InexactExc, MathExc) // Inexact result
DEFINE_EXC (InvalidFpOpExc, MathExc) // Invalid operation
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IEXMATHEXC_H

112
Iex/IexNamespace.h Normal file
View File

@ -0,0 +1,112 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXNAMESPACE_H
#define INCLUDED_IEXNAMESPACE_H
//
// The purpose of this file is to make it possible to specify an
// IEX_INTERNAL_NAMESPACE as a preprocessor definition and have all of the
// Iex symbols defined within that namespace rather than the standard
// Iex namespace. Those symbols are made available to client code through
// the IEX_NAMESPACE in addition to the IEX_INTERNAL_NAMESPACE.
//
// To ensure source code compatibility, the IEX_NAMESPACE defaults to Iex
// and then "using namespace IEX_INTERNAL_NAMESPACE;" brings all of the
// declarations from the IEX_INTERNAL_NAMESPACE into the IEX_NAMESPACE. This
// means that client code can continue to use syntax like Iex::BaseExc, but
// at link time it will resolve to a mangled symbol based on the
// IEX_INTERNAL_NAMESPACE.
//
// As an example, if one needed to build against a newer version of Iex and
// have it run alongside an older version in the same application, it is now
// possible to use an internal namespace to prevent collisions between the
// older versions of Iex symbols and the newer ones. To do this, the
// following could be defined at build time:
//
// IEX_INTERNAL_NAMESPACE = Iex_v2
//
// This means that declarations inside Iex headers look like this (after the
// preprocessor has done its work):
//
// namespace Iex_v2 {
// ...
// class declarations
// ...
// }
//
// namespace Iex {
// using namespace Iex_v2;
// }
//
//
// Open Source version of this file pulls in the IlmBaseConfig.h file
// for the configure time options.
//
#include "IlmBaseConfig.h"
#ifndef IEX_NAMESPACE
#define IEX_NAMESPACE Iex
#endif
#ifndef IEX_INTERNAL_NAMESPACE
#define IEX_INTERNAL_NAMESPACE IEX_NAMESPACE
#endif
//
// We need to be sure that we import the internal namespace into the public one.
// To do this, we use the small bit of code below which initially defines
// IEX_INTERNAL_NAMESPACE (so it can be referenced) and then defines
// IEX_NAMESPACE and pulls the internal symbols into the public namespace.
//
namespace IEX_INTERNAL_NAMESPACE {}
namespace IEX_NAMESPACE {
using namespace IEX_INTERNAL_NAMESPACE;
}
//
// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
// future extension to the namespace mechanism is possible without changing
// project source code.
//
#define IEX_INTERNAL_NAMESPACE_HEADER_ENTER namespace IEX_INTERNAL_NAMESPACE {
#define IEX_INTERNAL_NAMESPACE_HEADER_EXIT }
#define IEX_INTERNAL_NAMESPACE_SOURCE_ENTER namespace IEX_INTERNAL_NAMESPACE {
#define IEX_INTERNAL_NAMESPACE_SOURCE_EXIT }
#endif // INCLUDED_IEXNAMESPACE_H

873
Iex/IexThrowErrnoExc.cpp Normal file
View File

@ -0,0 +1,873 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------
//
// Exceptions that correspond to "errno" error codes,
// and a function to make throwing those exceptions easy.
//
//----------------------------------------------------------------
#include "IexThrowErrnoExc.h"
#include "IexErrnoExc.h"
#include <string.h>
#include <errno.h>
#ifdef PLATFORM_WINDOWS
#include <windows.h>
#endif
IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
void throwErrnoExc (const std::string &text, int errnum)
{
#ifdef PLATFORM_WINDOWS
if (0 != getenv("IEXDEBUGTHROW"))
DebugBreak();
#endif
const char *entext = strerror (errnum);
std::string tmp (text);
std::string::size_type pos;
while (std::string::npos != (pos = tmp.find ("%T")))
tmp.replace (pos, 2, entext, strlen (entext));
switch (errnum)
{
#if defined (EPERM)
case EPERM:
throw EpermExc (tmp);
#endif
#if defined (ENOENT)
case ENOENT:
throw EnoentExc (tmp);
#endif
#if defined (ESRCH)
case ESRCH:
throw EsrchExc (tmp);
#endif
#if defined (EINTR)
case EINTR:
throw EintrExc (tmp);
#endif
#if defined (EIO)
case EIO:
throw EioExc (tmp);
#endif
#if defined (ENXIO)
case ENXIO:
throw EnxioExc (tmp);
#endif
#if defined (E2BIG)
case E2BIG:
throw E2bigExc (tmp);
#endif
#if defined (ENOEXEC)
case ENOEXEC:
throw EnoexecExc (tmp);
#endif
#if defined (EBADF)
case EBADF:
throw EbadfExc (tmp);
#endif
#if defined (ECHILD)
case ECHILD:
throw EchildExc (tmp);
#endif
#if defined (EAGAIN)
case EAGAIN:
throw EagainExc (tmp);
#endif
#if defined (ENOMEM)
case ENOMEM:
throw EnomemExc (tmp);
#endif
#if defined (EACCES)
case EACCES:
throw EaccesExc (tmp);
#endif
#if defined (EFAULT)
case EFAULT:
throw EfaultExc (tmp);
#endif
#if defined (ENOTBLK)
case ENOTBLK:
throw EnotblkExc (tmp);
#endif
#if defined (EBUSY)
case EBUSY:
throw EbusyExc (tmp);
#endif
#if defined (EEXIST)
case EEXIST:
throw EexistExc (tmp);
#endif
#if defined (EXDEV)
case EXDEV:
throw ExdevExc (tmp);
#endif
#if defined (ENODEV)
case ENODEV:
throw EnodevExc (tmp);
#endif
#if defined (ENOTDIR)
case ENOTDIR:
throw EnotdirExc (tmp);
#endif
#if defined (EISDIR)
case EISDIR:
throw EisdirExc (tmp);
#endif
#if defined (EINVAL)
case EINVAL:
throw EinvalExc (tmp);
#endif
#if defined (ENFILE)
case ENFILE:
throw EnfileExc (tmp);
#endif
#if defined (EMFILE)
case EMFILE:
throw EmfileExc (tmp);
#endif
#if defined (ENOTTY)
case ENOTTY:
throw EnottyExc (tmp);
#endif
#if defined (ETXTBSY)
case ETXTBSY:
throw EtxtbsyExc (tmp);
#endif
#if defined (EFBIG)
case EFBIG:
throw EfbigExc (tmp);
#endif
#if defined (ENOSPC)
case ENOSPC:
throw EnospcExc (tmp);
#endif
#if defined (ESPIPE)
case ESPIPE:
throw EspipeExc (tmp);
#endif
#if defined (EROFS)
case EROFS:
throw ErofsExc (tmp);
#endif
#if defined (EMLINK)
case EMLINK:
throw EmlinkExc (tmp);
#endif
#if defined (EPIPE)
case EPIPE:
throw EpipeExc (tmp);
#endif
#if defined (EDOM)
case EDOM:
throw EdomExc (tmp);
#endif
#if defined (ERANGE)
case ERANGE:
throw ErangeExc (tmp);
#endif
#if defined (ENOMSG)
case ENOMSG:
throw EnomsgExc (tmp);
#endif
#if defined (EIDRM)
case EIDRM:
throw EidrmExc (tmp);
#endif
#if defined (ECHRNG)
case ECHRNG:
throw EchrngExc (tmp);
#endif
#if defined (EL2NSYNC)
case EL2NSYNC:
throw El2nsyncExc (tmp);
#endif
#if defined (EL3HLT)
case EL3HLT:
throw El3hltExc (tmp);
#endif
#if defined (EL3RST)
case EL3RST:
throw El3rstExc (tmp);
#endif
#if defined (ELNRNG)
case ELNRNG:
throw ElnrngExc (tmp);
#endif
#if defined (EUNATCH)
case EUNATCH:
throw EunatchExc (tmp);
#endif
#if defined (ENOSCI)
case ENOCSI:
throw EnocsiExc (tmp);
#endif
#if defined (EL2HLT)
case EL2HLT:
throw El2hltExc (tmp);
#endif
#if defined (EDEADLK)
case EDEADLK:
throw EdeadlkExc (tmp);
#endif
#if defined (ENOLCK)
case ENOLCK:
throw EnolckExc (tmp);
#endif
#if defined (EBADE)
case EBADE:
throw EbadeExc (tmp);
#endif
#if defined (EBADR)
case EBADR:
throw EbadrExc (tmp);
#endif
#if defined (EXFULL)
case EXFULL:
throw ExfullExc (tmp);
#endif
#if defined (ENOANO)
case ENOANO:
throw EnoanoExc (tmp);
#endif
#if defined (EBADRQC)
case EBADRQC:
throw EbadrqcExc (tmp);
#endif
#if defined (EBADSLT)
case EBADSLT:
throw EbadsltExc (tmp);
#endif
#if defined (EDEADLOCK) && defined (EDEADLK)
#if EDEADLOCK != EDEADLK
case EDEADLOCK:
throw EdeadlockExc (tmp);
#endif
#elif defined (EDEADLOCK)
case EDEADLOCK:
throw EdeadlockExc (tmp);
#endif
#if defined (EBFONT)
case EBFONT:
throw EbfontExc (tmp);
#endif
#if defined (ENOSTR)
case ENOSTR:
throw EnostrExc (tmp);
#endif
#if defined (ENODATA)
case ENODATA:
throw EnodataExc (tmp);
#endif
#if defined (ETIME)
case ETIME:
throw EtimeExc (tmp);
#endif
#if defined (ENOSR)
case ENOSR:
throw EnosrExc (tmp);
#endif
#if defined (ENONET)
case ENONET:
throw EnonetExc (tmp);
#endif
#if defined (ENOPKG)
case ENOPKG:
throw EnopkgExc (tmp);
#endif
#if defined (EREMOTE)
case EREMOTE:
throw EremoteExc (tmp);
#endif
#if defined (ENOLINK)
case ENOLINK:
throw EnolinkExc (tmp);
#endif
#if defined (EADV)
case EADV:
throw EadvExc (tmp);
#endif
#if defined (ESRMNT)
case ESRMNT:
throw EsrmntExc (tmp);
#endif
#if defined (ECOMM)
case ECOMM:
throw EcommExc (tmp);
#endif
#if defined (EPROTO)
case EPROTO:
throw EprotoExc (tmp);
#endif
#if defined (EMULTIHOP)
case EMULTIHOP:
throw EmultihopExc (tmp);
#endif
#if defined (EBADMSG)
case EBADMSG:
throw EbadmsgExc (tmp);
#endif
#if defined (ENAMETOOLONG)
case ENAMETOOLONG:
throw EnametoolongExc (tmp);
#endif
#if defined (EOVERFLOW)
case EOVERFLOW:
throw EoverflowExc (tmp);
#endif
#if defined (ENOTUNIQ)
case ENOTUNIQ:
throw EnotuniqExc (tmp);
#endif
#if defined (EBADFD)
case EBADFD:
throw EbadfdExc (tmp);
#endif
#if defined (EREMCHG)
case EREMCHG:
throw EremchgExc (tmp);
#endif
#if defined (ELIBACC)
case ELIBACC:
throw ElibaccExc (tmp);
#endif
#if defined (ELIBBAD)
case ELIBBAD:
throw ElibbadExc (tmp);
#endif
#if defined (ELIBSCN)
case ELIBSCN:
throw ElibscnExc (tmp);
#endif
#if defined (ELIBMAX)
case ELIBMAX:
throw ElibmaxExc (tmp);
#endif
#if defined (ELIBEXEC)
case ELIBEXEC:
throw ElibexecExc (tmp);
#endif
#if defined (EILSEQ)
case EILSEQ:
throw EilseqExc (tmp);
#endif
#if defined (ENOSYS)
case ENOSYS:
throw EnosysExc (tmp);
#endif
#if defined (ELOOP)
case ELOOP:
throw EloopExc (tmp);
#endif
#if defined (ERESTART)
case ERESTART:
throw ErestartExc (tmp);
#endif
#if defined (ESTRPIPE)
case ESTRPIPE:
throw EstrpipeExc (tmp);
#endif
#if defined (ENOTEMPTY)
case ENOTEMPTY:
throw EnotemptyExc (tmp);
#endif
#if defined (EUSERS)
case EUSERS:
throw EusersExc (tmp);
#endif
#if defined (ENOTSOCK)
case ENOTSOCK:
throw EnotsockExc (tmp);
#endif
#if defined (EDESTADDRREQ)
case EDESTADDRREQ:
throw EdestaddrreqExc (tmp);
#endif
#if defined (EMSGSIZE)
case EMSGSIZE:
throw EmsgsizeExc (tmp);
#endif
#if defined (EPROTOTYPE)
case EPROTOTYPE:
throw EprototypeExc (tmp);
#endif
#if defined (ENOPROTOOPT)
case ENOPROTOOPT:
throw EnoprotooptExc (tmp);
#endif
#if defined (EPROTONOSUPPORT)
case EPROTONOSUPPORT:
throw EprotonosupportExc (tmp);
#endif
#if defined (ESOCKTNOSUPPORT)
case ESOCKTNOSUPPORT:
throw EsocktnosupportExc (tmp);
#endif
#if defined (EOPNOTSUPP)
case EOPNOTSUPP:
throw EopnotsuppExc (tmp);
#endif
#if defined (EPFNOSUPPORT)
case EPFNOSUPPORT:
throw EpfnosupportExc (tmp);
#endif
#if defined (EAFNOSUPPORT)
case EAFNOSUPPORT:
throw EafnosupportExc (tmp);
#endif
#if defined (EADDRINUSE)
case EADDRINUSE:
throw EaddrinuseExc (tmp);
#endif
#if defined (EADDRNOTAVAIL)
case EADDRNOTAVAIL:
throw EaddrnotavailExc (tmp);
#endif
#if defined (ENETDOWN)
case ENETDOWN:
throw EnetdownExc (tmp);
#endif
#if defined (ENETUNREACH)
case ENETUNREACH:
throw EnetunreachExc (tmp);
#endif
#if defined (ENETRESET)
case ENETRESET:
throw EnetresetExc (tmp);
#endif
#if defined (ECONNABORTED)
case ECONNABORTED:
throw EconnabortedExc (tmp);
#endif
#if defined (ECONNRESET)
case ECONNRESET:
throw EconnresetExc (tmp);
#endif
#if defined (ENOBUFS)
case ENOBUFS:
throw EnobufsExc (tmp);
#endif
#if defined (EISCONN)
case EISCONN:
throw EisconnExc (tmp);
#endif
#if defined (ENOTCONN)
case ENOTCONN:
throw EnotconnExc (tmp);
#endif
#if defined (ESHUTDOWN)
case ESHUTDOWN:
throw EshutdownExc (tmp);
#endif
#if defined (ETOOMANYREFS)
case ETOOMANYREFS:
throw EtoomanyrefsExc (tmp);
#endif
#if defined (ETIMEDOUT)
case ETIMEDOUT:
throw EtimedoutExc (tmp);
#endif
#if defined (ECONNREFUSED)
case ECONNREFUSED:
throw EconnrefusedExc (tmp);
#endif
#if defined (EHOSTDOWN)
case EHOSTDOWN:
throw EhostdownExc (tmp);
#endif
#if defined (EHOSTUNREACH)
case EHOSTUNREACH:
throw EhostunreachExc (tmp);
#endif
#if defined (EALREADY)
case EALREADY:
throw EalreadyExc (tmp);
#endif
#if defined (EINPROGRESS)
case EINPROGRESS:
throw EinprogressExc (tmp);
#endif
#if defined (ESTALE)
case ESTALE:
throw EstaleExc (tmp);
#endif
#if defined (EIORESID)
case EIORESID:
throw EioresidExc (tmp);
#endif
#if defined (EUCLEAN)
case EUCLEAN:
throw EucleanExc (tmp);
#endif
#if defined (ENOTNAM)
case ENOTNAM:
throw EnotnamExc (tmp);
#endif
#if defined (ENAVAIL)
case ENAVAIL:
throw EnavailExc (tmp);
#endif
#if defined (EISNAM)
case EISNAM:
throw EisnamExc (tmp);
#endif
#if defined (EREMOTEIO)
case EREMOTEIO:
throw EremoteioExc (tmp);
#endif
#if defined (EINIT)
case EINIT:
throw EinitExc (tmp);
#endif
#if defined (EREMDEV)
case EREMDEV:
throw EremdevExc (tmp);
#endif
#if defined (ECANCELED)
case ECANCELED:
throw EcanceledExc (tmp);
#endif
#if defined (ENOLIMFILE)
case ENOLIMFILE:
throw EnolimfileExc (tmp);
#endif
#if defined (EPROCLIM)
case EPROCLIM:
throw EproclimExc (tmp);
#endif
#if defined (EDISJOINT)
case EDISJOINT:
throw EdisjointExc (tmp);
#endif
#if defined (ENOLOGIN)
case ENOLOGIN:
throw EnologinExc (tmp);
#endif
#if defined (ELOGINLIM)
case ELOGINLIM:
throw EloginlimExc (tmp);
#endif
#if defined (EGROUPLOOP)
case EGROUPLOOP:
throw EgrouploopExc (tmp);
#endif
#if defined (ENOATTACH)
case ENOATTACH:
throw EnoattachExc (tmp);
#endif
#if defined (ENOTSUP) && defined (EOPNOTSUPP)
#if ENOTSUP != EOPNOTSUPP
case ENOTSUP:
throw EnotsupExc (tmp);
#endif
#elif defined (ENOTSUP)
case ENOTSUP:
throw EnotsupExc (tmp);
#endif
#if defined (ENOATTR)
case ENOATTR:
throw EnoattrExc (tmp);
#endif
#if defined (EDIRCORRUPTED)
case EDIRCORRUPTED:
throw EdircorruptedExc (tmp);
#endif
#if defined (EDQUOT)
case EDQUOT:
throw EdquotExc (tmp);
#endif
#if defined (ENFSREMOTE)
case ENFSREMOTE:
throw EnfsremoteExc (tmp);
#endif
#if defined (ECONTROLLER)
case ECONTROLLER:
throw EcontrollerExc (tmp);
#endif
#if defined (ENOTCONTROLLER)
case ENOTCONTROLLER:
throw EnotcontrollerExc (tmp);
#endif
#if defined (EENQUEUED)
case EENQUEUED:
throw EenqueuedExc (tmp);
#endif
#if defined (ENOTENQUEUED)
case ENOTENQUEUED:
throw EnotenqueuedExc (tmp);
#endif
#if defined (EJOINED)
case EJOINED:
throw EjoinedExc (tmp);
#endif
#if defined (ENOTJOINED)
case ENOTJOINED:
throw EnotjoinedExc (tmp);
#endif
#if defined (ENOPROC)
case ENOPROC:
throw EnoprocExc (tmp);
#endif
#if defined (EMUSTRUN)
case EMUSTRUN:
throw EmustrunExc (tmp);
#endif
#if defined (ENOTSTOPPED)
case ENOTSTOPPED:
throw EnotstoppedExc (tmp);
#endif
#if defined (ECLOCKCPU)
case ECLOCKCPU:
throw EclockcpuExc (tmp);
#endif
#if defined (EINVALSTATE)
case EINVALSTATE:
throw EinvalstateExc (tmp);
#endif
#if defined (ENOEXIST)
case ENOEXIST:
throw EnoexistExc (tmp);
#endif
#if defined (EENDOFMINOR)
case EENDOFMINOR:
throw EendofminorExc (tmp);
#endif
#if defined (EBUFSIZE)
case EBUFSIZE:
throw EbufsizeExc (tmp);
#endif
#if defined (EEMPTY)
case EEMPTY:
throw EemptyExc (tmp);
#endif
#if defined (ENOINTRGROUP)
case ENOINTRGROUP:
throw EnointrgroupExc (tmp);
#endif
#if defined (EINVALMODE)
case EINVALMODE:
throw EinvalmodeExc (tmp);
#endif
#if defined (ECANTEXTENT)
case ECANTEXTENT:
throw EcantextentExc (tmp);
#endif
#if defined (EINVALTIME)
case EINVALTIME:
throw EinvaltimeExc (tmp);
#endif
#if defined (EDESTROYED)
case EDESTROYED:
throw EdestroyedExc (tmp);
#endif
}
throw ErrnoExc (tmp);
}
void throwErrnoExc (const std::string &text)
{
throwErrnoExc (text, errno);
}
void throwErrnoExc()
{
std::string txt = "%T.";
throwErrnoExc (txt);
}
IEX_INTERNAL_NAMESPACE_SOURCE_EXIT

97
Iex/IexThrowErrnoExc.h Normal file
View File

@ -0,0 +1,97 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXTHROWERRNOEXC_H
#define INCLUDED_IEXTHROWERRNOEXC_H
//----------------------------------------------------------
//
// A function which throws ExcErrno exceptions
//
//----------------------------------------------------------
#include "IexBaseExc.h"
#include "IexExport.h"
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
//--------------------------------------------------------------------------
//
// Function throwErrnoExc() throws an exception which corresponds to
// error code errnum. The exception text is initialized with a copy
// of the string passed to throwErrnoExc(), where all occurrences of
// "%T" have been replaced with the output of strerror(oserror()).
//
// Example:
//
// If opening file /tmp/output failed with an ENOENT error code,
// calling
//
// throwErrnoExc ();
//
// or
//
// throwErrnoExc ("%T.");
//
// will throw an EnoentExc whose text reads
//
// No such file or directory.
//
// More detailed messages can be assembled using stringstreams:
//
// std::stringstream s;
// s << "Cannot open file " << name << " (%T).";
// throwErrnoExc (s);
//
// The resulting exception contains the following text:
//
// Cannot open file /tmp/output (No such file or directory).
//
// Alternatively, you may want to use the THROW_ERRNO macro defined
// in IexMacros.h:
//
// THROW_ERRNO ("Cannot open file " << name << " (%T).")
//
//--------------------------------------------------------------------------
IEX_EXPORT void throwErrnoExc(const std::string &txt, int errnum);
IEX_EXPORT void throwErrnoExc(const std::string &txt);
IEX_EXPORT void throwErrnoExc();
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IEXTHROWERRNOEXC_H

22
Iex/Makefile.am Normal file
View File

@ -0,0 +1,22 @@
## Process this file with automake to produce Makefile.in
INCLUDES = -I$(top_srcdir)/config
lib_LTLIBRARIES = libIex.la
libIex_la_SOURCES = IexThrowErrnoExc.cpp IexBaseExc.cpp IexBaseExc.h \
IexErrnoExc.h Iex.h IexMacros.h IexMathExc.h \
IexThrowErrnoExc.h
libIex_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
if LIB_SUFFIX_EXISTS
libIex_la_LDFLAGS += -release @LIB_SUFFIX@
endif
libIexincludedir = $(includedir)/OpenEXR
libIexinclude_HEADERS = IexBaseExc.h IexMathExc.h IexThrowErrnoExc.h \
IexErrnoExc.h IexMacros.h Iex.h \
IexForward.h IexNamespace.h IexExport.h
EXTRA_DIST = CMakeLists.txt

708
Iex/Makefile.in Normal file
View File

@ -0,0 +1,708 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@LIB_SUFFIX_EXISTS_TRUE@am__append_1 = -release @LIB_SUFFIX@
subdir = Iex
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(libIexinclude_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" \
"$(DESTDIR)$(libIexincludedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libIex_la_LIBADD =
am_libIex_la_OBJECTS = IexThrowErrnoExc.lo IexBaseExc.lo
libIex_la_OBJECTS = $(am_libIex_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libIex_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(libIex_la_LDFLAGS) $(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libIex_la_SOURCES)
DIST_SOURCES = $(libIex_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(libIexinclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
AM_CXXFLAGS = @AM_CXXFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
ILMBASE_VERSION = @ILMBASE_VERSION@
ILMBASE_VERSION_API = @ILMBASE_VERSION_API@
ILMBASE_VERSION_MAJOR = @ILMBASE_VERSION_MAJOR@
ILMBASE_VERSION_MINOR = @ILMBASE_VERSION_MINOR@
ILMBASE_VERSION_PATCH = @ILMBASE_VERSION_PATCH@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIB_SUFFIX = @LIB_SUFFIX@
LIB_SUFFIX_DASH = @LIB_SUFFIX_DASH@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
acx_pthread_config = @acx_pthread_config@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
INCLUDES = -I$(top_srcdir)/config
lib_LTLIBRARIES = libIex.la
libIex_la_SOURCES = IexThrowErrnoExc.cpp IexBaseExc.cpp IexBaseExc.h \
IexErrnoExc.h Iex.h IexMacros.h IexMathExc.h \
IexThrowErrnoExc.h
libIex_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined \
$(am__append_1)
libIexincludedir = $(includedir)/OpenEXR
libIexinclude_HEADERS = IexBaseExc.h IexMathExc.h IexThrowErrnoExc.h \
IexErrnoExc.h IexMacros.h Iex.h \
IexForward.h IexNamespace.h IexExport.h
EXTRA_DIST = CMakeLists.txt
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Iex/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign Iex/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libIex.la: $(libIex_la_OBJECTS) $(libIex_la_DEPENDENCIES) $(EXTRA_libIex_la_DEPENDENCIES)
$(AM_V_CXXLD)$(libIex_la_LINK) -rpath $(libdir) $(libIex_la_OBJECTS) $(libIex_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IexBaseExc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IexThrowErrnoExc.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-libIexincludeHEADERS: $(libIexinclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(libIexinclude_HEADERS)'; test -n "$(libIexincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(libIexincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libIexincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libIexincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libIexincludedir)" || exit $$?; \
done
uninstall-libIexincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libIexinclude_HEADERS)'; test -n "$(libIexincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(libIexincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libIexincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-libIexincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libIexincludeHEADERS uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libIexincludeHEADERS \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am \
uninstall-libIexincludeHEADERS uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

66
IexMath/CMakeLists.txt Normal file
View File

@ -0,0 +1,66 @@
# pstanczyk@ilm.com
SET (ILMBASE_LIB_TARGETS "")
IF ( OPENEXR_BUILD_SHARED )
LIST ( APPEND ILMBASE_LIB_TARGETS IexMath )
ADD_LIBRARY ( IexMath SHARED
IexMathFloatExc.cpp
IexMathFpu.cpp
)
TARGET_COMPILE_DEFINITIONS ( IexMath PRIVATE IEXMATH_EXPORTS )
IF (WIN32)
TARGET_COMPILE_DEFINITIONS ( IexMath PUBLIC OPENEXR_DLL )
ENDIF ()
TARGET_LINK_LIBRARIES( IexMath
PUBLIC IlmBase::Iex )
SET_TARGET_PROPERTIES ( IexMath
PROPERTIES
VERSION ${OPENEXR_VERSION}
SOVERSION ${OPENEXR_SOVERSION}
OUTPUT_NAME "IexMath${ILMBASE_LIBSUFFIX}"
)
ENDIF ()
IF (BUILD_ILMBASE_STATIC)
LIST ( APPEND ILMBASE_LIB_TARGETS IexMath_static )
ADD_LIBRARY ( IexMath_static STATIC
IexMathFloatExc.cpp
IexMathFpu.cpp
)
SET_TARGET_PROPERTIES ( IexMath_static
PROPERTIES
VERSION ${ILMBASE_VERSION_MAJOR}.${ILMBASE_VERSION_MINOR}.${ILMBASE_VERSION_PATCH}
OUTPUT_NAME "IexMath${ILMBASE_LIBSUFFIX}_s"
)
ENDIF( )
IF (OPENEXR_BUILD_SHARED OR BUILD_ILMBASE_STATIC)
INSTALL ( TARGETS ${ILMBASE_LIB_TARGETS}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION ${RUNTIME_DIR}
)
ENDIF ()
INSTALL (
FILES
IexMathFloatExc.h
IexMathFpu.h
IexMathIeeeExc.h
DESTINATION
include/OpenEXR
)
if (OPENEXR_BUILD_SHARED)
add_library(IlmBase::IexMath ALIAS IexMath)
endif()
if (BUILD_ILMBASE_STATIC)
add_library(IlmBase::IexMath_static ALIAS IexMath_static)
endif()

131
IexMath/IexMathFloatExc.cpp Normal file
View File

@ -0,0 +1,131 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------
//
// A function to control which IEEE floating
// point exceptions will be translated into
// C++ MathExc exceptions.
//
//-----------------------------------------------------
#include <IexMathFloatExc.h>
#include <IexMacros.h>
#include <IexMathFpu.h>
#if 0
#include <iostream>
#define debug(x) (std::cout << x << std::flush)
#else
#define debug(x)
#endif
IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
namespace {
void
fpeHandler (int type, const char explanation[])
{
switch (type)
{
case IEEE_OVERFLOW:
throw OverflowExc (explanation);
case IEEE_UNDERFLOW:
throw UnderflowExc (explanation);
case IEEE_DIVZERO:
throw DivzeroExc (explanation);
case IEEE_INEXACT:
throw InexactExc (explanation);
case IEEE_INVALID:
throw InvalidFpOpExc (explanation);
}
throw MathExc (explanation);
}
} // namespace
void
mathExcOn (int when)
{
debug ("mathExcOn (when = 0x" << std::hex << when << ")\n");
setFpExceptions (when);
setFpExceptionHandler (fpeHandler);
}
int
getMathExcOn ()
{
int when = fpExceptions();
debug ("getMathExcOn () == 0x" << std::hex << when << ")\n");
return when;
}
MathExcOn::MathExcOn (int when)
: _changed (false)
{
_saved = getMathExcOn();
if (_saved != when)
{
_changed = true;
mathExcOn (when);
}
}
MathExcOn::~MathExcOn ()
{
if (_changed)
mathExcOn (_saved);
}
void
MathExcOn::handleOutstandingExceptions()
{
handleExceptionsSetInRegisters();
}
IEX_INTERNAL_NAMESPACE_SOURCE_EXIT

130
IexMath/IexMathFloatExc.h Normal file
View File

@ -0,0 +1,130 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IEXMATHFLOATEXC_H
#define INCLUDED_IEXMATHFLOATEXC_H
#ifndef IEXMATH_EXPORT_H
#define IEXMATH_EXPORT_H
#if defined(OPENEXR_DLL)
#if defined(IEXMATH_EXPORTS)
#define IEXMATH_EXPORT __declspec(dllexport)
#else
#define IEXMATH_EXPORT __declspec(dllimport)
#endif
#define IEXMATH_EXPORT_CONST
#else
#define IEXMATH_EXPORT
#define IEXMATH_EXPORT_CONST const
#endif
#endif
#include "IexNamespace.h"
#include "IexMathExc.h"
//#include <IexBaseExc.h>
#include "IexMathIeeeExc.h"
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
//-------------------------------------------------------------
// Function mathExcOn() defines which floating point exceptions
// will be trapped and converted to C++ exceptions.
//-------------------------------------------------------------
IEXMATH_EXPORT
void mathExcOn (int when = (IEEE_OVERFLOW | IEEE_DIVZERO | IEEE_INVALID));
//----------------------------------------------------------------------
// Function getMathExcOn() tells you for which floating point exceptions
// trapping and conversion to C++ exceptions is currently enabled.
//----------------------------------------------------------------------
IEXMATH_EXPORT
int getMathExcOn();
//------------------------------------------------------------------------
// A classs that temporarily sets floating point exception trapping
// and conversion, and later restores the previous settings.
//
// Example:
//
// float
// trickyComputation (float x)
// {
// MathExcOn meo (0); // temporarily disable floating
// // point exception trapping
//
// float result = ...; // computation which may cause
// // floating point exceptions
//
// return result; // destruction of meo restores
// } // the program's previous floating
// // point exception settings
//------------------------------------------------------------------------
class MathExcOn
{
public:
IEXMATH_EXPORT MathExcOn (int when);
IEXMATH_EXPORT ~MathExcOn ();
// It is possible for functions to set the exception registers
// yet not trigger a SIGFPE. Specifically, the implementation
// of pow(x, y) we're using can generates a NaN from a negative x
// and fractional y but a SIGFPE is not generated.
// This function examimes the exception registers and calls the
// fpHandler if those registers modulo the exception mask are set.
// It should be called wherever this class is commonly used where it has
// been found that certain floating point exceptions are not being thrown.
IEXMATH_EXPORT void handleOutstandingExceptions();
private:
bool _changed;
int _saved;
};
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif

530
IexMath/IexMathFpu.cpp Normal file
View File

@ -0,0 +1,530 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------
//
// Functions to control floating point exceptions.
//
//------------------------------------------------------------------------
#include "IexMathFpu.h"
#include <stdint.h>
#include <IlmBaseConfig.h>
#include <stdio.h>
#if 0
#include <iostream>
#define debug(x) (std::cout << x << std::flush)
#else
#define debug(x)
#endif
#if defined(HAVE_UCONTEXT_H) && (defined(__x86_64__) || defined(_M_X64) || defined(__i386__) || defined(_M_IX86))
#include <ucontext.h>
#include <signal.h>
#include <iostream>
#include <stdint.h>
IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
namespace FpuControl
{
//-------------------------------------------------------------------
//
// Modern x86 processors and all AMD64 processors have two
// sets of floating-point control/status registers: cw and sw
// for legacy x87 stack-based arithmetic, and mxcsr for
// SIMD arithmetic. When setting exception masks or checking
// for exceptions, we must set/check all relevant registers,
// since applications may contain code that uses either FP
// model.
//
// These functions handle both FP models for x86 and AMD64.
//
//-------------------------------------------------------------------
//-------------------------------------------------------------------
//
// Restore the control register state from a signal handler
// user context, optionally clearing the exception bits
// in the restored control register, if applicable.
//
//-------------------------------------------------------------------
void restoreControlRegs (const ucontext_t & ucon,
bool clearExceptions = false);
//------------------------------------------------------------
//
// Set exception mask bits in the control register state.
// A value of 1 means the exception is masked, a value of
// 0 means the exception is enabled.
//
// setExceptionMask returns the previous mask value. If
// the 'exceptions' pointer is non-null, it returns in
// this argument the FPU exception bits.
//
//------------------------------------------------------------
const int INVALID_EXC = (1<<0);
const int DENORMAL_EXC = (1<<1);
const int DIVZERO_EXC = (1<<2);
const int OVERFLOW_EXC = (1<<3);
const int UNDERFLOW_EXC = (1<<4);
const int INEXACT_EXC = (1<<5);
const int ALL_EXC = INVALID_EXC | DENORMAL_EXC | DIVZERO_EXC |
OVERFLOW_EXC | UNDERFLOW_EXC | INEXACT_EXC;
int setExceptionMask (int mask, int * exceptions = 0);
int getExceptionMask ();
//---------------------------------------------
//
// Get/clear the exception bits in the FPU.
//
//---------------------------------------------
int getExceptions ();
void clearExceptions ();
//------------------------------------------------------------------
//
// Everything below here is implementation. Do not use these
// constants or functions in your applications or libraries.
// This is not the code you're looking for. Move along.
//
// Optimization notes -- on a Pentium 4, at least, it appears
// to be faster to get the mxcsr first and then the cw; and to
// set the cw first and then the mxcsr. Also, it seems to
// be faster to clear the sw exception bits after setting
// cw and mxcsr.
//
//------------------------------------------------------------------
static inline uint16_t
getSw ()
{
uint16_t sw;
asm volatile ("fnstsw %0" : "=m" (sw) : );
return sw;
}
static inline void
setCw (uint16_t cw)
{
asm volatile ("fldcw %0" : : "m" (cw) );
}
static inline uint16_t
getCw ()
{
uint16_t cw;
asm volatile ("fnstcw %0" : "=m" (cw) : );
return cw;
}
static inline void
setMxcsr (uint32_t mxcsr, bool clearExceptions)
{
mxcsr &= clearExceptions ? 0xffffffc0 : 0xffffffff;
asm volatile ("ldmxcsr %0" : : "m" (mxcsr) );
}
static inline uint32_t
getMxcsr ()
{
uint32_t mxcsr;
asm volatile ("stmxcsr %0" : "=m" (mxcsr) : );
return mxcsr;
}
static inline int
calcMask (uint16_t cw, uint32_t mxcsr)
{
//
// Hopefully, if the user has been using FpuControl functions,
// the masks are the same, but just in case they're not, we
// AND them together to report the proper subset of the masks.
//
return (cw & ALL_EXC) & ((mxcsr >> 7) & ALL_EXC);
}
inline int
setExceptionMask (int mask, int * exceptions)
{
uint16_t cw = getCw ();
uint32_t mxcsr = getMxcsr ();
if (exceptions)
*exceptions = (mxcsr & ALL_EXC) | (getSw () & ALL_EXC);
int oldmask = calcMask (cw, mxcsr);
//
// The exception constants are chosen very carefully so that
// we can do a simple mask and shift operation to insert
// them into the control words. The mask operation is for
// safety, in case the user accidentally set some other
// bits in the exception mask.
//
mask &= ALL_EXC;
cw = (cw & ~ALL_EXC) | mask;
mxcsr = (mxcsr & ~(ALL_EXC << 7)) | (mask << 7);
setCw (cw);
setMxcsr (mxcsr, false);
return oldmask;
}
inline int
getExceptionMask ()
{
uint32_t mxcsr = getMxcsr ();
uint16_t cw = getCw ();
return calcMask (cw, mxcsr);
}
inline int
getExceptions ()
{
return (getMxcsr () | getSw ()) & ALL_EXC;
}
void
clearExceptions ()
{
uint32_t mxcsr = getMxcsr () & 0xffffffc0;
asm volatile ("ldmxcsr %0\n"
"fnclex"
: : "m" (mxcsr) );
}
// If the fpe was taken while doing a float-to-int cast using the x87,
// the rounding mode and possibly the precision will be wrong. So instead
// of restoring to the state as of the fault, we force the rounding mode
// to be 'nearest' and the precision to be double extended.
//
// rounding mode is in bits 10-11, value 00 == round to nearest
// precision is in bits 8-9, value 11 == double extended (80-bit)
//
const uint16_t cwRestoreMask = ~((3 << 10) | (3 << 8));
const uint16_t cwRestoreVal = (0 << 10) | (3 << 8);
#ifdef ILMBASE_HAVE_CONTROL_REGISTER_SUPPORT
inline void
restoreControlRegs (const ucontext_t & ucon, bool clearExceptions)
{
setCw ((ucon.uc_mcontext.fpregs->cwd & cwRestoreMask) | cwRestoreVal);
setMxcsr (ucon.uc_mcontext.fpregs->mxcsr, clearExceptions);
}
#else
//
// Ugly, the mxcsr isn't defined in GNU libc ucontext_t, but
// it's passed to the signal handler by the kernel. Use
// the kernel's version of the ucontext to get it, see
// <asm/sigcontext.h>
//
#include <asm/sigcontext.h>
inline void
restoreControlRegs (const ucontext_t & ucon, bool clearExceptions)
{
setCw ((ucon.uc_mcontext.fpregs->cw & cwRestoreMask) | cwRestoreVal);
_fpstate * kfp = reinterpret_cast<_fpstate *> (ucon.uc_mcontext.fpregs);
setMxcsr (kfp->magic == 0 ? kfp->mxcsr : 0, clearExceptions);
}
#endif
} // namespace FpuControl
namespace {
volatile FpExceptionHandler fpeHandler = 0;
extern "C" void
catchSigFpe (int sig, siginfo_t *info, ucontext_t *ucon)
{
debug ("catchSigFpe (sig = "<< sig << ", ...)\n");
FpuControl::restoreControlRegs (*ucon, true);
if (fpeHandler == 0)
return;
if (info->si_code == SI_USER)
{
fpeHandler (0, "Floating-point exception, caused by "
"a signal sent from another process.");
return;
}
if (sig == SIGFPE)
{
switch (info->si_code)
{
//
// IEEE 754 floating point exceptions:
//
case FPE_FLTDIV:
fpeHandler (IEEE_DIVZERO, "Floating-point division by zero.");
return;
case FPE_FLTOVF:
fpeHandler (IEEE_OVERFLOW, "Floating-point overflow.");
return;
case FPE_FLTUND:
fpeHandler (IEEE_UNDERFLOW, "Floating-point underflow.");
return;
case FPE_FLTRES:
fpeHandler (IEEE_INEXACT, "Inexact floating-point result.");
return;
case FPE_FLTINV:
fpeHandler (IEEE_INVALID, "Invalid floating-point operation.");
return;
//
// Other arithmetic exceptions which can also
// be trapped by the operating system:
//
case FPE_INTDIV:
fpeHandler (0, "Integer division by zero.");
break;
case FPE_INTOVF:
fpeHandler (0, "Integer overflow.");
break;
case FPE_FLTSUB:
fpeHandler (0, "Subscript out of range.");
break;
}
}
fpeHandler (0, "Floating-point exception.");
}
} // namespace
void
setFpExceptions (int when)
{
int mask = FpuControl::ALL_EXC;
if (when & IEEE_OVERFLOW)
mask &= ~FpuControl::OVERFLOW_EXC;
if (when & IEEE_UNDERFLOW)
mask &= ~FpuControl::UNDERFLOW_EXC;
if (when & IEEE_DIVZERO)
mask &= ~FpuControl::DIVZERO_EXC;
if (when & IEEE_INEXACT)
mask &= ~FpuControl::INEXACT_EXC;
if (when & IEEE_INVALID)
mask &= ~FpuControl::INVALID_EXC;
//
// The Linux kernel apparently sometimes passes
// incorrect si_info to signal handlers unless
// the exception flags are cleared.
//
// XXX is this still true on 2.4+ kernels?
//
FpuControl::setExceptionMask (mask);
FpuControl::clearExceptions ();
}
int
fpExceptions ()
{
int mask = FpuControl::getExceptionMask ();
int when = 0;
if (!(mask & FpuControl::OVERFLOW_EXC))
when |= IEEE_OVERFLOW;
if (!(mask & FpuControl::UNDERFLOW_EXC))
when |= IEEE_UNDERFLOW;
if (!(mask & FpuControl::DIVZERO_EXC))
when |= IEEE_DIVZERO;
if (!(mask & FpuControl::INEXACT_EXC))
when |= IEEE_INEXACT;
if (!(mask & FpuControl::INVALID_EXC))
when |= IEEE_INVALID;
return when;
}
void
handleExceptionsSetInRegisters()
{
if (fpeHandler == 0)
return;
int mask = FpuControl::getExceptionMask ();
int exc = FpuControl::getExceptions();
if (!(mask & FpuControl::DIVZERO_EXC) && (exc & FpuControl::DIVZERO_EXC))
{
fpeHandler(IEEE_DIVZERO, "Floating-point division by zero.");
return;
}
if (!(mask & FpuControl::OVERFLOW_EXC) && (exc & FpuControl::OVERFLOW_EXC))
{
fpeHandler(IEEE_OVERFLOW, "Floating-point overflow.");
return;
}
if (!(mask & FpuControl::UNDERFLOW_EXC) && (exc & FpuControl::UNDERFLOW_EXC))
{
fpeHandler(IEEE_UNDERFLOW, "Floating-point underflow.");
return;
}
if (!(mask & FpuControl::INEXACT_EXC) && (exc & FpuControl::INEXACT_EXC))
{
fpeHandler(IEEE_INEXACT, "Inexact floating-point result.");
return;
}
if (!(mask & FpuControl::INVALID_EXC) && (exc & FpuControl::INVALID_EXC))
{
fpeHandler(IEEE_INVALID, "Invalid floating-point operation.");
return;
}
}
void
setFpExceptionHandler (FpExceptionHandler handler)
{
if (fpeHandler == 0)
{
struct sigaction action;
sigemptyset (&action.sa_mask);
action.sa_flags = SA_SIGINFO | SA_NOMASK;
action.sa_sigaction = (void (*) (int, siginfo_t *, void *)) catchSigFpe;
action.sa_restorer = 0;
sigaction (SIGFPE, &action, 0);
}
fpeHandler = handler;
}
IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
#else
#include <signal.h>
#include <assert.h>
IEX_INTERNAL_NAMESPACE_SOURCE_ENTER
namespace
{
volatile FpExceptionHandler fpeHandler = 0;
void fpExc_(int x)
{
if (fpeHandler != 0)
{
fpeHandler(x, "");
}
else
{
assert(0 != "Floating point exception");
}
}
}
void
setFpExceptions( int )
{
}
void
setFpExceptionHandler (FpExceptionHandler handler)
{
// improve floating point exception handling nanoscopically above "nothing at all"
fpeHandler = handler;
signal(SIGFPE, fpExc_);
}
int
fpExceptions()
{
return 0;
}
void
handleExceptionsSetInRegisters()
{
// No implementation on this platform
}
IEX_INTERNAL_NAMESPACE_SOURCE_EXIT
#endif

91
IexMath/IexMathFpu.h Normal file
View File

@ -0,0 +1,91 @@
#ifndef INCLUDED_IEXMATHFPU_H
#define INCLUDED_IEXMATHFPU_H
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//------------------------------------------------------------------------
//
// Functions to control floating point exceptions.
//
//------------------------------------------------------------------------
#include "IexMathIeeeExc.h"
#include "IexNamespace.h"
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
//-----------------------------------------
// setFpExceptions() defines which floating
// point exceptions cause SIGFPE signals.
//-----------------------------------------
void setFpExceptions (int when = (IEEE_OVERFLOW | IEEE_DIVZERO | IEEE_INVALID));
//----------------------------------------
// fpExceptions() tells you which floating
// point exceptions cause SIGFPE signals.
//----------------------------------------
int fpExceptions ();
//------------------------------------------
// setFpExceptionHandler() defines a handler
// that will be called when SIGFPE occurs.
//------------------------------------------
extern "C" typedef void (* FpExceptionHandler) (int type, const char explanation[]);
void setFpExceptionHandler (FpExceptionHandler handler);
// -----------------------------------------
// handleExceptionsSetInRegisters() examines
// the exception registers and calls the
// floating point exception handler if the
// bits are set. This function exists to
// allow trapping of exception register states
// that can get set though no SIGFPE occurs.
// -----------------------------------------
void handleExceptionsSetInRegisters();
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif

62
IexMath/IexMathIeeeExc.h Normal file
View File

@ -0,0 +1,62 @@
#ifndef INCLUDED_IEXMATHIEEE_EXC_H
#define INCLUDED_IEXMATHIEEE_EXC_H
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 1997, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//---------------------------------------------------------------------------
//
// Names for the loating point exceptions defined by IEEE standard 754
//
//---------------------------------------------------------------------------
#include "IexNamespace.h"
IEX_INTERNAL_NAMESPACE_HEADER_ENTER
enum IeeeExcType
{
IEEE_OVERFLOW = 1,
IEEE_UNDERFLOW = 2,
IEEE_DIVZERO = 4,
IEEE_INEXACT = 8,
IEEE_INVALID = 16
};
IEX_INTERNAL_NAMESPACE_HEADER_EXIT
#endif

20
IexMath/Makefile.am Normal file
View File

@ -0,0 +1,20 @@
## Process this file with automake to produce Makefile.in
lib_LTLIBRARIES = libIexMath.la
libIexMathincludedir = $(includedir)/OpenEXR
libIexMath_la_SOURCES = IexMathFloatExc.cpp IexMathFpu.cpp
libIexMathinclude_HEADERS = IexMathFloatExc.h IexMathFpu.h IexMathIeeeExc.h
libIexMath_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
if LIB_SUFFIX_EXISTS
libIexMath_la_LDFLAGS += -release @LIB_SUFFIX@
endif
libIexMath_la_LIBADD = ../Iex/libIex.la
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex \
-I$(top_srcdir)/config
EXTRA_DIST = CMakeLists.txt

689
IexMath/Makefile.in Normal file
View File

@ -0,0 +1,689 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@LIB_SUFFIX_EXISTS_TRUE@am__append_1 = -release @LIB_SUFFIX@
subdir = IexMath
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(libIexMathinclude_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" \
"$(DESTDIR)$(libIexMathincludedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libIexMath_la_DEPENDENCIES = ../Iex/libIex.la
am_libIexMath_la_OBJECTS = IexMathFloatExc.lo IexMathFpu.lo
libIexMath_la_OBJECTS = $(am_libIexMath_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libIexMath_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(libIexMath_la_LDFLAGS) $(LDFLAGS) \
-o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
SOURCES = $(libIexMath_la_SOURCES)
DIST_SOURCES = $(libIexMath_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(libIexMathinclude_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
AM_CXXFLAGS = @AM_CXXFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
ILMBASE_VERSION = @ILMBASE_VERSION@
ILMBASE_VERSION_API = @ILMBASE_VERSION_API@
ILMBASE_VERSION_MAJOR = @ILMBASE_VERSION_MAJOR@
ILMBASE_VERSION_MINOR = @ILMBASE_VERSION_MINOR@
ILMBASE_VERSION_PATCH = @ILMBASE_VERSION_PATCH@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIB_SUFFIX = @LIB_SUFFIX@
LIB_SUFFIX_DASH = @LIB_SUFFIX_DASH@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
acx_pthread_config = @acx_pthread_config@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libIexMath.la
libIexMathincludedir = $(includedir)/OpenEXR
libIexMath_la_SOURCES = IexMathFloatExc.cpp IexMathFpu.cpp
libIexMathinclude_HEADERS = IexMathFloatExc.h IexMathFpu.h IexMathIeeeExc.h
libIexMath_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined \
$(am__append_1)
libIexMath_la_LIBADD = ../Iex/libIex.la
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex \
-I$(top_srcdir)/config
EXTRA_DIST = CMakeLists.txt
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign IexMath/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign IexMath/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libIexMath.la: $(libIexMath_la_OBJECTS) $(libIexMath_la_DEPENDENCIES) $(EXTRA_libIexMath_la_DEPENDENCIES)
$(AM_V_CXXLD)$(libIexMath_la_LINK) -rpath $(libdir) $(libIexMath_la_OBJECTS) $(libIexMath_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IexMathFloatExc.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IexMathFpu.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-libIexMathincludeHEADERS: $(libIexMathinclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(libIexMathinclude_HEADERS)'; test -n "$(libIexMathincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(libIexMathincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libIexMathincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libIexMathincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libIexMathincludedir)" || exit $$?; \
done
uninstall-libIexMathincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libIexMathinclude_HEADERS)'; test -n "$(libIexMathincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(libIexMathincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libIexMathincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-libIexMathincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libIexMathincludeHEADERS \
uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libIexMathincludeHEADERS \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am \
uninstall-libIexMathincludeHEADERS uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

10
IexTest/CMakeLists.txt Normal file
View File

@ -0,0 +1,10 @@
# yue.nicholas@gmail.com
ADD_EXECUTABLE ( IexTest
main.cpp
testBaseExc.cpp
)
TARGET_LINK_LIBRARIES ( IexTest IlmBase::Iex${OPENEXR_TARGET_SUFFIX} )
ADD_TEST ( TestIex IexTest )

13
IexTest/Makefile.am Normal file
View File

@ -0,0 +1,13 @@
## Process this file with automake to produce Makefile.in
check_PROGRAMS = IexTest
IexTest_SOURCES = main.cpp testBaseExc.cpp testBaseExc.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config
LDADD = -L$(top_builddir)/Iex -lIex
TESTS = IexTest
EXTRA_DIST = CMakeLists.txt

985
IexTest/Makefile.in Normal file
View File

@ -0,0 +1,985 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
check_PROGRAMS = IexTest$(EXEEXT)
TESTS = IexTest$(EXEEXT)
subdir = IexTest
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(top_srcdir)/test-driver
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am_IexTest_OBJECTS = main.$(OBJEXT) testBaseExc.$(OBJEXT)
IexTest_OBJECTS = $(am_IexTest_OBJECTS)
IexTest_LDADD = $(LDADD)
IexTest_DEPENDENCIES =
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(IexTest_SOURCES)
DIST_SOURCES = $(IexTest_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
am__tty_colors_dummy = \
mgn= red= grn= lgn= blu= brg= std=; \
am__color_tests=no
am__tty_colors = { \
$(am__tty_colors_dummy); \
if test "X$(AM_COLOR_TESTS)" = Xno; then \
am__color_tests=no; \
elif test "X$(AM_COLOR_TESTS)" = Xalways; then \
am__color_tests=yes; \
elif test "X$$TERM" != Xdumb && { test -t 1; } 2>/dev/null; then \
am__color_tests=yes; \
fi; \
if test $$am__color_tests = yes; then \
red=''; \
grn=''; \
lgn=''; \
blu=''; \
mgn=''; \
brg=''; \
std=''; \
fi; \
}
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__recheck_rx = ^[ ]*:recheck:[ ]*
am__global_test_result_rx = ^[ ]*:global-test-result:[ ]*
am__copy_in_global_log_rx = ^[ ]*:copy-in-global-log:[ ]*
# A command that, given a newline-separated list of test names on the
# standard input, print the name of the tests that are to be re-run
# upon "make recheck".
am__list_recheck_tests = $(AWK) '{ \
recheck = 1; \
while ((rc = (getline line < ($$0 ".trs"))) != 0) \
{ \
if (rc < 0) \
{ \
if ((getline line2 < ($$0 ".log")) < 0) \
recheck = 0; \
break; \
} \
else if (line ~ /$(am__recheck_rx)[nN][Oo]/) \
{ \
recheck = 0; \
break; \
} \
else if (line ~ /$(am__recheck_rx)[yY][eE][sS]/) \
{ \
break; \
} \
}; \
if (recheck) \
print $$0; \
close ($$0 ".trs"); \
close ($$0 ".log"); \
}'
# A command that, given a newline-separated list of test names on the
# standard input, create the global log from their .trs and .log files.
am__create_global_log = $(AWK) ' \
function fatal(msg) \
{ \
print "fatal: making $@: " msg | "cat >&2"; \
exit 1; \
} \
function rst_section(header) \
{ \
print header; \
len = length(header); \
for (i = 1; i <= len; i = i + 1) \
printf "="; \
printf "\n\n"; \
} \
{ \
copy_in_global_log = 1; \
global_test_result = "RUN"; \
while ((rc = (getline line < ($$0 ".trs"))) != 0) \
{ \
if (rc < 0) \
fatal("failed to read from " $$0 ".trs"); \
if (line ~ /$(am__global_test_result_rx)/) \
{ \
sub("$(am__global_test_result_rx)", "", line); \
sub("[ ]*$$", "", line); \
global_test_result = line; \
} \
else if (line ~ /$(am__copy_in_global_log_rx)[nN][oO]/) \
copy_in_global_log = 0; \
}; \
if (copy_in_global_log) \
{ \
rst_section(global_test_result ": " $$0); \
while ((rc = (getline line < ($$0 ".log"))) != 0) \
{ \
if (rc < 0) \
fatal("failed to read from " $$0 ".log"); \
print line; \
}; \
printf "\n"; \
}; \
close ($$0 ".trs"); \
close ($$0 ".log"); \
}'
# Restructured Text title.
am__rst_title = { sed 's/.*/ & /;h;s/./=/g;p;x;s/ *$$//;p;g' && echo; }
# Solaris 10 'make', and several other traditional 'make' implementations,
# pass "-e" to $(SHELL), and POSIX 2008 even requires this. Work around it
# by disabling -e (using the XSI extension "set +e") if it's set.
am__sh_e_setup = case $$- in *e*) set +e;; esac
# Default flags passed to test drivers.
am__common_driver_flags = \
--color-tests "$$am__color_tests" \
--enable-hard-errors "$$am__enable_hard_errors" \
--expect-failure "$$am__expect_failure"
# To be inserted before the command running the test. Creates the
# directory for the log if needed. Stores in $dir the directory
# containing $f, in $tst the test, in $log the log. Executes the
# developer- defined test setup AM_TESTS_ENVIRONMENT (if any), and
# passes TESTS_ENVIRONMENT. Set up options for the wrapper that
# will run the test scripts (or their associated LOG_COMPILER, if
# thy have one).
am__check_pre = \
$(am__sh_e_setup); \
$(am__vpath_adj_setup) $(am__vpath_adj) \
$(am__tty_colors); \
srcdir=$(srcdir); export srcdir; \
case "$@" in \
*/*) am__odir=`echo "./$@" | sed 's|/[^/]*$$||'`;; \
*) am__odir=.;; \
esac; \
test "x$$am__odir" = x"." || test -d "$$am__odir" \
|| $(MKDIR_P) "$$am__odir" || exit $$?; \
if test -f "./$$f"; then dir=./; \
elif test -f "$$f"; then dir=; \
else dir="$(srcdir)/"; fi; \
tst=$$dir$$f; log='$@'; \
if test -n '$(DISABLE_HARD_ERRORS)'; then \
am__enable_hard_errors=no; \
else \
am__enable_hard_errors=yes; \
fi; \
case " $(XFAIL_TESTS) " in \
*[\ \ ]$$f[\ \ ]* | *[\ \ ]$$dir$$f[\ \ ]*) \
am__expect_failure=yes;; \
*) \
am__expect_failure=no;; \
esac; \
$(AM_TESTS_ENVIRONMENT) $(TESTS_ENVIRONMENT)
# A shell command to get the names of the tests scripts with any registered
# extension removed (i.e., equivalently, the names of the test logs, with
# the '.log' extension removed). The result is saved in the shell variable
# '$bases'. This honors runtime overriding of TESTS and TEST_LOGS. Sadly,
# we cannot use something simpler, involving e.g., "$(TEST_LOGS:.log=)",
# since that might cause problem with VPATH rewrites for suffix-less tests.
# See also 'test-harness-vpath-rewrite.sh' and 'test-trs-basic.sh'.
am__set_TESTS_bases = \
bases='$(TEST_LOGS)'; \
bases=`for i in $$bases; do echo $$i; done | sed 's/\.log$$//'`; \
bases=`echo $$bases`
RECHECK_LOGS = $(TEST_LOGS)
AM_RECURSIVE_TARGETS = check recheck
TEST_SUITE_LOG = test-suite.log
TEST_EXTENSIONS = @EXEEXT@ .test
LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
LOG_COMPILE = $(LOG_COMPILER) $(AM_LOG_FLAGS) $(LOG_FLAGS)
am__set_b = \
case '$@' in \
*/*) \
case '$*' in \
*/*) b='$*';; \
*) b=`echo '$@' | sed 's/\.log$$//'`; \
esac;; \
*) \
b='$*';; \
esac
am__test_logs1 = $(TESTS:=.log)
am__test_logs2 = $(am__test_logs1:@EXEEXT@.log=.log)
TEST_LOGS = $(am__test_logs2:.test.log=.log)
TEST_LOG_DRIVER = $(SHELL) $(top_srcdir)/test-driver
TEST_LOG_COMPILE = $(TEST_LOG_COMPILER) $(AM_TEST_LOG_FLAGS) \
$(TEST_LOG_FLAGS)
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
AM_CXXFLAGS = @AM_CXXFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
ILMBASE_VERSION = @ILMBASE_VERSION@
ILMBASE_VERSION_API = @ILMBASE_VERSION_API@
ILMBASE_VERSION_MAJOR = @ILMBASE_VERSION_MAJOR@
ILMBASE_VERSION_MINOR = @ILMBASE_VERSION_MINOR@
ILMBASE_VERSION_PATCH = @ILMBASE_VERSION_PATCH@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIB_SUFFIX = @LIB_SUFFIX@
LIB_SUFFIX_DASH = @LIB_SUFFIX_DASH@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
acx_pthread_config = @acx_pthread_config@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
IexTest_SOURCES = main.cpp testBaseExc.cpp testBaseExc.h
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config
LDADD = -L$(top_builddir)/Iex -lIex
EXTRA_DIST = CMakeLists.txt
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .log .o .obj .test .test$(EXEEXT) .trs
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign IexTest/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign IexTest/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
clean-checkPROGRAMS:
@list='$(check_PROGRAMS)'; test -n "$$list" || exit 0; \
echo " rm -f" $$list; \
rm -f $$list || exit $$?; \
test -n "$(EXEEXT)" || exit 0; \
list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \
echo " rm -f" $$list; \
rm -f $$list
IexTest$(EXEEXT): $(IexTest_OBJECTS) $(IexTest_DEPENDENCIES) $(EXTRA_IexTest_DEPENDENCIES)
@rm -f IexTest$(EXEEXT)
$(AM_V_CXXLD)$(CXXLINK) $(IexTest_OBJECTS) $(IexTest_LDADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/main.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testBaseExc.Po@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
# Recover from deleted '.trs' file; this should ensure that
# "rm -f foo.log; make foo.trs" re-run 'foo.test', and re-create
# both 'foo.log' and 'foo.trs'. Break the recipe in two subshells
# to avoid problems with "make -n".
.log.trs:
rm -f $< $@
$(MAKE) $(AM_MAKEFLAGS) $<
# Leading 'am--fnord' is there to ensure the list of targets does not
# expand to empty, as could happen e.g. with make check TESTS=''.
am--fnord $(TEST_LOGS) $(TEST_LOGS:.log=.trs): $(am__force_recheck)
am--force-recheck:
@:
$(TEST_SUITE_LOG): $(TEST_LOGS)
@$(am__set_TESTS_bases); \
am__f_ok () { test -f "$$1" && test -r "$$1"; }; \
redo_bases=`for i in $$bases; do \
am__f_ok $$i.trs && am__f_ok $$i.log || echo $$i; \
done`; \
if test -n "$$redo_bases"; then \
redo_logs=`for i in $$redo_bases; do echo $$i.log; done`; \
redo_results=`for i in $$redo_bases; do echo $$i.trs; done`; \
if $(am__make_dryrun); then :; else \
rm -f $$redo_logs && rm -f $$redo_results || exit 1; \
fi; \
fi; \
if test -n "$$am__remaking_logs"; then \
echo "fatal: making $(TEST_SUITE_LOG): possible infinite" \
"recursion detected" >&2; \
else \
am__remaking_logs=yes $(MAKE) $(AM_MAKEFLAGS) $$redo_logs; \
fi; \
if $(am__make_dryrun); then :; else \
st=0; \
errmsg="fatal: making $(TEST_SUITE_LOG): failed to create"; \
for i in $$redo_bases; do \
test -f $$i.trs && test -r $$i.trs \
|| { echo "$$errmsg $$i.trs" >&2; st=1; }; \
test -f $$i.log && test -r $$i.log \
|| { echo "$$errmsg $$i.log" >&2; st=1; }; \
done; \
test $$st -eq 0 || exit 1; \
fi
@$(am__sh_e_setup); $(am__tty_colors); $(am__set_TESTS_bases); \
ws='[ ]'; \
results=`for b in $$bases; do echo $$b.trs; done`; \
test -n "$$results" || results=/dev/null; \
all=` grep "^$$ws*:test-result:" $$results | wc -l`; \
pass=` grep "^$$ws*:test-result:$$ws*PASS" $$results | wc -l`; \
fail=` grep "^$$ws*:test-result:$$ws*FAIL" $$results | wc -l`; \
skip=` grep "^$$ws*:test-result:$$ws*SKIP" $$results | wc -l`; \
xfail=`grep "^$$ws*:test-result:$$ws*XFAIL" $$results | wc -l`; \
xpass=`grep "^$$ws*:test-result:$$ws*XPASS" $$results | wc -l`; \
error=`grep "^$$ws*:test-result:$$ws*ERROR" $$results | wc -l`; \
if test `expr $$fail + $$xpass + $$error` -eq 0; then \
success=true; \
else \
success=false; \
fi; \
br='==================='; br=$$br$$br$$br$$br; \
result_count () \
{ \
if test x"$$1" = x"--maybe-color"; then \
maybe_colorize=yes; \
elif test x"$$1" = x"--no-color"; then \
maybe_colorize=no; \
else \
echo "$@: invalid 'result_count' usage" >&2; exit 4; \
fi; \
shift; \
desc=$$1 count=$$2; \
if test $$maybe_colorize = yes && test $$count -gt 0; then \
color_start=$$3 color_end=$$std; \
else \
color_start= color_end=; \
fi; \
echo "$${color_start}# $$desc $$count$${color_end}"; \
}; \
create_testsuite_report () \
{ \
result_count $$1 "TOTAL:" $$all "$$brg"; \
result_count $$1 "PASS: " $$pass "$$grn"; \
result_count $$1 "SKIP: " $$skip "$$blu"; \
result_count $$1 "XFAIL:" $$xfail "$$lgn"; \
result_count $$1 "FAIL: " $$fail "$$red"; \
result_count $$1 "XPASS:" $$xpass "$$red"; \
result_count $$1 "ERROR:" $$error "$$mgn"; \
}; \
{ \
echo "$(PACKAGE_STRING): $(subdir)/$(TEST_SUITE_LOG)" | \
$(am__rst_title); \
create_testsuite_report --no-color; \
echo; \
echo ".. contents:: :depth: 2"; \
echo; \
for b in $$bases; do echo $$b; done \
| $(am__create_global_log); \
} >$(TEST_SUITE_LOG).tmp || exit 1; \
mv $(TEST_SUITE_LOG).tmp $(TEST_SUITE_LOG); \
if $$success; then \
col="$$grn"; \
else \
col="$$red"; \
test x"$$VERBOSE" = x || cat $(TEST_SUITE_LOG); \
fi; \
echo "$${col}$$br$${std}"; \
echo "$${col}Testsuite summary for $(PACKAGE_STRING)$${std}"; \
echo "$${col}$$br$${std}"; \
create_testsuite_report --maybe-color; \
echo "$$col$$br$$std"; \
if $$success; then :; else \
echo "$${col}See $(subdir)/$(TEST_SUITE_LOG)$${std}"; \
if test -n "$(PACKAGE_BUGREPORT)"; then \
echo "$${col}Please report to $(PACKAGE_BUGREPORT)$${std}"; \
fi; \
echo "$$col$$br$$std"; \
fi; \
$$success || exit 1
check-TESTS:
@list='$(RECHECK_LOGS)'; test -z "$$list" || rm -f $$list
@list='$(RECHECK_LOGS:.log=.trs)'; test -z "$$list" || rm -f $$list
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
log_list=`for i in $$bases; do echo $$i.log; done`; \
trs_list=`for i in $$bases; do echo $$i.trs; done`; \
log_list=`echo $$log_list`; trs_list=`echo $$trs_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) TEST_LOGS="$$log_list"; \
exit $$?;
recheck: all $(check_PROGRAMS)
@test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
@set +e; $(am__set_TESTS_bases); \
bases=`for i in $$bases; do echo $$i; done \
| $(am__list_recheck_tests)` || exit 1; \
log_list=`for i in $$bases; do echo $$i.log; done`; \
log_list=`echo $$log_list`; \
$(MAKE) $(AM_MAKEFLAGS) $(TEST_SUITE_LOG) \
am__force_recheck=am--force-recheck \
TEST_LOGS="$$log_list"; \
exit $$?
IexTest.log: IexTest$(EXEEXT)
@p='IexTest$(EXEEXT)'; \
b='IexTest'; \
$(am__check_pre) $(LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_LOG_DRIVER_FLAGS) $(LOG_DRIVER_FLAGS) -- $(LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
.test.log:
@p='$<'; \
$(am__set_b); \
$(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
--log-file $$b.log --trs-file $$b.trs \
$(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
"$$tst" $(AM_TESTS_FD_REDIRECT)
@am__EXEEXT_TRUE@.test$(EXEEXT).log:
@am__EXEEXT_TRUE@ @p='$<'; \
@am__EXEEXT_TRUE@ $(am__set_b); \
@am__EXEEXT_TRUE@ $(am__check_pre) $(TEST_LOG_DRIVER) --test-name "$$f" \
@am__EXEEXT_TRUE@ --log-file $$b.log --trs-file $$b.trs \
@am__EXEEXT_TRUE@ $(am__common_driver_flags) $(AM_TEST_LOG_DRIVER_FLAGS) $(TEST_LOG_DRIVER_FLAGS) -- $(TEST_LOG_COMPILE) \
@am__EXEEXT_TRUE@ "$$tst" $(AM_TESTS_FD_REDIRECT)
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
$(MAKE) $(AM_MAKEFLAGS) $(check_PROGRAMS)
$(MAKE) $(AM_MAKEFLAGS) check-TESTS
check: check-am
all-am: Makefile
installdirs:
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
-test -z "$(TEST_LOGS)" || rm -f $(TEST_LOGS)
-test -z "$(TEST_LOGS:.log=.trs)" || rm -f $(TEST_LOGS:.log=.trs)
-test -z "$(TEST_SUITE_LOG)" || rm -f $(TEST_SUITE_LOG)
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-checkPROGRAMS clean-generic clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am:
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am:
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am:
.MAKE: check-am install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-TESTS check-am clean \
clean-checkPROGRAMS clean-generic clean-libtool cscopelist-am \
ctags ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
recheck tags tags-am uninstall uninstall-am
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

48
IexTest/main.cpp Normal file
View File

@ -0,0 +1,48 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#include <testBaseExc.h>
#include <string.h>
#define TEST(x) if (argc < 2 || !strcmp (argv[1], #x)) x();
int
main (int argc, char *argv[])
{
TEST (testBaseExc);
return 0;
}

210
IexTest/testBaseExc.cpp Normal file
View File

@ -0,0 +1,210 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#include <testBaseExc.h>
#include <Iex.h>
#include <iostream>
#include <stdexcept>
#include <assert.h>
namespace {
void
throwArgExc ()
{
throw IEX_INTERNAL_NAMESPACE::ArgExc ("ArgExc");
}
void
throwLogicError ()
{
throw std::logic_error("logic_error");
}
void
throwInt ()
{
throw 3;
}
void
throwNested()
{
try
{
throwArgExc();
}
catch (const IEX_INTERNAL_NAMESPACE::ArgExc &)
{
try
{
throwInt();
}
catch (...)
{
}
throw;
}
}
void
test1 ()
{
std::cout << "1" << std::endl;
try
{
throwArgExc();
}
catch (const IEX_INTERNAL_NAMESPACE::ArgExc &)
{
return;
}
catch (std::exception &)
{
assert (false);
}
catch (...)
{
assert (false);
}
assert (false);
}
void
test2 ()
{
std::cout << "2" << std::endl;
try
{
throwLogicError();
}
catch (const IEX_INTERNAL_NAMESPACE::ArgExc &)
{
assert (false);
}
catch (std::exception &)
{
return;
}
catch (...)
{
assert (false);
}
assert (false);
}
void
test3 ()
{
std::cout << "3" << std::endl;
try
{
throwArgExc();
}
catch (std::exception &)
{
return;
}
catch (...)
{
assert (false);
}
assert (false);
}
void
test4 ()
{
std::cout << "4" << std::endl;
try
{
throwInt();
}
catch (const IEX_INTERNAL_NAMESPACE::ArgExc &)
{
assert (false);
}
catch (std::exception &)
{
assert (false);
}
catch (...)
{
return;
}
assert (false);
}
void
test5()
{
std::cout << "5" << std::endl;
try
{
throwNested();
}
catch (const IEX_INTERNAL_NAMESPACE::ArgExc &e)
{
assert (std::string(e.what()) == "ArgExc");
}
}
} // namespace
void
testBaseExc()
{
std::cout << "See if throw and catch work:" << std::endl;
test1();
test2();
test3();
test4();
test5();
std::cout << "ok\n" << std::endl;
}

38
IexTest/testBaseExc.h Normal file
View File

@ -0,0 +1,38 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
void testBaseExc();

11
IlmBase.pc.in Normal file
View File

@ -0,0 +1,11 @@
prefix=@prefix@
exec_prefix=@exec_prefix@
libdir=@libdir@
includedir=@includedir@
OpenEXR_includedir=@includedir@/OpenEXR
Name: IlmBase
Description: Base math and exception libraries
Version: @ILMBASE_VERSION@
Libs: -L${libdir} -lImath -lHalf -lIex -lIexMath -lIlmThread @PTHREAD_LIBS@
Cflags: @PTHREAD_CFLAGS@ -I${OpenEXR_includedir}

83
IlmThread/CMakeLists.txt Normal file
View File

@ -0,0 +1,83 @@
# yue.nicholas@gmail.com
SET( ILMTHREAD_LIBRARY_SOURCES
IlmThread.cpp
IlmThreadMutex.cpp
IlmThreadMutexPosix.cpp
IlmThreadPool.cpp
IlmThreadPosix.cpp
IlmThreadSemaphore.cpp
IlmThreadSemaphorePosixCompat.cpp
IlmThreadSemaphorePosix.cpp
)
IF (WIN32)
SET( ILMTHREAD_LIBRARY_SOURCES ${ILMTHREAD_LIBRARY_SOURCES}
IlmThreadMutexWin32.cpp
IlmThreadSemaphoreWin32.cpp
IlmThreadWin32.cpp
)
ENDIF()
SET (ILMBASE_LIB_TARGETS "")
IF ( OPENEXR_BUILD_SHARED )
LIST ( APPEND ILMBASE_LIB_TARGETS IlmThread )
ADD_LIBRARY ( IlmThread SHARED ${ILMTHREAD_LIBRARY_SOURCES} )
TARGET_COMPILE_DEFINITIONS ( IlmThread PRIVATE ILMTHREAD_EXPORTS )
IF (WIN32)
TARGET_COMPILE_DEFINITIONS ( IlmThread PUBLIC OPENEXR_DLL )
ENDIF ()
TARGET_LINK_LIBRARIES( IlmThread
PUBLIC IlmBase::Iex )
SET_TARGET_PROPERTIES ( IlmThread
PROPERTIES
VERSION ${OPENEXR_VERSION}
SOVERSION ${OPENEXR_SOVERSION}
OUTPUT_NAME "IlmThread${ILMBASE_LIBSUFFIX}"
)
ENDIF ()
IF (BUILD_ILMBASE_STATIC)
LIST ( APPEND ILMBASE_LIB_TARGETS IlmThread_static )
ADD_LIBRARY ( IlmThread_static STATIC ${ILMTHREAD_LIBRARY_SOURCES} )
SET_TARGET_PROPERTIES ( IlmThread_static
PROPERTIES
VERSION ${ILMBASE_VERSION_MAJOR}.${ILMBASE_VERSION_MINOR}.${ILMBASE_VERSION_PATCH}
OUTPUT_NAME "IlmThread${ILMBASE_LIBSUFFIX}_s"
)
ENDIF ()
IF (OPENEXR_BUILD_SHARED OR BUILD_ILMBASE_STATIC)
INSTALL ( TARGETS ${ILMBASE_LIB_TARGETS}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION ${RUNTIME_DIR}
)
ENDIF ()
INSTALL (
FILES
IlmThreadPool.h
IlmThread.h
IlmThreadSemaphore.h
IlmThreadMutex.h
IlmThreadNamespace.h
IlmThreadExport.h
IlmThreadForward.h
DESTINATION
include/OpenEXR
)
if (OPENEXR_BUILD_SHARED)
add_library(IlmBase::IlmThread ALIAS IlmThread)
endif()
if (BUILD_ILMBASE_STATIC)
add_library(IlmBase::IlmThread_static ALIAS IlmThread_static)
endif()

116
IlmThread/IlmThread.cpp Normal file
View File

@ -0,0 +1,116 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Thread -- this file contains two implementations of thread:
// - dummy implementation for platforms that do not support threading
// when OPENEXR_FORCE_CXX03 is on
// - c++11 and newer version
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#include "IlmThread.h"
#include "Iex.h"
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
#ifndef ILMBASE_FORCE_CXX03
//-----------------------------------------------------------------------------
// C++11 and newer implementation
//-----------------------------------------------------------------------------
bool
supportsThreads ()
{
return true;
}
Thread::Thread ()
{
// empty
}
Thread::~Thread ()
{
// hopefully the thread has basically exited and we are just
// cleaning up, because run is a virtual function, so the v-table
// has already been partly destroyed...
if ( _thread.joinable () )
_thread.join ();
}
void
Thread::start ()
{
_thread = std::thread (&Thread::run, this);
}
#else
# if !defined (_WIN32) &&!(_WIN64) && !(HAVE_PTHREAD)
//-----------------------------------------------------------------------------
// OPENEXR_FORCE_CXX03 with no windows / pthread support
//-----------------------------------------------------------------------------
bool
supportsThreads ()
{
return false;
}
Thread::Thread ()
{
throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
}
Thread::~Thread ()
{
throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
}
void
Thread::start ()
{
throw IEX_NAMESPACE::NoImplExc ("Threads not supported on this platform.");
}
# endif
#endif
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT

153
IlmThread/IlmThread.h Normal file
View File

@ -0,0 +1,153 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_ILM_THREAD_H
#define INCLUDED_ILM_THREAD_H
//-----------------------------------------------------------------------------
//
// class Thread
//
// Class Thread is a portable interface to a system-dependent thread
// primitive. In order to make a thread actually do something useful,
// you must derive a subclass from class Thread and implement the
// run() function. If the operating system supports threading then
// the run() function will be executed int a new thread.
//
// The actual creation of the thread is done by the start() routine
// which then calls the run() function. In general the start()
// routine should be called from the constructor of the derived class.
//
// The base-class thread destructor will join/destroy the thread.
//
// IMPORTANT: Due to the mechanisms that encapsulate the low-level
// threading primitives in a C++ class there is a race condition
// with code resembling the following:
//
// {
// WorkerThread myThread;
// } // myThread goes out of scope, is destroyed
// // and the thread is joined
//
// The race is between the parent thread joining the child thread
// in the destructor of myThread, and the run() function in the
// child thread. If the destructor gets executed first then run()
// will be called with an invalid "this" pointer.
//
// This issue can be fixed by using a Semaphore to keep track of
// whether the run() function has already been called. You can
// include a Semaphore member variable within your derived class
// which you post() on in the run() function, and wait() on in the
// destructor before the thread is joined. Alternatively you could
// do something like this:
//
// Semaphore runStarted;
//
// void WorkerThread::run ()
// {
// runStarted.post()
// // do some work
// ...
// }
//
// {
// WorkerThread myThread;
// runStarted.wait (); // ensure that we have started
// // the run function
// } // myThread goes out of scope, is destroyed
// // and the thread is joined
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#include "IlmThreadExport.h"
#include "IlmThreadNamespace.h"
#ifdef ILMBASE_FORCE_CXX03
# if defined _WIN32 || defined _WIN64
# ifdef NOMINMAX
# undef NOMINMAX
# endif
# define NOMINMAX
# include <windows.h>
# include <process.h>
# elif HAVE_PTHREAD
# include <pthread.h>
# endif
#else
# include <thread>
#endif
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Query function to determine if the current platform supports
// threads AND this library was compiled with threading enabled.
//
ILMTHREAD_EXPORT bool supportsThreads ();
class Thread
{
public:
ILMTHREAD_EXPORT Thread ();
ILMTHREAD_EXPORT virtual ~Thread ();
ILMTHREAD_EXPORT void start ();
ILMTHREAD_EXPORT virtual void run () = 0;
private:
#ifdef ILMBASE_FORCE_CXX03
# if defined _WIN32 || defined _WIN64
HANDLE _thread;
# elif HAVE_PTHREAD
pthread_t _thread;
# endif
void operator = (const Thread& t); // not implemented
Thread (const Thread& t); // not implemented
#else
std::thread _thread;
Thread &operator= (const Thread& t) = delete;
Thread (const Thread& t) = delete;
#endif
};
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_ILM_THREAD_H

View File

@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#if defined(OPENEXR_DLL)
#if defined(ILMTHREAD_EXPORTS)
#define ILMTHREAD_EXPORT __declspec(dllexport)
#define ILMTHREAD_EXPORT_CONST extern __declspec(dllexport)
#else
#define ILMTHREAD_EXPORT __declspec(dllimport)
#define ILMTHREAD_EXPORT_CONST extern __declspec(dllimport)
#endif
#else
#define ILMTHREAD_EXPORT
#define ILMTHREAD_EXPORT_CONST extern const
#endif

View File

@ -0,0 +1,60 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_ILMTHREADFORWARD_H
#define INCLUDED_ILMTHREADFORWARD_H
#include "IlmThreadNamespace.h"
#ifndef ILMBASE_FORCE_CXX03
namespace std { class mutex; }
#endif
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
class Thread;
#ifdef ILMBASE_FORCE_CXX03
class Mutex;
#else
using Mutex = std::mutex;
#endif
class Lock;
class ThreadPool;
class Task;
class TaskGroup;
class Semaphore;
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_ILMTHREADFORWARD_H

View File

@ -0,0 +1,60 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Mutex, class Lock -- dummy implementation
// for platforms that do not support threading
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#ifdef ILMBASE_FORCE_CXX03
# if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
# include "IlmThreadMutex.h"
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
Mutex::Mutex () {}
Mutex::~Mutex () {}
void Mutex::lock () const {}
void Mutex::unlock () const {}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
# endif
#endif

180
IlmThread/IlmThreadMutex.h Normal file
View File

@ -0,0 +1,180 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_ILM_THREAD_MUTEX_H
#define INCLUDED_ILM_THREAD_MUTEX_H
//-----------------------------------------------------------------------------
//
// class Mutex, class Lock
//
// Class Mutex is a wrapper for a system-dependent mutual exclusion
// mechanism. Actual locking and unlocking of a Mutex object must
// be performed using an instance of a Lock (defined below).
//
// Class lock provides safe locking and unlocking of mutexes even in
// the presence of C++ exceptions. Constructing a Lock object locks
// the mutex; destroying the Lock unlocks the mutex.
//
// Lock objects are not themselves thread-safe. You should never
// share a Lock object among multiple threads.
//
// Typical usage:
//
// Mutex mtx; // Create a Mutex object that is visible
// //to multiple threads
//
// ... // create some threads
//
// // Then, within each thread, construct a critical section like so:
//
// {
// Lock lock (mtx); // Lock constructor locks the mutex
// ... // do some computation on shared data
// } // leaving the block unlocks the mutex
//
//-----------------------------------------------------------------------------
#include "IlmThreadExport.h"
#include "IlmBaseConfig.h"
#include "IlmThreadNamespace.h"
#ifdef ILMBASE_FORCE_CXX03
# if defined _WIN32 || defined _WIN64
# ifdef NOMINMAX
# undef NOMINMAX
# endif
# define NOMINMAX
# include <windows.h>
# elif HAVE_PTHREAD
# include <pthread.h>
# endif
#else
# include <mutex>
#endif
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
// in c++11, this can just be
//
// using Mutex = std::mutex;
// unfortunately we can't use std::unique_lock as a replacement for Lock since
// they have different API.
//
// if we decide to break the API, we can just
//
// using Lock = std::lock_guard<std::mutex>;
// or
// using Lock = std::unique_lock<std::mutex>;
//
// (or eliminate the type completely and have people use the std library)
#ifdef ILMBASE_FORCE_CXX03
class Lock;
class ILMTHREAD_EXPORT Mutex
{
public:
Mutex ();
virtual ~Mutex ();
private:
void lock () const;
void unlock () const;
#if defined _WIN32 || defined _WIN64
mutable CRITICAL_SECTION _mutex;
#elif HAVE_PTHREAD
mutable pthread_mutex_t _mutex;
#endif
void operator = (const Mutex& M); // not implemented
Mutex (const Mutex& M); // not implemented
friend class Lock;
};
#else
using Mutex = std::mutex;
#endif
class ILMTHREAD_EXPORT Lock
{
public:
Lock (const Mutex& m, bool autoLock = true):
_mutex (const_cast<Mutex &>(m)), _locked (false)
{
if (autoLock)
{
_mutex.lock();
_locked = true;
}
}
~Lock ()
{
if (_locked)
_mutex.unlock();
}
void acquire ()
{
_mutex.lock();
_locked = true;
}
void release ()
{
_mutex.unlock();
_locked = false;
}
bool locked ()
{
return _locked;
}
private:
Mutex & _mutex;
bool _locked;
};
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_ILM_THREAD_MUTEX_H

View File

@ -0,0 +1,87 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Mutex -- implementation for
// platforms that support Posix threads
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#ifdef ILMBASE_FORCE_CXX03
# if HAVE_PTHREAD
# include "IlmThreadMutex.h"
# include "Iex.h"
# include <assert.h>
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
Mutex::Mutex ()
{
if (int error = ::pthread_mutex_init (&_mutex, 0))
IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot initialize mutex (%T).", error);
}
Mutex::~Mutex ()
{
int error = ::pthread_mutex_destroy (&_mutex);
assert (error == 0);
}
void
Mutex::lock () const
{
if (int error = ::pthread_mutex_lock (&_mutex))
IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot lock mutex (%T).", error);
}
void
Mutex::unlock () const
{
if (int error = ::pthread_mutex_unlock (&_mutex))
IEX_INTERNAL_NAMESPACE::throwErrnoExc ("Cannot unlock mutex (%T).", error);
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
# endif
#endif

View File

@ -0,0 +1,78 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Mutex -- implementation for Windows
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#ifdef ILMBASE_FORCE_CXX03
# include "IlmThreadMutex.h"
# include "Iex.h"
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
Mutex::Mutex ()
{
::InitializeCriticalSection (&_mutex);
}
Mutex::~Mutex ()
{
::DeleteCriticalSection (&_mutex);
}
void
Mutex::lock () const
{
::EnterCriticalSection (&_mutex);
}
void
Mutex::unlock () const
{
::LeaveCriticalSection (&_mutex);
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
#endif

View File

@ -0,0 +1,114 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_ILMTHREADNAMESPACE_H
#define INCLUDED_ILMTHREADNAMESPACE_H
//
// The purpose of this file is to make it possible to specify an
// ILMTHREAD_INTERNAL_NAMESPACE as a preprocessor definition and have all of
// the IlmThread symbols defined within that namespace rather than the
// standard IlmThread namespace. Those symbols are made available to client
// code through the ILMTHREAD_NAMESPACE in addition to the
// ILMTHREAD_INTERNAL_NAMESPACE.
//
// To ensure source code compatibility, the ILMTHREAD_NAMESPACE defaults to
// IlmThread and then "using namespace ILMTHREAD_INTERNAL_NAMESPACE;" brings
// all of the declarations from the ILMTHREAD_INTERNAL_NAMESPACE into the
// ILMTHREAD_NAMESPACE. This means that client code can continue to use
// syntax like IlmThread::Thread, but at link time it will resolve to a
// mangled symbol based on the ILMTHREAD_INTERNAL_NAMESPACE.
//
// As an example, if one needed to build against a newer version of IlmThread
// and have it run alongside an older version in the same application, it is
// now possible to use an internal namespace to prevent collisions between
// the older versions of IlmThread symbols and the newer ones. To do this,
// the following could be defined at build time:
//
// ILMTHREAD_INTERNAL_NAMESPACE = IlmThread_v2
//
// This means that declarations inside IlmThread headers look like this
// (after the preprocessor has done its work):
//
// namespace IlmThread_v2 {
// ...
// class declarations
// ...
// }
//
// namespace IlmThread {
// using namespace IlmThread_v2;
// }
//
//
// Open Source version of this file pulls in the IlmBaseConfig.h file
// for the configure time options.
//
#include "IlmBaseConfig.h"
#ifndef ILMTHREAD_NAMESPACE
#define ILMTHREAD_NAMESPACE IlmThread
#endif
#ifndef ILMTHREAD_INTERNAL_NAMESPACE
#define ILMTHREAD_INTERNAL_NAMESPACE ILMTHREAD_NAMESPACE
#endif
//
// We need to be sure that we import the internal namespace into the public one.
// To do this, we use the small bit of code below which initially defines
// ILMTHREAD_INTERNAL_NAMESPACE (so it can be referenced) and then defines
// ILMTHREAD_NAMESPACE and pulls the internal symbols into the public
// namespace.
//
namespace ILMTHREAD_INTERNAL_NAMESPACE {}
namespace ILMTHREAD_NAMESPACE {
using namespace ILMTHREAD_INTERNAL_NAMESPACE;
}
//
// There are identical pairs of HEADER/SOURCE ENTER/EXIT macros so that
// future extension to the namespace mechanism is possible without changing
// project source code.
//
#define ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER namespace ILMTHREAD_INTERNAL_NAMESPACE {
#define ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT }
#define ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER namespace ILMTHREAD_INTERNAL_NAMESPACE {
#define ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT }
#endif // INCLUDED_ILMTHREADNAMESPACE_H

851
IlmThread/IlmThreadPool.cpp Normal file
View File

@ -0,0 +1,851 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Task, class ThreadPool, class TaskGroup
//
//-----------------------------------------------------------------------------
#include "IlmThread.h"
#include "IlmThreadMutex.h"
#include "IlmThreadSemaphore.h"
#include "IlmThreadPool.h"
#include "Iex.h"
#include <vector>
#ifndef ILMBASE_FORCE_CXX03
# include <memory>
# include <atomic>
# include <thread>
#endif
using namespace std;
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
#if defined(__GNU_LIBRARY__) && ( __GLIBC__ < 2 || ( __GLIBC__ == 2 && __GLIBC_MINOR__ < 21 ) )
# define ENABLE_SEM_DTOR_WORKAROUND
#endif
struct TaskGroup::Data
{
Data ();
~Data ();
void addTask () ;
void removeTask ();
#ifndef ILMBASE_FORCE_CXX03
std::atomic<int> numPending;
#else
int numPending; // number of pending tasks to still execute
#endif
Semaphore isEmpty; // used to signal that the taskgroup is empty
#if defined(ENABLE_SEM_DTOR_WORKAROUND) || defined(ILMBASE_FORCE_CXX03)
// this mutex is also used to lock numPending in the legacy c++ mode...
Mutex dtorMutex; // used to work around the glibc bug:
// http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
#endif
};
struct ThreadPool::Data
{
typedef ThreadPoolProvider *TPPointer;
Data ();
~Data();
struct SafeProvider
{
SafeProvider (Data *d, ThreadPoolProvider *p) : _data( d ), _ptr( p )
{
}
~SafeProvider()
{
if ( _data )
_data->coalesceProviderUse();
}
SafeProvider (const SafeProvider &o)
: _data( o._data ), _ptr( o._ptr )
{
if ( _data )
_data->bumpProviderUse();
}
SafeProvider &operator= (const SafeProvider &o)
{
if ( this != &o )
{
if ( o._data )
o._data->bumpProviderUse();
if ( _data )
_data->coalesceProviderUse();
_data = o._data;
_ptr = o._ptr;
}
return *this;
}
#ifndef ILMBASE_FORCE_CXX03
SafeProvider( SafeProvider &&o )
: _data( o._data ), _ptr( o._ptr )
{
o._data = nullptr;
}
SafeProvider &operator=( SafeProvider &&o )
{
std::swap( _data, o._data );
std::swap( _ptr, o._ptr );
return *this;
}
#endif
inline ThreadPoolProvider *get () const
{
return _ptr;
}
ThreadPoolProvider *operator-> () const
{
return get();
}
Data *_data;
ThreadPoolProvider *_ptr;
};
// NB: In C++20, there is full support for atomic shared_ptr, but that is not
// yet in use or finalized. Once stabilized, add appropriate usage here
inline SafeProvider getProvider ();
inline void coalesceProviderUse ();
inline void bumpProviderUse ();
inline void setProvider (ThreadPoolProvider *p);
#ifdef ILMBASE_FORCE_CXX03
Semaphore provSem;
Mutex provMutex;
int provUsers;
ThreadPoolProvider *provider;
ThreadPoolProvider *oldprovider;
#else
std::atomic<ThreadPoolProvider *> provider;
std::atomic<int> provUsers;
#endif
};
namespace {
class DefaultWorkerThread;
struct DefaultWorkData
{
Semaphore taskSemaphore; // threads wait on this for ready tasks
mutable Mutex taskMutex; // mutual exclusion for the tasks list
vector<Task*> tasks; // the list of tasks to execute
Semaphore threadSemaphore; // signaled when a thread starts executing
mutable Mutex threadMutex; // mutual exclusion for threads list
vector<DefaultWorkerThread*> threads; // the list of all threads
#ifdef ILMBASE_FORCE_CXX03
bool stopping; // flag indicating whether to stop threads
mutable Mutex stopMutex; // mutual exclusion for stopping flag
#else
std::atomic<bool> hasThreads;
std::atomic<bool> stopping;
#endif
inline bool stopped () const
{
#ifdef ILMBASE_FORCE_CXX03
Lock lock (stopMutex);
return stopping;
#else
return stopping.load( std::memory_order_relaxed );
#endif
}
inline void stop ()
{
#ifdef ILMBASE_FORCE_CXX03
Lock lock (stopMutex);
#endif
stopping = true;
}
};
//
// class WorkerThread
//
class DefaultWorkerThread: public Thread
{
public:
DefaultWorkerThread (DefaultWorkData* data);
virtual void run ();
private:
DefaultWorkData * _data;
};
DefaultWorkerThread::DefaultWorkerThread (DefaultWorkData* data):
_data (data)
{
start();
}
void
DefaultWorkerThread::run ()
{
//
// Signal that the thread has started executing
//
_data->threadSemaphore.post();
while (true)
{
//
// Wait for a task to become available
//
_data->taskSemaphore.wait();
{
Lock taskLock (_data->taskMutex);
//
// If there is a task pending, pop off the next task in the FIFO
//
if (!_data->tasks.empty())
{
Task* task = _data->tasks.back();
_data->tasks.pop_back();
taskLock.release();
TaskGroup* taskGroup = task->group();
task->execute();
delete task;
taskGroup->_data->removeTask ();
}
else if (_data->stopped())
{
break;
}
}
}
}
//
// class DefaultThreadPoolProvider
//
class DefaultThreadPoolProvider : public ThreadPoolProvider
{
public:
DefaultThreadPoolProvider(int count);
virtual ~DefaultThreadPoolProvider();
virtual int numThreads() const;
virtual void setNumThreads(int count);
virtual void addTask(Task *task);
virtual void finish();
private:
DefaultWorkData _data;
};
DefaultThreadPoolProvider::DefaultThreadPoolProvider (int count)
{
setNumThreads(count);
}
DefaultThreadPoolProvider::~DefaultThreadPoolProvider ()
{
finish();
}
int
DefaultThreadPoolProvider::numThreads () const
{
Lock lock (_data.threadMutex);
return static_cast<int> (_data.threads.size());
}
void
DefaultThreadPoolProvider::setNumThreads (int count)
{
//
// Lock access to thread list and size
//
Lock lock (_data.threadMutex);
size_t desired = static_cast<size_t>(count);
if (desired > _data.threads.size())
{
//
// Add more threads
//
while (_data.threads.size() < desired)
_data.threads.push_back (new DefaultWorkerThread (&_data));
}
else if ((size_t)count < _data.threads.size())
{
//
// Wait until all existing threads are finished processing,
// then delete all threads.
//
finish ();
//
// Add in new threads
//
while (_data.threads.size() < desired)
_data.threads.push_back (new DefaultWorkerThread (&_data));
}
#ifndef ILMBASE_FORCE_CXX03
_data.hasThreads = !(_data.threads.empty());
#endif
}
void
DefaultThreadPoolProvider::addTask (Task *task)
{
//
// Lock the threads, needed to access numThreads
//
#ifdef ILMBASE_FORCE_CXX03
bool doPush;
{
Lock lock (_data.threadMutex);
doPush = !_data.threads.empty();
}
#else
bool doPush = _data.hasThreads.load( std::memory_order_relaxed );
#endif
if ( doPush )
{
//
// Get exclusive access to the tasks queue
//
{
Lock taskLock (_data.taskMutex);
//
// Push the new task into the FIFO
//
_data.tasks.push_back (task);
}
//
// Signal that we have a new task to process
//
_data.taskSemaphore.post ();
}
else
{
// this path shouldn't normally happen since we have the
// NullThreadPoolProvider, but just in case...
task->execute ();
task->group()->_data->removeTask ();
delete task;
}
}
void
DefaultThreadPoolProvider::finish ()
{
_data.stop();
//
// Signal enough times to allow all threads to stop.
//
// Wait until all threads have started their run functions.
// If we do not wait before we destroy the threads then it's
// possible that the threads have not yet called their run
// functions.
// If this happens then the run function will be called off
// of an invalid object and we will crash, most likely with
// an error like: "pure virtual method called"
//
size_t curT = _data.threads.size();
for (size_t i = 0; i != curT; ++i)
{
_data.taskSemaphore.post();
_data.threadSemaphore.wait();
}
//
// Join all the threads
//
for (size_t i = 0; i != curT; ++i)
delete _data.threads[i];
Lock lock1 (_data.taskMutex);
#ifdef ILMBASE_FORCE_CXX03
Lock lock2 (_data.stopMutex);
#endif
_data.threads.clear();
_data.tasks.clear();
_data.stopping = false;
}
class NullThreadPoolProvider : public ThreadPoolProvider
{
virtual ~NullThreadPoolProvider() {}
virtual int numThreads () const { return 0; }
virtual void setNumThreads (int count)
{
}
virtual void addTask (Task *t)
{
t->execute ();
t->group()->_data->removeTask ();
delete t;
}
virtual void finish () {}
};
} //namespace
//
// struct TaskGroup::Data
//
TaskGroup::Data::Data (): isEmpty (1), numPending (0)
{
// empty
}
TaskGroup::Data::~Data ()
{
//
// A TaskGroup acts like an "inverted" semaphore: if the count
// is above 0 then waiting on the taskgroup will block. This
// destructor waits until the taskgroup is empty before returning.
//
isEmpty.wait ();
#ifdef ENABLE_SEM_DTOR_WORKAROUND
// Update: this was fixed in v. 2.2.21, so this ifdef checks for that
//
// Alas, given the current bug in glibc we need a secondary
// syncronisation primitive here to account for the fact that
// destructing the isEmpty Semaphore in this thread can cause
// an error for a separate thread that is issuing the post() call.
// We are entitled to destruct the semaphore at this point, however,
// that post() call attempts to access data out of the associated
// memory *after* it has woken the waiting threads, including this one,
// potentially leading to invalid memory reads.
// http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
Lock lock (dtorMutex);
#endif
}
void
TaskGroup::Data::addTask ()
{
//
// in c++11, we use an atomic to protect numPending to avoid the
// extra lock but for c++98, to add the ability for custom thread
// pool we add the lock here
//
#if ILMBASE_FORCE_CXX03
Lock lock (dtorMutex);
#endif
if (numPending++ == 0)
isEmpty.wait ();
}
void
TaskGroup::Data::removeTask ()
{
// Alas, given the current bug in glibc we need a secondary
// syncronisation primitive here to account for the fact that
// destructing the isEmpty Semaphore in a separate thread can
// cause an error. Issuing the post call here the current libc
// implementation attempts to access memory *after* it has woken
// waiting threads.
// Since other threads are entitled to delete the semaphore the
// access to the memory location can be invalid.
// http://sources.redhat.com/bugzilla/show_bug.cgi?id=12674
// Update: this bug has been fixed, but how do we know which
// glibc version we're in?
// Further update:
//
// we could remove this if it is a new enough glibc, however
// we've changed the API to enable a custom override of a
// thread pool. In order to provide safe access to the numPending,
// we need the lock anyway, except for c++11 or newer
#ifdef ILMBASE_FORCE_CXX03
Lock lock (dtorMutex);
if (--numPending == 0)
isEmpty.post ();
#else
if (--numPending == 0)
{
#ifdef ENABLE_SEM_DTOR_WORKAROUND
Lock lock (dtorMutex);
#endif
isEmpty.post ();
}
#endif
}
//
// struct ThreadPool::Data
//
ThreadPool::Data::Data ():
provUsers (0), provider (NULL)
#ifdef ILMBASE_FORCE_CXX03
, oldprovider (NULL)
#else
#endif
{
// empty
}
ThreadPool::Data::~Data()
{
#ifdef ILMBASE_FORCE_CXX03
provider->finish();
#else
ThreadPoolProvider *p = provider.load( std::memory_order_relaxed );
p->finish();
#endif
}
inline ThreadPool::Data::SafeProvider
ThreadPool::Data::getProvider ()
{
#ifdef ILMBASE_FORCE_CXX03
Lock provLock( provMutex );
++provUsers;
return SafeProvider( this, provider );
#else
provUsers.fetch_add( 1, std::memory_order_relaxed );
return SafeProvider( this, provider.load( std::memory_order_relaxed ) );
#endif
}
inline void
ThreadPool::Data::coalesceProviderUse ()
{
#ifdef ILMBASE_FORCE_CXX03
Lock provLock( provMutex );
--provUsers;
if ( provUsers == 0 )
{
if ( oldprovider )
provSem.post();
}
#else
int ov = provUsers.fetch_sub( 1, std::memory_order_relaxed );
// ov is the previous value, so one means that now it might be 0
if ( ov == 1 )
{
}
#endif
}
inline void
ThreadPool::Data::bumpProviderUse ()
{
#ifdef ILMBASE_FORCE_CXX03
Lock lock (provMutex);
++provUsers;
#else
provUsers.fetch_add( 1, std::memory_order_relaxed );
#endif
}
inline void
ThreadPool::Data::setProvider (ThreadPoolProvider *p)
{
#ifdef ILMBASE_FORCE_CXX03
Lock provLock( provMutex );
if ( oldprovider )
throw IEX_INTERNAL_NAMESPACE::ArgExc ("Attempt to set the thread pool provider while"
" another thread is currently setting the provider.");
oldprovider = provider;
provider = p;
while ( provUsers > 0 )
{
provLock.release();
provSem.wait();
provLock.acquire();
}
if ( oldprovider )
{
oldprovider->finish();
delete oldprovider;
oldprovider = NULL;
}
#else
ThreadPoolProvider *old = provider.load( std::memory_order_relaxed );
do
{
if ( ! provider.compare_exchange_weak( old, p, std::memory_order_release, std::memory_order_relaxed ) )
continue;
} while ( false );
// wait for any other users to finish prior to deleting, given
// that these are just mostly to query the thread count or push a
// task to the queue (so fast), just spin...
//
// (well, and normally, people don't do this mid stream anyway, so
// this will be 0 99.999% of the time, but just to be safe)
//
while ( provUsers.load( std::memory_order_relaxed ) > 0 )
std::this_thread::yield();
if ( old )
{
old->finish();
delete old;
}
// NB: the shared_ptr mechanism is safer and means we don't have
// to have the provUsers counter since the shared_ptr keeps that
// for us. However, gcc 4.8/9 compilers which many people are
// still using even though it is 2018 forgot to add the shared_ptr
// functions... once that compiler is fully deprecated, switch to
// using the below, change provider to a std::shared_ptr and remove
// provUsers...
//
// std::shared_ptr<ThreadPoolProvider> newp( p );
// std::shared_ptr<ThreadPoolProvider> curp = std::atomic_load_explicit( &provider, std::memory_order_relaxed );
// do
// {
// if ( ! std::atomic_compare_exchange_weak_explicit( &provider, &curp, newp, std::memory_order_release, std::memory_order_relaxed ) )
// continue;
// } while ( false );
// if ( curp )
// curp->finish();
#endif
}
//
// class Task
//
Task::Task (TaskGroup* g): _group(g)
{
if ( g )
g->_data->addTask ();
}
Task::~Task()
{
// empty
}
TaskGroup*
Task::group ()
{
return _group;
}
TaskGroup::TaskGroup ():
_data (new Data())
{
// empty
}
TaskGroup::~TaskGroup ()
{
delete _data;
}
void
TaskGroup::finishOneTask ()
{
_data->removeTask ();
}
//
// class ThreadPoolProvider
//
ThreadPoolProvider::ThreadPoolProvider()
{
}
ThreadPoolProvider::~ThreadPoolProvider()
{
}
//
// class ThreadPool
//
ThreadPool::ThreadPool (unsigned nthreads):
_data (new Data)
{
if ( nthreads == 0 )
_data->setProvider( new NullThreadPoolProvider );
else
_data->setProvider( new DefaultThreadPoolProvider( int(nthreads) ) );
}
ThreadPool::~ThreadPool ()
{
delete _data;
}
int
ThreadPool::numThreads () const
{
return _data->getProvider ()->numThreads ();
}
void
ThreadPool::setNumThreads (int count)
{
if (count < 0)
throw IEX_INTERNAL_NAMESPACE::ArgExc ("Attempt to set the number of threads "
"in a thread pool to a negative value.");
bool doReset = false;
{
Data::SafeProvider sp = _data->getProvider ();
int curT = sp->numThreads ();
if ( curT == count )
return;
if ( curT == 0 )
{
NullThreadPoolProvider *npp = dynamic_cast<NullThreadPoolProvider *>( sp.get() );
if ( npp )
doReset = true;
}
else if ( count == 0 )
{
DefaultThreadPoolProvider *dpp = dynamic_cast<DefaultThreadPoolProvider *>( sp.get() );
if ( dpp )
doReset = true;
}
if ( ! doReset )
sp->setNumThreads( count );
}
if ( doReset )
{
if ( count == 0 )
_data->setProvider( new NullThreadPoolProvider );
else
_data->setProvider( new DefaultThreadPoolProvider( count ) );
}
}
void
ThreadPool::setThreadProvider (ThreadPoolProvider *provider)
{
_data->setProvider (provider);
}
void
ThreadPool::addTask (Task* task)
{
_data->getProvider ()->addTask (task);
}
ThreadPool&
ThreadPool::globalThreadPool ()
{
//
// The global thread pool
//
static ThreadPool gThreadPool (0);
return gThreadPool;
}
void
ThreadPool::addGlobalTask (Task* task)
{
globalThreadPool().addTask (task);
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT

214
IlmThread/IlmThreadPool.h Normal file
View File

@ -0,0 +1,214 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_ILM_THREAD_POOL_H
#define INCLUDED_ILM_THREAD_POOL_H
//-----------------------------------------------------------------------------
//
// class Task, class ThreadPool, class TaskGroup
//
// Class ThreadPool manages a set of worker threads and accepts
// tasks for processing. Tasks added to the thread pool are
// executed concurrently by the worker threads.
//
// Class Task provides an abstract interface for a task which
// a ThreadPool works on. Derived classes need to implement the
// execute() function which performs the actual task.
//
// Class TaskGroup allows synchronization on the completion of a set
// of tasks. Every task that is added to a ThreadPool belongs to a
// single TaskGroup. The destructor of the TaskGroup waits for all
// tasks in the group to finish.
//
// Note: if you plan to use the ThreadPool interface in your own
// applications note that the implementation of the ThreadPool calls
// operator delete on tasks as they complete. If you define a custom
// operator new for your tasks, for instance to use a custom heap,
// then you must also write an appropriate operator delete.
//
//-----------------------------------------------------------------------------
#include "IlmThreadNamespace.h"
#include "IlmThreadExport.h"
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
class TaskGroup;
class Task;
//-------------------------------------------------------
// ThreadPoolProvider -- this is a pure virtual interface
// enabling custom overloading of the threads used and how
// the implementation of the processing of tasks
// is implemented
//-------------------------------------------------------
class ILMTHREAD_EXPORT ThreadPoolProvider
{
public:
ThreadPoolProvider();
virtual ~ThreadPoolProvider();
// as in ThreadPool below
virtual int numThreads () const = 0;
// as in ThreadPool below
virtual void setNumThreads (int count) = 0;
// as in ThreadPool below
virtual void addTask (Task* task) = 0;
// Ensure that all tasks in this set are finished
// and threads shutdown
virtual void finish () = 0;
// Make the provider non-copyable
#if __cplusplus >= 201103L
ThreadPoolProvider (const ThreadPoolProvider &) = delete;
ThreadPoolProvider &operator= (const ThreadPoolProvider &) = delete;
ThreadPoolProvider (ThreadPoolProvider &&) = delete;
ThreadPoolProvider &operator= (ThreadPoolProvider &&) = delete;
#else
private:
ThreadPoolProvider (const ThreadPoolProvider &);
ThreadPoolProvider &operator= (const ThreadPoolProvider &);
#endif
};
class ILMTHREAD_EXPORT ThreadPool
{
public:
//-------------------------------------------------------
// Constructor -- creates numThreads worker threads which
// wait until a task is available,
// using a default ThreadPoolProvider
//-------------------------------------------------------
ThreadPool (unsigned numThreads = 0);
//-----------------------------------------------------------
// Destructor -- waits for all tasks to complete, joins all
// the threads to the calling thread, and then destroys them.
//-----------------------------------------------------------
virtual ~ThreadPool ();
//--------------------------------------------------------
// Query and set the number of worker threads in the pool.
//
// Warning: never call setNumThreads from within a worker
// thread as this will almost certainly cause a deadlock
// or crash.
//--------------------------------------------------------
int numThreads () const;
void setNumThreads (int count);
//--------------------------------------------------------
// Set the thread provider for the pool.
//
// The ThreadPool takes ownership of the ThreadPoolProvider
// and will call delete on it when it is finished or when
// it is changed
//
// Warning: never call setThreadProvider from within a worker
// thread as this will almost certainly cause a deadlock
// or crash.
//--------------------------------------------------------
void setThreadProvider (ThreadPoolProvider *provider);
//------------------------------------------------------------
// Add a task for processing. The ThreadPool can handle any
// number of tasks regardless of the number of worker threads.
// The tasks are first added onto a queue, and are executed
// by threads as they become available, in FIFO order.
//------------------------------------------------------------
void addTask (Task* task);
//-------------------------------------------
// Access functions for the global threadpool
//-------------------------------------------
static ThreadPool& globalThreadPool ();
static void addGlobalTask (Task* task);
struct Data;
protected:
Data * _data;
};
class ILMTHREAD_EXPORT Task
{
public:
Task (TaskGroup* g);
virtual ~Task ();
virtual void execute () = 0;
TaskGroup * group();
protected:
TaskGroup * _group;
};
class ILMTHREAD_EXPORT TaskGroup
{
public:
TaskGroup();
~TaskGroup();
// marks one task as finished
// should be used by the thread pool provider to notify
// as it finishes tasks
void finishOneTask ();
struct Data;
Data* const _data;
};
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_ILM_THREAD_POOL_H

View File

@ -0,0 +1,100 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Thread -- implementation for
// platforms that support Posix threads
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if HAVE_PTHREAD
#ifdef ILMBASE_FORCE_CXX03
#include "IlmThread.h"
#include "Iex.h"
#include <assert.h>
extern "C"
{
typedef void * (* Start) (void *);
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
bool
supportsThreads ()
{
return true;
}
namespace {
void
threadLoop (void * t)
{
return (reinterpret_cast<Thread*>(t))->run();
}
} // namespace
Thread::Thread ()
{
// empty
}
Thread::~Thread ()
{
int error = ::pthread_join (_thread, 0);
assert (error == 0);
}
void
Thread::start ()
{
if (int error = ::pthread_create (&_thread, 0, Start (threadLoop), this))
IEX_NAMESPACE::throwErrnoExc ("Cannot create new thread (%T).", error);
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
#endif
#endif

View File

@ -0,0 +1,60 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- dummy implementation for
// for platforms that do not support threading
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if !defined (_WIN32) && !(_WIN64) && !(HAVE_PTHREAD)
#include "IlmThreadSemaphore.h"
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
Semaphore::Semaphore (unsigned int value) {}
Semaphore::~Semaphore () {}
void Semaphore::wait () {}
bool Semaphore::tryWait () {return true;}
void Semaphore::post () {}
int Semaphore::value () const {return 0;}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
#endif

View File

@ -0,0 +1,127 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_ILM_THREAD_SEMAPHORE_H
#define INCLUDED_ILM_THREAD_SEMAPHORE_H
//-----------------------------------------------------------------------------
//
// class Semaphore -- a wrapper class for
// system-dependent counting semaphores
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#include "IlmThreadExport.h"
#include "IlmThreadNamespace.h"
#if defined _WIN32 || defined _WIN64
# ifdef NOMINMAX
# undef NOMINMAX
# endif
# define NOMINMAX
# include <windows.h>
#elif HAVE_POSIX_SEMAPHORES
# include <semaphore.h>
#else
# ifdef ILMBASE_FORCE_CXX03
# if HAVE_PTHREAD
# include <pthread.h>
# endif
# else
# include <mutex>
# include <condition_variable>
# endif
#endif
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_ENTER
class ILMTHREAD_EXPORT Semaphore
{
public:
Semaphore (unsigned int value = 0);
virtual ~Semaphore();
void wait();
bool tryWait();
void post();
int value() const;
private:
#if defined _WIN32 || defined _WIN64
mutable HANDLE _semaphore;
#elif defined(HAVE_POSIX_SEMAPHORES)
mutable sem_t _semaphore;
#else
//
// If the platform has Posix threads but no semapohores,
// then we implement them ourselves using condition variables
//
struct sema_t
{
unsigned int count;
unsigned long numWaiting;
# if ILMBASE_FORCE_CXX03
# if HAVE_PTHREAD
pthread_mutex_t mutex;
pthread_cond_t nonZero;
# else
# error unhandled legacy setup
# endif
# else
std::mutex mutex;
std::condition_variable nonZero;
# endif
};
mutable sema_t _semaphore;
#endif
void operator = (const Semaphore& s); // not implemented
Semaphore (const Semaphore& s); // not implemented
};
ILMTHREAD_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_ILM_THREAD_SEMAPHORE_H

View File

@ -0,0 +1,106 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- implementation for platforms
// that support Posix threads and Posix semaphores
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if HAVE_PTHREAD && HAVE_POSIX_SEMAPHORES
#include "IlmThreadSemaphore.h"
#include "Iex.h"
#include <assert.h>
#include <errno.h>
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
Semaphore::Semaphore (unsigned int value)
{
if (::sem_init (&_semaphore, 0, value))
IEX_NAMESPACE::throwErrnoExc ("Cannot initialize semaphore (%T).");
}
Semaphore::~Semaphore ()
{
int error = ::sem_destroy (&_semaphore);
assert (error == 0);
}
void
Semaphore::wait ()
{
while( ::sem_wait( &_semaphore ) == -1 && errno == EINTR )
{
}
}
bool
Semaphore::tryWait ()
{
return sem_trywait (&_semaphore) == 0;
}
void
Semaphore::post ()
{
if (::sem_post (&_semaphore))
IEX_NAMESPACE::throwErrnoExc ("Post operation on semaphore failed (%T).");
}
int
Semaphore::value () const
{
int value;
if (::sem_getvalue (&_semaphore, &value))
IEX_NAMESPACE::throwErrnoExc ("Cannot read semaphore value (%T).");
return value;
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
#endif

View File

@ -0,0 +1,227 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- implementation for for platforms that do
// support Posix threads but do not support Posix semaphores,
// for example, OS X
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#if (!HAVE_POSIX_SEMAPHORES) && !defined (_WIN32) && ! defined (_WIN64)
#include "IlmThreadSemaphore.h"
#include "Iex.h"
#include <assert.h>
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
#if ILMBASE_FORCE_CXX03 && HAVE_PTHREAD
Semaphore::Semaphore (unsigned int value)
{
if (int error = ::pthread_mutex_init (&_semaphore.mutex, 0))
IEX_NAMESPACE::throwErrnoExc ("Cannot initialize mutex (%T).", error);
if (int error = ::pthread_cond_init (&_semaphore.nonZero, 0))
IEX_NAMESPACE::throwErrnoExc ("Cannot initialize condition variable (%T).",
error);
_semaphore.count = value;
_semaphore.numWaiting = 0;
}
Semaphore::~Semaphore ()
{
int error = ::pthread_cond_destroy (&_semaphore.nonZero);
assert (error == 0);
error = ::pthread_mutex_destroy (&_semaphore.mutex);
assert (error == 0);
}
void
Semaphore::wait ()
{
::pthread_mutex_lock (&_semaphore.mutex);
_semaphore.numWaiting++;
while (_semaphore.count == 0)
{
if (int error = ::pthread_cond_wait (&_semaphore.nonZero,
&_semaphore.mutex))
{
::pthread_mutex_unlock (&_semaphore.mutex);
IEX_NAMESPACE::throwErrnoExc ("Cannot wait on condition variable (%T).",
error);
}
}
_semaphore.numWaiting--;
_semaphore.count--;
::pthread_mutex_unlock (&_semaphore.mutex);
}
bool
Semaphore::tryWait ()
{
::pthread_mutex_lock (&_semaphore.mutex);
if (_semaphore.count == 0)
{
::pthread_mutex_unlock (&_semaphore.mutex);
return false;
}
else
{
_semaphore.count--;
::pthread_mutex_unlock (&_semaphore.mutex);
return true;
}
}
void
Semaphore::post ()
{
::pthread_mutex_lock (&_semaphore.mutex);
if (_semaphore.numWaiting > 0)
{
int error;
if (_semaphore.numWaiting > 1 && _semaphore.count > 1)
{
error = ::pthread_cond_broadcast (&_semaphore.nonZero);
}
else
{
error = ::pthread_cond_signal (&_semaphore.nonZero);
}
if (error)
{
::pthread_mutex_unlock (&_semaphore.mutex);
IEX_NAMESPACE::throwErrnoExc ("Cannot signal condition variable (%T).",
error);
}
}
_semaphore.count++;
::pthread_mutex_unlock (&_semaphore.mutex);
}
int
Semaphore::value () const
{
::pthread_mutex_lock (&_semaphore.mutex);
int value = _semaphore.count;
::pthread_mutex_unlock (&_semaphore.mutex);
return value;
}
#else
Semaphore::Semaphore (unsigned int value)
{
_semaphore.count = value;
_semaphore.numWaiting = 0;
}
Semaphore::~Semaphore ()
{
}
void
Semaphore::wait ()
{
std::unique_lock<std::mutex> lk(_semaphore.mutex);
_semaphore.numWaiting++;
while (_semaphore.count == 0)
_semaphore.nonZero.wait (lk);
_semaphore.numWaiting--;
_semaphore.count--;
}
bool
Semaphore::tryWait ()
{
std::lock_guard<std::mutex> lk(_semaphore.mutex);
if (_semaphore.count == 0)
return false;
_semaphore.count--;
return true;
}
void
Semaphore::post ()
{
std::lock_guard<std::mutex> lk(_semaphore.mutex);
_semaphore.count++;
if (_semaphore.numWaiting > 0)
{
if (_semaphore.count > 1)
_semaphore.nonZero.notify_all();
else
_semaphore.nonZero.notify_one();
}
}
int
Semaphore::value () const
{
std::lock_guard<std::mutex> lk(_semaphore.mutex);
return _semaphore.count;
}
#endif
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
#endif

View File

@ -0,0 +1,147 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Semaphore -- implementation for Windows
//
//-----------------------------------------------------------------------------
#include "IlmThreadSemaphore.h"
#include "Iex.h"
#include <string>
#include <assert.h>
#include <iostream>
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
using namespace IEX_NAMESPACE;
namespace {
std::string
errorString ()
{
LPSTR messageBuffer;
DWORD bufferLength;
std::string message;
//
// Call FormatMessage() to allow for message
// text to be acquired from the system.
//
if (bufferLength = FormatMessageA (FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_IGNORE_INSERTS |
FORMAT_MESSAGE_FROM_SYSTEM,
0,
GetLastError (),
MAKELANGID (LANG_NEUTRAL,
SUBLANG_DEFAULT),
(LPSTR) &messageBuffer,
0,
NULL))
{
message = messageBuffer;
LocalFree (messageBuffer);
}
return message;
}
} // namespace
Semaphore::Semaphore (unsigned int value)
{
if ((_semaphore = ::CreateSemaphore (0, value, 0x7fffffff, 0)) == 0)
{
THROW (LogicExc, "Could not create semaphore "
"(" << errorString() << ").");
}
}
Semaphore::~Semaphore()
{
bool ok = ::CloseHandle (_semaphore) != FALSE;
assert (ok);
}
void
Semaphore::wait()
{
if (::WaitForSingleObject (_semaphore, INFINITE) != WAIT_OBJECT_0)
{
THROW (LogicExc, "Could not wait on semaphore "
"(" << errorString() << ").");
}
}
bool
Semaphore::tryWait()
{
return ::WaitForSingleObject (_semaphore, 0) == WAIT_OBJECT_0;
}
void
Semaphore::post()
{
if (!::ReleaseSemaphore (_semaphore, 1, 0))
{
THROW (LogicExc, "Could not post on semaphore "
"(" << errorString() << ").");
}
}
int
Semaphore::value() const
{
LONG v = -1;
if (!::ReleaseSemaphore (_semaphore, 0, &v) || v < 0)
{
THROW (LogicExc, "Could not get value of semaphore "
"(" << errorString () << ").");
}
return v;
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT

View File

@ -0,0 +1,101 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2005-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//-----------------------------------------------------------------------------
//
// class Thread -- implementation for Windows
//
//-----------------------------------------------------------------------------
#include "IlmBaseConfig.h"
#ifdef ILMBASE_FORCE_CXX03
#include "IlmThread.h"
#include "Iex.h"
#include <iostream>
#include <assert.h>
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_ENTER
bool
supportsThreads ()
{
return true;
}
namespace {
unsigned __stdcall
threadLoop (void * t)
{
reinterpret_cast<Thread*>(t)->run();
_endthreadex (0);
return 0;
}
} // namespace
Thread::Thread ()
{
// empty
}
Thread::~Thread ()
{
DWORD status = ::WaitForSingleObject (_thread, INFINITE);
assert (status == WAIT_OBJECT_0);
bool ok = ::CloseHandle (_thread) != FALSE;
assert (ok);
}
void
Thread::start ()
{
unsigned id;
_thread = (HANDLE)::_beginthreadex (0, 0, &threadLoop, this, 0, &id);
if (_thread == 0)
IEX_NAMESPACE::throwErrnoExc ("Cannot create new thread (%T).");
}
ILMTHREAD_INTERNAL_NAMESPACE_SOURCE_EXIT
#endif

31
IlmThread/Makefile.am Normal file
View File

@ -0,0 +1,31 @@
## Process this file with automake to produce Makefile.in
lib_LTLIBRARIES = libIlmThread.la
libIlmThread_la_SOURCES = IlmThreadPool.h IlmThread.h \
IlmThreadSemaphore.h IlmThreadMutex.h \
IlmThreadPool.cpp IlmThread.cpp \
IlmThreadSemaphore.cpp IlmThreadMutex.cpp \
IlmThreadPosix.cpp IlmThreadSemaphorePosix.cpp \
IlmThreadSemaphorePosixCompat.cpp \
IlmThreadMutexPosix.cpp
libIlmThread_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ -no-undefined
if LIB_SUFFIX_EXISTS
libIlmThread_la_LDFLAGS += -release @LIB_SUFFIX@
endif
libIlmThread_la_LIBADD = ../Iex/libIex.la
libIlmThreadincludedir = $(includedir)/OpenEXR
libIlmThreadinclude_HEADERS = IlmThreadPool.h IlmThread.h \
IlmThreadSemaphore.h IlmThreadMutex.h \
IlmThreadNamespace.h IlmThreadForward.h \
IlmThreadExport.h
noinst_HEADERS =
EXTRA_DIST = $(noinst_HEADERS) IlmThreadMutexWin32.cpp IlmThreadSemaphoreWin32.cpp \
IlmThreadWin32.cpp CMakeLists.txt
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config

729
IlmThread/Makefile.in Normal file
View File

@ -0,0 +1,729 @@
# Makefile.in generated by automake 1.13.4 from Makefile.am.
# @configure_input@
# Copyright (C) 1994-2013 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
# PARTICULAR PURPOSE.
@SET_MAKE@
VPATH = @srcdir@
am__is_gnu_make = test -n '$(MAKEFILE_LIST)' && test -n '$(MAKELEVEL)'
am__make_running_with_option = \
case $${target_option-} in \
?) ;; \
*) echo "am__make_running_with_option: internal error: invalid" \
"target option '$${target_option-}' specified" >&2; \
exit 1;; \
esac; \
has_opt=no; \
sane_makeflags=$$MAKEFLAGS; \
if $(am__is_gnu_make); then \
sane_makeflags=$$MFLAGS; \
else \
case $$MAKEFLAGS in \
*\\[\ \ ]*) \
bs=\\; \
sane_makeflags=`printf '%s\n' "$$MAKEFLAGS" \
| sed "s/$$bs$$bs[$$bs $$bs ]*//g"`;; \
esac; \
fi; \
skip_next=no; \
strip_trailopt () \
{ \
flg=`printf '%s\n' "$$flg" | sed "s/$$1.*$$//"`; \
}; \
for flg in $$sane_makeflags; do \
test $$skip_next = yes && { skip_next=no; continue; }; \
case $$flg in \
*=*|--*) continue;; \
-*I) strip_trailopt 'I'; skip_next=yes;; \
-*I?*) strip_trailopt 'I';; \
-*O) strip_trailopt 'O'; skip_next=yes;; \
-*O?*) strip_trailopt 'O';; \
-*l) strip_trailopt 'l'; skip_next=yes;; \
-*l?*) strip_trailopt 'l';; \
-[dEDm]) skip_next=yes;; \
-[JT]) skip_next=yes;; \
esac; \
case $$flg in \
*$$target_option*) has_opt=yes; break;; \
esac; \
done; \
test $$has_opt = yes
am__make_dryrun = (target_option=n; $(am__make_running_with_option))
am__make_keepgoing = (target_option=k; $(am__make_running_with_option))
pkgdatadir = $(datadir)/@PACKAGE@
pkgincludedir = $(includedir)/@PACKAGE@
pkglibdir = $(libdir)/@PACKAGE@
pkglibexecdir = $(libexecdir)/@PACKAGE@
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
install_sh_DATA = $(install_sh) -c -m 644
install_sh_PROGRAM = $(install_sh) -c
install_sh_SCRIPT = $(install_sh) -c
INSTALL_HEADER = $(INSTALL_DATA)
transform = $(program_transform_name)
NORMAL_INSTALL = :
PRE_INSTALL = :
POST_INSTALL = :
NORMAL_UNINSTALL = :
PRE_UNINSTALL = :
POST_UNINSTALL = :
build_triplet = @build@
host_triplet = @host@
@LIB_SUFFIX_EXISTS_TRUE@am__append_1 = -release @LIB_SUFFIX@
subdir = IlmThread
DIST_COMMON = $(srcdir)/Makefile.in $(srcdir)/Makefile.am \
$(top_srcdir)/depcomp $(libIlmThreadinclude_HEADERS) \
$(noinst_HEADERS)
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
am__aclocal_m4_deps = $(top_srcdir)/m4/ax_cxx_compile_stdcxx.m4 \
$(top_srcdir)/m4/threads.m4 $(top_srcdir)/configure.ac
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
$(ACLOCAL_M4)
mkinstalldirs = $(install_sh) -d
CONFIG_HEADER = $(top_builddir)/config/IlmBaseConfig.h
CONFIG_CLEAN_FILES =
CONFIG_CLEAN_VPATH_FILES =
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
am__vpath_adj = case $$p in \
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
*) f=$$p;; \
esac;
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
am__install_max = 40
am__nobase_strip_setup = \
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
am__nobase_strip = \
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
am__nobase_list = $(am__nobase_strip_setup); \
for p in $$list; do echo "$$p $$p"; done | \
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
if (++n[$$2] == $(am__install_max)) \
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
END { for (dir in files) print dir, files[dir] }'
am__base_list = \
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
am__uninstall_files_from_dir = { \
test -z "$$files" \
|| { test ! -d "$$dir" && test ! -f "$$dir" && test ! -r "$$dir"; } \
|| { echo " ( cd '$$dir' && rm -f" $$files ")"; \
$(am__cd) "$$dir" && rm -f $$files; }; \
}
am__installdirs = "$(DESTDIR)$(libdir)" \
"$(DESTDIR)$(libIlmThreadincludedir)"
LTLIBRARIES = $(lib_LTLIBRARIES)
libIlmThread_la_DEPENDENCIES = ../Iex/libIex.la
am_libIlmThread_la_OBJECTS = IlmThreadPool.lo IlmThread.lo \
IlmThreadSemaphore.lo IlmThreadMutex.lo IlmThreadPosix.lo \
IlmThreadSemaphorePosix.lo IlmThreadSemaphorePosixCompat.lo \
IlmThreadMutexPosix.lo
libIlmThread_la_OBJECTS = $(am_libIlmThread_la_OBJECTS)
AM_V_lt = $(am__v_lt_@AM_V@)
am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@)
am__v_lt_0 = --silent
am__v_lt_1 =
libIlmThread_la_LINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX \
$(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=link $(CXXLD) \
$(AM_CXXFLAGS) $(CXXFLAGS) $(libIlmThread_la_LDFLAGS) \
$(LDFLAGS) -o $@
AM_V_P = $(am__v_P_@AM_V@)
am__v_P_ = $(am__v_P_@AM_DEFAULT_V@)
am__v_P_0 = false
am__v_P_1 = :
AM_V_GEN = $(am__v_GEN_@AM_V@)
am__v_GEN_ = $(am__v_GEN_@AM_DEFAULT_V@)
am__v_GEN_0 = @echo " GEN " $@;
am__v_GEN_1 =
AM_V_at = $(am__v_at_@AM_V@)
am__v_at_ = $(am__v_at_@AM_DEFAULT_V@)
am__v_at_0 = @
am__v_at_1 =
DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/config
depcomp = $(SHELL) $(top_srcdir)/depcomp
am__depfiles_maybe = depfiles
am__mv = mv -f
CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS)
LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CXXFLAGS) $(CXXFLAGS)
AM_V_CXX = $(am__v_CXX_@AM_V@)
am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@)
am__v_CXX_0 = @echo " CXX " $@;
am__v_CXX_1 =
CXXLD = $(CXX)
CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \
$(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CXXLD = $(am__v_CXXLD_@AM_V@)
am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@)
am__v_CXXLD_0 = @echo " CXXLD " $@;
am__v_CXXLD_1 =
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \
$(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \
$(AM_CFLAGS) $(CFLAGS)
AM_V_CC = $(am__v_CC_@AM_V@)
am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@)
am__v_CC_0 = @echo " CC " $@;
am__v_CC_1 =
CCLD = $(CC)
LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \
$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
$(AM_LDFLAGS) $(LDFLAGS) -o $@
AM_V_CCLD = $(am__v_CCLD_@AM_V@)
am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@)
am__v_CCLD_0 = @echo " CCLD " $@;
am__v_CCLD_1 =
SOURCES = $(libIlmThread_la_SOURCES)
DIST_SOURCES = $(libIlmThread_la_SOURCES)
am__can_run_installinfo = \
case $$AM_UPDATE_INFO_DIR in \
n|no|NO) false;; \
*) (install-info --version) >/dev/null 2>&1;; \
esac
HEADERS = $(libIlmThreadinclude_HEADERS) $(noinst_HEADERS)
am__tagged_files = $(HEADERS) $(SOURCES) $(TAGS_FILES) $(LISP)
# Read a list of newline-separated strings from the standard input,
# and print each of them once, without duplicates. Input order is
# *not* preserved.
am__uniquify_input = $(AWK) '\
BEGIN { nonempty = 0; } \
{ items[$$0] = 1; nonempty = 1; } \
END { if (nonempty) { for (i in items) print i; }; } \
'
# Make sure the list of sources is unique. This is necessary because,
# e.g., the same source file might be shared among _SOURCES variables
# for different programs/libraries.
am__define_uniq_tagged_files = \
list='$(am__tagged_files)'; \
unique=`for i in $$list; do \
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
done | $(am__uniquify_input)`
ETAGS = etags
CTAGS = ctags
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
ACLOCAL = @ACLOCAL@
AMTAR = @AMTAR@
AM_CFLAGS = @AM_CFLAGS@
AM_CXXFLAGS = @AM_CXXFLAGS@
AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@
AR = @AR@
AUTOCONF = @AUTOCONF@
AUTOHEADER = @AUTOHEADER@
AUTOMAKE = @AUTOMAKE@
AWK = @AWK@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CXXDEPMODE = @CXXDEPMODE@
CXXFLAGS = @CXXFLAGS@
CYGPATH_W = @CYGPATH_W@
DEFS = @DEFS@
DEPDIR = @DEPDIR@
DLLTOOL = @DLLTOOL@
DSYMUTIL = @DSYMUTIL@
DUMPBIN = @DUMPBIN@
ECHO_C = @ECHO_C@
ECHO_N = @ECHO_N@
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
FGREP = @FGREP@
GREP = @GREP@
HAVE_CXX11 = @HAVE_CXX11@
HAVE_CXX14 = @HAVE_CXX14@
HAVE_CXX17 = @HAVE_CXX17@
HAVE_UCONTEXT_H = @HAVE_UCONTEXT_H@
ILMBASE_VERSION = @ILMBASE_VERSION@
ILMBASE_VERSION_API = @ILMBASE_VERSION_API@
ILMBASE_VERSION_MAJOR = @ILMBASE_VERSION_MAJOR@
ILMBASE_VERSION_MINOR = @ILMBASE_VERSION_MINOR@
ILMBASE_VERSION_PATCH = @ILMBASE_VERSION_PATCH@
INSTALL = @INSTALL@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
LD = @LD@
LDFLAGS = @LDFLAGS@
LIBOBJS = @LIBOBJS@
LIBS = @LIBS@
LIBTOOL = @LIBTOOL@
LIBTOOL_VERSION = @LIBTOOL_VERSION@
LIB_SUFFIX = @LIB_SUFFIX@
LIB_SUFFIX_DASH = @LIB_SUFFIX_DASH@
LIPO = @LIPO@
LN_S = @LN_S@
LTLIBOBJS = @LTLIBOBJS@
MAINT = @MAINT@
MAKEINFO = @MAKEINFO@
MANIFEST_TOOL = @MANIFEST_TOOL@
MKDIR_P = @MKDIR_P@
NM = @NM@
NMEDIT = @NMEDIT@
OBJDUMP = @OBJDUMP@
OBJEXT = @OBJEXT@
OTOOL = @OTOOL@
OTOOL64 = @OTOOL64@
PACKAGE = @PACKAGE@
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_STRING = @PACKAGE_STRING@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
PACKAGE_URL = @PACKAGE_URL@
PACKAGE_VERSION = @PACKAGE_VERSION@
PATH_SEPARATOR = @PATH_SEPARATOR@
PTHREAD_CC = @PTHREAD_CC@
PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
PTHREAD_LIBS = @PTHREAD_LIBS@
RANLIB = @RANLIB@
SED = @SED@
SET_MAKE = @SET_MAKE@
SHELL = @SHELL@
STRIP = @STRIP@
VERSION = @VERSION@
abs_builddir = @abs_builddir@
abs_srcdir = @abs_srcdir@
abs_top_builddir = @abs_top_builddir@
abs_top_srcdir = @abs_top_srcdir@
ac_ct_AR = @ac_ct_AR@
ac_ct_CC = @ac_ct_CC@
ac_ct_CXX = @ac_ct_CXX@
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
acx_pthread_config = @acx_pthread_config@
am__include = @am__include@
am__leading_dot = @am__leading_dot@
am__quote = @am__quote@
am__tar = @am__tar@
am__untar = @am__untar@
bindir = @bindir@
build = @build@
build_alias = @build_alias@
build_cpu = @build_cpu@
build_os = @build_os@
build_vendor = @build_vendor@
builddir = @builddir@
datadir = @datadir@
datarootdir = @datarootdir@
docdir = @docdir@
dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
srcdir = @srcdir@
sysconfdir = @sysconfdir@
target_alias = @target_alias@
top_build_prefix = @top_build_prefix@
top_builddir = @top_builddir@
top_srcdir = @top_srcdir@
lib_LTLIBRARIES = libIlmThread.la
libIlmThread_la_SOURCES = IlmThreadPool.h IlmThread.h \
IlmThreadSemaphore.h IlmThreadMutex.h \
IlmThreadPool.cpp IlmThread.cpp \
IlmThreadSemaphore.cpp IlmThreadMutex.cpp \
IlmThreadPosix.cpp IlmThreadSemaphorePosix.cpp \
IlmThreadSemaphorePosixCompat.cpp \
IlmThreadMutexPosix.cpp
libIlmThread_la_LDFLAGS = -version-info @LIBTOOL_VERSION@ \
-no-undefined $(am__append_1)
libIlmThread_la_LIBADD = ../Iex/libIex.la
libIlmThreadincludedir = $(includedir)/OpenEXR
libIlmThreadinclude_HEADERS = IlmThreadPool.h IlmThread.h \
IlmThreadSemaphore.h IlmThreadMutex.h \
IlmThreadNamespace.h IlmThreadForward.h \
IlmThreadExport.h
noinst_HEADERS =
EXTRA_DIST = $(noinst_HEADERS) IlmThreadMutexWin32.cpp IlmThreadSemaphoreWin32.cpp \
IlmThreadWin32.cpp CMakeLists.txt
INCLUDES = -I$(top_builddir) -I$(top_srcdir)/Iex -I$(top_srcdir)/config
all: all-am
.SUFFIXES:
.SUFFIXES: .cpp .lo .o .obj
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
@for dep in $?; do \
case '$(am__configure_deps)' in \
*$$dep*) \
( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \
&& { if test -f $@; then exit 0; else break; fi; }; \
exit 1;; \
esac; \
done; \
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign IlmThread/Makefile'; \
$(am__cd) $(top_srcdir) && \
$(AUTOMAKE) --foreign IlmThread/Makefile
.PRECIOUS: Makefile
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
@case '$?' in \
*config.status*) \
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \
*) \
echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \
cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \
esac;
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
$(am__aclocal_m4_deps):
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
@$(NORMAL_INSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
list2=; for p in $$list; do \
if test -f $$p; then \
list2="$$list2 $$p"; \
else :; fi; \
done; \
test -z "$$list2" || { \
echo " $(MKDIR_P) '$(DESTDIR)$(libdir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libdir)" || exit 1; \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
}
uninstall-libLTLIBRARIES:
@$(NORMAL_UNINSTALL)
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
for p in $$list; do \
$(am__strip_dir) \
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
done
clean-libLTLIBRARIES:
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
@list='$(lib_LTLIBRARIES)'; \
locs=`for p in $$list; do echo $$p; done | \
sed 's|^[^/]*$$|.|; s|/[^/]*$$||; s|$$|/so_locations|' | \
sort -u`; \
test -z "$$locs" || { \
echo rm -f $${locs}; \
rm -f $${locs}; \
}
libIlmThread.la: $(libIlmThread_la_OBJECTS) $(libIlmThread_la_DEPENDENCIES) $(EXTRA_libIlmThread_la_DEPENDENCIES)
$(AM_V_CXXLD)$(libIlmThread_la_LINK) -rpath $(libdir) $(libIlmThread_la_OBJECTS) $(libIlmThread_la_LIBADD) $(LIBS)
mostlyclean-compile:
-rm -f *.$(OBJEXT)
distclean-compile:
-rm -f *.tab.c
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThread.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThreadMutex.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThreadMutexPosix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThreadPool.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThreadPosix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThreadSemaphore.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThreadSemaphorePosix.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IlmThreadSemaphorePosixCompat.Plo@am__quote@
.cpp.o:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $<
.cpp.obj:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'`
.cpp.lo:
@am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
@am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $<
mostlyclean-libtool:
-rm -f *.lo
clean-libtool:
-rm -rf .libs _libs
install-libIlmThreadincludeHEADERS: $(libIlmThreadinclude_HEADERS)
@$(NORMAL_INSTALL)
@list='$(libIlmThreadinclude_HEADERS)'; test -n "$(libIlmThreadincludedir)" || list=; \
if test -n "$$list"; then \
echo " $(MKDIR_P) '$(DESTDIR)$(libIlmThreadincludedir)'"; \
$(MKDIR_P) "$(DESTDIR)$(libIlmThreadincludedir)" || exit 1; \
fi; \
for p in $$list; do \
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
echo "$$d$$p"; \
done | $(am__base_list) | \
while read files; do \
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(libIlmThreadincludedir)'"; \
$(INSTALL_HEADER) $$files "$(DESTDIR)$(libIlmThreadincludedir)" || exit $$?; \
done
uninstall-libIlmThreadincludeHEADERS:
@$(NORMAL_UNINSTALL)
@list='$(libIlmThreadinclude_HEADERS)'; test -n "$(libIlmThreadincludedir)" || list=; \
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
dir='$(DESTDIR)$(libIlmThreadincludedir)'; $(am__uninstall_files_from_dir)
ID: $(am__tagged_files)
$(am__define_uniq_tagged_files); mkid -fID $$unique
tags: tags-am
TAGS: tags
tags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
set x; \
here=`pwd`; \
$(am__define_uniq_tagged_files); \
shift; \
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
test -n "$$unique" || unique=$$empty_fix; \
if test $$# -gt 0; then \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
"$$@" $$unique; \
else \
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
$$unique; \
fi; \
fi
ctags: ctags-am
CTAGS: ctags
ctags-am: $(TAGS_DEPENDENCIES) $(am__tagged_files)
$(am__define_uniq_tagged_files); \
test -z "$(CTAGS_ARGS)$$unique" \
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
$$unique
GTAGS:
here=`$(am__cd) $(top_builddir) && pwd` \
&& $(am__cd) $(top_srcdir) \
&& gtags -i $(GTAGS_ARGS) "$$here"
cscopelist: cscopelist-am
cscopelist-am: $(am__tagged_files)
list='$(am__tagged_files)'; \
case "$(srcdir)" in \
[\\/]* | ?:[\\/]*) sdir="$(srcdir)" ;; \
*) sdir=$(subdir)/$(srcdir) ;; \
esac; \
for i in $$list; do \
if test -f "$$i"; then \
echo "$(subdir)/$$i"; \
else \
echo "$$sdir/$$i"; \
fi; \
done >> $(top_builddir)/cscope.files
distclean-tags:
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
distdir: $(DISTFILES)
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
list='$(DISTFILES)'; \
dist_files=`for file in $$list; do echo $$file; done | \
sed -e "s|^$$srcdirstrip/||;t" \
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
case $$dist_files in \
*/*) $(MKDIR_P) `echo "$$dist_files" | \
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
sort -u` ;; \
esac; \
for file in $$dist_files; do \
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
if test -d $$d/$$file; then \
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
if test -d "$(distdir)/$$file"; then \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
fi; \
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
else \
test -f "$(distdir)/$$file" \
|| cp -p $$d/$$file "$(distdir)/$$file" \
|| exit 1; \
fi; \
done
check-am: all-am
check: check-am
all-am: Makefile $(LTLIBRARIES) $(HEADERS)
installdirs:
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(libIlmThreadincludedir)"; do \
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
done
install: install-am
install-exec: install-exec-am
install-data: install-data-am
uninstall: uninstall-am
install-am: all-am
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
installcheck: installcheck-am
install-strip:
if test -z '$(STRIP)'; then \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
install; \
else \
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
"INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'" install; \
fi
mostlyclean-generic:
clean-generic:
distclean-generic:
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
maintainer-clean-generic:
@echo "This command is intended for maintainers to use"
@echo "it deletes files that may require special tools to rebuild."
clean: clean-am
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
mostlyclean-am
distclean: distclean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-tags
dvi: dvi-am
dvi-am:
html: html-am
html-am:
info: info-am
info-am:
install-data-am: install-libIlmThreadincludeHEADERS
install-dvi: install-dvi-am
install-dvi-am:
install-exec-am: install-libLTLIBRARIES
install-html: install-html-am
install-html-am:
install-info: install-info-am
install-info-am:
install-man:
install-pdf: install-pdf-am
install-pdf-am:
install-ps: install-ps-am
install-ps-am:
installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -rf ./$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
mostlyclean: mostlyclean-am
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
mostlyclean-libtool
pdf: pdf-am
pdf-am:
ps: ps-am
ps-am:
uninstall-am: uninstall-libIlmThreadincludeHEADERS \
uninstall-libLTLIBRARIES
.MAKE: install-am install-strip
.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \
clean-libLTLIBRARIES clean-libtool cscopelist-am ctags \
ctags-am distclean distclean-compile distclean-generic \
distclean-libtool distclean-tags distdir dvi dvi-am html \
html-am info info-am install install-am install-data \
install-data-am install-dvi install-dvi-am install-exec \
install-exec-am install-html install-html-am install-info \
install-info-am install-libIlmThreadincludeHEADERS \
install-libLTLIBRARIES install-man install-pdf install-pdf-am \
install-ps install-ps-am install-strip installcheck \
installcheck-am installdirs maintainer-clean \
maintainer-clean-generic mostlyclean mostlyclean-compile \
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
tags tags-am uninstall uninstall-am \
uninstall-libIlmThreadincludeHEADERS uninstall-libLTLIBRARIES
# Tell versions [3.59,3.63) of GNU make to not export all variables.
# Otherwise a system limit (for SysV at least) may be exceeded.
.NOEXPORT:

97
Imath/CMakeLists.txt Normal file
View File

@ -0,0 +1,97 @@
# yue.nicholas@gmail.com
SET (ILMBASE_LIB_TARGETS "")
SET ( IMATH_SOURCES
ImathRandom.cpp
ImathColorAlgo.cpp
ImathFun.cpp
ImathVec.cpp
ImathMatrixAlgo.cpp
)
IF ( OPENEXR_BUILD_SHARED )
LIST ( APPEND ILMBASE_LIB_TARGETS Imath )
ADD_LIBRARY ( Imath SHARED ${IMATH_SOURCES} )
TARGET_COMPILE_DEFINITIONS ( Imath PRIVATE IMATH_EXPORTS )
IF (WIN32)
TARGET_COMPILE_DEFINITIONS ( Imath PUBLIC OPENEXR_DLL )
ENDIF ()
TARGET_LINK_LIBRARIES(Imath PUBLIC IlmBase::Iex)
SET_TARGET_PROPERTIES ( Imath
PROPERTIES
VERSION ${OPENEXR_VERSION}
SOVERSION ${OPENEXR_SOVERSION}
OUTPUT_NAME "Imath${ILMBASE_LIBSUFFIX}"
)
ENDIF ()
IF (BUILD_ILMBASE_STATIC)
LIST ( APPEND ILMBASE_LIB_TARGETS Imath_static )
ADD_LIBRARY ( Imath_static STATIC ${IMATH_SOURCES} )
SET_TARGET_PROPERTIES ( Imath_static
PROPERTIES
VERSION ${ILMBASE_VERSION_MAJOR}.${ILMBASE_VERSION_MINOR}.${ILMBASE_VERSION_PATCH}
OUTPUT_NAME "Imath${ILMBASE_LIBSUFFIX}_s"
)
ENDIF ()
IF (OPENEXR_BUILD_SHARED OR BUILD_ILMBASE_STATIC)
INSTALL ( TARGETS ${ILMBASE_LIB_TARGETS}
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION ${RUNTIME_DIR}
)
ENDIF ()
INSTALL (
FILES
ImathBoxAlgo.h
ImathBox.h
ImathColorAlgo.h
ImathColor.h
ImathEuler.h
ImathExc.h
ImathExport.h
ImathForward.h
ImathFrame.h
ImathFrustum.h
ImathFrustumTest.h
ImathFun.h
ImathGL.h
ImathGLU.h
ImathHalfLimits.h
ImathInt64.h
ImathInterval.h
ImathLimits.h
ImathLineAlgo.h
ImathLine.h
ImathMath.h
ImathMatrixAlgo.h
ImathMatrix.h
ImathNamespace.h
ImathPlane.h
ImathPlatform.h
ImathQuat.h
ImathRandom.h
ImathRoots.h
ImathShear.h
ImathSphere.h
ImathVecAlgo.h
ImathVec.h
DESTINATION
include/OpenEXR
)
if (OPENEXR_BUILD_SHARED)
add_library(IlmBase::Imath ALIAS Imath)
endif()
if (BUILD_ILMBASE_STATIC)
add_library(IlmBase::Imath_static ALIAS Imath_static)
endif()

849
Imath/ImathBox.h Normal file
View File

@ -0,0 +1,849 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHBOX_H
#define INCLUDED_IMATHBOX_H
//-------------------------------------------------------------------
//
// class Imath::Box<class T>
// --------------------------------
//
// This class imposes the following requirements on its
// parameter class:
//
// 1) The class T must implement these operators:
// + - < > <= >= =
// with the signature (T,T) and the expected
// return values for a numeric type.
//
// 2) The class T must implement operator=
// with the signature (T,float and/or double)
//
// 3) The class T must have a constructor which takes
// a float (and/or double) for use in initializing the box.
//
// 4) The class T must have a function T::dimensions()
// which returns the number of dimensions in the class
// (since its assumed its a vector) -- preferably, this
// returns a constant expression.
//
//-------------------------------------------------------------------
#include "ImathVec.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
class Box
{
public:
//-------------------------
// Data Members are public
//-------------------------
T min;
T max;
//-----------------------------------------------------
// Constructors - an "empty" box is created by default
//-----------------------------------------------------
Box ();
Box (const T &point);
Box (const T &minT, const T &maxT);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Box<T> &src) const;
bool operator != (const Box<T> &src) const;
//------------------
// Box manipulation
//------------------
void makeEmpty ();
void extendBy (const T &point);
void extendBy (const Box<T> &box);
void makeInfinite ();
//---------------------------------------------------
// Query functions - these compute results each time
//---------------------------------------------------
T size () const;
T center () const;
bool intersects (const T &point) const;
bool intersects (const Box<T> &box) const;
unsigned int majorAxis () const;
//----------------
// Classification
//----------------
bool isEmpty () const;
bool hasVolume () const;
bool isInfinite () const;
};
//--------------------
// Convenient typedefs
//--------------------
typedef Box <V2s> Box2s;
typedef Box <V2i> Box2i;
typedef Box <V2f> Box2f;
typedef Box <V2d> Box2d;
typedef Box <V3s> Box3s;
typedef Box <V3i> Box3i;
typedef Box <V3f> Box3f;
typedef Box <V3d> Box3d;
//----------------
// Implementation
template <class T>
inline Box<T>::Box()
{
makeEmpty();
}
template <class T>
inline Box<T>::Box (const T &point)
{
min = point;
max = point;
}
template <class T>
inline Box<T>::Box (const T &minT, const T &maxT)
{
min = minT;
max = maxT;
}
template <class T>
inline bool
Box<T>::operator == (const Box<T> &src) const
{
return (min == src.min && max == src.max);
}
template <class T>
inline bool
Box<T>::operator != (const Box<T> &src) const
{
return (min != src.min || max != src.max);
}
template <class T>
inline void Box<T>::makeEmpty()
{
min = T(T::baseTypeMax());
max = T(T::baseTypeMin());
}
template <class T>
inline void Box<T>::makeInfinite()
{
min = T(T::baseTypeMin());
max = T(T::baseTypeMax());
}
template <class T>
inline void
Box<T>::extendBy(const T &point)
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (point[i] < min[i])
min[i] = point[i];
if (point[i] > max[i])
max[i] = point[i];
}
}
template <class T>
inline void
Box<T>::extendBy(const Box<T> &box)
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (box.min[i] < min[i])
min[i] = box.min[i];
if (box.max[i] > max[i])
max[i] = box.max[i];
}
}
template <class T>
inline bool
Box<T>::intersects(const T &point) const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (point[i] < min[i] || point[i] > max[i])
return false;
}
return true;
}
template <class T>
inline bool
Box<T>::intersects(const Box<T> &box) const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (box.max[i] < min[i] || box.min[i] > max[i])
return false;
}
return true;
}
template <class T>
inline T
Box<T>::size() const
{
if (isEmpty())
return T (0);
return max - min;
}
template <class T>
inline T
Box<T>::center() const
{
return (max + min) / 2;
}
template <class T>
inline bool
Box<T>::isEmpty() const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (max[i] < min[i])
return true;
}
return false;
}
template <class T>
inline bool
Box<T>::isInfinite() const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (min[i] != T::baseTypeMin() || max[i] != T::baseTypeMax())
return false;
}
return true;
}
template <class T>
inline bool
Box<T>::hasVolume() const
{
for (unsigned int i = 0; i < min.dimensions(); i++)
{
if (max[i] <= min[i])
return false;
}
return true;
}
template<class T>
inline unsigned int
Box<T>::majorAxis() const
{
unsigned int major = 0;
T s = size();
for (unsigned int i = 1; i < min.dimensions(); i++)
{
if (s[i] > s[major])
major = i;
}
return major;
}
//-------------------------------------------------------------------
//
// Partial class specializations for Imath::Vec2<T> and Imath::Vec3<T>
//
//-------------------------------------------------------------------
template <typename T> class Box;
template <class T>
class Box<Vec2<T> >
{
public:
//-------------------------
// Data Members are public
//-------------------------
Vec2<T> min;
Vec2<T> max;
//-----------------------------------------------------
// Constructors - an "empty" box is created by default
//-----------------------------------------------------
Box();
Box (const Vec2<T> &point);
Box (const Vec2<T> &minT, const Vec2<T> &maxT);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Box<Vec2<T> > &src) const;
bool operator != (const Box<Vec2<T> > &src) const;
//------------------
// Box manipulation
//------------------
void makeEmpty();
void extendBy (const Vec2<T> &point);
void extendBy (const Box<Vec2<T> > &box);
void makeInfinite();
//---------------------------------------------------
// Query functions - these compute results each time
//---------------------------------------------------
Vec2<T> size() const;
Vec2<T> center() const;
bool intersects (const Vec2<T> &point) const;
bool intersects (const Box<Vec2<T> > &box) const;
unsigned int majorAxis() const;
//----------------
// Classification
//----------------
bool isEmpty() const;
bool hasVolume() const;
bool isInfinite() const;
};
//----------------
// Implementation
template <class T>
inline Box<Vec2<T> >::Box()
{
makeEmpty();
}
template <class T>
inline Box<Vec2<T> >::Box (const Vec2<T> &point)
{
min = point;
max = point;
}
template <class T>
inline Box<Vec2<T> >::Box (const Vec2<T> &minT, const Vec2<T> &maxT)
{
min = minT;
max = maxT;
}
template <class T>
inline bool
Box<Vec2<T> >::operator == (const Box<Vec2<T> > &src) const
{
return (min == src.min && max == src.max);
}
template <class T>
inline bool
Box<Vec2<T> >::operator != (const Box<Vec2<T> > &src) const
{
return (min != src.min || max != src.max);
}
template <class T>
inline void Box<Vec2<T> >::makeEmpty()
{
min = Vec2<T>(Vec2<T>::baseTypeMax());
max = Vec2<T>(Vec2<T>::baseTypeMin());
}
template <class T>
inline void Box<Vec2<T> >::makeInfinite()
{
min = Vec2<T>(Vec2<T>::baseTypeMin());
max = Vec2<T>(Vec2<T>::baseTypeMax());
}
template <class T>
inline void
Box<Vec2<T> >::extendBy (const Vec2<T> &point)
{
if (point[0] < min[0])
min[0] = point[0];
if (point[0] > max[0])
max[0] = point[0];
if (point[1] < min[1])
min[1] = point[1];
if (point[1] > max[1])
max[1] = point[1];
}
template <class T>
inline void
Box<Vec2<T> >::extendBy (const Box<Vec2<T> > &box)
{
if (box.min[0] < min[0])
min[0] = box.min[0];
if (box.max[0] > max[0])
max[0] = box.max[0];
if (box.min[1] < min[1])
min[1] = box.min[1];
if (box.max[1] > max[1])
max[1] = box.max[1];
}
template <class T>
inline bool
Box<Vec2<T> >::intersects (const Vec2<T> &point) const
{
if (point[0] < min[0] || point[0] > max[0] ||
point[1] < min[1] || point[1] > max[1])
return false;
return true;
}
template <class T>
inline bool
Box<Vec2<T> >::intersects (const Box<Vec2<T> > &box) const
{
if (box.max[0] < min[0] || box.min[0] > max[0] ||
box.max[1] < min[1] || box.min[1] > max[1])
return false;
return true;
}
template <class T>
inline Vec2<T>
Box<Vec2<T> >::size() const
{
if (isEmpty())
return Vec2<T> (0);
return max - min;
}
template <class T>
inline Vec2<T>
Box<Vec2<T> >::center() const
{
return (max + min) / 2;
}
template <class T>
inline bool
Box<Vec2<T> >::isEmpty() const
{
if (max[0] < min[0] ||
max[1] < min[1])
return true;
return false;
}
template <class T>
inline bool
Box<Vec2<T> > ::isInfinite() const
{
if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
min[1] != limits<T>::min() || max[1] != limits<T>::max())
return false;
return true;
}
template <class T>
inline bool
Box<Vec2<T> >::hasVolume() const
{
if (max[0] <= min[0] ||
max[1] <= min[1])
return false;
return true;
}
template <class T>
inline unsigned int
Box<Vec2<T> >::majorAxis() const
{
unsigned int major = 0;
Vec2<T> s = size();
if (s[1] > s[major])
major = 1;
return major;
}
template <class T>
class Box<Vec3<T> >
{
public:
//-------------------------
// Data Members are public
//-------------------------
Vec3<T> min;
Vec3<T> max;
//-----------------------------------------------------
// Constructors - an "empty" box is created by default
//-----------------------------------------------------
Box();
Box (const Vec3<T> &point);
Box (const Vec3<T> &minT, const Vec3<T> &maxT);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Box<Vec3<T> > &src) const;
bool operator != (const Box<Vec3<T> > &src) const;
//------------------
// Box manipulation
//------------------
void makeEmpty();
void extendBy (const Vec3<T> &point);
void extendBy (const Box<Vec3<T> > &box);
void makeInfinite ();
//---------------------------------------------------
// Query functions - these compute results each time
//---------------------------------------------------
Vec3<T> size() const;
Vec3<T> center() const;
bool intersects (const Vec3<T> &point) const;
bool intersects (const Box<Vec3<T> > &box) const;
unsigned int majorAxis() const;
//----------------
// Classification
//----------------
bool isEmpty() const;
bool hasVolume() const;
bool isInfinite() const;
};
//----------------
// Implementation
template <class T>
inline Box<Vec3<T> >::Box()
{
makeEmpty();
}
template <class T>
inline Box<Vec3<T> >::Box (const Vec3<T> &point)
{
min = point;
max = point;
}
template <class T>
inline Box<Vec3<T> >::Box (const Vec3<T> &minT, const Vec3<T> &maxT)
{
min = minT;
max = maxT;
}
template <class T>
inline bool
Box<Vec3<T> >::operator == (const Box<Vec3<T> > &src) const
{
return (min == src.min && max == src.max);
}
template <class T>
inline bool
Box<Vec3<T> >::operator != (const Box<Vec3<T> > &src) const
{
return (min != src.min || max != src.max);
}
template <class T>
inline void Box<Vec3<T> >::makeEmpty()
{
min = Vec3<T>(Vec3<T>::baseTypeMax());
max = Vec3<T>(Vec3<T>::baseTypeMin());
}
template <class T>
inline void Box<Vec3<T> >::makeInfinite()
{
min = Vec3<T>(Vec3<T>::baseTypeMin());
max = Vec3<T>(Vec3<T>::baseTypeMax());
}
template <class T>
inline void
Box<Vec3<T> >::extendBy (const Vec3<T> &point)
{
if (point[0] < min[0])
min[0] = point[0];
if (point[0] > max[0])
max[0] = point[0];
if (point[1] < min[1])
min[1] = point[1];
if (point[1] > max[1])
max[1] = point[1];
if (point[2] < min[2])
min[2] = point[2];
if (point[2] > max[2])
max[2] = point[2];
}
template <class T>
inline void
Box<Vec3<T> >::extendBy (const Box<Vec3<T> > &box)
{
if (box.min[0] < min[0])
min[0] = box.min[0];
if (box.max[0] > max[0])
max[0] = box.max[0];
if (box.min[1] < min[1])
min[1] = box.min[1];
if (box.max[1] > max[1])
max[1] = box.max[1];
if (box.min[2] < min[2])
min[2] = box.min[2];
if (box.max[2] > max[2])
max[2] = box.max[2];
}
template <class T>
inline bool
Box<Vec3<T> >::intersects (const Vec3<T> &point) const
{
if (point[0] < min[0] || point[0] > max[0] ||
point[1] < min[1] || point[1] > max[1] ||
point[2] < min[2] || point[2] > max[2])
return false;
return true;
}
template <class T>
inline bool
Box<Vec3<T> >::intersects (const Box<Vec3<T> > &box) const
{
if (box.max[0] < min[0] || box.min[0] > max[0] ||
box.max[1] < min[1] || box.min[1] > max[1] ||
box.max[2] < min[2] || box.min[2] > max[2])
return false;
return true;
}
template <class T>
inline Vec3<T>
Box<Vec3<T> >::size() const
{
if (isEmpty())
return Vec3<T> (0);
return max - min;
}
template <class T>
inline Vec3<T>
Box<Vec3<T> >::center() const
{
return (max + min) / 2;
}
template <class T>
inline bool
Box<Vec3<T> >::isEmpty() const
{
if (max[0] < min[0] ||
max[1] < min[1] ||
max[2] < min[2])
return true;
return false;
}
template <class T>
inline bool
Box<Vec3<T> >::isInfinite() const
{
if (min[0] != limits<T>::min() || max[0] != limits<T>::max() ||
min[1] != limits<T>::min() || max[1] != limits<T>::max() ||
min[2] != limits<T>::min() || max[2] != limits<T>::max())
return false;
return true;
}
template <class T>
inline bool
Box<Vec3<T> >::hasVolume() const
{
if (max[0] <= min[0] ||
max[1] <= min[1] ||
max[2] <= min[2])
return false;
return true;
}
template <class T>
inline unsigned int
Box<Vec3<T> >::majorAxis() const
{
unsigned int major = 0;
Vec3<T> s = size();
if (s[1] > s[major])
major = 1;
if (s[2] > s[major])
major = 2;
return major;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHBOX_H

1016
Imath/ImathBoxAlgo.h Normal file

File diff suppressed because it is too large Load Diff

736
Imath/ImathColor.h Normal file
View File

@ -0,0 +1,736 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2004-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHCOLOR_H
#define INCLUDED_IMATHCOLOR_H
//----------------------------------------------------
//
// A three and four component color class template.
//
//----------------------------------------------------
#include "ImathVec.h"
#include "ImathNamespace.h"
#include "half.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
class Color3: public Vec3 <T>
{
public:
//-------------
// Constructors
//-------------
Color3 (); // no initialization
explicit Color3 (T a); // (a a a)
Color3 (T a, T b, T c); // (a b c)
//---------------------------------
// Copy constructors and assignment
//---------------------------------
Color3 (const Color3 &c);
template <class S> Color3 (const Vec3<S> &v);
const Color3 & operator = (const Color3 &c);
//------------------------
// Component-wise addition
//------------------------
const Color3 & operator += (const Color3 &c);
Color3 operator + (const Color3 &c) const;
//---------------------------
// Component-wise subtraction
//---------------------------
const Color3 & operator -= (const Color3 &c);
Color3 operator - (const Color3 &c) const;
//------------------------------------
// Component-wise multiplication by -1
//------------------------------------
Color3 operator - () const;
const Color3 & negate ();
//------------------------------
// Component-wise multiplication
//------------------------------
const Color3 & operator *= (const Color3 &c);
const Color3 & operator *= (T a);
Color3 operator * (const Color3 &c) const;
Color3 operator * (T a) const;
//------------------------
// Component-wise division
//------------------------
const Color3 & operator /= (const Color3 &c);
const Color3 & operator /= (T a);
Color3 operator / (const Color3 &c) const;
Color3 operator / (T a) const;
};
template <class T> class Color4
{
public:
//-------------------
// Access to elements
//-------------------
T r, g, b, a;
T & operator [] (int i);
const T & operator [] (int i) const;
//-------------
// Constructors
//-------------
Color4 (); // no initialization
explicit Color4 (T a); // (a a a a)
Color4 (T a, T b, T c, T d); // (a b c d)
//---------------------------------
// Copy constructors and assignment
//---------------------------------
Color4 (const Color4 &v);
template <class S> Color4 (const Color4<S> &v);
const Color4 & operator = (const Color4 &v);
//----------------------
// Compatibility with Sb
//----------------------
template <class S>
void setValue (S a, S b, S c, S d);
template <class S>
void setValue (const Color4<S> &v);
template <class S>
void getValue (S &a, S &b, S &c, S &d) const;
template <class S>
void getValue (Color4<S> &v) const;
T * getValue();
const T * getValue() const;
//---------
// Equality
//---------
template <class S>
bool operator == (const Color4<S> &v) const;
template <class S>
bool operator != (const Color4<S> &v) const;
//------------------------
// Component-wise addition
//------------------------
const Color4 & operator += (const Color4 &v);
Color4 operator + (const Color4 &v) const;
//---------------------------
// Component-wise subtraction
//---------------------------
const Color4 & operator -= (const Color4 &v);
Color4 operator - (const Color4 &v) const;
//------------------------------------
// Component-wise multiplication by -1
//------------------------------------
Color4 operator - () const;
const Color4 & negate ();
//------------------------------
// Component-wise multiplication
//------------------------------
const Color4 & operator *= (const Color4 &v);
const Color4 & operator *= (T a);
Color4 operator * (const Color4 &v) const;
Color4 operator * (T a) const;
//------------------------
// Component-wise division
//------------------------
const Color4 & operator /= (const Color4 &v);
const Color4 & operator /= (T a);
Color4 operator / (const Color4 &v) const;
Color4 operator / (T a) const;
//----------------------------------------------------------
// Number of dimensions, i.e. number of elements in a Color4
//----------------------------------------------------------
static unsigned int dimensions() {return 4;}
//-------------------------------------------------
// Limitations of type T (see also class limits<T>)
//-------------------------------------------------
static T baseTypeMin() {return limits<T>::min();}
static T baseTypeMax() {return limits<T>::max();}
static T baseTypeSmallest() {return limits<T>::smallest();}
static T baseTypeEpsilon() {return limits<T>::epsilon();}
//--------------------------------------------------------------
// Base type -- in templates, which accept a parameter, V, which
// could be a Color4<T>, you can refer to T as
// V::BaseType
//--------------------------------------------------------------
typedef T BaseType;
};
//--------------
// Stream output
//--------------
template <class T>
std::ostream & operator << (std::ostream &s, const Color4<T> &v);
//----------------------------------------------------
// Reverse multiplication: S * Color4<T>
//----------------------------------------------------
template <class S, class T> Color4<T> operator * (S a, const Color4<T> &v);
//-------------------------
// Typedefs for convenience
//-------------------------
typedef Color3<float> Color3f;
typedef Color3<half> Color3h;
typedef Color3<unsigned char> Color3c;
typedef Color3<half> C3h;
typedef Color3<float> C3f;
typedef Color3<unsigned char> C3c;
typedef Color4<float> Color4f;
typedef Color4<half> Color4h;
typedef Color4<unsigned char> Color4c;
typedef Color4<float> C4f;
typedef Color4<half> C4h;
typedef Color4<unsigned char> C4c;
typedef unsigned int PackedColor;
//-------------------------
// Implementation of Color3
//-------------------------
template <class T>
inline
Color3<T>::Color3 (): Vec3 <T> ()
{
// empty
}
template <class T>
inline
Color3<T>::Color3 (T a): Vec3 <T> (a)
{
// empty
}
template <class T>
inline
Color3<T>::Color3 (T a, T b, T c): Vec3 <T> (a, b, c)
{
// empty
}
template <class T>
inline
Color3<T>::Color3 (const Color3 &c): Vec3 <T> (c)
{
// empty
}
template <class T>
template <class S>
inline
Color3<T>::Color3 (const Vec3<S> &v): Vec3 <T> (v)
{
//empty
}
template <class T>
inline const Color3<T> &
Color3<T>::operator = (const Color3 &c)
{
*((Vec3<T> *) this) = c;
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator += (const Color3 &c)
{
*((Vec3<T> *) this) += c;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator + (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this + (const Vec3<T> &)c);
}
template <class T>
inline const Color3<T> &
Color3<T>::operator -= (const Color3 &c)
{
*((Vec3<T> *) this) -= c;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator - (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this - (const Vec3<T> &)c);
}
template <class T>
inline Color3<T>
Color3<T>::operator - () const
{
return Color3 (-(*(Vec3<T> *)this));
}
template <class T>
inline const Color3<T> &
Color3<T>::negate ()
{
((Vec3<T> *) this)->negate();
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator *= (const Color3 &c)
{
*((Vec3<T> *) this) *= c;
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator *= (T a)
{
*((Vec3<T> *) this) *= a;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator * (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this * (const Vec3<T> &)c);
}
template <class T>
inline Color3<T>
Color3<T>::operator * (T a) const
{
return Color3 (*(Vec3<T> *)this * a);
}
template <class T>
inline const Color3<T> &
Color3<T>::operator /= (const Color3 &c)
{
*((Vec3<T> *) this) /= c;
return *this;
}
template <class T>
inline const Color3<T> &
Color3<T>::operator /= (T a)
{
*((Vec3<T> *) this) /= a;
return *this;
}
template <class T>
inline Color3<T>
Color3<T>::operator / (const Color3 &c) const
{
return Color3 (*(Vec3<T> *)this / (const Vec3<T> &)c);
}
template <class T>
inline Color3<T>
Color3<T>::operator / (T a) const
{
return Color3 (*(Vec3<T> *)this / a);
}
//-----------------------
// Implementation of Color4
//-----------------------
template <class T>
inline T &
Color4<T>::operator [] (int i)
{
return (&r)[i];
}
template <class T>
inline const T &
Color4<T>::operator [] (int i) const
{
return (&r)[i];
}
template <class T>
inline
Color4<T>::Color4 ()
{
// empty
}
template <class T>
inline
Color4<T>::Color4 (T x)
{
r = g = b = a = x;
}
template <class T>
inline
Color4<T>::Color4 (T x, T y, T z, T w)
{
r = x;
g = y;
b = z;
a = w;
}
template <class T>
inline
Color4<T>::Color4 (const Color4 &v)
{
r = v.r;
g = v.g;
b = v.b;
a = v.a;
}
template <class T>
template <class S>
inline
Color4<T>::Color4 (const Color4<S> &v)
{
r = T (v.r);
g = T (v.g);
b = T (v.b);
a = T (v.a);
}
template <class T>
inline const Color4<T> &
Color4<T>::operator = (const Color4 &v)
{
r = v.r;
g = v.g;
b = v.b;
a = v.a;
return *this;
}
template <class T>
template <class S>
inline void
Color4<T>::setValue (S x, S y, S z, S w)
{
r = T (x);
g = T (y);
b = T (z);
a = T (w);
}
template <class T>
template <class S>
inline void
Color4<T>::setValue (const Color4<S> &v)
{
r = T (v.r);
g = T (v.g);
b = T (v.b);
a = T (v.a);
}
template <class T>
template <class S>
inline void
Color4<T>::getValue (S &x, S &y, S &z, S &w) const
{
x = S (r);
y = S (g);
z = S (b);
w = S (a);
}
template <class T>
template <class S>
inline void
Color4<T>::getValue (Color4<S> &v) const
{
v.r = S (r);
v.g = S (g);
v.b = S (b);
v.a = S (a);
}
template <class T>
inline T *
Color4<T>::getValue()
{
return (T *) &r;
}
template <class T>
inline const T *
Color4<T>::getValue() const
{
return (const T *) &r;
}
template <class T>
template <class S>
inline bool
Color4<T>::operator == (const Color4<S> &v) const
{
return r == v.r && g == v.g && b == v.b && a == v.a;
}
template <class T>
template <class S>
inline bool
Color4<T>::operator != (const Color4<S> &v) const
{
return r != v.r || g != v.g || b != v.b || a != v.a;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator += (const Color4 &v)
{
r += v.r;
g += v.g;
b += v.b;
a += v.a;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator + (const Color4 &v) const
{
return Color4 (r + v.r, g + v.g, b + v.b, a + v.a);
}
template <class T>
inline const Color4<T> &
Color4<T>::operator -= (const Color4 &v)
{
r -= v.r;
g -= v.g;
b -= v.b;
a -= v.a;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator - (const Color4 &v) const
{
return Color4 (r - v.r, g - v.g, b - v.b, a - v.a);
}
template <class T>
inline Color4<T>
Color4<T>::operator - () const
{
return Color4 (-r, -g, -b, -a);
}
template <class T>
inline const Color4<T> &
Color4<T>::negate ()
{
r = -r;
g = -g;
b = -b;
a = -a;
return *this;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator *= (const Color4 &v)
{
r *= v.r;
g *= v.g;
b *= v.b;
a *= v.a;
return *this;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator *= (T x)
{
r *= x;
g *= x;
b *= x;
a *= x;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator * (const Color4 &v) const
{
return Color4 (r * v.r, g * v.g, b * v.b, a * v.a);
}
template <class T>
inline Color4<T>
Color4<T>::operator * (T x) const
{
return Color4 (r * x, g * x, b * x, a * x);
}
template <class T>
inline const Color4<T> &
Color4<T>::operator /= (const Color4 &v)
{
r /= v.r;
g /= v.g;
b /= v.b;
a /= v.a;
return *this;
}
template <class T>
inline const Color4<T> &
Color4<T>::operator /= (T x)
{
r /= x;
g /= x;
b /= x;
a /= x;
return *this;
}
template <class T>
inline Color4<T>
Color4<T>::operator / (const Color4 &v) const
{
return Color4 (r / v.r, g / v.g, b / v.b, a / v.a);
}
template <class T>
inline Color4<T>
Color4<T>::operator / (T x) const
{
return Color4 (r / x, g / x, b / x, a / x);
}
template <class T>
std::ostream &
operator << (std::ostream &s, const Color4<T> &v)
{
return s << '(' << v.r << ' ' << v.g << ' ' << v.b << ' ' << v.a << ')';
}
//-----------------------------------------
// Implementation of reverse multiplication
//-----------------------------------------
template <class S, class T>
inline Color4<T>
operator * (S x, const Color4<T> &v)
{
return Color4<T> (x * v.r, x * v.g, x * v.b, x * v.a);
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHCOLOR_H

178
Imath/ImathColorAlgo.cpp Normal file
View File

@ -0,0 +1,178 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
//----------------------------------------------------------------------------
//
// Implementation of non-template items declared in ImathColorAlgo.h
//
//----------------------------------------------------------------------------
#include "ImathColorAlgo.h"
IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
Vec3<double>
hsv2rgb_d(const Vec3<double> &hsv)
{
double hue = hsv.x;
double sat = hsv.y;
double val = hsv.z;
double x = 0.0, y = 0.0, z = 0.0;
if (hue == 1) hue = 0;
else hue *= 6;
int i = int(Math<double>::floor(hue));
double f = hue-i;
double p = val*(1-sat);
double q = val*(1-(sat*f));
double t = val*(1-(sat*(1-f)));
switch (i)
{
case 0: x = val; y = t; z = p; break;
case 1: x = q; y = val; z = p; break;
case 2: x = p; y = val; z = t; break;
case 3: x = p; y = q; z = val; break;
case 4: x = t; y = p; z = val; break;
case 5: x = val; y = p; z = q; break;
}
return Vec3<double>(x,y,z);
}
Color4<double>
hsv2rgb_d(const Color4<double> &hsv)
{
double hue = hsv.r;
double sat = hsv.g;
double val = hsv.b;
double r = 0.0, g = 0.0, b = 0.0;
if (hue == 1) hue = 0;
else hue *= 6;
int i = int(Math<double>::floor(hue));
double f = hue-i;
double p = val*(1-sat);
double q = val*(1-(sat*f));
double t = val*(1-(sat*(1-f)));
switch (i)
{
case 0: r = val; g = t; b = p; break;
case 1: r = q; g = val; b = p; break;
case 2: r = p; g = val; b = t; break;
case 3: r = p; g = q; b = val; break;
case 4: r = t; g = p; b = val; break;
case 5: r = val; g = p; b = q; break;
}
return Color4<double>(r,g,b,hsv.a);
}
Vec3<double>
rgb2hsv_d(const Vec3<double> &c)
{
const double &x = c.x;
const double &y = c.y;
const double &z = c.z;
double max = (x > y) ? ((x > z) ? x : z) : ((y > z) ? y : z);
double min = (x < y) ? ((x < z) ? x : z) : ((y < z) ? y : z);
double range = max - min;
double val = max;
double sat = 0;
double hue = 0;
if (max != 0) sat = range/max;
if (sat != 0)
{
double h;
if (x == max) h = (y - z) / range;
else if (y == max) h = 2 + (z - x) / range;
else h = 4 + (x - y) / range;
hue = h/6.;
if (hue < 0.)
hue += 1.0;
}
return Vec3<double>(hue,sat,val);
}
Color4<double>
rgb2hsv_d(const Color4<double> &c)
{
const double &r = c.r;
const double &g = c.g;
const double &b = c.b;
double max = (r > g) ? ((r > b) ? r : b) : ((g > b) ? g : b);
double min = (r < g) ? ((r < b) ? r : b) : ((g < b) ? g : b);
double range = max - min;
double val = max;
double sat = 0;
double hue = 0;
if (max != 0) sat = range/max;
if (sat != 0)
{
double h;
if (r == max) h = (g - b) / range;
else if (g == max) h = 2 + (b - r) / range;
else h = 4 + (r - g) / range;
hue = h/6.;
if (hue < 0.)
hue += 1.0;
}
return Color4<double>(hue,sat,val,c.a);
}
IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT

257
Imath/ImathColorAlgo.h Normal file
View File

@ -0,0 +1,257 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHCOLORALGO_H
#define INCLUDED_IMATHCOLORALGO_H
#include "ImathColor.h"
#include "ImathExport.h"
#include "ImathMath.h"
#include "ImathLimits.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Non-templated helper routines for color conversion.
// These routines eliminate type warnings under g++.
//
IMATH_EXPORT Vec3<double> hsv2rgb_d(const Vec3<double> &hsv);
IMATH_EXPORT Color4<double> hsv2rgb_d(const Color4<double> &hsv);
IMATH_EXPORT Vec3<double> rgb2hsv_d(const Vec3<double> &rgb);
IMATH_EXPORT Color4<double> rgb2hsv_d(const Color4<double> &rgb);
//
// Color conversion functions and general color algorithms
//
// hsv2rgb(), rgb2hsv(), rgb2packed(), packed2rgb()
// see each funtion definition for details.
//
template<class T>
Vec3<T>
hsv2rgb(const Vec3<T> &hsv)
{
if ( limits<T>::isIntegral() )
{
Vec3<double> v = Vec3<double>(hsv.x / double(limits<T>::max()),
hsv.y / double(limits<T>::max()),
hsv.z / double(limits<T>::max()));
Vec3<double> c = hsv2rgb_d(v);
return Vec3<T>((T) (c.x * limits<T>::max()),
(T) (c.y * limits<T>::max()),
(T) (c.z * limits<T>::max()));
}
else
{
Vec3<double> v = Vec3<double>(hsv.x, hsv.y, hsv.z);
Vec3<double> c = hsv2rgb_d(v);
return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
}
}
template<class T>
Color4<T>
hsv2rgb(const Color4<T> &hsv)
{
if ( limits<T>::isIntegral() )
{
Color4<double> v = Color4<double>(hsv.r / float(limits<T>::max()),
hsv.g / float(limits<T>::max()),
hsv.b / float(limits<T>::max()),
hsv.a / float(limits<T>::max()));
Color4<double> c = hsv2rgb_d(v);
return Color4<T>((T) (c.r * limits<T>::max()),
(T) (c.g * limits<T>::max()),
(T) (c.b * limits<T>::max()),
(T) (c.a * limits<T>::max()));
}
else
{
Color4<double> v = Color4<double>(hsv.r, hsv.g, hsv.b, hsv.a);
Color4<double> c = hsv2rgb_d(v);
return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
}
}
template<class T>
Vec3<T>
rgb2hsv(const Vec3<T> &rgb)
{
if ( limits<T>::isIntegral() )
{
Vec3<double> v = Vec3<double>(rgb.x / double(limits<T>::max()),
rgb.y / double(limits<T>::max()),
rgb.z / double(limits<T>::max()));
Vec3<double> c = rgb2hsv_d(v);
return Vec3<T>((T) (c.x * limits<T>::max()),
(T) (c.y * limits<T>::max()),
(T) (c.z * limits<T>::max()));
}
else
{
Vec3<double> v = Vec3<double>(rgb.x, rgb.y, rgb.z);
Vec3<double> c = rgb2hsv_d(v);
return Vec3<T>((T) c.x, (T) c.y, (T) c.z);
}
}
template<class T>
Color4<T>
rgb2hsv(const Color4<T> &rgb)
{
if ( limits<T>::isIntegral() )
{
Color4<double> v = Color4<double>(rgb.r / float(limits<T>::max()),
rgb.g / float(limits<T>::max()),
rgb.b / float(limits<T>::max()),
rgb.a / float(limits<T>::max()));
Color4<double> c = rgb2hsv_d(v);
return Color4<T>((T) (c.r * limits<T>::max()),
(T) (c.g * limits<T>::max()),
(T) (c.b * limits<T>::max()),
(T) (c.a * limits<T>::max()));
}
else
{
Color4<double> v = Color4<double>(rgb.r, rgb.g, rgb.b, rgb.a);
Color4<double> c = rgb2hsv_d(v);
return Color4<T>((T) c.r, (T) c.g, (T) c.b, (T) c.a);
}
}
template <class T>
PackedColor
rgb2packed(const Vec3<T> &c)
{
if ( limits<T>::isIntegral() )
{
float x = c.x / float(limits<T>::max());
float y = c.y / float(limits<T>::max());
float z = c.z / float(limits<T>::max());
return rgb2packed( V3f(x,y,z) );
}
else
{
return ( (PackedColor) (c.x * 255) |
(((PackedColor) (c.y * 255)) << 8) |
(((PackedColor) (c.z * 255)) << 16) | 0xFF000000 );
}
}
template <class T>
PackedColor
rgb2packed(const Color4<T> &c)
{
if ( limits<T>::isIntegral() )
{
float r = c.r / float(limits<T>::max());
float g = c.g / float(limits<T>::max());
float b = c.b / float(limits<T>::max());
float a = c.a / float(limits<T>::max());
return rgb2packed( C4f(r,g,b,a) );
}
else
{
return ( (PackedColor) (c.r * 255) |
(((PackedColor) (c.g * 255)) << 8) |
(((PackedColor) (c.b * 255)) << 16) |
(((PackedColor) (c.a * 255)) << 24));
}
}
//
// This guy can't return the result because the template
// parameter would not be in the function signiture. So instead,
// its passed in as an argument.
//
template <class T>
void
packed2rgb(PackedColor packed, Vec3<T> &out)
{
if ( limits<T>::isIntegral() )
{
T f = limits<T>::max() / ((PackedColor)0xFF);
out.x = (packed & 0xFF) * f;
out.y = ((packed & 0xFF00) >> 8) * f;
out.z = ((packed & 0xFF0000) >> 16) * f;
}
else
{
T f = T(1) / T(255);
out.x = (packed & 0xFF) * f;
out.y = ((packed & 0xFF00) >> 8) * f;
out.z = ((packed & 0xFF0000) >> 16) * f;
}
}
template <class T>
void
packed2rgb(PackedColor packed, Color4<T> &out)
{
if ( limits<T>::isIntegral() )
{
T f = limits<T>::max() / ((PackedColor)0xFF);
out.r = (packed & 0xFF) * f;
out.g = ((packed & 0xFF00) >> 8) * f;
out.b = ((packed & 0xFF0000) >> 16) * f;
out.a = ((packed & 0xFF000000) >> 24) * f;
}
else
{
T f = T(1) / T(255);
out.r = (packed & 0xFF) * f;
out.g = ((packed & 0xFF00) >> 8) * f;
out.b = ((packed & 0xFF0000) >> 16) * f;
out.a = ((packed & 0xFF000000) >> 24) * f;
}
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHCOLORALGO_H

927
Imath/ImathEuler.h Normal file
View File

@ -0,0 +1,927 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHEULER_H
#define INCLUDED_IMATHEULER_H
//----------------------------------------------------------------------
//
// template class Euler<T>
//
// This class represents euler angle orientations. The class
// inherits from Vec3 to it can be freely cast. The additional
// information is the euler priorities rep. This class is
// essentially a rip off of Ken Shoemake's GemsIV code. It has
// been modified minimally to make it more understandable, but
// hardly enough to make it easy to grok completely.
//
// There are 24 possible combonations of Euler angle
// representations of which 12 are common in CG and you will
// probably only use 6 of these which in this scheme are the
// non-relative-non-repeating types.
//
// The representations can be partitioned according to two
// criteria:
//
// 1) Are the angles measured relative to a set of fixed axis
// or relative to each other (the latter being what happens
// when rotation matrices are multiplied together and is
// almost ubiquitous in the cg community)
//
// 2) Is one of the rotations repeated (ala XYX rotation)
//
// When you construct a given representation from scratch you
// must order the angles according to their priorities. So, the
// easiest is a softimage or aerospace (yaw/pitch/roll) ordering
// of ZYX.
//
// float x_rot = 1;
// float y_rot = 2;
// float z_rot = 3;
//
// Eulerf angles(z_rot, y_rot, x_rot, Eulerf::ZYX);
// -or-
// Eulerf angles( V3f(z_rot,y_rot,z_rot), Eulerf::ZYX );
//
// If instead, the order was YXZ for instance you would have to
// do this:
//
// float x_rot = 1;
// float y_rot = 2;
// float z_rot = 3;
//
// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ);
// -or-
// Eulerf angles( V3f(y_rot,x_rot,z_rot), Eulerf::YXZ );
//
// Notice how the order you put the angles into the three slots
// should correspond to the enum (YXZ) ordering. The input angle
// vector is called the "ijk" vector -- not an "xyz" vector. The
// ijk vector order is the same as the enum. If you treat the
// Euler<> as a Vec<> (which it inherts from) you will find the
// angles are ordered in the same way, i.e.:
//
// V3f v = angles;
// // v.x == y_rot, v.y == x_rot, v.z == z_rot
//
// If you just want the x, y, and z angles stored in a vector in
// that order, you can do this:
//
// V3f v = angles.toXYZVector()
// // v.x == x_rot, v.y == y_rot, v.z == z_rot
//
// If you want to set the Euler with an XYZVector use the
// optional layout argument:
//
// Eulerf angles(x_rot, y_rot, z_rot,
// Eulerf::YXZ,
// Eulerf::XYZLayout);
//
// This is the same as:
//
// Eulerf angles(y_rot, x_rot, z_rot, Eulerf::YXZ);
//
// Note that this won't do anything intelligent if you have a
// repeated axis in the euler angles (e.g. XYX)
//
// If you need to use the "relative" versions of these, you will
// need to use the "r" enums.
//
// The units of the rotation angles are assumed to be radians.
//
//----------------------------------------------------------------------
#include "ImathMath.h"
#include "ImathVec.h"
#include "ImathQuat.h"
#include "ImathMatrix.h"
#include "ImathLimits.h"
#include "ImathNamespace.h"
#include <iostream>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
// Disable MS VC++ warnings about conversion from double to float
#pragma warning(disable:4244)
#endif
template <class T>
class Euler : public Vec3<T>
{
public:
using Vec3<T>::x;
using Vec3<T>::y;
using Vec3<T>::z;
enum Order
{
//
// All 24 possible orderings
//
XYZ = 0x0101, // "usual" orderings
XZY = 0x0001,
YZX = 0x1101,
YXZ = 0x1001,
ZXY = 0x2101,
ZYX = 0x2001,
XZX = 0x0011, // first axis repeated
XYX = 0x0111,
YXY = 0x1011,
YZY = 0x1111,
ZYZ = 0x2011,
ZXZ = 0x2111,
XYZr = 0x2000, // relative orderings -- not common
XZYr = 0x2100,
YZXr = 0x1000,
YXZr = 0x1100,
ZXYr = 0x0000,
ZYXr = 0x0100,
XZXr = 0x2110, // relative first axis repeated
XYXr = 0x2010,
YXYr = 0x1110,
YZYr = 0x1010,
ZYZr = 0x0110,
ZXZr = 0x0010,
// ||||
// VVVV
// Legend: ABCD
// A -> Initial Axis (0==x, 1==y, 2==z)
// B -> Parity Even (1==true)
// C -> Initial Repeated (1==true)
// D -> Frame Static (1==true)
//
Legal = XYZ | XZY | YZX | YXZ | ZXY | ZYX |
XZX | XYX | YXY | YZY | ZYZ | ZXZ |
XYZr| XZYr| YZXr| YXZr| ZXYr| ZYXr|
XZXr| XYXr| YXYr| YZYr| ZYZr| ZXZr,
Min = 0x0000,
Max = 0x2111,
Default = XYZ
};
enum Axis { X = 0, Y = 1, Z = 2 };
enum InputLayout { XYZLayout, IJKLayout };
//--------------------------------------------------------------------
// Constructors -- all default to ZYX non-relative ala softimage
// (where there is no argument to specify it)
//
// The Euler-from-matrix constructors assume that the matrix does
// not include shear or non-uniform scaling, but the constructors
// do not examine the matrix to verify this assumption. If necessary,
// you can adjust the matrix by calling the removeScalingAndShear()
// function, defined in ImathMatrixAlgo.h.
//--------------------------------------------------------------------
Euler();
Euler(const Euler&);
Euler(Order p);
Euler(const Vec3<T> &v, Order o = Default, InputLayout l = IJKLayout);
Euler(T i, T j, T k, Order o = Default, InputLayout l = IJKLayout);
Euler(const Euler<T> &euler, Order newp);
Euler(const Matrix33<T> &, Order o = Default);
Euler(const Matrix44<T> &, Order o = Default);
//---------------------------------
// Algebraic functions/ Operators
//---------------------------------
const Euler<T>& operator= (const Euler<T>&);
const Euler<T>& operator= (const Vec3<T>&);
//--------------------------------------------------------
// Set the euler value
// This does NOT convert the angles, but setXYZVector()
// does reorder the input vector.
//--------------------------------------------------------
static bool legal(Order);
void setXYZVector(const Vec3<T> &);
Order order() const;
void setOrder(Order);
void set(Axis initial,
bool relative,
bool parityEven,
bool firstRepeats);
//------------------------------------------------------------
// Conversions, toXYZVector() reorders the angles so that
// the X rotation comes first, followed by the Y and Z
// in cases like XYX ordering, the repeated angle will be
// in the "z" component
//
// The Euler-from-matrix extract() functions assume that the
// matrix does not include shear or non-uniform scaling, but
// the extract() functions do not examine the matrix to verify
// this assumption. If necessary, you can adjust the matrix
// by calling the removeScalingAndShear() function, defined
// in ImathMatrixAlgo.h.
//------------------------------------------------------------
void extract(const Matrix33<T>&);
void extract(const Matrix44<T>&);
void extract(const Quat<T>&);
Matrix33<T> toMatrix33() const;
Matrix44<T> toMatrix44() const;
Quat<T> toQuat() const;
Vec3<T> toXYZVector() const;
//---------------------------------------------------
// Use this function to unpack angles from ijk form
//---------------------------------------------------
void angleOrder(int &i, int &j, int &k) const;
//---------------------------------------------------
// Use this function to determine mapping from xyz to ijk
// - reshuffles the xyz to match the order
//---------------------------------------------------
void angleMapping(int &i, int &j, int &k) const;
//----------------------------------------------------------------------
//
// Utility methods for getting continuous rotations. None of these
// methods change the orientation given by its inputs (or at least
// that is the intent).
//
// angleMod() converts an angle to its equivalent in [-PI, PI]
//
// simpleXYZRotation() adjusts xyzRot so that its components differ
// from targetXyzRot by no more than +-PI
//
// nearestRotation() adjusts xyzRot so that its components differ
// from targetXyzRot by as little as possible.
// Note that xyz here really means ijk, because
// the order must be provided.
//
// makeNear() adjusts "this" Euler so that its components differ
// from target by as little as possible. This method
// might not make sense for Eulers with different order
// and it probably doesn't work for repeated axis and
// relative orderings (TODO).
//
//-----------------------------------------------------------------------
static float angleMod (T angle);
static void simpleXYZRotation (Vec3<T> &xyzRot,
const Vec3<T> &targetXyzRot);
static void nearestRotation (Vec3<T> &xyzRot,
const Vec3<T> &targetXyzRot,
Order order = XYZ);
void makeNear (const Euler<T> &target);
bool frameStatic() const { return _frameStatic; }
bool initialRepeated() const { return _initialRepeated; }
bool parityEven() const { return _parityEven; }
Axis initialAxis() const { return _initialAxis; }
protected:
bool _frameStatic : 1; // relative or static rotations
bool _initialRepeated : 1; // init axis repeated as last
bool _parityEven : 1; // "parity of axis permutation"
#if defined _WIN32 || defined _WIN64
Axis _initialAxis ; // First axis of rotation
#else
Axis _initialAxis : 2; // First axis of rotation
#endif
};
//--------------------
// Convenient typedefs
//--------------------
typedef Euler<float> Eulerf;
typedef Euler<double> Eulerd;
//---------------
// Implementation
//---------------
template<class T>
inline void
Euler<T>::angleOrder(int &i, int &j, int &k) const
{
i = _initialAxis;
j = _parityEven ? (i+1)%3 : (i > 0 ? i-1 : 2);
k = _parityEven ? (i > 0 ? i-1 : 2) : (i+1)%3;
}
template<class T>
inline void
Euler<T>::angleMapping(int &i, int &j, int &k) const
{
int m[3];
m[_initialAxis] = 0;
m[(_initialAxis+1) % 3] = _parityEven ? 1 : 2;
m[(_initialAxis+2) % 3] = _parityEven ? 2 : 1;
i = m[0];
j = m[1];
k = m[2];
}
template<class T>
inline void
Euler<T>::setXYZVector(const Vec3<T> &v)
{
int i,j,k;
angleMapping(i,j,k);
(*this)[i] = v.x;
(*this)[j] = v.y;
(*this)[k] = v.z;
}
template<class T>
inline Vec3<T>
Euler<T>::toXYZVector() const
{
int i,j,k;
angleMapping(i,j,k);
return Vec3<T>((*this)[i],(*this)[j],(*this)[k]);
}
template<class T>
Euler<T>::Euler() :
Vec3<T>(0,0,0),
_frameStatic(true),
_initialRepeated(false),
_parityEven(true),
_initialAxis(X)
{}
template<class T>
Euler<T>::Euler(typename Euler<T>::Order p) :
Vec3<T>(0,0,0),
_frameStatic(true),
_initialRepeated(false),
_parityEven(true),
_initialAxis(X)
{
setOrder(p);
}
template<class T>
inline Euler<T>::Euler( const Vec3<T> &v,
typename Euler<T>::Order p,
typename Euler<T>::InputLayout l )
{
setOrder(p);
if ( l == XYZLayout ) setXYZVector(v);
else { x = v.x; y = v.y; z = v.z; }
}
template<class T>
inline Euler<T>::Euler(const Euler<T> &euler)
{
operator=(euler);
}
template<class T>
inline Euler<T>::Euler(const Euler<T> &euler,Order p)
{
setOrder(p);
Matrix33<T> M = euler.toMatrix33();
extract(M);
}
template<class T>
inline Euler<T>::Euler( T xi, T yi, T zi,
typename Euler<T>::Order p,
typename Euler<T>::InputLayout l)
{
setOrder(p);
if ( l == XYZLayout ) setXYZVector(Vec3<T>(xi,yi,zi));
else { x = xi; y = yi; z = zi; }
}
template<class T>
inline Euler<T>::Euler( const Matrix33<T> &M, typename Euler::Order p )
{
setOrder(p);
extract(M);
}
template<class T>
inline Euler<T>::Euler( const Matrix44<T> &M, typename Euler::Order p )
{
setOrder(p);
extract(M);
}
template<class T>
inline void Euler<T>::extract(const Quat<T> &q)
{
extract(q.toMatrix33());
}
template<class T>
void Euler<T>::extract(const Matrix33<T> &M)
{
int i,j,k;
angleOrder(i,j,k);
if (_initialRepeated)
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][i], M[k][i]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
M[1][0], M[1][1], M[1][2], 0,
M[2][0], M[2][1], M[2][2], 0,
0, 0, 0, 1);
//
// Extract the other two angles, y and z, from N.
//
T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
y = Math<T>::atan2 (sy, N[i][i]);
z = Math<T>::atan2 (N[j][k], N[j][j]);
}
else
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][k], M[k][k]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * Matrix44<T> (M[0][0], M[0][1], M[0][2], 0,
M[1][0], M[1][1], M[1][2], 0,
M[2][0], M[2][1], M[2][2], 0,
0, 0, 0, 1);
//
// Extract the other two angles, y and z, from N.
//
T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
y = Math<T>::atan2 (-N[i][k], cy);
z = Math<T>::atan2 (-N[j][i], N[j][j]);
}
if (!_parityEven)
*this *= -1;
if (!_frameStatic)
{
T t = x;
x = z;
z = t;
}
}
template<class T>
void Euler<T>::extract(const Matrix44<T> &M)
{
int i,j,k;
angleOrder(i,j,k);
if (_initialRepeated)
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][i], M[k][i]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * M;
//
// Extract the other two angles, y and z, from N.
//
T sy = Math<T>::sqrt (N[j][i]*N[j][i] + N[k][i]*N[k][i]);
y = Math<T>::atan2 (sy, N[i][i]);
z = Math<T>::atan2 (N[j][k], N[j][j]);
}
else
{
//
// Extract the first angle, x.
//
x = Math<T>::atan2 (M[j][k], M[k][k]);
//
// Remove the x rotation from M, so that the remaining
// rotation, N, is only around two axes, and gimbal lock
// cannot occur.
//
Vec3<T> r (0, 0, 0);
r[i] = (_parityEven? -x: x);
Matrix44<T> N;
N.rotate (r);
N = N * M;
//
// Extract the other two angles, y and z, from N.
//
T cy = Math<T>::sqrt (N[i][i]*N[i][i] + N[i][j]*N[i][j]);
y = Math<T>::atan2 (-N[i][k], cy);
z = Math<T>::atan2 (-N[j][i], N[j][j]);
}
if (!_parityEven)
*this *= -1;
if (!_frameStatic)
{
T t = x;
x = z;
z = t;
}
}
template<class T>
Matrix33<T> Euler<T>::toMatrix33() const
{
int i,j,k;
angleOrder(i,j,k);
Vec3<T> angles;
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles *= -1.0;
T ci = Math<T>::cos(angles.x);
T cj = Math<T>::cos(angles.y);
T ch = Math<T>::cos(angles.z);
T si = Math<T>::sin(angles.x);
T sj = Math<T>::sin(angles.y);
T sh = Math<T>::sin(angles.z);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
Matrix33<T> M;
if ( _initialRepeated )
{
M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci;
M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss;
}
else
{
M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci;
}
return M;
}
template<class T>
Matrix44<T> Euler<T>::toMatrix44() const
{
int i,j,k;
angleOrder(i,j,k);
Vec3<T> angles;
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles *= -1.0;
T ci = Math<T>::cos(angles.x);
T cj = Math<T>::cos(angles.y);
T ch = Math<T>::cos(angles.z);
T si = Math<T>::sin(angles.x);
T sj = Math<T>::sin(angles.y);
T sh = Math<T>::sin(angles.z);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
Matrix44<T> M;
if ( _initialRepeated )
{
M[i][i] = cj; M[j][i] = sj*si; M[k][i] = sj*ci;
M[i][j] = sj*sh; M[j][j] = -cj*ss+cc; M[k][j] = -cj*cs-sc;
M[i][k] = -sj*ch; M[j][k] = cj*sc+cs; M[k][k] = cj*cc-ss;
}
else
{
M[i][i] = cj*ch; M[j][i] = sj*sc-cs; M[k][i] = sj*cc+ss;
M[i][j] = cj*sh; M[j][j] = sj*ss+cc; M[k][j] = sj*cs-sc;
M[i][k] = -sj; M[j][k] = cj*si; M[k][k] = cj*ci;
}
return M;
}
template<class T>
Quat<T> Euler<T>::toQuat() const
{
Vec3<T> angles;
int i,j,k;
angleOrder(i,j,k);
if ( _frameStatic ) angles = (*this);
else angles = Vec3<T>(z,y,x);
if ( !_parityEven ) angles.y = -angles.y;
T ti = angles.x*0.5;
T tj = angles.y*0.5;
T th = angles.z*0.5;
T ci = Math<T>::cos(ti);
T cj = Math<T>::cos(tj);
T ch = Math<T>::cos(th);
T si = Math<T>::sin(ti);
T sj = Math<T>::sin(tj);
T sh = Math<T>::sin(th);
T cc = ci*ch;
T cs = ci*sh;
T sc = si*ch;
T ss = si*sh;
T parity = _parityEven ? 1.0 : -1.0;
Quat<T> q;
Vec3<T> a;
if ( _initialRepeated )
{
a[i] = cj*(cs + sc);
a[j] = sj*(cc + ss) * parity,
a[k] = sj*(cs - sc);
q.r = cj*(cc - ss);
}
else
{
a[i] = cj*sc - sj*cs,
a[j] = (cj*ss + sj*cc) * parity,
a[k] = cj*cs - sj*sc;
q.r = cj*cc + sj*ss;
}
q.v = a;
return q;
}
template<class T>
inline bool
Euler<T>::legal(typename Euler<T>::Order order)
{
return (order & ~Legal) ? false : true;
}
template<class T>
typename Euler<T>::Order
Euler<T>::order() const
{
int foo = (_initialAxis == Z ? 0x2000 : (_initialAxis == Y ? 0x1000 : 0));
if (_parityEven) foo |= 0x0100;
if (_initialRepeated) foo |= 0x0010;
if (_frameStatic) foo++;
return (Order)foo;
}
template<class T>
inline void Euler<T>::setOrder(typename Euler<T>::Order p)
{
set( p & 0x2000 ? Z : (p & 0x1000 ? Y : X), // initial axis
!(p & 0x1), // static?
!!(p & 0x100), // permutation even?
!!(p & 0x10)); // initial repeats?
}
template<class T>
void Euler<T>::set(typename Euler<T>::Axis axis,
bool relative,
bool parityEven,
bool firstRepeats)
{
_initialAxis = axis;
_frameStatic = !relative;
_parityEven = parityEven;
_initialRepeated = firstRepeats;
}
template<class T>
const Euler<T>& Euler<T>::operator= (const Euler<T> &euler)
{
x = euler.x;
y = euler.y;
z = euler.z;
_initialAxis = euler._initialAxis;
_frameStatic = euler._frameStatic;
_parityEven = euler._parityEven;
_initialRepeated = euler._initialRepeated;
return *this;
}
template<class T>
const Euler<T>& Euler<T>::operator= (const Vec3<T> &v)
{
x = v.x;
y = v.y;
z = v.z;
return *this;
}
template<class T>
std::ostream& operator << (std::ostream &o, const Euler<T> &euler)
{
char a[3] = { 'X', 'Y', 'Z' };
const char* r = euler.frameStatic() ? "" : "r";
int i,j,k;
euler.angleOrder(i,j,k);
if ( euler.initialRepeated() ) k = i;
return o << "("
<< euler.x << " "
<< euler.y << " "
<< euler.z << " "
<< a[i] << a[j] << a[k] << r << ")";
}
template <class T>
float
Euler<T>::angleMod (T angle)
{
const T pi = static_cast<T>(M_PI);
angle = fmod(T (angle), T (2 * pi));
if (angle < -pi) angle += 2 * pi;
if (angle > +pi) angle -= 2 * pi;
return angle;
}
template <class T>
void
Euler<T>::simpleXYZRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot)
{
Vec3<T> d = xyzRot - targetXyzRot;
xyzRot[0] = targetXyzRot[0] + angleMod(d[0]);
xyzRot[1] = targetXyzRot[1] + angleMod(d[1]);
xyzRot[2] = targetXyzRot[2] + angleMod(d[2]);
}
template <class T>
void
Euler<T>::nearestRotation (Vec3<T> &xyzRot, const Vec3<T> &targetXyzRot,
Order order)
{
int i,j,k;
Euler<T> e (0,0,0, order);
e.angleOrder(i,j,k);
simpleXYZRotation(xyzRot, targetXyzRot);
Vec3<T> otherXyzRot;
otherXyzRot[i] = M_PI+xyzRot[i];
otherXyzRot[j] = M_PI-xyzRot[j];
otherXyzRot[k] = M_PI+xyzRot[k];
simpleXYZRotation(otherXyzRot, targetXyzRot);
Vec3<T> d = xyzRot - targetXyzRot;
Vec3<T> od = otherXyzRot - targetXyzRot;
T dMag = d.dot(d);
T odMag = od.dot(od);
if (odMag < dMag)
{
xyzRot = otherXyzRot;
}
}
template <class T>
void
Euler<T>::makeNear (const Euler<T> &target)
{
Vec3<T> xyzRot = toXYZVector();
Vec3<T> targetXyz;
if (order() != target.order())
{
Euler<T> targetSameOrder = Euler<T>(target, order());
targetXyz = targetSameOrder.toXYZVector();
}
else
{
targetXyz = target.toXYZVector();
}
nearestRotation(xyzRot, targetXyz, order());
setXYZVector(xyzRot);
}
#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER
#pragma warning(default:4244)
#endif
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHEULER_H

73
Imath/ImathExc.h Normal file
View File

@ -0,0 +1,73 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHEXC_H
#define INCLUDED_IMATHEXC_H
//-----------------------------------------------
//
// Imath library-specific exceptions
//
//-----------------------------------------------
#include "ImathNamespace.h"
#include "IexBaseExc.h"
#include "ImathExport.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
// Attempt to normalize null vector
DEFINE_EXC_EXP (IMATH_EXPORT, NullVecExc, ::IEX_NAMESPACE::MathExc)
// Attempt to normalize a point at infinity
DEFINE_EXC_EXP (IMATH_EXPORT, InfPointExc, ::IEX_NAMESPACE::MathExc)
// Attempt to normalize null quaternion
DEFINE_EXC_EXP (IMATH_EXPORT, NullQuatExc, ::IEX_NAMESPACE::MathExc)
// Attempt to invert singular matrix
DEFINE_EXC_EXP (IMATH_EXPORT, SingMatrixExc, ::IEX_NAMESPACE::MathExc)
// Attempt to remove zero scaling from matrix
DEFINE_EXC_EXP (IMATH_EXPORT, ZeroScaleExc, ::IEX_NAMESPACE::MathExc)
// Attempt to normalize a vector of whose elementsare an integer type
DEFINE_EXC_EXP (IMATH_EXPORT, IntVecNormalizeExc, ::IEX_NAMESPACE::MathExc)
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHEXC_H

46
Imath/ImathExport.h Normal file
View File

@ -0,0 +1,46 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#if defined(OPENEXR_DLL)
#if defined(IMATH_EXPORTS)
#define IMATH_EXPORT __declspec(dllexport)
#define IMATH_EXPORT_CONST extern __declspec(dllexport)
#else
#define IMATH_EXPORT __declspec(dllimport)
#define IMATH_EXPORT_CONST extern __declspec(dllimport)
#endif
#else
#define IMATH_EXPORT
#define IMATH_EXPORT_CONST extern const
#endif

72
Imath/ImathForward.h Normal file
View File

@ -0,0 +1,72 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHFORWARD_H
#define INCLUDED_IMATHFORWARD_H
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Basic template type declarations.
//
template <class T> class Box;
template <class T> class Color3;
template <class T> class Color4;
template <class T> class Euler;
template <class T> class Frustum;
template <class T> class FrustumTest;
template <class T> class Interval;
template <class T> class Line3;
template <class T> class Matrix33;
template <class T> class Matrix44;
template <class T> class Plane3;
template <class T> class Quat;
template <class T> class Shear6;
template <class T> class Sphere3;
template <class T> class TMatrix;
template <class T> class TMatrixBase;
template <class T> class TMatrixData;
template <class T> class Vec2;
template <class T> class Vec3;
template <class T> class Vec4;
class Rand32;
class Rand48;
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFORWARD_H

192
Imath/ImathFrame.h Normal file
View File

@ -0,0 +1,192 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHFRAME_H
#define INCLUDED_IMATHFRAME_H
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template<class T> class Vec3;
template<class T> class Matrix44;
//
// These methods compute a set of reference frames, defined by their
// transformation matrix, along a curve. It is designed so that the
// array of points and the array of matrices used to fetch these routines
// don't need to be ordered as the curve.
//
// A typical usage would be :
//
// m[0] = IMATH_INTERNAL_NAMESPACE::firstFrame( p[0], p[1], p[2] );
// for( int i = 1; i < n - 1; i++ )
// {
// m[i] = IMATH_INTERNAL_NAMESPACE::nextFrame( m[i-1], p[i-1], p[i], t[i-1], t[i] );
// }
// m[n-1] = IMATH_INTERNAL_NAMESPACE::lastFrame( m[n-2], p[n-2], p[n-1] );
//
// See Graphics Gems I for the underlying algorithm.
//
template<class T> Matrix44<T> firstFrame( const Vec3<T>&, // First point
const Vec3<T>&, // Second point
const Vec3<T>& ); // Third point
template<class T> Matrix44<T> nextFrame( const Matrix44<T>&, // Previous matrix
const Vec3<T>&, // Previous point
const Vec3<T>&, // Current point
Vec3<T>&, // Previous tangent
Vec3<T>& ); // Current tangent
template<class T> Matrix44<T> lastFrame( const Matrix44<T>&, // Previous matrix
const Vec3<T>&, // Previous point
const Vec3<T>& ); // Last point
//
// firstFrame - Compute the first reference frame along a curve.
//
// This function returns the transformation matrix to the reference frame
// defined by the three points 'pi', 'pj' and 'pk'. Note that if the two
// vectors <pi,pj> and <pi,pk> are colinears, an arbitrary twist value will
// be choosen.
//
// Throw 'NullVecExc' if 'pi' and 'pj' are equals.
//
template<class T> Matrix44<T> firstFrame
(
const Vec3<T>& pi, // First point
const Vec3<T>& pj, // Second point
const Vec3<T>& pk ) // Third point
{
Vec3<T> t = pj - pi; t.normalizeExc();
Vec3<T> n = t.cross( pk - pi ); n.normalize();
if( n.length() == 0.0f )
{
int i = fabs( t[0] ) < fabs( t[1] ) ? 0 : 1;
if( fabs( t[2] ) < fabs( t[i] )) i = 2;
Vec3<T> v( 0.0, 0.0, 0.0 ); v[i] = 1.0;
n = t.cross( v ); n.normalize();
}
Vec3<T> b = t.cross( n );
Matrix44<T> M;
M[0][0] = t[0]; M[0][1] = t[1]; M[0][2] = t[2]; M[0][3] = 0.0,
M[1][0] = n[0]; M[1][1] = n[1]; M[1][2] = n[2]; M[1][3] = 0.0,
M[2][0] = b[0]; M[2][1] = b[1]; M[2][2] = b[2]; M[2][3] = 0.0,
M[3][0] = pi[0]; M[3][1] = pi[1]; M[3][2] = pi[2]; M[3][3] = 1.0;
return M;
}
//
// nextFrame - Compute the next reference frame along a curve.
//
// This function returns the transformation matrix to the next reference
// frame defined by the previously computed transformation matrix and the
// new point and tangent vector along the curve.
//
template<class T> Matrix44<T> nextFrame
(
const Matrix44<T>& Mi, // Previous matrix
const Vec3<T>& pi, // Previous point
const Vec3<T>& pj, // Current point
Vec3<T>& ti, // Previous tangent vector
Vec3<T>& tj ) // Current tangent vector
{
Vec3<T> a(0.0, 0.0, 0.0); // Rotation axis.
T r = 0.0; // Rotation angle.
if( ti.length() != 0.0 && tj.length() != 0.0 )
{
ti.normalize(); tj.normalize();
T dot = ti.dot( tj );
//
// This is *really* necessary :
//
if( dot > 1.0 ) dot = 1.0;
else if( dot < -1.0 ) dot = -1.0;
r = acosf( dot );
a = ti.cross( tj );
}
if( a.length() != 0.0 && r != 0.0 )
{
Matrix44<T> R; R.setAxisAngle( a, r );
Matrix44<T> Tj; Tj.translate( pj );
Matrix44<T> Ti; Ti.translate( -pi );
return Mi * Ti * R * Tj;
}
else
{
Matrix44<T> Tr; Tr.translate( pj - pi );
return Mi * Tr;
}
}
//
// lastFrame - Compute the last reference frame along a curve.
//
// This function returns the transformation matrix to the last reference
// frame defined by the previously computed transformation matrix and the
// last point along the curve.
//
template<class T> Matrix44<T> lastFrame
(
const Matrix44<T>& Mi, // Previous matrix
const Vec3<T>& pi, // Previous point
const Vec3<T>& pj ) // Last point
{
Matrix44<T> Tr; Tr.translate( pj - pi );
return Mi * Tr;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFRAME_H

741
Imath/ImathFrustum.h Normal file
View File

@ -0,0 +1,741 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHFRUSTUM_H
#define INCLUDED_IMATHFRUSTUM_H
#include "ImathVec.h"
#include "ImathPlane.h"
#include "ImathLine.h"
#include "ImathMatrix.h"
#include "ImathLimits.h"
#include "ImathFun.h"
#include "ImathNamespace.h"
#include "IexMathExc.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// template class Frustum<T>
//
// The frustum is always located with the eye point at the
// origin facing down -Z. This makes the Frustum class
// compatable with OpenGL (or anything that assumes a camera
// looks down -Z, hence with a right-handed coordinate system)
// but not with RenderMan which assumes the camera looks down
// +Z. Additional functions are provided for conversion from
// and from various camera coordinate spaces.
//
// nearPlane/farPlane: near/far are keywords used by Microsoft's
// compiler, so we use nearPlane/farPlane instead to avoid
// issues.
template<class T>
class Frustum
{
public:
Frustum();
Frustum(const Frustum &);
Frustum(T nearPlane, T farPlane, T left, T right, T top, T bottom, bool ortho=false);
Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
virtual ~Frustum();
//--------------------
// Assignment operator
//--------------------
const Frustum & operator = (const Frustum &);
//--------------------
// Operators: ==, !=
//--------------------
bool operator == (const Frustum<T> &src) const;
bool operator != (const Frustum<T> &src) const;
//--------------------------------------------------------
// Set functions change the entire state of the Frustum
//--------------------------------------------------------
void set(T nearPlane, T farPlane,
T left, T right,
T top, T bottom,
bool ortho=false);
void set(T nearPlane, T farPlane, T fovx, T fovy, T aspect);
//------------------------------------------------------
// These functions modify an already valid frustum state
//------------------------------------------------------
void modifyNearAndFar(T nearPlane, T farPlane);
void setOrthographic(bool);
//--------------
// Access
//--------------
bool orthographic() const { return _orthographic; }
T nearPlane() const { return _nearPlane; }
T hither() const { return _nearPlane; }
T farPlane() const { return _farPlane; }
T yon() const { return _farPlane; }
T left() const { return _left; }
T right() const { return _right; }
T bottom() const { return _bottom; }
T top() const { return _top; }
//-----------------------------------------------------------------------
// Sets the planes in p to be the six bounding planes of the frustum, in
// the following order: top, right, bottom, left, near, far.
// Note that the planes have normals that point out of the frustum.
// The version of this routine that takes a matrix applies that matrix
// to transform the frustum before setting the planes.
//-----------------------------------------------------------------------
void planes(Plane3<T> p[6]) const;
void planes(Plane3<T> p[6], const Matrix44<T> &M) const;
//----------------------
// Derived Quantities
//----------------------
T fovx() const;
T fovy() const;
T aspect() const;
Matrix44<T> projectionMatrix() const;
bool degenerate() const;
//-----------------------------------------------------------------------
// Takes a rectangle in the screen space (i.e., -1 <= left <= right <= 1
// and -1 <= bottom <= top <= 1) of this Frustum, and returns a new
// Frustum whose near clipping-plane window is that rectangle in local
// space.
//-----------------------------------------------------------------------
Frustum<T> window(T left, T right, T top, T bottom) const;
//----------------------------------------------------------
// Projection is in screen space / Conversion from Z-Buffer
//----------------------------------------------------------
Line3<T> projectScreenToRay( const Vec2<T> & ) const;
Vec2<T> projectPointToScreen( const Vec3<T> & ) const;
T ZToDepth(long zval, long min, long max) const;
T normalizedZToDepth(T zval) const;
long DepthToZ(T depth, long zmin, long zmax) const;
T worldRadius(const Vec3<T> &p, T radius) const;
T screenRadius(const Vec3<T> &p, T radius) const;
protected:
Vec2<T> screenToLocal( const Vec2<T> & ) const;
Vec2<T> localToScreen( const Vec2<T> & ) const;
protected:
T _nearPlane;
T _farPlane;
T _left;
T _right;
T _top;
T _bottom;
bool _orthographic;
};
template<class T>
inline Frustum<T>::Frustum()
{
set(T (0.1),
T (1000.0),
T (-1.0),
T (1.0),
T (1.0),
T (-1.0),
false);
}
template<class T>
inline Frustum<T>::Frustum(const Frustum &f)
{
*this = f;
}
template<class T>
inline Frustum<T>::Frustum(T n, T f, T l, T r, T t, T b, bool o)
{
set(n,f,l,r,t,b,o);
}
template<class T>
inline Frustum<T>::Frustum(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
{
set(nearPlane,farPlane,fovx,fovy,aspect);
}
template<class T>
Frustum<T>::~Frustum()
{
}
template<class T>
const Frustum<T> &
Frustum<T>::operator = (const Frustum &f)
{
_nearPlane = f._nearPlane;
_farPlane = f._farPlane;
_left = f._left;
_right = f._right;
_top = f._top;
_bottom = f._bottom;
_orthographic = f._orthographic;
return *this;
}
template <class T>
bool
Frustum<T>::operator == (const Frustum<T> &src) const
{
return
_nearPlane == src._nearPlane &&
_farPlane == src._farPlane &&
_left == src._left &&
_right == src._right &&
_top == src._top &&
_bottom == src._bottom &&
_orthographic == src._orthographic;
}
template <class T>
inline bool
Frustum<T>::operator != (const Frustum<T> &src) const
{
return !operator== (src);
}
template<class T>
void Frustum<T>::set(T n, T f, T l, T r, T t, T b, bool o)
{
_nearPlane = n;
_farPlane = f;
_left = l;
_right = r;
_bottom = b;
_top = t;
_orthographic = o;
}
template<class T>
void Frustum<T>::modifyNearAndFar(T n, T f)
{
if ( _orthographic )
{
_nearPlane = n;
}
else
{
Line3<T> lowerLeft( Vec3<T>(0,0,0), Vec3<T>(_left,_bottom,-_nearPlane) );
Line3<T> upperRight( Vec3<T>(0,0,0), Vec3<T>(_right,_top,-_nearPlane) );
Plane3<T> nearPlane( Vec3<T>(0,0,-1), n );
Vec3<T> ll,ur;
nearPlane.intersect(lowerLeft,ll);
nearPlane.intersect(upperRight,ur);
_left = ll.x;
_right = ur.x;
_top = ur.y;
_bottom = ll.y;
_nearPlane = n;
_farPlane = f;
}
_farPlane = f;
}
template<class T>
void Frustum<T>::setOrthographic(bool ortho)
{
_orthographic = ortho;
}
template<class T>
void Frustum<T>::set(T nearPlane, T farPlane, T fovx, T fovy, T aspect)
{
if (fovx != 0 && fovy != 0)
throw IEX_NAMESPACE::ArgExc ("fovx and fovy cannot both be non-zero.");
const T two = static_cast<T>(2);
if (fovx != 0)
{
_right = nearPlane * Math<T>::tan(fovx / two);
_left = -_right;
_top = ((_right - _left) / aspect) / two;
_bottom = -_top;
}
else
{
_top = nearPlane * Math<T>::tan(fovy / two);
_bottom = -_top;
_right = (_top - _bottom) * aspect / two;
_left = -_right;
}
_nearPlane = nearPlane;
_farPlane = farPlane;
_orthographic = false;
}
template<class T>
T Frustum<T>::fovx() const
{
return Math<T>::atan2(_right,_nearPlane) - Math<T>::atan2(_left,_nearPlane);
}
template<class T>
T Frustum<T>::fovy() const
{
return Math<T>::atan2(_top,_nearPlane) - Math<T>::atan2(_bottom,_nearPlane);
}
template<class T>
T Frustum<T>::aspect() const
{
T rightMinusLeft = _right-_left;
T topMinusBottom = _top-_bottom;
if (abs(topMinusBottom) < 1 &&
abs(rightMinusLeft) > limits<T>::max() * abs(topMinusBottom))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"aspect ratio cannot be computed.");
}
return rightMinusLeft / topMinusBottom;
}
template<class T>
Matrix44<T> Frustum<T>::projectionMatrix() const
{
T rightPlusLeft = _right+_left;
T rightMinusLeft = _right-_left;
T topPlusBottom = _top+_bottom;
T topMinusBottom = _top-_bottom;
T farPlusNear = _farPlane+_nearPlane;
T farMinusNear = _farPlane-_nearPlane;
if ((abs(rightMinusLeft) < 1 &&
abs(rightPlusLeft) > limits<T>::max() * abs(rightMinusLeft)) ||
(abs(topMinusBottom) < 1 &&
abs(topPlusBottom) > limits<T>::max() * abs(topMinusBottom)) ||
(abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear)))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
if ( _orthographic )
{
T tx = -rightPlusLeft / rightMinusLeft;
T ty = -topPlusBottom / topMinusBottom;
T tz = -farPlusNear / farMinusNear;
if ((abs(rightMinusLeft) < 1 &&
2 > limits<T>::max() * abs(rightMinusLeft)) ||
(abs(topMinusBottom) < 1 &&
2 > limits<T>::max() * abs(topMinusBottom)) ||
(abs(farMinusNear) < 1 &&
2 > limits<T>::max() * abs(farMinusNear)))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
T A = 2 / rightMinusLeft;
T B = 2 / topMinusBottom;
T C = -2 / farMinusNear;
return Matrix44<T>( A, 0, 0, 0,
0, B, 0, 0,
0, 0, C, 0,
tx, ty, tz, 1.f );
}
else
{
T A = rightPlusLeft / rightMinusLeft;
T B = topPlusBottom / topMinusBottom;
T C = -farPlusNear / farMinusNear;
T farTimesNear = -2 * _farPlane * _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
T D = farTimesNear / farMinusNear;
T twoTimesNear = 2 * _nearPlane;
if ((abs(rightMinusLeft) < 1 &&
abs(twoTimesNear) > limits<T>::max() * abs(rightMinusLeft)) ||
(abs(topMinusBottom) < 1 &&
abs(twoTimesNear) > limits<T>::max() * abs(topMinusBottom)))
{
throw IEX_NAMESPACE::DivzeroExc ("Bad viewing frustum: "
"projection matrix cannot be computed.");
}
T E = twoTimesNear / rightMinusLeft;
T F = twoTimesNear / topMinusBottom;
return Matrix44<T>( E, 0, 0, 0,
0, F, 0, 0,
A, B, C, -1,
0, 0, D, 0 );
}
}
template<class T>
bool Frustum<T>::degenerate() const
{
return (_nearPlane == _farPlane) ||
(_left == _right) ||
(_top == _bottom);
}
template<class T>
Frustum<T> Frustum<T>::window(T l, T r, T t, T b) const
{
// move it to 0->1 space
Vec2<T> bl = screenToLocal( Vec2<T>(l,b) );
Vec2<T> tr = screenToLocal( Vec2<T>(r,t) );
return Frustum<T>(_nearPlane, _farPlane, bl.x, tr.x, tr.y, bl.y, _orthographic);
}
template<class T>
Vec2<T> Frustum<T>::screenToLocal(const Vec2<T> &s) const
{
return Vec2<T>( _left + (_right-_left) * (1.f+s.x) / 2.f,
_bottom + (_top-_bottom) * (1.f+s.y) / 2.f );
}
template<class T>
Vec2<T> Frustum<T>::localToScreen(const Vec2<T> &p) const
{
T leftPlusRight = _left - T (2) * p.x + _right;
T leftMinusRight = _left-_right;
T bottomPlusTop = _bottom - T (2) * p.y + _top;
T bottomMinusTop = _bottom-_top;
if ((abs(leftMinusRight) < T (1) &&
abs(leftPlusRight) > limits<T>::max() * abs(leftMinusRight)) ||
(abs(bottomMinusTop) < T (1) &&
abs(bottomPlusTop) > limits<T>::max() * abs(bottomMinusTop)))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: "
"local-to-screen transformation cannot be computed");
}
return Vec2<T>( leftPlusRight / leftMinusRight,
bottomPlusTop / bottomMinusTop );
}
template<class T>
Line3<T> Frustum<T>::projectScreenToRay(const Vec2<T> &p) const
{
Vec2<T> point = screenToLocal(p);
if (orthographic())
return Line3<T>( Vec3<T>(point.x,point.y, 0.0),
Vec3<T>(point.x,point.y,-1.0));
else
return Line3<T>( Vec3<T>(0, 0, 0), Vec3<T>(point.x,point.y,-_nearPlane));
}
template<class T>
Vec2<T> Frustum<T>::projectPointToScreen(const Vec3<T> &point) const
{
if (orthographic() || point.z == T (0))
return localToScreen( Vec2<T>( point.x, point.y ) );
else
return localToScreen( Vec2<T>( point.x * _nearPlane / -point.z,
point.y * _nearPlane / -point.z ) );
}
template<class T>
T Frustum<T>::ZToDepth(long zval,long zmin,long zmax) const
{
int zdiff = zmax - zmin;
if (zdiff == 0)
{
throw IEX_NAMESPACE::DivzeroExc
("Bad call to Frustum::ZToDepth: zmax == zmin");
}
if ( zval > zmax+1 ) zval -= zdiff;
T fzval = (T(zval) - T(zmin)) / T(zdiff);
return normalizedZToDepth(fzval);
}
template<class T>
T Frustum<T>::normalizedZToDepth(T zval) const
{
T Zp = zval * 2.0 - 1;
if ( _orthographic )
{
return -(Zp*(_farPlane-_nearPlane) + (_farPlane+_nearPlane))/2;
}
else
{
T farTimesNear = 2 * _farPlane * _nearPlane;
T farMinusNear = Zp * (_farPlane - _nearPlane) - _farPlane - _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc
("Frustum::normalizedZToDepth cannot be computed. The "
"near and far clipping planes of the viewing frustum "
"may be too close to each other");
}
return farTimesNear / farMinusNear;
}
}
template<class T>
long Frustum<T>::DepthToZ(T depth,long zmin,long zmax) const
{
long zdiff = zmax - zmin;
T farMinusNear = _farPlane-_nearPlane;
if ( _orthographic )
{
T farPlusNear = 2*depth + _farPlane + _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: near and far clipping planes "
"are too close to each other");
}
T Zp = -farPlusNear/farMinusNear;
return long(0.5*(Zp+1)*zdiff) + zmin;
}
else
{
// Perspective
T farTimesNear = 2*_farPlane*_nearPlane;
if (abs(depth) < 1 &&
abs(farTimesNear) > limits<T>::max() * abs(depth))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad call to DepthToZ function: value of `depth' "
"is too small");
}
T farPlusNear = farTimesNear/depth + _farPlane + _nearPlane;
if (abs(farMinusNear) < 1 &&
abs(farPlusNear) > limits<T>::max() * abs(farMinusNear))
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: near and far clipping planes "
"are too close to each other");
}
T Zp = farPlusNear/farMinusNear;
return long(0.5*(Zp+1)*zdiff) + zmin;
}
}
template<class T>
T Frustum<T>::screenRadius(const Vec3<T> &p, T radius) const
{
// Derivation:
// Consider X-Z plane.
// X coord of projection of p = xp = p.x * (-_nearPlane / p.z)
// Let q be p + (radius, 0, 0).
// X coord of projection of q = xq = (p.x - radius) * (-_nearPlane / p.z)
// X coord of projection of segment from p to q = r = xp - xq
// = radius * (-_nearPlane / p.z)
// A similar analysis holds in the Y-Z plane.
// So r is the quantity we want to return.
if (abs(p.z) > 1 || abs(-_nearPlane) < limits<T>::max() * abs(p.z))
{
return radius * (-_nearPlane / p.z);
}
else
{
throw IEX_NAMESPACE::DivzeroExc
("Bad call to Frustum::screenRadius: the magnitude of `p' "
"is too small");
}
return radius * (-_nearPlane / p.z);
}
template<class T>
T Frustum<T>::worldRadius(const Vec3<T> &p, T radius) const
{
if (abs(-_nearPlane) > 1 || abs(p.z) < limits<T>::max() * abs(-_nearPlane))
{
return radius * (p.z / -_nearPlane);
}
else
{
throw IEX_NAMESPACE::DivzeroExc
("Bad viewing frustum: the near clipping plane is too "
"close to zero");
}
}
template<class T>
void Frustum<T>::planes(Plane3<T> p[6]) const
{
//
// Plane order: Top, Right, Bottom, Left, Near, Far.
// Normals point outwards.
//
if (! _orthographic)
{
Vec3<T> a( _left, _bottom, -_nearPlane);
Vec3<T> b( _left, _top, -_nearPlane);
Vec3<T> c( _right, _top, -_nearPlane);
Vec3<T> d( _right, _bottom, -_nearPlane);
Vec3<T> o(0,0,0);
p[0].set( o, c, b );
p[1].set( o, d, c );
p[2].set( o, a, d );
p[3].set( o, b, a );
}
else
{
p[0].set( Vec3<T>( 0, 1, 0), _top );
p[1].set( Vec3<T>( 1, 0, 0), _right );
p[2].set( Vec3<T>( 0,-1, 0),-_bottom );
p[3].set( Vec3<T>(-1, 0, 0),-_left );
}
p[4].set( Vec3<T>(0, 0, 1), -_nearPlane );
p[5].set( Vec3<T>(0, 0,-1), _farPlane );
}
template<class T>
void Frustum<T>::planes(Plane3<T> p[6], const Matrix44<T> &M) const
{
//
// Plane order: Top, Right, Bottom, Left, Near, Far.
// Normals point outwards.
//
Vec3<T> a = Vec3<T>( _left, _bottom, -_nearPlane) * M;
Vec3<T> b = Vec3<T>( _left, _top, -_nearPlane) * M;
Vec3<T> c = Vec3<T>( _right, _top, -_nearPlane) * M;
Vec3<T> d = Vec3<T>( _right, _bottom, -_nearPlane) * M;
if (! _orthographic)
{
double s = _farPlane / double(_nearPlane);
T farLeft = (T) (s * _left);
T farRight = (T) (s * _right);
T farTop = (T) (s * _top);
T farBottom = (T) (s * _bottom);
Vec3<T> e = Vec3<T>( farLeft, farBottom, -_farPlane) * M;
Vec3<T> f = Vec3<T>( farLeft, farTop, -_farPlane) * M;
Vec3<T> g = Vec3<T>( farRight, farTop, -_farPlane) * M;
Vec3<T> o = Vec3<T>(0,0,0) * M;
p[0].set( o, c, b );
p[1].set( o, d, c );
p[2].set( o, a, d );
p[3].set( o, b, a );
p[4].set( a, d, c );
p[5].set( e, f, g );
}
else
{
Vec3<T> e = Vec3<T>( _left, _bottom, -_farPlane) * M;
Vec3<T> f = Vec3<T>( _left, _top, -_farPlane) * M;
Vec3<T> g = Vec3<T>( _right, _top, -_farPlane) * M;
Vec3<T> h = Vec3<T>( _right, _bottom, -_farPlane) * M;
p[0].set( c, g, f );
p[1].set( d, h, g );
p[2].set( a, e, h );
p[3].set( b, f, e );
p[4].set( a, d, c );
p[5].set( e, f, g );
}
}
typedef Frustum<float> Frustumf;
typedef Frustum<double> Frustumd;
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#if defined _WIN32 || defined _WIN64
#ifdef _redef_near
#define near
#endif
#ifdef _redef_far
#define far
#endif
#endif
#endif // INCLUDED_IMATHFRUSTUM_H

417
Imath/ImathFrustumTest.h Normal file
View File

@ -0,0 +1,417 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2011-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHFRUSTUMTEST_H
#define INCLUDED_IMATHFRUSTUMTEST_H
//-------------------------------------------------------------------------
//
// This file contains algorithms applied to or in conjunction with
// Frustum visibility testing (Imath::Frustum).
//
// Methods for frustum-based rejection of primitives are contained here.
//
//-------------------------------------------------------------------------
#include "ImathFrustum.h"
#include "ImathBox.h"
#include "ImathSphere.h"
#include "ImathMatrix.h"
#include "ImathVec.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
/////////////////////////////////////////////////////////////////
// FrustumTest
//
// template class FrustumTest<T>
//
// This is a helper class, designed to accelerate the case
// where many tests are made against the same frustum.
// That's a really common case.
//
// The acceleration is achieved by pre-computing the planes of
// the frustum, along with the ablsolute values of the plane normals.
//
//////////////////////////////////////////////////////////////////
// How to use this
//
// Given that you already have:
// Imath::Frustum myFrustum
// Imath::Matrix44 myCameraWorldMatrix
//
// First, make a frustum test object:
// FrustumTest myFrustumTest(myFrustum, myCameraWorldMatrix)
//
// Whenever the camera or frustum changes, call:
// myFrustumTest.setFrustum(myFrustum, myCameraWorldMatrix)
//
// For each object you want to test for visibility, call:
// myFrustumTest.isVisible(myBox)
// myFrustumTest.isVisible(mySphere)
// myFrustumTest.isVisible(myVec3)
// myFrustumTest.completelyContains(myBox)
// myFrustumTest.completelyContains(mySphere)
//
//////////////////////////////////////////////////////////////////
// Explanation of how it works
//
//
// We store six world-space Frustum planes (nx, ny, nz, offset)
//
// Points: To test a Vec3 for visibility, test it against each plane
// using the normal (v dot n - offset) method. (the result is exact)
//
// BBoxes: To test an axis-aligned bbox, test the center against each plane
// using the normal (v dot n - offset) method, but offset by the
// box extents dot the abs of the plane normal. (the result is NOT
// exact, but will not return false-negatives.)
//
// Spheres: To test a sphere, test the center against each plane
// using the normal (v dot n - offset) method, but offset by the
// sphere's radius. (the result is NOT exact, but will not return
// false-negatives.)
//
//
// SPECIAL NOTE: "Where are the dot products?"
// Actual dot products are currently slow for most SIMD architectures.
// In order to keep this code optimization-ready, the dot products
// are all performed using vector adds and multipies.
//
// In order to do this, the plane equations are stored in "transpose"
// form, with the X components grouped into an X vector, etc.
//
template <class T>
class FrustumTest
{
public:
FrustumTest()
{
Frustum<T> frust;
Matrix44<T> cameraMat;
cameraMat.makeIdentity();
setFrustum(frust, cameraMat);
}
FrustumTest(const Frustum<T> &frustum, const Matrix44<T> &cameraMat)
{
setFrustum(frustum, cameraMat);
}
////////////////////////////////////////////////////////////////////
// setFrustum()
// This updates the frustum test with a new frustum and matrix.
// This should usually be called just once per frame.
void setFrustum(const Frustum<T> &frustum, const Matrix44<T> &cameraMat);
////////////////////////////////////////////////////////////////////
// isVisible()
// Check to see if shapes are visible.
bool isVisible(const Sphere3<T> &sphere) const;
bool isVisible(const Box<Vec3<T> > &box) const;
bool isVisible(const Vec3<T> &vec) const;
////////////////////////////////////////////////////////////////////
// completelyContains()
// Check to see if shapes are entirely contained.
bool completelyContains(const Sphere3<T> &sphere) const;
bool completelyContains(const Box<Vec3<T> > &box) const;
// These next items are kept primarily for debugging tools.
// It's useful for drawing the culling environment, and also
// for getting an "outside view" of the culling frustum.
IMATH_INTERNAL_NAMESPACE::Matrix44<T> cameraMat() const {return cameraMatrix;}
IMATH_INTERNAL_NAMESPACE::Frustum<T> currentFrustum() const {return currFrustum;}
protected:
// To understand why the planes are stored this way, see
// the SPECIAL NOTE above.
Vec3<T> planeNormX[2]; // The X compunents from 6 plane equations
Vec3<T> planeNormY[2]; // The Y compunents from 6 plane equations
Vec3<T> planeNormZ[2]; // The Z compunents from 6 plane equations
Vec3<T> planeOffsetVec[2]; // The distance offsets from 6 plane equations
// The absolute values are stored to assist with bounding box tests.
Vec3<T> planeNormAbsX[2]; // The abs(X) compunents from 6 plane equations
Vec3<T> planeNormAbsY[2]; // The abs(X) compunents from 6 plane equations
Vec3<T> planeNormAbsZ[2]; // The abs(X) compunents from 6 plane equations
// These are kept primarily for debugging tools.
Frustum<T> currFrustum;
Matrix44<T> cameraMatrix;
};
////////////////////////////////////////////////////////////////////
// setFrustum()
// This should usually only be called once per frame, or however
// often the camera moves.
template<class T>
void FrustumTest<T>::setFrustum(const Frustum<T> &frustum,
const Matrix44<T> &cameraMat)
{
Plane3<T> frustumPlanes[6];
frustum.planes(frustumPlanes, cameraMat);
// Here's where we effectively transpose the plane equations.
// We stuff all six X's into the two planeNormX vectors, etc.
for (int i = 0; i < 2; ++i)
{
int index = i * 3;
planeNormX[i] = Vec3<T>(frustumPlanes[index + 0].normal.x,
frustumPlanes[index + 1].normal.x,
frustumPlanes[index + 2].normal.x);
planeNormY[i] = Vec3<T>(frustumPlanes[index + 0].normal.y,
frustumPlanes[index + 1].normal.y,
frustumPlanes[index + 2].normal.y);
planeNormZ[i] = Vec3<T>(frustumPlanes[index + 0].normal.z,
frustumPlanes[index + 1].normal.z,
frustumPlanes[index + 2].normal.z);
planeNormAbsX[i] = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].x),
IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].y),
IMATH_INTERNAL_NAMESPACE::abs(planeNormX[i].z));
planeNormAbsY[i] = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].x),
IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].y),
IMATH_INTERNAL_NAMESPACE::abs(planeNormY[i].z));
planeNormAbsZ[i] = Vec3<T>(IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].x),
IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].y),
IMATH_INTERNAL_NAMESPACE::abs(planeNormZ[i].z));
planeOffsetVec[i] = Vec3<T>(frustumPlanes[index + 0].distance,
frustumPlanes[index + 1].distance,
frustumPlanes[index + 2].distance);
}
currFrustum = frustum;
cameraMatrix = cameraMat;
}
////////////////////////////////////////////////////////////////////
// isVisible(Sphere)
// Returns true if any part of the sphere is inside
// the frustum.
// The result MAY return close false-positives, but not false-negatives.
//
template<typename T>
bool FrustumTest<T>::isVisible(const Sphere3<T> &sphere) const
{
Vec3<T> center = sphere.center;
Vec3<T> radiusVec = Vec3<T>(sphere.radius, sphere.radius, sphere.radius);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
- radiusVec
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
- radiusVec
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// completelyContains(Sphere)
// Returns true if every part of the sphere is inside
// the frustum.
// The result MAY return close false-negatives, but not false-positives.
//
template<typename T>
bool FrustumTest<T>::completelyContains(const Sphere3<T> &sphere) const
{
Vec3<T> center = sphere.center;
Vec3<T> radiusVec = Vec3<T>(sphere.radius, sphere.radius, sphere.radius);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
+ radiusVec
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
+ radiusVec
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// isVisible(Box)
// Returns true if any part of the axis-aligned box
// is inside the frustum.
// The result MAY return close false-positives, but not false-negatives.
//
template<typename T>
bool FrustumTest<T>::isVisible(const Box<Vec3<T> > &box) const
{
if (box.isEmpty())
return false;
Vec3<T> center = (box.min + box.max) / 2;
Vec3<T> extent = (box.max - center);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
- planeNormAbsX[0] * extent.x
- planeNormAbsY[0] * extent.y
- planeNormAbsZ[0] * extent.z
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
- planeNormAbsX[1] * extent.x
- planeNormAbsY[1] * extent.y
- planeNormAbsZ[1] * extent.z
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// completelyContains(Box)
// Returns true if every part of the axis-aligned box
// is inside the frustum.
// The result MAY return close false-negatives, but not false-positives.
//
template<typename T>
bool FrustumTest<T>::completelyContains(const Box<Vec3<T> > &box) const
{
if (box.isEmpty())
return false;
Vec3<T> center = (box.min + box.max) / 2;
Vec3<T> extent = (box.max - center);
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = planeNormX[0] * center.x
+ planeNormY[0] * center.y
+ planeNormZ[0] * center.z
+ planeNormAbsX[0] * extent.x
+ planeNormAbsY[0] * extent.y
+ planeNormAbsZ[0] * extent.z
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = planeNormX[1] * center.x
+ planeNormY[1] * center.y
+ planeNormZ[1] * center.z
+ planeNormAbsX[1] * extent.x
+ planeNormAbsY[1] * extent.y
+ planeNormAbsZ[1] * extent.z
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// isVisible(Vec3)
// Returns true if the point is inside the frustum.
//
template<typename T>
bool FrustumTest<T>::isVisible(const Vec3<T> &vec) const
{
// This is a vertical dot-product on three vectors at once.
Vec3<T> d0 = (planeNormX[0] * vec.x)
+ (planeNormY[0] * vec.y)
+ (planeNormZ[0] * vec.z)
- planeOffsetVec[0];
if (d0.x >= 0 || d0.y >= 0 || d0.z >= 0)
return false;
Vec3<T> d1 = (planeNormX[1] * vec.x)
+ (planeNormY[1] * vec.y)
+ (planeNormZ[1] * vec.z)
- planeOffsetVec[1];
if (d1.x >= 0 || d1.y >= 0 || d1.z >= 0)
return false;
return true;
}
typedef FrustumTest<float> FrustumTestf;
typedef FrustumTest<double> FrustumTestd;
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFRUSTUMTEST_H

181
Imath/ImathFun.cpp Normal file
View File

@ -0,0 +1,181 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#include "ImathFun.h"
IMATH_INTERNAL_NAMESPACE_SOURCE_ENTER
float
succf (float f)
{
union {float f; int i;} u;
u.f = f;
if ((u.i & 0x7f800000) == 0x7f800000)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x00000000 || u.i == 0x80000000)
{
// Plus or minus zero.
u.i = 0x00000001;
}
else if (u.i > 0)
{
// Positive float, normalized or denormalized.
// Incrementing the largest positive float
// produces +infinity.
++u.i;
}
else
{
// Negative normalized or denormalized float.
--u.i;
}
return u.f;
}
float
predf (float f)
{
union {float f; int i;} u;
u.f = f;
if ((u.i & 0x7f800000) == 0x7f800000)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x00000000 || u.i == 0x80000000)
{
// Plus or minus zero.
u.i = 0x80000001;
}
else if (u.i > 0)
{
// Positive float, normalized or denormalized.
--u.i;
}
else
{
// Negative normalized or denormalized float.
// Decrementing the largest negative float
// produces -infinity.
++u.i;
}
return u.f;
}
double
succd (double d)
{
union {double d; Int64 i;} u;
u.d = d;
if ((u.i & 0x7ff0000000000000LL) == 0x7ff0000000000000LL)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x0000000000000000LL || u.i == 0x8000000000000000LL)
{
// Plus or minus zero.
u.i = 0x0000000000000001LL;
}
else if (u.d > 0)
{
// Positive double, normalized or denormalized.
// Incrementing the largest positive double
// produces +infinity.
++u.i;
}
else
{
// Negative normalized or denormalized double.
--u.i;
}
return u.d;
}
double
predd (double d)
{
union {double d; Int64 i;} u;
u.d = d;
if ((u.i & 0x7ff0000000000000LL) == 0x7ff0000000000000LL)
{
// Nan or infinity; don't change value.
}
else if (u.i == 0x0000000000000000LL || u.i == 0x8000000000000000LL)
{
// Plus or minus zero.
u.i = 0x8000000000000001LL;
}
else if (u.d > 0)
{
// Positive double, normalized or denormalized.
--u.i;
}
else
{
// Negative normalized or denormalized double.
// Decrementing the largest negative double
// produces -infinity.
++u.i;
}
return u.d;
}
IMATH_INTERNAL_NAMESPACE_SOURCE_EXIT

269
Imath/ImathFun.h Normal file
View File

@ -0,0 +1,269 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHFUN_H
#define INCLUDED_IMATHFUN_H
//-----------------------------------------------------------------------------
//
// Miscellaneous utility functions
//
//-----------------------------------------------------------------------------
#include "ImathExport.h"
#include "ImathLimits.h"
#include "ImathInt64.h"
#include "ImathNamespace.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <class T>
inline T
abs (T a)
{
return (a > T(0)) ? a : -a;
}
template <class T>
inline int
sign (T a)
{
return (a > T(0))? 1 : ((a < T(0)) ? -1 : 0);
}
template <class T, class Q>
inline T
lerp (T a, T b, Q t)
{
return (T) (a * (1 - t) + b * t);
}
template <class T, class Q>
inline T
ulerp (T a, T b, Q t)
{
return (T) ((a > b)? (a - (a - b) * t): (a + (b - a) * t));
}
template <class T>
inline T
lerpfactor(T m, T a, T b)
{
//
// Return how far m is between a and b, that is return t such that
// if:
// t = lerpfactor(m, a, b);
// then:
// m = lerp(a, b, t);
//
// If a==b, return 0.
//
T d = b - a;
T n = m - a;
if (abs(d) > T(1) || abs(n) < limits<T>::max() * abs(d))
return n / d;
return T(0);
}
template <class T>
inline T
clamp (T a, T l, T h)
{
return (a < l)? l : ((a > h)? h : a);
}
template <class T>
inline int
cmp (T a, T b)
{
return IMATH_INTERNAL_NAMESPACE::sign (a - b);
}
template <class T>
inline int
cmpt (T a, T b, T t)
{
return (IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t)? 0 : cmp (a, b);
}
template <class T>
inline bool
iszero (T a, T t)
{
return (IMATH_INTERNAL_NAMESPACE::abs (a) <= t) ? 1 : 0;
}
template <class T1, class T2, class T3>
inline bool
equal (T1 a, T2 b, T3 t)
{
return IMATH_INTERNAL_NAMESPACE::abs (a - b) <= t;
}
template <class T>
inline int
floor (T x)
{
return (x >= 0)? int (x): -(int (-x) + (-x > int (-x)));
}
template <class T>
inline int
ceil (T x)
{
return -floor (-x);
}
template <class T>
inline int
trunc (T x)
{
return (x >= 0) ? int(x) : -int(-x);
}
//
// Integer division and remainder where the
// remainder of x/y has the same sign as x:
//
// divs(x,y) == (abs(x) / abs(y)) * (sign(x) * sign(y))
// mods(x,y) == x - y * divs(x,y)
//
inline int
divs (int x, int y)
{
return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
((y >= 0)? -(-x / y): (-x / -y));
}
inline int
mods (int x, int y)
{
return (x >= 0)? ((y >= 0)? ( x % y): ( x % -y)):
((y >= 0)? -(-x % y): -(-x % -y));
}
//
// Integer division and remainder where the
// remainder of x/y is always positive:
//
// divp(x,y) == floor (double(x) / double (y))
// modp(x,y) == x - y * divp(x,y)
//
inline int
divp (int x, int y)
{
return (x >= 0)? ((y >= 0)? ( x / y): -( x / -y)):
((y >= 0)? -((y-1-x) / y): ((-y-1-x) / -y));
}
inline int
modp (int x, int y)
{
return x - y * divp (x, y);
}
//----------------------------------------------------------
// Successor and predecessor for floating-point numbers:
//
// succf(f) returns float(f+e), where e is the smallest
// positive number such that float(f+e) != f.
//
// predf(f) returns float(f-e), where e is the smallest
// positive number such that float(f-e) != f.
//
// succd(d) returns double(d+e), where e is the smallest
// positive number such that double(d+e) != d.
//
// predd(d) returns double(d-e), where e is the smallest
// positive number such that double(d-e) != d.
//
// Exceptions: If the input value is an infinity or a nan,
// succf(), predf(), succd(), and predd() all
// return the input value without changing it.
//
//----------------------------------------------------------
IMATH_EXPORT float succf (float f);
IMATH_EXPORT float predf (float f);
IMATH_EXPORT double succd (double d);
IMATH_EXPORT double predd (double d);
//
// Return true if the number is not a NaN or Infinity.
//
inline bool
finitef (float f)
{
union {float f; int i;} u;
u.f = f;
return (u.i & 0x7f800000) != 0x7f800000;
}
inline bool
finited (double d)
{
union {double d; Int64 i;} u;
u.d = d;
return (u.i & 0x7ff0000000000000LL) != 0x7ff0000000000000LL;
}
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHFUN_H

166
Imath/ImathGL.h Normal file
View File

@ -0,0 +1,166 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHGL_H
#define INCLUDED_IMATHGL_H
#include <GL/gl.h>
#include "ImathVec.h"
#include "ImathMatrix.h"
#include "IexMathExc.h"
#include "ImathFun.h"
#include "ImathNamespace.h"
inline void glVertex ( const IMATH_INTERNAL_NAMESPACE::V3f &v ) { glVertex3f(v.x,v.y,v.z); }
inline void glVertex ( const IMATH_INTERNAL_NAMESPACE::V2f &v ) { glVertex2f(v.x,v.y); }
inline void glNormal ( const IMATH_INTERNAL_NAMESPACE::V3f &n ) { glNormal3f(n.x,n.y,n.z); }
inline void glColor ( const IMATH_INTERNAL_NAMESPACE::V3f &c ) { glColor3f(c.x,c.y,c.z); }
inline void glTranslate ( const IMATH_INTERNAL_NAMESPACE::V3f &t ) { glTranslatef(t.x,t.y,t.z); }
inline void glTexCoord( const IMATH_INTERNAL_NAMESPACE::V2f &t )
{
glTexCoord2f(t.x,t.y);
}
inline void glDisableTexture()
{
glActiveTexture(GL_TEXTURE1);
glBindTexture(GL_TEXTURE_2D, 0);
glDisable(GL_TEXTURE_2D);
glActiveTexture(GL_TEXTURE0);
}
namespace {
const float GL_FLOAT_MAX = 1.8e+19; // sqrt (FLT_MAX)
inline bool
badFloat (float f)
{
return !IMATH_INTERNAL_NAMESPACE::finitef (f) || f < - GL_FLOAT_MAX || f > GL_FLOAT_MAX;
}
} // namespace
inline void
throwBadMatrix (const IMATH_INTERNAL_NAMESPACE::M44f& m)
{
if (badFloat (m[0][0]) ||
badFloat (m[0][1]) ||
badFloat (m[0][2]) ||
badFloat (m[0][3]) ||
badFloat (m[1][0]) ||
badFloat (m[1][1]) ||
badFloat (m[1][2]) ||
badFloat (m[1][3]) ||
badFloat (m[2][0]) ||
badFloat (m[2][1]) ||
badFloat (m[2][2]) ||
badFloat (m[2][3]) ||
badFloat (m[3][0]) ||
badFloat (m[3][1]) ||
badFloat (m[3][2]) ||
badFloat (m[3][3]))
throw IEX_NAMESPACE::OverflowExc ("GL matrix overflow");
}
inline void
glMultMatrix( const IMATH_INTERNAL_NAMESPACE::M44f& m )
{
throwBadMatrix (m);
glMultMatrixf( (GLfloat*)m[0] );
}
inline void
glMultMatrix( const IMATH_INTERNAL_NAMESPACE::M44f* m )
{
throwBadMatrix (*m);
glMultMatrixf( (GLfloat*)(*m)[0] );
}
inline void
glLoadMatrix( const IMATH_INTERNAL_NAMESPACE::M44f& m )
{
throwBadMatrix (m);
glLoadMatrixf( (GLfloat*)m[0] );
}
inline void
glLoadMatrix( const IMATH_INTERNAL_NAMESPACE::M44f* m )
{
throwBadMatrix (*m);
glLoadMatrixf( (GLfloat*)(*m)[0] );
}
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
//
// Class objects that push/pop the GL state. These objects assist with
// proper cleanup of the state when exceptions are thrown.
//
class GLPushMatrix {
public:
GLPushMatrix () { glPushMatrix(); }
~GLPushMatrix() { glPopMatrix(); }
};
class GLPushAttrib {
public:
GLPushAttrib (GLbitfield mask) { glPushAttrib (mask); }
~GLPushAttrib() { glPopAttrib(); }
};
class GLBegin {
public:
GLBegin (GLenum mode) { glBegin (mode); }
~GLBegin() { glEnd(); }
};
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif

54
Imath/ImathGLU.h Normal file
View File

@ -0,0 +1,54 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHGLU_H
#define INCLUDED_IMATHGLU_H
#include <GL/gl.h>
#include <GL/glu.h>
#include "ImathVec.h"
inline
void
gluLookAt(const IMATH_INTERNAL_NAMESPACE::V3f &pos, const IMATH_INTERNAL_NAMESPACE::V3f &interest, const IMATH_INTERNAL_NAMESPACE::V3f &up)
{
gluLookAt(pos.x, pos.y, pos.z,
interest.x, interest.y, interest.z,
up.x, up.y, up.z);
}
#endif

68
Imath/ImathHalfLimits.h Normal file
View File

@ -0,0 +1,68 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2002-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATHHALFLIMITS_H
#define INCLUDED_IMATHHALFLIMITS_H
//--------------------------------------------------
//
// Imath-style limits for class half.
//
//--------------------------------------------------
#include "ImathLimits.h"
#include "ImathNamespace.h"
#include "half.h"
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
template <>
struct limits <half>
{
static float min() {return -HALF_MAX;}
static float max() {return HALF_MAX;}
static float smallest() {return HALF_MIN;}
static float epsilon() {return HALF_EPSILON;}
static bool isIntegral() {return false;}
static bool isSigned() {return true;}
};
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATHHALFLIMITS_H

65
Imath/ImathInt64.h Normal file
View File

@ -0,0 +1,65 @@
///////////////////////////////////////////////////////////////////////////
//
// Copyright (c) 2006-2012, Industrial Light & Magic, a division of Lucas
// Digital Ltd. LLC
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Industrial Light & Magic nor the names of
// its contributors may be used to endorse or promote products derived
// from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
///////////////////////////////////////////////////////////////////////////
#ifndef INCLUDED_IMATH_INT64_H
#define INCLUDED_IMATH_INT64_H
//----------------------------------------------------------------------------
//
// Int64 -- unsigned 64-bit integers
//
//----------------------------------------------------------------------------
#include "ImathNamespace.h"
#include <limits.h>
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER
#if (defined _WIN32 || defined _WIN64) && _MSC_VER >= 1300
typedef unsigned __int64 Int64;
typedef __int64 SInt64;
#elif ULONG_MAX == 18446744073709551615LU
typedef long unsigned int Int64;
typedef long int SInt64;
#else
typedef long long unsigned int Int64;
typedef long long int SInt64;
#endif
IMATH_INTERNAL_NAMESPACE_HEADER_EXIT
#endif // INCLUDED_IMATH_INT64_H

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