mirror of
https://gitee.com/openharmony/third_party_libsnd
synced 2024-11-27 03:50:29 +00:00
Make custom chunks work on AIFF files.
This commit is contained in:
parent
40ea763f58
commit
f472c9b2c9
@ -1,3 +1,11 @@
|
||||
2011-12-31 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
|
||||
|
||||
* tests/chunk_test.c tests/Makefile.am
|
||||
New test for custom chunks.
|
||||
|
||||
* src/aiff.c src/chunk.c src/common.h src/sndfile.c
|
||||
Make custom chunks work on AIFF files.
|
||||
|
||||
2011-11-12 Erik de Castro Lopo <erikd AT mega-nerd DOT com>
|
||||
|
||||
* src/sndfile.h.in src/common.h src/sndfile.c
|
||||
|
117
src/aiff.c
117
src/aiff.c
@ -222,6 +222,10 @@ static int aiff_read_chanmap (SF_PRIVATE * psf, unsigned dword) ;
|
||||
|
||||
static unsigned int marker_to_position (const MARK_ID_POS *m, unsigned short n, int marksize) ;
|
||||
|
||||
static int aiff_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info) ;
|
||||
static int aiff_get_chunk_size (SF_PRIVATE *psf, SF_CHUNK_INFO * chunk_info) ;
|
||||
static int aiff_get_chunk_data (SF_PRIVATE *psf, SF_CHUNK_INFO * chunk_info) ;
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
** Public function.
|
||||
*/
|
||||
@ -241,6 +245,10 @@ aiff_open (SF_PRIVATE *psf)
|
||||
if (psf->file.mode == SFM_READ || (psf->file.mode == SFM_RDWR && psf->filelength > 0))
|
||||
{ if ((error = aiff_read_header (psf, &comm_fmt)))
|
||||
return error ;
|
||||
|
||||
psf->get_chunk_size = aiff_get_chunk_size ;
|
||||
psf->get_chunk_data = aiff_get_chunk_data ;
|
||||
|
||||
psf_fseek (psf, psf->dataoffset, SEEK_SET) ;
|
||||
} ;
|
||||
|
||||
@ -270,6 +278,8 @@ aiff_open (SF_PRIVATE *psf)
|
||||
return error ;
|
||||
|
||||
psf->write_header = aiff_write_header ;
|
||||
|
||||
psf->set_chunk = aiff_set_chunk ;
|
||||
} ;
|
||||
|
||||
psf->container_close = aiff_close ;
|
||||
@ -410,7 +420,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
return SFE_AIFF_NO_FORM ;
|
||||
|
||||
psf_binheader_readf (psf, "E4", &FORMsize) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf->headindex - 8, FORMsize) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf->headindex - 8, FORMsize) ;
|
||||
|
||||
if (psf->fileoffset > 0 && psf->filelength > FORMsize + 8)
|
||||
{ /* Set file length. */
|
||||
@ -438,7 +448,7 @@ 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) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, paiff->comm_offset, comm_fmt->size) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, paiff->comm_offset, comm_fmt->size) ;
|
||||
|
||||
psf->sf.samplerate = tenbytefloat2int (comm_fmt->sampleRate) ;
|
||||
psf->sf.frames = comm_fmt->numSampleFrames ;
|
||||
@ -457,7 +467,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
return SFE_AIFF_PEAK_B4_COMM ;
|
||||
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf->headindex - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf->headindex - 8, dword) ;
|
||||
|
||||
psf_log_printf (psf, "%M : %d\n", marker, dword) ;
|
||||
if (dword != AIFF_PEAK_CHUNK_SIZE (psf->sf.channels))
|
||||
@ -504,7 +514,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
paiff->ssnd_offset = psf_ftell (psf) - 4 ;
|
||||
psf_binheader_readf (psf, "E444", &SSNDsize, &(ssnd_fmt.offset), &(ssnd_fmt.blocksize)) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, paiff->ssnd_offset, SSNDsize) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, paiff->ssnd_offset, SSNDsize) ;
|
||||
|
||||
psf->datalength = SSNDsize - sizeof (ssnd_fmt) ;
|
||||
psf->dataoffset = psf_ftell (psf) ;
|
||||
@ -545,7 +555,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case c_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf))
|
||||
@ -565,7 +575,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case AUTH_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 1)
|
||||
@ -585,7 +595,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
unsigned int timestamp ;
|
||||
|
||||
psf_binheader_readf (psf, "E42", &dword, &count) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, 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)
|
||||
@ -616,7 +626,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
{ unsigned appl_marker ;
|
||||
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 1)
|
||||
@ -648,7 +658,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case NAME_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 2)
|
||||
@ -665,7 +675,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case ANNO_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
if (dword == 0)
|
||||
break ;
|
||||
if (dword >= SIGNED_SIZEOF (psf->u.scbuf) - 2)
|
||||
@ -682,7 +692,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case INST_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, 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) ;
|
||||
@ -750,7 +760,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case basc_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_log_printf (psf, " basc : %u\n", dword) ;
|
||||
|
||||
if ((error = aiff_read_basc_chunk (psf, dword)))
|
||||
@ -759,7 +769,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case MARK_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
|
||||
{ unsigned short mark_id, n = 0 ;
|
||||
unsigned int position ;
|
||||
@ -816,7 +826,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case SFX_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_log_printf (psf, " %M : %d\n", marker, dword) ;
|
||||
|
||||
psf_binheader_readf (psf, "j", dword) ;
|
||||
@ -833,7 +843,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
|
||||
case CHAN_MARKER :
|
||||
psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_chunk_store (&psf->chunk_log, marker, psf_ftell (psf) - 8, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf) - 8, dword) ;
|
||||
|
||||
if (dword < 12)
|
||||
{ psf_log_printf (psf, " %M : %d (should be >= 12)\n", marker, dword) ;
|
||||
@ -852,6 +862,7 @@ aiff_read_header (SF_PRIVATE *psf, COMM_CHUNK *comm_fmt)
|
||||
&& psf_isprint ((marker >> 8) & 0xFF) && psf_isprint (marker & 0xFF))
|
||||
{ psf_binheader_readf (psf, "E4", &dword) ;
|
||||
psf_log_printf (psf, " %M : %d (unknown marker)\n", marker, dword) ;
|
||||
psf_store_read_chunk (&psf->rchunks, marker, psf_ftell (psf), dword) ;
|
||||
|
||||
psf_binheader_readf (psf, "j", dword) ;
|
||||
break ;
|
||||
@ -1078,34 +1089,34 @@ aiff_rewrite_header (SF_PRIVATE *psf)
|
||||
** 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 ;
|
||||
uint32_t k ;
|
||||
int ch, 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 < psf->chunk_log.count ; k++)
|
||||
{ switch (psf->chunk_log.chunks [k].marker)
|
||||
for (k = 0 ; k < psf->rchunks.count ; k++)
|
||||
{ switch (psf->rchunks.chunks [k].marker)
|
||||
{ case FORM_MARKER :
|
||||
psf_binheader_writef (psf, "Etm8", FORM_MARKER, psf->filelength - 8) ;
|
||||
break ;
|
||||
|
||||
case COMM_MARKER :
|
||||
psf->headindex = psf->chunk_log.chunks [k].offset ;
|
||||
psf->headindex = psf->rchunks.chunks [k].offset ;
|
||||
comm_frames = psf->sf.frames ;
|
||||
comm_size = psf->chunk_log.chunks [k].len ;
|
||||
comm_size = psf->rchunks.chunks [k].len ;
|
||||
psf_binheader_writef (psf, "Em42t4", COMM_MARKER, comm_size, psf->sf.channels, comm_frames) ;
|
||||
break ;
|
||||
|
||||
case SSND_MARKER :
|
||||
psf->headindex = psf->chunk_log.chunks [k].offset ;
|
||||
psf->headindex = psf->rchunks.chunks [k].offset ;
|
||||
psf_binheader_writef (psf, "Etm8", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK) ;
|
||||
break ;
|
||||
|
||||
case PEAK_MARKER :
|
||||
psf->headindex = psf->chunk_log.chunks [k].offset ;
|
||||
psf->headindex = psf->rchunks.chunks [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++)
|
||||
@ -1130,7 +1141,7 @@ 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 = 0 ;
|
||||
unsigned int comm_type, comm_size, comm_encoding, comm_frames = 0, uk ;
|
||||
int k, endian, has_data = SF_FALSE ;
|
||||
short bit_width ;
|
||||
|
||||
@ -1153,7 +1164,7 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
psf->sf.frames = psf->datalength / (psf->bytewidth * psf->sf.channels) ;
|
||||
} ;
|
||||
|
||||
if (psf->file.mode == SFM_RDWR && psf->dataoffset > 0 && psf->chunk_log.count > 0)
|
||||
if (psf->file.mode == SFM_RDWR && psf->dataoffset > 0 && psf->rchunks.count > 0)
|
||||
{ int err = aiff_rewrite_header (psf) ;
|
||||
if (current > 0)
|
||||
psf_fseek (psf, current, SEEK_SET) ;
|
||||
@ -1422,6 +1433,10 @@ aiff_write_header (SF_PRIVATE *psf, int calc_length)
|
||||
psf_binheader_writef (psf, "Eft8", (float) psf->peak_info->peaks [k].value, psf->peak_info->peaks [k].position) ;
|
||||
} ;
|
||||
|
||||
/* Write custom headers. */
|
||||
for (uk = 0 ; uk < psf->wchunks.used ; uk++)
|
||||
psf_binheader_writef (psf, "Em4b", (int) psf->wchunks.chunks [uk].marker, psf->wchunks.chunks [uk].len, psf->wchunks.chunks [uk].data, make_size_t (psf->wchunks.chunks [uk].len)) ;
|
||||
|
||||
/* Write SSND chunk. */
|
||||
paiff->ssnd_offset = psf->headindex ;
|
||||
psf_binheader_writef (psf, "Etm844", SSND_MARKER, psf->datalength + SIZEOF_SSND_CHUNK, 0, 0) ;
|
||||
@ -1733,3 +1748,55 @@ aiff_read_chanmap (SF_PRIVATE * psf, unsigned dword)
|
||||
return 0 ;
|
||||
} /* aiff_read_chanmap */
|
||||
|
||||
/*==============================================================================
|
||||
*/
|
||||
|
||||
static int
|
||||
aiff_id_to_marker (const SF_CHUNK_INFO * chunk_info)
|
||||
{ const unsigned char * cptr ;
|
||||
|
||||
if (chunk_info->id_size != 4)
|
||||
return 0 ;
|
||||
|
||||
cptr = (const unsigned char *) chunk_info->id ;
|
||||
return (cptr [3] << 24) + (cptr [2] << 16) + (cptr [1] << 8) + cptr [0] ;
|
||||
} /* aiff_id_to_marker */
|
||||
|
||||
static int
|
||||
aiff_set_chunk (SF_PRIVATE *psf, const SF_CHUNK_INFO * chunk_info)
|
||||
{ int marker = aiff_id_to_marker (chunk_info) ;
|
||||
|
||||
return psf_save_write_chunk (&psf->wchunks, marker, chunk_info) ;
|
||||
} /* aiff_set_chunk */
|
||||
|
||||
|
||||
static int
|
||||
aiff_get_chunk_size (SF_PRIVATE *psf, SF_CHUNK_INFO * chunk_info)
|
||||
{ int indx, marker = aiff_id_to_marker (chunk_info) ;
|
||||
|
||||
if ((indx = psf_find_read_chunk (&psf->rchunks, marker)) < 0)
|
||||
return SFE_UNKNOWN_CHUNK ;
|
||||
|
||||
chunk_info->datalen = psf->rchunks.chunks [indx].len ;
|
||||
|
||||
return SFE_NO_ERROR ;
|
||||
} /* aiff_get_chunk_size */
|
||||
|
||||
static int
|
||||
aiff_get_chunk_data (SF_PRIVATE *psf, SF_CHUNK_INFO * chunk_info)
|
||||
{ int indx, marker = aiff_id_to_marker (chunk_info) ;
|
||||
sf_count_t pos ;
|
||||
|
||||
if ((indx = psf_find_read_chunk (&psf->rchunks, marker)) < 0)
|
||||
return SFE_UNKNOWN_CHUNK ;
|
||||
|
||||
if (chunk_info->data == NULL)
|
||||
return SFE_BAD_CHUNK_DATA_PTR ;
|
||||
|
||||
pos = psf_ftell (psf) ;
|
||||
psf_fseek (psf, psf->rchunks.chunks [indx].offset, SEEK_SET) ;
|
||||
psf_fread (chunk_info->data, SF_MIN (chunk_info->datalen, psf->rchunks.chunks [indx].len), 1, psf) ;
|
||||
psf_fseek (psf, pos, SEEK_SET) ;
|
||||
|
||||
return SFE_NO_ERROR ;
|
||||
} /* aiff_get_chunk_data */
|
||||
|
55
src/chunk.c
55
src/chunk.c
@ -26,22 +26,22 @@
|
||||
#include "common.h"
|
||||
|
||||
|
||||
void
|
||||
psf_chunk_store (PRIV_CHUNK_LOG * pchk, int64_t marker, sf_count_t offset, sf_count_t len)
|
||||
int
|
||||
psf_store_read_chunk (READ_CHUNKS * pchk, int64_t marker, sf_count_t offset, uint32_t len)
|
||||
{
|
||||
if (pchk->count == 0)
|
||||
{ pchk->used = 0 ;
|
||||
pchk->count = 20 ;
|
||||
pchk->chunks = calloc (pchk->count, sizeof (CHUNK_LOG)) ;
|
||||
pchk->chunks = calloc (pchk->count, sizeof (READ_CHUNK)) ;
|
||||
}
|
||||
else if (pchk->used >= pchk->count)
|
||||
{ CHUNK_LOG * old_ptr = pchk->chunks ;
|
||||
{ READ_CHUNK * old_ptr = pchk->chunks ;
|
||||
int new_count = 3 * (pchk->count + 1) / 2 ;
|
||||
|
||||
pchk->chunks = realloc (old_ptr, new_count * sizeof (CHUNK_LOG)) ;
|
||||
pchk->chunks = realloc (old_ptr, new_count * sizeof (READ_CHUNK)) ;
|
||||
if (pchk->chunks == NULL)
|
||||
{ pchk->chunks = old_ptr ;
|
||||
return ;
|
||||
return SFE_MALLOC_FAILED ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
@ -51,17 +51,48 @@ psf_chunk_store (PRIV_CHUNK_LOG * pchk, int64_t marker, sf_count_t offset, sf_co
|
||||
|
||||
pchk->used ++ ;
|
||||
|
||||
return ;
|
||||
} /* psf_chunk_store */
|
||||
return SFE_NO_ERROR ;
|
||||
} /* psf_store_read_chunk */
|
||||
|
||||
int
|
||||
psf_chunk_find (PRIV_CHUNK_LOG * pchk, int64_t marker)
|
||||
{ int k ;
|
||||
psf_save_write_chunk (WRITE_CHUNKS * pchk, int64_t marker, const SF_CHUNK_INFO * chunk_info)
|
||||
{ uint32_t len ;
|
||||
|
||||
if (pchk->count == 0)
|
||||
{ pchk->used = 0 ;
|
||||
pchk->count = 20 ;
|
||||
pchk->chunks = calloc (pchk->count, sizeof (WRITE_CHUNK)) ;
|
||||
}
|
||||
else if (pchk->used >= pchk->count)
|
||||
{ WRITE_CHUNK * old_ptr = pchk->chunks ;
|
||||
int new_count = 3 * (pchk->count + 1) / 2 ;
|
||||
|
||||
pchk->chunks = realloc (old_ptr, new_count * sizeof (WRITE_CHUNK)) ;
|
||||
if (pchk->chunks == NULL)
|
||||
{ pchk->chunks = old_ptr ;
|
||||
return SFE_MALLOC_FAILED ;
|
||||
} ;
|
||||
} ;
|
||||
|
||||
len = chunk_info->datalen ;
|
||||
while (len & 3) len ++ ;
|
||||
|
||||
pchk->chunks [pchk->used].marker = marker ;
|
||||
pchk->chunks [pchk->used].len = len ;
|
||||
pchk->chunks [pchk->used].data = psf_memdup (chunk_info->data, chunk_info->datalen) ;
|
||||
|
||||
pchk->used ++ ;
|
||||
|
||||
return SFE_NO_ERROR ;
|
||||
} /* psf_store_read_chunk */
|
||||
|
||||
int
|
||||
psf_find_read_chunk (READ_CHUNKS * pchk, int64_t marker)
|
||||
{ uint32_t k ;
|
||||
|
||||
for (k = 0 ; k < pchk->used ; k++)
|
||||
if (pchk->chunks [k].marker == marker)
|
||||
return k ;
|
||||
|
||||
return -1 ;
|
||||
} /* psf_chunk_find */
|
||||
|
||||
} /* psf_find_read_chunk */
|
||||
|
45
src/common.h
45
src/common.h
@ -222,14 +222,26 @@ typedef struct
|
||||
typedef struct
|
||||
{ int64_t marker ;
|
||||
sf_count_t offset ;
|
||||
sf_count_t len ;
|
||||
} CHUNK_LOG ;
|
||||
uint32_t len ;
|
||||
} READ_CHUNK ;
|
||||
|
||||
typedef struct
|
||||
{ int count ;
|
||||
int used ;
|
||||
CHUNK_LOG * chunks ;
|
||||
} PRIV_CHUNK_LOG ;
|
||||
{ int64_t marker ;
|
||||
uint32_t len ;
|
||||
void *data ;
|
||||
} WRITE_CHUNK ;
|
||||
|
||||
typedef struct
|
||||
{ uint32_t count ;
|
||||
uint32_t used ;
|
||||
READ_CHUNK *chunks ;
|
||||
} READ_CHUNKS ;
|
||||
|
||||
typedef struct
|
||||
{ uint32_t count ;
|
||||
uint32_t used ;
|
||||
WRITE_CHUNK *chunks ;
|
||||
} WRITE_CHUNKS ;
|
||||
|
||||
static inline size_t
|
||||
make_size_t (int x)
|
||||
@ -244,6 +256,13 @@ typedef wchar_t sfwchar_t ;
|
||||
typedef int16_t sfwchar_t ;
|
||||
#endif
|
||||
|
||||
|
||||
static inline void *
|
||||
psf_memdup (const void *src, size_t n)
|
||||
{ void * mem = calloc (1, n & 3 ? n + 4 - (n & 3) : n) ;
|
||||
return memcpy (mem, src, n) ;
|
||||
} /* psf_memdup */
|
||||
|
||||
/*
|
||||
** This version of isprint specifically ignores any locale info. Its used for
|
||||
** determining which characters can be printed in things like hexdumps.
|
||||
@ -452,7 +471,8 @@ typedef struct sf_private_tag
|
||||
void *vio_user_data ;
|
||||
|
||||
/* Chunk get/set. */
|
||||
PRIV_CHUNK_LOG chunk_log ;
|
||||
READ_CHUNKS rchunks ;
|
||||
WRITE_CHUNKS wchunks ;
|
||||
int (*set_chunk) (struct sf_private_tag*, const SF_CHUNK_INFO * chunk_info) ;
|
||||
int (*get_chunk_size) (struct sf_private_tag*, SF_CHUNK_INFO * chunk_info) ;
|
||||
int (*get_chunk_data) (struct sf_private_tag*, SF_CHUNK_INFO * chunk_info) ;
|
||||
@ -649,8 +669,11 @@ enum
|
||||
SFE_VORBIS_ENCODER_BUG,
|
||||
|
||||
SFE_RF64_NOT_RF64,
|
||||
SFE_BAD_CHUNK_INFO_PTR,
|
||||
SFE_BAD_READ_CHUNK_PTR,
|
||||
SFE_UNKNOWN_CHUNK,
|
||||
SFE_BAD_CHUNK_FORMAT,
|
||||
SFE_BAD_CHUNK_MARKER,
|
||||
SFE_BAD_CHUNK_DATA_PTR,
|
||||
|
||||
SFE_MAX_ERROR /* This must be last in list. */
|
||||
} ;
|
||||
@ -838,8 +861,10 @@ int interleave_init (SF_PRIVATE *psf) ;
|
||||
** Chunk logging functions.
|
||||
*/
|
||||
|
||||
void psf_chunk_store (PRIV_CHUNK_LOG * pchk, int64_t marker, sf_count_t offset, sf_count_t len) ;
|
||||
int psf_chunk_find (PRIV_CHUNK_LOG * pchk, int64_t marker) ;
|
||||
int psf_store_read_chunk (READ_CHUNKS * pchk, int64_t marker, sf_count_t offset, uint32_t len) ;
|
||||
int psf_save_write_chunk (WRITE_CHUNKS * pchk, int64_t marker, const SF_CHUNK_INFO * chunk_info) ;
|
||||
int psf_find_read_chunk (READ_CHUNKS * pchk, int64_t marker) ;
|
||||
int psf_find_write_chunk (WRITE_CHUNKS * pchk, int64_t marker) ;
|
||||
|
||||
/*------------------------------------------------------------------------------------
|
||||
** Functions that work like OpenBSD's strlcpy/strlcat to replace strncpy/strncat.
|
||||
|
@ -254,8 +254,11 @@ ErrorStruct SndfileErrors [] =
|
||||
|
||||
{ SFE_RF64_NOT_RF64 , "Error : Not an RF64 file." },
|
||||
|
||||
{ SFE_BAD_CHUNK_INFO_PTR , "Error : Bad SF_CHUNK_INFO pointer." },
|
||||
{ SFE_BAD_READ_CHUNK_PTR , "Error : Bad SF_CHUNK_INFO pointer." },
|
||||
{ SFE_UNKNOWN_CHUNK , "Error : Uknown chunk marker." },
|
||||
{ SFE_BAD_CHUNK_FORMAT , "Error : Reading/writing chunks from this file format is not supported." },
|
||||
{ SFE_BAD_CHUNK_MARKER , "Error : Bad chunk marker." },
|
||||
{ SFE_BAD_CHUNK_DATA_PTR , "Error : Bad data pointer in SF_CHUNK_INFO struct." },
|
||||
|
||||
{ SFE_MAX_ERROR , "Maximum error number." },
|
||||
{ SFE_MAX_ERROR + 1 , NULL }
|
||||
@ -2515,7 +2518,8 @@ copy_filename (SF_PRIVATE *psf, const char *path)
|
||||
|
||||
static int
|
||||
psf_close (SF_PRIVATE *psf)
|
||||
{ int error = 0 ;
|
||||
{ uint32_t k ;
|
||||
int error = 0 ;
|
||||
|
||||
if (psf->codec_close)
|
||||
error = psf->codec_close (psf) ;
|
||||
@ -2536,7 +2540,12 @@ psf_close (SF_PRIVATE *psf)
|
||||
free (psf->instrument) ;
|
||||
free (psf->channel_map) ;
|
||||
free (psf->format_desc) ;
|
||||
free (psf->chunk_log.chunks) ;
|
||||
|
||||
if (psf->wchunks.chunks)
|
||||
for (k = 0 ; k < psf->wchunks.used ; k++)
|
||||
free (psf->wchunks.chunks [k].data) ;
|
||||
free (psf->rchunks.chunks) ;
|
||||
free (psf->wchunks.chunks) ;
|
||||
|
||||
memset (psf, 0, sizeof (SF_PRIVATE)) ;
|
||||
free (psf) ;
|
||||
@ -2916,12 +2925,12 @@ sf_set_chunk (SNDFILE * sndfile, const SF_CHUNK_INFO * chunk_info)
|
||||
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
|
||||
|
||||
if (chunk_info == NULL)
|
||||
return SFE_BAD_CHUNK_INFO_PTR ;
|
||||
return SFE_BAD_READ_CHUNK_PTR ;
|
||||
|
||||
if (psf->set_chunk)
|
||||
return psf->set_chunk (psf, chunk_info) ;
|
||||
|
||||
return SFE_UNIMPLEMENTED ;
|
||||
return SFE_BAD_CHUNK_FORMAT ;
|
||||
} /* sf_set_chunk */
|
||||
|
||||
|
||||
@ -2932,12 +2941,12 @@ sf_get_chunk_size (SNDFILE * sndfile, SF_CHUNK_INFO * chunk_info)
|
||||
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
|
||||
|
||||
if (chunk_info == NULL)
|
||||
return SFE_BAD_CHUNK_INFO_PTR ;
|
||||
return SFE_BAD_READ_CHUNK_PTR ;
|
||||
|
||||
if (psf->get_chunk_size)
|
||||
return psf->get_chunk_size (psf, chunk_info) ;
|
||||
|
||||
return SFE_UNIMPLEMENTED ;
|
||||
return SFE_BAD_CHUNK_FORMAT ;
|
||||
} /* sf_get_chunk_size */
|
||||
|
||||
int
|
||||
@ -2947,10 +2956,10 @@ sf_get_chunk_data (SNDFILE * sndfile, SF_CHUNK_INFO * chunk_info)
|
||||
VALIDATE_SNDFILE_AND_ASSIGN_PSF (sndfile, psf, 1) ;
|
||||
|
||||
if (chunk_info == NULL)
|
||||
return SFE_BAD_CHUNK_INFO_PTR ;
|
||||
return SFE_BAD_READ_CHUNK_PTR ;
|
||||
|
||||
if (psf->get_chunk_data)
|
||||
return psf->get_chunk_data (psf, chunk_info) ;
|
||||
|
||||
return SFE_UNIMPLEMENTED ;
|
||||
return SFE_BAD_CHUNK_FORMAT ;
|
||||
} /* sf_get_chunk_data */
|
||||
|
Loading…
Reference in New Issue
Block a user