Merge branch 'develop' for release v3.46.1

This commit is contained in:
emeric
2024-01-07 16:15:49 +01:00
7 changed files with 113 additions and 99 deletions
+8
View File
@@ -292,6 +292,13 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
session.getDboSession().execute("UPDATE scan_settings SET scan_version = scan_version + 1"); session.getDboSession().execute("UPDATE scan_settings SET scan_version = scan_version + 1");
} }
void migrateFromV48(Session& session)
{
// Regression for the extra tags not being parsed
// Just increment the scan version of the settings to make the next scheduled scan rescan everything
session.getDboSession().execute("UPDATE scan_settings SET scan_version = scan_version + 1");
}
void doDbMigration(Session& session) void doDbMigration(Session& session)
{ {
static const std::string outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" }; static const std::string outdatedMsg{ "Outdated database, please rebuild it (delete the .db file and restart)" };
@@ -318,6 +325,7 @@ CREATE TABLE IF NOT EXISTS "track_backup" (
{45, migrateFromV45}, {45, migrateFromV45},
{46, migrateFromV46}, {46, migrateFromV46},
{47, migrateFromV47}, {47, migrateFromV47},
{48, migrateFromV48},
}; };
{ {
+1 -1
View File
@@ -26,7 +26,7 @@ namespace Database
class Session; class Session;
using Version = std::size_t; using Version = std::size_t;
static constexpr Version LMS_DATABASE_VERSION{ 48 }; static constexpr Version LMS_DATABASE_VERSION{ 49 };
class VersionInfo class VersionInfo
{ {
public: public:
+75 -80
View File
@@ -25,6 +25,8 @@
#define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL #define STBIR_DEFAULT_FILTER_DOWNSAMPLE STBIR_FILTER_MITCHELL
#define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM #define STBIR_DEFAULT_FILTER_UPSAMPLE STBIR_FILTER_CATMULLROM
#define STBI_FAILURE_USERMSG
#include <stb_image.h> #include <stb_image.h>
#include <stb_image_resize.h> #include <stb_image_resize.h>
@@ -34,99 +36,92 @@
namespace Image namespace Image
{ {
std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize) std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize)
{ {
return std::make_unique<STB::RawImage>(encodedData, encodedDataSize); return std::make_unique<STB::RawImage>(encodedData, encodedDataSize);
} }
std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path) std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path)
{ {
return std::make_unique<STB::RawImage>(path); return std::make_unique<STB::RawImage>(path);
} }
void void init(const std::filesystem::path&)
init(const std::filesystem::path&) {
{ }
}
} }
namespace Image::STB namespace Image::STB
{ {
RawImage::RawImage(const std::byte* encodedData, std::size_t encodedDataSize) RawImage::RawImage(const std::byte* encodedData, std::size_t encodedDataSize)
{ {
int n; int n;
_data = UniquePtrFree {stbi_load_from_memory(reinterpret_cast<const stbi_uc*>(encodedData), encodedDataSize, &_width, &_height, &n, 3), std::free}; _data = UniquePtrFree{ ::stbi_load_from_memory(reinterpret_cast<const stbi_uc*>(encodedData), encodedDataSize, &_width, &_height, &n, 3), std::free };
if (!_data) if (!_data)
throw ImageException {"Cannot load image from memory"}; throw ImageException{ "Cannot load image from memory: " + std::string{ ::stbi_failure_reason() } };
} }
RawImage::RawImage(const std::filesystem::path& p) RawImage::RawImage(const std::filesystem::path& p)
{ {
int n; int n;
_data = UniquePtrFree {stbi_load(p.string().c_str(), &_width, &_height, &n, 3), std::free}; _data = UniquePtrFree{ stbi_load(p.string().c_str(), &_width, &_height, &n, 3), std::free };
if (!_data) if (!_data)
throw ImageException {"Cannot load image from memory"}; throw ImageException{ "Cannot load image from file: " + std::string{ ::stbi_failure_reason() } };
} }
void void RawImage::resize(ImageSize width)
RawImage::resize(ImageSize width) {
{ size_t height;
size_t height; if (_width == _height)
if (_width == _height) {
{ height = width;
height = width; }
} else if (_width > _height)
else if (_width > _height) {
{ height = (size_t)((float)width / _width * _height);
height = (size_t)((float)width/_width*_height); }
} else
else {
{ height = width;
height = width; width = (size_t)((float)height / _height * _width);
width = (size_t)((float)height/_height*_width); }
}
UniquePtrFree resizedData {reinterpret_cast<unsigned char*>(malloc(width*height*3)), std::free}; UniquePtrFree resizedData{ reinterpret_cast<unsigned char*>(malloc(width * height * 3)), std::free };
if (!resizedData) if (!resizedData)
throw ImageException {"Cannot allocate memory for resized image!"}; throw ImageException{ "Cannot allocate memory for resized image!" };
if (stbir_resize_uint8_srgb(reinterpret_cast<const unsigned char*>(_data.get()), _width, _height, 0, if (::stbir_resize_uint8_srgb(reinterpret_cast<const unsigned char*>(_data.get()), _width, _height, 0,
reinterpret_cast<unsigned char*>(resizedData.get()), width, height, 0, reinterpret_cast<unsigned char*>(resizedData.get()), width, height, 0,
3, STBIR_ALPHA_CHANNEL_NONE, 0) == 0) 3, STBIR_ALPHA_CHANNEL_NONE, 0) == 0)
{ {
throw ImageException {"Failed to resize image!"}; throw ImageException{ "Failed to resize image:" + std::string{ ::stbi_failure_reason() } };
} }
_data = std::move(resizedData); _data = std::move(resizedData);
_height = height; _height = height;
_width = width; _width = width;
} }
std::unique_ptr<IEncodedImage> std::unique_ptr<IEncodedImage> RawImage::encodeToJPEG(unsigned quality) const
RawImage::encodeToJPEG(unsigned quality) const {
{ return std::make_unique<JPEGImage>(*this, quality);
return std::make_unique<JPEGImage>(*this, quality); }
}
ImageSize ImageSize RawImage::getWidth() const
RawImage::getWidth() const {
{ return _width;
return _width; }
}
ImageSize ImageSize RawImage::getHeight() const
RawImage::getHeight() const {
{ return _height;
return _height; }
}
const std::byte* const std::byte* RawImage::getData() const
RawImage::getData() const {
{ if (!_data)
if (!_data) return nullptr;
return nullptr;
return reinterpret_cast<const std::byte*>(_data.get());
}
}
return reinterpret_cast<const std::byte*>(_data.get());
}
}
+16 -16
View File
@@ -31,24 +31,24 @@
namespace Image::STB namespace Image::STB
{ {
class RawImage : public IRawImage class RawImage : public IRawImage
{ {
public: public:
RawImage(const std::byte* encodedData, std::size_t encodedDataSize); RawImage(const std::byte* encodedData, std::size_t encodedDataSize);
RawImage(const std::filesystem::path& path); RawImage(const std::filesystem::path& path);
void resize(ImageSize width) override; void resize(ImageSize width) override;
std::unique_ptr<IEncodedImage> encodeToJPEG(unsigned quality) const override; std::unique_ptr<IEncodedImage> encodeToJPEG(unsigned quality) const override;
ImageSize getWidth() const; ImageSize getWidth() const;
ImageSize getHeight() const; ImageSize getHeight() const;
const std::byte* getData() const; const std::byte* getData() const;
private: private:
int _width; int _width;
int _height; int _height;
using UniquePtrFree = std::unique_ptr<unsigned char, decltype(&std::free)>; using UniquePtrFree = std::unique_ptr<unsigned char, decltype(&std::free)>;
UniquePtrFree _data {nullptr, std::free}; UniquePtrFree _data{ nullptr, std::free };
}; };
} }
@@ -429,16 +429,22 @@ namespace Cover
std::set<std::filesystem::path> parentPaths; std::set<std::filesystem::path> parentPaths;
{ {
Session& session{ _db.getTLSSession() }; Session& session{ _db.getTLSSession() };
Track::FindParameters params;
params.setArtist(artistId, { TrackArtistLinkType::ReleaseArtist });
auto transaction{ session.createReadTransaction() }; auto transaction{ session.createReadTransaction() };
Track::find(session, Track::FindParameters{}.setArtist(artistId), [&](const Track::pointer& track) Track::find(session, params, [&](const Track::pointer& track)
{ {
parentPaths.insert(track->getPath().parent_path()); parentPaths.insert(track->getPath().parent_path());
}); });
} }
if (parentPaths.size() == 1) if (parentPaths.size() == 1)
{
artistImage = getFromDirectory(parentPaths.begin()->parent_path(), width, _artistFileNames, false); artistImage = getFromDirectory(parentPaths.begin()->parent_path(), width, _artistFileNames, false);
}
else if (parentPaths.size() > 1) else if (parentPaths.size() > 1)
{ {
const std::filesystem::path longestCommonPath{ PathUtils::getLongestCommonPath(std::cbegin(parentPaths), std::cend(parentPaths)) }; const std::filesystem::path longestCommonPath{ PathUtils::getLongestCommonPath(std::cbegin(parentPaths), std::cend(parentPaths)) };
@@ -224,7 +224,11 @@ namespace Scanner
void ScanStepScanFiles::process(ScanContext& context) void ScanStepScanFiles::process(ScanContext& context)
{ {
_metadataParser->setUserExtraTags(_extraTagsToParse); {
std::vector<std::string> tagsToParse{ _extraTagsToParse };
tagsToParse.insert(std::end(tagsToParse), std::cbegin(_settings.extraTags), std::cend(_settings.extraTags));
_metadataParser->setUserExtraTags(tagsToParse);
}
context.currentStepStats.totalElems = context.stats.filesScanned; context.currentStepStats.totalElems = context.stats.filesScanned;
+1
View File
@@ -66,6 +66,7 @@ TEST(Path, getLongestCommonPathIterator)
{{"/foo", "/bar"}, "/"}, {{"/foo", "/bar"}, "/"},
{{"/foo/bar/file1.txt", "/foo/bar/file2.txt"}, "/foo/bar"}, {{"/foo/bar/file1.txt", "/foo/bar/file2.txt"}, "/foo/bar"},
{{"/foo", "/foo/"}, "/foo"}, {{"/foo", "/foo/"}, "/foo"},
{{"/foo", "/foo"}, "/foo"},
{{"/foo/", "/foo/"}, "/foo/"}, {{"/foo/", "/foo/"}, "/foo/"},
{{"/foo/", "/foo/", "/bar"}, "/"}, {{"/foo/", "/foo/", "/bar"}, "/"},
{{"/foo/", "/foo/", "/foo/bar"}, "/foo"}, {{"/foo/", "/foo/", "/foo/bar"}, "/foo"},