mirror of https://github.com/mosra/magnum.git
50 changed files with 2704 additions and 0 deletions
@ -0,0 +1,58 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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 Text) |
||||||
|
|
||||||
|
set(MagnumFont_SOURCES |
||||||
|
MagnumFont.cpp) |
||||||
|
|
||||||
|
set(MagnumFont_HEADERS |
||||||
|
MagnumFont.h) |
||||||
|
|
||||||
|
add_library(MagnumFontObjects OBJECT ${MagnumFont_SOURCES}) |
||||||
|
set_target_properties(MagnumFontObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") |
||||||
|
|
||||||
|
add_plugin(MagnumFont ${MAGNUM_PLUGINS_FONT_INSTALL_DIR} |
||||||
|
MagnumFont.conf |
||||||
|
$<TARGET_OBJECTS:MagnumFontObjects> |
||||||
|
pluginRegistrationMagnumFont.cpp) |
||||||
|
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 STATIC $<TARGET_OBJECTS:MagnumFontObjects>) |
||||||
|
target_link_libraries(MagnumFontTestLib |
||||||
|
${MAGNUM_LIBRARIES} |
||||||
|
${MAGNUM_TEXT_LIBRARIES} |
||||||
|
TgaImporterTestLib) |
||||||
|
|
||||||
|
add_subdirectory(Test) |
||||||
|
endif() |
||||||
@ -0,0 +1,238 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "MagnumFont.h" |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <Utility/Directory.h> |
||||||
|
#include <Utility/Unicode.h> |
||||||
|
#include <Text/GlyphCache.h> |
||||||
|
#include <Trade/ImageData.h> |
||||||
|
|
||||||
|
#include "TgaImporter/TgaImporter.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Text { |
||||||
|
|
||||||
|
struct MagnumFont::Data { |
||||||
|
Utility::Configuration conf; |
||||||
|
Trade::ImageData2D image; |
||||||
|
std::unordered_map<char32_t, UnsignedInt> glyphId; |
||||||
|
std::vector<Vector2> glyphAdvance; |
||||||
|
}; |
||||||
|
|
||||||
|
namespace { |
||||||
|
class MagnumFontLayouter: public AbstractLayouter { |
||||||
|
public: |
||||||
|
explicit MagnumFontLayouter(const std::unordered_map<char32_t, UnsignedInt>& glyphId, const std::vector<Vector2>& glyphAdvance, const GlyphCache& cache, Float fontSize, Float textSize, const std::string& text); |
||||||
|
|
||||||
|
std::tuple<Rectangle, Rectangle, Vector2> renderGlyph(UnsignedInt i) override; |
||||||
|
|
||||||
|
private: |
||||||
|
const std::vector<Vector2>& glyphAdvance; |
||||||
|
const GlyphCache& cache; |
||||||
|
const Float fontSize, textSize; |
||||||
|
std::vector<UnsignedInt> glyphs; |
||||||
|
}; |
||||||
|
} |
||||||
|
|
||||||
|
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; } |
||||||
|
|
||||||
|
void MagnumFont::doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, const Float) { |
||||||
|
/* We need just the configuration file and image file */ |
||||||
|
if(data.size() != 2) { |
||||||
|
Error() << "Text::MagnumFont::openData(): wanted two files, got" << data.size(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Open the configuration file */ |
||||||
|
std::istringstream in({reinterpret_cast<const char*>(data[0].second.begin()), data[0].second.size()}); |
||||||
|
Utility::Configuration conf(in, Utility::Configuration::Flag::SkipComments); |
||||||
|
if(!conf.isValid() || conf.isEmpty()) { |
||||||
|
Error() << "Text::MagnumFont::openData(): cannot open file" << data[0].first << conf.isValid(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check version */ |
||||||
|
if(conf.value<UnsignedInt>("version") != 1) { |
||||||
|
Error() << "Text::MagnumFont::openData(): unsupported file version, expected 1 but got" |
||||||
|
<< conf.value<UnsignedInt>("version"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check that we have also the image file */ |
||||||
|
if(conf.value("image") != data[1].first) { |
||||||
|
Error() << "Text::MagnumFont::openData(): expected file" |
||||||
|
<< conf.value("image") << "but got" << data[1].first; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Open and load image file */ |
||||||
|
Trade::TgaImporter importer; |
||||||
|
if(!importer.openData(data[1].second)) { |
||||||
|
Error() << "Text::MagnumFont::openData(): cannot open image file"; |
||||||
|
return; |
||||||
|
} |
||||||
|
std::optional<Trade::ImageData2D> image = importer.image2D(0); |
||||||
|
if(!image) { |
||||||
|
Error() << "Text::MagnumFont::openData(): cannot load image file"; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
openInternal(std::move(conf), std::move(*image)); |
||||||
|
} |
||||||
|
|
||||||
|
void MagnumFont::doOpenFile(const std::string& filename, Float) { |
||||||
|
/* Open the configuration file */ |
||||||
|
Utility::Configuration conf(filename, Utility::Configuration::Flag::ReadOnly|Utility::Configuration::Flag::SkipComments); |
||||||
|
if(!conf.isValid() || conf.isEmpty()) { |
||||||
|
Error() << "Text::MagnumFont::openFile(): cannot open file" << filename << conf.isValid(); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Check version */ |
||||||
|
if(conf.value<UnsignedInt>("version") != 1) { |
||||||
|
Error() << "Text::MagnumFont::openFile(): unsupported file version, expected 1 but got" |
||||||
|
<< conf.value<UnsignedInt>("version"); |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
/* Open and load image file */ |
||||||
|
const std::string imageFilename = Utility::Directory::join(Utility::Directory::path(filename), conf.value("image")); |
||||||
|
Trade::TgaImporter importer; |
||||||
|
if(!importer.openFile(imageFilename)) { |
||||||
|
Error() << "Text::MagnumFont::openFile(): cannot open image file" << imageFilename; |
||||||
|
return; |
||||||
|
} |
||||||
|
std::optional<Trade::ImageData2D> image = importer.image2D(0); |
||||||
|
if(!image) { |
||||||
|
Error() << "Text::MagnumFont::openFile(): cannot load image file"; |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
openInternal(std::move(conf), std::move(*image)); |
||||||
|
} |
||||||
|
|
||||||
|
void MagnumFont::openInternal(Utility::Configuration&& conf, Trade::ImageData2D&& image) { |
||||||
|
/* Everything okay, save the data internally */ |
||||||
|
_opened = new Data{std::move(conf), std::move(image), {}, {}}; |
||||||
|
_size = _opened->conf.value<Float>("fontSize"); |
||||||
|
|
||||||
|
/* Glyph advances */ |
||||||
|
const std::vector<Utility::ConfigurationGroup*> glyphs = _opened->conf.groups("glyph"); |
||||||
|
_opened->glyphAdvance.reserve(glyphs.size()); |
||||||
|
for(const Utility::ConfigurationGroup* const g: glyphs) |
||||||
|
_opened->glyphAdvance.push_back(g->value<Vector2>("advance")); |
||||||
|
|
||||||
|
/* Fill character->glyph map */ |
||||||
|
const std::vector<Utility::ConfigurationGroup*> chars = _opened->conf.groups("char"); |
||||||
|
for(const Utility::ConfigurationGroup* const c: chars) { |
||||||
|
const UnsignedInt glyphId = c->value<UnsignedInt>("glyph"); |
||||||
|
CORRADE_INTERNAL_ASSERT(glyphId < _opened->glyphAdvance.size()); |
||||||
|
_opened->glyphId.emplace(c->value<char32_t>("unicode"), glyphId); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void MagnumFont::doClose() { |
||||||
|
delete _opened; |
||||||
|
_opened = nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
UnsignedInt MagnumFont::doGlyphId(const char32_t character) { |
||||||
|
auto it = _opened->glyphId.find(character); |
||||||
|
return it != _opened->glyphId.end() ? it->second : 0; |
||||||
|
} |
||||||
|
|
||||||
|
Vector2 MagnumFont::doGlyphAdvance(const UnsignedInt glyph) { |
||||||
|
return glyph < _opened->glyphAdvance.size() ? _opened->glyphAdvance[glyph] : Vector2(); |
||||||
|
} |
||||||
|
|
||||||
|
GlyphCache* MagnumFont::doCreateGlyphCache() { |
||||||
|
/* Set cache image */ |
||||||
|
auto cache = new Text::GlyphCache( |
||||||
|
_opened->conf.value<Vector2i>("originalImageSize"), |
||||||
|
_opened->image.size(), |
||||||
|
_opened->conf.value<Vector2i>("padding")); |
||||||
|
cache->setImage({}, _opened->image); |
||||||
|
|
||||||
|
/* Fill glyph map */ |
||||||
|
const std::vector<Utility::ConfigurationGroup*> glyphs = _opened->conf.groups("glyph"); |
||||||
|
for(std::size_t i = 0; i != glyphs.size(); ++i) |
||||||
|
cache->insert(i, glyphs[i]->value<Vector2i>("position"), glyphs[i]->value<Rectanglei>("rectangle")); |
||||||
|
|
||||||
|
return cache; |
||||||
|
} |
||||||
|
|
||||||
|
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<char32_t, UnsignedInt>& glyphId, const std::vector<Vector2>& 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(); ) { |
||||||
|
UnsignedInt codepoint; |
||||||
|
std::tie(codepoint, i) = Utility::Unicode::nextChar(text, i); |
||||||
|
const auto it = glyphId.find(codepoint); |
||||||
|
glyphs.push_back(it == glyphId.end() ? 0 : it->second); |
||||||
|
} |
||||||
|
_glyphCount = glyphs.size(); |
||||||
|
} |
||||||
|
|
||||||
|
std::tuple<Rectangle, Rectangle, Vector2> MagnumFontLayouter::renderGlyph(UnsignedInt i) { |
||||||
|
/* Position of the texture in the resulting glyph, texture coordinates */ |
||||||
|
Vector2i position; |
||||||
|
Rectanglei rectangle; |
||||||
|
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())/Vector2(cache.textureSize()), |
||||||
|
Vector2(rectangle.topRight())/Vector2(cache.textureSize())); |
||||||
|
|
||||||
|
/* Absolute quad position, composed from cursor position, glyph offset
|
||||||
|
and texture position, denormalized to requested text size */ |
||||||
|
Rectangle quadPosition = Rectangle::fromSize( |
||||||
|
Vector2(texturePosition.left(), texturePosition.bottom())*textSize, |
||||||
|
texturePosition.size()*textSize); |
||||||
|
|
||||||
|
/* Advance for given glyph, denormalized to requested text size */ |
||||||
|
const Vector2 advance = glyphAdvance[glyphs[i]]*textSize/fontSize; |
||||||
|
|
||||||
|
return std::make_tuple(quadPosition, textureCoordinates, advance); |
||||||
|
} |
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,140 @@ |
|||||||
|
#ifndef Magnum_Text_MagnumFont_h |
||||||
|
#define Magnum_Text_MagnumFont_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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::Text::MagnumFont |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Text/AbstractFont.h> |
||||||
|
#include <Trade/Trade.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Text { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief Simple bitmap font plugin |
||||||
|
|
||||||
|
This plugin depends on @ref Trade::TgaImporter "TgaImporter" plugin and is |
||||||
|
built if `WITH_MAGNUMFONT` is enabled in CMake. To use dynamic plugin, you need |
||||||
|
to load `%MagnumFont` plugin from `fonts/` subdirectory of your plugin dir. To |
||||||
|
use static plugin or use this as a dependency of another plugin, you need to |
||||||
|
request `%MagnumFont` component in CMake and link to |
||||||
|
`${MAGNUMPLUGINS_MAGNUMFONT_LIBRARIES}`. See @ref building-plugins and |
||||||
|
@ref cmake-plugins for more information. |
||||||
|
|
||||||
|
The font consists of two files, one text file containing character and glyph |
||||||
|
info and one TGA file containing the glyphs in distance field format. The font |
||||||
|
can be conveniently created from any other format using MagnumFontConverter. |
||||||
|
The file syntax is as in following: |
||||||
|
|
||||||
|
# Font image filename |
||||||
|
image=font.tga |
||||||
|
|
||||||
|
# Size of unscaled font image |
||||||
|
originalImageSize=1536 1536 |
||||||
|
|
||||||
|
# Glyph padding |
||||||
|
padding=9 |
||||||
|
|
||||||
|
# Font size |
||||||
|
fontSize=128 |
||||||
|
|
||||||
|
# Character |
||||||
|
[char] |
||||||
|
|
||||||
|
# UTF-32 codepoint ('a') |
||||||
|
unicode=0061 |
||||||
|
|
||||||
|
# Glyph ID |
||||||
|
glyph=1 |
||||||
|
|
||||||
|
# Advance to next character in pixels (i.e. on unscaled font image) |
||||||
|
advance=45 0 |
||||||
|
|
||||||
|
# Another character |
||||||
|
[char] |
||||||
|
unicode=0062 |
||||||
|
glyph=2 |
||||||
|
advance=42 0 |
||||||
|
|
||||||
|
# ... |
||||||
|
|
||||||
|
# Glyph 0, a.k.a. "Not Found" glyph |
||||||
|
[glyph] |
||||||
|
|
||||||
|
# Glyph texture position relative to baseline, in pixels |
||||||
|
position=5 -1 |
||||||
|
|
||||||
|
# Glyph rectangle in font image, in pixels (left, bottom, right, top) |
||||||
|
rectangle=0 0 42 25 |
||||||
|
|
||||||
|
# Glyph 1 |
||||||
|
[glyph] |
||||||
|
position=0 0 |
||||||
|
rectangle=45 0 44 25 |
||||||
|
|
||||||
|
# ... |
||||||
|
|
||||||
|
@see Trade::TgaImporter |
||||||
|
*/ |
||||||
|
class MagnumFont: public AbstractFont { |
||||||
|
public: |
||||||
|
/** @brief Default constructor */ |
||||||
|
explicit MagnumFont(); |
||||||
|
|
||||||
|
/** @brief Plugin manager constructor */ |
||||||
|
explicit MagnumFont(PluginManager::AbstractManager* manager, std::string plugin); |
||||||
|
|
||||||
|
~MagnumFont(); |
||||||
|
|
||||||
|
private: |
||||||
|
struct Data; |
||||||
|
|
||||||
|
Features doFeatures() const override; |
||||||
|
|
||||||
|
bool doIsOpened() const override; |
||||||
|
|
||||||
|
void doOpenData(const std::vector<std::pair<std::string, Containers::ArrayReference<const unsigned char>>>& data, Float) override; |
||||||
|
|
||||||
|
void doOpenFile(const std::string& filename, Float) override; |
||||||
|
|
||||||
|
void doClose() override; |
||||||
|
|
||||||
|
UnsignedInt doGlyphId(char32_t character) override; |
||||||
|
|
||||||
|
Vector2 doGlyphAdvance(UnsignedInt glyph) override; |
||||||
|
|
||||||
|
GlyphCache* doCreateGlyphCache() override; |
||||||
|
|
||||||
|
AbstractLayouter* doLayout(const GlyphCache& cache, Float size, const std::string& text) override; |
||||||
|
|
||||||
|
Data* _opened; |
||||||
|
|
||||||
|
void openInternal(Utility::Configuration&& conf, Trade::ImageData2D&& image); |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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}/magnumFontTestConfigure.h.cmake |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/magnumFontTestConfigure.h) |
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}) |
||||||
|
|
||||||
|
corrade_add_test(MagnumFontTest MagnumFontTest.cpp LIBRARIES MagnumFontTestLib ${GL_TEST_LIBRARIES}) |
||||||
@ -0,0 +1,105 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <Test/AbstractOpenGLTester.h> |
||||||
|
#include <Text/GlyphCache.h> |
||||||
|
#include <Utility/Directory.h> |
||||||
|
|
||||||
|
#include "MagnumFont/MagnumFont.h" |
||||||
|
|
||||||
|
#include "magnumFontTestConfigure.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Text { namespace Test { |
||||||
|
|
||||||
|
class MagnumFontTest: public Magnum::Test::AbstractOpenGLTester { |
||||||
|
public: |
||||||
|
explicit MagnumFontTest(); |
||||||
|
|
||||||
|
void properties(); |
||||||
|
void layout(); |
||||||
|
void createGlyphCache(); |
||||||
|
}; |
||||||
|
|
||||||
|
MagnumFontTest::MagnumFontTest() { |
||||||
|
addTests({&MagnumFontTest::properties, |
||||||
|
&MagnumFontTest::layout, |
||||||
|
&MagnumFontTest::createGlyphCache}); |
||||||
|
} |
||||||
|
|
||||||
|
void MagnumFontTest::properties() { |
||||||
|
MagnumFont font; |
||||||
|
CORRADE_VERIFY(font.openFile(Utility::Directory::join(MAGNUMFONT_TEST_DIR, "font.conf"), 0.0f)); |
||||||
|
CORRADE_COMPARE(font.size(), 16.0f); |
||||||
|
CORRADE_COMPARE(font.glyphAdvance(font.glyphId(U'W')), Vector2(23.0f, 0.0f)); |
||||||
|
} |
||||||
|
|
||||||
|
void MagnumFontTest::layout() { |
||||||
|
MagnumFont font; |
||||||
|
CORRADE_VERIFY(font.openFile(Utility::Directory::join(MAGNUMFONT_TEST_DIR, "font.conf"), 0.0f)); |
||||||
|
|
||||||
|
/* Fill the cache with some fake glyphs */ |
||||||
|
GlyphCache cache(Vector2i(256)); |
||||||
|
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"); |
||||||
|
CORRADE_VERIFY(layouter); |
||||||
|
CORRADE_COMPARE(layouter->glyphCount(), 4); |
||||||
|
|
||||||
|
Rectangle position; |
||||||
|
Rectangle textureCoordinates; |
||||||
|
Vector2 advance; |
||||||
|
|
||||||
|
/* 'W' */ |
||||||
|
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(0); |
||||||
|
CORRADE_COMPARE(position, Rectangle({0.78125f, 1.0625f}, {1.28125f, 4.8125f})); |
||||||
|
CORRADE_COMPARE(textureCoordinates, Rectangle({0, 0.03125f}, {0.0625f, 0.5f})); |
||||||
|
CORRADE_COMPARE(advance, Vector2(0.71875f, 0.0f)); |
||||||
|
|
||||||
|
/* 'a' (not found) */ |
||||||
|
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(1); |
||||||
|
CORRADE_COMPARE(position, Rectangle()); |
||||||
|
CORRADE_COMPARE(textureCoordinates, Rectangle()); |
||||||
|
CORRADE_COMPARE(advance, Vector2(0.25f, 0.0f)); |
||||||
|
|
||||||
|
/* 'v' (not found) */ |
||||||
|
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(2); |
||||||
|
CORRADE_COMPARE(position, Rectangle()); |
||||||
|
CORRADE_COMPARE(textureCoordinates, Rectangle()); |
||||||
|
CORRADE_COMPARE(advance, Vector2(0.25f, 0.0f)); |
||||||
|
|
||||||
|
/* 'e' */ |
||||||
|
std::tie(position, textureCoordinates, advance) = layouter->renderGlyph(3); |
||||||
|
CORRADE_COMPARE(position, Rectangle({0.78125f, 0.375f}, {2.28125f, 1.25f})); |
||||||
|
CORRADE_COMPARE(textureCoordinates, Rectangle({0.0625f, 0.015625f}, {0.25f, 0.125f})); |
||||||
|
CORRADE_COMPARE(advance, Vector2(0.375f, 0.0f)); |
||||||
|
} |
||||||
|
|
||||||
|
void MagnumFontTest::createGlyphCache() { |
||||||
|
/** @todo */ |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Text::Test::MagnumFontTest) |
||||||
@ -0,0 +1,29 @@ |
|||||||
|
version=1 |
||||||
|
image=font.tga |
||||||
|
originalImageSize=1536 1536 |
||||||
|
padding=24 24 |
||||||
|
fontSize=16 |
||||||
|
[char] |
||||||
|
unicode=57 |
||||||
|
glyph=2 |
||||||
|
[char] |
||||||
|
unicode=61 |
||||||
|
glyph=0 |
||||||
|
[char] |
||||||
|
unicode=65 |
||||||
|
glyph=1 |
||||||
|
[char] |
||||||
|
unicode=76 |
||||||
|
glyph=0 |
||||||
|
[glyph] |
||||||
|
advance=8 0 |
||||||
|
position=24 24 |
||||||
|
rectangle=24 24 -24 -24 |
||||||
|
[glyph] |
||||||
|
advance=12 0 |
||||||
|
position=25 12 |
||||||
|
rectangle=16 4 64 32 |
||||||
|
[glyph] |
||||||
|
advance=23 0 |
||||||
|
position=25 34 |
||||||
|
rectangle=0 8 16 128 |
||||||
Binary file not shown.
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 MAGNUMFONT_TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}" |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "MagnumFont/MagnumFont.h" |
||||||
|
|
||||||
|
CORRADE_PLUGIN_REGISTER(MagnumFont, Magnum::Text::MagnumFont, |
||||||
|
"cz.mosra.magnum.Text.AbstractFont/0.2") |
||||||
@ -0,0 +1,57 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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 Text) |
||||||
|
|
||||||
|
set(MagnumFontConverter_SOURCES |
||||||
|
MagnumFontConverter.cpp) |
||||||
|
|
||||||
|
set(MagnumFontConverter_HEADERS |
||||||
|
MagnumFontConverter.h) |
||||||
|
|
||||||
|
add_library(MagnumFontConverterObjects OBJECT ${MagnumFontConverter_SOURCES}) |
||||||
|
set_target_properties(MagnumFontConverterObjects PROPERTIES COMPILE_FLAGS "${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") |
||||||
|
|
||||||
|
add_plugin(MagnumFontConverter ${MAGNUM_PLUGINS_FONTCONVERTER_INSTALL_DIR} |
||||||
|
MagnumFontConverter.conf |
||||||
|
$<TARGET_OBJECTS:MagnumFontConverterObjects> |
||||||
|
pluginRegistrationMagnumFontConverter.cpp) |
||||||
|
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_GL_TESTS) |
||||||
|
add_library(MagnumFontConverterTestLib STATIC $<TARGET_OBJECTS:MagnumFontConverterObjects>) |
||||||
|
target_link_libraries(MagnumFontConverterTestLib |
||||||
|
${MAGNUM_LIBRARIES} |
||||||
|
${MAGNUM_TEXT_LIBRARIES} |
||||||
|
TgaImageConverterTestLib) |
||||||
|
add_subdirectory(Test) |
||||||
|
endif() |
||||||
@ -0,0 +1 @@ |
|||||||
|
depends=TgaImageConverter |
||||||
@ -0,0 +1,115 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "MagnumFontConverter.h" |
||||||
|
|
||||||
|
#include <sstream> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <Utility/Directory.h> |
||||||
|
#include <ColorFormat.h> |
||||||
|
#include <Image.h> |
||||||
|
#include <Text/GlyphCache.h> |
||||||
|
#include <Text/AbstractFont.h> |
||||||
|
#include <TgaImageConverter/TgaImageConverter.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Text { |
||||||
|
|
||||||
|
MagnumFontConverter::MagnumFontConverter() = default; |
||||||
|
|
||||||
|
MagnumFontConverter::MagnumFontConverter(PluginManager::AbstractManager* manager, std::string plugin): AbstractFontConverter(manager, std::move(plugin)) {} |
||||||
|
|
||||||
|
auto MagnumFontConverter::doFeatures() const -> Features { |
||||||
|
return Feature::ExportFont|Feature::ConvertData|Feature::MultiFile; |
||||||
|
} |
||||||
|
|
||||||
|
#ifndef _WIN32 |
||||||
|
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const |
||||||
|
#else |
||||||
|
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> MagnumFontConverter::doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const |
||||||
|
#endif |
||||||
|
{ |
||||||
|
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()); |
||||||
|
|
||||||
|
/* Compress glyph IDs so the glyphs are in consecutive array, glyph 0
|
||||||
|
should stay at position 0 */ |
||||||
|
std::unordered_map<UnsignedInt, UnsignedInt> glyphIdMap; |
||||||
|
glyphIdMap.reserve(cache.glyphCount()); |
||||||
|
glyphIdMap.emplace(0, 0); |
||||||
|
for(const std::pair<UnsignedInt, std::pair<Vector2i, Rectanglei>>& glyph: cache) |
||||||
|
glyphIdMap.emplace(glyph.first, glyphIdMap.size()); |
||||||
|
|
||||||
|
/** @todo Save only glyphs contained in @p characters */ |
||||||
|
|
||||||
|
/* Inverse map from new glyph IDs to old ones */ |
||||||
|
std::vector<UnsignedInt> inverseGlyphIdMap(glyphIdMap.size()); |
||||||
|
for(const std::pair<UnsignedInt, UnsignedInt>& map: glyphIdMap) |
||||||
|
inverseGlyphIdMap[map.second] = map.first; |
||||||
|
|
||||||
|
/* 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); |
||||||
|
group->setValue("unicode", c); |
||||||
|
|
||||||
|
/* Map old glyph ID to new, if not found, map to glyph 0 */ |
||||||
|
auto found = glyphIdMap.find(glyphId); |
||||||
|
group->setValue("glyph", found == glyphIdMap.end() ? 0 : glyphIdMap.at(glyphId)); |
||||||
|
} |
||||||
|
|
||||||
|
/* Save glyph properties in order which preserves their IDs, remove padding
|
||||||
|
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<Vector2i, Rectanglei> 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())); |
||||||
|
} |
||||||
|
|
||||||
|
std::ostringstream confOut; |
||||||
|
configuration.save(confOut); |
||||||
|
std::string confStr = confOut.str(); |
||||||
|
Containers::Array<unsigned char> confData{confStr.size()}; |
||||||
|
std::copy(confStr.begin(), confStr.end(), confData.begin()); |
||||||
|
|
||||||
|
/* Save cache image */ |
||||||
|
Image2D image(ColorFormat::Red, ColorType::UnsignedByte); |
||||||
|
cache.texture().image(0, image); |
||||||
|
auto tgaData = Trade::TgaImageConverter().exportToData(image); |
||||||
|
|
||||||
|
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> out; |
||||||
|
out.emplace_back(filename + ".conf", std::move(confData)); |
||||||
|
out.emplace_back(filename + ".tga", std::move(tgaData)); |
||||||
|
return std::move(out); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,70 @@ |
|||||||
|
#ifndef Magnum_Text_MagnumFontConverter_h |
||||||
|
#define Magnum_Text_MagnumFontConverter_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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::Text::MagnumFontConverter |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Text/AbstractFontConverter.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Text { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief MagnumFont converter plugin |
||||||
|
|
||||||
|
Expects filename prefix, creates two files, `prefix.conf` and `prefix.tga`. See |
||||||
|
@ref MagnumFont for more information about the font. |
||||||
|
|
||||||
|
This plugin is available only on desktop OpenGL, as it uses @ref Texture::image() |
||||||
|
to read back the generated data. It depends on |
||||||
|
@ref Trade::TgaImageConverter "TgaImageConverter" plugin and is built if |
||||||
|
`WITH_MAGNUMFONTCONVERTER` is enabled in CMake. To use dynamic plugin, you need |
||||||
|
to load `%MagnumFontConverter` plugin from `fontconverters/` subdirectory of |
||||||
|
your plugin dir. To use static plugin or use this as a dependency of another |
||||||
|
plugin, you need to request `%MagnumFontConverter` component in CMake and link |
||||||
|
to `${MAGNUMPLUGINS_MAGNUMFONTCONVERTER_LIBRARIES}`. See @ref building-plugins |
||||||
|
and @ref cmake-plugins for more information. |
||||||
|
*/ |
||||||
|
class MagnumFontConverter: public Text::AbstractFontConverter { |
||||||
|
public: |
||||||
|
/** @brief Default constructor */ |
||||||
|
explicit MagnumFontConverter(); |
||||||
|
|
||||||
|
/** @brief Plugin manager constructor */ |
||||||
|
explicit MagnumFontConverter(PluginManager::AbstractManager* manager, std::string plugin); |
||||||
|
|
||||||
|
private: |
||||||
|
Features doFeatures() const override; |
||||||
|
#ifndef _WIN32 |
||||||
|
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::u32string& characters) const override; |
||||||
|
#else |
||||||
|
std::vector<std::pair<std::string, Containers::Array<unsigned char>>> doExportFontToData(AbstractFont& font, GlyphCache& cache, const std::string& filename, const std::vector<char32_t>& characters) const override; |
||||||
|
#endif |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,36 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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}/magnumFontConverterTestConfigure.h.cmake |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/magnumFontConverterTestConfigure.h) |
||||||
|
|
||||||
|
include_directories(${CMAKE_CURRENT_BINARY_DIR}/../../FreeTypeFont/Test/ |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}/../../MagnumFont/Test/ |
||||||
|
${CMAKE_CURRENT_BINARY_DIR}) |
||||||
|
|
||||||
|
corrade_add_test(MagnumFontConverterTest MagnumFontConverterTest.cpp LIBRARIES |
||||||
|
MagnumFontConverterTestLib |
||||||
|
FreeTypeFontTestLib |
||||||
|
TgaImporterTestLib |
||||||
|
${GL_TEST_LIBRARIES}) |
||||||
@ -0,0 +1,100 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <Utility/Directory.h> |
||||||
|
#include <TestSuite/Compare/File.h> |
||||||
|
#include <ColorFormat.h> |
||||||
|
#include <Extensions.h> |
||||||
|
#include <TextureFormat.h> |
||||||
|
#include <Test/AbstractOpenGLTester.h> |
||||||
|
#include <Text/GlyphCache.h> |
||||||
|
#include <Trade/ImageData.h> |
||||||
|
|
||||||
|
#include "FreeTypeFont/FreeTypeFont.h" |
||||||
|
#include "MagnumFontConverter/MagnumFontConverter.h" |
||||||
|
#include "TgaImporter/TgaImporter.h" |
||||||
|
|
||||||
|
#include "freeTypeFontTestConfigure.h" |
||||||
|
#include "magnumFontTestConfigure.h" |
||||||
|
#include "magnumFontConverterTestConfigure.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Text { namespace Test { |
||||||
|
|
||||||
|
class MagnumFontConverterTest: public Magnum::Test::AbstractOpenGLTester { |
||||||
|
public: |
||||||
|
explicit MagnumFontConverterTest(); |
||||||
|
|
||||||
|
~MagnumFontConverterTest(); |
||||||
|
|
||||||
|
void exportFont(); |
||||||
|
}; |
||||||
|
|
||||||
|
MagnumFontConverterTest::MagnumFontConverterTest() { |
||||||
|
addTests({&MagnumFontConverterTest::exportFont}); |
||||||
|
|
||||||
|
FreeTypeFont::initialize(); |
||||||
|
} |
||||||
|
|
||||||
|
MagnumFontConverterTest::~MagnumFontConverterTest() { |
||||||
|
FreeTypeFont::finalize(); |
||||||
|
} |
||||||
|
|
||||||
|
void MagnumFontConverterTest::exportFont() { |
||||||
|
/* Remove previously created files */ |
||||||
|
Utility::Directory::rm(Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font.conf")); |
||||||
|
Utility::Directory::rm(Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font.tga")); |
||||||
|
|
||||||
|
/* Open font */ |
||||||
|
FreeTypeFont font; |
||||||
|
CORRADE_VERIFY(font.openFile(Utility::Directory::join(FREETYPEFONT_TEST_DIR, "Oxygen.ttf"), 16.0f)); |
||||||
|
|
||||||
|
/* Create fake cache */ |
||||||
|
MAGNUM_ASSERT_EXTENSION_SUPPORTED(Extensions::GL::ARB::texture_rg); |
||||||
|
GlyphCache cache(TextureFormat::R8, Vector2i(1536), Vector2i(256), Vector2i(24)); |
||||||
|
cache.insert(font.glyphId(U'W'), {25, 34}, {{0, 8}, {16, 128}}); |
||||||
|
cache.insert(font.glyphId(U'e'), {25, 12}, {{16, 4}, {64, 32}}); |
||||||
|
|
||||||
|
/* Convert the file */ |
||||||
|
MagnumFontConverter converter; |
||||||
|
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 */ |
||||||
|
CORRADE_COMPARE_AS(Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font.conf"), |
||||||
|
Utility::Directory::join(MAGNUMFONT_TEST_DIR, "font.conf"), |
||||||
|
TestSuite::Compare::File); |
||||||
|
|
||||||
|
/* Verify font image, no need to test image contents, as the image is garbage anyway */ |
||||||
|
Trade::TgaImporter importer; |
||||||
|
CORRADE_VERIFY(importer.openFile(Utility::Directory::join(MAGNUMFONTCONVERTER_TEST_WRITE_DIR, "font.tga"))); |
||||||
|
std::optional<Trade::ImageData2D> image = importer.image2D(0); |
||||||
|
CORRADE_VERIFY(image); |
||||||
|
CORRADE_COMPARE(image->size(), Vector2i(256)); |
||||||
|
CORRADE_COMPARE(image->format(), ColorFormat::Red); |
||||||
|
CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Text::Test::MagnumFontConverterTest) |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 MAGNUMFONTCONVERTER_TEST_WRITE_DIR "${CMAKE_CURRENT_BINARY_DIR}" |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "MagnumFontConverter/MagnumFontConverter.h" |
||||||
|
|
||||||
|
CORRADE_PLUGIN_REGISTER(MagnumFontConverter, Magnum::Text::MagnumFontConverter, |
||||||
|
"cz.mosra.magnum.Text.AbstractFontConverter/0.1") |
||||||
@ -0,0 +1,46 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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. |
||||||
|
# |
||||||
|
|
||||||
|
set(TgaImageConverter_SRCS |
||||||
|
TgaImageConverter.cpp) |
||||||
|
|
||||||
|
set(TgaImageConverter_HEADERS |
||||||
|
TgaImageConverter.h) |
||||||
|
|
||||||
|
add_library(TgaImageConverterObjects OBJECT ${TgaImageConverter_SRCS}) |
||||||
|
set_target_properties(TgaImageConverterObjects PROPERTIES COMPILE_FLAGS "-DTgaImageConverterObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") |
||||||
|
|
||||||
|
add_plugin(TgaImageConverter ${MAGNUM_PLUGINS_IMAGECONVERTER_INSTALL_DIR} |
||||||
|
TgaImageConverter.conf |
||||||
|
$<TARGET_OBJECTS:TgaImageConverterObjects> |
||||||
|
pluginRegistrationTgaImageConverter.cpp) |
||||||
|
target_link_libraries(TgaImageConverter ${MAGNUM_LIBRARIES}) |
||||||
|
|
||||||
|
install(FILES ${TgaImageConverter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImageConverter) |
||||||
|
|
||||||
|
if(BUILD_TESTS) |
||||||
|
add_library(TgaImageConverterTestLib SHARED $<TARGET_OBJECTS:TgaImageConverterObjects>) |
||||||
|
target_link_libraries(TgaImageConverterTestLib ${MAGNUM_LIBRARIES}) |
||||||
|
add_subdirectory(Test) |
||||||
|
endif() |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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(TgaImageConverterTest TgaImageConverterTest.cpp LIBRARIES TgaImageConverterTestLib TgaImporterTestLib) |
||||||
@ -0,0 +1,113 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <sstream> |
||||||
|
#include <tuple> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
#include <Utility/Directory.h> |
||||||
|
#include <ColorFormat.h> |
||||||
|
#include <Image.h> |
||||||
|
#include <Trade/ImageData.h> |
||||||
|
#include <TgaImageConverter/TgaImageConverter.h> |
||||||
|
#include <TgaImporter/TgaImporter.h> |
||||||
|
|
||||||
|
#include "configure.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { namespace Test { |
||||||
|
|
||||||
|
class TgaImageConverterTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
explicit TgaImageConverterTest(); |
||||||
|
|
||||||
|
void wrongFormat(); |
||||||
|
void wrongType(); |
||||||
|
|
||||||
|
void data(); |
||||||
|
}; |
||||||
|
|
||||||
|
namespace { |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
const Image2D original(ColorFormat::BGR, ColorType::UnsignedByte, {2, 3}, new char[18] |
||||||
|
#else |
||||||
|
const Image2D original(ColorFormat::RGB, ColorType::UnsignedByte, {2, 3}, new char[18] |
||||||
|
#endif |
||||||
|
{ |
||||||
|
1, 2, 3, 2, 3, 4, |
||||||
|
3, 4, 5, 4, 5, 6, |
||||||
|
5, 6, 7, 6, 7, 8 |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
TgaImageConverterTest::TgaImageConverterTest() { |
||||||
|
addTests({&TgaImageConverterTest::wrongFormat, |
||||||
|
&TgaImageConverterTest::wrongType, |
||||||
|
|
||||||
|
&TgaImageConverterTest::data}); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImageConverterTest::wrongFormat() { |
||||||
|
ImageReference2D image(ColorFormat::RG, ColorType::UnsignedByte, {}, nullptr); |
||||||
|
|
||||||
|
std::ostringstream out; |
||||||
|
Error::setOutput(&out); |
||||||
|
|
||||||
|
const auto data = TgaImageConverter().exportToData(image); |
||||||
|
CORRADE_VERIFY(!data); |
||||||
|
CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::convertToData(): unsupported image format ColorFormat::RG\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImageConverterTest::wrongType() { |
||||||
|
ImageReference2D image(ColorFormat::Red, ColorType::Float, {}, nullptr); |
||||||
|
|
||||||
|
std::ostringstream out; |
||||||
|
Error::setOutput(&out); |
||||||
|
|
||||||
|
const auto data = TgaImageConverter().exportToData(image); |
||||||
|
CORRADE_VERIFY(!data); |
||||||
|
CORRADE_COMPARE(out.str(), "Trade::TgaImageConverter::convertToData(): unsupported image type ColorType::Float\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImageConverterTest::data() { |
||||||
|
const auto data = TgaImageConverter().exportToData(original); |
||||||
|
|
||||||
|
TgaImporter importer; |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
std::optional<Trade::ImageData2D> converted = importer.image2D(0); |
||||||
|
CORRADE_VERIFY(converted); |
||||||
|
|
||||||
|
CORRADE_COMPARE(converted->size(), Vector2i(2, 3)); |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
CORRADE_COMPARE(converted->format(), ColorFormat::BGR); |
||||||
|
#else |
||||||
|
CORRADE_COMPARE(converted->format(), ColorFormat::RGB); |
||||||
|
#endif |
||||||
|
CORRADE_COMPARE(converted->type(), ColorType::UnsignedByte); |
||||||
|
CORRADE_COMPARE(std::string(reinterpret_cast<const char*>(converted->data()), 2*3*3), |
||||||
|
std::string(reinterpret_cast<const char*>(original.data()), 2*3*3)); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Trade::Test::TgaImageConverterTest) |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 TGAIMAGECONVERTER_TEST_DIR "${CMAKE_CURRENT_BINARY_DIR}" |
||||||
@ -0,0 +1,98 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "TgaImageConverter.h" |
||||||
|
|
||||||
|
#include <fstream> |
||||||
|
#include <tuple> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <Utility/Endianness.h> |
||||||
|
#include <ColorFormat.h> |
||||||
|
#include <Image.h> |
||||||
|
|
||||||
|
#ifdef MAGNUM_TARGET_GLES |
||||||
|
#include <algorithm> |
||||||
|
#include <Swizzle.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "TgaImporter/TgaHeader.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { |
||||||
|
|
||||||
|
TgaImageConverter::TgaImageConverter() = default; |
||||||
|
|
||||||
|
TgaImageConverter::TgaImageConverter(PluginManager::AbstractManager* manager, std::string plugin): AbstractImageConverter(manager, std::move(plugin)) {} |
||||||
|
|
||||||
|
auto TgaImageConverter::doFeatures() const -> Features { return Feature::ConvertData; } |
||||||
|
|
||||||
|
Containers::Array<unsigned char> TgaImageConverter::doExportToData(const ImageReference2D& image) const { |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
if(image.format() != ColorFormat::BGR && |
||||||
|
image.format() != ColorFormat::BGRA && |
||||||
|
image.format() != ColorFormat::Red) |
||||||
|
#else |
||||||
|
if(image.format() != ColorFormat::RGB && |
||||||
|
image.format() != ColorFormat::RGBA && |
||||||
|
image.format() != ColorFormat::Red) |
||||||
|
#endif |
||||||
|
{ |
||||||
|
Error() << "Trade::TgaImageConverter::convertToData(): unsupported image format" << image.format(); |
||||||
|
return nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
if(image.type() != ColorType::UnsignedByte) { |
||||||
|
Error() << "Trade::TgaImageConverter::convertToData(): unsupported image type" << image.type(); |
||||||
|
return nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
/* Initialize data buffer */ |
||||||
|
const UnsignedByte pixelSize = image.pixelSize(); |
||||||
|
auto data = Containers::Array<unsigned char>::zeroInitialized(sizeof(TgaHeader) + pixelSize*image.size().product()); |
||||||
|
|
||||||
|
/* Fill header */ |
||||||
|
auto header = reinterpret_cast<TgaHeader*>(data.begin()); |
||||||
|
header->imageType = image.format() == ColorFormat::Red ? 3 : 2; |
||||||
|
header->bpp = pixelSize*8; |
||||||
|
header->width = Utility::Endianness::littleEndian(image.size().x()); |
||||||
|
header->height = Utility::Endianness::littleEndian(image.size().y()); |
||||||
|
|
||||||
|
/* Fill data */ |
||||||
|
std::copy(image.data(), image.data()+pixelSize*image.size().product(), data.begin()+sizeof(TgaHeader)); |
||||||
|
|
||||||
|
#ifdef MAGNUM_TARGET_GLES |
||||||
|
if(image->format() == ColorFormat::RGB) { |
||||||
|
auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.begin()+sizeof(TgaHeader)); |
||||||
|
std::transform(pixels, pixels + image.size().product(), pixels, |
||||||
|
[](Math::Vector3<UnsignedByte> pixel) { return swizzle<'b', 'g', 'r'>(pixel); }); |
||||||
|
} else if(image.format() == ColorFormat::RGBA) { |
||||||
|
auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data.begin()+sizeof(TgaHeader)); |
||||||
|
std::transform(pixels, pixels + image.size().product(), pixels, |
||||||
|
[](Math::Vector4<UnsignedByte> pixel) { return swizzle<'b', 'g', 'r', 'a'>(pixel); }); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
return std::move(data); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,72 @@ |
|||||||
|
#ifndef Magnum_Trade_TgaImageConverter_h |
||||||
|
#define Magnum_Trade_TgaImageConverter_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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::Trade::TgaImageConverter |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Trade/AbstractImageConverter.h> |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
#if defined(TgaImageConverter_EXPORTS) || defined(TgaImageConverterObjects_EXPORTS) |
||||||
|
#define MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT CORRADE_VISIBILITY_EXPORT |
||||||
|
#else |
||||||
|
#define MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT CORRADE_VISIBILITY_IMPORT |
||||||
|
#endif |
||||||
|
#define MAGNUM_TRADE_TGAIMAGECONVERTER_LOCAL CORRADE_VISIBILITY_LOCAL |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief TGA image converter plugin |
||||||
|
|
||||||
|
Supports images with format @ref ColorFormat::BGR, @ref ColorFormat::BGRA or |
||||||
|
@ref ColorFormat::Red and type @ref ColorType::UnsignedByte. |
||||||
|
|
||||||
|
This plugin is built if `WITH_TGAIMAGECONVERTER` is enabled in CMake. To use |
||||||
|
dynamic plugin, you need to load `%TgaImageConverter` plugin from |
||||||
|
`imageconverters/` subdirectory of your plugin dir. To use static plugin or use |
||||||
|
this as a dependency of another plugin, you need to request `%TgaImageConverter` |
||||||
|
component in CMake and link to `${MAGNUMPLUGINS_TGAIMAGECONVERTER_LIBRARIES}`. |
||||||
|
See @ref building-plugins and @ref cmake-plugins for more information. |
||||||
|
*/ |
||||||
|
class MAGNUM_TRADE_TGAIMAGECONVERTER_EXPORT TgaImageConverter: public AbstractImageConverter { |
||||||
|
public: |
||||||
|
/** @brief Default constructor */ |
||||||
|
explicit TgaImageConverter(); |
||||||
|
|
||||||
|
/** @brief Plugin manager constructor */ |
||||||
|
explicit TgaImageConverter(PluginManager::AbstractManager* manager, std::string plugin); |
||||||
|
|
||||||
|
private: |
||||||
|
Features MAGNUM_TRADE_TGAIMAGECONVERTER_LOCAL doFeatures() const override; |
||||||
|
Containers::Array<unsigned char> MAGNUM_TRADE_TGAIMAGECONVERTER_LOCAL doExportToData(const ImageReference2D& image) const override; |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "TgaImageConverter/TgaImageConverter.h" |
||||||
|
|
||||||
|
CORRADE_PLUGIN_REGISTER(TgaImageConverter, Magnum::Trade::TgaImageConverter, |
||||||
|
"cz.mosra.magnum.Trade.AbstractImageConverter/0.2.1") |
||||||
@ -0,0 +1,47 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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. |
||||||
|
# |
||||||
|
|
||||||
|
set(TgaImporter_SRCS |
||||||
|
TgaImporter.cpp) |
||||||
|
|
||||||
|
set(TgaImporter_HEADERS |
||||||
|
TgaHeader.h |
||||||
|
TgaImporter.h) |
||||||
|
|
||||||
|
add_library(TgaImporterObjects OBJECT ${TgaImporter_SRCS}) |
||||||
|
set_target_properties(TgaImporterObjects PROPERTIES COMPILE_FLAGS "-DTgaImporterObjects_EXPORTS ${CMAKE_SHARED_LIBRARY_CXX_FLAGS}") |
||||||
|
|
||||||
|
add_plugin(TgaImporter ${MAGNUM_PLUGINS_IMPORTER_INSTALL_DIR} |
||||||
|
TgaImporter.conf |
||||||
|
$<TARGET_OBJECTS:TgaImporterObjects> |
||||||
|
pluginRegistrationTgaImporter.cpp) |
||||||
|
target_link_libraries(TgaImporter ${MAGNUM_LIBRARIES}) |
||||||
|
|
||||||
|
install(FILES ${TgaImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/TgaImporter) |
||||||
|
|
||||||
|
if(BUILD_TESTS) |
||||||
|
add_library(TgaImporterTestLib SHARED $<TARGET_OBJECTS:TgaImporterObjects>) |
||||||
|
target_link_libraries(TgaImporterTestLib ${MAGNUM_LIBRARIES}) |
||||||
|
add_subdirectory(Test) |
||||||
|
endif() |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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(TgaImporterTest TgaImporterTest.cpp LIBRARIES TgaImporterTestLib) |
||||||
@ -0,0 +1,239 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <sstream> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
#include <Utility/Directory.h> |
||||||
|
#include <ColorFormat.h> |
||||||
|
#include <Trade/ImageData.h> |
||||||
|
|
||||||
|
#include "TgaImporter/TgaImporter.h" |
||||||
|
|
||||||
|
#include "configure.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { namespace Test { |
||||||
|
|
||||||
|
class TgaImporterTest: public TestSuite::Tester { |
||||||
|
public: |
||||||
|
TgaImporterTest(); |
||||||
|
|
||||||
|
void openInexistent(); |
||||||
|
void openShort(); |
||||||
|
void paletted(); |
||||||
|
void compressed(); |
||||||
|
|
||||||
|
void colorBits16(); |
||||||
|
void colorBits24(); |
||||||
|
void colorBits32(); |
||||||
|
|
||||||
|
void grayscaleBits8(); |
||||||
|
void grayscaleBits16(); |
||||||
|
|
||||||
|
void file(); |
||||||
|
}; |
||||||
|
|
||||||
|
TgaImporterTest::TgaImporterTest() { |
||||||
|
addTests({&TgaImporterTest::openInexistent, |
||||||
|
&TgaImporterTest::openShort, |
||||||
|
&TgaImporterTest::paletted, |
||||||
|
&TgaImporterTest::compressed, |
||||||
|
|
||||||
|
&TgaImporterTest::colorBits16, |
||||||
|
&TgaImporterTest::colorBits24, |
||||||
|
&TgaImporterTest::colorBits32, |
||||||
|
|
||||||
|
&TgaImporterTest::grayscaleBits8, |
||||||
|
&TgaImporterTest::grayscaleBits16, |
||||||
|
|
||||||
|
&TgaImporterTest::file}); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::openInexistent() { |
||||||
|
std::ostringstream debug; |
||||||
|
Error::setOutput(&debug); |
||||||
|
|
||||||
|
TgaImporter importer; |
||||||
|
CORRADE_VERIFY(!importer.openFile("inexistent.file")); |
||||||
|
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::openFile(): cannot open file inexistent.file\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::openShort() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::ostringstream debug; |
||||||
|
Error::setOutput(&debug); |
||||||
|
CORRADE_VERIFY(!importer.image2D(0)); |
||||||
|
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): the file is too short: 17 bytes\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::paletted() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::ostringstream debug; |
||||||
|
Error::setOutput(&debug); |
||||||
|
CORRADE_VERIFY(!importer.image2D(0)); |
||||||
|
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): paletted files are not supported\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::compressed() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::ostringstream debug; |
||||||
|
Error::setOutput(&debug); |
||||||
|
CORRADE_VERIFY(!importer.image2D(0)); |
||||||
|
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported (compressed?) image type: 9\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::colorBits16() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0 }; |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::ostringstream debug; |
||||||
|
Error::setOutput(&debug); |
||||||
|
CORRADE_VERIFY(!importer.image2D(0)); |
||||||
|
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported color bits-per-pixel: 16\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::colorBits24() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { |
||||||
|
0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 24, 0, |
||||||
|
1, 2, 3, 2, 3, 4, |
||||||
|
3, 4, 5, 4, 5, 6, |
||||||
|
5, 6, 7, 6, 7, 8 |
||||||
|
}; |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
const char* pixels = reinterpret_cast<const char*>(data) + 18; |
||||||
|
#else |
||||||
|
const char pixels[] = { |
||||||
|
3, 2, 1, 4, 3, 2, |
||||||
|
5, 4, 3, 6, 5, 4, |
||||||
|
7, 6, 5, 8, 7, 6 |
||||||
|
}; |
||||||
|
#endif |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::optional<Trade::ImageData2D> image = importer.image2D(0); |
||||||
|
CORRADE_VERIFY(image); |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
CORRADE_COMPARE(image->format(), ColorFormat::BGR); |
||||||
|
#else |
||||||
|
CORRADE_COMPARE(image->format(), ColorFormat::RGB); |
||||||
|
#endif |
||||||
|
CORRADE_COMPARE(image->size(), Vector2i(2, 3)); |
||||||
|
CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); |
||||||
|
CORRADE_COMPARE(std::string(reinterpret_cast<const char*>(image->data()), 2*3*3), std::string(pixels, 2*3*3)); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::colorBits32() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { |
||||||
|
0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 32, 0, |
||||||
|
1, 2, 3, 1, 2, 3, 4, 1, |
||||||
|
3, 4, 5, 1, 4, 5, 6, 1, |
||||||
|
5, 6, 7, 1, 6, 7, 8, 1 |
||||||
|
}; |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
const char* pixels = reinterpret_cast<const char*>(data) + 18; |
||||||
|
#else |
||||||
|
const char pixels[] = { |
||||||
|
3, 2, 1, 1, 4, 3, 2, 1, |
||||||
|
5, 4, 3, 1, 6, 5, 4, 1, |
||||||
|
7, 6, 5, 1, 8, 7, 6, 1 |
||||||
|
}; |
||||||
|
#endif |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::optional<Trade::ImageData2D> image = importer.image2D(0); |
||||||
|
CORRADE_VERIFY(image); |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
CORRADE_COMPARE(image->format(), ColorFormat::BGRA); |
||||||
|
#else |
||||||
|
CORRADE_COMPARE(image->format(), ColorFormat::RGBA); |
||||||
|
#endif |
||||||
|
CORRADE_COMPARE(image->size(), Vector2i(2, 3)); |
||||||
|
CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); |
||||||
|
CORRADE_COMPARE(std::string(reinterpret_cast<const char*>(image->data()), 2*3*3), std::string(pixels, 2*3*3)); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::grayscaleBits8() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { |
||||||
|
0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 8, 0, |
||||||
|
1, 2, |
||||||
|
3, 4, |
||||||
|
5, 6 |
||||||
|
}; |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::optional<Trade::ImageData2D> image = importer.image2D(0); |
||||||
|
CORRADE_VERIFY(image); |
||||||
|
CORRADE_COMPARE(image->format(), ColorFormat::Red); |
||||||
|
CORRADE_COMPARE(image->size(), Vector2i(2, 3)); |
||||||
|
CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); |
||||||
|
CORRADE_COMPARE(std::string(reinterpret_cast<const char*>(image->data()), 2*3), |
||||||
|
std::string(reinterpret_cast<const char*>(data) + 18, 2*3)); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::grayscaleBits16() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0 }; |
||||||
|
CORRADE_VERIFY(importer.openData(data)); |
||||||
|
|
||||||
|
std::ostringstream debug; |
||||||
|
Error::setOutput(&debug); |
||||||
|
CORRADE_VERIFY(!importer.image2D(0)); |
||||||
|
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported grayscale bits-per-pixel: 16\n"); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporterTest::file() { |
||||||
|
TgaImporter importer; |
||||||
|
const unsigned char data[] = { |
||||||
|
0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 8, 0, |
||||||
|
1, 2, |
||||||
|
3, 4, |
||||||
|
5, 6 |
||||||
|
}; |
||||||
|
CORRADE_VERIFY(importer.openFile(Utility::Directory::join(TGAIMPORTER_TEST_DIR, "file.tga"))); |
||||||
|
|
||||||
|
std::optional<Trade::ImageData2D> image = importer.image2D(0); |
||||||
|
CORRADE_VERIFY(image); |
||||||
|
CORRADE_COMPARE(image->format(), ColorFormat::Red); |
||||||
|
CORRADE_COMPARE(image->size(), Vector2i(2, 3)); |
||||||
|
CORRADE_COMPARE(image->type(), ColorType::UnsignedByte); |
||||||
|
CORRADE_COMPARE(std::string(reinterpret_cast<const char*>(image->data()), 2*3), |
||||||
|
std::string(reinterpret_cast<const char*>(data) + 18, 2*3)); |
||||||
|
} |
||||||
|
|
||||||
|
}}} |
||||||
|
|
||||||
|
CORRADE_TEST_MAIN(Magnum::Trade::Test::TgaImporterTest) |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 TGAIMPORTER_TEST_DIR "${CMAKE_CURRENT_SOURCE_DIR}" |
||||||
Binary file not shown.
@ -0,0 +1,58 @@ |
|||||||
|
#ifndef Magnum_Trade_TgaHeader_h |
||||||
|
#define Magnum_Trade_TgaHeader_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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::Trade::TgaHeader |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Types.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { |
||||||
|
|
||||||
|
#pragma pack(1) |
||||||
|
/** @brief TGA file header */ |
||||||
|
/** @todoc Enable @c INLINE_SIMPLE_STRUCTS again when unclosed <component> in tagfile is fixed*/ |
||||||
|
struct TgaHeader { |
||||||
|
UnsignedByte identsize; /**< @brief Size of ID field that follows header (0) */ |
||||||
|
UnsignedByte colorMapType; /**< @brief 0 = None, 1 = paletted */ |
||||||
|
UnsignedByte imageType; /**< @brief 0 = none, 1 = indexed, 2 = rgb, 3 = grey, +8=rle */ |
||||||
|
UnsignedShort colorMapStart; /**< @brief First color map entry */ |
||||||
|
UnsignedShort colorMapLength; /**< @brief Number of colors */ |
||||||
|
UnsignedByte colorMapBpp; /**< @brief Bits per palette entry */ |
||||||
|
UnsignedShort beginX; /**< @brief %Image x origin */ |
||||||
|
UnsignedShort beginY; /**< @brief %Image y origin */ |
||||||
|
UnsignedShort width; /**< @brief %Image width */ |
||||||
|
UnsignedShort height; /**< @brief %Image height */ |
||||||
|
UnsignedByte bpp; /**< @brief Bits per pixel (8, 16, 24, 32) */ |
||||||
|
UnsignedByte descriptor; /**< @brief %Image descriptor */ |
||||||
|
}; |
||||||
|
#pragma pack() |
||||||
|
|
||||||
|
static_assert(sizeof(TgaHeader) == 18, "TgaHeader size is not 18 bytes"); |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,4 @@ |
|||||||
|
author=Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
[metadata] |
||||||
|
name=TGA image importer |
||||||
@ -0,0 +1,160 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "TgaImporter.h" |
||||||
|
|
||||||
|
#include <fstream> |
||||||
|
#include <sstream> |
||||||
|
#include <Utility/Endianness.h> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <ColorFormat.h> |
||||||
|
#include <Trade/ImageData.h> |
||||||
|
|
||||||
|
#ifdef MAGNUM_TARGET_GLES |
||||||
|
#include <algorithm> |
||||||
|
#include <Context.h> |
||||||
|
#include <Extensions.h> |
||||||
|
#include <Swizzle.h> |
||||||
|
#endif |
||||||
|
|
||||||
|
#include "TgaHeader.h" |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { |
||||||
|
|
||||||
|
TgaImporter::TgaImporter(): in(nullptr) {} |
||||||
|
|
||||||
|
TgaImporter::TgaImporter(PluginManager::AbstractManager* manager, std::string plugin): AbstractImporter(manager, std::move(plugin)), in(nullptr) {} |
||||||
|
|
||||||
|
TgaImporter::~TgaImporter() { close(); } |
||||||
|
|
||||||
|
auto TgaImporter::doFeatures() const -> Features { return Feature::OpenData; } |
||||||
|
|
||||||
|
bool TgaImporter::doIsOpened() const { return in; } |
||||||
|
|
||||||
|
void TgaImporter::doOpenData(const Containers::ArrayReference<const unsigned char> data) { |
||||||
|
in = new std::istringstream(std::string(reinterpret_cast<const char*>(data.begin()), data.size())); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporter::doOpenFile(const std::string& filename) { |
||||||
|
in = new std::ifstream(filename.c_str()); |
||||||
|
if(in->good()) return; |
||||||
|
|
||||||
|
Error() << "Trade::TgaImporter::openFile(): cannot open file" << filename; |
||||||
|
close(); |
||||||
|
} |
||||||
|
|
||||||
|
void TgaImporter::doClose() { |
||||||
|
delete in; |
||||||
|
in = nullptr; |
||||||
|
} |
||||||
|
|
||||||
|
UnsignedInt TgaImporter::doImage2DCount() const { return 1; } |
||||||
|
|
||||||
|
std::optional<ImageData2D> TgaImporter::doImage2D(UnsignedInt) { |
||||||
|
/* Check if the file is long enough */ |
||||||
|
in->seekg(0, std::istream::end); |
||||||
|
std::streampos filesize = in->tellg(); |
||||||
|
in->seekg(0, std::istream::beg); |
||||||
|
if(filesize < std::streampos(sizeof(TgaHeader))) { |
||||||
|
Error() << "Trade::TgaImporter::image2D(): the file is too short:" << filesize << "bytes"; |
||||||
|
return std::nullopt; |
||||||
|
} |
||||||
|
|
||||||
|
TgaHeader header; |
||||||
|
in->read(reinterpret_cast<char*>(&header), sizeof(TgaHeader)); |
||||||
|
|
||||||
|
/* Convert to machine endian */ |
||||||
|
header.width = Utility::Endianness::littleEndian(header.width); |
||||||
|
header.height = Utility::Endianness::littleEndian(header.height); |
||||||
|
|
||||||
|
/* Image format */ |
||||||
|
ColorFormat format; |
||||||
|
if(header.colorMapType != 0) { |
||||||
|
Error() << "Trade::TgaImporter::image2D(): paletted files are not supported"; |
||||||
|
return std::nullopt; |
||||||
|
} |
||||||
|
|
||||||
|
/* Color */ |
||||||
|
if(header.imageType == 2) { |
||||||
|
switch(header.bpp) { |
||||||
|
case 24: |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
format = ColorFormat::BGR; |
||||||
|
#else |
||||||
|
format = ColorFormat::RGB; |
||||||
|
#endif |
||||||
|
break; |
||||||
|
case 32: |
||||||
|
#ifndef MAGNUM_TARGET_GLES |
||||||
|
format = ColorFormat::BGRA; |
||||||
|
#else |
||||||
|
format = ColorFormat::RGBA; |
||||||
|
#endif |
||||||
|
break; |
||||||
|
default: |
||||||
|
Error() << "Trade::TgaImporter::image2D(): unsupported color bits-per-pixel:" << header.bpp; |
||||||
|
return std::nullopt; |
||||||
|
} |
||||||
|
|
||||||
|
/* Grayscale */ |
||||||
|
} else if(header.imageType == 3) { |
||||||
|
#ifdef MAGNUM_TARGET_GLES |
||||||
|
format = Context::current() && Context::current()->isExtensionSupported<Extensions::GL::EXT::texture_rg>() ? |
||||||
|
ColorFormat::Red : ColorFormat::Luminance; |
||||||
|
#else |
||||||
|
format = ColorFormat::Red; |
||||||
|
#endif |
||||||
|
if(header.bpp != 8) { |
||||||
|
Error() << "Trade::TgaImporter::image2D(): unsupported grayscale bits-per-pixel:" << header.bpp; |
||||||
|
return std::nullopt; |
||||||
|
} |
||||||
|
|
||||||
|
/* Compressed files */ |
||||||
|
} else { |
||||||
|
Error() << "Trade::TgaImporter::image2D(): unsupported (compressed?) image type:" << header.imageType; |
||||||
|
return std::nullopt; |
||||||
|
} |
||||||
|
|
||||||
|
const std::size_t dataSize = header.width*header.height*header.bpp/8; |
||||||
|
char* const data = new char[dataSize]; |
||||||
|
in->read(data, dataSize); |
||||||
|
|
||||||
|
Vector2i size(header.width, header.height); |
||||||
|
|
||||||
|
#ifdef MAGNUM_TARGET_GLES |
||||||
|
if(format == ColorFormat::RGB) { |
||||||
|
auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data); |
||||||
|
std::transform(pixels, pixels + size.product(), pixels, |
||||||
|
[](Math::Vector3<UnsignedByte> pixel) { return swizzle<'b', 'g', 'r'>(pixel); }); |
||||||
|
} else if(format == ColorFormat::RGBA) { |
||||||
|
auto pixels = reinterpret_cast<Math::Vector4<UnsignedByte>*>(data); |
||||||
|
std::transform(pixels, pixels + size.product(), pixels, |
||||||
|
[](Math::Vector4<UnsignedByte> pixel) { return swizzle<'b', 'g', 'r', 'a'>(pixel); }); |
||||||
|
} |
||||||
|
#endif |
||||||
|
|
||||||
|
return ImageData2D(format, ColorType::UnsignedByte, size, data); |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,90 @@ |
|||||||
|
#ifndef Magnum_Trade_TgaImporter_h |
||||||
|
#define Magnum_Trade_TgaImporter_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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::Trade::TgaImporter |
||||||
|
*/ |
||||||
|
|
||||||
|
#include <Utility/Visibility.h> |
||||||
|
#include <Trade/AbstractImporter.h> |
||||||
|
|
||||||
|
#ifndef DOXYGEN_GENERATING_OUTPUT |
||||||
|
#if defined(TgaImporter_EXPORTS) || defined(TgaImporterObjects_EXPORTS) |
||||||
|
#define MAGNUM_TRADE_TGAIMPORTER_EXPORT CORRADE_VISIBILITY_EXPORT |
||||||
|
#else |
||||||
|
#define MAGNUM_TRADE_TGAIMPORTER_EXPORT CORRADE_VISIBILITY_IMPORT |
||||||
|
#endif |
||||||
|
#define MAGNUM_TRADE_TGAIMPORTER_LOCAL CORRADE_VISIBILITY_LOCAL |
||||||
|
#endif |
||||||
|
|
||||||
|
namespace Magnum { namespace Trade { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief TGA importer plugin |
||||||
|
|
||||||
|
Supports uncompressed BGR, BGRA or grayscale images with 8 bits per channel. |
||||||
|
|
||||||
|
This plugin is built if `WITH_TGAIMPORTER` is enabled in CMake. To use dynamic |
||||||
|
plugin, you need to load `%TgaImporter` plugin from `importers/` subdirectory |
||||||
|
of your plugin dir. To use static plugin or use this as a dependency of another |
||||||
|
plugin, you need to request `%TgaImporter` component in CMake and link to |
||||||
|
`${MAGNUMPLUGINS_TGAIMPORTER_LIBRARIES}`. See @ref building-plugins and |
||||||
|
@ref cmake-plugins for more information. |
||||||
|
|
||||||
|
The images are imported with @ref ColorType::UnsignedByte and @ref ColorFormat::BGR, |
||||||
|
@ref ColorFormat::BGRA or @ref ColorFormat::Red, respectively. Grayscale images |
||||||
|
require extension @extension{ARB,texture_rg}. |
||||||
|
|
||||||
|
In OpenGL ES BGR and BGRA images are converted to @ref ColorFormat::RGB |
||||||
|
and @ref ColorFormat::RGBA. In OpenGL ES 2.0, if @es_extension{EXT,texture_rg} |
||||||
|
is not supported, grayscale images use @ref ColorFormat::Luminance instead of |
||||||
|
@ref ColorFormat::Red. |
||||||
|
*/ |
||||||
|
class MAGNUM_TRADE_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter { |
||||||
|
public: |
||||||
|
/** @brief Default constructor */ |
||||||
|
explicit TgaImporter(); |
||||||
|
|
||||||
|
/** @brief Plugin manager constructor */ |
||||||
|
explicit TgaImporter(PluginManager::AbstractManager* manager, std::string plugin); |
||||||
|
|
||||||
|
~TgaImporter(); |
||||||
|
|
||||||
|
private: |
||||||
|
Features MAGNUM_TRADE_TGAIMPORTER_LOCAL doFeatures() const override; |
||||||
|
bool MAGNUM_TRADE_TGAIMPORTER_LOCAL doIsOpened() const override; |
||||||
|
void MAGNUM_TRADE_TGAIMPORTER_LOCAL doOpenData(Containers::ArrayReference<const unsigned char> data) override; |
||||||
|
void MAGNUM_TRADE_TGAIMPORTER_LOCAL doOpenFile(const std::string& filename) override; |
||||||
|
void MAGNUM_TRADE_TGAIMPORTER_LOCAL doClose() override; |
||||||
|
UnsignedInt MAGNUM_TRADE_TGAIMPORTER_LOCAL doImage2DCount() const override; |
||||||
|
std::optional<ImageData2D> MAGNUM_TRADE_TGAIMPORTER_LOCAL doImage2D(UnsignedInt id) override; |
||||||
|
|
||||||
|
std::istream* in; |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "TgaImporter.h" |
||||||
|
|
||||||
|
CORRADE_PLUGIN_REGISTER(TgaImporter, Magnum::Trade::TgaImporter, |
||||||
|
"cz.mosra.magnum.Trade.AbstractImporter/0.3") |
||||||
@ -0,0 +1,51 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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 |
||||||
|
$<TARGET_OBJECTS:WavAudioImporterObjects> |
||||||
|
pluginRegistrationWavAudioImporter.cpp) |
||||||
|
target_link_libraries(WavAudioImporter ${MAGNUM_LIBRARIES} ${MAGNUM_AUDIO_LIBRARIES}) |
||||||
|
|
||||||
|
install(FILES ${WavAudioImporter_HEADERS} DESTINATION ${MAGNUM_PLUGINS_INCLUDE_INSTALL_DIR}/WavAudioImporter) |
||||||
|
|
||||||
|
if(BUILD_TESTS) |
||||||
|
add_library(WavAudioImporterTestLib STATIC $<TARGET_OBJECTS:WavAudioImporterObjects>) |
||||||
|
target_link_libraries(WavAudioImporterTestLib ${MAGNUM_LIBRARIES} ${MAGNUM_AUDIO_LIBRARIES}) |
||||||
|
add_subdirectory(Test) |
||||||
|
endif() |
||||||
@ -0,0 +1,30 @@ |
|||||||
|
# |
||||||
|
# This file is part of Magnum. |
||||||
|
# |
||||||
|
# Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
# |
||||||
|
# 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) |
||||||
@ -0,0 +1,123 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <sstream> |
||||||
|
#include <Containers/Array.h> |
||||||
|
#include <TestSuite/Tester.h> |
||||||
|
#include <Utility/Directory.h> |
||||||
|
|
||||||
|
#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<unsigned char>(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<unsigned char> 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<unsigned char> 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) |
||||||
@ -0,0 +1,25 @@ |
|||||||
|
/* |
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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}" |
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -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š <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <Types.h> |
||||||
|
|
||||||
|
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 |
||||||
@ -0,0 +1,130 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <Utility/Assert.h> |
||||||
|
#include <Utility/Debug.h> |
||||||
|
#include <Utility/Endianness.h> |
||||||
|
|
||||||
|
#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<const unsigned char> 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<const WavHeader*>(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<unsigned char>(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<unsigned char> WavImporter::doData() { |
||||||
|
Containers::Array<unsigned char> copy(_data.size()); |
||||||
|
std::copy(_data.begin(), _data.end(), copy.begin()); |
||||||
|
return copy; |
||||||
|
} |
||||||
|
|
||||||
|
}} |
||||||
@ -0,0 +1,78 @@ |
|||||||
|
#ifndef Magnum_Audio_WavImporter_h |
||||||
|
#define Magnum_Audio_WavImporter_h |
||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 <Containers/Array.h> |
||||||
|
#include <Utility/Visibility.h> |
||||||
|
#include <Audio/AbstractImporter.h> |
||||||
|
|
||||||
|
namespace Magnum { namespace Audio { |
||||||
|
|
||||||
|
/**
|
||||||
|
@brief WAV importer plugin |
||||||
|
|
||||||
|
Supports mono and stereo PCM files with 8 or 16 bits per channel. The files are |
||||||
|
imported with @ref Buffer::Format::Mono8, @ref Buffer::Format::Mono16, |
||||||
|
@ref Buffer::Format::Stereo8 or @ref Buffer::Format::Stereo16, respectively. |
||||||
|
|
||||||
|
This plugin is built if `WITH_WAVAUDIOIMPORTER` is enabled in CMake. To use |
||||||
|
dynamic plugin, you need to load `%WavAudioImporter` plugin from `audioimporters/` |
||||||
|
subdirectory of your plugin dir. To use static plugin or or use this as a |
||||||
|
dependency of another plugin, you need to request `%WavAudioImporter` component |
||||||
|
in CMake and link to `${MAGNUMPLUGINS_WAVAUDIOIMPORTER_LIBRARIES}`. See |
||||||
|
@ref building-plugins and @ref cmake-plugins for more information. |
||||||
|
*/ |
||||||
|
class WavImporter: public AbstractImporter { |
||||||
|
public: |
||||||
|
/** @brief Default constructor */ |
||||||
|
explicit WavImporter(); |
||||||
|
|
||||||
|
/** @brief Plugin manager constructor */ |
||||||
|
explicit WavImporter(PluginManager::AbstractManager* manager, std::string plugin); |
||||||
|
|
||||||
|
~WavImporter(); |
||||||
|
|
||||||
|
private: |
||||||
|
Features doFeatures() const override; |
||||||
|
bool doIsOpened() const override; |
||||||
|
void doOpenData(Containers::ArrayReference<const unsigned char> data) override; |
||||||
|
void doClose() override; |
||||||
|
|
||||||
|
Buffer::Format doFormat() const override; |
||||||
|
UnsignedInt doFrequency() const override; |
||||||
|
Containers::Array<unsigned char> doData() override; |
||||||
|
|
||||||
|
Containers::Array<unsigned char> _data; |
||||||
|
Buffer::Format _format; |
||||||
|
UnsignedInt _frequency; |
||||||
|
}; |
||||||
|
|
||||||
|
}} |
||||||
|
|
||||||
|
#endif |
||||||
@ -0,0 +1,28 @@ |
|||||||
|
/*
|
||||||
|
This file is part of Magnum. |
||||||
|
|
||||||
|
Copyright © 2010, 2011, 2012, 2013 Vladimír Vondruš <mosra@centrum.cz> |
||||||
|
|
||||||
|
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 "WavAudioImporter/WavImporter.h" |
||||||
|
|
||||||
|
CORRADE_PLUGIN_REGISTER(WavAudioImporter, Magnum::Audio::WavImporter, |
||||||
|
"cz.mosra.magnum.Audio.AbstractImporter/0.1") |
||||||
Loading…
Reference in new issue