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 }