Mercurial > foo_out_sdl
diff foosdk/sdk/foobar2000/helpers/album_art_helpers.cpp @ 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 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/foosdk/sdk/foobar2000/helpers/album_art_helpers.cpp Mon Jan 05 02:15:46 2026 -0500 @@ -0,0 +1,108 @@ +#include "StdAfx.h" +#include "album_art_helpers.h" +#include <SDK/imageLoaderLite.h> +#include <SDK/album_art_helpers.h> + +#ifdef _WIN32 +#include <libPPUI/gdiplus_helpers.h> +using namespace Gdiplus; +static GdiplusErrorHandler EH; + +static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) +{ + UINT num = 0; // number of image encoders + UINT size = 0; // size of the image encoder array in bytes + + ImageCodecInfo* pImageCodecInfo = NULL; + + GetImageEncodersSize(&num, &size); + if (size == 0) + return -1; // Failure + + pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); + if (pImageCodecInfo == NULL) + return -1; // Failure + + GetImageEncoders(num, size, pImageCodecInfo); + + for (UINT j = 0; j < num; ++j) + { + if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) + { + *pClsid = pImageCodecInfo[j].Clsid; + free(pImageCodecInfo); + return j; // Success + } + } + + free(pImageCodecInfo); + return -1; // Failure +} + +static void SaveImage(Gdiplus::Bitmap* image, const TCHAR* out, const TCHAR* format, ULONG quality) { + CLSID encoderClsid; + EncoderParameters encoderParameters; + + if (GetEncoderClsid(format, &encoderClsid) < 0) throw std::runtime_error("Encoder not found"); + + if (_tcscmp(format, _T("image/jpeg")) == 0) { + encoderParameters.Count = 1; + encoderParameters.Parameter[0].Guid = EncoderQuality; + encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong; + encoderParameters.Parameter[0].NumberOfValues = 1; + encoderParameters.Parameter[0].Value = &quality; + + EH << image->Save(out, &encoderClsid, &encoderParameters); + } else { + EH << image->Save(out, &encoderClsid, NULL); + } +} + +#endif + +namespace album_art_helpers { + bool isJPEG(album_art_data_ptr aa) { + if (aa->size() < 2) return false; + const uint8_t* p = (const uint8_t*)aa->data(); + return p[0] == 0xFF && p[1] == 0xD8; + } + + bool isPNG(album_art_data_ptr aa) { + if (aa->size() < 2) return false; + const uint8_t* p = (const uint8_t*)aa->data(); + return p[0] == 0x89 && p[1] == 0x50; + } + bool isWebP(album_art_data_ptr aa) { + if (aa->size() < 12) return false; + const uint8_t* p = (const uint8_t*)aa->data(); + return memcmp(p, "RIFF", 4) == 0 && memcmp(p + 8, "WEBP", 4) == 0; + } +#ifdef _WIN32 + album_art_data_ptr encodeJPEG(album_art_data_ptr aa, int quality1to100) { + GdiplusScope::Once(); + auto api = fb2k::imageLoaderLite::get(); + + std::unique_ptr< Gdiplus::Image > img(api->load(aa)); + + if (img->GetType() != Gdiplus::ImageTypeBitmap) throw std::runtime_error("Excepted a bitmap"); + + { + pfc::string8 temp_path, temp_file; + uGetTempPath(temp_path); + uGetTempFileName(temp_path, "img", 0, temp_file); + pfc::onLeaving scope([&] { + uDeleteFile(temp_file); + }); + SaveImage(static_cast<Gdiplus::Bitmap*>(img.get()), pfc::stringcvt::string_os_from_utf8(temp_file), L"image/jpeg", quality1to100); + + file::ptr f = fileOpenReadExisting(temp_file, fb2k::noAbort); + uint64_t s = f->get_size_ex(fb2k::noAbort); + if (s > 1024 * 1024 * 64) throw exception_io_data(); + auto obj = fb2k::service_new<album_art_data_impl>(); + obj->from_stream(f.get_ptr(), (size_t)s, fb2k::noAbort); + return obj; + } + + } +#endif +}
