diff --git a/Userland/Libraries/LibGfx/PNGLoader.cpp b/Userland/Libraries/LibGfx/PNGLoader.cpp index 8d723d4768..4dc64e36a6 100644 --- a/Userland/Libraries/LibGfx/PNGLoader.cpp +++ b/Userland/Libraries/LibGfx/PNGLoader.cpp @@ -54,6 +54,8 @@ struct [[gnu::packed]] Triplet { T r; T g; T b; + + bool operator==(Triplet const& other) const = default; }; template @@ -313,6 +315,24 @@ ALWAYS_INLINE static void unpack_triplets_without_alpha(PNGLoadingContext& conte } } +template +ALWAYS_INLINE static void unpack_triplets_with_transparency_value(PNGLoadingContext& context, Triplet transparency_value) +{ + for (int y = 0; y < context.height; ++y) { + auto* triplets = reinterpret_cast*>(context.scanlines[y].data.data()); + for (int i = 0; i < context.width; ++i) { + auto& pixel = (Pixel&)context.bitmap->scanline(y)[i]; + pixel.r = triplets[i].r; + pixel.g = triplets[i].g; + pixel.b = triplets[i].b; + if (triplets[i] == transparency_value) + pixel.a = 0x00; + else + pixel.a = 0xff; + } + } +} + NEVER_INLINE FLATTEN static ErrorOr unfilter(PNGLoadingContext& context) { // First unpack the scanlines to RGBA: @@ -352,12 +372,24 @@ NEVER_INLINE FLATTEN static ErrorOr unfilter(PNGLoadingContext& context) } break; case 2: - if (context.bit_depth == 8) { - unpack_triplets_without_alpha(context); - } else if (context.bit_depth == 16) { - unpack_triplets_without_alpha(context); + if (context.palette_transparency_data.size() == 6) { + if (context.bit_depth == 8) { + unpack_triplets_with_transparency_value(context, Triplet { context.palette_transparency_data[0], context.palette_transparency_data[2], context.palette_transparency_data[4] }); + } else if (context.bit_depth == 16) { + u16 tr = context.palette_transparency_data[0] | context.palette_transparency_data[1] << 8; + u16 tg = context.palette_transparency_data[2] | context.palette_transparency_data[3] << 8; + u16 tb = context.palette_transparency_data[4] | context.palette_transparency_data[5] << 8; + unpack_triplets_with_transparency_value(context, Triplet { tr, tg, tb }); + } else { + VERIFY_NOT_REACHED(); + } } else { - VERIFY_NOT_REACHED(); + if (context.bit_depth == 8) + unpack_triplets_without_alpha(context); + else if (context.bit_depth == 16) + unpack_triplets_without_alpha(context); + else + VERIFY_NOT_REACHED(); } break; case 6: