1 /*
2     Copyright (C) 2015 Canonical
3 
4     This project is free software: you can redistribute it and/or modify
5     it under the terms of the GNU General Public License as published by
6     the Free Software Foundation, either version 3 of the License, or
7     (at your option) any later version.
8 
9     This project is distributed in the hope that it will be useful,
10     but WITHOUT ANY WARRANTY; without even the implied warranty of
11     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12     GNU General Public License for more details.
13 
14     You should have received a copy of the GNU General Public License
15     along with this program.  If not, see <http://www.gnu.org/licenses/>.
16 */
17 
18 #include "telegramthumbnailercore.h"
19 
20 #include <QFileInfo>
21 #include <QProcess>
22 #include <QStringList>
23 #include <QImage>
24 #include <QCoreApplication>
25 
26 #ifdef UBUNTU_PHONE
27 #include <stdexcept>
28 #include <QDebug>
29 #include <QSize>
30 #include <QSharedPointer>
31 #include "thumbnailer-qt.h"
32 #endif
33 
34 // https://core.telegram.org/constructor/decryptedMessageMediaPhoto
35 // Content of thumbnail file (JPEGfile, quality 55, set in a square 90x90)
36 const int THUMB_QUAILTY = 55;
37 const int THUMB_SIZE    = 90;
38 
TelegramThumbnailerCore(QObject * parent)39 TelegramThumbnailerCore::TelegramThumbnailerCore(QObject *parent) : QObject(parent) {
40 }
41 
~TelegramThumbnailerCore()42 TelegramThumbnailerCore::~TelegramThumbnailerCore() {
43 }
44 
45 #ifdef UBUNTU_PHONE
createThumbnail(QString source,QString dest)46 void TelegramThumbnailerCore::createThumbnail(QString source, QString dest) {
47     try {
48         QSize size(THUMB_SIZE, THUMB_SIZE);
49         unity::thumbnailer::qt::Thumbnailer thumbnailer;
50 
51         QSharedPointer<unity::thumbnailer::qt::Request> request =
52                 thumbnailer.getThumbnail(source, size);
53         // We're on a generic thumbnailer thread, safe to call blocking method.
54         request->waitForFinished();
55         if (request->isValid()) {
56             QImage image = request->image();
57             image.save(dest, "JPEG", THUMB_QUAILTY);
58 
59             Q_EMIT thumbnailCreated(source);
60             return;
61         }
62     } catch (const std::runtime_error &e) {
63         qCritical() << "Failed to generate thumbnail!" << e.what();
64     } catch (...) {
65         qCritical() << "Failed to generate thumbnail!";
66     }
67     // Failed to create thumbnail, empty thumb to avoid calling back in here.
68     QImage image(THUMB_SIZE, THUMB_SIZE, QImage::Format_ARGB32);
69     image.fill(0);
70     image.save(dest, "JPEG", THUMB_QUAILTY);
71     qWarning() << "created thumbnail placeholder";
72 
73     Q_EMIT thumbnailCreated(source);
74 }
75 #endif
76 
77 #ifndef UBUNTU_PHONE
createThumbnail(QString source,QString dest)78 void TelegramThumbnailerCore::createThumbnail(QString source, QString dest) {
79     QString ffmpegPath;
80 #if defined(Q_OS_WIN)
81     ffmpegPath = QCoreApplication::applicationDirPath() + "/ffmpeg.exe";
82 #elif defined(Q_OS_MAC)
83     ffmpegPath = QCoreApplication::applicationDirPath() + "/ffmpeg";
84 #else
85     if (!QFileInfo::exists(ffmpegPath)) {
86         if(QFileInfo::exists("/usr/bin/avconv"))
87             ffmpegPath = "/usr/bin/avconv";
88         else
89             ffmpegPath = "ffmpeg";
90     }
91 #endif
92 
93     QStringList args;
94     args << "-itsoffset" << "-4";
95     args << "-i" << source;
96     args << "-vcodec" << "mjpeg";
97     args << "-vframes" << "1";
98     args << "-an";
99     args << "-f" << "rawvideo";
100     args << dest;
101     args << "-y";
102 
103     QProcess prc;
104     prc.start(ffmpegPath, args);
105     prc.waitForStarted();
106     prc.waitForFinished();
107 
108     if (prc.exitCode() == 0) {
109         Q_EMIT thumbnailCreated(source);
110     } else {
111         QImage image;
112         image.save(dest, "JPEG");
113         Q_EMIT thumbnailCreated(source);
114     }
115 }
116 #endif
117