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 grayscaleBits16();
void file();
void useTwice();
};
TgaImporterTest::TgaImporterTest() {
addTests({&TgaImporterTest::openNonexistent,
&TgaImporterTest::openShort,
addTests({&TgaImporterTest::openShort,
&TgaImporterTest::paletted,
&TgaImporterTest::compressed,
@ -71,20 +68,9 @@ TgaImporterTest::TgaImporterTest() {
&TgaImporterTest::grayscaleBits8,
&TgaImporterTest::grayscaleBits16,
&TgaImporterTest::file,
&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() {
TgaImporter importer;
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");
}
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() {
TgaImporter importer;
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 {
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; }
bool TgaImporter::doIsOpened() const { return in; }
bool TgaImporter::doIsOpened() const { return _in; }
void TgaImporter::doOpenData(const Containers::ArrayView<const char> data) {
in = new std::istringstream{{data, data.size()}};
}
void TgaImporter::doClose() { _in = nullptr; }
void TgaImporter::doOpenFile(const std::string& filename) {
in = new std::ifstream(filename, std::ifstream::binary);
if(in->good()) return;
Error() << "Trade::TgaImporter::openFile(): cannot open file" << filename;
close();
}
void TgaImporter::doClose() {
delete in;
in = nullptr;
void TgaImporter::doOpenData(const Containers::ArrayView<const char> data) {
_in = Containers::Array<char>{data.size()};
std::copy(data.begin(), data.end(), _in.begin());
}
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::streamoff filesize = in->tellg();
in->seekg(0, std::istream::beg);
if(filesize < std::streamoff(sizeof(TgaHeader))) {
Error() << "Trade::TgaImporter::image2D(): the file is too short:" << filesize << "bytes";
if(_in.size() < std::streamoff(sizeof(TgaHeader))) {
Error() << "Trade::TgaImporter::image2D(): the file is too short:" << _in.size() << "bytes";
return std::nullopt;
}
TgaHeader header;
in->read(reinterpret_cast<char*>(&header), sizeof(TgaHeader));
const TgaHeader& header = *reinterpret_cast<const TgaHeader*>(_in.data());
/* Convert to machine endian */
header.width = Utility::Endianness::littleEndian(header.width);
header.height = Utility::Endianness::littleEndian(header.height);
/* Size in machine endian */
const Vector2i size{Utility::Endianness::littleEndian(header.width),
Utility::Endianness::littleEndian(header.height)};
/* Image format */
PixelFormat format;
@ -132,17 +118,14 @@ std::optional<ImageData2D> TgaImporter::doImage2D(UnsignedInt) {
return std::nullopt;
}
const std::size_t dataSize = header.width*header.height*header.bpp/8;
Containers::Array<char> data{dataSize};
in->read(data, dataSize);
Containers::Array<char> data{std::size_t(size.product())*header.bpp/8};
std::copy_n(_in + sizeof(TgaHeader), data.size(), data.begin());
/* Adjust pixel storage if row size is not four byte aligned */
PixelStorage storage;
if((header.width*header.bpp/8)%4 != 0)
if((size.x()*header.bpp/8)%4 != 0)
storage.setAlignment(1);
Vector2i size(header.width, header.height);
if(format == PixelFormat::RGB) {
auto pixels = reinterpret_cast<Math::Vector3<UnsignedByte>*>(data.data());
std::transform(pixels, pixels + size.product(), pixels,

4
src/MagnumPlugins/TgaImporter/TgaImporter.h

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

Loading…
Cancel
Save