WCSLIB version 8.9 (2026/06/18)
-------------------------------

WCSLIB policy over the years has been to use the oldest version of C
that is sufficient for the job, currently C99.  However, as of this
release, C11 is essentially now a prerequisite for thread-safe
execution.  This arises from the need to use functions from stdatomic.h
to deal with race conditions that may arise in the wcserr routines (see
below).  For now, C99 is still sufficient for thread-safe execution if
the C99 compiler supports thread-local storage as required by wcsprintf
(most do), and if wcserr is not used.  However, that situation may not
persist.

It does not seem unreasonable, nor particularly onerous, to require a
more modern, thread-aware compiler, namely C11, for threaded execution.
(It's still pretty old!)

This release is the product of Thomas Robitaille's investigations into
thread-related problems experienced by Astropy.

* C library

  - In wcsprintf.c, added the thread-local storage (TLS) specifier to
    static variables.  Without it the module-static output buffer is
    shared across all threads.  Consequently, if two threads call
    wcsprintf() concurrently after either has called wcsprintf_set(NULL)
    they will interleave their writes into the same wcsprintf_buff.
    While not a problem in itself, if the buffer needs to grow they will
    race on the realloc() of wcsprintf_buff, thereby corrupting the
    heap and typically crashing inside realloc().  Reported by Thomas
    Robitaille with patch.

  - In wcserr.c, conflicts may arise among threads that share a struct
    containing a wcserr struct (namely celprm, disprm, linprm, prjprm,
    spcprm, spxprm, tabprm, and wcsprm).  Two threads may attempt
    simultaneously to operate on the shared wcserr struct, i.e. to set,
    clear, or copy it, leading to race conditions and potentially
    segfaults if one thread attempts to read a wcserr struct that is in
    the process of being cleared by another.  The solution consists of
    a simple locking mechanism - a spinlock native to C11, provided by
    stdatomic.h - implemented as a pre-processor macro.  For C99, the
    macro defaults to a no-op, which means that the problem persists.
    Consequently, C11 is now required for thread-safe execution if
    wcserr is used.  Reported by Thomas Robitaille with patch. 

  - In wcs.c, amended error return mapping for the lin routines to
    account for the addition of LINERR_BAD_PARAM in WCSLIB 8.7.
    Reported by Thomas Robitaille with patch. 

  - In wcshdo(), fixed a bug introduced in the last release in
    converting from sprintf() to snprintf() when writing the keycomment
    for AXIS.jhat.  Reported by Thomas Robitaille with patch.

  - New test program, twcsprintf_pthread, exercises wcsprintf() in
    threaded execution.  Contributed by Thomas Robitaille.

* Installation

  - Bumped the value of _POSIX_C_SOURCE to 200112L in configure.ac.  The
    old value, 1, restricts stdio.h to POSIX.1-1990 interfaces, which
    does not include snprintf().  WCSLIB was failing to compile on macOS
    with recent versions of clang (16 and later), which promote implicit
    function declarations from a warning to a hard error.  Reported by
    Thomas Robitaille.

  - In configure.ac, added tests for an appropriate thread-local storage
    (TLS) qualifier for C99 (it's native in C11).  Propagated by pre-
    processor macro WCSLIB_TLS via CPPFLAGS, specifically to the static
    variables in wcsprintf.c (see above).

* User manual

  - Updated the section on thread-safety in light of the above changes
    to wcsprintf and wcserr.


WCSLIB version 8.8 (2026/05/22)
-------------------------------

* C library

  - In tabini(), persuant to the previous revision, when checking that
    the total number of elements in the coordinate array does not exceed
    INT_MAX, we need to allow for the possibility that K[m] == 0 for all
    m, meaning that the axis lengths are as yet unknown.  Reported by
    Thomas Robitaille with patch.


WCSLIB version 8.7 (2026/05/11)
-------------------------------

The changes in this release were prompted almost exclusively by
Anthropic's Claude Code AI static code analysis tool.  Rob Seaman ran
it on WCSLIB 8.6 and, under his supervision, Claude produced a detailed
report of WCSLIB's shortcomings and a summary of its historical
development.

In addition to its own analysis, Claude Code relied heavily on three
other static code analysis tools: scan-build and clang-tidy from LLVM
22.1.2, and cppcheck 2.20.0.  In fact, clang-tidy made the majority of
change suggestions, which prompted me to install a slightly older
version, LLVM 20.1.2, and run it myself.  Curiously, scan-build, which
is said to be the most thorough, produced a clean result.  cppcheck
found a few issues that were missed by the others.

Claude Code did a pretty good job of summarising the often tediously
nit-picky output of the static analysers, and also in constructing a
history of WCSLIB's code development from the RCS revisions.

This exercise resulted in the changes to the C library detailed below.
Mostly they could be described as armour-plating, if not gold-plating.
However, there was one bug and several instances of potential memory-
related issues, mostly in seldom-taken paths through the code such as
error processing.

* C library

  - In wcshdo_util(), a static helper function for wcshdo(), fixed a
    bug that would have caused the keycomment to be truncated to a
    single character when keyvalues exceeded 20 characters.

  - Fixed various memory-related issues, such as potential memory leaks
    on error return, potentially dereferencing null pointers, incorrect
    handling of failed calls to realloc(), etc. in wcsprt(), wcssub(),
    wcstrim(), wcspcx(), disset(), discpy(), diswarp(), and various of
    the static distortions helper functions.

    In wcsprintf(), call va_end() if memory allocation fails in order
    to release the memory allocated by va_start().

    In wcserr_clear(), ensure that errp is non-NULL before dereferencing
    it.

    In tabini(), check that the total number of elements in the
    coordinate array does not exceed INT_MAX.

  - In prj.c and sph.c, removed the hand-coded copysign() macro, which
    is now provided by C99.

  - In wcsinit(), lininit(), and disinit(), check that the value
    provided for naxis is not too large.  Negative values also now
    return WCSERR_BAD_PARAM, LINERR_BAD_PARAM (new), and
    DISERR_BAD_PARAM rather than WCSERR_MEMORY, etc.

    In conjunction with the above, global variables that record various
    limits are now declared in a new header file, wcslimits.h.  Their
    values are set in wcs.c, including a limit of 31 for NAXIS and also
    the default limits for the number of PVi_ma, PSi_ma, DPja, and DQia
    keywords, which may be changed.

    In cylfix(), use the maximum value of NAXIS from wcslimits.h.

  - Throughout the C library, replaced use of strcpy() (200 occurrences)
    and strcat() (23 occurrences) with strncpy(), and sprintf() (202
    occurrences) with snprintf().  These mostly related to in-memory
    copying of string constants, etc., which are inherently well-
    constrained.

    Likewise, in wcsprintf() and wcsfprintf(), replaced use of
    vsprintf() with vsnprintf().

    Likewise for the test suite.

  - In wcsmath.h, parenthesised three macro definitions to ensure the
    correct order of precedence when used in arithmetic expressions.

  - Addressed, by way of appeasement, a plethora of inconsequential
    warnings from clang-tidy relating to putative "bug-prone"
    constructs, none of which were bugs, in the following categories:
     - bugprone-branch-clone
     - bugprone-implicit-widening-of-multiplication-result
     - bugprone-integer-division
     - bugprone-multi-level-implicit-pointer-conversion
     - bugprone-narrowing-conversions
     - bugprone-not-null-terminated-result
     - bugprone-suspicious-string-compare
     - bugprone-switch-missing-default-case
    The following categories were disabled:
     - bugprone-assignment-in-if-condition  [I drew the line here!]
     - bugprone-easily-swappable-parameters [can't change API!]
     - bugprone-reserved-identifier         [only in sundazel]

  - In the test suite, replaced the remaining heritage K&R-style
    variable declarations with intermingled ANSI-style.  Likewise for
    the last few surviving K&R-style function prototypes.

* Fortran wrappers

  - Replaced a single use of sprintf(), in keyget_(), with snprintf().

* PGSBOX

  - In cpgsbox() and cpglbox(), replaced use of strcpy() with strncpy(),
    and sprintf() with snprintf().

    Likewise for test program cpgtest.

* Utilities

  - Replaced use of strcpy() with strncpy(), and sprintf() with
    snprintf().

* Installation

  - Added rules to invoke clang-tidy (for code development).

* User manual

  - Documentation generation moved to Doxygen 1.17.0 (was 1.16.0).
    While the Doxygen bug reported in WCSLIB 8.5 has now been fixed,
    the makefile patch has been left in place for the time being.


WCSLIB version 8.6 (2026/03/30)
-------------------------------

* C library

  - In linx2p(), replaced two uses of goto statements to work around an
    apparent compiler bug.  Reported by Cyril Richard.

* PGSBOX

  - PGSBOX now accounts for the possibility that the coordinate system
    is not defined outside the frame.  Previously this was important for
    determining axis crossings and hence axis labelling.  However, it is
    not valid for -TAB coordinates in FITS for which extrapolation is
    strictly limited to half a pixel.

* User manual

  - Documentation generation moved to Doxygen 1.16.0 (was 1.15.0).
    While the Doxygen bug reported in version 8.5 has now been fixed,
    the makefile patch has been left in place for the time being.


WCSLIB version 8.5 (2025/12/06)
-------------------------------

WCSLIB's RCS version files are now included in the distribution thereby
providing a documented history of all changes made since v1.0.  They
will be found in RCS subdirectories in each code directory.  A small
number of discontinued files are preserved with their RCS version files
having a ',x' suffix instead of ',v'.

* C library

  - In linp2x(), quarantine NaN elements of the pixel coordinate vector
    from infecting non-NaN elements in the case where the PCij matrix is
    diagonal (noting that zero * NaN = NaN).  Likewise in linx2p().
    Reported by Thomas Robitaille with patch.

  - Quelled nuisance compiler warnings in wcspih() and wcsbth().

* User manual

  - Documentation generation moved to Doxygen 1.15.0 (was 1.12.0).
    The makefile patches doxygen.sty as per my Doxygen bug report 11881.


WCSLIB version 8.4 (2024/10/29)
-------------------------------

* C library

  - Fixed some problems in wcs_chksum() and changed wcs_fletcher32() to
    conform to the standard computation.

  - New test program, twcs_pthread.

* User manual

  - Documentation generation moved to doxygen 1.12.0 (was 1.10.0).


WCSLIB version 8.3 (2024/05/14)
-------------------------------

* C library

  - Until now, wcsset() always operated unconditionally - the wcsprm
    struct was set or reset regardless of its current state.  Likewise
    the various *set() functions for the other structs.

    However, in some situations, particularly in threaded applications,
    it is desirable to have wcsset(), etc., check the state of the
    struct and return immediately if it has already been set.  This may
    now be accomplished by setting wcsprm::flag == 1 (instead of 0)
    before calling wcsset().  Likewise for the other structs.  This sets
    a "bypass" flag within the struct itself.

  - A new function, wcsenq(), queries the state of the wcsprm struct,
    specifically whether WCSLIB is managing its memory, whether the
    struct has been set, whether or not it is in bypass mode, and
    whether it is self-consistent.  There are corresponding functions
    for the other structs: celenq(), disenq(), linenq(), prjenq(),
    spcenq(), and tabenq().  Please refer to the WCSLIB manual.

  - In the C test suite, modified twcs to test wcsenq() and also
    wcsset() in bypass mode.

  - Quelled nuisance compiler warnings in wcsbth(), wcspih(), wcsp2s(),
    and wcshdo().

* Fortran wrappers

  - Interprocedural Link Time Optimization (LTO), when used with the
    strict compiler options required by some Linux distributions, may
    place more stringent requirements on mixing code written in
    different languages.  Specifically, as far as WCSLIB is concerned,
    this applies for Fortran calling C (or vice versa) where the
    function parameter list includes a character variable.

    It is important to note that the existing Fortran wrappers work as
    they did before, with or without LTO, that issues only arise when
    strict LTO compiler options are enabled, and that wrappers without
    a character argument are unaffected.

    Fortran 2003 introduced the "language-binding-spec" attribute using
    the keyword BIND.  The INTERFACE block for a procedure may be given
    the BIND(C) attribute to specify the interface of an external,
    interoperable C function.  Use of this BIND(C) attribute is now
    virtually mandated by LTO (with said strict compiler options).

    The WCSLIB Fortran wrappers are written in C, e.g. wcs_f.c, with a
    Fortran-compliant interface, and these C functions are intended to
    be called directly from Fortran applications.  Three options were
    considered for achieving strict LTO compliance:

      1) Require that all existing Fortran applications be modified to
         conform to the Fortran 2003 language binding specification via
         the addition of INTERFACE blocks bearing the BIND(C) attribute
         for the existing wrappers.

         This option is clearly untenable.

      2) Rewrite the WCSLIB Fortran wrappers completely in Fortran 2003.

         It seems that this option may be tenable as the BIND(C) spec
         allows for C-equivalent derived types.  However, it would
         require rewriting all of the wrappers, 5 kloc of C code, in
         Fortran 2003 code that must directly manipulate the internals
         of all of the WCSLIB structs.

      3) Introduce a new layer of thin wrappers, written in Fortran
         2003, that do nothing more than define the INTERFACE to the
         existing wrappers written in C and then call them.
         Essentially this extracts the changes required in option (1)
         into a new set of wrappers.

         This was the option chosen on the basis of simplicity - only
         specific wrappers, namely those with character arguments, need
         be rewrapped.  It also minimises WCSLIB's exposure to Fortran
         2003, particularly for the sake of legacy astronomical packages
         such as Miriad and AIPS.  Further, it admits the possibility of
         the optional use of this extra layer of wrappers.

    The new Fortran 2003 wrappers reside in the Fortran subdirectory in
    files by the name of *_bindc.f90.  By default they are not compiled
    and not used.  To use them, WCSLIB must be configure'd with the new
    '--with-bindc' option.  This causes the new BIND(C) wrappers to be
    compiled, and the names of the old wrappers to be changed, for
    example from wcspih_() to wcspih_c().

    LTO compile problems reported by Eli Schwartz, Gentoo maintainer.

  - Added wrappers for celenq(), disenq(), linenq(), prjenq(), spcenq(),
    tabenq(), and wcsenq().

  - In the Fortran test suite, modified twcs to test WCSENQ and also
    WCSSET in bypass mode.

