Mercurial > foo_out_sdl
comparison foosdk/sdk/libPPUI/gdiplus-helpers-webp.h @ 1:20d02a178406 default tip
*: check in everything else
yay
| author | Paper <paper@tflc.us> |
|---|---|
| date | Mon, 05 Jan 2026 02:15:46 -0500 |
| parents | |
| children |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #pragma once | |
| 2 | |
| 3 #include "gdiplus_helpers.h" | |
| 4 | |
| 5 // Presumes prior #include of webp/decode.h | |
| 6 | |
| 7 inline bool IsImageWebP(const void * ptr, size_t bytes) { | |
| 8 if (bytes < 12) return false; | |
| 9 return memcmp(ptr, "RIFF", 4) == 0 && memcmp((const char*)ptr + 8, "WEBP", 4) == 0; | |
| 10 } | |
| 11 | |
| 12 | |
| 13 // WebP-aware GdiplusImageFromMem | |
| 14 static std::unique_ptr<Gdiplus::Image> GdiplusImageFromMem2(const void * ptr, size_t bytes) { | |
| 15 GdiplusErrorHandler EH; | |
| 16 using namespace Gdiplus; | |
| 17 if (IsImageWebP(ptr, bytes)) { | |
| 18 WebPBitstreamFeatures bs; | |
| 19 if (WebPGetFeatures((const uint8_t*)ptr, bytes, &bs) != VP8_STATUS_OK) { | |
| 20 throw std::runtime_error("WebP decoding failure"); | |
| 21 } | |
| 22 const Gdiplus::PixelFormat pf = bs.has_alpha ? PixelFormat32bppARGB : PixelFormat32bppRGB; | |
| 23 const int pfBytes = 4; // Gdiplus RGB is 4 bytes | |
| 24 int w = 0, h = 0; | |
| 25 // ALWAYS decode BGRA, Gdiplus will disregard alpha if was not originally present | |
| 26 uint8_t * decodedData = WebPDecodeBGRA((const uint8_t*)ptr, bytes, &w, &h); | |
| 27 pfc::onLeaving scope([decodedData] {WebPFree(decodedData); }); | |
| 28 if (decodedData == nullptr || w <= 0 || h <= 0) throw std::runtime_error("WebP decoding failure"); | |
| 29 | |
| 30 std::unique_ptr<Bitmap> ret ( new Gdiplus::Bitmap(w, h, pf) ); | |
| 31 EH << ret->GetLastStatus(); | |
| 32 Rect rc(0, 0, w, h); | |
| 33 Gdiplus::BitmapData bitmapData; | |
| 34 EH << ret->LockBits(&rc, 0, pf, &bitmapData); | |
| 35 uint8_t * target = (uint8_t*)bitmapData.Scan0; | |
| 36 const uint8_t * source = decodedData; | |
| 37 for (int y = 0; y < h; ++y) { | |
| 38 memcpy(target, source, w * pfBytes); | |
| 39 target += bitmapData.Stride; | |
| 40 source += pfBytes * w; | |
| 41 } | |
| 42 EH << ret->UnlockBits(&bitmapData); | |
| 43 return ret; | |
| 44 } | |
| 45 return GdiplusImageFromMem(ptr, bytes); | |
| 46 } |
