Browse Source

Trade: add flags to AbstractImporter and AbstractImageConverter.

pull/427/merge
Vladimír Vondruš 6 years ago
parent
commit
0bdb70fcf6
  1. 3
      doc/changelog.dox
  2. 26
      src/Magnum/Trade/AbstractImageConverter.cpp
  3. 72
      src/Magnum/Trade/AbstractImageConverter.h
  4. 28
      src/Magnum/Trade/AbstractImporter.cpp
  5. 73
      src/Magnum/Trade/AbstractImporter.h
  6. 54
      src/Magnum/Trade/Test/AbstractImageConverterTest.cpp
  7. 77
      src/Magnum/Trade/Test/AbstractImporterTest.cpp

3
doc/changelog.dox

@ -276,6 +276,9 @@ See also:
- @ref Trade::PhongMaterialData now supports both color and texture instead - @ref Trade::PhongMaterialData now supports both color and texture instead
of just one or the other, can reference normal textures as well and of just one or the other, can reference normal textures as well and
specfify texture coordinate transform specfify texture coordinate transform
- Added @ref Trade::AbstractImporter::setFlags() and
@ref Trade::AbstractImageConverter::setFlags() for configuring common
plugin behavior such as output verbosity level
- @ref magnum-imageconverter "magnum-imageconverter" has a new `--info` - @ref magnum-imageconverter "magnum-imageconverter" has a new `--info`
option for printing detailed info about a particular file option for printing detailed info about a particular file
- RLE compression support in @ref Trade::TgaImporter "TgaImporter" - RLE compression support in @ref Trade::TgaImporter "TgaImporter"

26
src/Magnum/Trade/AbstractImageConverter.cpp

@ -74,6 +74,13 @@ AbstractImageConverter::AbstractImageConverter(PluginManager::Manager<AbstractIm
AbstractImageConverter::AbstractImageConverter(PluginManager::AbstractManager& manager, const std::string& plugin): PluginManager::AbstractManagingPlugin<AbstractImageConverter>{manager, plugin} {} AbstractImageConverter::AbstractImageConverter(PluginManager::AbstractManager& manager, const std::string& plugin): PluginManager::AbstractManagingPlugin<AbstractImageConverter>{manager, plugin} {}
void AbstractImageConverter::setFlags(ImageConverterFlags flags) {
_flags = flags;
doSetFlags(flags);
}
void AbstractImageConverter::doSetFlags(ImageConverterFlags) {}
Containers::Optional<Image2D> AbstractImageConverter::exportToImage(const ImageView2D& image) { Containers::Optional<Image2D> AbstractImageConverter::exportToImage(const ImageView2D& image) {
CORRADE_ASSERT(features() & ImageConverterFeature::ConvertImage, CORRADE_ASSERT(features() & ImageConverterFeature::ConvertImage,
"Trade::AbstractImageConverter::exportToImage(): feature not supported", {}); "Trade::AbstractImageConverter::exportToImage(): feature not supported", {});
@ -208,4 +215,23 @@ Debug& operator<<(Debug& debug, const ImageConverterFeatures value) {
ImageConverterFeature::ConvertCompressedFile}); ImageConverterFeature::ConvertCompressedFile});
} }
Debug& operator<<(Debug& debug, const ImageConverterFlag value) {
debug << "Trade::ImageConverterFlag" << Debug::nospace;
switch(value) {
/* LCOV_EXCL_START */
#define _c(v) case ImageConverterFlag::v: return debug << "::" #v;
_c(Verbose)
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, const ImageConverterFlags value) {
return Containers::enumSetDebugOutput(debug, value, "Trade::ImageConverterFlags{}", {
ImageConverterFlag::Verbose});
}
}} }}

72
src/Magnum/Trade/AbstractImageConverter.h

