diff --git a/QtMeshViewer/Header/tga.h b/QtMeshViewer/Header/tga.h index 6e77435..9edf68f 100644 --- a/QtMeshViewer/Header/tga.h +++ b/QtMeshViewer/Header/tga.h @@ -2,137 +2,145 @@ #include #include #include +#include +#include +#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(&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)) - { - std::vector vui8Pixels; - vui8Pixels.resize(ui32Size); - fsPicture.read(reinterpret_cast(vui8Pixels.data()), ui32Size); - - for (unsigned int y = 0; y < ui32Height; 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); - 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; - - do { - fsPicture.read(reinterpret_cast(&tempChunkHeader), sizeof(tempChunkHeader)); - - if (tempChunkHeader >> 7) // repeat count - { - // just use the first 7 bits - tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1); - - fsPicture.read(reinterpret_cast(&tempData), ui32BpP / 8); - - 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)); - - 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++) - { - fsPicture.read(reinterpret_cast(&tempData), ui32BpP / 8); - - 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)); - - 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; + + // read in the header + quint8 ui8x18Header[19] = { 0 }; + file.read(reinterpret_cast(&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)) + { + QVector vui8Pixels; + vui8Pixels.resize(ui32Size); + file.read(reinterpret_cast(vui8Pixels.data()), ui32Size); + + for (unsigned int y = 0; y < ui32Height; y++) + { + //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 + { + quint8 tempChunkHeader; + quint8 tempData[5]; + unsigned int tmp_pixelIndex = 0; + + do { + file.read(reinterpret_cast(&tempChunkHeader), sizeof(tempChunkHeader)); + + if (tempChunkHeader >> 7) // repeat count + { + // just use the first 7 bits + tempChunkHeader = (quint8(tempChunkHeader << 1) >> 1); + + file.read(reinterpret_cast(&tempData), ui32BpP / 8); + + 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)); + + 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++) + { + file.read(reinterpret_cast(&tempData), ui32BpP / 8); + + 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)); + + img.setPixel(tmp_pixelIndex % ui32Width, ui32Height - 1 - (tmp_pixelIndex / ui32Width), color.rgba()); + tmp_pixelIndex++; + } + } + } while (tmp_pixelIndex < (ui32Width * ui32Height)); + } + // not useable format + else + { + success = false; + } } - fsPicture.close(); - success = true; + TOC("end"); + + if (file.isOpen()) + file.close(); return img; }