/* -*- mode: c -*- */

/* Licensed under a 3-clause BSD style license - see LICENSE.rst */

/* "projections.c" is auto-generated by erfa_generator.py from the
   template "projections.c.templ". Do *not* edit "projections.c"
   directly. */

#include <Python.h> /* Python */

#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include <numpy/arrayobject.h> /* Numpy */
#include <numpy/npy_math.h> /* Numpy */

#include "prj.h" /* from wcslib */
#include "wcsmath.h"


#if PY_MAJOR_VERSION >= 3
#define PY3K 1
#else
#define PY3K 0
#endif


static void set_error(int status) {
  switch (status) {
  case 1:
    PyErr_SetString(PyExc_MemoryError, "NULL pointer passed");
    break;
  case 2:
    PyErr_SetString(PyExc_ValueError, "Invalid projection parameters");
    break;
  default:
    PyErr_SetString(PyExc_RuntimeError, "Unknown error");
    break;
  }
}


static PyObject *do_work(struct prjprm *prj, PyObject *in[2],
                         int (*prjset)(struct prjprm *),
                         int (*prjtrn)(struct prjprm *, int, int, int, int, const double[], const double[], double[], double[], int[]))
{
  PyArrayObject* in_array[2] = { NULL, NULL };
  PyArrayObject* out_array[2] = { NULL, NULL };
  PyArrayObject* stat_array = NULL;
  Py_ssize_t n;
  Py_ssize_t i;
  PyObject* result = NULL;
  int status = -1;

  prj->phi0 = UNDEFINED;
  prj->theta0 = UNDEFINED;

  if ((status = prjset(prj))) {
    goto exit;
  }

  /* TODO: This assumes the same shape for the input arrays.  Instead,
     we should broadcast */

  for (i = 0; i < 2; ++i) {
    in_array[i] = (PyArrayObject *) PyArray_ContiguousFromObject(
        in[i], NPY_DOUBLE, 1, NPY_MAXDIMS);
    if (in_array[i] == NULL) {
      goto exit;
    }
  }

  if (PyArray_NDIM(in_array[0]) != PyArray_NDIM(in_array[1])) {
    PyErr_SetString(PyExc_ValueError, "input array dimensions do not match");
    goto exit;
  }

  n = 1;
  for (i = 0; i < PyArray_NDIM(in_array[0]); ++i) {
    if (PyArray_DIM(in_array[0], i) != PyArray_DIM(in_array[1], i)) {
      PyErr_SetString(PyExc_ValueError, "input array dimensions do not match");
      goto exit;
    }
    n *= PyArray_DIM(in_array[0], i);
  }

  for (i = 0; i < 2; ++i) {
    out_array[i] = (PyArrayObject *) PyArray_SimpleNew(
        PyArray_NDIM(in_array[0]), PyArray_DIMS(in_array[0]), NPY_DOUBLE);
    if (out_array[i] == NULL) {
      goto exit;
    }
  }

  stat_array = (PyArrayObject *) PyArray_SimpleNew(
      PyArray_NDIM(in_array[0]), PyArray_DIMS(in_array[0]), NPY_INT);
  if (stat_array == NULL) {
    goto exit;
  }

  Py_BEGIN_ALLOW_THREADS

  status = prjtrn(prj, n, 0, 1, 1,
                  (double *)PyArray_DATA(in_array[0]),
                  (double *)PyArray_DATA(in_array[1]),
                  (double *)PyArray_DATA(out_array[0]),
                  (double *)PyArray_DATA(out_array[1]),
                  (int *)PyArray_DATA(stat_array));

  Py_END_ALLOW_THREADS

  if (status) {
    if (status == 3) {
      for (i = 0; i < n; ++i) {
        if (((int *)PyArray_DATA(stat_array))[i]) {
          ((double *)PyArray_DATA(out_array[0]))[i] = NPY_NAN;
          ((double *)PyArray_DATA(out_array[1]))[i] = NPY_NAN;
        }
      }
      status = 0;
    } else {
      goto exit;
    }
  }

  result = Py_BuildValue("(OO)", out_array[0], out_array[1]);

 exit:
  if (status > 0) {
    set_error(status);
  }

  for (i = 0; i < 2; ++i) {
    Py_XDECREF(in_array[i]);
    Py_XDECREF(out_array[i]);
  }
  Py_XDECREF(stat_array);

  return result;
}




