From e5a598414fbf142d3f7c150b8bdb6856ea268218 Mon Sep 17 00:00:00 2001 From: LepkoQQ Date: Sun, 26 Apr 2020 20:02:30 +0200 Subject: [PATCH] LibGfx: PNGLoader support for grayscale images with alpha. --- Libraries/LibGfx/PNGLoader.cpp | 44 +++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) diff --git a/Libraries/LibGfx/PNGLoader.cpp b/Libraries/LibGfx/PNGLoader.cpp index 9c4c686368..a7e64b8a9b 100644 --- a/Libraries/LibGfx/PNGLoader.cpp +++ b/Libraries/LibGfx/PNGLoader.cpp @@ -67,6 +67,18 @@ struct [[gnu::packed]] PaletteEntry //u8 a; }; +struct [[gnu::packed]] Tuple +{ + u8 gray; + u8 a; +}; + +struct [[gnu::packed]] Tuple16 +{ + u16 gray; + u16 a; +}; + struct [[gnu::packed]] Triplet { u8 r; @@ -331,6 +343,33 @@ template ASSERT_NOT_REACHED(); } break; + case 4: + if (context.bit_depth == 8) { + for (int y = 0; y < context.height; ++y) { + auto* tuples = (Tuple*)context.scanlines[y].data.data(); + for (int i = 0; i < context.width; ++i) { + auto& pixel = (Pixel&)context.bitmap->scanline(y)[i]; + pixel.r = tuples[i].gray; + pixel.g = tuples[i].gray; + pixel.b = tuples[i].gray; + pixel.a = tuples[i].a; + } + } + } else if (context.bit_depth == 16) { + for (int y = 0; y < context.height; ++y) { + auto* tuples = (Tuple16*)context.scanlines[y].data.data(); + for (int i = 0; i < context.width; ++i) { + auto& pixel = (Pixel&)context.bitmap->scanline(y)[i]; + pixel.r = tuples[i].gray & 0xFF; + pixel.g = tuples[i].gray & 0xFF; + pixel.b = tuples[i].gray & 0xFF; + pixel.a = tuples[i].a & 0xFF; + } + } + } else { + ASSERT_NOT_REACHED(); + } + break; case 2: if (context.bit_depth == 8) { for (int y = 0; y < context.height; ++y) { @@ -617,9 +656,8 @@ static bool process_IHDR(const ByteBuffer& data, PNGLoadingContext& context, boo context.bytes_per_pixel = ihdr.bit_depth / 8; break; case 4: // Each pixel is a grayscale sample, followed by an alpha sample. - // FIXME: Implement grayscale PNG support. - dbgprintf("PNGLoader::process_IHDR: Unsupported grayscale format.\n"); - return false; + context.bytes_per_pixel = 2 * ihdr.bit_depth / 8; + break; case 2: context.bytes_per_pixel = 3 * (ihdr.bit_depth / 8); break;