Caching webp converted
This commit is contained in:
parent
ca5fecef31
commit
27c6cb6eeb
@ -1876,13 +1876,7 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
.addClass(attrs.imgClass);
|
||||
|
||||
var setSrc = function (blob) {
|
||||
if (WebpManager.isWebpSupported()) {
|
||||
imgElement.attr('src', FileManager.getUrl(blob, 'image/webp'));
|
||||
return;
|
||||
}
|
||||
FileManager.getByteArray(blob).then(function (bytes) {
|
||||
imgElement.attr('src', WebpManager.getPngUrlFromData(bytes));
|
||||
});
|
||||
imgElement.attr('src', FileManager.getUrl(blob));
|
||||
};
|
||||
|
||||
imgElement.css({
|
||||
@ -1894,12 +1888,16 @@ angular.module('myApp.directives', ['myApp.filters'])
|
||||
height: $scope.document.thumb.height
|
||||
});
|
||||
|
||||
var smallLocation = $scope.document.thumb.location;
|
||||
var smallLocation = angular.copy($scope.document.thumb.location);
|
||||
smallLocation.sticker = true;
|
||||
|
||||
var fullLocation = {
|
||||
_: 'inputDocumentFileLocation',
|
||||
id: $scope.document.id,
|
||||
access_hash: $scope.document.access_hash,
|
||||
dc_id: $scope.document.dc_id
|
||||
dc_id: $scope.document.dc_id,
|
||||
file_name: $scope.document.file_name,
|
||||
sticker: true
|
||||
};
|
||||
|
||||
|
||||
|
@ -255,7 +255,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
|
||||
}
|
||||
})
|
||||
|
||||
.factory('MtpApiFileManager', function (MtpApiManager, $q, FileManager, IdbFileStorage, TmpfsFileStorage, MemoryFileStorage) {
|
||||
.factory('MtpApiFileManager', function (MtpApiManager, $q, FileManager, IdbFileStorage, TmpfsFileStorage, MemoryFileStorage, WebpManager) {
|
||||
|
||||
var cachedFs = false;
|
||||
var cachedFsPromise = false;
|
||||
@ -318,17 +318,25 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
|
||||
return 'video' + location.id + '.mp4';
|
||||
|
||||
case 'inputDocumentFileLocation':
|
||||
var fileName = (location.file_name || '').split('.', 2);
|
||||
var ext = fileName[1] || '';
|
||||
if (location.sticker && !WebpManager.isWebpSupported()) {
|
||||
ext += '.png';
|
||||
}
|
||||
if (fileName.length) {
|
||||
return fileName[0] + '_' + location.id + '.' + ext;
|
||||
}
|
||||
return 'doc' + location.id;
|
||||
|
||||
case 'inputAudioFileLocation':
|
||||
return 'audio' + location.id;
|
||||
}
|
||||
|
||||
if (!location.volume_id) {
|
||||
console.trace('Empty location', location);
|
||||
default:
|
||||
if (!location.volume_id) {
|
||||
console.trace('Empty location', location);
|
||||
}
|
||||
return location.volume_id + '_' + location.local_id + '_' + location.secret + '.jpg';
|
||||
}
|
||||
|
||||
return location.volume_id + '_' + location.local_id + '_' + location.secret + '.jpg';
|
||||
};
|
||||
|
||||
function getTempFileName(file) {
|
||||
@ -374,7 +382,7 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
|
||||
}
|
||||
// console.log('dload small', location);
|
||||
var fileName = getFileName(location),
|
||||
mimeType = 'image/jpeg',
|
||||
mimeType = location.sticker ? 'image/webp' : 'image/jpeg',
|
||||
cachedPromise = cachedSavePromises[fileName] || cachedDownloadPromises[fileName];
|
||||
|
||||
if (cachedPromise) {
|
||||
@ -403,11 +411,20 @@ angular.module('izhukov.mtproto.wrapper', ['izhukov.utils', 'izhukov.mtproto'])
|
||||
});
|
||||
});
|
||||
|
||||
var processDownloaded = function (blob) {
|
||||
if (!location.sticker || WebpManager.isWebpSupported()) {
|
||||
return qSync.when(blob);
|
||||
}
|
||||
return WebpManager.getPngBlobFromWebp(blob);
|
||||
};
|
||||
|
||||
return fileStorage.getFileWriter(fileName, mimeType).then(function (fileWriter) {
|
||||
return downloadPromise.then(function (result) {
|
||||
return FileManager.write(fileWriter, result.bytes).then(function () {
|
||||
return cachedDownloads[fileName] = fileWriter.finalize();
|
||||
});
|
||||
return processDownloaded.then(function (proccessedResult) {
|
||||
return FileManager.write(fileWriter, proccessedResult.bytes).then(function () {
|
||||
return cachedDownloads[fileName] = fileWriter.finalize();
|
||||
});
|
||||
})
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@ -656,6 +656,121 @@ angular.module('izhukov.utils', [])
|
||||
};
|
||||
})
|
||||
|
||||
.service('WebpManager', function (qSync, $q) {
|
||||
var nativeWebpSupport = false;
|
||||
|
||||
var image = new Image();
|
||||
image.onload = function () {
|
||||
nativeWebpSupport = this.width === 2 && this.height === 1;
|
||||
};
|
||||
image.onerror = function () {
|
||||
nativeWebpSupport = false;
|
||||
};
|
||||
image.src = 'data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==';
|
||||
|
||||
var canvas, context;
|
||||
|
||||
function getCanvasFromWebp(data) {
|
||||
var start = tsNow();
|
||||
|
||||
var decoder = new WebPDecoder();
|
||||
|
||||
var config = decoder.WebPDecoderConfig;
|
||||
var buffer = config.j || config.output;
|
||||
var bitstream = config.input;
|
||||
|
||||
if (!decoder.WebPInitDecoderConfig(config)) {
|
||||
console.error('[webpjs] Library version mismatch!');
|
||||
return false;
|
||||
}
|
||||
|
||||
// console.log('[webpjs] status code', decoder.VP8StatusCode);
|
||||
var StatusCode = decoder.VP8StatusCode;
|
||||
|
||||
status = decoder.WebPGetFeatures(data, data.length, bitstream);
|
||||
if (status != (StatusCode.VP8_STATUS_OK || 0)) {
|
||||
console.error('[webpjs] status error', status, StatusCode);
|
||||
}
|
||||
|
||||
var mode = decoder.WEBP_CSP_MODE;
|
||||
buffer.colorspace = mode.MODE_RGBA;
|
||||
buffer.J = 4;
|
||||
|
||||
try {
|
||||
status = decoder.WebPDecode(data, data.length, config);
|
||||
} catch (e) {
|
||||
status = e;
|
||||
}
|
||||
|
||||
ok = (status == 0);
|
||||
if (!ok) {
|
||||
console.error('[webpjs] decoding failed', status);
|
||||
return false;
|
||||
}
|
||||
|
||||
// console.log('[webpjs] decoded: ', buffer.width, buffer.height, bitstream.has_alpha, 'Now saving...');
|
||||
var bitmap = buffer.c.RGBA.ma;
|
||||
|
||||
// console.log('[webpjs] done in ', tsNow() - start);
|
||||
|
||||
if (!bitmap) {
|
||||
return false;
|
||||
}
|
||||
var biHeight = buffer.height;
|
||||
var biWidth = buffer.width;
|
||||
|
||||
if (!canvas || !context) {
|
||||
canvas = document.createElement('canvas');
|
||||
context = canvas.getContext('2d');
|
||||
} else {
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
canvas.height = biHeight;
|
||||
canvas.width = biWidth;
|
||||
|
||||
var output = context.createImageData(canvas.width, canvas.height);
|
||||
var outputData = output.data;
|
||||
|
||||
for (var h = 0; h < biHeight; h++) {
|
||||
for (var w = 0; w < biWidth; w++) {
|
||||
outputData[0+w*4+(biWidth*4)*h] = bitmap[1+w*4+(biWidth*4)*h];
|
||||
outputData[1+w*4+(biWidth*4)*h] = bitmap[2+w*4+(biWidth*4)*h];
|
||||
outputData[2+w*4+(biWidth*4)*h] = bitmap[3+w*4+(biWidth*4)*h];
|
||||
outputData[3+w*4+(biWidth*4)*h] = bitmap[0+w*4+(biWidth*4)*h];
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
context.putImageData(output, 0, 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function getPngBlobFromWebp (data) {
|
||||
if (!getCanvasFromWebp(data)) {
|
||||
return qSync.reject({type: 'WEBP_PROCESS_FAILEd'});
|
||||
}
|
||||
if (canvas.toBlob === undefined) {
|
||||
return dataUrlToBlob(canvas.toDataURL('image/png'));
|
||||
}
|
||||
|
||||
var deferred = $q.defer();
|
||||
canvas.toBlob(function (blob) {
|
||||
deferred.resolve(blob);
|
||||
}, 'image/png');
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
return {
|
||||
isWebpSupported: function () {
|
||||
return nativeWebpSupport;
|
||||
},
|
||||
getPngBlobFromWebp: getPngBlobFromWebp
|
||||
}
|
||||
|
||||
})
|
||||
|
||||
|
||||
.service('CryptoWorker', function ($timeout, $q) {
|
||||
|
||||
var webWorker = false,
|
||||
|
@ -451,103 +451,3 @@ function versionCompare (ver1, ver2) {
|
||||
};
|
||||
|
||||
})(window);
|
||||
|
||||
|
||||
(function (global) {
|
||||
var nativeWebpSupport = false;
|
||||
|
||||
var image = new Image();
|
||||
image.onload = function () {
|
||||
nativeWebpSupport = this.width === 2 && this.height === 1;
|
||||
};
|
||||
image.onerror = function () {
|
||||
nativeWebpSupport = false;
|
||||
};
|
||||
image.src = 'data:image/webp;base64,UklGRjIAAABXRUJQVlA4ICYAAACyAgCdASoCAAEALmk0mk0iIiIiIgBoSygABc6zbAAA/v56QAAAAA==';
|
||||
|
||||
var canvas, context;
|
||||
|
||||
function getPngUrlFromData(data) {
|
||||
var start = tsNow();
|
||||
|
||||
var decoder = new WebPDecoder();
|
||||
|
||||
var config = decoder.WebPDecoderConfig;
|
||||
var buffer = config.j || config.output;
|
||||
var bitstream = config.input;
|
||||
|
||||
if (!decoder.WebPInitDecoderConfig(config)) {
|
||||
console.error('[webpjs] Library version mismatch!');
|
||||
return false;
|
||||
}
|
||||
|
||||
// console.log('[webpjs] status code', decoder.VP8StatusCode);
|
||||
var StatusCode = decoder.VP8StatusCode;
|
||||
|
||||
status = decoder.WebPGetFeatures(data, data.length, bitstream);
|
||||
if (status != (StatusCode.VP8_STATUS_OK || 0)) {
|
||||
console.error('[webpjs] status error', status, StatusCode);
|
||||
}
|
||||
|
||||
var mode = decoder.WEBP_CSP_MODE;
|
||||
buffer.colorspace = mode.MODE_RGBA;
|
||||
buffer.J = 4;
|
||||
|
||||
try {
|
||||
status = decoder.WebPDecode(data, data.length, config);
|
||||
} catch (e) {
|
||||
status = e;
|
||||
}
|
||||
|
||||
ok = (status == 0);
|
||||
if (!ok) {
|
||||
console.error('[webpjs] decoding failed', status);
|
||||
return false;
|
||||
}
|
||||
|
||||
// console.log('[webpjs] decoded: ', buffer.width, buffer.height, bitstream.has_alpha, 'Now saving...');
|
||||
var bitmap = buffer.c.RGBA.ma;
|
||||
|
||||
// console.log('[webpjs] done in ', tsNow() - start);
|
||||
|
||||
if (!bitmap) {
|
||||
return false;
|
||||
}
|
||||
var biHeight = buffer.height;
|
||||
var biWidth = buffer.width;
|
||||
|
||||
if (!canvas || !context) {
|
||||
canvas = document.createElement('canvas');
|
||||
context = canvas.getContext('2d');
|
||||
} else {
|
||||
context.clearRect(0, 0, canvas.width, canvas.height);
|
||||
}
|
||||
canvas.height = biHeight;
|
||||
canvas.width = biWidth;
|
||||
|
||||
var output = context.createImageData(canvas.width, canvas.height);
|
||||
var outputData = output.data;
|
||||
|
||||
for (var h = 0; h < biHeight; h++) {
|
||||
for (var w = 0; w < biWidth; w++) {
|
||||
outputData[0+w*4+(biWidth*4)*h] = bitmap[1+w*4+(biWidth*4)*h];
|
||||
outputData[1+w*4+(biWidth*4)*h] = bitmap[2+w*4+(biWidth*4)*h];
|
||||
outputData[2+w*4+(biWidth*4)*h] = bitmap[3+w*4+(biWidth*4)*h];
|
||||
outputData[3+w*4+(biWidth*4)*h] = bitmap[0+w*4+(biWidth*4)*h];
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
context.putImageData(output, 0, 0);
|
||||
|
||||
return canvas.toDataURL('image/png');
|
||||
}
|
||||
|
||||
|
||||
global.WebpManager = {
|
||||
isWebpSupported: function () {
|
||||
return nativeWebpSupport;
|
||||
},
|
||||
getPngUrlFromData: getPngUrlFromData
|
||||
}
|
||||
})(window);
|
||||
|
@ -3445,7 +3445,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
inputFileLocation = {
|
||||
_: 'inputDocumentFileLocation',
|
||||
id: docID,
|
||||
access_hash: doc.access_hash
|
||||
access_hash: doc.access_hash,
|
||||
file_name: doc.file_name
|
||||
};
|
||||
|
||||
if (historyDoc.downloaded === undefined) {
|
||||
@ -3463,7 +3464,8 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
inputFileLocation = {
|
||||
_: 'inputDocumentFileLocation',
|
||||
id: docID,
|
||||
access_hash: doc.access_hash
|
||||
access_hash: doc.access_hash,
|
||||
file_name: doc.file_name
|
||||
};
|
||||
|
||||
if (historyDoc.downloaded && !toFileEntry) {
|
||||
@ -3783,20 +3785,13 @@ angular.module('myApp.services', ['myApp.i18n', 'izhukov.utils'])
|
||||
|
||||
function downloadStickerThumb (docID) {
|
||||
var doc = AppDocsManager.getDoc(docID);
|
||||
return MtpApiFileManager.downloadSmallFile(doc.thumb.location).then(function (blob) {
|
||||
if (WebpManager.isWebpSupported()) {
|
||||
return {
|
||||
id: doc.id,
|
||||
src: FileManager.getUrl(blob, 'image/webp')
|
||||
};
|
||||
}
|
||||
|
||||
return FileManager.getByteArray(blob).then(function (bytes) {
|
||||
return {
|
||||
id: doc.id,
|
||||
src: WebpManager.getPngUrlFromData(bytes)
|
||||
};
|
||||
});
|
||||
var thumbLocation = angular.copy(doc.thumb.location);
|
||||
thumbLocation.sticker = true;
|
||||
return MtpApiFileManager.downloadSmallFile(thumbLocation).then(function (blob) {
|
||||
return {
|
||||
id: doc.id,
|
||||
src: FileManager.getUrl(blob, 'image/webp')
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user