@ -99,6 +99,45 @@ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImageConverterFeature value)
/** @debugoperatorenum{ImageConverterFeatures} */ /** @debugoperatorenum{ImageConverterFeatures} */
MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImageConverterFeatures value); MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImageConverterFeatures value);
/**
@brief Image converter flag
@m_since_latest
@see @ref ImageConverterFlags, @ref AbstractImageConverter::setFlags()
*/
enum class ImageConverterFlag: UnsignedByte {
/**
* Print verbose diagnostic during import. By default the importer only
* prints messages on error or when some operation might cause unexpected
* data modification or loss.
*/
Verbose = 1 << 0
/** @todo Y flip */
};
/**
@brief Image converter flags
@m_since_latest
@see @ref AbstractImporter::setFlags()
*/
typedef Containers::EnumSet<ImageConverterFlag> ImageConverterFlags;
CORRADE_ENUMSET_OPERATORS(ImageConverterFlags)
/**
@debugoperatorenum{ImageConverterFlag}
@m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImageConverterFlag value);
/**
@debugoperatorenum{ImageConverterFlags}
@m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImageConverterFlags value);
/** /**
@brief Base for image converter plugins @brief Base for image converter plugins
@ -202,6 +241,22 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract
/** @brief Features supported by this converter */ /** @brief Features supported by this converter */
ImageConverterFeatures features() const { return doFeatures(); } ImageConverterFeatures features() const { return doFeatures(); }
/**
* @brief Converter flags
* @m_since_latest
*/
ImageConverterFlags flags() const { return _flags; }
/**
* @brief Set converter flags
* @m_since_latest
*
* Some flags can be set only if the converter supports particular
* features, see documentation of each @ref ImageConverterFlag for more
* information. By default no flags are set.
*/
void setFlags(ImageConverterFlags flags);
/** /**
* @brief Convert image to different format * @brief Convert image to different format
* *
@ -288,6 +343,21 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract
/** @brief Implementation of @ref features() */ /** @brief Implementation of @ref features() */
virtual ImageConverterFeatures doFeatures() const = 0; virtual ImageConverterFeatures doFeatures() const = 0;
/**
* @brief Implementation for @ref setFlags()
*
* Useful when the converter needs to modify some internal state on
* flag setup. Default implementation does nothing and this
* function doesn't need to be implemented --- the flags are available
* through @ref flags().
*
* To reduce the amount of error checking on user side, this function
* isn't expected to fail --- if a flag combination is invalid /
* unsuported, error reporting should be delayed to various conversion
* functions, where the user is expected to do error handling anyway.
*/
virtual void doSetFlags(ImageConverterFlags flags);
/** @brief Implementation of @ref exportToImage() */ /** @brief Implementation of @ref exportToImage() */
virtual Containers::Optional<Image2D> doExportToImage(const ImageView2D& image); virtual Containers::Optional<Image2D> doExportToImage(const ImageView2D& image);
@ -317,6 +387,8 @@ class MAGNUM_TRADE_EXPORT AbstractImageConverter: public PluginManager::Abstract
* and saves the result to given file. * and saves the result to given file.
*/ */
virtual bool doExportToFile(const CompressedImageView2D& image, const std::string& filename); virtual bool doExportToFile(const CompressedImageView2D& image, const std::string& filename);
ImageConverterFlags _flags;
}; };
}} }}

28
src/Magnum/Trade/AbstractImporter.cpp

