Skip to content
Snippets Groups Projects
Commit 1c5631a5 authored by Anakin's avatar Anakin
Browse files

improve image load performance,

can be improved more, but scanline has wrong results
parent bc5bfc62
No related branches found
No related tags found
No related merge requests found
......@@ -2,137 +2,145 @@
#include <fstream>
#include <QImage>
#include <QColor>
#include <QVector>
#include <QFile>
#include "Profiler.h"
QImage loadTga(QString filePath, bool &success)
{
TIC("start");
QImage img;
success = true;
// 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;
return img;
}
// read in the header
std::uint8_t ui8x18Header[19] = { 0 };
fsPicture.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header) - 1);
//get variables
std::uint32_t ui32BpP;
std::uint32_t ui32Width;
std::uint32_t ui32Height;
std::uint32_t ui32IDLength;
std::uint32_t ui32PicType;
std::uint32_t ui32PaletteLength;
std::uint32_t ui32Size;
// extract all information from header
ui32IDLength = ui8x18Header[0];
ui32PicType = ui8x18Header[2];
ui32PaletteLength = ui8x18Header[6] * 0x100 + ui8x18Header[5];
ui32Width = ui8x18Header[13] * 0x100 + ui8x18Header[12];
ui32Height = ui8x18Header[15] * 0x100 + ui8x18Header[14];
ui32BpP = ui8x18Header[16];
// calculate some more information
ui32Size = ui32Width * ui32Height * ui32BpP / 8;
// jump to the data block
fsPicture.seekg(ui32IDLength + ui32PaletteLength, std::ios_base::cur);
img = QImage(ui32Width, ui32Height, QImage::Format_RGBA8888);
// uncompressed
if (ui32PicType == 2 && (ui32BpP == 24 || ui32BpP == 32))
else
{
std::vector<std::uint8_t> vui8Pixels;
vui8Pixels.resize(ui32Size);
fsPicture.read(reinterpret_cast<char*>(vui8Pixels.data()), ui32Size);
for (unsigned int y = 0; y < ui32Height; y++)
// read in the header
quint8 ui8x18Header[19] = { 0 };
file.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header) - 1);
//get variables
quint32 ui32BpP;
quint32 ui32Width;
quint32 ui32Height;
quint32 ui32IDLength;
quint32 ui32PicType;
quint32 ui32PaletteLength;
quint32 ui32Size;
// extract all information from header
ui32IDLength = ui8x18Header[0];
ui32PicType = ui8x18Header[2];
ui32PaletteLength = ui8x18Header[6] * 0x100 + ui8x18Header[5];
ui32Width = ui8x18Header[13] * 0x100 + ui8x18Header[12];
ui32Height = ui8x18Header[15] * 0x100 + ui8x18Header[14];
ui32BpP = ui8x18Header[16];
// calculate some more information
ui32Size = ui32Width * ui32Height * ui32BpP / 8;
// jump to the data block
file.seek(ui32IDLength + ui32PaletteLength + 18);
img = QImage(ui32Width, ui32Height, QImage::Format_RGBA8888);
// uncompressed
if (ui32PicType == 2 && (ui32BpP == 24 || ui32BpP == 32))
{
for (unsigned int x = 0; x < ui32Width; x++)
QVector<quint8> vui8Pixels;
vui8Pixels.resize(ui32Size);
file.read(reinterpret_cast<char*>(vui8Pixels.data()), ui32Size);
for (unsigned int y = 0; y < ui32Height; y++)
{
int valr = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 2);
int valg = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 1);
int valb = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8);
int vala = 255;
if (ui32BpP == 32)
vala = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 3);
QColor value(valr, valg, valb, vala);
img.setPixel(x, ui32Width - 1 - y, value.rgba());
//QRgb* imgLine = (QRgb*)img.scanLine(y);
for (unsigned int x = 0; x < ui32Width; x++)
{
int valr = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 2);
int valg = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 1);
int valb = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8);
int vala = 255;
if (ui32BpP == 32)
vala = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 3);
QColor value(valr, valg, valb, vala);
//imgLine[x] = value.rgba();
img.setPixel(x, ui32Width - 1 - y, value.rgba());
}
}
}
}
// else if compressed 24 or 32 bit
else if (ui32PicType == 10 && (ui32BpP == 24 || ui32BpP == 32)) // compressed
{
std::uint8_t tempChunkHeader;
std::uint8_t tempData[5];
unsigned int tmp_pixelIndex = 0;
// else if compressed 24 or 32 bit
else if (ui32PicType == 10 && (ui32BpP == 24 || ui32BpP == 32)) // compressed
{
quint8 tempChunkHeader;
quint8 tempData[5];
unsigned int tmp_pixelIndex = 0;
do {
fsPicture.read(reinterpret_cast<char*>(&tempChunkHeader), sizeof(tempChunkHeader));
do {
file.read(reinterpret_cast<char*>(&tempChunkHeader), sizeof(tempChunkHeader));
if (tempChunkHeader >> 7) // repeat count
{
// just use the first 7 bits
tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1);
if (tempChunkHeader >> 7) // repeat count
{
// just use the first 7 bits
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++)
{
QColor color;
for (int i = 0; i <= tempChunkHeader; i++)
{
QColor color;
if (ui32BpP == 32)
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], tempData[3]));
else
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], 255));
if (ui32BpP == 32)
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], tempData[3]));
else
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], 255));
img.setPixel(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color.rgba());
tmp_pixelIndex++;
img.setPixel(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color.rgba());
tmp_pixelIndex++;
}
}
}
else // data count
{
// just use the first 7 bits
tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1);
for (int i = 0; i <= tempChunkHeader; i++)
else // data count
{
fsPicture.read(reinterpret_cast<char*>(&tempData), ui32BpP / 8);
// just use the first 7 bits
tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1);
QColor color;
for (int i = 0; i <= tempChunkHeader; i++)
{
file.read(reinterpret_cast<char*>(&tempData), ui32BpP / 8);
if (ui32BpP == 32)
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], tempData[3]));
else
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], 255));
QColor color;
img.setPixel(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color.rgba());
tmp_pixelIndex++;
if (ui32BpP == 32)
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], tempData[3]));
else
color.setRgba(qRgba(tempData[2], tempData[1], tempData[0], 255));
img.setPixel(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color.rgba());
tmp_pixelIndex++;
}
}
}
} while (tmp_pixelIndex < (ui32Width * ui32Height));
}
// not useable format
else
{
fsPicture.close();
success = false;
return img;
} while (tmp_pixelIndex < (ui32Width * ui32Height));
}
// not useable format
else
{
success = false;
}
}
fsPicture.close();
success = true;
TOC("end");
if (file.isOpen())
file.close();
return img;
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment