libsndfile: update to 1.0.19 (LBSNDF-7)

http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2009-0186
http://www.mega-nerd.com/libsndfile/libsndfile-1.0.19.tar.gz

This will likely require a fresh boostrap to updated source checkouts.

git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@13415 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
Michael Jerris
2009-05-21 21:09:30 +00:00
parent d875d23de5
commit 77fab7603a
252 changed files with 28081 additions and 6032 deletions

View File

@@ -1,5 +1,5 @@
/*
** Copyright (C) 1999-2006 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 1999-2009 Erik de Castro Lopo <erikd@mega-nerd.com>
** Copyright (C) 2005 David Viens <davidv@plogue.com>
**
** This program is free software; you can redistribute it and/or modify
@@ -58,6 +58,8 @@
#define sowt_MARKER (MAKE_MARKER ('s', 'o', 'w', 't'))
#define twos_MARKER (MAKE_MARKER ('t', 'w', 'o', 's'))
#define raw_MARKER (MAKE_MARKER ('r', 'a', 'w', ' '))
#define in24_MARKER (MAKE_MARKER ('i', 'n', '2', '4'))
#define ni24_MARKER (MAKE_MARKER ('4', '2', 'n', '1'))
#define in32_MARKER (MAKE_MARKER ('i', 'n', '3', '2'))
#define ni32_MARKER (MAKE_MARKER ('2', '3', 'n', 'i'))
@@ -75,6 +77,14 @@
#define GSM_MARKER (MAKE_MARKER ('G', 'S', 'M', ' '))
#define ima4_MARKER (MAKE_MARKER ('i', 'm', 'a', '4'))
/*
** This value is officially assigned to Mega Nerd Pty Ltd by Apple
** Corportation as the Application marker for libsndfile.
**
** See : http://developer.apple.com/faq/datatype.html
*/
#define m3ga_MARKER (MAKE_MARKER ('m', '3', 'g', 'a'))
/* Unsupported AIFC encodings.*/
#define MAC3_MARKER (MAKE_MARKER ('M', 'A', 'C', '3'))
@@ -172,8 +182,12 @@ typedef struct
} MARK_ID_POS ;
typedef struct
{ sf_count_t comm_offset ;
{ PRIV_CHUNK4 chunk4 ;
sf_count_t comm_offset ;
sf_count_t ssnd_offset ;
MARK_ID_POS *markstr ;
} AIFF_PRIVATE ;
/*------------------------------------------------------------------------------
@@ -214,7 +228,7 @@ aiff_open (SF_PRIVATE *psf)
memset (&comm_fmt, 0, sizeof (comm_fmt)) ;
subformat = psf->sf.format & SF_FORMAT_SUBMASK ;
subformat = SF_CODEC (psf->sf.format) ;
if ((psf->container_data = calloc (1, sizeof (AIFF_PRIVATE))) == NULL)
return SFE_MALLOC_FAILED ;
@@ -222,7 +236,6 @@ aiff_open (SF_PRIVATE *psf)
if (psf->mode == SFM_READ || (psf->mode == SFM_RDWR && psf->filelength > 0))
{ if ((error = aiff_read_header (psf, &comm_fmt)))
return error ;
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
} ;
@@ -230,7 +243,7 @@ aiff_open (SF_PRIVATE *psf)
{ if (psf->is_pipe)
return SFE_NO_PIPE_WRITE ;
if ((psf->sf.format & SF_FORMAT_TYPEMASK) != SF_FORMAT_AIFF)
if ((SF_CONTAINER (psf->sf.format)) != SF_FORMAT_AIFF)
return SFE_BAD_OPEN_FORMAT ;
if (psf->mode == SFM_WRITE && (subformat == SF_FORMAT_FLOAT || subformat == SF_FORMAT_DOUBLE))
@@ -257,7 +270,7 @@ aiff_open (SF_PRIVATE *psf)
psf->container_close = aiff_close ;
psf->command = aiff_command ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
switch (SF_CODEC (psf->sf.format))
{ case SF_FORMAT_PCM_U8 :
error = pcm_init (psf) ;
break ;
@@ -353,13 +366,15 @@ marker_to_position (const MARK_ID_POS *m, unsigned short n, int marksize)
static int
aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
{ SSND_CHUNK ssnd_fmt ;
MARK_ID_POS *markstr = NULL ;
AIFF_PRIVATE *paiff ;
unsigned marker, dword, FORMsize, SSNDsize, bytesread ;
int k, found_chunk = 0, done = 0, error = 0 ;
char *cptr, byte ;
int instr_found = 0, mark_found = 0, mark_count = 0 ;
if (psf->filelength > SF_PLATFORM_S64 (0xffffffff))
psf_log_printf (psf, "Warning : filelength > 0xffffffff. This is bad!!!!\n") ;
if ((paiff = psf->container_data) == NULL)
return SFE_INTERNAL ;
@@ -390,6 +405,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
return SFE_AIFF_NO_FORM ;
psf_binheader_readf (psf, "E4", &FORMsize) ;
pchk4_store (&(paiff->chunk4), marker, psf->headindex - 8, FORMsize) ;
if (psf->fileoffset > 0 && psf->filelength > FORMsize + 8)
{ /* Set file length. */
@@ -417,6 +433,8 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
case COMM_MARKER :
paiff->comm_offset = psf_ftell (psf) - 4 ;
error = aiff_read_comm_chunk (psf, comm_fmt) ;
pchk4_store (&paiff->chunk4, marker, paiff->comm_offset, comm_fmt->size) ;
psf->sf.samplerate = tenbytefloat2int (comm_fmt->sampleRate) ;
psf->sf.frames = comm_fmt->numSampleFrames ;
@@ -435,6 +453,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
return SFE_AIFF_PEAK_B4_COMM ;
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf->headindex - 8, dword) ;
psf_log_printf (psf, "%M : %d\n", marker, dword) ;
if (dword != AIFF_PEAK_CHUNK_SIZE (psf->sf.channels))
@@ -466,20 +485,22 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
psf->peak_info->peaks [dword].value = value ;
psf->peak_info->peaks [dword].position = position ;
LSF_SNPRINTF (cptr, sizeof (psf->u.scbuf), " %2d %-12ld %g\n",
snprintf (cptr, sizeof (psf->u.scbuf), " %2d %-12ld %g\n",
dword, (long) psf->peak_info->peaks [dword].position, psf->peak_info->peaks [dword].value) ;
cptr [sizeof (psf->u.scbuf) - 1] = 0 ;
psf_log_printf (psf, cptr) ;
} ;
psf->peak_info->peak_loc = ((found_chunk & HAVE_SSND) == 0) ? SF_PEAK_START : SF_PEAK_END ;
break ;
case SSND_MARKER :
if ((found_chunk & HAVE_AIFC) && (found_chunk & HAVE_FVER) == 0)
psf_log_printf (psf, "*** Valid AIFC files should have an FVER chunk.\n") ;
paiff->ssnd_offset = psf_ftell (psf) - 4 ;
psf_binheader_readf (psf, "E444", &SSNDsize, &(ssnd_fmt.offset), &(ssnd_fmt.blocksize)) ;
pchk4_store (&paiff->chunk4, marker, paiff->ssnd_offset, SSNDsize) ;
psf->datalength = SSNDsize - sizeof (ssnd_fmt) ;
psf->dataoffset = psf_ftell (psf) ;
@@ -491,27 +512,37 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
else
psf_log_printf (psf, " SSND : %u\n", SSNDsize) ;
if (ssnd_fmt.offset == 0 || psf->dataoffset + ssnd_fmt.offset == ssnd_fmt.blocksize)
{ psf_log_printf (psf, " Offset : %u\n", ssnd_fmt.offset) ;
psf_log_printf (psf, " Block Size : %u\n", ssnd_fmt.blocksize) ;
psf->dataoffset += ssnd_fmt.offset ;
psf->datalength -= ssnd_fmt.offset ;
}
else
{ psf_log_printf (psf, " Offset : %u (Should be zero)\n", ssnd_fmt.offset) ;
psf_log_printf (psf, " Block Size : %u ???\n", ssnd_fmt.blocksize) ;
} ;
/* Only set dataend if there really is data at the end. */
if (psf->datalength + psf->dataoffset < psf->filelength)
psf->dataend = psf->datalength + psf->dataoffset ;
psf_log_printf (psf, " Offset : %u\n", ssnd_fmt.offset) ;
psf_log_printf (psf, " Block Size : %u\n", ssnd_fmt.blocksize) ;
found_chunk |= HAVE_SSND ;
if (! psf->sf.seekable)
break ;
/* Seek to end of SSND chunk. */
/* Seek to end of SSND chunk. */
psf_fseek (psf, psf->dataoffset + psf->datalength + (SSNDsize & 1), SEEK_SET) ;
break ;
case c_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
if (dword == 0)
break ;
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1)
if (dword >= SIGNED_SIZEOF (psf->u.scbuf))
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
return SFE_INTERNAL ;
} ;
@@ -519,15 +550,19 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
cptr = psf->u.cbuf ;
psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
cptr [dword] = 0 ;
psf_sanitize_string (cptr, dword) ;
psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
psf_store_string (psf, SF_STR_COPYRIGHT, cptr) ;
break ;
case AUTH_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
if (dword == 0)
break ;
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 1)
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 1)
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
return SFE_INTERNAL ;
} ;
@@ -544,6 +579,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
unsigned int timestamp ;
psf_binheader_readf (psf, "E42", &dword, &count) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
psf_log_printf (psf, " %M : %d\n count : %d\n", marker, dword, count) ;
dword += (dword & 1) ;
if (dword == 0)
@@ -571,7 +607,10 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
break ;
case APPL_MARKER :
{ unsigned appl_marker ;
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
if (dword == 0)
break ;
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 1)
@@ -580,8 +619,14 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
break ;
} ;
if (dword < 4)
{ psf_log_printf (psf, " %M : %d (too small, skipping)\n", marker, dword) ;
psf_binheader_readf (psf, "j", dword + (dword & 1)) ;
break ;
} ;
cptr = psf->u.cbuf ;
psf_binheader_readf (psf, "b", cptr, dword + (dword & 1)) ;
psf_binheader_readf (psf, "mb", &appl_marker, cptr, dword + (dword & 1) - 4) ;
cptr [dword] = 0 ;
for (k = 0 ; k < (int) dword ; k++)
@@ -590,15 +635,17 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
break ;
} ;
psf_log_printf (psf, " %M : %s\n", marker, cptr) ;
psf_log_printf (psf, " %M : %d\n AppSig : %M\n Name : %s\n", marker, dword, appl_marker, cptr) ;
psf_store_string (psf, SF_STR_SOFTWARE, cptr) ;
} ;
break ;
case NAME_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
if (dword == 0)
break ;
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 2)
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 2)
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
return SFE_INTERNAL ;
} ;
@@ -612,9 +659,10 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
case ANNO_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
if (dword == 0)
break ;
if (dword > SIGNED_SIZEOF (psf->u.scbuf) - 2)
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 2)
{ psf_log_printf (psf, " %M : %d (too big)\n", marker, dword) ;
return SFE_INTERNAL ;
} ;
@@ -628,6 +676,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
case INST_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
if (dword != SIZEOF_INST_CHUNK)
{ psf_log_printf (psf, " %M : %d (should be %d)\n", marker, dword, SIZEOF_INST_CHUNK) ;
psf_binheader_readf (psf, "j", dword) ;
@@ -679,7 +728,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
loop_mode = get_loop_mode_str (mode) ;
mode = get_loop_mode (mode) ;
if (mode == SF_LOOP_NONE)
psf->instrument->loops [0].mode = SF_LOOP_NONE ;
psf->instrument->loops [1].mode = SF_LOOP_NONE ;
else
{ psf->instrument->loop_count += 1 ;
psf->instrument->loops [1].mode = SF_LOOP_FORWARD ;
@@ -695,6 +744,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
case basc_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
psf_log_printf (psf, " basc : %u\n", dword) ;
if ((error = aiff_read_basc_chunk (psf, dword)))
@@ -703,6 +753,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
case MARK_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
{ unsigned short mark_id, n = 0 ;
unsigned char pstr_len ;
@@ -710,20 +761,27 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
bytesread = psf_binheader_readf (psf, "E2", &n) ;
mark_count = n ;
markstr = calloc (mark_count, sizeof (MARK_ID_POS)) ;
psf_log_printf (psf, " Count : %d\n", mark_count) ;
if (paiff->markstr != NULL)
{ psf_log_printf (psf, "*** Second MARK chunk found. Throwing away the first.\n") ;
free (paiff->markstr) ;
} ;
paiff->markstr = calloc (mark_count, sizeof (MARK_ID_POS)) ;
if (paiff->markstr == NULL)
return SFE_MALLOC_FAILED ;
for (n = 0 ; n < mark_count && bytesread < dword ; n++)
{ bytesread += psf_binheader_readf (psf, "E241", &mark_id, &position, &pstr_len) ;
psf_log_printf (psf, " Mark ID : %u\n Position : %u\n", mark_id, position) ;
pstr_len += (pstr_len & 1) + 1 ; /* fudgy, fudgy, hack, hack */
pstr_len += (pstr_len & 1) ? 0 : 1 ;
bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, pstr_len) ;
psf->u.scbuf [pstr_len] = 0 ;
psf_log_printf (psf, " Name : %s\n", psf->u.scbuf) ;
markstr [n].markerID = mark_id ;
markstr [n].position = position ;
paiff->markstr [n].markerID = mark_id ;
paiff->markstr [n].position = position ;
/*
** TODO if psf->u.scbuf is equal to
** either Beg_loop, Beg loop or beg loop and spam
@@ -742,6 +800,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
case SFX_MARKER :
psf_binheader_readf (psf, "E4", &dword) ;
pchk4_store (&paiff->chunk4, marker, psf_ftell (psf) - 8, dword) ;
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
psf_binheader_readf (psf, "j", dword) ;
@@ -786,16 +845,13 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
for (j = 0 ; j<psf->instrument->loop_count ; j ++)
{ if (j < ARRAY_LEN (psf->instrument->loops))
{ psf->instrument->loops [j].start = marker_to_position (markstr, psf->instrument->loops [j].start, mark_count) ;
psf->instrument->loops [j].end = marker_to_position (markstr, psf->instrument->loops [j].end, mark_count) ;
{ psf->instrument->loops [j].start = marker_to_position (paiff->markstr, psf->instrument->loops [j].start, mark_count) ;
psf->instrument->loops [j].end = marker_to_position (paiff->markstr, psf->instrument->loops [j].end, mark_count) ;
psf->instrument->loops [j].mode = SF_LOOP_FORWARD ;
} ;
} ;
} ;
if (markstr)
free (markstr) ;
if (! (found_chunk & HAVE_FORM))
return SFE_AIFF_NO_FORM ;
@@ -813,7 +869,13 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
static int
aiff_close (SF_PRIVATE *psf)
{
{ AIFF_PRIVATE *paiff = psf->container_data ;
if (paiff != NULL && paiff->markstr != NULL)
{ free (paiff->markstr) ;
paiff->markstr = NULL ;
} ;
if (psf->mode == SFM_WRITE || psf->mode == SFM_RDWR)
{ aiff_write_tailer (psf) ;
aiff_write_header (psf, SF_TRUE) ;
@@ -840,23 +902,31 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
psf_binheader_readf (psf, "E242b", &(comm_fmt->numChannels), &(comm_fmt->numSampleFrames),
&(comm_fmt->sampleSize), &(comm_fmt->sampleRate), SIGNED_SIZEOF (comm_fmt->sampleRate)) ;
if (comm_fmt->size > 0x10000 && (comm_fmt->size & 0xffff) == 0)
{ psf_log_printf (psf, " COMM : %d (0x%x) *** should be ", comm_fmt->size, comm_fmt->size) ;
comm_fmt->size = ENDSWAP_INT (comm_fmt->size) ;
psf_log_printf (psf, "%d (0x%x)\n", comm_fmt->size, comm_fmt->size) ;
}
else
psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ;
if (comm_fmt->size == SIZEOF_AIFF_COMM)
comm_fmt->encoding = NONE_MARKER ;
else if (comm_fmt->size == SIZEOF_AIFC_COMM_MIN)
bytesread += psf_binheader_readf (psf, "Em", &(comm_fmt->encoding)) ;
else if (comm_fmt->size >= SIZEOF_AIFC_COMM)
{ unsigned char encoding_len ;
unsigned read_len ;
bytesread += psf_binheader_readf (psf, "Em1", &(comm_fmt->encoding), &encoding_len) ;
comm_fmt->size = SF_MIN (sizeof (psf->u.scbuf), make_size_t (comm_fmt->size)) ;
memset (psf->u.scbuf, 0, comm_fmt->size) ;
bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf,
comm_fmt->size - SIZEOF_AIFC_COMM + 1) ;
psf->u.scbuf [encoding_len] = 0 ;
read_len = comm_fmt->size - SIZEOF_AIFC_COMM + 1 ;
bytesread += psf_binheader_readf (psf, "b", psf->u.scbuf, read_len) ;
psf->u.scbuf [read_len + 1] = 0 ;
} ;
psf_log_printf (psf, " COMM : %d\n", comm_fmt->size) ;
psf_log_printf (psf, " Sample Rate : %d\n", tenbytefloat2int (comm_fmt->sampleRate)) ;
psf_log_printf (psf, " Frames : %u%s\n", comm_fmt->numSampleFrames, (comm_fmt->numSampleFrames == 0 && psf->filelength > 104) ? " (Should not be 0)" : "") ;
psf_log_printf (psf, " Channels : %d\n", comm_fmt->numChannels) ;
@@ -883,11 +953,13 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
break ;
case twos_MARKER :
case in24_MARKER :
case in32_MARKER :
psf->sf.format = (SF_ENDIAN_BIG | SF_FORMAT_AIFF | subformat) ;
break ;
case sowt_MARKER :
case ni24_MARKER :
case ni32_MARKER :
psf->endian = SF_ENDIAN_LITTLE ;
psf->sf.format = (SF_ENDIAN_LITTLE | SF_FORMAT_AIFF | subformat) ;
@@ -961,13 +1033,71 @@ aiff_read_comm_chunk (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
} /* aiff_read_comm_chunk */
/*==========================================================================================
*/
static int
aiff_rewrite_header (SF_PRIVATE *psf, AIFF_PRIVATE * paiff)
{
/* Assuming here that the header has already been written and just
** needs to be corrected for new data length. That means that we
** only change the length fields of the FORM and SSND chunks ;
** everything else can be skipped over.
*/
int k, ch ;
int comm_size, comm_frames ;
psf_fseek (psf, 0, SEEK_SET) ;
psf_fread (psf->header, psf->dataoffset, 1, psf) ;
psf->headindex = 0 ;
for (k = 0 ; k < paiff->chunk4.count ; k++)
{ switch (paiff->chunk4.l [k].chunk)
{ case FORM_MARKER :
psf_binheader_writef (psf, "Etm8", FORM_MARKER, psf->filelength - 8) ;
break ;
case COMM_MARKER :
psf->headindex = paiff->chunk4.l [k].offset ;
comm_frames = psf->sf.frames ;
comm_size = paiff->chunk4.l [k].len ;
psf_binheader_writef (psf, "Em42t4", COMM_MARKER, comm_size, psf->sf.channels, comm_frames) ;
break ;
case SSND_MARKER :
psf->headindex = paiff->chunk4.l [k].offset ;
psf_binheader_writef (psf, "Etm8", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK) ;
break ;
case PEAK_MARKER :
psf->headindex = paiff->chunk4.l [k].offset ;
psf_binheader_writef (psf, "Em4", PEAK_MARKER, AIFF_PEAK_CHUNK_SIZE (psf->sf.channels)) ;
psf_binheader_writef (psf, "E44", 1, time (NULL)) ;
for (ch = 0 ; ch < psf->sf.channels ; ch++)
psf_binheader_writef (psf, "Eft8", (float) psf->peak_info->peaks [ch].value, psf->peak_info->peaks [ch].position) ;
break ;
default :
/* There are a whole bunch of chunks we should just ignore. */
break ;
} ;
} ;
/* Header mangling complete so write it out. */
psf_fseek (psf, 0, SEEK_SET) ;
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
return 0 ;
} /* aiff_rewrite_header */
static int
aiff_write_header (SF_PRIVATE *psf, int calc_length)
{ sf_count_t current ;
AIFF_PRIVATE *paiff ;
unsigned char comm_sample_rate [10], comm_zero_bytes [2] = { 0, 0 } ;
unsigned int comm_type, comm_size, comm_encoding, comm_frames ;
int k, endian ;
unsigned int comm_type, comm_size, comm_encoding, comm_frames = 0 ;
int k, endian, has_data = SF_FALSE ;
short bit_width ;
if ((paiff = psf->container_data) == NULL)
@@ -975,6 +1105,9 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
current = psf_ftell (psf) ;
if (current > psf->dataoffset)
has_data = SF_TRUE ;
if (calc_length)
{ psf->filelength = psf_get_filelen (psf) ;
@@ -986,43 +1119,14 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
} ;
if (psf->mode == SFM_RDWR && psf->dataoffset > 0)
{ /* Assuming here that the header has already been written and just
** needs to be corrected for new data length. That means that we
** only change the length fields of the FORM and SSND chunks ;
** everything else can be skipped over.
*/
/* First write new FORM chunk. */
psf->headindex = 0 ;
psf_fseek (psf, 0, SEEK_SET) ;
psf_binheader_writef (psf, "Etm8", FORM_MARKER, psf->filelength - 8) ;
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
/* Now write frame count field of COMM chunk header. */
psf->headindex = 0 ;
psf_fseek (psf, paiff->comm_offset + 10, SEEK_SET) ;
psf_binheader_writef (psf, "Et8", psf->sf.frames) ;
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
/* Now write new SSND chunk header. */
psf->headindex = 0 ;
psf_fseek (psf, paiff->ssnd_offset, SEEK_SET) ;
psf_binheader_writef (psf, "Etm8", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK) ;
psf_fwrite (psf->header, psf->headindex, 1, psf) ;
if (current < psf->dataoffset)
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
else if (current > 0)
if (psf->mode == SFM_RDWR && psf->dataoffset > 0 && paiff->chunk4.count > 0)
{ int err = aiff_rewrite_header (psf, paiff) ;
if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
return 0 ;
return err ;
} ;
endian = psf->sf.format & SF_FORMAT_ENDMASK ;
endian = SF_ENDIAN (psf->sf.format) ;
if (CPU_IS_LITTLE_ENDIAN && endian == SF_ENDIAN_CPU)
endian = SF_ENDIAN_LITTLE ;
@@ -1030,7 +1134,7 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
bit_width = psf->bytewidth * 8 ;
comm_frames = (psf->sf.frames > 0xFFFFFFFF) ? 0xFFFFFFFF : psf->sf.frames ;
switch (psf->sf.format & SF_FORMAT_SUBMASK)
switch (SF_CODEC (psf->sf.format))
{ case SF_FORMAT_PCM_S8 :
case SF_FORMAT_PCM_16 :
case SF_FORMAT_PCM_24 :
@@ -1158,16 +1262,16 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
/* Write AIFF/AIFC marker and COM chunk. */
if (comm_type == AIFC_MARKER)
/* AIFC must have an FVER chunk. */
psf_binheader_writef (psf, "Emm44m4", comm_type, FVER_MARKER, 4, 0xA2805140, COMM_MARKER, comm_size) ;
psf_binheader_writef (psf, "Emm44", comm_type, FVER_MARKER, 4, 0xA2805140) ;
else
psf_binheader_writef (psf, "Emm4", comm_type, COMM_MARKER, comm_size) ;
psf_binheader_writef (psf, "Em", comm_type) ;
paiff->comm_offset = psf->headindex - 8 ;
memset (comm_sample_rate, 0, sizeof (comm_sample_rate)) ;
uint2tenbytefloat (psf->sf.samplerate, comm_sample_rate) ;
psf_binheader_writef (psf, "Et242", psf->sf.channels, comm_frames, bit_width) ;
psf_binheader_writef (psf, "Em42t42", COMM_MARKER, comm_size, psf->sf.channels, comm_frames, bit_width) ;
psf_binheader_writef (psf, "b", comm_sample_rate, sizeof (comm_sample_rate)) ;
/* AIFC chunks have some extra data. */
@@ -1253,9 +1357,12 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
if (psf->error)
return psf->error ;
if (has_data && psf->dataoffset != psf->headindex)
return psf->error = SFE_INTERNAL ;
psf->dataoffset = psf->headindex ;
if (current < psf->dataoffset)
if (! has_data)
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
else if (current > 0)
psf_fseek (psf, current, SEEK_SET) ;
@@ -1298,7 +1405,7 @@ aiff_write_tailer (SF_PRIVATE *psf)
static void
aiff_write_strings (SF_PRIVATE *psf, int location)
{ int k ;
{ int k, slen ;
for (k = 0 ; k < SF_MAX_STRINGS ; k++)
{ if (psf->strings [k].type == 0)
@@ -1309,7 +1416,8 @@ aiff_write_strings (SF_PRIVATE *psf, int location)
switch (psf->strings [k].type)
{ case SF_STR_SOFTWARE :
psf_binheader_writef (psf, "EmS", APPL_MARKER, psf->strings [k].str) ;
slen = strlen (psf->strings [k].str) ;
psf_binheader_writef (psf, "Em4mb", APPL_MARKER, slen + 4, m3ga_MARKER, psf->strings [k].str, make_size_t (slen + (slen & 1))) ;
break ;
case SF_STR_TITLE :
@@ -1340,17 +1448,8 @@ aiff_write_strings (SF_PRIVATE *psf, int location)
} /* aiff_write_strings */
static int
aiff_command (SF_PRIVATE *psf, int command, void *data, int datasize)
aiff_command (SF_PRIVATE * UNUSED (psf), int UNUSED (command), void * UNUSED (data), int UNUSED (datasize))
{
/* Avoid compiler warnings. */
psf = psf ;
data = data ;
datasize = datasize ;
switch (command)
{ default : break ;
} ;
return 0 ;
} /* aiff_command */
@@ -1448,10 +1547,11 @@ static int
aiff_read_basc_chunk (SF_PRIVATE * psf, int datasize)
{ const char * type_str ;
basc_CHUNK bc ;
int count ;
psf_binheader_readf (psf, "E442", &bc.version, &bc.numBeats, &bc.rootNote) ;
psf_binheader_readf (psf, "E222", &bc.scaleType, &bc.sigNumerator, &bc.sigDenominator) ;
psf_binheader_readf (psf, "E2j", &bc.loopType, datasize - sizeof (bc)) ;
count = psf_binheader_readf (psf, "E442", &bc.version, &bc.numBeats, &bc.rootNote) ;
count += psf_binheader_readf (psf, "E222", &bc.scaleType, &bc.sigNumerator, &bc.sigDenominator) ;
count += psf_binheader_readf (psf, "E2j", &bc.loopType, datasize - sizeof (bc)) ;
psf_log_printf (psf, " Version ? : %u\n Num Beats : %u\n Root Note : 0x%x\n",
bc.version, bc.numBeats, bc.rootNote) ;
@@ -1504,13 +1604,9 @@ aiff_read_basc_chunk (SF_PRIVATE * psf, int datasize)
* ((bc.numBeats * 4.0) / bc.sigDenominator) * 60.0 ;
psf->loop_info->root_key = bc.rootNote ;
if (count < datasize)
psf_binheader_readf (psf, "j", datasize - count) ;
return 0 ;
} /* aiff_read_basc_chunk */
/*
** Do not edit or modify anything in this comment block.
** The arch-tag line is a file identity tag for the GNU Arch
** revision control system.
**
** arch-tag: 7dec56ca-d6f2-48cf-863b-a72e7e17a5d9
*/