* PGSBOX

  - Changes mirroring those described above for the Fortran wrappers,
    the difference being that here we have a mix of C calling Fortran
    (e.g. cpgsbox() calling PGSBOX) as well as Fortran calling C (e.g.
    PGWCSL calling pgwcsl_c()).  As with the Fortran wrappers, the new
    configure option, '--with-bindc', chooses whether to use the new
    BIND(C) PGSBOX wrappers.

* Installation

  - Added '--with-bindc' as a new configure option (or BINDC=yes from
    the environment) to signal the use of the new strictly LTO-compliant
    Fortran wrappers.  See above.

  - Modified 'configure' to report the version of gcc used.  Likewise,
    for the 'show' rule in makedefs.

* User manual

  - Quelled a nuisance compiler warning in doxextr.

  - Documentation generation moved to doxygen 1.10.0 (was 1.9.8).


WCSLIB version 8.2.2 (2023/11/29)
---------------------------------

* C library (installation)

  - In prj.c, a number of variables with global scope that are only used
    internally were declared static to avoid namespace conflicts arising
    in Link Time Optimization (LTO) builds of the Rwcs wrappers.  This
    is a patch release as it does not affect the library itself other
    than in localising some symbols that were never meant to be global.
    Reported by Rodrigo Carrizo with patch.

    Likewise for an internally used helper function, prjoff().
    Likewise for a handful of variables in cel.c, dis.c, lin.c, tab.c,
    wcs.c, wcsfix.c, and wcshdr.c.


