/* $Id: qfits_byteswap.c,v 1.2 2009-11-27 12:37:19 agabasch Exp $
 *
 * This file is part of the ESO QFITS Library
 * Copyright (C) 2001-2004 European Southern Observatory
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

/*
 * $Author: agabasch $
 * $Date: 2009-11-27 12:37:19 $
 * $Revision: 1.2 $
 * $Name: not supported by cvs2svn $
 */

/*-----------------------------------------------------------------------------
                                   Includes
 -----------------------------------------------------------------------------*/

#include "config.h"

#include "qfits_byteswap.h"

/*----------------------------------------------------------------------------*/
/**
 * @defgroup    qfits_byteswap  Low-level byte-swapping routines
 *
 *  This module offers access to byte-swapping routines.
 *  Generic routines are offered that should work everywhere.
 *  Assembler is also included for x86 architectures, and dedicated
 *  assembler calls for processors > 386.
 *
 */
/*----------------------------------------------------------------------------*/
/**@{*/

/*-----------------------------------------------------------------------------
                              Function codes
 -----------------------------------------------------------------------------*/

/*----------------------------------------------------------------------------*/
/**
  @brief    Swap a 16-bit number
  @param    w A 16-bit (short) number to byte-swap.
  @return   The swapped version of w, w is untouched.

  This function swaps a 16-bit number, returned the swapped value without
  modifying the passed argument. Assembler included for x86 architectures.
 */
/*----------------------------------------------------------------------------*/
unsigned short qfits_swap_bytes_16(unsigned short w)
{
    return (((w) & 0x00ff) << 8 | ((w) & 0xff00) >> 8);
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Swap a 32-bit number
  @param    dw A 32-bit (long) number to byte-swap.
  @return   The swapped version of dw, dw is untouched.

  This function swaps a 32-bit number, returned the swapped value without
  modifying the passed argument. Assembler included for x86 architectures
  and optimized for processors above 386.
 */
/*----------------------------------------------------------------------------*/
unsigned int qfits_swap_bytes_32(unsigned int dw)
{
    return ((((dw) & 0xff000000) >> 24) | (((dw) & 0x00ff0000) >>  8) |
            (((dw) & 0x0000ff00) <<  8) | (((dw) & 0x000000ff) << 24));
}

/*----------------------------------------------------------------------------*/
/**
  @brief    Swaps bytes in a variable of given size
  @param    p pointer to void (generic pointer)
  @param    s size of the element to swap, pointed to by p
  @return    void

  This byte-swapper is portable and works for any even variable size.
  It is not truly the most efficient ever, but does its job fine
  everywhere this file compiles.
 */
/*----------------------------------------------------------------------------*/
void qfits_swap_bytes(void * p, int s)
{
    unsigned char tmp, *a, *b ;

    a = (unsigned char*)p ;
    b = a + s ;

    while (a<b) {
        tmp = *a ;
        *a++ = *--b ;
        *b = tmp ;
    }
}

/**@}*/
