/* 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 "misc.h"
#include <speex/speex_header.h>
#include <speex/speex.h>

#ifndef NULL
#define NULL 0
#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;
*/

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;
}

char *speex_header_to_packet(SpeexHeader *header, int *size)
{
   SpeexHeader *le_header;
   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
   
   speex_move(le_header, header, sizeof(SpeexHeader));
   
   /*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;
}

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_warning ("This doesn't look like a Speex file");
         return NULL;
      }
   
   /*FIXME: Do we allow larger headers?*/
   if (size < (int)sizeof(SpeexHeader))
   {
      speex_warning("Speex header too small");
      return NULL;
   }
   
   le_header = (SpeexHeader*)speex_alloc(sizeof(SpeexHeader));
   
   speex_move(le_header, packet, sizeof(SpeexHeader));
   
   /*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);

   return le_header;

}
