mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 09:57:34 +00:00
LibGfx: Templatize some of the scanline unpacking code
This commit is contained in:
parent
19587934f3
commit
8ea4375d4a
1 changed files with 52 additions and 61 deletions
|
@ -299,14 +299,11 @@ ALWAYS_INLINE static void unfilter_impl(Gfx::Bitmap& bitmap, int y, const void*
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context)
|
template<typename T>
|
||||||
|
ALWAYS_INLINE static void unpack_grayscale_without_alpha(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) {
|
for (int y = 0; y < context.height; ++y) {
|
||||||
auto* gray_values = (u8*)context.scanlines[y].data.data();
|
auto* gray_values = reinterpret_cast<const T*>(context.scanlines[y].data.data());
|
||||||
for (int i = 0; i < context.width; ++i) {
|
for (int i = 0; i < context.width; ++i) {
|
||||||
auto& pixel = (Pixel&)context.bitmap->scanline(y)[i];
|
auto& pixel = (Pixel&)context.bitmap->scanline(y)[i];
|
||||||
pixel.r = gray_values[i];
|
pixel.r = gray_values[i];
|
||||||
|
@ -315,17 +312,47 @@ NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context)
|
||||||
pixel.a = 0xff;
|
pixel.a = 0xff;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (context.bit_depth == 16) {
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
ALWAYS_INLINE static void unpack_grayscale_with_alpha(PNGLoadingContext& context)
|
||||||
|
{
|
||||||
for (int y = 0; y < context.height; ++y) {
|
for (int y = 0; y < context.height; ++y) {
|
||||||
auto* gray_values = (u16*)context.scanlines[y].data.data();
|
auto* tuples = reinterpret_cast<const Tuple<T>*>(context.scanlines[y].data.data());
|
||||||
for (int i = 0; i < context.width; ++i) {
|
for (int i = 0; i < context.width; ++i) {
|
||||||
auto& pixel = (Pixel&)context.bitmap->scanline(y)[i];
|
auto& pixel = (Pixel&)context.bitmap->scanline(y)[i];
|
||||||
pixel.r = gray_values[i] & 0xFF;
|
pixel.r = tuples[i].gray;
|
||||||
pixel.g = gray_values[i] & 0xFF;
|
pixel.g = tuples[i].gray;
|
||||||
pixel.b = gray_values[i] & 0xFF;
|
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;
|
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) {
|
||||||
|
unpack_grayscale_without_alpha<u8>(context);
|
||||||
|
} else if (context.bit_depth == 16) {
|
||||||
|
unpack_grayscale_without_alpha<u16>(context);
|
||||||
} else if (context.bit_depth == 1 || context.bit_depth == 2 || context.bit_depth == 4) {
|
} else if (context.bit_depth == 1 || context.bit_depth == 2 || context.bit_depth == 4) {
|
||||||
auto pixels_per_byte = 8 / context.bit_depth;
|
auto pixels_per_byte = 8 / context.bit_depth;
|
||||||
auto mask = (1 << context.bit_depth) - 1;
|
auto mask = (1 << context.bit_depth) - 1;
|
||||||
|
@ -347,54 +374,18 @@ NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context)
|
||||||
break;
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
if (context.bit_depth == 8) {
|
if (context.bit_depth == 8) {
|
||||||
for (int y = 0; y < context.height; ++y) {
|
unpack_grayscale_with_alpha<u8>(context);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (context.bit_depth == 16) {
|
} else if (context.bit_depth == 16) {
|
||||||
for (int y = 0; y < context.height; ++y) {
|
unpack_grayscale_with_alpha<u16>(context);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
if (context.bit_depth == 8) {
|
if (context.bit_depth == 8) {
|
||||||
for (int y = 0; y < context.height; ++y) {
|
unpack_triplets_without_alpha<u8>(context);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (context.bit_depth == 16) {
|
} else if (context.bit_depth == 16) {
|
||||||
for (int y = 0; y < context.height; ++y) {
|
unpack_grayscale_without_alpha<u16>(context);
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
ASSERT_NOT_REACHED();
|
ASSERT_NOT_REACHED();
|
||||||
}
|
}
|
||||||
|
@ -406,7 +397,7 @@ NEVER_INLINE FLATTEN static void unfilter(PNGLoadingContext& context)
|
||||||
}
|
}
|
||||||
} else if (context.bit_depth == 16) {
|
} else if (context.bit_depth == 16) {
|
||||||
for (int y = 0; y < context.height; ++y) {
|
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) {
|
for (int i = 0; i < context.width; ++i) {
|
||||||
auto& pixel = (Pixel&)context.bitmap->scanline(y)[i];
|
auto& pixel = (Pixel&)context.bitmap->scanline(y)[i];
|
||||||
pixel.r = triplets[i].r & 0xFF;
|
pixel.r = triplets[i].r & 0xFF;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue