rle and 24bit support,

need to write direct into image for performance
This commit is contained in:
Anakin 2017-01-05 11:31:36 +01:00
parent 552f86bf2d
commit 0bbc0da324
4 changed files with 143 additions and 7 deletions

139
QtMeshViewer/Header/tga.h Normal file
View File

@ -0,0 +1,139 @@
#pragma once
#include <fstream>
#include <QImage>
#include <QColor>
#include <iostream>
QImage loadTga(const char* filePath, bool &success)
{
QImage img;
if (!img.load(filePath))
{
// open the file
std::fstream fsPicture(filePath, std::ios::in | std::ios::binary);
if (!fsPicture.is_open())
{
img = QImage(1, 1, QImage::Format_RGB32);
img.fill(Qt::red);
success = false;
return img;
}
// some variables
std::vector<std::uint8_t>* vui8Pixels;
std::uint32_t ui32BpP;
std::uint32_t ui32Width;
std::uint32_t ui32Height;
// read in the header
std::uint8_t ui8x18Header[19] = { 0 };
fsPicture.read(reinterpret_cast<char*>(&ui8x18Header), sizeof(ui8x18Header) - 1);
//get variables
vui8Pixels = new std::vector<std::uint8_t>;
bool bCompressed;
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;
bCompressed = ui32PicType == 9 || ui32PicType == 10;
vui8Pixels->resize(ui32Size);
// jump to the data block
fsPicture.seekg(ui32IDLength + ui32PaletteLength, std::ios_base::cur);
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];
unsigned int tempByteIndex = 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->at(tempByteIndex++) = tempData[0];
vui8Pixels->at(tempByteIndex++) = tempData[1];
vui8Pixels->at(tempByteIndex++) = tempData[2];
if (ui32BpP == 32) vui8Pixels->at(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->at(tempByteIndex++) = tempData[0];
vui8Pixels->at(tempByteIndex++) = tempData[1];
vui8Pixels->at(tempByteIndex++) = tempData[2];
if (ui32BpP == 32) vui8Pixels->at(tempByteIndex++) = tempData[3];
}
}
} while (tempByteIndex < ui32Size);
}
// not useable format
else
{
fsPicture.close();
img = QImage(1, 1, QImage::Format_RGB32);
img.fill(Qt::red);
success = false;
return img;
}
fsPicture.close();
img = QImage(ui32Width, ui32Height, QImage::Format_RGB888);
int pixelSize = ui32BpP == 32 ? 4 : 3;
//TODO: write direct into img
for (unsigned int x = 0; x < ui32Width; x++)
{
for (unsigned int y = 0; y < ui32Height; y++)
{
int valr = vui8Pixels->at(y * ui32Width * pixelSize + x * pixelSize + 2);
int valg = vui8Pixels->at(y * ui32Width * pixelSize + x * pixelSize + 1);
int valb = vui8Pixels->at(y * ui32Width * pixelSize + x * pixelSize);
QColor value(valr, valg, valb);
img.setPixelColor(x, y, value);
}
}
img = img.mirrored();
}
success = true;
return img;
}

View File

@ -2,6 +2,7 @@
#include "..\Header\MshFile.h" #include "..\Header\MshFile.h"
#include "..\Header\OglViewerWidget.h" #include "..\Header\OglViewerWidget.h"
#include "..\Header\MainWindow.h" #include "..\Header\MainWindow.h"
#include "..\Header\tga.h"
#include <cmath> #include <cmath>
@ -110,13 +111,8 @@ void GeometryEngine::loadFile(const char* filePath)
void GeometryEngine::loadTexture(const char* filePath) void GeometryEngine::loadTexture(const char* filePath)
{ {
bool loadSuccess;
QImage img; QImage img = loadTga(filePath, loadSuccess);
if (!img.load(filePath))
{
img = QImage(1, 1, QImage::Format_RGB32);
img.fill(Qt::red);
}
// Load image to OglTexture // Load image to OglTexture
QOpenGLTexture* new_texture = new QOpenGLTexture(img.mirrored()); QOpenGLTexture* new_texture = new QOpenGLTexture(img.mirrored());

View File

@ -5,6 +5,7 @@
#include <QFileDialog> #include <QFileDialog>
#include <QFile> #include <QFile>
#include <QPalette> #include <QPalette>
#include "..\Header\FileInterface.h"
#define WINDOW_NAME "Mesh Viewer" #define WINDOW_NAME "Mesh Viewer"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 KiB

After

Width:  |  Height:  |  Size: 173 KiB