@ -90,6 +90,15 @@ AbstractImporter::AbstractImporter(PluginManager::Manager<AbstractImporter>& man
AbstractImporter::AbstractImporter(PluginManager::AbstractManager& manager, const std::string& plugin): PluginManager::AbstractManagingPlugin<AbstractImporter>{manager, plugin} {} AbstractImporter::AbstractImporter(PluginManager::AbstractManager& manager, const std::string& plugin): PluginManager::AbstractManagingPlugin<AbstractImporter>{manager, plugin} {}
void AbstractImporter::setFlags(ImporterFlags flags) {
CORRADE_ASSERT(!isOpened(),
"Trade::AbstractImporter::setFlags(): can't be set while a file is opened", );
_flags = flags;
doSetFlags(flags);
}
void AbstractImporter::doSetFlags(ImporterFlags) {}
void AbstractImporter::setFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* const userData) { void AbstractImporter::setFileCallback(Containers::Optional<Containers::ArrayView<const char>>(*callback)(const std::string&, InputFileCallbackPolicy, void*), void* const userData) {
CORRADE_ASSERT(!isOpened(), "Trade::AbstractImporter::setFileCallback(): can't be set while a file is opened", ); CORRADE_ASSERT(!isOpened(), "Trade::AbstractImporter::setFileCallback(): can't be set while a file is opened", );
CORRADE_ASSERT(features() & (ImporterFeature::FileCallback|ImporterFeature::OpenData), "Trade::AbstractImporter::setFileCallback(): importer supports neither loading from data nor via callbacks, callbacks can't be used", ); CORRADE_ASSERT(features() & (ImporterFeature::FileCallback|ImporterFeature::OpenData), "Trade::AbstractImporter::setFileCallback(): importer supports neither loading from data nor via callbacks, callbacks can't be used", );
@ -955,4 +964,23 @@ Debug& operator<<(Debug& debug, const ImporterFeatures value) {
ImporterFeature::FileCallback}); ImporterFeature::FileCallback});
} }
Debug& operator<<(Debug& debug, const ImporterFlag value) {
debug << "Trade::ImporterFlag" << Debug::nospace;
switch(value) {
/* LCOV_EXCL_START */
#define _c(v) case ImporterFlag::v: return debug << "::" #v;
_c(Verbose)
#undef _c
/* LCOV_EXCL_STOP */
}
return debug << "(" << Debug::nospace << reinterpret_cast<void*>(UnsignedByte(value)) << Debug::nospace << ")";
}
Debug& operator<<(Debug& debug, const ImporterFlags value) {
return Containers::enumSetDebugOutput(debug, value, "Trade::ImporterFlags{}", {
ImporterFlag::Verbose});
}
}} }}

73
src/Magnum/Trade/AbstractImporter.h

@ -92,6 +92,45 @@ MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImporterFeatures value);
typedef CORRADE_DEPRECATED("use InputFileCallbackPolicy instead") InputFileCallbackPolicy ImporterFileCallbackPolicy; typedef CORRADE_DEPRECATED("use InputFileCallbackPolicy instead") InputFileCallbackPolicy ImporterFileCallbackPolicy;
#endif #endif
/**
@brief Importer flag
@m_since_latest
@see @ref ImporterFlags, @ref AbstractImporter::setFlags()
*/
enum class ImporterFlag: UnsignedByte {
/**
* Print verbose diagnostic during import. By default the importer only
* prints messages on error or when some operation might cause unexpected
* data modification or loss.
*/
Verbose = 1 << 0,
/** @todo Y flip for images, "I want to import just once, don't copy" ... */
};
/**
@brief Importer flags
@m_since_latest
@see @ref AbstractImporter::setFlags()
*/
typedef Containers::EnumSet<ImporterFlag> ImporterFlags;
CORRADE_ENUMSET_OPERATORS(ImporterFlags)
/**
@debugoperatorenum{ImporterFlag}
@m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImporterFlag value);
/**
@debugoperatorenum{ImporterFlags}
@m_since_latest
*/
MAGNUM_TRADE_EXPORT Debug& operator<<(Debug& debug, ImporterFlags value);
/** /**
@brief Base for importer plugins @brief Base for importer plugins
@ -322,6 +361,23 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/** @brief Features supported by this importer */ /** @brief Features supported by this importer */
ImporterFeatures features() const { return doFeatures(); } ImporterFeatures features() const { return doFeatures(); }
/**
* @brief Importer flags
* @m_since_latest
*/
ImporterFlags flags() const { return _flags; }
/**
* @brief Set importer flags
* @m_since_latest
*
* It's expected that this function is called *before* a file is
* opened. Some flags can be set only if the importer supports
* particular features, see documentation of each @ref ImporterFlag for
* more information. By default no flags are set.
*/
void setFlags(ImporterFlags flags);
/** /**
* @brief File opening callback function * @brief File opening callback function
* *
@ -1255,6 +1311,21 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/** @brief Implementation for @ref features() */ /** @brief Implementation for @ref features() */
virtual ImporterFeatures doFeatures() const = 0; virtual ImporterFeatures doFeatures() const = 0;
/**
* @brief Implementation for @ref setFlags()
*
* Useful when the importer needs to modify some internal state on
* flag setup. Default implementation does nothing and this
* function doesn't need to be implemented --- the flags are available
* through @ref flags().
*
* To reduce the amount of error checking on user side, this function
* isn't expected to fail --- if a flag combination is invalid /
* unsuported, error reporting should be delayed to @ref openFile() and
* others, where the user is expected to do error handling anyway.
*/
virtual void doSetFlags(ImporterFlags flags);
/** /**
* @brief Implementation for @ref setFileCallback() * @brief Implementation for @ref setFileCallback()
* *
@ -1761,6 +1832,8 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/** @brief Implementation for @ref importerState() */ /** @brief Implementation for @ref importerState() */
virtual const void* doImporterState() const; virtual const void* doImporterState() const;
ImporterFlags _flags;
Containers::Optional<Containers::ArrayView<const char>>(*_fileCallback)(const std::string&, InputFileCallbackPolicy, void*){}; Containers::Optional<Containers::ArrayView<const char>>(*_fileCallback)(const std::string&, InputFileCallbackPolicy, void*){};
void* _fileCallbackUserData{}; void* _fileCallbackUserData{};