WCSLIB version 8.2.1 (2023/11/17)
---------------------------------

* Installation

  - With searching enabled in the HTML manual, doxygen creates a new
    subdirectory, html/search, which must be installed explicitly.


WCSLIB version 8.2 (2023/11/16)
-------------------------------

* C library

  - In wcshdo(), fixed character buffer overflows in the comment string
    for the longitude and latitude axes triggered by some projections,
    and also the formatting for generic coordinate systems.  Reported by
    Shu Niu.

* User manual

  - Documentation generation moved to doxygen 1.9.8 (was 1.9.7).

  - Enabled searching in the HTML manual.


WCSLIB version 8.1 (2023/07/06)
-------------------------------

Changes in the contents of the auxprm struct (in 8.0 beta) necessitated
incrementing the major version number from 7 to 8, i.e. the ABI changed.
Took the opportunity for minor tweaks to wcsprm and disprm.

* C library

  - In disprm, changed the order of maxdis and totdis to ensure correct
    alignment of doubles on 32-bit machines.

* Fortran wrappers

  - Match changes to disprm in the C library.

  - In the Fortran test suite, inserted a brief pause between plots in
    tprj2, tspc, and tpih2, which have long been a blur.

* PGSBOX

  - Quell innocuous compiler warnings from gfortran 12.1.0.  Inserted a
    brief pause between plots in pgtest and cpgtest.


