improve image load performance,

can be improved more, but scanline has wrong results
This commit is contained in:
Anakin 2017-02-01 17:41:29 +01:00
parent bc5bfc62bc
commit 1c5631a5e0
1 changed files with 124 additions and 116 deletions

View File

@ -2,35 +2,39 @@
#include <fstream> #include <fstream>
#include <QImage> #include <QImage>
#include <QColor> #include <QColor>
#include <QVector>
#include <QFile>
#include "Profiler.h"
QImage loadTga(QString filePath, bool &success) QImage loadTga(QString filePath, bool &success)
{ {
TIC("start");
QImage img; QImage img;
success = true;
// open the file // open the file
std::fstream fsPicture(filePath.toStdString().c_str(), std::ios::in | std::ios::binary); QFile file(filePath);
if (!fsPicture.is_open()) if (!file.open(QIODevice::ReadOnly))
{ {
img = QImage(1, 1, QImage::Format_RGB32);
img.fill(Qt::red);
success = false; success = false;
return img;
} }
else
{
// read in the header // read in the header
std::uint8_t ui8x18Header[19] = { 0 }; quint8 ui8x18Header[19] = { 0 };
fsPicture.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header) - 1); file.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header) - 1);
//get variables //get variables
std::uint32_t ui32BpP; quint32 ui32BpP;
std::uint32_t ui32Width; quint32 ui32Width;
std::uint32_t ui32Height; quint32 ui32Height;
std::uint32_t ui32IDLength; quint32 ui32IDLength;
std::uint32_t ui32PicType; quint32 ui32PicType;
std::uint32_t ui32PaletteLength; quint32 ui32PaletteLength;
std::uint32_t ui32Size; quint32 ui32Size;
// extract all information from header // extract all information from header
ui32IDLength = ui8x18Header[0]; ui32IDLength = ui8x18Header[0];
@ -44,19 +48,20 @@ QImage loadTga(QString filePath, bool &success)
ui32Size = ui32Width * ui32Height * ui32BpP / 8; ui32Size = ui32Width * ui32Height * ui32BpP / 8;
// jump to the data block // jump to the data block
fsPicture.seekg(ui32IDLength + ui32PaletteLength, std::ios_base::cur); file.seek(ui32IDLength + ui32PaletteLength + 18);
img = QImage(ui32Width, ui32Height, QImage::Format_RGBA8888); img = QImage(ui32Width, ui32Height, QImage::Format_RGBA8888);
// uncompressed // uncompressed
if (ui32PicType == 2 && (ui32BpP == 24 || ui32BpP == 32)) if (ui32PicType == 2 && (ui32BpP == 24 || ui32BpP == 32))
{ {
std::vector<std::uint8_t> vui8Pixels; QVector<quint8> vui8Pixels;
vui8Pixels.resize(ui32Size); vui8Pixels.resize(ui32Size);
fsPicture.read(reinterpret_cast<char*>(vui8Pixels.data()), ui32Size); file.read(reinterpret_cast<char*>(vui8Pixels.data()), ui32Size);
for (unsigned int y = 0; y < ui32Height; y++) for (unsigned int y = 0; y < ui32Height; y++)
{ {
//QRgb* imgLine = (QRgb*)img.scanLine(y);
for (unsigned int x = 0; x < ui32Width; x++) for (unsigned int x = 0; x < ui32Width; x++)
{ {
int valr = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 2); int valr = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 2);
@ -67,6 +72,8 @@ QImage loadTga(QString filePath, bool &success)
vala = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 3); vala = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 3);
QColor value(valr, valg, valb, vala); QColor value(valr, valg, valb, vala);
//imgLine[x] = value.rgba();
img.setPixel(x, ui32Width - 1 - y, value.rgba()); img.setPixel(x, ui32Width - 1 - y, value.rgba());
} }
} }
@ -74,19 +81,19 @@ QImage loadTga(QString filePath, bool &success)
// else if compressed 24 or 32 bit // else if compressed 24 or 32 bit
else if (ui32PicType == 10 && (ui32BpP == 24 || ui32BpP == 32)) // compressed else if (ui32PicType == 10 && (ui32BpP == 24 || ui32BpP == 32)) // compressed
{ {
std::uint8_t tempChunkHeader; quint8 tempChunkHeader;
std::uint8_t tempData[5]; quint8 tempData[5];
unsigned int tmp_pixelIndex = 0; unsigned int tmp_pixelIndex = 0;
do { do {
fsPicture.read(reinterpret_cast<char*>(&tempChunkHeader), sizeof(tempChunkHeader)); file.read(reinterpret_cast<char*>(&tempChunkHeader), sizeof(tempChunkHeader));
if (tempChunkHeader >> 7) // repeat count if (tempChunkHeader >> 7) // repeat count
{ {
// just use the first 7 bits // just use the first 7 bits
tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1); tempChunkHeader = (quint8(tempChunkHeader << 1) >> 1);
fsPicture.read(reinterpret_cast<char*>(&tempData), ui32BpP / 8); file.read(reinterpret_cast<char*>(&tempData), ui32BpP / 8);
for (int i = 0; i <= tempChunkHeader; i++) for (int i = 0; i <= tempChunkHeader; i++)
{ {
@ -108,7 +115,7 @@ QImage loadTga(QString filePath, bool &success)
for (int i = 0; i <= tempChunkHeader; i++) for (int i = 0; i <= tempChunkHeader; i++)
{ {
fsPicture.read(reinterpret_cast<char*>(&tempData), ui32BpP / 8); file.read(reinterpret_cast<char*>(&tempData), ui32BpP / 8);
QColor color; QColor color;
@ -126,13 +133,14 @@ QImage loadTga(QString filePath, bool &success)
// not useable format // not useable format
else else
{ {
fsPicture.close();
success = false; success = false;
return img; }
} }
fsPicture.close(); TOC("end");
success = true;
if (file.isOpen())
file.close();
return img; return img;
} }