54
src/Magnum/Trade/Test/AbstractImageConverterTest.cpp

@ -48,6 +48,9 @@ struct AbstractImageConverterTest: TestSuite::Tester {
void construct(); void construct();
void constructWithPluginManagerReference(); void constructWithPluginManagerReference();
void setFlags();
void setFlagsNotImplemented();
void thingNotSupported(); void thingNotSupported();
void exportToImage(); void exportToImage();
@ -82,12 +85,17 @@ struct AbstractImageConverterTest: TestSuite::Tester {
void debugFeature(); void debugFeature();
void debugFeatures(); void debugFeatures();
void debugFlag();
void debugFlags();
}; };
AbstractImageConverterTest::AbstractImageConverterTest() { AbstractImageConverterTest::AbstractImageConverterTest() {
addTests({&AbstractImageConverterTest::construct, addTests({&AbstractImageConverterTest::construct,
&AbstractImageConverterTest::constructWithPluginManagerReference, &AbstractImageConverterTest::constructWithPluginManagerReference,
&AbstractImageConverterTest::setFlags,
&AbstractImageConverterTest::setFlagsNotImplemented,
&AbstractImageConverterTest::thingNotSupported, &AbstractImageConverterTest::thingNotSupported,
&AbstractImageConverterTest::exportToImage, &AbstractImageConverterTest::exportToImage,
@ -121,7 +129,9 @@ AbstractImageConverterTest::AbstractImageConverterTest() {
&AbstractImageConverterTest::exportImageDataToFile, &AbstractImageConverterTest::exportImageDataToFile,
&AbstractImageConverterTest::debugFeature, &AbstractImageConverterTest::debugFeature,
&AbstractImageConverterTest::debugFeatures}); &AbstractImageConverterTest::debugFeatures,
&AbstractImageConverterTest::debugFlag,
&AbstractImageConverterTest::debugFlags});
/* Create testing dir */ /* Create testing dir */
Utility::Directory::mkpath(TRADE_TEST_OUTPUT_DIR); Utility::Directory::mkpath(TRADE_TEST_OUTPUT_DIR);
@ -147,6 +157,34 @@ void AbstractImageConverterTest::constructWithPluginManagerReference() {
CORRADE_COMPARE(converter.features(), ImageConverterFeatures{}); CORRADE_COMPARE(converter.features(), ImageConverterFeatures{});
} }
void AbstractImageConverterTest::setFlags() {
struct: AbstractImageConverter {
ImageConverterFeatures doFeatures() const override { return {}; }
void doSetFlags(ImageConverterFlags flags) override {
_flags = flags;
}
ImageConverterFlags _flags;
} converter;
CORRADE_COMPARE(converter.flags(), ImageConverterFlags{});
CORRADE_COMPARE(converter._flags, ImageConverterFlags{});
converter.setFlags(ImageConverterFlag::Verbose);
CORRADE_COMPARE(converter.flags(), ImageConverterFlag::Verbose);
CORRADE_COMPARE(converter._flags, ImageConverterFlag::Verbose);
}
void AbstractImageConverterTest::setFlagsNotImplemented() {
struct: AbstractImageConverter {
ImageConverterFeatures doFeatures() const override { return {}; }
} converter;
CORRADE_COMPARE(converter.flags(), ImageConverterFlags{});
converter.setFlags(ImageConverterFlag::Verbose);
CORRADE_COMPARE(converter.flags(), ImageConverterFlag::Verbose);
/* Should just work, no need to implement the function */
}
void AbstractImageConverterTest::thingNotSupported() { void AbstractImageConverterTest::thingNotSupported() {
#ifdef CORRADE_NO_ASSERT #ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions"); CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
@ -554,6 +592,20 @@ void AbstractImageConverterTest::debugFeatures() {
CORRADE_COMPARE(out.str(), "Trade::ImageConverterFeature::ConvertData|Trade::ImageConverterFeature::ConvertCompressedFile Trade::ImageConverterFeatures{}\n"); CORRADE_COMPARE(out.str(), "Trade::ImageConverterFeature::ConvertData|Trade::ImageConverterFeature::ConvertCompressedFile Trade::ImageConverterFeatures{}\n");
} }
void AbstractImageConverterTest::debugFlag() {
std::ostringstream out;
Debug{&out} << ImageConverterFlag::Verbose << ImageConverterFlag(0xf0);
CORRADE_COMPARE(out.str(), "Trade::ImageConverterFlag::Verbose Trade::ImageConverterFlag(0xf0)\n");
}
void AbstractImageConverterTest::debugFlags() {
std::ostringstream out;
Debug{&out} << (ImageConverterFlag::Verbose|ImageConverterFlag(0xf0)) << ImageConverterFlags{};
CORRADE_COMPARE(out.str(), "Trade::ImageConverterFlag::Verbose|Trade::ImageConverterFlag(0xf0) Trade::ImageConverterFlags{}\n");
}
}}}} }}}}
CORRADE_TEST_MAIN(Magnum::Trade::Test::AbstractImageConverterTest) CORRADE_TEST_MAIN(Magnum::Trade::Test::AbstractImageConverterTest)

