SWBF2-Classic-Msh-Viewer/MshViewer/Source/Texture.cpp
Anakin a875820f48 removed unused files,
removed unused functions,
removed unused variables,
reduced dynamic stack memory (there was too much allocated),
moved some code around into better place,
implemented destructor (there is still a std::_face_node left on the stack when the program is done),
2016-10-31 16:19:12 +01:00

133 lines
3.7 KiB
C++

#include "Texture.h"
#include <iostream>
#include <fstream>
#include <Windows.h>
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<char*>(&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<char*>(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];
int tempByteIndex = 0;
std::size_t tempPixelIndex = 0;
do {
fsPicture.read(reinterpret_cast<char*>(&tempChunkHeader), sizeof(tempChunkHeader));
if (tempChunkHeader >> 7) // repeat count
{
// just use the first 7 bits
tempChunkHeader = (uint8_t(tempChunkHeader << 1) >> 1);
fsPicture.read(reinterpret_cast<char*>(&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<char*>(&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<std::uint8_t> 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;
}