static PyObject*
Py_azpx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":azpx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, azpset, azpx2s);
}


static PyObject*
Py_azps2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":azps2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, azpset, azps2x);
}




static PyObject*
Py_szpx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" "d" 
                        ":szpx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        ,
                        
                        
                        &prj.pv[2 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, szpset, szpx2s);
}


static PyObject*
Py_szps2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" "d" 
                        ":szps2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        ,
                        
                        
                        &prj.pv[2 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, szpset, szps2x);
}




static PyObject*
Py_tanx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":tanx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, tanset, tanx2s);
}


static PyObject*
Py_tans2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":tans2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, tanset, tans2x);
}




static PyObject*
Py_stgx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":stgx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, stgset, stgx2s);
}


static PyObject*
Py_stgs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":stgs2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, stgset, stgs2x);
}




static PyObject*
Py_sinx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":sinx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, sinset, sinx2s);
}


static PyObject*
Py_sins2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":sins2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, sinset, sins2x);
}




static PyObject*
Py_arcx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":arcx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, arcset, arcx2s);
}


static PyObject*
Py_arcs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":arcs2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, arcset, arcs2x);
}




static PyObject*
Py_zeax2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":zeax2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, zeaset, zeax2s);
}


static PyObject*
Py_zeas2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":zeas2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, zeaset, zeas2x);
}




static PyObject*
Py_airx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" 
                        ":airx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, airset, airx2s);
}


static PyObject*
Py_airs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" 
                        ":airs2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, airset, airs2x);
}




static PyObject*
Py_cypx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":cypx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, cypset, cypx2s);
}


static PyObject*
Py_cyps2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":cyps2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, cypset, cyps2x);
}




static PyObject*
Py_ceax2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" 
                        ":ceax2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, ceaset, ceax2s);
}


static PyObject*
Py_ceas2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" 
                        ":ceas2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, ceaset, ceas2x);
}




static PyObject*
Py_merx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":merx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, merset, merx2s);
}


static PyObject*
Py_mers2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":mers2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, merset, mers2x);
}




static PyObject*
Py_sflx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":sflx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, sflset, sflx2s);
}


static PyObject*
Py_sfls2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":sfls2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, sflset, sfls2x);
}




static PyObject*
Py_parx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":parx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, parset, parx2s);
}


static PyObject*
Py_pars2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":pars2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, parset, pars2x);
}




static PyObject*
Py_molx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":molx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, molset, molx2s);
}


static PyObject*
Py_mols2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":mols2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, molset, mols2x);
}




static PyObject*
Py_aitx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":aitx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, aitset, aitx2s);
}


static PyObject*
Py_aits2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":aits2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, aitset, aits2x);
}




static PyObject*
Py_copx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":copx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, copset, copx2s);
}


static PyObject*
Py_cops2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":cops2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, copset, cops2x);
}




static PyObject*
Py_coex2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":coex2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, coeset, coex2s);
}


static PyObject*
Py_coes2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":coes2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, coeset, coes2x);
}




static PyObject*
Py_codx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":codx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, codset, codx2s);
}


static PyObject*
Py_cods2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":cods2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, codset, cods2x);
}




static PyObject*
Py_coox2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":coox2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, cooset, coox2s);
}


static PyObject*
Py_coos2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":coos2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, cooset, coos2x);
}




static PyObject*
Py_bonx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" 
                        ":bonx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, bonset, bonx2s);
}


static PyObject*
Py_bons2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" 
                        ":bons2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, bonset, bons2x);
}




static PyObject*
Py_pcox2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":pcox2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, pcoset, pcox2s);
}


static PyObject*
Py_pcos2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":pcos2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, pcoset, pcos2x);
}




static PyObject*
Py_tscx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":tscx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, tscset, tscx2s);
}


static PyObject*
Py_tscs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":tscs2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, tscset, tscs2x);
}




static PyObject*
Py_cscx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":cscx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, cscset, cscx2s);
}


