#pragma once #include #include #include #include #include #include "Profiler.h" QImage loadTga(QString filePath, bool &success) { TIC("start"); QImage img; success = true; // open the file QFile file(filePath); if (!file.open(QIODevice::ReadOnly)) { success = false; } else { // 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 = reinterpret_cast(img.scanLine(ui32Height - y - 1)); for (unsigned int x = 0; x < ui32Width; x++) { int valr = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8); int valg = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 1); int valb = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 2); int vala = 255; if (ui32BpP == 32) vala = vui8Pixels.at(y * ui32Width * ui32BpP / 8 + x * ui32BpP / 8 + 3); imgLine[x] = QColor(valr, valg, valb, vala).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; } } TOC("end"); if (file.isOpen()) file.close(); return img; }