Skip to content

Commit

Permalink
Common: fix loaded images without alpha converted to 32-bit
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-mogilko committed Jan 5, 2025
1 parent 979704b commit 3d40a28
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
7 changes: 5 additions & 2 deletions Common/gfx/bitmap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ void ReadPixelsFromMemory(Bitmap *dst, const uint8_t *src_buffer, const size_t s

// Converts loaded bitmap to the requested color depth,
// optionally fixups color palette
static Bitmap *BitmapColorDepthFixup(Bitmap *bmp, int dst_color_depth, RGB *pal)
static Bitmap *BitmapColorDepthFixup(Bitmap *bmp, int dst_color_depth, RGB *pal, bool src_has_alpha)
{
int bmp_depth = bmp->GetColorDepth();
int dest_depth = get_color_load_depth(bmp_depth, false);
Expand All @@ -301,6 +301,9 @@ static Bitmap *BitmapColorDepthFixup(Bitmap *bmp, int dst_color_depth, RGB *pal)
bmp->WrapAllegroBitmap(al_bmp, false);
}

if ((dest_depth == 32) && !src_has_alpha)
BitmapHelper::MakeOpaqueSkipMask(bmp);

/* construct a fake palette if 8-bit mode is not involved */
if ((bmp_depth != 8) && (dest_depth != 8) && pal)
generate_332_palette(pal);
Expand All @@ -322,7 +325,7 @@ Bitmap* LoadBitmap(Stream *in, const String& ext, int dst_color_depth, RGB *pal)
if (!bmp)
return nullptr;
// Perform color depth and palette fixups
Bitmap *fixed_bmp = BitmapColorDepthFixup(bmp, dst_color_depth, pal);
Bitmap *fixed_bmp = BitmapColorDepthFixup(bmp, dst_color_depth, pal, pxbuf.HasAlphaChannel());
if (fixed_bmp != bmp)
delete bmp;
return fixed_bmp;
Expand Down
7 changes: 5 additions & 2 deletions Common/gfx/bitmapdata.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ enum PixelFormat
kPxFmt_R5G6B5, // 16-bit R5G6B5, historical 16-bit pixel format in AGS
kPxFmt_R8G8B8, // 24-bit RGB (no alpha)
kPxFmt_A8R8G8B8, // 32-bit ARGB
kPxFmt_X8R8G8B8, // 32-bit RGB with no valid alpha
};

// Returns bits-per-pixel from format
Expand All @@ -55,6 +56,7 @@ inline int PixelFormatToPixelBits(PixelFormat fmt)
case kPxFmt_R5G6B5: return 16;
case kPxFmt_R8G8B8: return 24;
case kPxFmt_A8R8G8B8: return 32;
case kPxFmt_X8R8G8B8: return 32;
default: return 0;
}
}
Expand All @@ -64,7 +66,7 @@ inline int PixelFormatToPixelBytes(PixelFormat fmt)
return (PixelFormatToPixelBits(fmt) + 7) / 8;
}

inline PixelFormat ColorDepthToPixelFormat(int color_depth)
inline PixelFormat ColorDepthToPixelFormat(int color_depth, bool alpha_valid = true)
{
switch (color_depth)
{
Expand All @@ -74,7 +76,7 @@ inline PixelFormat ColorDepthToPixelFormat(int color_depth)
case 15: return kPxFmt_R5G5B5;
case 16: return kPxFmt_R5G6B5;
case 24: return kPxFmt_R8G8B8;
case 32: return kPxFmt_A8R8G8B8;
case 32: return alpha_valid ? kPxFmt_A8R8G8B8 : kPxFmt_X8R8G8B8;
default: return kPxFmt_Undefined;
}
}
Expand Down Expand Up @@ -119,6 +121,7 @@ class BitmapData
operator bool() const { return _cbuf != nullptr; }

inline PixelFormat GetFormat() const { return _format; }
inline bool HasAlphaChannel() const { return _format == kPxFmt_A8R8G8B8; }
inline int GetColorDepth() const { return _bitsPerPixel; }
inline int GetWidth() const { return _width; }
inline int GetHeight() const { return _height; }
Expand Down
9 changes: 8 additions & 1 deletion Common/gfx/image_file.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -559,6 +559,7 @@ PixelBuffer LoadBMP(Stream *in, RGB *pal) {
int rMask = 0;
int gMask = 0;
int bMask = 0;
bool hasAlpha = false;

const soff_t format_at = in->GetPosition(); // starting offset

Expand Down Expand Up @@ -610,6 +611,8 @@ PixelBuffer LoadBMP(Stream *in, RGB *pal) {
rMask = in->ReadInt32();
gMask = in->ReadInt32();
bMask = in->ReadInt32();
// TODO: might need to support alpha bits, if it's present in the header
// also set hasAlpha = true in such case
} else {
bmp_read_palette(hdr.offsetBits - 54, pal, in, false);
}
Expand Down Expand Up @@ -643,7 +646,11 @@ PixelBuffer LoadBMP(Stream *in, RGB *pal) {
if (bpp < 8)
bpp = 8;

PixelBuffer pxdata(w, h, ColorDepthToPixelFormat(bpp));
// TODO: if we support loading 32-bit ARGB images (existing old BMP loader code doesn't),
// then we might also have to test if there's ANY alpha present in the image
// AFTER decoding the pixel data, and adjust the format info (?).

PixelBuffer pxdata(w, h, ColorDepthToPixelFormat(bpp, hasAlpha));
if (!pxdata) {
return {};
}
Expand Down

0 comments on commit 3d40a28

Please sign in to comment.