Browse Source

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.
pull/34/head
Vladimír Vondruš 13 years ago
parent
commit
4a657b77d2
  1. 42
      src/Plugins/TgaImporter/Test/TgaImporterTest.cpp
  2. 66
      src/Plugins/TgaImporter/TgaImporter.cpp
  3. 2
      src/Plugins/TgaImporter/TgaImporter.h

42
src/Plugins/TgaImporter/Test/TgaImporterTest.cpp

@ -64,50 +64,51 @@ void TgaImporterTest::openInexistent() {
} }
void TgaImporterTest::openShort() { 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 }; 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; std::ostringstream debug;
Error::setOutput(&debug); Error::setOutput(&debug);
CORRADE_VERIFY(!importer.image2D(0));
TgaImporter importer;
CORRADE_VERIFY(!importer.openData(data));
CORRADE_COMPARE(debug.str(), "TgaImporter: the file is too short: 17 bytes\n"); CORRADE_COMPARE(debug.str(), "TgaImporter: the file is too short: 17 bytes\n");
} }
void TgaImporterTest::paletted() { 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 }; 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; std::ostringstream debug;
Error::setOutput(&debug); Error::setOutput(&debug);
CORRADE_VERIFY(!importer.image2D(0));
TgaImporter importer;
CORRADE_VERIFY(!importer.openData(data));
CORRADE_COMPARE(debug.str(), "TgaImporter: paletted files are not supported\n"); CORRADE_COMPARE(debug.str(), "TgaImporter: paletted files are not supported\n");
} }
void TgaImporterTest::nonRgb() { 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 }; 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; std::ostringstream debug;
Error::setOutput(&debug); Error::setOutput(&debug);
CORRADE_VERIFY(!importer.image2D(0));
TgaImporter importer;
CORRADE_VERIFY(!importer.openData(data));
CORRADE_COMPARE(debug.str(), "TgaImporter: non-RGB files are not supported\n"); CORRADE_COMPARE(debug.str(), "TgaImporter: non-RGB files are not supported\n");
} }
void TgaImporterTest::bits16() { 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 }; 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; std::ostringstream debug;
Error::setOutput(&debug); Error::setOutput(&debug);
CORRADE_VERIFY(!importer.image2D(0));
TgaImporter importer;
CORRADE_VERIFY(!importer.openData(data));
CORRADE_COMPARE(debug.str(), "TgaImporter: unsupported bits-per-pixel: 16\n"); CORRADE_COMPARE(debug.str(), "TgaImporter: unsupported bits-per-pixel: 16\n");
} }
void TgaImporterTest::bits24() { void TgaImporterTest::bits24() {
TgaImporter importer;
const char data[] = { const char data[] = {
0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 24, 0, 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 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 3, 2, 1, 4, 3, 2, 5, 4, 3, 6, 5, 4, 7, 6, 5, 8, 7, 6
}; };
#endif #endif
TgaImporter importer;
CORRADE_VERIFY(importer.openData(data)); CORRADE_VERIFY(importer.openData(data));
auto image = importer.image2D(0);
Trade::ImageData2D* image = importer.image2D(0);
CORRADE_VERIFY(image);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(image->format(), Trade::ImageData2D::Format::BGR); CORRADE_COMPARE(image->format(), Trade::ImageData2D::Format::BGR);
#else #else
@ -131,9 +132,12 @@ void TgaImporterTest::bits24() {
CORRADE_COMPARE(image->size(), Math::Vector2<GLsizei>(2, 3)); CORRADE_COMPARE(image->size(), Math::Vector2<GLsizei>(2, 3));
CORRADE_COMPARE(image->type(), Trade::ImageData2D::Type::UnsignedByte); CORRADE_COMPARE(image->type(), Trade::ImageData2D::Type::UnsignedByte);
CORRADE_COMPARE(std::string(static_cast<const char*>(image->data()), 2*3*3), std::string(pixels, 2*3*3)); CORRADE_COMPARE(std::string(static_cast<const char*>(image->data()), 2*3*3), std::string(pixels, 2*3*3));
delete image;
} }
void TgaImporterTest::bits32() { void TgaImporterTest::bits32() {
TgaImporter importer;
const char data[] = { const char data[] = {
0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 3, 0, 32, 0, 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 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 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 #endif
TgaImporter importer;
CORRADE_VERIFY(importer.openData(data)); CORRADE_VERIFY(importer.openData(data));
auto image = importer.image2D(0);
Trade::ImageData2D* image = importer.image2D(0);
CORRADE_VERIFY(image);
#ifndef MAGNUM_TARGET_GLES #ifndef MAGNUM_TARGET_GLES
CORRADE_COMPARE(image->format(), Trade::ImageData2D::Format::BGRA); CORRADE_COMPARE(image->format(), Trade::ImageData2D::Format::BGRA);
#else #else
@ -157,6 +161,8 @@ void TgaImporterTest::bits32() {
CORRADE_COMPARE(image->size(), Math::Vector2<GLsizei>(2, 3)); CORRADE_COMPARE(image->size(), Math::Vector2<GLsizei>(2, 3));
CORRADE_COMPARE(image->type(), Trade::ImageData2D::Type::UnsignedByte); CORRADE_COMPARE(image->type(), Trade::ImageData2D::Type::UnsignedByte);
CORRADE_COMPARE(std::string(static_cast<const char*>(image->data()), 2*3*3), std::string(pixels, 2*3*3)); CORRADE_COMPARE(std::string(static_cast<const char*>(image->data()), 2*3*3), std::string(pixels, 2*3*3));
delete image;
} }
}}}} }}}}