static PyObject*
Py_cscs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":cscs2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, cscset, cscs2x);
}




static PyObject*
Py_qscx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":qscx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, qscset, qscx2s);
}


static PyObject*
Py_qscs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":qscs2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, qscset, qscs2x);
}




static PyObject*
Py_hpxx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":hpxx2s",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, hpxset, hpxx2s);
}


static PyObject*
Py_hpxs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        "d" "d" 
                        ":hpxs2x",
                        &in[0], &in[1]
                        
                        ,
                        &prj.pv[0 + 1]
                        ,
                        
                        
                        &prj.pv[1 + 1]
                        
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, hpxset, hpxs2x);
}




static PyObject*
Py_xphx2s(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":xphx2s",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, xphset, xphx2s);
}


static PyObject*
Py_xphs2x(PyObject* __, PyObject* args, PyObject* kwds)
{
  PyObject* in[2] = { NULL, NULL };

  struct prjprm prj;

  memset(&prj, 0, sizeof(struct prjprm));

  if (!PyArg_ParseTuple(args,
                        "OO"
                        
                        ":xphs2x",
                        &in[0], &in[1]
                        
                        )) {
    return NULL;
  }

  return do_work(&prj, in, xphset, xphs2x);
}





/***************************************************************************
 * Module-level
 ***************************************************************************/

