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() {
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<GLsizei>(2, 3));
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));
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<GLsizei>(2, 3));
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));
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");
#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<const char*>(data), size));
return open(in);
close();
in = new std::istringstream(std::string(reinterpret_cast<const char*>(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<char*>(&header), sizeof(Header));
in->read(reinterpret_cast<char*>(&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<GLsizei> 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);
}
}}}

2
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;
};
}}}

Loading…
Cancel
Save