Implement znelson recommendation

This commit is contained in:
jpirnay
2026-03-07 10:11:54 +01:00
parent 36a91a53a3
commit ae19e975fa
+20 -14
View File
@@ -286,15 +286,26 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
uint32_t* rowAccum = nullptr; // Accumulator for each output X (32-bit for larger sums) uint32_t* rowAccum = nullptr; // Accumulator for each output X (32-bit for larger sums)
uint32_t* rowCount = nullptr; // Count of source pixels accumulated per output X uint32_t* rowCount = nullptr; // Count of source pixels accumulated per output X
auto cleanupResources = [&]() { // RAII guard: frees all heap resources on any return path, including early exits.
delete[] rowAccum; // Holds references so it always sees the latest pointer values assigned below.
delete[] rowCount; struct Cleanup {
delete atkinsonDitherer; uint8_t*& rowBuffer;
delete fsDitherer; uint8_t*& mcuRowBuffer;
delete atkinson1BitDitherer; AtkinsonDitherer*& atkinsonDitherer;
free(mcuRowBuffer); FloydSteinbergDitherer*& fsDitherer;
free(rowBuffer); Atkinson1BitDitherer*& atkinson1BitDitherer;
}; uint32_t*& rowAccum;
uint32_t*& rowCount;
~Cleanup() {
delete[] rowAccum;
delete[] rowCount;
delete atkinsonDitherer;
delete fsDitherer;
delete atkinson1BitDitherer;
free(mcuRowBuffer);
free(rowBuffer);
}
} cleanup{rowBuffer, mcuRowBuffer, atkinsonDitherer, fsDitherer, atkinson1BitDitherer, rowAccum, rowCount};
// Allocate row buffer // Allocate row buffer
rowBuffer = static_cast<uint8_t*>(malloc(bytesPerRow)); rowBuffer = static_cast<uint8_t*>(malloc(bytesPerRow));
@@ -311,14 +322,12 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
// Validate MCU row buffer size before allocation // Validate MCU row buffer size before allocation
if (mcuRowPixels > MAX_MCU_ROW_BYTES) { if (mcuRowPixels > MAX_MCU_ROW_BYTES) {
LOG_DBG("JPG", "MCU row buffer too large (%d bytes), max: %d", mcuRowPixels, MAX_MCU_ROW_BYTES); LOG_DBG("JPG", "MCU row buffer too large (%d bytes), max: %d", mcuRowPixels, MAX_MCU_ROW_BYTES);
cleanupResources();
return false; return false;
} }
mcuRowBuffer = static_cast<uint8_t*>(malloc(mcuRowPixels)); mcuRowBuffer = static_cast<uint8_t*>(malloc(mcuRowPixels));
if (!mcuRowBuffer) { if (!mcuRowBuffer) {
LOG_ERR("JPG", "Failed to allocate MCU row buffer (%d bytes)", mcuRowPixels); LOG_ERR("JPG", "Failed to allocate MCU row buffer (%d bytes)", mcuRowPixels);
cleanupResources();
return false; return false;
} }
@@ -363,7 +372,6 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
} else { } else {
LOG_ERR("JPG", "JPEG decode MCU failed at (%d, %d) with error code: %d", mcuX, mcuY, mcuStatus); LOG_ERR("JPG", "JPEG decode MCU failed at (%d, %d) with error code: %d", mcuX, mcuY, mcuStatus);
} }
cleanupResources();
return false; return false;
} }
@@ -545,8 +553,6 @@ bool JpegToBmpConverter::jpegFileToBmpStreamInternal(FsFile& jpegFile, Print& bm
} }
} }
cleanupResources();
LOG_DBG("JPG", "Successfully converted JPEG to BMP"); LOG_DBG("JPG", "Successfully converted JPEG to BMP");
return true; return true;
} }