static PyMethodDef module_methods[] = {
  
  
  {"azpx2s", (PyCFunction)Py_azpx2s, METH_VARARGS, NULL},
  
  {"azps2x", (PyCFunction)Py_azps2x, METH_VARARGS, NULL},
  
  
  
  {"szpx2s", (PyCFunction)Py_szpx2s, METH_VARARGS, NULL},
  
  {"szps2x", (PyCFunction)Py_szps2x, METH_VARARGS, NULL},
  
  
  
  {"tanx2s", (PyCFunction)Py_tanx2s, METH_VARARGS, NULL},
  
  {"tans2x", (PyCFunction)Py_tans2x, METH_VARARGS, NULL},
  
  
  
  {"stgx2s", (PyCFunction)Py_stgx2s, METH_VARARGS, NULL},
  
  {"stgs2x", (PyCFunction)Py_stgs2x, METH_VARARGS, NULL},
  
  
  
  {"sinx2s", (PyCFunction)Py_sinx2s, METH_VARARGS, NULL},
  
  {"sins2x", (PyCFunction)Py_sins2x, METH_VARARGS, NULL},
  
  
  
  {"arcx2s", (PyCFunction)Py_arcx2s, METH_VARARGS, NULL},
  
  {"arcs2x", (PyCFunction)Py_arcs2x, METH_VARARGS, NULL},
  
  
  
  {"zeax2s", (PyCFunction)Py_zeax2s, METH_VARARGS, NULL},
  
  {"zeas2x", (PyCFunction)Py_zeas2x, METH_VARARGS, NULL},
  
  
  
  {"airx2s", (PyCFunction)Py_airx2s, METH_VARARGS, NULL},
  
  {"airs2x", (PyCFunction)Py_airs2x, METH_VARARGS, NULL},
  
  
  
  {"cypx2s", (PyCFunction)Py_cypx2s, METH_VARARGS, NULL},
  
  {"cyps2x", (PyCFunction)Py_cyps2x, METH_VARARGS, NULL},
  
  
  
  {"ceax2s", (PyCFunction)Py_ceax2s, METH_VARARGS, NULL},
  
  {"ceas2x", (PyCFunction)Py_ceas2x, METH_VARARGS, NULL},
  
  
  
  {"merx2s", (PyCFunction)Py_merx2s, METH_VARARGS, NULL},
  
  {"mers2x", (PyCFunction)Py_mers2x, METH_VARARGS, NULL},
  
  
  
  {"sflx2s", (PyCFunction)Py_sflx2s, METH_VARARGS, NULL},
  
  {"sfls2x", (PyCFunction)Py_sfls2x, METH_VARARGS, NULL},
  
  
  
  {"parx2s", (PyCFunction)Py_parx2s, METH_VARARGS, NULL},
  
  {"pars2x", (PyCFunction)Py_pars2x, METH_VARARGS, NULL},
  
  
  
  {"molx2s", (PyCFunction)Py_molx2s, METH_VARARGS, NULL},
  
  {"mols2x", (PyCFunction)Py_mols2x, METH_VARARGS, NULL},
  
  
  
  {"aitx2s", (PyCFunction)Py_aitx2s, METH_VARARGS, NULL},
  
  {"aits2x", (PyCFunction)Py_aits2x, METH_VARARGS, NULL},
  
  
  
  {"copx2s", (PyCFunction)Py_copx2s, METH_VARARGS, NULL},
  
  {"cops2x", (PyCFunction)Py_cops2x, METH_VARARGS, NULL},
  
  
  
  {"coex2s", (PyCFunction)Py_coex2s, METH_VARARGS, NULL},
  
  {"coes2x", (PyCFunction)Py_coes2x, METH_VARARGS, NULL},
  
  
  
  {"codx2s", (PyCFunction)Py_codx2s, METH_VARARGS, NULL},
  
  {"cods2x", (PyCFunction)Py_cods2x, METH_VARARGS, NULL},
  
  
  
  {"coox2s", (PyCFunction)Py_coox2s, METH_VARARGS, NULL},
  
  {"coos2x", (PyCFunction)Py_coos2x, METH_VARARGS, NULL},
  
  
  
  {"bonx2s", (PyCFunction)Py_bonx2s, METH_VARARGS, NULL},
  
  {"bons2x", (PyCFunction)Py_bons2x, METH_VARARGS, NULL},
  
  
  
  {"pcox2s", (PyCFunction)Py_pcox2s, METH_VARARGS, NULL},
  
  {"pcos2x", (PyCFunction)Py_pcos2x, METH_VARARGS, NULL},
  
  
  
  {"tscx2s", (PyCFunction)Py_tscx2s, METH_VARARGS, NULL},
  
  {"tscs2x", (PyCFunction)Py_tscs2x, METH_VARARGS, NULL},
  
  
  
  {"cscx2s", (PyCFunction)Py_cscx2s, METH_VARARGS, NULL},
  
  {"cscs2x", (PyCFunction)Py_cscs2x, METH_VARARGS, NULL},
  
  
  
  {"qscx2s", (PyCFunction)Py_qscx2s, METH_VARARGS, NULL},
  
  {"qscs2x", (PyCFunction)Py_qscs2x, METH_VARARGS, NULL},
  
  
  
  {"hpxx2s", (PyCFunction)Py_hpxx2s, METH_VARARGS, NULL},
  
  {"hpxs2x", (PyCFunction)Py_hpxs2x, METH_VARARGS, NULL},
  
  
  
  {"xphx2s", (PyCFunction)Py_xphx2s, METH_VARARGS, NULL},
  
  {"xphs2x", (PyCFunction)Py_xphs2x, METH_VARARGS, NULL},
  
  
  {NULL}  /* Sentinel */
};

struct module_state {
/* The Sun compiler can't handle empty structs */
#if defined(__SUNPRO_C) || defined(_MSC_VER)
    int _dummy;
#endif
};

#if PY3K
    static struct PyModuleDef moduledef = {
        PyModuleDef_HEAD_INIT,
        "_projections",
        NULL,
        sizeof(struct module_state),
        module_methods,
        NULL,
        NULL,
        NULL,
        NULL
    };

    #define INITERROR return NULL

    PyMODINIT_FUNC
    PyInit__projections(void)

#else
    #define INITERROR return

    PyMODINIT_FUNC
    init_projections(void)
#endif

{
  PyObject* m;

#if PY3K
  m = PyModule_Create(&moduledef);
#else
  m = Py_InitModule3("_projections", module_methods, NULL);
#endif

  if (m == NULL)
    INITERROR;

  import_array();

#ifdef HAVE_WCSLIB_VERSION
  if (PyModule_AddStringConstant(m, "__version__", wcslib_version(NULL))) {
    INITERROR;
  }
#else
  if (PyModule_AddStringConstant(m, "__version__", "4.x")) {
    INITERROR;
  }
#endif

#if PY3K
  return m;
#endif
}