Browse Source

TgaImporter: drop istream in favor of plain array.

Much simpler code.
pull/107/head
Vladimír Vondruš 11 years ago
parent
commit
d4e53f16e8
  1. 39
      src/MagnumPlugins/TgaImporter/Test/TgaImporterTest.cpp
  2. 51
      src/MagnumPlugins/TgaImporter/TgaImporter.cpp
  3. 4
      src/MagnumPlugins/TgaImporter/TgaImporter.h

39
src/MagnumPlugins/TgaImporter/Test/TgaImporterTest.cpp

@ -53,14 +53,11 @@ class TgaImporterTest: public TestSuite::Tester {
void grayscaleBits8(); void grayscaleBits8();
void grayscaleBits16(); void grayscaleBits16();
void file();
void useTwice(); void useTwice();
}; };
TgaImporterTest::TgaImporterTest() { TgaImporterTest::TgaImporterTest() {
addTests({&TgaImporterTest::openNonexistent, addTests({&TgaImporterTest::openShort,
&TgaImporterTest::openShort,
&TgaImporterTest::paletted, &TgaImporterTest::paletted,
&TgaImporterTest::compressed, &TgaImporterTest::compressed,
@ -71,20 +68,9 @@ TgaImporterTest::TgaImporterTest() {
&TgaImporterTest::grayscaleBits8, &TgaImporterTest::grayscaleBits8,
&TgaImporterTest::grayscaleBits16, &TgaImporterTest::grayscaleBits16,
&TgaImporterTest::file,
&TgaImporterTest::useTwice}); &TgaImporterTest::useTwice});
} }
void TgaImporterTest::openNonexistent() {
std::ostringstream debug;
Error::setOutput(&debug);
TgaImporter importer;
CORRADE_VERIFY(!importer.openFile("nonexistent.file"));
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::openFile(): cannot open file nonexistent.file\n");
}
void TgaImporterTest::openShort() { void TgaImporterTest::openShort() {
TgaImporter importer; TgaImporter importer;
const char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; const char data[] = { 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 };
@ -214,29 +200,6 @@ void TgaImporterTest::grayscaleBits16() {
CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported grayscale bits-per-pixel: 16\n"); CORRADE_COMPARE(debug.str(), "Trade::TgaImporter::image2D(): unsupported grayscale bits-per-pixel: 16\n");
} }
void TgaImporterTest::file() {
TgaImporter importer;
const 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);
#ifndef MAGNUM_TARGET_GLES2
CORRADE_COMPARE(image->format(), PixelFormat::Red);
#else
CORRADE_COMPARE(image->format(), PixelFormat::Luminance);
#endif
CORRADE_COMPARE(image->size(), Vector2i(2, 3));
CORRADE_COMPARE(image->type(), PixelType::UnsignedByte);
CORRADE_COMPARE_AS(image->data(), Containers::ArrayView<const char>{data}.suffix(18),
TestSuite::Compare::Container);
}
void TgaImporterTest::useTwice() { void TgaImporterTest::useTwice() {
TgaImporter importer; TgaImporter importer;
CORRADE_VERIFY(importer.openFile(Utility::Directory::join(TGAIMPORTER_TEST_DIR, "file.tga"))); CORRADE_VERIFY(importer.openFile(Utility::Directory::join(TGAIMPORTER_TEST_DIR, "file.tga")));

51
src/MagnumPlugins/TgaImporter/TgaImporter.cpp

@ -44,51 +44,37 @@
namespace Magnum { namespace Trade { namespace Magnum { namespace Trade {
TgaImporter::TgaImporter(): in(nullptr) {} TgaImporter::TgaImporter() = default;
TgaImporter::TgaImporter(PluginManager::AbstractManager& manager, std::string plugin): AbstractImporter(manager, std::move(plugin)), in(nullptr) {} TgaImporter::TgaImporter(PluginManager::AbstractManager& manager, std::string plugin): AbstractImporter{manager, std::move(plugin)} {}
TgaImporter::~TgaImporter() { close(); } TgaImporter::~TgaImporter() = default;
auto TgaImporter::doFeatures() const -> Features { return Feature::OpenData; } auto TgaImporter::doFeatures() const -> Features { return Feature::OpenData; }
bool TgaImporter::doIsOpened() const { return in; } bool TgaImporter::doIsOpened() const { return _in; }
void TgaImporter::doOpenData(const Containers::ArrayView<const char> data) { void TgaImporter::doClose() { _in = nullptr; }
in = new std::istringstream{{data, data.size()}};
}
void TgaImporter::doOpenFile(const std::string& filename) { void TgaImporter::doOpenData(const Containers::ArrayView<const char> data) {
in = new std::ifstream(filename, std::ifstream::binary); _in = Containers::Array<char>{data.size()};
if(in->good()) return; std::copy(data.begin(), data.end(), _in.begin());
Error() << "Trade::TgaImporter::openFile(): cannot open file" << filename;
close();
}
void TgaImporter::doClose() {
delete in;
in = nullptr;
} }
UnsignedInt TgaImporter::doImage2DCount() const { return 1; } UnsignedInt TgaImporter::doImage2DCount() const { return 1; }
std::optional<ImageData2D> TgaImporter::doImage2D(UnsignedInt) { std::optional<ImageData2D> TgaImporter::doImage2D(UnsignedInt) {
/* Check if the file is long enough */ /* Check if the file is long enough */
in->seekg(0, std::istream::end); if(_in.size() < std::streamoff(sizeof(TgaHeader))) {
std::streamoff filesize = in->tellg(); Error() << "Trade::TgaImporter::image2D(): the file is too short:" << _in.size() << "bytes";
in->seekg(0, std::istream::beg);
if(filesize < std::streamoff(sizeof(TgaHeader))) {
Error() << "Trade::TgaImporter::image2D(): the file is too short:" << filesize << "bytes";
return std::nullopt; return std::nullopt;
} }
TgaHeader header; const TgaHeader& header = *reinterpret_cast<const TgaHeader*>(_in.data());
in->read(reinterpret_cast<char*>(&header), sizeof(TgaHeader));
/* Convert to machine endian */ /* Size in machine endian */
header.width = Utility::Endianness::littleEndian(header.width); const Vector2i size{Utility::Endianness::littleEndian(header.width),
header.height = Utility::Endianness::littleEndian(header.height); Utility::Endianness::littleEndian(header.height)};
/* Image format */ /* Image format */
PixelFormat format; PixelFormat format;
@ -132,17 +118,14 @@ std::optional<ImageData2D> TgaImporter::doImage2D(UnsignedInt) {
return std::nullopt; return std::nullopt;
} }
const std::size_t dataSize = header.width*header.height*header.bpp/8; Containers::Array<char> data{std::size_t(size.product())*header.bpp/8};
Containers::Array<char> data{dataSize}; std::copy_n(_in + sizeof(TgaHeader), data.size(), data.begin());
in->read(data, dataSize);
/* Adjust pixel storage if row size is not four byte aligned */ /* Adjust pixel storage if row size is not four byte aligned */
PixelStorage storage; PixelStorage storage;
if((header.width*header.bpp/8)%4 != 0) if((size.x()*header.bpp/8)%4 != 0)
storage.setAlignment(1); storage.setAlignment(1);
Vector2i size(header.width, header.height);
if(format == PixelFormat::RGB) { if(format == PixelFormat::RGB) {
auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.data()); auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.data());
std::transform(pixels, pixels + size.product(), pixels, std::transform(pixels, pixels + size.product(), pixels,

4
src/MagnumPlugins/TgaImporter/TgaImporter.h

@ -29,6 +29,7 @@
* @brief Class @ref Magnum::Trade::TgaImporter * @brief Class @ref Magnum::Trade::TgaImporter
*/ */
#include <Corrade/Containers/Array.h>
#include <Corrade/Utility/VisibilityMacros.h> #include <Corrade/Utility/VisibilityMacros.h>
#include "Magnum/Trade/AbstractImporter.h" #include "Magnum/Trade/AbstractImporter.h"
@ -86,12 +87,11 @@ class MAGNUM_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter {
Features MAGNUM_TGAIMPORTER_LOCAL doFeatures() const override; Features MAGNUM_TGAIMPORTER_LOCAL doFeatures() const override;
bool MAGNUM_TGAIMPORTER_LOCAL doIsOpened() const override; bool MAGNUM_TGAIMPORTER_LOCAL doIsOpened() const override;
void MAGNUM_TGAIMPORTER_LOCAL doOpenData(Containers::ArrayView<const char> data) override; void MAGNUM_TGAIMPORTER_LOCAL doOpenData(Containers::ArrayView<const char> data) override;
void MAGNUM_TGAIMPORTER_LOCAL doOpenFile(const std::string& filename) override;
void MAGNUM_TGAIMPORTER_LOCAL doClose() override; void MAGNUM_TGAIMPORTER_LOCAL doClose() override;
UnsignedInt MAGNUM_TGAIMPORTER_LOCAL doImage2DCount() const override; UnsignedInt MAGNUM_TGAIMPORTER_LOCAL doImage2DCount() const override;
std::optional<ImageData2D> MAGNUM_TGAIMPORTER_LOCAL doImage2D(UnsignedInt id) override; std::optional<ImageData2D> MAGNUM_TGAIMPORTER_LOCAL doImage2D(UnsignedInt id) override;
std::istream* in; Containers::Array<char> _in;
}; };
}} }}

Loading…
Cancel
Save