Mercurial > foo_out_sdl
comparison 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 |
comparison
equal
deleted
inserted
replaced
| 0:e9bb126753e7 | 1:20d02a178406 |
|---|---|
| 1 #include "StdAfx.h" | |
| 2 #include "album_art_helpers.h" | |
| 3 #include <SDK/imageLoaderLite.h> | |
| 4 #include <SDK/album_art_helpers.h> | |
| 5 | |
| 6 #ifdef _WIN32 | |
| 7 #include <libPPUI/gdiplus_helpers.h> | |
| 8 using namespace Gdiplus; | |
| 9 static GdiplusErrorHandler EH; | |
| 10 | |
| 11 static int GetEncoderClsid(const WCHAR* format, CLSID* pClsid) | |
| 12 { | |
| 13 UINT num = 0; // number of image encoders | |
| 14 UINT size = 0; // size of the image encoder array in bytes | |
| 15 | |
| 16 ImageCodecInfo* pImageCodecInfo = NULL; | |
| 17 | |
| 18 GetImageEncodersSize(&num, &size); | |
| 19 if (size == 0) | |
| 20 return -1; // Failure | |
| 21 | |
| 22 pImageCodecInfo = (ImageCodecInfo*)(malloc(size)); | |
| 23 if (pImageCodecInfo == NULL) | |
| 24 return -1; // Failure | |
| 25 | |
| 26 GetImageEncoders(num, size, pImageCodecInfo); | |
| 27 | |
| 28 for (UINT j = 0; j < num; ++j) | |
| 29 { | |
| 30 if (wcscmp(pImageCodecInfo[j].MimeType, format) == 0) | |
| 31 { | |
| 32 *pClsid = pImageCodecInfo[j].Clsid; | |
| 33 free(pImageCodecInfo); | |
| 34 return j; // Success | |
| 35 } | |
| 36 } | |
| 37 | |
| 38 free(pImageCodecInfo); | |
| 39 return -1; // Failure | |
| 40 } | |
| 41 | |
| 42 static void SaveImage(Gdiplus::Bitmap* image, const TCHAR* out, const TCHAR* format, ULONG quality) { | |
| 43 CLSID encoderClsid; | |
| 44 EncoderParameters encoderParameters; | |
| 45 | |
| 46 if (GetEncoderClsid(format, &encoderClsid) < 0) throw std::runtime_error("Encoder not found"); | |
| 47 | |
| 48 if (_tcscmp(format, _T("image/jpeg")) == 0) { | |
| 49 encoderParameters.Count = 1; | |
| 50 encoderParameters.Parameter[0].Guid = EncoderQuality; | |
| 51 encoderParameters.Parameter[0].Type = EncoderParameterValueTypeLong; | |
| 52 encoderParameters.Parameter[0].NumberOfValues = 1; | |
| 53 encoderParameters.Parameter[0].Value = &quality; | |
| 54 | |
| 55 EH << image->Save(out, &encoderClsid, &encoderParameters); | |
| 56 } else { | |
| 57 EH << image->Save(out, &encoderClsid, NULL); | |
| 58 } | |
| 59 } | |
| 60 | |
| 61 #endif | |
| 62 | |
| 63 namespace album_art_helpers { | |
| 64 bool isJPEG(album_art_data_ptr aa) { | |
| 65 if (aa->size() < 2) return false; | |
| 66 const uint8_t* p = (const uint8_t*)aa->data(); | |
| 67 return p[0] == 0xFF && p[1] == 0xD8; | |
| 68 } | |
| 69 | |
| 70 bool isPNG(album_art_data_ptr aa) { | |
| 71 if (aa->size() < 2) return false; | |
| 72 const uint8_t* p = (const uint8_t*)aa->data(); | |
| 73 return p[0] == 0x89 && p[1] == 0x50; | |
| 74 } | |
| 75 bool isWebP(album_art_data_ptr aa) { | |
| 76 if (aa->size() < 12) return false; | |
| 77 const uint8_t* p = (const uint8_t*)aa->data(); | |
| 78 return memcmp(p, "RIFF", 4) == 0 && memcmp(p + 8, "WEBP", 4) == 0; | |
| 79 } | |
| 80 #ifdef _WIN32 | |
| 81 album_art_data_ptr encodeJPEG(album_art_data_ptr aa, int quality1to100) { | |
| 82 GdiplusScope::Once(); | |
| 83 auto api = fb2k::imageLoaderLite::get(); | |
| 84 | |
| 85 std::unique_ptr< Gdiplus::Image > img(api->load(aa)); | |
| 86 | |
| 87 if (img->GetType() != Gdiplus::ImageTypeBitmap) throw std::runtime_error("Excepted a bitmap"); | |
| 88 | |
| 89 { | |
| 90 pfc::string8 temp_path, temp_file; | |
| 91 uGetTempPath(temp_path); | |
| 92 uGetTempFileName(temp_path, "img", 0, temp_file); | |
| 93 pfc::onLeaving scope([&] { | |
| 94 uDeleteFile(temp_file); | |
| 95 }); | |
| 96 SaveImage(static_cast<Gdiplus::Bitmap*>(img.get()), pfc::stringcvt::string_os_from_utf8(temp_file), L"image/jpeg", quality1to100); | |
| 97 | |
| 98 file::ptr f = fileOpenReadExisting(temp_file, fb2k::noAbort); | |
| 99 uint64_t s = f->get_size_ex(fb2k::noAbort); | |
| 100 if (s > 1024 * 1024 * 64) throw exception_io_data(); | |
| 101 auto obj = fb2k::service_new<album_art_data_impl>(); | |
| 102 obj->from_stream(f.get_ptr(), (size_t)s, fb2k::noAbort); | |
| 103 return obj; | |
| 104 } | |
| 105 | |
| 106 } | |
| 107 #endif | |
| 108 } |
