Make closing a VGMSTREAM with duplicate STREAMFILEs safe

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@189 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2008-05-20 20:19:46 +00:00
parent 7f33ba0d23
commit bbb03de6af
9 changed files with 52 additions and 22 deletions

View File

@ -34,8 +34,8 @@ void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
int step_index = stream->adpcm_step_index;
if (first_sample==0) {
step_index = read_16bitLE(stream->offset+2,stream->streamfile);
hist1 = read_16bitLE(stream->offset,stream->streamfile);
step_index = read_16bitLE(stream->offset+2,stream->streamfile);
}
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {

View File

@ -121,9 +121,14 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
{
int i;
STREAMFILE * chstreamfile;
/* ADX is so tightly interleaved that having two buffers is silly */
chstreamfile = streamFile->open(streamFile,filename,18*0x400);
if (!chstreamfile) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,18*0x400);
if (!vgmstream->ch[i].streamfile) goto fail;
vgmstream->ch[i].streamfile = chstreamfile;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=

View File

@ -38,11 +38,15 @@ VGMSTREAM * init_vgmstream_afc(STREAMFILE *streamFile) {
/* open the file for reading by each channel */
{
STREAMFILE *chstreamfile;
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,9*0x400);
if (!vgmstream->ch[i].streamfile) goto fail;
/* both channels use same buffer, as interleave is so small */
chstreamfile = streamFile->open(streamFile,filename,9*channel_count*0x100);
if (!chstreamfile) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = chstreamfile;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=

View File

@ -26,7 +26,7 @@ VGMSTREAM * init_vgmstream_halpst(STREAMFILE *streamFile) {
/* details */
channel_count = read_32bitBE(0xc,streamFile);
max_block = read_32bitBE(0x10,streamFile);
max_block = read_32bitBE(0x10,streamFile)/channel_count;
/* have I ever seen a mono .hps? */
if (channel_count!=2) goto fail;

View File

@ -4,6 +4,7 @@
VGMSTREAM * init_vgmstream_ngc_adpdtk(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * chstreamfile;
char filename[260];
size_t file_size;
@ -30,11 +31,15 @@ VGMSTREAM * init_vgmstream_ngc_adpdtk(STREAMFILE *streamFile) {
vgmstream->layout_type = layout_dtk_interleave;
vgmstream->meta_type = meta_NGC_ADPDTK;
/* locality is such that two streamfiles is silly */
chstreamfile = streamFile->open(streamFile,filename,32*0x400);
if (!chstreamfile) goto fail;
for (i=0;i<2;i++) {
vgmstream->ch[i].channel_start_offset =
vgmstream->ch[i].offset = 0;
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,32*0x400);
vgmstream->ch[i].streamfile = chstreamfile;
}
return vgmstream;

View File

@ -73,10 +73,13 @@ VGMSTREAM * init_vgmstream_cdxa(STREAMFILE *streamFile) {
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
STREAMFILE *chstreamfile;
chstreamfile = streamFile->open(streamFile,filename,2352);
if (!vgmstream->ch[i].streamfile) goto fail;
if (!chstreamfile) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = chstreamfile;
}
}

View File

@ -35,10 +35,15 @@ VGMSTREAM * init_vgmstream_raw(STREAMFILE *streamFile) {
/* open the file for reading by each channel */
{
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x1000);
STREAMFILE *chstreamfile;
if (!vgmstream->ch[i].streamfile) goto fail;
/* have both channels use the same buffer, as interleave is so small */
chstreamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!chstreamfile) goto fail;
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = chstreamfile;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=(off_t)(i*vgmstream->interleave_block_size);

View File

@ -174,12 +174,24 @@ VGMSTREAM * allocate_vgmstream(int channel_count, int looped) {
}
void close_vgmstream(VGMSTREAM * vgmstream) {
int i;
int i,j;
if (!vgmstream) return;
for (i=0;i<vgmstream->channels;i++)
if (vgmstream->ch[i].streamfile)
for (i=0;i<vgmstream->channels;i++) {
if (vgmstream->ch[i].streamfile) {
close_streamfile(vgmstream->ch[i].streamfile);
/* Multiple channels might have the same streamfile. Find the others
* that are the same as this and clear them so they won't be closed
* again. */
for (j=0;j<vgmstream->channels;j++) {
if (i!=j && vgmstream->ch[j].streamfile ==
vgmstream->ch[i].streamfile) {
vgmstream->ch[j].streamfile = NULL;
}
}
vgmstream->ch[i].streamfile = NULL;
}
}
if (vgmstream->loop_ch) free(vgmstream->loop_ch);
if (vgmstream->start_ch) free(vgmstream->start_ch);

View File

@ -147,11 +147,7 @@ typedef struct {
/* channels */
VGMSTREAMCHANNEL * ch; /* pointer to array of channels */
/* channel copies
* NOTE: Care must be taken when deallocating that the same STREAMFILE
* isn't closed twice, but also that everything is deallocated. Generally
* a channel should only have one STREAMFILE in its lifetime.
*/
/* channel copies */
VGMSTREAMCHANNEL * start_ch; /* copies of channel status as they were at the beginning of the stream */
VGMSTREAMCHANNEL * loop_ch; /* copies of channel status as they were at the loop point */