LibGfx: Templatize some of the scanline unpacking code

This commit is contained in:
Andreas Kling 2020-06-02 17:34:56 +02:00
parent 19587934f3
commit 8ea4375d4a
Notes: sideshowbarker 2024-07-19 05:53:05 +09:00

View file

@ -299,33 +299,60 @@ ALWAYS_INLINE static void unfilter_impl(Gfx::Bitmap& bitmap, int y, const void*
}
}
template<typename T>
ALWAYS_INLINE static void unpack_grayscale_without_alpha(PNGLoadingContext& context)
{
for (int y = 0; y < context.height; ++y) {
auto* gray_values = reinterpret_cast<const T*>(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<typename T>
ALWAYS_INLINE static void unpack_grayscale_with_alpha(PNGLoadingContext& context)
{
for (int y = 0; y < context.height; ++y) {
auto* tuples = reinterpret_cast<const Tuple<T>*>(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<typename T>
ALWAYS_INLINE static void unpack_triplets_without_alpha(PNGLoadingContext& context)
{
for (int y = 0; y < context.height; ++y) {
auto* triplets = reinterpret_cast<const Triplet<T>*>(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<u8>(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<u16>(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<u8>*)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<u8>(context);
} else if (context.bit_depth == 16) {
for (int y = 0; y < context.height; ++y) {
auto* tuples = (Tuple<u16>*)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<u16>(context);
} else {
ASSERT_NOT_REACHED();
}
break;
case 2:
if (context.bit_depth == 8) {
for (int y = 0; y < context.height; ++y) {
auto* triplets = (Triplet<u8>*)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<u8>(context);
} else if (context.bit_depth == 16) {
for (int y = 0; y < context.height; ++y) {
auto* triplets = (Triplet<u16>*)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<u16>(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<u16>*)context.scanlines[y].data.data();
auto* triplets = reinterpret_cast<const Quad<u16>*>(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;