#include "Texture.h" #include TextureTGA::TextureTGA(const char * filePath) { // open the file std::fstream fsPicture(filePath, std::ios::in | std::ios::binary); if (!fsPicture.is_open()) throw std::invalid_argument(std::string("file not found: ") += filePath); // read in the header std::uint8_t ui8x18Header[19] = { 0 }; fsPicture.read(reinterpret_cast(&ui8x18Header), sizeof(ui8x18Header)-1); // extract all information from header ui32IDLength = ui8x18Header[0]; bColorTabel = ui8x18Header[1] == 1; ui32PicType = ui8x18Header[2]; ui32PaletteBegin = ui8x18Header[4] * 0x100 + ui8x18Header[3]; ui32PaletteLength = ui8x18Header[6] * 0x100 + ui8x18Header[5]; ui32PaletteBpP = ui8x18Header[7]; ui32Width = ui8x18Header[13] * 0x100 + ui8x18Header[12]; ui32Height = ui8x18Header[15] * 0x100 + ui8x18Header[14]; ui32BpP = ui8x18Header[16]; ui32Attribut = ui8x18Header[17]; // calculate some more information ui32Size = ui32Width * ui32Height * ui32BpP/8; bCompressed = ui32PicType == 9 || ui32PicType == 10; vui8Pixels.resize(ui32Size); /* consol output of the header std::cout << "Header\n" << "ID länge: " << ui32IDLength << std::endl << "Farbtabelle: " << (int)bColorTabel << std::endl << "Bildtype: " << ui32PicType << std::endl << "Palletenbegin: " << ui32PaletteBegin << std::endl << "Palletenlängen: " << ui32PaletteLength << std::endl << "Bits pro Palleteneintrag: " << ui32PaletteBpP << std::endl << "Breite: " << ui32Width << std::endl << "Höhe: " << ui32Height << std::endl << "Bit pro Pixel: " << ui32BpP << std::endl << "Bild Attribute: " << ui32Attribut << std::endl;*/ // jump to the data block fsPicture.seekg(ui32IDLength + ui32PaletteLength, std::ios_base::cur); // If not compressed 24 or 32 bit if (ui32PicType == 2 && (ui32BpP == 24 || ui32BpP == 32)) { fsPicture.read(reinterpret_cast(vui8Pixels.data()), ui32Size); } // 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 tempByteIndex = 0; std::size_t tempPixelIndex = 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++) { vui8Pixels[tempByteIndex++] = tempData[0]; vui8Pixels[tempByteIndex++] = tempData[1]; vui8Pixels[tempByteIndex++] = tempData[2]; if(ui32BpP == 32) vui8Pixels[tempByteIndex++] = tempData[3]; } } 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); vui8Pixels[tempByteIndex++] = tempData[0]; vui8Pixels[tempByteIndex++] = tempData[1]; vui8Pixels[tempByteIndex++] = tempData[2]; if (ui32BpP == 32) vui8Pixels[tempByteIndex++] = tempData[3]; } } } while (tempByteIndex < ui32Size); } // not useable format else { fsPicture.close(); throw std::invalid_argument("Invaild File Format! Required 24 or 31 Bit Image."); } fsPicture.close(); } TextureTGA::~TextureTGA() { vui8Pixels.clear(); } std::vector TextureTGA::getData() const { return vui8Pixels; } bool TextureTGA::hasAlpha() const { return ui32BpP == 32; } std::uint32_t TextureTGA::getWidth() const { return ui32Width; } std::uint32_t TextureTGA::getHeight() const { return ui32Height; }