/* Copyright (C) 2002 Jean-Marc Valin 
   File: speex_header.c
   Describes the Speex header

   Redistribution and use in source and binary forms, with or without
   modification, are permitted provided that the following conditions
   are met:
   
   - Redistributions of source code must retain the above copyright
   notice, this list of conditions and the following disclaimer.
   
   - Redistributions in binary form must reproduce the above copyright
   notice, this list of conditions and the following disclaimer in the
   documentation and/or other materials provided with the distribution.
   
   - Neither the name of the Xiph.org Foundation nor the names of its
   contributors may be used to endorse or promote products derived from
   this software without specific prior written permission.
   
   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
   ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
   A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR
   CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include "arch.h"
#include "../include/speex/speex_header.h"
#include "../include/speex/speex.h"
#include "os_support.h"

#ifndef NULL
#define NULL 0
#endif

/** Convert little endian */
static inline spx_int32_t le_int(spx_int32_t i)
{
#if !defined(__LITTLE_ENDIAN__) && ( defined(WORDS_BIGENDIAN) || defined(__BIG_ENDIAN__) )
   spx_uint32_t ui, ret;
   ui = i;
   ret =  ui>>24;
   ret |= (ui>>8)&0x0000ff00;
   ret |= (ui<<8)&0x00ff0000;
   ret |= (ui<<24);
   return ret;
#else
   return i;
#endif
}

#define ENDIAN_SWITCH(x) {x=le_int(x);}


/*
typedef struct SpeexHeader {
   char speex_string[8];
   char speex_version[SPEEX_HEADER_VERSION_LENGTH];
   int speex_version_id;
   int header_size;
   int rate;
   int mode;
   int mode_bitstream_version;
   int nb_channels;
   int bitrate;
   int frame_size;
   int vbr;
   int frames_per_packet;
   int extra_headers;
   int reserved1;
   int reserved2;
} SpeexHeader;
*/

EXPORT void speex_init_header(SpeexHeader *header, int rate, int nb_channels, const SpeexMode *m)
{
   int i;
   const char *h="Speex   ";
   /*
   strncpy(header->speex_string, "Speex   ", 8);
   strncpy(header->speex_version, SPEEX_VERSION, SPEEX_HEADER_VERSION_LENGTH-1);
   header->speex_version[SPEEX_HEADER_VERSION_LENGTH-1]=0;
   */
   for (i=0;i<8;i++)
      header->speex_string[i]=h[i];
   for (i=0;i<SPEEX_HEADER_VERSION_LENGTH-1 && SPEEX_VERSION[i];i++)
      header->speex_version[i]=SPEEX_VERSION[i];
   for (;i<SPEEX_HEADER_VERSION_LENGTH;i++)
      header->speex_version[i]=0;
   
   header->speex_version_id = 1;
   header->header_size = sizeof(SpeexHeader);
   
   header->rate = rate;
   header->mode = m->modeID;
   header->mode_bitstream_version = m->bitstream_version;
   if (m->modeID<0)
      speex_warning("This mode is meant to be used alone");
   header->nb_channels = nb_channels;
   header->bitrate = -1;
   speex_mode_query(m, SPEEX_MODE_FRAME_SIZE, &header->frame_size);
   header->vbr = 0;
   
   header->frames_per_packet = 0;
   header->extra_headers = 0;
   header->reserved1 = 0;
   header->reserved2 = 0;
}

EXPORT char *speex_header_to_packet(SpeexHeader *header, int *size)
{
   SpeexHeader *le_header;
   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
   
   SPEEX_COPY(le_header, header, 1);
   
   /*Make sure everything is now little-endian*/
   ENDIAN_SWITCH(le_header->speex_version_id);
   ENDIAN_SWITCH(le_header->header_size);
   ENDIAN_SWITCH(le_header->rate);
   ENDIAN_SWITCH(le_header->mode);
   ENDIAN_SWITCH(le_header->mode_bitstream_version);
   ENDIAN_SWITCH(le_header->nb_channels);
   ENDIAN_SWITCH(le_header->bitrate);
   ENDIAN_SWITCH(le_header->frame_size);
   ENDIAN_SWITCH(le_header->vbr);
   ENDIAN_SWITCH(le_header->frames_per_packet);
   ENDIAN_SWITCH(le_header->extra_headers);

   *size = sizeof(SpeexHeader);
   return (char *)le_header;
}

EXPORT SpeexHeader *speex_packet_to_header(char *packet, int size)
{
   int i;
   SpeexHeader *le_header;
   const char *h = "Speex   ";
   for (i=0;i<8;i++)
      if (packet[i]!=h[i])
      {
         speex_notify("This doesn't look like a Speex file");
         return NULL;
      }
   
   /*FIXME: Do we allow larger headers?*/
   if (size < (int)sizeof(SpeexHeader))
   {
      speex_notify("Speex header too small");
      return NULL;
   }
   
   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
   
   SPEEX_COPY(le_header, (SpeexHeader*)packet, 1);
   
   /*Make sure everything is converted correctly from little-endian*/
   ENDIAN_SWITCH(le_header->speex_version_id);
   ENDIAN_SWITCH(le_header->header_size);
   ENDIAN_SWITCH(le_header->rate);
   ENDIAN_SWITCH(le_header->mode);
   ENDIAN_SWITCH(le_header->mode_bitstream_version);
   ENDIAN_SWITCH(le_header->nb_channels);
   ENDIAN_SWITCH(le_header->bitrate);
   ENDIAN_SWITCH(le_header->frame_size);
   ENDIAN_SWITCH(le_header->vbr);
   ENDIAN_SWITCH(le_header->frames_per_packet);
   ENDIAN_SWITCH(le_header->extra_headers);

   if (le_header->mode >= SPEEX_NB_MODES || le_header->mode < 0)
   {
      speex_notify("Invalid mode specified in Speex header");
      speex_free (le_header);
      return NULL;
   }

   if (le_header->nb_channels>2)
      le_header->nb_channels = 2;
   if (le_header->nb_channels<1)
      le_header->nb_channels = 1;

   return le_header;

}

EXPORT void speex_header_free(void *ptr)
{
   speex_free(ptr);
}
