diff data/fileio/OggVorbisFileReader.cpp @ 1527:710e6250a401 zoom

Merge from default branch
author Chris Cannam
date Mon, 17 Sep 2018 13:51:14 +0100
parents ce08318aad83
children 70e172e6cc59
line wrap: on
line diff
--- a/data/fileio/OggVorbisFileReader.cpp	Mon Dec 12 15:18:52 2016 +0000
+++ b/data/fileio/OggVorbisFileReader.cpp	Mon Sep 17 13:51:14 2018 +0100
@@ -40,6 +40,10 @@
     CodedAudioFileReader(mode, targetRate, normalised),
     m_source(source),
     m_path(source.getLocalFilename()),
+    m_qfile(0),
+    m_ffile(0),
+    m_oggz(0),
+    m_fishSound(0),
     m_reporter(reporter),
     m_fileSize(0),
     m_bytesRead(0),
@@ -60,12 +64,36 @@
 
     Profiler profiler("OggVorbisFileReader::OggVorbisFileReader");
 
-    QFileInfo info(m_path);
-    m_fileSize = info.size();
+    // These shenanigans are to avoid using oggz_open(..) with a local
+    // codepage on Windows (make sure proper filename encoding is used)
+    
+    m_qfile = new QFile(m_path);
+    if (!m_qfile->open(QIODevice::ReadOnly)) {
+        m_error = QString("Failed to open file %1 for reading.").arg(m_path);
+        SVDEBUG << "OggVorbisFileReader: " << m_error << endl;
+        delete m_qfile;
+        m_qfile = 0;
+        return;
+    }
+    
+    m_fileSize = m_qfile->size();
 
-    if (!(m_oggz = oggz_open(m_path.toLocal8Bit().data(), OGGZ_READ))) {
-	m_error = QString("File %1 is not an OGG file.").arg(m_path);
-	return;
+    m_ffile = fdopen(dup(m_qfile->handle()), "rb");
+    if (!m_ffile) {
+        m_error = QString("Failed to open file pointer for file %1").arg(m_path);
+        SVDEBUG << "OggVorbisFileReader: " << m_error << endl;
+        delete m_qfile;
+        m_qfile = 0;
+        return;
+    }
+    
+    if (!(m_oggz = oggz_open_stdio(m_ffile, OGGZ_READ))) {
+        m_error = QString("File %1 is not an OGG file.").arg(m_path);
+        fclose(m_ffile);
+        m_ffile = 0;
+        delete m_qfile;
+        m_qfile = 0;
+        return;
     }
 
     FishSoundInfo fsinfo;
@@ -114,6 +142,11 @@
         m_decodeThread->wait();
         delete m_decodeThread;
     }
+    if (m_qfile) {
+        // don't fclose m_ffile; oggz_close did that
+        delete m_qfile;
+        m_qfile = 0;
+    }
 }
 
 void
@@ -134,8 +167,14 @@
         
     fish_sound_delete(m_reader->m_fishSound);
     m_reader->m_fishSound = 0;
+
     oggz_close(m_reader->m_oggz);
     m_reader->m_oggz = 0;
+
+    // don't fclose m_ffile; oggz_close did that
+
+    delete m_reader->m_qfile;
+    m_reader->m_qfile = 0;
     
     if (m_reader->isDecodeCacheInitialised()) m_reader->finishDecodeCache();
     m_reader->m_completion = 100;
@@ -172,7 +211,7 @@
 
 int
 OggVorbisFileReader::acceptFrames(FishSound *fs, float **frames, long nframes,
-				  void *data)
+                                  void *data)
 {
     OggVorbisFileReader *reader = (OggVorbisFileReader *)data;
 
@@ -196,11 +235,11 @@
     }
 
     if (reader->m_channelCount == 0) {
-	FishSoundInfo fsinfo;
-	fish_sound_command(fs, FISH_SOUND_GET_INFO,
-			   &fsinfo, sizeof(FishSoundInfo));
-	reader->m_fileRate = fsinfo.samplerate;
-	reader->m_channelCount = fsinfo.channels;
+        FishSoundInfo fsinfo;
+        fish_sound_command(fs, FISH_SOUND_GET_INFO,
+                           &fsinfo, sizeof(FishSoundInfo));
+        reader->m_fileRate = fsinfo.samplerate;
+        reader->m_channelCount = fsinfo.channels;
         reader->initialiseDecodeCache();
     }