Establish png lazy transparency detection
This commit is contained in:
@@ -34,8 +34,11 @@ struct PngOverlayCtx {
|
|||||||
float yScale;
|
float yScale;
|
||||||
int lastDstY;
|
int lastDstY;
|
||||||
// Color-key transparency (tRNS chunk) for TRUECOLOR and GRAYSCALE images.
|
// Color-key transparency (tRNS chunk) for TRUECOLOR and GRAYSCALE images.
|
||||||
// -1 means no color key. For TRUECOLOR: 0x00RRGGBB; for GRAYSCALE: low byte only.
|
// Initialized lazily on the first draw callback because tRNS is processed during decode(),
|
||||||
|
// not during open() — so hasAlpha()/getTransparentColor() are only valid once decode() starts.
|
||||||
|
// -2 = not yet read; -1 = no color key; >=0 = 0x00RRGGBB (TRUECOLOR) or low-byte gray.
|
||||||
int32_t transparentColor;
|
int32_t transparentColor;
|
||||||
|
PNG* pngObj; // for lazy-init of transparentColor on first callback
|
||||||
};
|
};
|
||||||
|
|
||||||
// PNGdec file I/O callbacks — mirror the pattern in PngToFramebufferConverter.cpp.
|
// PNGdec file I/O callbacks — mirror the pattern in PngToFramebufferConverter.cpp.
|
||||||
@@ -71,6 +74,15 @@ int32_t pngSleepSeek(PNGFILE* pFile, int32_t pos) {
|
|||||||
int pngOverlayDraw(PNGDRAW* pDraw) {
|
int pngOverlayDraw(PNGDRAW* pDraw) {
|
||||||
PngOverlayCtx* ctx = reinterpret_cast<PngOverlayCtx*>(pDraw->pUser);
|
PngOverlayCtx* ctx = reinterpret_cast<PngOverlayCtx*>(pDraw->pUser);
|
||||||
|
|
||||||
|
// Lazy-init: tRNS chunk is processed during decode() before any IDAT data, so by the time
|
||||||
|
// the first draw callback fires, hasAlpha() / getTransparentColor() are already valid.
|
||||||
|
if (ctx->transparentColor == -2) {
|
||||||
|
const int pt = pDraw->iPixelType;
|
||||||
|
ctx->transparentColor = (pDraw->iHasAlpha && (pt == PNG_PIXEL_TRUECOLOR || pt == PNG_PIXEL_GRAYSCALE))
|
||||||
|
? (int32_t)ctx->pngObj->getTransparentColor()
|
||||||
|
: -1;
|
||||||
|
}
|
||||||
|
|
||||||
const int destY = ctx->dstY + (int)(pDraw->y * ctx->yScale);
|
const int destY = ctx->dstY + (int)(pDraw->y * ctx->yScale);
|
||||||
if (destY == ctx->lastDstY) return 1; // skip duplicate rows from Y scaling
|
if (destY == ctx->lastDstY) return 1; // skip duplicate rows from Y scaling
|
||||||
ctx->lastDstY = destY;
|
ctx->lastDstY = destY;
|
||||||
@@ -520,13 +532,8 @@ void SleepActivity::renderOverlaySleepScreen() const {
|
|||||||
ctx.dstY = (pageHeight - dstH) / 2;
|
ctx.dstY = (pageHeight - dstH) / 2;
|
||||||
ctx.yScale = yScale;
|
ctx.yScale = yScale;
|
||||||
ctx.lastDstY = -1;
|
ctx.lastDstY = -1;
|
||||||
// Populate color-key transparency for TRUECOLOR/GRAYSCALE PNGs with a tRNS chunk.
|
ctx.transparentColor = -2; // will be resolved on first draw callback (after tRNS is parsed)
|
||||||
// TRUECOLOR_ALPHA and GRAY_ALPHA carry per-pixel alpha, handled directly in the callback.
|
ctx.pngObj = png;
|
||||||
// INDEXED+tRNS stores per-palette alpha at pPalette[768+idx], also handled there.
|
|
||||||
const int pixType = png->getPixelType();
|
|
||||||
ctx.transparentColor = (png->hasAlpha() && (pixType == PNG_PIXEL_TRUECOLOR || pixType == PNG_PIXEL_GRAYSCALE))
|
|
||||||
? (int32_t)png->getTransparentColor()
|
|
||||||
: -1;
|
|
||||||
|
|
||||||
rc = png->decode(&ctx, 0);
|
rc = png->decode(&ctx, 0);
|
||||||
png->close();
|
png->close();
|
||||||
|
|||||||
Reference in New Issue
Block a user