diff --git a/build/unix/Makefile.am b/build/unix/Makefile.am
index cc23cab..e311ca1 100644
--- a/build/unix/Makefile.am
+++ b/build/unix/Makefile.am
@@ -1,10 +1,54 @@
ACLOCAL_AMFLAGS = -I m4
-warningflags = -Wall -Wextra -Wshadow -Wno-expansion-to-defined -Wno-missing-field-initializers
+warningflags = \
+ -Wall \
+ -Wextra \
+ -Wshadow \
+ -Wunused \
+ -Wnull-dereference \
+ -Wvla \
+ -Wstrict-aliasing \
+ -Wuninitialized \
+ -Wunused-parameter \
+ -Wreorder \
+ -Wsign-compare \
+ -Wunreachable-code \
+ -Wconversion \
+ -Wno-sign-conversion \
+ $(COMPWARNFLAGS)
+
+if CLG
+
+# Clang
+warningflags += \
+ -Wshadow-all \
+ -Wshorten-64-to-32 \
+ -Wint-conversion \
+ -Wconditional-uninitialized \
+ -Wconstant-conversion \
+ -Wunused-private-field \
+ -Wbool-conversion \
+ -Wextra-semi \
+ -Wnullable-to-nonnull-conversion \
+ -Wno-unused-private-field \
+ -Wno-unused-command-line-argument
+# -Wzero-as-null-pointer-constant
+
+else
+
+# GCC
+warningflags += \
+ -Wredundant-decls \
+ -Wno-ignored-attributes \
+ -Wno-expansion-to-defined
+
+endif
+
+warnflagscpp =
includeflags = -I$(srcdir)/../../src
-commonflags = $(DEBUGCFLAGS) $(MFLAGS) $(warningflags) $(includeflags)
-AM_CXXFLAGS = -std=$(CXXSTD) $(commonflags)
-AM_LDFLAGS = $(PLUGINLDFLAGS)
+commoncflags = $(DEBUGCFLAGS) $(MFLAGS) $(warningflags) $(includeflags) $(STACKREALIGN)
+AM_CXXFLAGS = -std=$(CXXSTD) $(commoncflags) $(warnflagscpp) $(EXTRA_CXXFLAGS)
+AM_LDFLAGS = $(PLUGINLDFLAGS)
lib_LTLIBRARIES = libfmtconv.la
@@ -52,8 +96,6 @@ libfmtconv_la_SOURCES = \
../../src/conc/ObjPool.h \
../../src/conc/ObjPool.hpp \
../../src/ffft/def.h \
- ../../src/ffft/DynArray.h \
- ../../src/ffft/DynArray.hpp \
../../src/ffft/FFTReal.h \
../../src/ffft/FFTReal.hpp \
../../src/ffft/OscSinCos.h \
@@ -129,6 +171,8 @@ libfmtconv_la_SOURCES = \
../../src/fmtcl/DiscreteFirCustom.h \
../../src/fmtcl/DiscreteFirInterface.cpp \
../../src/fmtcl/DiscreteFirInterface.h \
+ ../../src/fmtcl/Dither.cpp \
+ ../../src/fmtcl/Dither.h \
../../src/fmtcl/ErrDifBuf.cpp \
../../src/fmtcl/ErrDifBuf.h \
../../src/fmtcl/ErrDifBuf.hpp \
@@ -138,6 +182,7 @@ libfmtconv_la_SOURCES = \
../../src/fmtcl/FilterResize.h \
../../src/fmtcl/fnc.cpp \
../../src/fmtcl/fnc.h \
+ ../../src/fmtcl/InterlacingType.h \
../../src/fmtcl/KernelData.cpp \
../../src/fmtcl/KernelData.h \
../../src/fmtcl/Mat3.h \
@@ -150,9 +195,14 @@ libfmtconv_la_SOURCES = \
../../src/fmtcl/MatrixProc.cpp \
../../src/fmtcl/MatrixProc.h \
../../src/fmtcl/MatrixProc_macro.h \
+ ../../src/fmtcl/MatrixUtil.cpp \
+ ../../src/fmtcl/MatrixUtil.h \
../../src/fmtcl/MatrixWrap.h \
../../src/fmtcl/MatrixWrap.hpp \
+ ../../src/fmtcl/PicFmt.h \
../../src/fmtcl/PrimariesPreset.h \
+ ../../src/fmtcl/PrimUtil.cpp \
+ ../../src/fmtcl/PrimUtil.h \
../../src/fmtcl/Proxy.h \
../../src/fmtcl/Proxy.hpp \
../../src/fmtcl/ProxyRwCpp.h \
@@ -163,8 +213,11 @@ libfmtconv_la_SOURCES = \
../../src/fmtcl/ReadWrapperFlt.hpp \
../../src/fmtcl/ReadWrapperInt.h \
../../src/fmtcl/ReadWrapperInt.hpp \
+ ../../src/fmtcl/ResamplePlaneData.h \
../../src/fmtcl/ResampleSpecPlane.cpp \
../../src/fmtcl/ResampleSpecPlane.h \
+ ../../src/fmtcl/ResampleUtil.cpp \
+ ../../src/fmtcl/ResampleUtil.h \
../../src/fmtcl/ResizeData.cpp \
../../src/fmtcl/ResizeData.h \
../../src/fmtcl/ResizeData.hpp \
@@ -212,6 +265,8 @@ libfmtconv_la_SOURCES = \
../../src/fmtcl/TransOpSLog.h \
../../src/fmtcl/TransOpSLog3.cpp \
../../src/fmtcl/TransOpSLog3.h \
+ ../../src/fmtcl/TransUtil.cpp \
+ ../../src/fmtcl/TransUtil.h \
../../src/fmtcl/Vec3.h \
../../src/fmtcl/Vec3.hpp \
../../src/fmtcl/VoidAndCluster.cpp \
@@ -223,7 +278,7 @@ libfmtconv_la_SOURCES = \
../../src/fstb/CpuId.cpp \
../../src/fstb/CpuId.h \
../../src/fstb/def.h \
- ../../src/fstb/fnc.cpp \
+ ../../src/fstb/fnc_fstb.cpp \
../../src/fstb/fnc.h \
../../src/fstb/fnc.hpp \
../../src/fstb/SingleObj.h \
diff --git a/build/unix/configure.ac b/build/unix/configure.ac
index 0a52132..65676fb 100644
--- a/build/unix/configure.ac
+++ b/build/unix/configure.ac
@@ -1,4 +1,4 @@
-AC_INIT([fmtconv], [r22], [http://forum.doom9.org/showthread.php?t=166504], [fmtconv], [http://forum.doom9.org/showthread.php?t=166504])
+AC_INIT([fmtconv], [r23], [http://forum.doom9.org/showthread.php?t=166504], [fmtconv], [http://forum.doom9.org/showthread.php?t=166504])
AC_CONFIG_MACRO_DIR([m4])
AM_INIT_AUTOMAKE([foreign no-dist-gzip dist-xz subdir-objects no-define])
@@ -6,32 +6,26 @@ AM_SILENT_RULES([yes])
LT_INIT([win32-dll disable-static])
+: ${CXXFLAGS=""}
+: ${CFLAGS=""}
+
AC_PROG_CXX
+AC_PROG_CC
AC_CANONICAL_HOST
AC_ARG_ENABLE([debug], AS_HELP_STRING([--enable-debug], [Compilation options required for debugging. [default=no]]))
+AC_ARG_ENABLE([clang], AS_HELP_STRING([--enable-clang], [Use Clang as compiler along with libc++. [default=no]]))
-AC_LANG_PUSH([C++])
-AS_IF([test "x$CXXSTD" = "x"], AX_CHECK_COMPILE_FLAG([-std=c++17], [CXXSTD="c++17"]))
-AS_IF([test "x$CXXSTD" = "x"], AX_CHECK_COMPILE_FLAG([-std=c++11], [CXXSTD="c++11"]))
-AS_IF([test "x$CXXSTD" = "x"], AC_MSG_ERROR([Minimum requirement: C++11]))
-AX_CHECK_COMPILE_FLAG([-Wunused-private-field] , [CXXFLAGS="$CXXFLAGS -Wno-unused-private-field"] , , [-Werror])
-AX_CHECK_COMPILE_FLAG([-Wunused-command-line-argument], [CXXFLAGS="$CXXFLAGS -Wno-unused-command-line-argument"], , [-Werror])
-AC_LANG_POP([C++])
-# It seems that -latomic is needed only for some versions of GCC < 5.3
-AX_CHECK_LINK_FLAG([-latomic], [LIBS="$LIBS -latomic"])
-
-AS_IF(
- [test "x$enable_debug" = "xyes"],
- [DEBUGCFLAGS="-O0 -g3 -ggdb"],
- [DEBUGCFLAGS="-O3 -g3 -DNDEBUG"]
-)
X86="false"
PPC="false"
ARM="false"
+WIN="false"
+UNX="false"
+MAC="false"
+CLG="false"
AS_CASE(
[$host_cpu],
@@ -44,21 +38,62 @@ AS_CASE(
AS_CASE(
[$host_os],
- [cygwin*|mingw*],
- [AS_IF(
- [test "x$BITS" = "x32"],
- [
- PLUGINLDFLAGS="-Wl,--kill-at"
- STACKREALIGN="-mstackrealign"
- ]
- )]
+ [cygwin*|mingw*], [WIN="true"],
+ [darwin*], [MAC="true"],
+ [*linux*|gnu*|dragonfly*|*bsd*], [UNX="true"]
)
AS_IF(
- [test "x$X86" = "xtrue"],
+ [test "x$enable_debug" = "xyes"],
+ [
+ DEBUGCFLAGS="-O0 -g3 -ggdb"
+ AC_MSG_NOTICE([Debug mode enabled.])
+ ],
+ [DEBUGCFLAGS="-O3 -g3 -DNDEBUG"]
+)
+
+AS_IF(
+ [test "x$enable_clang" = "xyes"],
+ [
+ CLG="true"
+ CXX="clang++"
+ CC="clang"
+ LD="clang++"
+ MFLAGS="$MFLAGS -fexperimental-new-pass-manager -mllvm -inline-threshold=1000"
+ COMPWARNFLAGS=""
+ AC_MSG_NOTICE([Using clang as compiler.])
+ ],
+ [COMPWARNFLAGS="-Wduplicated-cond -Wduplicated-branches -Wlogical-op"]
+)
+
+AC_LANG_PUSH([C++])
+#AS_IF([test "x$CXXSTD" = "x"], AX_CHECK_COMPILE_FLAG([-std=c++20], [CXXSTD="c++20"]))
+#AS_IF([test "x$CXXSTD" = "x"], AX_CHECK_COMPILE_FLAG([-std=c++17], [CXXSTD="c++17"]))
+AS_IF([test "x$CXXSTD" = "x"], AX_CHECK_COMPILE_FLAG([-std=c++14], [CXXSTD="c++14"]))
+AS_IF([test "x$CXXSTD" = "x"], AC_MSG_ERROR([Minimum requirement: C++14]))
+AC_LANG_POP([C++])
+
+# It seems that -latomic is needed only for some versions of GCC < 5.3
+AX_CHECK_LINK_FLAG([-latomic], [LIBS="$LIBS -latomic"])
+
+AS_IF(
+ [test "x$WIN" = "xtrue"],
[
- MFLAGS="-mfpmath=sse -msse2 -Wno-ignored-attributes"
+ AS_IF(
+ [test "x$BITS" = "x32"],
+ [
+ PLUGINLDFLAGS="-Wl,--kill-at"
+ STACKREALIGN="-mstackrealign"
+ ]
+ )
+ ]
+)
+AS_IF(
+ [test "x$X86" = "xtrue"],
+ [
+ MFLAGS="$MFLAGS -mfpmath=sse -msse2"
+ COMPWARNFLAGS="$COMPWARNFLAGS -Wno-ignored-attributes"
# We need this to use CMPXCHG16B for 2x64-bit CAS (compare and swap)
AS_IF([test "x$BITS" = "x64"], [MFLAGS="$MFLAGS -mcx16"])
]
@@ -72,19 +107,27 @@ AS_IF(
AX_CHECK_COMPILE_FLAG([-mfpu=neon], [MFLAGS="$MFLAGS -mfpu=neon"])
# GCC 7 emits some warnings about ABI changes when using std::vector
- AX_CHECK_COMPILE_FLAG([-Wpsabi -Werror], [MFLAGS="$MFLAGS -Wno-psabi"])
+ AX_CHECK_COMPILE_FLAG([-Wpsabi], [COMPWARNFLAGS="$COMPWARNFLAGS -Wno-psabi"], , [-Werror])
]
)
+AX_CHECK_COMPILE_FLAG([-Wmisleading-indentation] , [COMPWARNFLAGS="$COMPWARNFLAGS -Wmisleading-indentation"] , , [-Werror])
+# Clang only
+AX_CHECK_COMPILE_FLAG([-Wno-implicit-int-float-conversion], [COMPWARNFLAGS="$COMPWARNFLAGS -Wno-implicit-int-float-conversion"], , [-Werror])
+
+AC_SUBST([CXXSTD])
+AC_SUBST([EXTRA_CXXFLAGS])
+AC_SUBST([LDFLAGS])
AC_SUBST([MFLAGS])
AC_SUBST([DEBUGCFLAGS])
-AC_SUBST([CXXSTD])
AC_SUBST([PLUGINLDFLAGS])
AC_SUBST([STACKREALIGN])
AM_CONDITIONAL([X86], [test "x$X86" = "xtrue"])
AM_CONDITIONAL([ARM], [test "x$ARM" = "xtrue"])
-
+AM_CONDITIONAL([UNX], [test "x$UNX" = "xtrue"])
+AM_CONDITIONAL([WIN], [test "x$WIN" = "xtrue"])
+AM_CONDITIONAL([CLG], [test "x$CLG" = "xtrue"])
AC_CONFIG_FILES([Makefile])
AC_OUTPUT
diff --git a/build/win/fmtconv.vcxproj b/build/win/fmtconv.vcxproj
index 6190cf5..c8f1bed 100644
--- a/build/win/fmtconv.vcxproj
+++ b/build/win/fmtconv.vcxproj
@@ -32,10 +32,11 @@
Unicode
- true
+ true
+ false
- false
+ false
true
@@ -45,8 +46,13 @@
+
+ true
+
+
+ false
+
- <_ProjectFileVersion>10.0.30319.1
$(ProjectDir)$(Configuration)$(Platform)\
$(ProjectDir)$(Configuration)$(Platform)\
AllRules.ruleset
@@ -57,11 +63,13 @@
Disabled
_DEBUG;%(PreprocessorDefinitions)
- true
EnableFastChecks
MultiThreadedDebug
true
+
+ true
+
@@ -74,6 +82,7 @@
true
+ true
true
true
@@ -102,8 +111,11 @@
Level4
- 4127;4505
+ 4127
ProgramDatabase
+ true
+ true
+ /Zc:__cplusplus %(AdditionalOptions)
true
@@ -136,11 +148,13 @@
+
+
@@ -150,9 +164,12 @@
+
+
+
@@ -165,7 +182,9 @@
+
+
@@ -197,6 +216,7 @@
+
@@ -269,8 +289,6 @@
-
-
@@ -311,6 +329,7 @@
+
@@ -327,7 +346,10 @@
AdvancedVectorExtensions2
+
+
+
@@ -353,6 +375,7 @@
+
@@ -378,14 +401,15 @@
-
- $(IntDir)%(Filename)1.obj
- $(IntDir)%(Filename)1.xdc
-
+
+
+
+
+
diff --git a/build/win/fmtconv.vcxproj.filters b/build/win/fmtconv.vcxproj.filters
index 93e2181..1bf331d 100644
--- a/build/win/fmtconv.vcxproj.filters
+++ b/build/win/fmtconv.vcxproj.filters
@@ -177,12 +177,6 @@
ffft
-
- ffft
-
-
- ffft
-
ffft
@@ -532,6 +526,30 @@
fmtcl
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
@@ -561,7 +579,7 @@
vsutl
-
+
fstb
@@ -756,5 +774,24 @@
fmtcl
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+ fmtcl
+
+
+
+
+
\ No newline at end of file
diff --git a/build/win/toolset.props b/build/win/toolset.props
index 4227e63..8e24a0c 100644
--- a/build/win/toolset.props
+++ b/build/win/toolset.props
@@ -4,9 +4,9 @@
<_ProjectFileVersion>12.0.30501.0
- v141_xp
+ v142
- v141
+ v142
\ No newline at end of file
diff --git a/doc/fmtconv.html b/doc/fmtconv.html
index 8cc575a..2a0b9fe 100644
--- a/doc/fmtconv.html
+++ b/doc/fmtconv.html
@@ -15,7 +15,7 @@
Abstract
Authors: Firesledge (aka Cretindesalpes)
-Version: r22
+Version: r23
Download: http://ldesoras.free.fr/prod.html
Category: Format tools
Requirements: Vapoursynth
@@ -205,7 +205,7 @@ Compiling from the source code
Visual C++
-Visual Studio 2013 or later is required, previous versions are
+
Visual Studio 2019 or later is required, previous versions are
not supported anymore.
Just load build/win/fmtconv.sln
and run the compiler.
@@ -215,7 +215,6 @@ Visual C++
Add .
(the src
directory) as include path.
-Use the v120_xp
toolset for the 32-bit version.
For the whole project, enable the SS2 instruction set.
Enable the AVX2 instruction set for the *.cpp
files containing avx2
in their name, and the AVX set for the avx
files.
Enable optimizations maximizing speed and “any suitable” functions for inlining.
@@ -223,13 +222,18 @@ Visual C++
GNU/Linux and other Unix-like systems
-On Linux and similar GNU-based systems, the build
directory
-contains autotools settings:
+On Linux and similar GNU-based systems (including MSYS2 and Cygwin), the
+build
directory contains autotools settings:
cd build/unix
./autogen.sh
./configure
make
make install
+You can add some options to the configure
command:
+
+--enable-debug
to activate debugging code
+--enable-clang
to use Clang instead of the default compiler, usually GCC
+
GCC
@@ -247,7 +251,7 @@ GCC
Add AvstpFinder.cpp
on Windows.
Use the following options (on a single line):
--std=c++11 -shared -fabi-version=6 -msse2 -mcx16 -O3 -DNDEBUG -I.
+-std=c++14 -shared -fabi-version=6 -msse2 -mcx16 -O3 -DNDEBUG -I.
-Wall -Wextra -Wno-unused-parameter -Wno-unused-result -Wno-missing-field-initializers -Wshadow
-Wno-unused-private-field
@@ -276,7 +280,7 @@ GCC
Link with -latomic -lpthread
.
With MinGW, it seems you will need a specific MinGW-64 build supporting
-C++11 threading (not tested here yet, please report if you find something
+C++14 threading (not tested here yet, please report if you find something
useful).
III) Filters description
@@ -298,6 +302,9 @@ bitdepth
staticnoise: int : opt; (False)
cpuopt : int : opt; (-1)
patsize : int : opt; (32)
+ tpdfo : int : opt; (0)
+ tpdfn : int : opt; (0)
+ corplane : int : opt; (0)
)
@@ -309,14 +316,14 @@ bitdepth
Doing a full-range ↔ TV-range conversion between integer formats, because the resulting values haven’t an exact representation.
-Pure ordered dithering seems to be retained better than noise or error
-diffusion by video compression in 8 bits.
-Therefore this is the recommended method to avoid color banding, unless you
-encode at very high bitrates.
-If you don’t care about video compression, error diffusion gives the most
-accurate results.
-To avoid discontinuities between purely flat areas and dithered areas, you
-can add a bit of noise.
+Video compression seems to retrain better pure ordered (Bayer) dithering.
+Therefore this is the recommended method to avoid color banding in 8 bit
+signals, unless you encode at high bitrates.
+If you don’t care about video compression, error diffusion, void and cluster
+and quasirandom sequence methods give the most accurate results.
+To avoid discontinuities between purely flat areas and dithered areas (also
+called noise modulation), you can add a bit of noise, ideally in triangular
+distribution.
The internal noise generator is deterministic and will give the same result
each run.
@@ -381,10 +388,11 @@ Parameters
2 Round, may be a bit faster but possibly less accurate.
3 Sierra-2-4A error diffusion, aka “Filter Lite”. Quick and excellent quality, similar to Floyd-Steinberg.
4 Stucki error diffusion. Preserves delicate edges better but distorts gradients.
-5 Atkinson error diffusion. Generates distinct patterns but keeps clean the flat areas.
-6 Floyd-Steinberg error diffusion. Classic.
+5 Atkinson error diffusion. Generates distinct patterns but keeps clean the flat areas (noise modulation).
+6 Classic Floyd-Steinberg error diffusion, modified for serpentine scan (avoids worm artefacts).
7 Ostromoukhov error diffusion . Slow, available only for integer input at the moment. Avoids usual F-S artefacts.
-8 Void and cluster halftone dithering. Better visual aspect than ordered dithering.
+8 Void and cluster halftone dithering. This is a way to generate blue-noise dither and has a much better visual aspect than ordered dithering.
+9 Dither using quasirandom sequences . Good intermediated between Void and cluster and error diffusion algorithms.
When using error-diffusion dithering on interlaced content, you should
@@ -408,7 +416,7 @@
Parameters
dyn
Indicates if the ordered dither pattern is dynamic (True) or static (False).
-If dynamic, the pattern is rotated each frame.
+If dynamic, the pattern is changed or rotated each frame.
staticnoise
If set to 1, the noise generated with ampn is static
@@ -425,6 +433,27 @@
Parameters
Width of the pattern used in the Void and cluster algorithm.
The only valid values are 4, 8, 16 and 32.
+tpdfo
+Set it to 1 to enable the triangular probability distribution function
+(TPDF) for halftone-based dithering algorithms.
+It has no effect on error diffusion methods.
+0 is the standard rectangular distribution (RPDF).
+Note that when triangular distribution is enabled, the maximum halftone
+amplitude is multiplied by 1.414 at constant ampo .
+
+tpdfn
+Same as tpdfo , but for the additive noise part.
+TPDF noise looks more natural than RPDF noise, and is a crude approximation of
+a gaussian noise, with a bounded amplitude.
+Maximum noise amplitude is multiplied by 1.414 at constant ampn ,
+so the introduced noise power is kept approximately constant.
+
+corplane
+Set it to 1 to keep the dither and noise patterns correlated for all the
+planes.
+When processing a RGB picture, it helps to prevent colored noise on grey
+features.
+
convert
@@ -502,7 +531,7 @@ convert
cplaced : data : opt; (cplace)
matd : data : opt;
- # Transfert curve parameters
+ # Transfer curve parameters
transs : data[] : opt;
transd : data[] : opt;
cont : float : opt;
@@ -1361,6 +1390,8 @@ transfer
flt : int : opt;
fulls : int : opt; (True)
fulld : int : opt; (True)
+ logceis : int : opt; (800)
+ logceid : int : opt; (800)
cpuopt : int : opt; (-1)
blacklvl : float : opt; (0)
)
@@ -1427,8 +1458,8 @@ Parameters
"slog"
−0.006…10 Sony S-Log Linear 1.0 is the reference white, peak white is at 10.0.
"slog2"
−0.0085…14.13 Sony S-Log 2 Linear 1.0 is the reference white, peak white is at 14.13.
"slog3"
0…38.421 Sony S-Log3.
-"logc2"
Unspecified Arri Log C Alexa 2.x (800 EI), linear scene exposure Peak white is 57.45 linear. The negative part of the range allows coding sensor noise.
-"logc3"
Unspecified Arri Log C Alexa 3.x (800 EI), linear scene exposure Peak white is 55.08 linear. The negative part of the range allows coding sensor noise.
+"logc2"
Unspecified Arri Log C Alexa 2.x, linear scene exposure Peak white is 57.45 linear. The negative part of the range allows coding sensor noise. logceis and logceid set the Exposure Index (EI).
+"logc3"
Unspecified Arri Log C Alexa 3.x, linear scene exposure Peak white is 55.08 linear. The negative part of the range allows coding sensor noise. logceis and logceid set the Exposure Index (EI).
"canonlog"
0…8.00903 Canon-Log Peak white is 8.00903 in linear scale and 1.08676 in compressed scale.
"adobergb"
0…1 Adobe RGB (1998 and Wide Gamut)
"romm"
0…1 ProPhoto, ROMM
@@ -1468,6 +1499,11 @@ Parameters
in TV-range (16 to 240 for the Y’Cb’Cr’ chroma planes).
This value has no meaning for float data.
+logceis, logceid
+Exposure index (EI) for the Arri Log C Alexa 2.x and 3.x curves.
+Allowed values are:
+160, 200, 250, 320, 400, 500, 640, 800 (default), 1000, 1280 and 1600.
+
cpuopt
Limits the CPU instruction set.
−1: automatic (no limitation),
@@ -1524,7 +1560,23 @@
IV) Troubleshooting
V) Changelog
-r22, 2019.12.11
+r24, 202?-??-??
+
+bitdepth
: added dithering mode 9: quasirandom sequences.
+bitdepth
: added a triangular probability distribution function (TPDF) for the dithering patterns and noises, along with the associated parameters tpdfo and tpdfn .
+bitdepth
: added corplane parameter to prevent colored noise in RGB processing.
+
+
+r23, 2021-07-14
+
+transfer
: added an Exposure Index (EI) parameter for the Arri Log C Alexa 2.x and 3.x curves.
+bitdepth
: properly sets the _ColorRange
attribute.
+Doesn’t output a debug message when AVSTP is not found.
+Fixed a concurrency issue by using a more recent toolkit when compiling with MSVC.
+Windows XP is not supported any more.
+
+
+r22, 2019-12-11
bitdepth
: upconversions for full range data now scale to the maximum value instead of shifting bits. Thanks to Z4ST1N for the report.
matrix
: added support for the YDzDx, ICtCp-PQ and ICtCp-HLG colorspaces.
@@ -1543,25 +1595,25 @@ V) Changelog
Fixed compilation for Linux on ARM or aarch64. Binaries not tested yet.
-r21, 2019.12.08
+r21, 2019-12-08
transfer
: fixed highlight clipping for several high dynamic range transfer curves, thanks to groucho86 for the report.
-r20, 2016.03.25
+r20, 2016-03-25
primaries
: fixed a bug preventing to set all primaries individually without specifying any preset.
primaries
: fixed a bug in the color conversion, thanks to J1Man for having spotted it.
-r19, 2016.03.19
+r19, 2016-03-19
primaries
: refined the values for the Adobe Wide gamut and BT.2020 primaries.
primaries
: added DCI-P3, ACES AP0/AP1, S-Gamut, S-Gamut3.Cine, ALEXA and V-Gamut presets.
transfer
: added ACEScc, ERIMM, S-Log2, S-Log3 and V-Log curves.
-r18, 2016.03.08
+r18, 2016-03-08
Added the primaries
function to convert between gamuts.
The “full” range is now closer to what is specified in the standards.
@@ -1569,7 +1621,7 @@ V) Changelog
transfer
: added the Adobe RGB and ProPhoto / ROMM curves.
-r17, 2015.07.08
+r17, 2015-07-08
bitdepth
: added “Void and cluster” dithering method and its patsize parameter.
bitdepth
: added floating point implementation for the Ostromoukhov dithering
@@ -1577,7 +1629,7 @@ V) Changelog
bitdepth
: fixed incorrect conversion from float to 8-bit integer using the “fast” modes with SSE2 instruction set.
-r16, 2015.07.01
+r16, 2015-07-01
bitdepth
: added support for 11-bit and 14-bit integer input.
bitdepth
: fixed a slight plane inconsistency when dithering grey multi-plane pictures using an error diffusion algorithm.
@@ -1586,18 +1638,18 @@ V) Changelog
transfer
: added the blacklvl parameter.
-r15, 2015.05.22
+r15, 2015-05-22
resample
and bitdepth
: fixed a bug creating dark lines or weird patterns. Was introduced in r13 while trying to fix the buffer overflow problem. Thanks to feisty2 for spotting it.
resample
: fixed the non-SIMD code path, causing crashes.
-r14, 2015.05.20
+r14, 2015-05-20
matrix
: fixed a bug introducing wrong offsets in custom matrix coefficients, thanks to mawen1250 for the report.
-r13, 2015.05.18
+r13, 2015-05-18
matrix
: optimized the SSE2 and AVX2 paths for integer data.
Added cpuopt to some functions, to manually limit the instruction set optimizations.
@@ -1606,23 +1658,23 @@ V) Changelog
Removed the int16tofloat
and floattoint16
temporary functions.
-r12, 2015.05.08
+r12, 2015-05-08
resample
: fixed a crash in the AVX2 code path, thanks to HolyWu for spotting it.
-r11, 2015.05.07
+r11, 2015-05-07
transfer
: fixed a bug in the SSE2 code path.
-r10, 2015.05.06
+r10, 2015-05-06
fmtconv is compatible with the older Vapoursynth versions again until API 3.2 is out.
Source code: fixed compilation problems.
-r9, 2015.05.06
+r9, 2015-05-06
Added the transfer
function.
resample
: Most kernel-related parameters are now arrays, allowing to specify different values for each plane.
@@ -1632,25 +1684,25 @@ V) Changelog
bitdepth
: SSE2 optimizations for the “fast” algorithm.
-r8, 2013.11.30
+r8, 2013-11-30
resample
: Fixed bugs introduced in r7.
Fixed a range conversion issue in “plane copy” modes with source and destination formats are the same.
-r7, 2013.11.27
+r7, 2013-11-27
64-bit windows version.
resample
: A few optimizations for special cases.
resample
: fixed the coefficients used in integer resizing, whose sum was sometimes off by a few units.
-r6, 2013.08.24
+r6, 2013-08-24
matrix
: single-plane output now works correctly.
-r5, 2013.08.18
+r5, 2013-08-18
Added 12-bit support for all the functions.
Added matrix2020cl
to convert between linear RGB and Y’Cb’Cr’ colorspaces using the BT.2020 constant luminance matrix.
@@ -1660,7 +1712,7 @@ V) Changelog
resample
: added SSE2 integer calculations for slight speed improvement. Activated by default, use flt=1 to compute everything in float (previous operating mode).
-r4, 2012.12.09
+r4, 2012-12-09
Added a documentation.
Filters now write some frame properties when known.
@@ -1677,7 +1729,7 @@ V) Changelog
Added nativetostack16
.
-r3, 2012.11.23
+r3, 2012-11-23
bitdepth
: changed the bitdepth parameter to bits .
bitdepth
: added SSE2 optimizations for upconversions.
@@ -1686,7 +1738,7 @@ V) Changelog
resample
: fixed the planes parameter previously interpreted as 0 (black or green screen).
-r2, 2012.11.18
+r2, 2012-11-18
bitdepth
: implemented fast dither mode (but not in SSE2 yet).
bitdepth
: optimized float-to-integer path.
@@ -1696,7 +1748,7 @@ V) Changelog
resample
: fixed white/magenta screen with 8-bit input and float output.
-r1, 2012.11.16
+r1, 2012-11-16
diff --git a/src/AvstpWrapper.cpp b/src/AvstpWrapper.cpp
index b4f7d09..c7ced4c 100644
--- a/src/AvstpWrapper.cpp
+++ b/src/AvstpWrapper.cpp
@@ -22,6 +22,11 @@ To Public License, Version 2, as published by Sam Hocevar. See
+// Define this macro to output error messages
+#undef AvstpWrapper_DEBUG_VERBOSE
+
+
+
/*\\\ INCLUDE FILES \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
#if defined (_MSC_VER)
@@ -159,10 +164,12 @@ AvstpWrapper::AvstpWrapper ()
#if defined (_MSC_VER) && defined (USE_AVSTP)
if (_dll_hnd == 0)
{
+#if defined (AvstpWrapper_DEBUG_VERBOSE)
::OutputDebugStringW (
L"AvstpWrapper: cannot find avstp.dll."
L"Usage restricted to single threading.\n"
);
+#endif
// throw std::runtime_error ("Cannot find avstp.dll.");
#endif
assign_fallback ();
diff --git a/src/VapourSynth.h b/src/VapourSynth.h
index fec53ad..b4e7ff0 100644
--- a/src/VapourSynth.h
+++ b/src/VapourSynth.h
@@ -461,10 +461,6 @@ typedef const VSFrameRef *(VS_CC *VSFilterGetFrame)(int n, int activationReason,
-typedef int (VS_CC *VSGetOutputIndex)(VSFrameContext *frameCtx);
-
-
-
/*
==============================================================================
Name: *VSFilterFree
diff --git a/src/conc/AioAdd.h b/src/conc/AioAdd.h
index 45fa578..ad59ef9 100644
--- a/src/conc/AioAdd.h
+++ b/src/conc/AioAdd.h
@@ -46,7 +46,7 @@ class AioAdd
AioAdd (T operand);
virtual ~AioAdd () = default;
- inline T operator () (T old_val) const;
+ inline T operator () (T old_val) const noexcept;
@@ -70,7 +70,9 @@ class AioAdd
AioAdd () = delete;
AioAdd (const AioAdd &other) = delete;
+ AioAdd (const AioAdd &&other) = delete;
AioAdd & operator = (const AioAdd &other) = delete;
+ AioAdd & operator = (const AioAdd &&other) = delete;
bool operator == (const AioAdd &other) const = delete;
bool operator != (const AioAdd &other) const = delete;
diff --git a/src/conc/AioAdd.hpp b/src/conc/AioAdd.hpp
index 37be677..289b15e 100644
--- a/src/conc/AioAdd.hpp
+++ b/src/conc/AioAdd.hpp
@@ -43,9 +43,9 @@ AioAdd ::AioAdd (T operand)
template
-T AioAdd ::operator () (T old_val) const
+T AioAdd ::operator () (T old_val) const noexcept
{
- return (old_val + _operand);
+ return old_val + _operand;
}
diff --git a/src/conc/AioMax.h b/src/conc/AioMax.h
index 850a55e..054b6ff 100644
--- a/src/conc/AioMax.h
+++ b/src/conc/AioMax.h
@@ -44,9 +44,8 @@ class AioMax
explicit inline
AioMax (T operand);
- virtual ~AioMax () = default;
- inline T operator () (T old_val) const;
+ inline T operator () (T old_val) const noexcept;
@@ -70,7 +69,9 @@ class AioMax
AioMax () = delete;
AioMax (const AioMax &other) = delete;
+ AioMax (const AioMax &&other) = delete;
AioMax & operator = (const AioMax &other) = delete;
+ AioMax & operator = (const AioMax &&other) = delete;
bool operator == (const AioMax &other) const = delete;
bool operator != (const AioMax &other) const = delete;
diff --git a/src/conc/AioMax.hpp b/src/conc/AioMax.hpp
index 1ac6a29..1ea8ddf 100644
--- a/src/conc/AioMax.hpp
+++ b/src/conc/AioMax.hpp
@@ -45,9 +45,9 @@ AioMax ::AioMax (T operand)
template
-T AioMax ::operator () (T old_val) const
+T AioMax ::operator () (T old_val) const noexcept
{
- return (std::max (old_val, _operand));
+ return std::max (old_val, _operand);
}
diff --git a/src/conc/AioSub.h b/src/conc/AioSub.h
index cce1528..64e5ed3 100644
--- a/src/conc/AioSub.h
+++ b/src/conc/AioSub.h
@@ -47,9 +47,8 @@ class AioSub
explicit inline
AioSub (T operand);
- virtual ~AioSub () = default;
- inline T operator () (T old_val) const;
+ inline T operator () (T old_val) const noexcept;
@@ -73,7 +72,9 @@ class AioSub
AioSub () = delete;
AioSub (const AioSub &other) = delete;
+ AioSub (const AioSub &&other) = delete;
AioSub & operator = (const AioSub &other) = delete;
+ AioSub & operator = (const AioSub &&other) = delete;
bool operator == (const AioSub &other) const = delete;
bool operator != (const AioSub &other) const = delete;
diff --git a/src/conc/AioSub.hpp b/src/conc/AioSub.hpp
index 2208095..ebf99d8 100644
--- a/src/conc/AioSub.hpp
+++ b/src/conc/AioSub.hpp
@@ -43,9 +43,9 @@ AioSub ::AioSub (T operand)
template
-T AioSub ::operator () (T old_val) const
+T AioSub ::operator () (T old_val) const noexcept
{
- return (old_val - _operand);
+ return old_val - _operand;
}
diff --git a/src/conc/AtomicInt.h b/src/conc/AtomicInt.h
index 2117805..db88c17 100644
--- a/src/conc/AtomicInt.h
+++ b/src/conc/AtomicInt.h
@@ -41,6 +41,8 @@ To Public License, Version 2, as published by Sam Hocevar. See
#include "conc/def.h"
+#include
+
#include
#if (conc_ARCHI == conc_ARCHI_X86)
@@ -59,6 +61,14 @@ namespace conc
template
class AtomicInt
{
+ static_assert (
+ ( std::is_trivially_copyable ::value
+ && std::is_copy_constructible ::value
+ && std::is_move_constructible ::value
+ && std::is_copy_assignable ::value
+ && std::is_move_assignable ::value),
+ "Requirements on T"
+ );
/*\\\ PUBLIC \\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\*/
@@ -66,30 +76,30 @@ class AtomicInt
typedef T DataType;
- inline AtomicInt ();
+ inline AtomicInt () noexcept;
inline explicit
- AtomicInt (T val);
- inline AtomicInt (const AtomicInt &other);
+ AtomicInt (T val) noexcept;
+ inline AtomicInt (const AtomicInt &other) noexcept;
inline AtomicInt &
- operator = (T other);
+ operator = (T other) noexcept;
- inline operator T () const;
+ inline operator T () const noexcept;
- inline T swap (T other);
- inline T cas (T other, T comp);
+ inline T swap (T other) noexcept;
+ inline T cas (T other, T comp) noexcept;
// Beware while using the result of these operators, modification and
// read is not atomic. Use directly the AtomicIntOp instead.
inline AtomicInt &
- operator += (const T &other);
+ operator += (const T &other) noexcept;
inline AtomicInt &
- operator -= (const T &other);
+ operator -= (const T &other) noexcept;
inline AtomicInt &
- operator ++ ();
- inline T operator ++ (int);
+ operator ++ () noexcept;
+ inline T operator ++ (int) noexcept;
inline AtomicInt &
- operator -- ();
- inline T operator -- (int);
+ operator -- () noexcept;
+ inline T operator -- (int) noexcept;
@@ -105,13 +115,14 @@ class AtomicInt
#if (conc_ARCHI == conc_ARCHI_X86)
- enum { SZ = sizeof (T) };
- enum { SL2 = (SZ > 16) ? -1
- : ((SZ > 8) ? 4
- : ((SZ > 4) ? 3
- : ((SZ > 2) ? 2
- : ((SZ > 1) ? 1
- : 0)))) };
+ static constexpr int SZ = int (sizeof (T));
+ static constexpr int SL2 =
+ (SZ > 16) ? -1
+ : ((SZ > 8) ? 4
+ : ((SZ > 4) ? 3
+ : ((SZ > 2) ? 2
+ : ((SZ > 1) ? 1
+ : 0))));
typedef AtomicMem StoredTypeWrapper;
typedef typename StoredTypeWrapper::DataType StoredType;
diff --git a/src/conc/AtomicInt.hpp b/src/conc/AtomicInt.hpp
index 490a4a7..a5f7e43 100644
--- a/src/conc/AtomicInt.hpp
+++ b/src/conc/AtomicInt.hpp
@@ -52,7 +52,7 @@ namespace conc
template
-AtomicInt ::AtomicInt ()
+AtomicInt ::AtomicInt () noexcept
: _val ()
{
#if (conc_ARCHI == conc_ARCHI_X86)
@@ -63,7 +63,7 @@ AtomicInt ::AtomicInt ()
template
-AtomicInt ::AtomicInt (T val)
+AtomicInt ::AtomicInt (T val) noexcept
: _val (val)
{
#if (conc_ARCHI == conc_ARCHI_X86)
@@ -74,19 +74,18 @@ AtomicInt ::AtomicInt (T val)
template
-AtomicInt ::AtomicInt (const AtomicInt &other)
+AtomicInt ::AtomicInt (const AtomicInt &other) noexcept
: _val (T (other))
{
#if (conc_ARCHI == conc_ARCHI_X86)
assert (is_ptr_aligned_nz ((const void *) (&_val), sizeof (_val)));
#endif // conc_ARCHI
- assert (&other != 0);
}
template
-AtomicInt & AtomicInt ::operator = (T other)
+AtomicInt & AtomicInt ::operator = (T other) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
StoredTypeWrapper::swap (_val, other);
@@ -100,7 +99,7 @@ AtomicInt & AtomicInt ::operator = (T other)
template
-AtomicInt ::operator T () const
+AtomicInt ::operator T () const noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
return (T (_val));
@@ -112,7 +111,7 @@ AtomicInt ::operator T () const
template
-T AtomicInt ::swap (T other)
+T AtomicInt ::swap (T other) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
return (T (StoredTypeWrapper::swap (_val, other)));
@@ -124,12 +123,14 @@ T AtomicInt ::swap (T other)
template
-T AtomicInt ::cas (T other, T comp)
+T AtomicInt ::cas (T other, T comp) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
return (T (StoredTypeWrapper::cas (_val, other, comp)));
#else // conc_ARCHI
- _val.compare_exchange_weak (comp, other);
+ // Some algorithms do something specific upon failure, so we need to
+ // use the strong version.
+ _val.compare_exchange_strong (comp, other);
return (comp);
#endif // conc_ARCHI
}
@@ -137,7 +138,7 @@ T AtomicInt ::cas (T other, T comp)
template
-AtomicInt & AtomicInt ::operator += (const T &other)
+AtomicInt & AtomicInt ::operator += (const T &other) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
AioAdd ftor (other);
@@ -152,7 +153,7 @@ AtomicInt & AtomicInt ::operator += (const T &other)
template
-AtomicInt & AtomicInt ::operator -= (const T &other)
+AtomicInt & AtomicInt ::operator -= (const T &other) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
AioSub ftor (other);
@@ -167,7 +168,7 @@ AtomicInt & AtomicInt ::operator -= (const T &other)
template
-AtomicInt & AtomicInt ::operator ++ ()
+AtomicInt & AtomicInt ::operator ++ () noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
return ((*this) += 1);
@@ -180,7 +181,7 @@ AtomicInt & AtomicInt ::operator ++ ()
template
-T AtomicInt ::operator ++ (int)
+T AtomicInt ::operator ++ (int) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
const T prev = _val;
@@ -194,7 +195,7 @@ T AtomicInt ::operator ++ (int)
template
-AtomicInt & AtomicInt ::operator -- ()
+AtomicInt & AtomicInt ::operator -- () noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
return ((*this) -= 1);
@@ -207,7 +208,7 @@ AtomicInt & AtomicInt ::operator -- ()
template
-T AtomicInt ::operator -- (int)
+T AtomicInt ::operator -- (int) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
const T prev = _val;
diff --git a/src/conc/AtomicIntOp.h b/src/conc/AtomicIntOp.h
index b17811b..93f23ed 100644
--- a/src/conc/AtomicIntOp.h
+++ b/src/conc/AtomicIntOp.h
@@ -61,16 +61,16 @@ class AtomicIntOp
template
static inline void
- exec (AtomicInt &atom, F &ftor);
+ exec (AtomicInt &atom, F &ftor) noexcept;
template
static inline T
- exec_old (AtomicInt &atom, F &ftor);
+ exec_old (AtomicInt &atom, F &ftor) noexcept;
template
static inline T
- exec_new (AtomicInt &atom, F &ftor);
+ exec_new (AtomicInt &atom, F &ftor) noexcept;
template
static inline void
- exec_both (AtomicInt &atom, F &ftor, T &val_old, T &val_new);
+ exec_both (AtomicInt &atom, F &ftor, T &val_old, T &val_new) noexcept;
diff --git a/src/conc/AtomicIntOp.hpp b/src/conc/AtomicIntOp.hpp
index bb3030a..673531a 100644
--- a/src/conc/AtomicIntOp.hpp
+++ b/src/conc/AtomicIntOp.hpp
@@ -34,7 +34,7 @@ namespace conc
template
-void AtomicIntOp::exec (AtomicInt &atom, F &ftor)
+void AtomicIntOp::exec (AtomicInt &atom, F &ftor) noexcept
{
T val_new;
T val_old;
@@ -44,7 +44,7 @@ void AtomicIntOp::exec (AtomicInt &atom, F &ftor)
template
-T AtomicIntOp::exec_old (AtomicInt &atom, F &ftor)
+T AtomicIntOp::exec_old (AtomicInt &atom, F &ftor) noexcept
{
T val_new;
T val_old;
@@ -56,7 +56,7 @@ T AtomicIntOp::exec_old (AtomicInt &atom, F &ftor)
template
-T AtomicIntOp::exec_new (AtomicInt &atom, F &ftor)
+T AtomicIntOp::exec_new (AtomicInt &atom, F &ftor) noexcept
{
T val_new;
T val_old;
@@ -68,7 +68,7 @@ T AtomicIntOp::exec_new (AtomicInt &atom, F &ftor)
template
-void AtomicIntOp::exec_both (AtomicInt &atom, F &ftor, T &val_old, T &val_new)
+void AtomicIntOp::exec_both (AtomicInt &atom, F &ftor, T &val_old, T &val_new) noexcept
{
T val_cur;
do
diff --git a/src/conc/AtomicMem.h b/src/conc/AtomicMem.h
index 2975666..ad985ec 100644
--- a/src/conc/AtomicMem.h
+++ b/src/conc/AtomicMem.h
@@ -53,9 +53,9 @@ class AtomicMem
conc_TYPEDEF_ALIGN (4, DataType, DataTypeAlign);
conc_FORCEINLINE static DataType
- swap (volatile DataType &dest, DataType excg);
+ swap (volatile DataType &dest, DataType excg) noexcept;
conc_FORCEINLINE static DataType
- cas (volatile DataType &dest, DataType excg, DataType comp);
+ cas (volatile DataType &dest, DataType excg, DataType comp) noexcept;
}; // class AtomicMem
@@ -68,9 +68,9 @@ class AtomicMem <3>
conc_TYPEDEF_ALIGN (8, DataType, DataTypeAlign);
conc_FORCEINLINE static DataType
- swap (volatile DataType &dest, DataType excg);
+ swap (volatile DataType &dest, DataType excg) noexcept;
conc_FORCEINLINE static DataType
- cas (volatile DataType &dest, DataType excg, DataType comp);
+ cas (volatile DataType &dest, DataType excg, DataType comp) noexcept;
}; // class AtomicMem <3>
@@ -85,9 +85,9 @@ class AtomicMem <4>
conc_TYPEDEF_ALIGN (16, DataType, DataTypeAlign);
conc_FORCEINLINE static DataType
- swap (volatile DataType &dest, DataType excg);
+ swap (volatile DataType &dest, DataType excg) noexcept;
conc_FORCEINLINE static DataType
- cas (volatile DataType &dest, DataType excg, DataType comp);
+ cas (volatile DataType &dest, DataType excg, DataType comp) noexcept;
}; // class AtomicMem <4>
#endif // conc_HAS_CAS_128
diff --git a/src/conc/AtomicMem.hpp b/src/conc/AtomicMem.hpp
index e639a6b..dbdfa24 100644
--- a/src/conc/AtomicMem.hpp
+++ b/src/conc/AtomicMem.hpp
@@ -36,7 +36,7 @@ namespace conc
template
-typename AtomicMem ::DataType AtomicMem ::swap (volatile DataType &dest, DataType excg)
+typename AtomicMem ::DataType AtomicMem ::swap (volatile DataType &dest, DataType excg) noexcept
{
static_assert ((SL2 >= 0 && SL2 <= 2), "");
@@ -46,7 +46,7 @@ typename AtomicMem ::DataType AtomicMem ::swap (volatile DataType &des
template
-typename AtomicMem ::DataType AtomicMem ::cas (volatile DataType &dest, DataType excg, DataType comp)
+typename AtomicMem ::DataType AtomicMem ::cas (volatile DataType &dest, DataType excg, DataType comp) noexcept
{
static_assert ((SL2 >= 0 && SL2 <= 2), "");
@@ -55,14 +55,14 @@ typename AtomicMem ::DataType AtomicMem ::cas (volatile DataType &dest
-AtomicMem <3>::DataType AtomicMem <3>::swap (volatile DataType &dest, DataType excg)
+AtomicMem <3>::DataType AtomicMem <3>::swap (volatile DataType &dest, DataType excg) noexcept
{
return (Interlocked::swap (dest, excg));
}
-AtomicMem <3>::DataType AtomicMem <3>::cas (volatile DataType &dest, DataType excg, DataType comp)
+AtomicMem <3>::DataType AtomicMem <3>::cas (volatile DataType &dest, DataType excg, DataType comp) noexcept
{
return (Interlocked::cas (dest, excg, comp));
}
@@ -73,7 +73,7 @@ AtomicMem <3>::DataType AtomicMem <3>::cas (volatile DataType &dest, DataType ex
-AtomicMem <4>::DataType AtomicMem <4>::swap (volatile DataType &dest, DataType excg)
+AtomicMem <4>::DataType AtomicMem <4>::swap (volatile DataType &dest, DataType excg) noexcept
{
Interlocked::Data128 old;
@@ -90,7 +90,7 @@ AtomicMem <4>::DataType AtomicMem <4>::swap (volatile DataType &dest, DataType e
-AtomicMem <4>::DataType AtomicMem <4>::cas (volatile DataType &dest, DataType excg, DataType comp)
+AtomicMem <4>::DataType AtomicMem <4>::cas (volatile DataType &dest, DataType excg, DataType comp) noexcept
{
Interlocked::Data128 old;
diff --git a/src/conc/AtomicPtr.h b/src/conc/AtomicPtr.h
index 293431a..85bdca8 100644
--- a/src/conc/AtomicPtr.h
+++ b/src/conc/AtomicPtr.h
@@ -48,18 +48,18 @@ class AtomicPtr
public:
- inline AtomicPtr ();
- inline AtomicPtr (T *ptr);
+ inline AtomicPtr () noexcept;
+ inline AtomicPtr (T *ptr) noexcept;
inline AtomicPtr &
- operator = (T *other_ptr);
+ operator = (T *other_ptr) noexcept;
- inline operator T * () const;
+ inline operator T * () const noexcept;
- bool operator == (T *other_ptr) const;
- bool operator != (T *other_ptr) const;
+ bool operator == (T *other_ptr) const noexcept;
+ bool operator != (T *other_ptr) const noexcept;
- inline T * swap (T *other_ptr);
- inline T * cas (T *other_ptr, T *comp_ptr);
+ inline T * swap (T *other_ptr) noexcept;
+ inline T * cas (T *other_ptr, T *comp_ptr) noexcept;
@@ -73,7 +73,7 @@ class AtomicPtr
private:
- inline T * read_ptr () const;
+ inline T * read_ptr () const noexcept;
#if (conc_ARCHI == conc_ARCHI_X86)
diff --git a/src/conc/AtomicPtr.hpp b/src/conc/AtomicPtr.hpp
index c6f83bc..f20c63e 100644
--- a/src/conc/AtomicPtr.hpp
+++ b/src/conc/AtomicPtr.hpp
@@ -41,7 +41,7 @@ namespace conc
template
-AtomicPtr ::AtomicPtr ()
+AtomicPtr ::AtomicPtr () noexcept
: _ptr ()
{
#if (conc_ARCHI == conc_ARCHI_X86)
@@ -52,18 +52,23 @@ AtomicPtr ::AtomicPtr ()
template
-AtomicPtr ::AtomicPtr (T *ptr)
+AtomicPtr ::AtomicPtr (T *ptr) noexcept
+#if (conc_ARCHI == conc_ARCHI_X86)
+: _ptr ()
+#else // conc_ARCHI
: _ptr (ptr)
+#endif // conc_ARCHI
{
#if (conc_ARCHI == conc_ARCHI_X86)
assert (is_ptr_aligned_nz ((const void *) (&_ptr), sizeof (_ptr)));
+ _ptr._void_ptr = ptr;
#endif // conc_ARCHI
}
template
-AtomicPtr & AtomicPtr ::operator = (T *other_ptr)
+AtomicPtr & AtomicPtr ::operator = (T *other_ptr) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
Interlocked::swap (_ptr._void_ptr, other_ptr);
@@ -77,7 +82,7 @@ AtomicPtr & AtomicPtr ::operator = (T *other_ptr)
template
-AtomicPtr ::operator T * () const
+AtomicPtr ::operator T * () const noexcept
{
return (read_ptr ());
}
@@ -85,7 +90,7 @@ AtomicPtr ::operator T * () const
template
-bool AtomicPtr ::operator == (T *other_ptr) const
+bool AtomicPtr ::operator == (T *other_ptr) const noexcept
{
const T * ptr = read_ptr ();
@@ -95,7 +100,7 @@ bool AtomicPtr ::operator == (T *other_ptr) const
template
-bool AtomicPtr ::operator != (T *other_ptr) const
+bool AtomicPtr ::operator != (T *other_ptr) const noexcept
{
return (! ((*this) == other_ptr));
}
@@ -103,7 +108,7 @@ bool AtomicPtr ::operator != (T *other_ptr) const
template
-T * AtomicPtr ::swap (T *other_ptr)
+T * AtomicPtr ::swap (T *other_ptr) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
return (static_cast (Interlocked::swap (
@@ -118,7 +123,7 @@ T * AtomicPtr ::swap (T *other_ptr)
template
-T * AtomicPtr ::cas (T *other_ptr, T *comp_ptr)
+T * AtomicPtr ::cas (T *other_ptr, T *comp_ptr) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
return (static_cast (Interlocked::cas (
@@ -127,7 +132,9 @@ T * AtomicPtr ::cas (T *other_ptr, T *comp_ptr)
comp_ptr
)));
#else // conc_ARCHI
- _ptr.compare_exchange_weak (comp_ptr, other_ptr);
+ // Some algorithms do something specific upon failure, so we need to
+ // use the strong version.
+ _ptr.compare_exchange_strong (comp_ptr, other_ptr);
return (comp_ptr);
#endif // conc_ARCHI
}
@@ -143,12 +150,12 @@ T * AtomicPtr ::cas (T *other_ptr, T *comp_ptr)
template
-T * AtomicPtr ::read_ptr () const
+T * AtomicPtr ::read_ptr () const noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86)
- return (static_cast (_ptr._t_ptr));
+ return _ptr._t_ptr;
#else // conc_ARCHI
- return (_ptr.load ());
+ return _ptr.load ();
#endif // conc_ARCHI
}
diff --git a/src/conc/AtomicPtrIntPair.h b/src/conc/AtomicPtrIntPair.h
index b466ade..293575b 100644
--- a/src/conc/AtomicPtrIntPair.h
+++ b/src/conc/AtomicPtrIntPair.h
@@ -60,13 +60,13 @@ class AtomicPtrIntPair
public:
- AtomicPtrIntPair ();
+ AtomicPtrIntPair () noexcept;
- void set (T * ptr, ptrdiff_t val);
- void get (T * &ptr, ptrdiff_t &val) const;
- T * get_ptr () const;
- ptrdiff_t get_val () const;
- bool cas2 (T *new_ptr, ptrdiff_t new_val, T *comp_ptr, ptrdiff_t comp_val);
+ void set (T * ptr, intptr_t val) noexcept;
+ void get (T * &ptr, intptr_t &val) const noexcept;
+ T * get_ptr () const noexcept;
+ intptr_t get_val () const noexcept;
+ bool cas2 (T *new_ptr, intptr_t new_val, T *comp_ptr, intptr_t comp_val) noexcept;
@@ -101,9 +101,8 @@ class AtomicPtrIntPair
class RealContent
{
public:
- T * volatile _ptr;
- volatile intptr_t
- _val;
+ T * _ptr;
+ intptr_t _val;
};
static_assert (sizeof (RealContent) <= sizeof (DataType), "");
@@ -113,7 +112,7 @@ class AtomicPtrIntPair
RealContent _content;
};
- static void cas_combi (Combi &old, Combi &dest, const Combi &excg, const Combi &comp);
+ static void cas_combi (Combi &old, Combi &dest, const Combi &excg, const Combi &comp) noexcept;
Combi _data;
diff --git a/src/conc/AtomicPtrIntPair.hpp b/src/conc/AtomicPtrIntPair.hpp
index 850894d..0ea5cfc 100644
--- a/src/conc/AtomicPtrIntPair.hpp
+++ b/src/conc/AtomicPtrIntPair.hpp
@@ -36,24 +36,24 @@ namespace conc
template
-AtomicPtrIntPair ::AtomicPtrIntPair ()
+AtomicPtrIntPair ::AtomicPtrIntPair () noexcept
: _data ()
{
- set (0, 0);
+ set (nullptr, 0);
}
template
-void AtomicPtrIntPair ::set (T * ptr, ptrdiff_t val)
+void AtomicPtrIntPair ::set (T * ptr, intptr_t val) noexcept
{
+ const RealContent content = { ptr, val };
+
#if (conc_ARCHI == conc_ARCHI_X86 || ! conc_USE_STD_ATOMIC_128BITS)
- _data._content._ptr = ptr;
- _data._content._val = val;
+ _data._content = content;
#else // conc_ARCHI
- const RealContent content = { ptr, val };
_data.store (content);
#endif // conc_ARCHI
@@ -62,7 +62,7 @@ void AtomicPtrIntPair ::set (T * ptr, ptrdiff_t val)
template
-void AtomicPtrIntPair ::get (T * &ptr, ptrdiff_t &val) const
+void AtomicPtrIntPair ::get (T * &ptr, intptr_t &val) const noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86 || ! conc_USE_STD_ATOMIC_128BITS)
@@ -90,7 +90,7 @@ void AtomicPtrIntPair ::get (T * &ptr, ptrdiff_t &val) const
template
-T * AtomicPtrIntPair ::get_ptr () const
+T * AtomicPtrIntPair ::get_ptr () const noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86 || ! conc_USE_STD_ATOMIC_128BITS)
@@ -108,7 +108,7 @@ T * AtomicPtrIntPair ::get_ptr () const
template
-ptrdiff_t AtomicPtrIntPair ::get_val () const
+intptr_t AtomicPtrIntPair ::get_val () const noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86 || ! conc_USE_STD_ATOMIC_128BITS)
@@ -126,7 +126,7 @@ ptrdiff_t AtomicPtrIntPair ::get_val () const
template
-bool AtomicPtrIntPair ::cas2 (T *new_ptr, ptrdiff_t new_val, T *comp_ptr, ptrdiff_t comp_val)
+bool AtomicPtrIntPair ::cas2 (T *new_ptr, intptr_t new_val, T *comp_ptr, intptr_t comp_val) noexcept
{
#if (conc_ARCHI == conc_ARCHI_X86 || ! conc_USE_STD_ATOMIC_128BITS)
@@ -148,7 +148,9 @@ bool AtomicPtrIntPair ::cas2 (T *new_ptr, ptrdiff_t new_val, T *comp_ptr, ptr
const RealContent val = { new_ptr , new_val };
RealContent expected = { comp_ptr, comp_val };
- return (_data.compare_exchange_weak (expected, val));
+ // Some algorithms do something specific upon failure, so we need to
+ // use the strong version.
+ return (_data.compare_exchange_strong (expected, val));
#endif // conc_ARCHI
}
@@ -166,7 +168,7 @@ bool AtomicPtrIntPair ::cas2 (T *new_ptr, ptrdiff_t new_val, T *comp_ptr, ptr
#if (conc_ARCHI == conc_ARCHI_X86 || ! conc_USE_STD_ATOMIC_128BITS)
template
-void AtomicPtrIntPair ::cas_combi (Combi &old, Combi &dest, const Combi &excg, const Combi &comp)
+void AtomicPtrIntPair ::cas_combi (Combi &old, Combi &dest, const Combi &excg, const Combi &comp) noexcept
{
#if (conc_WORD_SIZE == 64)
diff --git a/src/conc/CellPool.h b/src/conc/CellPool.h
index ce14cb1..1d38cda 100644
--- a/src/conc/CellPool.h
+++ b/src/conc/CellPool.h
@@ -65,7 +65,7 @@ class CellPool
inline CellType *
take_cell (bool autogrow_flag = false);
- inline void return_cell (CellType &cell);
+ inline void return_cell (CellType &cell) noexcept;
@@ -126,7 +126,9 @@ class CellPool
private:
CellPool (const CellPool &other) = delete;
+ CellPool (CellPool &&other) = delete;
CellPool & operator = (const CellPool &other) = delete;
+ CellPool & operator = (CellPool &&other) = delete;
bool operator == (const CellPool &other) const = delete;
bool operator != (const CellPool &other) const = delete;
diff --git a/src/conc/CellPool.hpp b/src/conc/CellPool.hpp
index 5bd6152..821b4fe 100644
--- a/src/conc/CellPool.hpp
+++ b/src/conc/CellPool.hpp
@@ -53,7 +53,7 @@ CellPool ::CellPool ()
for (int zone_index = 0; zone_index < MAX_NBR_ZONES; ++zone_index)
{
- _m_ptr->_zone_list [zone_index] = 0;
+ _m_ptr->_zone_list [zone_index] = nullptr;
}
}
@@ -73,13 +73,13 @@ template
void CellPool ::clear_all ()
{
#if !defined (NDEBUG)
- size_t nbr_total_cells =
+ const size_t nbr_total_cells =
compute_total_size_for_zones (_m_ptr->_nbr_zones);
assert (_m_ptr->_nbr_avail_cells == nbr_total_cells);
#endif
- while (_cell_stack.pop () != 0)
+ while (_cell_stack.pop () != nullptr)
{
continue;
}
@@ -89,10 +89,10 @@ void CellPool ::clear_all ()
{
AtomicPtr & zone_ptr_ref = _m_ptr->_zone_list [zone_index];
CellType * zone_ptr = zone_ptr_ref;
- if (zone_ptr != 0)
+ if (zone_ptr != nullptr)
{
dealloc_cells (zone_ptr);
- zone_ptr_ref = 0;
+ zone_ptr_ref = nullptr;
}
}
_m_ptr->_nbr_zones = 0;
@@ -113,8 +113,8 @@ void CellPool ::expand_to (size_t nbr_cells)
while (total_size < nbr_cells && zone_index < MAX_NBR_ZONES)
{
AtomicPtr & zone_ptr_ref = _m_ptr->_zone_list [zone_index];
- CellType * zone_ptr = zone_ptr_ref;
- if (zone_ptr == 0)
+ const CellType * zone_ptr = zone_ptr_ref;
+ if (zone_ptr == nullptr)
{
allocate_zone (cur_size, zone_ptr_ref);
}
@@ -134,7 +134,7 @@ void CellPool ::expand_to (size_t nbr_cells)
template
typename CellPool ::CellType * CellPool ::take_cell (bool autogrow_flag)
{
- CellType * cell_ptr = 0;
+ CellType * cell_ptr = nullptr;
const int nbr_zones = _m_ptr->_nbr_zones;
@@ -142,27 +142,32 @@ typename CellPool ::CellType * CellPool ::take_cell (bool autogrow_flag)
{
cell_ptr = _cell_stack.pop ();
- if ((cell_ptr == 0) && autogrow_flag && (nbr_zones < MAX_NBR_ZONES))
+ if ( cell_ptr == nullptr
+ && autogrow_flag
+ && nbr_zones < MAX_NBR_ZONES)
{
- const size_t new_size = compute_total_size_for_zones (nbr_zones + 1);
+ const size_t new_size =
+ compute_total_size_for_zones (nbr_zones + 1);
expand_to (new_size);
}
}
- while ((cell_ptr == 0) && autogrow_flag && (nbr_zones < MAX_NBR_ZONES));
+ while ( cell_ptr == nullptr
+ && autogrow_flag
+ && nbr_zones < MAX_NBR_ZONES);
- if (cell_ptr != 0)
+ if (cell_ptr != nullptr)
{
-- _m_ptr->_nbr_avail_cells;
}
- return (cell_ptr);
+ return cell_ptr;
}
// Thread-safe
template
-void CellPool