Mercurial > public > ostc_companion
view 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 source
#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; }
