From 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d Mon Sep 17 00:00:00 2001 From: Jef Date: Tue, 24 Sep 2024 14:54:57 +0200 Subject: Initial community commit --- .../openmpt-trunk/mptrack/Image.h | 137 +++++++++++++++++++++ 1 file changed, 137 insertions(+) create mode 100644 Src/external_dependencies/openmpt-trunk/mptrack/Image.h (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/Image.h') diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/Image.h b/Src/external_dependencies/openmpt-trunk/mptrack/Image.h new file mode 100644 index 00000000..8ac3c788 --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/mptrack/Image.h @@ -0,0 +1,137 @@ +/* + * Image.h + * ------- + * Purpose: Bitmap and Vector image file handling. + * Notes : (currently none) + * Authors: OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#pragma once + +#include "openmpt/all/BuildSettings.hpp" + +#include "../common/FileReaderFwd.h" + +// GDI+ +namespace Gdiplus { +#include +class Image; +class Bitmap; +class Metafile; +} + + +OPENMPT_NAMESPACE_BEGIN + + +class bad_image : public std::runtime_error { public: bad_image() : std::runtime_error("") { } }; + + +class RawGDIDIB +{ +public: + struct Pixel + { + // Component order must be compatible with Microsoft DIBs! + uint8 b; + uint8 g; + uint8 r; + uint8 a; + constexpr Pixel() noexcept + : b(0), g(0), r(0), a(0) {} + constexpr Pixel(uint8 r, uint8 g, uint8 b, uint8 a) noexcept + : b(b), g(g), r(r), a(a) {} + constexpr Pixel(COLORREF color) noexcept + : b(GetBValue(color)), g(GetGValue(color)), r(GetRValue(color)), a(0) {} + }; +private: + uint32 width; + uint32 height; + std::vector pixels; +public: + RawGDIDIB(uint32 width, uint32 height); +public: + constexpr uint32 Width() const noexcept { return width; } + constexpr uint32 Height() const noexcept { return height; } + MPT_FORCEINLINE Pixel &operator()(uint32 x, uint32 y) noexcept { return pixels[y * width + x]; } + MPT_FORCEINLINE const Pixel &operator()(uint32 x, uint32 y) const noexcept { return pixels[y * width + x]; } + std::vector &Pixels() { return pixels; } + const std::vector &Pixels() const { return pixels; } +}; + + +class GdiplusRAII +{ +private: + ULONG_PTR gdiplusToken = 0; +public: + GdiplusRAII(); + ~GdiplusRAII(); +}; + + +namespace GDIP +{ + + std::unique_ptr LoadPixelImage(mpt::const_byte_span file); + std::unique_ptr LoadPixelImage(FileReader file); + + std::unique_ptr LoadVectorImage(mpt::const_byte_span file); + std::unique_ptr LoadVectorImage(FileReader file); + + std::unique_ptr ResizeImage(Gdiplus::Image &src, double scaling, int spriteWidth = 0, int spriteHeight = 0); + std::unique_ptr ResizeImage(Gdiplus::Bitmap &src, double scaling, int spriteWidth = 0, int spriteHeight = 0); + + using Pixel = Gdiplus::ARGB; + + template + inline Pixel * GetScanline(const TBitmapData &bitmapData, std::size_t y) noexcept + { + if(bitmapData.Stride >= 0) + { + return reinterpret_cast(mpt::void_cast(mpt::void_cast(bitmapData.Scan0) + y * bitmapData.Stride)); + } else + { + return reinterpret_cast(mpt::void_cast(mpt::void_cast(bitmapData.Scan0) + (bitmapData.Height - 1 - y) * (-bitmapData.Stride))); + } + } + + constexpr Pixel AsPixel(uint8 r, uint8 g, uint8 b, uint8 a) noexcept + { + return Pixel(0) + | (static_cast(r) << RED_SHIFT) + | (static_cast(g) << GREEN_SHIFT) + | (static_cast(b) << BLUE_SHIFT) + | (static_cast(a) << ALPHA_SHIFT) + ; + } + + constexpr uint8 R(Pixel p) noexcept { return static_cast(p >> RED_SHIFT); } + constexpr uint8 G(Pixel p) noexcept { return static_cast(p >> GREEN_SHIFT); } + constexpr uint8 B(Pixel p) noexcept { return static_cast(p >> BLUE_SHIFT); } + constexpr uint8 A(Pixel p) noexcept { return static_cast(p >> ALPHA_SHIFT); } + + constexpr RawGDIDIB::Pixel ToRawGDIDIB(Pixel p) noexcept + { + return RawGDIDIB::Pixel(GDIP::R(p), GDIP::G(p), GDIP::B(p), GDIP::A(p)); + } + +} // namespace GDIP + + +std::unique_ptr ToRawGDIDIB(Gdiplus::Bitmap &bitmap); + +bool CopyToCompatibleBitmap(CBitmap &dst, CDC &dc, const RawGDIDIB &src); + +bool CopyToCompatibleBitmap(CBitmap &dst, CDC &dc, Gdiplus::Image &src); + +std::unique_ptr LoadPixelImage(mpt::const_byte_span file, double scaling = 1.0, int spriteWidth = 0, int spriteHeight = 0); +std::unique_ptr LoadPixelImage(FileReader file, double scaling = 1.0, int spriteWidth = 0, int spriteHeight = 0); + +bool LoadCompatibleBitmapFromPixelImage(CBitmap &dst, CDC &dc, mpt::const_byte_span file); +bool LoadCompatibleBitmapFromPixelImage(CBitmap &dst, CDC &dc, FileReader file); + + +OPENMPT_NAMESPACE_END -- cgit