WCSLIB version 8.0 beta (2023/07/01)
------------------------------------

Beta test version, not publically released.

* C library

  - Support planetary keywords A_RADIUS, B_RADIUS, C_RADIUS, BLON_OBS,
    BLAT_OBS, and BDIS_OBS in auxprm by analogy with the Solar keywords
    added at 7.1.  Requested by Chiara Marmo (Observatoire de Paris).

  - Added wcsprm::time to the wcsprm struct to record the TIME axis
    number (along with lng, lat, and spec).

  - Fixed a bug in wcspih() and wcsbth() where trailing blanks were not
    stripped from string keyvalues.  Reported by Naveen Dukiya.

    Changed test program tdis3 to test this.

  - Fixed a problem affecting thread safety in disp2x(), disx2p(), and
    diswarp().  Reported by Mohammad Akhlaghi.

* Fortran wrappers

  - Match changes to the C library supporting planetary keywords in
    auxprm and the addition of wcsprm::time.

* User manual

  - Documentation generation moved to doxygen 1.9.7 (was 1.9.5).


WCSLIB version 7.12 (2022/09/09)
--------------------------------

* C library

  - In wcsp2s() and wcss2p(), fixed handling of status returns from
    linp2x() and linx2p() relating to distortion functions, specifically
    with respect to setting the stat[] vector.  Reported by Sepideh
    Eskandarlou (via Mohammad Akhlaghi).

  - When extracting by axis type, wcssub() did not account for the
    possibility of time axes with -TAB or -LOG algorithm codes.
    Reported by Mihai Cara.

