mirror of
https://github.com/daveallie/crosspoint-reader.git
synced 2026-02-04 22:57:50 +03:00
fix: rendering correctly + alpha channel
This commit is contained in:
parent
40b5420e11
commit
73f47423e7
@ -155,6 +155,11 @@ BmpReaderError Bitmap::parseHeaders() {
|
|||||||
if (colorsUsed > 256u) return BmpReaderError::PaletteTooLarge;
|
if (colorsUsed > 256u) return BmpReaderError::PaletteTooLarge;
|
||||||
seekCur(4);
|
seekCur(4);
|
||||||
|
|
||||||
|
// Robustness Fix: Skip extended header bytes (V4/V5)
|
||||||
|
if (biSize > 40) {
|
||||||
|
seekCur(biSize - 40);
|
||||||
|
}
|
||||||
|
|
||||||
if (width <= 0 || height <= 0) return BmpReaderError::BadDimensions;
|
if (width <= 0 || height <= 0) return BmpReaderError::BadDimensions;
|
||||||
|
|
||||||
constexpr int MAX_IMAGE_WIDTH = 2048;
|
constexpr int MAX_IMAGE_WIDTH = 2048;
|
||||||
@ -165,11 +170,33 @@ BmpReaderError Bitmap::parseHeaders() {
|
|||||||
|
|
||||||
rowBytes = (width * bpp + 31) / 32 * 4;
|
rowBytes = (width * bpp + 31) / 32 * 4;
|
||||||
|
|
||||||
for (int i = 0; i < 256; i++) paletteLum[i] = static_cast<uint8_t>(i);
|
// Initialize safe default palette
|
||||||
if (colorsUsed > 0) {
|
if (bpp == 1) {
|
||||||
for (uint32_t i = 0; i < colorsUsed; i++) {
|
// For 1-bit, default to Black(0) and White(1)
|
||||||
|
paletteLum[0] = 0;
|
||||||
|
paletteLum[1] = 255;
|
||||||
|
} else if (bpp <= 8) {
|
||||||
|
int maxIdx = (1 << bpp) - 1;
|
||||||
|
for (int i = 0; i <= maxIdx; i++) {
|
||||||
|
paletteLum[i] = (i * 255) / maxIdx;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (int i = 0; i < 256; i++) paletteLum[i] = static_cast<uint8_t>(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
// If indexed color (<=8bpp), we MUST load the palette.
|
||||||
|
// The palette is located AFTER the DIB header.
|
||||||
|
if (bpp <= 8) {
|
||||||
|
// Explicit seek to palette start
|
||||||
|
if (!seekSet(14 + biSize)) return BmpReaderError::SeekStartFailed;
|
||||||
|
|
||||||
|
uint32_t colorsToRead = colorsUsed;
|
||||||
|
if (colorsToRead == 0) colorsToRead = 1 << bpp;
|
||||||
|
if (colorsToRead > 256) colorsToRead = 256;
|
||||||
|
|
||||||
|
for (uint32_t i = 0; i < colorsToRead; i++) {
|
||||||
uint8_t rgb[4];
|
uint8_t rgb[4];
|
||||||
readBytes(rgb, 4);
|
if (readBytes(rgb, 4) != 4) break;
|
||||||
paletteLum[i] = (77u * rgb[2] + 150u * rgb[1] + 29u * rgb[0]) >> 8;
|
paletteLum[i] = (77u * rgb[2] + 150u * rgb[1] + 29u * rgb[0]) >> 8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +251,14 @@ BmpReaderError Bitmap::readNextRow(uint8_t* data, uint8_t* rowBuffer) const {
|
|||||||
case 32: {
|
case 32: {
|
||||||
const uint8_t* p = rowBuffer;
|
const uint8_t* p = rowBuffer;
|
||||||
for (int x = 0; x < width; x++) {
|
for (int x = 0; x < width; x++) {
|
||||||
uint8_t lum = (77u * p[2] + 150u * p[1] + 29u * p[0]) >> 8;
|
uint8_t lum; // Declare lum here
|
||||||
|
// Handle Alpha channel (byte 3). If transparent (<128), treat as White.
|
||||||
|
// This fixes 32-bit icons appearing as black squares on white backgrounds.
|
||||||
|
if (p[3] < 128) {
|
||||||
|
lum = 255;
|
||||||
|
} else {
|
||||||
|
lum = (77u * p[2] + 150u * p[1] + 29u * p[0]) >> 8;
|
||||||
|
}
|
||||||
packPixel(lum);
|
packPixel(lum);
|
||||||
p += 4;
|
p += 4;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -584,7 +584,13 @@ void GfxRenderer::drawBitmap(const Bitmap &bitmap, const int x, const int y,
|
|||||||
|
|
||||||
const uint8_t val = outputRow[bmpX / 4] >> (6 - ((bmpX * 2) % 8)) & 0x3;
|
const uint8_t val = outputRow[bmpX / 4] >> (6 - ((bmpX * 2) % 8)) & 0x3;
|
||||||
|
|
||||||
if (renderMode == BW && val < 3) {
|
// In BW mode:
|
||||||
|
// 0 = Black (< 45)
|
||||||
|
// 1 = Dark Gray (< 70)
|
||||||
|
// 2 = Light Gray (< 140)
|
||||||
|
// 3 = White
|
||||||
|
// Draw black for val < 2 (everything below 70), treating Light Gray as White.
|
||||||
|
if (renderMode == BW && val < 2) {
|
||||||
drawPixel(screenX, screenY);
|
drawPixel(screenX, screenY);
|
||||||
} else if (renderMode == GRAYSCALE_MSB && (val == 1 || val == 2)) {
|
} else if (renderMode == GRAYSCALE_MSB && (val == 1 || val == 2)) {
|
||||||
drawPixel(screenX, screenY, false);
|
drawPixel(screenX, screenY, false);
|
||||||
@ -631,8 +637,9 @@ void GfxRenderer::draw2BitImage(const uint8_t data[], int x, int y, int w,
|
|||||||
// Extract 2-bit value (4 pixels per byte)
|
// Extract 2-bit value (4 pixels per byte)
|
||||||
const uint8_t val = (srcRow[col / 4] >> (6 - ((col % 4) * 2))) & 0x3;
|
const uint8_t val = (srcRow[col / 4] >> (6 - ((col % 4) * 2))) & 0x3;
|
||||||
|
|
||||||
// val < 3 means black pixel in 2-bit representation
|
// val < 2 means black pixel in 2-bit representation (0=Black, 1=DarkGray)
|
||||||
if (val < 3) {
|
// 2=LightGray, 3=White -> Treat as White
|
||||||
|
if (val < 2) {
|
||||||
// In Portrait: physical Y = DISPLAY_HEIGHT - 1 - screenX
|
// In Portrait: physical Y = DISPLAY_HEIGHT - 1 - screenX
|
||||||
const int physY = HalDisplay::DISPLAY_HEIGHT - 1 - screenX;
|
const int physY = HalDisplay::DISPLAY_HEIGHT - 1 - screenX;
|
||||||
const uint16_t byteIndex =
|
const uint16_t byteIndex =
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user