                 Changes in version 2.8.6 (2026-08-21)                  

    o   `Rcpp::stop()`, rather than `Rf_error()`, is now used to signal errors within
	the C++ interface codebase, to ensure correct stack unwinding. (Reported by
	Iñaki Ucar.)

    o   An attempt at a workaround for a GCC-ASAN (16.1.1) issue has been made,
	although it may well result from a bug in GCC (cf. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=125187).
	(Reported by BDR.)

                 Changes in version 2.8.5 (2026-02-24)                  

    o   Calling saveTransform() with one argument now returns the serialised transform
	object, as intended, rather than producing an error.

    o   Comparisons between floating-point and enumeration types are now avoided when
	using the C++20 or later standard for compilation, since this now leads to a
	warning. (Reported by BDR.)

    o   The "Upgrading to RNiftyReg 2.x" section of the README has been removed, since
	the 2.x line of releases is now over 10 years old(!).

                 Changes in version 2.8.4 (2024-09-30)                  

    o   The logic for reading FSL-FLIRT transforms from file previously overlooked a
	quirk whereby FLIRT flips images whose xforms have positive determinant (see,
	for example, https://neurostars.org/t/understanding-fsl-flirt-transformation-matrices/26406).
	This could result in a spurious flip when these transforms were applied, if the
	originally registered images were in, say, LAS and RAS orientations. This
	detail is now handled when FLIRT transforms are imported. (Reported by Martin
	Wilson.)

    o   Affine initialisation matrices for linear registration would previously be
	replaced by a default internally. This has been corrected.

    o   Default affine initialisation matrices now take the pixel/voxel dimensions into
	account when image "sform" and "qform" codes are both zero.

    o   The package's dependency on the "ore" package has been removed, with base R
	regular expression functions being used instead.

                 Changes in version 2.8.3 (2024-06-20)                  

    o   A NiftyReg class method referencing a nonexistent data member has been removed.
	(Picked up by LLVM pre-19, reported by BDR.)

                 Changes in version 2.8.2 (2024-06-04)                  

    o   Objects of class "niftyregRDS" gain a simple asAffine() method for convenience.

    o   The code should now ensure that an affine result from loadTransform() has the
	"affine" class.

    o   An incorrect internal assignment has been corrected.

                 Changes in version 2.8.1 (2023-07-18)                  

    o   Package tests now write files to the R session's temporary directory to avoid
	problems on CRAN.

                 Changes in version 2.8.0 (2023-07-07)                  

    o   The saveTransform() and loadTransform() functions now also work with nonlinear
	transforms, and saveTransform() can return the serialised transform rather than
	writing it to file.

    o   asAffine() is now generic, with methods for various classes including
	"niftiImage". This method now exposes, for the first time, the affine
	transforms that NiftyReg stores as NIfTI extensions within nonlinear
	transforms.

    o   Affine matrix elements are now rounded to six decimal places for printing.

    o   The package now uses tinytest rather than testthat for unit testing.

                 Changes in version 2.7.1 (2022-11-18)                  

    o   A note is now emitted when converting a "niftyreg" object resulting from a
	nonlinear registration to an array or "niftiImage" (implicitly or explicitly).
	This clarifies that the transformed image, not the control point image, will be
	converted, as there is some ambiguity in this case. (Raised by issue #22.)

    o   A number of warnings from modern compilers have been addressed.

                 Changes in version 2.7.0 (2020-09-12)                  

    o   New functions saveTransform() and loadTransform() allow a linear transform to
	be serialised, complete with source and target image metadata, into a single
	compact RDS file. This does not yet work with nonlinear transforms, because
	of their more complex metadata. (Suggested by Yves Rozenholc and Christine
	Keribin.)

    o   There is now an asNifti() method for "niftyreg" objects, for use with RNifti
	version 1.2.0 and above. This allows, for example, writeNifti() to be called
	directly on the result of a registration. (Suggested by @charleswg, issue
	#10.)

                 Changes in version 2.6.8 (2020-04-01)                  

    o   Mask images without a valid "qform" would lead to inaccurate resampling and
	hence spurious errors. This has been corrected. (Reported by @christmanjc,
	issue #9.)

                 Changes in version 2.6.7 (2019-09-11)                  

    o   It is once again possible to interrupt linear registrations. The relevant code
	had been accidentally removed during an upstream update. (Reported by Mark
	Padgham, issue #8.)

    o   A C++ bug picked up valgrind has been fixed. This could lead to erroneous
	initialisation (or possibly even a crash) when searching a deformation field,
	if "nearest=TRUE" had been specified.

                 Changes in version 2.6.6 (2019-03-20)                  

    o   This update makes a minor change to the package directory structure to satisfy
	current CRAN requirements.

                 Changes in version 2.6.5 (2019-01-31)                  

    o   The core registration functions gain an argument to control the maximum number
	of OpenMP threads to use, where applicable. The default is determined by the
	"RNiftyReg.threads" option, which is now set during testing to comply with
	CRAN's multithreading requirements.

                 Changes in version 2.6.4 (2018-11-01)                  

    o   The algorithm for searching a deformation field is now more careful to avoid a
	potentially infinite loop.

                        Changes in version 2.6.3                        

    o   The package now checks at load time whether it was built against a version of
	the RNifti package which is compatible with the currently installed one, and
	raises a warning prompting reinstallation if not.

                        Changes in version 2.6.2                        

    o   Searching a deformation field is now done with gradient descent, rather than
	exhaustively. This makes applyTransform() substantially faster when applying a
	nonlinear transform to points.

                 Changes in version 2.6.1 (2017-11-26)                  

    o   The target image for a half transform now has its xform modified to better
	represent a half-way space between the original source and target.

    o   The package now uses a configure script to more robustly detect OpenMP support.

                 Changes in version 2.6.0 (2017-06-27)                  

    o   New convenience functions translate(), rescale(), skew() and rotate() can be
	used to apply simple transformations to images easily.

    o   The niftyreg() group of functions gain a "precision" argument, which controls
	the working precision of the optimisation.

    o   A single angle supplied to buildAffine() with a 2D source file will now be
	interpreted in the way that would usually be expected (i.e., equivalent to a
	yaw angle).

    o   Compositions of two affine transformations appear to have been happening in the
	wrong order. This has been corrected.

    o   ANALYZE-format files, whose orientation is intrinsically ambiguous, are now
	assumed to be use LAS storage order (with a warning).

    o   The registration functions will no longer modify the low-level C structures
	attributed to their arguments.

    o   The "loder" package is now used in preference to "png".

                 Changes in version 2.5.0 (2017-02-04)                  

    o   RNiftyReg can now register 2D multichannel (RGB or RGBA) images. The red, green
	and blue channels are averaged internally before applying the algorithm.
	Previously such images would produce an error or segfault. (Reported by John
	Muschelli, issue #4.)

    o   The decomposeAffine() function now uses a Cholesky decomposition internally.
	(Hat-tip to Tim Tierney.)

    o   The "nBins" argument to niftyreg.nonlinear() was not previously passed to the
	NiftyReg library. This has been corrected.

    o   Applying a scale transform to a new image with applyTransform() should no
	longer produce a warning. (Reported by Tim Tierney.)

    o   The NiftyReg library has been updated.

                 Changes in version 2.4.1 (2016-12-08)                  

    o   The package has been updated for compatibility with "RNifti" version 0.3.0.

                 Changes in version 2.4.0 (2016-09-21)                  

    o   The package's functions for working with NIfTI-1 files and associated image
	data structures have been moved into the new "RNifti" package, since they are
	useful more broadly. RNiftyReg is therefore more focussed on registration.

    o   The "internal" argument to niftyreg(), and its linear and nonlinear variants,
	can now be set to avoid creating any internal images in the result. This should
	only be necessary in exceptional circumstances, and the default behaviour
	remains as before.

                 Changes in version 2.3.0 (2016-05-07)                  

    o   The new similarity() function can be used to calculate a metric of similarity
	between two images (currently only normalised mutual information). This should
	not decrease after registration!

    o   The composeTransforms() function now accepts more than two arguments, and
	handles NULL arguments (corresponding to no transform).

    o   The package can now work with "MriImage" objects (from package "tractor.base").

    o   It is now possible to interrupt the main registration functions.

    o   The pixdim() and pixunits() functions are now (S3) generic.

    o   The C++ code underlying the updateNifti() function could sometimes produce
	spurious errors about missing strings, when passed a list. This has been
	corrected. (Reported by Tim Tierney.)

                 Changes in version 2.2.0 (2016-03-03)                  

    o   The new asAffine() function can be used to coerce a numeric matrix to the
	"affine" class.

    o   The updateNifti() function now accepts a named list of header elements, of
	the sort generated by dumpNifti(), as its second argument. This allows
	elements of the image's internal metadata to be updated manually, for
	advanced users.

    o   It is now possible to disable the comment lines usually produced by
	writeAffine().

    o   The niftyreg() function, and the two more specialised functions, gain an
	"internal" argument, which results in an internal image as output.

    o   There is now a replacement method for pixunits().

    o   The result of calling dumpNifti() now has a class and a print() method.

    o   Elements of the "scales" argument to buildAffine() may now be negative.

    o   Setting xforms would not work if the image did not already contain a
	valid internal pointer attribute. This has been corrected.

    o   An incompatibility with C++11 has been fixed.

                 Changes in version 2.1.0 (2015-10-16)                  

    o   New functions for replacing an image's sform and qform matrices have been
	added. These are for advanced use only.

    o   Some tests are skipped on Solaris, to avoid failures which have been hard to
	reproduce.

                 Changes in version 2.0.1 (2015-09-23)                  

    o   Fixes for Solaris compilation and UBSAN issues.

                 Changes in version 2.0.0 (2015-09-15)                  

    o   This is a more-or-less complete rewrite of the package, with the goals of
	simplifying both the package's dependencies and its usage. The upstream
	NiftyReg code has also been updated. However, it should still be possible to
	read and use transformations created using RNiftyReg 1.x.

    o   The oro.nifti package is no longer needed, nor used for reading and writing
	NIfTI files (RNiftyReg now offers readNifti() and writeNifti(), which are much
	faster). However, objects of S4 class "nifti" can still be used with the
	package if desired. Functions return either plain R arrays with attributes, or
	bare-bones "internalImage" objects, which contain only some basic metadata and
	a pointer to a C-level data structure.

    o   There are new functions for halving a transform (halfTransform), composing two
	transforms (composeTransforms), and building an affine transform from scratch
	(buildAffine).

    o   Registration is now symmetric by default (for both linear and nonlinear), a
	newer symmetric nonlinear approach is now used, and default cost function
	weights have been tweaked. Therefore, the arguments to the core niftyreg()
	function, and its linear and nonlinear special cases, have changed in both name
	and defaults. See ?niftyreg and related help pages for details.

    o   It is no longer necessary to use functions specific to transform type to
	perform many operations. For example, the work of the old applyAffine(),
	applyControlPoints(), transformWithAffine() and transformWithControlPoints()
	functions is done by the flexible new applyTransform() function. The forward
	and reverse transforms can always be obtained from a registration using the new
	forward() and reverse() functions, no matter what their type is. However, some
	affine-only functions, such as decomposeAffine(), retain their names.

    o   The "affineType" attribute has gone, and convertAffine() is no longer a
	user-visible function. All affine matrices are stored using the NiftyReg
	convention. FSL-FLIRT affines can still be read in, but they are converted to
	NiftyReg convention immediately. In addition, source and target image
	information is attached to the transforms in attributes, and so does not need
	to be specified in most function calls.

    o   Many smaller changes. The newly updated README file should be used as the main
	reference point for usage, supplemented by the R-level function documentation.

                        Changes in version 1.1.4                        

    o   The package was not consistent about how to treat images without NIfTI
	orientation information, and this could lead to erroneous results when
	transforming points between spaces using an affine matrix. This has been
	corrected. (Reported by Jiří Borovec.)

                 Changes in version 1.1.3 (2015-02-18)                  

    o   The C++ code is now more careful to avoid buffer overruns when text fields in
	a "nifti" object are too long.

                 Changes in version 1.1.2 (2013-11-07)                  

    o   Some sample data has been added to the package, along with some code examples.

    o   Code tweaks have been made for C++11 compatibility.

                 Changes in version 1.1.1 (2013-09-27)                  

    o   Under certain circumstances the NiftyReg C++ code could create a control point
	image corresponding to an invalid "nifti" object, resulting in a spurious
	error when running niftyreg.nonlinear(). This has been corrected. (Reported by
	Andreas Heindl.)

                 Changes in version 1.1.0 (2013-07-23)                  

    o   A set of functions has been added for transforming points between spaces using
	an affine or nonlinear transformation.

    o   All registration functions gain an "estimateOnly" option, which can be used to
	estimate a transformation without actually resampling the image.

    o   The new getDeformationField() function can be used to obtain the deformation
	field and/or Jacobian determinant map corresponding to a transformation.

    o   The invertAffine() function has been added to invert an affine matrix while
	preserving its "affineType" attribute.

    o   RNiftyReg will now use OpenMP, if supported by the current build of R.

    o   Image arguments are now coerced automatically to the "nifti" class if they are
	not already of this type.

    o   Image data is no longer copied between data structure types when not needed,
	saving a bit of time and memory.

    o   It is no longer an error in readAffine() if the affine type is not specified
	or stored.

                 Changes in version 1.0.2 (2013-01-19)                  

    o   A further compiler-sensitive problem, which was causing the package to fail to
	install using Solaris Studio, has been addressed.

                        Changes in version 1.0.1                        

    o   A Windows-specific compile-time problem has been addressed.

                 Changes in version 1.0.0 (2012-11-26)                  

    o   RNiftyReg now provides an interface to the symmetric version of the NiftyReg
	nonlinear registration algorithm. This allows consistent transformations to be
	obtained in both directions, in one operation.

    o   The upstream code has been updated to match NiftyReg v1.3.9. Default cost
	function weightings have also been tweaked to match those used in that release.

    o   The type of an affine matrix is now written to file with it. The type therefore
	does not necessarily need to be specified when reading the matrix back in.

    o   The "interpolationPrecision" option has been removed where it appeared. The
	code now simply makes an appropriate choice in each case.

    o   Internal calculation of the final control point spacing from an initial control
	point image was sometimes wrong. This has been corrected.

                 Changes in version 0.6.2 (2012-04-05)                  

    o   Nonlinear registration now works properly for 2D target images.

    o   Control point spacing is now set from the initial control point image (as it
	should be), if one is supplied.

    o   Two small bugs in the upstream NiftyReg code have been fixed.

    o   Attempting to perform 4D-to-2D registration now produces a more specific
	error message.

                 Changes in version 0.6.1 (2012-03-17)                  

    o   The package now redefines standard C print functions to avoid problems with
	output not being captured by R.

                        Changes in version 0.6.0                        

    o   RNiftyReg can now perform nonlinear registration via the niftyreg.nonlinear()
	function. This method optimises over a set of moveable control points arranged
	in a grid over the image. The applyControlPoints() function has also been
	added as the nonlinear equivalent of applyAffine(). See ?niftyreg.nonlinear
	for details on these new functions. The niftyreg() function now serves as a
	common interface to both the linear and nonlinear optimisations.

    o   The "initAffine" argument to niftyreg() now accepts a list of matrices as well
	as a single affine matrix.

    o   The upstream NiftyReg code has been updated, thereby taking in a number of
	tweaks added since the last release version.

    o   A bug in the quaternion-to-matrix conversion in xformToAffine() has been fixed.

                 Changes in version 0.5.0 (2011-11-02)                  

    o   The niftyreg() and applyAffine() functions gain an "interpolationPrecision"
	argument, which affects the data type of the final image. See ?niftyreg for
	details.

    o   The actual number of algorithm iterations run at each level is now stored in
	the output produced by niftyreg().

    o   A bug has been addressed whereby niftyreg() returned the affine matrix used
	for initialisation, if specified, rather than the final one. (Reported by
	Brandon Whitcher.)

    o   The first level of the algorithm is supposed to include both a rigid-body and
	affine optimisation, but the latter was previously omitted due to a bug. This
	has been corrected. In addition, the first level is allowed twice as many
	iterations as subsequent levels, as in the original NiftyReg implementation.

    o   The "data_type" slot of the "nifti" class is now properly set in the image
	returned by niftyreg().

    o   The underlying NIfTI reference library files have been updated.

    o   Spurious parameters have been removed to avoid warnings at compile time.

    o   Calls to problematic C/C++ functions such as exit() have been avoided
	(although NIfTI and NiftyReg library functions still use printf() and the 
	like).

                 Changes in version 0.4.1 (2011-07-28)                  

    o   The reportr package is now properly imported in the namespace file.

                        Changes in version 0.4.0                        

    o   The applyAffine() function has been added as a convenience wrapper to
	niftyreg(...,nLevels=0), for applying a precomputed affine transformation to
	a new image without further optimisation.

    o   RNiftyReg now uses the reportr package for message and error reporting.

    o   The package now has a formal namespace.

                 Changes in version 0.3.1 (2011-01-04)                  

    o   A bug in previous releases affecting the downsampling of images during early
	"levels" of alignment has been fixed. Coregistration of larger images, in
	particular, should be improved as a result.

                 Changes in version 0.3.0 (2010-12-20)                  

    o   2D-to-2D, 3D-to-2D and 4D-to-3D registration are now supported by niftyreg().
	As a result of this added flexibility, a list of affine matrices, rather than
	a single matrix, is now returned by this function.

    o   An image of fewer than 4 pixels/voxels in any dimension cannot be registered
	since it cannot accommodate a single matching block. Providing such an image
	as the source or target now produces an error rather than a crash. (Thanks to
	Takeo Katsuki for pointing this out.)

    o   Further documentation improvements.

                 Changes in version 0.2.0 (2010-09-11)                  

    o   Added an option to niftyreg() to control the type of interpolation that is
	applied to the final coregistered image.

    o   Performing better type checking of image data before passing it to the C++
	code, to avoid intermittent errors from R.

    o   Documentation improvements.

                 Changes in version 0.1.0 (2010-09-06)                  

    o   First public release. 3D affine and rigid-body registration are available.