* Utilities

  - Fixed a bit of confusion in wcsgrid relating to cfitsio file opening
    syntax, e.g. file.fits+1.  It now matches wcsware in that regard.

  - Portability fix in sundazel - need to define _POSIX_C_SOURCE as
    199506L in order to get the declaration of localtime_r().  Reported
    by Marc Espie.

* User manual

  - Documentation generation moved to doxygen 1.9.5 (was 1.9.3).


WCSLIB version 7.11 (2022/04/26)
--------------------------------

* C library

  - In tabini(), the default index array should contain a 1-relative
    sequence: {1, 2,... N}.  Previously it was 0-relative.


WCSLIB version 7.10 (2022/04/24)
--------------------------------

* C library

  - In tabcpy(), collapse degenerate table index arrays if they are
    collapsed in the source struct.  Minor fix for output formatting
    in tabprt().

  - In the C test suite, added calls to wcstrim() in twcsfix to tidy
    the structs before printing.

* Utilities

  - The default option in wcsware now trims the wcsprm struct before
    printing it.  Use the '-p' option to print the untrimmed struct.


WCSLIB version 7.9 (2022/03/26)
-------------------------------

* C library

  - In wcsset(), bug fix for identifying time coordinate axes.
    Reported by Mihai Cara with patch.


WCSLIB version 7.8 (2022/03/25)
-------------------------------

* C library

  - In wcssub(), bug fix for tabular coordinates that change axis
    number, thus requiring tabprm::map to be updated.  Reported by
    Mihai Cara with patch.

    Also in wcssub():
      - check that all axes of a multi-dimensional table are extracted
        together,
      - fixed potential memory leaks for tabular coordinate axes when
        an attempt to subimage non-separable axes fails,
      - the error messages for non-separable coordinate systems are
        generally more informative,
      - subimage extraction by coordinate type now recognises time
        coordinate axis types via WCSSUB_TIME.

  - wcsset() now identifies time coordinate axes in wcsprm::types.

  - Extended test program twcssub to test the above modifications.

* Installation

  - Bug fix in the utils makefile for creating $(MANDIR)/man1.
    Reported by Aleksander Kurek.

  - Bug fix in the Fortran makefile for compiling and using 'tofits'.
    Reported by Stefan Brüns.

* User manual

  - Documentation generation moved to doxygen 1.9.3 (was 1.9.1).


WCSLIB version 7.7 (2021/07/12)
-------------------------------

* C library

  - In disfree() and disset(), removed potential for double invokation
    of free() on allocated memory.  Reported by Cyril Richard.

  - In wcsutil_fptr2str(), fixed a bug reported by Ralf Palsa (with fix)
    that caused it to be overly enthusiastic in stripping leading zeroes
    off addresses of function pointers.

  - In wcspcx(), replaced variable length arrays with allocated memory
    (portability issue).  Reported by Mihai Cara with patch.

  - Fixed buglets in wcsbth() and linsize() uncovered by gcc 11.1.0.

  - Quelled inconsequential compiler warnings from gcc 11.1.0 concerning
    wcsmix() (function prototype in wcs.h), wcstrim(), wcseulexe(),
    wcsulex(), and wcsutrne().

  - Defined _POSIX_C_SOURCE appropriately in tprj2.c and tspc.c to get
    the function prototype etc. for nanosleep() from time.h.

* Fortran wrappers

  - Quelled numerous inconsequential compiler warnings from gfortran
    11.1.0.

  - Fixed minor bugs uncovered by gfortran 11.1.0 in test programs tdis2
    and ttab3.

