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;
+}
+
+