Skip to content

Commit

Permalink
[wip] Trade: support mip levels in image import.
Browse files Browse the repository at this point in the history
There's a new level option in each imageND() API, plus an
imageNDLevelCount() query to get image level count.

TODO: changelog entry
TODO: update all plugins
  • Loading branch information
mosra committed Aug 27, 2019
1 parent 40b8815 commit f9844bb
Show file tree
Hide file tree
Showing 10 changed files with 461 additions and 53 deletions.
89 changes: 79 additions & 10 deletions src/Magnum/Trade/AbstractImporter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@
namespace Magnum { namespace Trade {

std::string AbstractImporter::pluginInterface() {
return "cz.mosra.magnum.Trade.AbstractImporter/0.3";
return "cz.mosra.magnum.Trade.AbstractImporter/0.3.1";
}

#ifndef CORRADE_PLUGINMANAGER_NO_DYNAMIC_PLUGIN_SUPPORT
Expand Down Expand Up @@ -535,6 +535,14 @@ UnsignedInt AbstractImporter::image1DCount() const {

UnsignedInt AbstractImporter::doImage1DCount() const { return 0; }

UnsignedInt AbstractImporter::image1DLevelCount(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DLevelCount(): no file opened", {});
CORRADE_ASSERT(id < doImage1DCount(), "Trade::AbstractImporter::image1DLevelCount(): index out of range", {});
return doImage1DLevelCount(id);
}

UnsignedInt AbstractImporter::doImage1DLevelCount(UnsignedInt) { return 1; }

Int AbstractImporter::image1DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1DForName(): no file opened", {});
return doImage1DForName(name);
Expand All @@ -550,13 +558,28 @@ std::string AbstractImporter::image1DName(const UnsignedInt id) {

std::string AbstractImporter::doImage1DName(UnsignedInt) { return {}; }

Containers::Optional<ImageData1D> AbstractImporter::image1D(const UnsignedInt id) {
Containers::Optional<ImageData1D> AbstractImporter::image1D(const UnsignedInt id, const UnsignedInt level) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image1D(): no file opened", {});
CORRADE_ASSERT(id < doImage1DCount(), "Trade::AbstractImporter::image1D(): index out of range", {});
return doImage1D(id);
#ifndef CORRADE_NO_ASSERT
/* Check that non-trivial level is in bounds, failing the import instead of
asserting if the reported level count is zero (indicating an error).
Doing this only if assertions are enabled -- with assertions disabled
(and sane importer implementation), the importer failure happens inside
doImage1D() instead, giving consistent result in both cases. */
if(level) {
const UnsignedInt levelCount = doImage1DLevelCount(id);
if(!levelCount) {
Error{} << "Trade::AbstractImporter::image1D(): image reported zero levels";
return {};
}
CORRADE_ASSERT(level < levelCount, "Trade::AbstractImporter::image1D(): level out of range", {});
}
#endif
return doImage1D(id, level);
}

Containers::Optional<ImageData1D> AbstractImporter::doImage1D(UnsignedInt) {
Containers::Optional<ImageData1D> AbstractImporter::doImage1D(UnsignedInt, UnsignedInt) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::image1D(): not implemented", {});
}

Expand All @@ -567,6 +590,14 @@ UnsignedInt AbstractImporter::image2DCount() const {

UnsignedInt AbstractImporter::doImage2DCount() const { return 0; }

UnsignedInt AbstractImporter::image2DLevelCount(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2DLevelCount(): no file opened", {});
CORRADE_ASSERT(id < doImage2DCount(), "Trade::AbstractImporter::image2DLevelCount(): index out of range", {});
return doImage2DLevelCount(id);
}

UnsignedInt AbstractImporter::doImage2DLevelCount(UnsignedInt) { return 1; }

Int AbstractImporter::image2DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2DForName(): no file opened", {});
return doImage2DForName(name);
Expand All @@ -582,13 +613,28 @@ std::string AbstractImporter::image2DName(const UnsignedInt id) {

std::string AbstractImporter::doImage2DName(UnsignedInt) { return {}; }

Containers::Optional<ImageData2D> AbstractImporter::image2D(const UnsignedInt id) {
Containers::Optional<ImageData2D> AbstractImporter::image2D(const UnsignedInt id, const UnsignedInt level) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image2D(): no file opened", {});
CORRADE_ASSERT(id < doImage2DCount(), "Trade::AbstractImporter::image2D(): index out of range", {});
return doImage2D(id);
#ifndef CORRADE_NO_ASSERT
/* Check that non-trivial level is in bounds, failing the import instead of
asserting if the reported level count is zero (indicating an error).
Doing this only if assertions are enabled -- with assertions disabled
(and sane importer implementation), the importer failure happens inside
doImage1D() instead, giving consistent result in both cases. */
if(level) {
const UnsignedInt levelCount = doImage2DLevelCount(id);
if(!levelCount) {
Error{} << "Trade::AbstractImporter::image2D(): image reported zero levels";
return {};
}
CORRADE_ASSERT(level < levelCount, "Trade::AbstractImporter::image2D(): level out of range", {});
}
#endif
return doImage2D(id, level);
}

Containers::Optional<ImageData2D> AbstractImporter::doImage2D(UnsignedInt) {
Containers::Optional<ImageData2D> AbstractImporter::doImage2D(UnsignedInt, UnsignedInt) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::image2D(): not implemented", {});
}

Expand All @@ -599,6 +645,14 @@ UnsignedInt AbstractImporter::image3DCount() const {

UnsignedInt AbstractImporter::doImage3DCount() const { return 0; }

UnsignedInt AbstractImporter::image3DLevelCount(const UnsignedInt id) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3DLevelCount(): no file opened", {});
CORRADE_ASSERT(id < doImage3DCount(), "Trade::AbstractImporter::image3DLevelCount(): index out of range", {});
return doImage3DLevelCount(id);
}

UnsignedInt AbstractImporter::doImage3DLevelCount(UnsignedInt) { return 1; }

Int AbstractImporter::image3DForName(const std::string& name) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3DForName(): no file opened", {});
return doImage3DForName(name);
Expand All @@ -614,13 +668,28 @@ std::string AbstractImporter::image3DName(const UnsignedInt id) {

std::string AbstractImporter::doImage3DName(UnsignedInt) { return {}; }

Containers::Optional<ImageData3D> AbstractImporter::image3D(const UnsignedInt id) {
Containers::Optional<ImageData3D> AbstractImporter::image3D(const UnsignedInt id, const UnsignedInt level) {
CORRADE_ASSERT(isOpened(), "Trade::AbstractImporter::image3D(): no file opened", {});
CORRADE_ASSERT(id < doImage3DCount(), "Trade::AbstractImporter::image3D(): index out of range", {});
return doImage3D(id);
#ifndef CORRADE_NO_ASSERT
/* Check that non-trivial level is in bounds, failing the import instead of
asserting if the reported level count is zero (indicating an error).
Doing this only if assertions are enabled -- with assertions disabled
(and sane importer implementation), the importer failure happens inside
doImage3D() instead, giving consistent result in both cases. */
if(level) {
const UnsignedInt levelCount = doImage3DLevelCount(id);
if(!levelCount) {
Error{} << "Trade::AbstractImporter::image3D(): image reported zero levels";
return {};
}
CORRADE_ASSERT(level < levelCount, "Trade::AbstractImporter::image3D(): level out of range", {});
}
#endif
return doImage3D(id, level);
}

Containers::Optional<ImageData3D> AbstractImporter::doImage3D(UnsignedInt) {
Containers::Optional<ImageData3D> AbstractImporter::doImage3D(UnsignedInt, UnsignedInt) {
CORRADE_ASSERT(false, "Trade::AbstractImporter::image3D(): not implemented", {});
}

Expand Down
88 changes: 77 additions & 11 deletions src/Magnum/Trade/AbstractImporter.h
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,7 @@ checked by the implementation:
- All `do*()` implementations working on an opened file are called only if
there is any file opened.
- All `do*()` implementations taking data ID as parameter are called only if
the ID is from valid range.
the IDs are from valid range.
@attention
@ref Corrade::Containers::Array instances returned from the plugin
Expand Down Expand Up @@ -234,7 +234,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
* @brief Plugin interface
*
* @code{.cpp}
* "cz.mosra.magnum.Trade.AbstractImporter/0.3"
* "cz.mosra.magnum.Trade.AbstractImporter/0.3.1"
* @endcode
*/
static std::string pluginInterface();
Expand Down Expand Up @@ -762,9 +762,19 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
* @brief One-dimensional image count
*
* Expects that a file is opened.
* @see @ref image1DLevelCount()
*/
UnsignedInt image1DCount() const;

/**
* @brief One-dimensional image mip level count
* @param id Image ID, from range [0, @ref image1DCount())
*
* Returns at least one level in successful cases, zero on failure.
* Expects that a file is opened.
*/
UnsignedInt image1DLevelCount(UnsignedInt id);

/**
* @brief One-dimensional image ID for given name
*
Expand All @@ -786,19 +796,34 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/**
* @brief One-dimensional image
* @param id Image ID, from range [0, @ref image1DCount()).
* @param level Mip level, from range [0, @ref image1DLevelCount())
*
* Returns given image or @ref Containers::NullOpt if importing failed.
* Expects that a file is opened.
* Expects that a file is opened. Non-zero @p level values are checked
* against @ref image1DLevelCount() unless Magnum is built with
* @ref CORRADE_NO_ASSERT. If reported level count is zero, this
* function returns @ref Containers::NullOpt as well, indicating
* an import error.
*/
Containers::Optional<ImageData1D> image1D(UnsignedInt id);
Containers::Optional<ImageData1D> image1D(UnsignedInt id, UnsignedInt level = 0);

/**
* @brief Two-dimensional image count
*
* Expects that a file is opened.
* @see @ref image2DLevelCount()
*/
UnsignedInt image2DCount() const;

/**
* @brief Two-dimensional image mip level count
* @param id Image ID, from range [0, @ref image2DCount()).
*
* Returns at least one level in successful cases, zero on failure.
* Expects that a file is opened.
*/
UnsignedInt image2DLevelCount(UnsignedInt id);

/**
* @brief Two-dimensional image ID for given name
*
Expand All @@ -820,19 +845,34 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/**
* @brief Two-dimensional image
* @param id Image ID, from range [0, @ref image2DCount()).
* @param level Mip level, from range [0, @ref image2DLevelCount())
*
* Returns given image or @ref Containers::NullOpt if importing failed.
* Expects that a file is opened.
* Expects that a file is opened. Non-zero @p level values are checked
* against @ref image2DLevelCount() unless Magnum is built with
* @ref CORRADE_NO_ASSERT. If reported level count is zero, this
* function returns @ref Containers::NullOpt as well, indicating
* an import error.
*/
Containers::Optional<ImageData2D> image2D(UnsignedInt id);
Containers::Optional<ImageData2D> image2D(UnsignedInt id, UnsignedInt level = 0);

/**
* @brief Three-dimensional image count
*
* Expects that a file is opened.
* @see @ref image3DLevelCount()
*/
UnsignedInt image3DCount() const;

/**
* @brief Three-dimensional image mip level count
* @param id Image ID, from range [0, @ref image3DCount())
*
* Returns at least one level in successful cases, zero on failure.
* Expects that a file is opened.
*/
UnsignedInt image3DLevelCount(UnsignedInt id);

/**
* @brief Three-dimensional image ID for given name
*
Expand All @@ -854,11 +894,16 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
/**
* @brief Three-dimensional image
* @param id Image ID, from range [0, @ref image3DCount()).
* @param level Mip level, from range [0, @ref image3DLevelCount())
*
* Returns given image or @ref Containers::NullOpt if importing failed.
* Expects that a file is opened.
* Expects that a file is opened. Non-zero @p level values are checked
* against @ref image3DLevelCount() unless Magnum is built with
* @ref CORRADE_NO_ASSERT. If reported level count is zero, this
* function returns @ref Containers::NullOpt as well, indicating
* an import error.
*/
Containers::Optional<ImageData3D> image3D(UnsignedInt id);
Containers::Optional<ImageData3D> image3D(UnsignedInt id, UnsignedInt level = 0);

/*@}*/

Expand Down Expand Up @@ -1176,6 +1221,13 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
*/
virtual UnsignedInt doImage1DCount() const;

/**
* @brief Implementation for @ref image1DLevelCount()
*
* Default implementation returns @cpp 1 @ce.
*/
virtual UnsignedInt doImage1DLevelCount(UnsignedInt id);

/**
* @brief Implementation for @ref image1DForName()
*
Expand All @@ -1191,7 +1243,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
virtual std::string doImage1DName(UnsignedInt id);

/** @brief Implementation for @ref image1D() */
virtual Containers::Optional<ImageData1D> doImage1D(UnsignedInt id);
virtual Containers::Optional<ImageData1D> doImage1D(UnsignedInt id, UnsignedInt level);

/**
* @brief Implementation for @ref image2DCount()
Expand All @@ -1200,6 +1252,13 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
*/
virtual UnsignedInt doImage2DCount() const;

/**
* @brief Implementation for @ref image2DLevelCount()
*
* Default implementation returns @cpp 1 @ce.
*/
virtual UnsignedInt doImage2DLevelCount(UnsignedInt id);

/**
* @brief Implementation for @ref image2DForName()
*
Expand All @@ -1215,7 +1274,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
virtual std::string doImage2DName(UnsignedInt id);

/** @brief Implementation for @ref image2D() */
virtual Containers::Optional<ImageData2D> doImage2D(UnsignedInt id);
virtual Containers::Optional<ImageData2D> doImage2D(UnsignedInt id, UnsignedInt level);

/**
* @brief Implementation for @ref image3DCount()
Expand All @@ -1224,6 +1283,13 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
*/
virtual UnsignedInt doImage3DCount() const;

/**
* @brief Implementation for @ref image3DLevelCount()
*
* Default implementation returns @cpp 1 @ce.
*/
virtual UnsignedInt doImage3DLevelCount(UnsignedInt id);

/**
* @brief Implementation for @ref image3DForName()
*
Expand All @@ -1239,7 +1305,7 @@ class MAGNUM_TRADE_EXPORT AbstractImporter: public PluginManager::AbstractManagi
virtual std::string doImage3DName(UnsignedInt id);

/** @brief Implementation for @ref image3D() */
virtual Containers::Optional<ImageData3D> doImage3D(UnsignedInt id);
virtual Containers::Optional<ImageData3D> doImage3D(UnsignedInt id, UnsignedInt level);

/** @brief Implementation for @ref importerState() */
virtual const void* doImporterState() const;
Expand Down
Loading

0 comments on commit f9844bb

Please sign in to comment.