* Utilities

  - Moved 'tofits' from ./C/test/ into the utilities directory as it's
    generally useful, and added usage (converted to man page).

    Also made it a bit smarter in dealing with ISO/IEC 8859 and UTF-8
    encoded byte streams, in particular translating non-breaking spaces
    into ordinary spaces.

* Installation

  - Two patches for configure.ac provided by Mosč Giordano:
    1. makes it possible to build the Windows library using the MinGW
       cross-compiler,
    2. makes the soname of the MacOSX library consistent with other
       Unix systems.


WCSLIB version 7.6 (2021/04/13)
-------------------------------

* C library

  - Bug fix in tabs2x() triggered for 1-dimensional coordinate lookup
    tables on axes > 1.  Reported by Mihai Cara.

  - In datfix(), don't return status 0 if no change was made (fix for
    change made at release 7.4).  Reported by Derek Homeier.

  - New function wcspcx() in the wcsfix suite regularizes the linear
    transformation component of a coordinate description to make it more
    human-readable.  It decomposes CDi_ja into PCi_ja and CDELTia in
    such a way that CDELTia forms meaningful scaling parameters, often
    leaving an orthogonal or near-orthogonal matrix.  Optionally, it can
    then permute rows of this matrix to unscramble axis permutations.

    A test header may be generated from wcspcx.keyrec for input to
    wcsware (not exercised as part of the standard test suite).

  - New function wcstrim() frees memory allocated by wcsinit() for
    arrays in a wcsprm struct that remain unused after the struct has
    been set up.

  - New functions wcssize(), auxsize(), tabsize(), linsize(), dissize(),
    celsize(), prjsize(), spcsize(), and wcserr_size() compute the total
    size of the relevant structs, including allocated memory.

  - In the C test suite, inserted a brief pause in tprj2 and tspc, which
    otherwise have now become a blur.

* Fortran wrappers

  - Added wrappers for wcspcx(), wcstrim(), wcssize(), auxsize(),
    tabsize(), linsize(), dissize(), celsize(), prjsize(), spcsize(),
    and wcserr_size().

* Utilities

  - Added -c, -cp, -C, and -Cp options to wcsware to apply wcspcx()
    in a variety of ways, -m to apply wcstrim(), and -z to report the
    total size of the wcsprm struct with a breakdown of the sizes of
    its constituent structs.

  - Fixed compiler warnings for sundazel (portability issue).

* Installation

  - Upped the required version of Flex to 2.6.0 (was 2.5.9).  Problems
    with Flex 2.5.39 reported by Derek Homeier.

    Also added '--disable-flex' as a new configure option to force the
    use of the pre-generated Flex sources.


WCSLIB version 7.5 (2021/03/20)
-------------------------------

The C code in WCSLIB is moving piecemeal to the C99 standard.  In fact,
various indispensible C99 constructs have been used in WCSLIB for many
years: the long long int data type (in fitshdr() only); stdint.h,
inttypes.h, and the use of PRI formatting control (in wcsprintf(), which
is widely used by the library); and the C99-extended library function
vsnprintf() (used by wcserr for a decade).  Flex-generated C code also
uses C99 extensions, though with workarounds if they are not available.

Except in the header prologues, which are formatted in a special way for
generating the user manual, comments were changed en masse to C99 style
in release 7.3.1, and variable declarations in code that I have occasion
to modify will transition to the more general placement allowed by C99.
However, I have no plans to use any of the more esoteric features of
C99.

* C library

  - New function, wcsccs(), changes the celestial coordinate system of a
    wcsprm struct, for example, from equatorial to galactic coordinates.
    The parameters that define the spherical coordinate transformation
    must be provided.  This allows WCSLIB to provide this functionality
    without needing to know anything about specific celestial coordinate
    systems, and has the advantage of making the routine completely
    general.  Requested by Mohammad Akhlaghi.

    Modified test program twcsfix also to test wcsccs().

  - Fixed a problem common to all of the Flex code (fitshdr, wcsbth,
    wcspih, wcsulex, and wcsutrn) that made it thread-unsafe.  Reported
    by Cyril Richard.

    Added a new test program, tpthreads, to test thread safety.  It is
    only used for code development, and not exercised as part of the
    standard test suite.

  - In fitshdr(), fixed a problem that potentially could arise on
    systems where sizeof(long long int) is greater than 8 (64 bits).

* Fortran wrappers

  - Match changes to the C library: added a wrapper for wcsccs(), and
    modified twcsfix.f.

  - Because null addresses cannot be passed to functions in Fortran,
    wcssub_() now interprets *nsub == -1 && *axes == -1 as a signal to
    do a deep copy of one wcsprm struct to another.

