/*
** Copyright (C) 2010-2011 Erik de Castro Lopo <erikd@mega-nerd.com>
**
** All rights reserved.
**
** 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 author nor the names of any 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 COPYRIGHT OWNER 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.
*/

#include	<stdio.h>
#include	<stdlib.h>
#include	<string.h>
#include	<inttypes.h>
#include	<ctype.h>
#include	<math.h>
#include	<errno.h>
#include	<unistd.h>
#include	<fcntl.h>
#include	<sys/stat.h>
#include	<sys/types.h>

#include	<sndfile.h>

#include	"common.h"

#define	BUFFER_LEN		(1 << 16)

#define	NOT(x)			(! (x))


static void usage_exit (const char *progname) ;
static void salvage_file (const char * broken_wav, const char * fixed_w64) ;

int
main (int argc, char *argv [])
{
	if (argc != 3)
		usage_exit (program_name (argv [0])) ;

	salvage_file (argv [1], argv [2]) ;

	return 0 ;
} /* main */

/*==============================================================================
*/

static void lseek_or_die (int fd, off_t offset, int whence) ;
static sf_count_t get_file_length (int fd, const char * name) ;
static sf_count_t find_data_offset (int fd, int format) ;
static void copy_data (int fd, SNDFILE * sndfile, int readsize) ;


static void
usage_exit (const char *progname)
{	printf ("Usage :\n\n  %s <broken wav file> <fixed w64 file>\n\n", progname) ;
	puts ("Salvages the audio data from WAV files which are more than 4G in length.\n") ;
	printf ("Using %s.\n\n", sf_version_string ()) ;
	exit (0) ;
} /* usage_exit */

static void
salvage_file (const char * broken_wav, const char * fixed_w64)
{	SNDFILE * sndfile ;
	SF_INFO sfinfo ;
	sf_count_t broken_len, data_offset ;
	int fd, read_size ;

	if (strcmp (broken_wav, fixed_w64) == 0)
	{	printf ("Error : Input and output files must be different.\n\n") ;
		exit (1) ;
		} ;

	if ((fd = open (broken_wav, O_RDONLY)) < 0)
	{	printf ("Error : Not able to open file '%s' : %s\n", broken_wav, strerror (errno)) ;
		exit (1) ;
		} ;

	broken_len = get_file_length (fd, broken_wav) ;
	if (broken_len <= 0xffffffff)
		printf ("File is not greater than 4Gig but salvaging anyway.\n") ;

	/* Grab the format info from the broken file. */
	memset (&sfinfo, 0, sizeof (sfinfo)) ;
	if ((sndfile = sf_open (broken_wav, SFM_READ, &sfinfo)) == NULL)
	{	printf ("sf_open ('%s') failed : %s\n", broken_wav, sf_strerror (NULL)) ;
		exit (1) ;
		} ;
	sf_close (sndfile) ;

	data_offset = find_data_offset (fd, sfinfo.format & SF_FORMAT_TYPEMASK) ;

	printf ("Offset to audio data : %" PRId64 "\n", data_offset) ;

	switch (sfinfo.format & SF_FORMAT_TYPEMASK)
	{	case SF_FORMAT_WAV :
		case SF_FORMAT_WAVEX :
			sfinfo.format = SF_FORMAT_W64 | (sfinfo.format & SF_FORMAT_SUBMASK) ;
			break ;

		default :
			printf ("Don't currently support this file type.\n") ;
			exit (1) ;
		} ;

	switch (sfinfo.format & SF_FORMAT_SUBMASK)
	{	case SF_FORMAT_PCM_U8 :
		case SF_FORMAT_PCM_S8 :
				read_size = 1 ;
				break ;

		case SF_FORMAT_PCM_16 :
				read_size = 2 ;
				break ;

		case SF_FORMAT_PCM_24 :
				read_size = 3 ;
				break ;

		case SF_FORMAT_PCM_32 :
		case SF_FORMAT_FLOAT :
				read_size = 4 ;
				break ;

		case SF_FORMAT_DOUBLE :
				read_size = 8 ;
				break ;

		default :
			printf ("Sorry, don't currently support this file encoding type.\n") ;
			exit (1) ;
		} ;

	read_size *= sfinfo.channels ;

	if ((sndfile = sf_open (fixed_w64, SFM_WRITE, &sfinfo)) == NULL)
	{	printf ("sf_open ('%s') failed : %s\n", broken_wav, sf_strerror (NULL)) ;
		exit (1) ;
		} ;

	lseek_or_die (fd, data_offset, SEEK_SET) ;

	copy_data (fd, sndfile, read_size) ;

	sf_close (sndfile) ;

	puts ("Done!") ;
} /* salvage_file */

/*------------------------------------------------------------------------------
*/

static void
lseek_or_die (int fd, off_t offset, int whence)
{
	if (lseek (fd, offset, whence) < 0)
	{	printf ("lseek failed : %s\n", strerror (errno)) ;
		exit (1) ;
		} ;

	return ;
} /* lseek_or_die */


static sf_count_t
get_file_length (int fd, const char * name)
{	struct stat sbuf ;

	if (sizeof (sbuf.st_size) != 8)
	{	puts ("Error : sizeof (sbuf.st_size) != 8. Was program compiled with\n"
				"        64 bit file offsets?\n") ;
		exit (1) ;
		} ;

	if (fstat (fd, &sbuf) != 0)
	{	printf ("Error : fstat ('%s') failed : %s\n", name, strerror (errno)) ;
		exit (1) ;
		} ;

	return sbuf.st_size ;
} /* get_file_length */

static sf_count_t
find_data_offset (int fd, int format)
{	char buffer [8192], *cptr ;
	const char * target = "XXXX" ;
	sf_count_t offset = -1, extra ;
	int rlen, slen ;

	switch (format)
	{	case SF_FORMAT_WAV :
		case SF_FORMAT_WAVEX :
			target = "data" ;
			extra = 8 ;
			break ;

		case SF_FORMAT_AIFF :
			target = "SSND" ;
			extra = 16 ;
			break ;

		default :
			puts ("Error : Sorry, don't handle this input file format.\n") ;
			exit (1) ;
		} ;

	slen = strlen (target) ;

	lseek_or_die (fd, 0, SEEK_SET) ;

	printf ("Searching for '%s' maker.\n", target) ;

	if ((rlen = read (fd, buffer, sizeof (buffer))) < 0)
	{	printf ("Error : failed read : %s\n", strerror (errno)) ;
		exit (1) ;
		} ;

	cptr = memchr (buffer, target [0], rlen - slen) ;
	if (cptr && memcmp (cptr, target, slen) == 0)
		offset = cptr - buffer  ;
	else
	{	printf ("Error : Could not find data offset.\n") ;
		exit (1) ;
		} ;

	return offset + extra ;
} /* find_data_offset */

static void
copy_data (int fd, SNDFILE * sndfile, int readsize)
{	static char * buffer ;
	sf_count_t readlen, count ;
	int bufferlen, done = 0 ;

	bufferlen = readsize * 1024 ;
	buffer = malloc (bufferlen) ;

	while (NOT (done) && (readlen = read (fd, buffer, bufferlen)) >= 0)
	{	if (readlen < bufferlen)
		{	readlen -= readlen % readsize ;
			done = 1 ;
			} ;

		if ((count = sf_write_raw (sndfile, buffer, readlen)) != readlen)
		{	printf ("Error : sf_write_raw returned %" PRId64 " : %s\n", count, sf_strerror (sndfile)) ;
			return ;
			} ;
		} ;

	free (buffer) ;

	return ;
} /* copy_data */

