summaryrefslogtreecommitdiffstats
path: root/src/qml/asyncimageprovider.cpp
blob: f0cec41612478323a4ac3232f076ed0e338c54d3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include "qml/asyncimageprovider.h"

#include "library/coverartcache.h"

namespace {
const QString kCoverArtPrefix = QStringLiteral("coverart/");
}

namespace mixxx {
namespace qml {

AsyncImageResponse::AsyncImageResponse(const QString& id, const QSize& requestedSize)
        : m_id(id), m_requestedSize(requestedSize) {
    setAutoDelete(false);
}

QQuickTextureFactory* AsyncImageResponse::textureFactory() const {
    return QQuickTextureFactory::textureFactoryForImage(m_image);
}

void AsyncImageResponse::run() {
    if (m_id.startsWith(kCoverArtPrefix)) {
        QString trackLocation = AsyncImageProvider::coverArtUrlIdToTrackLocation(m_id);

        // TODO: This code does not allow to override embedded cover art with
        // a custom image, which is possible in Mixxx. We need to access the
        // actual CoverInfo of the track instead of constructing a default
        // instance on the fly.
        //
        // Unfortunately, TrackCollectionManager::getTrackByRef will not work
        // when called from another thread (like this one). We need a solution
        // for that.
        CoverInfo coverInfo(CoverInfoRelative(), trackLocation);
        coverInfo.type = CoverInfoRelative::METADATA;
        CoverInfo::LoadedImage loadedImage = coverInfo.loadImage();
        if (loadedImage.result != CoverInfo::LoadedImage::Result::Ok) {
            coverInfo.type = CoverInfoRelative::FILE;
            loadedImage = coverInfo.loadImage();
        }
        m_image = loadedImage.image;
    } else {
        qWarning() << "ImageProvider: Unknown ID " << m_id;
    }

    if (!m_image.isNull() && m_requestedSize.isValid()) {
        m_image = m_image.scaled(m_requestedSize);
    }

    emit finished();
}

QQuickImageResponse* AsyncImageProvider::requestImageResponse(
        const QString& id, const QSize& requestedSize) {
    AsyncImageResponse* response = new AsyncImageResponse(id, requestedSize);
    pool.start(response);
    return response;
}

// static
const QString AsyncImageProvider::kProviderName = QStringLiteral("mixxx");

// static
QUrl AsyncImageProvider::trackLocationToCoverArtUrl(const QString& trackLocation) {
    QUrl url("image://" + kProviderName + "/" + kCoverArtPrefix);
    return url.resolved(
            QString::fromLatin1(trackLocation.toUtf8().toBase64(
                    QByteArray::Base64UrlEncoding)));
}

//static
QString AsyncImageProvider::coverArtUrlIdToTrackLocation(const QString& coverArtUrlId) {
    return QString::fromUtf8(QByteArray::fromBase64(
            coverArtUrlId.mid(kCoverArtPrefix.size()).toLatin1(), QByteArray::Base64UrlEncoding));
}

} // namespace qml
} // namespace mixxx