|
1
|
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
|