Mercurial > public > ostc_companion
diff ostc45_icon.cpp @ 5:115cfa4a3239 default tip
Added icon upload function for OSTC 4/5
For the upload the same process as the one for the firmware update is used => CRC functionality has been copied from the ostc_pack SW
| author | Ideenmodellierer |
|---|---|
| date | Tue, 30 Dec 2025 21:41:02 +0100 |
| parents | |
| children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ostc45_icon.cpp Tue Dec 30 21:41:02 2025 +0100 @@ -0,0 +1,163 @@ +#include "ostc45_icon.h" + + +//OSTC45_Icon::OSTC45_Icon() {} + + +#pragma pack(push, 1) +struct BMPFileHeader +{ + uint16_t bfType; + uint32_t bfSize; + uint16_t bfReserved1; + uint16_t bfReserved2; + uint32_t bfOffBits; +}; + +struct BMPInfoHeader +{ + uint32_t biSize; + int32_t biWidth; + int32_t biHeight; + uint16_t biPlanes; + uint16_t biBitCount; + uint32_t biCompression; + uint32_t biSizeImage; + int32_t biXPelsPerMeter; + int32_t biYPelsPerMeter; + uint32_t biClrUsed; + uint32_t biClrImportant; +}; +#pragma pack(pop) + +BmpToArray::BmpToArray(const QString& filename) +{ + loadBMP(filename); +} + +void BmpToArray::loadBMP(const QString& filename) +{ + QFile file(filename); + int dstY; + QByteArray rowBuffer; + bool topDown = false; + BMPFileHeader fileHeader; + BMPInfoHeader infoHeader; + + if (!file.open(QIODevice::ReadOnly)) + throw std::runtime_error("Cannot open BMP file"); + + if (file.read(reinterpret_cast<char*>(&fileHeader), + sizeof(BMPFileHeader)) != sizeof(BMPFileHeader)) + throw std::runtime_error("Failed to read BMP file header"); + + if (file.read(reinterpret_cast<char*>(&infoHeader), + sizeof(BMPInfoHeader)) != sizeof(BMPInfoHeader)) + throw std::runtime_error("Failed to read BMP info header"); + + if (fileHeader.bfType != 0x4D42) + throw std::runtime_error("Not a valid BMP file"); + + if (infoHeader.biBitCount != 8) + throw std::runtime_error("Only 8-bit BMP supported"); + if (infoHeader.biCompression != 0) + throw std::runtime_error("Compressed BMP not supported"); + + if(infoHeader.biWidth > 800) + throw std::runtime_error("Only BMP with 800 or less horizontal pixels supported"); + + if(infoHeader.biHeight > 480) + throw std::runtime_error("Only BMP with 480 or less vertical pixels supported"); + + // Width / Height + width = infoHeader.biWidth; + height = infoHeader.biHeight; + + if ((int32_t)height < 0) { + height = -((int32_t)height); + topDown = true; + } + + // Palette + uint32_t colorCount = infoHeader.biClrUsed; + if (colorCount == 0) colorCount = 256; + if (colorCount > 256) colorCount = 256; + + clut.resize(colorCount); + + for (uint32_t i = 0; i < colorCount; ++i) + file.read(reinterpret_cast<char*>(&clut[i]), 4); + + // CLUT in 32-Bit transform 0x00RRGGBB + clut32.resize(255, 0); + + for (uint32_t i = 0; i < colorCount && i < 255; ++i) + { + clut32[i] = + (clut[i].r << 16) | + (clut[i].g << 8) | + (clut[i].b); + } + + // Pixel-Data + if (!file.seek(fileHeader.bfOffBits)) + throw std::runtime_error("Failed to seek to pixel data"); + + pixelData.resize(width * height); + + size_t rowSize = (width + 3) & ~3; // 4-Byte alignment + + rowBuffer.resize(rowSize); + + for (int y = 0; y < height; ++y) + { + if (file.read(rowBuffer.data(), rowSize) != rowSize) + throw std::runtime_error("Failed to read BMP pixel row"); + + if (topDown) + { + dstY = height - 1 - y; + } + else + { + dstY = y; + } + + for (int x = 0; x < width; ++x) + { + pixelData[x * height + dstY] = + static_cast<uint8_t>(rowBuffer[x]); + } + } + + +} +QByteArray BmpToArray::getTransferBytes() const +{ + QByteArray out; + + out.reserve(clut32.size() * 4 + pixelData.size()); + + // CLUT (32 Bit, Little Endian) + for (uint32_t color : clut32) + { + out.append(static_cast<char>( color & 0xFF)); + out.append(static_cast<char>((color >> 8) & 0xFF)); + out.append(static_cast<char>((color >> 16) & 0xFF)); + out.append(static_cast<char>((color >> 24) & 0xFF)); + } + + // Pixel (8 Bit) + out.append(reinterpret_cast<const char*>(pixelData.data()), + pixelData.size()); + + return out; +} + +void BmpToArray::getImageXY(uint32_t* x, uint32_t* y) +{ + *x = width; + *y = height; +} + +
