From d44a90e440fb376d9febff81db06673e38f468e1 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 15:15:18 +0100 Subject: [PATCH 1/6] Header writing to a separate function --- src/OpenStreetMap-esp32.cpp | 69 ++++++++++++++++++++----------------- 1 file changed, 38 insertions(+), 31 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index d1bfe94..c1ae39a 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -377,7 +377,7 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t if (!readTileDataToBuffer(stream, buffer, contentSize, result)) { http.end(); - log_e("%s", result); + log_e("%s", result.c_str()); return false; } @@ -412,37 +412,8 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t return true; } -bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &result, uint8_t sdPin, uint32_t frequency) +bool writeHeader(File &file, LGFX_Sprite &map) { - log_i("Saving map as %s", filename); - - if (!map.getBuffer()) - { - result = "No data in map"; - return false; - } - - MemoryBuffer rowBuffer(map.width() * 3); - if (!rowBuffer.isAllocated()) - { - result = "Row buffer allocation failed"; - return false; - } - - if (!SD.begin(sdPin, SPI, frequency)) - { - result = "SD Card mount failed"; - return false; - } - - File file = SD.open(filename, FILE_WRITE); - if (!file) - { - result = "Failed to open file"; - SD.end(); - return false; - } - // BMP Header (54 bytes) uint16_t bfType = 0x4D42; // "BM" uint32_t biSizeImage = map.width() * map.height() * 3; // 3 bytes per pixel (RGB888) @@ -485,6 +456,42 @@ bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &resu writeLE(biClrUsed, 4); writeLE(biClrImportant, 4); + return true; +} + +bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &result, uint8_t sdPin, uint32_t frequency) +{ + log_i("Saving map as %s", filename); + + if (!map.getBuffer()) + { + result = "No data in map"; + return false; + } + + MemoryBuffer rowBuffer(map.width() * 3); + if (!rowBuffer.isAllocated()) + { + result = "Row buffer allocation failed"; + return false; + } + + if (!SD.begin(sdPin, SPI, frequency)) + { + result = "SD Card mount failed"; + return false; + } + + File file = SD.open(filename, FILE_WRITE); + if (!file) + { + result = "Failed to open file"; + SD.end(); + return false; + } + + writeHeader(file, map); + uint8_t *buf = rowBuffer.get(); for (uint16_t y = 0; y < map.height(); y++) { From 53d27785753f17f34dc55abc0f4422ef7d125f79 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 15:45:54 +0100 Subject: [PATCH 2/6] Map writing to a separate function --- src/OpenStreetMap-esp32.cpp | 52 +++++++++++++++++++++++++------------ src/OpenStreetMap-esp32.h | 4 ++- 2 files changed, 38 insertions(+), 18 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index c1ae39a..ec8613e 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -412,7 +412,7 @@ bool OpenStreetMap::downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t return true; } -bool writeHeader(File &file, LGFX_Sprite &map) +bool OpenStreetMap::writeHeader(const LGFX_Sprite &map, File &file) { // BMP Header (54 bytes) uint16_t bfType = 0x4D42; // "BM" @@ -459,6 +459,27 @@ bool writeHeader(File &file, LGFX_Sprite &map) return true; } +bool OpenStreetMap::writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer) +{ + uint8_t *buf = buffer.get(); + for (uint16_t y = 0; y < map.height(); y++) + { + for (uint16_t x = 0; x < map.width(); x++) + { + uint16_t rgb565Color = map.readPixel(x, y); + uint8_t red8 = ((rgb565Color >> 11) & 0x1F) * 255 / 31; + uint8_t green8 = ((rgb565Color >> 5) & 0x3F) * 255 / 63; + uint8_t blue8 = (rgb565Color & 0x1F) * 255 / 31; + + buf[x * 3] = blue8; + buf[x * 3 + 1] = green8; + buf[x * 3 + 2] = red8; + } + file.write(buffer.get(), buffer.size()); + } + return true; +} + bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &result, uint8_t sdPin, uint32_t frequency) { log_i("Saving map as %s", filename); @@ -490,25 +511,22 @@ bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &resu return false; } - writeHeader(file, map); - - uint8_t *buf = rowBuffer.get(); - for (uint16_t y = 0; y < map.height(); y++) + if (!writeHeader(map, file)) { - for (uint16_t x = 0; x < map.width(); x++) - { - uint16_t rgb565Color = map.readPixel(x, y); - uint8_t red8 = ((rgb565Color >> 11) & 0x1F) * 255 / 31; - uint8_t green8 = ((rgb565Color >> 5) & 0x3F) * 255 / 63; - uint8_t blue8 = (rgb565Color & 0x1F) * 255 / 31; - - buf[x * 3] = blue8; - buf[x * 3 + 1] = green8; - buf[x * 3 + 2] = red8; - } - file.write(buf, rowBuffer.size()); + result = "Failed to write bmp header"; + file.close(); + SD.end(); + return false; } + if (!writeMap(map, file, rowBuffer)) + { + result = "Failed to write map data"; + file.close(); + SD.end(); + return false; + } + file.close(); SD.end(); result = "Map saved as " + String(filename); diff --git a/src/OpenStreetMap-esp32.h b/src/OpenStreetMap-esp32.h index 5712345..988a15a 100644 --- a/src/OpenStreetMap-esp32.h +++ b/src/OpenStreetMap-esp32.h @@ -70,6 +70,8 @@ class OpenStreetMap bool downloadAndDecodeTile(CachedTile &tile, uint32_t x, uint32_t y, uint8_t zoom, String &result); bool readTileDataToBuffer(WiFiClient *stream, MemoryBuffer &buffer, size_t contentSize, String &result); bool composeMap(LGFX_Sprite &mapSprite, const tileList &requiredTiles, uint8_t zoom); + bool writeHeader(const LGFX_Sprite &map, File &file); + bool writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer); std::vector tilesCache; uint16_t *currentTileBuffer = nullptr; @@ -84,7 +86,7 @@ class OpenStreetMap int32_t startTileIndexX = 0; int32_t startTileIndexY = 0; - uint16_t numberOfColums = 0; + uint16_t numberOfColums = 0; }; #endif From aa453ae426d21311c7415e6c754916733a4a5514 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 16:01:09 +0100 Subject: [PATCH 3/6] Cleanup --- src/OpenStreetMap-esp32.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index ec8613e..f9968c4 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -462,6 +462,7 @@ bool OpenStreetMap::writeHeader(const LGFX_Sprite &map, File &file) bool OpenStreetMap::writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer) { uint8_t *buf = buffer.get(); + const size_t size = buffer.size(); for (uint16_t y = 0; y < map.height(); y++) { for (uint16_t x = 0; x < map.width(); x++) @@ -475,9 +476,10 @@ bool OpenStreetMap::writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer) buf[x * 3 + 1] = green8; buf[x * 3 + 2] = red8; } - file.write(buffer.get(), buffer.size()); - } - return true; + if (file.write(buf, size) != size) + return false; + } + return true; } bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &result, uint8_t sdPin, uint32_t frequency) @@ -516,7 +518,7 @@ bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &resu result = "Failed to write bmp header"; file.close(); SD.end(); - return false; + return false; } if (!writeMap(map, file, rowBuffer)) @@ -524,8 +526,8 @@ bool OpenStreetMap::saveMap(const char *filename, LGFX_Sprite &map, String &resu result = "Failed to write map data"; file.close(); SD.end(); - return false; - } + return false; + } file.close(); SD.end(); From de813d0befaff17d0759a996b01279e0e9f27c33 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 16:25:27 +0100 Subject: [PATCH 4/6] Bail out on write errors --- src/OpenStreetMap-esp32.cpp | 51 ++++++++++++++++++++----------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index f9968c4..34d3038 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -431,32 +431,35 @@ bool OpenStreetMap::writeHeader(const LGFX_Sprite &map, File &file) uint32_t biClrUsed = 0; uint32_t biClrImportant = 0; - // Write BMP header (Ensuring little-endian format) - auto writeLE = [&](uint32_t value, uint8_t size) - { - for (uint8_t i = 0; i < size; i++) - file.write(static_cast(value >> (8 * i))); + auto writeLE = [&](uint32_t value, uint8_t size) -> bool { + for (uint8_t i = 0; i < size; i++) { + if (file.write(static_cast(value >> (8 * i))) != 1) { + return false; + } + } + return true; }; - writeLE(bfType, 2); - writeLE(bfSize, 4); - writeLE(0, 2); // bfReserved - writeLE(0, 2); - writeLE(bfOffBits, 4); - - writeLE(biSize, 4); - writeLE(biWidth, 4); - writeLE(biHeight, 4); - writeLE(biPlanes, 2); - writeLE(biBitCount, 2); - writeLE(biCompression, 4); - writeLE(biSizeImage, 4); - writeLE(biXPelsPerMeter, 4); - writeLE(biYPelsPerMeter, 4); - writeLE(biClrUsed, 4); - writeLE(biClrImportant, 4); - - return true; + bool success = true; + + if (!(success &= writeLE(bfType, 2))) return false; + if (!(success &= writeLE(bfSize, 4))) return false; + if (!(success &= writeLE(0, 2))) return false; // bfReserved + if (!(success &= writeLE(0, 2))) return false; + if (!(success &= writeLE(bfOffBits, 4))) return false; + if (!(success &= writeLE(biSize, 4))) return false; + if (!(success &= writeLE(biWidth, 4))) return false; + if (!(success &= writeLE(biHeight, 4))) return false; + if (!(success &= writeLE(biPlanes, 2))) return false; + if (!(success &= writeLE(biBitCount, 2))) return false; + if (!(success &= writeLE(biCompression, 4))) return false; + if (!(success &= writeLE(biSizeImage, 4))) return false; + if (!(success &= writeLE(biXPelsPerMeter, 4))) return false; + if (!(success &= writeLE(biYPelsPerMeter, 4))) return false; + if (!(success &= writeLE(biClrUsed, 4))) return false; + if (!(success &= writeLE(biClrImportant, 4))) return false; + + return success; } bool OpenStreetMap::writeMap(LGFX_Sprite &map, File &file, MemoryBuffer &buffer) From e689ae733952a2bcdbb598451665f1d36a82cdf7 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 16:31:05 +0100 Subject: [PATCH 5/6] Cleanup --- src/OpenStreetMap-esp32.cpp | 57 ++++++++++++++++++++++++------------- 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index 34d3038..fe53079 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -431,9 +431,12 @@ bool OpenStreetMap::writeHeader(const LGFX_Sprite &map, File &file) uint32_t biClrUsed = 0; uint32_t biClrImportant = 0; - auto writeLE = [&](uint32_t value, uint8_t size) -> bool { - for (uint8_t i = 0; i < size; i++) { - if (file.write(static_cast(value >> (8 * i))) != 1) { + auto writeLE = [&](uint32_t value, uint8_t size) -> bool + { + for (uint8_t i = 0; i < size; i++) + { + if (file.write(static_cast(value >> (8 * i))) != 1) + { return false; } } @@ -442,22 +445,38 @@ bool OpenStreetMap::writeHeader(const LGFX_Sprite &map, File &file) bool success = true; - if (!(success &= writeLE(bfType, 2))) return false; - if (!(success &= writeLE(bfSize, 4))) return false; - if (!(success &= writeLE(0, 2))) return false; // bfReserved - if (!(success &= writeLE(0, 2))) return false; - if (!(success &= writeLE(bfOffBits, 4))) return false; - if (!(success &= writeLE(biSize, 4))) return false; - if (!(success &= writeLE(biWidth, 4))) return false; - if (!(success &= writeLE(biHeight, 4))) return false; - if (!(success &= writeLE(biPlanes, 2))) return false; - if (!(success &= writeLE(biBitCount, 2))) return false; - if (!(success &= writeLE(biCompression, 4))) return false; - if (!(success &= writeLE(biSizeImage, 4))) return false; - if (!(success &= writeLE(biXPelsPerMeter, 4))) return false; - if (!(success &= writeLE(biYPelsPerMeter, 4))) return false; - if (!(success &= writeLE(biClrUsed, 4))) return false; - if (!(success &= writeLE(biClrImportant, 4))) return false; + if (!(success &= writeLE(bfType, 2))) + return false; + if (!(success &= writeLE(bfSize, 4))) + return false; + if (!(success &= writeLE(0, 2))) + return false; // bfReserved + if (!(success &= writeLE(0, 2))) + return false; + if (!(success &= writeLE(bfOffBits, 4))) + return false; + if (!(success &= writeLE(biSize, 4))) + return false; + if (!(success &= writeLE(biWidth, 4))) + return false; + if (!(success &= writeLE(biHeight, 4))) + return false; + if (!(success &= writeLE(biPlanes, 2))) + return false; + if (!(success &= writeLE(biBitCount, 2))) + return false; + if (!(success &= writeLE(biCompression, 4))) + return false; + if (!(success &= writeLE(biSizeImage, 4))) + return false; + if (!(success &= writeLE(biXPelsPerMeter, 4))) + return false; + if (!(success &= writeLE(biYPelsPerMeter, 4))) + return false; + if (!(success &= writeLE(biClrUsed, 4))) + return false; + if (!(success &= writeLE(biClrImportant, 4))) + return false; return success; } From a40665f2b5989bebef71cd7e1a16a1d4f18b0bf1 Mon Sep 17 00:00:00 2001 From: Cellie Date: Sat, 22 Mar 2025 16:47:22 +0100 Subject: [PATCH 6/6] Cleanup --- src/OpenStreetMap-esp32.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/OpenStreetMap-esp32.cpp b/src/OpenStreetMap-esp32.cpp index fe53079..4c50109 100644 --- a/src/OpenStreetMap-esp32.cpp +++ b/src/OpenStreetMap-esp32.cpp @@ -434,12 +434,9 @@ bool OpenStreetMap::writeHeader(const LGFX_Sprite &map, File &file) auto writeLE = [&](uint32_t value, uint8_t size) -> bool { for (uint8_t i = 0; i < size; i++) - { if (file.write(static_cast(value >> (8 * i))) != 1) - { return false; - } - } + return true; }; @@ -450,7 +447,7 @@ bool OpenStreetMap::writeHeader(const LGFX_Sprite &map, File &file) if (!(success &= writeLE(bfSize, 4))) return false; if (!(success &= writeLE(0, 2))) - return false; // bfReserved + return false; if (!(success &= writeLE(0, 2))) return false; if (!(success &= writeLE(bfOffBits, 4)))