* Utilities

  - New utility, sundazel, computes the local time of the Sun's passage
    through the specified apparent longitude or latitude in a user-
    defined coordinate system.  It can also perform several other Solar
    related calculations.  (It is unrelated to FITS WCS, and does not
    use WCSLIB.)

* Installation

  - Added an 'uninstall' rule to the makefiles.  Suggested by
    Cyril Richard.


WCSLIB version 7.4 (2021/01/31)
-------------------------------

* C library

  - In wcshdo(), fixed a bug introduced in release 5.9 that potentially
    caused loss of numerical precision in the sprintf() formatting of
    floating point keyvalues.  This was triggered when a large range of
    CRPIXja, PCi_ja, or CDELTia values (as three separate groups) were
    formatted using an 'f' format descriptor, the range not being so
    large that it would have forced wcshdo() to revert to 'E' format.
    Reported by Mohammad Akhlaghi.

    Also in wcshdo(), fixed a bug introduced in release 7.1 that caused
    the coefficients of the TPD distortion function not to be written to
    the header.  TPD and Polynomial distortion function headers will now
    always include the DPja.DOCORR keyword.  Reported by Derek Homeier
    with patch.

  - In wcsset(), fixed a segv generated in attempting to report a non-
    standard units string with wcserr message reporting disabled.
    Reported by Mohammad Akhlaghi.

    In wcsutrne(), allow 'Angstroms' and 'angstroms' as additional
    synonyms for 'Angstrom'.

  - In datfix(), ensure that 0 is returned if an informational message
    is set in wcsprm::err.  Consequent on feedback independently from
    Mihai Cara and Bruce Merry.

    Clarified that informational messages may be set in wcsprm::err
    for returns of 0 from datfix(), obsfix(), unitfix(), and spcfix().

* User manual

  - Added cautions about translating CDi_ja to PCi_ja plus CDELTia for
    those historical distortion functions (TPV, TNX, ZPX) that expect to
    operate on intermediate world coordinates, rather than intermediate
    pixel coordinates.  Consequent on feedback from Mohammad Akhlaghi.

  - Documentation generation moved to doxygen 1.9.1 (was 1.8.19).


WCSLIB version 7.3.1 (2020/08/17)
---------------------------------

There are no functional changes in this release.

