Introduced lmscore lib to centralize services, migrated cover service
This commit is contained in:
@@ -1,8 +1,9 @@
|
||||
|
||||
add_subdirectory(auth)
|
||||
add_subdirectory(av)
|
||||
add_subdirectory(cover)
|
||||
add_subdirectory(database)
|
||||
add_subdirectory(image)
|
||||
add_subdirectory(lmscore)
|
||||
add_subdirectory(metadata)
|
||||
add_subdirectory(recommendation)
|
||||
add_subdirectory(scanner)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
add_library(lmscover SHARED
|
||||
impl/CoverService.cpp
|
||||
)
|
||||
|
||||
target_include_directories(lmscover INTERFACE
|
||||
include
|
||||
)
|
||||
|
||||
target_include_directories(lmscover PRIVATE
|
||||
include
|
||||
impl
|
||||
)
|
||||
|
||||
target_link_libraries(lmscover PRIVATE
|
||||
lmsav
|
||||
)
|
||||
|
||||
target_link_libraries(lmscover PUBLIC
|
||||
lmsdatabase
|
||||
lmsutils
|
||||
std::filesystem
|
||||
)
|
||||
|
||||
if (IMAGE_LIBRARY STREQUAL STB)
|
||||
target_sources(lmscover PRIVATE
|
||||
impl/stb/JPEGImage.cpp
|
||||
impl/stb/RawImage.cpp
|
||||
)
|
||||
target_compile_options(lmscover PRIVATE "-DLMS_SUPPORT_IMAGE_STB")
|
||||
target_include_directories(lmscover PRIVATE ${STB_INCLUDE_DIR})
|
||||
elseif (IMAGE_LIBRARY STREQUAL GraphicsMagick++)
|
||||
target_sources(lmscover PRIVATE
|
||||
impl/graphicsmagick/JPEGImage.cpp
|
||||
impl/graphicsmagick/RawImage.cpp
|
||||
)
|
||||
target_compile_options(lmscover PRIVATE "-DLMS_SUPPORT_IMAGE_GM")
|
||||
target_link_libraries(lmscover PRIVATE PkgConfig::GraphicsMagick++)
|
||||
else ()
|
||||
message(FATAL_ERROR "Invalid IMAGE_LIBRARY provided")
|
||||
endif()
|
||||
|
||||
install(TARGETS lmscover DESTINATION lib)
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
|
||||
add_library(lmsimage SHARED
|
||||
)
|
||||
|
||||
target_include_directories(lmsimage INTERFACE
|
||||
include
|
||||
)
|
||||
|
||||
target_include_directories(lmsimage PRIVATE
|
||||
include
|
||||
impl
|
||||
)
|
||||
|
||||
target_link_libraries(lmsimage PUBLIC
|
||||
lmsutils
|
||||
std::filesystem
|
||||
)
|
||||
|
||||
if (IMAGE_LIBRARY STREQUAL STB)
|
||||
target_sources(lmsimage PRIVATE
|
||||
impl/stb/JPEGImage.cpp
|
||||
impl/stb/RawImage.cpp
|
||||
)
|
||||
target_compile_options(lmsimage PRIVATE "-DLMS_SUPPORT_IMAGE_STB")
|
||||
target_include_directories(lmsimage PRIVATE ${STB_INCLUDE_DIR})
|
||||
elseif (IMAGE_LIBRARY STREQUAL GraphicsMagick++)
|
||||
target_sources(lmsimage PRIVATE
|
||||
impl/graphicsmagick/JPEGImage.cpp
|
||||
impl/graphicsmagick/RawImage.cpp
|
||||
)
|
||||
target_compile_options(lmsimage PRIVATE "-DLMS_SUPPORT_IMAGE_GM")
|
||||
target_link_libraries(lmsimage PRIVATE PkgConfig::GraphicsMagick++)
|
||||
else ()
|
||||
message(FATAL_ERROR "Invalid IMAGE_LIBRARY provided")
|
||||
endif()
|
||||
|
||||
install(TARGETS lmsimage DESTINATION lib)
|
||||
|
||||
+11
-2
@@ -25,7 +25,16 @@
|
||||
#include "JPEGImage.hpp"
|
||||
#include "Exception.hpp"
|
||||
|
||||
namespace CoverArt::GraphicsMagick {
|
||||
namespace Image::GraphicsMagick
|
||||
{
|
||||
|
||||
std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize)
|
||||
{
|
||||
return std::make_unique<RawImage>(encodedData, encodedDataSize);
|
||||
}
|
||||
|
||||
std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path)
|
||||
{
|
||||
|
||||
void
|
||||
init(const std::filesystem::path& path)
|
||||
@@ -116,5 +125,5 @@ RawImage::getMagickImage() const
|
||||
return _image;
|
||||
}
|
||||
|
||||
} // namespace CoverArt::GraphicsMagick
|
||||
} // namespace Image::GraphicsMagick
|
||||
|
||||
@@ -22,10 +22,10 @@
|
||||
#define STB_IMAGE_WRITE_IMPLEMENTATION
|
||||
#include <stb/stb_image_write.h>
|
||||
|
||||
#include "image/Exception.hpp"
|
||||
#include "RawImage.hpp"
|
||||
#include "Exception.hpp"
|
||||
|
||||
namespace Cover::STB
|
||||
namespace Image::STB
|
||||
{
|
||||
JPEGImage::JPEGImage(const RawImage& rawImage, unsigned quality)
|
||||
{
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "cover/IEncodedImage.hpp"
|
||||
#include "image/IEncodedImage.hpp"
|
||||
|
||||
namespace Cover::STB
|
||||
namespace Image::STB
|
||||
{
|
||||
class RawImage;
|
||||
class JPEGImage : public IEncodedImage
|
||||
@@ -30,9 +30,22 @@
|
||||
|
||||
#include "JPEGImage.hpp"
|
||||
|
||||
#include "Exception.hpp"
|
||||
#include "image/Exception.hpp"
|
||||
|
||||
namespace Cover::STB
|
||||
namespace Image
|
||||
{
|
||||
std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize)
|
||||
{
|
||||
return std::make_unique<STB::RawImage>(encodedData, encodedDataSize);
|
||||
}
|
||||
|
||||
std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path)
|
||||
{
|
||||
return std::make_unique<STB::RawImage>(path);
|
||||
}
|
||||
}
|
||||
|
||||
namespace Image::STB
|
||||
{
|
||||
RawImage::RawImage(const std::byte* encodedData, std::size_t encodedDataSize)
|
||||
{
|
||||
@@ -26,10 +26,10 @@
|
||||
#include <cstddef>
|
||||
#include <filesystem>
|
||||
|
||||
#include "cover/IEncodedImage.hpp"
|
||||
#include "IRawImage.hpp"
|
||||
#include "image/IEncodedImage.hpp"
|
||||
#include "image/IRawImage.hpp"
|
||||
|
||||
namespace Cover::STB
|
||||
namespace Image::STB
|
||||
{
|
||||
class RawImage : public IRawImage
|
||||
{
|
||||
@@ -21,7 +21,7 @@
|
||||
|
||||
#include "utils/Exception.hpp"
|
||||
|
||||
namespace Cover
|
||||
namespace Image
|
||||
{
|
||||
// internal use only
|
||||
class ImageException : public LmsException
|
||||
+1
-1
@@ -22,7 +22,7 @@
|
||||
#include <cstddef>
|
||||
#include <string_view>
|
||||
|
||||
namespace Cover
|
||||
namespace Image
|
||||
{
|
||||
using ImageSize = std::size_t;
|
||||
|
||||
@@ -21,9 +21,9 @@
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "cover/IEncodedImage.hpp"
|
||||
#include "image/IEncodedImage.hpp"
|
||||
|
||||
namespace Cover
|
||||
namespace Image
|
||||
{
|
||||
class IRawImage
|
||||
{
|
||||
@@ -32,5 +32,8 @@ namespace Cover
|
||||
virtual void resize(ImageSize width) = 0;
|
||||
virtual std::unique_ptr<IEncodedImage> encodeToJPEG(unsigned quality) const = 0;
|
||||
};
|
||||
|
||||
std::unique_ptr<IRawImage> decodeImage(const std::byte* encodedData, std::size_t encodedDataSize);
|
||||
std::unique_ptr<IRawImage> decodeImage(const std::filesystem::path& path);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
|
||||
add_library(lmscore SHARED
|
||||
impl/CoverService.cpp
|
||||
)
|
||||
|
||||
target_include_directories(lmscore INTERFACE
|
||||
include
|
||||
)
|
||||
|
||||
target_include_directories(lmscore PRIVATE
|
||||
include
|
||||
impl
|
||||
)
|
||||
|
||||
target_link_libraries(lmscore PRIVATE
|
||||
lmsav
|
||||
lmsimage
|
||||
)
|
||||
|
||||
target_link_libraries(lmscore PUBLIC
|
||||
lmsdatabase
|
||||
lmsimage
|
||||
lmsutils
|
||||
std::filesystem
|
||||
)
|
||||
|
||||
install(TARGETS lmscore DESTINATION lib)
|
||||
|
||||
@@ -26,19 +26,12 @@
|
||||
#include "database/Session.hpp"
|
||||
#include "database/Track.hpp"
|
||||
|
||||
#if LMS_SUPPORT_IMAGE_STB
|
||||
#include "stb/RawImage.hpp"
|
||||
using RawImage = Cover::STB::RawImage;
|
||||
#elif LMS_SUPPORT_IMAGE_GM
|
||||
#include "graphicsmagick/RawImage.hpp"
|
||||
using RawImage = Cover::GraphicsMagick::RawImage;
|
||||
#endif
|
||||
|
||||
#include "image/Exception.hpp"
|
||||
#include "image/IRawImage.hpp"
|
||||
#include "utils/IConfig.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
#include "utils/Random.hpp"
|
||||
#include "utils/Utils.hpp"
|
||||
#include "Exception.hpp"
|
||||
|
||||
namespace
|
||||
{
|
||||
@@ -79,6 +72,8 @@ namespace
|
||||
|
||||
namespace Cover {
|
||||
|
||||
using namespace Image;
|
||||
|
||||
static
|
||||
bool
|
||||
isFileSupported(const std::filesystem::path& file, const std::vector<std::filesystem::path>& extensions)
|
||||
@@ -117,7 +112,7 @@ CoverService::CoverService(Database::Db& db,
|
||||
{
|
||||
getDefault(512);
|
||||
}
|
||||
catch (const ImageException& e)
|
||||
catch (const Image::ImageException& e)
|
||||
{
|
||||
throw LmsException("Cannot read default cover file '" + _defaultCoverPath.string() + "': " + e.what());
|
||||
}
|
||||
@@ -135,11 +130,11 @@ CoverService::getFromAvMediaFile(const Av::IAudioFile& input, ImageSize width) c
|
||||
|
||||
try
|
||||
{
|
||||
RawImage rawImage {picture.data, picture.dataSize};
|
||||
rawImage.resize(width);
|
||||
image = rawImage.encodeToJPEG(_jpegQuality);
|
||||
std::unique_ptr<IRawImage> rawImage {decodeImage(picture.data, picture.dataSize)};
|
||||
rawImage->resize(width);
|
||||
image = rawImage->encodeToJPEG(_jpegQuality);
|
||||
}
|
||||
catch (const ImageException& e)
|
||||
catch (const Image::ImageException& e)
|
||||
{
|
||||
LMS_LOG(COVER, ERROR) << "Cannot read embedded cover: " << e.what();
|
||||
}
|
||||
@@ -155,9 +150,9 @@ CoverService::getFromCoverFile(const std::filesystem::path& p, ImageSize width)
|
||||
|
||||
try
|
||||
{
|
||||
RawImage rawImage {p};
|
||||
rawImage.resize(width);
|
||||
image = rawImage.encodeToJPEG(_jpegQuality);
|
||||
std::unique_ptr<IRawImage> rawImage {decodeImage(p)};
|
||||
rawImage->resize(width);
|
||||
image = rawImage->encodeToJPEG(_jpegQuality);
|
||||
}
|
||||
catch (const ImageException& e)
|
||||
{
|
||||
@@ -29,8 +29,8 @@
|
||||
#include <variant>
|
||||
#include <vector>
|
||||
|
||||
#include "cover/ICoverService.hpp"
|
||||
#include "cover/IEncodedImage.hpp"
|
||||
#include "lmscore/services/ICoverService.hpp"
|
||||
#include "image/IEncodedImage.hpp"
|
||||
#include "database/Types.hpp"
|
||||
|
||||
namespace Database
|
||||
@@ -96,34 +96,34 @@ namespace Cover
|
||||
CoverService& operator=(CoverService&&) = delete;
|
||||
|
||||
private:
|
||||
std::shared_ptr<IEncodedImage> getFromTrack(Database::TrackId trackId, ImageSize width) override;
|
||||
std::shared_ptr<IEncodedImage> getFromRelease(Database::ReleaseId releaseId, ImageSize width) override;
|
||||
std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::TrackId trackId, Image::ImageSize width) override;
|
||||
std::shared_ptr<Image::IEncodedImage> getFromRelease(Database::ReleaseId releaseId, Image::ImageSize width) override;
|
||||
void flushCache() override;
|
||||
void setJpegQuality(unsigned quality) override;
|
||||
|
||||
std::shared_ptr<IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, ImageSize width, bool allowReleaseFallback);
|
||||
std::unique_ptr<IEncodedImage> getFromAvMediaFile(const Av::IAudioFile& input, ImageSize width) const;
|
||||
std::unique_ptr<IEncodedImage> getFromCoverFile(const std::filesystem::path& p, ImageSize width) const;
|
||||
std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::Session& dbSession, Database::TrackId trackId, Image::ImageSize width, bool allowReleaseFallback);
|
||||
std::unique_ptr<Image::IEncodedImage> getFromAvMediaFile(const Av::IAudioFile& input, Image::ImageSize width) const;
|
||||
std::unique_ptr<Image::IEncodedImage> getFromCoverFile(const std::filesystem::path& p, Image::ImageSize width) const;
|
||||
|
||||
std::unique_ptr<IEncodedImage> getFromTrack(const std::filesystem::path& path, ImageSize width) const;
|
||||
std::unique_ptr<Image::IEncodedImage> getFromTrack(const std::filesystem::path& path, Image::ImageSize width) const;
|
||||
std::multimap<std::string, std::filesystem::path> getCoverPaths(const std::filesystem::path& directoryPath) const;
|
||||
std::unique_ptr<IEncodedImage> getFromDirectory(const std::filesystem::path& directory, ImageSize width) const;
|
||||
std::unique_ptr<IEncodedImage> getFromSameNamedFile(const std::filesystem::path& filePath, ImageSize width) const;
|
||||
std::shared_ptr<IEncodedImage> getDefault(ImageSize width);
|
||||
std::unique_ptr<Image::IEncodedImage> getFromDirectory(const std::filesystem::path& directory, Image::ImageSize width) const;
|
||||
std::unique_ptr<Image::IEncodedImage> getFromSameNamedFile(const std::filesystem::path& filePath, Image::ImageSize width) const;
|
||||
std::shared_ptr<Image::IEncodedImage> getDefault(Image::ImageSize width);
|
||||
|
||||
bool checkCoverFile(const std::filesystem::path& directoryPath) const;
|
||||
|
||||
Database::Db& _db;
|
||||
|
||||
std::shared_mutex _cacheMutex;
|
||||
std::unordered_map<CacheEntryDesc, std::shared_ptr<IEncodedImage>> _cache;
|
||||
std::unordered_map<ImageSize, std::shared_ptr<IEncodedImage>> _defaultCoverCache;
|
||||
std::unordered_map<CacheEntryDesc, std::shared_ptr<Image::IEncodedImage>> _cache;
|
||||
std::unordered_map<Image::ImageSize, std::shared_ptr<Image::IEncodedImage>> _defaultCoverCache;
|
||||
std::atomic<std::size_t> _cacheMisses {};
|
||||
std::atomic<std::size_t> _cacheHits {};
|
||||
std::size_t _cacheSize {};
|
||||
|
||||
void saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<IEncodedImage> image);
|
||||
std::shared_ptr<IEncodedImage> loadFromCache(const CacheEntryDesc& entryDesc);
|
||||
void saveToCache(const CacheEntryDesc& entryDesc, std::shared_ptr<Image::IEncodedImage> image);
|
||||
std::shared_ptr<Image::IEncodedImage> loadFromCache(const CacheEntryDesc& entryDesc);
|
||||
|
||||
const std::filesystem::path _defaultCoverPath;
|
||||
const std::size_t _maxCacheSize;
|
||||
+3
-3
@@ -23,7 +23,7 @@
|
||||
#include <memory>
|
||||
|
||||
#include "database/Types.hpp"
|
||||
#include "cover/IEncodedImage.hpp"
|
||||
#include "image/IEncodedImage.hpp"
|
||||
|
||||
namespace Database
|
||||
{
|
||||
@@ -37,8 +37,8 @@ namespace Cover
|
||||
public:
|
||||
virtual ~ICoverService() = default;
|
||||
|
||||
virtual std::shared_ptr<IEncodedImage> getFromTrack(Database::TrackId trackId, ImageSize width) = 0;
|
||||
virtual std::shared_ptr<IEncodedImage> getFromRelease(Database::ReleaseId releaseId, ImageSize width) = 0;
|
||||
virtual std::shared_ptr<Image::IEncodedImage> getFromTrack(Database::TrackId trackId, Image::ImageSize width) = 0;
|
||||
virtual std::shared_ptr<Image::IEncodedImage> getFromRelease(Database::ReleaseId releaseId, Image::ImageSize width) = 0;
|
||||
|
||||
virtual void flushCache() = 0;
|
||||
|
||||
@@ -19,7 +19,7 @@ target_include_directories(lmssubsonic PRIVATE
|
||||
target_link_libraries(lmssubsonic PRIVATE
|
||||
lmsauth
|
||||
lmsav
|
||||
lmscover
|
||||
lmscore
|
||||
lmsdatabase
|
||||
lmsrecommendation
|
||||
lmsscanner
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
|
||||
#include "auth/IPasswordService.hpp"
|
||||
#include "auth/IEnvService.hpp"
|
||||
#include "cover/ICoverService.hpp"
|
||||
#include "lmscore/services/ICoverService.hpp"
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Db.hpp"
|
||||
@@ -1802,7 +1802,7 @@ handleGetCoverArt(RequestContext& context, const Wt::Http::Request& /*request*/,
|
||||
std::size_t size {getParameterAs<std::size_t>(context.parameters, "size").value_or(256)};
|
||||
size = Utils::clamp(size, std::size_t {32}, std::size_t {1024});
|
||||
|
||||
std::shared_ptr<Cover::IEncodedImage> cover;
|
||||
std::shared_ptr<Image::IEncodedImage> cover;
|
||||
if (trackId)
|
||||
cover = Service<Cover::ICoverService>::get()->getFromTrack(*trackId, size);
|
||||
else if (releaseId)
|
||||
|
||||
@@ -51,7 +51,7 @@ target_include_directories(lms PRIVATE
|
||||
target_link_libraries(lms PRIVATE
|
||||
lmsav
|
||||
lmsauth
|
||||
lmscover
|
||||
lmscore
|
||||
lmsdatabase
|
||||
lmsrecommendation
|
||||
lmsscanner
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@
|
||||
#include "auth/IAuthTokenService.hpp"
|
||||
#include "auth/IPasswordService.hpp"
|
||||
#include "auth/IEnvService.hpp"
|
||||
#include "cover/ICoverService.hpp"
|
||||
#include "lmscore/services/ICoverService.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Session.hpp"
|
||||
#include "scanner/IScanner.hpp"
|
||||
|
||||
@@ -30,7 +30,7 @@
|
||||
|
||||
#include "auth/IEnvService.hpp"
|
||||
#include "auth/IPasswordService.hpp"
|
||||
#include "cover/ICoverService.hpp"
|
||||
#include "lmscore/services/ICoverService.hpp"
|
||||
#include "database/Artist.hpp"
|
||||
#include "database/Cluster.hpp"
|
||||
#include "database/Db.hpp"
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include <Wt/WApplication.h>
|
||||
#include <Wt/Http/Response.h>
|
||||
|
||||
#include "cover/ICoverService.hpp"
|
||||
#include "lmscore/services/ICoverService.hpp"
|
||||
#include "database/Track.hpp"
|
||||
#include "utils/Exception.hpp"
|
||||
#include "utils/Logger.hpp"
|
||||
@@ -83,7 +83,7 @@ CoverResource::handleRequest(const Wt::Http::Request& request, Wt::Http::Respons
|
||||
return;
|
||||
}
|
||||
|
||||
std::shared_ptr<Cover::IEncodedImage> cover;
|
||||
std::shared_ptr<Image::IEncodedImage> cover;
|
||||
|
||||
if (trackIdStr)
|
||||
{
|
||||
|
||||
@@ -4,7 +4,7 @@ add_executable(lms-cover
|
||||
)
|
||||
|
||||
target_link_libraries(lms-cover PRIVATE
|
||||
lmscover
|
||||
lmscore
|
||||
Boost::program_options
|
||||
)
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#include <boost/program_options.hpp>
|
||||
|
||||
#include "cover/ICoverService.hpp"
|
||||
#include "lmscore/services/ICoverService.hpp"
|
||||
#include "database/Db.hpp"
|
||||
#include "database/Release.hpp"
|
||||
#include "database/Session.hpp"
|
||||
@@ -36,7 +36,7 @@
|
||||
|
||||
static
|
||||
void
|
||||
dumpTrackCovers(Database::Session& session, Cover::ImageSize width)
|
||||
dumpTrackCovers(Database::Session& session, Image::ImageSize width)
|
||||
{
|
||||
std::vector<Database::TrackId> trackIds;
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user