mirror of https://github.com/procxx/kepka.git
sending gifv done
This commit is contained in:
parent
d966eebb7c
commit
2e853f9338
|
@ -938,7 +938,7 @@ namespace App {
|
||||||
if (!item->toHistoryForwarded() && item->out()) {
|
if (!item->toHistoryForwarded() && item->out()) {
|
||||||
if (HistoryMedia *media = item->getMedia()) {
|
if (HistoryMedia *media = item->getMedia()) {
|
||||||
if (DocumentData *doc = media->getDocument()) {
|
if (DocumentData *doc = media->getDocument()) {
|
||||||
if (doc->type == AnimatedDocument && doc->mime.toLower() == qstr("video/mp4")) {
|
if (doc->isGifv()) {
|
||||||
addSavedGif(doc);
|
addSavedGif(doc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1623,6 +1623,9 @@ namespace App {
|
||||||
}
|
}
|
||||||
convert->id = document;
|
convert->id = document;
|
||||||
convert->status = FileReady;
|
convert->status = FileReady;
|
||||||
|
if (cSavedGifs().indexOf(convert) >= 0) { // id changed
|
||||||
|
Local::writeSavedGifs();
|
||||||
|
}
|
||||||
sentSticker = !!convert->sticker();
|
sentSticker = !!convert->sticker();
|
||||||
}
|
}
|
||||||
convert->access = access;
|
convert->access = access;
|
||||||
|
|
|
@ -23,7 +23,7 @@ Copyright (c) 2014-2015 John Preston, https://desktop.telegram.org
|
||||||
static const int32 AppVersion = 9015;
|
static const int32 AppVersion = 9015;
|
||||||
static const wchar_t *AppVersionStr = L"0.9.15";
|
static const wchar_t *AppVersionStr = L"0.9.15";
|
||||||
static const bool DevVersion = false;
|
static const bool DevVersion = false;
|
||||||
#define BETA_VERSION (9015004ULL) // just comment this line to build public version
|
#define BETA_VERSION (9015005ULL) // just comment this line to build public version
|
||||||
|
|
||||||
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
static const wchar_t *AppNameOld = L"Telegram Win (Unofficial)";
|
||||||
static const wchar_t *AppName = L"Telegram Desktop";
|
static const wchar_t *AppName = L"Telegram Desktop";
|
||||||
|
|
|
@ -358,13 +358,20 @@ ClipReader::~ClipReader() {
|
||||||
class ClipReaderImplementation {
|
class ClipReaderImplementation {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
ClipReaderImplementation(FileLocation *location, QByteArray *data) : _location(location), _data(data), _device(0) {
|
ClipReaderImplementation(FileLocation *location, QByteArray *data)
|
||||||
|
: _location(location)
|
||||||
|
, _data(data)
|
||||||
|
, _device(0)
|
||||||
|
, _dataSize(0) {
|
||||||
}
|
}
|
||||||
virtual bool readNextFrame(QImage &to, bool &hasAlpha, const QSize &size) = 0;
|
virtual bool readNextFrame(QImage &to, bool &hasAlpha, const QSize &size) = 0;
|
||||||
virtual int32 nextFrameDelay() = 0;
|
virtual int32 nextFrameDelay() = 0;
|
||||||
virtual bool start() = 0;
|
virtual bool start(bool onlyGifv) = 0;
|
||||||
virtual ~ClipReaderImplementation() {
|
virtual ~ClipReaderImplementation() {
|
||||||
}
|
}
|
||||||
|
int64 dataSize() const {
|
||||||
|
return _dataSize;
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FileLocation *_location;
|
FileLocation *_location;
|
||||||
|
@ -372,14 +379,17 @@ protected:
|
||||||
QFile _file;
|
QFile _file;
|
||||||
QBuffer _buffer;
|
QBuffer _buffer;
|
||||||
QIODevice *_device;
|
QIODevice *_device;
|
||||||
|
int64 _dataSize;
|
||||||
|
|
||||||
void initDevice() {
|
void initDevice() {
|
||||||
if (_data->isEmpty()) {
|
if (_data->isEmpty()) {
|
||||||
if (_file.isOpen()) _file.close();
|
if (_file.isOpen()) _file.close();
|
||||||
_file.setFileName(_location->name());
|
_file.setFileName(_location->name());
|
||||||
|
_dataSize = _file.size();
|
||||||
} else {
|
} else {
|
||||||
if (_buffer.isOpen()) _buffer.close();
|
if (_buffer.isOpen()) _buffer.close();
|
||||||
_buffer.setBuffer(_data);
|
_buffer.setBuffer(_data);
|
||||||
|
_dataSize = _data->size();
|
||||||
}
|
}
|
||||||
_device = _data->isEmpty() ? static_cast<QIODevice*>(&_file) : static_cast<QIODevice*>(&_buffer);
|
_device = _data->isEmpty() ? static_cast<QIODevice*>(&_file) : static_cast<QIODevice*>(&_buffer);
|
||||||
}
|
}
|
||||||
|
@ -432,7 +442,8 @@ public:
|
||||||
return _frameDelay;
|
return _frameDelay;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start() {
|
bool start(bool onlyGifv) {
|
||||||
|
if (onlyGifv) return false;
|
||||||
return jumpToStart();
|
return jumpToStart();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -632,7 +643,7 @@ public:
|
||||||
return qsl("for file '%1', data size '%2'").arg(_location ? _location->name() : QString()).arg(_data->size());
|
return qsl("for file '%1', data size '%2'").arg(_location ? _location->name() : QString()).arg(_data->size());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool start() {
|
bool start(bool onlyGifv) {
|
||||||
initDevice();
|
initDevice();
|
||||||
if (!_device->open(QIODevice::ReadOnly)) {
|
if (!_device->open(QIODevice::ReadOnly)) {
|
||||||
LOG(("Gif Error: Unable to open device %1").arg(logData()));
|
LOG(("Gif Error: Unable to open device %1").arg(logData()));
|
||||||
|
@ -671,6 +682,18 @@ public:
|
||||||
// Get a pointer to the codec context for the audio stream
|
// Get a pointer to the codec context for the audio stream
|
||||||
_codecContext = _fmtContext->streams[_streamId]->codec;
|
_codecContext = _fmtContext->streams[_streamId]->codec;
|
||||||
_codec = avcodec_find_decoder(_codecContext->codec_id);
|
_codec = avcodec_find_decoder(_codecContext->codec_id);
|
||||||
|
|
||||||
|
if (onlyGifv) {
|
||||||
|
if (av_find_best_stream(_fmtContext, AVMEDIA_TYPE_AUDIO, -1, -1, 0, 0) >= 0) { // should be no audio stream
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (dataSize() > AnimationInMemory) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (_codecContext->codec_id != AV_CODEC_ID_H264) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
av_opt_set_int(_codecContext, "refcounted_frames", 1, 0);
|
av_opt_set_int(_codecContext, "refcounted_frames", 1, 0);
|
||||||
if ((res = avcodec_open2(_codecContext, _codec, 0)) < 0) {
|
if ((res = avcodec_open2(_codecContext, _codec, 0)) < 0) {
|
||||||
LOG(("Gif Error: Unable to avcodec_open2 %1, error %2, %3").arg(logData()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
LOG(("Gif Error: Unable to avcodec_open2 %1, error %2, %3").arg(logData()).arg(res).arg(av_make_error_string(err, sizeof(err), res)));
|
||||||
|
@ -680,6 +703,11 @@ public:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int32 duration() const {
|
||||||
|
if (_fmtContext->streams[_streamId]->duration == AV_NOPTS_VALUE) return 0;
|
||||||
|
return (_fmtContext->streams[_streamId]->duration * _fmtContext->streams[_streamId]->time_base.num) / _fmtContext->streams[_streamId]->time_base.den;
|
||||||
|
}
|
||||||
|
|
||||||
~FFMpegReaderImplementation() {
|
~FFMpegReaderImplementation() {
|
||||||
if (_ioContext) av_free(_ioContext);
|
if (_ioContext) av_free(_ioContext);
|
||||||
if (_codecContext) avcodec_close(_codecContext);
|
if (_codecContext) avcodec_close(_codecContext);
|
||||||
|
@ -864,7 +892,7 @@ public:
|
||||||
|
|
||||||
_implementation = new FFMpegReaderImplementation(_location, &_data);
|
_implementation = new FFMpegReaderImplementation(_location, &_data);
|
||||||
// _implementation = new QtGifReaderImplementation(_location, &_data);
|
// _implementation = new QtGifReaderImplementation(_location, &_data);
|
||||||
return _implementation->start();
|
return _implementation->start(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipProcessResult error() {
|
ClipProcessResult error() {
|
||||||
|
@ -1108,3 +1136,30 @@ void ClipReadManager::clear() {
|
||||||
ClipReadManager::~ClipReadManager() {
|
ClipReadManager::~ClipReadManager() {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MTPDocumentAttribute clipReadAnimatedAttributes(const QString &fname, const QByteArray &data, QImage &cover) {
|
||||||
|
FileLocation localloc(StorageFilePartial, fname);
|
||||||
|
QByteArray localdata(data);
|
||||||
|
|
||||||
|
FFMpegReaderImplementation *reader = new FFMpegReaderImplementation(&localloc, &localdata);
|
||||||
|
if (reader->start(true)) {
|
||||||
|
bool hasAlpha = false;
|
||||||
|
if (reader->readNextFrame(cover, hasAlpha, QSize())) {
|
||||||
|
if (cover.width() > 0 && cover.height() > 0 && cover.width() < cover.height() * 10 && cover.height() < cover.width() * 10) {
|
||||||
|
if (hasAlpha) {
|
||||||
|
QImage cache;
|
||||||
|
ClipFrameRequest request;
|
||||||
|
request.framew = request.outerw = cover.width();
|
||||||
|
request.frameh = request.outerh = cover.height();
|
||||||
|
request.factor = 1;
|
||||||
|
cover = _prepareFrame(request, cover, cache, hasAlpha).toImage();
|
||||||
|
}
|
||||||
|
int32 duration = reader->duration();
|
||||||
|
delete reader;
|
||||||
|
return MTP_documentAttributeVideo(MTP_int(duration), MTP_int(cover.width()), MTP_int(cover.height()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
delete reader;
|
||||||
|
return MTP_documentAttributeFilename(MTP_string(fname));
|
||||||
|
}
|
||||||
|
|
|
@ -646,3 +646,5 @@ private:
|
||||||
bool _needReProcess;
|
bool _needReProcess;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
MTPDocumentAttribute clipReadAnimatedAttributes(const QString &fname, const QByteArray &data, QImage &cover);
|
||||||
|
|
|
@ -944,7 +944,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) {
|
||||||
if (doc->loading()) {
|
if (doc->loading()) {
|
||||||
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_cancel_download), this, SLOT(cancelContextDownload()))->setEnabled(true);
|
||||||
} else {
|
} else {
|
||||||
if (doc->mime.toLower() == qstr("video/mp4") && doc->type == AnimatedDocument) {
|
if (doc->isGifv()) {
|
||||||
_menu->addAction(lang(lng_context_save_gif), this, SLOT(saveContextGif()))->setEnabled(true);
|
_menu->addAction(lang(lng_context_save_gif), this, SLOT(saveContextGif()))->setEnabled(true);
|
||||||
}
|
}
|
||||||
if (!doc->already(true).isEmpty()) {
|
if (!doc->already(true).isEmpty()) {
|
||||||
|
@ -3181,10 +3181,8 @@ void HistoryWidget::savedGifsGot(const MTPmessages_SavedGifs &gifs) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void HistoryWidget::saveGif(DocumentData *doc) {
|
void HistoryWidget::saveGif(DocumentData *doc) {
|
||||||
if (doc->mime.toLower() == qstr("video/mp4") && doc->type == AnimatedDocument) {
|
if (doc->isGifv() && cSavedGifs().indexOf(doc) != 0) {
|
||||||
if (cSavedGifs().indexOf(doc) != 0) {
|
MTP::send(MTPmessages_SaveGif(MTP_inputDocument(MTP_long(doc->id), MTP_long(doc->access)), MTP_bool(false)), rpcDone(&HistoryWidget::saveGifDone, doc));
|
||||||
MTP::send(MTPmessages_SaveGif(MTP_inputDocument(MTP_long(doc->id), MTP_long(doc->access)), MTP_bool(false)), rpcDone(&HistoryWidget::saveGifDone, doc));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5468,7 +5466,12 @@ namespace {
|
||||||
MTPVector<MTPDocumentAttribute> _composeDocumentAttributes(DocumentData *document) {
|
MTPVector<MTPDocumentAttribute> _composeDocumentAttributes(DocumentData *document) {
|
||||||
QVector<MTPDocumentAttribute> attributes(1, MTP_documentAttributeFilename(MTP_string(document->name)));
|
QVector<MTPDocumentAttribute> attributes(1, MTP_documentAttributeFilename(MTP_string(document->name)));
|
||||||
if (document->dimensions.width() > 0 && document->dimensions.height() > 0) {
|
if (document->dimensions.width() > 0 && document->dimensions.height() > 0) {
|
||||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height())));
|
int32 duration = document->duration();
|
||||||
|
if (duration >= 0) {
|
||||||
|
attributes.push_back(MTP_documentAttributeVideo(MTP_int(duration), MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height())));
|
||||||
|
} else {
|
||||||
|
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(document->dimensions.width()), MTP_int(document->dimensions.height())));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (document->type == AnimatedDocument) {
|
if (document->type == AnimatedDocument) {
|
||||||
attributes.push_back(MTP_documentAttributeAnimated());
|
attributes.push_back(MTP_documentAttributeAnimated());
|
||||||
|
|
|
@ -294,13 +294,12 @@ void FileLoadTask::process() {
|
||||||
MTPDocument document(MTP_documentEmpty(MTP_long(0)));
|
MTPDocument document(MTP_documentEmpty(MTP_long(0)));
|
||||||
MTPAudio audio(MTP_audioEmpty(MTP_long(0)));
|
MTPAudio audio(MTP_audioEmpty(MTP_long(0)));
|
||||||
|
|
||||||
bool song = false;
|
bool song = false, gif = false;
|
||||||
if (_type != PrepareAudio) {
|
if (_type != PrepareAudio) {
|
||||||
if (filemime == qstr("audio/mp3") || filemime == qstr("audio/m4a") || filemime == qstr("audio/aac") || filemime == qstr("audio/ogg") || filemime == qstr("audio/flac") ||
|
if (filemime == qstr("audio/mp3") || filemime == qstr("audio/m4a") || filemime == qstr("audio/aac") || filemime == qstr("audio/ogg") || filemime == qstr("audio/flac") ||
|
||||||
filename.endsWith(qstr(".mp3"), Qt::CaseInsensitive) || filename.endsWith(qstr(".m4a"), Qt::CaseInsensitive) ||
|
filename.endsWith(qstr(".mp3"), Qt::CaseInsensitive) || filename.endsWith(qstr(".m4a"), Qt::CaseInsensitive) ||
|
||||||
filename.endsWith(qstr(".aac"), Qt::CaseInsensitive) || filename.endsWith(qstr(".ogg"), Qt::CaseInsensitive) ||
|
filename.endsWith(qstr(".aac"), Qt::CaseInsensitive) || filename.endsWith(qstr(".ogg"), Qt::CaseInsensitive) ||
|
||||||
filename.endsWith(qstr(".flac"), Qt::CaseInsensitive)) {
|
filename.endsWith(qstr(".flac"), Qt::CaseInsensitive)) {
|
||||||
|
|
||||||
QImage cover;
|
QImage cover;
|
||||||
QByteArray coverBytes, coverFormat;
|
QByteArray coverBytes, coverFormat;
|
||||||
MTPDocumentAttribute audioAttribute = audioReadSongAttributes(_filepath, _content, cover, coverBytes, coverFormat);
|
MTPDocumentAttribute audioAttribute = audioReadSongAttributes(_filepath, _content, cover, coverBytes, coverFormat);
|
||||||
|
@ -327,9 +326,37 @@ void FileLoadTask::process() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (filemime == qstr("video/mp4") || filename.endsWith(qstr(".mp4"), Qt::CaseInsensitive)) {
|
||||||
|
QImage cover;
|
||||||
|
MTPDocumentAttribute animatedAttribute = clipReadAnimatedAttributes(_filepath, _content, cover);
|
||||||
|
if (animatedAttribute.type() == mtpc_documentAttributeVideo) {
|
||||||
|
int32 cw = cover.width(), ch = cover.height();
|
||||||
|
if (cw < 20 * ch && ch < 20 * cw) {
|
||||||
|
attributes.push_back(MTP_documentAttributeAnimated());
|
||||||
|
attributes.push_back(animatedAttribute);
|
||||||
|
gif = true;
|
||||||
|
|
||||||
|
QPixmap full = (cw > 90 || ch > 90) ? QPixmap::fromImage(cover.scaled(90, 90, Qt::KeepAspectRatio, Qt::SmoothTransformation), Qt::ColorOnly) : QPixmap::fromImage(cover, Qt::ColorOnly);
|
||||||
|
{
|
||||||
|
QByteArray thumbFormat = "JPG";
|
||||||
|
int32 thumbQuality = 87;
|
||||||
|
|
||||||
|
QBuffer buffer(&thumbdata);
|
||||||
|
full.save(&buffer, thumbFormat, thumbQuality);
|
||||||
|
}
|
||||||
|
|
||||||
|
thumb = full;
|
||||||
|
thumbSize = MTP_photoSize(MTP_string(""), MTP_fileLocationUnavailable(MTP_long(0), MTP_int(0), MTP_long(0)), MTP_int(full.width()), MTP_int(full.height()), MTP_int(0));
|
||||||
|
|
||||||
|
thumbId = MTP::nonce<uint64>();
|
||||||
|
|
||||||
|
filemime = qstr("video/mp4");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fullimage.isNull() && fullimage.width() > 0 && !song) {
|
if (!fullimage.isNull() && fullimage.width() > 0 && !song && !gif) {
|
||||||
int32 w = fullimage.width(), h = fullimage.height();
|
int32 w = fullimage.width(), h = fullimage.height();
|
||||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(w), MTP_int(h)));
|
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(w), MTP_int(h)));
|
||||||
|
|
||||||
|
|
|
@ -552,7 +552,8 @@ namespace {
|
||||||
lskStickers = 0x0b, // no data
|
lskStickers = 0x0b, // no data
|
||||||
lskSavedPeers = 0x0c, // no data
|
lskSavedPeers = 0x0c, // no data
|
||||||
lskReportSpamStatuses = 0x0d, // no data
|
lskReportSpamStatuses = 0x0d, // no data
|
||||||
lskSavedGifs = 0x0e,
|
lskSavedGifsOld = 0x0e,
|
||||||
|
lskSavedGifs = 0x0f,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef QMap<PeerId, FileKey> DraftsMap;
|
typedef QMap<PeerId, FileKey> DraftsMap;
|
||||||
|
@ -569,7 +570,7 @@ namespace {
|
||||||
FileLocationAliases _fileLocationAliases;
|
FileLocationAliases _fileLocationAliases;
|
||||||
FileKey _locationsKey = 0, _reportSpamStatusesKey = 0;
|
FileKey _locationsKey = 0, _reportSpamStatusesKey = 0;
|
||||||
|
|
||||||
FileKey _recentStickersKeyOld = 0, _stickersKey = 0, _savedGifsKey;
|
FileKey _recentStickersKeyOld = 0, _stickersKey = 0, _savedGifsKey = 0;
|
||||||
|
|
||||||
FileKey _backgroundKey = 0;
|
FileKey _backgroundKey = 0;
|
||||||
bool _backgroundWasRead = false;
|
bool _backgroundWasRead = false;
|
||||||
|
@ -1720,6 +1721,10 @@ namespace {
|
||||||
case lskStickers: {
|
case lskStickers: {
|
||||||
map.stream >> stickersKey;
|
map.stream >> stickersKey;
|
||||||
} break;
|
} break;
|
||||||
|
case lskSavedGifsOld: {
|
||||||
|
quint64 key;
|
||||||
|
map.stream >> key;
|
||||||
|
} break;
|
||||||
case lskSavedGifs: {
|
case lskSavedGifs: {
|
||||||
map.stream >> savedGifsKey;
|
map.stream >> savedGifsKey;
|
||||||
} break;
|
} break;
|
||||||
|
@ -2974,8 +2979,8 @@ namespace Local {
|
||||||
for (SavedGifs::const_iterator i = saved.cbegin(), e = saved.cend(); i != e; ++i) {
|
for (SavedGifs::const_iterator i = saved.cbegin(), e = saved.cend(); i != e; ++i) {
|
||||||
DocumentData *doc = *i;
|
DocumentData *doc = *i;
|
||||||
|
|
||||||
// id + access + date + namelen + name + mimelen + mime + dc + size + width + height + type
|
// id + access + date + namelen + name + mimelen + mime + dc + size + width + height + type + duration
|
||||||
size += sizeof(quint64) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
size += sizeof(quint64) + sizeof(quint64) + sizeof(qint32) + _stringSize(doc->name) + _stringSize(doc->mime) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32) + sizeof(qint32);
|
||||||
|
|
||||||
// thumb
|
// thumb
|
||||||
size += _storageImageLocationSize();
|
size += _storageImageLocationSize();
|
||||||
|
@ -2991,7 +2996,7 @@ namespace Local {
|
||||||
for (SavedGifs::const_iterator i = saved.cbegin(), e = saved.cend(); i != e; ++i) {
|
for (SavedGifs::const_iterator i = saved.cbegin(), e = saved.cend(); i != e; ++i) {
|
||||||
DocumentData *doc = *i;
|
DocumentData *doc = *i;
|
||||||
|
|
||||||
data.stream << quint64(doc->id) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type);
|
data.stream << quint64(doc->id) << quint64(doc->access) << qint32(doc->date) << doc->name << doc->mime << qint32(doc->dc) << qint32(doc->size) << qint32(doc->dimensions.width()) << qint32(doc->dimensions.height()) << qint32(doc->type) << qint32(doc->duration());
|
||||||
_writeStorageImageLocation(data.stream, doc->thumb->location());
|
_writeStorageImageLocation(data.stream, doc->thumb->location());
|
||||||
}
|
}
|
||||||
FileWriteDescriptor file(_savedGifsKey);
|
FileWriteDescriptor file(_savedGifsKey);
|
||||||
|
@ -3020,8 +3025,8 @@ namespace Local {
|
||||||
for (uint32 i = 0; i < cnt; ++i) {
|
for (uint32 i = 0; i < cnt; ++i) {
|
||||||
quint64 id, access;
|
quint64 id, access;
|
||||||
QString name, mime;
|
QString name, mime;
|
||||||
qint32 date, dc, size, width, height, type;
|
qint32 date, dc, size, width, height, type, duration;
|
||||||
gifs.stream >> id >> access >> date >> name >> mime >> dc >> size >> width >> height >> type;
|
gifs.stream >> id >> access >> date >> name >> mime >> dc >> size >> width >> height >> type >> duration;
|
||||||
|
|
||||||
StorageImageLocation thumb(_readStorageImageLocation(gifs));
|
StorageImageLocation thumb(_readStorageImageLocation(gifs));
|
||||||
|
|
||||||
|
@ -3034,7 +3039,11 @@ namespace Local {
|
||||||
attributes.push_back(MTP_documentAttributeAnimated());
|
attributes.push_back(MTP_documentAttributeAnimated());
|
||||||
}
|
}
|
||||||
if (width > 0 && height > 0) {
|
if (width > 0 && height > 0) {
|
||||||
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
if (duration >= 0) {
|
||||||
|
attributes.push_back(MTP_documentAttributeVideo(MTP_int(duration), MTP_int(width), MTP_int(height)));
|
||||||
|
} else {
|
||||||
|
attributes.push_back(MTP_documentAttributeImageSize(MTP_int(width), MTP_int(height)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentData *doc = App::documentSet(id, 0, access, date, attributes, mime, thumb.isNull() ? ImagePtr() : ImagePtr(thumb), dc, size, thumb);
|
DocumentData *doc = App::documentSet(id, 0, access, date, attributes, mime, thumb.isNull() ? ImagePtr() : ImagePtr(thumb), dc, size, thumb);
|
||||||
|
|
|
@ -1490,7 +1490,7 @@ DocumentData::DocumentData(const DocumentId &id, const uint64 &access, int32 dat
|
||||||
, status(FileReady)
|
, status(FileReady)
|
||||||
, uploadOffset(0)
|
, uploadOffset(0)
|
||||||
, _additional(0)
|
, _additional(0)
|
||||||
, _isImage(false)
|
, _duration(-1)
|
||||||
, _actionOnLoad(ActionOnLoadNone)
|
, _actionOnLoad(ActionOnLoadNone)
|
||||||
, _loader(0) {
|
, _loader(0) {
|
||||||
_location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
_location = Local::readFileLocation(mediaKey(DocumentFileLocation, dc, id));
|
||||||
|
@ -1524,7 +1524,7 @@ void DocumentData::setattributes(const QVector<MTPDocumentAttribute> &attributes
|
||||||
if (type == FileDocument) {
|
if (type == FileDocument) {
|
||||||
type = VideoDocument;
|
type = VideoDocument;
|
||||||
}
|
}
|
||||||
// duration = d.vduration.v;
|
_duration = d.vduration.v;
|
||||||
dimensions = QSize(d.vw.v, d.vh.v);
|
dimensions = QSize(d.vw.v, d.vh.v);
|
||||||
} break;
|
} break;
|
||||||
case mtpc_documentAttributeAudio: {
|
case mtpc_documentAttributeAudio: {
|
||||||
|
@ -1812,7 +1812,8 @@ bool fileIsImage(const QString &name, const QString &mime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void DocumentData::recountIsImage() {
|
void DocumentData::recountIsImage() {
|
||||||
_isImage = fileIsImage(name, mime);
|
if (isAnimation() || type == VideoDocument) return;
|
||||||
|
_duration = fileIsImage(name, mime) ? 1 : -1; // hack
|
||||||
}
|
}
|
||||||
|
|
||||||
DocumentData::~DocumentData() {
|
DocumentData::~DocumentData() {
|
||||||
|
|
|
@ -1132,8 +1132,14 @@ public:
|
||||||
bool isAnimation() const {
|
bool isAnimation() const {
|
||||||
return (type == AnimatedDocument) || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive);
|
return (type == AnimatedDocument) || !mime.compare(qstr("image/gif"), Qt::CaseInsensitive);
|
||||||
}
|
}
|
||||||
|
bool isGifv() const {
|
||||||
|
return (type == AnimatedDocument) && !mime.compare(qstr("video/mp4"), Qt::CaseInsensitive);
|
||||||
|
}
|
||||||
|
int32 duration() const {
|
||||||
|
return (isAnimation() || type == VideoDocument) ? _duration : -1;
|
||||||
|
}
|
||||||
bool isImage() const {
|
bool isImage() const {
|
||||||
return _isImage;
|
return !isAnimation() && (type != VideoDocument) && (_duration > 0);
|
||||||
}
|
}
|
||||||
void recountIsImage();
|
void recountIsImage();
|
||||||
|
|
||||||
|
@ -1159,7 +1165,7 @@ private:
|
||||||
FileLocation _location;
|
FileLocation _location;
|
||||||
QByteArray _data;
|
QByteArray _data;
|
||||||
DocumentAdditionalData *_additional;
|
DocumentAdditionalData *_additional;
|
||||||
bool _isImage;
|
int32 _duration;
|
||||||
|
|
||||||
ActionOnLoad _actionOnLoad;
|
ActionOnLoad _actionOnLoad;
|
||||||
FullMsgId _actionOnLoadMsgId;
|
FullMsgId _actionOnLoadMsgId;
|
||||||
|
|
|
@ -34,8 +34,8 @@ IDI_ICON1 ICON "SourceFiles\\art\\icon256.ico"
|
||||||
//
|
//
|
||||||
|
|
||||||
VS_VERSION_INFO VERSIONINFO
|
VS_VERSION_INFO VERSIONINFO
|
||||||
FILEVERSION 0,9,15,4
|
FILEVERSION 0,9,15,5
|
||||||
PRODUCTVERSION 0,9,15,4
|
PRODUCTVERSION 0,9,15,5
|
||||||
FILEFLAGSMASK 0x3fL
|
FILEFLAGSMASK 0x3fL
|
||||||
#ifdef _DEBUG
|
#ifdef _DEBUG
|
||||||
FILEFLAGS 0x1L
|
FILEFLAGS 0x1L
|
||||||
|
@ -51,10 +51,10 @@ BEGIN
|
||||||
BLOCK "040904b0"
|
BLOCK "040904b0"
|
||||||
BEGIN
|
BEGIN
|
||||||
VALUE "CompanyName", "Telegram Messenger LLP"
|
VALUE "CompanyName", "Telegram Messenger LLP"
|
||||||
VALUE "FileVersion", "0.9.15.4"
|
VALUE "FileVersion", "0.9.15.5"
|
||||||
VALUE "LegalCopyright", "Copyright (C) 2013"
|
VALUE "LegalCopyright", "Copyright (C) 2013"
|
||||||
VALUE "ProductName", "Telegram Desktop"
|
VALUE "ProductName", "Telegram Desktop"
|
||||||
VALUE "ProductVersion", "0.9.15.4"
|
VALUE "ProductVersion", "0.9.15.5"
|
||||||
END
|
END
|
||||||
END
|
END
|
||||||
BLOCK "VarFileInfo"
|
BLOCK "VarFileInfo"
|
||||||
|
|
|
@ -3,4 +3,4 @@ AppVersionStrMajor 0.9
|
||||||
AppVersionStrSmall 0.9.15
|
AppVersionStrSmall 0.9.15
|
||||||
AppVersionStr 0.9.15
|
AppVersionStr 0.9.15
|
||||||
DevChannel 0
|
DevChannel 0
|
||||||
BetaVersion 9015004
|
BetaVersion 9015005
|
||||||
|
|
Loading…
Reference in New Issue