77
src/Magnum/Trade/Test/AbstractImporterTest.cpp

@ -62,6 +62,10 @@ struct AbstractImporterTest: TestSuite::Tester {
void construct(); void construct();
void constructWithPluginManagerReference(); void constructWithPluginManagerReference();
void setFlags();
void setFlagsFileOpened();
void setFlagsNotImplemented();
void openData(); void openData();
void openFileAsData(); void openFileAsData();
void openFileAsDataNotFound(); void openFileAsDataNotFound();
@ -241,6 +245,8 @@ struct AbstractImporterTest: TestSuite::Tester {
void debugFeature(); void debugFeature();
void debugFeatures(); void debugFeatures();
void debugFlag();
void debugFlags();
}; };
constexpr struct { constexpr struct {
@ -255,6 +261,10 @@ AbstractImporterTest::AbstractImporterTest() {
addTests({&AbstractImporterTest::construct, addTests({&AbstractImporterTest::construct,
&AbstractImporterTest::constructWithPluginManagerReference, &AbstractImporterTest::constructWithPluginManagerReference,
&AbstractImporterTest::setFlags,
&AbstractImporterTest::setFlagsFileOpened,
&AbstractImporterTest::setFlagsNotImplemented,
&AbstractImporterTest::openData, &AbstractImporterTest::openData,
&AbstractImporterTest::openFileAsData, &AbstractImporterTest::openFileAsData,
&AbstractImporterTest::openFileAsDataNotFound, &AbstractImporterTest::openFileAsDataNotFound,
@ -436,7 +446,9 @@ AbstractImporterTest::AbstractImporterTest() {
&AbstractImporterTest::importerStateNoFile, &AbstractImporterTest::importerStateNoFile,
&AbstractImporterTest::debugFeature, &AbstractImporterTest::debugFeature,
&AbstractImporterTest::debugFeatures}); &AbstractImporterTest::debugFeatures,
&AbstractImporterTest::debugFlag,
&AbstractImporterTest::debugFlags});
} }
void AbstractImporterTest::construct() { void AbstractImporterTest::construct() {
@ -467,6 +479,55 @@ void AbstractImporterTest::constructWithPluginManagerReference() {
CORRADE_VERIFY(!importer.isOpened()); CORRADE_VERIFY(!importer.isOpened());
} }
void AbstractImporterTest::setFlags() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
void doSetFlags(ImporterFlags flags) override {
_flags = flags;
}
bool doIsOpened() const override { return false; }
void doClose() override {}
ImporterFlags _flags;
} importer;
CORRADE_COMPARE(importer.flags(), ImporterFlags{});
CORRADE_COMPARE(importer._flags, ImporterFlags{});
importer.setFlags(ImporterFlag::Verbose);
CORRADE_COMPARE(importer.flags(), ImporterFlag::Verbose);
CORRADE_COMPARE(importer._flags, ImporterFlag::Verbose);
}
void AbstractImporterTest::setFlagsNotImplemented() {
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return false; }
void doClose() override {}
} importer;
CORRADE_COMPARE(importer.flags(), ImporterFlags{});
importer.setFlags(ImporterFlag::Verbose);
CORRADE_COMPARE(importer.flags(), ImporterFlag::Verbose);
/* Should just work, no need to implement the function */
}
void AbstractImporterTest::setFlagsFileOpened() {
#ifdef CORRADE_NO_ASSERT
CORRADE_SKIP("CORRADE_NO_ASSERT defined, can't test assertions");
#endif
struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return {}; }
bool doIsOpened() const override { return true; }
void doClose() override {}
} importer;
std::ostringstream out;
Error redirectError{&out};
importer.setFlags(ImporterFlag::Verbose);
CORRADE_COMPARE(out.str(), "Trade::AbstractImporter::setFlags(): can't be set while a file is opened\n");
}
void AbstractImporterTest::openData() { void AbstractImporterTest::openData() {
struct: AbstractImporter { struct: AbstractImporter {
ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; } ImporterFeatures doFeatures() const override { return ImporterFeature::OpenData; }
@ -3965,6 +4026,20 @@ void AbstractImporterTest::debugFeatures() {
CORRADE_COMPARE(out.str(), "Trade::ImporterFeature::OpenData|Trade::ImporterFeature::OpenState Trade::ImporterFeatures{}\n"); CORRADE_COMPARE(out.str(), "Trade::ImporterFeature::OpenData|Trade::ImporterFeature::OpenState Trade::ImporterFeatures{}\n");
} }
void AbstractImporterTest::debugFlag() {
std::ostringstream out;
Debug{&out} << ImporterFlag::Verbose << ImporterFlag(0xf0);
CORRADE_COMPARE(out.str(), "Trade::ImporterFlag::Verbose Trade::ImporterFlag(0xf0)\n");
}
void AbstractImporterTest::debugFlags() {
std::ostringstream out;
Debug{&out} << (ImporterFlag::Verbose|ImporterFlag(0xf0)) << ImporterFlags{};
CORRADE_COMPARE(out.str(), "Trade::ImporterFlag::Verbose|Trade::ImporterFlag(0xf0) Trade::ImporterFlags{}\n");
}
}}}} }}}}
CORRADE_TEST_MAIN(Magnum::Trade::Test::AbstractImporterTest) CORRADE_TEST_MAIN(Magnum::Trade::Test::AbstractImporterTest)

Loading…
Cancel
Save