File indexing completed on 2024-05-12 04:02:23
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 }