diff --git a/CMakeLists.txt b/CMakeLists.txt index 0f4a85d..0ed5424 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,6 +28,7 @@ find_package(Qt5Concurrent REQUIRED) find_package(Qt5LinguistTools REQUIRED) set(QWT_NAMES qwt-qt5 qwt) # find versions for Qt5 only find_package(Qwt) +find_package(ZLIB REQUIRED) find_package(Threads REQUIRED) if(QWT_FOUND) @@ -86,8 +87,8 @@ set(FILEFORMATS_SOURCES "src/FileFormats/ym2612_to_wopi.cpp" "src/FileFormats/ym2151_to_wopi.cpp") add_library(FileFormats STATIC ${FILEFORMATS_SOURCES}) -target_include_directories(FileFormats PUBLIC "src") -target_link_libraries(FileFormats PUBLIC Common) +target_include_directories(FileFormats PUBLIC "src" PRIVATE ${ZLIB_INCLUDE_DIRS}) +target_link_libraries(FileFormats PUBLIC Common PRIVATE ${ZLIB_LIBRARIES}) include(src/opl/chips/chipset.cmake) add_library(Chips STATIC ${CHIPS_SOURCES}) diff --git a/FMBankEdit.pro b/FMBankEdit.pro index 18e35a9..62e6ae7 100644 --- a/FMBankEdit.pro +++ b/FMBankEdit.pro @@ -45,6 +45,7 @@ win32 { CONFIG += rtmidi CONFIG += rtaudio #CONFIG += plots +LIBS += -lz !macx:{ QMAKE_CXXFLAGS += -fopenmp diff --git a/src/FileFormats/format_vgm_import.cpp b/src/FileFormats/format_vgm_import.cpp index 22506b0..bfb6beb 100644 --- a/src/FileFormats/format_vgm_import.cpp +++ b/src/FileFormats/format_vgm_import.cpp @@ -23,19 +23,83 @@ #include #include +#include +#include #include #include static void make_size_table(uint8_t *table, unsigned version); +static gzFile gzopen_q(const QString &path, const char *mode); const char magic_vgm[4] = {0x56, 0x67, 0x6D, 0x20}; +const unsigned char magic_gzip[2] = {0x1F, 0x8B}; -bool VGM_Importer::detect(const QString &, char *magic) +bool VGM_Importer::detect(const QString &filePath, char *magic) { - return (memcmp(magic_vgm, magic, 4) == 0); + if(memcmp(magic_vgm, magic, 4) == 0) + return true; + + //Try as compressed VGM file + if(memcmp(magic_gzip, magic, 2) == 0) + { + gzFile vgz = gzopen_q(filePath, "rb"); + if(!vgz) + return false; + + char compMagic[4]; + int count = gzread(vgz, compMagic, 4); + gzclose(vgz); + if(count == 4 && memcmp(compMagic, magic_vgm, 4) == 0) + return true; + } + + return false; } FfmtErrCode VGM_Importer::loadFile(QString filePath, FmBank &bank) +{ + QFile file(filePath); + if(!file.open(QIODevice::ReadOnly)) + return FfmtErrCode::ERR_NOFILE; + + char magic[4]; + if(file.read(magic, 4) != 4) + return FfmtErrCode::ERR_BADFORMAT; + + if(memcmp(magic_vgm, magic, 4) == 0) + { + file.seek(0); + return load(file, bank); + } + + file.close(); + + //Try as compressed VGM file + if(memcmp(magic_gzip, magic, 2) == 0) + { + gzFile vgz = gzopen_q(filePath, "rb"); + if(!vgz) + return FfmtErrCode::ERR_NOFILE; + + QBuffer buffer; + buffer.open(QBuffer::ReadWrite); + + z_size_t n; + char buf[1024]; + while((n = gzread(vgz, buf, sizeof(buf))) > 0) + buffer.write(buf, n); + if(n == (z_size_t)-1) + return FfmtErrCode::ERR_BADFORMAT; + gzclose(vgz); + + buffer.open(QIODevice::ReadOnly); + return load(buffer, bank); + } + + return FfmtErrCode::ERR_BADFORMAT; +} + +FfmtErrCode VGM_Importer::load(QIODevice &file, FmBank &bank) { RawYm2612ToWopi pseudoChip; RawYm2612ToWopi pseudoChip2608; @@ -46,10 +110,6 @@ FfmtErrCode VGM_Importer::loadFile(QString filePath, FmBank &bank) char magic[4]; uint8_t numb[4]; - QFile file(filePath); - if(!file.open(QIODevice::ReadOnly)) - return FfmtErrCode::ERR_NOFILE; - bank.reset(); if(file.read(magic, 4) != 4) return FfmtErrCode::ERR_BADFORMAT; @@ -212,7 +272,7 @@ QString VGM_Importer::formatModuleName() const QString VGM_Importer::formatExtensionMask() const { - return "*.vgm"; + return "*.vgm *.vgz"; } BankFormats VGM_Importer::formatId() const @@ -309,3 +369,12 @@ static void make_size_table(uint8_t *table, unsigned version) for(unsigned a = 0xE2; a <= 0xFF; ++a) table[a] = 4; // three operands, reserved for future use } + +static gzFile gzopen_q(const QString &path, const char *mode) +{ +#ifndef _WIN32 + return gzopen(path.toStdString().c_str(), "rb"); +#else + return gzopen_w(path.toStdWString().c_str(), "rb"); +#endif +} diff --git a/src/FileFormats/format_vgm_import.h b/src/FileFormats/format_vgm_import.h index b07adf6..2cbe4c4 100644 --- a/src/FileFormats/format_vgm_import.h +++ b/src/FileFormats/format_vgm_import.h @@ -21,6 +21,8 @@ #include "ffmt_base.h" +class QIODevice; + /** * @brief Import from VGM files */ @@ -34,6 +36,9 @@ class VGM_Importer final : public FmBankFormatBase QString formatModuleName() const override; QString formatExtensionMask() const override; BankFormats formatId() const override; + +private: + FfmtErrCode load(QIODevice &file, FmBank &bank); }; #endif // VGM_IMPORT_H