66
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"); static_assert(sizeof(TgaImporter::Header) == 18, "TgaImporter: header size is not 18 bytes");
#endif #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(); } 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) { bool TgaImporter::TgaImporter::openData(const void* const data, const std::size_t size) {
std::istringstream in(std::string(reinterpret_cast<const char*>(data), size)); close();
return open(in);
in = new std::istringstream(std::string(reinterpret_cast<const char*>(data), size));
return true;
} }
bool TgaImporter::TgaImporter::openFile(const std::string& filename) { bool TgaImporter::TgaImporter::openFile(const std::string& filename) {
std::ifstream in(filename.c_str()); close();
if(in.good()) return open(in);
in = new std::ifstream(filename.c_str());
if(in->good()) return true;
Error() << "TgaImporter: cannot open file" << filename; Error() << "TgaImporter: cannot open file" << filename;
close();
return false; return false;
} }
bool TgaImporter::open(std::istream& in) { void TgaImporter::close() {
if(_image) 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 */ /* Check if the file is long enough */
in.seekg(0, std::istream::end); in->seekg(0, std::istream::end);
std::streampos filesize = in.tellg(); std::streampos filesize = in->tellg();
in.seekg(0, std::istream::beg); in->seekg(0, std::istream::beg);
if(filesize < std::streampos(sizeof(Header))) { if(filesize < std::streampos(sizeof(Header))) {
Error() << "TgaImporter: the file is too short:" << filesize << "bytes"; Error() << "TgaImporter: the file is too short:" << filesize << "bytes";
return false; return nullptr;
} }
Header header; Header header;
in.read(reinterpret_cast<char*>(&header), sizeof(Header)); in->read(reinterpret_cast<char*>(&header), sizeof(Header));
/* Convert to machine endian */ /* Convert to machine endian */
header.width = Endianness::littleEndian(header.width); header.width = Endianness::littleEndian(header.width);
@ -84,12 +99,12 @@ bool TgaImporter::open(std::istream& in) {
if(header.colorMapType != 0) { if(header.colorMapType != 0) {
Error() << "TgaImporter: paletted files are not supported"; Error() << "TgaImporter: paletted files are not supported";
return false; return nullptr;
} }
if(header.imageType != 2) { if(header.imageType != 2) {
Error() << "TgaImporter: non-RGB files are not supported"; Error() << "TgaImporter: non-RGB files are not supported";
return false; return nullptr;
} }
ImageData2D::Format format; ImageData2D::Format format;
@ -110,12 +125,12 @@ bool TgaImporter::open(std::istream& in) {
break; break;
default: default:
Error() << "TgaImporter: unsupported bits-per-pixel:" << header.bpp; Error() << "TgaImporter: unsupported bits-per-pixel:" << header.bpp;
return false; return nullptr;
} }
std::size_t size = header.width*header.height*header.bpp/8; std::size_t size = header.width*header.height*header.bpp/8;
char* buffer = new char[size]; char* buffer = new char[size];
in.read(buffer, size); in->read(buffer, size);
Math::Vector2<GLsizei> dimensions(header.width, header.height); Math::Vector2<GLsizei> dimensions(header.width, header.height);
@ -131,22 +146,7 @@ bool TgaImporter::open(std::istream& in) {
} }
#endif #endif
_image = new ImageData2D(dimensions, format, ImageData2D::Type::UnsignedByte, buffer); return 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;
} }
}}} }}}

2
src/Plugins/TgaImporter/TgaImporter.h

@ -87,7 +87,7 @@ class MAGNUM_TGAIMPORTER_EXPORT TgaImporter: public AbstractImporter {
private: private:
bool MAGNUM_TGAIMPORTER_LOCAL open(std::istream& in); bool MAGNUM_TGAIMPORTER_LOCAL open(std::istream& in);
ImageData2D* _image; std::istream* in;
}; };
}}} }}}

Loading…
Cancel
Save