From 8ea4375d4ad050cc869ebaf52edd8389c0da8bca Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Tue, 2 Jun 2020 17:34:56 +0200 Subject: [PATCH] LibGfx: Templatize some of the scanline unpacking code --- Libraries/LibGfx/PNGLoader.cpp | 113 +++++++++++++++------------------ 1 file changed, 52 insertions(+), 61 deletions(-) diff --git a/Libraries/LibGfx/PNGLoader.cpp b/Libraries/LibGfx/PNGLoader.cpp index 65090e3e79..584b77bc6c 100644 --- a/Libraries/LibGfx/PNGLoader.cpp +++ b/Libraries/LibGfx/PNGLoader.cpp @@ -299,33 +299,60 @@ ALWAYS_INLINE static void unfilter_impl(Gfx::Bitmap& bitmap, int y, const void* } } +template +ALWAYS_INLINE static void unpack_grayscale_without_alpha(PNGLoadingContext& context) +{ + for (int y = 0; y < context.height; ++y) { + auto* gray_values = 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 = gray_values[i]; + pixel.g = gray_values[i]; + pixel.b = gray_values[i]; + pixel.a = 0xff; + } + } +} + +template +ALWAYS_INLINE static void unpack_grayscale_with_alpha(PNGLoadingContext& context) +{ + for (int y = 0; y < context.height; ++y) { + auto* tuples = 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 = tuples[i].gray; + pixel.g = tuples[i].gray; + pixel.b = tuples[i].gray; + pixel.a = tuples[i].a; + } + } +} + +template +ALWAYS_INLINE static void unpack_triplets_without_alpha(PNGLoadingContext& context) +{ + 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; + pixel.a = 0xff; + } + } +} + NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context) { // First unpack the scanlines to RGBA: switch (context.color_type) { case 0: if (context.bit_depth == 8) { - for (int y = 0; y < context.height; ++y) { - auto* gray_values = (u8*)context.scanlines[y].data.data(); - for (int i = 0; i < context.width; ++i) { - auto& pixel = (Pixel&)context.bitmap->scanline(y)[i]; - pixel.r = gray_values[i]; - pixel.g = gray_values[i]; - pixel.b = gray_values[i]; - pixel.a = 0xff; - } - } + unpack_grayscale_without_alpha(context); } else if (context.bit_depth == 16) { - for (int y = 0; y < context.height; ++y) { - auto* gray_values = (u16*)context.scanlines[y].data.data(); - for (int i = 0; i < context.width; ++i) { - auto& pixel = (Pixel&)context.bitmap->scanline(y)[i]; - pixel.r = gray_values[i] & 0xFF; - pixel.g = gray_values[i] & 0xFF; - pixel.b = gray_values[i] & 0xFF; - pixel.a = 0xff; - } - } + unpack_grayscale_without_alpha(context); } else if (context.bit_depth == 1 || context.bit_depth == 2 || context.bit_depth == 4) { auto pixels_per_byte = 8 / context.bit_depth; auto mask = (1 << context.bit_depth) - 1; @@ -347,54 +374,18 @@ NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context) 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; - } - } + unpack_grayscale_with_alpha(context); } else if (context.bit_depth == 16) { - 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 & 0xFF; - pixel.g = tuples[i].gray & 0xFF; - pixel.b = tuples[i].gray & 0xFF; - pixel.a = tuples[i].a & 0xFF; - } - } + unpack_grayscale_with_alpha(context); } else { ASSERT_NOT_REACHED(); } break; case 2: if (context.bit_depth == 8) { - for (int y = 0; y < context.height; ++y) { - auto* triplets = (Triplet*)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; - pixel.a = 0xff; - } - } + unpack_triplets_without_alpha(context); } else if (context.bit_depth == 16) { - for (int y = 0; y < context.height; ++y) { - auto* triplets = (Triplet*)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 & 0xFF; - pixel.g = triplets[i].g & 0xFF; - pixel.b = triplets[i].b & 0xFF; - pixel.a = 0xff; - } - } + unpack_grayscale_without_alpha(context); } else { ASSERT_NOT_REACHED(); } @@ -406,7 +397,7 @@ NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context) } } else if (context.bit_depth == 16) { for (int y = 0; y < context.height; ++y) { - auto* triplets = (Quad*)context.scanlines[y].data.data(); + 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 & 0xFF;