comparison foosdk/sdk/foobar2000/SDK/image.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 "foobar2000-sdk-pch.h"
2 #include "image.h"
3 #include "album_art.h"
4
5 namespace fb2k {
6 bool imageSize_t::equals(imageSize_t const & v1, imageSize_t const & v2) {
7 return v1.width == v2.width && v1.height == v2.height;
8 }
9 bool imageSize_t::greater(const fb2k::imageSize_t &v1, const fb2k::imageSize_t &v2) {
10 // v1 > v2
11 if (v1.width > v2.width) return true;
12 if (v1.width < v2.width) return false;
13 return v1.height > v2.height;
14 }
15 bool imageSize_t::isValid() const {
16 return width > 0 && height > 0;
17 }
18
19 imageSize_t imageSize_t::fitIn( double longerEdge ) const {
20 if (!isValid() || longerEdge <= 0) return empty();
21
22 if (height <= longerEdge && width <= longerEdge) return *this;
23
24 imageSize_t rv = {};
25 if (width > height) {
26 rv.width = longerEdge;
27 rv.height = longerEdge * height / width;
28 } else {
29 rv.height = longerEdge;
30 rv.width = longerEdge * width / height;
31 }
32 return rv;
33 }
34 imageSize_t imageSize_t::fitIn( imageSize_t size ) const {
35 if (!isValid() || !size.isValid()) return empty();
36
37 if (width <= size.width && height <= size.height) return *this;
38
39 imageSize_t rv = {};
40 double ratio = size.width / size.height;
41 double ourRatio = width / height;
42 if (ratio < ourRatio) {
43 // fit width
44 rv.width = size.width;
45 rv.height = height * (size.width / width);
46 } else {
47 // fit height
48 rv.height = size.height;
49 rv.width = width * (size.height / height);
50 }
51 return rv;
52 }
53
54 void imageSize_t::sanitize() {
55 if (width < 0) width = 0;
56 if (height < 0) height = 0;
57 width = pfc::rint32(width);
58 height = pfc::rint32(height);
59 }
60 image::ptr image::resizeToFit( imageSize_t fitInSize ) {
61 fitInSize.sanitize();
62 imageSize_t ourSize = size();
63 imageSize_t resizeTo = ourSize.fitIn(fitInSize);
64 if (resizeTo == ourSize || !resizeTo.isValid()) return this;
65 return resize( resizeTo );
66 }
67
68
69
70 static imageSize_t imageSizeSafe(imageRef img) {
71 if (img.is_valid()) return img->size();
72 else return imageSize_t::empty();
73 }
74 imageRef imageCreator::loadImageNamed2( const char * imgName, arg_t & arg ) {
75 auto ret = loadImageNamed( imgName, arg.inWantSize );
76 arg.outRealSize = imageSizeSafe(ret);
77 return ret;
78 }
79 imageRef imageCreator::loadImageData2( const void * data, size_t size, stringRef sourceURL, arg_t & arg ) {
80 auto ret = loadImageData(data, size, sourceURL);
81 arg.outRealSize = imageSizeSafe(ret);
82 return ret;
83 }
84 imageRef imageCreator::loadImageData2(memBlockRef block, stringRef sourceURL, arg_t & arg) {
85 auto ret = loadImageData(block, sourceURL);
86 arg.outRealSize = imageSizeSafe(ret);
87 return ret;
88 }
89 imageRef imageCreator::loadImageFromFile2(const char * filePath, abort_callback & aborter, arg_t & arg) {
90 auto ret = loadImageFromFile(filePath, aborter);
91 arg.outRealSize = imageSizeSafe(ret);
92 return ret;
93 }
94 imageRef imageCreator::loadImageFromFile3( fsItemFile::ptr fsFile, abort_callback & aborter, arg_t & arg ) {
95 return loadImageFromFile2( fsFile->canonicalPath()->c_str(), aborter, arg);
96 }
97
98
99 void imageLocation_t::setPath( const char * path_ ) {
100 this->path = makeString(path_);
101 }
102 void imageLocation_t::setPath(stringRef path_) {
103 this->path = path_;
104 }
105 bool imageLocation_t::setTrack2( trackRef track ) {
106 return setTrack2( track, album_art_ids::cover_front );
107 }
108 bool imageLocation_t::setTrack2( trackRef track, const GUID & albumArtID ) {
109 if (track.is_empty()) return false;
110 setPath( pfc::format("trackimage://", pfc::print_guid(albumArtID), ",", track->get_path()));
111 return true;
112 }
113 void imageLocation_t::setStock( const char * name ) {
114 setPath( pfc::format( "stockimage://", name ) );
115 }
116 stringRef imageLocation_t::getStock( ) const {
117 if (path.is_valid()) {
118 if (matchProtocol( path->c_str(), "stockimage" ) ) {
119 return makeString( strstr( path->c_str(), "://" ) + 3 );
120 }
121 }
122 return nullptr;
123 }
124
125 void imageLocation_t::setEmbedded( const char * path_, const GUID & albumArtID ) {
126 setPath( PFC_string_formatter() << "embedded://" << pfc::print_guid(albumArtID) << "," << path_);
127 }
128 bool imageLocation_t::equals(const fb2k::imageLocation_t &l1, const fb2k::imageLocation_t &l2) {
129 if ( l1.path.is_empty() && l2.path.is_empty() ) return true;
130 if ( l1.path.is_empty() || l2.path.is_empty() ) return false;
131 return l1.path->equals( l2.path );
132 }
133 bool imageLocation_t::operator==( imageLocation_t const & other) const {
134 return equals(*this, other);
135 }
136 bool imageLocation_t::operator!=( imageLocation_t const & other) const {
137 return !equals(*this, other);
138 }
139
140 imageRef imageLoader::loadStock( const char * name, arg_t const & arg, abort_callback & aborter ) {
141 imageLocation_t loc; loc.setStock( name );
142 return loadSynchronously(loc, arg, aborter);
143 }
144
145 }
146
147 pfc::string_base & operator<<(pfc::string_base & p_fmt,const fb2k::imageSize_t & imgSize) {
148 auto iw = pfc::rint32(imgSize.width);
149 auto ih = pfc::rint32(imgSize.height);
150 if (iw == imgSize.width && ih == imgSize.height) {
151 return p_fmt << "(" << iw << "x" << ih << ")";
152 } else {
153 return p_fmt << "(" << imgSize.width << "x" << imgSize.height << ")";
154 }
155 }
156