mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-09-24 19:28:24 +02:00
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:
parent
7f33ba0d23
commit
bbb03de6af
@ -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) {
|
||||
|
@ -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=
|
||||
|
@ -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=
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user