* C library
* Fortran wrappers
* PGSBOX
* Utilities

  - Changed all C code, including within the flex sources, Fortran and
    PGSBOX wrappers, and test suite, to use C99 style commenting (i.e.
    using //), excluding the header prologues used to generate the user
    manual.

* User manual

  - Documentation generation moved to doxygen 1.8.19 (was 1.8.18).


WCSLIB version 7.3 (2020/06/03)
-------------------------------

* C library

  - wcshdo() was writing MJD-OBS twice to the header, and MJD-BEG not
    at all.

  - In wcshdo(), if MJDREF assumes its default value, just write
    MJDREF = 0 (not MJDREFI & MJDREFF), and omit writing DATEREF,
    which, with a value of '1858-11-17', looks strange and is
    potentially confusing.  Reported by Thomas Robitaille.

    If the fractional part of MJDREF is zero, then just write the
    integer part as MJDREF (i.e. not as MJDREFI & MJDREFF).

  - Bug fix in wcsfix() - it was writing error messages that referred
    to DATE-REF and MJD-REF rather then DATEREF and MJDREF.  Reported
    by Mihai Cara.

  - Under control of a new flag, WCSHDR_DATEREF, added the option to
    wcspih() and wcsbth() to accept DATE-REF, MJD-REF, MJD-REFI,
    MJD-REFF, JDREF, JD-REFI, and JD-REFF as synonyms for the standard
    keywords, DATEREF, MJDREF, MJDREFI, MJDREFF, JDREF, JDREFI, and
    JDREFF.  The latter buck the pattern set by the other date keywords
    ({DATE,MJD}-{OBS,BEG,AVG,END}), thereby increasing the potential
    for confusion and error.

* Fortran wrappers

  - As compilers are becoming much stricter (gfortran 10), modified all
    Fortran test programs to use the type-specific equivalents of the
    various *PUT and *GET routines.  Reported by Ole Streicher.

  - For the fitshdr wrappers, added type-specific equivalents of
    KEYGET: KEYGTI, KEYGTD, and KEYGTC.

* PGSBOX

  - Modified pgtest to use the type-specific equivalents of WCSPUT.

* User manual

  - In the section "WCSLIB Fortran wrappers", promoted use of the type-
    specific equivalents of the various *PUT and *GET routines.

  - In the section "FITS-WCS and related software", added ASCL and ADS
    codes, where they exist, for all software packages mentioned.

  - Documentation generation moved to doxygen 1.8.18 (was 1.8.17).


WCSLIB version 7.2 (2020/03/09)
-------------------------------

* C library

  - In wcssub(), fixed a bug relating to handling coordinate lookup
    tables.  Reported by Mihai Cara with fix.

    Also increased the number of coordinate axes handled from 10 to 32.

* Installation

  - New configure option, '--disable-shared', defeats generation of the
    sharable library.


WCSLIB version 7.1 (2020/01/01)
-------------------------------

Changes in the contents of the wcsprm struct necessitated incrementing
the major version number from 6 to 7 (i.e. the ABI changed).

* C library

  - In wcsset(), set wcsprm::mjdref[] to zero if neither it nor
    wcsprm::dateref are defined, as per the standard.  Reported by
    Thomas Robitaille.

    wcsset() now also checks that the number of coordinate axes does not
    exceed 32.

  - In tabs2x(), fixed an out-of-bounds array access produced by invalid
    world coordinates.  Reported by Mihai Cara and Michael Seifert.

    In tab.c, declare static three helper functions, tabedge(),
    tabrow(), and tabvox(), used by tabs2x().  Increased the number of
    coordinate axes handled by tabvox() from 16 to 32.

  - Extended datfix() to handle MJDREF/DATEREF, overlooked in the
    changes in release 6.1.  Also fixed the handling of MJD < 0.

  - Support Solar keywords RSUN_REF, DSUN_OBS, CRLN_OBS, CRLT_OBS,
    HGLN_OBS, and HGLT_OBS by accomodating them within an auxiliary
    struct, auxprm, within the wcsprm struct.  Now filled by the header
    parsers, wcspih() and wcsbth() and handled routinely by wcsinit(),
    wcssub(), wcscompare(), wcsfree(), wcsprt(), wcsset(), and wcshdo().
    Requested by Stuart Mumford (SunPy) with input from Bill Thompson.

  - Bug fix in wcsprintf_set() for resetting the output disposition.
    Reported by Mihai Cara with patch.

  - In dis.{h,c}, the DOCORR record is now handled as a first-class
    value via disprm::docorr.  This required changing the struct.

  - In cel.c, spc.c, wcserr.c, wcsfix.c, wcshdr.c, and wcsutil.c,
    quelled compiler warnings from gcc 9.2.0 generated by
    -Wmaybe-uninitialized and -Wstringop-truncation (via -Wall).

    Similarly for various programs in the test suite.

  - In various functions, quelled warnings from the Microsoft Visual C++
    compiler, mostly relating to pointer arithmetic.  Reported by
    Michael Seifert.

* Fortran wrappers

  - Handled compiler warnings from gcc 9.2.0 generated by
    -Wstringop-truncation (via -Wall).

  - Minor enhancements to character argument handling, including, in
    prjget_(), blank-filling the returned strings matching PRJ_CODE and
    PRJ_NAME, and likewise for SPC_TYPE and SPC_CODE in spcget_().

* Utilities

  - In wcsgrid, handled compiler warnings from gcc 9.2.0 generated by
    -Wstringop-truncation (via -Wall).

* User manual

  - In the section on "FITS-WCS and related software", added mention of
    the R wrappers (Rwcs).  Suggested by Aaron Robotham.

  - Added a new section detailing the limit on the number of image axes
    that WCSLIB can handle (currently 32), and how this could be
    increased if needed.  Prompted by Thomas Robitaille.

  - Augmented the section on the Fortran wrappers, particularly with
    respect to character string handling in argument lists.

  - Documentation generation moved to doxygen 1.8.17 (was 1.8.16).


WCSLIB version 6.4 (2019/08/15)
-------------------------------

* Installation

  - The rule change to the Fortran makefile in v6.3 to add getwcstab_f.o
    to the sharable library causes it to depend on CFITSIO to resolve
    fits_get_wcstab().  Hence backed out of that change.

* User manual

  - Documentation generation moved to doxygen 1.8.16 (was 1.8.14).


WCSLIB version 6.3 (2019/07/12)
-------------------------------

* C library

  - Fixed the Polynomial and TPD distortions so that, as stipulated in
    WCS Paper IV, they are now considered to return an additive
    correction to be applied to the given coordinates, rather than the
    corrected coordinates themselves.

    Added a new subsection to the prologue of dis.h entitled 'Historical
