File indexing completed on 2024-05-12 15:50:11

0001 /* -*- C++ -*-
0002     This file is part of ThreadWeaver.
0003 
0004     SPDX-FileCopyrightText: 2005-2014 Mirko Boehm <mirko@kde.org>
0005 
0006     SPDX-License-Identifier: LGPL-2.0-or-later
0007 */
0008 
0009 #include <QBuffer>
0010 #include <QFile>
0011 #include <QFileInfo>
0012 #include <QImageReader>
0013 #include <QLocale>
0014 #include <QtDebug>
0015 
0016 #include <ThreadWeaver/Exception>
0017 #include <ThreadWeaver/ThreadWeaver>
0018 
0019 #include "Image.h"
0020 #include "Model.h"
0021 
0022 // const int Image::ThumbHeight = 75;
0023 // const int Image::ThumbWidth = 120;
0024 const int Image::ThumbHeight = 60;
0025 const int Image::ThumbWidth = 80;
0026 QReadWriteLock Image::Lock;
0027 int Image::ProcessingOrder;
0028 
0029 Image::Image(const QString inputFileName, const QString outputFileName, Model *model, int id)
0030     : m_inputFileName(inputFileName)
0031     , m_outputFileName(outputFileName)
0032     , m_model(model)
0033     , m_id(id)
0034 {
0035 }
0036 
0037 Progress Image::progress() const
0038 {
0039     return qMakePair(m_progress.loadRelaxed(), Step_NumberOfSteps);
0040 }
0041 
0042 QString Image::description() const
0043 {
0044     QReadLocker l(&Lock);
0045     return m_description;
0046 }
0047 
0048 QString Image::details() const
0049 {
0050     QReadLocker l(&Lock);
0051     return m_details;
0052 }
0053 
0054 QString Image::details2() const
0055 {
0056     QReadLocker l(&Lock);
0057     return m_details2;
0058 }
0059 
0060 int Image::processingOrder() const
0061 {
0062     return m_processingOrder.loadAcquire();
0063 }
0064 
0065 const QString Image::inputFileName() const
0066 {
0067     return m_inputFileName;
0068 }
0069 
0070 const QString Image::outputFileName() const
0071 {
0072     return m_outputFileName;
0073 }
0074 
0075 QImage Image::thumbNail() const
0076 {
0077     QReadLocker r(&Lock);
0078     return m_thumbnail;
0079 }
0080 
0081 void Image::loadFile()
0082 {
0083     m_processingOrder.storeRelease(ProcessingOrder++);
0084     QFile file(m_inputFileName);
0085     if (!file.open(QIODevice::ReadOnly)) {
0086         error(Step_LoadFile, tr("Unable to load input file!"));
0087     }
0088     m_imageData = file.readAll();
0089     QFileInfo fi(file);
0090     QLocale locale;
0091     QString details2 = tr("%1kB").arg(locale.toString(fi.size() / 1024));
0092     {
0093         QWriteLocker l(&Lock);
0094         m_description = fi.fileName();
0095         m_details2 = details2;
0096     }
0097     announceProgress(Step_LoadFile);
0098 }
0099 
0100 void Image::loadImage()
0101 {
0102     m_processingOrder.storeRelease(ProcessingOrder++);
0103     QBuffer in(&m_imageData);
0104     in.open(QIODevice::ReadOnly);
0105     QImageReader reader(&in);
0106     m_image = reader.read();
0107     m_imageData.clear();
0108     if (m_image.isNull()) {
0109         QWriteLocker l(&Lock);
0110         m_details = tr("%1!").arg(reader.errorString());
0111         error(Step_LoadImage, m_details);
0112     }
0113     QString details = tr("%1x%2 pixels").arg(m_image.width()).arg(m_image.height());
0114     {
0115         QWriteLocker l(&Lock);
0116         m_details = details;
0117     }
0118     announceProgress(Step_LoadImage);
0119 }
0120 
0121 void Image::computeThumbNail()
0122 {
0123     m_processingOrder.storeRelease(ProcessingOrder++);
0124     QImage thumb = m_image.scaled(ThumbWidth, ThumbHeight, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation);
0125     if (thumb.isNull()) {
0126         error(Step_ComputeThumbNail, tr("Unable to compute thumbnail!"));
0127     }
0128     { // thumb is implicitly shared, no copy:
0129         QWriteLocker l(&Lock);
0130         m_thumbnail = thumb;
0131     }
0132 
0133     m_image = QImage();
0134     announceProgress(Step_ComputeThumbNail);
0135 }
0136 
0137 void Image::saveThumbNail()
0138 {
0139     QImage thumb;
0140     {
0141         QReadLocker r(&Lock);
0142         thumb = m_thumbnail;
0143     }
0144     if (!thumb.save(m_outputFileName)) {
0145         error(Step_SaveThumbNail, tr("Unable to save output file!"));
0146     }
0147     announceProgress(Step_SaveThumbNail);
0148 }
0149 
0150 void Image::announceProgress(Steps step)
0151 {
0152     m_progress.storeRelease(step);
0153     if (m_model) {
0154         m_model->progressChanged();
0155         m_model->elementChanged(m_id);
0156     }
0157 }
0158 
0159 void Image::error(Image::Steps step, const QString &message)
0160 {
0161     m_failedStep.storeRelaxed(step);
0162     announceProgress(Step_Complete);
0163     throw ThreadWeaver::JobFailed(message);
0164 }