summary refs log tree commit diff
path: root/src/MxcImageProvider.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/MxcImageProvider.cpp')
-rw-r--r--src/MxcImageProvider.cpp420
1 files changed, 199 insertions, 221 deletions
diff --git a/src/MxcImageProvider.cpp b/src/MxcImageProvider.cpp

index 056374a9..5d0ee0be 100644 --- a/src/MxcImageProvider.cpp +++ b/src/MxcImageProvider.cpp
@@ -24,70 +24,70 @@ QHash<QString, mtx::crypto::EncryptedFile> infos; QQuickImageResponse * MxcImageProvider::requestImageResponse(const QString &id, const QSize &requestedSize) { - auto id_ = id; - bool crop = true; - double radius = 0; - - auto queryStart = id.lastIndexOf('?'); - if (queryStart != -1) { - id_ = id.left(queryStart); - auto query = id.midRef(queryStart + 1); - auto queryBits = query.split('&'); - - for (auto b : queryBits) { - if (b == "scale") { - crop = false; - } else if (b.startsWith("radius=")) { - radius = b.mid(7).toDouble(); - } - } + auto id_ = id; + bool crop = true; + double radius = 0; + + auto queryStart = id.lastIndexOf('?'); + if (queryStart != -1) { + id_ = id.left(queryStart); + auto query = id.midRef(queryStart + 1); + auto queryBits = query.split('&'); + + for (auto b : queryBits) { + if (b == "scale") { + crop = false; + } else if (b.startsWith("radius=")) { + radius = b.mid(7).toDouble(); + } } + } - MxcImageResponse *response = new MxcImageResponse(id_, crop, radius, requestedSize); - pool.start(response); - return response; + MxcImageResponse *response = new MxcImageResponse(id_, crop, radius, requestedSize); + pool.start(response); + return response; } void MxcImageProvider::addEncryptionInfo(mtx::crypto::EncryptedFile info) { - infos.insert(QString::fromStdString(info.url), info); + infos.insert(QString::fromStdString(info.url), info); } void MxcImageResponse::run() { - MxcImageProvider::download( - m_id, - m_requestedSize, - [this](QString, QSize, QImage image, QString) { - if (image.isNull()) { - m_error = "Failed to download image."; - } else { - m_image = image; - } - emit finished(); - }, - m_crop, - m_radius); + MxcImageProvider::download( + m_id, + m_requestedSize, + [this](QString, QSize, QImage image, QString) { + if (image.isNull()) { + m_error = "Failed to download image."; + } else { + m_image = image; + } + emit finished(); + }, + m_crop, + m_radius); } static QImage clipRadius(QImage img, double radius) { - QImage out(img.size(), QImage::Format_ARGB32_Premultiplied); - out.fill(Qt::transparent); + QImage out(img.size(), QImage::Format_ARGB32_Premultiplied); + out.fill(Qt::transparent); - QPainter painter(&out); - painter.setRenderHint(QPainter::Antialiasing, true); - painter.setRenderHint(QPainter::SmoothPixmapTransform, true); + QPainter painter(&out); + painter.setRenderHint(QPainter::Antialiasing, true); + painter.setRenderHint(QPainter::SmoothPixmapTransform, true); - QPainterPath ppath; - ppath.addRoundedRect(img.rect(), radius, radius, Qt::SizeMode::RelativeSize); + QPainterPath ppath; + ppath.addRoundedRect(img.rect(), radius, radius, Qt::SizeMode::RelativeSize); - painter.setClipPath(ppath); - painter.drawImage(img.rect(), img); + painter.setClipPath(ppath); + painter.drawImage(img.rect(), img); - return out; + return out; } void @@ -97,187 +97,165 @@ MxcImageProvider::download(const QString &id, bool crop, double radius) { - std::optional<mtx::crypto::EncryptedFile> encryptionInfo; - auto temp = infos.find("mxc://" + id); - if (temp != infos.end()) - encryptionInfo = *temp; - - if (requestedSize.isValid() && !encryptionInfo) { - QString fileName = - QString("%1_%2x%3_%4_radius%5") - .arg(QString::fromUtf8(id.toUtf8().toBase64(QByteArray::Base64UrlEncoding | - QByteArray::OmitTrailingEquals))) - .arg(requestedSize.width()) - .arg(requestedSize.height()) - .arg(crop ? "crop" : "scale") - .arg(radius); - QFileInfo fileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + - "/media_cache", - fileName); - QDir().mkpath(fileInfo.absolutePath()); - - if (fileInfo.exists()) { - QImage image = utils::readImageFromFile(fileInfo.absoluteFilePath()); - if (!image.isNull()) { - image = image.scaled( - requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - if (radius != 0) { - image = clipRadius(std::move(image), radius); - } - - if (!image.isNull()) { - then(id, requestedSize, image, fileInfo.absoluteFilePath()); - return; - } - } + std::optional<mtx::crypto::EncryptedFile> encryptionInfo; + auto temp = infos.find("mxc://" + id); + if (temp != infos.end()) + encryptionInfo = *temp; + + if (requestedSize.isValid() && !encryptionInfo) { + QString fileName = QString("%1_%2x%3_%4_radius%5") + .arg(QString::fromUtf8(id.toUtf8().toBase64( + QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals))) + .arg(requestedSize.width()) + .arg(requestedSize.height()) + .arg(crop ? "crop" : "scale") + .arg(radius); + QFileInfo fileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + + "/media_cache", + fileName); + QDir().mkpath(fileInfo.absolutePath()); + + if (fileInfo.exists()) { + QImage image = utils::readImageFromFile(fileInfo.absoluteFilePath()); + if (!image.isNull()) { + image = image.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + if (radius != 0) { + image = clipRadius(std::move(image), radius); } - mtx::http::ThumbOpts opts; - opts.mxc_url = "mxc://" + id.toStdString(); - opts.width = requestedSize.width() > 0 ? requestedSize.width() : -1; - opts.height = requestedSize.height() > 0 ? requestedSize.height() : -1; - opts.method = crop ? "crop" : "scale"; - http::client()->get_thumbnail( - opts, - [fileInfo, requestedSize, radius, then, id](const std::string &res, - mtx::http::RequestErr err) { - if (err || res.empty()) { - then(id, QSize(), {}, ""); - - return; - } - - auto data = QByteArray(res.data(), (int)res.size()); - QImage image = utils::readImage(data); - if (!image.isNull()) { - image = image.scaled( - requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); - - if (radius != 0) { - image = clipRadius(std::move(image), radius); - } - } - image.setText("mxc url", "mxc://" + id); - if (image.save(fileInfo.absoluteFilePath(), "png")) - nhlog::ui()->debug("Wrote: {}", - fileInfo.absoluteFilePath().toStdString()); - else - nhlog::ui()->debug("Failed to write: {}", - fileInfo.absoluteFilePath().toStdString()); - - then(id, requestedSize, image, fileInfo.absoluteFilePath()); - }); - } else { - try { - QString fileName = - QString("%1_radius%2") - .arg(QString::fromUtf8(id.toUtf8().toBase64( - QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals))) - .arg(radius); - - QFileInfo fileInfo( - QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + - "/media_cache", - fileName); - QDir().mkpath(fileInfo.absolutePath()); - - if (fileInfo.exists()) { - if (encryptionInfo) { - QFile f(fileInfo.absoluteFilePath()); - f.open(QIODevice::ReadOnly); - - QByteArray fileData = f.readAll(); - auto tempData = - mtx::crypto::to_string(mtx::crypto::decrypt_file( - fileData.toStdString(), encryptionInfo.value())); - auto data = - QByteArray(tempData.data(), (int)tempData.size()); - QImage image = utils::readImage(data); - image.setText("mxc url", "mxc://" + id); - if (!image.isNull()) { - if (radius != 0) { - image = - clipRadius(std::move(image), radius); - } - - then(id, - requestedSize, - image, - fileInfo.absoluteFilePath()); - return; - } - } else { - QImage image = - utils::readImageFromFile(fileInfo.absoluteFilePath()); - if (!image.isNull()) { - if (radius != 0) { - image = - clipRadius(std::move(image), radius); - } - - then(id, - requestedSize, - image, - fileInfo.absoluteFilePath()); - return; - } - } + if (!image.isNull()) { + then(id, requestedSize, image, fileInfo.absoluteFilePath()); + return; + } + } + } + + mtx::http::ThumbOpts opts; + opts.mxc_url = "mxc://" + id.toStdString(); + opts.width = requestedSize.width() > 0 ? requestedSize.width() : -1; + opts.height = requestedSize.height() > 0 ? requestedSize.height() : -1; + opts.method = crop ? "crop" : "scale"; + http::client()->get_thumbnail( + opts, + [fileInfo, requestedSize, radius, then, id](const std::string &res, + mtx::http::RequestErr err) { + if (err || res.empty()) { + then(id, QSize(), {}, ""); + + return; + } + + auto data = QByteArray(res.data(), (int)res.size()); + QImage image = utils::readImage(data); + if (!image.isNull()) { + image = + image.scaled(requestedSize, Qt::KeepAspectRatio, Qt::SmoothTransformation); + + if (radius != 0) { + image = clipRadius(std::move(image), radius); + } + } + image.setText("mxc url", "mxc://" + id); + if (image.save(fileInfo.absoluteFilePath(), "png")) + nhlog::ui()->debug("Wrote: {}", fileInfo.absoluteFilePath().toStdString()); + else + nhlog::ui()->debug("Failed to write: {}", + fileInfo.absoluteFilePath().toStdString()); + + then(id, requestedSize, image, fileInfo.absoluteFilePath()); + }); + } else { + try { + QString fileName = QString("%1_radius%2") + .arg(QString::fromUtf8(id.toUtf8().toBase64( + QByteArray::Base64UrlEncoding | QByteArray::OmitTrailingEquals))) + .arg(radius); + + QFileInfo fileInfo(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + + "/media_cache", + fileName); + QDir().mkpath(fileInfo.absolutePath()); + + if (fileInfo.exists()) { + if (encryptionInfo) { + QFile f(fileInfo.absoluteFilePath()); + f.open(QIODevice::ReadOnly); + + QByteArray fileData = f.readAll(); + auto tempData = mtx::crypto::to_string( + mtx::crypto::decrypt_file(fileData.toStdString(), encryptionInfo.value())); + auto data = QByteArray(tempData.data(), (int)tempData.size()); + QImage image = utils::readImage(data); + image.setText("mxc url", "mxc://" + id); + if (!image.isNull()) { + if (radius != 0) { + image = clipRadius(std::move(image), radius); } - http::client()->download( - "mxc://" + id.toStdString(), - [fileInfo, requestedSize, then, id, radius, encryptionInfo]( - const std::string &res, - const std::string &, - const std::string &originalFilename, - mtx::http::RequestErr err) { - if (err) { - then(id, QSize(), {}, ""); - return; - } - - auto tempData = res; - QFile f(fileInfo.absoluteFilePath()); - if (!f.open(QIODevice::Truncate | QIODevice::WriteOnly)) { - then(id, QSize(), {}, ""); - return; - } - f.write(tempData.data(), tempData.size()); - f.close(); - - if (encryptionInfo) { - tempData = - mtx::crypto::to_string(mtx::crypto::decrypt_file( - tempData, encryptionInfo.value())); - auto data = - QByteArray(tempData.data(), (int)tempData.size()); - QImage image = utils::readImage(data); - if (radius != 0) { - image = clipRadius(std::move(image), radius); - } - - image.setText("original filename", - QString::fromStdString(originalFilename)); - image.setText("mxc url", "mxc://" + id); - then( - id, requestedSize, image, fileInfo.absoluteFilePath()); - return; - } - - QImage image = - utils::readImageFromFile(fileInfo.absoluteFilePath()); - if (radius != 0) { - image = clipRadius(std::move(image), radius); - } - - image.setText("original filename", - QString::fromStdString(originalFilename)); - image.setText("mxc url", "mxc://" + id); - then(id, requestedSize, image, fileInfo.absoluteFilePath()); - }); - } catch (std::exception &e) { - nhlog::net()->error("Exception while downloading media: {}", e.what()); + then(id, requestedSize, image, fileInfo.absoluteFilePath()); + return; + } + } else { + QImage image = utils::readImageFromFile(fileInfo.absoluteFilePath()); + if (!image.isNull()) { + if (radius != 0) { + image = clipRadius(std::move(image), radius); + } + + then(id, requestedSize, image, fileInfo.absoluteFilePath()); + return; + } } + } + + http::client()->download( + "mxc://" + id.toStdString(), + [fileInfo, requestedSize, then, id, radius, encryptionInfo]( + const std::string &res, + const std::string &, + const std::string &originalFilename, + mtx::http::RequestErr err) { + if (err) { + then(id, QSize(), {}, ""); + return; + } + + auto tempData = res; + QFile f(fileInfo.absoluteFilePath()); + if (!f.open(QIODevice::Truncate | QIODevice::WriteOnly)) { + then(id, QSize(), {}, ""); + return; + } + f.write(tempData.data(), tempData.size()); + f.close(); + + if (encryptionInfo) { + tempData = mtx::crypto::to_string( + mtx::crypto::decrypt_file(tempData, encryptionInfo.value())); + auto data = QByteArray(tempData.data(), (int)tempData.size()); + QImage image = utils::readImage(data); + if (radius != 0) { + image = clipRadius(std::move(image), radius); + } + + image.setText("original filename", QString::fromStdString(originalFilename)); + image.setText("mxc url", "mxc://" + id); + then(id, requestedSize, image, fileInfo.absoluteFilePath()); + return; + } + + QImage image = utils::readImageFromFile(fileInfo.absoluteFilePath()); + if (radius != 0) { + image = clipRadius(std::move(image), radius); + } + + image.setText("original filename", QString::fromStdString(originalFilename)); + image.setText("mxc url", "mxc://" + id); + then(id, requestedSize, image, fileInfo.absoluteFilePath()); + }); + } catch (std::exception &e) { + nhlog::net()->error("Exception while downloading media: {}", e.what()); } + } }