diff --git a/src/Plugins/MagnumFont/CMakeLists.txt b/src/Plugins/MagnumFont/CMakeLists.txt index 40509699e..11d09f8e5 100644 --- a/src/Plugins/MagnumFont/CMakeLists.txt +++ b/src/Plugins/MagnumFont/CMakeLists.txt @@ -31,7 +31,7 @@ set(MagnumFont_HEADERS MagnumFont.h) add_library(MagnumFontObjects OBJECT ${MagnumFont_SOURCES}) -set_target_properties(MagnumFontObjects PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +set_target_properties(MagnumFontObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") add_plugin(MagnumFont ${MAGNUM_PLUGINS_FONT_INSTALL_DIR} MagnumFont.conf @@ -41,13 +41,18 @@ target_link_libraries(MagnumFont ${MAGNUM_LIBRARIES} ${MAGNUM_TEXT_LIBRARIES}) +if(WIN32) + target_link_libraries(MagnumFont TgaImporter) +endif() + install(FILES ${MagnumFont_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/MagnumFont) if(BUILD_GL_TESTS) - add_library(MagnumFontTestLib $) + add_library(MagnumFontTestLib STATIC $) target_link_libraries(MagnumFontTestLib ${MAGNUM_LIBRARIES} ${MAGNUM_TEXT_LIBRARIES} TgaImporterTestLib) + add_subdirectory(Test) endif() diff --git a/src/Plugins/MagnumFont/MagnumFont.cpp b/src/Plugins/MagnumFont/MagnumFont.cpp index 33a12b7bc..94590c4f2 100644 --- a/src/Plugins/MagnumFont/MagnumFont.cpp +++ b/src/Plugins/MagnumFont/MagnumFont.cpp @@ -49,13 +49,13 @@ struct MagnumFont::Data { namespace { class MagnumFontLayouter: public AbstractLayouter { public: - explicit MagnumFontLayouter(const std::unordered_map& glyphId, const std::vector& glyphAdvance, const GlyphCache* cache, Float fontSize, Float textSize, const std::string& text); + explicit MagnumFontLayouter(const std::unordered_map& glyphId, const std::vector& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, const std::string& text); std::tuple renderGlyph(UnsignedInt i) override; private: const std::vector& glyphAdvance; - const GlyphCache* const cache; + const GlyphCache& cache; const Float fontSize, textSize; std::vector glyphs; }; @@ -65,6 +65,8 @@ MagnumFont::MagnumFont(): _opened(nullptr) {} MagnumFont::MagnumFont(PluginManager::AbstractManager* const manager, std::string plugin): AbstractFont(manager, std::move(plugin)), _opened(nullptr) {} +MagnumFont::~MagnumFont() { close(); } + auto MagnumFont::doFeatures() const -> Features { return Feature::OpenData|Feature::MultiFile|Feature::PreparedGlyphCache; } bool MagnumFont::doIsOpened() const { return _opened; } @@ -72,7 +74,7 @@ bool MagnumFont::doIsOpened() const { return _opened; } void MagnumFont::doOpenData(const std::vector>>& data, const Float) { /* We need just the configuration file and image file */ if(data.size() != 2) { - Error() << "Magnum::Text::MagnumFont::openData(): wanted two files, got" << data.size(); + Error() << "Text::MagnumFont::openData(): wanted two files, got" << data.size(); return; } @@ -80,20 +82,20 @@ void MagnumFont::doOpenData(const std::vector(data[0].second.begin()), data[0].second.size())); Utility::Configuration conf(in, Utility::Configuration::Flag::SkipComments); if(!conf.isValid() || conf.isEmpty()) { - Error() << "Magnum::Text::MagnumFont::openData(): cannot open file" << data[0].first << conf.isValid(); + Error() << "Text::MagnumFont::openData(): cannot open file" << data[0].first << conf.isValid(); return; } /* Check version */ if(conf.value("version") != 1) { - Error() << "Magnum::Text::MagnumFont::openData(): unsupported file version, expected 1 but got" + Error() << "Text::MagnumFont::openData(): unsupported file version, expected 1 but got" << conf.value("version"); return; } /* Check that we have also the image file */ if(conf.value("image") != data[1].first) { - Error() << "Magnum::Text::MagnumFont::openData(): expected file" + Error() << "Text::MagnumFont::openData(): expected file" << conf.value("image") << "but got" << data[1].first; return; } @@ -101,12 +103,12 @@ void MagnumFont::doOpenData(const std::vector("version") != 1) { - Error() << "Magnum::Text::MagnumFont::openFile(): unsupported file version, expected 1 but got" + Error() << "Text::MagnumFont::openFile(): unsupported file version, expected 1 but got" << conf.value("version"); return; } @@ -133,12 +135,12 @@ void MagnumFont::doOpenFile(const std::string& filename, Float) { const std::string imageFilename = Utility::Directory::join(Utility::Directory::path(filename), conf.value("image")); Trade::TgaImporter importer; if(!importer.openFile(imageFilename)) { - Error() << "Magnum::Text::MagnumFont::openFile(): cannot open image file" << imageFilename; + Error() << "Text::MagnumFont::openFile(): cannot open image file" << imageFilename; return; } Trade::ImageData2D* image = importer.image2D(0); if(!image) { - Error() << "Magnum::Text::MagnumFont::openFile(): cannot load image file"; + Error() << "Text::MagnumFont::openFile(): cannot load image file"; return; } @@ -201,13 +203,13 @@ GlyphCache* MagnumFont::doCreateGlyphCache() { return cache; } -AbstractLayouter* MagnumFont::doLayout(const GlyphCache* cache, Float size, const std::string& text) { +AbstractLayouter* MagnumFont::doLayout(const GlyphCache& cache, Float size, const std::string& text) { return new MagnumFontLayouter(_opened->glyphId, _opened->glyphAdvance, cache, this->size(), size, text); } namespace { -MagnumFontLayouter::MagnumFontLayouter(const std::unordered_map& glyphId, const std::vector& glyphAdvance, const GlyphCache* cache, Float fontSize, Float textSize, const std::string& text): glyphAdvance(glyphAdvance), cache(cache), fontSize(fontSize), textSize(textSize) { +MagnumFontLayouter::MagnumFontLayouter(const std::unordered_map& glyphId, const std::vector& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, const std::string& text): glyphAdvance(glyphAdvance), cache(cache), fontSize(fontSize), textSize(textSize) { /* Get glyph codes from characters */ glyphs.reserve(text.size()); for(std::size_t i = 0; i != text.size(); ) { @@ -223,12 +225,12 @@ std::tuple MagnumFontLayouter::renderGlyph(Unsign /* Position of the texture in the resulting glyph, texture coordinates */ Vector2i position; Rectanglei rectangle; - std::tie(position, rectangle) = (*cache)[glyphs[i]]; + std::tie(position, rectangle) = cache[glyphs[i]]; const Rectangle texturePosition = Rectangle::fromSize(Vector2(position)/fontSize, Vector2(rectangle.size())/fontSize); - const Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache->textureSize(), - Vector2(rectangle.topRight())/cache->textureSize()); + const Rectangle textureCoordinates(Vector2(rectangle.bottomLeft())/cache.textureSize(), + Vector2(rectangle.topRight())/cache.textureSize()); /* Absolute quad position, composed from cursor position, glyph offset and texture position, denormalized to requested text size */ diff --git a/src/Plugins/MagnumFont/MagnumFont.h b/src/Plugins/MagnumFont/MagnumFont.h index 065b8f1e6..760eef1f7 100644 --- a/src/Plugins/MagnumFont/MagnumFont.h +++ b/src/Plugins/MagnumFont/MagnumFont.h @@ -99,6 +99,8 @@ class MagnumFont: public AbstractFont { /** @brief Plugin manager constructor */ explicit MagnumFont(PluginManager::AbstractManager* manager, std::string plugin); + ~MagnumFont(); + private: class Data; @@ -118,7 +120,7 @@ class MagnumFont: public AbstractFont { GlyphCache* doCreateGlyphCache() override; - AbstractLayouter* doLayout(const GlyphCache* cache, Float size, const std::string& text) override; + AbstractLayouter* doLayout(const GlyphCache& cache, Float size, const std::string& text) override; Data* _opened; diff --git a/src/Plugins/MagnumFont/Test/MagnumFontTest.cpp b/src/Plugins/MagnumFont/Test/MagnumFontTest.cpp index d31dbd4b7..35b130f8e 100644 --- a/src/Plugins/MagnumFont/Test/MagnumFontTest.cpp +++ b/src/Plugins/MagnumFont/Test/MagnumFontTest.cpp @@ -63,7 +63,7 @@ void MagnumFontTest::layout() { cache.insert(font.glyphId(U'W'), {25, 34}, {{0, 8}, {16, 128}}); cache.insert(font.glyphId(U'e'), {25, 12}, {{16, 4}, {64, 32}}); - AbstractLayouter* layouter = font.layout(&cache, 0.5f, "Wave"); + AbstractLayouter* layouter = font.layout(cache, 0.5f, "Wave"); CORRADE_VERIFY(layouter); CORRADE_COMPARE(layouter->glyphCount(), 4); diff --git a/src/Plugins/MagnumFontConverter/CMakeLists.txt b/src/Plugins/MagnumFontConverter/CMakeLists.txt index 849b8f705..71efa0c47 100644 --- a/src/Plugins/MagnumFontConverter/CMakeLists.txt +++ b/src/Plugins/MagnumFontConverter/CMakeLists.txt @@ -31,7 +31,7 @@ set(MagnumFontConverter_HEADERS MagnumFontConverter.h) add_library(MagnumFontConverterObjects OBJECT ${MagnumFontConverter_SOURCES}) -set_target_properties(MagnumFontConverterObjects PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +set_target_properties(MagnumFontConverterObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") add_plugin(MagnumFontConverter ${MAGNUM_PLUGINS_FONTCONVERTER_INSTALL_DIR} MagnumFontConverter.conf @@ -41,12 +41,17 @@ target_link_libraries(MagnumFontConverter ${MAGNUM_LIBRARIES} ${MAGNUM_TEXT_LIBRARIES}) +if(WIN32) + target_link_libraries(MagnumFontConverter TgaImageConverter) +endif() + install(FILES ${MagnumFontConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/MagnumFontConverter) -if(BUILD_TESTS) - add_library(MagnumFontConverterTestLib $) +if(BUILD_GL_TESTS) + add_library(MagnumFontConverterTestLib STATIC $) target_link_libraries(MagnumFontConverterTestLib ${MAGNUM_LIBRARIES} - ${MAGNUM_TEXT_LIBRARIES}) + ${MAGNUM_TEXT_LIBRARIES} + TgaImageConverterTestLib) add_subdirectory(Test) endif() diff --git a/src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp b/src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp index 7b5282bd4..364f4745d 100644 --- a/src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp +++ b/src/Plugins/MagnumFontConverter/MagnumFontConverter.cpp @@ -43,21 +43,21 @@ auto MagnumFontConverter::doFeatures() const -> Features { return Feature::ExportFont|Feature::ConvertData|Feature::MultiFile; } -std::vector>> MagnumFontConverter::doExportFontToData(AbstractFont* font, GlyphCache* cache, const std::string& filename, const std::u32string& characters) const { +std::vector>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const { Utility::Configuration configuration; configuration.setValue("version", 1); configuration.setValue("image", Utility::Directory::filename(filename) + ".tga"); - configuration.setValue("originalImageSize", cache->textureSize()); - configuration.setValue("padding", cache->padding()); - configuration.setValue("fontSize", font->size()); + configuration.setValue("originalImageSize", cache.textureSize()); + configuration.setValue("padding", cache.padding()); + configuration.setValue("fontSize", font.size()); /* Compress glyph IDs so the glyphs are in consecutive array, glyph 0 should stay at position 0 */ std::unordered_map glyphIdMap; - glyphIdMap.reserve(cache->glyphCount()); + glyphIdMap.reserve(cache.glyphCount()); glyphIdMap.emplace(0, 0); - for(const std::pair>& glyph: *cache) + for(const std::pair>& glyph: cache) glyphIdMap.emplace(glyph.first, glyphIdMap.size()); /** @todo Save only glyphs contained in @p characters */ @@ -70,7 +70,7 @@ std::vector>> MagnumFont /* Character->glyph map, map glyph IDs to new ones */ for(const char32_t c: characters) { Utility::ConfigurationGroup* group = configuration.addGroup("char"); - const UnsignedInt glyphId = font->glyphId(c); + const UnsignedInt glyphId = font.glyphId(c); group->setValue("unicode", c); /* Map old glyph ID to new, if not found, map to glyph 0 */ @@ -82,12 +82,12 @@ std::vector>> MagnumFont from the values so they aren't added twice when using the font later */ /** @todo Some better way to handle this padding stuff */ for(UnsignedInt oldGlyphId: inverseGlyphIdMap) { - std::pair glyph = (*cache)[oldGlyphId]; + std::pair glyph = cache[oldGlyphId]; Utility::ConfigurationGroup* group = configuration.addGroup("glyph"); - group->setValue("advance", font->glyphAdvance(oldGlyphId)); - group->setValue("position", glyph.first+cache->padding()); - group->setValue("rectangle", Rectanglei(glyph.second.bottomLeft()+cache->padding(), - glyph.second.topRight()-cache->padding())); + group->setValue("advance", font.glyphAdvance(oldGlyphId)); + group->setValue("position", glyph.first+cache.padding()); + group->setValue("rectangle", Rectanglei(glyph.second.bottomLeft()+cache.padding(), + glyph.second.topRight()-cache.padding())); } std::ostringstream confOut; @@ -98,7 +98,7 @@ std::vector>> MagnumFont /* Save cache image */ Image2D image(ImageFormat::Red, ImageType::UnsignedByte); - cache->texture()->image(0, image); + cache.texture().image(0, image); auto tgaData = Trade::TgaImageConverter().exportToData(image); std::vector>> out; diff --git a/src/Plugins/MagnumFontConverter/MagnumFontConverter.h b/src/Plugins/MagnumFontConverter/MagnumFontConverter.h index a0e773397..7b1be2ad2 100644 --- a/src/Plugins/MagnumFontConverter/MagnumFontConverter.h +++ b/src/Plugins/MagnumFontConverter/MagnumFontConverter.h @@ -48,7 +48,7 @@ class MagnumFontConverter: public Text::AbstractFontConverter { private: Features doFeatures() const override; - std::vector>> doExportFontToData(AbstractFont* font, GlyphCache* cache, const std::string& filename, const std::u32string& characters) const override; + std::vector>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const override; }; }} diff --git a/src/Plugins/MagnumFontConverter/Test/CMakeLists.txt b/src/Plugins/MagnumFontConverter/Test/CMakeLists.txt index 7a41395ad..a6b28e93e 100644 --- a/src/Plugins/MagnumFontConverter/Test/CMakeLists.txt +++ b/src/Plugins/MagnumFontConverter/Test/CMakeLists.txt @@ -32,6 +32,5 @@ include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../FreeTypeFont/Test/ corrade_add_test(MagnumFontConverterTest MagnumFontConverterTest.cpp LIBRARIES MagnumFontConverterTestLib FreeTypeFontTestLib - TgaImageConverterTestLib TgaImporterTestLib ${GL_TEST_LIBRARIES}) diff --git a/src/Plugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp b/src/Plugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp index a57311e09..2ef161a5a 100644 --- a/src/Plugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp +++ b/src/Plugins/MagnumFontConverter/Test/MagnumFontConverterTest.cpp @@ -77,7 +77,7 @@ void MagnumFontConverterTest::exportFont() { /* Convert the file */ MagnumFontConverter converter; - converter.exportFontToFile(&font, &cache, Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font"), "Wave"); + converter.exportFontToFile(font, cache, Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font"), "Wave"); /* Verify font parameters */ /** @todo This might behave differently elsewhere due to unspecified order of glyphs in cache */ diff --git a/src/Plugins/TgaImageConverter/CMakeLists.txt b/src/Plugins/TgaImageConverter/CMakeLists.txt index 81195bbba..f72e90679 100644 --- a/src/Plugins/TgaImageConverter/CMakeLists.txt +++ b/src/Plugins/TgaImageConverter/CMakeLists.txt @@ -29,7 +29,7 @@ set(TgaImageConverter_HEADERS TgaImageConverter.h) add_library(TgaImageConverterObjects OBJECT ${TgaImageConverter_SRCS}) -set_target_properties(TgaImageConverterObjects PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +set_target_properties(TgaImageConverterObjects PROPERTIES COMPILE_FLAGS "-DTgaImageConverterObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") add_plugin(TgaImageConverter ${MAGNUM_PLUGINS_IMAGECONVERTER_INSTALL_DIR} TgaImageConverter.conf @@ -40,7 +40,7 @@ target_link_libraries(TgaImageConverter ${MAGNUM_LIBRARIES}) install(FILES ${TgaImageConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImageConverter) if(BUILD_TESTS) - add_library(TgaImageConverterTestLib $) + add_library(TgaImageConverterTestLib SHARED $) target_link_libraries(TgaImageConverterTestLib ${MAGNUM_LIBRARIES}) add_subdirectory(Test) endif() diff --git a/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp index 16cb5562b..e8ee0b5fb 100644 --- a/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp +++ b/src/Plugins/TgaImageConverter/Test/TgaImageConverterTest.cpp @@ -75,7 +75,7 @@ void TgaImageConverterTest::wrongFormat() { const auto data = TgaImageConverter().exportToData(image); CORRADE_VERIFY(!data); - CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image format ImageFormat::RG\n"); + CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::convertToData(): unsupported image format ImageFormat::RG\n"); } void TgaImageConverterTest::wrongType() { @@ -86,7 +86,7 @@ void TgaImageConverterTest::wrongType() { const auto data = TgaImageConverter().exportToData(image); CORRADE_VERIFY(!data); - CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image type ImageType::Float\n"); + CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::convertToData(): unsupported image type ImageType::Float\n"); } void TgaImageConverterTest::data() { diff --git a/src/Plugins/TgaImageConverter/TgaImageConverter.cpp b/src/Plugins/TgaImageConverter/TgaImageConverter.cpp index ed236a02f..1e259fdc0 100644 --- a/src/Plugins/TgaImageConverter/TgaImageConverter.cpp +++ b/src/Plugins/TgaImageConverter/TgaImageConverter.cpp @@ -57,12 +57,12 @@ Containers::Array TgaImageConverter::doExportToData(const ImageRe image.format() != ImageFormat::Red) #endif { - Error() << "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image format" << image.format(); + Error() << "Trade::TgaImageConverter::convertToData(): unsupported image format" << image.format(); return nullptr; } if(image.type() != ImageType::UnsignedByte) { - Error() << "Trade::TgaImageConverter::TgaImageConverter::convertToData(): unsupported image type" << image.type(); + Error() << "Trade::TgaImageConverter::convertToData(): unsupported image type" << image.type(); return nullptr; } diff --git a/src/Plugins/TgaImageConverter/TgaImageConverter.h b/src/Plugins/TgaImageConverter/TgaImageConverter.h index 07c983b01..1379582cb 100644 --- a/src/Plugins/TgaImageConverter/TgaImageConverter.h +++ b/src/Plugins/TgaImageConverter/TgaImageConverter.h @@ -31,7 +31,7 @@ #include #ifndef DOXYGEN_GENERATING_OUTPUT -#ifdef TgaImageConverter_EXPORTS +#if defined(TgaImageConverter_EXPORTS) || defined(TgaImageConverterObjects_EXPORTS) #define MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT CORRADE_VISIBILITY_EXPORT #else #define MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT CORRADE_VISIBILITY_IMPORT @@ -44,9 +44,8 @@ namespace Magnum { namespace Trade { /** @brief TGA image converter -Supports images with format @ref ImageFormat "ImageFormat::BGR", -@ref ImageFormat "ImageFormat::BGRA" or @ref ImageFormat "ImageFormat::Red" and -type @ref ImageType "ImageType::UnsignedByte". +Supports images with format @ref ImageFormat::BGR, @ref ImageFormat::BGRA or +@ref ImageFormat::Red and type @ref ImageType::UnsignedByte. */ class MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT TgaImageConverter: public AbstractImageConverter { public: diff --git a/src/Plugins/TgaImporter/CMakeLists.txt b/src/Plugins/TgaImporter/CMakeLists.txt index ce8654b2e..90b63a1ea 100644 --- a/src/Plugins/TgaImporter/CMakeLists.txt +++ b/src/Plugins/TgaImporter/CMakeLists.txt @@ -30,7 +30,7 @@ set(TgaImporter_HEADERS TgaImporter.h) add_library(TgaImporterObjects OBJECT ${TgaImporter_SRCS}) -set_target_properties(TgaImporterObjects PROPERTIES COMPILE_FLAGS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}) +set_target_properties(TgaImporterObjects PROPERTIES COMPILE_FLAGS "-DTgaImporterObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") add_plugin(TgaImporter ${MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR} TgaImporter.conf @@ -41,7 +41,7 @@ target_link_libraries(TgaImporter ${MAGNUM_LIBRARIES}) install(FILES ${TgaImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImporter) if(BUILD_TESTS) - add_library(TgaImporterTestLib $) + add_library(TgaImporterTestLib SHARED $) target_link_libraries(TgaImporterTestLib ${MAGNUM_LIBRARIES}) add_subdirectory(Test) endif() diff --git a/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp b/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp index bb39fca3c..fb9738344 100644 --- a/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp +++ b/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp @@ -76,7 +76,7 @@ void TgaImporterTest::openInexistent() { TgaImporter importer; CORRADE_VERIFY(!importer.openFile("inexistent.file")); - CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::TgaImporter::openFile(): cannot open file inexistent.file\n"); + CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::openFile(): cannot open file inexistent.file\n"); } void TgaImporterTest::openShort() { @@ -87,7 +87,7 @@ void TgaImporterTest::openShort() { std::ostringstream debug; Error::setOutput(&debug); CORRADE_VERIFY(!importer.image2D(0)); - CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::TgaImporter::image2D(): the file is too short: 17 bytes\n"); + CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): the file is too short: 17 bytes\n"); } void TgaImporterTest::paletted() { @@ -98,7 +98,7 @@ void TgaImporterTest::paletted() { std::ostringstream debug; Error::setOutput(&debug); CORRADE_VERIFY(!importer.image2D(0)); - CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::TgaImporter::image2D(): paletted files are not supported\n"); + CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): paletted files are not supported\n"); } void TgaImporterTest::compressed() { @@ -109,7 +109,7 @@ void TgaImporterTest::compressed() { std::ostringstream debug; Error::setOutput(&debug); CORRADE_VERIFY(!importer.image2D(0)); - CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::TgaImporter::image2D(): unsupported (compressed?) image type: 9\n"); + CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported (compressed?) image type: 9\n"); } void TgaImporterTest::colorBits16() { @@ -120,7 +120,7 @@ void TgaImporterTest::colorBits16() { std::ostringstream debug; Error::setOutput(&debug); CORRADE_VERIFY(!importer.image2D(0)); - CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::TgaImporter::image2D(): unsupported color bits-per-pixel: 16\n"); + CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported color bits-per-pixel: 16\n"); } void TgaImporterTest::colorBits24() { @@ -216,7 +216,7 @@ void TgaImporterTest::grayscaleBits16() { std::ostringstream debug; Error::setOutput(&debug); CORRADE_VERIFY(!importer.image2D(0)); - CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::TgaImporter::image2D(): unsupported grayscale bits-per-pixel: 16\n"); + CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported grayscale bits-per-pixel: 16\n"); } void TgaImporterTest::file() { diff --git a/src/Plugins/TgaImporter/TgaHeader.h b/src/Plugins/TgaImporter/TgaHeader.h index 875b30bbd..def766d8e 100644 --- a/src/Plugins/TgaImporter/TgaHeader.h +++ b/src/Plugins/TgaImporter/TgaHeader.h @@ -28,7 +28,7 @@ * @brief Struct Magnum::Trade::TgaHeader */ -#include +#include namespace Magnum { namespace Trade { @@ -49,7 +49,7 @@ struct TgaHeader { UnsignedByte bpp; /**< @brief Bits per pixel (8, 16, 24, 32) */ UnsignedByte descriptor; /**< @brief %Image descriptor */ }; -#pragma pack(8) +#pragma pack() static_assert(sizeof(TgaHeader) == 18, "TgaHeader size is not 18 bytes"); diff --git a/src/Plugins/TgaImporter/TgaImporter.cpp b/src/Plugins/TgaImporter/TgaImporter.cpp index b858bc20b..555b6b83f 100644 --- a/src/Plugins/TgaImporter/TgaImporter.cpp +++ b/src/Plugins/TgaImporter/TgaImporter.cpp @@ -70,7 +70,7 @@ void TgaImporter::doOpenFile(const std::string& filename) { in = new std::ifstream(filename.c_str()); if(in->good()) return; - Error() << "Trade::TgaImporter::TgaImporter::openFile(): cannot open file" << filename; + Error() << "Trade::TgaImporter::openFile(): cannot open file" << filename; close(); } @@ -87,7 +87,7 @@ ImageData2D* TgaImporter::doImage2D(UnsignedInt) { std::streampos filesize = in->tellg(); in->seekg(0, std::istream::beg); if(filesize < std::streampos(sizeof(TgaHeader))) { - Error() << "Trade::TgaImporter::TgaImporter::image2D(): the file is too short:" << filesize << "bytes"; + Error() << "Trade::TgaImporter::image2D(): the file is too short:" << filesize << "bytes"; return nullptr; } @@ -101,7 +101,7 @@ ImageData2D* TgaImporter::doImage2D(UnsignedInt) { /* Image format */ ImageFormat format; if(header.colorMapType != 0) { - Error() << "Trade::TgaImporter::TgaImporter::image2D(): paletted files are not supported"; + Error() << "Trade::TgaImporter::image2D(): paletted files are not supported"; return nullptr; } @@ -123,7 +123,7 @@ ImageData2D* TgaImporter::doImage2D(UnsignedInt) { #endif break; default: - Error() << "Trade::TgaImporter::TgaImporter::image2D(): unsupported color bits-per-pixel:" << header.bpp; + Error() << "Trade::TgaImporter::image2D(): unsupported color bits-per-pixel:" << header.bpp; return nullptr; } @@ -136,13 +136,13 @@ ImageData2D* TgaImporter::doImage2D(UnsignedInt) { format = ImageFormat::Red; #endif if(header.bpp != 8) { - Error() << "Trade::TgaImporter::TgaImporter::image2D(): unsupported grayscale bits-per-pixel:" << header.bpp; + Error() << "Trade::TgaImporter::image2D(): unsupported grayscale bits-per-pixel:" << header.bpp; return nullptr; } /* Compressed files */ } else { - Error() << "Trade::TgaImporter::TgaImporter::image2D(): unsupported (compressed?) image type:" << header.imageType; + Error() << "Trade::TgaImporter::image2D(): unsupported (compressed?) image type:" << header.imageType; return nullptr; } diff --git a/src/Plugins/TgaImporter/TgaImporter.h b/src/Plugins/TgaImporter/TgaImporter.h index 84bb20040..0e08b168d 100644 --- a/src/Plugins/TgaImporter/TgaImporter.h +++ b/src/Plugins/TgaImporter/TgaImporter.h @@ -32,7 +32,7 @@ #include #ifndef DOXYGEN_GENERATING_OUTPUT -#ifdef TgaImporter_EXPORTS +#if defined(TgaImporter_EXPORTS) || defined(TgaImporterObjects_EXPORTS) #define MAGNUM_TRADE_TGAIMPORTER_EXPORT CORRADE_VISIBILITY_EXPORT #else #define MAGNUM_TRADE_TGAIMPORTER_EXPORT CORRADE_VISIBILITY_IMPORT @@ -47,15 +47,14 @@ namespace Magnum { namespace Trade { Supports uncompressed BGR, BGRA or grayscale images with 8 bits per channel. -The images are imported with @ref ImageType "ImageType::UnsignedByte" and -@ref ImageFormat "ImageFormat::BGR", @ref ImageFormat "ImageFormat::BGRA" or -@ref ImageFormat "ImageFormat::Red" respectively. Grayscale images require -extension @extension{ARB,texture_rg}. +The images are imported with @ref ImageType::UnsignedByte and @ref ImageFormat::BGR, +@ref ImageFormat::BGRA or @ref ImageFormat::Red, respectively. Grayscale images +require extension @extension{ARB,texture_rg}. -In OpenGL ES BGR and BGRA images are converted to @ref ImageFormat "ImageFormat::RGB" -and @ref ImageFormat "ImageFormat::RGBA". In OpenGL ES 2.0, if @es_extension{EXT,texture_rg} -is not supported, grayscale images use @ref ImageFormat "ImageFormat::Luminance" -instead of @ref ImageFormat "ImageFormat::Red". +In OpenGL ES BGR and BGRA images are converted to @ref ImageFormat::RGB +and @ref ImageFormat::RGBA. In OpenGL ES 2.0, if @es_extension{EXT,texture_rg} +is not supported, grayscale images use @ref ImageFormat::Luminance instead of +@ref ImageFormat::Red. */ class MAGNUM_TRADE_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter { public: @@ -65,7 +64,7 @@ class MAGNUM_TRADE_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter { /** @brief Plugin manager constructor */ explicit TgaImporter(PluginManager::AbstractManager* manager, std::string plugin); - virtual ~TgaImporter(); + ~TgaImporter(); private: Features MAGNUM_TRADE_TGAIMPORTER_LOCAL doFeatures() const override; diff --git a/src/Plugins/WavAudioImporter/CMakeLists.txt b/src/Plugins/WavAudioImporter/CMakeLists.txt new file mode 100644 index 000000000..0d2e69d3d --- /dev/null +++ b/src/Plugins/WavAudioImporter/CMakeLists.txt @@ -0,0 +1,51 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +find_package(Magnum REQUIRED Audio) + +include_directories(${MAGNUM_AUDIO_INCLUDE_DIRS}) + +set(WavAudioImporter_SRCS + WavImporter.cpp) + +set(WavAudioImporter_HEADERS + WavHeader.h + WavImporter.h) + +add_library(WavAudioImporterObjects OBJECT ${WavAudioImporter_SRCS}) +set_target_properties(WavAudioImporterObjects PROPERTIES COMPILE_FLAGS "-DWavAudioImporterObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") + +add_plugin(WavAudioImporter ${MAGNUM_PLUGINS_AUDIOIMPORTER_INSTALL_DIR} + WavAudioImporter.conf + $ + pluginRegistrationWavAudioImporter.cpp) +target_link_libraries(WavAudioImporter ${MAGNUM_AUDIO_LIBRARIES}) + +install(FILES ${WavAudioImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/WavAudioImporter) + +if(BUILD_TESTS) + add_library(WavAudioImporterTestLib STATIC $) + target_link_libraries(WavAudioImporterTestLib ${MAGNUM_LIBRARIES} ${MAGNUM_AUDIO_LIBRARIES}) + add_subdirectory(Test) +endif() diff --git a/src/Plugins/WavAudioImporter/Test/CMakeLists.txt b/src/Plugins/WavAudioImporter/Test/CMakeLists.txt new file mode 100644 index 000000000..fda7c7e61 --- /dev/null +++ b/src/Plugins/WavAudioImporter/Test/CMakeLists.txt @@ -0,0 +1,30 @@ +# +# This file is part of Magnum. +# +# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +# + +configure_file(${CMAKE_CURRENT_SOURCE_DIR}/configure.h.cmake + ${CMAKE_CURRENT_BINARY_DIR}/configure.h) + +include_directories(${CMAKE_CURRENT_BINARY_DIR}) + +corrade_add_test(WavAudioImporterTest WavImporterTest.cpp LIBRARIES WavAudioImporterTestLib) diff --git a/src/Plugins/WavAudioImporter/Test/WavImporterTest.cpp b/src/Plugins/WavAudioImporter/Test/WavImporterTest.cpp new file mode 100644 index 000000000..1a9593379 --- /dev/null +++ b/src/Plugins/WavAudioImporter/Test/WavImporterTest.cpp @@ -0,0 +1,123 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include +#include +#include +#include + +#include "WavAudioImporter/WavImporter.h" + +#include "configure.h" + +namespace Magnum { namespace Audio { namespace Test { + +class WavImporterTest: public TestSuite::Tester { + public: + explicit WavImporterTest(); + + void wrongSize(); + void wrongSignature(); + void unsupportedFormat(); + void unsupportedChannelCount(); + void mono16(); + void stereo8(); +}; + +WavImporterTest::WavImporterTest() { + addTests({&WavImporterTest::wrongSize, + &WavImporterTest::wrongSignature, + &WavImporterTest::unsupportedFormat, + &WavImporterTest::unsupportedChannelCount, + &WavImporterTest::mono16, + &WavImporterTest::stereo8}); +} + +void WavImporterTest::wrongSize() { + std::ostringstream out; + Error::setOutput(&out); + + WavImporter importer; + CORRADE_VERIFY(!importer.openData(Containers::Array(43))); + CORRADE_COMPARE(out.str(), "Audio::WavImporter::openData(): the file is too short: 43 bytes\n"); +} + +void WavImporterTest::wrongSignature() { + std::ostringstream out; + Error::setOutput(&out); + + WavImporter importer; + CORRADE_VERIFY(!importer.openFile(Utility::Directory::join(WAVAUDIOIMPORTER_TEST_DIR, "wrongSignature.wav"))); + CORRADE_COMPARE(out.str(), "Audio::WavImporter::openData(): the file signature is invalid\n"); +} + +void WavImporterTest::unsupportedFormat() { + std::ostringstream out; + Error::setOutput(&out); + + WavImporter importer; + CORRADE_VERIFY(!importer.openFile(Utility::Directory::join(WAVAUDIOIMPORTER_TEST_DIR, "unsupportedFormat.wav"))); + CORRADE_COMPARE(out.str(), "Audio::WavImporter::openData(): unsupported audio format 2\n"); +} + +void WavImporterTest::unsupportedChannelCount() { + std::ostringstream out; + Error::setOutput(&out); + + WavImporter importer; + CORRADE_VERIFY(!importer.openFile(Utility::Directory::join(WAVAUDIOIMPORTER_TEST_DIR, "unsupportedChannelCount.wav"))); + CORRADE_COMPARE(out.str(), "Audio::WavImporter::openData(): unsupported channel count 6 with 8 bits per sample\n"); +} + +void WavImporterTest::mono16() { + WavImporter importer; + CORRADE_VERIFY(importer.openFile(Utility::Directory::join(WAVAUDIOIMPORTER_TEST_DIR, "mono16.wav"))); + + CORRADE_COMPARE(importer.format(), Buffer::Format::Mono16); + CORRADE_COMPARE(importer.frequency(), 44000); + Containers::Array data = importer.data(); + CORRADE_COMPARE(data.size(), 4); + CORRADE_COMPARE(data[0], 0x1d); + CORRADE_COMPARE(data[1], 0x10); + CORRADE_COMPARE(data[2], 0x71); + CORRADE_COMPARE(data[3], 0xC5); +} + +void WavImporterTest::stereo8() { + WavImporter importer; + CORRADE_VERIFY(importer.openFile(Utility::Directory::join(WAVAUDIOIMPORTER_TEST_DIR, "stereo8.wav"))); + + CORRADE_COMPARE(importer.format(), Buffer::Format::Stereo8); + CORRADE_COMPARE(importer.frequency(), 96000); + Containers::Array data = importer.data(); + CORRADE_COMPARE(data.size(), 4); + CORRADE_COMPARE(data[0], 0xde); + CORRADE_COMPARE(data[1], 0xfe); + CORRADE_COMPARE(data[2], 0xca); + CORRADE_COMPARE(data[3], 0x7e); +} + +}}} + +CORRADE_TEST_MAIN(Magnum::Audio::Test::WavImporterTest) diff --git a/src/Plugins/WavAudioImporter/Test/configure.h.cmake b/src/Plugins/WavAudioImporter/Test/configure.h.cmake new file mode 100644 index 000000000..d5a41dac3 --- /dev/null +++ b/src/Plugins/WavAudioImporter/Test/configure.h.cmake @@ -0,0 +1,25 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#define WAVAUDIOIMPORTER_TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}" diff --git a/src/Plugins/WavAudioImporter/Test/mono16.wav b/src/Plugins/WavAudioImporter/Test/mono16.wav new file mode 100644 index 000000000..30d898274 Binary files /dev/null and b/src/Plugins/WavAudioImporter/Test/mono16.wav differ diff --git a/src/Plugins/WavAudioImporter/Test/stereo8.wav b/src/Plugins/WavAudioImporter/Test/stereo8.wav new file mode 100644 index 000000000..02298ef3b Binary files /dev/null and b/src/Plugins/WavAudioImporter/Test/stereo8.wav differ diff --git a/src/Plugins/WavAudioImporter/Test/unsupportedChannelCount.wav b/src/Plugins/WavAudioImporter/Test/unsupportedChannelCount.wav new file mode 100644 index 000000000..2f0b89221 Binary files /dev/null and b/src/Plugins/WavAudioImporter/Test/unsupportedChannelCount.wav differ diff --git a/src/Plugins/WavAudioImporter/Test/unsupportedFormat.wav b/src/Plugins/WavAudioImporter/Test/unsupportedFormat.wav new file mode 100644 index 000000000..443eefa82 Binary files /dev/null and b/src/Plugins/WavAudioImporter/Test/unsupportedFormat.wav differ diff --git a/src/Plugins/WavAudioImporter/Test/wrongSignature.wav b/src/Plugins/WavAudioImporter/Test/wrongSignature.wav new file mode 100644 index 000000000..e50f1cd12 Binary files /dev/null and b/src/Plugins/WavAudioImporter/Test/wrongSignature.wav differ diff --git a/src/Plugins/WavAudioImporter/WavAudioImporter.conf b/src/Plugins/WavAudioImporter/WavAudioImporter.conf new file mode 100644 index 000000000..e69de29bb diff --git a/src/Plugins/WavAudioImporter/WavHeader.h b/src/Plugins/WavAudioImporter/WavHeader.h new file mode 100644 index 000000000..e472b8f5f --- /dev/null +++ b/src/Plugins/WavAudioImporter/WavHeader.h @@ -0,0 +1,60 @@ +#ifndef Magnum_Audio_WavHeader_h +#define Magnum_Audio_WavHeader_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Struct Magnum::Audio::WavHeader + */ + +#include + +namespace Magnum { namespace Audio { + +#pragma pack(1) +/** @brief WAV file header */ +struct WavHeader { + char chunkId[4]; /**< @brief `RIFF` characters */ + UnsignedInt chunkSize; /**< @brief Size of the rest of the file */ + char format[4]; /**< @brief `WAVE` characters */ + + char subChunk1Id[4]; /**< @brief `fmt ` characters */ + UnsignedInt subChunk1Size; /**< @brief 16 for PCM */ + UnsignedShort audioFormat; /**< @brief 1 = PCM */ + UnsignedShort numChannels; /**< @brief 1 = Mono, 2 = Stereo */ + UnsignedInt sampleRate; /**< @brief Sample rate in Hz */ + UnsignedInt byteRate; /**< @brief Bytes per second */ + UnsignedShort blockAlign; /**< @brief Bytes per sample (all channels) */ + UnsignedShort bitsPerSample; /**< @brief Bits per sample (one channel) */ + + char subChunk2Id[4]; /**< @brief `data` characters */ + UnsignedInt subChunk2Size; /**< @brief Size of the following data */ +}; +#pragma pack() + +static_assert(sizeof(WavHeader) == 44, "WavHeader size is not 44 bytes"); + +}} + +#endif diff --git a/src/Plugins/WavAudioImporter/WavImporter.cpp b/src/Plugins/WavAudioImporter/WavImporter.cpp new file mode 100644 index 000000000..db93e0885 --- /dev/null +++ b/src/Plugins/WavAudioImporter/WavImporter.cpp @@ -0,0 +1,130 @@ +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "WavImporter.h" + +#include +#include +#include + +#include "WavHeader.h" + +namespace Magnum { namespace Audio { + +WavImporter::WavImporter() = default; + +WavImporter::WavImporter(PluginManager::AbstractManager* manager, std::string plugin): AbstractImporter(manager, std::move(plugin)) {} + +WavImporter::~WavImporter() { close(); } + +auto WavImporter::doFeatures() const -> Features { return Feature::OpenData; } + +bool WavImporter::doIsOpened() const { return _data; } + +void WavImporter::doOpenData(Containers::ArrayReference data) { + /* Check file size */ + if(data.size() < sizeof(WavHeader)) { + Error() << "Audio::WavImporter::openData(): the file is too short:" << data.size() << "bytes"; + return; + } + + /* Get header contents and fix endianness */ + WavHeader header(*reinterpret_cast(data.begin())); + Utility::Endianness::littleEndianInPlace(header.chunkSize, + header.subChunk1Size, header.audioFormat, header.numChannels, + header.sampleRate, header.byteRate, header.blockAlign, + header.bitsPerSample, header.subChunk2Size); + + /* Check file signature */ + if(std::strncmp(header.chunkId, "RIFF", 4) != 0 || + std::strncmp(header.format, "WAVE", 4) != 0 || + std::strncmp(header.subChunk1Id, "fmt ", 4) != 0 || + std::strncmp(header.subChunk2Id, "data", 4) != 0) { + Error() << "Audio::WavImporter::openData(): the file signature is invalid"; + return; + } + + /* Check file size */ + if(header.chunkSize + 8 != data.size()) { + Error() << "Audio::WavImporter::openData(): the file has improper size, expected" + << header.chunkSize + 8 << "but got" << data.size(); + return; + } + + /* Check PCM format */ + if(header.audioFormat != 1) { + Error() << "Audio::WavImporter::openData(): unsupported audio format" << header.audioFormat; + return; + } + + /* Verify more things */ + if(header.subChunk1Size != 16 || + header.subChunk2Size + 44 != data.size() || + header.blockAlign != header.numChannels*header.bitsPerSample/8 || + header.byteRate != header.sampleRate*header.blockAlign) { + Error() << "Audio::WavImporter::openData(): the file is corrupted"; + return; + } + + /* Decide about format */ + if(header.numChannels == 1 && header.bitsPerSample == 8) + _format = Buffer::Format::Mono8; + else if(header.numChannels == 1 && header.bitsPerSample == 16) + _format = Buffer::Format::Mono16; + else if(header.numChannels == 2 && header.bitsPerSample == 8) + _format = Buffer::Format::Stereo8; + else if(header.numChannels == 2 && header.bitsPerSample == 16) + _format = Buffer::Format::Stereo16; + else { + Error() << "Audio::WavImporter::openData(): unsupported channel count" + << header.numChannels << "with" << header.bitsPerSample + << "bits per sample"; + return; + } + + /* Save frequency */ + _frequency = header.sampleRate; + + /** @todo Convert the data from little endian too */ + CORRADE_INTERNAL_ASSERT(!Utility::Endianness::isBigEndian()); + + /* Copy the data */ + _data = Containers::Array(header.subChunk2Size); + std::copy(data.begin()+sizeof(WavHeader), data.end(), _data.begin()); + return; +} + +void WavImporter::doClose() { _data = nullptr; } + +Buffer::Format WavImporter::doFormat() const { return _format; } + +UnsignedInt WavImporter::doFrequency() const { return _frequency; } + +Containers::Array WavImporter::doData() { + Containers::Array copy(_data.size()); + std::copy(_data.begin(), _data.end(), copy.begin()); + return copy; +} + +}} diff --git a/src/Plugins/WavAudioImporter/WavImporter.h b/src/Plugins/WavAudioImporter/WavImporter.h new file mode 100644 index 000000000..770461bbb --- /dev/null +++ b/src/Plugins/WavAudioImporter/WavImporter.h @@ -0,0 +1,71 @@ +#ifndef Magnum_Audio_WavImporter_h +#define Magnum_Audio_WavImporter_h +/* + This file is part of Magnum. + + Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included + in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +/** @file + * @brief Class Magnum::Audio::WavImporter + */ + +#include +#include +#include