From 4a657b77d2421b3f0bd094b7bb7e852af56575d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Fri, 29 Mar 2013 15:09:56 +0100 Subject: [PATCH] TgaImporter: parsing the image on call to image2D(). Solves the problem about image deletion, the image is imported again on every request and the user is responsible for its deletion. Now also asserting that the file is opened and that the image ID is zero. --- .../TgaImporter/Test/TgaImporterTest.cpp | 42 +++++++----- src/Plugins/TgaImporter/TgaImporter.cpp | 66 +++++++++---------- src/Plugins/TgaImporter/TgaImporter.h | 2 +- 3 files changed, 58 insertions(+), 52 deletions(-) diff --git a/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp b/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp index d11bccebd..ec7da8321 100644 --- a/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp +++ b/src/Plugins/TgaImporter/Test/TgaImporterTest.cpp @@ -64,50 +64,51 @@ void TgaImporterTest::openInexistent() { } 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 }; + CORRADE_VERIFY(importer.openData(data)); std::ostringstream debug; Error::setOutput(&debug); - - TgaImporter importer; - CORRADE_VERIFY(!importer.openData(data)); + CORRADE_VERIFY(!importer.image2D(0)); CORRADE_COMPARE(debug.str(), "TgaImporter: the file is too short: 17 bytes\n"); } void TgaImporterTest::paletted() { + TgaImporter importer; const 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); - - TgaImporter importer; - CORRADE_VERIFY(!importer.openData(data)); + CORRADE_VERIFY(!importer.image2D(0)); CORRADE_COMPARE(debug.str(), "TgaImporter: paletted files are not supported\n"); } void TgaImporterTest::nonRgb() { + TgaImporter importer; const char data[] = { 0, 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); - - TgaImporter importer; - CORRADE_VERIFY(!importer.openData(data)); + CORRADE_VERIFY(!importer.image2D(0)); CORRADE_COMPARE(debug.str(), "TgaImporter: non-RGB files are not supported\n"); } void TgaImporterTest::bits16() { + TgaImporter importer; const 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); - - TgaImporter importer; - CORRADE_VERIFY(!importer.openData(data)); + CORRADE_VERIFY(!importer.image2D(0)); CORRADE_COMPARE(debug.str(), "TgaImporter: unsupported bits-per-pixel: 16\n"); } void TgaImporterTest::bits24() { + TgaImporter importer; const 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 @@ -119,10 +120,10 @@ void TgaImporterTest::bits24() { 3, 2, 1, 4, 3, 2, 5, 4, 3, 6, 5, 4, 7, 6, 5, 8, 7, 6 }; #endif - - TgaImporter importer; CORRADE_VERIFY(importer.openData(data)); - auto image = importer.image2D(0); + + Trade::ImageData2D* image = importer.image2D(0); + CORRADE_VERIFY(image); #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE(image->format(), Trade::ImageData2D::Format::BGR); #else @@ -131,9 +132,12 @@ void TgaImporterTest::bits24() { CORRADE_COMPARE(image->size(), Math::Vector2(2, 3)); CORRADE_COMPARE(image->type(), Trade::ImageData2D::Type::UnsignedByte); CORRADE_COMPARE(std::string(static_cast(image->data()), 2*3*3), std::string(pixels, 2*3*3)); + + delete image; } void TgaImporterTest::bits32() { + TgaImporter importer; const 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 @@ -145,10 +149,10 @@ void TgaImporterTest::bits32() { 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 - - TgaImporter importer; CORRADE_VERIFY(importer.openData(data)); - auto image = importer.image2D(0); + + Trade::ImageData2D* image = importer.image2D(0); + CORRADE_VERIFY(image); #ifndef MAGNUM_TARGET_GLES CORRADE_COMPARE(image->format(), Trade::ImageData2D::Format::BGRA); #else @@ -157,6 +161,8 @@ void TgaImporterTest::bits32() { CORRADE_COMPARE(image->size(), Math::Vector2(2, 3)); CORRADE_COMPARE(image->type(), Trade::ImageData2D::Type::UnsignedByte); CORRADE_COMPARE(std::string(static_cast(image->data()), 2*3*3), std::string(pixels, 2*3*3)); + + delete image; } }}}} diff --git a/src/Plugins/TgaImporter/TgaImporter.cpp b/src/Plugins/TgaImporter/TgaImporter.cpp index c9697e51a..bb1f97c59 100644 --- a/src/Plugins/TgaImporter/TgaImporter.cpp +++ b/src/Plugins/TgaImporter/TgaImporter.cpp @@ -40,9 +40,9 @@ namespace Magnum { namespace Trade { namespace TgaImporter { static_assert(sizeof(TgaImporter::Header) == 18, "TgaImporter: header size is not 18 bytes"); #endif -TgaImporter::TgaImporter(): _image(nullptr) {} +TgaImporter::TgaImporter(): in(nullptr) {} -TgaImporter::TgaImporter(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin): AbstractImporter(manager, std::move(plugin)), _image(nullptr) {} +TgaImporter::TgaImporter(Corrade::PluginManager::AbstractPluginManager* manager, std::string plugin): AbstractImporter(manager, std::move(plugin)), in(nullptr) {} TgaImporter::~TgaImporter() { close(); } @@ -51,32 +51,47 @@ TgaImporter::Features TgaImporter::features() const { } bool TgaImporter::TgaImporter::openData(const void* const data, const std::size_t size) { - std::istringstream in(std::string(reinterpret_cast(data), size)); - return open(in); + close(); + + in = new std::istringstream(std::string(reinterpret_cast(data), size)); + return true; } bool TgaImporter::TgaImporter::openFile(const std::string& filename) { - std::ifstream in(filename.c_str()); - if(in.good()) return open(in); + close(); + + in = new std::ifstream(filename.c_str()); + if(in->good()) return true; Error() << "TgaImporter: cannot open file" << filename; + close(); return false; } -bool TgaImporter::open(std::istream& in) { - if(_image) close(); +void TgaImporter::close() { + delete in; + in = nullptr; +} + +UnsignedInt TgaImporter::TgaImporter::image2DCount() const { + return in ? 1 : 0; +} + +ImageData2D* TgaImporter::image2D(UnsignedInt id) { + CORRADE_ASSERT(in, "Trade::TgaImporter::TgaImporter::image2D(): no file opened", nullptr); + CORRADE_ASSERT(id == 0, "Trade::TgaImporter::TgaImporter::image2D(): wrong image ID", nullptr); /* Check if the file is long enough */ - in.seekg(0, std::istream::end); - std::streampos filesize = in.tellg(); - in.seekg(0, std::istream::beg); + in->seekg(0, std::istream::end); + std::streampos filesize = in->tellg(); + in->seekg(0, std::istream::beg); if(filesize < std::streampos(sizeof(Header))) { Error() << "TgaImporter: the file is too short:" << filesize << "bytes"; - return false; + return nullptr; } Header header; - in.read(reinterpret_cast(&header), sizeof(Header)); + in->read(reinterpret_cast(&header), sizeof(Header)); /* Convert to machine endian */ header.width = Endianness::littleEndian(header.width); @@ -84,12 +99,12 @@ bool TgaImporter::open(std::istream& in) { if(header.colorMapType != 0) { Error() << "TgaImporter: paletted files are not supported"; - return false; + return nullptr; } if(header.imageType != 2) { Error() << "TgaImporter: non-RGB files are not supported"; - return false; + return nullptr; } ImageData2D::Format format; @@ -110,12 +125,12 @@ bool TgaImporter::open(std::istream& in) { break; default: Error() << "TgaImporter: unsupported bits-per-pixel:" << header.bpp; - return false; + return nullptr; } std::size_t size = header.width*header.height*header.bpp/8; char* buffer = new char[size]; - in.read(buffer, size); + in->read(buffer, size); Math::Vector2 dimensions(header.width, header.height); @@ -131,22 +146,7 @@ bool TgaImporter::open(std::istream& in) { } #endif - _image = new ImageData2D(dimensions, format, ImageData2D::Type::UnsignedByte, buffer); - return true; -} - -void TgaImporter::close() { - /** @todo fixme: delete it only if it wasn't retrieved by user */ - //delete _image; - _image = nullptr; -} - -UnsignedInt TgaImporter::TgaImporter::image2DCount() const { - return _image ? 1 : 0; -} - -ImageData2D* TgaImporter::image2D(UnsignedInt) { - return _image; + return new ImageData2D(dimensions, format, ImageData2D::Type::UnsignedByte, buffer); } }}} diff --git a/src/Plugins/TgaImporter/TgaImporter.h b/src/Plugins/TgaImporter/TgaImporter.h index 3a4a4fc45..9ca30db32 100644 --- a/src/Plugins/TgaImporter/TgaImporter.h +++ b/src/Plugins/TgaImporter/TgaImporter.h @@ -87,7 +87,7 @@ class MAGNUM_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter { private: bool MAGNUM_TGAIMPORTER_LOCAL open(std::istream& in); - ImageData2D* _image; + std::istream* in; }; }}}